summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 14:33:06 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 14:33:06 +0000
commit061da546b983eb767bad15e67af1174fb0bcf31c (patch)
tree83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp
parentImport LLVM 10.0.0 release including clang, lld and lldb. (diff)
downloadwireguard-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.cpp155
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);
+}