diff options
Diffstat (limited to 'libunwindstack/tests/DexFilesTest.cpp')
-rw-r--r-- | libunwindstack/tests/DexFilesTest.cpp | 154 |
1 files changed, 89 insertions, 65 deletions
diff --git a/libunwindstack/tests/DexFilesTest.cpp b/libunwindstack/tests/DexFilesTest.cpp index 1ea9e5c..655dcc8 100644 --- a/libunwindstack/tests/DexFilesTest.cpp +++ b/libunwindstack/tests/DexFilesTest.cpp @@ -22,8 +22,8 @@ #include <gtest/gtest.h> -#include <unwindstack/DexFiles.h> #include <unwindstack/Elf.h> +#include <unwindstack/JitDebug.h> #include <unwindstack/MapInfo.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> @@ -32,6 +32,10 @@ #include "ElfFake.h" #include "MemoryFake.h" +#if !defined(NO_LIBDEXFILE_SUPPORT) +#include <DexFile.h> +#endif + namespace unwindstack { class DexFilesTest : public ::testing::Test { @@ -48,8 +52,7 @@ class DexFilesTest : public ::testing::Test { } void Init(ArchEnum arch) { - dex_files_.reset(new DexFiles(process_memory_)); - dex_files_->SetArch(arch); + dex_files_ = JitDebug<DexFile>::Create(arch, process_memory_); maps_.reset( new BufferMaps("1000-4000 ---s 00000000 00:00 0 /fake/elf\n" @@ -86,10 +89,11 @@ class DexFilesTest : public ::testing::Test { Init(ARCH_ARM); } - void WriteDescriptor32(uint64_t addr, uint32_t head); - void WriteDescriptor64(uint64_t addr, uint64_t head); - void WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev, uint32_t dex_file); - void WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev, uint64_t dex_file); + void WriteDescriptor32(uint64_t addr, uint32_t entry); + void WriteDescriptor64(uint64_t addr, uint64_t entry); + void WriteEntry32Pack(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex); + void WriteEntry32Pad(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex); + void WriteEntry64(uint64_t addr, uint64_t next, uint64_t prev, uint64_t dex); void WriteDex(uint64_t dex_file); static constexpr size_t kMapGlobalNonReadable = 2; @@ -101,40 +105,70 @@ class DexFilesTest : public ::testing::Test { std::shared_ptr<Memory> process_memory_; MemoryFake* memory_; - std::unique_ptr<DexFiles> dex_files_; + std::unique_ptr<JitDebug<DexFile>> dex_files_; std::unique_ptr<BufferMaps> maps_; }; -void DexFilesTest::WriteDescriptor32(uint64_t addr, uint32_t head) { - // void* first_entry_ - memory_->SetData32(addr + 12, head); +void DexFilesTest::WriteDescriptor32(uint64_t addr, uint32_t entry) { + // Format of the 32 bit JITDescriptor structure: + // uint32_t version + memory_->SetData32(addr, 1); + // uint32_t action_flag + memory_->SetData32(addr + 4, 0); + // uint32_t relevant_entry + memory_->SetData32(addr + 8, 0); + // uint32_t first_entry + memory_->SetData32(addr + 12, entry); +} + +void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t entry) { + // Format of the 64 bit JITDescriptor structure: + // uint32_t version + memory_->SetData32(addr, 1); + // uint32_t action_flag + memory_->SetData32(addr + 4, 0); + // uint64_t relevant_entry + memory_->SetData64(addr + 8, 0); + // uint64_t first_entry + memory_->SetData64(addr + 16, entry); } -void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t head) { - // void* first_entry_ - memory_->SetData64(addr + 16, head); +void DexFilesTest::WriteEntry32Pack(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex) { + // Format of the 32 bit JITCodeEntry structure: + // uint32_t next + memory_->SetData32(addr, next); + // uint32_t prev + memory_->SetData32(addr + 4, prev); + // uint32_t dex + memory_->SetData32(addr + 8, dex); + // uint64_t symfile_size + memory_->SetData64(addr + 12, sizeof(kDexData) * sizeof(uint32_t)); } -void DexFilesTest::WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev, - uint32_t dex_file) { - // Format of the 32 bit DEXFileEntry structure: +void DexFilesTest::WriteEntry32Pad(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex) { + // Format of the 32 bit JITCodeEntry structure: // uint32_t next - memory_->SetData32(entry_addr, next); + memory_->SetData32(addr, next); // uint32_t prev - memory_->SetData32(entry_addr + 4, prev); - // uint32_t dex_file - memory_->SetData32(entry_addr + 8, dex_file); + memory_->SetData32(addr + 4, prev); + // uint32_t dex + memory_->SetData32(addr + 8, dex); + // uint32_t pad + memory_->SetData32(addr + 12, 0); + // uint64_t symfile_size + memory_->SetData64(addr + 16, sizeof(kDexData) * sizeof(uint32_t)); } -void DexFilesTest::WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev, - uint64_t dex_file) { - // Format of the 64 bit DEXFileEntry structure: +void DexFilesTest::WriteEntry64(uint64_t addr, uint64_t next, uint64_t prev, uint64_t dex) { + // Format of the 64 bit JITCodeEntry structure: // uint64_t next - memory_->SetData64(entry_addr, next); + memory_->SetData64(addr, next); // uint64_t prev - memory_->SetData64(entry_addr + 8, prev); - // uint64_t dex_file - memory_->SetData64(entry_addr + 16, dex_file); + memory_->SetData64(addr + 8, prev); + // uint64_t dex + memory_->SetData64(addr + 16, dex); + // uint64_t symfile_size + memory_->SetData64(addr + 24, sizeof(kDexData) * sizeof(uint32_t)); } void DexFilesTest::WriteDex(uint64_t dex_file) { @@ -144,9 +178,8 @@ void DexFilesTest::WriteDex(uint64_t dex_file) { TEST_F(DexFilesTest, get_method_information_invalid) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFileEntries); - dex_files_->GetMethodInformation(maps_.get(), info, 0, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0, &method_name, &method_offset); EXPECT_EQ("nothing", method_name); EXPECT_EQ(0x124U, method_offset); } @@ -154,13 +187,12 @@ TEST_F(DexFilesTest, get_method_information_invalid) { TEST_F(DexFilesTest, get_method_information_32) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFiles); WriteDescriptor32(0xf800, 0x200000); - WriteEntry32(0x200000, 0, 0, 0x300000); + WriteEntry32Pad(0x200000, 0, 0, 0x300000); WriteDex(0x300000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(0U, method_offset); } @@ -170,13 +202,12 @@ TEST_F(DexFilesTest, get_method_information_64) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFiles); WriteDescriptor64(0xf800, 0x200000); WriteEntry64(0x200000, 0, 0, 0x301000); WriteDex(0x301000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x301102, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x301102, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(2U, method_offset); } @@ -184,14 +215,14 @@ TEST_F(DexFilesTest, get_method_information_64) { TEST_F(DexFilesTest, get_method_information_not_first_entry_32) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFiles); WriteDescriptor32(0xf800, 0x200000); - WriteEntry32(0x200000, 0x200100, 0, 0x100000); - WriteEntry32(0x200100, 0, 0x200000, 0x300000); + WriteEntry32Pad(0x200000, 0x200100, 0, 0x100000); + WriteDex(0x100000); + WriteEntry32Pad(0x200100, 0, 0x200000, 0x300000); WriteDex(0x300000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(4U, method_offset); } @@ -201,14 +232,14 @@ TEST_F(DexFilesTest, get_method_information_not_first_entry_64) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFiles); WriteDescriptor64(0xf800, 0x200000); WriteEntry64(0x200000, 0x200100, 0, 0x100000); + WriteDex(0x100000); WriteEntry64(0x200100, 0, 0x200000, 0x300000); WriteDex(0x300000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300106, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300106, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(6U, method_offset); } @@ -216,19 +247,18 @@ TEST_F(DexFilesTest, get_method_information_not_first_entry_64) { TEST_F(DexFilesTest, get_method_information_cached) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFiles); WriteDescriptor32(0xf800, 0x200000); - WriteEntry32(0x200000, 0, 0, 0x300000); + WriteEntry32Pad(0x200000, 0, 0, 0x300000); WriteDex(0x300000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(0U, method_offset); // Clear all memory and make sure that data is acquired from the cache. memory_->Clear(); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(0U, method_offset); } @@ -236,26 +266,24 @@ TEST_F(DexFilesTest, get_method_information_cached) { TEST_F(DexFilesTest, get_method_information_search_libs) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFiles); WriteDescriptor32(0xf800, 0x200000); - WriteEntry32(0x200000, 0x200100, 0, 0x100000); - WriteEntry32(0x200100, 0, 0x200000, 0x300000); + WriteEntry32Pad(0x200000, 0x200100, 0, 0x100000); + WriteDex(0x100000); + WriteEntry32Pad(0x200100, 0, 0x200000, 0x300000); WriteDex(0x300000); // Only search a given named list of libs. std::vector<std::string> libs{"libart.so"}; - dex_files_.reset(new DexFiles(process_memory_, libs)); - dex_files_->SetArch(ARCH_ARM); + dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_, libs); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset); EXPECT_EQ("nothing", method_name); EXPECT_EQ(0x124U, method_offset); MapInfo* map_info = maps_->Get(kMapGlobal); map_info->name = "/system/lib/libart.so"; - dex_files_.reset(new DexFiles(process_memory_, libs)); - dex_files_->SetArch(ARCH_ARM); + dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_, libs); // Set the rw map to the same name or this will not scan this entry. map_info = maps_->Get(kMapGlobalRw); map_info->name = "/system/lib/libart.so"; @@ -263,7 +291,7 @@ TEST_F(DexFilesTest, get_method_information_search_libs) { // DexFiles object. libs.clear(); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(4U, method_offset); } @@ -271,26 +299,24 @@ TEST_F(DexFilesTest, get_method_information_search_libs) { TEST_F(DexFilesTest, get_method_information_global_skip_zero_32) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFiles); // First global variable found, but value is zero. WriteDescriptor32(0xa800, 0); WriteDescriptor32(0xf800, 0x200000); - WriteEntry32(0x200000, 0, 0, 0x300000); + WriteEntry32Pad(0x200000, 0, 0, 0x300000); WriteDex(0x300000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(0U, method_offset); // Verify that second is ignored when first is set to non-zero - dex_files_.reset(new DexFiles(process_memory_)); - dex_files_->SetArch(ARCH_ARM); + dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_); method_name = "fail"; method_offset = 0x123; WriteDescriptor32(0xa800, 0x100000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); EXPECT_EQ("fail", method_name); EXPECT_EQ(0x123U, method_offset); } @@ -300,7 +326,6 @@ TEST_F(DexFilesTest, get_method_information_global_skip_zero_64) { std::string method_name = "nothing"; uint64_t method_offset = 0x124; - MapInfo* info = maps_->Get(kMapDexFiles); // First global variable found, but value is zero. WriteDescriptor64(0xa800, 0); @@ -309,17 +334,16 @@ TEST_F(DexFilesTest, get_method_information_global_skip_zero_64) { WriteEntry64(0x200000, 0, 0, 0x300000); WriteDex(0x300000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); EXPECT_EQ("Main.<init>", method_name); EXPECT_EQ(0U, method_offset); // Verify that second is ignored when first is set to non-zero - dex_files_.reset(new DexFiles(process_memory_)); - dex_files_->SetArch(ARCH_ARM64); + dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM64, process_memory_); method_name = "fail"; method_offset = 0x123; WriteDescriptor64(0xa800, 0x100000); - dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset); + dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); EXPECT_EQ("fail", method_name); EXPECT_EQ(0x123U, method_offset); } |