aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/Process/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/Process/Utility')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp89
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h291
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp172
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp143
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp143
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp182
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h31
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp466
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h79
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp276
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h48
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp131
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h53
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp107
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.cpp58
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp104
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp179
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h45
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h572
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h25
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h47
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h4
40 files changed, 2950 insertions, 508 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp
index 685d9d0824f6..c4f45f759a33 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp
@@ -82,6 +82,7 @@ const char *AuxVector::GetEntryName(EntryType type) const {
case ENTRY_NAME(AUXV_AT_SECURE); break;
case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break;
case ENTRY_NAME(AUXV_AT_RANDOM); break;
+ case ENTRY_NAME(AUXV_AT_HWCAP2); break;
case ENTRY_NAME(AUXV_AT_EXECFN); break;
case ENTRY_NAME(AUXV_AT_SYSINFO); break;
case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h
index c8c8b1249413..07a0010e198f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h
@@ -50,6 +50,7 @@ public:
AUXV_AT_SECURE = 23, ///< Boolean, was exec setuid-like?
AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
AUXV_AT_RANDOM = 25, ///< Address of 16 random bytes.
+ AUXV_AT_HWCAP2 = 26, ///< Extension of AT_HWCAP.
AUXV_AT_EXECFN = 31, ///< Filename of executable.
AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system
/// calls and other nice things.
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 443638aa39f6..5463a071503c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -151,10 +151,8 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
const uint32_t msbyte = msbit / 8;
const uint32_t lsbyte = lsbit / 8;
- ConstString containing_reg_name(reg_name_str);
-
const RegisterInfo *containing_reg_info =
- GetRegisterInfo(containing_reg_name);
+ GetRegisterInfo(reg_name_str);
if (containing_reg_info) {
const uint32_t max_bit = containing_reg_info->byte_size * 8;
if (msbit < max_bit && lsbit < max_bit) {
@@ -189,7 +187,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
}
} else {
printf("error: invalid concrete register \"%s\"\n",
- containing_reg_name.GetCString());
+ reg_name_str.c_str());
}
} else {
printf("error: msbit (%u) must be greater than lsbit (%u)\n",
@@ -217,7 +215,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
if (composite_reg_list->GetItemAtIndexAsString(
composite_idx, composite_reg_name, nullptr)) {
const RegisterInfo *composite_reg_info =
- GetRegisterInfo(composite_reg_name);
+ GetRegisterInfo(composite_reg_name.GetStringRef());
if (composite_reg_info) {
composite_offset = std::min(composite_offset,
composite_reg_info->byte_offset);
@@ -357,7 +355,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
if (invalidate_reg_list->GetItemAtIndexAsString(
idx, invalidate_reg_name)) {
const RegisterInfo *invalidate_reg_info =
- GetRegisterInfo(invalidate_reg_name);
+ GetRegisterInfo(invalidate_reg_name.GetStringRef());
if (invalidate_reg_info) {
m_invalidate_regs_map[i].push_back(
invalidate_reg_info->kinds[eRegisterKindLLDB]);
@@ -430,9 +428,6 @@ void DynamicRegisterInfo::AddRegister(RegisterInfo &reg_info,
assert(set < m_set_reg_nums.size());
assert(set < m_set_names.size());
m_set_reg_nums[set].push_back(reg_num);
- size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
- if (m_reg_data_byte_size < end_reg_offset)
- m_reg_data_byte_size = end_reg_offset;
}
void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
@@ -617,8 +612,70 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
break;
}
}
+
+ // At this stage call ConfigureOffsets to calculate register offsets for
+ // targets supporting dynamic offset calculation. It also calculates
+ // total byte size of register data.
+ ConfigureOffsets();
+
+ // Check if register info is reconfigurable
+ // AArch64 SVE register set has configurable register sizes
+ if (arch.GetTriple().isAArch64()) {
+ for (const auto &reg : m_regs) {
+ if (strcmp(reg.name, "vg") == 0) {
+ m_is_reconfigurable = true;
+ break;
+ }
+ }
+ }
+}
+
+void DynamicRegisterInfo::ConfigureOffsets() {
+ // We are going to create a map between remote (eRegisterKindProcessPlugin)
+ // and local (eRegisterKindLLDB) register numbers. This map will give us
+ // remote register numbers in increasing order for offset calculation.
+ std::map<uint32_t, uint32_t> remote_to_local_regnum_map;
+ for (const auto &reg : m_regs)
+ remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] =
+ reg.kinds[eRegisterKindLLDB];
+
+ // At this stage we manually calculate g/G packet offsets of all primary
+ // registers, only if target XML or qRegisterInfo packet did not send
+ // an offset explicitly.
+ uint32_t reg_offset = 0;
+ for (auto const &regnum_pair : remote_to_local_regnum_map) {
+ if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 &&
+ m_regs[regnum_pair.second].value_regs == nullptr) {
+ m_regs[regnum_pair.second].byte_offset = reg_offset;
+
+ reg_offset = m_regs[regnum_pair.second].byte_offset +
+ m_regs[regnum_pair.second].byte_size;
+ }
+ }
+
+ // Now update all value_regs with each register info as needed
+ for (auto &reg : m_regs) {
+ if (reg.value_regs != nullptr) {
+ // Assign a valid offset to all pseudo registers if not assigned by stub.
+ // Pseudo registers with value_regs list populated will share same offset
+ // as that of their corresponding primary register in value_regs list.
+ if (reg.byte_offset == LLDB_INVALID_INDEX32) {
+ uint32_t value_regnum = reg.value_regs[0];
+ if (value_regnum != LLDB_INVALID_INDEX32)
+ reg.byte_offset =
+ GetRegisterInfoAtIndex(remote_to_local_regnum_map[value_regnum])
+ ->byte_offset;
+ }
+ }
+
+ reg_offset = reg.byte_offset + reg.byte_size;
+ if (m_reg_data_byte_size < reg_offset)
+ m_reg_data_byte_size = reg_offset;
+ }
}
+bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable; }
+
size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }
size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }
@@ -737,16 +794,10 @@ void DynamicRegisterInfo::Dump() const {
}
}
-const lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
- lldb_private::ConstString reg_name) const {
- for (auto &reg_info : m_regs) {
- // We can use pointer comparison since we used a ConstString to set the
- // "name" member in AddRegister()
- assert(ConstString(reg_info.name).GetCString() == reg_info.name &&
- "reg_info.name not from a ConstString?");
- if (reg_info.name == reg_name.GetCString()) {
+const lldb_private::RegisterInfo *
+DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name) const {
+ for (auto &reg_info : m_regs)
+ if (reg_info.name == reg_name)
return &reg_info;
- }
- }
return nullptr;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index 48939375a504..fbf9db685b71 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -17,6 +17,10 @@
#include "lldb/lldb-private.h"
class DynamicRegisterInfo {
+protected:
+ DynamicRegisterInfo(DynamicRegisterInfo &) = default;
+ DynamicRegisterInfo &operator=(DynamicRegisterInfo &) = default;
+
public:
DynamicRegisterInfo() = default;
@@ -25,9 +29,6 @@ public:
virtual ~DynamicRegisterInfo() = default;
- DynamicRegisterInfo(DynamicRegisterInfo &) = delete;
- void operator=(DynamicRegisterInfo &) = delete;
-
DynamicRegisterInfo(DynamicRegisterInfo &&info);
DynamicRegisterInfo &operator=(DynamicRegisterInfo &&info);
@@ -63,6 +64,11 @@ public:
void Clear();
+ bool IsReconfigurable();
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfo(llvm::StringRef reg_name) const;
+
protected:
// Classes that inherit from DynamicRegisterInfo can see and modify these
typedef std::vector<lldb_private::RegisterInfo> reg_collection;
@@ -74,11 +80,10 @@ protected:
typedef std::vector<uint8_t> dwarf_opcode;
typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
- const lldb_private::RegisterInfo *
- GetRegisterInfo(lldb_private::ConstString reg_name) const;
-
void MoveFrom(DynamicRegisterInfo &&info);
+ void ConfigureOffsets();
+
reg_collection m_regs;
set_collection m_sets;
set_reg_num_collection m_set_reg_nums;
@@ -89,5 +94,6 @@ protected:
size_t m_reg_data_byte_size = 0u; // The number of bytes required to store
// all registers
bool m_finalized = false;
+ bool m_is_reconfigurable = false;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
new file mode 100644
index 000000000000..7f6f7cf5832d
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
@@ -0,0 +1,291 @@
+//===-- LinuxPTraceDefines_arm64sve.h ------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
+
+#include <stdint.h>
+
+namespace lldb_private {
+namespace sve {
+
+/*
+ * The SVE architecture leaves space for future expansion of the
+ * vector length beyond its initial architectural limit of 2048 bits
+ * (16 quadwords).
+ *
+ * See <Linux kernel source tree>/Documentation/arm64/sve.rst for a description
+ * of the vl/vq terminology.
+ */
+
+const uint16_t vq_bytes = 16; /* number of bytes per quadword */
+
+const uint16_t vq_min = 1;
+const uint16_t vq_max = 512;
+
+const uint16_t vl_min = vq_min * vq_bytes;
+const uint16_t vl_max = vq_max * vq_bytes;
+
+const uint16_t num_of_zregs = 32;
+const uint16_t num_of_pregs = 16;
+
+inline uint16_t vl_valid(uint16_t vl) {
+ return (vl % vq_bytes == 0 && vl >= vl_min && vl <= vl_max);
+}
+
+inline uint16_t vq_from_vl(uint16_t vl) { return vl / vq_bytes; }
+inline uint16_t vl_from_vq(uint16_t vq) { return vq * vq_bytes; }
+
+/* A new signal frame record sve_context encodes the SVE Registers on signal
+ * delivery. sve_context struct definition may be included in asm/sigcontext.h.
+ * We define sve_context_size which will be used by LLDB sve helper functions.
+ * More information on sve_context can be found in Linux kernel source tree at
+ * Documentation/arm64/sve.rst.
+ */
+
+const uint16_t sve_context_size = 16;
+
+/*
+ * If the SVE registers are currently live for the thread at signal delivery,
+ * sve_context.head.size >=
+ * SigContextSize(vq_from_vl(sve_context.vl))
+ * and the register data may be accessed using the Sig*() functions.
+ *
+ * If sve_context.head.size <
+ * SigContextSize(vq_from_vl(sve_context.vl)),
+ * the SVE registers were not live for the thread and no register data
+ * is included: in this case, the Sig*() functions should not be
+ * used except for this check.
+ *
+ * The same convention applies when returning from a signal: a caller
+ * will need to remove or resize the sve_context block if it wants to
+ * make the SVE registers live when they were previously non-live or
+ * vice-versa. This may require the the caller to allocate fresh
+ * memory and/or move other context blocks in the signal frame.
+ *
+ * Changing the vector length during signal return is not permitted:
+ * sve_context.vl must equal the thread's current vector length when
+ * doing a sigreturn.
+ *
+ *
+ * Note: for all these functions, the "vq" argument denotes the SVE
+ * vector length in quadwords (i.e., units of 128 bits).
+ *
+ * The correct way to obtain vq is to use vq_from_vl(vl). The
+ * result is valid if and only if vl_valid(vl) is true. This is
+ * guaranteed for a struct sve_context written by the kernel.
+ *
+ *
+ * Additional functions describe the contents and layout of the payload.
+ * For each, Sig*Offset(args) is the start offset relative to
+ * the start of struct sve_context, and Sig*Size(args) is the
+ * size in bytes:
+ *
+ * x type description
+ * - ---- -----------
+ * REGS the entire SVE context
+ *
+ * ZREGS __uint128_t[num_of_zregs][vq] all Z-registers
+ * ZREG __uint128_t[vq] individual Z-register Zn
+ *
+ * PREGS uint16_t[num_of_pregs][vq] all P-registers
+ * PREG uint16_t[vq] individual P-register Pn
+ *
+ * FFR uint16_t[vq] first-fault status register
+ *
+ * Additional data might be appended in the future.
+ */
+
+inline uint16_t SigZRegSize(uint16_t vq) { return vq * vq_bytes; }
+inline uint16_t SigPRegSize(uint16_t vq) { return vq * vq_bytes / 8; }
+inline uint16_t SigFFRSize(uint16_t vq) { return SigPRegSize(vq); }
+
+inline uint32_t SigRegsOffset() {
+ return (sve_context_size + vq_bytes - 1) / vq_bytes * vq_bytes;
+}
+
+inline uint32_t SigZRegsOffset() { return SigRegsOffset(); }
+
+inline uint32_t SigZRegOffset(uint16_t vq, uint16_t n) {
+ return SigRegsOffset() + SigZRegSize(vq) * n;
+}
+
+inline uint32_t SigZRegsSize(uint16_t vq) {
+ return SigZRegOffset(vq, num_of_zregs) - SigRegsOffset();
+}
+
+inline uint32_t SigPRegsOffset(uint16_t vq) {
+ return SigRegsOffset() + SigZRegsSize(vq);
+}
+
+inline uint32_t SigPRegOffset(uint16_t vq, uint16_t n) {
+ return SigPRegsOffset(vq) + SigPRegSize(vq) * n;
+}
+
+inline uint32_t SigpRegsSize(uint16_t vq) {
+ return SigPRegOffset(vq, num_of_pregs) - SigPRegsOffset(vq);
+}
+
+inline uint32_t SigFFROffset(uint16_t vq) {
+ return SigPRegsOffset(vq) + SigpRegsSize(vq);
+}
+
+inline uint32_t SigRegsSize(uint16_t vq) {
+ return SigFFROffset(vq) + SigFFRSize(vq) - SigRegsOffset();
+}
+
+inline uint32_t SVESigContextSize(uint16_t vq) {
+ return SigRegsOffset() + SigRegsSize(vq);
+}
+
+struct user_sve_header {
+ uint32_t size; /* total meaningful regset content in bytes */
+ uint32_t max_size; /* maxmium possible size for this thread */
+ uint16_t vl; /* current vector length */
+ uint16_t max_vl; /* maximum possible vector length */
+ uint16_t flags;
+ uint16_t reserved;
+};
+
+/* Definitions for user_sve_header.flags: */
+const uint16_t ptrace_regs_mask = 1 << 0;
+const uint16_t ptrace_regs_fpsimd = 0;
+const uint16_t ptrace_regs_sve = ptrace_regs_mask;
+
+/*
+ * The remainder of the SVE state follows struct user_sve_header. The
+ * total size of the SVE state (including header) depends on the
+ * metadata in the header: PTraceSize(vq, flags) gives the total size
+ * of the state in bytes, including the header.
+ *
+ * Refer to <asm/sigcontext.h> for details of how to pass the correct
+ * "vq" argument to these macros.
+ */
+
+/* Offset from the start of struct user_sve_header to the register data */
+inline uint16_t PTraceRegsOffset() {
+ return (sizeof(struct user_sve_header) + vq_bytes - 1) / vq_bytes * vq_bytes;
+}
+
+/*
+ * The register data content and layout depends on the value of the
+ * flags field.
+ */
+
+/*
+ * (flags & ptrace_regs_mask) == ptrace_regs_fpsimd case:
+ *
+ * The payload starts at offset PTraceFPSIMDOffset, and is of type
+ * struct user_fpsimd_state. Additional data might be appended in the
+ * future: use PTraceFPSIMDSize(vq, flags) to compute the total size.
+ * PTraceFPSIMDSize(vq, flags) will never be less than
+ * sizeof(struct user_fpsimd_state).
+ */
+
+const uint32_t ptrace_fpsimd_offset = PTraceRegsOffset();
+
+/* Return size of struct user_fpsimd_state from asm/ptrace.h */
+inline uint32_t PTraceFPSIMDSize(uint16_t vq, uint16_t flags) { return 528; }
+
+/*
+ * (flags & ptrace_regs_mask) == ptrace_regs_sve case:
+ *
+ * The payload starts at offset PTraceSVEOffset, and is of size
+ * PTraceSVESize(vq, flags).
+ *
+ * Additional functions describe the contents and layout of the payload.
+ * For each, PTrace*X*Offset(args) is the start offset relative to
+ * the start of struct user_sve_header, and PTrace*X*Size(args) is
+ * the size in bytes:
+ *
+ * x type description
+ * - ---- -----------
+ * ZREGS \
+ * ZREG |
+ * PREGS | refer to <asm/sigcontext.h>
+ * PREG |
+ * FFR /
+ *
+ * FPSR uint32_t FPSR
+ * FPCR uint32_t FPCR
+ *
+ * Additional data might be appended in the future.
+ */
+
+inline uint32_t PTraceZRegSize(uint16_t vq) { return SigZRegSize(vq); }
+
+inline uint32_t PTracePRegSize(uint16_t vq) { return SigPRegSize(vq); }
+
+inline uint32_t PTraceFFRSize(uint16_t vq) { return SigFFRSize(vq); }
+
+const uint32_t fpsr_size = sizeof(uint32_t);
+const uint32_t fpcr_size = sizeof(uint32_t);
+
+inline uint32_t SigToPTrace(uint32_t offset) {
+ return offset - SigRegsOffset() + PTraceRegsOffset();
+}
+
+const uint32_t ptrace_sve_offset = PTraceRegsOffset();
+
+inline uint32_t PTraceZRegsOffset(uint16_t vq) {
+ return SigToPTrace(SigZRegsOffset());
+}
+
+inline uint32_t PTraceZRegOffset(uint16_t vq, uint16_t n) {
+ return SigToPTrace(SigZRegOffset(vq, n));
+}
+
+inline uint32_t PTraceZRegsSize(uint16_t vq) {
+ return PTraceZRegOffset(vq, num_of_zregs) - SigToPTrace(SigRegsOffset());
+}
+
+inline uint32_t PTracePRegsOffset(uint16_t vq) {
+ return SigToPTrace(SigPRegsOffset(vq));
+}
+
+inline uint32_t PTracePRegOffset(uint16_t vq, uint16_t n) {
+ return SigToPTrace(SigPRegOffset(vq, n));
+}
+
+inline uint32_t PTracePRegsSize(uint16_t vq) {
+ return PTracePRegOffset(vq, num_of_pregs) - PTracePRegsOffset(vq);
+}
+
+inline uint32_t PTraceFFROffset(uint16_t vq) {
+ return SigToPTrace(SigFFROffset(vq));
+}
+
+inline uint32_t PTraceFPSROffset(uint16_t vq) {
+ return (PTraceFFROffset(vq) + PTraceFFRSize(vq) + (vq_bytes - 1)) / vq_bytes *
+ vq_bytes;
+}
+
+inline uint32_t PTraceFPCROffset(uint16_t vq) {
+ return PTraceFPSROffset(vq) + fpsr_size;
+}
+
+/*
+ * Any future extension appended after FPCR must be aligned to the next
+ * 128-bit boundary.
+ */
+
+inline uint32_t PTraceSVESize(uint16_t vq, uint16_t flags) {
+ return (PTraceFPCROffset(vq) + fpcr_size - ptrace_sve_offset + vq_bytes - 1) /
+ vq_bytes * vq_bytes;
+}
+
+inline uint32_t PTraceSize(uint16_t vq, uint16_t flags) {
+ return (flags & ptrace_regs_mask) == ptrace_regs_sve
+ ? ptrace_sve_offset + PTraceSVESize(vq, flags)
+ : ptrace_fpsimd_offset + PTraceFPSIMDSize(vq, flags);
+}
+
+} // namespace SVE
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
index 0c7d9ddc5ac6..947b970edf6c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
@@ -7,80 +7,93 @@
//===----------------------------------------------------------------------===//
#include "LinuxProcMaps.h"
-#include "llvm/ADT/StringRef.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringExtractor.h"
+#include "llvm/ADT/StringRef.h"
using namespace lldb_private;
-static Status
+enum class MapsKind { Maps, SMaps };
+
+static llvm::Expected<MemoryRegionInfo> ProcMapError(const char *msg,
+ MapsKind kind) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(), msg,
+ kind == MapsKind::Maps ? "maps" : "smaps");
+}
+
+static llvm::Expected<MemoryRegionInfo>
ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line,
- MemoryRegionInfo &memory_region_info) {
- memory_region_info.Clear();
-
+ MapsKind maps_kind) {
+ MemoryRegionInfo region;
StringExtractor line_extractor(maps_line);
-
+
// Format: {address_start_hex}-{address_end_hex} perms offset dev inode
// pathname perms: rwxp (letter is present if set, '-' if not, final
// character is p=private, s=shared).
-
+
// Parse out the starting address
lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0);
-
+
// Parse out hyphen separating start and end address from range.
if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-'))
- return Status(
- "malformed /proc/{pid}/maps entry, missing dash between address range");
-
+ return ProcMapError(
+ "malformed /proc/{pid}/%s entry, missing dash between address range",
+ maps_kind);
+
// Parse out the ending address
lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address);
-
+
// Parse out the space after the address.
if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' '))
- return Status(
- "malformed /proc/{pid}/maps entry, missing space after range");
-
+ return ProcMapError(
+ "malformed /proc/{pid}/%s entry, missing space after range", maps_kind);
+
// Save the range.
- memory_region_info.GetRange().SetRangeBase(start_address);
- memory_region_info.GetRange().SetRangeEnd(end_address);
-
- // Any memory region in /proc/{pid}/maps is by definition mapped into the
- // process.
- memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
-
+ region.GetRange().SetRangeBase(start_address);
+ region.GetRange().SetRangeEnd(end_address);
+
+ // Any memory region in /proc/{pid}/(maps|smaps) is by definition mapped
+ // into the process.
+ region.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
+
// Parse out each permission entry.
if (line_extractor.GetBytesLeft() < 4)
- return Status("malformed /proc/{pid}/maps entry, missing some portion of "
- "permissions");
-
+ return ProcMapError(
+ "malformed /proc/{pid}/%s entry, missing some portion of "
+ "permissions",
+ maps_kind);
+
// Handle read permission.
const char read_perm_char = line_extractor.GetChar();
if (read_perm_char == 'r')
- memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
+ region.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
else if (read_perm_char == '-')
- memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+ region.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
else
- return Status("unexpected /proc/{pid}/maps read permission char");
-
+ return ProcMapError("unexpected /proc/{pid}/%s read permission char",
+ maps_kind);
+
// Handle write permission.
const char write_perm_char = line_extractor.GetChar();
if (write_perm_char == 'w')
- memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
+ region.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
else if (write_perm_char == '-')
- memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+ region.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
else
- return Status("unexpected /proc/{pid}/maps write permission char");
-
+ return ProcMapError("unexpected /proc/{pid}/%s write permission char",
+ maps_kind);
+
// Handle execute permission.
const char exec_perm_char = line_extractor.GetChar();
if (exec_perm_char == 'x')
- memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
+ region.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
else if (exec_perm_char == '-')
- memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+ region.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
else
- return Status("unexpected /proc/{pid}/maps exec permission char");
-
+ return ProcMapError("unexpected /proc/{pid}/%s exec permission char",
+ maps_kind);
+
line_extractor.GetChar(); // Read the private bit
line_extractor.SkipSpaces(); // Skip the separator
line_extractor.GetHexMaxU64(false, 0); // Read the offset
@@ -89,13 +102,13 @@ ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line,
line_extractor.GetHexMaxU64(false, 0); // Read the major device number
line_extractor.SkipSpaces(); // Skip the separator
line_extractor.GetU64(0, 10); // Read the inode number
-
+
line_extractor.SkipSpaces();
const char *name = line_extractor.Peek();
if (name)
- memory_region_info.SetName(name);
-
- return Status();
+ region.SetName(name);
+
+ return region;
}
void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map,
@@ -104,9 +117,80 @@ void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map,
llvm::StringRef line;
while (!lines.empty()) {
std::tie(line, lines) = lines.split('\n');
- MemoryRegionInfo region;
- Status error = ParseMemoryRegionInfoFromProcMapsLine(line, region);
- if (!callback(region, error))
+ if (!callback(ParseMemoryRegionInfoFromProcMapsLine(line, MapsKind::Maps)))
break;
}
}
+
+void lldb_private::ParseLinuxSMapRegions(llvm::StringRef linux_smap,
+ LinuxMapCallback const &callback) {
+ // Entries in /smaps look like:
+ // 00400000-0048a000 r-xp 00000000 fd:03 960637
+ // Size: 552 kB
+ // Rss: 460 kB
+ // <...>
+ // VmFlags: rd ex mr mw me dw
+ // 00500000-0058a000 rwxp 00000000 fd:03 960637
+ // <...>
+ //
+ // Where the first line is identical to the /maps format
+ // and VmFlags is only printed for kernels >= 3.8.
+
+ llvm::StringRef lines(linux_smap);
+ llvm::StringRef line;
+ llvm::Optional<MemoryRegionInfo> region;
+
+ while (lines.size()) {
+ std::tie(line, lines) = lines.split('\n');
+
+ // A property line looks like:
+ // <word>: <value>
+ // (no spaces on the left hand side)
+ // A header will have a ':' but the LHS will contain spaces
+ llvm::StringRef name;
+ llvm::StringRef value;
+ std::tie(name, value) = line.split(':');
+
+ // If this line is a property line
+ if (!name.contains(' ')) {
+ if (region) {
+ if (name == "VmFlags") {
+ if (value.contains("mt"))
+ region->SetMemoryTagged(MemoryRegionInfo::eYes);
+ else
+ region->SetMemoryTagged(MemoryRegionInfo::eNo);
+ }
+ // Ignore anything else
+ } else {
+ // Orphaned settings line
+ callback(ProcMapError(
+ "Found a property line without a corresponding mapping "
+ "in /proc/{pid}/%s",
+ MapsKind::SMaps));
+ return;
+ }
+ } else {
+ // Must be a new region header
+ if (region) {
+ // Save current region
+ callback(*region);
+ region.reset();
+ }
+
+ // Try to start a new region
+ llvm::Expected<MemoryRegionInfo> new_region =
+ ParseMemoryRegionInfoFromProcMapsLine(line, MapsKind::SMaps);
+ if (new_region) {
+ region = *new_region;
+ } else {
+ // Stop at first invalid region header
+ callback(new_region.takeError());
+ return;
+ }
+ }
+ }
+
+ // Catch last region
+ if (region)
+ callback(*region);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
index 363f248fd416..02f78d55c290 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
@@ -11,16 +11,16 @@
#include "lldb/lldb-forward.h"
#include "llvm/ADT/StringRef.h"
-#include <functional>
-
+#include "llvm/Support/Error.h"
namespace lldb_private {
-typedef std::function<bool(const lldb_private::MemoryRegionInfo &,
- const lldb_private::Status &)> LinuxMapCallback;
+typedef std::function<bool(llvm::Expected<MemoryRegionInfo>)> LinuxMapCallback;
void ParseLinuxMapRegions(llvm::StringRef linux_map,
LinuxMapCallback const &callback);
+void ParseLinuxSMapRegions(llvm::StringRef linux_smap,
+ LinuxMapCallback const &callback);
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
index 4dd619e3bade..d4b0f4039da9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
@@ -14,79 +14,72 @@ LinuxSignals::LinuxSignals() : UnixSignals() { Reset(); }
void LinuxSignals::Reset() {
m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
- // ===== =========== ======== ===== ======
- // ====================================== ======
- AddSignal(1, "SIGHUP", false, true, true, "hangup");
- AddSignal(2, "SIGINT", true, true, true, "interrupt");
- AddSignal(3, "SIGQUIT", false, true, true, "quit");
- AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
- AddSignal(5, "SIGTRAP", true, true, true,
- "trace trap (not reset when caught)");
- AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
- AddSignal(7, "SIGBUS", false, true, true, "bus error");
- AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
- AddSignal(9, "SIGKILL", false, true, true, "kill");
- AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1");
- AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
- AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2");
- AddSignal(13, "SIGPIPE", false, true, true,
- "write to pipe with reading end closed");
- AddSignal(14, "SIGALRM", false, false, false, "alarm");
- AddSignal(15, "SIGTERM", false, true, true, "termination requested");
- AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault");
- AddSignal(17, "SIGCHLD", false, false, true, "child status has changed",
- "SIGCLD");
- AddSignal(18, "SIGCONT", false, true, true, "process continue");
- AddSignal(19, "SIGSTOP", true, true, true, "process stop");
- AddSignal(20, "SIGTSTP", false, true, true, "tty stop");
- AddSignal(21, "SIGTTIN", false, true, true, "background tty read");
- AddSignal(22, "SIGTTOU", false, true, true, "background tty write");
- AddSignal(23, "SIGURG", false, true, true, "urgent data on socket");
- AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded");
- AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded");
- AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm");
- AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
- AddSignal(28, "SIGWINCH", false, true, true, "window size changes");
- AddSignal(29, "SIGIO", false, true, true, "input/output ready/Pollable event",
- "SIGPOLL");
- AddSignal(30, "SIGPWR", false, true, true, "power failure");
- AddSignal(31, "SIGSYS", false, true, true, "invalid system call");
- AddSignal(32, "SIG32", false, false, false,
- "threading library internal signal 1");
- AddSignal(33, "SIG33", false, false, false,
- "threading library internal signal 2");
- AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
- AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
- AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
- AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
- AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
- AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
- AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
- AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
- AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
- AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
- AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
- AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
- AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
- AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
- AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
- AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
- AddSignal(50, "SIGRTMAX-14", false, false, false,
- "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill
- // -l" output
- AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
- AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
- AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
- AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
- AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
- AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
- AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
- AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
- AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
- AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
- AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
- AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
- AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
- AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
+ // clang-format off
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============== ======== ====== ====== ===================================================
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
+ AddSignal(7, "SIGBUS", false, true, true, "bus error");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2");
+ AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm");
+ AddSignal(15, "SIGTERM", false, true, true, "termination requested");
+ AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault");
+ AddSignal(17, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD");
+ AddSignal(18, "SIGCONT", false, false, true, "process continue");
+ AddSignal(19, "SIGSTOP", true, true, true, "process stop");
+ AddSignal(20, "SIGTSTP", false, true, true, "tty stop");
+ AddSignal(21, "SIGTTIN", false, true, true, "background tty read");
+ AddSignal(22, "SIGTTOU", false, true, true, "background tty write");
+ AddSignal(23, "SIGURG", false, true, true, "urgent data on socket");
+ AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded");
+ AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded");
+ AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm");
+ AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(28, "SIGWINCH", false, true, true, "window size changes");
+ AddSignal(29, "SIGIO", false, true, true, "input/output ready/Pollable event", "SIGPOLL");
+ AddSignal(30, "SIGPWR", false, true, true, "power failure");
+ AddSignal(31, "SIGSYS", false, true, true, "invalid system call");
+ AddSignal(32, "SIG32", false, false, false, "threading library internal signal 1");
+ AddSignal(33, "SIG33", false, false, false, "threading library internal signal 2");
+ AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(50, "SIGRTMAX-14", false, false, false, "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill -l" output
+ AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
+ AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
+ AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
+ AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
+ AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
+ AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
+ AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
+ AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
+ AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
+ AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
+ AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
+ AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
+ AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
+ AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
+ // clang-format on
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
index 8f75844277c0..fb51c56953f8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
@@ -14,79 +14,72 @@ MipsLinuxSignals::MipsLinuxSignals() : UnixSignals() { Reset(); }
void MipsLinuxSignals::Reset() {
m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
- // ===== =========== ======== ===== ======
- // ====================================== ========
- AddSignal(1, "SIGHUP", false, true, true, "hangup");
- AddSignal(2, "SIGINT", true, true, true, "interrupt");
- AddSignal(3, "SIGQUIT", false, true, true, "quit");
- AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
- AddSignal(5, "SIGTRAP", true, true, true,
- "trace trap (not reset when caught)");
- AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
- AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump");
- AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
- AddSignal(9, "SIGKILL", false, true, true, "kill");
- AddSignal(10, "SIGBUS", false, true, true, "bus error");
- AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
- AddSignal(12, "SIGSYS", false, true, true, "invalid system call");
- AddSignal(13, "SIGPIPE", false, true, true,
- "write to pipe with reading end closed");
- AddSignal(14, "SIGALRM", false, false, false, "alarm");
- AddSignal(15, "SIGTERM", false, true, true, "termination requested");
- AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1");
- AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2");
- AddSignal(18, "SIGCHLD", false, false, true, "child status has changed",
- "SIGCLD");
- AddSignal(19, "SIGPWR", false, true, true, "power failure");
- AddSignal(20, "SIGWINCH", false, true, true, "window size changes");
- AddSignal(21, "SIGURG", false, true, true, "urgent data on socket");
- AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event",
- "SIGPOLL");
- AddSignal(23, "SIGSTOP", true, true, true, "process stop");
- AddSignal(24, "SIGTSTP", false, true, true, "tty stop");
- AddSignal(25, "SIGCONT", false, true, true, "process continue");
- AddSignal(26, "SIGTTIN", false, true, true, "background tty read");
- AddSignal(27, "SIGTTOU", false, true, true, "background tty write");
- AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm");
- AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm");
- AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded");
- AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded");
- AddSignal(32, "SIG32", false, false, false,
- "threading library internal signal 1");
- AddSignal(33, "SIG33", false, false, false,
- "threading library internal signal 2");
- AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
- AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
- AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
- AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
- AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
- AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
- AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
- AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
- AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
- AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
- AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
- AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
- AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
- AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
- AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
- AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
- AddSignal(50, "SIGRTMAX-14", false, false, false,
- "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill
- // -l" output
- AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
- AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
- AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
- AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
- AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
- AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
- AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
- AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
- AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
- AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
- AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
- AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
- AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
- AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
+ // clang-format off
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============== ======== ====== ====== ===================================================
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
+ AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGBUS", false, true, true, "bus error");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGSYS", false, true, true, "invalid system call");
+ AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm");
+ AddSignal(15, "SIGTERM", false, true, true, "termination requested");
+ AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2");
+ AddSignal(18, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD");
+ AddSignal(19, "SIGPWR", false, true, true, "power failure");
+ AddSignal(20, "SIGWINCH", false, true, true, "window size changes");
+ AddSignal(21, "SIGURG", false, true, true, "urgent data on socket");
+ AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event", "SIGPOLL");
+ AddSignal(23, "SIGSTOP", true, true, true, "process stop");
+ AddSignal(24, "SIGTSTP", false, true, true, "tty stop");
+ AddSignal(25, "SIGCONT", false, false, true, "process continue");
+ AddSignal(26, "SIGTTIN", false, true, true, "background tty read");
+ AddSignal(27, "SIGTTOU", false, true, true, "background tty write");
+ AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm");
+ AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded");
+ AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded");
+ AddSignal(32, "SIG32", false, false, false, "threading library internal signal 1");
+ AddSignal(33, "SIG33", false, false, false, "threading library internal signal 2");
+ AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(50, "SIGRTMAX-14", false, false, false, "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill -l" output
+ AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
+ AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
+ AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
+ AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
+ AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
+ AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
+ AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
+ AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
+ AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
+ AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
+ AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
+ AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
+ AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
+ AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
+ // clang-format on
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
new file mode 100644
index 000000000000..ee5295bf6565
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
@@ -0,0 +1,182 @@
+//===-- NativeProcessSoftwareSingleStep.cpp -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeProcessSoftwareSingleStep.h"
+
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#include <unordered_map>
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+struct EmulatorBaton {
+ NativeProcessProtocol &m_process;
+ NativeRegisterContext &m_reg_context;
+
+ // eRegisterKindDWARF -> RegsiterValue
+ std::unordered_map<uint32_t, RegisterValue> m_register_values;
+
+ EmulatorBaton(NativeProcessProtocol &process,
+ NativeRegisterContext &reg_context)
+ : m_process(process), m_reg_context(reg_context) {}
+};
+
+} // anonymous namespace
+
+static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+
+ size_t bytes_read;
+ emulator_baton->m_process.ReadMemory(addr, dst, length, bytes_read);
+ return bytes_read;
+}
+
+static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+
+ auto it = emulator_baton->m_register_values.find(
+ reg_info->kinds[eRegisterKindDWARF]);
+ if (it != emulator_baton->m_register_values.end()) {
+ reg_value = it->second;
+ return true;
+ }
+
+ // The emulator only fill in the dwarf regsiter numbers (and in some case the
+ // generic register numbers). Get the full register info from the register
+ // context based on the dwarf register numbers.
+ const RegisterInfo *full_reg_info =
+ emulator_baton->m_reg_context.GetRegisterInfo(
+ eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
+
+ Status error =
+ emulator_baton->m_reg_context.ReadRegister(full_reg_info, reg_value);
+ if (error.Success())
+ return true;
+
+ return false;
+}
+
+static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+ emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
+ reg_value;
+ return true;
+}
+
+static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst,
+ size_t length) {
+ return length;
+}
+
+static lldb::addr_t ReadFlags(NativeRegisterContext &regsiter_context) {
+ const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ return regsiter_context.ReadRegisterAsUnsigned(flags_info,
+ LLDB_INVALID_ADDRESS);
+}
+
+Status NativeProcessSoftwareSingleStep::SetupSoftwareSingleStepping(
+ NativeThreadProtocol &thread) {
+ Status error;
+ NativeProcessProtocol &process = thread.GetProcess();
+ NativeRegisterContext &register_context = thread.GetRegisterContext();
+ const ArchSpec &arch = process.GetArchitecture();
+
+ std::unique_ptr<EmulateInstruction> emulator_up(
+ EmulateInstruction::FindPlugin(arch, eInstructionTypePCModifying,
+ nullptr));
+
+ if (emulator_up == nullptr)
+ return Status("Instruction emulator not found!");
+
+ EmulatorBaton baton(process, register_context);
+ emulator_up->SetBaton(&baton);
+ emulator_up->SetReadMemCallback(&ReadMemoryCallback);
+ emulator_up->SetReadRegCallback(&ReadRegisterCallback);
+ emulator_up->SetWriteMemCallback(&WriteMemoryCallback);
+ emulator_up->SetWriteRegCallback(&WriteRegisterCallback);
+
+ if (!emulator_up->ReadInstruction())
+ return Status("Read instruction failed!");
+
+ bool emulation_result =
+ emulator_up->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
+
+ const RegisterInfo *reg_info_pc = register_context.GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *reg_info_flags = register_context.GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+
+ auto pc_it =
+ baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
+ auto flags_it =
+ baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
+
+ lldb::addr_t next_pc;
+ lldb::addr_t next_flags;
+ if (emulation_result) {
+ assert(pc_it != baton.m_register_values.end() &&
+ "Emulation was successfull but PC wasn't updated");
+ next_pc = pc_it->second.GetAsUInt64();
+
+ if (flags_it != baton.m_register_values.end())
+ next_flags = flags_it->second.GetAsUInt64();
+ else
+ next_flags = ReadFlags(register_context);
+ } else if (pc_it == baton.m_register_values.end()) {
+ // Emulate instruction failed and it haven't changed PC. Advance PC with
+ // the size of the current opcode because the emulation of all
+ // PC modifying instruction should be successful. The failure most
+ // likely caused by a not supported instruction which don't modify PC.
+ next_pc = register_context.GetPC() + emulator_up->GetOpcode().GetByteSize();
+ next_flags = ReadFlags(register_context);
+ } else {
+ // The instruction emulation failed after it modified the PC. It is an
+ // unknown error where we can't continue because the next instruction is
+ // modifying the PC but we don't know how.
+ return Status("Instruction emulation failed unexpectedly.");
+ }
+
+ int size_hint = 0;
+ if (arch.GetMachine() == llvm::Triple::arm) {
+ if (next_flags & 0x20) {
+ // Thumb mode
+ size_hint = 2;
+ } else {
+ // Arm mode
+ size_hint = 4;
+ }
+ } else if (arch.IsMIPS() || arch.GetTriple().isPPC64())
+ size_hint = 4;
+ error = process.SetBreakpoint(next_pc, size_hint, /*hardware=*/false);
+
+ // If setting the breakpoint fails because next_pc is out of the address
+ // space, ignore it and let the debugee segfault.
+ if (error.GetError() == EIO || error.GetError() == EFAULT) {
+ return Status();
+ } else if (error.Fail())
+ return error;
+
+ m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
+
+ return Status();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h
new file mode 100644
index 000000000000..f9435b7a84ba
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h
@@ -0,0 +1,31 @@
+//===-- NativeProcessSoftwareSingleStep.h -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeProcessSoftwareSingleStep_h
+#define lldb_NativeProcessSoftwareSingleStep_h
+
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
+
+#include <map>
+
+namespace lldb_private {
+
+class NativeProcessSoftwareSingleStep {
+public:
+ Status SetupSoftwareSingleStepping(NativeThreadProtocol &thread);
+
+protected:
+ // List of thread ids stepping with a breakpoint with the address of
+ // the relevan breakpoint
+ std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeProcessSoftwareSingleStep_h
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
new file mode 100644
index 000000000000..5c05baf71764
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
@@ -0,0 +1,466 @@
+//===-- NativeRegisterContextDBReg_arm64.cpp ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextDBReg_arm64.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+using namespace lldb_private;
+
+// E (bit 0), used to enable breakpoint/watchpoint
+constexpr uint32_t g_enable_bit = 1;
+// PAC (bits 2:1): 0b10
+constexpr uint32_t g_pac_bits = (2 << 1);
+
+// Returns appropriate control register bits for the specified size
+static constexpr inline uint64_t GetSizeBits(int size) {
+ // BAS (bits 12:5) hold a bit-mask of addresses to watch
+ // e.g. 0b00000001 means 1 byte at address
+ // 0b00000011 means 2 bytes (addr..addr+1)
+ // ...
+ // 0b11111111 means 8 bytes (addr..addr+7)
+ return ((1 << size) - 1) << 5;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareBreakpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(log, std::move(error),
+ "failed to read debug registers: {0}");
+ return 0;
+ }
+
+ return m_max_hbp_supported;
+}
+
+uint32_t
+NativeRegisterContextDBReg_arm64::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to set breakpoint: failed to read debug registers: {0}");
+ return LLDB_INVALID_INDEX32;
+ }
+
+ uint32_t control_value = 0, bp_index = 0;
+
+ // Check if size has a valid hardware breakpoint length.
+ if (size != 4)
+ return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware
+ // breakpoint
+
+ // Check 4-byte alignment for hardware breakpoint target address.
+ if (addr & 0x03)
+ return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
+
+ // Setup control value
+ control_value = g_enable_bit | g_pac_bits | GetSizeBits(size);
+
+ // Iterate over stored breakpoints and find a free bp_index
+ bp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ if (!BreakpointIsEnabled(i))
+ bp_index = i; // Mark last free slot
+ else if (m_hbp_regs[i].address == addr)
+ return LLDB_INVALID_INDEX32; // We do not support duplicate breakpoints.
+ }
+
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update breakpoint in local cache
+ m_hbp_regs[bp_index].real_addr = addr;
+ m_hbp_regs[bp_index].address = addr;
+ m_hbp_regs[bp_index].control = control_value;
+
+ // PTRACE call to set corresponding hardware breakpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+ if (error) {
+ m_hbp_regs[bp_index].address = 0;
+ m_hbp_regs[bp_index].control &= ~1;
+
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to set breakpoint: failed to write debug registers: {0}");
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return bp_index;
+}
+
+bool NativeRegisterContextDBReg_arm64::ClearHardwareBreakpoint(
+ uint32_t hw_idx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ LLDB_LOG(log, "hw_idx: {0}", hw_idx);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to clear breakpoint: failed to read debug registers: {0}");
+ return false;
+ }
+
+ if (hw_idx >= m_max_hbp_supported)
+ return false;
+
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hbp_regs[hw_idx].address;
+ uint32_t tempControl = m_hbp_regs[hw_idx].control;
+
+ m_hbp_regs[hw_idx].control &= ~g_enable_bit;
+ m_hbp_regs[hw_idx].address = 0;
+
+ // PTRACE call to clear corresponding hardware breakpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+ if (error) {
+ m_hbp_regs[hw_idx].control = tempControl;
+ m_hbp_regs[hw_idx].address = tempAddr;
+
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to clear breakpoint: failed to write debug registers: {0}");
+ return false;
+ }
+
+ return true;
+}
+
+Status NativeRegisterContextDBReg_arm64::GetHardwareBreakHitIndex(
+ uint32_t &bp_index, lldb::addr_t trap_addr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__);
+
+ lldb::addr_t break_addr;
+
+ for (bp_index = 0; bp_index < m_max_hbp_supported; ++bp_index) {
+ break_addr = m_hbp_regs[bp_index].address;
+
+ if (BreakpointIsEnabled(bp_index) && trap_addr == break_addr) {
+ m_hbp_regs[bp_index].hit_addr = trap_addr;
+ return Status();
+ }
+ }
+
+ bp_index = LLDB_INVALID_INDEX32;
+ return Status();
+}
+
+Status NativeRegisterContextDBReg_arm64::ClearAllHardwareBreakpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error)
+ return Status(std::move(error));
+
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ if (BreakpointIsEnabled(i)) {
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hbp_regs[i].address;
+ uint32_t tempControl = m_hbp_regs[i].control;
+
+ // Clear watchpoints in local cache
+ m_hbp_regs[i].control &= ~g_enable_bit;
+ m_hbp_regs[i].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+ if (error) {
+ m_hbp_regs[i].control = tempControl;
+ m_hbp_regs[i].address = tempAddr;
+
+ return Status(std::move(error));
+ }
+ }
+ }
+
+ return Status();
+}
+
+bool NativeRegisterContextDBReg_arm64::BreakpointIsEnabled(uint32_t bp_index) {
+ if ((m_hbp_regs[bp_index].control & g_enable_bit) != 0)
+ return true;
+ else
+ return false;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(log, std::move(error),
+ "failed to read debug registers: {0}");
+ return 0;
+ }
+
+ return m_max_hwp_supported;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
+ watch_flags);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to set watchpoint: failed to read debug registers: {0}");
+ return LLDB_INVALID_INDEX32;
+ }
+
+ uint32_t control_value = 0, wp_index = 0;
+ lldb::addr_t real_addr = addr;
+
+ // Check if we are setting watchpoint other than read/write/access Also
+ // update watchpoint flag to match AArch64 write-read bit configuration.
+ switch (watch_flags) {
+ case 1:
+ watch_flags = 2;
+ break;
+ case 2:
+ watch_flags = 1;
+ break;
+ case 3:
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
+
+ // Check if size has a valid hardware watchpoint length.
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return LLDB_INVALID_INDEX32;
+
+ // Check 8-byte alignment for hardware watchpoint target address. Below is a
+ // hack to recalculate address and size in order to make sure we can watch
+ // non 8-byte aligned addresses as well.
+ if (addr & 0x07) {
+ uint8_t watch_mask = (addr & 0x07) + size;
+
+ if (watch_mask > 0x08)
+ return LLDB_INVALID_INDEX32;
+ else if (watch_mask <= 0x02)
+ size = 2;
+ else if (watch_mask <= 0x04)
+ size = 4;
+ else
+ size = 8;
+
+ addr = addr & (~0x07);
+ }
+
+ // Setup control value
+ control_value = g_enable_bit | g_pac_bits | GetSizeBits(size);
+ control_value |= watch_flags << 3;
+
+ // Iterate over stored watchpoints and find a free wp_index
+ wp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if (!WatchpointIsEnabled(i))
+ wp_index = i; // Mark last free slot
+ else if (m_hwp_regs[i].address == addr) {
+ return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
+ }
+ }
+
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
+ m_hwp_regs[wp_index].address = addr;
+ m_hwp_regs[wp_index].control = control_value;
+
+ // PTRACE call to set corresponding watchpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error) {
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].control &= ~g_enable_bit;
+
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to set watchpoint: failed to write debug registers: {0}");
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return wp_index;
+}
+
+bool NativeRegisterContextDBReg_arm64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to clear watchpoint: failed to read debug registers: {0}");
+ return false;
+ }
+
+ if (wp_index >= m_max_hwp_supported)
+ return false;
+
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+ uint32_t tempControl = m_hwp_regs[wp_index].control;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].control &= ~g_enable_bit;
+ m_hwp_regs[wp_index].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error) {
+ m_hwp_regs[wp_index].control = tempControl;
+ m_hwp_regs[wp_index].address = tempAddr;
+
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to clear watchpoint: failed to write debug registers: {0}");
+ return false;
+ }
+
+ return true;
+}
+
+Status NativeRegisterContextDBReg_arm64::ClearAllHardwareWatchpoints() {
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error)
+ return Status(std::move(error));
+
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if (WatchpointIsEnabled(i)) {
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[i].address;
+ uint32_t tempControl = m_hwp_regs[i].control;
+
+ // Clear watchpoints in local cache
+ m_hwp_regs[i].control &= ~g_enable_bit;
+ m_hwp_regs[i].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error) {
+ m_hwp_regs[i].control = tempControl;
+ m_hwp_regs[i].address = tempAddr;
+
+ return Status(std::move(error));
+ }
+ }
+ }
+
+ return Status();
+}
+
+uint32_t
+NativeRegisterContextDBReg_arm64::GetWatchpointSize(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {
+ case 0x01:
+ return 1;
+ case 0x03:
+ return 2;
+ case 0x0f:
+ return 4;
+ case 0xff:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+bool NativeRegisterContextDBReg_arm64::WatchpointIsEnabled(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if ((m_hwp_regs[wp_index].control & g_enable_bit) != 0)
+ return true;
+ else
+ return false;
+}
+
+Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error)
+ return Status(std::move(error));
+
+ uint32_t watch_size;
+ lldb::addr_t watch_addr;
+
+ for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+ watch_size = GetWatchpointSize(wp_index);
+ watch_addr = m_hwp_regs[wp_index].address;
+
+ if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+ trap_addr < watch_addr + watch_size) {
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
+ return Status();
+ }
+ }
+
+ wp_index = LLDB_INVALID_INDEX32;
+ return Status();
+}
+
+lldb::addr_t
+NativeRegisterContextDBReg_arm64::GetWatchpointAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].real_addr;
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+NativeRegisterContextDBReg_arm64::GetWatchpointHitAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
+ return LLDB_INVALID_ADDRESS;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
new file mode 100644
index 000000000000..12ef5571f64c
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
@@ -0,0 +1,79 @@
+//===-- NativeRegisterContextDBReg_arm64.h ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextDBReg_arm64_h
+#define lldb_NativeRegisterContextDBReg_arm64_h
+
+#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+
+#include <array>
+
+namespace lldb_private {
+
+class NativeRegisterContextDBReg_arm64
+ : public virtual NativeRegisterContextRegisterInfo {
+public:
+ uint32_t NumSupportedHardwareBreakpoints() override;
+
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
+
+ Status ClearAllHardwareBreakpoints() override;
+
+ Status GetHardwareBreakHitIndex(uint32_t &bp_index,
+ lldb::addr_t trap_addr) override;
+
+ bool BreakpointIsEnabled(uint32_t bp_index);
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
+
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+ Status ClearAllHardwareWatchpoints() override;
+
+ Status GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
+
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
+
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
+
+ uint32_t GetWatchpointSize(uint32_t wp_index);
+
+ bool WatchpointIsEnabled(uint32_t wp_index);
+
+ // Debug register type select
+ enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
+
+protected:
+ // Debug register info for hardware breakpoints and watchpoints management.
+ struct DREG {
+ lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
+ // occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
+ uint32_t control; // Breakpoint/watchpoint control value.
+ };
+
+ std::array<struct DREG, 16> m_hbp_regs; // hardware breakpoints
+ std::array<struct DREG, 16> m_hwp_regs; // hardware watchpoints
+
+ uint32_t m_max_hbp_supported;
+ uint32_t m_max_hwp_supported;
+
+ virtual llvm::Error ReadHardwareDebugInfo() = 0;
+ virtual llvm::Error WriteHardwareDebugRegs(DREGType hwbType) = 0;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextDBReg_arm64_h
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp
new file mode 100644
index 000000000000..56c1757ee89d
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp
@@ -0,0 +1,276 @@
+//===-- NativeRegisterContextDBReg_x86.cpp --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextDBReg_x86.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+using namespace lldb_private;
+
+// Returns mask/value for status bit of wp_index in DR6
+static inline uint64_t GetStatusBit(uint32_t wp_index) {
+ // DR6: ...BBBB
+ // 3210 <- status bits for bp./wp. i; 1 if hit
+ return 1 << wp_index;
+}
+
+// Returns mask/value for global enable bit of wp_index in DR7
+static inline uint64_t GetEnableBit(uint32_t wp_index) {
+ // DR7: ...GLGLGLGL
+ // 33221100 <- global/local enable for bp./wp.; 1 if enabled
+ // we use global bits because NetBSD kernel does not preserve local
+ // bits reliably; Linux seems fine with either
+ return 1 << (2 * wp_index + 1);
+}
+
+// Returns mask for both enable bits of wp_index in DR7
+static inline uint64_t GetBothEnableBitMask(uint32_t wp_index) {
+ // DR7: ...GLGLGLGL
+ // 33221100 <- global/local enable for bp./wp.; 1 if enabled
+ return 3 << (2 * wp_index + 1);
+}
+
+// Returns value for type bits of wp_index in DR7
+static inline uint64_t GetWatchTypeBits(uint32_t watch_flags,
+ uint32_t wp_index) {
+ // DR7:
+ // bit: 3322222222221111...
+ // 1098765432109876...
+ // val: SSTTSSTTSSTTSSTT...
+ // wp.: 3333222211110000...
+ //
+ // where T - type is 01 for write, 11 for r/w
+ return watch_flags << (16 + 4 * wp_index);
+}
+
+// Returns value for size bits of wp_index in DR7
+static inline uint64_t GetWatchSizeBits(uint32_t size, uint32_t wp_index) {
+ // DR7:
+ // bit: 3322222222221111...
+ // 1098765432109876...
+ // val: SSTTSSTTSSTTSSTT...
+ // wp.: 3333222211110000...
+ //
+ // where S - size is:
+ // 00 for 1 byte
+ // 01 for 2 bytes
+ // 10 for 8 bytes
+ // 11 for 4 bytes
+ return (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
+}
+
+// Returns bitmask for all bits controlling wp_index in DR7
+static inline uint64_t GetWatchControlBitmask(uint32_t wp_index) {
+ // DR7:
+ // bit: 33222222222211111111110000000000
+ // 10987654321098765432109876543210
+ // val: SSTTSSTTSSTTSSTTxxxxxxGLGLGLGLGL
+ // wp.: 3333222211110000xxxxxxEE33221100
+ return GetBothEnableBitMask(wp_index) | (0xF << (16 + 4 * wp_index));
+}
+
+// Bit mask for control bits regarding all watchpoints.
+static constexpr uint64_t watchpoint_all_control_bit_mask = 0xFFFF00FF;
+
+const RegisterInfo *NativeRegisterContextDBReg_x86::GetDR(int num) const {
+ assert(num >= 0 && num <= 7);
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ return GetRegisterInfoAtIndex(lldb_dr0_i386 + num);
+ case llvm::Triple::x86_64:
+ return GetRegisterInfoAtIndex(lldb_dr0_x86_64 + num);
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+}
+
+Status NativeRegisterContextDBReg_x86::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ RegisterValue dr6;
+ Status error = ReadRegister(GetDR(6), dr6);
+ if (error.Fail())
+ is_hit = false;
+ else
+ is_hit = dr6.GetAsUInt64() & GetStatusBit(wp_index);
+
+ return error;
+}
+
+Status
+NativeRegisterContextDBReg_x86::GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Status error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ } else if (is_hit) {
+ return error;
+ }
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Status();
+}
+
+Status NativeRegisterContextDBReg_x86::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ RegisterValue dr7;
+ Status error = ReadRegister(GetDR(7), dr7);
+ if (error.Fail())
+ is_vacant = false;
+ else
+ is_vacant = !(dr7.GetAsUInt64() & GetEnableBit(wp_index));
+
+ return error;
+}
+
+Status NativeRegisterContextDBReg_x86::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ // Read only watchpoints aren't supported on x86_64. Fall back to read/write
+ // waitchpoints instead.
+ // TODO: Add logic to detect when a write happens and ignore that watchpoint
+ // hit.
+ if (watch_flags == 2)
+ watch_flags = 3;
+
+ if (watch_flags != 1 && watch_flags != 3)
+ return Status("Invalid read/write bits for watchpoint");
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return Status("Invalid size for watchpoint");
+
+ bool is_vacant;
+ Status error = IsWatchpointVacant(wp_index, is_vacant);
+ if (error.Fail())
+ return error;
+ if (!is_vacant)
+ return Status("Watchpoint index not vacant");
+
+ RegisterValue dr7, drN;
+ error = ReadRegister(GetDR(7), dr7);
+ if (error.Fail())
+ return error;
+ error = ReadRegister(GetDR(wp_index), drN);
+ if (error.Fail())
+ return error;
+
+ uint64_t control_bits = dr7.GetAsUInt64() & ~GetWatchControlBitmask(wp_index);
+ control_bits |= GetEnableBit(wp_index) |
+ GetWatchTypeBits(watch_flags, wp_index) |
+ GetWatchSizeBits(size, wp_index);
+
+ // Clear dr6 if address or bits changed (i.e. we're not reenabling the same
+ // watchpoint). This can not be done when clearing watchpoints since
+ // the gdb-remote protocol repeatedly clears and readds watchpoints on all
+ // program threads, effectively clearing pending events on NetBSD.
+ // NB: enable bits in dr7 are always 0 here since we're (re)adding it
+ if (drN.GetAsUInt64() != addr ||
+ (dr7.GetAsUInt64() & GetWatchControlBitmask(wp_index)) !=
+ (GetWatchTypeBits(watch_flags, wp_index) |
+ GetWatchSizeBits(size, wp_index))) {
+ ClearWatchpointHit(wp_index);
+
+ // We skip update to drN if neither address nor mode changed.
+ error = WriteRegister(GetDR(wp_index), RegisterValue(addr));
+ if (error.Fail())
+ return error;
+ }
+
+ error = WriteRegister(GetDR(7), RegisterValue(control_bits));
+ if (error.Fail())
+ return error;
+
+ return error;
+}
+
+bool NativeRegisterContextDBReg_x86::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
+
+ RegisterValue dr7;
+ Status error = ReadRegister(GetDR(7), dr7);
+ if (error.Fail())
+ return false;
+
+ return WriteRegister(GetDR(7), RegisterValue(dr7.GetAsUInt64() &
+ ~GetBothEnableBitMask(wp_index)))
+ .Success();
+}
+
+Status NativeRegisterContextDBReg_x86::ClearWatchpointHit(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ RegisterValue dr6;
+ Status error = ReadRegister(GetDR(6), dr6);
+ if (error.Fail())
+ return error;
+
+ return WriteRegister(
+ GetDR(6), RegisterValue(dr6.GetAsUInt64() & ~GetStatusBit(wp_index)));
+}
+
+Status NativeRegisterContextDBReg_x86::ClearAllHardwareWatchpoints() {
+ RegisterValue dr7;
+ Status error = ReadRegister(GetDR(7), dr7);
+ if (error.Fail())
+ return error;
+ return WriteRegister(
+ GetDR(7),
+ RegisterValue(dr7.GetAsUInt64() & ~watchpoint_all_control_bit_mask));
+}
+
+uint32_t NativeRegisterContextDBReg_x86::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
+ bool is_vacant;
+ Status error = IsWatchpointVacant(wp_index, is_vacant);
+ if (is_vacant) {
+ error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+ if (error.Success())
+ return wp_index;
+ }
+ if (error.Fail() && log) {
+ LLDB_LOGF(log, "NativeRegisterContextDBReg_x86::%s Error: %s",
+ __FUNCTION__, error.AsCString());
+ }
+ }
+ return LLDB_INVALID_INDEX32;
+}
+
+lldb::addr_t
+NativeRegisterContextDBReg_x86::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ RegisterValue drN;
+ if (ReadRegister(GetDR(wp_index), drN).Fail())
+ return LLDB_INVALID_ADDRESS;
+ return drN.GetAsUInt64();
+}
+
+uint32_t NativeRegisterContextDBReg_x86::NumSupportedHardwareWatchpoints() {
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
new file mode 100644
index 000000000000..c0c6ce29eab5
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
@@ -0,0 +1,48 @@
+//===-- NativeRegisterContextDBReg_x86.h ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextDBReg_x86_h
+#define lldb_NativeRegisterContextDBReg_x86_h
+
+#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+
+namespace lldb_private {
+
+class NativeRegisterContextDBReg_x86
+ : public virtual NativeRegisterContextRegisterInfo {
+public:
+ Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+
+ Status GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
+
+ Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
+
+ Status ClearWatchpointHit(uint32_t wp_index) override;
+
+ Status ClearAllHardwareWatchpoints() override;
+
+ Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags,
+ uint32_t wp_index);
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
+
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ const RegisterInfo *GetDR(int num) const;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextDBReg_x86_h
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
index 10d346a3cb7e..acebe9d53568 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
@@ -35,7 +35,7 @@ struct GPR {
uint32_t gs;
};
-struct dbreg {
+struct DBG {
uint32_t dr[8]; /* debug registers */
/* Index 0-3: debug address registers */
/* Index 4-5: reserved */
@@ -48,10 +48,13 @@ using FPR_i386 = FXSAVE;
struct UserArea {
GPR gpr;
FPR_i386 i387;
+ DBG dbg;
};
#define DR_SIZE sizeof(uint32_t)
-#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(dbreg, dr[reg_index]))
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, dbg) + \
+ LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
#define DECLARE_REGISTER_INFOS_I386_STRUCT
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
index c1f390ade9b9..e0f3971c6e27 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
@@ -59,7 +59,9 @@ struct UserArea {
DBG dbg;
};
-#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, dbg) + \
+ LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64
// structure.
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
index e7c180dbdd27..1ceca65c97c3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
@@ -19,21 +19,21 @@ public:
virtual ~RegisterContextMach_arm();
protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override;
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override;
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override;
- int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override;
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override;
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override;
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override;
- int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
index 09966be60c92..da5411eb2de2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
@@ -19,17 +19,17 @@ public:
virtual ~RegisterContextMach_i386();
protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override;
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override;
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override;
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override;
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override;
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
index 2a8a2cca2f8a..c131c8282bd2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
@@ -20,17 +20,17 @@ public:
virtual ~RegisterContextMach_x86_64();
protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override;
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override;
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override;
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override;
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override;
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index 617893b6b3b0..97a760396ba9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -25,88 +25,25 @@
using namespace lldb;
using namespace lldb_private;
-// arm general purpose registers.
-const uint32_t g_gpr_regnums_arm[] = {
- gpr_r0_arm, gpr_r1_arm, gpr_r2_arm, gpr_r3_arm, gpr_r4_arm,
- gpr_r5_arm, gpr_r6_arm, gpr_r7_arm, gpr_r8_arm, gpr_r9_arm,
- gpr_r10_arm, gpr_r11_arm, gpr_r12_arm, gpr_sp_arm, gpr_lr_arm,
- gpr_pc_arm, gpr_cpsr_arm,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-
-};
-static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
- k_num_gpr_registers_arm,
- "g_gpr_regnums_arm has wrong number of register infos");
-
-// arm floating point registers.
-static const uint32_t g_fpu_regnums_arm[] = {
- fpu_s0_arm, fpu_s1_arm, fpu_s2_arm, fpu_s3_arm, fpu_s4_arm,
- fpu_s5_arm, fpu_s6_arm, fpu_s7_arm, fpu_s8_arm, fpu_s9_arm,
- fpu_s10_arm, fpu_s11_arm, fpu_s12_arm, fpu_s13_arm, fpu_s14_arm,
- fpu_s15_arm, fpu_s16_arm, fpu_s17_arm, fpu_s18_arm, fpu_s19_arm,
- fpu_s20_arm, fpu_s21_arm, fpu_s22_arm, fpu_s23_arm, fpu_s24_arm,
- fpu_s25_arm, fpu_s26_arm, fpu_s27_arm, fpu_s28_arm, fpu_s29_arm,
- fpu_s30_arm, fpu_s31_arm, fpu_fpscr_arm, fpu_d0_arm, fpu_d1_arm,
- fpu_d2_arm, fpu_d3_arm, fpu_d4_arm, fpu_d5_arm, fpu_d6_arm,
- fpu_d7_arm, fpu_d8_arm, fpu_d9_arm, fpu_d10_arm, fpu_d11_arm,
- fpu_d12_arm, fpu_d13_arm, fpu_d14_arm, fpu_d15_arm, fpu_d16_arm,
- fpu_d17_arm, fpu_d18_arm, fpu_d19_arm, fpu_d20_arm, fpu_d21_arm,
- fpu_d22_arm, fpu_d23_arm, fpu_d24_arm, fpu_d25_arm, fpu_d26_arm,
- fpu_d27_arm, fpu_d28_arm, fpu_d29_arm, fpu_d30_arm, fpu_d31_arm,
- fpu_q0_arm, fpu_q1_arm, fpu_q2_arm, fpu_q3_arm, fpu_q4_arm,
- fpu_q5_arm, fpu_q6_arm, fpu_q7_arm, fpu_q8_arm, fpu_q9_arm,
- fpu_q10_arm, fpu_q11_arm, fpu_q12_arm, fpu_q13_arm, fpu_q14_arm,
- fpu_q15_arm,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-
-};
-static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
- k_num_fpr_registers_arm,
- "g_fpu_regnums_arm has wrong number of register infos");
-
-// Number of register sets provided by this context.
-enum { k_num_register_sets = 2 };
-
-// Register sets for arm.
-static const lldb_private::RegisterSet g_reg_sets_arm[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_arm,
- g_gpr_regnums_arm},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_arm,
- g_fpu_regnums_arm}};
-
bool RegisterContextPOSIX_arm::IsGPR(unsigned reg) {
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+ if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_arm::GPRegSet)
+ return true;
+ return false;
}
bool RegisterContextPOSIX_arm::IsFPR(unsigned reg) {
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+ if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_arm::FPRegSet)
+ return true;
+ return false;
}
RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : lldb_private::RegisterContext(thread, concrete_frame_idx) {
- m_register_info_up.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine()) {
- case llvm::Triple::arm:
- m_reg_info.num_registers = k_num_registers_arm;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
- m_reg_info.last_gpr = k_last_gpr_arm;
- m_reg_info.first_fpr = k_first_fpr_arm;
- m_reg_info.last_fpr = k_last_fpr_arm;
- m_reg_info.first_fpr_v = fpu_s0_arm;
- m_reg_info.last_fpr_v = fpu_s31_arm;
- m_reg_info.gpr_flags = gpr_cpsr_arm;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- ::memset(&m_fpr, 0, sizeof m_fpr);
-}
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm> register_info)
+ : lldb_private::RegisterContext(thread, 0),
+ m_register_info_up(std::move(register_info)) {}
RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() {}
@@ -115,19 +52,15 @@ void RegisterContextPOSIX_arm::Invalidate() {}
void RegisterContextPOSIX_arm::InvalidateAllRegisters() {}
unsigned RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+ return m_register_info_up->GetRegisterInfo()[reg].byte_offset;
}
unsigned RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+ return m_register_info_up->GetRegisterInfo()[reg].byte_size;
}
size_t RegisterContextPOSIX_arm::GetRegisterCount() {
- size_t num_registers =
- m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- return num_registers;
+ return m_register_info_up->GetRegisterCount();
}
size_t RegisterContextPOSIX_arm::GetGPRSize() {
@@ -143,41 +76,23 @@ const lldb_private::RegisterInfo *RegisterContextPOSIX_arm::GetRegisterInfo() {
const lldb_private::RegisterInfo *
RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg) {
- if (reg < m_reg_info.num_registers)
+ if (reg < GetRegisterCount())
return &GetRegisterInfo()[reg];
- else
- return nullptr;
+
+ return nullptr;
}
size_t RegisterContextPOSIX_arm::GetRegisterSetCount() {
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set) {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
-
- return sets;
+ return m_register_info_up->GetRegisterSetCount();
}
const lldb_private::RegisterSet *
RegisterContextPOSIX_arm::GetRegisterSet(size_t set) {
- if (IsRegisterSetAvailable(set)) {
- switch (m_register_info_up->m_target_arch.GetMachine()) {
- case llvm::Triple::arm:
- return &g_reg_sets_arm[set];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
- }
- return nullptr;
+ return m_register_info_up->GetRegisterSet(set);
}
const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
-}
-
-bool RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) {
- return set_index < k_num_register_sets;
+ if (reg < GetRegisterCount())
+ return GetRegisterInfo()[reg].name;
+ return nullptr;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
index d6967f05ed48..099c37d46f49 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
@@ -10,17 +10,15 @@
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H
#include "RegisterInfoInterface.h"
-#include "lldb-arm-register-enums.h"
+#include "RegisterInfoPOSIX_arm.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
class RegisterContextPOSIX_arm : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_arm(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_arm(
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm> register_info);
~RegisterContextPOSIX_arm() override;
@@ -45,46 +43,7 @@ public:
const char *GetRegisterName(unsigned reg);
protected:
- struct RegInfo {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- struct QReg {
- uint8_t bytes[16];
- };
-
- struct FPU {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
-
- uint32_t m_gpr_arm[lldb_private::k_num_gpr_registers_arm]; // 32-bit general
- // purpose
- // registers.
- RegInfo m_reg_info;
- struct RegisterContextPOSIX_arm::FPU
- m_fpr; // floating-point registers including extended register sets.
- std::unique_ptr<lldb_private::RegisterInfoInterface>
- m_register_info_up; // Register Info Interface (FreeBSD or Linux)
-
- // Determines if an extended register set is supported on the processor
- // running the inferior process.
- virtual bool IsRegisterSetAvailable(size_t set_index);
+ std::unique_ptr<RegisterInfoPOSIX_arm> m_register_info_up;
virtual const lldb_private::RegisterInfo *GetRegisterInfo();
@@ -92,6 +51,8 @@ protected:
bool IsFPR(unsigned reg);
+ size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm::FPU); }
+
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool WriteGPR() = 0;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 8ef587f13e3a..3f52501c35f3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -39,14 +39,18 @@ bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) {
return false;
}
+bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const {
+ if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_arm64::SVERegSet)
+ return true;
+ return false;
+}
+
RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
lldb_private::Thread &thread,
std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
: lldb_private::RegisterContext(thread, 0),
- m_register_info_up(std::move(register_info)) {
-
- ::memset(&m_fpr, 0, sizeof m_fpr);
-}
+ m_register_info_up(std::move(register_info)) {}
RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() {}
@@ -82,8 +86,8 @@ const lldb_private::RegisterInfo *
RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) {
if (reg < GetRegisterCount())
return &GetRegisterInfo()[reg];
- else
- return nullptr;
+
+ return nullptr;
}
size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index c2d5aee7f73c..a3f07bb2823b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -11,12 +11,9 @@
#include "RegisterInfoInterface.h"
#include "RegisterInfoPOSIX_arm64.h"
-#include "lldb-arm64-register-enums.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
public:
RegisterContextPOSIX_arm64(
@@ -46,13 +43,6 @@ public:
const char *GetRegisterName(unsigned reg);
protected:
- uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit
- // general
- // purpose
- // registers.
-
- struct RegisterInfoPOSIX_arm64::FPU
- m_fpr; // floating-point registers including extended register sets.
std::unique_ptr<RegisterInfoPOSIX_arm64> m_register_info_up;
virtual const lldb_private::RegisterInfo *GetRegisterInfo();
@@ -63,6 +53,23 @@ protected:
size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); }
+ bool IsSVE(unsigned reg) const;
+
+ bool IsSVEZ(unsigned reg) const { return m_register_info_up->IsSVEZReg(reg); }
+ bool IsSVEP(unsigned reg) const { return m_register_info_up->IsSVEPReg(reg); }
+ bool IsSVEVG(unsigned reg) const {
+ return m_register_info_up->IsSVERegVG(reg);
+ }
+
+ uint32_t GetRegNumSVEZ0() const {
+ return m_register_info_up->GetRegNumSVEZ0();
+ }
+ uint32_t GetRegNumSVEFFR() const {
+ return m_register_info_up->GetRegNumSVEFFR();
+ }
+ uint32_t GetRegNumFPCR() const { return m_register_info_up->GetRegNumFPCR(); }
+ uint32_t GetRegNumFPSR() const { return m_register_info_up->GetRegNumFPSR(); }
+
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool WriteGPR() = 0;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
index 1843a2a6aff3..b66dc3f44524 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
@@ -14,10 +14,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-using namespace lldb_private;
-
-class ProcessMonitor;
-
class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext {
public:
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
index e2c33461c8f1..5dd8c890da6e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
@@ -14,8 +14,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
// Internal codes for all powerpc registers.
enum {
k_first_gpr_powerpc,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
index 7df732d13ffa..7027af04f0bb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
@@ -15,8 +15,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext {
public:
RegisterContextPOSIX_s390x(
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index ac271a90d6a1..2c7f63503d7c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -119,20 +119,21 @@ static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
"g_gpr_regnums_x86_64 has wrong number of register infos");
static const uint32_t g_lldb_regnums_x86_64[] = {
- lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
- lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
- lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
- lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
- lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
- lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
- lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
- lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
- lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
- lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
- lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
- lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
- lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
+ lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
+ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
+ lldb_fip_x86_64, lldb_foseg_x86_64, lldb_fooff_x86_64,
+ lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64,
+ lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64,
+ lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64,
+ lldb_st6_x86_64, lldb_st7_x86_64, lldb_mm0_x86_64,
+ lldb_mm1_x86_64, lldb_mm2_x86_64, lldb_mm3_x86_64,
+ lldb_mm4_x86_64, lldb_mm5_x86_64, lldb_mm6_x86_64,
+ lldb_mm7_x86_64, lldb_xmm0_x86_64, lldb_xmm1_x86_64,
+ lldb_xmm2_x86_64, lldb_xmm3_x86_64, lldb_xmm4_x86_64,
+ lldb_xmm5_x86_64, lldb_xmm6_x86_64, lldb_xmm7_x86_64,
+ lldb_xmm8_x86_64, lldb_xmm9_x86_64, lldb_xmm10_x86_64,
+ lldb_xmm11_x86_64, lldb_xmm12_x86_64, lldb_xmm13_x86_64,
+ lldb_xmm14_x86_64, lldb_xmm15_x86_64,
LLDB_INVALID_REGNUM // Register sets must be terminated with
// LLDB_INVALID_REGNUM.
};
@@ -275,6 +276,84 @@ uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = {
lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64,
LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_fip[] = {lldb_fip_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_fdp[] = {lldb_fdp_x86_64,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_fip[] = {
+ lldb_fip_x86_64, lldb_fioff_x86_64, lldb_fiseg_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_fdp[] = {
+ lldb_fdp_x86_64, lldb_fooff_x86_64, lldb_foseg_x86_64, LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_contained_st0_32[] = {lldb_st0_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st1_32[] = {lldb_st1_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st2_32[] = {lldb_st2_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st3_32[] = {lldb_st3_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st4_32[] = {lldb_st4_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st5_32[] = {lldb_st5_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st6_32[] = {lldb_st6_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st7_32[] = {lldb_st7_i386,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st0_32[] = {
+ lldb_st0_i386, lldb_mm0_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st1_32[] = {
+ lldb_st1_i386, lldb_mm1_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st2_32[] = {
+ lldb_st2_i386, lldb_mm2_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st3_32[] = {
+ lldb_st3_i386, lldb_mm3_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st4_32[] = {
+ lldb_st4_i386, lldb_mm4_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st5_32[] = {
+ lldb_st5_i386, lldb_mm5_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st6_32[] = {
+ lldb_st6_i386, lldb_mm6_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st7_32[] = {
+ lldb_st7_i386, lldb_mm7_i386, LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_contained_st0_64[] = {lldb_st0_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st1_64[] = {lldb_st1_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st2_64[] = {lldb_st2_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st3_64[] = {lldb_st3_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st4_64[] = {lldb_st4_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st5_64[] = {lldb_st5_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st6_64[] = {lldb_st6_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st7_64[] = {lldb_st7_x86_64,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st0_64[] = {
+ lldb_st0_x86_64, lldb_mm0_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st1_64[] = {
+ lldb_st1_x86_64, lldb_mm1_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st2_64[] = {
+ lldb_st2_x86_64, lldb_mm2_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st3_64[] = {
+ lldb_st3_x86_64, lldb_mm3_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st4_64[] = {
+ lldb_st4_x86_64, lldb_mm4_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st5_64[] = {
+ lldb_st5_x86_64, lldb_mm5_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st6_64[] = {
+ lldb_st6_x86_64, lldb_mm6_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st7_64[] = {
+ lldb_st7_x86_64, lldb_mm7_x86_64, LLDB_INVALID_REGNUM};
+
// Number of register sets provided by this context.
enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index c4886ae618a2..d6672835b4a8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -15,8 +15,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
class RegisterContextPOSIX_x86 : public lldb_private::RegisterContext {
public:
RegisterContextPOSIX_x86(lldb_private::Thread &thread,
@@ -108,6 +106,48 @@ public:
static uint32_t g_invalidate_r14[];
static uint32_t g_invalidate_r15[];
+ static uint32_t g_contained_fip[];
+ static uint32_t g_contained_fdp[];
+
+ static uint32_t g_invalidate_fip[];
+ static uint32_t g_invalidate_fdp[];
+
+ static uint32_t g_contained_st0_32[];
+ static uint32_t g_contained_st1_32[];
+ static uint32_t g_contained_st2_32[];
+ static uint32_t g_contained_st3_32[];
+ static uint32_t g_contained_st4_32[];
+ static uint32_t g_contained_st5_32[];
+ static uint32_t g_contained_st6_32[];
+ static uint32_t g_contained_st7_32[];
+
+ static uint32_t g_invalidate_st0_32[];
+ static uint32_t g_invalidate_st1_32[];
+ static uint32_t g_invalidate_st2_32[];
+ static uint32_t g_invalidate_st3_32[];
+ static uint32_t g_invalidate_st4_32[];
+ static uint32_t g_invalidate_st5_32[];
+ static uint32_t g_invalidate_st6_32[];
+ static uint32_t g_invalidate_st7_32[];
+
+ static uint32_t g_contained_st0_64[];
+ static uint32_t g_contained_st1_64[];
+ static uint32_t g_contained_st2_64[];
+ static uint32_t g_contained_st3_64[];
+ static uint32_t g_contained_st4_64[];
+ static uint32_t g_contained_st5_64[];
+ static uint32_t g_contained_st6_64[];
+ static uint32_t g_contained_st7_64[];
+
+ static uint32_t g_invalidate_st0_64[];
+ static uint32_t g_invalidate_st1_64[];
+ static uint32_t g_invalidate_st2_64[];
+ static uint32_t g_invalidate_st3_64[];
+ static uint32_t g_invalidate_st4_64[];
+ static uint32_t g_invalidate_st5_64[];
+ static uint32_t g_invalidate_st6_64[];
+ static uint32_t g_invalidate_st7_64[];
+
protected:
struct RegInfo {
uint32_t num_registers;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.cpp
new file mode 100644
index 000000000000..b21c72bd9621
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.cpp
@@ -0,0 +1,58 @@
+//===-- RegisterContext_x86.cpp ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContext_x86.h"
+
+using namespace lldb_private;
+
+// Convert the 8-bit abridged FPU Tag Word (as found in FXSAVE) to the full
+// 16-bit FPU Tag Word (as found in FSAVE, and used by gdb protocol). This
+// requires knowing the values of the ST(i) registers and the FPU Status Word.
+uint16_t lldb_private::AbridgedToFullTagWord(uint8_t abridged_tw, uint16_t sw,
+ llvm::ArrayRef<MMSReg> st_regs) {
+ // Tag word is using internal FPU register numbering rather than ST(i).
+ // Mapping to ST(i): i = FPU regno - TOP (Status Word, bits 11:13).
+ // Here we start with FPU reg 7 and go down.
+ int st = 7 - ((sw >> 11) & 7);
+ uint16_t tw = 0;
+ for (uint8_t mask = 0x80; mask != 0; mask >>= 1) {
+ tw <<= 2;
+ if (abridged_tw & mask) {
+ // The register is non-empty, so we need to check the value of ST(i).
+ uint16_t exp =
+ st_regs[st].comp.sign_exp & 0x7fff; // Discard the sign bit.
+ if (exp == 0) {
+ if (st_regs[st].comp.mantissa == 0)
+ tw |= 1; // Zero
+ else
+ tw |= 2; // Denormal
+ } else if (exp == 0x7fff)
+ tw |= 2; // Infinity or NaN
+ // 0 if normal number
+ } else
+ tw |= 3; // Empty register
+
+ // Rotate ST down.
+ st = (st - 1) & 7;
+ }
+
+ return tw;
+}
+
+// Convert the 16-bit FPU Tag Word to the abridged 8-bit value, to be written
+// into FXSAVE.
+uint8_t lldb_private::FullToAbridgedTagWord(uint16_t tw) {
+ uint8_t abridged_tw = 0;
+ for (uint16_t mask = 0xc000; mask != 0; mask >>= 2) {
+ abridged_tw <<= 1;
+ // full TW uses 11 for empty registers, aTW uses 0
+ if ((tw & mask) != mask)
+ abridged_tw |= 1;
+ }
+ return abridged_tw;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
index 27a1bad4d53f..76e004ce0ceb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -12,6 +12,7 @@
#include <cstddef>
#include <cstdint>
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/Support/Compiler.h"
@@ -239,10 +240,23 @@ enum {
// Generic floating-point registers
+LLVM_PACKED_START
+struct MMSRegComp {
+ uint64_t mantissa;
+ uint16_t sign_exp;
+};
+
struct MMSReg {
- uint8_t bytes[10];
+ union {
+ uint8_t bytes[10];
+ MMSRegComp comp;
+ };
uint8_t pad[6];
};
+LLVM_PACKED_END
+
+static_assert(sizeof(MMSRegComp) == 10, "MMSRegComp is not 10 bytes of size");
+static_assert(sizeof(MMSReg) == 16, "MMSReg is not 16 bytes of size");
struct XMMReg {
uint8_t bytes[16]; // 128-bits for each XMM register
@@ -369,6 +383,10 @@ inline void YMMToXState(const YMMReg& input, void* xmm_bytes, void* ymmh_bytes)
::memcpy(ymmh_bytes, input.bytes + sizeof(XMMReg), sizeof(YMMHReg));
}
+uint16_t AbridgedToFullTagWord(uint8_t abridged_tw, uint16_t sw,
+ llvm::ArrayRef<MMSReg> st_regs);
+uint8_t FullToAbridgedTagWord(uint16_t tw);
+
} // namespace lldb_private
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
index 8fc4d5282b06..17b96f944cda 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
@@ -71,9 +71,87 @@ GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
}
}
+// Number of register sets provided by this context.
+enum {
+ k_num_gpr_registers = gpr_cpsr - gpr_r0 + 1,
+ k_num_fpr_registers = fpu_q15 - fpu_s0 + 1,
+ k_num_register_sets = 2
+};
+
+// arm general purpose registers.
+static const uint32_t g_gpr_regnums_arm[] = {
+ gpr_r0, gpr_r1,
+ gpr_r2, gpr_r3,
+ gpr_r4, gpr_r5,
+ gpr_r6, gpr_r7,
+ gpr_r8, gpr_r9,
+ gpr_r10, gpr_r11,
+ gpr_r12, gpr_sp,
+ gpr_lr, gpr_pc,
+ gpr_cpsr, LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
+ k_num_gpr_registers,
+ "g_gpr_regnums_arm has wrong number of register infos");
+
+// arm floating point registers.
+static const uint32_t g_fpu_regnums_arm[] = {
+ fpu_s0, fpu_s1,
+ fpu_s2, fpu_s3,
+ fpu_s4, fpu_s5,
+ fpu_s6, fpu_s7,
+ fpu_s8, fpu_s9,
+ fpu_s10, fpu_s11,
+ fpu_s12, fpu_s13,
+ fpu_s14, fpu_s15,
+ fpu_s16, fpu_s17,
+ fpu_s18, fpu_s19,
+ fpu_s20, fpu_s21,
+ fpu_s22, fpu_s23,
+ fpu_s24, fpu_s25,
+ fpu_s26, fpu_s27,
+ fpu_s28, fpu_s29,
+ fpu_s30, fpu_s31,
+ fpu_fpscr, fpu_d0,
+ fpu_d1, fpu_d2,
+ fpu_d3, fpu_d4,
+ fpu_d5, fpu_d6,
+ fpu_d7, fpu_d8,
+ fpu_d9, fpu_d10,
+ fpu_d11, fpu_d12,
+ fpu_d13, fpu_d14,
+ fpu_d15, fpu_d16,
+ fpu_d17, fpu_d18,
+ fpu_d19, fpu_d20,
+ fpu_d21, fpu_d22,
+ fpu_d23, fpu_d24,
+ fpu_d25, fpu_d26,
+ fpu_d27, fpu_d28,
+ fpu_d29, fpu_d30,
+ fpu_d31, fpu_q0,
+ fpu_q1, fpu_q2,
+ fpu_q3, fpu_q4,
+ fpu_q5, fpu_q6,
+ fpu_q7, fpu_q8,
+ fpu_q9, fpu_q10,
+ fpu_q11, fpu_q12,
+ fpu_q13, fpu_q14,
+ fpu_q15, LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
+ k_num_fpr_registers,
+ "g_fpu_regnums_arm has wrong number of register infos");
+
+// Register sets for arm.
+static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers,
+ g_gpr_regnums_arm},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers,
+ g_fpu_regnums_arm}};
+
RegisterInfoPOSIX_arm::RegisterInfoPOSIX_arm(
const lldb_private::ArchSpec &target_arch)
- : lldb_private::RegisterInfoInterface(target_arch),
+ : lldb_private::RegisterInfoAndSetInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
m_register_info_count(GetRegisterInfoCount(target_arch)) {}
@@ -81,11 +159,35 @@ size_t RegisterInfoPOSIX_arm::GetGPRSize() const {
return sizeof(struct RegisterInfoPOSIX_arm::GPR);
}
+size_t RegisterInfoPOSIX_arm::GetFPRSize() const {
+ return sizeof(struct RegisterInfoPOSIX_arm::FPU);
+}
+
const lldb_private::RegisterInfo *
RegisterInfoPOSIX_arm::GetRegisterInfo() const {
return m_register_info_p;
}
+size_t RegisterInfoPOSIX_arm::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+size_t RegisterInfoPOSIX_arm::GetRegisterSetFromRegisterIndex(
+ uint32_t reg_index) const {
+ if (reg_index <= gpr_cpsr)
+ return GPRegSet;
+ if (reg_index <= fpu_q15)
+ return FPRegSet;
+ return LLDB_INVALID_REGNUM;
+}
+
+const lldb_private::RegisterSet *
+RegisterInfoPOSIX_arm::GetRegisterSet(size_t set_index) const {
+ if (set_index < GetRegisterSetCount())
+ return &g_reg_sets_arm[set_index];
+ return nullptr;
+}
+
uint32_t RegisterInfoPOSIX_arm::GetRegisterCount() const {
return m_register_info_count;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
index 1cf896e3decf..db155d757ca8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
@@ -9,12 +9,14 @@
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H
-#include "RegisterInfoInterface.h"
+#include "RegisterInfoAndSetInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
-class RegisterInfoPOSIX_arm : public lldb_private::RegisterInfoInterface {
+class RegisterInfoPOSIX_arm : public lldb_private::RegisterInfoAndSetInterface {
public:
+ enum { GPRegSet = 0, FPRegSet};
+
struct GPR {
uint32_t r[16]; // R0-R15
uint32_t cpsr; // CPSR
@@ -49,10 +51,19 @@ public:
size_t GetGPRSize() const override;
+ size_t GetFPRSize() const override;
+
const lldb_private::RegisterInfo *GetRegisterInfo() const override;
uint32_t GetRegisterCount() const override;
+ const lldb_private::RegisterSet *
+ GetRegisterSet(size_t reg_set) const override;
+
+ size_t GetRegisterSetCount() const override;
+
+ size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
+
private:
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index 4537cee42ad9..515c9f44e1e2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -25,6 +25,24 @@
(LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::FPU, reg) + \
sizeof(RegisterInfoPOSIX_arm64::GPR))
+// This information is based on AArch64 with SVE architecture reference manual.
+// AArch64 with SVE has 32 Z and 16 P vector registers. There is also an FFR
+// (First Fault) register and a VG (Vector Granule) pseudo register.
+
+// SVE 16-byte quad word is the basic unit of expansion in vector length.
+#define SVE_QUAD_WORD_BYTES 16
+
+// Vector length is the multiplier which decides the no of quad words,
+// (multiples of 128-bits or 16-bytes) present in a Z register. Vector length
+// is decided during execution and can change at runtime. SVE AArch64 register
+// infos have modes one for each valid value of vector length. A change in
+// vector length requires register context to update sizes of SVE Z, P and FFR.
+// Also register context needs to update byte offsets of all registers affected
+// by the change in vector length.
+#define SVE_REGS_DEFAULT_OFFSET_LINUX sizeof(RegisterInfoPOSIX_arm64::GPR)
+
+#define SVE_OFFSET_VG SVE_REGS_DEFAULT_OFFSET_LINUX
+
#define EXC_OFFSET_NAME(reg) \
(LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::EXC, reg) + \
sizeof(RegisterInfoPOSIX_arm64::GPR) + \
@@ -51,6 +69,7 @@
// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
#include "RegisterInfos_arm64.h"
+#include "RegisterInfos_arm64_sve.h"
#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
static const lldb_private::RegisterInfo *
@@ -69,7 +88,8 @@ GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
enum {
k_num_gpr_registers = gpr_w28 - gpr_x0 + 1,
k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1,
- k_num_register_sets = 2
+ k_num_sve_registers = sve_ffr - sve_vg + 1,
+ k_num_register_sets = 3
};
// ARM64 general purpose registers.
@@ -133,13 +153,38 @@ static const uint32_t g_fpu_regnums_arm64[] = {
static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
1) == k_num_fpr_registers,
"g_fpu_regnums_arm64 has wrong number of register infos");
-// clang-format on
+
+// ARM64 SVE registers.
+static const uint32_t g_sve_regnums_arm64[] = {
+ sve_vg, sve_z0, sve_z1,
+ sve_z2, sve_z3, sve_z4,
+ sve_z5, sve_z6, sve_z7,
+ sve_z8, sve_z9, sve_z10,
+ sve_z11, sve_z12, sve_z13,
+ sve_z14, sve_z15, sve_z16,
+ sve_z17, sve_z18, sve_z19,
+ sve_z20, sve_z21, sve_z22,
+ sve_z23, sve_z24, sve_z25,
+ sve_z26, sve_z27, sve_z28,
+ sve_z29, sve_z30, sve_z31,
+ sve_p0, sve_p1, sve_p2,
+ sve_p3, sve_p4, sve_p5,
+ sve_p6, sve_p7, sve_p8,
+ sve_p9, sve_p10, sve_p11,
+ sve_p12, sve_p13, sve_p14,
+ sve_p15, sve_ffr, LLDB_INVALID_REGNUM};
+static_assert(((sizeof g_sve_regnums_arm64 / sizeof g_sve_regnums_arm64[0]) -
+ 1) == k_num_sve_registers,
+ "g_sve_regnums_arm64 has wrong number of register infos");
+
// Register sets for ARM64.
static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers,
g_gpr_regnums_arm64},
{"Floating Point Registers", "fpu", k_num_fpr_registers,
- g_fpu_regnums_arm64}};
+ g_fpu_regnums_arm64},
+ {"Scalable Vector Extension Registers", "sve", k_num_sve_registers,
+ g_sve_regnums_arm64}};
static uint32_t
GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
@@ -159,25 +204,13 @@ RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
: lldb_private::RegisterInfoAndSetInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
m_register_info_count(GetRegisterInfoCount(target_arch)) {
-
- switch (target_arch.GetMachine()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_32:
- num_registers = k_num_gpr_registers + k_num_fpr_registers;
- num_gpr_registers = k_num_gpr_registers;
- num_fpr_registers = k_num_fpr_registers;
- last_gpr = gpr_w28;
- first_fpr = fpu_v0;
- last_fpr = fpu_fpcr;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
}
uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
- return num_gpr_registers + num_fpr_registers;
+ if (IsSVEEnabled())
+ return k_num_gpr_registers + k_num_fpr_registers + k_num_sve_registers;
+
+ return k_num_gpr_registers + k_num_fpr_registers;
}
size_t RegisterInfoPOSIX_arm64::GetGPRSize() const {
@@ -194,22 +227,120 @@ RegisterInfoPOSIX_arm64::GetRegisterInfo() const {
}
size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const {
- return k_num_register_sets;
+ if (IsSVEEnabled())
+ return k_num_register_sets;
+ return k_num_register_sets - 1;
}
size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex(
uint32_t reg_index) const {
- if (reg_index <= last_gpr)
+ if (reg_index <= gpr_w28)
return GPRegSet;
- else if (reg_index <= last_fpr)
+ if (reg_index <= fpu_fpcr)
return FPRegSet;
+ if (reg_index <= sve_ffr)
+ return SVERegSet;
return LLDB_INVALID_REGNUM;
}
const lldb_private::RegisterSet *
RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const {
- if (set_index < k_num_register_sets)
+ if (set_index < GetRegisterSetCount())
return &g_reg_sets_arm64[set_index];
-
return nullptr;
}
+
+uint32_t
+RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
+ // sve_vq contains SVE Quad vector length in context of AArch64 SVE.
+ // SVE register infos if enabled cannot be disabled by selecting sve_vq = 0.
+ // Also if an invalid or previously set vector length is passed to this
+ // function then it will exit immediately with previously set vector length.
+ if (!VectorSizeIsValid(sve_vq) || m_vector_reg_vq == sve_vq)
+ return m_vector_reg_vq;
+
+ // We cannot enable AArch64 only mode if SVE was enabled.
+ if (sve_vq == eVectorQuadwordAArch64 &&
+ m_vector_reg_vq > eVectorQuadwordAArch64)
+ sve_vq = eVectorQuadwordAArch64SVE;
+
+ m_vector_reg_vq = sve_vq;
+
+ if (sve_vq == eVectorQuadwordAArch64) {
+ m_register_info_count =
+ static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
+ sizeof(g_register_infos_arm64_le[0]));
+ m_register_info_p = g_register_infos_arm64_le;
+
+ return m_vector_reg_vq;
+ }
+
+ m_register_info_count =
+ static_cast<uint32_t>(sizeof(g_register_infos_arm64_sve_le) /
+ sizeof(g_register_infos_arm64_sve_le[0]));
+
+ std::vector<lldb_private::RegisterInfo> &reg_info_ref =
+ m_per_vq_reg_infos[sve_vq];
+
+ if (reg_info_ref.empty()) {
+ reg_info_ref = llvm::makeArrayRef(g_register_infos_arm64_sve_le,
+ m_register_info_count);
+
+ uint32_t offset = SVE_REGS_DEFAULT_OFFSET_LINUX;
+
+ reg_info_ref[fpu_fpsr].byte_offset = offset;
+ reg_info_ref[fpu_fpcr].byte_offset = offset + 4;
+ reg_info_ref[sve_vg].byte_offset = offset + 8;
+ offset += 16;
+
+ // Update Z registers size and offset
+ uint32_t s_reg_base = fpu_s0;
+ uint32_t d_reg_base = fpu_d0;
+ uint32_t v_reg_base = fpu_v0;
+ uint32_t z_reg_base = sve_z0;
+
+ for (uint32_t index = 0; index < 32; index++) {
+ reg_info_ref[s_reg_base + index].byte_offset = offset;
+ reg_info_ref[d_reg_base + index].byte_offset = offset;
+ reg_info_ref[v_reg_base + index].byte_offset = offset;
+ reg_info_ref[z_reg_base + index].byte_offset = offset;
+
+ reg_info_ref[z_reg_base + index].byte_size = sve_vq * SVE_QUAD_WORD_BYTES;
+ offset += reg_info_ref[z_reg_base + index].byte_size;
+ }
+
+ // Update P registers and FFR size and offset
+ for (uint32_t it = sve_p0; it <= sve_ffr; it++) {
+ reg_info_ref[it].byte_offset = offset;
+ reg_info_ref[it].byte_size = sve_vq * SVE_QUAD_WORD_BYTES / 8;
+ offset += reg_info_ref[it].byte_size;
+ }
+
+ m_per_vq_reg_infos[sve_vq] = reg_info_ref;
+ }
+
+ m_register_info_p = reg_info_ref.data();
+ return m_vector_reg_vq;
+}
+
+bool RegisterInfoPOSIX_arm64::IsSVEZReg(unsigned reg) const {
+ return (sve_z0 <= reg && reg <= sve_z31);
+}
+
+bool RegisterInfoPOSIX_arm64::IsSVEPReg(unsigned reg) const {
+ return (sve_p0 <= reg && reg <= sve_p15);
+}
+
+bool RegisterInfoPOSIX_arm64::IsSVERegVG(unsigned reg) const {
+ return sve_vg == reg;
+}
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEZ0() const { return sve_z0; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEFFR() const { return sve_ffr; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPCR() const { return fpu_fpcr; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPSR() const { return fpu_fpsr; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEVG() const { return sve_vg; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index 2da6a531a6b6..2929f2009dd9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -12,13 +12,24 @@
#include "RegisterInfoAndSetInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
+#include <map>
+
+enum class SVEState { Unknown, Disabled, FPSIMD, Full };
class RegisterInfoPOSIX_arm64
: public lldb_private::RegisterInfoAndSetInterface {
public:
- enum { GPRegSet = 0, FPRegSet };
+ enum { GPRegSet = 0, FPRegSet, SVERegSet };
+
+ // AArch64 Register set FP/SIMD feature configuration
+ enum {
+ eVectorQuadwordAArch64,
+ eVectorQuadwordAArch64SVE,
+ eVectorQuadwordAArch64SVEMax = 256
+ };
// based on RegisterContextDarwin_arm64.h
+ LLVM_PACKED_START
struct GPR {
uint64_t x[29]; // x0-x28
uint64_t fp; // x29
@@ -27,6 +38,7 @@ public:
uint64_t pc; // pc
uint32_t cpsr; // cpsr
};
+ LLVM_PACKED_END
// based on RegisterContextDarwin_arm64.h
struct VReg {
@@ -73,14 +85,33 @@ public:
size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
+ uint32_t ConfigureVectorRegisterInfos(uint32_t sve_vq);
+
+ bool VectorSizeIsValid(uint32_t vq) {
+ if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax)
+ return true;
+ return false;
+ }
+
+ bool IsSVEEnabled() const { return m_vector_reg_vq > eVectorQuadwordAArch64; }
+
+ bool IsSVEZReg(unsigned reg) const;
+ bool IsSVEPReg(unsigned reg) const;
+ bool IsSVERegVG(unsigned reg) const;
+
+ uint32_t GetRegNumSVEZ0() const;
+ uint32_t GetRegNumSVEFFR() const;
+ uint32_t GetRegNumFPCR() const;
+ uint32_t GetRegNumFPSR() const;
+ uint32_t GetRegNumSVEVG() const;
+
private:
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+ typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>>
+ per_vq_register_infos;
+
+ per_vq_register_infos m_per_vq_reg_infos;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
+ uint32_t m_vector_reg_vq = eVectorQuadwordAArch64;
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h
new file mode 100644
index 000000000000..9551db7e8ebf
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h
@@ -0,0 +1,572 @@
+//===-- RegisterInfos_arm64_sve.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT
+
+enum {
+ sve_vg = exc_far,
+
+ sve_z0,
+ sve_z1,
+ sve_z2,
+ sve_z3,
+ sve_z4,
+ sve_z5,
+ sve_z6,
+ sve_z7,
+ sve_z8,
+ sve_z9,
+ sve_z10,
+ sve_z11,
+ sve_z12,
+ sve_z13,
+ sve_z14,
+ sve_z15,
+ sve_z16,
+ sve_z17,
+ sve_z18,
+ sve_z19,
+ sve_z20,
+ sve_z21,
+ sve_z22,
+ sve_z23,
+ sve_z24,
+ sve_z25,
+ sve_z26,
+ sve_z27,
+ sve_z28,
+ sve_z29,
+ sve_z30,
+ sve_z31,
+
+ sve_p0,
+ sve_p1,
+ sve_p2,
+ sve_p3,
+ sve_p4,
+ sve_p5,
+ sve_p6,
+ sve_p7,
+ sve_p8,
+ sve_p9,
+ sve_p10,
+ sve_p11,
+ sve_p12,
+ sve_p13,
+ sve_p14,
+ sve_p15,
+
+ sve_ffr,
+};
+
+#ifndef SVE_OFFSET_VG
+#error SVE_OFFSET_VG must be defined before including this header file
+#endif
+
+static uint32_t g_sve_s0_invalidates[] = {sve_z0, fpu_v0, fpu_d0,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s1_invalidates[] = {sve_z1, fpu_v1, fpu_d1,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s2_invalidates[] = {sve_z2, fpu_v2, fpu_d2,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s3_invalidates[] = {sve_z3, fpu_v3, fpu_d3,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s4_invalidates[] = {sve_z4, fpu_v4, fpu_d4,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s5_invalidates[] = {sve_z5, fpu_v5, fpu_d5,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s6_invalidates[] = {sve_z6, fpu_v6, fpu_d6,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s7_invalidates[] = {sve_z7, fpu_v7, fpu_d7,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s8_invalidates[] = {sve_z8, fpu_v8, fpu_d8,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s9_invalidates[] = {sve_z9, fpu_v9, fpu_d9,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s10_invalidates[] = {sve_z10, fpu_v10, fpu_d10,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s11_invalidates[] = {sve_z11, fpu_v11, fpu_d11,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s12_invalidates[] = {sve_z12, fpu_v12, fpu_d12,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s13_invalidates[] = {sve_z13, fpu_v13, fpu_d13,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s14_invalidates[] = {sve_z14, fpu_v14, fpu_d14,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s15_invalidates[] = {sve_z15, fpu_v15, fpu_d15,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s16_invalidates[] = {sve_z16, fpu_v16, fpu_d16,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s17_invalidates[] = {sve_z17, fpu_v17, fpu_d17,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s18_invalidates[] = {sve_z18, fpu_v18, fpu_d18,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s19_invalidates[] = {sve_z19, fpu_v19, fpu_d19,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s20_invalidates[] = {sve_z20, fpu_v20, fpu_d20,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s21_invalidates[] = {sve_z21, fpu_v21, fpu_d21,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s22_invalidates[] = {sve_z22, fpu_v22, fpu_d22,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s23_invalidates[] = {sve_z23, fpu_v23, fpu_d23,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s24_invalidates[] = {sve_z24, fpu_v24, fpu_d24,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s25_invalidates[] = {sve_z25, fpu_v25, fpu_d25,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s26_invalidates[] = {sve_z26, fpu_v26, fpu_d26,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s27_invalidates[] = {sve_z27, fpu_v27, fpu_d27,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s28_invalidates[] = {sve_z28, fpu_v28, fpu_d28,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s29_invalidates[] = {sve_z29, fpu_v29, fpu_d29,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s30_invalidates[] = {sve_z30, fpu_v30, fpu_d30,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s31_invalidates[] = {sve_z31, fpu_v31, fpu_d31,
+ LLDB_INVALID_REGNUM};
+
+static uint32_t g_sve_d0_invalidates[] = {sve_z0, fpu_v0, fpu_s0,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d1_invalidates[] = {sve_z1, fpu_v1, fpu_s1,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d2_invalidates[] = {sve_z2, fpu_v2, fpu_s2,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d3_invalidates[] = {sve_z3, fpu_v3, fpu_s3,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d4_invalidates[] = {sve_z4, fpu_v4, fpu_s4,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d5_invalidates[] = {sve_z5, fpu_v5, fpu_s5,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d6_invalidates[] = {sve_z6, fpu_v6, fpu_s6,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d7_invalidates[] = {sve_z7, fpu_v7, fpu_s7,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d8_invalidates[] = {sve_z8, fpu_v8, fpu_s8,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d9_invalidates[] = {sve_z9, fpu_v9, fpu_s9,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d10_invalidates[] = {sve_z10, fpu_v10, fpu_s10,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d11_invalidates[] = {sve_z11, fpu_v11, fpu_s11,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d12_invalidates[] = {sve_z12, fpu_v12, fpu_s12,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d13_invalidates[] = {sve_z13, fpu_v13, fpu_s13,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d14_invalidates[] = {sve_z14, fpu_v14, fpu_s14,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d15_invalidates[] = {sve_z15, fpu_v15, fpu_s15,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d16_invalidates[] = {sve_z16, fpu_v16, fpu_s16,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d17_invalidates[] = {sve_z17, fpu_v17, fpu_s17,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d18_invalidates[] = {sve_z18, fpu_v18, fpu_s18,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d19_invalidates[] = {sve_z19, fpu_v19, fpu_s19,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d20_invalidates[] = {sve_z20, fpu_v20, fpu_s20,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d21_invalidates[] = {sve_z21, fpu_v21, fpu_s21,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d22_invalidates[] = {sve_z22, fpu_v22, fpu_s22,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d23_invalidates[] = {sve_z23, fpu_v23, fpu_s23,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d24_invalidates[] = {sve_z24, fpu_v24, fpu_s24,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d25_invalidates[] = {sve_z25, fpu_v25, fpu_s25,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d26_invalidates[] = {sve_z26, fpu_v26, fpu_s26,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d27_invalidates[] = {sve_z27, fpu_v27, fpu_s27,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d28_invalidates[] = {sve_z28, fpu_v28, fpu_s28,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d29_invalidates[] = {sve_z29, fpu_v29, fpu_s29,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d30_invalidates[] = {sve_z30, fpu_v30, fpu_s30,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d31_invalidates[] = {sve_z31, fpu_v31, fpu_s31,
+ LLDB_INVALID_REGNUM};
+
+static uint32_t g_sve_v0_invalidates[] = {sve_z0, fpu_d0, fpu_s0,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v1_invalidates[] = {sve_z1, fpu_d1, fpu_s1,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v2_invalidates[] = {sve_z2, fpu_d2, fpu_s2,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v3_invalidates[] = {sve_z3, fpu_d3, fpu_s3,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v4_invalidates[] = {sve_z4, fpu_d4, fpu_s4,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v5_invalidates[] = {sve_z5, fpu_d5, fpu_s5,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v6_invalidates[] = {sve_z6, fpu_d6, fpu_s6,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v7_invalidates[] = {sve_z7, fpu_d7, fpu_s7,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v8_invalidates[] = {sve_z8, fpu_d8, fpu_s8,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v9_invalidates[] = {sve_z9, fpu_d9, fpu_s9,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v10_invalidates[] = {sve_z10, fpu_d10, fpu_s10,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v11_invalidates[] = {sve_z11, fpu_d11, fpu_s11,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v12_invalidates[] = {sve_z12, fpu_d12, fpu_s12,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v13_invalidates[] = {sve_z13, fpu_d13, fpu_s13,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v14_invalidates[] = {sve_z14, fpu_d14, fpu_s14,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v15_invalidates[] = {sve_z15, fpu_d15, fpu_s15,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v16_invalidates[] = {sve_z16, fpu_d16, fpu_s16,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v17_invalidates[] = {sve_z17, fpu_d17, fpu_s17,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v18_invalidates[] = {sve_z18, fpu_d18, fpu_s18,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v19_invalidates[] = {sve_z19, fpu_d19, fpu_s19,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v20_invalidates[] = {sve_z20, fpu_d20, fpu_s20,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v21_invalidates[] = {sve_z21, fpu_d21, fpu_s21,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v22_invalidates[] = {sve_z22, fpu_d22, fpu_s22,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v23_invalidates[] = {sve_z23, fpu_d23, fpu_s23,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v24_invalidates[] = {sve_z24, fpu_d24, fpu_s24,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v25_invalidates[] = {sve_z25, fpu_d25, fpu_s25,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v26_invalidates[] = {sve_z26, fpu_d26, fpu_s26,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v27_invalidates[] = {sve_z27, fpu_d27, fpu_s27,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v28_invalidates[] = {sve_z28, fpu_d28, fpu_s28,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v29_invalidates[] = {sve_z29, fpu_d29, fpu_s29,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v30_invalidates[] = {sve_z30, fpu_d30, fpu_s30,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v31_invalidates[] = {sve_z31, fpu_d31, fpu_s31,
+ LLDB_INVALID_REGNUM};
+
+static uint32_t g_contained_z0[] = {sve_z0, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z1[] = {sve_z1, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z2[] = {sve_z2, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z3[] = {sve_z3, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z4[] = {sve_z4, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z5[] = {sve_z5, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z6[] = {sve_z6, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z7[] = {sve_z7, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z8[] = {sve_z8, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z9[] = {sve_z9, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z10[] = {sve_z10, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z11[] = {sve_z11, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z12[] = {sve_z12, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z13[] = {sve_z13, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z14[] = {sve_z14, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z15[] = {sve_z15, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z16[] = {sve_z16, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z17[] = {sve_z17, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z18[] = {sve_z18, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z19[] = {sve_z19, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z20[] = {sve_z20, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z21[] = {sve_z21, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z22[] = {sve_z22, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z23[] = {sve_z23, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z24[] = {sve_z24, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z25[] = {sve_z25, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z26[] = {sve_z26, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z27[] = {sve_z27, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z28[] = {sve_z28, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z29[] = {sve_z29, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z30[] = {sve_z30, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z31[] = {sve_z31, LLDB_INVALID_REGNUM};
+
+#define VG_OFFSET_NAME(reg) SVE_OFFSET_VG
+
+#define SVE_REG_KIND(reg) MISC_KIND(reg, sve, LLDB_INVALID_REGNUM)
+#define MISC_VG_KIND(lldb_kind) MISC_KIND(vg, sve, LLDB_INVALID_REGNUM)
+
+// Default offset SVE Z registers and all corresponding pseudo registers
+// ( S, D and V registers) is zero and will be configured during execution.
+
+// Defines sve pseudo vector (V) register with 16-byte size
+#define DEFINE_VREG_SVE(vreg, zreg) \
+ { \
+ #vreg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \
+ VREG_KIND(vreg), g_contained_##zreg, g_sve_##vreg##_invalidates, \
+ nullptr, 0 \
+ }
+
+// Defines S and D pseudo registers mapping over corresponding vector register
+#define DEFINE_FPU_PSEUDO_SVE(reg, size, zreg) \
+ { \
+ #reg, nullptr, size, 0, lldb::eEncodingIEEE754, lldb::eFormatFloat, \
+ LLDB_KIND(fpu_##reg), g_contained_##zreg, g_sve_##reg##_invalidates, \
+ nullptr, 0 \
+ }
+
+// Defines a Z vector register with 16-byte default size
+#define DEFINE_ZREG(reg) \
+ { \
+ #reg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \
+ SVE_REG_KIND(reg), nullptr, nullptr, nullptr, 0 \
+ }
+
+// Defines a P vector register with 2-byte default size
+#define DEFINE_PREG(reg) \
+ { \
+ #reg, nullptr, 2, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \
+ SVE_REG_KIND(reg), nullptr, nullptr, nullptr, 0 \
+ }
+
+static lldb_private::RegisterInfo g_register_infos_arm64_sve_le[] = {
+ // clang-format off
+ // DEFINE_GPR64(name, GENERIC KIND)
+ DEFINE_GPR64(x0, LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GPR64(x1, LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GPR64(x2, LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GPR64(x3, LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GPR64(x4, LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GPR64(x5, LLDB_REGNUM_GENERIC_ARG6),
+ DEFINE_GPR64(x6, LLDB_REGNUM_GENERIC_ARG7),
+ DEFINE_GPR64(x7, LLDB_REGNUM_GENERIC_ARG8),
+ DEFINE_GPR64(x8, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x9, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x10, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x11, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x12, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x13, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x14, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x15, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x16, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x17, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x18, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x19, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x20, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x21, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x22, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x23, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x24, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x25, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x26, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x27, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x28, LLDB_INVALID_REGNUM),
+ // DEFINE_GPR64(name, GENERIC KIND)
+ DEFINE_GPR64_ALT(fp, x29, LLDB_REGNUM_GENERIC_FP),
+ DEFINE_GPR64_ALT(lr, x30, LLDB_REGNUM_GENERIC_RA),
+ DEFINE_GPR64_ALT(sp, x31, LLDB_REGNUM_GENERIC_SP),
+ DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC),
+
+ // DEFINE_MISC_REGS(name, size, TYPE, lldb kind)
+ DEFINE_MISC_REGS(cpsr, 4, GPR, gpr_cpsr),
+
+ // DEFINE_GPR32(name, parent name)
+ DEFINE_GPR32(w0, x0),
+ DEFINE_GPR32(w1, x1),
+ DEFINE_GPR32(w2, x2),
+ DEFINE_GPR32(w3, x3),
+ DEFINE_GPR32(w4, x4),
+ DEFINE_GPR32(w5, x5),
+ DEFINE_GPR32(w6, x6),
+ DEFINE_GPR32(w7, x7),
+ DEFINE_GPR32(w8, x8),
+ DEFINE_GPR32(w9, x9),
+ DEFINE_GPR32(w10, x10),
+ DEFINE_GPR32(w11, x11),
+ DEFINE_GPR32(w12, x12),
+ DEFINE_GPR32(w13, x13),
+ DEFINE_GPR32(w14, x14),
+ DEFINE_GPR32(w15, x15),
+ DEFINE_GPR32(w16, x16),
+ DEFINE_GPR32(w17, x17),
+ DEFINE_GPR32(w18, x18),
+ DEFINE_GPR32(w19, x19),
+ DEFINE_GPR32(w20, x20),
+ DEFINE_GPR32(w21, x21),
+ DEFINE_GPR32(w22, x22),
+ DEFINE_GPR32(w23, x23),
+ DEFINE_GPR32(w24, x24),
+ DEFINE_GPR32(w25, x25),
+ DEFINE_GPR32(w26, x26),
+ DEFINE_GPR32(w27, x27),
+ DEFINE_GPR32(w28, x28),
+
+ // DEFINE_VREG_SVE(v register, z register)
+ DEFINE_VREG_SVE(v0, z0),
+ DEFINE_VREG_SVE(v1, z1),
+ DEFINE_VREG_SVE(v2, z2),
+ DEFINE_VREG_SVE(v3, z3),
+ DEFINE_VREG_SVE(v4, z4),
+ DEFINE_VREG_SVE(v5, z5),
+ DEFINE_VREG_SVE(v6, z6),
+ DEFINE_VREG_SVE(v7, z7),
+ DEFINE_VREG_SVE(v8, z8),
+ DEFINE_VREG_SVE(v9, z9),
+ DEFINE_VREG_SVE(v10, z10),
+ DEFINE_VREG_SVE(v11, z11),
+ DEFINE_VREG_SVE(v12, z12),
+ DEFINE_VREG_SVE(v13, z13),
+ DEFINE_VREG_SVE(v14, z14),
+ DEFINE_VREG_SVE(v15, z15),
+ DEFINE_VREG_SVE(v16, z16),
+ DEFINE_VREG_SVE(v17, z17),
+ DEFINE_VREG_SVE(v18, z18),
+ DEFINE_VREG_SVE(v19, z19),
+ DEFINE_VREG_SVE(v20, z20),
+ DEFINE_VREG_SVE(v21, z21),
+ DEFINE_VREG_SVE(v22, z22),
+ DEFINE_VREG_SVE(v23, z23),
+ DEFINE_VREG_SVE(v24, z24),
+ DEFINE_VREG_SVE(v25, z25),
+ DEFINE_VREG_SVE(v26, z26),
+ DEFINE_VREG_SVE(v27, z27),
+ DEFINE_VREG_SVE(v28, z28),
+ DEFINE_VREG_SVE(v29, z29),
+ DEFINE_VREG_SVE(v30, z30),
+ DEFINE_VREG_SVE(v31, z31),
+
+ // DEFINE_FPU_PSEUDO(name, size, ENDIAN OFFSET, parent register)
+ DEFINE_FPU_PSEUDO_SVE(s0, 4, z0),
+ DEFINE_FPU_PSEUDO_SVE(s1, 4, z1),
+ DEFINE_FPU_PSEUDO_SVE(s2, 4, z2),
+ DEFINE_FPU_PSEUDO_SVE(s3, 4, z3),
+ DEFINE_FPU_PSEUDO_SVE(s4, 4, z4),
+ DEFINE_FPU_PSEUDO_SVE(s5, 4, z5),
+ DEFINE_FPU_PSEUDO_SVE(s6, 4, z6),
+ DEFINE_FPU_PSEUDO_SVE(s7, 4, z7),
+ DEFINE_FPU_PSEUDO_SVE(s8, 4, z8),
+ DEFINE_FPU_PSEUDO_SVE(s9, 4, z9),
+ DEFINE_FPU_PSEUDO_SVE(s10, 4, z10),
+ DEFINE_FPU_PSEUDO_SVE(s11, 4, z11),
+ DEFINE_FPU_PSEUDO_SVE(s12, 4, z12),
+ DEFINE_FPU_PSEUDO_SVE(s13, 4, z13),
+ DEFINE_FPU_PSEUDO_SVE(s14, 4, z14),
+ DEFINE_FPU_PSEUDO_SVE(s15, 4, z15),
+ DEFINE_FPU_PSEUDO_SVE(s16, 4, z16),
+ DEFINE_FPU_PSEUDO_SVE(s17, 4, z17),
+ DEFINE_FPU_PSEUDO_SVE(s18, 4, z18),
+ DEFINE_FPU_PSEUDO_SVE(s19, 4, z19),
+ DEFINE_FPU_PSEUDO_SVE(s20, 4, z20),
+ DEFINE_FPU_PSEUDO_SVE(s21, 4, z21),
+ DEFINE_FPU_PSEUDO_SVE(s22, 4, z22),
+ DEFINE_FPU_PSEUDO_SVE(s23, 4, z23),
+ DEFINE_FPU_PSEUDO_SVE(s24, 4, z24),
+ DEFINE_FPU_PSEUDO_SVE(s25, 4, z25),
+ DEFINE_FPU_PSEUDO_SVE(s26, 4, z26),
+ DEFINE_FPU_PSEUDO_SVE(s27, 4, z27),
+ DEFINE_FPU_PSEUDO_SVE(s28, 4, z28),
+ DEFINE_FPU_PSEUDO_SVE(s29, 4, z29),
+ DEFINE_FPU_PSEUDO_SVE(s30, 4, z30),
+ DEFINE_FPU_PSEUDO_SVE(s31, 4, z31),
+
+ DEFINE_FPU_PSEUDO_SVE(d0, 8, z0),
+ DEFINE_FPU_PSEUDO_SVE(d1, 8, z1),
+ DEFINE_FPU_PSEUDO_SVE(d2, 8, z2),
+ DEFINE_FPU_PSEUDO_SVE(d3, 8, z3),
+ DEFINE_FPU_PSEUDO_SVE(d4, 8, z4),
+ DEFINE_FPU_PSEUDO_SVE(d5, 8, z5),
+ DEFINE_FPU_PSEUDO_SVE(d6, 8, z6),
+ DEFINE_FPU_PSEUDO_SVE(d7, 8, z7),
+ DEFINE_FPU_PSEUDO_SVE(d8, 8, z8),
+ DEFINE_FPU_PSEUDO_SVE(d9, 8, z9),
+ DEFINE_FPU_PSEUDO_SVE(d10, 8, z10),
+ DEFINE_FPU_PSEUDO_SVE(d11, 8, z11),
+ DEFINE_FPU_PSEUDO_SVE(d12, 8, z12),
+ DEFINE_FPU_PSEUDO_SVE(d13, 8, z13),
+ DEFINE_FPU_PSEUDO_SVE(d14, 8, z14),
+ DEFINE_FPU_PSEUDO_SVE(d15, 8, z15),
+ DEFINE_FPU_PSEUDO_SVE(d16, 8, z16),
+ DEFINE_FPU_PSEUDO_SVE(d17, 8, z17),
+ DEFINE_FPU_PSEUDO_SVE(d18, 8, z18),
+ DEFINE_FPU_PSEUDO_SVE(d19, 8, z19),
+ DEFINE_FPU_PSEUDO_SVE(d20, 8, z20),
+ DEFINE_FPU_PSEUDO_SVE(d21, 8, z21),
+ DEFINE_FPU_PSEUDO_SVE(d22, 8, z22),
+ DEFINE_FPU_PSEUDO_SVE(d23, 8, z23),
+ DEFINE_FPU_PSEUDO_SVE(d24, 8, z24),
+ DEFINE_FPU_PSEUDO_SVE(d25, 8, z25),
+ DEFINE_FPU_PSEUDO_SVE(d26, 8, z26),
+ DEFINE_FPU_PSEUDO_SVE(d27, 8, z27),
+ DEFINE_FPU_PSEUDO_SVE(d28, 8, z28),
+ DEFINE_FPU_PSEUDO_SVE(d29, 8, z29),
+ DEFINE_FPU_PSEUDO_SVE(d30, 8, z30),
+ DEFINE_FPU_PSEUDO_SVE(d31, 8, z31),
+
+ // DEFINE_MISC_REGS(name, size, TYPE, lldb kind)
+ DEFINE_MISC_REGS(fpsr, 4, FPU, fpu_fpsr),
+ DEFINE_MISC_REGS(fpcr, 4, FPU, fpu_fpcr),
+
+ DEFINE_MISC_REGS(vg, 8, VG, sve_vg),
+ // DEFINE_ZREG(name)
+ DEFINE_ZREG(z0),
+ DEFINE_ZREG(z1),
+ DEFINE_ZREG(z2),
+ DEFINE_ZREG(z3),
+ DEFINE_ZREG(z4),
+ DEFINE_ZREG(z5),
+ DEFINE_ZREG(z6),
+ DEFINE_ZREG(z7),
+ DEFINE_ZREG(z8),
+ DEFINE_ZREG(z9),
+ DEFINE_ZREG(z10),
+ DEFINE_ZREG(z11),
+ DEFINE_ZREG(z12),
+ DEFINE_ZREG(z13),
+ DEFINE_ZREG(z14),
+ DEFINE_ZREG(z15),
+ DEFINE_ZREG(z16),
+ DEFINE_ZREG(z17),
+ DEFINE_ZREG(z18),
+ DEFINE_ZREG(z19),
+ DEFINE_ZREG(z20),
+ DEFINE_ZREG(z21),
+ DEFINE_ZREG(z22),
+ DEFINE_ZREG(z23),
+ DEFINE_ZREG(z24),
+ DEFINE_ZREG(z25),
+ DEFINE_ZREG(z26),
+ DEFINE_ZREG(z27),
+ DEFINE_ZREG(z28),
+ DEFINE_ZREG(z29),
+ DEFINE_ZREG(z30),
+ DEFINE_ZREG(z31),
+
+ // DEFINE_PREG(name)
+ DEFINE_PREG(p0),
+ DEFINE_PREG(p1),
+ DEFINE_PREG(p2),
+ DEFINE_PREG(p3),
+ DEFINE_PREG(p4),
+ DEFINE_PREG(p5),
+ DEFINE_PREG(p6),
+ DEFINE_PREG(p7),
+ DEFINE_PREG(p8),
+ DEFINE_PREG(p9),
+ DEFINE_PREG(p10),
+ DEFINE_PREG(p11),
+ DEFINE_PREG(p12),
+ DEFINE_PREG(p13),
+ DEFINE_PREG(p14),
+ DEFINE_PREG(p15),
+
+ // DEFINE FFR
+ DEFINE_PREG(ffr)
+ // clang-format on
+};
+
+#endif // DECLARE_REGISTER_INFOS_ARM64_SVE_STRUCT
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
index 343579cd2657..15c7cac544a1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
@@ -87,15 +87,14 @@
nullptr, nullptr, nullptr, 0 \
}
-#define DEFINE_FP_MM(reg, i) \
+#define DEFINE_FP_MM(reg, i, streg) \
{ \
- #reg #i, nullptr, sizeof(uint64_t), \
- LLVM_EXTENSION FPR_OFFSET( \
- stmm[i]), eEncodingUint, eFormatHex, \
- {ehframe_mm##i##_i386, dwarf_mm##i##_i386, \
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- lldb_mm##i##_i386 }, \
- nullptr, nullptr, nullptr, 0 \
+ #reg #i, nullptr, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingUint, eFormatHex, \
+ {dwarf_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_mm##i##_i386 }, \
+ RegisterContextPOSIX_x86::g_contained_##streg##_32, \
+ RegisterContextPOSIX_x86::g_invalidate_##streg##_32, nullptr, 0 \
}
#define DEFINE_XMM(reg, i) \
@@ -251,10 +250,12 @@ static RegisterInfo g_register_infos_i386[] = {
// FP registers.
DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2),
DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5),
- DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0),
- DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3),
- DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6),
- DEFINE_FP_MM(mm, 7),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7),
+
+ DEFINE_FP_MM(mm, 0, st0), DEFINE_FP_MM(mm, 1, st1),
+ DEFINE_FP_MM(mm, 2, st2), DEFINE_FP_MM(mm, 3, st3),
+ DEFINE_FP_MM(mm, 4, st4), DEFINE_FP_MM(mm, 5, st5),
+ DEFINE_FP_MM(mm, 6, st6), DEFINE_FP_MM(mm, 7, st7),
// XMM registers
DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 51be31f8e028..90863dfdb090 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -10,8 +10,8 @@
// Computes the offset of the given GPR in the user data area.
#define GPR_OFFSET(regname) (offsetof(GPR, regname))
-#define FPR_OFFSET(regname) (offsetof(FPR, regname))
-#define VMX_OFFSET(regname) (offsetof(VMX, regname))
+#define FPR_OFFSET(regname) (sizeof(GPR) + offsetof(FPR, regname))
+#define VMX_OFFSET(regname) (sizeof(GPR) + sizeof(FPR) + offsetof(VMX, regname))
#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
#ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index af3027afa73c..41c04b20f391 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -88,15 +88,14 @@
nullptr, nullptr, nullptr, 0 \
}
-#define DEFINE_FP_MM(reg, i) \
+#define DEFINE_FP_MM(reg, i, streg) \
{ \
- #reg #i, nullptr, sizeof(uint64_t), \
- LLVM_EXTENSION FPR_OFFSET( \
- stmm[i]), eEncodingUint, eFormatHex, \
- {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, \
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- lldb_mm##i##_x86_64 }, \
- nullptr, nullptr, nullptr, 0 \
+ #reg #i, nullptr, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingUint, eFormatHex, \
+ {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_mm##i##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##streg##_64, \
+ RegisterContextPOSIX_x86::g_invalidate_##streg##_64, nullptr, 0 \
}
#define DEFINE_XMM(reg, i) \
@@ -195,6 +194,14 @@
RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
}
+#define DEFINE_FPR_32(name, reg, kind1, kind2, kind3, kind4, reg64) \
+ { \
+ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
// clang-format off
static RegisterInfo g_register_infos_x86_64[] = {
// General purpose registers EH_Frame DWARF Generic Process Plugin
@@ -251,26 +258,30 @@ static RegisterInfo g_register_infos_x86_64[] = {
DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13),
DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15),
-// i387 Floating point registers. EH_frame DWARF Generic Process Plugin
-// ====================================== =============== ================== =================== ====================
+// i387 Floating point registers. EH_frame DWARF Generic Process Plugin reg64
+// ====================================== =============== ================== =================== ==================== =====
DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_32(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip),
+ DEFINE_FPR_32(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip),
+ DEFINE_FPR(fip, ptr.x86_64.fip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_32(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp),
+ DEFINE_FPR_32(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp),
+ DEFINE_FPR(fdp, ptr.x86_64.fdp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
// FP registers.
DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2),
DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5),
- DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0),
- DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3),
- DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6),
- DEFINE_FP_MM(mm, 7),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7),
+
+ DEFINE_FP_MM(mm, 0, st0), DEFINE_FP_MM(mm, 1, st1),
+ DEFINE_FP_MM(mm, 2, st2), DEFINE_FP_MM(mm, 3, st3),
+ DEFINE_FP_MM(mm, 4, st4), DEFINE_FP_MM(mm, 5, st5),
+ DEFINE_FP_MM(mm, 6, st6), DEFINE_FP_MM(mm, 7, st7),
// XMM registers
DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index 35f1a4075d09..4d10600f4771 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -106,7 +106,7 @@ enum {
lldb_bnd1_i386,
lldb_bnd2_i386,
lldb_bnd3_i386,
- k_last_mpxr = lldb_bnd3_i386,
+ k_last_mpxr_i386 = lldb_bnd3_i386,
k_first_mpxc_i386,
lldb_bndcfgu_i386 = k_first_mpxc_i386,
@@ -228,8 +228,10 @@ enum {
lldb_fop_x86_64,
lldb_fiseg_x86_64,
lldb_fioff_x86_64,
+ lldb_fip_x86_64,
lldb_foseg_x86_64,
lldb_fooff_x86_64,
+ lldb_fdp_x86_64,
lldb_mxcsr_x86_64,
lldb_mxcsrmask_x86_64,
lldb_st0_x86_64,