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 <memory>
     20 #include <unordered_map>
     21 
     22 #include <gtest/gtest.h>
     23 
     24 #include <unwindstack/DwarfError.h>
     25 #include <unwindstack/DwarfLocation.h>
     26 #include <unwindstack/DwarfMemory.h>
     27 #include <unwindstack/DwarfStructs.h>
     28 #include <unwindstack/Log.h>
     29 
     30 #include "DwarfCfa.h"
     31 
     32 #include "LogFake.h"
     33 #include "MemoryFake.h"
     34 
     35 namespace unwindstack {
     36 
     37 template <typename TypeParam>
     38 class DwarfCfaTest : public ::testing::Test {
     39  protected:
     40   void SetUp() override {
     41     ResetLogs();
     42     memory_.Clear();
     43 
     44     dmem_.reset(new DwarfMemory(&memory_));
     45 
     46     cie_.cfa_instructions_offset = 0x1000;
     47     cie_.cfa_instructions_end = 0x1030;
     48     // These two values should be different to distinguish between
     49     // operations that deal with code versus data.
     50     cie_.code_alignment_factor = 4;
     51     cie_.data_alignment_factor = 8;
     52 
     53     fde_.cfa_instructions_offset = 0x2000;
     54     fde_.cfa_instructions_end = 0x2030;
     55     fde_.pc_start = 0x2000;
     56     fde_.cie = &cie_;
     57 
     58     cfa_.reset(new DwarfCfa<TypeParam>(dmem_.get(), &fde_));
     59   }
     60 
     61   MemoryFake memory_;
     62   std::unique_ptr<DwarfMemory> dmem_;
     63   std::unique_ptr<DwarfCfa<TypeParam>> cfa_;
     64   DwarfCie cie_;
     65   DwarfFde fde_;
     66 };
     67 TYPED_TEST_CASE_P(DwarfCfaTest);
     68 
     69 // NOTE: All test class variables need to be referenced as this->.
     70 
     71 TYPED_TEST_P(DwarfCfaTest, cfa_illegal) {
     72   for (uint8_t i = 0x17; i < 0x3f; i++) {
     73     if (i == 0x2e || i == 0x2f) {
     74       // Skip gnu extension ops.
     75       continue;
     76     }
     77     this->memory_.SetMemory(0x2000, std::vector<uint8_t>{i});
     78     dwarf_loc_regs_t loc_regs;
     79 
     80     ASSERT_FALSE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2001, &loc_regs));
     81     ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->cfa_->LastErrorCode());
     82     ASSERT_EQ(0x2001U, this->dmem_->cur_offset());
     83 
     84     ASSERT_EQ("", GetFakeLogPrint());
     85     ASSERT_EQ("", GetFakeLogBuf());
     86   }
     87 }
     88 
     89 TYPED_TEST_P(DwarfCfaTest, cfa_nop) {
     90   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x00});
     91   dwarf_loc_regs_t loc_regs;
     92 
     93   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2001, &loc_regs));
     94   ASSERT_EQ(0x2001U, this->dmem_->cur_offset());
     95   ASSERT_EQ(0U, loc_regs.size());
     96 
     97   ASSERT_EQ("", GetFakeLogPrint());
     98   ASSERT_EQ("", GetFakeLogBuf());
     99 }
    100 
    101 // This test needs to be examined.
    102 TYPED_TEST_P(DwarfCfaTest, cfa_offset) {
    103   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x83, 0x04});
    104   dwarf_loc_regs_t loc_regs;
    105 
    106   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2002, &loc_regs));
    107   ASSERT_EQ(0x2002U, this->dmem_->cur_offset());
    108   ASSERT_EQ(1U, loc_regs.size());
    109   auto location = loc_regs.find(3);
    110   ASSERT_NE(loc_regs.end(), location);
    111   ASSERT_EQ(DWARF_LOCATION_OFFSET, location->second.type);
    112   ASSERT_EQ(32U, location->second.values[0]);
    113 
    114   ASSERT_EQ("", GetFakeLogPrint());
    115   ASSERT_EQ("", GetFakeLogBuf());
    116 
    117   ResetLogs();
    118   this->memory_.SetMemory(0x2100, std::vector<uint8_t>{0x83, 0x84, 0x01});
    119   loc_regs.clear();
    120 
    121   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2100, 0x2103, &loc_regs));
    122   ASSERT_EQ(0x2103U, this->dmem_->cur_offset());
    123   ASSERT_EQ(1U, loc_regs.size());
    124   location = loc_regs.find(3);
    125   ASSERT_NE(loc_regs.end(), location);
    126   ASSERT_EQ(DWARF_LOCATION_OFFSET, location->second.type);
    127   ASSERT_EQ(1056U, location->second.values[0]);
    128 
    129   ASSERT_EQ("", GetFakeLogPrint());
    130   ASSERT_EQ("", GetFakeLogBuf());
    131 }
    132 
    133 TYPED_TEST_P(DwarfCfaTest, cfa_offset_extended) {
    134   this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x05, 0x03, 0x02});
    135   dwarf_loc_regs_t loc_regs;
    136 
    137   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x500, 0x503, &loc_regs));
    138   ASSERT_EQ(0x503U, this->dmem_->cur_offset());
    139   ASSERT_EQ(1U, loc_regs.size());
    140   auto location = loc_regs.find(3);
    141   ASSERT_NE(loc_regs.end(), location);
    142   ASSERT_EQ(DWARF_LOCATION_OFFSET, location->second.type);
    143   ASSERT_EQ(2U, location->second.values[0]);
    144 
    145   ASSERT_EQ("", GetFakeLogPrint());
    146   ASSERT_EQ("", GetFakeLogBuf());
    147 
    148   ResetLogs();
    149   loc_regs.clear();
    150   this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x05, 0x81, 0x01, 0x82, 0x12});
    151 
    152   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x1500, 0x1505, &loc_regs));
    153   ASSERT_EQ(0x1505U, this->dmem_->cur_offset());
    154   ASSERT_EQ(1U, loc_regs.size());
    155   location = loc_regs.find(129);
    156   ASSERT_NE(loc_regs.end(), location);
    157   ASSERT_EQ(DWARF_LOCATION_OFFSET, location->second.type);
    158   ASSERT_EQ(2306U, location->second.values[0]);
    159 
    160   ASSERT_EQ("", GetFakeLogPrint());
    161   ASSERT_EQ("", GetFakeLogBuf());
    162 }
    163 
    164 TYPED_TEST_P(DwarfCfaTest, cfa_offset_extended_sf) {
    165   this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x11, 0x05, 0x10});
    166   dwarf_loc_regs_t loc_regs;
    167 
    168   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x500, 0x503, &loc_regs));
    169   ASSERT_EQ(0x503U, this->dmem_->cur_offset());
    170   ASSERT_EQ(1U, loc_regs.size());
    171   auto location = loc_regs.find(5);
    172   ASSERT_NE(loc_regs.end(), location);
    173   ASSERT_EQ(DWARF_LOCATION_OFFSET, location->second.type);
    174   ASSERT_EQ(0x80U, location->second.values[0]);
    175 
    176   ASSERT_EQ("", GetFakeLogPrint());
    177   ASSERT_EQ("", GetFakeLogBuf());
    178 
    179   // Check a negative value for the offset.
    180   ResetLogs();
    181   loc_regs.clear();
    182   this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x11, 0x86, 0x01, 0xff, 0x7f});
    183 
    184   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x1500, 0x1505, &loc_regs));
    185   ASSERT_EQ(0x1505U, this->dmem_->cur_offset());
    186   ASSERT_EQ(1U, loc_regs.size());
    187   location = loc_regs.find(134);
    188   ASSERT_NE(loc_regs.end(), location);
    189   ASSERT_EQ(DWARF_LOCATION_OFFSET, location->second.type);
    190   ASSERT_EQ(static_cast<uint64_t>(-8), location->second.values[0]);
    191 
    192   ASSERT_EQ("", GetFakeLogPrint());
    193   ASSERT_EQ("", GetFakeLogBuf());
    194 }
    195 
    196 TYPED_TEST_P(DwarfCfaTest, cfa_restore) {
    197   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0xc2});
    198   dwarf_loc_regs_t loc_regs;
    199 
    200   ASSERT_FALSE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2001, &loc_regs));
    201   ASSERT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->cfa_->LastErrorCode());
    202   ASSERT_EQ(0x2001U, this->dmem_->cur_offset());
    203   ASSERT_EQ(0U, loc_regs.size());
    204 
    205   ASSERT_EQ("4 unwind restore while processing cie\n", GetFakeLogPrint());
    206   ASSERT_EQ("", GetFakeLogBuf());
    207 
    208   ResetLogs();
    209   dwarf_loc_regs_t cie_loc_regs;
    210   cie_loc_regs[2] = {.type = DWARF_LOCATION_REGISTER, .values = {0, 0}};
    211   this->cfa_->set_cie_loc_regs(&cie_loc_regs);
    212   this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x82, 0x04, 0xc2});
    213 
    214   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x3000, 0x3003, &loc_regs));
    215   ASSERT_EQ(0x3003U, this->dmem_->cur_offset());
    216   ASSERT_EQ(1U, loc_regs.size());
    217   auto location = loc_regs.find(2);
    218   ASSERT_NE(loc_regs.end(), location);
    219   ASSERT_EQ(DWARF_LOCATION_REGISTER, location->second.type);
    220 
    221   ASSERT_EQ("", GetFakeLogPrint());
    222   ASSERT_EQ("", GetFakeLogBuf());
    223 }
    224 
    225 TYPED_TEST_P(DwarfCfaTest, cfa_restore_extended) {
    226   this->memory_.SetMemory(0x4000, std::vector<uint8_t>{0x06, 0x08});
    227   dwarf_loc_regs_t loc_regs;
    228 
    229   ASSERT_FALSE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x4000, 0x4002, &loc_regs));
    230   ASSERT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->cfa_->LastErrorCode());
    231   ASSERT_EQ(0x4002U, this->dmem_->cur_offset());
    232   ASSERT_EQ(0U, loc_regs.size());
    233 
    234   ASSERT_EQ("4 unwind restore while processing cie\n", GetFakeLogPrint());
    235   ASSERT_EQ("", GetFakeLogBuf());
    236 
    237   ResetLogs();
    238   loc_regs.clear();
    239   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x05, 0x82, 0x02, 0x04, 0x06, 0x82, 0x02});
    240   dwarf_loc_regs_t cie_loc_regs;
    241   cie_loc_regs[258] = {.type = DWARF_LOCATION_REGISTER, .values = {0, 0}};
    242   this->cfa_->set_cie_loc_regs(&cie_loc_regs);
    243 
    244   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x5000, 0x5007, &loc_regs));
    245   ASSERT_EQ(0x5007U, this->dmem_->cur_offset());
    246   ASSERT_EQ(1U, loc_regs.size());
    247   auto location = loc_regs.find(258);
    248   ASSERT_NE(loc_regs.end(), location);
    249   ASSERT_EQ(DWARF_LOCATION_REGISTER, location->second.type);
    250 
    251   ASSERT_EQ("", GetFakeLogPrint());
    252   ASSERT_EQ("", GetFakeLogBuf());
    253 }
    254 
    255 TYPED_TEST_P(DwarfCfaTest, cfa_set_loc) {
    256   uint8_t buffer[1 + sizeof(TypeParam)];
    257   buffer[0] = 0x1;
    258   TypeParam address;
    259   std::string raw_data("Raw Data: 0x01 ");
    260   std::string address_str;
    261   if (sizeof(TypeParam) == 4) {
    262     address = 0x81234578U;
    263     address_str = "0x81234578";
    264     raw_data += "0x78 0x45 0x23 0x81";
    265   } else {
    266     address = 0x8123456712345678ULL;
    267     address_str = "0x8123456712345678";
    268     raw_data += "0x78 0x56 0x34 0x12 0x67 0x45 0x23 0x81";
    269   }
    270   memcpy(&buffer[1], &address, sizeof(address));
    271 
    272   this->memory_.SetMemory(0x50, buffer, sizeof(buffer));
    273   ResetLogs();
    274   dwarf_loc_regs_t loc_regs;
    275   ASSERT_TRUE(
    276       this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x50, 0x51 + sizeof(TypeParam), &loc_regs));
    277   ASSERT_EQ(0x51 + sizeof(TypeParam), this->dmem_->cur_offset());
    278   ASSERT_EQ(address, this->cfa_->cur_pc());
    279   ASSERT_EQ(0U, loc_regs.size());
    280 
    281   ASSERT_EQ("", GetFakeLogPrint());
    282   ASSERT_EQ("", GetFakeLogBuf());
    283 
    284   // Check for a set going back.
    285   ResetLogs();
    286   loc_regs.clear();
    287   this->fde_.pc_start = address + 0x10;
    288   ASSERT_TRUE(
    289       this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x50, 0x51 + sizeof(TypeParam), &loc_regs));
    290   ASSERT_EQ(0x51 + sizeof(TypeParam), this->dmem_->cur_offset());
    291   ASSERT_EQ(address, this->cfa_->cur_pc());
    292   ASSERT_EQ(0U, loc_regs.size());
    293 
    294   std::string cur_address_str(address_str);
    295   cur_address_str[cur_address_str.size() - 2] = '8';
    296   std::string expected = "4 unwind Warning: PC is moving backwards: old " + cur_address_str +
    297                          " new " + address_str + "\n";
    298   ASSERT_EQ(expected, GetFakeLogPrint());
    299   ASSERT_EQ("", GetFakeLogBuf());
    300 }
    301 
    302 TYPED_TEST_P(DwarfCfaTest, cfa_advance_loc1) {
    303   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x02, 0x04});
    304   dwarf_loc_regs_t loc_regs;
    305 
    306   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x202, &loc_regs));
    307   ASSERT_EQ(0x202U, this->dmem_->cur_offset());
    308   ASSERT_EQ(this->fde_.pc_start + 0x10, this->cfa_->cur_pc());
    309   ASSERT_EQ(0U, loc_regs.size());
    310 
    311   ASSERT_EQ("", GetFakeLogPrint());
    312   ASSERT_EQ("", GetFakeLogBuf());
    313 }
    314 
    315 TYPED_TEST_P(DwarfCfaTest, cfa_advance_loc2) {
    316   this->memory_.SetMemory(0x600, std::vector<uint8_t>{0x03, 0x04, 0x03});
    317   dwarf_loc_regs_t loc_regs;
    318 
    319   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x600, 0x603, &loc_regs));
    320   ASSERT_EQ(0x603U, this->dmem_->cur_offset());
    321   ASSERT_EQ(this->fde_.pc_start + 0xc10U, this->cfa_->cur_pc());
    322   ASSERT_EQ(0U, loc_regs.size());
    323 
    324   ASSERT_EQ("", GetFakeLogPrint());
    325   ASSERT_EQ("", GetFakeLogBuf());
    326 }
    327 
    328 TYPED_TEST_P(DwarfCfaTest, cfa_advance_loc4) {
    329   this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x04, 0x04, 0x03, 0x02, 0x01});
    330   dwarf_loc_regs_t loc_regs;
    331 
    332   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x500, 0x505, &loc_regs));
    333   ASSERT_EQ(0x505U, this->dmem_->cur_offset());
    334   ASSERT_EQ(this->fde_.pc_start + 0x4080c10, this->cfa_->cur_pc());
    335   ASSERT_EQ(0U, loc_regs.size());
    336 
    337   ASSERT_EQ("", GetFakeLogPrint());
    338   ASSERT_EQ("", GetFakeLogBuf());
    339 }
    340 
    341 TYPED_TEST_P(DwarfCfaTest, cfa_undefined) {
    342   this->memory_.SetMemory(0xa00, std::vector<uint8_t>{0x07, 0x09});
    343   dwarf_loc_regs_t loc_regs;
    344 
    345   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0xa00, 0xa02, &loc_regs));
    346   ASSERT_EQ(0xa02U, this->dmem_->cur_offset());
    347   ASSERT_EQ(1U, loc_regs.size());
    348   auto location = loc_regs.find(9);
    349   ASSERT_NE(loc_regs.end(), location);
    350   ASSERT_EQ(DWARF_LOCATION_UNDEFINED, location->second.type);
    351 
    352   ASSERT_EQ("", GetFakeLogPrint());
    353   ASSERT_EQ("", GetFakeLogBuf());
    354 
    355   ResetLogs();
    356   loc_regs.clear();
    357   this->memory_.SetMemory(0x1a00, std::vector<uint8_t>{0x07, 0x81, 0x01});
    358 
    359   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x1a00, 0x1a03, &loc_regs));
    360   ASSERT_EQ(0x1a03U, this->dmem_->cur_offset());
    361   ASSERT_EQ(1U, loc_regs.size());
    362   location = loc_regs.find(129);
    363   ASSERT_NE(loc_regs.end(), location);
    364   ASSERT_EQ(DWARF_LOCATION_UNDEFINED, location->second.type);
    365 
    366   ASSERT_EQ("", GetFakeLogPrint());
    367   ASSERT_EQ("", GetFakeLogBuf());
    368 }
    369 
    370 TYPED_TEST_P(DwarfCfaTest, cfa_same) {
    371   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x08, 0x7f});
    372   dwarf_loc_regs_t loc_regs;
    373 
    374   loc_regs[127] = {.type = DWARF_LOCATION_REGISTER, .values = {0, 0}};
    375   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x102, &loc_regs));
    376   ASSERT_EQ(0x102U, this->dmem_->cur_offset());
    377   ASSERT_EQ(0U, loc_regs.size());
    378   ASSERT_EQ(0U, loc_regs.count(127));
    379 
    380   ASSERT_EQ("", GetFakeLogPrint());
    381   ASSERT_EQ("", GetFakeLogBuf());
    382 
    383   ResetLogs();
    384   loc_regs.clear();
    385   this->memory_.SetMemory(0x2100, std::vector<uint8_t>{0x08, 0xff, 0x01});
    386 
    387   loc_regs[255] = {.type = DWARF_LOCATION_REGISTER, .values = {0, 0}};
    388   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2100, 0x2103, &loc_regs));
    389   ASSERT_EQ(0x2103U, this->dmem_->cur_offset());
    390   ASSERT_EQ(0U, loc_regs.size());
    391   ASSERT_EQ(0U, loc_regs.count(255));
    392 
    393   ASSERT_EQ("", GetFakeLogPrint());
    394   ASSERT_EQ("", GetFakeLogBuf());
    395 }
    396 
    397 TYPED_TEST_P(DwarfCfaTest, cfa_register) {
    398   this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x09, 0x02, 0x01});
    399   dwarf_loc_regs_t loc_regs;
    400 
    401   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x300, 0x303, &loc_regs));
    402   ASSERT_EQ(0x303U, this->dmem_->cur_offset());
    403   ASSERT_EQ(1U, loc_regs.size());
    404   auto location = loc_regs.find(2);
    405   ASSERT_NE(loc_regs.end(), location);
    406   ASSERT_EQ(DWARF_LOCATION_REGISTER, location->second.type);
    407   ASSERT_EQ(1U, location->second.values[0]);
    408 
    409   ASSERT_EQ("", GetFakeLogPrint());
    410   ASSERT_EQ("", GetFakeLogBuf());
    411 
    412   ResetLogs();
    413   loc_regs.clear();
    414   this->memory_.SetMemory(0x4300, std::vector<uint8_t>{0x09, 0xff, 0x01, 0xff, 0x03});
    415 
    416   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x4300, 0x4305, &loc_regs));
    417   ASSERT_EQ(0x4305U, this->dmem_->cur_offset());
    418   ASSERT_EQ(1U, loc_regs.size());
    419   location = loc_regs.find(255);
    420   ASSERT_NE(loc_regs.end(), location);
    421   ASSERT_EQ(DWARF_LOCATION_REGISTER, location->second.type);
    422   ASSERT_EQ(511U, location->second.values[0]);
    423 
    424   ASSERT_EQ("", GetFakeLogPrint());
    425   ASSERT_EQ("", GetFakeLogBuf());
    426 }
    427 
    428 TYPED_TEST_P(DwarfCfaTest, cfa_state) {
    429   this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x0a});
    430   dwarf_loc_regs_t loc_regs;
    431 
    432   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x300, 0x301, &loc_regs));
    433   ASSERT_EQ(0x301U, this->dmem_->cur_offset());
    434   ASSERT_EQ(0U, loc_regs.size());
    435 
    436   ASSERT_EQ("", GetFakeLogPrint());
    437   ASSERT_EQ("", GetFakeLogBuf());
    438 
    439   ResetLogs();
    440   this->memory_.SetMemory(0x4300, std::vector<uint8_t>{0x0b});
    441 
    442   loc_regs.clear();
    443   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x4300, 0x4301, &loc_regs));
    444   ASSERT_EQ(0x4301U, this->dmem_->cur_offset());
    445   ASSERT_EQ(0U, loc_regs.size());
    446 
    447   ASSERT_EQ("", GetFakeLogPrint());
    448   ASSERT_EQ("", GetFakeLogBuf());
    449 
    450   ResetLogs();
    451   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x85, 0x02, 0x0a, 0x86, 0x04, 0x0b});
    452 
    453   loc_regs.clear();
    454   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2005, &loc_regs));
    455   ASSERT_EQ(0x2005U, this->dmem_->cur_offset());
    456   ASSERT_EQ(2U, loc_regs.size());
    457   ASSERT_NE(loc_regs.end(), loc_regs.find(5));
    458   ASSERT_NE(loc_regs.end(), loc_regs.find(6));
    459 
    460   loc_regs.clear();
    461   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2006, &loc_regs));
    462   ASSERT_EQ(0x2006U, this->dmem_->cur_offset());
    463   ASSERT_EQ(1U, loc_regs.size());
    464   ASSERT_NE(loc_regs.end(), loc_regs.find(5));
    465 
    466   ResetLogs();
    467   this->memory_.SetMemory(
    468       0x6000, std::vector<uint8_t>{0x0a, 0x85, 0x02, 0x0a, 0x86, 0x04, 0x0a, 0x87, 0x01, 0x0a, 0x89,
    469                                    0x05, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b});
    470 
    471   loc_regs.clear();
    472   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x6000, 0x600c, &loc_regs));
    473   ASSERT_EQ(0x600cU, this->dmem_->cur_offset());
    474   ASSERT_EQ(4U, loc_regs.size());
    475   ASSERT_NE(loc_regs.end(), loc_regs.find(5));
    476   ASSERT_NE(loc_regs.end(), loc_regs.find(6));
    477   ASSERT_NE(loc_regs.end(), loc_regs.find(7));
    478   ASSERT_NE(loc_regs.end(), loc_regs.find(9));
    479 
    480   loc_regs.clear();
    481   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x6000, 0x600d, &loc_regs));
    482   ASSERT_EQ(0x600dU, this->dmem_->cur_offset());
    483   ASSERT_EQ(3U, loc_regs.size());
    484   ASSERT_NE(loc_regs.end(), loc_regs.find(5));
    485   ASSERT_NE(loc_regs.end(), loc_regs.find(6));
    486   ASSERT_NE(loc_regs.end(), loc_regs.find(7));
    487 
    488   loc_regs.clear();
    489   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x6000, 0x600e, &loc_regs));
    490   ASSERT_EQ(0x600eU, this->dmem_->cur_offset());
    491   ASSERT_EQ(2U, loc_regs.size());
    492   ASSERT_NE(loc_regs.end(), loc_regs.find(5));
    493   ASSERT_NE(loc_regs.end(), loc_regs.find(6));
    494 
    495   loc_regs.clear();
    496   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x6000, 0x600f, &loc_regs));
    497   ASSERT_EQ(0x600fU, this->dmem_->cur_offset());
    498   ASSERT_EQ(1U, loc_regs.size());
    499   ASSERT_NE(loc_regs.end(), loc_regs.find(5));
    500 
    501   loc_regs.clear();
    502   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x6000, 0x6010, &loc_regs));
    503   ASSERT_EQ(0x6010U, this->dmem_->cur_offset());
    504   ASSERT_EQ(0U, loc_regs.size());
    505 
    506   loc_regs.clear();
    507   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x6000, 0x6011, &loc_regs));
    508   ASSERT_EQ(0x6011U, this->dmem_->cur_offset());
    509   ASSERT_EQ(0U, loc_regs.size());
    510 }
    511 
    512 // This test verifies that the cfa offset is saved and restored properly.
    513 // Even though the spec is not clear about whether the offset is also
    514 // restored, the gcc unwinder does, and libunwind does too.
    515 TYPED_TEST_P(DwarfCfaTest, cfa_state_cfa_offset_restore) {
    516   this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x0a, 0x0e, 0x40, 0x0b});
    517   dwarf_loc_regs_t loc_regs;
    518   loc_regs[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {5, 100}};
    519 
    520   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x3000, 0x3004, &loc_regs));
    521   ASSERT_EQ(0x3004U, this->dmem_->cur_offset());
    522   ASSERT_EQ(1U, loc_regs.size());
    523   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    524   ASSERT_EQ(5U, loc_regs[CFA_REG].values[0]);
    525   ASSERT_EQ(100U, loc_regs[CFA_REG].values[1]);
    526 
    527   ASSERT_EQ("", GetFakeLogPrint());
    528   ASSERT_EQ("", GetFakeLogBuf());
    529 }
    530 
    531 TYPED_TEST_P(DwarfCfaTest, cfa_def_cfa) {
    532   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0c, 0x7f, 0x74});
    533   dwarf_loc_regs_t loc_regs;
    534 
    535   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x103, &loc_regs));
    536   ASSERT_EQ(0x103U, this->dmem_->cur_offset());
    537   ASSERT_EQ(1U, loc_regs.size());
    538   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    539   ASSERT_EQ(0x7fU, loc_regs[CFA_REG].values[0]);
    540   ASSERT_EQ(0x74U, loc_regs[CFA_REG].values[1]);
    541 
    542   ASSERT_EQ("", GetFakeLogPrint());
    543   ASSERT_EQ("", GetFakeLogBuf());
    544 
    545   ResetLogs();
    546   loc_regs.clear();
    547   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0c, 0xff, 0x02, 0xf4, 0x04});
    548 
    549   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x205, &loc_regs));
    550   ASSERT_EQ(0x205U, this->dmem_->cur_offset());
    551   ASSERT_EQ(1U, loc_regs.size());
    552   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    553   ASSERT_EQ(0x17fU, loc_regs[CFA_REG].values[0]);
    554   ASSERT_EQ(0x274U, loc_regs[CFA_REG].values[1]);
    555 
    556   ASSERT_EQ("", GetFakeLogPrint());
    557   ASSERT_EQ("", GetFakeLogBuf());
    558 }
    559 
    560 TYPED_TEST_P(DwarfCfaTest, cfa_def_cfa_sf) {
    561   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x12, 0x30, 0x25});
    562   dwarf_loc_regs_t loc_regs;
    563 
    564   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x103, &loc_regs));
    565   ASSERT_EQ(0x103U, this->dmem_->cur_offset());
    566   ASSERT_EQ(1U, loc_regs.size());
    567   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    568   ASSERT_EQ(0x30U, loc_regs[CFA_REG].values[0]);
    569   ASSERT_EQ(0x128U, loc_regs[CFA_REG].values[1]);
    570 
    571   ASSERT_EQ("", GetFakeLogPrint());
    572   ASSERT_EQ("", GetFakeLogBuf());
    573 
    574   // Test a negative value.
    575   ResetLogs();
    576   loc_regs.clear();
    577   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x12, 0xa3, 0x01, 0xfa, 0x7f});
    578 
    579   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x205, &loc_regs));
    580   ASSERT_EQ(0x205U, this->dmem_->cur_offset());
    581   ASSERT_EQ(1U, loc_regs.size());
    582   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    583   ASSERT_EQ(0xa3U, loc_regs[CFA_REG].values[0]);
    584   ASSERT_EQ(static_cast<uint64_t>(-48), loc_regs[CFA_REG].values[1]);
    585 
    586   ASSERT_EQ("", GetFakeLogPrint());
    587   ASSERT_EQ("", GetFakeLogBuf());
    588 }
    589 
    590 TYPED_TEST_P(DwarfCfaTest, cfa_def_cfa_register) {
    591   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0d, 0x72});
    592   dwarf_loc_regs_t loc_regs;
    593 
    594   // This fails because the cfa is not defined as a register.
    595   ASSERT_FALSE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x102, &loc_regs));
    596   ASSERT_EQ(0U, loc_regs.size());
    597   ASSERT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->cfa_->LastErrorCode());
    598 
    599   ASSERT_EQ("4 unwind Attempt to set new register, but cfa is not already set to a register.\n",
    600             GetFakeLogPrint());
    601   ASSERT_EQ("", GetFakeLogBuf());
    602 
    603   ResetLogs();
    604   loc_regs.clear();
    605   loc_regs[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {3, 20}};
    606 
    607   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x102, &loc_regs));
    608   ASSERT_EQ(0x102U, this->dmem_->cur_offset());
    609   ASSERT_EQ(1U, loc_regs.size());
    610   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    611   ASSERT_EQ(0x72U, loc_regs[CFA_REG].values[0]);
    612   ASSERT_EQ(20U, loc_regs[CFA_REG].values[1]);
    613 
    614   ASSERT_EQ("", GetFakeLogPrint());
    615   ASSERT_EQ("", GetFakeLogBuf());
    616 
    617   ResetLogs();
    618   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0d, 0xf9, 0x20});
    619   loc_regs.clear();
    620   loc_regs[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {3, 60}};
    621 
    622   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x203, &loc_regs));
    623   ASSERT_EQ(0x203U, this->dmem_->cur_offset());
    624   ASSERT_EQ(1U, loc_regs.size());
    625   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    626   ASSERT_EQ(0x1079U, loc_regs[CFA_REG].values[0]);
    627   ASSERT_EQ(60U, loc_regs[CFA_REG].values[1]);
    628 
    629   ASSERT_EQ("", GetFakeLogPrint());
    630   ASSERT_EQ("", GetFakeLogBuf());
    631 }
    632 
    633 TYPED_TEST_P(DwarfCfaTest, cfa_def_cfa_offset) {
    634   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0e, 0x59});
    635   dwarf_loc_regs_t loc_regs;
    636 
    637   // This fails because the cfa is not defined as a register.
    638   ASSERT_FALSE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x102, &loc_regs));
    639   ASSERT_EQ(0U, loc_regs.size());
    640   ASSERT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->cfa_->LastErrorCode());
    641 
    642   ASSERT_EQ("4 unwind Attempt to set offset, but cfa is not set to a register.\n",
    643             GetFakeLogPrint());
    644   ASSERT_EQ("", GetFakeLogBuf());
    645 
    646   ResetLogs();
    647   loc_regs.clear();
    648   loc_regs[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {3}};
    649 
    650   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x102, &loc_regs));
    651   ASSERT_EQ(0x102U, this->dmem_->cur_offset());
    652   ASSERT_EQ(1U, loc_regs.size());
    653   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    654   ASSERT_EQ(3U, loc_regs[CFA_REG].values[0]);
    655   ASSERT_EQ(0x59U, loc_regs[CFA_REG].values[1]);
    656 
    657   ASSERT_EQ("", GetFakeLogPrint());
    658   ASSERT_EQ("", GetFakeLogBuf());
    659 
    660   ResetLogs();
    661   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0e, 0xd4, 0x0a});
    662   loc_regs.clear();
    663   loc_regs[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {3}};
    664 
    665   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x203, &loc_regs));
    666   ASSERT_EQ(0x203U, this->dmem_->cur_offset());
    667   ASSERT_EQ(1U, loc_regs.size());
    668   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    669   ASSERT_EQ(3U, loc_regs[CFA_REG].values[0]);
    670   ASSERT_EQ(0x554U, loc_regs[CFA_REG].values[1]);
    671 
    672   ASSERT_EQ("", GetFakeLogPrint());
    673   ASSERT_EQ("", GetFakeLogBuf());
    674 }
    675 
    676 TYPED_TEST_P(DwarfCfaTest, cfa_def_cfa_offset_sf) {
    677   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x13, 0x23});
    678   dwarf_loc_regs_t loc_regs;
    679 
    680   // This fails because the cfa is not defined as a register.
    681   ASSERT_FALSE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x102, &loc_regs));
    682   ASSERT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->cfa_->LastErrorCode());
    683 
    684   ASSERT_EQ("4 unwind Attempt to set offset, but cfa is not set to a register.\n",
    685             GetFakeLogPrint());
    686   ASSERT_EQ("", GetFakeLogBuf());
    687 
    688   ResetLogs();
    689   loc_regs.clear();
    690   loc_regs[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {3}};
    691 
    692   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x102, &loc_regs));
    693   ASSERT_EQ(0x102U, this->dmem_->cur_offset());
    694   ASSERT_EQ(1U, loc_regs.size());
    695   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    696   ASSERT_EQ(3U, loc_regs[CFA_REG].values[0]);
    697   ASSERT_EQ(0x118U, loc_regs[CFA_REG].values[1]);
    698 
    699   ASSERT_EQ("", GetFakeLogPrint());
    700   ASSERT_EQ("", GetFakeLogBuf());
    701 
    702   // Negative offset.
    703   ResetLogs();
    704   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x13, 0xf6, 0x7f});
    705   loc_regs.clear();
    706   loc_regs[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {3}};
    707 
    708   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x203, &loc_regs));
    709   ASSERT_EQ(0x203U, this->dmem_->cur_offset());
    710   ASSERT_EQ(1U, loc_regs.size());
    711   ASSERT_EQ(DWARF_LOCATION_REGISTER, loc_regs[CFA_REG].type);
    712   ASSERT_EQ(3U, loc_regs[CFA_REG].values[0]);
    713   ASSERT_EQ(static_cast<TypeParam>(-80), static_cast<TypeParam>(loc_regs[CFA_REG].values[1]));
    714 
    715   ASSERT_EQ("", GetFakeLogPrint());
    716   ASSERT_EQ("", GetFakeLogBuf());
    717 }
    718 
    719 TYPED_TEST_P(DwarfCfaTest, cfa_def_cfa_expression) {
    720   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0f, 0x04, 0x01, 0x02, 0x03, 0x04});
    721   dwarf_loc_regs_t loc_regs;
    722 
    723   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x106, &loc_regs));
    724   ASSERT_EQ(0x106U, this->dmem_->cur_offset());
    725   ASSERT_EQ(1U, loc_regs.size());
    726 
    727   ASSERT_EQ("", GetFakeLogPrint());
    728   ASSERT_EQ("", GetFakeLogBuf());
    729 
    730   ResetLogs();
    731   std::vector<uint8_t> ops{0x0f, 0x81, 0x01};
    732   for (uint8_t i = 3; i < 132; i++) {
    733     ops.push_back(i - 1);
    734   }
    735   this->memory_.SetMemory(0x200, ops);
    736   loc_regs.clear();
    737   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x284, &loc_regs));
    738   ASSERT_EQ(0x284U, this->dmem_->cur_offset());
    739   ASSERT_EQ(1U, loc_regs.size());
    740   ASSERT_EQ(DWARF_LOCATION_VAL_EXPRESSION, loc_regs[CFA_REG].type);
    741   ASSERT_EQ(0x81U, loc_regs[CFA_REG].values[0]);
    742 
    743   ASSERT_EQ("", GetFakeLogPrint());
    744   ASSERT_EQ("", GetFakeLogBuf());
    745 }
    746 
    747 TYPED_TEST_P(DwarfCfaTest, cfa_expression) {
    748   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x10, 0x04, 0x02, 0x40, 0x20});
    749   dwarf_loc_regs_t loc_regs;
    750 
    751   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x105, &loc_regs));
    752   ASSERT_EQ(0x105U, this->dmem_->cur_offset());
    753   ASSERT_EQ(1U, loc_regs.size());
    754   auto location = loc_regs.find(4);
    755   ASSERT_NE(loc_regs.end(), location);
    756   ASSERT_EQ(DWARF_LOCATION_EXPRESSION, location->second.type);
    757   ASSERT_EQ(2U, location->second.values[0]);
    758   ASSERT_EQ(0x105U, location->second.values[1]);
    759 
    760   ASSERT_EQ("", GetFakeLogPrint());
    761   ASSERT_EQ("", GetFakeLogBuf());
    762 
    763   ResetLogs();
    764   std::vector<uint8_t> ops{0x10, 0xff, 0x01, 0x82, 0x01};
    765   for (uint8_t i = 5; i < 135; i++) {
    766     ops.push_back(i - 4);
    767   }
    768 
    769   this->memory_.SetMemory(0x200, ops);
    770   loc_regs.clear();
    771   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x287, &loc_regs));
    772   ASSERT_EQ(0x287U, this->dmem_->cur_offset());
    773   ASSERT_EQ(1U, loc_regs.size());
    774   location = loc_regs.find(255);
    775   ASSERT_NE(loc_regs.end(), location);
    776   ASSERT_EQ(DWARF_LOCATION_EXPRESSION, location->second.type);
    777   ASSERT_EQ(130U, location->second.values[0]);
    778   ASSERT_EQ(0x287U, location->second.values[1]);
    779 
    780   ASSERT_EQ("", GetFakeLogPrint());
    781   ASSERT_EQ("", GetFakeLogBuf());
    782 }
    783 
    784 TYPED_TEST_P(DwarfCfaTest, cfa_val_offset) {
    785   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x14, 0x45, 0x54});
    786   dwarf_loc_regs_t loc_regs;
    787 
    788   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x103, &loc_regs));
    789   ASSERT_EQ(0x103U, this->dmem_->cur_offset());
    790   ASSERT_EQ(1U, loc_regs.size());
    791   auto location = loc_regs.find(69);
    792   ASSERT_NE(loc_regs.end(), location);
    793   ASSERT_EQ(DWARF_LOCATION_VAL_OFFSET, location->second.type);
    794   ASSERT_EQ(0x2a0U, location->second.values[0]);
    795 
    796   ASSERT_EQ("", GetFakeLogPrint());
    797   ASSERT_EQ("", GetFakeLogBuf());
    798 
    799   ResetLogs();
    800   loc_regs.clear();
    801   this->memory_.SetMemory(0x400, std::vector<uint8_t>{0x14, 0xa2, 0x02, 0xb4, 0x05});
    802 
    803   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x400, 0x405, &loc_regs));
    804   ASSERT_EQ(0x405U, this->dmem_->cur_offset());
    805   ASSERT_EQ(1U, loc_regs.size());
    806   location = loc_regs.find(290);
    807   ASSERT_NE(loc_regs.end(), location);
    808   ASSERT_EQ(DWARF_LOCATION_VAL_OFFSET, location->second.type);
    809   ASSERT_EQ(0x15a0U, location->second.values[0]);
    810 
    811   ASSERT_EQ("", GetFakeLogPrint());
    812   ASSERT_EQ("", GetFakeLogBuf());
    813 }
    814 
    815 TYPED_TEST_P(DwarfCfaTest, cfa_val_offset_sf) {
    816   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x15, 0x56, 0x12});
    817   dwarf_loc_regs_t loc_regs;
    818 
    819   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x103, &loc_regs));
    820   ASSERT_EQ(0x103U, this->dmem_->cur_offset());
    821   ASSERT_EQ(1U, loc_regs.size());
    822   auto location = loc_regs.find(86);
    823   ASSERT_NE(loc_regs.end(), location);
    824   ASSERT_EQ(DWARF_LOCATION_VAL_OFFSET, location->second.type);
    825   ASSERT_EQ(0x90U, location->second.values[0]);
    826 
    827   ASSERT_EQ("", GetFakeLogPrint());
    828   ASSERT_EQ("", GetFakeLogBuf());
    829 
    830   // Negative value.
    831   ResetLogs();
    832   loc_regs.clear();
    833   this->memory_.SetMemory(0xa00, std::vector<uint8_t>{0x15, 0xff, 0x01, 0xc0, 0x7f});
    834 
    835   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0xa00, 0xa05, &loc_regs));
    836   ASSERT_EQ(0xa05U, this->dmem_->cur_offset());
    837   ASSERT_EQ(1U, loc_regs.size());
    838   location = loc_regs.find(255);
    839   ASSERT_NE(loc_regs.end(), location);
    840   ASSERT_EQ(DWARF_LOCATION_VAL_OFFSET, location->second.type);
    841   ASSERT_EQ(static_cast<uint64_t>(-512), location->second.values[0]);
    842 
    843   ASSERT_EQ("", GetFakeLogPrint());
    844   ASSERT_EQ("", GetFakeLogBuf());
    845 }
    846 
    847 TYPED_TEST_P(DwarfCfaTest, cfa_val_expression) {
    848   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x16, 0x05, 0x02, 0x10, 0x20});
    849   dwarf_loc_regs_t loc_regs;
    850 
    851   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x100, 0x105, &loc_regs));
    852   ASSERT_EQ(0x105U, this->dmem_->cur_offset());
    853   ASSERT_EQ(1U, loc_regs.size());
    854   auto location = loc_regs.find(5);
    855   ASSERT_NE(loc_regs.end(), location);
    856   ASSERT_EQ(DWARF_LOCATION_VAL_EXPRESSION, location->second.type);
    857   ASSERT_EQ(2U, location->second.values[0]);
    858   ASSERT_EQ(0x105U, location->second.values[1]);
    859 
    860   ASSERT_EQ("", GetFakeLogPrint());
    861   ASSERT_EQ("", GetFakeLogBuf());
    862 
    863   ResetLogs();
    864   std::vector<uint8_t> ops{0x16, 0x83, 0x10, 0xa8, 0x01};
    865   for (uint8_t i = 0; i < 168; i++) {
    866     ops.push_back(i);
    867   }
    868 
    869   this->memory_.SetMemory(0xa00, ops);
    870   loc_regs.clear();
    871 
    872   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0xa00, 0xaad, &loc_regs));
    873   ASSERT_EQ(0xaadU, this->dmem_->cur_offset());
    874   ASSERT_EQ(1U, loc_regs.size());
    875   location = loc_regs.find(2051);
    876   ASSERT_NE(loc_regs.end(), location);
    877   ASSERT_EQ(DWARF_LOCATION_VAL_EXPRESSION, location->second.type);
    878   ASSERT_EQ(168U, location->second.values[0]);
    879   ASSERT_EQ(0xaadU, location->second.values[1]);
    880 
    881   ASSERT_EQ("", GetFakeLogPrint());
    882   ASSERT_EQ("", GetFakeLogBuf());
    883 }
    884 
    885 TYPED_TEST_P(DwarfCfaTest, cfa_gnu_args_size) {
    886   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x2e, 0x04});
    887   dwarf_loc_regs_t loc_regs;
    888 
    889   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2002, &loc_regs));
    890   ASSERT_EQ(0x2002U, this->dmem_->cur_offset());
    891   ASSERT_EQ(0U, loc_regs.size());
    892 
    893   ASSERT_EQ("", GetFakeLogPrint());
    894   ASSERT_EQ("", GetFakeLogBuf());
    895 
    896   ResetLogs();
    897   loc_regs.clear();
    898   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x2e, 0xa4, 0x80, 0x04});
    899 
    900   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x5000, 0x5004, &loc_regs));
    901   ASSERT_EQ(0x5004U, this->dmem_->cur_offset());
    902   ASSERT_EQ(0U, loc_regs.size());
    903 
    904   ASSERT_EQ("", GetFakeLogPrint());
    905   ASSERT_EQ("", GetFakeLogBuf());
    906 }
    907 
    908 TYPED_TEST_P(DwarfCfaTest, cfa_gnu_negative_offset_extended) {
    909   this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x2f, 0x08, 0x10});
    910   dwarf_loc_regs_t loc_regs;
    911 
    912   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x500, 0x503, &loc_regs));
    913   ASSERT_EQ(0x503U, this->dmem_->cur_offset());
    914   ASSERT_EQ(1U, loc_regs.size());
    915   auto location = loc_regs.find(8);
    916   ASSERT_NE(loc_regs.end(), location);
    917   ASSERT_EQ(DWARF_LOCATION_OFFSET, location->second.type);
    918   ASSERT_EQ(static_cast<uint64_t>(-16), location->second.values[0]);
    919 
    920   ASSERT_EQ("", GetFakeLogPrint());
    921   ASSERT_EQ("", GetFakeLogBuf());
    922 
    923   ResetLogs();
    924   loc_regs.clear();
    925   this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x2f, 0x81, 0x02, 0xff, 0x01});
    926 
    927   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x1500, 0x1505, &loc_regs));
    928   ASSERT_EQ(0x1505U, this->dmem_->cur_offset());
    929   ASSERT_EQ(1U, loc_regs.size());
    930   location = loc_regs.find(257);
    931   ASSERT_NE(loc_regs.end(), location);
    932   ASSERT_EQ(DWARF_LOCATION_OFFSET, location->second.type);
    933   ASSERT_EQ(static_cast<uint64_t>(-255), location->second.values[0]);
    934 
    935   ASSERT_EQ("", GetFakeLogPrint());
    936   ASSERT_EQ("", GetFakeLogBuf());
    937 }
    938 
    939 TYPED_TEST_P(DwarfCfaTest, cfa_register_override) {
    940   this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x09, 0x02, 0x01, 0x09, 0x02, 0x04});
    941   dwarf_loc_regs_t loc_regs;
    942 
    943   ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x300, 0x306, &loc_regs));
    944   ASSERT_EQ(0x306U, this->dmem_->cur_offset());
    945   ASSERT_EQ(1U, loc_regs.size());
    946   auto location = loc_regs.find(2);
    947   ASSERT_NE(loc_regs.end(), location);
    948   ASSERT_EQ(DWARF_LOCATION_REGISTER, location->second.type);
    949   ASSERT_EQ(4U, location->second.values[0]);
    950 
    951   ASSERT_EQ("", GetFakeLogPrint());
    952   ASSERT_EQ("", GetFakeLogBuf());
    953 }
    954 
    955 REGISTER_TYPED_TEST_CASE_P(DwarfCfaTest, cfa_illegal, cfa_nop, cfa_offset, cfa_offset_extended,
    956                            cfa_offset_extended_sf, cfa_restore, cfa_restore_extended, cfa_set_loc,
    957                            cfa_advance_loc1, cfa_advance_loc2, cfa_advance_loc4, cfa_undefined,
    958                            cfa_same, cfa_register, cfa_state, cfa_state_cfa_offset_restore,
    959                            cfa_def_cfa, cfa_def_cfa_sf, cfa_def_cfa_register, cfa_def_cfa_offset,
    960                            cfa_def_cfa_offset_sf, cfa_def_cfa_expression, cfa_expression,
    961                            cfa_val_offset, cfa_val_offset_sf, cfa_val_expression, cfa_gnu_args_size,
    962                            cfa_gnu_negative_offset_extended, cfa_register_override);
    963 
    964 typedef ::testing::Types<uint32_t, uint64_t> DwarfCfaTestTypes;
    965 INSTANTIATE_TYPED_TEST_CASE_P(, DwarfCfaTest, DwarfCfaTestTypes);
    966 
    967 }  // namespace unwindstack
    968