Home | History | Annotate | Download | only in tests
      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:
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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