From fd2c8d65722165034a0635cb3c7b2cb93a3d662d Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 16 Nov 2017 13:38:57 +0000 Subject: [PATCH] Implement core dump debugging for PPC64le Summary: Implement core dump debugging for PPC64le. Reviewers: labath Reviewed By: labath Subscribers: JDevlieghere, krytarowski, clayborg, labath, lbianc, nemanjai, gut, anajuliapc, mgorny, kbarton, lldb-commits Differential Revision: https://reviews.llvm.org/D39681 Patch by Alexandre Yukio Yamashita llvm-svn: 318399 --- .../postmortem/elf-core/TestLinuxCore.py | 8 + .../postmortem/elf-core/linux-ppc64le.core | Bin 0 -> 330648 bytes .../postmortem/elf-core/linux-ppc64le.out | Bin 0 -> 3128 bytes lldb/source/Plugins/Process/Utility/CMakeLists.txt | 1 + .../Utility/RegisterContextPOSIX_ppc64le.cpp | 216 +++++++++++++++++++++ .../Process/Utility/RegisterContextPOSIX_ppc64le.h | 82 ++++++++ .../Process/Utility/RegisterInfos_ppc64le.h | 2 +- .../source/Plugins/Process/elf-core/CMakeLists.txt | 1 + .../Plugins/Process/elf-core/ProcessElfCore.cpp | 82 +++----- .../elf-core/RegisterContextPOSIXCore_ppc64le.cpp | 132 +++++++++++++ .../elf-core/RegisterContextPOSIXCore_ppc64le.h | 52 +++++ .../Plugins/Process/elf-core/ThreadElfCore.cpp | 17 +- .../Plugins/Process/elf-core/ThreadElfCore.h | 3 + .../Plugins/Process/elf-core/elf-core-enums.h | 55 ++++++ 14 files changed, 597 insertions(+), 54 deletions(-) create mode 100644 lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-ppc64le.core create mode 100755 lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-ppc64le.out create mode 100644 lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp create mode 100644 lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h create mode 100644 lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp create mode 100644 lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h create mode 100644 lldb/source/Plugins/Process/elf-core/elf-core-enums.h diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py index 1c0d8f5..63b9334 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -24,11 +24,13 @@ class LinuxCoreTestCase(TestBase): _mips64_n64_pid = 25619 _mips64_n32_pid = 3670 _mips_o32_pid = 3532 + _ppc64le_pid = 28147 _i386_regions = 4 _x86_64_regions = 5 _s390x_regions = 2 _mips_regions = 5 + _ppc64le_regions = 2 def setUp(self): super(LinuxCoreTestCase, self).setUp() @@ -58,6 +60,12 @@ class LinuxCoreTestCase(TestBase): @skipIf(oslist=['windows']) @skipIf(triple='^mips') + def test_ppc64le(self): + """Test that lldb can read the process information from an ppc64le linux core file.""" + self.do_test("linux-ppc64le", self._ppc64le_pid, self._ppc64le_regions) + + @skipIf(oslist=['windows']) + @skipIf(triple='^mips') def test_x86_64(self): """Test that lldb can read the process information from an x86_64 linux core file.""" self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-ppc64le.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-ppc64le.core new file mode 100644 index 0000000000000000000000000000000000000000..c0ed578bd79654e1d30f966a84733ad12cec2b10 GIT binary patch literal 330648 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 literal 0 HcmV?d00001 diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-ppc64le.out b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-ppc64le.out new file mode 100755 index 0000000000000000000000000000000000000000..05c69fd291b7446cbf114f8279bb510d3214189d GIT binary patch literal 3128 zcmb_e&ubi29RI$VO?Hzsn@!ScLQyADX(Qd4O^jw+ZL>)*F+^(wYXy<*?CvBxWOrtn zA9e$&jhT}Hw9#{)oJh!{c)?G_W)PfWiQd=_DxI*xLPN=bPP;R11s55aV+xp?;amU`>@NMhp> z>NG7;4aB&=rKZ-UTI{G=-}84b@*0Gb`QXDmvV47acaii0zWd+d&d<)C*Unrng-#G^ zliBgy*ko=ZH<`_ak!gHXo78jqm?j+B8LQc_JiBf=fms{X-U+Kw2>5|rClA;D6;2-LCcy1hg6*Vn=Odv)^8|I%cJwl8NL`Bf>cK_h!nNB*_-SY? zDqWa>-edUeA~8rbr;oAr{uVg}^b^gbm+rFZ-ltx{7@||r2p})lTzaX0`u!;MH3}7R zav#j43nDIpEc$`z1#}c>vtwibt)aE-w7=#DR{cWFcEaYK8annqt>OBl)_toSdRDek z3s5OH!V3-en&suS>J;TyNEHm}SeT)hZ)|UJR&6<3c0CJ9F4pqIl92}G zDt7BXlZq=X&gcEnD)xm~zk_y_&V6wNw_PgV)olY8RFH0xw*BxEUj;f99wimx^F{Wk z&?TE9U4`yP?9_D$_XSSUEFllP zm{*15xPhgwIH6t&?OG*kS3nP}W&pZXEiQXz-2%Pr*6B_Fy<(NZm7?jH4)(54ZD$$l zb62T^*M-naawzn z*Y6g3C|{nZ7SA7$z=gV>i?weTK_SB%>SrEE=Sl`2Q6I1Ri0CBaQ^hSYd&rMO>d*Zo V>Iz#w3Ww!C$qRiZ0y&rS{{l8SdYk|N literal 0 HcmV?d00001 diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt index dc1cf56..3780fb5 100644 --- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt @@ -39,6 +39,7 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN RegisterContextPOSIX_arm64.cpp RegisterContextPOSIX_mips64.cpp RegisterContextPOSIX_powerpc.cpp + RegisterContextPOSIX_ppc64le.cpp RegisterContextPOSIX_s390x.cpp RegisterContextPOSIX_x86.cpp RegisterContextThreadMemory.cpp diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp new file mode 100644 index 0000000..de410f0 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp @@ -0,0 +1,216 @@ +//===-- RegisterContextPOSIX_ppc64le.cpp -------------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +#include "lldb/Core/RegisterValue.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "llvm/Support/Compiler.h" + +#include "Plugins/Process/elf-core/ProcessElfCore.h" +#include "RegisterContextPOSIX_ppc64le.h" + +using namespace lldb_private; +using namespace lldb; + +static const uint32_t g_gpr_regnums[] = { + gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le, + gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le, + gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le, + gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le, + gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le, + gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le, + gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le, + gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_ppc64le, + gpr_pc_ppc64le, gpr_msr_ppc64le, gpr_origr3_ppc64le, gpr_ctr_ppc64le, + gpr_lr_ppc64le, gpr_xer_ppc64le, gpr_cr_ppc64le, gpr_softe_ppc64le, + gpr_trap_ppc64le, +}; + +static const uint32_t g_fpr_regnums[] = { + fpr_f0_ppc64le, fpr_f1_ppc64le, fpr_f2_ppc64le, fpr_f3_ppc64le, + fpr_f4_ppc64le, fpr_f5_ppc64le, fpr_f6_ppc64le, fpr_f7_ppc64le, + fpr_f8_ppc64le, fpr_f9_ppc64le, fpr_f10_ppc64le, fpr_f11_ppc64le, + fpr_f12_ppc64le, fpr_f13_ppc64le, fpr_f14_ppc64le, fpr_f15_ppc64le, + fpr_f16_ppc64le, fpr_f17_ppc64le, fpr_f18_ppc64le, fpr_f19_ppc64le, + fpr_f20_ppc64le, fpr_f21_ppc64le, fpr_f22_ppc64le, fpr_f23_ppc64le, + fpr_f24_ppc64le, fpr_f25_ppc64le, fpr_f26_ppc64le, fpr_f27_ppc64le, + fpr_f28_ppc64le, fpr_f29_ppc64le, fpr_f30_ppc64le, fpr_f31_ppc64le, + fpr_fpscr_ppc64le, +}; + +static const uint32_t g_vmx_regnums[] = { + vmx_vr0_ppc64le, vmx_vr1_ppc64le, vmx_vr2_ppc64le, vmx_vr3_ppc64le, + vmx_vr4_ppc64le, vmx_vr5_ppc64le, vmx_vr6_ppc64le, vmx_vr7_ppc64le, + vmx_vr8_ppc64le, vmx_vr9_ppc64le, vmx_vr10_ppc64le, vmx_vr11_ppc64le, + vmx_vr12_ppc64le, vmx_vr13_ppc64le, vmx_vr14_ppc64le, vmx_vr15_ppc64le, + vmx_vr16_ppc64le, vmx_vr17_ppc64le, vmx_vr18_ppc64le, vmx_vr19_ppc64le, + vmx_vr20_ppc64le, vmx_vr21_ppc64le, vmx_vr22_ppc64le, vmx_vr23_ppc64le, + vmx_vr24_ppc64le, vmx_vr25_ppc64le, vmx_vr26_ppc64le, vmx_vr27_ppc64le, + vmx_vr28_ppc64le, vmx_vr29_ppc64le, vmx_vr30_ppc64le, vmx_vr31_ppc64le, + vmx_vscr_ppc64le, vmx_vrsave_ppc64le, +}; + +static const uint32_t g_vsx_regnums[] = { + vsx_vs0_ppc64le, vsx_vs1_ppc64le, vsx_vs2_ppc64le, vsx_vs3_ppc64le, + vsx_vs4_ppc64le, vsx_vs5_ppc64le, vsx_vs6_ppc64le, vsx_vs7_ppc64le, + vsx_vs8_ppc64le, vsx_vs9_ppc64le, vsx_vs10_ppc64le, vsx_vs11_ppc64le, + vsx_vs12_ppc64le, vsx_vs13_ppc64le, vsx_vs14_ppc64le, vsx_vs15_ppc64le, + vsx_vs16_ppc64le, vsx_vs17_ppc64le, vsx_vs18_ppc64le, vsx_vs19_ppc64le, + vsx_vs20_ppc64le, vsx_vs21_ppc64le, vsx_vs22_ppc64le, vsx_vs23_ppc64le, + vsx_vs24_ppc64le, vsx_vs25_ppc64le, vsx_vs26_ppc64le, vsx_vs27_ppc64le, + vsx_vs28_ppc64le, vsx_vs29_ppc64le, vsx_vs30_ppc64le, vsx_vs31_ppc64le, + vsx_vs32_ppc64le, vsx_vs33_ppc64le, vsx_vs34_ppc64le, vsx_vs35_ppc64le, + vsx_vs36_ppc64le, vsx_vs37_ppc64le, vsx_vs38_ppc64le, vsx_vs39_ppc64le, + vsx_vs40_ppc64le, vsx_vs41_ppc64le, vsx_vs42_ppc64le, vsx_vs43_ppc64le, + vsx_vs44_ppc64le, vsx_vs45_ppc64le, vsx_vs46_ppc64le, vsx_vs47_ppc64le, + vsx_vs48_ppc64le, vsx_vs49_ppc64le, vsx_vs50_ppc64le, vsx_vs51_ppc64le, + vsx_vs52_ppc64le, vsx_vs53_ppc64le, vsx_vs54_ppc64le, vsx_vs55_ppc64le, + vsx_vs56_ppc64le, vsx_vs57_ppc64le, vsx_vs58_ppc64le, vsx_vs59_ppc64le, + vsx_vs60_ppc64le, vsx_vs61_ppc64le, vsx_vs62_ppc64le, vsx_vs63_ppc64le, +}; + +// Number of register sets provided by this context. +enum { k_num_register_sets = 4 }; + +static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le, + g_gpr_regnums}, + {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64le, + g_fpr_regnums}, + {"Altivec/VMX Registers", "vmx", k_num_vmx_registers_ppc64le, + g_vmx_regnums}, + {"VSX Registers", "vsx", k_num_vsx_registers_ppc64le, g_vsx_regnums}, +}; + +bool RegisterContextPOSIX_ppc64le::IsGPR(unsigned reg) { + return (reg <= k_last_gpr_ppc64le); // GPR's come first. +} + +bool RegisterContextPOSIX_ppc64le::IsFPR(unsigned reg) { + return (reg >= k_first_fpr_ppc64le) && (reg <= k_last_fpr_ppc64le); +} + +bool RegisterContextPOSIX_ppc64le::IsVMX(unsigned reg) { + return (reg >= k_first_vmx_ppc64le) && (reg <= k_last_vmx_ppc64le); +} + +bool RegisterContextPOSIX_ppc64le::IsVSX(unsigned reg) { + return (reg >= k_first_vsx_ppc64le) && (reg <= k_last_vsx_ppc64le); +} + +RegisterContextPOSIX_ppc64le::RegisterContextPOSIX_ppc64le( + Thread &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) { + m_register_info_ap.reset(register_info); + + ProcessSP base = CalculateProcess(); + if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) + return; +} + +void RegisterContextPOSIX_ppc64le::InvalidateAllRegisters() {} + +unsigned RegisterContextPOSIX_ppc64le::GetRegisterOffset(unsigned reg) { + assert(reg < k_num_registers_ppc64le && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned RegisterContextPOSIX_ppc64le::GetRegisterSize(unsigned reg) { + assert(reg < k_num_registers_ppc64le && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +size_t RegisterContextPOSIX_ppc64le::GetRegisterCount() { + size_t num_registers = k_num_registers_ppc64le; + return num_registers; +} + +size_t RegisterContextPOSIX_ppc64le::GetGPRSize() { + return m_register_info_ap->GetGPRSize(); +} + +const RegisterInfo *RegisterContextPOSIX_ppc64le::GetRegisterInfo() { + // Commonly, this method is overridden and g_register_infos is copied and + // specialized. + // So, use GetRegisterInfo() rather than g_register_infos in this scope. + return m_register_info_ap->GetRegisterInfo(); +} + +const RegisterInfo * +RegisterContextPOSIX_ppc64le::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_registers_ppc64le) + return &GetRegisterInfo()[reg]; + else + return NULL; +} + +size_t RegisterContextPOSIX_ppc64le::GetRegisterSetCount() { + size_t sets = 0; + for (size_t set = 0; set < k_num_register_sets; ++set) { + if (IsRegisterSetAvailable(set)) + ++sets; + } + + return sets; +} + +const RegisterSet *RegisterContextPOSIX_ppc64le::GetRegisterSet(size_t set) { + if (IsRegisterSetAvailable(set)) + return &g_reg_sets_ppc64le[set]; + else + return NULL; +} + +const char *RegisterContextPOSIX_ppc64le::GetRegisterName(unsigned reg) { + assert(reg < k_num_registers_ppc64le && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +lldb::ByteOrder RegisterContextPOSIX_ppc64le::GetByteOrder() { + // Get the target process whose privileged thread was used for the register + // read. + lldb::ByteOrder byte_order = eByteOrderInvalid; + Process *process = CalculateProcess().get(); + + if (process) + byte_order = process->GetByteOrder(); + return byte_order; +} + +bool RegisterContextPOSIX_ppc64le::IsRegisterSetAvailable(size_t set_index) { + size_t num_sets = k_num_register_sets; + + return (set_index < num_sets); +} + +// Used when parsing DWARF and EH frame information and any other +// object file sections that contain register numbers in them. +uint32_t RegisterContextPOSIX_ppc64le::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + const uint32_t num_regs = GetRegisterCount(); + + assert(kind < kNumRegisterKinds); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); + + if (reg_info->kinds[kind] == num) + return reg_idx; + } + + return LLDB_INVALID_REGNUM; +} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h new file mode 100644 index 0000000..1070b4d --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h @@ -0,0 +1,82 @@ +//===-- RegisterContextPOSIX_ppc64le.h --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextPOSIX_ppc64le_h_ +#define liblldb_RegisterContextPOSIX_ppc64le_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" +#include "RegisterInfoInterface.h" +#include "Utility/PPC64LE_DWARF_Registers.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_ppc64le : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_ppc64le( + lldb_private::Thread &thread, uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + +protected: + // 64-bit general purpose registers. + uint64_t m_gpr_ppc64le[k_num_gpr_registers_ppc64le]; + + // floating-point registers including extended register. + uint64_t m_fpr_ppc64le[k_num_fpr_registers_ppc64le]; + + // VMX registers. + uint64_t m_vmx_ppc64le[k_num_vmx_registers_ppc64le * 2]; + + // VSX registers. + uint64_t m_vsx_ppc64le[k_num_vsx_registers_ppc64le * 2]; + + std::unique_ptr m_register_info_ap; + + // Determines if an extended register set is supported on the processor + // running the inferior process. + virtual bool IsRegisterSetAvailable(size_t set_index); + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + bool IsVMX(unsigned reg); + + bool IsVSX(unsigned reg); + + lldb::ByteOrder GetByteOrder(); +}; + +#endif // liblldb_RegisterContextPOSIX_ppc64le_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h index 8b5dd4b..bffa7a1 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h @@ -98,10 +98,10 @@ DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \ - DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \ DEFINE_GPR(msr, "msr", LLDB_INVALID_REGNUM), \ DEFINE_GPR(origr3, "orig_r3", LLDB_INVALID_REGNUM), \ DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \ + DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \ DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \ DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \ DEFINE_GPR(softe, "softe", LLDB_INVALID_REGNUM), \ diff --git a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt index c7ffae6..5df4e26 100644 --- a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt +++ b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt @@ -7,6 +7,7 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN RegisterContextPOSIXCore_arm64.cpp RegisterContextPOSIXCore_mips64.cpp RegisterContextPOSIXCore_powerpc.cpp + RegisterContextPOSIXCore_ppc64le.cpp RegisterContextPOSIXCore_s390x.cpp RegisterContextPOSIXCore_x86_64.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index ed9058e..6993a9b 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -36,6 +36,7 @@ // Project includes #include "ProcessElfCore.h" #include "ThreadElfCore.h" +#include "elf-core-enums.h" using namespace lldb_private; @@ -427,40 +428,6 @@ lldb::addr_t ProcessElfCore::GetImageInfoAddress() { return LLDB_INVALID_ADDRESS; } -/// Core files PT_NOTE segment descriptor types -enum { - NT_PRSTATUS = 1, - NT_FPREGSET, - NT_PRPSINFO, - NT_TASKSTRUCT, - NT_PLATFORM, - NT_AUXV, - NT_FILE = 0x46494c45, - NT_PRXFPREG = 0x46e62b7f, - NT_SIGINFO = 0x53494749, - NT_OPENBSD_PROCINFO = 10, - NT_OPENBSD_AUXV = 11, - NT_OPENBSD_REGS = 20, - NT_OPENBSD_FPREGS = 21, -}; - -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 }; -} - // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details. static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data, ArchSpec &arch) { @@ -563,8 +530,12 @@ Status ProcessElfCore::ParseThreadContextsFromNoteSegment( note.Parse(segment_data, &offset); // Beginning of new thread - if ((note.n_type == NT_PRSTATUS && have_prstatus) || - (note.n_type == NT_PRPSINFO && have_prpsinfo)) { + if (((note.n_type == LINUX::NT_PRSTATUS || + note.n_type == FREEBSD::NT_PRSTATUS) && + have_prstatus) || + ((note.n_type == LINUX::NT_PRPSINFO || + note.n_type == FREEBSD::NT_PRPSINFO) && + have_prpsinfo)) { assert(thread_data->gpregset.GetByteSize() > 0); // Add the new thread to thread list m_thread_data.push_back(*thread_data); @@ -627,22 +598,22 @@ Status ProcessElfCore::ParseThreadContextsFromNoteSegment( // "OpenBSD@nnn" so match on the initial part of the string. m_os = llvm::Triple::OpenBSD; switch (note.n_type) { - case NT_OPENBSD_PROCINFO: + case OPENBSD::NT_PROCINFO: ParseOpenBSDProcInfo(*thread_data, note_data); break; - case NT_OPENBSD_AUXV: + case OPENBSD::NT_AUXV: m_auxv = DataExtractor(note_data); break; - case NT_OPENBSD_REGS: + case OPENBSD::NT_REGS: thread_data->gpregset = note_data; break; - case NT_OPENBSD_FPREGS: + case OPENBSD::NT_FPREGS: thread_data->fpregset = note_data; break; } } else if (note.n_name == "CORE") { switch (note.n_type) { - case NT_PRSTATUS: + case LINUX::NT_PRSTATUS: have_prstatus = true; error = prstatus.Parse(note_data, arch); if (error.Fail()) @@ -652,17 +623,22 @@ Status ProcessElfCore::ParseThreadContextsFromNoteSegment( header_size = ELFLinuxPrStatus::GetSize(arch); 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.insert( + std::make_pair(note.n_type, thread_data->gpregset)); break; - case NT_FPREGSET: + 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) - thread_data->fpregset = note_data; - else if(arch.IsMIPS()) + 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.n_type, note_data)); + } break; - case NT_PRPSINFO: + case LINUX::NT_PRPSINFO: have_prpsinfo = true; error = prpsinfo.Parse(note_data, arch); if (error.Fail()) @@ -670,10 +646,10 @@ Status ProcessElfCore::ParseThreadContextsFromNoteSegment( thread_data->name = prpsinfo.pr_fname; SetID(prpsinfo.pr_pid); break; - case NT_AUXV: + case LINUX::NT_AUXV: m_auxv = DataExtractor(note_data); break; - case NT_FILE: { + case LINUX::NT_FILE: { m_nt_file_entries.clear(); lldb::offset_t offset = 0; const uint64_t count = note_data.GetAddress(&offset); @@ -691,7 +667,7 @@ Status ProcessElfCore::ParseThreadContextsFromNoteSegment( m_nt_file_entries[i].path.SetCString(path); } } break; - case NT_SIGINFO: { + case LINUX::NT_SIGINFO: { error = siginfo.Parse(note_data, arch); if (error.Fail()) return error; @@ -702,8 +678,14 @@ Status ProcessElfCore::ParseThreadContextsFromNoteSegment( } } else if (note.n_name == "LINUX") { switch (note.n_type) { - case NT_PRXFPREG: + case LINUX::NT_PRXFPREG: thread_data->fpregset = 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.n_type, note_data)); + break; } } diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp new file mode 100644 index 0000000..c84da89 --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp @@ -0,0 +1,132 @@ +//===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextPOSIXCore_ppc64le.h" + +#include "lldb/Core/RegisterValue.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" + +#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" +#include "elf-core-enums.h" + +using namespace lldb_private; + +RegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le( + Thread &thread, RegisterInfoInterface *register_info, + const llvm::DenseMap ®sets) + : 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); + 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); + 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); + m_vsx_buffer.reset( + new DataBufferHeap(vsxregset.GetDataStart(), vsxregset.GetByteSize())); + m_vsx.SetData(m_vsx_buffer); + m_vsx.SetByteOrder(vsxregset.GetByteOrder()); +} + +size_t RegisterContextCorePOSIX_ppc64le::GetFPRSize() const { + return k_num_fpr_registers_ppc64le * sizeof(uint64_t); +} + +size_t RegisterContextCorePOSIX_ppc64le::GetVMXSize() const { + return (k_num_vmx_registers_ppc64le - 1) * sizeof(uint64_t) * 2 + + sizeof(uint32_t); +} + +size_t RegisterContextCorePOSIX_ppc64le::GetVSXSize() const { + return k_num_vsx_registers_ppc64le * sizeof(uint64_t) * 2; +} + +bool RegisterContextCorePOSIX_ppc64le::ReadRegister( + const RegisterInfo *reg_info, RegisterValue &value) { + lldb::offset_t offset = reg_info->byte_offset; + + if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) { + uint64_t v; + offset -= GetGPRSize(); + offset = m_fpr.CopyData(offset, reg_info->byte_size, &v); + + if (offset == reg_info->byte_size) { + value.SetBytes(&v, reg_info->byte_size, m_fpr.GetByteOrder()); + return true; + } + } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) { + uint32_t v[4]; + offset -= GetGPRSize() + GetFPRSize(); + offset = m_vmx.CopyData(offset, reg_info->byte_size, &v); + + if (offset == reg_info->byte_size) { + value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder()); + return true; + } + } else if (IsVSX(reg_info->kinds[lldb::eRegisterKindLLDB])) { + uint32_t v[4]; + lldb::offset_t tmp_offset; + offset -= GetGPRSize() + GetFPRSize() + GetVMXSize(); + + if (offset < GetVSXSize() / 2) { + tmp_offset = m_vsx.CopyData(offset / 2, reg_info->byte_size / 2, &v); + + if (tmp_offset != reg_info->byte_size / 2) { + return false; + } + + uint8_t *dst = (uint8_t *)&v + sizeof(uint64_t); + tmp_offset = m_fpr.CopyData(offset / 2, reg_info->byte_size / 2, dst); + + if (tmp_offset != reg_info->byte_size / 2) { + return false; + } + + value.SetBytes(&v, reg_info->byte_size, m_vsx.GetByteOrder()); + return true; + } else { + offset = + m_vmx.CopyData(offset - GetVSXSize() / 2, reg_info->byte_size, &v); + if (offset == reg_info->byte_size) { + value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder()); + return true; + } + } + } else { + uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); + + if (offset == reg_info->byte_offset + reg_info->byte_size) { + if (reg_info->byte_size < sizeof(v)) + value = (uint32_t)v; + else + value = v; + return true; + } + } + + return false; +} + +bool RegisterContextCorePOSIX_ppc64le::WriteRegister( + const RegisterInfo *reg_info, const RegisterValue &value) { + return false; +} diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h new file mode 100644 index 0000000..cd64947 --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h @@ -0,0 +1,52 @@ +//===-- RegisterContextPOSIXCore_ppc64le.h ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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 "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); + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) override; + +protected: + size_t GetFPRSize() const; + + size_t GetVMXSize() const; + + size_t GetVSXSize() const; + +private: + lldb::DataBufferSP m_gpr_buffer; + lldb::DataBufferSP m_fpr_buffer; + lldb::DataBufferSP m_vmx_buffer; + lldb::DataBufferSP m_vsx_buffer; + lldb_private::DataExtractor m_gpr; + lldb_private::DataExtractor m_fpr; + lldb_private::DataExtractor m_vmx; + lldb_private::DataExtractor m_vsx; +}; + +#endif // liblldb_RegisterContextCorePOSIX_ppc64le_h_ diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 096c203..3a1a4d9 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -18,9 +18,9 @@ #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" -#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" -#include "Plugins/Process/Utility/RegisterContextLinux_mips.h" #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" +#include "Plugins/Process/Utility/RegisterContextLinux_mips.h" +#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" @@ -28,11 +28,13 @@ #include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h" #include "ProcessElfCore.h" #include "RegisterContextPOSIXCore_arm.h" #include "RegisterContextPOSIXCore_arm64.h" #include "RegisterContextPOSIXCore_mips64.h" #include "RegisterContextPOSIXCore_powerpc.h" +#include "RegisterContextPOSIXCore_ppc64le.h" #include "RegisterContextPOSIXCore_s390x.h" #include "RegisterContextPOSIXCore_x86_64.h" #include "ThreadElfCore.h" @@ -46,7 +48,8 @@ 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_fpregset_data(td.fpregset), m_vregset_data(td.vregset), + m_regsets_data(td.regsets) {} ThreadElfCore::~ThreadElfCore() { DestroyThread(); } @@ -142,6 +145,9 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { case llvm::Triple::mips64: reg_interface = new RegisterContextLinux_mips64(arch); break; + case llvm::Triple::ppc64le: + reg_interface = new RegisterInfoPOSIX_ppc64le(arch); + break; case llvm::Triple::systemz: reg_interface = new RegisterContextLinux_s390x(arch); break; @@ -213,6 +219,10 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { *this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data)); break; + case llvm::Triple::ppc64le: + m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_ppc64le( + *this, reg_interface, m_regsets_data)); + break; case llvm::Triple::systemz: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x( *this, reg_interface, m_gpregset_data, m_fpregset_data)); @@ -265,6 +275,7 @@ size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) { switch (arch.GetCore()) { case lldb_private::ArchSpec::eCore_s390x_generic: case lldb_private::ArchSpec::eCore_x86_64_x86_64: + case lldb_private::ArchSpec::eCore_ppc64le_generic: return sizeof(ELFLinuxPrStatus); case lldb_private::ArchSpec::eCore_x86_32_i386: case lldb_private::ArchSpec::eCore_x86_32_i486: diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h index 5218754..c38a42e 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h @@ -18,6 +18,7 @@ // Project includes #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" +#include "llvm/ADT/DenseMap.h" struct compat_timeval { alignas(8) uint64_t tv_sec; @@ -131,6 +132,7 @@ struct ThreadData { lldb_private::DataExtractor gpregset; lldb_private::DataExtractor fpregset; lldb_private::DataExtractor vregset; + llvm::DenseMap regsets; lldb::tid_t tid; int signo = 0; int prstatus_sig = 0; @@ -179,6 +181,7 @@ protected: lldb_private::DataExtractor m_gpregset_data; lldb_private::DataExtractor m_fpregset_data; lldb_private::DataExtractor m_vregset_data; + llvm::DenseMap m_regsets_data; 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 new file mode 100644 index 0000000..b3bddfa --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/elf-core-enums.h @@ -0,0 +1,55 @@ +//===-- 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 + +/// 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, +}; +} + +#endif // #ifndef LLDB_ELF_CORE_ENUMS_H -- 2.7.4