diff options
Diffstat (limited to 'libunwindstack/tests/JitDebugTest.cpp')
-rw-r--r-- | libunwindstack/tests/JitDebugTest.cpp | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/libunwindstack/tests/JitDebugTest.cpp b/libunwindstack/tests/JitDebugTest.cpp index b1ca111cbc..438194a9fb 100644 --- a/libunwindstack/tests/JitDebugTest.cpp +++ b/libunwindstack/tests/JitDebugTest.cpp @@ -46,8 +46,7 @@ class JitDebugTest : public ::testing::Test { } void Init(ArchEnum arch) { - jit_debug_.reset(new JitDebug(process_memory_)); - jit_debug_->SetArch(arch); + jit_debug_ = JitDebug<Elf>::Create(arch, process_memory_); maps_.reset( new BufferMaps("1000-4000 ---s 00000000 00:00 0 /fake/elf1\n" @@ -62,6 +61,12 @@ class JitDebugTest : public ::testing::Test { "200000-210000 rw-p 0002000 00:00 0 /fake/elf4\n")); ASSERT_TRUE(maps_->Parse()); + // Ensure all memory of the ELF file is initialized, + // otherwise reads within it may fail. + for (uint64_t addr = 0x4000; addr < 0x6000; addr += 8) { + memory_->SetData64(addr, 0); + } + MapInfo* map_info = maps_->Get(3); ASSERT_TRUE(map_info != nullptr); CreateFakeElf(map_info); @@ -94,7 +99,7 @@ class JitDebugTest : public ::testing::Test { ehdr.e_shstrndx = 1; ehdr.e_shoff = sh_offset; ehdr.e_shentsize = sizeof(ShdrType); - ehdr.e_shnum = 3; + ehdr.e_shnum = 4; memory_->SetMemory(offset, &ehdr, sizeof(ehdr)); ShdrType shdr; @@ -110,6 +115,7 @@ class JitDebugTest : public ::testing::Test { shdr.sh_size = 0x100; memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr)); memory_->SetMemory(offset + 0x500, ".debug_frame"); + memory_->SetMemory(offset + 0x550, ".text"); sh_offset += sizeof(shdr); memset(&shdr, 0, sizeof(shdr)); @@ -120,6 +126,15 @@ class JitDebugTest : public ::testing::Test { shdr.sh_size = 0x200; memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr)); + sh_offset += sizeof(shdr); + memset(&shdr, 0, sizeof(shdr)); + shdr.sh_type = SHT_NOBITS; + shdr.sh_name = 0x50; + shdr.sh_addr = pc; + shdr.sh_offset = 0; + shdr.sh_size = size; + memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr)); + // Now add a single cie/fde. uint64_t dwarf_offset = offset + 0x600; if (class_type == ELFCLASS32) { @@ -168,7 +183,7 @@ class JitDebugTest : public ::testing::Test { std::shared_ptr<Memory> process_memory_; MemoryFake* memory_; - std::unique_ptr<JitDebug> jit_debug_; + std::unique_ptr<JitDebug<Elf>> jit_debug_; std::unique_ptr<BufferMaps> maps_; }; @@ -238,20 +253,20 @@ void JitDebugTest::WriteEntry64(uint64_t addr, uint64_t prev, uint64_t next, uin } TEST_F(JitDebugTest, get_elf_invalid) { - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf == nullptr); } TEST_F(JitDebugTest, get_elf_no_global_variable) { maps_.reset(new BufferMaps("")); - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf == nullptr); } TEST_F(JitDebugTest, get_elf_no_valid_descriptor_in_memory) { CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf == nullptr); } @@ -260,7 +275,7 @@ TEST_F(JitDebugTest, get_elf_no_valid_code_entry) { WriteDescriptor32(0xf800, 0x200000); - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf == nullptr); } @@ -269,7 +284,7 @@ TEST_F(JitDebugTest, get_elf_invalid_descriptor_first_entry) { WriteDescriptor32(0xf800, 0); - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf == nullptr); } @@ -280,7 +295,7 @@ TEST_F(JitDebugTest, get_elf_invalid_descriptor_version) { // Set the version to an invalid value. memory_->SetData32(0xf800, 2); - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf == nullptr); } @@ -290,12 +305,18 @@ TEST_F(JitDebugTest, get_elf_32) { WriteDescriptor32(0xf800, 0x200000); WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000); - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf != nullptr); + uint64_t text_addr; + uint64_t text_size; + ASSERT_TRUE(elf->GetTextRange(&text_addr, &text_size)); + ASSERT_EQ(text_addr, 0x1500u); + ASSERT_EQ(text_size, 0x200u); // Clear the memory and verify all of the data is cached. memory_->Clear(); - Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500); + WriteDescriptor32(0xf800, 0x200000); + Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf2 != nullptr); EXPECT_EQ(elf, elf2); } @@ -309,16 +330,15 @@ TEST_F(JitDebugTest, get_multiple_jit_debug_descriptors_valid) { WriteDescriptor32(0x12800, 0x201000); WriteEntry32Pad(0x201000, 0, 0, 0x5000, 0x1000); - ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr); - ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) == nullptr); + ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) != nullptr); + ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x2000) == nullptr); // Now clear the descriptor entry for the first one. WriteDescriptor32(0xf800, 0); - jit_debug_.reset(new JitDebug(process_memory_)); - jit_debug_->SetArch(ARCH_ARM); + jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_); - ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr); - ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) != nullptr); + ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) == nullptr); + ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x2000) != nullptr); } TEST_F(JitDebugTest, get_elf_x86) { @@ -329,13 +349,14 @@ TEST_F(JitDebugTest, get_elf_x86) { WriteDescriptor32(0xf800, 0x200000); WriteEntry32Pack(0x200000, 0, 0, 0x4000, 0x1000); - jit_debug_->SetArch(ARCH_X86); - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + jit_debug_ = JitDebug<Elf>::Create(ARCH_X86, process_memory_); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf != nullptr); // Clear the memory and verify all of the data is cached. memory_->Clear(); - Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500); + WriteDescriptor32(0xf800, 0x200000); + Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf2 != nullptr); EXPECT_EQ(elf, elf2); } @@ -348,12 +369,13 @@ TEST_F(JitDebugTest, get_elf_64) { WriteDescriptor64(0xf800, 0x200000); WriteEntry64(0x200000, 0, 0, 0x4000, 0x1000); - Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); + Elf* elf = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf != nullptr); // Clear the memory and verify all of the data is cached. memory_->Clear(); - Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500); + WriteDescriptor64(0xf800, 0x200000); + Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500); ASSERT_TRUE(elf2 != nullptr); EXPECT_EQ(elf, elf2); } @@ -366,20 +388,21 @@ TEST_F(JitDebugTest, get_elf_multiple_entries) { WriteEntry32Pad(0x200000, 0, 0x200100, 0x4000, 0x1000); WriteEntry32Pad(0x200100, 0x200100, 0, 0x5000, 0x1000); - Elf* elf_2 = jit_debug_->GetElf(maps_.get(), 0x2400); + Elf* elf_2 = jit_debug_->Get(maps_.get(), 0x2400); ASSERT_TRUE(elf_2 != nullptr); - Elf* elf_1 = jit_debug_->GetElf(maps_.get(), 0x1600); + Elf* elf_1 = jit_debug_->Get(maps_.get(), 0x1600); ASSERT_TRUE(elf_1 != nullptr); // Clear the memory and verify all of the data is cached. memory_->Clear(); - EXPECT_EQ(elf_1, jit_debug_->GetElf(maps_.get(), 0x1500)); - EXPECT_EQ(elf_1, jit_debug_->GetElf(maps_.get(), 0x16ff)); - EXPECT_EQ(elf_2, jit_debug_->GetElf(maps_.get(), 0x2300)); - EXPECT_EQ(elf_2, jit_debug_->GetElf(maps_.get(), 0x26ff)); - EXPECT_EQ(nullptr, jit_debug_->GetElf(maps_.get(), 0x1700)); - EXPECT_EQ(nullptr, jit_debug_->GetElf(maps_.get(), 0x2700)); + WriteDescriptor32(0xf800, 0x200000); + EXPECT_EQ(elf_1, jit_debug_->Get(maps_.get(), 0x1500)); + EXPECT_EQ(elf_1, jit_debug_->Get(maps_.get(), 0x16ff)); + EXPECT_EQ(elf_2, jit_debug_->Get(maps_.get(), 0x2300)); + EXPECT_EQ(elf_2, jit_debug_->Get(maps_.get(), 0x26ff)); + EXPECT_EQ(nullptr, jit_debug_->Get(maps_.get(), 0x1700)); + EXPECT_EQ(nullptr, jit_debug_->Get(maps_.get(), 0x2700)); } TEST_F(JitDebugTest, get_elf_search_libs) { @@ -390,21 +413,19 @@ TEST_F(JitDebugTest, get_elf_search_libs) { // Only search a given named list of libs. std::vector<std::string> libs{"libart.so"}; - jit_debug_.reset(new JitDebug(process_memory_, libs)); - jit_debug_->SetArch(ARCH_ARM); - EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr); + jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_, libs); + EXPECT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) == nullptr); // Change the name of the map that includes the value and verify this works. MapInfo* map_info = maps_->Get(5); map_info->name = "/system/lib/libart.so"; map_info = maps_->Get(6); map_info->name = "/system/lib/libart.so"; - jit_debug_.reset(new JitDebug(process_memory_, libs)); + jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_); // Make sure that clearing our copy of the libs doesn't affect the // JitDebug object. libs.clear(); - jit_debug_->SetArch(ARCH_ARM); - EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr); + EXPECT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) != nullptr); } } // namespace unwindstack |