diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp')
-rw-r--r-- | gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp b/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp new file mode 100644 index 00000000000..9e91464c441 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp @@ -0,0 +1,155 @@ +//===-- NativeProcessELFTest.cpp --------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TestingSupport/Host/NativeProcessTestUtils.h" + +#include "Plugins/Process/POSIX/NativeProcessELF.h" +#include "Plugins/Process/Utility/AuxVector.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataEncoder.h" +#include "lldb/Utility/DataExtractor.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/Support/MemoryBuffer.h" + +#include "gmock/gmock.h" + +using namespace lldb_private; +using namespace lldb; +using namespace testing; + +namespace { +class MockProcessELF : public MockProcess<NativeProcessELF> { +public: + using MockProcess::MockProcess; + using NativeProcessELF::GetAuxValue; + using NativeProcessELF::GetELFImageInfoAddress; +}; + +std::unique_ptr<llvm::MemoryBuffer> CreateAuxvData( + MockProcessELF &process, + llvm::ArrayRef<std::pair<AuxVector::EntryType, uint32_t>> auxv_data) { + auto addr_size = process.GetAddressByteSize(); + DataBufferSP buffer_sp( + new DataBufferHeap(auxv_data.size() * addr_size * 2, 0)); + DataEncoder encoder(buffer_sp, process.GetByteOrder(), addr_size); + uint32_t offset = 0; + for (auto &pair : auxv_data) { + offset = encoder.PutAddress(offset, pair.first); + offset = encoder.PutAddress(offset, pair.second); + } + return llvm::MemoryBuffer::getMemBufferCopy( + llvm::toStringRef(buffer_sp->GetData()), ""); +} + +} // namespace + +TEST(NativeProcessELFTest, GetAuxValue) { + NiceMock<MockDelegate> DummyDelegate; + MockProcessELF process(DummyDelegate, ArchSpec("i386-pc-linux")); + + uint64_t phdr_addr = 0x42; + auto auxv_buffer = CreateAuxvData( + process, {std::make_pair(AuxVector::AUXV_AT_PHDR, phdr_addr)}); + EXPECT_CALL(process, GetAuxvData()) + .WillOnce(Return(ByMove(std::move(auxv_buffer)))); + + ASSERT_EQ(phdr_addr, process.GetAuxValue(AuxVector::AUXV_AT_PHDR)); +} + +TEST(NativeProcessELFTest, GetELFImageInfoAddress) { + NiceMock<MockDelegate> DummyDelegate; + MockProcessELF process(DummyDelegate, ArchSpec("i386-pc-linux")); + + uint32_t load_base = 0x1000; + uint32_t info_addr = 0x3741; + uint32_t phdr_addr = load_base + sizeof(llvm::ELF::Elf32_Ehdr); + + auto auxv_buffer = CreateAuxvData( + process, + {std::make_pair(AuxVector::AUXV_AT_PHDR, phdr_addr), + std::make_pair(AuxVector::AUXV_AT_PHENT, sizeof(llvm::ELF::Elf32_Phdr)), + std::make_pair(AuxVector::AUXV_AT_PHNUM, 2)}); + EXPECT_CALL(process, GetAuxvData()) + .WillOnce(Return(ByMove(std::move(auxv_buffer)))); + + // We're going to set up a fake memory with 2 program headers and 1 entry in + // the dynamic section. For simplicity sake they will be contiguous in memory. + struct MemoryContents { + llvm::ELF::Elf32_Phdr phdr_load; + llvm::ELF::Elf32_Phdr phdr_dynamic; + llvm::ELF::Elf32_Dyn dyn_debug; + } MC; + // Setup the 2 program header entries + MC.phdr_load.p_type = llvm::ELF::PT_PHDR; + MC.phdr_load.p_vaddr = phdr_addr - load_base; + + MC.phdr_dynamic.p_type = llvm::ELF::PT_DYNAMIC; + MC.phdr_dynamic.p_vaddr = + (phdr_addr + 2 * sizeof(llvm::ELF::Elf32_Phdr)) - load_base; + MC.phdr_dynamic.p_memsz = sizeof(llvm::ELF::Elf32_Dyn); + + // Setup the single entry in the .dynamic section + MC.dyn_debug.d_tag = llvm::ELF::DT_DEBUG; + MC.dyn_debug.d_un.d_ptr = info_addr; + + FakeMemory M(&MC, sizeof(MC), phdr_addr); + EXPECT_CALL(process, ReadMemory(_, _)) + .WillRepeatedly(Invoke(&M, &FakeMemory::Read)); + + lldb::addr_t elf_info_addr = process.GetELFImageInfoAddress< + llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr, llvm::ELF::Elf32_Dyn>(); + + // Read the address at the elf_info_addr location to make sure we're reading + // the correct one. + lldb::offset_t info_addr_offset = elf_info_addr - phdr_addr; + DataExtractor mem_extractor(&MC, sizeof(MC), process.GetByteOrder(), + process.GetAddressByteSize()); + ASSERT_EQ(mem_extractor.GetAddress(&info_addr_offset), info_addr); +} + +TEST(NativeProcessELFTest, GetELFImageInfoAddress_NoDebugEntry) { + NiceMock<MockDelegate> DummyDelegate; + MockProcessELF process(DummyDelegate, ArchSpec("i386-pc-linux")); + + uint32_t phdr_addr = sizeof(llvm::ELF::Elf32_Ehdr); + + auto auxv_buffer = CreateAuxvData( + process, + {std::make_pair(AuxVector::AUXV_AT_PHDR, phdr_addr), + std::make_pair(AuxVector::AUXV_AT_PHENT, sizeof(llvm::ELF::Elf32_Phdr)), + std::make_pair(AuxVector::AUXV_AT_PHNUM, 2)}); + EXPECT_CALL(process, GetAuxvData()) + .WillOnce(Return(ByMove(std::move(auxv_buffer)))); + + // We're going to set up a fake memory with 2 program headers and 1 entry in + // the dynamic section. For simplicity sake they will be contiguous in memory. + struct MemoryContents { + llvm::ELF::Elf32_Phdr phdr_load; + llvm::ELF::Elf32_Phdr phdr_dynamic; + llvm::ELF::Elf32_Dyn dyn_notdebug; + } MC; + // Setup the 2 program header entries + MC.phdr_load.p_type = llvm::ELF::PT_PHDR; + MC.phdr_load.p_vaddr = phdr_addr; + + MC.phdr_dynamic.p_type = llvm::ELF::PT_DYNAMIC; + MC.phdr_dynamic.p_vaddr = (phdr_addr + 2 * sizeof(llvm::ELF::Elf32_Phdr)); + MC.phdr_dynamic.p_memsz = sizeof(llvm::ELF::Elf32_Dyn); + + // Setup the single entry in the .dynamic section + MC.dyn_notdebug.d_tag = llvm::ELF::DT_NULL; + + FakeMemory M(&MC, sizeof(MC), phdr_addr); + EXPECT_CALL(process, ReadMemory(_, _)) + .WillRepeatedly(Invoke(&M, &FakeMemory::Read)); + + lldb::addr_t elf_info_addr = process.GetELFImageInfoAddress< + llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr, llvm::ELF::Elf32_Dyn>(); + + ASSERT_EQ(elf_info_addr, LLDB_INVALID_ADDRESS); +} |