diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/Process/elf-core')
8 files changed, 172 insertions, 34 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index aa95e92607ad..ae19367ca3ae 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -52,9 +52,10 @@ void ProcessElfCore::Terminate() { lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, - const FileSpec *crash_file) { + const FileSpec *crash_file, + bool can_connect) { lldb::ProcessSP process_sp; - if (crash_file) { + if (crash_file && !can_connect) { // Read enough data for a ELF32 header or ELF64 header Note: Here we care // about e_type field only, so it is safe to ignore possible presence of // the header extension. @@ -97,7 +98,7 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp, ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file) - : Process(target_sp, listener_sp), m_core_file(core_file) {} + : PostMortemProcess(target_sp, listener_sp), m_core_file(core_file) {} // Destructor ProcessElfCore::~ProcessElfCore() { @@ -260,8 +261,8 @@ lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() { return m_dyld_up.get(); } -bool ProcessElfCore::UpdateThreadList(ThreadList &old_thread_list, - ThreadList &new_thread_list) { +bool ProcessElfCore::DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) { const uint32_t num_threads = GetNumThreadContexts(); if (!m_thread_data_valid) return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 6f6309799f43..d8e3cc9ae3e1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -19,7 +19,7 @@ #include <list> #include <vector> -#include "lldb/Target/Process.h" +#include "lldb/Target/PostMortemProcess.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -28,12 +28,13 @@ struct ThreadData; -class ProcessElfCore : public lldb_private::Process { +class ProcessElfCore : public lldb_private::PostMortemProcess { public: // Constructors and Destructors static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, - const lldb_private::FileSpec *crash_file_path); + const lldb_private::FileSpec *crash_file_path, + bool can_connect); static void Initialize(); @@ -104,8 +105,8 @@ public: protected: void Clear(); - bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list) override; + bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list, + lldb_private::ThreadList &new_thread_list) override; private: struct NT_FILE_Entry { @@ -125,8 +126,6 @@ private: lldb::ModuleSP m_core_module_sp; lldb_private::FileSpec m_core_file; std::string m_dyld_plugin_name; - ProcessElfCore(const ProcessElfCore &) = delete; - const ProcessElfCore &operator=(const ProcessElfCore &) = delete; // True if m_thread_contexts contains valid entries bool m_thread_data_valid = false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp index b76f26a584c0..2f71f175a00d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -16,9 +16,9 @@ using namespace lldb_private; RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm( - Thread &thread, RegisterInfoInterface *register_info, + Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm> register_info, const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes) - : RegisterContextPOSIX_arm(thread, 0, register_info) { + : RegisterContextPOSIX_arm(thread, std::move(register_info)) { m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(), gpregset.GetByteSize()); m_gpr.SetData(m_gpr_buffer); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h index f9ec08ed35fc..de343f9001e0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h @@ -18,7 +18,7 @@ class RegisterContextCorePOSIX_arm : public RegisterContextPOSIX_arm { public: RegisterContextCorePOSIX_arm( lldb_private::Thread &thread, - lldb_private::RegisterInfoInterface *register_info, + std::unique_ptr<RegisterInfoPOSIX_arm> register_info, const lldb_private::DataExtractor &gpregset, llvm::ArrayRef<lldb_private::CoreNote> notes); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index 685567416983..129a887a550c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "RegisterContextPOSIXCore_arm64.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Target/Thread.h" @@ -27,6 +28,12 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64( m_fpregset = getRegset( notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc); + + m_sveregset = + getRegset(notes, m_register_info_up->GetTargetArchitecture().GetTriple(), + AARCH64_SVE_Desc); + + ConfigureRegisterContext(); } RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {} @@ -45,9 +52,57 @@ bool RegisterContextCorePOSIX_arm64::WriteFPR() { return false; } +const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) { + return m_sveregset.GetDataStart() + offset; +} + +void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() { + if (m_sveregset.GetByteSize() > sizeof(sve::user_sve_header)) { + uint64_t sve_header_field_offset = 8; + m_sve_vector_length = m_sveregset.GetU16(&sve_header_field_offset); + sve_header_field_offset = 12; + uint16_t sve_header_flags_field = + m_sveregset.GetU16(&sve_header_field_offset); + if ((sve_header_flags_field & sve::ptrace_regs_mask) == + sve::ptrace_regs_fpsimd) + m_sve_state = SVEState::FPSIMD; + else if ((sve_header_flags_field & sve::ptrace_regs_mask) == + sve::ptrace_regs_sve) + m_sve_state = SVEState::Full; + + if (sve::vl_valid(m_sve_vector_length)) + m_register_info_up->ConfigureVectorRegisterInfos( + sve::vq_from_vl(m_sve_vector_length)); + else { + m_sve_state = SVEState::Disabled; + m_sve_vector_length = 0; + } + } else + m_sve_state = SVEState::Disabled; +} + +uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset( + const RegisterInfo *reg_info) { + // Start of Z0 data is after GPRs plus 8 bytes of vg register + uint32_t sve_reg_offset = LLDB_INVALID_INDEX32; + if (m_sve_state == SVEState::FPSIMD) { + const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + sve_reg_offset = sve::ptrace_fpsimd_offset + (reg - GetRegNumSVEZ0()) * 16; + } else if (m_sve_state == SVEState::Full) { + uint32_t sve_z0_offset = GetGPRSize() + 16; + sve_reg_offset = + sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset; + } + + return sve_reg_offset; +} + bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { - lldb::offset_t offset = reg_info->byte_offset; + Status error; + lldb::offset_t offset; + + offset = reg_info->byte_offset; if (offset + reg_info->byte_size <= GetGPRSize()) { uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); if (offset == reg_info->byte_offset + reg_info->byte_size) { @@ -60,15 +115,86 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, if (reg == LLDB_INVALID_REGNUM) return false; - offset -= GetGPRSize(); - if (IsFPR(reg) && offset + reg_info->byte_size <= GetFPUSize()) { - Status error; - value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset, - reg_info->byte_size, lldb::eByteOrderLittle, error); - return error.Success(); - } + if (IsFPR(reg)) { + if (m_sve_state == SVEState::Disabled) { + // SVE is disabled take legacy route for FPU register access + offset -= GetGPRSize(); + if (offset < m_fpregset.GetByteSize()) { + value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset, + reg_info->byte_size, lldb::eByteOrderLittle, + error); + return error.Success(); + } + } else { + // FPSR and FPCR will be located right after Z registers in + // SVEState::FPSIMD while in SVEState::Full they will be located at the + // end of register data after an alignment correction based on currently + // selected vector length. + uint32_t sve_reg_num = LLDB_INVALID_REGNUM; + if (reg == GetRegNumFPSR()) { + sve_reg_num = reg; + if (m_sve_state == SVEState::Full) + offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_vector_length)); + else if (m_sve_state == SVEState::FPSIMD) + offset = sve::ptrace_fpsimd_offset + (32 * 16); + } else if (reg == GetRegNumFPCR()) { + sve_reg_num = reg; + if (m_sve_state == SVEState::Full) + offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_vector_length)); + else if (m_sve_state == SVEState::FPSIMD) + offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4; + } else { + // Extract SVE Z register value register number for this reg_info + if (reg_info->value_regs && + reg_info->value_regs[0] != LLDB_INVALID_REGNUM) + sve_reg_num = reg_info->value_regs[0]; + offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num)); + } + + assert(sve_reg_num != LLDB_INVALID_REGNUM); + assert(offset < m_sveregset.GetByteSize()); + value.SetFromMemoryData(reg_info, GetSVEBuffer(offset), + reg_info->byte_size, lldb::eByteOrderLittle, + error); + } + } else if (IsSVE(reg)) { + if (IsSVEVG(reg)) { + value = GetSVERegVG(); + return true; + } - return false; + switch (m_sve_state) { + case SVEState::FPSIMD: { + // In FPSIMD state SVE payload mirrors legacy fpsimd struct and so just + // copy 16 bytes of v register to the start of z register. All other + // SVE register will be set to zero. + uint64_t byte_size = 1; + uint8_t zeros = 0; + const uint8_t *src = &zeros; + if (IsSVEZ(reg)) { + byte_size = 16; + offset = CalculateSVEOffset(reg_info); + assert(offset < m_sveregset.GetByteSize()); + src = GetSVEBuffer(offset); + } + value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle, + error); + } break; + case SVEState::Full: + offset = CalculateSVEOffset(reg_info); + assert(offset < m_sveregset.GetByteSize()); + value.SetFromMemoryData(reg_info, GetSVEBuffer(offset), + reg_info->byte_size, lldb::eByteOrderLittle, + error); + break; + case SVEState::Disabled: + default: + return false; + } + } else + return false; + + return error.Success(); } bool RegisterContextCorePOSIX_arm64::ReadAllRegisterValues( diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h index 830e0ff91e4c..a4fdc4f14328 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -9,7 +9,9 @@ #ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H #define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H +#include "Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" + #include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" @@ -49,6 +51,18 @@ private: lldb::DataBufferSP m_gpr_buffer; lldb_private::DataExtractor m_gpr; lldb_private::DataExtractor m_fpregset; + lldb_private::DataExtractor m_sveregset; + + SVEState m_sve_state; + uint16_t m_sve_vector_length = 0; + + const uint8_t *GetSVEBuffer(uint64_t offset = 0); + + void ConfigureRegisterContext(); + + uint32_t CalculateSVEOffset(const lldb_private::RegisterInfo *reg_info); + + uint64_t GetSVERegVG() { return m_sve_vector_length / 8; } }; #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h index 4e08aa280817..25abd7ed54b7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h @@ -107,6 +107,10 @@ constexpr RegsetDesc FPR_Desc[] = { {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS}, }; +constexpr RegsetDesc AARCH64_SVE_Desc[] = { + {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE}, +}; + constexpr RegsetDesc PPC_VMX_Desc[] = { {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX}, {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX}, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 9083ee060f07..6c3ee9debc7c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -86,9 +86,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { case llvm::Triple::FreeBSD: { switch (arch.GetMachine()) { case llvm::Triple::aarch64: - break; case llvm::Triple::arm: - reg_interface = new RegisterInfoPOSIX_arm(arch); break; case llvm::Triple::ppc: reg_interface = new RegisterContextFreeBSD_powerpc32(arch); @@ -126,9 +124,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { case llvm::Triple::Linux: { switch (arch.GetMachine()) { - case llvm::Triple::arm: - reg_interface = new RegisterInfoPOSIX_arm(arch); - break; case llvm::Triple::aarch64: break; case llvm::Triple::mipsel: @@ -163,9 +158,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { switch (arch.GetMachine()) { case llvm::Triple::aarch64: break; - case llvm::Triple::arm: - reg_interface = new RegisterInfoPOSIX_arm(arch); - break; case llvm::Triple::x86: reg_interface = new RegisterContextOpenBSD_i386(arch); break; @@ -182,7 +174,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { break; } - if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64) { + if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64 && + arch.GetMachine() != llvm::Triple::arm) { LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported", __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); assert(false && "Architecture or OS not supported"); @@ -196,7 +189,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { break; case llvm::Triple::arm: m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>( - *this, reg_interface, m_gpregset_data, m_notes); + *this, std::make_unique<RegisterInfoPOSIX_arm>(arch), m_gpregset_data, + m_notes); break; case llvm::Triple::mipsel: case llvm::Triple::mips: |