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 <gmock/gmock.h>
     20 #include <gtest/gtest.h>
     21 
     22 #include <unwindstack/DwarfError.h>
     23 #include <unwindstack/DwarfSection.h>
     24 
     25 #include "DwarfEncoding.h"
     26 
     27 #include "LogFake.h"
     28 #include "MemoryFake.h"
     29 #include "RegsFake.h"
     30 
     31 namespace unwindstack {
     32 
     33 template <typename TypeParam>
     34 class MockDwarfSectionImpl : public DwarfSectionImpl<TypeParam> {
     35  public:
     36   MockDwarfSectionImpl(Memory* memory) : DwarfSectionImpl<TypeParam>(memory) {}
     37   virtual ~MockDwarfSectionImpl() = default;
     38 
     39   MOCK_METHOD2(Init, bool(uint64_t, uint64_t));
     40 
     41   MOCK_METHOD2(GetFdeOffsetFromPc, bool(uint64_t, uint64_t*));
     42 
     43   MOCK_METHOD1(GetFdeFromIndex, const DwarfFde*(size_t));
     44 
     45   MOCK_METHOD1(GetCieOffsetFromFde32, uint64_t(uint32_t));
     46 
     47   MOCK_METHOD1(GetCieOffsetFromFde64, uint64_t(uint64_t));
     48 
     49   MOCK_METHOD1(AdjustPcFromFde, uint64_t(uint64_t));
     50 
     51   void TestSetCie32Value(uint32_t value32) { this->cie32_value_ = value32; }
     52 
     53   void TestSetCie64Value(uint64_t value64) { this->cie64_value_ = value64; }
     54 
     55   void TestSetCachedCieEntry(uint64_t offset, const DwarfCie& cie) {
     56     this->cie_entries_[offset] = cie;
     57   }
     58   void TestClearCachedCieEntry() { this->cie_entries_.clear(); }
     59 
     60   void TestSetCachedFdeEntry(uint64_t offset, const DwarfFde& fde) {
     61     this->fde_entries_[offset] = fde;
     62   }
     63   void TestClearCachedFdeEntry() { this->fde_entries_.clear(); }
     64 
     65   void TestSetCachedCieLocRegs(uint64_t offset, const dwarf_loc_regs_t& loc_regs) {
     66     this->cie_loc_regs_[offset] = loc_regs;
     67   }
     68   void TestClearCachedCieLocRegs() { this->cie_loc_regs_.clear(); }
     69 
     70   void TestClearError() { this->last_error_.code = DWARF_ERROR_NONE; }
     71 };
     72 
     73 template <typename TypeParam>
     74 class DwarfSectionImplTest : public ::testing::Test {
     75  protected:
     76   void SetUp() override {
     77     memory_.Clear();
     78     section_ = new MockDwarfSectionImpl<TypeParam>(&memory_);
     79     ResetLogs();
     80     section_->TestSetCie32Value(static_cast<uint32_t>(-1));
     81     section_->TestSetCie64Value(static_cast<uint64_t>(-1));
     82   }
     83 
     84   void TearDown() override { delete section_; }
     85 
     86   MemoryFake memory_;
     87   MockDwarfSectionImpl<TypeParam>* section_ = nullptr;
     88 };
     89 TYPED_TEST_CASE_P(DwarfSectionImplTest);
     90 
     91 // NOTE: All test class variables need to be referenced as this->.
     92 
     93 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) {
     94   DwarfCie cie{.version = 3, .return_address_register = 5};
     95   RegsImplFake<TypeParam> regs(10);
     96   dwarf_loc_regs_t loc_regs;
     97 
     98   regs.set_pc(0x100);
     99   regs.set_sp(0x2000);
    100   regs[5] = 0x20;
    101   regs[9] = 0x3000;
    102   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}};
    103   bool finished;
    104   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    105   EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
    106   EXPECT_EQ(0x5000U, this->section_->LastErrorAddress());
    107 }
    108 
    109 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) {
    110   DwarfCie cie{.version = 3, .return_address_register = 5};
    111   RegsImplFake<TypeParam> regs(10);
    112   dwarf_loc_regs_t loc_regs;
    113 
    114   regs.set_pc(0x100);
    115   regs.set_sp(0x2000);
    116   regs[5] = 0x20;
    117   regs[9] = 0x3000;
    118   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96});
    119   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}};
    120   bool finished;
    121   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    122   EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode());
    123 }
    124 
    125 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) {
    126   DwarfCie cie{.version = 3, .return_address_register = 5};
    127   RegsImplFake<TypeParam> regs(10);
    128   dwarf_loc_regs_t loc_regs;
    129 
    130   regs.set_pc(0x100);
    131   regs.set_sp(0x2000);
    132   regs[5] = 0x20;
    133   regs[9] = 0x3000;
    134   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
    135   TypeParam cfa_value = 0x12345;
    136   this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
    137   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}};
    138   bool finished;
    139   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    140   EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
    141 }
    142 
    143 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) {
    144   DwarfCie cie{.version = 3, .return_address_register = 5};
    145   RegsImplFake<TypeParam> regs(10);
    146   dwarf_loc_regs_t loc_regs;
    147 
    148   regs.set_pc(0x100);
    149   regs.set_sp(0x2000);
    150   regs[5] = 0x20;
    151   regs[9] = 0x3000;
    152   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
    153   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5004}};
    154   bool finished;
    155   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    156   ASSERT_FALSE(finished);
    157   EXPECT_EQ(0x80000000U, regs.sp());
    158   EXPECT_EQ(0x20U, regs.pc());
    159 }
    160 
    161 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) {
    162   DwarfCie cie{.version = 3, .return_address_register = 5};
    163   RegsImplFake<TypeParam> regs(10);
    164   dwarf_loc_regs_t loc_regs;
    165 
    166   regs.set_pc(0x100);
    167   regs.set_sp(0x2000);
    168   regs[5] = 0x20;
    169   regs[9] = 0x3000;
    170   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96});
    171   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}};
    172   bool finished;
    173   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    174   EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode());
    175 }
    176 
    177 TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) {
    178   DwarfCie cie{.return_address_register = 60};
    179   RegsImplFake<TypeParam> regs(10);
    180   dwarf_loc_regs_t loc_regs;
    181 
    182   bool finished;
    183   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    184   EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
    185 }
    186 
    187 TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) {
    188   DwarfCie cie{.return_address_register = 5};
    189   RegsImplFake<TypeParam> regs(10);
    190   dwarf_loc_regs_t loc_regs;
    191 
    192   bool finished;
    193   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    194   EXPECT_EQ(DWARF_ERROR_CFA_NOT_DEFINED, this->section_->LastErrorCode());
    195 }
    196 
    197 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) {
    198   DwarfCie cie{.return_address_register = 5};
    199   RegsImplFake<TypeParam> regs(10);
    200   dwarf_loc_regs_t loc_regs;
    201 
    202   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}};
    203   bool finished;
    204   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    205   EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
    206 
    207   this->section_->TestClearError();
    208   loc_regs.erase(CFA_REG);
    209   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_INVALID, {0, 0}};
    210   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    211   EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
    212 
    213   this->section_->TestClearError();
    214   loc_regs.erase(CFA_REG);
    215   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_OFFSET, {0, 0}};
    216   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    217   EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
    218 
    219   this->section_->TestClearError();
    220   loc_regs.erase(CFA_REG);
    221   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0, 0}};
    222   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    223   EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
    224 }
    225 
    226 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) {
    227   DwarfCie cie{.return_address_register = 5};
    228   RegsImplFake<TypeParam> regs(10);
    229   dwarf_loc_regs_t loc_regs;
    230 
    231   regs.set_pc(0x100);
    232   regs.set_sp(0x2000);
    233   regs[5] = 0x20;
    234   regs[9] = 0x3000;
    235   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {9, 0}};
    236   bool finished;
    237   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    238   EXPECT_FALSE(finished);
    239   EXPECT_EQ(0x20U, regs.pc());
    240   EXPECT_EQ(0x3000U, regs.sp());
    241 }
    242 
    243 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) {
    244   DwarfCie cie{.return_address_register = 5};
    245   RegsImplFake<TypeParam> regs(10);
    246   dwarf_loc_regs_t loc_regs;
    247 
    248   regs.set_pc(0x100);
    249   regs.set_sp(0x2000);
    250   regs[5] = 0x20;
    251   regs[6] = 0x4000;
    252   regs[9] = 0x3000;
    253   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {6, 0}};
    254   bool finished;
    255   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    256   EXPECT_FALSE(finished);
    257   EXPECT_EQ(0x20U, regs.pc());
    258   EXPECT_EQ(0x4000U, regs.sp());
    259 }
    260 
    261 TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) {
    262   DwarfCie cie{.return_address_register = 5};
    263   RegsImplFake<TypeParam> regs(10);
    264   dwarf_loc_regs_t loc_regs;
    265 
    266   regs.set_pc(0x100);
    267   regs.set_sp(0x2000);
    268   regs[1] = 0x100;
    269   regs[3] = 0x300;
    270   regs[8] = 0x10;
    271   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    272   loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 1}};
    273   loc_regs[9] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 2}};
    274   bool finished;
    275   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    276   EXPECT_EQ(0x301U, regs[1]);
    277   EXPECT_EQ(0x300U, regs[3]);
    278   EXPECT_EQ(0x10U, regs[8]);
    279   EXPECT_EQ(0x102U, regs[9]);
    280 }
    281 
    282 TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) {
    283   DwarfCie cie{.return_address_register = 5};
    284   RegsImplFake<TypeParam> regs(10);
    285   dwarf_loc_regs_t loc_regs;
    286 
    287   regs.set_pc(0x100);
    288   regs.set_sp(0x2000);
    289   regs[0] = 0x10;
    290   regs[1] = 0x20;
    291   regs[2] = 0x30;
    292   regs[3] = 0x40;
    293   regs[4] = 0x50;
    294   regs[5] = 0x60;
    295   regs[8] = 0x20;
    296   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    297   loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {0, 1}};
    298   loc_regs[2] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 2}};
    299   loc_regs[3] = DwarfLocation{DWARF_LOCATION_REGISTER, {2, 3}};
    300   loc_regs[4] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 4}};
    301   loc_regs[5] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 5}};
    302   bool finished;
    303   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    304   EXPECT_EQ(0x10U, regs[0]);
    305   EXPECT_EQ(0x11U, regs[1]);
    306   EXPECT_EQ(0x22U, regs[2]);
    307   EXPECT_EQ(0x33U, regs[3]);
    308   EXPECT_EQ(0x44U, regs[4]);
    309   EXPECT_EQ(0x55U, regs[5]);
    310   EXPECT_EQ(0x20U, regs[8]);
    311 }
    312 
    313 TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) {
    314   DwarfCie cie{.return_address_register = 5};
    315   RegsImplFake<TypeParam> regs(10);
    316   dwarf_loc_regs_t loc_regs;
    317 
    318   regs.set_pc(0x100);
    319   regs.set_sp(0x2000);
    320   regs[0] = 0x10;
    321   regs[8] = 0x20;
    322   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    323   loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x8, 0x5008}};
    324   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '1', 0x13, 0x08, 0x11});
    325   bool finished;
    326   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    327   EXPECT_EQ(0x10U, regs[0]);
    328   EXPECT_EQ(0x20U, regs[8]);
    329   EXPECT_EQ(0x11U, regs.dex_pc());
    330 }
    331 
    332 TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) {
    333   DwarfCie cie{.return_address_register = 5};
    334   RegsImplFake<TypeParam> regs(10);
    335   dwarf_loc_regs_t loc_regs;
    336 
    337   regs.set_pc(0x100);
    338   regs.set_sp(0x2000);
    339   regs[8] = 0x10;
    340   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    341   loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {10, 0}};
    342   bool finished;
    343   ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    344   EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
    345 }
    346 
    347 TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) {
    348   DwarfCie cie{.return_address_register = 5};
    349   RegsImplFake<TypeParam> regs(10);
    350   dwarf_loc_regs_t loc_regs;
    351 
    352   if (sizeof(TypeParam) == sizeof(uint64_t)) {
    353     this->memory_.SetData64(0x2150, 0x12345678abcdef00ULL);
    354   } else {
    355     this->memory_.SetData32(0x2150, 0x12345678);
    356   }
    357 
    358   regs.set_pc(0x100);
    359   regs.set_sp(0x2000);
    360   regs[3] = 0x234;
    361   regs[5] = 0x10;
    362   regs[8] = 0x2100;
    363   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    364   loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0x100, 0}};
    365   loc_regs[2] = DwarfLocation{DWARF_LOCATION_OFFSET, {0x50, 0}};
    366   loc_regs[3] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}};
    367   bool finished;
    368   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    369   EXPECT_FALSE(finished);
    370   EXPECT_EQ(0x10U, regs.pc());
    371   EXPECT_EQ(0x2100U, regs.sp());
    372   EXPECT_EQ(0x2200U, regs[1]);
    373   EXPECT_EQ(0x234U, regs[3]);
    374   if (sizeof(TypeParam) == sizeof(uint64_t)) {
    375     EXPECT_EQ(0x12345678abcdef00ULL, regs[2]);
    376   } else {
    377     EXPECT_EQ(0x12345678U, regs[2]);
    378   }
    379 }
    380 
    381 TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) {
    382   DwarfCie cie{.return_address_register = 5};
    383   RegsImplFake<TypeParam> regs(10);
    384   dwarf_loc_regs_t loc_regs;
    385 
    386   regs.set_pc(0x100);
    387   regs.set_sp(0x2000);
    388   regs[5] = 0x20;
    389   regs[8] = 0x10;
    390   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    391   loc_regs[5] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}};
    392   bool finished;
    393   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    394   EXPECT_TRUE(finished);
    395   EXPECT_EQ(0U, regs.pc());
    396   EXPECT_EQ(0x10U, regs.sp());
    397 }
    398 
    399 TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) {
    400   DwarfCie cie{.return_address_register = 5};
    401   RegsImplFake<TypeParam> regs(10);
    402   dwarf_loc_regs_t loc_regs;
    403 
    404   regs.set_pc(0x100);
    405   regs.set_sp(0x2000);
    406   regs[5] = 0;
    407   regs[8] = 0x10;
    408   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    409   bool finished;
    410   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    411   EXPECT_TRUE(finished);
    412   EXPECT_EQ(0U, regs.pc());
    413   EXPECT_EQ(0x10U, regs.sp());
    414 }
    415 
    416 TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) {
    417   DwarfCie cie{.return_address_register = 5};
    418   RegsImplFake<TypeParam> regs(10);
    419   dwarf_loc_regs_t loc_regs;
    420 
    421   regs.set_pc(0x100);
    422   regs.set_sp(0x2000);
    423   regs[5] = 0x20;
    424   regs[8] = 0x10;
    425   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    426   bool finished;
    427   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    428   EXPECT_FALSE(finished);
    429   EXPECT_EQ(0x20U, regs.pc());
    430   EXPECT_EQ(0x10U, regs.sp());
    431 }
    432 
    433 TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) {
    434   DwarfCie cie{.return_address_register = 5};
    435   RegsImplFake<TypeParam> regs(10);
    436   dwarf_loc_regs_t loc_regs;
    437 
    438   regs.set_pc(0x100);
    439   regs.set_sp(0x2000);
    440   regs[5] = 0x20;
    441   regs[8] = 0x10;
    442   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    443   // This should not result in any errors.
    444   loc_regs[20] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    445   bool finished;
    446   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    447   EXPECT_FALSE(finished);
    448   EXPECT_EQ(0x20U, regs.pc());
    449   EXPECT_EQ(0x10U, regs.sp());
    450 }
    451 
    452 TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) {
    453   DwarfCie cie{.version = 3, .return_address_register = 5};
    454   RegsImplFake<TypeParam> regs(10);
    455   dwarf_loc_regs_t loc_regs;
    456 
    457   regs.set_pc(0x100);
    458   regs.set_sp(0x2000);
    459   regs[8] = 0x3000;
    460   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
    461   TypeParam cfa_value = 0x12345;
    462   this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
    463   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    464   loc_regs[5] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}};
    465   bool finished;
    466   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    467   EXPECT_FALSE(finished);
    468   EXPECT_EQ(0x3000U, regs.sp());
    469   EXPECT_EQ(0x12345U, regs.pc());
    470 }
    471 
    472 TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) {
    473   DwarfCie cie{.version = 3, .return_address_register = 5};
    474   RegsImplFake<TypeParam> regs(10);
    475   dwarf_loc_regs_t loc_regs;
    476 
    477   regs.set_pc(0x100);
    478   regs.set_sp(0x2000);
    479   regs[8] = 0x3000;
    480   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
    481   loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
    482   loc_regs[5] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5004}};
    483   bool finished;
    484   ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
    485   EXPECT_FALSE(finished);
    486   EXPECT_EQ(0x3000U, regs.sp());
    487   EXPECT_EQ(0x80000000U, regs.pc());
    488 }
    489 
    490 TYPED_TEST_P(DwarfSectionImplTest, GetCie_fail_should_not_cache) {
    491   ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
    492   EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
    493   EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
    494   this->section_->TestClearError();
    495   ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
    496   EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
    497   EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
    498 }
    499 
    500 TYPED_TEST_P(DwarfSectionImplTest, GetCie_32_version_check) {
    501   this->memory_.SetData32(0x5000, 0x100);
    502   this->memory_.SetData32(0x5004, 0xffffffff);
    503   this->memory_.SetData8(0x5008, 0x1);
    504   this->memory_.SetData8(0x5009, '\0');
    505   this->memory_.SetData8(0x500a, 4);
    506   this->memory_.SetData8(0x500b, 8);
    507   this->memory_.SetData8(0x500c, 0x20);
    508 
    509   const DwarfCie* cie = this->section_->GetCie(0x5000);
    510   ASSERT_TRUE(cie != nullptr);
    511   EXPECT_EQ(1U, cie->version);
    512   EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
    513   EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
    514   EXPECT_EQ(0U, cie->segment_size);
    515   EXPECT_EQ(1U, cie->augmentation_string.size());
    516   EXPECT_EQ('\0', cie->augmentation_string[0]);
    517   EXPECT_EQ(0U, cie->personality_handler);
    518   EXPECT_EQ(0x500dU, cie->cfa_instructions_offset);
    519   EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
    520   EXPECT_EQ(4U, cie->code_alignment_factor);
    521   EXPECT_EQ(8, cie->data_alignment_factor);
    522   EXPECT_EQ(0x20U, cie->return_address_register);
    523   EXPECT_EQ(DWARF_ERROR_NONE, this->section_->LastErrorCode());
    524 
    525   this->section_->TestClearCachedCieEntry();
    526   // Set version to 0, 2, 5 and verify we fail.
    527   this->memory_.SetData8(0x5008, 0x0);
    528   this->section_->TestClearError();
    529   ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
    530   EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
    531 
    532   this->memory_.SetData8(0x5008, 0x2);
    533   this->section_->TestClearError();
    534   ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
    535   EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
    536 
    537   this->memory_.SetData8(0x5008, 0x5);
    538   this->section_->TestClearError();
    539   ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
    540   EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
    541 }
    542 
    543 TYPED_TEST_P(DwarfSectionImplTest, GetCie_negative_data_alignment_factor) {
    544   this->memory_.SetData32(0x5000, 0x100);
    545   this->memory_.SetData32(0x5004, 0xffffffff);
    546   this->memory_.SetData8(0x5008, 0x1);
    547   this->memory_.SetData8(0x5009, '\0');
    548   this->memory_.SetData8(0x500a, 4);
    549   this->memory_.SetMemory(0x500b, std::vector<uint8_t>{0xfc, 0xff, 0xff, 0xff, 0x7f});
    550   this->memory_.SetData8(0x5010, 0x20);
    551 
    552   const DwarfCie* cie = this->section_->GetCie(0x5000);
    553   ASSERT_TRUE(cie != nullptr);
    554   EXPECT_EQ(1U, cie->version);
    555   EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
    556   EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
    557   EXPECT_EQ(0U, cie->segment_size);
    558   EXPECT_EQ(1U, cie->augmentation_string.size());
    559   EXPECT_EQ('\0', cie->augmentation_string[0]);
    560   EXPECT_EQ(0U, cie->personality_handler);
    561   EXPECT_EQ(0x5011U, cie->cfa_instructions_offset);
    562   EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
    563   EXPECT_EQ(4U, cie->code_alignment_factor);
    564   EXPECT_EQ(-4, cie->data_alignment_factor);
    565   EXPECT_EQ(0x20U, cie->return_address_register);
    566 }
    567 
    568 TYPED_TEST_P(DwarfSectionImplTest, GetCie_64_no_augment) {
    569   this->memory_.SetData32(0x8000, 0xffffffff);
    570   this->memory_.SetData64(0x8004, 0x200);
    571   this->memory_.SetData64(0x800c, 0xffffffffffffffffULL);
    572   this->memory_.SetData8(0x8014, 0x1);
    573   this->memory_.SetData8(0x8015, '\0');
    574   this->memory_.SetData8(0x8016, 4);
    575   this->memory_.SetData8(0x8017, 8);
    576   this->memory_.SetData8(0x8018, 0x20);
    577 
    578   const DwarfCie* cie = this->section_->GetCie(0x8000);
    579   ASSERT_TRUE(cie != nullptr);
    580   EXPECT_EQ(1U, cie->version);
    581   EXPECT_EQ(DW_EH_PE_sdata8, cie->fde_address_encoding);
    582   EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
    583   EXPECT_EQ(0U, cie->segment_size);
    584   EXPECT_EQ(1U, cie->augmentation_string.size());
    585   EXPECT_EQ('\0', cie->augmentation_string[0]);
    586   EXPECT_EQ(0U, cie->personality_handler);
    587   EXPECT_EQ(0x8019U, cie->cfa_instructions_offset);
    588   EXPECT_EQ(0x820cU, cie->cfa_instructions_end);
    589   EXPECT_EQ(4U, cie->code_alignment_factor);
    590   EXPECT_EQ(8, cie->data_alignment_factor);
    591   EXPECT_EQ(0x20U, cie->return_address_register);
    592 }
    593 
    594 TYPED_TEST_P(DwarfSectionImplTest, GetCie_augment) {
    595   this->memory_.SetData32(0x5000, 0x100);
    596   this->memory_.SetData32(0x5004, 0xffffffff);
    597   this->memory_.SetData8(0x5008, 0x1);
    598   this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'});
    599   this->memory_.SetData8(0x500e, 4);
    600   this->memory_.SetData8(0x500f, 8);
    601   this->memory_.SetData8(0x5010, 0x10);
    602   // Augment length.
    603   this->memory_.SetData8(0x5011, 0xf);
    604   // L data.
    605   this->memory_.SetData8(0x5012, DW_EH_PE_textrel | DW_EH_PE_udata2);
    606   // P data.
    607   this->memory_.SetData8(0x5013, DW_EH_PE_udata4);
    608   this->memory_.SetData32(0x5014, 0x12345678);
    609   // R data.
    610   this->memory_.SetData8(0x5018, DW_EH_PE_udata2);
    611 
    612   const DwarfCie* cie = this->section_->GetCie(0x5000);
    613   ASSERT_TRUE(cie != nullptr);
    614   EXPECT_EQ(1U, cie->version);
    615   EXPECT_EQ(DW_EH_PE_udata2, cie->fde_address_encoding);
    616   EXPECT_EQ(DW_EH_PE_textrel | DW_EH_PE_udata2, cie->lsda_encoding);
    617   EXPECT_EQ(0U, cie->segment_size);
    618   EXPECT_EQ(5U, cie->augmentation_string.size());
    619   EXPECT_EQ('z', cie->augmentation_string[0]);
    620   EXPECT_EQ('L', cie->augmentation_string[1]);
    621   EXPECT_EQ('P', cie->augmentation_string[2]);
    622   EXPECT_EQ('R', cie->augmentation_string[3]);
    623   EXPECT_EQ('\0', cie->augmentation_string[4]);
    624   EXPECT_EQ(0x12345678U, cie->personality_handler);
    625   EXPECT_EQ(0x5021U, cie->cfa_instructions_offset);
    626   EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
    627   EXPECT_EQ(4U, cie->code_alignment_factor);
    628   EXPECT_EQ(8, cie->data_alignment_factor);
    629   EXPECT_EQ(0x10U, cie->return_address_register);
    630 }
    631 
    632 TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_3) {
    633   this->memory_.SetData32(0x5000, 0x100);
    634   this->memory_.SetData32(0x5004, 0xffffffff);
    635   this->memory_.SetData8(0x5008, 0x3);
    636   this->memory_.SetData8(0x5009, '\0');
    637   this->memory_.SetData8(0x500a, 4);
    638   this->memory_.SetData8(0x500b, 8);
    639   this->memory_.SetMemory(0x500c, std::vector<uint8_t>{0x81, 0x03});
    640 
    641   const DwarfCie* cie = this->section_->GetCie(0x5000);
    642   ASSERT_TRUE(cie != nullptr);
    643   EXPECT_EQ(3U, cie->version);
    644   EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
    645   EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
    646   EXPECT_EQ(0U, cie->segment_size);
    647   EXPECT_EQ(1U, cie->augmentation_string.size());
    648   EXPECT_EQ('\0', cie->augmentation_string[0]);
    649   EXPECT_EQ(0U, cie->personality_handler);
    650   EXPECT_EQ(0x500eU, cie->cfa_instructions_offset);
    651   EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
    652   EXPECT_EQ(4U, cie->code_alignment_factor);
    653   EXPECT_EQ(8, cie->data_alignment_factor);
    654   EXPECT_EQ(0x181U, cie->return_address_register);
    655 }
    656 
    657 TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_4) {
    658   this->memory_.SetData32(0x5000, 0x100);
    659   this->memory_.SetData32(0x5004, 0xffffffff);
    660   this->memory_.SetData8(0x5008, 0x4);
    661   this->memory_.SetData8(0x5009, '\0');
    662   this->memory_.SetData8(0x500a, 4);
    663   this->memory_.SetData8(0x500b, 0x13);
    664   this->memory_.SetData8(0x500c, 4);
    665   this->memory_.SetData8(0x500d, 8);
    666   this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x81, 0x03});
    667 
    668   const DwarfCie* cie = this->section_->GetCie(0x5000);
    669   ASSERT_TRUE(cie != nullptr);
    670   EXPECT_EQ(4U, cie->version);
    671   EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
    672   EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
    673   EXPECT_EQ(0x13U, cie->segment_size);
    674   EXPECT_EQ(1U, cie->augmentation_string.size());
    675   EXPECT_EQ('\0', cie->augmentation_string[0]);
    676   EXPECT_EQ(0U, cie->personality_handler);
    677   EXPECT_EQ(0x5010U, cie->cfa_instructions_offset);
    678   EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
    679   EXPECT_EQ(4U, cie->code_alignment_factor);
    680   EXPECT_EQ(8, cie->data_alignment_factor);
    681   EXPECT_EQ(0x181U, cie->return_address_register);
    682 }
    683 
    684 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_fail_should_not_cache) {
    685   ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
    686   EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
    687   EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
    688   this->section_->TestClearError();
    689   ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
    690   EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
    691   EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
    692 }
    693 
    694 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment) {
    695   this->memory_.SetData32(0x4000, 0x20);
    696   this->memory_.SetData32(0x4004, 0x8000);
    697   this->memory_.SetData32(0x4008, 0x5000);
    698   this->memory_.SetData32(0x400c, 0x100);
    699 
    700   EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
    701   DwarfCie cie{};
    702   cie.fde_address_encoding = DW_EH_PE_udata4;
    703   this->section_->TestSetCachedCieEntry(0x8000, cie);
    704   EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
    705 
    706   const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
    707   ASSERT_TRUE(fde != nullptr);
    708   ASSERT_TRUE(fde->cie != nullptr);
    709   EXPECT_EQ(0x4010U, fde->cfa_instructions_offset);
    710   EXPECT_EQ(0x4024U, fde->cfa_instructions_end);
    711   EXPECT_EQ(0x5000U, fde->pc_start);
    712   EXPECT_EQ(0x5100U, fde->pc_end);
    713   EXPECT_EQ(0x8000U, fde->cie_offset);
    714   EXPECT_EQ(0U, fde->lsda_address);
    715 }
    716 
    717 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment_non_zero_segment_size) {
    718   this->memory_.SetData32(0x4000, 0x30);
    719   this->memory_.SetData32(0x4004, 0x8000);
    720   this->memory_.SetData32(0x4018, 0x5000);
    721   this->memory_.SetData32(0x401c, 0x100);
    722 
    723   EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
    724   DwarfCie cie{};
    725   cie.fde_address_encoding = DW_EH_PE_udata4;
    726   cie.segment_size = 0x10;
    727   this->section_->TestSetCachedCieEntry(0x8000, cie);
    728   EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
    729 
    730   const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
    731   ASSERT_TRUE(fde != nullptr);
    732   ASSERT_TRUE(fde->cie != nullptr);
    733   EXPECT_EQ(0x4020U, fde->cfa_instructions_offset);
    734   EXPECT_EQ(0x4034U, fde->cfa_instructions_end);
    735   EXPECT_EQ(0x5000U, fde->pc_start);
    736   EXPECT_EQ(0x5100U, fde->pc_end);
    737   EXPECT_EQ(0x8000U, fde->cie_offset);
    738   EXPECT_EQ(0U, fde->lsda_address);
    739 }
    740 
    741 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_augment) {
    742   this->memory_.SetData32(0x4000, 0x100);
    743   this->memory_.SetData32(0x4004, 0x8000);
    744   this->memory_.SetData32(0x4008, 0x5000);
    745   this->memory_.SetData32(0x400c, 0x100);
    746   this->memory_.SetMemory(0x4010, std::vector<uint8_t>{0x82, 0x01});
    747   this->memory_.SetData16(0x4012, 0x1234);
    748 
    749   EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
    750   DwarfCie cie{};
    751   cie.fde_address_encoding = DW_EH_PE_udata4;
    752   cie.augmentation_string.push_back('z');
    753   cie.lsda_encoding = DW_EH_PE_udata2;
    754   this->section_->TestSetCachedCieEntry(0x8000, cie);
    755   EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
    756 
    757   const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
    758   ASSERT_TRUE(fde != nullptr);
    759   ASSERT_TRUE(fde->cie != nullptr);
    760   EXPECT_EQ(0x4094U, fde->cfa_instructions_offset);
    761   EXPECT_EQ(0x4104U, fde->cfa_instructions_end);
    762   EXPECT_EQ(0x5000U, fde->pc_start);
    763   EXPECT_EQ(0x5100U, fde->pc_end);
    764   EXPECT_EQ(0x8000U, fde->cie_offset);
    765   EXPECT_EQ(0x1234U, fde->lsda_address);
    766 }
    767 
    768 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_64_no_augment) {
    769   this->memory_.SetData32(0x4000, 0xffffffff);
    770   this->memory_.SetData64(0x4004, 0x100);
    771   this->memory_.SetData64(0x400c, 0x12345678);
    772   this->memory_.SetData32(0x4014, 0x5000);
    773   this->memory_.SetData32(0x4018, 0x100);
    774 
    775   EXPECT_CALL(*this->section_, GetCieOffsetFromFde64(0x12345678))
    776       .WillOnce(::testing::Return(0x12345678));
    777   DwarfCie cie{};
    778   cie.fde_address_encoding = DW_EH_PE_udata4;
    779   this->section_->TestSetCachedCieEntry(0x12345678, cie);
    780   EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
    781 
    782   const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
    783   ASSERT_TRUE(fde != nullptr);
    784   ASSERT_TRUE(fde->cie != nullptr);
    785   EXPECT_EQ(0x401cU, fde->cfa_instructions_offset);
    786   EXPECT_EQ(0x410cU, fde->cfa_instructions_end);
    787   EXPECT_EQ(0x5000U, fde->pc_start);
    788   EXPECT_EQ(0x5100U, fde->pc_end);
    789   EXPECT_EQ(0x12345678U, fde->cie_offset);
    790   EXPECT_EQ(0U, fde->lsda_address);
    791 }
    792 
    793 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_cached) {
    794   DwarfCie cie{};
    795   cie.fde_address_encoding = DW_EH_PE_udata4;
    796   cie.augmentation_string.push_back('z');
    797   cie.lsda_encoding = DW_EH_PE_udata2;
    798 
    799   DwarfFde fde_cached{};
    800   fde_cached.cfa_instructions_offset = 0x1000;
    801   fde_cached.cfa_instructions_end = 0x1100;
    802   fde_cached.pc_start = 0x9000;
    803   fde_cached.pc_end = 0x9400;
    804   fde_cached.cie_offset = 0x30000;
    805   fde_cached.cie = &cie;
    806   this->section_->TestSetCachedFdeEntry(0x6000, fde_cached);
    807 
    808   const DwarfFde* fde = this->section_->GetFdeFromOffset(0x6000);
    809   ASSERT_TRUE(fde != nullptr);
    810   ASSERT_EQ(&cie, fde->cie);
    811   EXPECT_EQ(0x1000U, fde->cfa_instructions_offset);
    812   EXPECT_EQ(0x1100U, fde->cfa_instructions_end);
    813   EXPECT_EQ(0x9000U, fde->pc_start);
    814   EXPECT_EQ(0x9400U, fde->pc_end);
    815   EXPECT_EQ(0x30000U, fde->cie_offset);
    816 }
    817 
    818 TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_not_cached) {
    819   DwarfCie cie{};
    820   cie.cfa_instructions_offset = 0x3000;
    821   cie.cfa_instructions_end = 0x3002;
    822   DwarfFde fde{};
    823   fde.cie = &cie;
    824   fde.cie_offset = 0x8000;
    825   fde.cfa_instructions_offset = 0x6000;
    826   fde.cfa_instructions_end = 0x6002;
    827 
    828   this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x09, 0x02, 0x01});
    829   this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
    830 
    831   dwarf_loc_regs_t loc_regs;
    832   ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs));
    833   ASSERT_EQ(2U, loc_regs.size());
    834 
    835   auto entry = loc_regs.find(2);
    836   ASSERT_NE(entry, loc_regs.end());
    837   ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
    838   ASSERT_EQ(1U, entry->second.values[0]);
    839 
    840   entry = loc_regs.find(4);
    841   ASSERT_NE(entry, loc_regs.end());
    842   ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
    843   ASSERT_EQ(3U, entry->second.values[0]);
    844 }
    845 
    846 TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) {
    847   DwarfCie cie{};
    848   cie.cfa_instructions_offset = 0x3000;
    849   cie.cfa_instructions_end = 0x3002;
    850   DwarfFde fde{};
    851   fde.cie = &cie;
    852   fde.cie_offset = 0x8000;
    853   fde.cfa_instructions_offset = 0x6000;
    854   fde.cfa_instructions_end = 0x6002;
    855 
    856   dwarf_loc_regs_t cie_loc_regs;
    857   cie_loc_regs[6] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 0}};
    858   this->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs);
    859   this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
    860 
    861   dwarf_loc_regs_t loc_regs;
    862   ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs));
    863   ASSERT_EQ(2U, loc_regs.size());
    864 
    865   auto entry = loc_regs.find(6);
    866   ASSERT_NE(entry, loc_regs.end());
    867   ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
    868   ASSERT_EQ(4U, entry->second.values[0]);
    869 
    870   entry = loc_regs.find(4);
    871   ASSERT_NE(entry, loc_regs.end());
    872   ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
    873   ASSERT_EQ(3U, entry->second.values[0]);
    874 }
    875 
    876 TYPED_TEST_P(DwarfSectionImplTest, Log) {
    877   DwarfCie cie{};
    878   cie.cfa_instructions_offset = 0x5000;
    879   cie.cfa_instructions_end = 0x5001;
    880   DwarfFde fde{};
    881   fde.cie = &cie;
    882   fde.cfa_instructions_offset = 0x6000;
    883   fde.cfa_instructions_end = 0x6001;
    884 
    885   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x00});
    886   this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0xc2});
    887   ASSERT_TRUE(this->section_->Log(2, 0x1000, 0x1000, &fde));
    888 
    889   ASSERT_EQ(
    890       "4 unwind     DW_CFA_nop\n"
    891       "4 unwind     Raw Data: 0x00\n"
    892       "4 unwind     DW_CFA_restore register(2)\n"
    893       "4 unwind     Raw Data: 0xc2\n",
    894       GetFakeLogPrint());
    895   ASSERT_EQ("", GetFakeLogBuf());
    896 }
    897 
    898 REGISTER_TYPED_TEST_CASE_P(
    899     DwarfSectionImplTest, Eval_cfa_expr_eval_fail, Eval_cfa_expr_no_stack,
    900     Eval_cfa_expr_is_register, Eval_cfa_expr, Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa,
    901     Eval_cfa_bad, Eval_cfa_register_prev, Eval_cfa_register_from_value, Eval_double_indirection,
    902     Eval_register_reference_chain, Eval_dex_pc, Eval_invalid_register, Eval_different_reg_locations,
    903     Eval_return_address_undefined, Eval_pc_zero, Eval_return_address, Eval_ignore_large_reg_loc,
    904     Eval_reg_expr, Eval_reg_val_expr, GetCie_fail_should_not_cache, GetCie_32_version_check,
    905     GetCie_negative_data_alignment_factor, GetCie_64_no_augment, GetCie_augment, GetCie_version_3,
    906     GetCie_version_4, GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment,
    907     GetFdeFromOffset_32_no_augment_non_zero_segment_size, GetFdeFromOffset_32_augment,
    908     GetFdeFromOffset_64_no_augment, GetFdeFromOffset_cached, GetCfaLocationInfo_cie_not_cached,
    909     GetCfaLocationInfo_cie_cached, Log);
    910 
    911 typedef ::testing::Types<uint32_t, uint64_t> DwarfSectionImplTestTypes;
    912 INSTANTIATE_TYPED_TEST_CASE_P(, DwarfSectionImplTest, DwarfSectionImplTestTypes);
    913 
    914 }  // namespace unwindstack
    915