diff options
3 files changed, 230 insertions, 123 deletions
diff --git a/lldb/unittests/Process/minidump/CMakeLists.txt b/lldb/unittests/Process/minidump/CMakeLists.txt index 84071099bb7..699c7984490 100644 --- a/lldb/unittests/Process/minidump/CMakeLists.txt +++ b/lldb/unittests/Process/minidump/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_unittest(LLDBMinidumpTests MinidumpParserTest.cpp + RegisterContextMinidumpTest.cpp LINK_LIBS lldbCore diff --git a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp index c87889ed9a0..02480587518 100644 --- a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp +++ b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp @@ -6,13 +6,10 @@ // //===----------------------------------------------------------------------===// -#include "Plugins/Process/Utility/RegisterContextLinux_i386.h" -#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" #include "Plugins/Process/minidump/MinidumpParser.h" #include "Plugins/Process/minidump/MinidumpTypes.h" #include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h" #include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h" - #include "TestingSupport/TestUtilities.h" #include "lldb/Host/FileSystem.h" #include "lldb/Target/MemoryRegionInfo.h" @@ -490,138 +487,102 @@ TEST_F(MinidumpParserTest, GetModuleListWow64) { #define REG_VAL32(x) *(reinterpret_cast<uint32_t *>(x)) #define REG_VAL64(x) *(reinterpret_cast<uint64_t *>(x)) -TEST_F(MinidumpParserTest, ConvertMinidumpContext_x86_32) { +TEST_F(MinidumpParserTest, GetThreadContext_x86_32) { SetUpData("linux-i386.dmp"); llvm::ArrayRef<MinidumpThread> thread_list = parser->GetThreads(); const MinidumpThread thread = thread_list[0]; llvm::ArrayRef<uint8_t> registers(parser->GetThreadContext(thread)); - - ArchSpec arch = parser->GetArchitecture(); - auto reg_interface = llvm::make_unique<RegisterContextLinux_i386>(arch); - lldb::DataBufferSP buf = - ConvertMinidumpContext_x86_32(registers, reg_interface.get()); - ASSERT_EQ(reg_interface->GetGPRSize(), buf->GetByteSize()); - - const RegisterInfo *reg_info = reg_interface->GetRegisterInfo(); - - std::map<uint64_t, uint32_t> reg_values; - - reg_values[lldb_eax_i386] = 0x00000000; - reg_values[lldb_ebx_i386] = 0xf7778000; - reg_values[lldb_ecx_i386] = 0x00000001; - reg_values[lldb_edx_i386] = 0xff9dd4a3; - reg_values[lldb_edi_i386] = 0x080482a8; - reg_values[lldb_esi_i386] = 0xff9dd55c; - reg_values[lldb_ebp_i386] = 0xff9dd53c; - reg_values[lldb_esp_i386] = 0xff9dd52c; - reg_values[lldb_eip_i386] = 0x080482a0; - reg_values[lldb_eflags_i386] = 0x00010282; - reg_values[lldb_cs_i386] = 0x00000023; - reg_values[lldb_fs_i386] = 0x00000000; - reg_values[lldb_gs_i386] = 0x00000063; - reg_values[lldb_ss_i386] = 0x0000002b; - reg_values[lldb_ds_i386] = 0x0000002b; - reg_values[lldb_es_i386] = 0x0000002b; - - for (uint32_t reg_index = 0; reg_index < reg_interface->GetRegisterCount(); - ++reg_index) { - if (reg_values.find(reg_index) != reg_values.end()) { - EXPECT_EQ(reg_values[reg_index], - REG_VAL32(buf->GetBytes() + reg_info[reg_index].byte_offset)); - } - } -} - -TEST_F(MinidumpParserTest, ConvertMinidumpContext_x86_64) { + const MinidumpContext_x86_32 *context; + EXPECT_TRUE(consumeObject(registers, context).Success()); + + EXPECT_EQ(MinidumpContext_x86_32_Flags(uint32_t(context->context_flags)), + MinidumpContext_x86_32_Flags::x86_32_Flag | + MinidumpContext_x86_32_Flags::Full | + MinidumpContext_x86_32_Flags::FloatingPoint); + + EXPECT_EQ(0x00000000u, context->eax); + EXPECT_EQ(0xf7778000u, context->ebx); + EXPECT_EQ(0x00000001u, context->ecx); + EXPECT_EQ(0xff9dd4a3u, context->edx); + EXPECT_EQ(0x080482a8u, context->edi); + EXPECT_EQ(0xff9dd55cu, context->esi); + EXPECT_EQ(0xff9dd53cu, context->ebp); + EXPECT_EQ(0xff9dd52cu, context->esp); + EXPECT_EQ(0x080482a0u, context->eip); + EXPECT_EQ(0x00010282u, context->eflags); + EXPECT_EQ(0x0023u, context->cs); + EXPECT_EQ(0x0000u, context->fs); + EXPECT_EQ(0x0063u, context->gs); + EXPECT_EQ(0x002bu, context->ss); + EXPECT_EQ(0x002bu, context->ds); + EXPECT_EQ(0x002bu, context->es); +} + +TEST_F(MinidumpParserTest, GetThreadContext_x86_64) { SetUpData("linux-x86_64.dmp"); llvm::ArrayRef<MinidumpThread> thread_list = parser->GetThreads(); const MinidumpThread thread = thread_list[0]; llvm::ArrayRef<uint8_t> registers(parser->GetThreadContext(thread)); - - ArchSpec arch = parser->GetArchitecture(); - auto reg_interface = llvm::make_unique<RegisterContextLinux_x86_64>(arch); - lldb::DataBufferSP buf = - ConvertMinidumpContext_x86_64(registers, reg_interface.get()); - ASSERT_EQ(reg_interface->GetGPRSize(), buf->GetByteSize()); - - const RegisterInfo *reg_info = reg_interface->GetRegisterInfo(); - - std::map<uint64_t, uint64_t> reg_values; - - reg_values[lldb_rax_x86_64] = 0x0000000000000000; - reg_values[lldb_rbx_x86_64] = 0x0000000000000000; - reg_values[lldb_rcx_x86_64] = 0x0000000000000010; - reg_values[lldb_rdx_x86_64] = 0x0000000000000000; - reg_values[lldb_rdi_x86_64] = 0x00007ffceb349cf0; - reg_values[lldb_rsi_x86_64] = 0x0000000000000000; - reg_values[lldb_rbp_x86_64] = 0x00007ffceb34a210; - reg_values[lldb_rsp_x86_64] = 0x00007ffceb34a210; - reg_values[lldb_r8_x86_64] = 0x00007fe9bc1aa9c0; - reg_values[lldb_r9_x86_64] = 0x0000000000000000; - reg_values[lldb_r10_x86_64] = 0x00007fe9bc3f16a0; - reg_values[lldb_r11_x86_64] = 0x0000000000000246; - reg_values[lldb_r12_x86_64] = 0x0000000000401c92; - reg_values[lldb_r13_x86_64] = 0x00007ffceb34a430; - reg_values[lldb_r14_x86_64] = 0x0000000000000000; - reg_values[lldb_r15_x86_64] = 0x0000000000000000; - reg_values[lldb_rip_x86_64] = 0x0000000000401dc6; - reg_values[lldb_rflags_x86_64] = 0x0000000000010206; - reg_values[lldb_cs_x86_64] = 0x0000000000000033; - reg_values[lldb_fs_x86_64] = 0x0000000000000000; - reg_values[lldb_gs_x86_64] = 0x0000000000000000; - reg_values[lldb_ss_x86_64] = 0x0000000000000000; - reg_values[lldb_ds_x86_64] = 0x0000000000000000; - reg_values[lldb_es_x86_64] = 0x0000000000000000; - - for (uint32_t reg_index = 0; reg_index < reg_interface->GetRegisterCount(); - ++reg_index) { - if (reg_values.find(reg_index) != reg_values.end()) { - EXPECT_EQ(reg_values[reg_index], - REG_VAL64(buf->GetBytes() + reg_info[reg_index].byte_offset)); - } - } -} - -TEST_F(MinidumpParserTest, ConvertMinidumpContext_x86_32_wow64) { + const MinidumpContext_x86_64 *context; + EXPECT_TRUE(consumeObject(registers, context).Success()); + + EXPECT_EQ(MinidumpContext_x86_64_Flags(uint32_t(context->context_flags)), + MinidumpContext_x86_64_Flags::x86_64_Flag | + MinidumpContext_x86_64_Flags::Control | + MinidumpContext_x86_64_Flags::FloatingPoint | + MinidumpContext_x86_64_Flags::Integer); + EXPECT_EQ(0x0000000000000000u, context->rax); + EXPECT_EQ(0x0000000000000000u, context->rbx); + EXPECT_EQ(0x0000000000000010u, context->rcx); + EXPECT_EQ(0x0000000000000000u, context->rdx); + EXPECT_EQ(0x00007ffceb349cf0u, context->rdi); + EXPECT_EQ(0x0000000000000000u, context->rsi); + EXPECT_EQ(0x00007ffceb34a210u, context->rbp); + EXPECT_EQ(0x00007ffceb34a210u, context->rsp); + EXPECT_EQ(0x00007fe9bc1aa9c0u, context->r8); + EXPECT_EQ(0x0000000000000000u, context->r9); + EXPECT_EQ(0x00007fe9bc3f16a0u, context->r10); + EXPECT_EQ(0x0000000000000246u, context->r11); + EXPECT_EQ(0x0000000000401c92u, context->r12); + EXPECT_EQ(0x00007ffceb34a430u, context->r13); + EXPECT_EQ(0x0000000000000000u, context->r14); + EXPECT_EQ(0x0000000000000000u, context->r15); + EXPECT_EQ(0x0000000000401dc6u, context->rip); + EXPECT_EQ(0x00010206u, context->eflags); + EXPECT_EQ(0x0033u, context->cs); + EXPECT_EQ(0x0000u, context->ss); +} + +TEST_F(MinidumpParserTest, GetThreadContext_x86_32_wow64) { SetUpData("fizzbuzz_wow64.dmp"); llvm::ArrayRef<MinidumpThread> thread_list = parser->GetThreads(); const MinidumpThread thread = thread_list[0]; llvm::ArrayRef<uint8_t> registers(parser->GetThreadContextWow64(thread)); - - ArchSpec arch = parser->GetArchitecture(); - auto reg_interface = llvm::make_unique<RegisterContextLinux_i386>(arch); - lldb::DataBufferSP buf = - ConvertMinidumpContext_x86_32(registers, reg_interface.get()); - ASSERT_EQ(reg_interface->GetGPRSize(), buf->GetByteSize()); - - const RegisterInfo *reg_info = reg_interface->GetRegisterInfo(); - - std::map<uint64_t, uint32_t> reg_values; - - reg_values[lldb_eax_i386] = 0x00000000; - reg_values[lldb_ebx_i386] = 0x0037f608; - reg_values[lldb_ecx_i386] = 0x00e61578; - reg_values[lldb_edx_i386] = 0x00000008; - reg_values[lldb_edi_i386] = 0x00000000; - reg_values[lldb_esi_i386] = 0x00000002; - reg_values[lldb_ebp_i386] = 0x0037f654; - reg_values[lldb_esp_i386] = 0x0037f5b8; - reg_values[lldb_eip_i386] = 0x77ce01fd; - reg_values[lldb_eflags_i386] = 0x00000246; - reg_values[lldb_cs_i386] = 0x00000023; - reg_values[lldb_fs_i386] = 0x00000053; - reg_values[lldb_gs_i386] = 0x0000002b; - reg_values[lldb_ss_i386] = 0x0000002b; - reg_values[lldb_ds_i386] = 0x0000002b; - reg_values[lldb_es_i386] = 0x0000002b; - - for (uint32_t reg_index = 0; reg_index < reg_interface->GetRegisterCount(); - ++reg_index) { - if (reg_values.find(reg_index) != reg_values.end()) { - EXPECT_EQ(reg_values[reg_index], - REG_VAL32(buf->GetBytes() + reg_info[reg_index].byte_offset)); - } - } + const MinidumpContext_x86_32 *context; + EXPECT_TRUE(consumeObject(registers, context).Success()); + + EXPECT_EQ(MinidumpContext_x86_32_Flags(uint32_t(context->context_flags)), + MinidumpContext_x86_32_Flags::x86_32_Flag | + MinidumpContext_x86_32_Flags::Full | + MinidumpContext_x86_32_Flags::FloatingPoint | + MinidumpContext_x86_32_Flags::ExtendedRegisters); + + EXPECT_EQ(0x00000000u, context->eax); + EXPECT_EQ(0x0037f608u, context->ebx); + EXPECT_EQ(0x00e61578u, context->ecx); + EXPECT_EQ(0x00000008u, context->edx); + EXPECT_EQ(0x00000000u, context->edi); + EXPECT_EQ(0x00000002u, context->esi); + EXPECT_EQ(0x0037f654u, context->ebp); + EXPECT_EQ(0x0037f5b8u, context->esp); + EXPECT_EQ(0x77ce01fdu, context->eip); + EXPECT_EQ(0x00000246u, context->eflags); + EXPECT_EQ(0x0023u, context->cs); + EXPECT_EQ(0x0053u, context->fs); + EXPECT_EQ(0x002bu, context->gs); + EXPECT_EQ(0x002bu, context->ss); + EXPECT_EQ(0x002bu, context->ds); + EXPECT_EQ(0x002bu, context->es); } TEST_F(MinidumpParserTest, MinidumpDuplicateModuleMinAddress) { diff --git a/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp b/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp new file mode 100644 index 00000000000..adc65d4f88d --- /dev/null +++ b/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp @@ -0,0 +1,145 @@ +//===-- RegisterContextMinidumpTest.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 "Plugins/Process/Utility/RegisterContextLinux_i386.h" +#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" +#include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h" +#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h" +#include "lldb/Utility/DataBuffer.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb_private::minidump; + +static uint32_t reg32(const DataBuffer &Buf, const RegisterInfo &Info) { + return *reinterpret_cast<const uint32_t *>(Buf.GetBytes() + Info.byte_offset); +} + +static uint64_t reg64(const DataBuffer &Buf, const RegisterInfo &Info) { + return *reinterpret_cast<const uint64_t *>(Buf.GetBytes() + Info.byte_offset); +} + +TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_32) { + MinidumpContext_x86_32 Context; + Context.context_flags = + static_cast<uint32_t>(MinidumpContext_x86_32_Flags::x86_32_Flag | + MinidumpContext_x86_32_Flags::Control | + MinidumpContext_x86_32_Flags::Segments | + MinidumpContext_x86_32_Flags::Integer); + Context.eax = 0x00010203; + Context.ebx = 0x04050607; + Context.ecx = 0x08090a0b; + Context.edx = 0x0c0d0e0f; + Context.edi = 0x10111213; + Context.esi = 0x14151617; + Context.ebp = 0x18191a1b; + Context.esp = 0x1c1d1e1f; + Context.eip = 0x20212223; + Context.eflags = 0x24252627; + Context.cs = 0x2829; + Context.fs = 0x2a2b; + Context.gs = 0x2c2d; + Context.ss = 0x2e2f; + Context.ds = 0x3031; + Context.es = 0x3233; + llvm::ArrayRef<uint8_t> ContextRef(reinterpret_cast<uint8_t *>(&Context), + sizeof(Context)); + + ArchSpec arch("i386-pc-linux"); + auto RegInterface = llvm::make_unique<RegisterContextLinux_i386>(arch); + lldb::DataBufferSP Buf = + ConvertMinidumpContext_x86_32(ContextRef, RegInterface.get()); + ASSERT_EQ(RegInterface->GetGPRSize(), Buf->GetByteSize()); + + const RegisterInfo *Info = RegInterface->GetRegisterInfo(); + ASSERT_NE(nullptr, Info); + + EXPECT_EQ(Context.eax, reg32(*Buf, Info[lldb_eax_i386])); + EXPECT_EQ(Context.ebx, reg32(*Buf, Info[lldb_ebx_i386])); + EXPECT_EQ(Context.ecx, reg32(*Buf, Info[lldb_ecx_i386])); + EXPECT_EQ(Context.edx, reg32(*Buf, Info[lldb_edx_i386])); + EXPECT_EQ(Context.edi, reg32(*Buf, Info[lldb_edi_i386])); + EXPECT_EQ(Context.esi, reg32(*Buf, Info[lldb_esi_i386])); + EXPECT_EQ(Context.ebp, reg32(*Buf, Info[lldb_ebp_i386])); + EXPECT_EQ(Context.esp, reg32(*Buf, Info[lldb_esp_i386])); + EXPECT_EQ(Context.eip, reg32(*Buf, Info[lldb_eip_i386])); + EXPECT_EQ(Context.eflags, reg32(*Buf, Info[lldb_eflags_i386])); + EXPECT_EQ(Context.cs, reg32(*Buf, Info[lldb_cs_i386])); + EXPECT_EQ(Context.fs, reg32(*Buf, Info[lldb_fs_i386])); + EXPECT_EQ(Context.gs, reg32(*Buf, Info[lldb_gs_i386])); + EXPECT_EQ(Context.ss, reg32(*Buf, Info[lldb_ss_i386])); + EXPECT_EQ(Context.ds, reg32(*Buf, Info[lldb_ds_i386])); + EXPECT_EQ(Context.es, reg32(*Buf, Info[lldb_es_i386])); +} + +TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_64) { + MinidumpContext_x86_64 Context; + Context.context_flags = + static_cast<uint32_t>(MinidumpContext_x86_64_Flags::x86_64_Flag | + MinidumpContext_x86_64_Flags::Control | + MinidumpContext_x86_64_Flags::Segments | + MinidumpContext_x86_64_Flags::Integer); + Context.rax = 0x0001020304050607; + Context.rbx = 0x08090a0b0c0d0e0f; + Context.rcx = 0x1011121314151617; + Context.rdx = 0x18191a1b1c1d1e1f; + Context.rdi = 0x2021222324252627; + Context.rsi = 0x28292a2b2c2d2e2f; + Context.rbp = 0x3031323334353637; + Context.rsp = 0x38393a3b3c3d3e3f; + Context.r8 = 0x4041424344454647; + Context.r9 = 0x48494a4b4c4d4e4f; + Context.r10 = 0x5051525354555657; + Context.r11 = 0x58595a5b5c5d5e5f; + Context.r12 = 0x6061626364656667; + Context.r13 = 0x68696a6b6c6d6e6f; + Context.r14 = 0x7071727374757677; + Context.r15 = 0x78797a7b7c7d7e7f; + Context.rip = 0x8081828384858687; + Context.eflags = 0x88898a8b; + Context.cs = 0x8c8d; + Context.fs = 0x8e8f; + Context.gs = 0x9091; + Context.ss = 0x9293; + Context.ds = 0x9495; + Context.ss = 0x9697; + llvm::ArrayRef<uint8_t> ContextRef(reinterpret_cast<uint8_t *>(&Context), + sizeof(Context)); + + ArchSpec arch("x86_64-pc-linux"); + auto RegInterface = llvm::make_unique<RegisterContextLinux_x86_64>(arch); + lldb::DataBufferSP Buf = + ConvertMinidumpContext_x86_64(ContextRef, RegInterface.get()); + ASSERT_EQ(RegInterface->GetGPRSize(), Buf->GetByteSize()); + + const RegisterInfo *Info = RegInterface->GetRegisterInfo(); + EXPECT_EQ(Context.rax, reg64(*Buf, Info[lldb_rax_x86_64])); + EXPECT_EQ(Context.rbx, reg64(*Buf, Info[lldb_rbx_x86_64])); + EXPECT_EQ(Context.rcx, reg64(*Buf, Info[lldb_rcx_x86_64])); + EXPECT_EQ(Context.rdx, reg64(*Buf, Info[lldb_rdx_x86_64])); + EXPECT_EQ(Context.rdi, reg64(*Buf, Info[lldb_rdi_x86_64])); + EXPECT_EQ(Context.rsi, reg64(*Buf, Info[lldb_rsi_x86_64])); + EXPECT_EQ(Context.rbp, reg64(*Buf, Info[lldb_rbp_x86_64])); + EXPECT_EQ(Context.rsp, reg64(*Buf, Info[lldb_rsp_x86_64])); + EXPECT_EQ(Context.r8, reg64(*Buf, Info[lldb_r8_x86_64])); + EXPECT_EQ(Context.r9, reg64(*Buf, Info[lldb_r9_x86_64])); + EXPECT_EQ(Context.r10, reg64(*Buf, Info[lldb_r10_x86_64])); + EXPECT_EQ(Context.r11, reg64(*Buf, Info[lldb_r11_x86_64])); + EXPECT_EQ(Context.r12, reg64(*Buf, Info[lldb_r12_x86_64])); + EXPECT_EQ(Context.r13, reg64(*Buf, Info[lldb_r13_x86_64])); + EXPECT_EQ(Context.r14, reg64(*Buf, Info[lldb_r14_x86_64])); + EXPECT_EQ(Context.r15, reg64(*Buf, Info[lldb_r15_x86_64])); + EXPECT_EQ(Context.rip, reg64(*Buf, Info[lldb_rip_x86_64])); + EXPECT_EQ(Context.eflags, reg64(*Buf, Info[lldb_rflags_x86_64])); + EXPECT_EQ(Context.cs, reg64(*Buf, Info[lldb_cs_x86_64])); + EXPECT_EQ(Context.fs, reg64(*Buf, Info[lldb_fs_x86_64])); + EXPECT_EQ(Context.gs, reg64(*Buf, Info[lldb_gs_x86_64])); + EXPECT_EQ(Context.ss, reg64(*Buf, Info[lldb_ss_x86_64])); + EXPECT_EQ(Context.ds, reg64(*Buf, Info[lldb_ds_x86_64])); + EXPECT_EQ(Context.es, reg64(*Buf, Info[lldb_es_x86_64])); +} |