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