diff options
author | David Srbecky <dsrbecky@google.com> | 2021-03-24 13:31:11 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-03-24 13:31:11 +0000 |
commit | 0f3e4f8b7598269ce67ad80265aa0f4b41b0739f (patch) | |
tree | c3976b1ebeaf3b2adfebae4442fa8532e759f493 | |
parent | fcdc5f2c4084890c2ca48d981f74c6ff7bac4889 (diff) | |
parent | c966e544b744dbb6154fac87a6602f0ccb91eac2 (diff) | |
download | unwinding-0f3e4f8b7598269ce67ad80265aa0f4b41b0739f.tar.gz |
Merge "Simplify DexFile implementation."
-rw-r--r-- | libunwindstack/DexFile.cpp | 129 | ||||
-rw-r--r-- | libunwindstack/DexFile.h | 58 | ||||
-rw-r--r-- | libunwindstack/DexFiles.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/Memory.cpp | 5 | ||||
-rw-r--r-- | libunwindstack/MemoryFileAtOffset.h | 2 | ||||
-rw-r--r-- | libunwindstack/MemoryLocal.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/Memory.h | 6 | ||||
-rw-r--r-- | libunwindstack/tests/DexFileTest.cpp | 132 | ||||
-rw-r--r-- | libunwindstack/tests/DexFilesTest.cpp | 38 |
9 files changed, 108 insertions, 268 deletions
diff --git a/libunwindstack/DexFile.cpp b/libunwindstack/DexFile.cpp index e1007c7..4cb2c93 100644 --- a/libunwindstack/DexFile.cpp +++ b/libunwindstack/DexFile.cpp @@ -32,6 +32,7 @@ #include <unwindstack/Memory.h> #include "DexFile.h" +#include "MemoryBuffer.h" namespace unwindstack { @@ -43,42 +44,47 @@ static bool CheckDexSupport() { return true; } -static bool HasDexSupport() { - static bool has_dex_support = CheckDexSupport(); - return has_dex_support; -} - -bool DexFile::IsValidPc(uint64_t dex_pc) { - return base_addr_ <= dex_pc && dex_pc < base_addr_ + size_; -} - -std::unique_ptr<DexFile> DexFile::Create(uint64_t dex_file_offset_in_memory, Memory* memory, +std::unique_ptr<DexFile> DexFile::Create(uint64_t base_addr, uint64_t file_size, Memory* memory, MapInfo* info) { - if (UNLIKELY(!HasDexSupport() || info == nullptr)) { + static bool has_dex_support = CheckDexSupport(); + if (!has_dex_support || file_size == 0) { return nullptr; } - size_t max_size = info->end - dex_file_offset_in_memory; - if (memory->IsLocal()) { - size_t size = max_size; - - std::string err_msg; - std::unique_ptr<art_api::dex::DexFile> art_dex_file = DexFile::OpenFromMemory( - reinterpret_cast<void const*>(dex_file_offset_in_memory), &size, info->name, &err_msg); - if (art_dex_file != nullptr && size <= max_size) { - return std::unique_ptr<DexFile>(new DexFile(dex_file_offset_in_memory, size, art_dex_file)); + // Try to map the file directly from disk. + std::unique_ptr<Memory> dex_memory; + if (info != nullptr && !info->name.empty()) { + if (info->start <= base_addr && base_addr < info->end) { + uint64_t offset_in_file = (base_addr - info->start) + info->offset; + if (file_size <= info->end - base_addr) { + dex_memory = Memory::CreateFileMemory(info->name, offset_in_file, file_size); + // On error, the results is null and we fall through to the fallback code-path. + } } } - if (!info->name.empty()) { - std::unique_ptr<DexFile> dex_file = - DexFileFromFile::Create(dex_file_offset_in_memory, - dex_file_offset_in_memory - info->start + info->offset, info->name); - if (dex_file) { - return dex_file; + // Fallback: make copy in local buffer. + if (dex_memory.get() == nullptr) { + std::unique_ptr<MemoryBuffer> copy(new MemoryBuffer); + if (!copy->Resize(file_size)) { + return nullptr; + } + if (!memory->ReadFully(base_addr, copy->GetPtr(0), file_size)) { + return nullptr; } + dex_memory = std::move(copy); } - return DexFileFromMemory::Create(dex_file_offset_in_memory, memory, info->name, max_size); + + std::string err_msg; + size_t actual_size = file_size; + const char* location = info != nullptr ? info->name.c_str() : ""; + std::unique_ptr<art_api::dex::DexFile> dex = + art_api::dex::DexFile::OpenFromMemory(dex_memory->GetPtr(), &actual_size, location, &err_msg); + if (dex != nullptr) { + return std::unique_ptr<DexFile>( + new DexFile(std::move(dex_memory), base_addr, file_size, std::move(dex))); + } + return nullptr; } bool DexFile::GetFunctionName(uint64_t dex_pc, SharedString* method_name, uint64_t* method_offset) { @@ -94,7 +100,7 @@ bool DexFile::GetFunctionName(uint64_t dex_pc, SharedString* method_name, uint64 } // Lookup the function in the underlying dex file. - art_api::dex::MethodInfo method_info = GetMethodInfoForOffset(dex_offset, false); + art_api::dex::MethodInfo method_info = dex_->GetMethodInfoForOffset(dex_offset, false); if (method_info.offset == 0) { return false; } @@ -112,71 +118,4 @@ bool DexFile::GetFunctionName(uint64_t dex_pc, SharedString* method_name, uint64 return true; } -std::unique_ptr<DexFileFromFile> DexFileFromFile::Create(uint64_t base_addr, - uint64_t dex_file_offset_in_file, - const std::string& file) { - if (UNLIKELY(!HasDexSupport())) { - return nullptr; - } - - android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(file.c_str(), O_RDONLY | O_CLOEXEC))); - if (fd == -1) { - return nullptr; - } - struct stat buf; - if (fstat(fd, &buf) == -1) { - return nullptr; - } - uint64_t end = static_cast<uint64_t>(buf.st_size); - if (dex_file_offset_in_file >= end) { - return nullptr; - } - uint64_t size = end - dex_file_offset_in_file; - - std::string error_msg; - std::unique_ptr<art_api::dex::DexFile> art_dex_file = - OpenFromFd(fd, dex_file_offset_in_file, file, &error_msg); - if (art_dex_file == nullptr) { - return nullptr; - } - - return std::unique_ptr<DexFileFromFile>(new DexFileFromFile(base_addr, size, art_dex_file)); -} - -std::unique_ptr<DexFileFromMemory> DexFileFromMemory::Create(uint64_t dex_file_offset_in_memory, - Memory* memory, - const std::string& name, - size_t max_size) { - if (UNLIKELY(!HasDexSupport())) { - return nullptr; - } - - std::vector<uint8_t> backing_memory; - - for (size_t size = 0;;) { - const size_t old_size = size; // The call below may increase the size. - std::string error_msg; - std::unique_ptr<art_api::dex::DexFile> art_dex_file = - OpenFromMemory(backing_memory.data(), &size, name, &error_msg); - if (size > max_size) { - return nullptr; - } - if (size > old_size) { - // Read more memory and retry. - backing_memory.resize(size); - if (!memory->ReadFully(dex_file_offset_in_memory, backing_memory.data(), - backing_memory.size())) { - return nullptr; - } - continue; - } - - if (art_dex_file != nullptr) { - return std::unique_ptr<DexFileFromMemory>(new DexFileFromMemory( - dex_file_offset_in_memory, size, art_dex_file, std::move(backing_memory))); - } - return nullptr; - } -} - } // namespace unwindstack diff --git a/libunwindstack/DexFile.h b/libunwindstack/DexFile.h index 59ad2f6..a80ea94 100644 --- a/libunwindstack/DexFile.h +++ b/libunwindstack/DexFile.h @@ -31,57 +31,39 @@ namespace unwindstack { -class DexFile : protected art_api::dex::DexFile { +struct MapInfo; +class Memory; + +class DexFile { struct Info { uint32_t offset; // Symbol start offset (relative to start of dex file). SharedString name; }; public: - virtual ~DexFile() = default; - - bool IsValidPc(uint64_t dex_pc); + bool IsValidPc(uint64_t dex_pc) { + return base_addr_ <= dex_pc && (dex_pc - base_addr_) < file_size_; + } bool GetFunctionName(uint64_t dex_pc, SharedString* method_name, uint64_t* method_offset); - static std::unique_ptr<DexFile> Create(uint64_t dex_file_offset_in_memory, Memory* memory, + static std::unique_ptr<DexFile> Create(uint64_t base_addr, uint64_t file_size, Memory* memory, MapInfo* info); - protected: - DexFile(uint64_t base_addr, uint64_t size, std::unique_ptr<art_api::dex::DexFile>& art_dex_file) - : art_api::dex::DexFile(art_dex_file), base_addr_(base_addr), size_(size) {} - - uint64_t base_addr_ = 0; // Absolute address where this DEX file is in memory. - uint64_t size_ = 0; // Size of the dex file. - - std::map<uint32_t, Info> symbols_; // Cache of read symbols (keyed by *end* offset). -}; - -class DexFileFromFile : public DexFile { - public: - static std::unique_ptr<DexFileFromFile> Create(uint64_t base_addr, - uint64_t dex_file_offset_in_file, - const std::string& file); - private: - DexFileFromFile(uint64_t base_addr, uint64_t size, - std::unique_ptr<art_api::dex::DexFile>& art_dex_file) - : DexFile(base_addr, size, art_dex_file) {} -}; - -class DexFileFromMemory : public DexFile { - public: - static std::unique_ptr<DexFileFromMemory> Create(uint64_t dex_file_offset_in_memory, - Memory* memory, const std::string& name, - size_t max_size); + DexFile(std::unique_ptr<Memory>&& memory, uint64_t base_addr, uint64_t file_size, + std::unique_ptr<art_api::dex::DexFile>&& dex) + : memory_(std::move(memory)), + base_addr_(base_addr), + file_size_(file_size), + dex_(std::move(dex)) {} + + std::unique_ptr<Memory> memory_; // Memory range containing the dex file. + uint64_t base_addr_ = 0; // Absolute address where this DEX file is in memory. + uint64_t file_size_ = 0; // Total number of bytes in the dex file. + std::unique_ptr<art_api::dex::DexFile> dex_; // Loaded underling dex object. - private: - DexFileFromMemory(uint64_t base_addr, uint64_t size, - std::unique_ptr<art_api::dex::DexFile>& art_dex_file, - std::vector<uint8_t>&& memory) - : DexFile(base_addr, size, art_dex_file), memory_(std::move(memory)) {} - - std::vector<uint8_t> memory_; + std::map<uint32_t, Info> symbols_; // Cache of read symbols (keyed by *end* offset). }; } // namespace unwindstack diff --git a/libunwindstack/DexFiles.cpp b/libunwindstack/DexFiles.cpp index 3507cc7..2a3912b 100644 --- a/libunwindstack/DexFiles.cpp +++ b/libunwindstack/DexFiles.cpp @@ -28,8 +28,8 @@ namespace unwindstack { template <> bool GlobalDebugInterface<DexFile>::Load(Maps* maps, std::shared_ptr<Memory>& memory, uint64_t addr, - uint64_t, /*out*/ std::unique_ptr<DexFile>& dex) { - dex = DexFile::Create(addr, memory.get(), maps->Find(addr)); + uint64_t size, /*out*/ std::unique_ptr<DexFile>& dex) { + dex = DexFile::Create(addr, size, memory.get(), maps->Find(addr)); return dex.get() != nullptr; } diff --git a/libunwindstack/Memory.cpp b/libunwindstack/Memory.cpp index 36a9bb5..ca4aac4 100644 --- a/libunwindstack/Memory.cpp +++ b/libunwindstack/Memory.cpp @@ -187,10 +187,11 @@ bool Memory::ReadString(uint64_t addr, std::string* dst, size_t max_read) { return false; } -std::unique_ptr<Memory> Memory::CreateFileMemory(const std::string& path, uint64_t offset) { +std::unique_ptr<Memory> Memory::CreateFileMemory(const std::string& path, uint64_t offset, + uint64_t size) { auto memory = std::make_unique<MemoryFileAtOffset>(); - if (memory->Init(path, offset)) { + if (memory->Init(path, offset, size)) { return memory; } diff --git a/libunwindstack/MemoryFileAtOffset.h b/libunwindstack/MemoryFileAtOffset.h index d136eb4..9949f26 100644 --- a/libunwindstack/MemoryFileAtOffset.h +++ b/libunwindstack/MemoryFileAtOffset.h @@ -30,6 +30,8 @@ class MemoryFileAtOffset : public Memory { bool Init(const std::string& file, uint64_t offset, uint64_t size = UINT64_MAX); + uint8_t* GetPtr(size_t addr = 0) override { return addr < size_ ? data_ + addr : nullptr; } + size_t Read(uint64_t addr, void* dst, size_t size) override; size_t Size() { return size_; } diff --git a/libunwindstack/MemoryLocal.h b/libunwindstack/MemoryLocal.h index 741f107..a5c7a48 100644 --- a/libunwindstack/MemoryLocal.h +++ b/libunwindstack/MemoryLocal.h @@ -28,8 +28,6 @@ class MemoryLocal : public Memory { MemoryLocal() = default; virtual ~MemoryLocal() = default; - bool IsLocal() const override { return true; } - size_t Read(uint64_t addr, void* dst, size_t size) override; long ReadTag(uint64_t addr) override; }; diff --git a/libunwindstack/include/unwindstack/Memory.h b/libunwindstack/include/unwindstack/Memory.h index 3d81878..4b33ddb 100644 --- a/libunwindstack/include/unwindstack/Memory.h +++ b/libunwindstack/include/unwindstack/Memory.h @@ -35,13 +35,15 @@ class Memory { static std::shared_ptr<Memory> CreateProcessMemoryCached(pid_t pid); static std::shared_ptr<Memory> CreateOfflineMemory(const uint8_t* data, uint64_t start, uint64_t end); - static std::unique_ptr<Memory> CreateFileMemory(const std::string& path, uint64_t offset); + static std::unique_ptr<Memory> CreateFileMemory(const std::string& path, uint64_t offset, + uint64_t size = UINT64_MAX); virtual bool ReadString(uint64_t addr, std::string* dst, size_t max_read); virtual void Clear() {} - virtual bool IsLocal() const { return false; } + // Get pointer to directly access the data for buffers that support it. + virtual uint8_t* GetPtr(size_t /*addr*/ = 0) { return nullptr; } virtual size_t Read(uint64_t addr, void* dst, size_t size) = 0; virtual long ReadTag(uint64_t) { return -1; } diff --git a/libunwindstack/tests/DexFileTest.cpp b/libunwindstack/tests/DexFileTest.cpp index 6919c65..1dc0db2 100644 --- a/libunwindstack/tests/DexFileTest.cpp +++ b/libunwindstack/tests/DexFileTest.cpp @@ -33,47 +33,6 @@ namespace unwindstack { -TEST(DexFileTest, from_file_open_non_exist) { - EXPECT_TRUE(DexFileFromFile::Create(0, 0, "/file/does/not/exist") == nullptr); -} - -TEST(DexFileTest, from_file_open_too_small) { - TemporaryFile tf; - ASSERT_TRUE(tf.fd != -1); - - ASSERT_EQ(size_t{10}, static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, 10)))); - - // Header too small. - EXPECT_TRUE(DexFileFromFile::Create(0, 0, tf.path) == nullptr); - - // Header correct, file too small. - ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); - ASSERT_EQ(sizeof(kDexData) - 1, - static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData) - 1)))); - EXPECT_TRUE(DexFileFromFile::Create(0, 0, tf.path) == nullptr); -} - -TEST(DexFileTest, from_file_open) { - TemporaryFile tf; - ASSERT_TRUE(tf.fd != -1); - - ASSERT_EQ(sizeof(kDexData), - static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData))))); - - EXPECT_TRUE(DexFileFromFile::Create(0, 0, tf.path) != nullptr); -} - -TEST(DexFileTest, from_file_open_non_zero_offset) { - TemporaryFile tf; - ASSERT_TRUE(tf.fd != -1); - - ASSERT_EQ(0x100, lseek(tf.fd, 0x100, SEEK_SET)); - ASSERT_EQ(sizeof(kDexData), - static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData))))); - - EXPECT_TRUE(DexFileFromFile::Create(0, 0x100, tf.path) != nullptr); -} - static constexpr size_t kNumLeakLoops = 5000; static constexpr size_t kMaxAllowedLeakBytes = 1024; @@ -100,35 +59,13 @@ TEST(DexFileTest, from_file_no_leak) { size_t first_allocated_bytes = 0; size_t last_allocated_bytes = 0; for (size_t i = 0; i < kNumLeakLoops; i++) { - EXPECT_TRUE(DexFileFromFile::Create(0, 0, tf.path) != nullptr); + MemoryFake memory; + MapInfo info(nullptr, nullptr, 0, 0x10000, 0, 0x5, tf.path); + EXPECT_TRUE(DexFile::Create(0, sizeof(kDexData), &memory, &info) != nullptr); ASSERT_NO_FATAL_FAILURE(CheckForLeak(i, &first_allocated_bytes, &last_allocated_bytes)); } } -TEST(DexFileTest, from_memory_fail_too_small_for_header) { - MemoryFake memory; - - memory.SetMemory(0x1000, kDexData, 10); - - EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "", sizeof(kDexData)) == nullptr); -} - -TEST(DexFileTest, from_memory_fail_too_small_for_data) { - MemoryFake memory; - - memory.SetMemory(0x1000, kDexData, sizeof(kDexData) - 2); - - EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "", sizeof(kDexData)) == nullptr); -} - -TEST(DexFileTest, from_memory_open) { - MemoryFake memory; - - memory.SetMemory(0x1000, kDexData, sizeof(kDexData)); - - EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "", sizeof(kDexData)) != nullptr); -} - TEST(DexFileTest, from_memory_no_leak) { MemoryFake memory; @@ -137,7 +74,7 @@ TEST(DexFileTest, from_memory_no_leak) { size_t first_allocated_bytes = 0; size_t last_allocated_bytes = 0; for (size_t i = 0; i < kNumLeakLoops; i++) { - EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "", sizeof(kDexData)) != nullptr); + EXPECT_TRUE(DexFile::Create(0x1000, sizeof(kDexData), &memory, nullptr) != nullptr); ASSERT_NO_FATAL_FAILURE(CheckForLeak(i, &first_allocated_bytes, &last_allocated_bytes)); } } @@ -152,7 +89,7 @@ TEST(DexFileTest, create_using_file) { MemoryFake memory; MapInfo info(nullptr, nullptr, 0, 0x10000, 0, 0x5, tf.path); - EXPECT_TRUE(DexFile::Create(0x500, &memory, &info) != nullptr); + EXPECT_TRUE(DexFile::Create(0x500, sizeof(kDexData), &memory, &info) != nullptr); } TEST(DexFileTest, create_using_file_non_zero_start) { @@ -165,7 +102,7 @@ TEST(DexFileTest, create_using_file_non_zero_start) { MemoryFake memory; MapInfo info(nullptr, nullptr, 0x100, 0x10000, 0, 0x5, tf.path); - EXPECT_TRUE(DexFile::Create(0x600, &memory, &info) != nullptr); + EXPECT_TRUE(DexFile::Create(0x600, sizeof(kDexData), &memory, &info) != nullptr); } TEST(DexFileTest, create_using_file_non_zero_offset) { @@ -178,21 +115,21 @@ TEST(DexFileTest, create_using_file_non_zero_offset) { MemoryFake memory; MapInfo info(nullptr, nullptr, 0x100, 0x10000, 0x200, 0x5, tf.path); - EXPECT_TRUE(DexFile::Create(0x400, &memory, &info) != nullptr); + EXPECT_TRUE(DexFile::Create(0x400, sizeof(kDexData), &memory, &info) != nullptr); } TEST(DexFileTest, create_using_memory_empty_file) { MemoryFake memory; memory.SetMemory(0x4000, kDexData, sizeof(kDexData)); MapInfo info(nullptr, nullptr, 0x100, 0x10000, 0x200, 0x5, ""); - EXPECT_TRUE(DexFile::Create(0x4000, &memory, &info) != nullptr); + EXPECT_TRUE(DexFile::Create(0x4000, sizeof(kDexData), &memory, &info) != nullptr); } TEST(DexFileTest, create_using_memory_file_does_not_exist) { MemoryFake memory; memory.SetMemory(0x4000, kDexData, sizeof(kDexData)); MapInfo info(nullptr, nullptr, 0x100, 0x10000, 0x200, 0x5, "/does/not/exist"); - EXPECT_TRUE(DexFile::Create(0x4000, &memory, &info) != nullptr); + EXPECT_TRUE(DexFile::Create(0x4000, sizeof(kDexData), &memory, &info) != nullptr); } TEST(DexFileTest, create_using_memory_file_is_malformed) { @@ -205,57 +142,34 @@ TEST(DexFileTest, create_using_memory_file_is_malformed) { MemoryFake memory; memory.SetMemory(0x4000, kDexData, sizeof(kDexData)); MapInfo info(nullptr, nullptr, 0x4000, 0x10000, 0x200, 0x5, "/does/not/exist"); - std::unique_ptr<DexFile> dex_file = DexFile::Create(0x4000, &memory, &info); + std::unique_ptr<DexFile> dex_file = DexFile::Create(0x4000, sizeof(kDexData), &memory, &info); ASSERT_TRUE(dex_file != nullptr); // Check it came from memory by clearing memory and verifying it fails. memory.Clear(); - dex_file = DexFile::Create(0x4000, &memory, &info); + dex_file = DexFile::Create(0x4000, sizeof(kDexData), &memory, &info); EXPECT_TRUE(dex_file == nullptr); } -TEST(DexFileTest, create_using_memory_size_too_small) { +TEST(DexFileTest, create_using_memory_header_too_small) { MemoryFake memory; - memory.SetMemory(0x4000, kDexData, sizeof(kDexData)); - MapInfo info(nullptr, nullptr, 0x100, sizeof(kDexData) - 2, 0x200, 0x5, "/does/not/exist"); - EXPECT_TRUE(DexFile::Create(0x4000, &memory, &info) != nullptr); + size_t size = 10; + memory.SetMemory(0x4000, kDexData, size); + EXPECT_TRUE(DexFile::Create(0x4000, size, &memory, nullptr) == nullptr); } -class MemoryLocalFake : public MemoryLocal { - public: - MemoryLocalFake(size_t memory_size) : backing_(memory_size) {} - virtual ~MemoryLocalFake() = default; - - void* Data() { return backing_.data(); } - - private: - std::vector<void*> backing_; -}; - -TEST(DexFileTest, create_using_local_memory) { - MemoryLocalFake memory(sizeof(kDexData)); - - memcpy(memory.Data(), kDexData, sizeof(kDexData)); - uint64_t start = reinterpret_cast<uint64_t>(memory.Data()); - MapInfo info(nullptr, nullptr, start, start + 0x1000, 0x200, 0x5, "/does/not/exist"); - EXPECT_TRUE(DexFile::Create(start, &memory, &info) != nullptr); -} - -TEST(DexFileTest, create_using_local_memory_size_too_small) { - MemoryLocalFake memory(sizeof(kDexData)); - - memcpy(memory.Data(), kDexData, sizeof(kDexData)); - uint64_t start = reinterpret_cast<uint64_t>(memory.Data()); - MapInfo info(nullptr, nullptr, start, start + sizeof(kDexData) - 2, 0x200, 0x5, - "/does/not/exist"); - EXPECT_TRUE(DexFile::Create(start, &memory, &info) == nullptr); +TEST(DexFileTest, create_using_memory_size_too_small) { + MemoryFake memory; + size_t size = sizeof(kDexData) - 1; + memory.SetMemory(0x4000, kDexData, size); + EXPECT_TRUE(DexFile::Create(0x4000, size, &memory, nullptr) == nullptr); } TEST(DexFileTest, get_method) { MemoryFake memory; memory.SetMemory(0x4000, kDexData, sizeof(kDexData)); MapInfo info(nullptr, nullptr, 0x100, 0x10000, 0x200, 0x5, ""); - std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, &memory, &info)); + std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, sizeof(kDexData), &memory, &info)); ASSERT_TRUE(dex_file != nullptr); SharedString method; @@ -273,7 +187,7 @@ TEST(DexFileTest, get_method_empty) { MemoryFake memory; memory.SetMemory(0x4000, kDexData, sizeof(kDexData)); MapInfo info(nullptr, nullptr, 0x100, 0x10000, 0x200, 0x5, ""); - std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, &memory, &info)); + std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, sizeof(kDexData), &memory, &info)); ASSERT_TRUE(dex_file != nullptr); SharedString method; @@ -292,7 +206,7 @@ TEST(DexFileTest, get_method_from_cache) { MemoryFake memory; MapInfo info(nullptr, nullptr, 0x4000, 0x10000, 0, 0x5, tf.path); - std::unique_ptr<DexFile> dex_file = DexFile::Create(0x4000, &memory, &info); + std::unique_ptr<DexFile> dex_file = DexFile::Create(0x4000, sizeof(kDexData), &memory, &info); EXPECT_TRUE(dex_file != nullptr); SharedString method; diff --git a/libunwindstack/tests/DexFilesTest.cpp b/libunwindstack/tests/DexFilesTest.cpp index ce3def6..8da32a1 100644 --- a/libunwindstack/tests/DexFilesTest.cpp +++ b/libunwindstack/tests/DexFilesTest.cpp @@ -101,8 +101,10 @@ class DexFilesTest : public ::testing::Test { 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 WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev, uint32_t dex_file, + uint64_t dex_size); + void WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev, uint64_t dex_file, + uint64_t dex_size); void WriteDex(uint64_t dex_file); static constexpr size_t kMapGlobalNonReadable = 2; @@ -143,7 +145,7 @@ void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t entry) { } void DexFilesTest::WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev, - uint32_t dex_file) { + uint32_t dex_file, uint64_t dex_size) { // Format of the 32 bit DEXFileEntry structure: // uint32_t next memory_->SetData32(entry_addr, next); @@ -153,11 +155,11 @@ void DexFilesTest::WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t pre memory_->SetData32(entry_addr + 8, dex_file); // uint32_t dex_size (present in the struct, but we ignore it) memory_->SetData32(entry_addr + 12, 0); // Align. - memory_->SetData64(entry_addr + 16, 0); + memory_->SetData64(entry_addr + 16, dex_size); } void DexFilesTest::WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev, - uint64_t dex_file) { + uint64_t dex_file, uint64_t dex_size) { // Format of the 64 bit DEXFileEntry structure: // uint64_t next memory_->SetData64(entry_addr, next); @@ -166,7 +168,7 @@ void DexFilesTest::WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t pre // uint64_t dex_file memory_->SetData64(entry_addr + 16, dex_file); // uint32_t dex_size (present in the struct, but we ignore it) - memory_->SetData64(entry_addr + 24, 0); + memory_->SetData64(entry_addr + 24, dex_size); } void DexFilesTest::WriteDex(uint64_t dex_file) { @@ -187,7 +189,7 @@ TEST_F(DexFilesTest, get_method_information_32) { uint64_t method_offset = 0x124; WriteDescriptor32(0x100800, 0x200000); - WriteEntry32(0x200000, 0, 0, 0x300000); + WriteEntry32(0x200000, 0, 0, 0x300000, sizeof(kDexData)); WriteDex(0x300000); dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); @@ -202,7 +204,7 @@ TEST_F(DexFilesTest, get_method_information_64) { uint64_t method_offset = 0x124; WriteDescriptor64(0x100800, 0x200000); - WriteEntry64(0x200000, 0, 0, 0x301000); + WriteEntry64(0x200000, 0, 0, 0x301000, sizeof(kDexData)); WriteDex(0x301000); dex_files_->GetFunctionName(maps_.get(), 0x301102, &method_name, &method_offset); @@ -215,8 +217,8 @@ TEST_F(DexFilesTest, get_method_information_not_first_entry_32) { uint64_t method_offset = 0x124; WriteDescriptor32(0x100800, 0x200000); - WriteEntry32(0x200000, 0x200100, 0, 0x100000); - WriteEntry32(0x200100, 0, 0x200000, 0x300000); + WriteEntry32(0x200000, 0x200100, 0, 0x100000, sizeof(kDexData)); + WriteEntry32(0x200100, 0, 0x200000, 0x300000, sizeof(kDexData)); WriteDex(0x300000); dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset); @@ -231,8 +233,8 @@ TEST_F(DexFilesTest, get_method_information_not_first_entry_64) { uint64_t method_offset = 0x124; WriteDescriptor64(0x100800, 0x200000); - WriteEntry64(0x200000, 0x200100, 0, 0x100000); - WriteEntry64(0x200100, 0, 0x200000, 0x300000); + WriteEntry64(0x200000, 0x200100, 0, 0x100000, sizeof(kDexData)); + WriteEntry64(0x200100, 0, 0x200000, 0x300000, sizeof(kDexData)); WriteDex(0x300000); dex_files_->GetFunctionName(maps_.get(), 0x300106, &method_name, &method_offset); @@ -245,7 +247,7 @@ TEST_F(DexFilesTest, get_method_information_cached) { uint64_t method_offset = 0x124; WriteDescriptor32(0x100800, 0x200000); - WriteEntry32(0x200000, 0, 0, 0x300000); + WriteEntry32(0x200000, 0, 0, 0x300000, sizeof(kDexData)); WriteDex(0x300000); dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); @@ -264,8 +266,8 @@ TEST_F(DexFilesTest, get_method_information_search_libs) { uint64_t method_offset = 0x124; WriteDescriptor32(0x100800, 0x200000); - WriteEntry32(0x200000, 0x200100, 0, 0x100000); - WriteEntry32(0x200100, 0, 0x200000, 0x300000); + WriteEntry32(0x200000, 0x200100, 0, 0x100000, sizeof(kDexData)); + WriteEntry32(0x200100, 0, 0x200000, 0x300000, sizeof(kDexData)); WriteDex(0x300000); // Only search a given named list of libs. @@ -299,7 +301,7 @@ TEST_F(DexFilesTest, get_method_information_global_skip_zero_32) { WriteDescriptor32(0xc800, 0); WriteDescriptor32(0x100800, 0x200000); - WriteEntry32(0x200000, 0, 0, 0x300000); + WriteEntry32(0x200000, 0, 0, 0x300000, sizeof(kDexData)); WriteDex(0x300000); dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); @@ -326,7 +328,7 @@ TEST_F(DexFilesTest, get_method_information_global_skip_zero_64) { WriteDescriptor64(0xc800, 0); WriteDescriptor64(0x100800, 0x200000); - WriteEntry64(0x200000, 0, 0, 0x300000); + WriteEntry64(0x200000, 0, 0, 0x300000, sizeof(kDexData)); WriteDex(0x300000); dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset); @@ -348,7 +350,7 @@ TEST_F(DexFilesTest, get_method_information_with_empty_map) { uint64_t method_offset = 0x124; WriteDescriptor32(0x503800, 0x506000); - WriteEntry32(0x506000, 0, 0, 0x510000); + WriteEntry32(0x506000, 0, 0, 0x510000, sizeof(kDexData)); WriteDex(0x510000); dex_files_->GetFunctionName(maps_.get(), 0x510100, &method_name, &method_offset); |