Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2018 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 <string.h>
     19 
     20 #include <memory>
     21 #include <vector>
     22 
     23 #include <gtest/gtest.h>
     24 
     25 #include <unwindstack/Elf.h>
     26 #include <unwindstack/JitDebug.h>
     27 #include <unwindstack/MapInfo.h>
     28 #include <unwindstack/Maps.h>
     29 #include <unwindstack/Memory.h>
     30 
     31 #include "ElfFake.h"
     32 #include "MemoryFake.h"
     33 
     34 namespace unwindstack {
     35 
     36 class JitDebugTest : public ::testing::Test {
     37  protected:
     38   void SetUp() override {
     39     memory_ = new MemoryFake;
     40     process_memory_.reset(memory_);
     41 
     42     jit_debug_.reset(new JitDebug(process_memory_));
     43     jit_debug_->SetArch(ARCH_ARM);
     44 
     45     maps_.reset(
     46         new BufferMaps("1000-4000 ---s 00000000 00:00 0\n"
     47                        "4000-6000 r--s 00000000 00:00 0\n"
     48                        "6000-8000 -w-s 00000000 00:00 0\n"
     49                        "a000-c000 --xp 00000000 00:00 0\n"
     50                        "c000-f000 rwxp 00000000 00:00 0\n"
     51                        "f000-11000 r-xp 00000000 00:00 0\n"
     52                        "12000-14000 r-xp 00000000 00:00 0\n"
     53                        "100000-110000 rw-p 0000000 00:00 0\n"
     54                        "200000-210000 rw-p 0000000 00:00 0\n"));
     55     ASSERT_TRUE(maps_->Parse());
     56 
     57     MapInfo* map_info = maps_->Get(3);
     58     ASSERT_TRUE(map_info != nullptr);
     59     MemoryFake* memory = new MemoryFake;
     60     ElfFake* elf = new ElfFake(memory);
     61     elf->FakeSetValid(true);
     62     ElfInterfaceFake* interface = new ElfInterfaceFake(memory);
     63     elf->FakeSetInterface(interface);
     64     interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800);
     65     map_info->elf.reset(elf);
     66 
     67     map_info = maps_->Get(5);
     68     ASSERT_TRUE(map_info != nullptr);
     69     memory = new MemoryFake;
     70     elf = new ElfFake(memory);
     71     elf->FakeSetValid(true);
     72     interface = new ElfInterfaceFake(memory);
     73     elf->FakeSetInterface(interface);
     74     interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800);
     75     map_info->elf.reset(elf);
     76 
     77     map_info = maps_->Get(6);
     78     ASSERT_TRUE(map_info != nullptr);
     79     memory = new MemoryFake;
     80     elf = new ElfFake(memory);
     81     elf->FakeSetValid(true);
     82     interface = new ElfInterfaceFake(memory);
     83     elf->FakeSetInterface(interface);
     84     interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800);
     85     map_info->elf.reset(elf);
     86   }
     87 
     88   template <typename EhdrType, typename ShdrType>
     89   void CreateElf(uint64_t offset, uint8_t class_type, uint8_t machine_type, uint32_t pc,
     90                  uint32_t size) {
     91     EhdrType ehdr;
     92     memset(&ehdr, 0, sizeof(ehdr));
     93     uint64_t sh_offset = sizeof(ehdr);
     94     memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
     95     ehdr.e_ident[EI_CLASS] = class_type;
     96     ehdr.e_machine = machine_type;
     97     ehdr.e_shstrndx = 1;
     98     ehdr.e_shoff = sh_offset;
     99     ehdr.e_shentsize = sizeof(ShdrType);
    100     ehdr.e_shnum = 3;
    101     memory_->SetMemory(offset, &ehdr, sizeof(ehdr));
    102 
    103     ShdrType shdr;
    104     memset(&shdr, 0, sizeof(shdr));
    105     shdr.sh_type = SHT_NULL;
    106     memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
    107 
    108     sh_offset += sizeof(shdr);
    109     memset(&shdr, 0, sizeof(shdr));
    110     shdr.sh_type = SHT_STRTAB;
    111     shdr.sh_name = 1;
    112     shdr.sh_offset = 0x500;
    113     shdr.sh_size = 0x100;
    114     memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
    115     memory_->SetMemory(offset + 0x500, ".debug_frame");
    116 
    117     sh_offset += sizeof(shdr);
    118     memset(&shdr, 0, sizeof(shdr));
    119     shdr.sh_type = SHT_PROGBITS;
    120     shdr.sh_name = 0;
    121     shdr.sh_addr = 0x600;
    122     shdr.sh_offset = 0x600;
    123     shdr.sh_size = 0x200;
    124     memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
    125 
    126     // Now add a single cie/fde.
    127     uint64_t dwarf_offset = offset + 0x600;
    128     if (class_type == ELFCLASS32) {
    129       // CIE 32 information.
    130       memory_->SetData32(dwarf_offset, 0xfc);
    131       memory_->SetData32(dwarf_offset + 0x4, 0xffffffff);
    132       memory_->SetData8(dwarf_offset + 0x8, 1);
    133       memory_->SetData8(dwarf_offset + 0x9, '\0');
    134       memory_->SetData8(dwarf_offset + 0xa, 0x4);
    135       memory_->SetData8(dwarf_offset + 0xb, 0x4);
    136       memory_->SetData8(dwarf_offset + 0xc, 0x1);
    137 
    138       // FDE 32 information.
    139       memory_->SetData32(dwarf_offset + 0x100, 0xfc);
    140       memory_->SetData32(dwarf_offset + 0x104, 0);
    141       memory_->SetData32(dwarf_offset + 0x108, pc);
    142       memory_->SetData32(dwarf_offset + 0x10c, size);
    143     } else {
    144       // CIE 64 information.
    145       memory_->SetData32(dwarf_offset, 0xffffffff);
    146       memory_->SetData64(dwarf_offset + 4, 0xf4);
    147       memory_->SetData64(dwarf_offset + 0xc, 0xffffffffffffffffULL);
    148       memory_->SetData8(dwarf_offset + 0x14, 1);
    149       memory_->SetData8(dwarf_offset + 0x15, '\0');
    150       memory_->SetData8(dwarf_offset + 0x16, 0x4);
    151       memory_->SetData8(dwarf_offset + 0x17, 0x4);
    152       memory_->SetData8(dwarf_offset + 0x18, 0x1);
    153 
    154       // FDE 64 information.
    155       memory_->SetData32(dwarf_offset + 0x100, 0xffffffff);
    156       memory_->SetData64(dwarf_offset + 0x104, 0xf4);
    157       memory_->SetData64(dwarf_offset + 0x10c, 0);
    158       memory_->SetData64(dwarf_offset + 0x114, pc);
    159       memory_->SetData64(dwarf_offset + 0x11c, size);
    160     }
    161   }
    162 
    163   void WriteDescriptor32(uint64_t addr, uint32_t entry);
    164   void WriteDescriptor64(uint64_t addr, uint64_t entry);
    165   void WriteEntry32Pack(uint64_t addr, uint32_t prev, uint32_t next, uint32_t elf_addr,
    166                         uint64_t elf_size);
    167   void WriteEntry32Pad(uint64_t addr, uint32_t prev, uint32_t next, uint32_t elf_addr,
    168                        uint64_t elf_size);
    169   void WriteEntry64(uint64_t addr, uint64_t prev, uint64_t next, uint64_t elf_addr,
    170                     uint64_t elf_size);
    171 
    172   std::shared_ptr<Memory> process_memory_;
    173   MemoryFake* memory_;
    174   std::unique_ptr<JitDebug> jit_debug_;
    175   std::unique_ptr<BufferMaps> maps_;
    176 };
    177 
    178 void JitDebugTest::WriteDescriptor32(uint64_t addr, uint32_t entry) {
    179   // Format of the 32 bit JITDescriptor structure:
    180   //   uint32_t version
    181   memory_->SetData32(addr, 1);
    182   //   uint32_t action_flag
    183   memory_->SetData32(addr + 4, 0);
    184   //   uint32_t relevant_entry
    185   memory_->SetData32(addr + 8, 0);
    186   //   uint32_t first_entry
    187   memory_->SetData32(addr + 12, entry);
    188 }
    189 
    190 void JitDebugTest::WriteDescriptor64(uint64_t addr, uint64_t entry) {
    191   // Format of the 64 bit JITDescriptor structure:
    192   //   uint32_t version
    193   memory_->SetData32(addr, 1);
    194   //   uint32_t action_flag
    195   memory_->SetData32(addr + 4, 0);
    196   //   uint64_t relevant_entry
    197   memory_->SetData64(addr + 8, 0);
    198   //   uint64_t first_entry
    199   memory_->SetData64(addr + 16, entry);
    200 }
    201 
    202 void JitDebugTest::WriteEntry32Pack(uint64_t addr, uint32_t prev, uint32_t next, uint32_t elf_addr,
    203                                     uint64_t elf_size) {
    204   // Format of the 32 bit JITCodeEntry structure:
    205   //   uint32_t next
    206   memory_->SetData32(addr, next);
    207   //   uint32_t prev
    208   memory_->SetData32(addr + 4, prev);
    209   //   uint32_t symfile_addr
    210   memory_->SetData32(addr + 8, elf_addr);
    211   //   uint64_t symfile_size
    212   memory_->SetData64(addr + 12, elf_size);
    213 }
    214 
    215 void JitDebugTest::WriteEntry32Pad(uint64_t addr, uint32_t prev, uint32_t next, uint32_t elf_addr,
    216                                    uint64_t elf_size) {
    217   // Format of the 32 bit JITCodeEntry structure:
    218   //   uint32_t next
    219   memory_->SetData32(addr, next);
    220   //   uint32_t prev
    221   memory_->SetData32(addr + 4, prev);
    222   //   uint32_t symfile_addr
    223   memory_->SetData32(addr + 8, elf_addr);
    224   //   uint32_t pad
    225   memory_->SetData32(addr + 12, 0);
    226   //   uint64_t symfile_size
    227   memory_->SetData64(addr + 16, elf_size);
    228 }
    229 
    230 void JitDebugTest::WriteEntry64(uint64_t addr, uint64_t prev, uint64_t next, uint64_t elf_addr,
    231                                 uint64_t elf_size) {
    232   // Format of the 64 bit JITCodeEntry structure:
    233   //   uint64_t next
    234   memory_->SetData64(addr, next);
    235   //   uint64_t prev
    236   memory_->SetData64(addr + 8, prev);
    237   //   uint64_t symfile_addr
    238   memory_->SetData64(addr + 16, elf_addr);
    239   //   uint64_t symfile_size
    240   memory_->SetData64(addr + 24, elf_size);
    241 }
    242 
    243 TEST_F(JitDebugTest, get_elf_invalid) {
    244   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    245   ASSERT_TRUE(elf == nullptr);
    246 }
    247 
    248 TEST_F(JitDebugTest, get_elf_no_global_variable) {
    249   maps_.reset(new BufferMaps(""));
    250   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    251   ASSERT_TRUE(elf == nullptr);
    252 }
    253 
    254 TEST_F(JitDebugTest, get_elf_no_valid_descriptor_in_memory) {
    255   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    256 
    257   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    258   ASSERT_TRUE(elf == nullptr);
    259 }
    260 
    261 TEST_F(JitDebugTest, get_elf_no_valid_code_entry) {
    262   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    263 
    264   WriteDescriptor32(0xf800, 0x200000);
    265 
    266   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    267   ASSERT_TRUE(elf == nullptr);
    268 }
    269 
    270 TEST_F(JitDebugTest, get_elf_invalid_descriptor_first_entry) {
    271   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    272 
    273   WriteDescriptor32(0xf800, 0);
    274 
    275   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    276   ASSERT_TRUE(elf == nullptr);
    277 }
    278 
    279 TEST_F(JitDebugTest, get_elf_invalid_descriptor_version) {
    280   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    281 
    282   WriteDescriptor32(0xf800, 0x20000);
    283   // Set the version to an invalid value.
    284   memory_->SetData32(0xf800, 2);
    285 
    286   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    287   ASSERT_TRUE(elf == nullptr);
    288 }
    289 
    290 TEST_F(JitDebugTest, get_elf_32) {
    291   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    292 
    293   WriteDescriptor32(0xf800, 0x200000);
    294   WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000);
    295 
    296   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    297   ASSERT_TRUE(elf != nullptr);
    298 
    299   // Clear the memory and verify all of the data is cached.
    300   memory_->Clear();
    301   Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
    302   ASSERT_TRUE(elf2 != nullptr);
    303   EXPECT_EQ(elf, elf2);
    304 }
    305 
    306 TEST_F(JitDebugTest, get_multiple_jit_debug_descriptors_valid) {
    307   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    308   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x5000, ELFCLASS32, EM_ARM, 0x2000, 0x300);
    309 
    310   WriteDescriptor32(0xf800, 0x200000);
    311   WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000);
    312   WriteDescriptor32(0x12800, 0x201000);
    313   WriteEntry32Pad(0x201000, 0, 0, 0x5000, 0x1000);
    314 
    315   ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr);
    316   ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) == nullptr);
    317 
    318   // Now clear the descriptor entry for the first one.
    319   WriteDescriptor32(0xf800, 0);
    320   jit_debug_.reset(new JitDebug(process_memory_));
    321   jit_debug_->SetArch(ARCH_ARM);
    322 
    323   ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr);
    324   ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) != nullptr);
    325 }
    326 
    327 TEST_F(JitDebugTest, get_elf_x86) {
    328   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    329 
    330   WriteDescriptor32(0xf800, 0x200000);
    331   WriteEntry32Pack(0x200000, 0, 0, 0x4000, 0x1000);
    332 
    333   jit_debug_->SetArch(ARCH_X86);
    334   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    335   ASSERT_TRUE(elf != nullptr);
    336 
    337   // Clear the memory and verify all of the data is cached.
    338   memory_->Clear();
    339   Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
    340   ASSERT_TRUE(elf2 != nullptr);
    341   EXPECT_EQ(elf, elf2);
    342 }
    343 
    344 TEST_F(JitDebugTest, get_elf_64) {
    345   CreateElf<Elf64_Ehdr, Elf64_Shdr>(0x4000, ELFCLASS64, EM_AARCH64, 0x1500, 0x200);
    346 
    347   WriteDescriptor64(0xf800, 0x200000);
    348   WriteEntry64(0x200000, 0, 0, 0x4000, 0x1000);
    349 
    350   jit_debug_->SetArch(ARCH_ARM64);
    351   Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
    352   ASSERT_TRUE(elf != nullptr);
    353 
    354   // Clear the memory and verify all of the data is cached.
    355   memory_->Clear();
    356   Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
    357   ASSERT_TRUE(elf2 != nullptr);
    358   EXPECT_EQ(elf, elf2);
    359 }
    360 
    361 TEST_F(JitDebugTest, get_elf_multiple_entries) {
    362   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    363   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x5000, ELFCLASS32, EM_ARM, 0x2300, 0x400);
    364 
    365   WriteDescriptor32(0xf800, 0x200000);
    366   WriteEntry32Pad(0x200000, 0, 0x200100, 0x4000, 0x1000);
    367   WriteEntry32Pad(0x200100, 0x200100, 0, 0x5000, 0x1000);
    368 
    369   Elf* elf_2 = jit_debug_->GetElf(maps_.get(), 0x2400);
    370   ASSERT_TRUE(elf_2 != nullptr);
    371 
    372   Elf* elf_1 = jit_debug_->GetElf(maps_.get(), 0x1600);
    373   ASSERT_TRUE(elf_1 != nullptr);
    374 
    375   // Clear the memory and verify all of the data is cached.
    376   memory_->Clear();
    377   EXPECT_EQ(elf_1, jit_debug_->GetElf(maps_.get(), 0x1500));
    378   EXPECT_EQ(elf_1, jit_debug_->GetElf(maps_.get(), 0x16ff));
    379   EXPECT_EQ(elf_2, jit_debug_->GetElf(maps_.get(), 0x2300));
    380   EXPECT_EQ(elf_2, jit_debug_->GetElf(maps_.get(), 0x26ff));
    381   EXPECT_EQ(nullptr, jit_debug_->GetElf(maps_.get(), 0x1700));
    382   EXPECT_EQ(nullptr, jit_debug_->GetElf(maps_.get(), 0x2700));
    383 }
    384 
    385 TEST_F(JitDebugTest, get_elf_search_libs) {
    386   CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
    387 
    388   WriteDescriptor32(0xf800, 0x200000);
    389   WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000);
    390 
    391   // Only search a given named list of libs.
    392   std::vector<std::string> libs{"libart.so"};
    393   jit_debug_.reset(new JitDebug(process_memory_, libs));
    394   jit_debug_->SetArch(ARCH_ARM);
    395   EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr);
    396 
    397   // Change the name of the map that includes the value and verify this works.
    398   MapInfo* map_info = maps_->Get(5);
    399   map_info->name = "/system/lib/libart.so";
    400   jit_debug_.reset(new JitDebug(process_memory_, libs));
    401   // Make sure that clearing our copy of the libs doesn't affect the
    402   // JitDebug object.
    403   libs.clear();
    404   jit_debug_->SetArch(ARCH_ARM);
    405   EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr);
    406 }
    407 
    408 }  // namespace unwindstack
    409