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 <elf.h>
     18 #include <fcntl.h>
     19 #include <sys/stat.h>
     20 #include <sys/types.h>
     21 #include <unistd.h>
     22 
     23 #include <gtest/gtest.h>
     24 
     25 #include <unwindstack/Elf.h>
     26 #include <unwindstack/MapInfo.h>
     27 
     28 #include "ElfTestUtils.h"
     29 #include "LogFake.h"
     30 #include "MemoryFake.h"
     31 
     32 #if !defined(PT_ARM_EXIDX)
     33 #define PT_ARM_EXIDX 0x70000001
     34 #endif
     35 
     36 namespace unwindstack {
     37 
     38 class ElfTest : public ::testing::Test {
     39  protected:
     40   void SetUp() override {
     41     memory_ = new MemoryFake;
     42   }
     43 
     44   void InitElf32(uint32_t machine_type) {
     45     Elf32_Ehdr ehdr;
     46     TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, machine_type);
     47 
     48     ehdr.e_phoff = 0x100;
     49     ehdr.e_ehsize = sizeof(ehdr);
     50     ehdr.e_phentsize = sizeof(Elf32_Phdr);
     51     ehdr.e_phnum = 1;
     52     ehdr.e_shentsize = sizeof(Elf32_Shdr);
     53     if (machine_type == EM_ARM) {
     54       ehdr.e_flags = 0x5000200;
     55       ehdr.e_phnum = 2;
     56     }
     57     memory_->SetMemory(0, &ehdr, sizeof(ehdr));
     58 
     59     Elf32_Phdr phdr;
     60     memset(&phdr, 0, sizeof(phdr));
     61     phdr.p_type = PT_LOAD;
     62     phdr.p_filesz = 0x10000;
     63     phdr.p_memsz = 0x10000;
     64     phdr.p_flags = PF_R | PF_X;
     65     phdr.p_align = 0x1000;
     66     memory_->SetMemory(0x100, &phdr, sizeof(phdr));
     67 
     68     if (machine_type == EM_ARM) {
     69       memset(&phdr, 0, sizeof(phdr));
     70       phdr.p_type = PT_ARM_EXIDX;
     71       phdr.p_offset = 0x30000;
     72       phdr.p_vaddr = 0x30000;
     73       phdr.p_paddr = 0x30000;
     74       phdr.p_filesz = 16;
     75       phdr.p_memsz = 16;
     76       phdr.p_flags = PF_R;
     77       phdr.p_align = 0x4;
     78       memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
     79     }
     80   }
     81 
     82   void InitElf64(uint32_t machine_type) {
     83     Elf64_Ehdr ehdr;
     84     TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, machine_type);
     85 
     86     ehdr.e_phoff = 0x100;
     87     ehdr.e_flags = 0x5000200;
     88     ehdr.e_ehsize = sizeof(ehdr);
     89     ehdr.e_phentsize = sizeof(Elf64_Phdr);
     90     ehdr.e_phnum = 1;
     91     ehdr.e_shentsize = sizeof(Elf64_Shdr);
     92     memory_->SetMemory(0, &ehdr, sizeof(ehdr));
     93 
     94     Elf64_Phdr phdr;
     95     memset(&phdr, 0, sizeof(phdr));
     96     phdr.p_type = PT_LOAD;
     97     phdr.p_filesz = 0x10000;
     98     phdr.p_memsz = 0x10000;
     99     phdr.p_flags = PF_R | PF_X;
    100     phdr.p_align = 0x1000;
    101     memory_->SetMemory(0x100, &phdr, sizeof(phdr));
    102   }
    103 
    104   MemoryFake* memory_;
    105 };
    106 
    107 TEST_F(ElfTest, invalid_memory) {
    108   Elf elf(memory_);
    109 
    110   ASSERT_FALSE(elf.Init());
    111   ASSERT_FALSE(elf.valid());
    112 }
    113 
    114 TEST_F(ElfTest, elf_invalid) {
    115   Elf elf(memory_);
    116 
    117   InitElf32(EM_386);
    118 
    119   // Corrupt the ELF signature.
    120   memory_->SetData32(0, 0x7f000000);
    121 
    122   ASSERT_FALSE(elf.Init());
    123   ASSERT_FALSE(elf.valid());
    124   ASSERT_TRUE(elf.interface() == nullptr);
    125 
    126   std::string name;
    127   ASSERT_FALSE(elf.GetSoname(&name));
    128 
    129   uint64_t func_offset;
    130   ASSERT_FALSE(elf.GetFunctionName(0, &name, &func_offset));
    131 
    132   ASSERT_FALSE(elf.Step(0, nullptr, nullptr));
    133 }
    134 
    135 TEST_F(ElfTest, elf32_invalid_machine) {
    136   Elf elf(memory_);
    137 
    138   InitElf32(EM_PPC);
    139 
    140   ResetLogs();
    141   ASSERT_FALSE(elf.Init());
    142 
    143   ASSERT_EQ("", GetFakeLogBuf());
    144   ASSERT_EQ("4 unwind 32 bit elf that is neither arm nor x86: e_machine = 20\n\n",
    145             GetFakeLogPrint());
    146 }
    147 
    148 TEST_F(ElfTest, elf64_invalid_machine) {
    149   Elf elf(memory_);
    150 
    151   InitElf64(EM_PPC64);
    152 
    153   ResetLogs();
    154   ASSERT_FALSE(elf.Init());
    155 
    156   ASSERT_EQ("", GetFakeLogBuf());
    157   ASSERT_EQ("4 unwind 64 bit elf that is neither aarch64 nor x86_64: e_machine = 21\n\n",
    158             GetFakeLogPrint());
    159 }
    160 
    161 TEST_F(ElfTest, elf_arm) {
    162   Elf elf(memory_);
    163 
    164   InitElf32(EM_ARM);
    165 
    166   ASSERT_TRUE(elf.Init());
    167   ASSERT_TRUE(elf.valid());
    168   ASSERT_EQ(static_cast<uint32_t>(EM_ARM), elf.machine_type());
    169   ASSERT_EQ(ELFCLASS32, elf.class_type());
    170   ASSERT_TRUE(elf.interface() != nullptr);
    171 }
    172 
    173 TEST_F(ElfTest, elf_x86) {
    174   Elf elf(memory_);
    175 
    176   InitElf32(EM_386);
    177 
    178   ASSERT_TRUE(elf.Init());
    179   ASSERT_TRUE(elf.valid());
    180   ASSERT_EQ(static_cast<uint32_t>(EM_386), elf.machine_type());
    181   ASSERT_EQ(ELFCLASS32, elf.class_type());
    182   ASSERT_TRUE(elf.interface() != nullptr);
    183 }
    184 
    185 TEST_F(ElfTest, elf_arm64) {
    186   Elf elf(memory_);
    187 
    188   InitElf64(EM_AARCH64);
    189 
    190   ASSERT_TRUE(elf.Init());
    191   ASSERT_TRUE(elf.valid());
    192   ASSERT_EQ(static_cast<uint32_t>(EM_AARCH64), elf.machine_type());
    193   ASSERT_EQ(ELFCLASS64, elf.class_type());
    194   ASSERT_TRUE(elf.interface() != nullptr);
    195 }
    196 
    197 TEST_F(ElfTest, elf_x86_64) {
    198   Elf elf(memory_);
    199 
    200   InitElf64(EM_X86_64);
    201 
    202   ASSERT_TRUE(elf.Init());
    203   ASSERT_TRUE(elf.valid());
    204   ASSERT_EQ(static_cast<uint32_t>(EM_X86_64), elf.machine_type());
    205   ASSERT_EQ(ELFCLASS64, elf.class_type());
    206   ASSERT_TRUE(elf.interface() != nullptr);
    207 }
    208 
    209 TEST_F(ElfTest, gnu_debugdata_init_fail32) {
    210   TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, false,
    211                                                [&](uint64_t offset, const void* ptr, size_t size) {
    212                                                  memory_->SetMemory(offset, ptr, size);
    213                                                });
    214 
    215   Elf elf(memory_);
    216   ASSERT_TRUE(elf.Init());
    217   ASSERT_TRUE(elf.interface() != nullptr);
    218   ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
    219   EXPECT_EQ(0x1acU, elf.interface()->gnu_debugdata_offset());
    220   EXPECT_EQ(0x100U, elf.interface()->gnu_debugdata_size());
    221 }
    222 
    223 TEST_F(ElfTest, gnu_debugdata_init_fail64) {
    224   TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, false,
    225                                                [&](uint64_t offset, const void* ptr, size_t size) {
    226                                                  memory_->SetMemory(offset, ptr, size);
    227                                                });
    228 
    229   Elf elf(memory_);
    230   ASSERT_TRUE(elf.Init());
    231   ASSERT_TRUE(elf.interface() != nullptr);
    232   ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
    233   EXPECT_EQ(0x200U, elf.interface()->gnu_debugdata_offset());
    234   EXPECT_EQ(0x100U, elf.interface()->gnu_debugdata_size());
    235 }
    236 
    237 TEST_F(ElfTest, gnu_debugdata_init32) {
    238   TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, true,
    239                                                [&](uint64_t offset, const void* ptr, size_t size) {
    240                                                  memory_->SetMemory(offset, ptr, size);
    241                                                });
    242 
    243   Elf elf(memory_);
    244   ASSERT_TRUE(elf.Init());
    245   ASSERT_TRUE(elf.interface() != nullptr);
    246   ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
    247   EXPECT_EQ(0x1acU, elf.interface()->gnu_debugdata_offset());
    248   EXPECT_EQ(0x8cU, elf.interface()->gnu_debugdata_size());
    249 
    250   elf.InitGnuDebugdata();
    251   ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
    252 }
    253 
    254 TEST_F(ElfTest, gnu_debugdata_init64) {
    255   TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, true,
    256                                                [&](uint64_t offset, const void* ptr, size_t size) {
    257                                                  memory_->SetMemory(offset, ptr, size);
    258                                                });
    259 
    260   Elf elf(memory_);
    261   ASSERT_TRUE(elf.Init());
    262   ASSERT_TRUE(elf.interface() != nullptr);
    263   ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
    264   EXPECT_EQ(0x200U, elf.interface()->gnu_debugdata_offset());
    265   EXPECT_EQ(0x90U, elf.interface()->gnu_debugdata_size());
    266 
    267   elf.InitGnuDebugdata();
    268   ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
    269 }
    270 
    271 class MockElf : public Elf {
    272  public:
    273   MockElf(Memory* memory) : Elf(memory) {}
    274   virtual ~MockElf() = default;
    275 
    276   void set_valid(bool valid) { valid_ = valid; }
    277   void set_elf_interface(ElfInterface* interface) { interface_.reset(interface); }
    278 };
    279 
    280 TEST_F(ElfTest, rel_pc) {
    281   MockElf elf(memory_);
    282 
    283   ElfInterface* interface = new ElfInterface32(memory_);
    284   elf.set_elf_interface(interface);
    285 
    286   elf.set_valid(true);
    287   interface->set_load_bias(0);
    288   MapInfo map_info{.start = 0x1000, .end = 0x2000};
    289 
    290   ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, &map_info));
    291 
    292   interface->set_load_bias(0x3000);
    293   ASSERT_EQ(0x3101U, elf.GetRelPc(0x1101, &map_info));
    294 
    295   elf.set_valid(false);
    296   ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, &map_info));
    297 }
    298 
    299 }  // namespace unwindstack
    300