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 "utils/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 if (process_memory == nullptr) {
40 process_memory = &process_memory_;
41 }
42
43 regs_arm_.reset(new RegsArm());
44 for (size_t i = 0; i < regs_arm_->total_regs(); i++) {
45 (*regs_arm_)[i] = 0;
46 }
47 regs_arm_->set_pc(0);
48 regs_arm_->set_sp(0);
49
50 exidx_.reset(new ArmExidx(regs_arm_.get(), &elf_memory_, process_memory));
51 if (log_ != ARM_LOG_NONE) {
52 exidx_->set_log(log_);
53 exidx_->set_log_indent(0);
54 exidx_->set_log_skip_execution(false);
55 }
56 data_ = exidx_->data();
57 exidx_->set_cfa(0x10000);
58 }
59
SetUp()60 void SetUp() override {
61 if (GetParam() == "no_logging") {
62 log_ = ARM_LOG_NONE;
63 } else if (GetParam() == "register_logging") {
64 log_ = ARM_LOG_BY_REG;
65 } else {
66 log_ = ARM_LOG_FULL;
67 }
68 elf_memory_.Clear();
69 process_memory_.Clear();
70 ResetExidx();
71 }
72
ResetExidx()73 void ResetExidx() {
74 ResetLogs();
75 Init();
76 }
77
78 std::unique_ptr<ArmExidx> exidx_;
79 std::unique_ptr<RegsArm> regs_arm_;
80 std::deque<uint8_t>* data_;
81
82 MemoryFake elf_memory_;
83 MemoryFake process_memory_;
84 ArmLogType log_;
85 };
86
TEST_P(ArmExidxDecodeTest,vsp_incr)87 TEST_P(ArmExidxDecodeTest, vsp_incr) {
88 // 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4
89 data_->push_back(0x00);
90 ASSERT_TRUE(exidx_->Decode());
91 ASSERT_FALSE(exidx_->pc_set());
92 ASSERT_EQ("", GetFakeLogBuf());
93 switch (log_) {
94 case ARM_LOG_NONE:
95 ASSERT_EQ("", GetFakeLogPrint());
96 break;
97 case ARM_LOG_FULL:
98 ASSERT_EQ("4 unwind vsp = vsp + 4\n", GetFakeLogPrint());
99 break;
100 case ARM_LOG_BY_REG:
101 exidx_->LogByReg();
102 ASSERT_EQ("4 unwind cfa = r13 + 4\n", GetFakeLogPrint());
103 break;
104 }
105 ASSERT_EQ(0x10004U, exidx_->cfa());
106
107 ResetExidx();
108 data_->clear();
109 data_->push_back(0x01);
110 ASSERT_TRUE(exidx_->Decode());
111 ASSERT_FALSE(exidx_->pc_set());
112 ASSERT_EQ("", GetFakeLogBuf());
113 switch (log_) {
114 case ARM_LOG_NONE:
115 ASSERT_EQ("", GetFakeLogPrint());
116 break;
117 case ARM_LOG_FULL:
118 ASSERT_EQ("4 unwind vsp = vsp + 8\n", GetFakeLogPrint());
119 break;
120 case ARM_LOG_BY_REG:
121 exidx_->LogByReg();
122 ASSERT_EQ("4 unwind cfa = r13 + 8\n", GetFakeLogPrint());
123 break;
124 }
125 ASSERT_EQ(0x10008U, exidx_->cfa());
126
127 ResetExidx();
128 data_->clear();
129 data_->push_back(0x3f);
130 ASSERT_TRUE(exidx_->Decode());
131 ASSERT_FALSE(exidx_->pc_set());
132 ASSERT_EQ("", GetFakeLogBuf());
133 switch (log_) {
134 case ARM_LOG_NONE:
135 ASSERT_EQ("", GetFakeLogPrint());
136 break;
137 case ARM_LOG_FULL:
138 ASSERT_EQ("4 unwind vsp = vsp + 256\n", GetFakeLogPrint());
139 break;
140 case ARM_LOG_BY_REG:
141 exidx_->LogByReg();
142 ASSERT_EQ("4 unwind cfa = r13 + 256\n", GetFakeLogPrint());
143 break;
144 }
145 ASSERT_EQ(0x10100U, exidx_->cfa());
146 }
147
TEST_P(ArmExidxDecodeTest,vsp_decr)148 TEST_P(ArmExidxDecodeTest, vsp_decr) {
149 // 01xxxxxx: vsp = vsp - (xxxxxx << 2) + 4
150 data_->push_back(0x40);
151 ASSERT_TRUE(exidx_->Decode());
152 ASSERT_FALSE(exidx_->pc_set());
153 ASSERT_EQ("", GetFakeLogBuf());
154 switch (log_) {
155 case ARM_LOG_NONE:
156 ASSERT_EQ("", GetFakeLogPrint());
157 break;
158 case ARM_LOG_FULL:
159 ASSERT_EQ("4 unwind vsp = vsp - 4\n", GetFakeLogPrint());
160 break;
161 case ARM_LOG_BY_REG:
162 exidx_->LogByReg();
163 ASSERT_EQ("4 unwind cfa = r13 - 4\n", GetFakeLogPrint());
164 break;
165 }
166 ASSERT_EQ(0xfffcU, exidx_->cfa());
167
168 ResetExidx();
169 data_->clear();
170 data_->push_back(0x41);
171 ASSERT_TRUE(exidx_->Decode());
172 ASSERT_FALSE(exidx_->pc_set());
173 ASSERT_EQ("", GetFakeLogBuf());
174 switch (log_) {
175 case ARM_LOG_NONE:
176 ASSERT_EQ("", GetFakeLogPrint());
177 break;
178 case ARM_LOG_FULL:
179 ASSERT_EQ("4 unwind vsp = vsp - 8\n", GetFakeLogPrint());
180 break;
181 case ARM_LOG_BY_REG:
182 exidx_->LogByReg();
183 ASSERT_EQ("4 unwind cfa = r13 - 8\n", GetFakeLogPrint());
184 break;
185 }
186 ASSERT_EQ(0xfff8U, exidx_->cfa());
187
188 ResetExidx();
189 data_->clear();
190 data_->push_back(0x7f);
191 ASSERT_TRUE(exidx_->Decode());
192 ASSERT_FALSE(exidx_->pc_set());
193 ASSERT_EQ("", GetFakeLogBuf());
194 switch (log_) {
195 case ARM_LOG_NONE:
196 ASSERT_EQ("", GetFakeLogPrint());
197 break;
198 case ARM_LOG_FULL:
199 ASSERT_EQ("4 unwind vsp = vsp - 256\n", GetFakeLogPrint());
200 break;
201 case ARM_LOG_BY_REG:
202 exidx_->LogByReg();
203 ASSERT_EQ("4 unwind cfa = r13 - 256\n", GetFakeLogPrint());
204 break;
205 }
206 ASSERT_EQ(0xff00U, exidx_->cfa());
207 }
208
TEST_P(ArmExidxDecodeTest,refuse_unwind)209 TEST_P(ArmExidxDecodeTest, refuse_unwind) {
210 // 10000000 00000000: Refuse to unwind
211 data_->push_back(0x80);
212 data_->push_back(0x00);
213 ASSERT_FALSE(exidx_->Decode());
214 ASSERT_EQ("", GetFakeLogBuf());
215 switch (log_) {
216 case ARM_LOG_NONE:
217 ASSERT_EQ("", GetFakeLogPrint());
218 break;
219 case ARM_LOG_FULL:
220 case ARM_LOG_BY_REG:
221 ASSERT_EQ("4 unwind Refuse to unwind\n", GetFakeLogPrint());
222 break;
223 }
224 ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status());
225 }
226
TEST_P(ArmExidxDecodeTest,pop_up_to_12)227 TEST_P(ArmExidxDecodeTest, pop_up_to_12) {
228 // 1000iiii iiiiiiii: Pop up to 12 integer registers
229 data_->push_back(0x88);
230 data_->push_back(0x00);
231 process_memory_.SetData32(0x10000, 0x10);
232 ASSERT_TRUE(exidx_->Decode());
233 ASSERT_TRUE(exidx_->pc_set());
234 ASSERT_EQ("", GetFakeLogBuf());
235 switch (log_) {
236 case ARM_LOG_NONE:
237 ASSERT_EQ("", GetFakeLogPrint());
238 break;
239 case ARM_LOG_FULL:
240 ASSERT_EQ("4 unwind pop {r15}\n", GetFakeLogPrint());
241 break;
242 case ARM_LOG_BY_REG:
243 exidx_->LogByReg();
244 ASSERT_EQ(
245 "4 unwind cfa = r13 + 4\n"
246 "4 unwind r15 = [cfa - 4]\n",
247 GetFakeLogPrint());
248 break;
249 }
250 ASSERT_EQ(0x10004U, exidx_->cfa());
251 ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
252
253 ResetExidx();
254 data_->push_back(0x8f);
255 data_->push_back(0xff);
256 for (size_t i = 0; i < 12; i++) {
257 process_memory_.SetData32(0x10000 + i * 4, i + 0x20);
258 }
259 exidx_->set_pc_set(false);
260 ASSERT_TRUE(exidx_->Decode());
261 ASSERT_TRUE(exidx_->pc_set());
262 ASSERT_EQ("", GetFakeLogBuf());
263 switch (log_) {
264 case ARM_LOG_NONE:
265 ASSERT_EQ("", GetFakeLogPrint());
266 break;
267 case ARM_LOG_FULL:
268 ASSERT_EQ("4 unwind pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}\n",
269 GetFakeLogPrint());
270 break;
271 case ARM_LOG_BY_REG:
272 exidx_->LogByReg();
273 ASSERT_EQ(
274 "4 unwind cfa = r13 + 48\n"
275 "4 unwind r4 = [cfa - 48]\n"
276 "4 unwind r5 = [cfa - 44]\n"
277 "4 unwind r6 = [cfa - 40]\n"
278 "4 unwind r7 = [cfa - 36]\n"
279 "4 unwind r8 = [cfa - 32]\n"
280 "4 unwind r9 = [cfa - 28]\n"
281 "4 unwind r10 = [cfa - 24]\n"
282 "4 unwind r11 = [cfa - 20]\n"
283 "4 unwind r12 = [cfa - 16]\n"
284 "4 unwind r13 = [cfa - 12]\n"
285 "4 unwind r14 = [cfa - 8]\n"
286 "4 unwind r15 = [cfa - 4]\n",
287 GetFakeLogPrint());
288 break;
289 }
290 // Popping r13 results in a modified cfa.
291 ASSERT_EQ(0x29U, exidx_->cfa());
292
293 ASSERT_EQ(0x20U, (*exidx_->regs())[4]);
294 ASSERT_EQ(0x21U, (*exidx_->regs())[5]);
295 ASSERT_EQ(0x22U, (*exidx_->regs())[6]);
296 ASSERT_EQ(0x23U, (*exidx_->regs())[7]);
297 ASSERT_EQ(0x24U, (*exidx_->regs())[8]);
298 ASSERT_EQ(0x25U, (*exidx_->regs())[9]);
299 ASSERT_EQ(0x26U, (*exidx_->regs())[10]);
300 ASSERT_EQ(0x27U, (*exidx_->regs())[11]);
301 ASSERT_EQ(0x28U, (*exidx_->regs())[12]);
302 ASSERT_EQ(0x29U, (*exidx_->regs())[13]);
303 ASSERT_EQ(0x2aU, (*exidx_->regs())[14]);
304 ASSERT_EQ(0x2bU, (*exidx_->regs())[15]);
305
306 ResetExidx();
307 exidx_->set_cfa(0x10034);
308 data_->push_back(0x81);
309 data_->push_back(0x28);
310 process_memory_.SetData32(0x10034, 0x11);
311 process_memory_.SetData32(0x10038, 0x22);
312 process_memory_.SetData32(0x1003c, 0x33);
313 exidx_->set_pc_set(false);
314 ASSERT_TRUE(exidx_->Decode());
315 ASSERT_FALSE(exidx_->pc_set());
316 ASSERT_EQ("", GetFakeLogBuf());
317 switch (log_) {
318 case ARM_LOG_NONE:
319 ASSERT_EQ("", GetFakeLogPrint());
320 break;
321 case ARM_LOG_FULL:
322 ASSERT_EQ("4 unwind pop {r7, r9, r12}\n", GetFakeLogPrint());
323 break;
324 case ARM_LOG_BY_REG:
325 exidx_->LogByReg();
326 ASSERT_EQ(
327 "4 unwind cfa = r13 + 12\n"
328 "4 unwind r7 = [cfa - 12]\n"
329 "4 unwind r9 = [cfa - 8]\n"
330 "4 unwind r12 = [cfa - 4]\n",
331 GetFakeLogPrint());
332 break;
333 }
334 ASSERT_EQ(0x10040U, exidx_->cfa());
335 ASSERT_EQ(0x11U, (*exidx_->regs())[7]);
336 ASSERT_EQ(0x22U, (*exidx_->regs())[9]);
337 ASSERT_EQ(0x33U, (*exidx_->regs())[12]);
338 }
339
TEST_P(ArmExidxDecodeTest,set_vsp_from_register)340 TEST_P(ArmExidxDecodeTest, set_vsp_from_register) {
341 // 1001nnnn: Set vsp = r[nnnn] (nnnn != 13, 15)
342 exidx_->set_cfa(0x100);
343 for (size_t i = 0; i < 15; i++) {
344 (*regs_arm_)[i] = i + 1;
345 }
346
347 data_->push_back(0x90);
348 ASSERT_TRUE(exidx_->Decode());
349 ASSERT_FALSE(exidx_->pc_set());
350 ASSERT_EQ("", GetFakeLogBuf());
351 switch (log_) {
352 case ARM_LOG_NONE:
353 ASSERT_EQ("", GetFakeLogPrint());
354 break;
355 case ARM_LOG_FULL:
356 ASSERT_EQ("4 unwind vsp = r0\n", GetFakeLogPrint());
357 break;
358 case ARM_LOG_BY_REG:
359 exidx_->LogByReg();
360 ASSERT_EQ("4 unwind cfa = r0\n", GetFakeLogPrint());
361 break;
362 }
363 ASSERT_EQ(1U, exidx_->cfa());
364
365 ResetExidx();
366 exidx_->set_cfa(0x100);
367 for (size_t i = 0; i < 15; i++) {
368 (*regs_arm_)[i] = i + 1;
369 }
370 data_->push_back(0x93);
371 ASSERT_TRUE(exidx_->Decode());
372 ASSERT_FALSE(exidx_->pc_set());
373 ASSERT_EQ("", GetFakeLogBuf());
374 switch (log_) {
375 case ARM_LOG_NONE:
376 ASSERT_EQ("", GetFakeLogPrint());
377 break;
378 case ARM_LOG_FULL:
379 ASSERT_EQ("4 unwind vsp = r3\n", GetFakeLogPrint());
380 break;
381 case ARM_LOG_BY_REG:
382 exidx_->LogByReg();
383 ASSERT_EQ("4 unwind cfa = r3\n", GetFakeLogPrint());
384 break;
385 }
386 ASSERT_EQ(4U, exidx_->cfa());
387
388 ResetExidx();
389 exidx_->set_cfa(0x100);
390 for (size_t i = 0; i < 15; i++) {
391 (*regs_arm_)[i] = i + 1;
392 }
393 data_->push_back(0x9e);
394 ASSERT_TRUE(exidx_->Decode());
395 ASSERT_FALSE(exidx_->pc_set());
396 ASSERT_EQ("", GetFakeLogBuf());
397 switch (log_) {
398 case ARM_LOG_NONE:
399 ASSERT_EQ("", GetFakeLogPrint());
400 break;
401 case ARM_LOG_FULL:
402 ASSERT_EQ("4 unwind vsp = r14\n", GetFakeLogPrint());
403 break;
404 case ARM_LOG_BY_REG:
405 exidx_->LogByReg();
406 ASSERT_EQ("4 unwind cfa = r14\n", GetFakeLogPrint());
407 break;
408 }
409 ASSERT_EQ(15U, exidx_->cfa());
410 }
411
TEST_P(ArmExidxDecodeTest,reserved_prefix)412 TEST_P(ArmExidxDecodeTest, reserved_prefix) {
413 // 10011101: Reserved as prefix for ARM register to register moves
414 data_->push_back(0x9d);
415 ASSERT_FALSE(exidx_->Decode());
416 ASSERT_EQ("", GetFakeLogBuf());
417 switch (log_) {
418 case ARM_LOG_NONE:
419 ASSERT_EQ("", GetFakeLogPrint());
420 break;
421 case ARM_LOG_FULL:
422 case ARM_LOG_BY_REG:
423 ASSERT_EQ("4 unwind [Reserved]\n", GetFakeLogPrint());
424 break;
425 }
426 ASSERT_EQ(ARM_STATUS_RESERVED, exidx_->status());
427
428 // 10011111: Reserved as prefix for Intel Wireless MMX register to register moves
429 ResetExidx();
430 data_->push_back(0x9f);
431 ASSERT_FALSE(exidx_->Decode());
432 ASSERT_EQ("", GetFakeLogBuf());
433 switch (log_) {
434 case ARM_LOG_NONE:
435 ASSERT_EQ("", GetFakeLogPrint());
436 break;
437 case ARM_LOG_FULL:
438 case ARM_LOG_BY_REG:
439 ASSERT_EQ("4 unwind [Reserved]\n", GetFakeLogPrint());
440 break;
441 }
442 ASSERT_EQ(ARM_STATUS_RESERVED, exidx_->status());
443 }
444
TEST_P(ArmExidxDecodeTest,pop_registers)445 TEST_P(ArmExidxDecodeTest, pop_registers) {
446 // 10100nnn: Pop r4-r[4+nnn]
447 data_->push_back(0xa0);
448 process_memory_.SetData32(0x10000, 0x14);
449 ASSERT_TRUE(exidx_->Decode());
450 ASSERT_FALSE(exidx_->pc_set());
451 ASSERT_EQ("", GetFakeLogBuf());
452 switch (log_) {
453 case ARM_LOG_NONE:
454 ASSERT_EQ("", GetFakeLogPrint());
455 break;
456 case ARM_LOG_FULL:
457 ASSERT_EQ("4 unwind pop {r4}\n", GetFakeLogPrint());
458 break;
459 case ARM_LOG_BY_REG:
460 exidx_->LogByReg();
461 ASSERT_EQ(
462 "4 unwind cfa = r13 + 4\n"
463 "4 unwind r4 = [cfa - 4]\n",
464 GetFakeLogPrint());
465 break;
466 }
467 ASSERT_EQ(0x10004U, exidx_->cfa());
468 ASSERT_EQ(0x14U, (*exidx_->regs())[4]);
469
470 ResetExidx();
471 data_->push_back(0xa3);
472 process_memory_.SetData32(0x10000, 0x20);
473 process_memory_.SetData32(0x10004, 0x30);
474 process_memory_.SetData32(0x10008, 0x40);
475 process_memory_.SetData32(0x1000c, 0x50);
476 ASSERT_TRUE(exidx_->Decode());
477 ASSERT_FALSE(exidx_->pc_set());
478 ASSERT_EQ("", GetFakeLogBuf());
479 switch (log_) {
480 case ARM_LOG_NONE:
481 ASSERT_EQ("", GetFakeLogPrint());
482 break;
483 case ARM_LOG_FULL:
484 ASSERT_EQ("4 unwind pop {r4-r7}\n", GetFakeLogPrint());
485 break;
486 case ARM_LOG_BY_REG:
487 exidx_->LogByReg();
488 ASSERT_EQ(
489 "4 unwind cfa = r13 + 16\n"
490 "4 unwind r4 = [cfa - 16]\n"
491 "4 unwind r5 = [cfa - 12]\n"
492 "4 unwind r6 = [cfa - 8]\n"
493 "4 unwind r7 = [cfa - 4]\n",
494 GetFakeLogPrint());
495 break;
496 }
497 ASSERT_EQ(0x10010U, exidx_->cfa());
498 ASSERT_EQ(0x20U, (*exidx_->regs())[4]);
499 ASSERT_EQ(0x30U, (*exidx_->regs())[5]);
500 ASSERT_EQ(0x40U, (*exidx_->regs())[6]);
501 ASSERT_EQ(0x50U, (*exidx_->regs())[7]);
502
503 ResetExidx();
504 data_->push_back(0xa7);
505 process_memory_.SetData32(0x10000, 0x41);
506 process_memory_.SetData32(0x10004, 0x51);
507 process_memory_.SetData32(0x10008, 0x61);
508 process_memory_.SetData32(0x1000c, 0x71);
509 process_memory_.SetData32(0x10010, 0x81);
510 process_memory_.SetData32(0x10014, 0x91);
511 process_memory_.SetData32(0x10018, 0xa1);
512 process_memory_.SetData32(0x1001c, 0xb1);
513 ASSERT_TRUE(exidx_->Decode());
514 ASSERT_FALSE(exidx_->pc_set());
515 ASSERT_EQ("", GetFakeLogBuf());
516 switch (log_) {
517 case ARM_LOG_NONE:
518 ASSERT_EQ("", GetFakeLogPrint());
519 break;
520 case ARM_LOG_FULL:
521 ASSERT_EQ("4 unwind pop {r4-r11}\n", GetFakeLogPrint());
522 break;
523 case ARM_LOG_BY_REG:
524 exidx_->LogByReg();
525 ASSERT_EQ(
526 "4 unwind cfa = r13 + 32\n"
527 "4 unwind r4 = [cfa - 32]\n"
528 "4 unwind r5 = [cfa - 28]\n"
529 "4 unwind r6 = [cfa - 24]\n"
530 "4 unwind r7 = [cfa - 20]\n"
531 "4 unwind r8 = [cfa - 16]\n"
532 "4 unwind r9 = [cfa - 12]\n"
533 "4 unwind r10 = [cfa - 8]\n"
534 "4 unwind r11 = [cfa - 4]\n",
535 GetFakeLogPrint());
536 break;
537 }
538 ASSERT_EQ(0x10020U, exidx_->cfa());
539 ASSERT_EQ(0x41U, (*exidx_->regs())[4]);
540 ASSERT_EQ(0x51U, (*exidx_->regs())[5]);
541 ASSERT_EQ(0x61U, (*exidx_->regs())[6]);
542 ASSERT_EQ(0x71U, (*exidx_->regs())[7]);
543 ASSERT_EQ(0x81U, (*exidx_->regs())[8]);
544 ASSERT_EQ(0x91U, (*exidx_->regs())[9]);
545 ASSERT_EQ(0xa1U, (*exidx_->regs())[10]);
546 ASSERT_EQ(0xb1U, (*exidx_->regs())[11]);
547 }
548
TEST_P(ArmExidxDecodeTest,pop_registers_with_r14)549 TEST_P(ArmExidxDecodeTest, pop_registers_with_r14) {
550 // 10101nnn: Pop r4-r[4+nnn], r14
551 data_->push_back(0xa8);
552 process_memory_.SetData32(0x10000, 0x12);
553 process_memory_.SetData32(0x10004, 0x22);
554 ASSERT_TRUE(exidx_->Decode());
555 ASSERT_FALSE(exidx_->pc_set());
556 ASSERT_EQ("", GetFakeLogBuf());
557 switch (log_) {
558 case ARM_LOG_NONE:
559 ASSERT_EQ("", GetFakeLogPrint());
560 break;
561 case ARM_LOG_FULL:
562 ASSERT_EQ("4 unwind pop {r4, r14}\n", GetFakeLogPrint());
563 break;
564 case ARM_LOG_BY_REG:
565 exidx_->LogByReg();
566 ASSERT_EQ(
567 "4 unwind cfa = r13 + 8\n"
568 "4 unwind r4 = [cfa - 8]\n"
569 "4 unwind r14 = [cfa - 4]\n",
570 GetFakeLogPrint());
571 break;
572 }
573 ASSERT_EQ(0x10008U, exidx_->cfa());
574 ASSERT_EQ(0x12U, (*exidx_->regs())[4]);
575 ASSERT_EQ(0x22U, (*exidx_->regs())[14]);
576
577 ResetExidx();
578 data_->push_back(0xab);
579 process_memory_.SetData32(0x10000, 0x1);
580 process_memory_.SetData32(0x10004, 0x2);
581 process_memory_.SetData32(0x10008, 0x3);
582 process_memory_.SetData32(0x1000c, 0x4);
583 process_memory_.SetData32(0x10010, 0x5);
584 ASSERT_TRUE(exidx_->Decode());
585 ASSERT_FALSE(exidx_->pc_set());
586 ASSERT_EQ("", GetFakeLogBuf());
587 switch (log_) {
588 case ARM_LOG_NONE:
589 ASSERT_EQ("", GetFakeLogPrint());
590 break;
591 case ARM_LOG_FULL:
592 ASSERT_EQ("4 unwind pop {r4-r7, r14}\n", GetFakeLogPrint());
593 break;
594 case ARM_LOG_BY_REG:
595 exidx_->LogByReg();
596 ASSERT_EQ(
597 "4 unwind cfa = r13 + 20\n"
598 "4 unwind r4 = [cfa - 20]\n"
599 "4 unwind r5 = [cfa - 16]\n"
600 "4 unwind r6 = [cfa - 12]\n"
601 "4 unwind r7 = [cfa - 8]\n"
602 "4 unwind r14 = [cfa - 4]\n",
603 GetFakeLogPrint());
604 break;
605 }
606 ASSERT_EQ(0x10014U, exidx_->cfa());
607 ASSERT_EQ(0x1U, (*exidx_->regs())[4]);
608 ASSERT_EQ(0x2U, (*exidx_->regs())[5]);
609 ASSERT_EQ(0x3U, (*exidx_->regs())[6]);
610 ASSERT_EQ(0x4U, (*exidx_->regs())[7]);
611 ASSERT_EQ(0x5U, (*exidx_->regs())[14]);
612
613 ResetExidx();
614 data_->push_back(0xaf);
615 process_memory_.SetData32(0x10000, 0x1a);
616 process_memory_.SetData32(0x10004, 0x2a);
617 process_memory_.SetData32(0x10008, 0x3a);
618 process_memory_.SetData32(0x1000c, 0x4a);
619 process_memory_.SetData32(0x10010, 0x5a);
620 process_memory_.SetData32(0x10014, 0x6a);
621 process_memory_.SetData32(0x10018, 0x7a);
622 process_memory_.SetData32(0x1001c, 0x8a);
623 process_memory_.SetData32(0x10020, 0x9a);
624 ASSERT_TRUE(exidx_->Decode());
625 ASSERT_FALSE(exidx_->pc_set());
626 ASSERT_EQ("", GetFakeLogBuf());
627 switch (log_) {
628 case ARM_LOG_NONE:
629 ASSERT_EQ("", GetFakeLogPrint());
630 break;
631 case ARM_LOG_FULL:
632 ASSERT_EQ("4 unwind pop {r4-r11, r14}\n", GetFakeLogPrint());
633 break;
634 case ARM_LOG_BY_REG:
635 exidx_->LogByReg();
636 ASSERT_EQ(
637 "4 unwind cfa = r13 + 36\n"
638 "4 unwind r4 = [cfa - 36]\n"
639 "4 unwind r5 = [cfa - 32]\n"
640 "4 unwind r6 = [cfa - 28]\n"
641 "4 unwind r7 = [cfa - 24]\n"
642 "4 unwind r8 = [cfa - 20]\n"
643 "4 unwind r9 = [cfa - 16]\n"
644 "4 unwind r10 = [cfa - 12]\n"
645 "4 unwind r11 = [cfa - 8]\n"
646 "4 unwind r14 = [cfa - 4]\n",
647 GetFakeLogPrint());
648 break;
649 }
650 ASSERT_EQ(0x10024U, exidx_->cfa());
651 ASSERT_EQ(0x1aU, (*exidx_->regs())[4]);
652 ASSERT_EQ(0x2aU, (*exidx_->regs())[5]);
653 ASSERT_EQ(0x3aU, (*exidx_->regs())[6]);
654 ASSERT_EQ(0x4aU, (*exidx_->regs())[7]);
655 ASSERT_EQ(0x5aU, (*exidx_->regs())[8]);
656 ASSERT_EQ(0x6aU, (*exidx_->regs())[9]);
657 ASSERT_EQ(0x7aU, (*exidx_->regs())[10]);
658 ASSERT_EQ(0x8aU, (*exidx_->regs())[11]);
659 ASSERT_EQ(0x9aU, (*exidx_->regs())[14]);
660 }
661
TEST_P(ArmExidxDecodeTest,finish)662 TEST_P(ArmExidxDecodeTest, finish) {
663 // 10110000: Finish
664 data_->push_back(0xb0);
665 ASSERT_FALSE(exidx_->Decode());
666 ASSERT_EQ("", GetFakeLogBuf());
667 switch (log_) {
668 case ARM_LOG_NONE:
669 ASSERT_EQ("", GetFakeLogPrint());
670 break;
671 case ARM_LOG_FULL:
672 ASSERT_EQ("4 unwind finish\n", GetFakeLogPrint());
673 break;
674 case ARM_LOG_BY_REG:
675 exidx_->LogByReg();
676 ASSERT_EQ("4 unwind cfa = r13\n", GetFakeLogPrint());
677 break;
678 }
679 ASSERT_EQ(0x10000U, exidx_->cfa());
680 ASSERT_EQ(ARM_STATUS_FINISH, exidx_->status());
681 }
682
TEST_P(ArmExidxDecodeTest,spare)683 TEST_P(ArmExidxDecodeTest, spare) {
684 // 10110001 00000000: Spare
685 data_->push_back(0xb1);
686 data_->push_back(0x00);
687 ASSERT_FALSE(exidx_->Decode());
688 ASSERT_EQ("", GetFakeLogBuf());
689 switch (log_) {
690 case ARM_LOG_NONE:
691 ASSERT_EQ("", GetFakeLogPrint());
692 break;
693 case ARM_LOG_FULL:
694 case ARM_LOG_BY_REG:
695 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint());
696 break;
697 }
698 ASSERT_EQ(0x10000U, exidx_->cfa());
699 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
700
701 // 10110001 xxxxyyyy: Spare (xxxx != 0000)
702 for (size_t x = 1; x < 16; x++) {
703 for (size_t y = 0; y < 16; y++) {
704 ResetExidx();
705 data_->push_back(0xb1);
706 data_->push_back((x << 4) | y);
707 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
708 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
709 switch (log_) {
710 case ARM_LOG_NONE:
711 ASSERT_EQ("", GetFakeLogPrint());
712 break;
713 case ARM_LOG_FULL:
714 case ARM_LOG_BY_REG:
715 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
716 break;
717 }
718 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
719 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
720 }
721 }
722
723 // 101101nn: Spare
724 for (size_t n = 0; n < 4; n++) {
725 ResetExidx();
726 data_->push_back(0xb4 | n);
727 ASSERT_FALSE(exidx_->Decode()) << "n = " << n;
728 ASSERT_EQ("", GetFakeLogBuf()) << "n = " << n;
729 switch (log_) {
730 case ARM_LOG_NONE:
731 ASSERT_EQ("", GetFakeLogPrint());
732 break;
733 case ARM_LOG_FULL:
734 case ARM_LOG_BY_REG:
735 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "n = " << n;
736 break;
737 }
738 ASSERT_EQ(0x10000U, exidx_->cfa()) << "n = " << n;
739 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
740 }
741
742 // 11000111 00000000: Spare
743 ResetExidx();
744 data_->push_back(0xc7);
745 data_->push_back(0x00);
746 ASSERT_FALSE(exidx_->Decode());
747 ASSERT_EQ("", GetFakeLogBuf());
748 switch (log_) {
749 case ARM_LOG_NONE:
750 ASSERT_EQ("", GetFakeLogPrint());
751 break;
752 case ARM_LOG_FULL:
753 case ARM_LOG_BY_REG:
754 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint());
755 break;
756 }
757 ASSERT_EQ(0x10000U, exidx_->cfa());
758 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
759
760 // 11000111 xxxxyyyy: Spare (xxxx != 0000)
761 for (size_t x = 1; x < 16; x++) {
762 for (size_t y = 0; y < 16; y++) {
763 ResetExidx();
764 data_->push_back(0xc7);
765 data_->push_back(0x10);
766 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
767 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
768 switch (log_) {
769 case ARM_LOG_NONE:
770 ASSERT_EQ("", GetFakeLogPrint());
771 break;
772 case ARM_LOG_FULL:
773 case ARM_LOG_BY_REG:
774 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
775 break;
776 }
777 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
778 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
779 }
780 }
781
782 // 11001yyy: Spare (yyy != 000, 001)
783 for (size_t y = 2; y < 8; y++) {
784 ResetExidx();
785 data_->push_back(0xc8 | y);
786 ASSERT_FALSE(exidx_->Decode()) << "y = " << y;
787 ASSERT_EQ("", GetFakeLogBuf()) << "y = " << y;
788 switch (log_) {
789 case ARM_LOG_NONE:
790 ASSERT_EQ("", GetFakeLogPrint());
791 break;
792 case ARM_LOG_FULL:
793 case ARM_LOG_BY_REG:
794 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "y = " << y;
795 break;
796 }
797 ASSERT_EQ(0x10000U, exidx_->cfa()) << "y = " << y;
798 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
799 }
800
801 // 11xxxyyy: Spare (xxx != 000, 001, 010)
802 for (size_t x = 3; x < 8; x++) {
803 for (size_t y = 0; y < 8; y++) {
804 ResetExidx();
805 data_->push_back(0xc0 | (x << 3) | y);
806 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
807 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
808 switch (log_) {
809 case ARM_LOG_NONE:
810 ASSERT_EQ("", GetFakeLogPrint());
811 break;
812 case ARM_LOG_FULL:
813 case ARM_LOG_BY_REG:
814 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
815 break;
816 }
817 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
818 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
819 }
820 }
821 }
822
TEST_P(ArmExidxDecodeTest,pop_registers_under_mask)823 TEST_P(ArmExidxDecodeTest, pop_registers_under_mask) {
824 // 10110001 0000iiii: Pop integer registers {r0, r1, r2, r3}
825 data_->push_back(0xb1);
826 data_->push_back(0x01);
827 process_memory_.SetData32(0x10000, 0x45);
828 ASSERT_TRUE(exidx_->Decode());
829 ASSERT_FALSE(exidx_->pc_set());
830 ASSERT_EQ("", GetFakeLogBuf());
831 switch (log_) {
832 case ARM_LOG_NONE:
833 ASSERT_EQ("", GetFakeLogPrint());
834 break;
835 case ARM_LOG_FULL:
836 ASSERT_EQ("4 unwind pop {r0}\n", GetFakeLogPrint());
837 break;
838 case ARM_LOG_BY_REG:
839 exidx_->LogByReg();
840 ASSERT_EQ(
841 "4 unwind cfa = r13 + 4\n"
842 "4 unwind r0 = [cfa - 4]\n",
843 GetFakeLogPrint());
844 break;
845 }
846 ASSERT_EQ(0x10004U, exidx_->cfa());
847 ASSERT_EQ(0x45U, (*exidx_->regs())[0]);
848
849 ResetExidx();
850 data_->push_back(0xb1);
851 data_->push_back(0x0a);
852 process_memory_.SetData32(0x10000, 0x23);
853 process_memory_.SetData32(0x10004, 0x24);
854 ASSERT_TRUE(exidx_->Decode());
855 ASSERT_FALSE(exidx_->pc_set());
856 ASSERT_EQ("", GetFakeLogBuf());
857 switch (log_) {
858 case ARM_LOG_NONE:
859 ASSERT_EQ("", GetFakeLogPrint());
860 break;
861 case ARM_LOG_FULL:
862 ASSERT_EQ("4 unwind pop {r1, r3}\n", GetFakeLogPrint());
863 break;
864 case ARM_LOG_BY_REG:
865 exidx_->LogByReg();
866 ASSERT_EQ(
867 "4 unwind cfa = r13 + 8\n"
868 "4 unwind r1 = [cfa - 8]\n"
869 "4 unwind r3 = [cfa - 4]\n",
870 GetFakeLogPrint());
871 break;
872 }
873 ASSERT_EQ(0x10008U, exidx_->cfa());
874 ASSERT_EQ(0x23U, (*exidx_->regs())[1]);
875 ASSERT_EQ(0x24U, (*exidx_->regs())[3]);
876
877 ResetExidx();
878 data_->push_back(0xb1);
879 data_->push_back(0x0f);
880 process_memory_.SetData32(0x10000, 0x65);
881 process_memory_.SetData32(0x10004, 0x54);
882 process_memory_.SetData32(0x10008, 0x43);
883 process_memory_.SetData32(0x1000c, 0x32);
884 ASSERT_TRUE(exidx_->Decode());
885 ASSERT_FALSE(exidx_->pc_set());
886 ASSERT_EQ("", GetFakeLogBuf());
887 switch (log_) {
888 case ARM_LOG_NONE:
889 ASSERT_EQ("", GetFakeLogPrint());
890 break;
891 case ARM_LOG_FULL:
892 ASSERT_EQ("4 unwind pop {r0, r1, r2, r3}\n", GetFakeLogPrint());
893 break;
894 case ARM_LOG_BY_REG:
895 exidx_->LogByReg();
896 ASSERT_EQ(
897 "4 unwind cfa = r13 + 16\n"
898 "4 unwind r0 = [cfa - 16]\n"
899 "4 unwind r1 = [cfa - 12]\n"
900 "4 unwind r2 = [cfa - 8]\n"
901 "4 unwind r3 = [cfa - 4]\n",
902 GetFakeLogPrint());
903 break;
904 }
905 ASSERT_EQ(0x10010U, exidx_->cfa());
906 ASSERT_EQ(0x65U, (*exidx_->regs())[0]);
907 ASSERT_EQ(0x54U, (*exidx_->regs())[1]);
908 ASSERT_EQ(0x43U, (*exidx_->regs())[2]);
909 ASSERT_EQ(0x32U, (*exidx_->regs())[3]);
910 }
911
TEST_P(ArmExidxDecodeTest,vsp_large_incr)912 TEST_P(ArmExidxDecodeTest, vsp_large_incr) {
913 // 10110010 uleb128: vsp = vsp + 0x204 + (uleb128 << 2)
914 data_->push_back(0xb2);
915 data_->push_back(0x7f);
916 ASSERT_TRUE(exidx_->Decode());
917 ASSERT_FALSE(exidx_->pc_set());
918 ASSERT_EQ("", GetFakeLogBuf());
919 switch (log_) {
920 case ARM_LOG_NONE:
921 ASSERT_EQ("", GetFakeLogPrint());
922 break;
923 case ARM_LOG_FULL:
924 ASSERT_EQ("4 unwind vsp = vsp + 1024\n", GetFakeLogPrint());
925 break;
926 case ARM_LOG_BY_REG:
927 exidx_->LogByReg();
928 ASSERT_EQ("4 unwind cfa = r13 + 1024\n", GetFakeLogPrint());
929 break;
930 }
931 ASSERT_EQ(0x10400U, exidx_->cfa());
932
933 ResetExidx();
934 data_->push_back(0xb2);
935 data_->push_back(0xff);
936 data_->push_back(0x02);
937 ASSERT_TRUE(exidx_->Decode());
938 ASSERT_FALSE(exidx_->pc_set());
939 ASSERT_EQ("", GetFakeLogBuf());
940 switch (log_) {
941 case ARM_LOG_NONE:
942 ASSERT_EQ("", GetFakeLogPrint());
943 break;
944 case ARM_LOG_FULL:
945 ASSERT_EQ("4 unwind vsp = vsp + 2048\n", GetFakeLogPrint());
946 break;
947 case ARM_LOG_BY_REG:
948 exidx_->LogByReg();
949 ASSERT_EQ("4 unwind cfa = r13 + 2048\n", GetFakeLogPrint());
950 break;
951 }
952 ASSERT_EQ(0x10800U, exidx_->cfa());
953
954 ResetExidx();
955 data_->push_back(0xb2);
956 data_->push_back(0xff);
957 data_->push_back(0x82);
958 data_->push_back(0x30);
959 ASSERT_TRUE(exidx_->Decode());
960 ASSERT_FALSE(exidx_->pc_set());
961 ASSERT_EQ("", GetFakeLogBuf());
962 switch (log_) {
963 case ARM_LOG_NONE:
964 ASSERT_EQ("", GetFakeLogPrint());
965 break;
966 case ARM_LOG_FULL:
967 ASSERT_EQ("4 unwind vsp = vsp + 3147776\n", GetFakeLogPrint());
968 break;
969 case ARM_LOG_BY_REG:
970 exidx_->LogByReg();
971 ASSERT_EQ("4 unwind cfa = r13 + 3147776\n", GetFakeLogPrint());
972 break;
973 }
974 ASSERT_EQ(0x310800U, exidx_->cfa());
975 }
976
TEST_P(ArmExidxDecodeTest,pop_vfp_fstmfdx)977 TEST_P(ArmExidxDecodeTest, pop_vfp_fstmfdx) {
978 // 10110011 sssscccc: Pop VFP double precision registers D[ssss]-D[ssss+cccc] by FSTMFDX
979 data_->push_back(0xb3);
980 data_->push_back(0x00);
981 ASSERT_TRUE(exidx_->Decode());
982 ASSERT_FALSE(exidx_->pc_set());
983 ASSERT_EQ("", GetFakeLogBuf());
984 switch (log_) {
985 case ARM_LOG_NONE:
986 ASSERT_EQ("", GetFakeLogPrint());
987 break;
988 case ARM_LOG_FULL:
989 ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint());
990 break;
991 case ARM_LOG_BY_REG:
992 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
993 break;
994 }
995 ASSERT_EQ(0x1000cU, exidx_->cfa());
996
997 ResetExidx();
998 data_->push_back(0xb3);
999 data_->push_back(0x48);
1000 ASSERT_TRUE(exidx_->Decode());
1001 ASSERT_FALSE(exidx_->pc_set());
1002 ASSERT_EQ("", GetFakeLogBuf());
1003 switch (log_) {
1004 case ARM_LOG_NONE:
1005 ASSERT_EQ("", GetFakeLogPrint());
1006 break;
1007 case ARM_LOG_FULL:
1008 ASSERT_EQ("4 unwind pop {d4-d12}\n", GetFakeLogPrint());
1009 break;
1010 case ARM_LOG_BY_REG:
1011 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1012 break;
1013 }
1014 ASSERT_EQ(0x1004cU, exidx_->cfa());
1015 }
1016
TEST_P(ArmExidxDecodeTest,pop_vfp8_fstmfdx)1017 TEST_P(ArmExidxDecodeTest, pop_vfp8_fstmfdx) {
1018 // 10111nnn: Pop VFP double precision registers D[8]-D[8+nnn] by FSTMFDX
1019 data_->push_back(0xb8);
1020 ASSERT_TRUE(exidx_->Decode());
1021 ASSERT_FALSE(exidx_->pc_set());
1022 ASSERT_EQ("", GetFakeLogBuf());
1023 switch (log_) {
1024 case ARM_LOG_NONE:
1025 ASSERT_EQ("", GetFakeLogPrint());
1026 break;
1027 case ARM_LOG_FULL:
1028 ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint());
1029 break;
1030 case ARM_LOG_BY_REG:
1031 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1032 break;
1033 }
1034 ASSERT_EQ(0x1000cU, exidx_->cfa());
1035
1036 ResetExidx();
1037 data_->push_back(0xbb);
1038 ASSERT_TRUE(exidx_->Decode());
1039 ASSERT_FALSE(exidx_->pc_set());
1040 ASSERT_EQ("", GetFakeLogBuf());
1041 switch (log_) {
1042 case ARM_LOG_NONE:
1043 ASSERT_EQ("", GetFakeLogPrint());
1044 break;
1045 case ARM_LOG_FULL:
1046 ASSERT_EQ("4 unwind pop {d8-d11}\n", GetFakeLogPrint());
1047 break;
1048 case ARM_LOG_BY_REG:
1049 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1050 break;
1051 }
1052 ASSERT_EQ(0x10024U, exidx_->cfa());
1053
1054 ResetExidx();
1055 data_->push_back(0xbf);
1056 ASSERT_TRUE(exidx_->Decode());
1057 ASSERT_FALSE(exidx_->pc_set());
1058 ASSERT_EQ("", GetFakeLogBuf());
1059 switch (log_) {
1060 case ARM_LOG_NONE:
1061 ASSERT_EQ("", GetFakeLogPrint());
1062 break;
1063 case ARM_LOG_FULL:
1064 ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint());
1065 break;
1066 case ARM_LOG_BY_REG:
1067 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1068 break;
1069 }
1070 ASSERT_EQ(0x10044U, exidx_->cfa());
1071 }
1072
TEST_P(ArmExidxDecodeTest,pop_mmx_wr10)1073 TEST_P(ArmExidxDecodeTest, pop_mmx_wr10) {
1074 // 11000nnn: Intel Wireless MMX pop wR[10]-wR[10+nnn] (nnn != 6, 7)
1075 data_->push_back(0xc0);
1076 ASSERT_TRUE(exidx_->Decode());
1077 ASSERT_FALSE(exidx_->pc_set());
1078 ASSERT_EQ("", GetFakeLogBuf());
1079 switch (log_) {
1080 case ARM_LOG_NONE:
1081 ASSERT_EQ("", GetFakeLogPrint());
1082 break;
1083 case ARM_LOG_FULL:
1084 ASSERT_EQ("4 unwind pop {wR10}\n", GetFakeLogPrint());
1085 break;
1086 case ARM_LOG_BY_REG:
1087 ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1088 break;
1089 }
1090 ASSERT_EQ(0x10008U, exidx_->cfa());
1091
1092 ResetExidx();
1093 data_->push_back(0xc2);
1094 ASSERT_TRUE(exidx_->Decode());
1095 ASSERT_FALSE(exidx_->pc_set());
1096 ASSERT_EQ("", GetFakeLogBuf());
1097 switch (log_) {
1098 case ARM_LOG_NONE:
1099 ASSERT_EQ("", GetFakeLogPrint());
1100 break;
1101 case ARM_LOG_FULL:
1102 ASSERT_EQ("4 unwind pop {wR10-wR12}\n", GetFakeLogPrint());
1103 break;
1104 case ARM_LOG_BY_REG:
1105 ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1106 break;
1107 }
1108 ASSERT_EQ(0x10018U, exidx_->cfa());
1109
1110 ResetExidx();
1111 data_->push_back(0xc5);
1112 ASSERT_TRUE(exidx_->Decode());
1113 ASSERT_FALSE(exidx_->pc_set());
1114 ASSERT_EQ("", GetFakeLogBuf());
1115 switch (log_) {
1116 case ARM_LOG_NONE:
1117 ASSERT_EQ("", GetFakeLogPrint());
1118 break;
1119 case ARM_LOG_FULL:
1120 ASSERT_EQ("4 unwind pop {wR10-wR15}\n", GetFakeLogPrint());
1121 break;
1122 case ARM_LOG_BY_REG:
1123 ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1124 break;
1125 }
1126 ASSERT_EQ(0x10030U, exidx_->cfa());
1127 }
1128
TEST_P(ArmExidxDecodeTest,pop_mmx_wr)1129 TEST_P(ArmExidxDecodeTest, pop_mmx_wr) {
1130 // 11000110 sssscccc: Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc]
1131 data_->push_back(0xc6);
1132 data_->push_back(0x00);
1133 ASSERT_TRUE(exidx_->Decode());
1134 ASSERT_FALSE(exidx_->pc_set());
1135 ASSERT_EQ("", GetFakeLogBuf());
1136 switch (log_) {
1137 case ARM_LOG_NONE:
1138 ASSERT_EQ("", GetFakeLogPrint());
1139 break;
1140 case ARM_LOG_FULL:
1141 ASSERT_EQ("4 unwind pop {wR0}\n", GetFakeLogPrint());
1142 break;
1143 case ARM_LOG_BY_REG:
1144 ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1145 break;
1146 }
1147 ASSERT_EQ(0x10008U, exidx_->cfa());
1148
1149 ResetExidx();
1150 data_->push_back(0xc6);
1151 data_->push_back(0x25);
1152 ASSERT_TRUE(exidx_->Decode());
1153 ASSERT_FALSE(exidx_->pc_set());
1154 ASSERT_EQ("", GetFakeLogBuf());
1155 switch (log_) {
1156 case ARM_LOG_NONE:
1157 ASSERT_EQ("", GetFakeLogPrint());
1158 break;
1159 case ARM_LOG_FULL:
1160 ASSERT_EQ("4 unwind pop {wR2-wR7}\n", GetFakeLogPrint());
1161 break;
1162 case ARM_LOG_BY_REG:
1163 ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1164 break;
1165 }
1166 ASSERT_EQ(0x10030U, exidx_->cfa());
1167
1168 ResetExidx();
1169 data_->push_back(0xc6);
1170 data_->push_back(0xff);
1171 ASSERT_TRUE(exidx_->Decode());
1172 ASSERT_FALSE(exidx_->pc_set());
1173 ASSERT_EQ("", GetFakeLogBuf());
1174 switch (log_) {
1175 case ARM_LOG_NONE:
1176 ASSERT_EQ("", GetFakeLogPrint());
1177 break;
1178 case ARM_LOG_FULL:
1179 ASSERT_EQ("4 unwind pop {wR15-wR30}\n", GetFakeLogPrint());
1180 break;
1181 case ARM_LOG_BY_REG:
1182 ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1183 break;
1184 }
1185 ASSERT_EQ(0x10080U, exidx_->cfa());
1186 }
1187
TEST_P(ArmExidxDecodeTest,pop_mmx_wcgr)1188 TEST_P(ArmExidxDecodeTest, pop_mmx_wcgr) {
1189 // 11000111 0000iiii: Intel Wireless MMX pop wCGR registes {wCGR0,1,2,3}
1190 data_->push_back(0xc7);
1191 data_->push_back(0x01);
1192 ASSERT_TRUE(exidx_->Decode());
1193 ASSERT_FALSE(exidx_->pc_set());
1194 ASSERT_EQ("", GetFakeLogBuf());
1195 switch (log_) {
1196 case ARM_LOG_NONE:
1197 ASSERT_EQ("", GetFakeLogPrint());
1198 break;
1199 case ARM_LOG_FULL:
1200 ASSERT_EQ("4 unwind pop {wCGR0}\n", GetFakeLogPrint());
1201 break;
1202 case ARM_LOG_BY_REG:
1203 ASSERT_EQ("4 unwind Unsupported wCGR register display\n", GetFakeLogPrint());
1204 break;
1205 }
1206 ASSERT_EQ(0x10004U, exidx_->cfa());
1207
1208 ResetExidx();
1209 data_->push_back(0xc7);
1210 data_->push_back(0x0a);
1211 ASSERT_TRUE(exidx_->Decode());
1212 ASSERT_FALSE(exidx_->pc_set());
1213 ASSERT_EQ("", GetFakeLogBuf());
1214 switch (log_) {
1215 case ARM_LOG_NONE:
1216 ASSERT_EQ("", GetFakeLogPrint());
1217 break;
1218 case ARM_LOG_FULL:
1219 ASSERT_EQ("4 unwind pop {wCGR1, wCGR3}\n", GetFakeLogPrint());
1220 break;
1221 case ARM_LOG_BY_REG:
1222 ASSERT_EQ("4 unwind Unsupported wCGR register display\n", GetFakeLogPrint());
1223 break;
1224 }
1225 ASSERT_EQ(0x10008U, exidx_->cfa());
1226
1227 ResetExidx();
1228 data_->push_back(0xc7);
1229 data_->push_back(0x0f);
1230 ASSERT_TRUE(exidx_->Decode());
1231 ASSERT_FALSE(exidx_->pc_set());
1232 ASSERT_EQ("", GetFakeLogBuf());
1233 switch (log_) {
1234 case ARM_LOG_NONE:
1235 ASSERT_EQ("", GetFakeLogPrint());
1236 break;
1237 case ARM_LOG_FULL:
1238 ASSERT_EQ("4 unwind pop {wCGR0, wCGR1, wCGR2, wCGR3}\n", GetFakeLogPrint());
1239 break;
1240 case ARM_LOG_BY_REG:
1241 ASSERT_EQ("4 unwind Unsupported wCGR register display\n", GetFakeLogPrint());
1242 break;
1243 }
1244 ASSERT_EQ(0x10010U, exidx_->cfa());
1245 }
1246
TEST_P(ArmExidxDecodeTest,pop_vfp16_vpush)1247 TEST_P(ArmExidxDecodeTest, pop_vfp16_vpush) {
1248 // 11001000 sssscccc: Pop VFP double precision registers d[16+ssss]-D[16+ssss+cccc] by VPUSH
1249 data_->push_back(0xc8);
1250 data_->push_back(0x00);
1251 ASSERT_TRUE(exidx_->Decode());
1252 ASSERT_FALSE(exidx_->pc_set());
1253 ASSERT_EQ("", GetFakeLogBuf());
1254 switch (log_) {
1255 case ARM_LOG_NONE:
1256 ASSERT_EQ("", GetFakeLogPrint());
1257 break;
1258 case ARM_LOG_FULL:
1259 ASSERT_EQ("4 unwind pop {d16}\n", GetFakeLogPrint());
1260 break;
1261 case ARM_LOG_BY_REG:
1262 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1263 break;
1264 }
1265 ASSERT_EQ(0x10008U, exidx_->cfa());
1266
1267 ResetExidx();
1268 data_->push_back(0xc8);
1269 data_->push_back(0x14);
1270 ASSERT_TRUE(exidx_->Decode());
1271 ASSERT_FALSE(exidx_->pc_set());
1272 ASSERT_EQ("", GetFakeLogBuf());
1273 switch (log_) {
1274 case ARM_LOG_NONE:
1275 ASSERT_EQ("", GetFakeLogPrint());
1276 break;
1277 case ARM_LOG_FULL:
1278 ASSERT_EQ("4 unwind pop {d17-d21}\n", GetFakeLogPrint());
1279 break;
1280 case ARM_LOG_BY_REG:
1281 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1282 break;
1283 }
1284 ASSERT_EQ(0x10028U, exidx_->cfa());
1285
1286 ResetExidx();
1287 data_->push_back(0xc8);
1288 data_->push_back(0xff);
1289 ASSERT_TRUE(exidx_->Decode());
1290 ASSERT_FALSE(exidx_->pc_set());
1291 ASSERT_EQ("", GetFakeLogBuf());
1292 switch (log_) {
1293 case ARM_LOG_NONE:
1294 ASSERT_EQ("", GetFakeLogPrint());
1295 break;
1296 case ARM_LOG_FULL:
1297 ASSERT_EQ("4 unwind pop {d31-d46}\n", GetFakeLogPrint());
1298 break;
1299 case ARM_LOG_BY_REG:
1300 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1301 break;
1302 }
1303 ASSERT_EQ(0x10080U, exidx_->cfa());
1304 }
1305
TEST_P(ArmExidxDecodeTest,pop_vfp_vpush)1306 TEST_P(ArmExidxDecodeTest, pop_vfp_vpush) {
1307 // 11001001 sssscccc: Pop VFP double precision registers d[ssss]-D[ssss+cccc] by VPUSH
1308 data_->push_back(0xc9);
1309 data_->push_back(0x00);
1310 ASSERT_TRUE(exidx_->Decode());
1311 ASSERT_FALSE(exidx_->pc_set());
1312 ASSERT_EQ("", GetFakeLogBuf());
1313 switch (log_) {
1314 case ARM_LOG_NONE:
1315 ASSERT_EQ("", GetFakeLogPrint());
1316 break;
1317 case ARM_LOG_FULL:
1318 ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint());
1319 break;
1320 case ARM_LOG_BY_REG:
1321 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1322 break;
1323 }
1324 ASSERT_EQ(0x10008U, exidx_->cfa());
1325
1326 ResetExidx();
1327 data_->push_back(0xc9);
1328 data_->push_back(0x23);
1329 ASSERT_TRUE(exidx_->Decode());
1330 ASSERT_FALSE(exidx_->pc_set());
1331 ASSERT_EQ("", GetFakeLogBuf());
1332 switch (log_) {
1333 case ARM_LOG_NONE:
1334 ASSERT_EQ("", GetFakeLogPrint());
1335 break;
1336 case ARM_LOG_FULL:
1337 ASSERT_EQ("4 unwind pop {d2-d5}\n", GetFakeLogPrint());
1338 break;
1339 case ARM_LOG_BY_REG:
1340 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1341 break;
1342 }
1343 ASSERT_EQ(0x10020U, exidx_->cfa());
1344
1345 ResetExidx();
1346 data_->push_back(0xc9);
1347 data_->push_back(0xff);
1348 ASSERT_TRUE(exidx_->Decode());
1349 ASSERT_FALSE(exidx_->pc_set());
1350 ASSERT_EQ("", GetFakeLogBuf());
1351 switch (log_) {
1352 case ARM_LOG_NONE:
1353 ASSERT_EQ("", GetFakeLogPrint());
1354 break;
1355 case ARM_LOG_FULL:
1356 ASSERT_EQ("4 unwind pop {d15-d30}\n", GetFakeLogPrint());
1357 break;
1358 case ARM_LOG_BY_REG:
1359 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1360 break;
1361 }
1362 ASSERT_EQ(0x10080U, exidx_->cfa());
1363 }
1364
TEST_P(ArmExidxDecodeTest,pop_vfp8_vpush)1365 TEST_P(ArmExidxDecodeTest, pop_vfp8_vpush) {
1366 // 11010nnn: Pop VFP double precision registers D[8]-D[8+nnn] by VPUSH
1367 data_->push_back(0xd0);
1368 ASSERT_TRUE(exidx_->Decode());
1369 ASSERT_FALSE(exidx_->pc_set());
1370 ASSERT_EQ("", GetFakeLogBuf());
1371 switch (log_) {
1372 case ARM_LOG_NONE:
1373 ASSERT_EQ("", GetFakeLogPrint());
1374 break;
1375 case ARM_LOG_FULL:
1376 ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint());
1377 break;
1378 case ARM_LOG_BY_REG:
1379 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1380 break;
1381 }
1382 ASSERT_EQ(0x10008U, exidx_->cfa());
1383
1384 ResetExidx();
1385 data_->push_back(0xd2);
1386 ASSERT_TRUE(exidx_->Decode());
1387 ASSERT_FALSE(exidx_->pc_set());
1388 ASSERT_EQ("", GetFakeLogBuf());
1389 switch (log_) {
1390 case ARM_LOG_NONE:
1391 ASSERT_EQ("", GetFakeLogPrint());
1392 break;
1393 case ARM_LOG_FULL:
1394 ASSERT_EQ("4 unwind pop {d8-d10}\n", GetFakeLogPrint());
1395 break;
1396 case ARM_LOG_BY_REG:
1397 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1398 break;
1399 }
1400 ASSERT_EQ(0x10018U, exidx_->cfa());
1401
1402 ResetExidx();
1403 data_->push_back(0xd7);
1404 ASSERT_TRUE(exidx_->Decode());
1405 ASSERT_FALSE(exidx_->pc_set());
1406 ASSERT_EQ("", GetFakeLogBuf());
1407 switch (log_) {
1408 case ARM_LOG_NONE:
1409 ASSERT_EQ("", GetFakeLogPrint());
1410 break;
1411 case ARM_LOG_FULL:
1412 ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint());
1413 break;
1414 case ARM_LOG_BY_REG:
1415 ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1416 break;
1417 }
1418 ASSERT_EQ(0x10040U, exidx_->cfa());
1419 }
1420
TEST_P(ArmExidxDecodeTest,expect_truncated)1421 TEST_P(ArmExidxDecodeTest, expect_truncated) {
1422 // This test verifies that any op that requires extra ops will
1423 // fail if the data is not present.
1424 data_->push_back(0x80);
1425 ASSERT_FALSE(exidx_->Decode());
1426 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1427
1428 data_->clear();
1429 data_->push_back(0xb1);
1430 ASSERT_FALSE(exidx_->Decode());
1431 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1432
1433 data_->clear();
1434 data_->push_back(0xb2);
1435 ASSERT_FALSE(exidx_->Decode());
1436 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1437
1438 data_->clear();
1439 data_->push_back(0xb3);
1440 ASSERT_FALSE(exidx_->Decode());
1441 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1442
1443 data_->clear();
1444 data_->push_back(0xc6);
1445 ASSERT_FALSE(exidx_->Decode());
1446 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1447
1448 data_->clear();
1449 data_->push_back(0xc7);
1450 ASSERT_FALSE(exidx_->Decode());
1451 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1452
1453 data_->clear();
1454 data_->push_back(0xc8);
1455 ASSERT_FALSE(exidx_->Decode());
1456 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1457
1458 data_->clear();
1459 data_->push_back(0xc9);
1460 ASSERT_FALSE(exidx_->Decode());
1461 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1462 }
1463
TEST_P(ArmExidxDecodeTest,verify_no_truncated)1464 TEST_P(ArmExidxDecodeTest, verify_no_truncated) {
1465 // This test verifies that no pattern results in a crash or truncation.
1466 MemoryFakeAlwaysReadZero memory_zero;
1467 Init(&memory_zero);
1468
1469 for (size_t x = 0; x < 256; x++) {
1470 if (x == 0xb2) {
1471 // This opcode is followed by an uleb128, so just skip this one.
1472 continue;
1473 }
1474 for (size_t y = 0; y < 256; y++) {
1475 data_->clear();
1476 data_->push_back(x);
1477 data_->push_back(y);
1478 if (!exidx_->Decode()) {
1479 ASSERT_NE(ARM_STATUS_TRUNCATED, exidx_->status())
1480 << "x y = 0x" << std::hex << x << " 0x" << y;
1481 ASSERT_NE(ARM_STATUS_READ_FAILED, exidx_->status())
1482 << "x y = 0x" << std::hex << x << " 0x" << y;
1483 }
1484 }
1485 }
1486 }
1487
TEST_P(ArmExidxDecodeTest,eval_multiple_decodes)1488 TEST_P(ArmExidxDecodeTest, eval_multiple_decodes) {
1489 // vsp = vsp + 4
1490 data_->push_back(0x00);
1491 // vsp = vsp + 12
1492 data_->push_back(0x02);
1493 // Finish
1494 data_->push_back(0xb0);
1495
1496 ASSERT_TRUE(exidx_->Eval());
1497 switch (log_) {
1498 case ARM_LOG_NONE:
1499 ASSERT_EQ("", GetFakeLogPrint());
1500 break;
1501 case ARM_LOG_FULL:
1502 ASSERT_EQ(
1503 "4 unwind vsp = vsp + 4\n"
1504 "4 unwind vsp = vsp + 12\n"
1505 "4 unwind finish\n",
1506 GetFakeLogPrint());
1507 break;
1508 case ARM_LOG_BY_REG:
1509 exidx_->LogByReg();
1510 ASSERT_EQ("4 unwind cfa = r13 + 16\n", GetFakeLogPrint());
1511 break;
1512 }
1513 ASSERT_EQ(0x10010U, exidx_->cfa());
1514 ASSERT_FALSE(exidx_->pc_set());
1515 }
1516
TEST_P(ArmExidxDecodeTest,eval_vsp_add_after_pop)1517 TEST_P(ArmExidxDecodeTest, eval_vsp_add_after_pop) {
1518 // Pop {r15}
1519 data_->push_back(0x88);
1520 data_->push_back(0x00);
1521 // vsp = vsp + 12
1522 data_->push_back(0x02);
1523 // Finish
1524 data_->push_back(0xb0);
1525 process_memory_.SetData32(0x10000, 0x10);
1526
1527 ASSERT_TRUE(exidx_->Eval());
1528 switch (log_) {
1529 case ARM_LOG_NONE:
1530 ASSERT_EQ("", GetFakeLogPrint());
1531 break;
1532 case ARM_LOG_FULL:
1533 ASSERT_EQ(
1534 "4 unwind pop {r15}\n"
1535 "4 unwind vsp = vsp + 12\n"
1536 "4 unwind finish\n",
1537 GetFakeLogPrint());
1538 break;
1539 case ARM_LOG_BY_REG:
1540 exidx_->LogByReg();
1541 ASSERT_EQ(
1542 "4 unwind cfa = r13 + 16\n"
1543 "4 unwind r15 = [cfa - 16]\n",
1544 GetFakeLogPrint());
1545 break;
1546 }
1547 ASSERT_EQ(0x10010U, exidx_->cfa());
1548 ASSERT_TRUE(exidx_->pc_set());
1549 ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1550 }
1551
TEST_P(ArmExidxDecodeTest,eval_vsp_add_large_after_pop)1552 TEST_P(ArmExidxDecodeTest, eval_vsp_add_large_after_pop) {
1553 // Pop {r15}
1554 data_->push_back(0x88);
1555 data_->push_back(0x00);
1556 // vsp = vsp + 1024
1557 data_->push_back(0xb2);
1558 data_->push_back(0x7f);
1559 // Finish
1560 data_->push_back(0xb0);
1561 process_memory_.SetData32(0x10000, 0x10);
1562
1563 ASSERT_TRUE(exidx_->Eval());
1564 switch (log_) {
1565 case ARM_LOG_NONE:
1566 ASSERT_EQ("", GetFakeLogPrint());
1567 break;
1568 case ARM_LOG_FULL:
1569 ASSERT_EQ(
1570 "4 unwind pop {r15}\n"
1571 "4 unwind vsp = vsp + 1024\n"
1572 "4 unwind finish\n",
1573 GetFakeLogPrint());
1574 break;
1575 case ARM_LOG_BY_REG:
1576 exidx_->LogByReg();
1577 ASSERT_EQ(
1578 "4 unwind cfa = r13 + 1028\n"
1579 "4 unwind r15 = [cfa - 1028]\n",
1580 GetFakeLogPrint());
1581 break;
1582 }
1583 ASSERT_EQ(0x10404U, exidx_->cfa());
1584 ASSERT_TRUE(exidx_->pc_set());
1585 ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1586 }
1587
TEST_P(ArmExidxDecodeTest,eval_vsp_sub_after_pop)1588 TEST_P(ArmExidxDecodeTest, eval_vsp_sub_after_pop) {
1589 // Pop {r15}
1590 data_->push_back(0x88);
1591 data_->push_back(0x00);
1592 // vsp = vsp - 4
1593 data_->push_back(0x41);
1594 // Finish
1595 data_->push_back(0xb0);
1596 process_memory_.SetData32(0x10000, 0x10);
1597
1598 ASSERT_TRUE(exidx_->Eval());
1599 switch (log_) {
1600 case ARM_LOG_NONE:
1601 ASSERT_EQ("", GetFakeLogPrint());
1602 break;
1603 case ARM_LOG_FULL:
1604 ASSERT_EQ(
1605 "4 unwind pop {r15}\n"
1606 "4 unwind vsp = vsp - 8\n"
1607 "4 unwind finish\n",
1608 GetFakeLogPrint());
1609 break;
1610 case ARM_LOG_BY_REG:
1611 exidx_->LogByReg();
1612 ASSERT_EQ(
1613 "4 unwind cfa = r13 - 4\n"
1614 "4 unwind r15 = [cfa + 4]\n",
1615 GetFakeLogPrint());
1616 break;
1617 }
1618 ASSERT_EQ(0xfffcU, exidx_->cfa());
1619 ASSERT_TRUE(exidx_->pc_set());
1620 ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1621 }
1622
TEST_P(ArmExidxDecodeTest,eval_pc_set)1623 TEST_P(ArmExidxDecodeTest, eval_pc_set) {
1624 // vsp = vsp + 4
1625 data_->push_back(0x00);
1626 // vsp = vsp + 12
1627 data_->push_back(0x02);
1628 // Pop {r15}
1629 data_->push_back(0x88);
1630 data_->push_back(0x00);
1631 // vsp = vsp + 12
1632 data_->push_back(0x02);
1633 // Finish
1634 data_->push_back(0xb0);
1635
1636 process_memory_.SetData32(0x10010, 0x10);
1637
1638 ASSERT_TRUE(exidx_->Eval());
1639 switch (log_) {
1640 case ARM_LOG_NONE:
1641 ASSERT_EQ("", GetFakeLogPrint());
1642 break;
1643 case ARM_LOG_FULL:
1644 ASSERT_EQ(
1645 "4 unwind vsp = vsp + 4\n"
1646 "4 unwind vsp = vsp + 12\n"
1647 "4 unwind pop {r15}\n"
1648 "4 unwind vsp = vsp + 12\n"
1649 "4 unwind finish\n",
1650 GetFakeLogPrint());
1651 break;
1652 case ARM_LOG_BY_REG:
1653 exidx_->LogByReg();
1654 ASSERT_EQ(
1655 "4 unwind cfa = r13 + 32\n"
1656 "4 unwind r15 = [cfa - 16]\n",
1657 GetFakeLogPrint());
1658 break;
1659 }
1660 ASSERT_EQ(0x10020U, exidx_->cfa());
1661 ASSERT_TRUE(exidx_->pc_set());
1662 ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1663 }
1664
1665 INSTANTIATE_TEST_SUITE_P(Unwindstack, ArmExidxDecodeTest,
1666 ::testing::Values("logging", "register_logging", "no_logging"));
1667
1668 } // namespace unwindstack
1669