aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/Process/elf-core
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/Process/elf-core')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp144
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp14
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: