Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdint.h>
     18 
     19 #include <deque>
     20 #include <vector>
     21 
     22 #include <gtest/gtest.h>
     23 
     24 #include <unwindstack/Log.h>
     25 
     26 #include "ArmExidx.h"
     27 
     28 #include "LogFake.h"
     29 #include "MemoryFake.h"
     30 
     31 namespace unwindstack {
     32 
     33 class ArmExidxExtractTest : public ::testing::Test {
     34  protected:
     35   void SetUp() override {
     36     ResetLogs();
     37     elf_memory_.Clear();
     38     exidx_ = new ArmExidx(nullptr, &elf_memory_, nullptr);
     39     data_ = exidx_->data();
     40     data_->clear();
     41   }
     42 
     43   void TearDown() override {
     44     delete exidx_;
     45   }
     46 
     47   ArmExidx* exidx_ = nullptr;
     48   std::deque<uint8_t>* data_;
     49   MemoryFake elf_memory_;
     50 };
     51 
     52 TEST_F(ArmExidxExtractTest, bad_alignment) {
     53   ASSERT_FALSE(exidx_->ExtractEntryData(0x1001));
     54   ASSERT_EQ(ARM_STATUS_INVALID_ALIGNMENT, exidx_->status());
     55   ASSERT_TRUE(data_->empty());
     56 }
     57 
     58 TEST_F(ArmExidxExtractTest, cant_unwind) {
     59   elf_memory_.SetData32(0x1000, 0x7fff2340);
     60   elf_memory_.SetData32(0x1004, 1);
     61   ASSERT_FALSE(exidx_->ExtractEntryData(0x1000));
     62   ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status());
     63   ASSERT_TRUE(data_->empty());
     64 }
     65 
     66 TEST_F(ArmExidxExtractTest, compact) {
     67   elf_memory_.SetData32(0x4000, 0x7ffa3000);
     68   elf_memory_.SetData32(0x4004, 0x80a8b0b0);
     69   ASSERT_TRUE(exidx_->ExtractEntryData(0x4000));
     70   ASSERT_EQ(3U, data_->size());
     71   ASSERT_EQ(0xa8, data_->at(0));
     72   ASSERT_EQ(0xb0, data_->at(1));
     73   ASSERT_EQ(0xb0, data_->at(2));
     74 
     75   // Missing finish gets added.
     76   elf_memory_.Clear();
     77   elf_memory_.SetData32(0x534, 0x7ffa3000);
     78   elf_memory_.SetData32(0x538, 0x80a1a2a3);
     79   ASSERT_TRUE(exidx_->ExtractEntryData(0x534));
     80   ASSERT_EQ(4U, data_->size());
     81   ASSERT_EQ(0xa1, data_->at(0));
     82   ASSERT_EQ(0xa2, data_->at(1));
     83   ASSERT_EQ(0xa3, data_->at(2));
     84   ASSERT_EQ(0xb0, data_->at(3));
     85 }
     86 
     87 TEST_F(ArmExidxExtractTest, compact_non_zero_personality) {
     88   elf_memory_.SetData32(0x4000, 0x7ffa3000);
     89 
     90   uint32_t compact_value = 0x80a8b0b0;
     91   for (size_t i = 1; i < 16; i++) {
     92     elf_memory_.SetData32(0x4004, compact_value | (i << 24));
     93     ASSERT_FALSE(exidx_->ExtractEntryData(0x4000));
     94     ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status());
     95   }
     96 }
     97 
     98 TEST_F(ArmExidxExtractTest, second_read_compact_personality_1_2) {
     99   elf_memory_.SetData32(0x5000, 0x1234);
    100   elf_memory_.SetData32(0x5004, 0x00001230);
    101   elf_memory_.SetData32(0x6234, 0x8100f3b0);
    102   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    103   ASSERT_EQ(2U, data_->size());
    104   ASSERT_EQ(0xf3, data_->at(0));
    105   ASSERT_EQ(0xb0, data_->at(1));
    106 
    107   elf_memory_.Clear();
    108   elf_memory_.SetData32(0x5000, 0x1234);
    109   elf_memory_.SetData32(0x5004, 0x00001230);
    110   elf_memory_.SetData32(0x6234, 0x8200f3f4);
    111   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    112   ASSERT_EQ(3U, data_->size());
    113   ASSERT_EQ(0xf3, data_->at(0));
    114   ASSERT_EQ(0xf4, data_->at(1));
    115   ASSERT_EQ(0xb0, data_->at(2));
    116 
    117   elf_memory_.Clear();
    118   elf_memory_.SetData32(0x5000, 0x1234);
    119   elf_memory_.SetData32(0x5004, 0x00001230);
    120   elf_memory_.SetData32(0x6234, 0x8201f3f4);
    121   elf_memory_.SetData32(0x6238, 0x102030b0);
    122   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    123   ASSERT_EQ(6U, data_->size());
    124   ASSERT_EQ(0xf3, data_->at(0));
    125   ASSERT_EQ(0xf4, data_->at(1));
    126   ASSERT_EQ(0x10, data_->at(2));
    127   ASSERT_EQ(0x20, data_->at(3));
    128   ASSERT_EQ(0x30, data_->at(4));
    129   ASSERT_EQ(0xb0, data_->at(5));
    130 
    131   elf_memory_.Clear();
    132   elf_memory_.SetData32(0x5000, 0x1234);
    133   elf_memory_.SetData32(0x5004, 0x00001230);
    134   elf_memory_.SetData32(0x6234, 0x8103f3f4);
    135   elf_memory_.SetData32(0x6238, 0x10203040);
    136   elf_memory_.SetData32(0x623c, 0x50607080);
    137   elf_memory_.SetData32(0x6240, 0x90a0c0d0);
    138   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    139   ASSERT_EQ(15U, data_->size());
    140   ASSERT_EQ(0xf3, data_->at(0));
    141   ASSERT_EQ(0xf4, data_->at(1));
    142   ASSERT_EQ(0x10, data_->at(2));
    143   ASSERT_EQ(0x20, data_->at(3));
    144   ASSERT_EQ(0x30, data_->at(4));
    145   ASSERT_EQ(0x40, data_->at(5));
    146   ASSERT_EQ(0x50, data_->at(6));
    147   ASSERT_EQ(0x60, data_->at(7));
    148   ASSERT_EQ(0x70, data_->at(8));
    149   ASSERT_EQ(0x80, data_->at(9));
    150   ASSERT_EQ(0x90, data_->at(10));
    151   ASSERT_EQ(0xa0, data_->at(11));
    152   ASSERT_EQ(0xc0, data_->at(12));
    153   ASSERT_EQ(0xd0, data_->at(13));
    154   ASSERT_EQ(0xb0, data_->at(14));
    155 }
    156 
    157 TEST_F(ArmExidxExtractTest, second_read_compact_personality_illegal) {
    158   elf_memory_.SetData32(0x5000, 0x7ffa1e48);
    159   elf_memory_.SetData32(0x5004, 0x1230);
    160   elf_memory_.SetData32(0x6234, 0x832132b0);
    161   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    162   ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status());
    163 
    164   elf_memory_.Clear();
    165   elf_memory_.SetData32(0x5000, 0x7ffa1e48);
    166   elf_memory_.SetData32(0x5004, 0x1230);
    167   elf_memory_.SetData32(0x6234, 0x842132b0);
    168   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    169   ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status());
    170 }
    171 
    172 TEST_F(ArmExidxExtractTest, second_read_offset_is_negative) {
    173   elf_memory_.SetData32(0x5000, 0x7ffa1e48);
    174   elf_memory_.SetData32(0x5004, 0x7fffb1e0);
    175   elf_memory_.SetData32(0x1e4, 0x842132b0);
    176   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    177   ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status());
    178 }
    179 
    180 TEST_F(ArmExidxExtractTest, second_read_not_compact) {
    181   elf_memory_.SetData32(0x5000, 0x1234);
    182   elf_memory_.SetData32(0x5004, 0x00001230);
    183   elf_memory_.SetData32(0x6234, 0x1);
    184   elf_memory_.SetData32(0x6238, 0x001122b0);
    185   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    186   ASSERT_EQ(3U, data_->size());
    187   ASSERT_EQ(0x11, data_->at(0));
    188   ASSERT_EQ(0x22, data_->at(1));
    189   ASSERT_EQ(0xb0, data_->at(2));
    190 
    191   elf_memory_.Clear();
    192   elf_memory_.SetData32(0x5000, 0x1234);
    193   elf_memory_.SetData32(0x5004, 0x00001230);
    194   elf_memory_.SetData32(0x6234, 0x2);
    195   elf_memory_.SetData32(0x6238, 0x00112233);
    196   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    197   ASSERT_EQ(4U, data_->size());
    198   ASSERT_EQ(0x11, data_->at(0));
    199   ASSERT_EQ(0x22, data_->at(1));
    200   ASSERT_EQ(0x33, data_->at(2));
    201   ASSERT_EQ(0xb0, data_->at(3));
    202 
    203   elf_memory_.Clear();
    204   elf_memory_.SetData32(0x5000, 0x1234);
    205   elf_memory_.SetData32(0x5004, 0x00001230);
    206   elf_memory_.SetData32(0x6234, 0x3);
    207   elf_memory_.SetData32(0x6238, 0x01112233);
    208   elf_memory_.SetData32(0x623c, 0x445566b0);
    209   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    210   ASSERT_EQ(7U, data_->size());
    211   ASSERT_EQ(0x11, data_->at(0));
    212   ASSERT_EQ(0x22, data_->at(1));
    213   ASSERT_EQ(0x33, data_->at(2));
    214   ASSERT_EQ(0x44, data_->at(3));
    215   ASSERT_EQ(0x55, data_->at(4));
    216   ASSERT_EQ(0x66, data_->at(5));
    217   ASSERT_EQ(0xb0, data_->at(6));
    218 
    219   elf_memory_.Clear();
    220   elf_memory_.SetData32(0x5000, 0x1234);
    221   elf_memory_.SetData32(0x5004, 0x00001230);
    222   elf_memory_.SetData32(0x6234, 0x3);
    223   elf_memory_.SetData32(0x6238, 0x05112233);
    224   elf_memory_.SetData32(0x623c, 0x01020304);
    225   elf_memory_.SetData32(0x6240, 0x05060708);
    226   elf_memory_.SetData32(0x6244, 0x090a0b0c);
    227   elf_memory_.SetData32(0x6248, 0x0d0e0f10);
    228   elf_memory_.SetData32(0x624c, 0x11121314);
    229   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    230   ASSERT_EQ(24U, data_->size());
    231   ASSERT_EQ(0x11, data_->at(0));
    232   ASSERT_EQ(0x22, data_->at(1));
    233   ASSERT_EQ(0x33, data_->at(2));
    234   ASSERT_EQ(0x01, data_->at(3));
    235   ASSERT_EQ(0x02, data_->at(4));
    236   ASSERT_EQ(0x03, data_->at(5));
    237   ASSERT_EQ(0x04, data_->at(6));
    238   ASSERT_EQ(0x05, data_->at(7));
    239   ASSERT_EQ(0x06, data_->at(8));
    240   ASSERT_EQ(0x07, data_->at(9));
    241   ASSERT_EQ(0x08, data_->at(10));
    242   ASSERT_EQ(0x09, data_->at(11));
    243   ASSERT_EQ(0x0a, data_->at(12));
    244   ASSERT_EQ(0x0b, data_->at(13));
    245   ASSERT_EQ(0x0c, data_->at(14));
    246   ASSERT_EQ(0x0d, data_->at(15));
    247   ASSERT_EQ(0x0e, data_->at(16));
    248   ASSERT_EQ(0x0f, data_->at(17));
    249   ASSERT_EQ(0x10, data_->at(18));
    250   ASSERT_EQ(0x11, data_->at(19));
    251   ASSERT_EQ(0x12, data_->at(20));
    252   ASSERT_EQ(0x13, data_->at(21));
    253   ASSERT_EQ(0x14, data_->at(22));
    254   ASSERT_EQ(0xb0, data_->at(23));
    255 }
    256 
    257 TEST_F(ArmExidxExtractTest, read_failures) {
    258   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    259   ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
    260   EXPECT_EQ(0x5004U, exidx_->status_address());
    261 
    262   elf_memory_.SetData32(0x5000, 0x100);
    263   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    264   ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
    265   EXPECT_EQ(0x5004U, exidx_->status_address());
    266 
    267   elf_memory_.SetData32(0x5004, 0x100);
    268   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    269   ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
    270   EXPECT_EQ(0x5104U, exidx_->status_address());
    271 
    272   elf_memory_.SetData32(0x5104, 0x1);
    273   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    274   ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
    275   EXPECT_EQ(0x5108U, exidx_->status_address());
    276 
    277   elf_memory_.SetData32(0x5108, 0x01010203);
    278   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    279   ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
    280   EXPECT_EQ(0x510cU, exidx_->status_address());
    281 }
    282 
    283 TEST_F(ArmExidxExtractTest, malformed) {
    284   elf_memory_.SetData32(0x5000, 0x100);
    285   elf_memory_.SetData32(0x5004, 0x100);
    286   elf_memory_.SetData32(0x5104, 0x1);
    287   elf_memory_.SetData32(0x5108, 0x06010203);
    288   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    289   ASSERT_EQ(ARM_STATUS_MALFORMED, exidx_->status());
    290 
    291   elf_memory_.Clear();
    292   elf_memory_.SetData32(0x5000, 0x100);
    293   elf_memory_.SetData32(0x5004, 0x100);
    294   elf_memory_.SetData32(0x5104, 0x1);
    295   elf_memory_.SetData32(0x5108, 0x81060203);
    296   ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
    297   ASSERT_EQ(ARM_STATUS_MALFORMED, exidx_->status());
    298 }
    299 
    300 TEST_F(ArmExidxExtractTest, cant_unwind_log) {
    301   elf_memory_.SetData32(0x1000, 0x7fff2340);
    302   elf_memory_.SetData32(0x1004, 1);
    303 
    304   exidx_->set_log(true);
    305   exidx_->set_log_indent(0);
    306   exidx_->set_log_skip_execution(false);
    307 
    308   ASSERT_FALSE(exidx_->ExtractEntryData(0x1000));
    309   ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status());
    310 
    311   ASSERT_EQ("4 unwind Raw Data: 0x00 0x00 0x00 0x01\n"
    312             "4 unwind [cantunwind]\n", GetFakeLogPrint());
    313 }
    314 
    315 TEST_F(ArmExidxExtractTest, raw_data_compact) {
    316   elf_memory_.SetData32(0x4000, 0x7ffa3000);
    317   elf_memory_.SetData32(0x4004, 0x80a8b0b0);
    318 
    319   exidx_->set_log(true);
    320   exidx_->set_log_indent(0);
    321   exidx_->set_log_skip_execution(false);
    322 
    323   ASSERT_TRUE(exidx_->ExtractEntryData(0x4000));
    324   ASSERT_EQ("4 unwind Raw Data: 0xa8 0xb0 0xb0\n", GetFakeLogPrint());
    325 }
    326 
    327 TEST_F(ArmExidxExtractTest, raw_data_non_compact) {
    328   elf_memory_.SetData32(0x5000, 0x1234);
    329   elf_memory_.SetData32(0x5004, 0x00001230);
    330   elf_memory_.SetData32(0x6234, 0x2);
    331   elf_memory_.SetData32(0x6238, 0x00112233);
    332 
    333   exidx_->set_log(true);
    334   exidx_->set_log_indent(0);
    335   exidx_->set_log_skip_execution(false);
    336 
    337   ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
    338   ASSERT_EQ("4 unwind Raw Data: 0x11 0x22 0x33 0xb0\n", GetFakeLogPrint());
    339 }
    340 
    341 }  // namespace unwindstack
    342