From bc8cc867a1ed3219fea6c87eda9106689dd2c932 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 28 Nov 2017 11:10:23 +0000 Subject: [PATCH] elf-core: Convert remaining register context to use register set maps In https://reviews.llvm.org/D39681, we started using a map instead passing a long list of register sets to the ppc64le register context. However, existing register contexts were still using the old method. This converts the remaining register contexts to use this approach. While doing that, I've had to modify the approach a bit: - the general purpose register set is still kept as a separate field, because this one is always present, and it's parsing is somewhat different than that of other register sets. - since the same register sets have different IDs on different operating systems, but we use the same register context class to represent different register sets, I've needed to add a layer of indirection to translate os-specific constants (e.g. NETBSD::NT_AMD64_FPREGS) into more generic terms (e.g. floating point register set). While slightly more complicated, this setup allows for better separation of concerns. The parsing code in ProcessElfCore can focus on parsing OS-specific core file notes, and can completely ignore architecture-specific register sets (by just storing any unrecognised notes in a map). These notes will then be passed on to the architecture-specific register context, which can just deal with architecture specifics, because the OS-specific note types are hidden in a register set description map. This way, adding an register set, which is already supported on other OSes, to a new OS, should in most cases be as simple as adding a new entry into the register set description map. Differential Revision: https://reviews.llvm.org/D40133 llvm-svn: 319162 --- .../source/Plugins/Process/elf-core/CMakeLists.txt | 1 + .../Plugins/Process/elf-core/ProcessElfCore.cpp | 63 ++++-------- .../Plugins/Process/elf-core/ProcessElfCore.h | 2 +- .../elf-core/RegisterContextPOSIXCore_arm.cpp | 2 +- .../elf-core/RegisterContextPOSIXCore_arm.h | 7 +- .../elf-core/RegisterContextPOSIXCore_arm64.cpp | 4 +- .../elf-core/RegisterContextPOSIXCore_arm64.h | 7 +- .../elf-core/RegisterContextPOSIXCore_mips64.cpp | 5 +- .../elf-core/RegisterContextPOSIXCore_mips64.h | 7 +- .../elf-core/RegisterContextPOSIXCore_powerpc.cpp | 8 +- .../elf-core/RegisterContextPOSIXCore_powerpc.h | 8 +- .../elf-core/RegisterContextPOSIXCore_ppc64le.cpp | 12 +-- .../elf-core/RegisterContextPOSIXCore_ppc64le.h | 9 +- .../elf-core/RegisterContextPOSIXCore_s390x.cpp | 4 +- .../elf-core/RegisterContextPOSIXCore_s390x.h | 7 +- .../elf-core/RegisterContextPOSIXCore_x86_64.cpp | 4 +- .../elf-core/RegisterContextPOSIXCore_x86_64.h | 7 +- .../Plugins/Process/elf-core/RegisterUtilities.cpp | 39 ++++++++ .../Plugins/Process/elf-core/RegisterUtilities.h | 110 +++++++++++++++++++++ .../Plugins/Process/elf-core/ThreadElfCore.cpp | 21 ++-- .../Plugins/Process/elf-core/ThreadElfCore.h | 16 +-- .../Plugins/Process/elf-core/elf-core-enums.h | 66 ------------- .../Plugins/Process/minidump/ThreadMinidump.cpp | 12 +-- 23 files changed, 226 insertions(+), 195 deletions(-) create mode 100644 lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp create mode 100644 lldb/source/Plugins/Process/elf-core/RegisterUtilities.h delete mode 100644 lldb/source/Plugins/Process/elf-core/elf-core-enums.h diff --git a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt index 5df4e26..3082c73 100644 --- a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt +++ b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt @@ -10,6 +10,7 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN RegisterContextPOSIXCore_ppc64le.cpp RegisterContextPOSIXCore_s390x.cpp RegisterContextPOSIXCore_x86_64.cpp + RegisterUtilities.cpp LINK_LIBS lldbCore diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 9fb2e02..7d6a0c9 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -32,11 +32,9 @@ #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" - -// Project includes +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "ProcessElfCore.h" #include "ThreadElfCore.h" -#include "elf-core-enums.h" using namespace lldb_private; @@ -524,12 +522,6 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef notes) { have_prstatus = true; ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture()); break; - case FREEBSD::NT_FPREGSET: - thread_data.fpregset = note.data; - break; - case FREEBSD::NT_PPC_VMX: - thread_data.vregset = note.data; - break; case FREEBSD::NT_PRPSINFO: have_prpsinfo = true; break; @@ -543,6 +535,7 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef notes) { m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4); break; default: + thread_data.notes.push_back(note); break; } } @@ -563,24 +556,21 @@ llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef notes) { if (!llvm::StringRef(note.info.n_name).startswith("NetBSD-CORE")) continue; - if (note.info.n_type == NETBSD::NT_PROCINFO) { + switch (note.info.n_type) { + case NETBSD::NT_PROCINFO: ParseNetBSDProcInfo(thread_data, note.data); - continue; - } - if (note.info.n_type == NETBSD::NT_AUXV) { + break; + case NETBSD::NT_AUXV: m_auxv = note.data; - continue; - } + break; - if (GetArchitecture().GetMachine() == llvm::Triple::x86_64) { - switch (note.info.n_type) { - case NETBSD::NT_AMD64_REGS: + case NETBSD::NT_AMD64_REGS: + if (GetArchitecture().GetMachine() == llvm::Triple::x86_64) thread_data.gpregset = note.data; - break; - case NETBSD::NT_AMD64_FPREGS: - thread_data.fpregset = note.data; - break; - } + break; + default: + thread_data.notes.push_back(note); + break; } } if (thread_data.gpregset.GetByteSize() == 0) { @@ -610,8 +600,8 @@ llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef notes) { case OPENBSD::NT_REGS: thread_data.gpregset = note.data; break; - case OPENBSD::NT_FPREGS: - thread_data.fpregset = note.data; + default: + thread_data.notes.push_back(note); break; } } @@ -667,8 +657,6 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef notes) { uint32_t header_size = ELFLinuxPrStatus::GetSize(arch); size_t len = note.data.GetByteSize() - header_size; thread_data.gpregset = DataExtractor(note.data, header_size, len); - if (arch.GetCore() == ArchSpec::eCore_ppc64le_generic) - thread_data.regsets.try_emplace(note.info.n_type, thread_data.gpregset); break; } case LINUX::NT_PRPSINFO: { @@ -711,25 +699,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef notes) { case LINUX::NT_AUXV: m_auxv = note.data; break; - case LINUX::NT_FPREGSET: - // In a i386 core file NT_FPREGSET is present, but it's not the result - // of the FXSAVE instruction like in 64 bit files. - // The result from FXSAVE is in NT_PRXFPREG for i386 core files - // - - if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64 || arch.IsMIPS()) - thread_data.fpregset = note.data; - else if (arch.GetCore() == ArchSpec::eCore_ppc64le_generic) { - thread_data.regsets.insert(std::make_pair(note.info.n_type, note.data)); - } - break; - case LINUX::NT_PPC_VMX: - case LINUX::NT_PPC_VSX: - if (arch.GetCore() == ArchSpec::eCore_ppc64le_generic) - thread_data.regsets.insert(std::make_pair(note.info.n_type, note.data)); - break; - case LINUX::NT_PRXFPREG: - thread_data.fpregset = note.data; + default: + thread_data.notes.push_back(note); break; } } diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 2c609b1..325c015 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -29,7 +29,7 @@ #include "lldb/Utility/Status.h" #include "Plugins/ObjectFile/ELF/ELFHeader.h" -#include "Plugins/Process/elf-core/elf-core-enums.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" struct ThreadData; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp index 81d88e6..0d68315 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -16,7 +16,7 @@ using namespace lldb_private; RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm( Thread &thread, RegisterInfoInterface *register_info, - const DataExtractor &gpregset, const DataExtractor &fpregset) + const DataExtractor &gpregset, llvm::ArrayRef notes) : RegisterContextPOSIX_arm(thread, 0, register_info) { m_gpr_buffer.reset( new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h index e095eac..a98d64c 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h @@ -10,11 +10,8 @@ #ifndef liblldb_RegisterContextCorePOSIX_arm_h_ #define liblldb_RegisterContextCorePOSIX_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" @@ -24,7 +21,7 @@ public: lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info, const lldb_private::DataExtractor &gpregset, - const lldb_private::DataExtractor &fpregset); + llvm::ArrayRef notes); ~RegisterContextCorePOSIX_arm() override; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index 41c02bf..919f890 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// #include "RegisterContextPOSIXCore_arm64.h" - +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" @@ -16,7 +16,7 @@ using namespace lldb_private; RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64( Thread &thread, RegisterInfoInterface *register_info, - const DataExtractor &gpregset, const DataExtractor &fpregset) + const DataExtractor &gpregset, llvm::ArrayRef notes) : RegisterContextPOSIX_arm64(thread, 0, register_info) { m_gpr_buffer.reset( new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h index 3a2bbdb..c519b15 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -10,11 +10,8 @@ #ifndef liblldb_RegisterContextCorePOSIX_arm64_h_ #define liblldb_RegisterContextCorePOSIX_arm64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" @@ -24,7 +21,7 @@ public: lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info, const lldb_private::DataExtractor &gpregset, - const lldb_private::DataExtractor &fpregset); + llvm::ArrayRef notes); ~RegisterContextCorePOSIX_arm64() override; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index 7549cf0..e252b5a 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -16,12 +16,15 @@ using namespace lldb_private; RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64( Thread &thread, RegisterInfoInterface *register_info, - const DataExtractor &gpregset, const DataExtractor &fpregset) + const DataExtractor &gpregset, llvm::ArrayRef notes) : RegisterContextPOSIX_mips64(thread, 0, register_info) { m_gpr_buffer.reset( new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); m_gpr.SetData(m_gpr_buffer); m_gpr.SetByteOrder(gpregset.GetByteOrder()); + + DataExtractor fpregset = getRegset( + notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc); m_fpr_buffer.reset( new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); m_fpr.SetData(m_fpr_buffer); diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h index 2cb527a..cf1d8a5b 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h @@ -10,11 +10,8 @@ #ifndef liblldb_RegisterContextCorePOSIX_mips64_h_ #define liblldb_RegisterContextCorePOSIX_mips64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" @@ -24,7 +21,7 @@ public: lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info, const lldb_private::DataExtractor &gpregset, - const lldb_private::DataExtractor &fpregset); + llvm::ArrayRef notes); ~RegisterContextCorePOSIX_mips64() override; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp index 62f6413..8670e34 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -17,17 +17,21 @@ using namespace lldb_private; RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc( Thread &thread, RegisterInfoInterface *register_info, - const DataExtractor &gpregset, const DataExtractor &fpregset, - const DataExtractor &vregset) + const DataExtractor &gpregset, llvm::ArrayRef notes) : RegisterContextPOSIX_powerpc(thread, 0, register_info) { m_gpr_buffer.reset( new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); m_gpr.SetData(m_gpr_buffer); m_gpr.SetByteOrder(gpregset.GetByteOrder()); + + ArchSpec arch = register_info->GetTargetArchitecture(); + DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc); m_fpr_buffer.reset( new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); m_fpr.SetData(m_fpr_buffer); m_fpr.SetByteOrder(fpregset.GetByteOrder()); + + DataExtractor vregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc); m_vec_buffer.reset( new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize())); m_vec.SetData(m_vec_buffer); diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h index aaa95e5..c352ab5 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h @@ -10,11 +10,8 @@ #ifndef liblldb_RegisterContextCorePOSIX_powerpc_h_ #define liblldb_RegisterContextCorePOSIX_powerpc_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Utility/DataExtractor.h" class RegisterContextCorePOSIX_powerpc : public RegisterContextPOSIX_powerpc { @@ -23,8 +20,7 @@ public: lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info, const lldb_private::DataExtractor &gpregset, - const lldb_private::DataExtractor &fpregset, - const lldb_private::DataExtractor &vregset); + llvm::ArrayRef notes); ~RegisterContextCorePOSIX_powerpc() override; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp index c84da89..2237e72 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp @@ -14,33 +14,33 @@ #include "lldb/Utility/DataBufferHeap.h" #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" -#include "elf-core-enums.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" using namespace lldb_private; RegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le( Thread &thread, RegisterInfoInterface *register_info, - const llvm::DenseMap ®sets) + const DataExtractor &gpregset, llvm::ArrayRef notes) : RegisterContextPOSIX_ppc64le(thread, 0, register_info) { - DataExtractor gpregset = regsets.lookup(LINUX::NT_PRSTATUS); m_gpr_buffer.reset( new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); m_gpr.SetData(m_gpr_buffer); m_gpr.SetByteOrder(gpregset.GetByteOrder()); - DataExtractor fpregset = regsets.lookup(LINUX::NT_FPREGSET); + ArchSpec arch = register_info->GetTargetArchitecture(); + DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc); m_fpr_buffer.reset( new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); m_fpr.SetData(m_fpr_buffer); m_fpr.SetByteOrder(fpregset.GetByteOrder()); - DataExtractor vmxregset = regsets.lookup(LINUX::NT_PPC_VMX); + DataExtractor vmxregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc); m_vmx_buffer.reset( new DataBufferHeap(vmxregset.GetDataStart(), vmxregset.GetByteSize())); m_vmx.SetData(m_vmx_buffer); m_vmx.SetByteOrder(vmxregset.GetByteOrder()); - DataExtractor vsxregset = regsets.lookup(LINUX::NT_PPC_VSX); + DataExtractor vsxregset = getRegset(notes, arch.GetTriple(), PPC_VSX_Desc); m_vsx_buffer.reset( new DataBufferHeap(vsxregset.GetDataStart(), vsxregset.GetByteSize())); m_vsx.SetData(m_vsx_buffer); diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h index cd64947..c860781 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h @@ -10,20 +10,17 @@ #ifndef liblldb_RegisterContextCorePOSIX_ppc64le_h_ #define liblldb_RegisterContextCorePOSIX_ppc64le_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Utility/DataExtractor.h" -#include "llvm/ADT/DenseMap.h" class RegisterContextCorePOSIX_ppc64le : public RegisterContextPOSIX_ppc64le { public: RegisterContextCorePOSIX_ppc64le( lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info, - const llvm::DenseMap ®sets); + const lldb_private::DataExtractor &gpregset, + llvm::ArrayRef notes); bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp index b3530a8..f0edbf1 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp @@ -17,13 +17,15 @@ using namespace lldb_private; RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x( Thread &thread, RegisterInfoInterface *register_info, - const DataExtractor &gpregset, const DataExtractor &fpregset) + const DataExtractor &gpregset, llvm::ArrayRef notes) : RegisterContextPOSIX_s390x(thread, 0, register_info) { m_gpr_buffer.reset( new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); m_gpr.SetData(m_gpr_buffer); m_gpr.SetByteOrder(gpregset.GetByteOrder()); + DataExtractor fpregset = getRegset( + notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc); m_fpr_buffer.reset( new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); m_fpr.SetData(m_fpr_buffer); diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h index 2b4ae10..0df1363 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h @@ -10,11 +10,8 @@ #ifndef liblldb_RegisterContextCorePOSIX_s390x_h_ #define liblldb_RegisterContextCorePOSIX_s390x_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Utility/DataExtractor.h" class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x { @@ -23,7 +20,7 @@ public: lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info, const lldb_private::DataExtractor &gpregset, - const lldb_private::DataExtractor &fpregset); + llvm::ArrayRef notes); ~RegisterContextCorePOSIX_s390x() override; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index 5766923..a5c7ffd 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -16,7 +16,7 @@ using namespace lldb_private; RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64( Thread &thread, RegisterInfoInterface *register_info, - const DataExtractor &gpregset, const DataExtractor &fpregset) + const DataExtractor &gpregset, llvm::ArrayRef notes) : RegisterContextPOSIX_x86(thread, 0, register_info) { size_t size, len; @@ -27,6 +27,8 @@ RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64( if (len != size) m_gpregset.reset(); + DataExtractor fpregset = getRegset( + notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc); size = sizeof(FXSAVE); m_fpregset.reset(new uint8_t[size]); len = diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h index 8340368..5096241 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h @@ -10,11 +10,8 @@ #ifndef liblldb_RegisterContextCorePOSIX_x86_64_h_ #define liblldb_RegisterContextCorePOSIX_x86_64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" class RegisterContextCorePOSIX_x86_64 : public RegisterContextPOSIX_x86 { public: @@ -22,7 +19,7 @@ public: lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info, const lldb_private::DataExtractor &gpregset, - const lldb_private::DataExtractor &fpregset); + llvm::ArrayRef notes); bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override; diff --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp new file mode 100644 index 0000000..3837aba --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp @@ -0,0 +1,39 @@ +//===-- RegisterUtilities.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Process/elf-core/RegisterUtilities.h" +#include "llvm/ADT/STLExtras.h" + +using namespace lldb_private; + +static llvm::Optional +getNoteType(const llvm::Triple &Triple, + llvm::ArrayRef RegsetDescs) { + for (const auto &Entry : RegsetDescs) { + if (Entry.OS != Triple.getOS()) + continue; + if (Entry.Arch != llvm::Triple::UnknownArch && + Entry.Arch != Triple.getArch()) + continue; + return Entry.Note; + } + return llvm::None; +} + +DataExtractor lldb_private::getRegset(llvm::ArrayRef Notes, + const llvm::Triple &Triple, + llvm::ArrayRef RegsetDescs) { + auto TypeOr = getNoteType(Triple, RegsetDescs); + if (!TypeOr) + return DataExtractor(); + uint32_t Type = *TypeOr; + auto Iter = llvm::find_if( + Notes, [Type](const CoreNote &Note) { return Note.info.n_type == Type; }); + return Iter == Notes.end() ? DataExtractor() : Iter->data; +} diff --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h new file mode 100644 index 0000000..9170d94 --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h @@ -0,0 +1,110 @@ +//===-- RegisterUtilities.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_REGISTERUTILITIES_H +#define LLDB_REGISTERUTILITIES_H + +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" +#include "lldb/Utility/DataExtractor.h" + +namespace lldb_private { +/// Core files PT_NOTE segment descriptor types + +namespace FREEBSD { +enum { + NT_PRSTATUS = 1, + NT_FPREGSET, + NT_PRPSINFO, + NT_THRMISC = 7, + NT_PROCSTAT_AUXV = 16, + NT_PPC_VMX = 0x100 +}; +} + +namespace NETBSD { +enum { NT_PROCINFO = 1, NT_AUXV, NT_AMD64_REGS = 33, NT_AMD64_FPREGS = 35 }; +} + +namespace OPENBSD { +enum { + NT_PROCINFO = 10, + NT_AUXV = 11, + NT_REGS = 20, + NT_FPREGS = 21, +}; +} + +namespace LINUX { +enum { + NT_PRSTATUS = 1, + NT_FPREGSET, + NT_PRPSINFO, + NT_TASKSTRUCT, + NT_PLATFORM, + NT_AUXV, + NT_FILE = 0x46494c45, + NT_SIGINFO = 0x53494749, + NT_PPC_VMX = 0x100, + NT_PPC_VSX = 0x102, + NT_PRXFPREG = 0x46e62b7f, +}; +} + +struct CoreNote { + ELFNote info; + DataExtractor data; +}; + +// A structure describing how to find a register set in a core file from a given +// OS. +struct RegsetDesc { + // OS to which this entry applies to. Must not be UnknownOS. + llvm::Triple::OSType OS; + + // Architecture to which this entry applies to. Can be UnknownArch, in which + // case it applies to all architectures of a given OS. + llvm::Triple::ArchType Arch; + + // The note type under which the register set can be found. + uint32_t Note; +}; + +// Returns the register set in Notes which corresponds to the specified Triple +// according to the list of register set descriptions in RegsetDescs. The list +// is scanned linearly, so you can use a more specific entry (e.g. linux-i386) +// to override a more general entry (e.g. general linux), as long as you place +// it earlier in the list. If a register set is not found, it returns an empty +// DataExtractor. +DataExtractor getRegset(llvm::ArrayRef Notes, + const llvm::Triple &Triple, + llvm::ArrayRef RegsetDescs); + +constexpr RegsetDesc FPR_Desc[] = { + {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_FPREGSET}, + // In a i386 core file NT_FPREGSET is present, but it's not the result + // of the FXSAVE instruction like in 64 bit files. + // The result from FXSAVE is in NT_PRXFPREG for i386 core files + {llvm::Triple::Linux, llvm::Triple::x86, LINUX::NT_PRXFPREG}, + {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_FPREGSET}, + {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::NT_AMD64_FPREGS}, + {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS}, +}; + +constexpr RegsetDesc PPC_VMX_Desc[] = { + {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_PPC_VMX}, + {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VMX}, +}; + +constexpr RegsetDesc PPC_VSX_Desc[] = { + {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VSX}, +}; + +} // namespace lldb_private + +#endif // #ifndef LLDB_REGISTERUTILITIES_H diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2dc15be..10c1ed2 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -47,9 +47,7 @@ using namespace lldb_private; //---------------------------------------------------------------------- ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td) : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(), - m_signo(td.signo), m_gpregset_data(td.gpregset), - m_fpregset_data(td.fpregset), m_vregset_data(td.vregset), - m_regsets_data(td.regsets) {} + m_signo(td.signo), m_gpregset_data(td.gpregset), m_notes(td.notes) {} ThreadElfCore::~ThreadElfCore() { DestroyThread(); } @@ -197,40 +195,39 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { switch (arch.GetMachine()) { case llvm::Triple::aarch64: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64( - *this, reg_interface, m_gpregset_data, m_fpregset_data)); + *this, reg_interface, m_gpregset_data, m_notes)); break; case llvm::Triple::arm: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm( - *this, reg_interface, m_gpregset_data, m_fpregset_data)); + *this, reg_interface, m_gpregset_data, m_notes)); break; case llvm::Triple::mipsel: case llvm::Triple::mips: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( - *this, reg_interface, m_gpregset_data, m_fpregset_data)); + *this, reg_interface, m_gpregset_data, m_notes)); break; case llvm::Triple::mips64: case llvm::Triple::mips64el: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( - *this, reg_interface, m_gpregset_data, m_fpregset_data)); + *this, reg_interface, m_gpregset_data, m_notes)); break; case llvm::Triple::ppc: case llvm::Triple::ppc64: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc( - *this, reg_interface, m_gpregset_data, m_fpregset_data, - m_vregset_data)); + *this, reg_interface, m_gpregset_data, m_notes)); break; case llvm::Triple::ppc64le: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_ppc64le( - *this, reg_interface, m_regsets_data)); + *this, reg_interface, m_gpregset_data, m_notes)); break; case llvm::Triple::systemz: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x( - *this, reg_interface, m_gpregset_data, m_fpregset_data)); + *this, reg_interface, m_gpregset_data, m_notes)); break; case llvm::Triple::x86: case llvm::Triple::x86_64: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64( - *this, reg_interface, m_gpregset_data, m_fpregset_data)); + *this, reg_interface, m_gpregset_data, m_notes)); break; default: break; diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h index cc91c34..335f698 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h @@ -10,15 +10,11 @@ #ifndef liblldb_ThreadElfCore_h_ #define liblldb_ThreadElfCore_h_ -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -// Project includes +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" #include "llvm/ADT/DenseMap.h" +#include struct compat_timeval { alignas(8) uint64_t tv_sec; @@ -130,9 +126,7 @@ static_assert(sizeof(ELFLinuxPrPsInfo) == 136, struct ThreadData { lldb_private::DataExtractor gpregset; - lldb_private::DataExtractor fpregset; - lldb_private::DataExtractor vregset; - llvm::DenseMap regsets; + std::vector notes; lldb::tid_t tid; int signo = 0; int prstatus_sig = 0; @@ -179,9 +173,7 @@ protected: int m_signo; lldb_private::DataExtractor m_gpregset_data; - lldb_private::DataExtractor m_fpregset_data; - lldb_private::DataExtractor m_vregset_data; - llvm::DenseMap m_regsets_data; + std::vector m_notes; bool CalculateStopInfo() override; }; diff --git a/lldb/source/Plugins/Process/elf-core/elf-core-enums.h b/lldb/source/Plugins/Process/elf-core/elf-core-enums.h deleted file mode 100644 index 44f17b2..0000000 --- a/lldb/source/Plugins/Process/elf-core/elf-core-enums.h +++ /dev/null @@ -1,66 +0,0 @@ -//===-- elf-core-enums.h ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_ELF_CORE_ENUMS_H -#define LLDB_ELF_CORE_ENUMS_H - -#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "lldb/Utility/DataExtractor.h" - -namespace lldb_private { -/// Core files PT_NOTE segment descriptor types - -namespace FREEBSD { -enum { - NT_PRSTATUS = 1, - NT_FPREGSET, - NT_PRPSINFO, - NT_THRMISC = 7, - NT_PROCSTAT_AUXV = 16, - NT_PPC_VMX = 0x100 -}; -} - -namespace NETBSD { -enum { NT_PROCINFO = 1, NT_AUXV, NT_AMD64_REGS = 33, NT_AMD64_FPREGS = 35 }; -} - -namespace OPENBSD { -enum { - NT_PROCINFO = 10, - NT_AUXV = 11, - NT_REGS = 20, - NT_FPREGS = 21, -}; -} - -namespace LINUX { -enum { - NT_PRSTATUS = 1, - NT_FPREGSET, - NT_PRPSINFO, - NT_TASKSTRUCT, - NT_PLATFORM, - NT_AUXV, - NT_FILE = 0x46494c45, - NT_SIGINFO = 0x53494749, - NT_PPC_VMX = 0x100, - NT_PPC_VSX = 0x102, - NT_PRXFPREG = 0x46e62b7f, -}; -} - -struct CoreNote { - ELFNote info; - DataExtractor data; -}; - -} // namespace lldb_private - -#endif // #ifndef LLDB_ELF_CORE_ENUMS_H diff --git a/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp b/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp index 0ce9543..3fafb61 100644 --- a/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -17,8 +17,8 @@ // Other libraries and framework includes #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" - #include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" @@ -74,20 +74,18 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { reg_interface = new RegisterContextLinux_i386(arch); lldb::DataBufferSP buf = ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface); - DataExtractor gpregs(buf, lldb::eByteOrderLittle, 4); - DataExtractor fpregs; + DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4); m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64( - *this, reg_interface, gpregs, fpregs)); + *this, reg_interface, gpregset, {})); break; } case llvm::Triple::x86_64: { reg_interface = new RegisterContextLinux_x86_64(arch); lldb::DataBufferSP buf = ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface); - DataExtractor gpregs(buf, lldb::eByteOrderLittle, 8); - DataExtractor fpregs; + DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8); m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64( - *this, reg_interface, gpregs, fpregs)); + *this, reg_interface, gpregset, {})); break; } default: -- 2.7.4