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