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 <type_traits>
     21 #include <unordered_map>
     22 
     23 #include <android-base/stringprintf.h>
     24 #include <gtest/gtest.h>
     25 
     26 #include <unwindstack/DwarfLocation.h>
     27 #include <unwindstack/DwarfMemory.h>
     28 #include <unwindstack/DwarfStructs.h>
     29 #include <unwindstack/Log.h>
     30 
     31 #include "DwarfCfa.h"
     32 
     33 #include "LogFake.h"
     34 #include "MemoryFake.h"
     35 
     36 namespace unwindstack {
     37 
     38 template <typename TypeParam>
     39 class DwarfCfaLogTest : public ::testing::Test {
     40  protected:
     41   void SetUp() override {
     42     ResetLogs();
     43     memory_.Clear();
     44 
     45     dmem_.reset(new DwarfMemory(&memory_));
     46 
     47     cie_.cfa_instructions_offset = 0x1000;
     48     cie_.cfa_instructions_end = 0x1030;
     49     // These two values should be different to distinguish between
     50     // operations that deal with code versus data.
     51     cie_.code_alignment_factor = 4;
     52     cie_.data_alignment_factor = 8;
     53 
     54     fde_.cfa_instructions_offset = 0x2000;
     55     fde_.cfa_instructions_end = 0x2030;
     56     fde_.pc_start = 0x2000;
     57     fde_.pc_end = 0x2000;
     58     fde_.pc_end = 0x10000;
     59     fde_.cie = &cie_;
     60     cfa_.reset(new DwarfCfa<TypeParam>(dmem_.get(), &fde_));
     61   }
     62 
     63   MemoryFake memory_;
     64   std::unique_ptr<DwarfMemory> dmem_;
     65   std::unique_ptr<DwarfCfa<TypeParam>> cfa_;
     66   DwarfCie cie_;
     67   DwarfFde fde_;
     68 };
     69 TYPED_TEST_CASE_P(DwarfCfaLogTest);
     70 
     71 // NOTE: All class variable references have to be prefaced with this->.
     72 
     73 TYPED_TEST_P(DwarfCfaLogTest, cfa_illegal) {
     74   for (uint8_t i = 0x17; i < 0x3f; i++) {
     75     if (i == 0x2e || i == 0x2f) {
     76       // Skip gnu extension ops.
     77       continue;
     78     }
     79     this->memory_.SetMemory(0x2000, std::vector<uint8_t>{i});
     80 
     81     ResetLogs();
     82     ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2001));
     83     std::string expected = "4 unwind Illegal\n";
     84     expected += android::base::StringPrintf("4 unwind Raw Data: 0x%02x\n", i);
     85     ASSERT_EQ(expected, GetFakeLogPrint());
     86     ASSERT_EQ("", GetFakeLogBuf());
     87   }
     88 }
     89 
     90 TYPED_TEST_P(DwarfCfaLogTest, cfa_nop) {
     91   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x00});
     92 
     93   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2001));
     94   std::string expected =
     95       "4 unwind DW_CFA_nop\n"
     96       "4 unwind Raw Data: 0x00\n";
     97   ASSERT_EQ(expected, GetFakeLogPrint());
     98   ASSERT_EQ("", GetFakeLogBuf());
     99 }
    100 
    101 TYPED_TEST_P(DwarfCfaLogTest, cfa_offset) {
    102   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x83, 0x04});
    103 
    104   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2002));
    105   std::string expected =
    106       "4 unwind DW_CFA_offset register(3) 4\n"
    107       "4 unwind Raw Data: 0x83 0x04\n";
    108   ASSERT_EQ(expected, GetFakeLogPrint());
    109   ASSERT_EQ("", GetFakeLogBuf());
    110 
    111   ResetLogs();
    112   this->memory_.SetMemory(0x2100, std::vector<uint8_t>{0x83, 0x84, 0x01});
    113 
    114   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2100, 0x2103));
    115   expected =
    116       "4 unwind DW_CFA_offset register(3) 132\n"
    117       "4 unwind Raw Data: 0x83 0x84 0x01\n";
    118   ASSERT_EQ(expected, GetFakeLogPrint());
    119   ASSERT_EQ("", GetFakeLogBuf());
    120 }
    121 
    122 TYPED_TEST_P(DwarfCfaLogTest, cfa_offset_extended) {
    123   this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x05, 0x03, 0x02});
    124 
    125   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x500, 0x503));
    126   std::string expected =
    127       "4 unwind DW_CFA_offset_extended register(3) 2\n"
    128       "4 unwind Raw Data: 0x05 0x03 0x02\n";
    129   ASSERT_EQ(expected, GetFakeLogPrint());
    130   ASSERT_EQ("", GetFakeLogBuf());
    131 
    132   ResetLogs();
    133   this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x05, 0x81, 0x01, 0x82, 0x12});
    134 
    135   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x1500, 0x1505));
    136   expected =
    137       "4 unwind DW_CFA_offset_extended register(129) 2306\n"
    138       "4 unwind Raw Data: 0x05 0x81 0x01 0x82 0x12\n";
    139   ASSERT_EQ(expected, GetFakeLogPrint());
    140   ASSERT_EQ("", GetFakeLogBuf());
    141 }
    142 
    143 TYPED_TEST_P(DwarfCfaLogTest, cfa_offset_extended_sf) {
    144   this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x11, 0x05, 0x10});
    145 
    146   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x500, 0x503));
    147   std::string expected =
    148       "4 unwind DW_CFA_offset_extended_sf register(5) 16\n"
    149       "4 unwind Raw Data: 0x11 0x05 0x10\n";
    150   ASSERT_EQ(expected, GetFakeLogPrint());
    151   ASSERT_EQ("", GetFakeLogBuf());
    152 
    153   // Check a negative value for the offset.
    154   ResetLogs();
    155   this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x11, 0x86, 0x01, 0xff, 0x7f});
    156 
    157   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x1500, 0x1505));
    158   expected =
    159       "4 unwind DW_CFA_offset_extended_sf register(134) -1\n"
    160       "4 unwind Raw Data: 0x11 0x86 0x01 0xff 0x7f\n";
    161   ASSERT_EQ(expected, GetFakeLogPrint());
    162   ASSERT_EQ("", GetFakeLogBuf());
    163 }
    164 
    165 TYPED_TEST_P(DwarfCfaLogTest, cfa_restore) {
    166   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0xc2});
    167 
    168   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2001));
    169   std::string expected =
    170       "4 unwind DW_CFA_restore register(2)\n"
    171       "4 unwind Raw Data: 0xc2\n";
    172   ASSERT_EQ(expected, GetFakeLogPrint());
    173   ASSERT_EQ("", GetFakeLogBuf());
    174 
    175   ResetLogs();
    176   this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x82, 0x04, 0xc2});
    177 
    178   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x3000, 0x3003));
    179   expected =
    180       "4 unwind DW_CFA_offset register(2) 4\n"
    181       "4 unwind Raw Data: 0x82 0x04\n"
    182       "4 unwind DW_CFA_restore register(2)\n"
    183       "4 unwind Raw Data: 0xc2\n";
    184   ASSERT_EQ(expected, GetFakeLogPrint());
    185   ASSERT_EQ("", GetFakeLogBuf());
    186 }
    187 
    188 TYPED_TEST_P(DwarfCfaLogTest, cfa_restore_extended) {
    189   this->memory_.SetMemory(0x4000, std::vector<uint8_t>{0x06, 0x08});
    190 
    191   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x4000, 0x4002));
    192   std::string expected =
    193       "4 unwind DW_CFA_restore_extended register(8)\n"
    194       "4 unwind Raw Data: 0x06 0x08\n";
    195   ASSERT_EQ(expected, GetFakeLogPrint());
    196   ASSERT_EQ("", GetFakeLogBuf());
    197 
    198   ResetLogs();
    199   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x05, 0x82, 0x02, 0x04, 0x06, 0x82, 0x02});
    200 
    201   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x5000, 0x5007));
    202   expected =
    203       "4 unwind DW_CFA_offset_extended register(258) 4\n"
    204       "4 unwind Raw Data: 0x05 0x82 0x02 0x04\n"
    205       "4 unwind DW_CFA_restore_extended register(258)\n"
    206       "4 unwind Raw Data: 0x06 0x82 0x02\n";
    207   ASSERT_EQ(expected, GetFakeLogPrint());
    208   ASSERT_EQ("", GetFakeLogBuf());
    209 }
    210 
    211 TYPED_TEST_P(DwarfCfaLogTest, cfa_set_loc) {
    212   uint8_t buffer[1 + sizeof(TypeParam)];
    213   buffer[0] = 0x1;
    214   TypeParam address;
    215   std::string raw_data("Raw Data: 0x01 ");
    216   std::string address_str;
    217   if (std::is_same<TypeParam, uint32_t>::value) {
    218     address = 0x81234578U;
    219     address_str = "0x81234578";
    220     raw_data += "0x78 0x45 0x23 0x81";
    221   } else {
    222     address = 0x8123456712345678ULL;
    223     address_str = "0x8123456712345678";
    224     raw_data += "0x78 0x56 0x34 0x12 0x67 0x45 0x23 0x81";
    225   }
    226   memcpy(&buffer[1], &address, sizeof(address));
    227 
    228   this->memory_.SetMemory(0x50, buffer, sizeof(buffer));
    229   ResetLogs();
    230 
    231   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x50, 0x51 + sizeof(TypeParam)));
    232   std::string expected = "4 unwind DW_CFA_set_loc " + address_str + "\n";
    233   expected += "4 unwind " + raw_data + "\n";
    234   expected += "4 unwind \n";
    235   expected += "4 unwind PC " + address_str + "\n";
    236   ASSERT_EQ(expected, GetFakeLogPrint());
    237   ASSERT_EQ("", GetFakeLogBuf());
    238 
    239   // Check for a set going back.
    240   ResetLogs();
    241   this->fde_.pc_start = address + 0x10;
    242 
    243   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x50, 0x51 + sizeof(TypeParam)));
    244   expected = "4 unwind DW_CFA_set_loc " + address_str + "\n";
    245   expected += "4 unwind " + raw_data + "\n";
    246   expected += "4 unwind \n";
    247   expected += "4 unwind PC " + address_str + "\n";
    248   ASSERT_EQ(expected, GetFakeLogPrint());
    249   ASSERT_EQ("", GetFakeLogBuf());
    250 }
    251 
    252 TYPED_TEST_P(DwarfCfaLogTest, cfa_advance_loc) {
    253   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x44});
    254 
    255   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x201));
    256   std::string expected =
    257       "4 unwind DW_CFA_advance_loc 4\n"
    258       "4 unwind Raw Data: 0x44\n"
    259       "4 unwind \n"
    260       "4 unwind PC 0x2010\n";
    261   ASSERT_EQ(expected, GetFakeLogPrint());
    262   ASSERT_EQ("", GetFakeLogBuf());
    263 
    264   ResetLogs();
    265   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0x100, 0x200, 0x201));
    266   expected =
    267       "4 unwind DW_CFA_advance_loc 4\n"
    268       "4 unwind Raw Data: 0x44\n"
    269       "4 unwind \n"
    270       "4 unwind PC 0x2110\n";
    271   ASSERT_EQ(expected, GetFakeLogPrint());
    272   ASSERT_EQ("", GetFakeLogBuf());
    273 }
    274 
    275 TYPED_TEST_P(DwarfCfaLogTest, cfa_advance_loc1) {
    276   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x02, 0x04});
    277 
    278   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x202));
    279   std::string expected =
    280       "4 unwind DW_CFA_advance_loc1 4\n"
    281       "4 unwind Raw Data: 0x02 0x04\n"
    282       "4 unwind \n"
    283       "4 unwind PC 0x2004\n";
    284   ASSERT_EQ(expected, GetFakeLogPrint());
    285   ASSERT_EQ("", GetFakeLogBuf());
    286 
    287   ResetLogs();
    288   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0x10, 0x200, 0x202));
    289   expected =
    290       "4 unwind DW_CFA_advance_loc1 4\n"
    291       "4 unwind Raw Data: 0x02 0x04\n"
    292       "4 unwind \n"
    293       "4 unwind PC 0x2014\n";
    294   ASSERT_EQ(expected, GetFakeLogPrint());
    295   ASSERT_EQ("", GetFakeLogBuf());
    296 }
    297 
    298 TYPED_TEST_P(DwarfCfaLogTest, cfa_advance_loc2) {
    299   this->memory_.SetMemory(0x600, std::vector<uint8_t>{0x03, 0x04, 0x03});
    300 
    301   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x600, 0x603));
    302   std::string expected =
    303       "4 unwind DW_CFA_advance_loc2 772\n"
    304       "4 unwind Raw Data: 0x03 0x04 0x03\n"
    305       "4 unwind \n"
    306       "4 unwind PC 0x2304\n";
    307   ASSERT_EQ(expected, GetFakeLogPrint());
    308   ASSERT_EQ("", GetFakeLogBuf());
    309 
    310   ResetLogs();
    311   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0x1000, 0x600, 0x603));
    312   expected =
    313       "4 unwind DW_CFA_advance_loc2 772\n"
    314       "4 unwind Raw Data: 0x03 0x04 0x03\n"
    315       "4 unwind \n"
    316       "4 unwind PC 0x3304\n";
    317   ASSERT_EQ(expected, GetFakeLogPrint());
    318   ASSERT_EQ("", GetFakeLogBuf());
    319 }
    320 
    321 TYPED_TEST_P(DwarfCfaLogTest, cfa_advance_loc4) {
    322   this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x04, 0x04, 0x03, 0x02, 0x01});
    323 
    324   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x500, 0x505));
    325   std::string expected =
    326       "4 unwind DW_CFA_advance_loc4 16909060\n"
    327       "4 unwind Raw Data: 0x04 0x04 0x03 0x02 0x01\n"
    328       "4 unwind \n"
    329       "4 unwind PC 0x1022304\n";
    330   ASSERT_EQ(expected, GetFakeLogPrint());
    331   ASSERT_EQ("", GetFakeLogBuf());
    332 
    333   ResetLogs();
    334   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0x2000, 0x500, 0x505));
    335   expected =
    336       "4 unwind DW_CFA_advance_loc4 16909060\n"
    337       "4 unwind Raw Data: 0x04 0x04 0x03 0x02 0x01\n"
    338       "4 unwind \n"
    339       "4 unwind PC 0x1024304\n";
    340   ASSERT_EQ(expected, GetFakeLogPrint());
    341   ASSERT_EQ("", GetFakeLogBuf());
    342 }
    343 
    344 TYPED_TEST_P(DwarfCfaLogTest, cfa_undefined) {
    345   this->memory_.SetMemory(0xa00, std::vector<uint8_t>{0x07, 0x09});
    346 
    347   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0xa00, 0xa02));
    348   std::string expected =
    349       "4 unwind DW_CFA_undefined register(9)\n"
    350       "4 unwind Raw Data: 0x07 0x09\n";
    351   ASSERT_EQ(expected, GetFakeLogPrint());
    352   ASSERT_EQ("", GetFakeLogBuf());
    353 
    354   ResetLogs();
    355   dwarf_loc_regs_t cie_loc_regs;
    356   this->memory_.SetMemory(0x1a00, std::vector<uint8_t>{0x07, 0x81, 0x01});
    357 
    358   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x1a00, 0x1a03));
    359   expected =
    360       "4 unwind DW_CFA_undefined register(129)\n"
    361       "4 unwind Raw Data: 0x07 0x81 0x01\n";
    362   ASSERT_EQ(expected, GetFakeLogPrint());
    363   ASSERT_EQ("", GetFakeLogBuf());
    364 }
    365 
    366 TYPED_TEST_P(DwarfCfaLogTest, cfa_same) {
    367   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x08, 0x7f});
    368 
    369   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
    370   std::string expected =
    371       "4 unwind DW_CFA_same_value register(127)\n"
    372       "4 unwind Raw Data: 0x08 0x7f\n";
    373   ASSERT_EQ(expected, GetFakeLogPrint());
    374   ASSERT_EQ("", GetFakeLogBuf());
    375 
    376   ResetLogs();
    377   this->memory_.SetMemory(0x2100, std::vector<uint8_t>{0x08, 0xff, 0x01});
    378 
    379   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2100, 0x2103));
    380   expected =
    381       "4 unwind DW_CFA_same_value register(255)\n"
    382       "4 unwind Raw Data: 0x08 0xff 0x01\n";
    383   ASSERT_EQ(expected, GetFakeLogPrint());
    384   ASSERT_EQ("", GetFakeLogBuf());
    385 }
    386 
    387 TYPED_TEST_P(DwarfCfaLogTest, cfa_register) {
    388   this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x09, 0x02, 0x01});
    389 
    390   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x300, 0x303));
    391   std::string expected =
    392       "4 unwind DW_CFA_register register(2) register(1)\n"
    393       "4 unwind Raw Data: 0x09 0x02 0x01\n";
    394   ASSERT_EQ(expected, GetFakeLogPrint());
    395   ASSERT_EQ("", GetFakeLogBuf());
    396 
    397   ResetLogs();
    398   this->memory_.SetMemory(0x4300, std::vector<uint8_t>{0x09, 0xff, 0x01, 0xff, 0x03});
    399 
    400   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x4300, 0x4305));
    401   expected =
    402       "4 unwind DW_CFA_register register(255) register(511)\n"
    403       "4 unwind Raw Data: 0x09 0xff 0x01 0xff 0x03\n";
    404   ASSERT_EQ(expected, GetFakeLogPrint());
    405   ASSERT_EQ("", GetFakeLogBuf());
    406 }
    407 
    408 TYPED_TEST_P(DwarfCfaLogTest, cfa_state) {
    409   this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x0a});
    410 
    411   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x300, 0x301));
    412 
    413   std::string expected =
    414       "4 unwind DW_CFA_remember_state\n"
    415       "4 unwind Raw Data: 0x0a\n";
    416   ASSERT_EQ(expected, GetFakeLogPrint());
    417   ASSERT_EQ("", GetFakeLogBuf());
    418 
    419   ResetLogs();
    420   this->memory_.SetMemory(0x4300, std::vector<uint8_t>{0x0b});
    421 
    422   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x4300, 0x4301));
    423 
    424   expected =
    425       "4 unwind DW_CFA_restore_state\n"
    426       "4 unwind Raw Data: 0x0b\n";
    427   ASSERT_EQ(expected, GetFakeLogPrint());
    428   ASSERT_EQ("", GetFakeLogBuf());
    429 }
    430 
    431 TYPED_TEST_P(DwarfCfaLogTest, cfa_state_cfa_offset_restore) {
    432   this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x0a, 0x0e, 0x40, 0x0b});
    433 
    434   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x3000, 0x3004));
    435 
    436   std::string expected =
    437       "4 unwind DW_CFA_remember_state\n"
    438       "4 unwind Raw Data: 0x0a\n"
    439       "4 unwind DW_CFA_def_cfa_offset 64\n"
    440       "4 unwind Raw Data: 0x0e 0x40\n"
    441       "4 unwind DW_CFA_restore_state\n"
    442       "4 unwind Raw Data: 0x0b\n";
    443   ASSERT_EQ(expected, GetFakeLogPrint());
    444   ASSERT_EQ("", GetFakeLogBuf());
    445 }
    446 
    447 TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa) {
    448   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0c, 0x7f, 0x74});
    449 
    450   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x103));
    451 
    452   std::string expected =
    453       "4 unwind DW_CFA_def_cfa register(127) 116\n"
    454       "4 unwind Raw Data: 0x0c 0x7f 0x74\n";
    455   ASSERT_EQ(expected, GetFakeLogPrint());
    456   ASSERT_EQ("", GetFakeLogBuf());
    457 
    458   ResetLogs();
    459   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0c, 0xff, 0x02, 0xf4, 0x04});
    460 
    461   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x205));
    462 
    463   expected =
    464       "4 unwind DW_CFA_def_cfa register(383) 628\n"
    465       "4 unwind Raw Data: 0x0c 0xff 0x02 0xf4 0x04\n";
    466   ASSERT_EQ(expected, GetFakeLogPrint());
    467   ASSERT_EQ("", GetFakeLogBuf());
    468 }
    469 
    470 TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_sf) {
    471   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x12, 0x30, 0x25});
    472 
    473   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x103));
    474 
    475   std::string expected =
    476       "4 unwind DW_CFA_def_cfa_sf register(48) 37\n"
    477       "4 unwind Raw Data: 0x12 0x30 0x25\n";
    478   ASSERT_EQ(expected, GetFakeLogPrint());
    479   ASSERT_EQ("", GetFakeLogBuf());
    480 
    481   // Test a negative value.
    482   ResetLogs();
    483   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x12, 0xa3, 0x01, 0xfa, 0x7f});
    484 
    485   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x205));
    486 
    487   expected =
    488       "4 unwind DW_CFA_def_cfa_sf register(163) -6\n"
    489       "4 unwind Raw Data: 0x12 0xa3 0x01 0xfa 0x7f\n";
    490   ASSERT_EQ(expected, GetFakeLogPrint());
    491   ASSERT_EQ("", GetFakeLogBuf());
    492 }
    493 
    494 TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_register) {
    495   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0d, 0x72});
    496 
    497   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
    498 
    499   std::string expected =
    500       "4 unwind DW_CFA_def_cfa_register register(114)\n"
    501       "4 unwind Raw Data: 0x0d 0x72\n";
    502   ASSERT_EQ(expected, GetFakeLogPrint());
    503   ASSERT_EQ("", GetFakeLogBuf());
    504 
    505   ResetLogs();
    506   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0d, 0xf9, 0x20});
    507 
    508   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x203));
    509 
    510   expected =
    511       "4 unwind DW_CFA_def_cfa_register register(4217)\n"
    512       "4 unwind Raw Data: 0x0d 0xf9 0x20\n";
    513   ASSERT_EQ(expected, GetFakeLogPrint());
    514   ASSERT_EQ("", GetFakeLogBuf());
    515 }
    516 
    517 TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_offset) {
    518   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0e, 0x59});
    519 
    520   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
    521 
    522   std::string expected =
    523       "4 unwind DW_CFA_def_cfa_offset 89\n"
    524       "4 unwind Raw Data: 0x0e 0x59\n";
    525   ASSERT_EQ(expected, GetFakeLogPrint());
    526   ASSERT_EQ("", GetFakeLogBuf());
    527 
    528   ResetLogs();
    529   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
    530 
    531   expected =
    532       "4 unwind DW_CFA_def_cfa_offset 89\n"
    533       "4 unwind Raw Data: 0x0e 0x59\n";
    534   ASSERT_EQ(expected, GetFakeLogPrint());
    535   ASSERT_EQ("", GetFakeLogBuf());
    536 
    537   ResetLogs();
    538   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0e, 0xd4, 0x0a});
    539 
    540   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x203));
    541 
    542   expected =
    543       "4 unwind DW_CFA_def_cfa_offset 1364\n"
    544       "4 unwind Raw Data: 0x0e 0xd4 0x0a\n";
    545   ASSERT_EQ(expected, GetFakeLogPrint());
    546   ASSERT_EQ("", GetFakeLogBuf());
    547 }
    548 
    549 TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_offset_sf) {
    550   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x13, 0x23});
    551 
    552   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
    553 
    554   std::string expected =
    555       "4 unwind DW_CFA_def_cfa_offset_sf 35\n"
    556       "4 unwind Raw Data: 0x13 0x23\n";
    557   ASSERT_EQ(expected, GetFakeLogPrint());
    558   ASSERT_EQ("", GetFakeLogBuf());
    559 
    560   ResetLogs();
    561   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
    562 
    563   expected =
    564       "4 unwind DW_CFA_def_cfa_offset_sf 35\n"
    565       "4 unwind Raw Data: 0x13 0x23\n";
    566   ASSERT_EQ(expected, GetFakeLogPrint());
    567   ASSERT_EQ("", GetFakeLogBuf());
    568 
    569   // Negative offset.
    570   ResetLogs();
    571   this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x13, 0xf6, 0x7f});
    572 
    573   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x203));
    574 
    575   expected =
    576       "4 unwind DW_CFA_def_cfa_offset_sf -10\n"
    577       "4 unwind Raw Data: 0x13 0xf6 0x7f\n";
    578   ASSERT_EQ(expected, GetFakeLogPrint());
    579   ASSERT_EQ("", GetFakeLogBuf());
    580 }
    581 
    582 TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_expression) {
    583   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0f, 0x04, 0x01, 0x02, 0x04, 0x05});
    584 
    585   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x106));
    586 
    587   std::string expected =
    588       "4 unwind DW_CFA_def_cfa_expression 4\n"
    589       "4 unwind Raw Data: 0x0f 0x04 0x01 0x02 0x04 0x05\n"
    590       "4 unwind   Illegal\n"
    591       "4 unwind   Raw Data: 0x01\n"
    592       "4 unwind   Illegal\n"
    593       "4 unwind   Raw Data: 0x02\n"
    594       "4 unwind   Illegal\n"
    595       "4 unwind   Raw Data: 0x04\n"
    596       "4 unwind   Illegal\n"
    597       "4 unwind   Raw Data: 0x05\n";
    598   ASSERT_EQ(expected, GetFakeLogPrint());
    599   ASSERT_EQ("", GetFakeLogBuf());
    600 
    601   ResetLogs();
    602   std::vector<uint8_t> ops{0x0f, 0x81, 0x01};
    603   expected = "4 unwind Raw Data: 0x0f 0x81 0x01";
    604   std::string op_string;
    605   for (uint8_t i = 3; i < 132; i++) {
    606     ops.push_back(0x05);
    607     op_string +=
    608         "4 unwind   Illegal\n"
    609         "4 unwind   Raw Data: 0x05\n";
    610     expected += " 0x05";
    611     if (((i + 1) % 10) == 0) {
    612       expected += "\n4 unwind Raw Data:";
    613     }
    614   }
    615   expected += '\n';
    616   this->memory_.SetMemory(0x200, ops);
    617   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x284));
    618 
    619   expected = "4 unwind DW_CFA_def_cfa_expression 129\n" + expected;
    620   ASSERT_EQ(expected + op_string, GetFakeLogPrint());
    621   ASSERT_EQ("", GetFakeLogBuf());
    622 }
    623 
    624 TYPED_TEST_P(DwarfCfaLogTest, cfa_expression) {
    625   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x10, 0x04, 0x02, 0xc0, 0xc1});
    626 
    627   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x105));
    628 
    629   std::string expected =
    630       "4 unwind DW_CFA_expression register(4) 2\n"
    631       "4 unwind Raw Data: 0x10 0x04 0x02 0xc0 0xc1\n"
    632       "4 unwind   Illegal\n"
    633       "4 unwind   Raw Data: 0xc0\n"
    634       "4 unwind   Illegal\n"
    635       "4 unwind   Raw Data: 0xc1\n";
    636   ASSERT_EQ(expected, GetFakeLogPrint());
    637   ASSERT_EQ("", GetFakeLogBuf());
    638 
    639   ResetLogs();
    640   std::vector<uint8_t> ops{0x10, 0xff, 0x01, 0x82, 0x01};
    641   expected = "4 unwind Raw Data: 0x10 0xff 0x01 0x82 0x01";
    642   std::string op_string;
    643   for (uint8_t i = 5; i < 135; i++) {
    644     ops.push_back(0xa0 + (i - 5) % 96);
    645     op_string += "4 unwind   Illegal\n";
    646     op_string += android::base::StringPrintf("4 unwind   Raw Data: 0x%02x\n", ops.back());
    647     expected += android::base::StringPrintf(" 0x%02x", ops.back());
    648     if (((i + 1) % 10) == 0) {
    649       expected += "\n4 unwind Raw Data:";
    650     }
    651   }
    652   expected = "4 unwind DW_CFA_expression register(255) 130\n" + expected + "\n";
    653 
    654   this->memory_.SetMemory(0x200, ops);
    655   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x287));
    656 
    657   ASSERT_EQ(expected + op_string, GetFakeLogPrint());
    658   ASSERT_EQ("", GetFakeLogBuf());
    659 }
    660 
    661 TYPED_TEST_P(DwarfCfaLogTest, cfa_val_offset) {
    662   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x14, 0x45, 0x54});
    663 
    664   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x103));
    665 
    666   std::string expected =
    667       "4 unwind DW_CFA_val_offset register(69) 84\n"
    668       "4 unwind Raw Data: 0x14 0x45 0x54\n";
    669   ASSERT_EQ(expected, GetFakeLogPrint());
    670   ASSERT_EQ("", GetFakeLogBuf());
    671 
    672   ResetLogs();
    673   this->memory_.SetMemory(0x400, std::vector<uint8_t>{0x14, 0xa2, 0x02, 0xb4, 0x05});
    674 
    675   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x400, 0x405));
    676 
    677   expected =
    678       "4 unwind DW_CFA_val_offset register(290) 692\n"
    679       "4 unwind Raw Data: 0x14 0xa2 0x02 0xb4 0x05\n";
    680   ASSERT_EQ(expected, GetFakeLogPrint());
    681   ASSERT_EQ("", GetFakeLogBuf());
    682 }
    683 
    684 TYPED_TEST_P(DwarfCfaLogTest, cfa_val_offset_sf) {
    685   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x15, 0x56, 0x12});
    686 
    687   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x103));
    688 
    689   std::string expected =
    690       "4 unwind DW_CFA_val_offset_sf register(86) 18\n"
    691       "4 unwind Raw Data: 0x15 0x56 0x12\n";
    692   ASSERT_EQ(expected, GetFakeLogPrint());
    693   ASSERT_EQ("", GetFakeLogBuf());
    694 
    695   // Negative value.
    696   ResetLogs();
    697   this->memory_.SetMemory(0xa00, std::vector<uint8_t>{0x15, 0xff, 0x01, 0xc0, 0x7f});
    698 
    699   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0xa00, 0xa05));
    700 
    701   expected =
    702       "4 unwind DW_CFA_val_offset_sf register(255) -64\n"
    703       "4 unwind Raw Data: 0x15 0xff 0x01 0xc0 0x7f\n";
    704   ASSERT_EQ(expected, GetFakeLogPrint());
    705   ASSERT_EQ("", GetFakeLogBuf());
    706 }
    707 
    708 TYPED_TEST_P(DwarfCfaLogTest, cfa_val_expression) {
    709   this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x16, 0x05, 0x02, 0xb0, 0xb1});
    710 
    711   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x105));
    712 
    713   std::string expected =
    714       "4 unwind DW_CFA_val_expression register(5) 2\n"
    715       "4 unwind Raw Data: 0x16 0x05 0x02 0xb0 0xb1\n"
    716       "4 unwind   Illegal\n"
    717       "4 unwind   Raw Data: 0xb0\n"
    718       "4 unwind   Illegal\n"
    719       "4 unwind   Raw Data: 0xb1\n";
    720   ASSERT_EQ(expected, GetFakeLogPrint());
    721   ASSERT_EQ("", GetFakeLogBuf());
    722 
    723   ResetLogs();
    724   std::vector<uint8_t> ops{0x16, 0x83, 0x10, 0xa8, 0x01};
    725   expected = "4 unwind Raw Data: 0x16 0x83 0x10 0xa8 0x01";
    726   std::string op_string;
    727   for (uint8_t i = 0; i < 168; i++) {
    728     ops.push_back(0xa0 + (i % 96));
    729     op_string += "4 unwind   Illegal\n";
    730     op_string += android::base::StringPrintf("4 unwind   Raw Data: 0x%02x\n", ops.back());
    731     expected += android::base::StringPrintf(" 0x%02x", ops.back());
    732     if (((i + 6) % 10) == 0) {
    733       expected += "\n4 unwind Raw Data:";
    734     }
    735   }
    736   expected = "4 unwind DW_CFA_val_expression register(2051) 168\n" + expected + "\n";
    737 
    738   this->memory_.SetMemory(0xa00, ops);
    739 
    740   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0xa00, 0xaad));
    741 
    742   ASSERT_EQ(expected + op_string, GetFakeLogPrint());
    743   ASSERT_EQ("", GetFakeLogBuf());
    744 }
    745 
    746 TYPED_TEST_P(DwarfCfaLogTest, cfa_gnu_args_size) {
    747   this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x2e, 0x04});
    748 
    749   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2002));
    750 
    751   std::string expected =
    752       "4 unwind DW_CFA_GNU_args_size 4\n"
    753       "4 unwind Raw Data: 0x2e 0x04\n";
    754   ASSERT_EQ(expected, GetFakeLogPrint());
    755   ASSERT_EQ("", GetFakeLogBuf());
    756 
    757   ResetLogs();
    758   this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x2e, 0xa4, 0x80, 0x04});
    759 
    760   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x5000, 0x5004));
    761 
    762   expected =
    763       "4 unwind DW_CFA_GNU_args_size 65572\n"
    764       "4 unwind Raw Data: 0x2e 0xa4 0x80 0x04\n";
    765   ASSERT_EQ(expected, GetFakeLogPrint());
    766   ASSERT_EQ("", GetFakeLogBuf());
    767 }
    768 
    769 TYPED_TEST_P(DwarfCfaLogTest, cfa_gnu_negative_offset_extended) {
    770   this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x2f, 0x08, 0x10});
    771 
    772   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x500, 0x503));
    773 
    774   std::string expected =
    775       "4 unwind DW_CFA_GNU_negative_offset_extended register(8) 16\n"
    776       "4 unwind Raw Data: 0x2f 0x08 0x10\n";
    777   ASSERT_EQ(expected, GetFakeLogPrint());
    778   ASSERT_EQ("", GetFakeLogBuf());
    779 
    780   ResetLogs();
    781   this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x2f, 0x81, 0x02, 0xff, 0x01});
    782 
    783   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x1500, 0x1505));
    784 
    785   expected =
    786       "4 unwind DW_CFA_GNU_negative_offset_extended register(257) 255\n"
    787       "4 unwind Raw Data: 0x2f 0x81 0x02 0xff 0x01\n";
    788   ASSERT_EQ(expected, GetFakeLogPrint());
    789   ASSERT_EQ("", GetFakeLogBuf());
    790 }
    791 
    792 TYPED_TEST_P(DwarfCfaLogTest, cfa_register_override) {
    793   this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x09, 0x02, 0x01, 0x09, 0x02, 0x04});
    794 
    795   ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x300, 0x306));
    796 
    797   std::string expected =
    798       "4 unwind DW_CFA_register register(2) register(1)\n"
    799       "4 unwind Raw Data: 0x09 0x02 0x01\n"
    800       "4 unwind DW_CFA_register register(2) register(4)\n"
    801       "4 unwind Raw Data: 0x09 0x02 0x04\n";
    802   ASSERT_EQ(expected, GetFakeLogPrint());
    803   ASSERT_EQ("", GetFakeLogBuf());
    804 }
    805 
    806 REGISTER_TYPED_TEST_CASE_P(DwarfCfaLogTest, cfa_illegal, cfa_nop, cfa_offset, cfa_offset_extended,
    807                            cfa_offset_extended_sf, cfa_restore, cfa_restore_extended, cfa_set_loc,
    808                            cfa_advance_loc, cfa_advance_loc1, cfa_advance_loc2, cfa_advance_loc4,
    809                            cfa_undefined, cfa_same, cfa_register, cfa_state,
    810                            cfa_state_cfa_offset_restore, cfa_def_cfa, cfa_def_cfa_sf,
    811                            cfa_def_cfa_register, cfa_def_cfa_offset, cfa_def_cfa_offset_sf,
    812                            cfa_def_cfa_expression, cfa_expression, cfa_val_offset,
    813                            cfa_val_offset_sf, cfa_val_expression, cfa_gnu_args_size,
    814                            cfa_gnu_negative_offset_extended, cfa_register_override);
    815 
    816 typedef ::testing::Types<uint32_t, uint64_t> DwarfCfaLogTestTypes;
    817 INSTANTIATE_TYPED_TEST_CASE_P(, DwarfCfaLogTest, DwarfCfaLogTestTypes);
    818 
    819 }  // namespace unwindstack
    820