diff options
author | Baligh Uddin <baligh@google.com> | 2020-10-09 04:52:00 +0000 |
---|---|---|
committer | Baligh Uddin <baligh@google.com> | 2020-10-16 15:46:24 +0000 |
commit | ce7b63697ea8fad79ce9ec444dd0b19ee880f046 (patch) | |
tree | 3ca71216cdb3c58a5d9607d5edcfcb707df1ae50 /libunwindstack/tests/MapInfoCreateMemoryTest.cpp | |
parent | b5e565d29b2185ff36d9f96f0477e397f9eb614b (diff) |
Remove libprocinfo, libbacktrace, libunwindstack
These projects have moved to a different location.
platform/system/core [libprocinfo] -> platform/system/libprocinfo
platform/system/core [libbacktrace] -> platform/system/unwinding [libbacktrace]
platform/system/core [libunwindstack] -> platform/system/unwinding [libunwindstack]
BUG: 163786882
Test: Local build + TH
Change-Id: Id6d278d917236df0ffd40b5c32593856e112cb5b
Diffstat (limited to 'libunwindstack/tests/MapInfoCreateMemoryTest.cpp')
-rw-r--r-- | libunwindstack/tests/MapInfoCreateMemoryTest.cpp | 414 |
1 files changed, 0 insertions, 414 deletions
diff --git a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp deleted file mode 100644 index 6d8d58e55..000000000 --- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <elf.h> -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/ptrace.h> -#include <sys/types.h> -#include <unistd.h> - -#include <memory> -#include <vector> - -#include <android-base/file.h> -#include <gtest/gtest.h> - -#include <unwindstack/Elf.h> -#include <unwindstack/MapInfo.h> -#include <unwindstack/Maps.h> -#include <unwindstack/Memory.h> - -#include "ElfTestUtils.h" -#include "MemoryFake.h" - -namespace unwindstack { - -class MapInfoCreateMemoryTest : public ::testing::Test { - protected: - template <typename Ehdr, typename Shdr> - static void InitElf(int fd, uint64_t file_offset, uint64_t sh_offset, uint8_t class_type) { - std::vector<uint8_t> buffer(20000); - memset(buffer.data(), 0, buffer.size()); - - Ehdr ehdr; - memset(&ehdr, 0, sizeof(ehdr)); - memcpy(ehdr.e_ident, ELFMAG, SELFMAG); - ehdr.e_ident[EI_CLASS] = class_type; - ehdr.e_shoff = sh_offset; - ehdr.e_shentsize = sizeof(Shdr) + 100; - ehdr.e_shnum = 4; - memcpy(&buffer[file_offset], &ehdr, sizeof(ehdr)); - - ASSERT_TRUE(android::base::WriteFully(fd, buffer.data(), buffer.size())); - } - - void SetUp() override { - std::vector<uint8_t> buffer(12288, 0); - memcpy(buffer.data(), ELFMAG, SELFMAG); - buffer[EI_CLASS] = ELFCLASS32; - ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), 1024)); - - memset(buffer.data(), 0, buffer.size()); - memcpy(&buffer[0x1000], ELFMAG, SELFMAG); - buffer[0x1000 + EI_CLASS] = ELFCLASS64; - buffer[0x2000] = 0xff; - ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, buffer.data(), buffer.size())); - - InitElf<Elf32_Ehdr, Elf32_Shdr>(elf32_at_map_.fd, 0x1000, 0x2000, ELFCLASS32); - InitElf<Elf64_Ehdr, Elf64_Shdr>(elf64_at_map_.fd, 0x2000, 0x3000, ELFCLASS64); - - memory_ = new MemoryFake; - process_memory_.reset(memory_); - } - - MemoryFake* memory_; - std::shared_ptr<Memory> process_memory_; - - TemporaryFile elf_; - - TemporaryFile elf_at_1000_; - - TemporaryFile elf32_at_map_; - TemporaryFile elf64_at_map_; -}; - -TEST_F(MapInfoCreateMemoryTest, end_le_start) { - MapInfo info(nullptr, nullptr, 0x100, 0x100, 0, 0, elf_.path); - - std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() == nullptr); - - info.end = 0xff; - memory.reset(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() == nullptr); - - // Make sure this test is valid. - info.end = 0x101; - memory.reset(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); -} - -// Verify that if the offset is non-zero but there is no elf at the offset, -// that the full file is used. -TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_full_file) { - MapInfo info(nullptr, nullptr, 0x100, 0x200, 0x100, 0, elf_.path); - - std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); - ASSERT_EQ(0x100U, info.elf_offset); - EXPECT_EQ(0x100U, info.elf_start_offset); - - // Read the entire file. - std::vector<uint8_t> buffer(1024); - ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 1024)); - ASSERT_TRUE(memcmp(buffer.data(), ELFMAG, SELFMAG) == 0); - ASSERT_EQ(ELFCLASS32, buffer[EI_CLASS]); - for (size_t i = EI_CLASS + 1; i < buffer.size(); i++) { - ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i; - } - - ASSERT_FALSE(memory->ReadFully(1024, buffer.data(), 1)); - - // Now verify the elf start offset is set correctly based on the previous - // info. - MapInfo prev_info(nullptr, nullptr, 0, 0x100, 0x10, 0, ""); - info.prev_map = &prev_info; - info.prev_real_map = &prev_info; - - // No preconditions met, change each one until it should set the elf start - // offset to zero. - info.elf_offset = 0; - info.elf_start_offset = 0; - info.memory_backed_elf = false; - memory.reset(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); - ASSERT_EQ(0x100U, info.elf_offset); - EXPECT_EQ(0x100U, info.elf_start_offset); - - prev_info.offset = 0; - info.elf_offset = 0; - info.elf_start_offset = 0; - info.memory_backed_elf = false; - memory.reset(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); - ASSERT_EQ(0x100U, info.elf_offset); - EXPECT_EQ(0x100U, info.elf_start_offset); - - prev_info.flags = PROT_READ; - info.elf_offset = 0; - info.elf_start_offset = 0; - info.memory_backed_elf = false; - memory.reset(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); - ASSERT_EQ(0x100U, info.elf_offset); - EXPECT_EQ(0x100U, info.elf_start_offset); - - prev_info.name = info.name; - info.elf_offset = 0; - info.elf_start_offset = 0; - info.memory_backed_elf = false; - memory.reset(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); - ASSERT_EQ(0x100U, info.elf_offset); - EXPECT_EQ(0U, info.elf_start_offset); -} - -// Verify that if the offset is non-zero and there is an elf at that -// offset, that only part of the file is used. -TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file) { - MapInfo info(nullptr, nullptr, 0x100, 0x200, 0x1000, 0, elf_at_1000_.path); - - std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); - ASSERT_EQ(0U, info.elf_offset); - EXPECT_EQ(0x1000U, info.elf_start_offset); - - // Read the valid part of the file. - std::vector<uint8_t> buffer(0x100); - ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 0x100)); - ASSERT_TRUE(memcmp(buffer.data(), ELFMAG, SELFMAG) == 0); - ASSERT_EQ(ELFCLASS64, buffer[EI_CLASS]); - for (size_t i = EI_CLASS + 1; i < buffer.size(); i++) { - ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i; - } - - ASSERT_FALSE(memory->ReadFully(0x100, buffer.data(), 1)); -} - -// Verify that if the offset is non-zero and there is an elf at that -// offset, that only part of the file is used. Further verify that if the -// embedded elf is bigger than the initial map, the new object is larger -// than the original map size. Do this for a 32 bit elf and a 64 bit elf. -TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_elf32) { - MapInfo info(nullptr, nullptr, 0x5000, 0x6000, 0x1000, 0, elf32_at_map_.path); - - std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); - ASSERT_EQ(0U, info.elf_offset); - EXPECT_EQ(0x1000U, info.elf_start_offset); - - // Verify the memory is a valid elf. - uint8_t e_ident[SELFMAG + 1]; - ASSERT_TRUE(memory->ReadFully(0, e_ident, SELFMAG)); - ASSERT_EQ(0, memcmp(e_ident, ELFMAG, SELFMAG)); - - // Read past the end of what would normally be the size of the map. - ASSERT_TRUE(memory->ReadFully(0x1000, e_ident, 1)); -} - -TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_elf64) { - MapInfo info(nullptr, nullptr, 0x7000, 0x8000, 0x2000, 0, elf64_at_map_.path); - - std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(info.memory_backed_elf); - ASSERT_EQ(0U, info.elf_offset); - EXPECT_EQ(0x2000U, info.elf_start_offset); - - // Verify the memory is a valid elf. - uint8_t e_ident[SELFMAG + 1]; - ASSERT_TRUE(memory->ReadFully(0, e_ident, SELFMAG)); - ASSERT_EQ(0, memcmp(e_ident, ELFMAG, SELFMAG)); - - // Read past the end of what would normally be the size of the map. - ASSERT_TRUE(memory->ReadFully(0x1000, e_ident, 1)); -} - -// Verify that device file names will never result in Memory object creation. -TEST_F(MapInfoCreateMemoryTest, check_device_maps) { - // Set up some memory so that a valid local memory object would - // be returned if the file mapping fails, but the device check is incorrect. - std::vector<uint8_t> buffer(1024); - uint64_t start = reinterpret_cast<uint64_t>(buffer.data()); - MapInfo info(nullptr, nullptr, start, start + buffer.size(), 0, 0x8000, "/dev/something"); - - std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() == nullptr); -} - -TEST_F(MapInfoCreateMemoryTest, process_memory) { - MapInfo info(nullptr, nullptr, 0x2000, 0x3000, 0, PROT_READ, ""); - - Elf32_Ehdr ehdr = {}; - TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM); - std::vector<uint8_t> buffer(1024); - memcpy(buffer.data(), &ehdr, sizeof(ehdr)); - - // Verify that the the process_memory object is used, so seed it - // with memory. - for (size_t i = sizeof(ehdr); i < buffer.size(); i++) { - buffer[i] = i % 256; - } - memory_->SetMemory(info.start, buffer.data(), buffer.size()); - - std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_TRUE(info.memory_backed_elf); - - memset(buffer.data(), 0, buffer.size()); - ASSERT_TRUE(memory->ReadFully(0, buffer.data(), buffer.size())); - ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr))); - for (size_t i = sizeof(ehdr); i < buffer.size(); i++) { - ASSERT_EQ(i % 256, buffer[i]) << "Failed at byte " << i; - } - - // Try to read outside of the map size. - ASSERT_FALSE(memory->ReadFully(buffer.size(), buffer.data(), 1)); -} - -TEST_F(MapInfoCreateMemoryTest, valid_rosegment_zero_offset) { - Maps maps; - maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0); - maps.Add(0x1000, 0x2600, 0, PROT_READ, "/only/in/memory.so", 0); - maps.Add(0x3000, 0x5000, 0x4000, PROT_READ | PROT_EXEC, "/only/in/memory.so", 0); - - Elf32_Ehdr ehdr = {}; - TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM); - memory_->SetMemory(0x1000, &ehdr, sizeof(ehdr)); - memory_->SetMemoryBlock(0x1000 + sizeof(ehdr), 0x1600 - sizeof(ehdr), 0xab); - - // Set the memory in the r-x map. - memory_->SetMemoryBlock(0x3000, 0x2000, 0x5d); - - MapInfo* map_info = maps.Find(0x3000); - ASSERT_TRUE(map_info != nullptr); - - std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_)); - ASSERT_TRUE(mem.get() != nullptr); - EXPECT_TRUE(map_info->memory_backed_elf); - EXPECT_EQ(0x4000UL, map_info->elf_offset); - EXPECT_EQ(0x4000UL, map_info->offset); - EXPECT_EQ(0U, map_info->elf_start_offset); - - // Verify that reading values from this memory works properly. - std::vector<uint8_t> buffer(0x4000); - size_t bytes = mem->Read(0, buffer.data(), buffer.size()); - ASSERT_EQ(0x1600UL, bytes); - ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr))); - for (size_t i = sizeof(ehdr); i < bytes; i++) { - ASSERT_EQ(0xab, buffer[i]) << "Failed at byte " << i; - } - - bytes = mem->Read(0x4000, buffer.data(), buffer.size()); - ASSERT_EQ(0x2000UL, bytes); - for (size_t i = 0; i < bytes; i++) { - ASSERT_EQ(0x5d, buffer[i]) << "Failed at byte " << i; - } -} - -TEST_F(MapInfoCreateMemoryTest, valid_rosegment_non_zero_offset) { - Maps maps; - maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0); - maps.Add(0x1000, 0x2000, 0, PROT_READ, "/only/in/memory.apk", 0); - maps.Add(0x2000, 0x3000, 0x1000, PROT_READ | PROT_EXEC, "/only/in/memory.apk", 0); - maps.Add(0x3000, 0x4000, 0xa000, PROT_READ, "/only/in/memory.apk", 0); - maps.Add(0x4000, 0x5000, 0xb000, PROT_READ | PROT_EXEC, "/only/in/memory.apk", 0); - - Elf32_Ehdr ehdr = {}; - TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM); - - // Setup an elf at offset 0x1000 in memory. - memory_->SetMemory(0x1000, &ehdr, sizeof(ehdr)); - memory_->SetMemoryBlock(0x1000 + sizeof(ehdr), 0x2000 - sizeof(ehdr), 0x12); - memory_->SetMemoryBlock(0x2000, 0x1000, 0x23); - - // Setup an elf at offset 0x3000 in memory.. - memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr)); - memory_->SetMemoryBlock(0x3000 + sizeof(ehdr), 0x4000 - sizeof(ehdr), 0x34); - memory_->SetMemoryBlock(0x4000, 0x1000, 0x43); - - MapInfo* map_info = maps.Find(0x4000); - ASSERT_TRUE(map_info != nullptr); - - std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_)); - ASSERT_TRUE(mem.get() != nullptr); - EXPECT_TRUE(map_info->memory_backed_elf); - EXPECT_EQ(0x1000UL, map_info->elf_offset); - EXPECT_EQ(0xb000UL, map_info->offset); - EXPECT_EQ(0xa000UL, map_info->elf_start_offset); - - // Verify that reading values from this memory works properly. - std::vector<uint8_t> buffer(0x4000); - size_t bytes = mem->Read(0, buffer.data(), buffer.size()); - ASSERT_EQ(0x1000UL, bytes); - ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr))); - for (size_t i = sizeof(ehdr); i < bytes; i++) { - ASSERT_EQ(0x34, buffer[i]) << "Failed at byte " << i; - } - - bytes = mem->Read(0x1000, buffer.data(), buffer.size()); - ASSERT_EQ(0x1000UL, bytes); - for (size_t i = 0; i < bytes; i++) { - ASSERT_EQ(0x43, buffer[i]) << "Failed at byte " << i; - } -} - -TEST_F(MapInfoCreateMemoryTest, rosegment_from_file) { - Maps maps; - maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0); - maps.Add(0x1000, 0x2000, 0x1000, PROT_READ, elf_at_1000_.path, 0); - maps.Add(0x2000, 0x3000, 0x2000, PROT_READ | PROT_EXEC, elf_at_1000_.path, 0); - - MapInfo* map_info = maps.Find(0x2000); - ASSERT_TRUE(map_info != nullptr); - - // Set up the size - Elf64_Ehdr ehdr; - ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET)); - ASSERT_TRUE(android::base::ReadFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr))); - - // Will not give the elf memory, because the read-only entry does not - // extend over the executable segment. - std::unique_ptr<Memory> memory(map_info->CreateMemory(process_memory_)); - ASSERT_TRUE(memory.get() != nullptr); - EXPECT_FALSE(map_info->memory_backed_elf); - std::vector<uint8_t> buffer(0x100); - EXPECT_EQ(0x2000U, map_info->offset); - EXPECT_EQ(0U, map_info->elf_offset); - EXPECT_EQ(0U, map_info->elf_start_offset); - ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 0x100)); - EXPECT_EQ(0xffU, buffer[0]); - - // Now init the elf data enough so that the file memory object will be used. - ehdr.e_shoff = 0x4000; - ehdr.e_shnum = 1; - ehdr.e_shentsize = 0x100; - ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET)); - ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr))); - - map_info->memory_backed_elf = false; - memory.reset(map_info->CreateMemory(process_memory_)); - EXPECT_FALSE(map_info->memory_backed_elf); - EXPECT_EQ(0x2000U, map_info->offset); - EXPECT_EQ(0x1000U, map_info->elf_offset); - EXPECT_EQ(0x1000U, map_info->elf_start_offset); - Elf64_Ehdr ehdr_mem; - ASSERT_TRUE(memory->ReadFully(0, &ehdr_mem, sizeof(ehdr_mem))); - EXPECT_TRUE(memcmp(&ehdr, &ehdr_mem, sizeof(ehdr)) == 0); -} - -} // namespace unwindstack |