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/ObjectFile/PECOFF/TestPECallFrameInfo.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/ObjectFile/PECOFF/TestPECallFrameInfo.cpp')
-rw-r--r-- | gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp b/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp new file mode 100644 index 00000000000..4e9182ec6a2 --- /dev/null +++ b/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp @@ -0,0 +1,328 @@ +//===-- TestPECallFrameInfo.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 "gtest/gtest.h" + +#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" +#include "Plugins/Process/Utility/lldb-x86-register-enums.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" + +#include "lldb/Core/Module.h" +#include "lldb/Symbol/CallFrameInfo.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "llvm/Testing/Support/Error.h" + +using namespace lldb_private; +using namespace lldb; + +class PECallFrameInfoTest : public testing::Test { + SubsystemRAII<FileSystem, ObjectFilePECOFF> subsystems; + +protected: + void GetUnwindPlan(addr_t file_addr, UnwindPlan &plan) const; +}; + +void PECallFrameInfoTest::GetUnwindPlan(addr_t file_addr, UnwindPlan &plan) const { + llvm::Expected<TestFile> ExpectedFile = TestFile::fromYaml( + R"( +--- !COFF +OptionalHeader: + AddressOfEntryPoint: 0 + ImageBase: 16777216 + SectionAlignment: 4096 + FileAlignment: 512 + MajorOperatingSystemVersion: 6 + MinorOperatingSystemVersion: 0 + MajorImageVersion: 0 + MinorImageVersion: 0 + MajorSubsystemVersion: 6 + MinorSubsystemVersion: 0 + Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI + DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ] + SizeOfStackReserve: 1048576 + SizeOfStackCommit: 4096 + SizeOfHeapReserve: 1048576 + SizeOfHeapCommit: 4096 + ExportTable: + RelativeVirtualAddress: 0 + Size: 0 + ImportTable: + RelativeVirtualAddress: 0 + Size: 0 + ResourceTable: + RelativeVirtualAddress: 0 + Size: 0 + ExceptionTable: + RelativeVirtualAddress: 12288 + Size: 60 + CertificateTable: + RelativeVirtualAddress: 0 + Size: 0 + BaseRelocationTable: + RelativeVirtualAddress: 0 + Size: 0 + Debug: + RelativeVirtualAddress: 0 + Size: 0 + Architecture: + RelativeVirtualAddress: 0 + Size: 0 + GlobalPtr: + RelativeVirtualAddress: 0 + Size: 0 + TlsTable: + RelativeVirtualAddress: 0 + Size: 0 + LoadConfigTable: + RelativeVirtualAddress: 0 + Size: 0 + BoundImport: + RelativeVirtualAddress: 0 + Size: 0 + IAT: + RelativeVirtualAddress: 0 + Size: 0 + DelayImportDescriptor: + RelativeVirtualAddress: 0 + Size: 0 + ClrRuntimeHeader: + RelativeVirtualAddress: 0 + Size: 0 +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 4096 + VirtualSize: 4096 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 8192 + VirtualSize: 68 + SectionData: 010C06000C3208F006E00470036002302105020005540D0000100000001100000020000019400E352F74670028646600213465001A3315015E000EF00CE00AD008C00650 + + +# Unwind info at 0x2000: +# 01 0C 06 00 No chained info, prolog size = 0xC, unwind codes size is 6 words, no frame register +# 0C 32 UOP_AllocSmall(2) 3 * 8 + 8 bytes, offset in prolog is 0xC +# 08 F0 UOP_PushNonVol(0) R15(0xF), offset in prolog is 8 +# 06 E0 UOP_PushNonVol(0) R14(0xE), offset in prolog is 6 +# 04 70 UOP_PushNonVol(0) RDI(7), offset in prolog is 4 +# 03 60 UOP_PushNonVol(0) RSI(6), offset in prolog is 3 +# 02 30 UOP_PushNonVol(0) RBX(3), offset in prolog is 2 +# Corresponding prolog: +# 00 push rbx
+# 02 push rsi
+# 03 push rdi
+# 04 push r14
+# 06 push r15
+# 08 sub rsp, 20h
+ +# Unwind info at 0x2010: +# 21 05 02 00 Has chained info, prolog size = 5, unwind codes size is 2 words, no frame register +# 05 54 0D 00 UOP_SaveNonVol(4) RBP(5) to RSP + 0xD * 8, offset in prolog is 5 +# Chained runtime function: +# 00 10 00 00 Start address is 0x1000 +# 00 11 00 00 End address is 0x1100 +# 00 20 00 00 Unwind info RVA is 0x2000 +# Corresponding prolog: +# 00 mov [rsp+68h], rbp + +# Unwind info at 0x2024: +# 19 40 0E 35 No chained info, prolog size = 0x40, unwind codes size is 0xE words, frame register is RBP, frame register offset is RSP + 3 * 16 +# 2F 74 67 00 UOP_SaveNonVol(4) RDI(7) to RSP + 0x67 * 8, offset in prolog is 0x2F +# 28 64 66 00 UOP_SaveNonVol(4) RSI(6) to RSP + 0x66 * 8, offset in prolog is 0x28 +# 21 34 65 00 UOP_SaveNonVol(4) RBX(3) to RSP + 0x65 * 8, offset in prolog is 0x21 +# 1A 33 UOP_SetFPReg(3), offset in prolog is 0x1A +# 15 01 5E 00 UOP_AllocLarge(1) 0x5E * 8 bytes, offset in prolog is 0x15 +# 0E F0 UOP_PushNonVol(0) R15(0xF), offset in prolog is 0xE +# 0C E0 UOP_PushNonVol(0) R14(0xE), offset in prolog is 0xC +# 0A D0 UOP_PushNonVol(0) R13(0xD), offset in prolog is 0xA +# 08 C0 UOP_PushNonVol(0) R12(0xC), offset in prolog is 8 +# 06 50 UOP_PushNonVol(0) RBP(5), offset in prolog is 6 +# Corresponding prolog: +# 00 mov [rsp+8], rcx
+# 05 push rbp
+# 06 push r12
+# 08 push r13
+# 0A push r14
+# 0C push r15
+# 0E sub rsp, 2F0h
+# 15 lea rbp, [rsp+30h]
+# 1A mov [rbp+2F8h], rbx
+# 21 mov [rbp+300h], rsi
+# 28 mov [rbp+308h], rdi
+ + - Name: .pdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 12288 + VirtualSize: 60 + SectionData: 000000000000000000000000000000000000000000000000001000000011000000200000001100000012000010200000001200000013000024200000 + +# 00 00 00 00 +# 00 00 00 00 Test correct processing of empty runtime functions at begin +# 00 00 00 00 + +# 00 00 00 00 +# 00 00 00 00 Test correct processing of empty runtime functions at begin +# 00 00 00 00 + +# 00 10 00 00 Start address is 0x1000 +# 00 11 00 00 End address is 0x1100 +# 00 20 00 00 Unwind info RVA is 0x2000 + +# 00 11 00 00 Start address is 0x1100 +# 00 12 00 00 End address is 0x1200 +# 10 20 00 00 Unwind info RVA is 0x2010 + +# 00 12 00 00 Start address is 0x1200 +# 00 13 00 00 End address is 0x1300 +# 24 20 00 00 Unwind info RVA is 0x2024 + +symbols: [] +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + ModuleSP module_sp = std::make_shared<Module>(ModuleSpec(FileSpec(ExpectedFile->name()))); + ObjectFile *object_file = module_sp->GetObjectFile(); + ASSERT_NE(object_file, nullptr); + + std::unique_ptr<CallFrameInfo> cfi = object_file->CreateCallFrameInfo(); + ASSERT_NE(cfi.get(), nullptr); + + SectionList *sect_list = object_file->GetSectionList(); + ASSERT_NE(sect_list, nullptr); + + EXPECT_TRUE(cfi->GetUnwindPlan(Address(file_addr, sect_list), plan)); +} + +TEST_F(PECallFrameInfoTest, Basic_eh) { + UnwindPlan plan(eRegisterKindLLDB); + GetUnwindPlan(0x1001080, plan); + EXPECT_EQ(plan.GetRowCount(), 7); + + UnwindPlan::Row row; + row.SetOffset(0); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 8); + row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true); + EXPECT_EQ(*plan.GetRowAtIndex(0), row); + + row.SetOffset(2); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x10); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, -0x10, true); + EXPECT_EQ(*plan.GetRowAtIndex(1), row); + + row.SetOffset(3); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x18); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, -0x18, true); + EXPECT_EQ(*plan.GetRowAtIndex(2), row); + + row.SetOffset(4); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x20); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, -0x20, true); + EXPECT_EQ(*plan.GetRowAtIndex(3), row); + + row.SetOffset(6); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x28); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true); + EXPECT_EQ(*plan.GetRowAtIndex(4), row); + + row.SetOffset(8); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x30); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true); + EXPECT_EQ(*plan.GetRowAtIndex(5), row); + + row.SetOffset(0xC); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x50); + EXPECT_EQ(*plan.GetRowAtIndex(6), row); +} + +TEST_F(PECallFrameInfoTest, Chained_eh) { + UnwindPlan plan(eRegisterKindLLDB); + GetUnwindPlan(0x1001180, plan); + EXPECT_EQ(plan.GetRowCount(), 2); + + UnwindPlan::Row row; + row.SetOffset(0); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x50); + row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, -0x10, true); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, -0x18, true); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, -0x20, true); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true); + EXPECT_EQ(*plan.GetRowAtIndex(0), row); + + row.SetOffset(5); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbp_x86_64, 0x18, true); + EXPECT_EQ(*plan.GetRowAtIndex(1), row); +} + +TEST_F(PECallFrameInfoTest, Frame_reg_eh) { + UnwindPlan plan(eRegisterKindLLDB); + GetUnwindPlan(0x1001280, plan); + EXPECT_EQ(plan.GetRowCount(), 11); + + UnwindPlan::Row row; + row.SetOffset(0); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 8); + row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true); + EXPECT_EQ(*plan.GetRowAtIndex(0), row); + + row.SetOffset(6); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x10); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbp_x86_64, -0x10, true); + EXPECT_EQ(*plan.GetRowAtIndex(1), row); + + row.SetOffset(8); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x18); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_r12_x86_64, -0x18, true); + EXPECT_EQ(*plan.GetRowAtIndex(2), row); + + row.SetOffset(0xA); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x20); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_r13_x86_64, -0x20, true); + EXPECT_EQ(*plan.GetRowAtIndex(3), row); + + row.SetOffset(0xC); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x28); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true); + EXPECT_EQ(*plan.GetRowAtIndex(4), row); + + row.SetOffset(0xE); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x30); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true); + EXPECT_EQ(*plan.GetRowAtIndex(5), row); + + row.SetOffset(0x15); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x320); + EXPECT_EQ(*plan.GetRowAtIndex(6), row); + + row.SetOffset(0x1A); + row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rbp_x86_64, 0x2F0); + EXPECT_EQ(*plan.GetRowAtIndex(7), row); + + row.SetOffset(0x21); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, 8, true); + EXPECT_EQ(*plan.GetRowAtIndex(8), row); + + row.SetOffset(0x28); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, 0x10, true); + EXPECT_EQ(*plan.GetRowAtIndex(9), row); + + row.SetOffset(0x2F); + row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, 0x18, true); + EXPECT_EQ(*plan.GetRowAtIndex(10), row); +} |