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