diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/Process/Utility')
148 files changed, 27699 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMDefines.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMDefines.h new file mode 100644 index 000000000000..fd3965fade19 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMDefines.h @@ -0,0 +1,191 @@ +//===-- ARMDefines.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_ARMDEFINES_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H + +#include "llvm/Support/ErrorHandling.h" + +#include <cassert> +#include <cstdint> + +// Common definitions for the ARM/Thumb Instruction Set Architecture. + +namespace lldb_private { + +// ARM shifter types +enum ARM_ShifterType { + SRType_LSL, + SRType_LSR, + SRType_ASR, + SRType_ROR, + SRType_RRX, + SRType_Invalid +}; + +// ARM conditions // Meaning (integer) Meaning (floating-point) +// Condition flags +#define COND_EQ \ + 0x0 // Equal Equal Z == 1 +#define COND_NE \ + 0x1 // Not equal Not equal, or unordered Z == 0 +#define COND_CS \ + 0x2 // Carry set >, ==, or unordered C == 1 +#define COND_HS 0x2 +#define COND_CC \ + 0x3 // Carry clear Less than C == 0 +#define COND_LO 0x3 +#define COND_MI \ + 0x4 // Minus, negative Less than N == 1 +#define COND_PL \ + 0x5 // Plus, positive or zero >, ==, or unordered N == 0 +#define COND_VS \ + 0x6 // Overflow Unordered V == 1 +#define COND_VC \ + 0x7 // No overflow Not unordered V == 0 +#define COND_HI \ + 0x8 // Unsigned higher Greater than, or unordered C == 1 and Z == + // 0 +#define COND_LS \ + 0x9 // Unsigned lower or same Less than or equal C == 0 or Z == + // 1 +#define COND_GE \ + 0xA // Greater than or equal Greater than or equal N == V +#define COND_LT \ + 0xB // Less than Less than, or unordered N != V +#define COND_GT \ + 0xC // Greater than Greater than Z == 0 and N == + // V +#define COND_LE \ + 0xD // Less than or equal <, ==, or unordered Z == 1 or N != + // V +#define COND_AL \ + 0xE // Always (unconditional) Always (unconditional) Any +#define COND_UNCOND 0xF + +static inline const char *ARMCondCodeToString(uint32_t CC) { + switch (CC) { + case COND_EQ: + return "eq"; + case COND_NE: + return "ne"; + case COND_HS: + return "hs"; + case COND_LO: + return "lo"; + case COND_MI: + return "mi"; + case COND_PL: + return "pl"; + case COND_VS: + return "vs"; + case COND_VC: + return "vc"; + case COND_HI: + return "hi"; + case COND_LS: + return "ls"; + case COND_GE: + return "ge"; + case COND_LT: + return "lt"; + case COND_GT: + return "gt"; + case COND_LE: + return "le"; + case COND_AL: + return "al"; + } + llvm_unreachable("Unknown condition code"); +} + +static inline bool ARMConditionPassed(const uint32_t condition, + const uint32_t cpsr) { + const uint32_t cpsr_n = (cpsr >> 31) & 1u; // Negative condition code flag + const uint32_t cpsr_z = (cpsr >> 30) & 1u; // Zero condition code flag + const uint32_t cpsr_c = (cpsr >> 29) & 1u; // Carry condition code flag + const uint32_t cpsr_v = (cpsr >> 28) & 1u; // Overflow condition code flag + + switch (condition) { + case COND_EQ: + return (cpsr_z == 1); + case COND_NE: + return (cpsr_z == 0); + case COND_CS: + return (cpsr_c == 1); + case COND_CC: + return (cpsr_c == 0); + case COND_MI: + return (cpsr_n == 1); + case COND_PL: + return (cpsr_n == 0); + case COND_VS: + return (cpsr_v == 1); + case COND_VC: + return (cpsr_v == 0); + case COND_HI: + return ((cpsr_c == 1) && (cpsr_z == 0)); + case COND_LS: + return ((cpsr_c == 0) || (cpsr_z == 1)); + case COND_GE: + return (cpsr_n == cpsr_v); + case COND_LT: + return (cpsr_n != cpsr_v); + case COND_GT: + return ((cpsr_z == 0) && (cpsr_n == cpsr_v)); + case COND_LE: + return ((cpsr_z == 1) || (cpsr_n != cpsr_v)); + case COND_AL: + case COND_UNCOND: + default: + return true; + } + return false; +} + +// Bit positions for CPSR +#define CPSR_T_POS 5 +#define CPSR_F_POS 6 +#define CPSR_I_POS 7 +#define CPSR_A_POS 8 +#define CPSR_E_POS 9 +#define CPSR_J_POS 24 +#define CPSR_Q_POS 27 +#define CPSR_V_POS 28 +#define CPSR_C_POS 29 +#define CPSR_Z_POS 30 +#define CPSR_N_POS 31 + +// CPSR mode definitions +#define CPSR_MODE_USR 0x10u +#define CPSR_MODE_FIQ 0x11u +#define CPSR_MODE_IRQ 0x12u +#define CPSR_MODE_SVC 0x13u +#define CPSR_MODE_ABT 0x17u +#define CPSR_MODE_UND 0x1bu +#define CPSR_MODE_SYS 0x1fu + +// Masks for CPSR +#define MASK_CPSR_MODE_MASK (0x0000001fu) +#define MASK_CPSR_IT_MASK (0x0600fc00u) +#define MASK_CPSR_T (1u << CPSR_T_POS) +#define MASK_CPSR_F (1u << CPSR_F_POS) +#define MASK_CPSR_I (1u << CPSR_I_POS) +#define MASK_CPSR_A (1u << CPSR_A_POS) +#define MASK_CPSR_E (1u << CPSR_E_POS) +#define MASK_CPSR_GE_MASK (0x000f0000u) +#define MASK_CPSR_J (1u << CPSR_J_POS) +#define MASK_CPSR_Q (1u << CPSR_Q_POS) +#define MASK_CPSR_V (1u << CPSR_V_POS) +#define MASK_CPSR_C (1u << CPSR_C_POS) +#define MASK_CPSR_Z (1u << CPSR_Z_POS) +#define MASK_CPSR_N (1u << CPSR_N_POS) + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMUtils.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMUtils.h new file mode 100644 index 000000000000..9256f926275b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMUtils.h @@ -0,0 +1,377 @@ +//===-- ARMUtils.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_ARMUTILS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H + +#include "ARMDefines.h" +#include "InstructionUtils.h" +#include "llvm/ADT/bit.h" +#include "llvm/Support/MathExtras.h" + +// Common utilities for the ARM/Thumb Instruction Set Architecture. + +namespace lldb_private { + +static inline uint32_t Align(uint32_t val, uint32_t alignment) { + return alignment * (val / alignment); +} + +static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, + ARM_ShifterType &shift_t) { + switch (type) { + default: + assert(0 && "Invalid shift type"); + break; + case 0: + shift_t = SRType_LSL; + return imm5; + case 1: + shift_t = SRType_LSR; + return (imm5 == 0 ? 32 : imm5); + case 2: + shift_t = SRType_ASR; + return (imm5 == 0 ? 32 : imm5); + case 3: + if (imm5 == 0) { + shift_t = SRType_RRX; + return 1; + } else { + shift_t = SRType_ROR; + return imm5; + } + } + shift_t = SRType_Invalid; + return UINT32_MAX; +} + +// A8.6.35 CMP (register) -- Encoding T3 +// Convenience function. +static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode, + ARM_ShifterType &shift_t) { + return DecodeImmShift(Bits32(opcode, 5, 4), + Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6), + shift_t); +} + +// A8.6.35 CMP (register) -- Encoding A1 +// Convenience function. +static inline uint32_t DecodeImmShiftARM(const uint32_t opcode, + ARM_ShifterType &shift_t) { + return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); +} + +static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t, + const uint32_t imm5) { + ARM_ShifterType dont_care; + return DecodeImmShift(shift_t, imm5, dont_care); +} + +static inline ARM_ShifterType DecodeRegShift(const uint32_t type) { + switch (type) { + default: + // assert(0 && "Invalid shift type"); + return SRType_Invalid; + case 0: + return SRType_LSL; + case 1: + return SRType_LSR; + case 2: + return SRType_ASR; + case 3: + return SRType_ROR; + } +} + +static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, + uint32_t &carry_out, bool *success) { + if (amount == 0) { + *success = false; + return 0; + } + *success = true; + carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0; + return value << amount; +} + +static inline uint32_t LSL(const uint32_t value, const uint32_t amount, + bool *success) { + *success = true; + if (amount == 0) + return value; + uint32_t dont_care; + uint32_t result = LSL_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; +} + +static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, + uint32_t &carry_out, bool *success) { + if (amount == 0) { + *success = false; + return 0; + } + *success = true; + carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0; + return value >> amount; +} + +static inline uint32_t LSR(const uint32_t value, const uint32_t amount, + bool *success) { + *success = true; + if (amount == 0) + return value; + uint32_t dont_care; + uint32_t result = LSR_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; +} + +static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, + uint32_t &carry_out, bool *success) { + if (amount == 0 || amount > 32) { + *success = false; + return 0; + } + *success = true; + bool negative = BitIsSet(value, 31); + if (amount <= 32) { + carry_out = Bit32(value, amount - 1); + int64_t extended = llvm::SignExtend64<32>(value); + return UnsignedBits(extended, amount + 31, amount); + } else { + carry_out = (negative ? 1 : 0); + return (negative ? 0xffffffff : 0); + } +} + +static inline uint32_t ASR(const uint32_t value, const uint32_t amount, + bool *success) { + *success = true; + if (amount == 0) + return value; + uint32_t dont_care; + uint32_t result = ASR_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; +} + +static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, + uint32_t &carry_out, bool *success) { + if (amount == 0) { + *success = false; + return 0; + } + *success = true; + uint32_t result = llvm::rotr<uint32_t>(value, amount); + carry_out = Bit32(value, 31); + return result; +} + +static inline uint32_t ROR(const uint32_t value, const uint32_t amount, + bool *success) { + *success = true; + if (amount == 0) + return value; + uint32_t dont_care; + uint32_t result = ROR_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; +} + +static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, + uint32_t &carry_out, bool *success) { + *success = true; + carry_out = Bit32(value, 0); + return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1); +} + +static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, + bool *success) { + *success = true; + uint32_t dont_care; + uint32_t result = RRX_C(value, carry_in, dont_care, success); + if (*success) + return result; + else + return 0; +} + +static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, + const uint32_t amount, const uint32_t carry_in, + uint32_t &carry_out, bool *success) { + if (type == SRType_RRX && amount != 1) { + *success = false; + return 0; + } + *success = true; + + if (amount == 0) { + carry_out = carry_in; + return value; + } + uint32_t result; + switch (type) { + case SRType_LSL: + result = LSL_C(value, amount, carry_out, success); + break; + case SRType_LSR: + result = LSR_C(value, amount, carry_out, success); + break; + case SRType_ASR: + result = ASR_C(value, amount, carry_out, success); + break; + case SRType_ROR: + result = ROR_C(value, amount, carry_out, success); + break; + case SRType_RRX: + result = RRX_C(value, carry_in, carry_out, success); + break; + default: + *success = false; + break; + } + if (*success) + return result; + else + return 0; +} + +static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, + const uint32_t amount, const uint32_t carry_in, + bool *success) { + // Don't care about carry out in this case. + uint32_t dont_care; + uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success); + if (*success) + return result; + else + return 0; +} + +static inline uint32_t bits(const uint32_t val, const uint32_t msbit, + const uint32_t lsbit) { + return Bits32(val, msbit, lsbit); +} + +static inline uint32_t bit(const uint32_t val, const uint32_t msbit) { + return bits(val, msbit, msbit); +} + +static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift) { + uint32_t m = shift % N; + return (val >> m) | (val << (N - m)); +} + +// (imm32, carry_out) = ARMExpandImm_C(imm12, carry_in) +static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, + uint32_t &carry_out) { + uint32_t imm32; // the expanded result + uint32_t imm = bits(opcode, 7, 0); // immediate value + uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount + if (amt == 0) { + imm32 = imm; + carry_out = carry_in; + } else { + imm32 = ror(imm, 32, amt); + carry_out = Bit32(imm32, 31); + } + return imm32; +} + +static inline uint32_t ARMExpandImm(uint32_t opcode) { + // 'carry_in' argument to following function call does not affect the imm32 + // result. + uint32_t carry_in = 0; + uint32_t carry_out; + return ARMExpandImm_C(opcode, carry_in, carry_out); +} + +// (imm32, carry_out) = ThumbExpandImm_C(imm12, carry_in) +static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, + uint32_t &carry_out) { + uint32_t imm32 = 0; // the expanded result + const uint32_t i = bit(opcode, 26); + const uint32_t imm3 = bits(opcode, 14, 12); + const uint32_t abcdefgh = bits(opcode, 7, 0); + const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh; + + if (bits(imm12, 11, 10) == 0) { + switch (bits(imm12, 9, 8)) { + default: // Keep static analyzer happy with a default case + break; + + case 0: + imm32 = abcdefgh; + break; + + case 1: + imm32 = abcdefgh << 16 | abcdefgh; + break; + + case 2: + imm32 = abcdefgh << 24 | abcdefgh << 8; + break; + + case 3: + imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh; + break; + } + carry_out = carry_in; + } else { + const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0); + imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7)); + carry_out = Bit32(imm32, 31); + } + return imm32; +} + +static inline uint32_t ThumbExpandImm(uint32_t opcode) { + // 'carry_in' argument to following function call does not affect the imm32 + // result. + uint32_t carry_in = 0; + uint32_t carry_out; + return ThumbExpandImm_C(opcode, carry_in, carry_out); +} + +// imm32 = ZeroExtend(i:imm3:imm8, 32) +static inline uint32_t ThumbImm12(uint32_t opcode) { + const uint32_t i = bit(opcode, 26); + const uint32_t imm3 = bits(opcode, 14, 12); + const uint32_t imm8 = bits(opcode, 7, 0); + const uint32_t imm12 = i << 11 | imm3 << 8 | imm8; + return imm12; +} + +// imm32 = ZeroExtend(imm7:'00', 32) +static inline uint32_t ThumbImm7Scaled(uint32_t opcode) { + const uint32_t imm7 = bits(opcode, 6, 0); + return imm7 * 4; +} + +// imm32 = ZeroExtend(imm8:'00', 32) +static inline uint32_t ThumbImm8Scaled(uint32_t opcode) { + const uint32_t imm8 = bits(opcode, 7, 0); + return imm8 * 4; +} + +// This function performs the check for the register numbers 13 and 15 that are +// not permitted for many Thumb register specifiers. +static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; } + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp new file mode 100644 index 000000000000..f495ffb1924e --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp @@ -0,0 +1,98 @@ +//===-- AuxVector.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 "AuxVector.h" +#include <optional> + +AuxVector::AuxVector(const lldb_private::DataExtractor &data) { + ParseAuxv(data); +} + +void AuxVector::ParseAuxv(const lldb_private::DataExtractor &data) { + lldb::offset_t offset = 0; + const size_t value_type_size = data.GetAddressByteSize() * 2; + while (data.ValidOffsetForDataOfSize(offset, value_type_size)) { + // We're not reading an address but an int that could be 32 or 64 bit + // depending on the address size, which is what GetAddress does. + const uint64_t type = data.GetAddress(&offset); + const uint64_t value = data.GetAddress(&offset); + if (type == AUXV_AT_NULL) + break; + if (type == AUXV_AT_IGNORE) + continue; + + m_auxv_entries[type] = value; + } +} + +std::optional<uint64_t> +AuxVector::GetAuxValue(enum EntryType entry_type) const { + auto it = m_auxv_entries.find(static_cast<uint64_t>(entry_type)); + if (it != m_auxv_entries.end()) + return it->second; + return std::nullopt; +} + +void AuxVector::DumpToLog(lldb_private::Log *log) const { + if (!log) + return; + + log->PutCString("AuxVector: "); + for (auto entry : m_auxv_entries) { + LLDB_LOGF(log, " %s [%" PRIu64 "]: %" PRIx64, + GetEntryName(static_cast<EntryType>(entry.first)), entry.first, + entry.second); + } +} + +const char *AuxVector::GetEntryName(EntryType type) const { + const char *name = "AT_???"; + +#define ENTRY_NAME(_type) \ + _type: \ + name = &#_type[5] + switch (type) { + case ENTRY_NAME(AUXV_AT_NULL); break; + case ENTRY_NAME(AUXV_AT_IGNORE); break; + case ENTRY_NAME(AUXV_AT_EXECFD); break; + case ENTRY_NAME(AUXV_AT_PHDR); break; + case ENTRY_NAME(AUXV_AT_PHENT); break; + case ENTRY_NAME(AUXV_AT_PHNUM); break; + case ENTRY_NAME(AUXV_AT_PAGESZ); break; + case ENTRY_NAME(AUXV_AT_BASE); break; + case ENTRY_NAME(AUXV_AT_FLAGS); break; + case ENTRY_NAME(AUXV_AT_ENTRY); break; + case ENTRY_NAME(AUXV_AT_NOTELF); break; + case ENTRY_NAME(AUXV_AT_UID); break; + case ENTRY_NAME(AUXV_AT_EUID); break; + case ENTRY_NAME(AUXV_AT_GID); break; + case ENTRY_NAME(AUXV_AT_EGID); break; + case ENTRY_NAME(AUXV_AT_CLKTCK); break; + case ENTRY_NAME(AUXV_AT_PLATFORM); break; + case ENTRY_NAME(AUXV_AT_HWCAP); break; + case ENTRY_NAME(AUXV_AT_FPUCW); break; + case ENTRY_NAME(AUXV_AT_DCACHEBSIZE); break; + case ENTRY_NAME(AUXV_AT_ICACHEBSIZE); break; + case ENTRY_NAME(AUXV_AT_UCACHEBSIZE); break; + case ENTRY_NAME(AUXV_AT_IGNOREPPC); break; + 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; + case ENTRY_NAME(AUXV_AT_L1I_CACHESHAPE); break; + case ENTRY_NAME(AUXV_AT_L1D_CACHESHAPE); break; + case ENTRY_NAME(AUXV_AT_L2_CACHESHAPE); break; + case ENTRY_NAME(AUXV_AT_L3_CACHESHAPE); break; + } +#undef ENTRY_NAME + + return name; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h new file mode 100644 index 000000000000..2670b34f6b0a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h @@ -0,0 +1,84 @@ +//===-- AuxVector.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_AUXVECTOR_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_AUXVECTOR_H + +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include <optional> +#include <unordered_map> + +class AuxVector { + +public: + AuxVector(const lldb_private::DataExtractor &data); + + /// Constants describing the type of entry. + /// On Linux and FreeBSD, running "LD_SHOW_AUXV=1 ./executable" will spew AUX + /// information. Added AUXV prefix to avoid potential conflicts with system- + /// defined macros. For FreeBSD, the numbers can be found in sys/elf_common.h. + enum EntryType { + AUXV_AT_NULL = 0, ///< End of auxv. + AUXV_AT_IGNORE = 1, ///< Ignore entry. + AUXV_AT_EXECFD = 2, ///< File descriptor of program. + AUXV_AT_PHDR = 3, ///< Program headers. + AUXV_AT_PHENT = 4, ///< Size of program header. + AUXV_AT_PHNUM = 5, ///< Number of program headers. + AUXV_AT_PAGESZ = 6, ///< Page size. + AUXV_AT_BASE = 7, ///< Interpreter base address. + AUXV_AT_FLAGS = 8, ///< Flags. + AUXV_AT_ENTRY = 9, ///< Program entry point. + AUXV_AT_NOTELF = 10, ///< Set if program is not an ELF. + AUXV_AT_UID = 11, ///< UID. + AUXV_AT_EUID = 12, ///< Effective UID. + AUXV_AT_GID = 13, ///< GID. + AUXV_AT_EGID = 14, ///< Effective GID. + + // At this point Linux and FreeBSD diverge and many of the following values + // are Linux specific. If you use them make sure you are in Linux specific + // code or they have the same value on other platforms. + + AUXV_AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)). + AUXV_AT_PLATFORM = 15, ///< String identifying platform. + AUXV_AT_HWCAP = + 16, ///< Machine dependent hints about processor capabilities. + AUXV_AT_FPUCW = 18, ///< Used FPU control word. + AUXV_AT_DCACHEBSIZE = 19, ///< Data cache block size. + AUXV_AT_ICACHEBSIZE = 20, ///< Instruction cache block size. + AUXV_AT_UCACHEBSIZE = 21, ///< Unified cache block size. + AUXV_AT_IGNOREPPC = 22, ///< Entry should be ignored. + 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. + AUXV_AT_SYSINFO_EHDR = 33, + AUXV_AT_L1I_CACHESHAPE = 34, ///< Shapes of the caches. + AUXV_AT_L1D_CACHESHAPE = 35, + AUXV_AT_L2_CACHESHAPE = 36, + AUXV_AT_L3_CACHESHAPE = 37, + + // Platform specific values which may overlap the Linux values. + + AUXV_FREEBSD_AT_HWCAP = 25, ///< FreeBSD specific AT_HWCAP value. + }; + + std::optional<uint64_t> GetAuxValue(enum EntryType entry_type) const; + void DumpToLog(lldb_private::Log *log) const; + const char *GetEntryName(EntryType type) const; + +private: + void ParseAuxv(const lldb_private::DataExtractor &data); + + std::unordered_map<uint64_t, uint64_t> m_auxv_entries; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp new file mode 100644 index 000000000000..ebf197339446 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -0,0 +1,139 @@ +//===-- FreeBSDSignals.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 "FreeBSDSignals.h" + +#ifdef __FreeBSD__ +#include <csignal> + +#ifndef FPE_FLTIDO +#define FPE_FLTIDO 9 +#endif + +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + static_assert(signal_name == signal_value, \ + "Value mismatch for signal number " #signal_name); \ + static_assert(code_name == code_value, \ + "Value mismatch for signal code " #code_name); \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#endif /* ifdef __FreeBSD */ + +using namespace lldb_private; + +FreeBSDSignals::FreeBSDSignals() : UnixSignals() { Reset(); } + +void FreeBSDSignals::Reset() { + UnixSignals::Reset(); + + // clang-format off + // SIGILL + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(SIGILL, 4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(SIGILL, 4, ILL_BADSTK, 8, "internal stack error"); + + // SIGFPE + ADD_SIGCODE(SIGFPE, 8, FPE_INTOVF, 1, "integer overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_INTDIV, 2, "integer divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTINV, 7, "invalid floating point operation"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTSUB, 8, "subscript out of range"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTIDO, 9, "input denormal operation"); + + // SIGBUS + ADD_SIGCODE(SIGBUS, 10, BUS_ADRALN, 1, "invalid address alignment"); + ADD_SIGCODE(SIGBUS, 10, BUS_ADRERR, 2, "nonexistent physical address"); + ADD_SIGCODE(SIGBUS, 10, BUS_OBJERR, 3, "object-specific hardware error"); + ADD_SIGCODE(SIGBUS, 10, BUS_OOMERR, 100, "no memory"); + + // SIGSEGV + ADD_SIGCODE(SIGSEGV, 11, SEGV_MAPERR, 1, "address not mapped to object", + SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_ACCERR, 2, "invalid permissions for mapped object", + SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_PKUERR, 100, "PKU violation", + SignalCodePrintOption::Address); + + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ===== ============== ======== ====== ====== ======================== + AddSignal(32, "SIGTHR", false, false, false, "thread interrupt"); + AddSignal(33, "SIGLIBRT", false, false, false, "reserved by real-time library"); + AddSignal(65, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(66, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(67, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(68, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(69, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(70, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(71, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(72, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(73, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(74, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(75, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(76, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(77, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(78, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(79, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(80, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(81, "SIGRTMIN+16", false, false, false, "real time signal 16"); + AddSignal(82, "SIGRTMIN+17", false, false, false, "real time signal 17"); + AddSignal(83, "SIGRTMIN+18", false, false, false, "real time signal 18"); + AddSignal(84, "SIGRTMIN+19", false, false, false, "real time signal 19"); + AddSignal(85, "SIGRTMIN+20", false, false, false, "real time signal 20"); + AddSignal(86, "SIGRTMIN+21", false, false, false, "real time signal 21"); + AddSignal(87, "SIGRTMIN+22", false, false, false, "real time signal 22"); + AddSignal(88, "SIGRTMIN+23", false, false, false, "real time signal 23"); + AddSignal(89, "SIGRTMIN+24", false, false, false, "real time signal 24"); + AddSignal(90, "SIGRTMIN+25", false, false, false, "real time signal 25"); + AddSignal(91, "SIGRTMIN+26", false, false, false, "real time signal 26"); + AddSignal(92, "SIGRTMIN+27", false, false, false, "real time signal 27"); + AddSignal(93, "SIGRTMIN+28", false, false, false, "real time signal 28"); + AddSignal(94, "SIGRTMIN+29", false, false, false, "real time signal 29"); + AddSignal(95, "SIGRTMIN+30", false, false, false, "real time signal 30"); + AddSignal(96, "SIGRTMAX-30", false, false, false, "real time signal 31"); + AddSignal(97, "SIGRTMAX-29", false, false, false, "real time signal 32"); + AddSignal(98, "SIGRTMAX-28", false, false, false, "real time signal 33"); + AddSignal(99, "SIGRTMAX-27", false, false, false, "real time signal 34"); + AddSignal(100, "SIGRTMAX-26", false, false, false, "real time signal 35"); + AddSignal(101, "SIGRTMAX-25", false, false, false, "real time signal 36"); + AddSignal(102, "SIGRTMAX-24", false, false, false, "real time signal 37"); + AddSignal(103, "SIGRTMAX-23", false, false, false, "real time signal 38"); + AddSignal(104, "SIGRTMAX-22", false, false, false, "real time signal 39"); + AddSignal(105, "SIGRTMAX-21", false, false, false, "real time signal 40"); + AddSignal(106, "SIGRTMAX-20", false, false, false, "real time signal 41"); + AddSignal(107, "SIGRTMAX-19", false, false, false, "real time signal 42"); + AddSignal(108, "SIGRTMAX-18", false, false, false, "real time signal 43"); + AddSignal(109, "SIGRTMAX-17", false, false, false, "real time signal 44"); + AddSignal(110, "SIGRTMAX-16", false, false, false, "real time signal 45"); + AddSignal(111, "SIGRTMAX-15", false, false, false, "real time signal 46"); + AddSignal(112, "SIGRTMAX-14", false, false, false, "real time signal 47"); + AddSignal(113, "SIGRTMAX-13", false, false, false, "real time signal 48"); + AddSignal(114, "SIGRTMAX-12", false, false, false, "real time signal 49"); + AddSignal(115, "SIGRTMAX-11", false, false, false, "real time signal 50"); + AddSignal(116, "SIGRTMAX-10", false, false, false, "real time signal 51"); + AddSignal(117, "SIGRTMAX-9", false, false, false, "real time signal 52"); + AddSignal(118, "SIGRTMAX-8", false, false, false, "real time signal 53"); + AddSignal(119, "SIGRTMAX-7", false, false, false, "real time signal 54"); + AddSignal(120, "SIGRTMAX-6", false, false, false, "real time signal 55"); + AddSignal(121, "SIGRTMAX-5", false, false, false, "real time signal 56"); + AddSignal(122, "SIGRTMAX-4", false, false, false, "real time signal 57"); + AddSignal(123, "SIGRTMAX-3", false, false, false, "real time signal 58"); + AddSignal(124, "SIGRTMAX-2", false, false, false, "real time signal 59"); + AddSignal(125, "SIGRTMAX-1", false, false, false, "real time signal 60"); + AddSignal(126, "SIGRTMAX", false, false, false, "real time signal 61"); + // clang-format on +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h new file mode 100644 index 000000000000..c4c810e54985 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h @@ -0,0 +1,27 @@ +//===-- FreeBSDSignals.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_FREEBSDSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H + +#include "lldb/Target/UnixSignals.h" + +namespace lldb_private { + +/// FreeBSD specific set of Unix signals. +class FreeBSDSignals : public UnixSignals { +public: + FreeBSDSignals(); + +private: + void Reset() override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp new file mode 100644 index 000000000000..15981a2c1cb8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -0,0 +1,181 @@ +//===-- GDBRemoteSignals.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 "GDBRemoteSignals.h" + +using namespace lldb_private; + +GDBRemoteSignals::GDBRemoteSignals() : UnixSignals() { Reset(); } + +GDBRemoteSignals::GDBRemoteSignals(const lldb::UnixSignalsSP &rhs) + : UnixSignals(*rhs) {} + +void GDBRemoteSignals::Reset() { + m_signals.clear(); + // 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, "emulation trap"); + 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, "SIGURG", false, true, true, "urgent data on socket"); + AddSignal(17, "SIGSTOP", true, true, true, "process stop"); + AddSignal(18, "SIGTSTP", false, true, true, "tty stop"); + AddSignal(19, "SIGCONT", false, false, true, "process continue"); + AddSignal(20, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD"); + AddSignal(21, "SIGTTIN", false, true, true, "background tty read"); + AddSignal(22, "SIGTTOU", false, true, true, "background tty write"); + AddSignal(23, "SIGIO", false, true, true, "input/output ready/Pollable event"); + 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, "SIGLOST", false, true, true, "resource lost"); + AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2"); + AddSignal(32, "SIGPWR", false, true, true, "power failure"); + AddSignal(33, "SIGPOLL", false, true, true, "pollable event"); + AddSignal(34, "SIGWIND", false, true, true, "SIGWIND"); + AddSignal(35, "SIGPHONE", false, true, true, "SIGPHONE"); + AddSignal(36, "SIGWAITING", false, true, true, "process's LWPs are blocked"); + AddSignal(37, "SIGLWP", false, true, true, "signal LWP"); + AddSignal(38, "SIGDANGER", false, true, true, "swap space dangerously low"); + AddSignal(39, "SIGGRANT", false, true, true, "monitor mode granted"); + AddSignal(40, "SIGRETRACT", false, true, true, "need to relinquish monitor mode"); + AddSignal(41, "SIGMSG", false, true, true, "monitor mode data available"); + AddSignal(42, "SIGSOUND", false, true, true, "sound completed"); + AddSignal(43, "SIGSAK", false, true, true, "secure attention"); + AddSignal(44, "SIGPRIO", false, true, true, "SIGPRIO"); + + AddSignal(45, "SIG33", false, false, false, "real-time event 33"); + AddSignal(46, "SIG34", false, false, false, "real-time event 34"); + AddSignal(47, "SIG35", false, false, false, "real-time event 35"); + AddSignal(48, "SIG36", false, false, false, "real-time event 36"); + AddSignal(49, "SIG37", false, false, false, "real-time event 37"); + AddSignal(50, "SIG38", false, false, false, "real-time event 38"); + AddSignal(51, "SIG39", false, false, false, "real-time event 39"); + AddSignal(52, "SIG40", false, false, false, "real-time event 40"); + AddSignal(53, "SIG41", false, false, false, "real-time event 41"); + AddSignal(54, "SIG42", false, false, false, "real-time event 42"); + AddSignal(55, "SIG43", false, false, false, "real-time event 43"); + AddSignal(56, "SIG44", false, false, false, "real-time event 44"); + AddSignal(57, "SIG45", false, false, false, "real-time event 45"); + AddSignal(58, "SIG46", false, false, false, "real-time event 46"); + AddSignal(59, "SIG47", false, false, false, "real-time event 47"); + AddSignal(60, "SIG48", false, false, false, "real-time event 48"); + AddSignal(61, "SIG49", false, false, false, "real-time event 49"); + AddSignal(62, "SIG50", false, false, false, "real-time event 50"); + AddSignal(63, "SIG51", false, false, false, "real-time event 51"); + AddSignal(64, "SIG52", false, false, false, "real-time event 52"); + AddSignal(65, "SIG53", false, false, false, "real-time event 53"); + AddSignal(66, "SIG54", false, false, false, "real-time event 54"); + AddSignal(67, "SIG55", false, false, false, "real-time event 55"); + AddSignal(68, "SIG56", false, false, false, "real-time event 56"); + AddSignal(69, "SIG57", false, false, false, "real-time event 57"); + AddSignal(70, "SIG58", false, false, false, "real-time event 58"); + AddSignal(71, "SIG59", false, false, false, "real-time event 59"); + AddSignal(72, "SIG60", false, false, false, "real-time event 60"); + AddSignal(73, "SIG61", false, false, false, "real-time event 61"); + AddSignal(74, "SIG62", false, false, false, "real-time event 62"); + AddSignal(75, "SIG63", false, false, false, "real-time event 63"); + + AddSignal(76, "SIGCANCEL", false, true, true, "LWP internal signal"); + + AddSignal(77, "SIG32", false, false, false, "real-time event 32"); + AddSignal(78, "SIG64", false, false, false, "real-time event 64"); + AddSignal(79, "SIG65", false, false, false, "real-time event 65"); + AddSignal(80, "SIG66", false, false, false, "real-time event 66"); + AddSignal(81, "SIG67", false, false, false, "real-time event 67"); + AddSignal(82, "SIG68", false, false, false, "real-time event 68"); + AddSignal(83, "SIG69", false, false, false, "real-time event 69"); + AddSignal(84, "SIG70", false, false, false, "real-time event 70"); + AddSignal(85, "SIG71", false, false, false, "real-time event 71"); + AddSignal(86, "SIG72", false, false, false, "real-time event 72"); + AddSignal(87, "SIG73", false, false, false, "real-time event 73"); + AddSignal(88, "SIG74", false, false, false, "real-time event 74"); + AddSignal(89, "SIG75", false, false, false, "real-time event 75"); + AddSignal(90, "SIG76", false, false, false, "real-time event 76"); + AddSignal(91, "SIG77", false, false, false, "real-time event 77"); + AddSignal(92, "SIG78", false, false, false, "real-time event 78"); + AddSignal(93, "SIG79", false, false, false, "real-time event 79"); + AddSignal(94, "SIG80", false, false, false, "real-time event 80"); + AddSignal(95, "SIG81", false, false, false, "real-time event 81"); + AddSignal(96, "SIG82", false, false, false, "real-time event 82"); + AddSignal(97, "SIG83", false, false, false, "real-time event 83"); + AddSignal(98, "SIG84", false, false, false, "real-time event 84"); + AddSignal(99, "SIG85", false, false, false, "real-time event 85"); + AddSignal(100, "SIG86", false, false, false, "real-time event 86"); + AddSignal(101, "SIG87", false, false, false, "real-time event 87"); + AddSignal(102, "SIG88", false, false, false, "real-time event 88"); + AddSignal(103, "SIG89", false, false, false, "real-time event 89"); + AddSignal(104, "SIG90", false, false, false, "real-time event 90"); + AddSignal(105, "SIG91", false, false, false, "real-time event 91"); + AddSignal(106, "SIG92", false, false, false, "real-time event 92"); + AddSignal(107, "SIG93", false, false, false, "real-time event 93"); + AddSignal(108, "SIG94", false, false, false, "real-time event 94"); + AddSignal(109, "SIG95", false, false, false, "real-time event 95"); + AddSignal(110, "SIG96", false, false, false, "real-time event 96"); + AddSignal(111, "SIG97", false, false, false, "real-time event 97"); + AddSignal(112, "SIG98", false, false, false, "real-time event 98"); + AddSignal(113, "SIG99", false, false, false, "real-time event 99"); + AddSignal(114, "SIG100", false, false, false, "real-time event 100"); + AddSignal(115, "SIG101", false, false, false, "real-time event 101"); + AddSignal(116, "SIG102", false, false, false, "real-time event 102"); + AddSignal(117, "SIG103", false, false, false, "real-time event 103"); + AddSignal(118, "SIG104", false, false, false, "real-time event 104"); + AddSignal(119, "SIG105", false, false, false, "real-time event 105"); + AddSignal(120, "SIG106", false, false, false, "real-time event 106"); + AddSignal(121, "SIG107", false, false, false, "real-time event 107"); + AddSignal(122, "SIG108", false, false, false, "real-time event 108"); + AddSignal(123, "SIG109", false, false, false, "real-time event 109"); + AddSignal(124, "SIG110", false, false, false, "real-time event 110"); + AddSignal(125, "SIG111", false, false, false, "real-time event 111"); + AddSignal(126, "SIG112", false, false, false, "real-time event 112"); + AddSignal(127, "SIG113", false, false, false, "real-time event 113"); + AddSignal(128, "SIG114", false, false, false, "real-time event 114"); + AddSignal(129, "SIG115", false, false, false, "real-time event 115"); + AddSignal(130, "SIG116", false, false, false, "real-time event 116"); + AddSignal(131, "SIG117", false, false, false, "real-time event 117"); + AddSignal(132, "SIG118", false, false, false, "real-time event 118"); + AddSignal(133, "SIG119", false, false, false, "real-time event 119"); + AddSignal(134, "SIG120", false, false, false, "real-time event 120"); + AddSignal(135, "SIG121", false, false, false, "real-time event 121"); + AddSignal(136, "SIG122", false, false, false, "real-time event 122"); + AddSignal(137, "SIG123", false, false, false, "real-time event 123"); + AddSignal(138, "SIG124", false, false, false, "real-time event 124"); + AddSignal(139, "SIG125", false, false, false, "real-time event 125"); + AddSignal(140, "SIG126", false, false, false, "real-time event 126"); + AddSignal(141, "SIG127", false, false, false, "real-time event 127"); + + AddSignal(142, "SIGINFO", false, true, true, "information request"); + AddSignal(143, "unknown", false, true, true, "unknown signal"); + + AddSignal(145, "EXC_BAD_ACCESS", false, true, true, "could not access memory"); + AddSignal(146, "EXC_BAD_INSTRUCTION", false, true, true, "illegal instruction/operand"); + AddSignal(147, "EXC_ARITHMETIC", false, true, true, "arithmetic exception"); + AddSignal(148, "EXC_EMULATION", false, true, true, "emulation instruction"); + AddSignal(149, "EXC_SOFTWARE", false, true, true, "software generated exception"); + AddSignal(150, "EXC_BREAKPOINT", false, true, true, "breakpoint"); + + AddSignal(151, "SIGLIBRT", false, true, true, "librt internal signal"); + + // clang-format on +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h new file mode 100644 index 000000000000..4c260b94eba8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -0,0 +1,30 @@ +//===-- GDBRemoteSignals.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_GDBREMOTESIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H + +#include "lldb/Target/UnixSignals.h" + +namespace lldb_private { + +/// Initially carries signals defined by the GDB Remote Serial Protocol. +/// Can be filled with platform's signals through PlatformRemoteGDBServer. +class GDBRemoteSignals : public UnixSignals { +public: + GDBRemoteSignals(); + + GDBRemoteSignals(const lldb::UnixSignalsSP &rhs); + +private: + void Reset() override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.cpp new file mode 100644 index 000000000000..bc06757c806a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.cpp @@ -0,0 +1,85 @@ +//===-- HistoryThread.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 "lldb/lldb-private.h" + +#include "Plugins/Process/Utility/HistoryThread.h" + +#include "Plugins/Process/Utility/HistoryUnwind.h" +#include "Plugins/Process/Utility/RegisterContextHistory.h" + +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrameList.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" + +#include <memory> + +using namespace lldb; +using namespace lldb_private; + +// Constructor + +HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, + std::vector<lldb::addr_t> pcs, + bool pcs_are_call_addresses) + : Thread(process, tid, true), m_framelist_mutex(), m_framelist(), + m_pcs(pcs), m_extended_unwind_token(LLDB_INVALID_ADDRESS), m_queue_name(), + m_thread_name(), m_originating_unique_thread_id(tid), + m_queue_id(LLDB_INVALID_QUEUE_ID) { + m_unwinder_up = + std::make_unique<HistoryUnwind>(*this, pcs, pcs_are_call_addresses); + Log *log = GetLog(LLDBLog::Object); + LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this)); +} + +// Destructor + +HistoryThread::~HistoryThread() { + Log *log = GetLog(LLDBLog::Object); + LLDB_LOGF(log, "%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")", + static_cast<void *>(this), GetID()); + DestroyThread(); +} + +lldb::RegisterContextSP HistoryThread::GetRegisterContext() { + RegisterContextSP rctx; + if (m_pcs.size() > 0) { + rctx = std::make_shared<RegisterContextHistory>( + *this, 0, GetProcess()->GetAddressByteSize(), m_pcs[0]); + } + return rctx; +} + +lldb::RegisterContextSP +HistoryThread::CreateRegisterContextForFrame(StackFrame *frame) { + return m_unwinder_up->CreateRegisterContextForFrame(frame); +} + +lldb::StackFrameListSP HistoryThread::GetStackFrameList() { + // FIXME do not throw away the lock after we acquire it.. + std::unique_lock<std::mutex> lock(m_framelist_mutex); + lock.unlock(); + if (m_framelist.get() == nullptr) { + m_framelist = + std::make_shared<StackFrameList>(*this, StackFrameListSP(), true); + } + + return m_framelist; +} + +uint32_t HistoryThread::GetExtendedBacktraceOriginatingIndexID() { + if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID) { + if (GetProcess()->HasAssignedIndexIDToThread( + m_originating_unique_thread_id)) { + return GetProcess()->AssignIndexIDToThread( + m_originating_unique_thread_id); + } + } + return LLDB_INVALID_THREAD_ID; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.h new file mode 100644 index 000000000000..a66e0f2d4207 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryThread.h @@ -0,0 +1,92 @@ +//===-- HistoryThread.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_HISTORYTHREAD_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H + +#include <mutex> + +#include "lldb/Core/UserSettingsController.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/StackFrameList.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/UserID.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +/// \class HistoryThread HistoryThread.h "HistoryThread.h" +/// A thread object representing a backtrace from a previous point in the +/// process execution +/// +/// This subclass of Thread is used to provide a backtrace from earlier in +/// process execution. It is given a backtrace list of pc addresses and it +/// will create stack frames for them. + +class HistoryThread : public lldb_private::Thread { +public: + HistoryThread(lldb_private::Process &process, lldb::tid_t tid, + std::vector<lldb::addr_t> pcs, + bool pcs_are_call_addresses = false); + + ~HistoryThread() override; + + lldb::RegisterContextSP GetRegisterContext() override; + + lldb::RegisterContextSP + CreateRegisterContextForFrame(StackFrame *frame) override; + + void RefreshStateAfterStop() override {} + + bool CalculateStopInfo() override { return false; } + + void SetExtendedBacktraceToken(uint64_t token) override { + m_extended_unwind_token = token; + } + + uint64_t GetExtendedBacktraceToken() override { + return m_extended_unwind_token; + } + + const char *GetQueueName() override { return m_queue_name.c_str(); } + + void SetQueueName(const char *name) override { m_queue_name = name; } + + lldb::queue_id_t GetQueueID() override { return m_queue_id; } + + void SetQueueID(lldb::queue_id_t queue) override { m_queue_id = queue; } + + const char *GetThreadName() { return m_thread_name.c_str(); } + + uint32_t GetExtendedBacktraceOriginatingIndexID() override; + + void SetThreadName(const char *name) { m_thread_name = name; } + + const char *GetName() override { return m_thread_name.c_str(); } + + void SetName(const char *name) override { m_thread_name = name; } + +protected: + virtual lldb::StackFrameListSP GetStackFrameList(); + + mutable std::mutex m_framelist_mutex; + lldb::StackFrameListSP m_framelist; + std::vector<lldb::addr_t> m_pcs; + + uint64_t m_extended_unwind_token; + std::string m_queue_name; + std::string m_thread_name; + lldb::tid_t m_originating_unique_thread_id; + lldb::queue_id_t m_queue_id; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp new file mode 100644 index 000000000000..7749dc6f5d51 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp @@ -0,0 +1,73 @@ +//===-- HistoryUnwind.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 "lldb/lldb-private.h" + +#include "Plugins/Process/Utility/HistoryUnwind.h" +#include "Plugins/Process/Utility/RegisterContextHistory.h" + +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +#include <memory> + +using namespace lldb; +using namespace lldb_private; + +// Constructor + +HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs, + bool pcs_are_call_addresses) + : Unwind(thread), m_pcs(pcs), + m_pcs_are_call_addresses(pcs_are_call_addresses) {} + +// Destructor + +HistoryUnwind::~HistoryUnwind() = default; + +void HistoryUnwind::DoClear() { + std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); + m_pcs.clear(); +} + +lldb::RegisterContextSP +HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) { + RegisterContextSP rctx; + if (frame) { + addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress( + &frame->GetThread()->GetProcess()->GetTarget()); + if (pc != LLDB_INVALID_ADDRESS) { + rctx = std::make_shared<RegisterContextHistory>( + *frame->GetThread().get(), frame->GetConcreteFrameIndex(), + frame->GetThread()->GetProcess()->GetAddressByteSize(), pc); + } + } + return rctx; +} + +bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, + lldb::addr_t &pc, + bool &behaves_like_zeroth_frame) { + // FIXME do not throw away the lock after we acquire it.. + std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex); + guard.unlock(); + if (frame_idx < m_pcs.size()) { + cfa = frame_idx; + pc = m_pcs[frame_idx]; + if (m_pcs_are_call_addresses) + behaves_like_zeroth_frame = true; + else + behaves_like_zeroth_frame = (frame_idx == 0); + return true; + } + return false; +} + +uint32_t HistoryUnwind::DoGetFrameCount() { return m_pcs.size(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.h new file mode 100644 index 000000000000..cb72b5d0a176 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.h @@ -0,0 +1,46 @@ +//===-- HistoryUnwind.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_HISTORYUNWIND_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H + +#include <vector> + +#include "lldb/Target/Unwind.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class HistoryUnwind : public lldb_private::Unwind { +public: + HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs, + bool pcs_are_call_addresses = false); + + ~HistoryUnwind() override; + +protected: + void DoClear() override; + + lldb::RegisterContextSP + DoCreateRegisterContextForFrame(StackFrame *frame) override; + + bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, + lldb::addr_t &pc, + bool &behaves_like_zeroth_frame) override; + uint32_t DoGetFrameCount() override; + +private: + std::vector<lldb::addr_t> m_pcs; + /// This boolean indicates that the PCs in the non-0 frames are call + /// addresses and not return addresses. + bool m_pcs_are_call_addresses; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp new file mode 100644 index 000000000000..32c71d87c7f5 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -0,0 +1,190 @@ +//===-- InferiorCallPOSIX.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 "InferiorCallPOSIX.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Host/Config.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/TypeSystem.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Platform.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +#if LLDB_ENABLE_POSIX +#include <sys/mman.h> +#else +// define them +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 +#endif + +using namespace lldb; +using namespace lldb_private; + +bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, + addr_t addr, addr_t length, unsigned prot, + unsigned flags, addr_t fd, addr_t offset) { + Thread *thread = + process->GetThreadList().GetExpressionExecutionThread().get(); + if (thread == nullptr) + return false; + + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = false; + + SymbolContextList sc_list; + process->GetTarget().GetImages().FindFunctions( + ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list); + const uint32_t count = sc_list.GetSize(); + if (count > 0) { + SymbolContext sc; + if (sc_list.GetContextAtIndex(0, sc)) { + const uint32_t range_scope = + eSymbolContextFunction | eSymbolContextSymbol; + const bool use_inline_block_range = false; + EvaluateExpressionOptions options; + options.SetStopOthers(true); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetTryAllThreads(true); + options.SetDebug(false); + options.SetTimeout(process->GetUtilityExpressionTimeout()); + options.SetTrapExceptions(false); + + addr_t prot_arg; + if (prot == eMmapProtNone) + prot_arg = PROT_NONE; + else { + prot_arg = 0; + if (prot & eMmapProtExec) + prot_arg |= PROT_EXEC; + if (prot & eMmapProtRead) + prot_arg |= PROT_READ; + if (prot & eMmapProtWrite) + prot_arg |= PROT_WRITE; + } + + AddressRange mmap_range; + if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, + mmap_range)) { + auto type_system_or_err = + process->GetTarget().GetScratchTypeSystemForLanguage( + eLanguageTypeC); + if (!type_system_or_err) { + llvm::consumeError(type_system_or_err.takeError()); + return false; + } + auto ts = *type_system_or_err; + if (!ts) + return false; + CompilerType void_ptr_type = + ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType(); + const ArchSpec arch = process->GetTarget().GetArchitecture(); + MmapArgList args = + process->GetTarget().GetPlatform()->GetMmapArgumentList( + arch, addr, length, prot_arg, flags, fd, offset); + lldb::ThreadPlanSP call_plan_sp( + new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), + void_ptr_type, args, options)); + if (call_plan_sp) { + DiagnosticManager diagnostics; + + StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); + if (frame) { + ExecutionContext exe_ctx; + frame->CalculateExecutionContext(exe_ctx); + ExpressionResults result = process->RunThreadPlan( + exe_ctx, call_plan_sp, options, diagnostics); + if (result == eExpressionCompleted) { + + allocated_addr = + call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( + LLDB_INVALID_ADDRESS); + if (process->GetAddressByteSize() == 4) { + if (allocated_addr == UINT32_MAX) + return false; + } else if (process->GetAddressByteSize() == 8) { + if (allocated_addr == UINT64_MAX) + return false; + } + return true; + } + } + } + } + } + } + + return false; +} + +bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, + addr_t length) { + Thread *thread = + process->GetThreadList().GetExpressionExecutionThread().get(); + if (thread == nullptr) + return false; + + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = false; + + SymbolContextList sc_list; + process->GetTarget().GetImages().FindFunctions( + ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list); + const uint32_t count = sc_list.GetSize(); + if (count > 0) { + SymbolContext sc; + if (sc_list.GetContextAtIndex(0, sc)) { + const uint32_t range_scope = + eSymbolContextFunction | eSymbolContextSymbol; + const bool use_inline_block_range = false; + EvaluateExpressionOptions options; + options.SetStopOthers(true); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetTryAllThreads(true); + options.SetDebug(false); + options.SetTimeout(process->GetUtilityExpressionTimeout()); + options.SetTrapExceptions(false); + + AddressRange munmap_range; + if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, + munmap_range)) { + lldb::addr_t args[] = {addr, length}; + lldb::ThreadPlanSP call_plan_sp( + new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), + CompilerType(), args, options)); + if (call_plan_sp) { + DiagnosticManager diagnostics; + + StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); + if (frame) { + ExecutionContext exe_ctx; + frame->CalculateExecutionContext(exe_ctx); + ExpressionResults result = process->RunThreadPlan( + exe_ctx, call_plan_sp, options, diagnostics); + if (result == eExpressionCompleted) { + return true; + } + } + } + } + } + } + + return false; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h new file mode 100644 index 000000000000..3623e10194f9 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h @@ -0,0 +1,35 @@ +//===-- InferiorCallPOSIX.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_INFERIORCALLPOSIX_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H + +// Inferior execution of POSIX functions. + +#include "lldb/lldb-types.h" + +namespace lldb_private { + +class Process; + +enum MmapProt { + eMmapProtNone = 0, + eMmapProtExec = 1, + eMmapProtRead = 2, + eMmapProtWrite = 4 +}; + +bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr, + lldb::addr_t addr, lldb::addr_t length, unsigned prot, + unsigned flags, lldb::addr_t fd, lldb::addr_t offset); + +bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length); + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InstructionUtils.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InstructionUtils.h new file mode 100644 index 000000000000..55b89440700b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InstructionUtils.h @@ -0,0 +1,116 @@ +//===-- InstructionUtils.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_INSTRUCTIONUTILS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H + +#include <cassert> +#include <cstdint> + +// Common utilities for manipulating instruction bit fields. + +namespace lldb_private { + +// Return the bit field(s) from the most significant bit (msbit) to the +// least significant bit (lsbit) of a 64-bit unsigned value. +static inline uint64_t Bits64(const uint64_t bits, const uint32_t msbit, + const uint32_t lsbit) { + assert(msbit < 64 && lsbit <= msbit); + return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1); +} + +// Return the bit field(s) from the most significant bit (msbit) to the +// least significant bit (lsbit) of a 32-bit unsigned value. +static inline uint32_t Bits32(const uint32_t bits, const uint32_t msbit, + const uint32_t lsbit) { + assert(msbit < 32 && lsbit <= msbit); + return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1); +} + +// Return the bit value from the 'bit' position of a 32-bit unsigned value. +static inline uint32_t Bit32(const uint32_t bits, const uint32_t bit) { + return (bits >> bit) & 1u; +} + +static inline uint64_t Bit64(const uint64_t bits, const uint32_t bit) { + return (bits >> bit) & 1ull; +} + +// Set the bit field(s) from the most significant bit (msbit) to the +// least significant bit (lsbit) of a 32-bit unsigned value to 'val'. +static inline void SetBits32(uint32_t &bits, const uint32_t msbit, + const uint32_t lsbit, const uint32_t val) { + assert(msbit < 32 && lsbit < 32 && msbit >= lsbit); + uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1); + bits &= ~(mask << lsbit); + bits |= (val & mask) << lsbit; +} + +// Set the 'bit' position of a 32-bit unsigned value to 'val'. +static inline void SetBit32(uint32_t &bits, const uint32_t bit, + const uint32_t val) { + SetBits32(bits, bit, bit, val); +} + +// Rotate a 32-bit unsigned value right by the specified amount. +static inline uint32_t Rotr32(uint32_t bits, uint32_t amt) { + assert(amt < 32 && "Invalid rotate amount"); + return (bits >> amt) | (bits << ((32 - amt) & 31)); +} + +// Rotate a 32-bit unsigned value left by the specified amount. +static inline uint32_t Rotl32(uint32_t bits, uint32_t amt) { + assert(amt < 32 && "Invalid rotate amount"); + return (bits << amt) | (bits >> ((32 - amt) & 31)); +} + +// Create a mask that starts at bit zero and includes "bit" +static inline uint64_t MaskUpToBit(const uint64_t bit) { + if (bit >= 63) + return -1ll; + return (1ull << (bit + 1ull)) - 1ull; +} + +// Return an integer result equal to the number of bits of x that are ones. +static inline uint32_t BitCount(uint64_t x) { + // c accumulates the total bits set in x + uint32_t c; + for (c = 0; x; ++c) { + x &= x - 1; // clear the least significant bit set + } + return c; +} + +static inline bool BitIsSet(const uint64_t value, const uint64_t bit) { + return (value & (1ull << bit)) != 0; +} + +static inline bool BitIsClear(const uint64_t value, const uint64_t bit) { + return (value & (1ull << bit)) == 0; +} + +static inline uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit, + const uint64_t lsbit) { + uint64_t result = value >> lsbit; + result &= MaskUpToBit(msbit - lsbit); + return result; +} + +static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit, + const uint64_t lsbit) { + uint64_t result = UnsignedBits(value, msbit, lsbit); + if (BitIsSet(value, msbit)) { + // Sign extend + result |= ~MaskUpToBit(msbit - lsbit); + } + return result; +} + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_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..8b5393ca1888 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h @@ -0,0 +1,293 @@ +//===-- 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 <cstdint> + +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 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; +}; + +using user_za_header = user_sve_header; + +/* 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 new file mode 100644 index 000000000000..fd803c8cabaf --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp @@ -0,0 +1,205 @@ +//===-- LinuxProcMaps.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 "LinuxProcMaps.h" +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/StringExtractor.h" +#include "llvm/ADT/StringRef.h" +#include <optional> + +using namespace lldb_private; + +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, + 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 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 ProcMapError( + "malformed /proc/{pid}/%s entry, missing space after range", maps_kind); + + // Save the range. + 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 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') + region.SetReadable(MemoryRegionInfo::OptionalBool::eYes); + else if (read_perm_char == '-') + region.SetReadable(MemoryRegionInfo::OptionalBool::eNo); + else + 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') + region.SetWritable(MemoryRegionInfo::OptionalBool::eYes); + else if (write_perm_char == '-') + region.SetWritable(MemoryRegionInfo::OptionalBool::eNo); + else + 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') + region.SetExecutable(MemoryRegionInfo::OptionalBool::eYes); + else if (exec_perm_char == '-') + region.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); + else + return ProcMapError("unexpected /proc/{pid}/%s exec permission char", + maps_kind); + + // Handle sharing status (private/shared). + const char sharing_char = line_extractor.GetChar(); + if (sharing_char == 's') + region.SetShared(MemoryRegionInfo::OptionalBool::eYes); + else if (sharing_char == 'p') + region.SetShared(MemoryRegionInfo::OptionalBool::eNo); + else + region.SetShared(MemoryRegionInfo::OptionalBool::eDontKnow); + + line_extractor.SkipSpaces(); // Skip the separator + line_extractor.GetHexMaxU64(false, 0); // Read the offset + line_extractor.GetHexMaxU64(false, 0); // Read the major device number + line_extractor.GetChar(); // Read the device id separator + 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) + region.SetName(name); + + return region; +} + +void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map, + LinuxMapCallback const &callback) { + llvm::StringRef lines(linux_map); + llvm::StringRef line; + while (!lines.empty()) { + std::tie(line, lines) = lines.split('\n'); + 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; + std::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 new file mode 100644 index 000000000000..02f78d55c290 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h @@ -0,0 +1,27 @@ +//===-- LinuxProcMaps.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_LINUXPROCMAPS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H + +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" + +namespace lldb_private { + +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 + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp new file mode 100644 index 000000000000..3f25dbc6abbb --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -0,0 +1,143 @@ +//===-- LinuxSignals.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 "LinuxSignals.h" + +#ifdef __linux__ +#include <csignal> + +#ifndef SEGV_BNDERR +#define SEGV_BNDERR 3 +#endif +#ifndef SEGV_MTEAERR +#define SEGV_MTEAERR 8 +#endif +#ifndef SEGV_MTESERR +#define SEGV_MTESERR 9 +#endif + +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + static_assert(signal_name == signal_value, \ + "Value mismatch for signal number " #signal_name); \ + static_assert(code_name == code_value, \ + "Value mismatch for signal code " #code_name); \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#endif /* ifdef __linux__ */ + +using namespace lldb_private; + +LinuxSignals::LinuxSignals() : UnixSignals() { Reset(); } + +void LinuxSignals::Reset() { + m_signals.clear(); + // 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"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(SIGILL, 4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(SIGILL, 4, ILL_BADSTK, 8, "internal stack error"); + + 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"); + ADD_SIGCODE(SIGBUS, 7, BUS_ADRALN, 1, "illegal alignment"); + ADD_SIGCODE(SIGBUS, 7, BUS_ADRERR, 2, "illegal address"); + ADD_SIGCODE(SIGBUS, 7, BUS_OBJERR, 3, "hardware error"); + + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + ADD_SIGCODE(SIGFPE, 8, FPE_INTDIV, 1, "integer divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_INTOVF, 2, "integer overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTINV, 7, "floating point invalid operation"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTSUB, 8, "subscript out of range"); + + 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"); + ADD_SIGCODE(SIGSEGV, 11, SEGV_MAPERR, 1, "address not mapped to object", SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_ACCERR, 2, "invalid permissions for mapped object", SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_BNDERR, 3, "failed address bounds checks", SignalCodePrintOption::Bounds); + ADD_SIGCODE(SIGSEGV, 11, SEGV_MTEAERR, 8, "async tag check fault"); + ADD_SIGCODE(SIGSEGV, 11, SEGV_MTESERR, 9, "sync tag check fault", SignalCodePrintOption::Address); + // Some platforms will occasionally send nonstandard spurious SI_KERNEL + // codes. One way to get this is via unaligned SIMD loads. Treat it as invalid address. + ADD_SIGCODE(SIGSEGV, 11, SI_KERNEL, 0x80, "invalid address", SignalCodePrintOption::Address); + + 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/LinuxSignals.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.h new file mode 100644 index 000000000000..32c4744a96d0 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.h @@ -0,0 +1,27 @@ +//===-- LinuxSignals.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_LINUXSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H + +#include "lldb/Target/UnixSignals.h" + +namespace lldb_private { + +/// Linux specific set of Unix signals. +class LinuxSignals : public UnixSignals { +public: + LinuxSignals(); + +private: + void Reset() override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp new file mode 100644 index 000000000000..7e25bc4ea2a2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp @@ -0,0 +1,356 @@ +//===-- MemoryTagManagerAArch64MTE.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 "MemoryTagManagerAArch64MTE.h" +#include "llvm/Support/Error.h" +#include <assert.h> + +using namespace lldb_private; + +static const unsigned MTE_START_BIT = 56; +static const unsigned MTE_TAG_MAX = 0xf; +static const unsigned MTE_GRANULE_SIZE = 16; + +lldb::addr_t +MemoryTagManagerAArch64MTE::GetLogicalTag(lldb::addr_t addr) const { + return (addr >> MTE_START_BIT) & MTE_TAG_MAX; +} + +lldb::addr_t +MemoryTagManagerAArch64MTE::RemoveTagBits(lldb::addr_t addr) const { + // Here we're ignoring the whole top byte. If you've got MTE + // you must also have TBI (top byte ignore). + // The other 4 bits could contain other extension bits or + // user metadata. + return addr & ~((lldb::addr_t)0xFF << MTE_START_BIT); +} + +ptrdiff_t MemoryTagManagerAArch64MTE::AddressDiff(lldb::addr_t addr1, + lldb::addr_t addr2) const { + return RemoveTagBits(addr1) - RemoveTagBits(addr2); +} + +lldb::addr_t MemoryTagManagerAArch64MTE::GetGranuleSize() const { + return MTE_GRANULE_SIZE; +} + +int32_t MemoryTagManagerAArch64MTE::GetAllocationTagType() const { + return eMTE_allocation; +} + +size_t MemoryTagManagerAArch64MTE::GetTagSizeInBytes() const { return 1; } + +MemoryTagManagerAArch64MTE::TagRange +MemoryTagManagerAArch64MTE::ExpandToGranule(TagRange range) const { + // Ignore reading a length of 0 + if (!range.IsValid()) + return range; + + const size_t granule = GetGranuleSize(); + + // Align start down to granule start + lldb::addr_t new_start = range.GetRangeBase(); + lldb::addr_t align_down_amount = new_start % granule; + new_start -= align_down_amount; + + // Account for the distance we moved the start above + size_t new_len = range.GetByteSize() + align_down_amount; + // Then align up to the end of the granule + size_t align_up_amount = granule - (new_len % granule); + if (align_up_amount != granule) + new_len += align_up_amount; + + return TagRange(new_start, new_len); +} + +static llvm::Error MakeInvalidRangeErr(lldb::addr_t addr, + lldb::addr_t end_addr) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "End address (0x%" PRIx64 + ") must be greater than the start address (0x%" PRIx64 ")", + end_addr, addr); +} + +llvm::Expected<MemoryTagManager::TagRange> +MemoryTagManagerAArch64MTE::MakeTaggedRange( + lldb::addr_t addr, lldb::addr_t end_addr, + const lldb_private::MemoryRegionInfos &memory_regions) const { + // First check that the range is not inverted. + // We must remove tags here otherwise an address with a higher + // tag value will always be > the other. + ptrdiff_t len = AddressDiff(end_addr, addr); + if (len <= 0) + return MakeInvalidRangeErr(addr, end_addr); + + // Region addresses will not have memory tags. So when searching + // we must use an untagged address. + MemoryRegionInfo::RangeType tag_range(RemoveTagBits(addr), len); + tag_range = ExpandToGranule(tag_range); + + // Make a copy so we can use the original for errors and the final return. + MemoryRegionInfo::RangeType remaining_range(tag_range); + + // While there are parts of the range that don't have a matching tagged memory + // region + while (remaining_range.IsValid()) { + // Search for a region that contains the start of the range + MemoryRegionInfos::const_iterator region = std::find_if( + memory_regions.cbegin(), memory_regions.cend(), + [&remaining_range](const MemoryRegionInfo ®ion) { + return region.GetRange().Contains(remaining_range.GetRangeBase()); + }); + + if (region == memory_regions.cend() || + region->GetMemoryTagged() != MemoryRegionInfo::eYes) { + // Some part of this range is untagged (or unmapped) so error + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Address range 0x%" PRIx64 ":0x%" PRIx64 + " is not in a memory tagged region", + tag_range.GetRangeBase(), + tag_range.GetRangeEnd()); + } + + // We've found some part of the range so remove that part and continue + // searching for the rest. Moving the base "slides" the range so we need to + // save/restore the original end. If old_end is less than the new base, the + // range will be set to have 0 size and we'll exit the while. + lldb::addr_t old_end = remaining_range.GetRangeEnd(); + remaining_range.SetRangeBase(region->GetRange().GetRangeEnd()); + remaining_range.SetRangeEnd(old_end); + } + + // Every part of the range is contained within a tagged memory region. + return tag_range; +} + +llvm::Expected<std::vector<MemoryTagManager::TagRange>> +MemoryTagManagerAArch64MTE::MakeTaggedRanges( + lldb::addr_t addr, lldb::addr_t end_addr, + const lldb_private::MemoryRegionInfos &memory_regions) const { + // First check that the range is not inverted. + // We must remove tags here otherwise an address with a higher + // tag value will always be > the other. + ptrdiff_t len = AddressDiff(end_addr, addr); + if (len <= 0) + return MakeInvalidRangeErr(addr, end_addr); + + std::vector<MemoryTagManager::TagRange> tagged_ranges; + // No memory regions means no tagged memory at all + if (memory_regions.empty()) + return tagged_ranges; + + // For the logic to work regions must be in ascending order + // which is what you'd have if you used GetMemoryRegions. + assert(std::is_sorted( + memory_regions.begin(), memory_regions.end(), + [](const MemoryRegionInfo &lhs, const MemoryRegionInfo &rhs) { + return lhs.GetRange().GetRangeBase() < rhs.GetRange().GetRangeBase(); + })); + + // If we're debugging userspace in an OS like Linux that uses an MMU, + // the only reason we'd get overlapping regions is incorrect data. + // It is possible that won't hold for embedded with memory protection + // units (MPUs) that allow overlaps. + // + // For now we're going to assume the former, as there is no good way + // to handle overlaps. For example: + // < requested range > + // [-- region 1 --] + // [-- region 2--] + // Where the first region will reduce the requested range to nothing + // and exit early before it sees the overlap. + MemoryRegionInfos::const_iterator overlap = std::adjacent_find( + memory_regions.begin(), memory_regions.end(), + [](const MemoryRegionInfo &lhs, const MemoryRegionInfo &rhs) { + return rhs.GetRange().DoesIntersect(lhs.GetRange()); + }); + UNUSED_IF_ASSERT_DISABLED(overlap); + assert(overlap == memory_regions.end()); + + // Region addresses will not have memory tags so when searching + // we must use an untagged address. + MemoryRegionInfo::RangeType range(RemoveTagBits(addr), len); + range = ExpandToGranule(range); + + // While there are regions to check and the range has non zero length + for (const MemoryRegionInfo ®ion : memory_regions) { + // If range we're checking has been reduced to zero length, exit early + if (!range.IsValid()) + break; + + // If the region doesn't overlap the range at all, ignore it. + if (!region.GetRange().DoesIntersect(range)) + continue; + + // If it's tagged record this sub-range. + // (assuming that it's already granule aligned) + if (region.GetMemoryTagged()) { + // The region found may extend outside the requested range. + // For example the first region might start before the range. + // We must only add what covers the requested range. + lldb::addr_t start = + std::max(range.GetRangeBase(), region.GetRange().GetRangeBase()); + lldb::addr_t end = + std::min(range.GetRangeEnd(), region.GetRange().GetRangeEnd()); + tagged_ranges.push_back(MemoryTagManager::TagRange(start, end - start)); + } + + // Move the range up to start at the end of the region. + lldb::addr_t old_end = range.GetRangeEnd(); + // This "slides" the range so it moves the end as well. + range.SetRangeBase(region.GetRange().GetRangeEnd()); + // So we set the end back to the original end address after sliding it up. + range.SetRangeEnd(old_end); + // (if the above were to try to set end < begin the range will just be set + // to 0 size) + } + + return tagged_ranges; +} + +llvm::Expected<std::vector<lldb::addr_t>> +MemoryTagManagerAArch64MTE::UnpackTagsData(const std::vector<uint8_t> &tags, + size_t granules /*=0*/) const { + // 0 means don't check the number of tags before unpacking + if (granules) { + size_t num_tags = tags.size() / GetTagSizeInBytes(); + if (num_tags != granules) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Packed tag data size does not match expected number of tags. " + "Expected %zu tag(s) for %zu granule(s), got %zu tag(s).", + granules, granules, num_tags); + } + } + + // (if bytes per tag was not 1, we would reconstruct them here) + + std::vector<lldb::addr_t> unpacked; + unpacked.reserve(tags.size()); + for (auto it = tags.begin(); it != tags.end(); ++it) { + // Check all tags are in range + if (*it > MTE_TAG_MAX) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Found tag 0x%x which is > max MTE tag value of 0x%x.", *it, + MTE_TAG_MAX); + } + unpacked.push_back(*it); + } + + return unpacked; +} + +std::vector<lldb::addr_t> +MemoryTagManagerAArch64MTE::UnpackTagsFromCoreFileSegment( + CoreReaderFn reader, lldb::addr_t tag_segment_virtual_address, + lldb::addr_t tag_segment_data_address, lldb::addr_t addr, + size_t len) const { + // We can assume by now that addr and len have been granule aligned by a tag + // manager. However because we have 2 tags per byte we need to round the range + // up again to align to 2 granule boundaries. + const size_t granule = GetGranuleSize(); + const size_t two_granules = granule * 2; + lldb::addr_t aligned_addr = addr; + size_t aligned_len = len; + + // First align the start address down. + if (aligned_addr % two_granules) { + assert(aligned_addr % two_granules == granule); + aligned_addr -= granule; + aligned_len += granule; + } + + // Then align the length up. + bool aligned_length_up = false; + if (aligned_len % two_granules) { + assert(aligned_len % two_granules == granule); + aligned_len += granule; + aligned_length_up = true; + } + + // ProcessElfCore should have validated this when it found the segment. + assert(aligned_addr >= tag_segment_virtual_address); + + // By now we know that aligned_addr is aligned to a 2 granule boundary. + const size_t offset_granules = + (aligned_addr - tag_segment_virtual_address) / granule; + // 2 tags per byte. + const size_t file_offset_in_bytes = offset_granules / 2; + + // By now we know that aligned_len is at least 2 granules. + const size_t tag_bytes_to_read = aligned_len / granule / 2; + std::vector<uint8_t> tag_data(tag_bytes_to_read); + const size_t bytes_copied = + reader(tag_segment_data_address + file_offset_in_bytes, tag_bytes_to_read, + tag_data.data()); + UNUSED_IF_ASSERT_DISABLED(bytes_copied); + assert(bytes_copied == tag_bytes_to_read); + + std::vector<lldb::addr_t> tags; + tags.reserve(2 * tag_data.size()); + // No need to check the range of the tag value here as each occupies only 4 + // bits. + for (auto tag_byte : tag_data) { + tags.push_back(tag_byte & 0xf); + tags.push_back(tag_byte >> 4); + } + + // If we aligned the address down, don't return the extra first tag. + if (addr != aligned_addr) + tags.erase(tags.begin()); + // If we aligned the length up, don't return the extra last tag. + if (aligned_length_up) + tags.pop_back(); + + return tags; +} + +llvm::Expected<std::vector<uint8_t>> MemoryTagManagerAArch64MTE::PackTags( + const std::vector<lldb::addr_t> &tags) const { + std::vector<uint8_t> packed; + packed.reserve(tags.size() * GetTagSizeInBytes()); + + for (auto tag : tags) { + if (tag > MTE_TAG_MAX) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Found tag 0x%" PRIx64 + " which is > max MTE tag value of 0x%x.", + tag, MTE_TAG_MAX); + } + packed.push_back(static_cast<uint8_t>(tag)); + } + + return packed; +} + +llvm::Expected<std::vector<lldb::addr_t>> +MemoryTagManagerAArch64MTE::RepeatTagsForRange( + const std::vector<lldb::addr_t> &tags, TagRange range) const { + std::vector<lldb::addr_t> new_tags; + + // If the range is not empty + if (range.IsValid()) { + if (tags.empty()) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Expected some tags to cover given range, got zero."); + } + + // We assume that this range has already been expanded/aligned to granules + size_t granules = range.GetByteSize() / GetGranuleSize(); + new_tags.reserve(granules); + for (size_t to_copy = 0; granules > 0; granules -= to_copy) { + to_copy = granules > tags.size() ? tags.size() : granules; + new_tags.insert(new_tags.end(), tags.begin(), tags.begin() + to_copy); + } + } + + return new_tags; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h new file mode 100644 index 000000000000..365e176e5b1d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h @@ -0,0 +1,63 @@ +//===-- MemoryTagManagerAArch64MTE.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_MEMORYTAGMANAGERAARCH64MTE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H + +#include "lldb/Target/MemoryTagManager.h" + +namespace lldb_private { + +class MemoryTagManagerAArch64MTE : public MemoryTagManager { +public: + // This enum is supposed to be shared for all of AArch64 but until + // there are more tag types than MTE, it will live here. + enum MTETagTypes { + eMTE_logical = 0, + eMTE_allocation = 1, + }; + + lldb::addr_t GetGranuleSize() const override; + int32_t GetAllocationTagType() const override; + size_t GetTagSizeInBytes() const override; + + lldb::addr_t GetLogicalTag(lldb::addr_t addr) const override; + lldb::addr_t RemoveTagBits(lldb::addr_t addr) const override; + ptrdiff_t AddressDiff(lldb::addr_t addr1, lldb::addr_t addr2) const override; + + TagRange ExpandToGranule(TagRange range) const override; + + llvm::Expected<TagRange> MakeTaggedRange( + lldb::addr_t addr, lldb::addr_t end_addr, + const lldb_private::MemoryRegionInfos &memory_regions) const override; + + llvm::Expected<std::vector<TagRange>> MakeTaggedRanges( + lldb::addr_t addr, lldb::addr_t end_addr, + const lldb_private::MemoryRegionInfos &memory_regions) const override; + + llvm::Expected<std::vector<lldb::addr_t>> + UnpackTagsData(const std::vector<uint8_t> &tags, + size_t granules = 0) const override; + + std::vector<lldb::addr_t> + UnpackTagsFromCoreFileSegment(CoreReaderFn reader, + lldb::addr_t tag_segment_virtual_address, + lldb::addr_t tag_segment_data_address, + lldb::addr_t addr, size_t len) const override; + + llvm::Expected<std::vector<uint8_t>> + PackTags(const std::vector<lldb::addr_t> &tags) const override; + + llvm::Expected<std::vector<lldb::addr_t>> + RepeatTagsForRange(const std::vector<lldb::addr_t> &tags, + TagRange range) const override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H 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..ef71a964eaf2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp @@ -0,0 +1,210 @@ +//===-- 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 ®_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 ®_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 ®_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 ®siter_context) { + const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); + return regsiter_context.ReadRegisterAsUnsigned(flags_info, + LLDB_INVALID_ADDRESS); +} + +static int GetSoftwareBreakpointSize(const ArchSpec &arch, + lldb::addr_t next_flags) { + if (arch.GetMachine() == llvm::Triple::arm) { + if (next_flags & 0x20) + // Thumb mode + return 2; + // Arm mode + return 4; + } + if (arch.IsMIPS() || arch.GetTriple().isPPC64() || + arch.GetTriple().isRISCV() || arch.GetTriple().isLoongArch()) + return 4; + return 0; +} + +static Status SetSoftwareBreakpointOnPC(const ArchSpec &arch, lldb::addr_t pc, + lldb::addr_t next_flags, + NativeProcessProtocol &process) { + int size_hint = GetSoftwareBreakpointSize(arch, next_flags); + Status error; + error = process.SetBreakpoint(pc, size_hint, /*hardware=*/false); + + // If setting the breakpoint fails because pc is out of the address + // space, ignore it and let the debugee segfault. + if (error.GetError() == EIO || error.GetError() == EFAULT) + return Status(); + if (error.Fail()) + return error; + + return Status(); +} + +Status NativeProcessSoftwareSingleStep::SetupSoftwareSingleStepping( + NativeThreadProtocol &thread) { + Status error; + NativeProcessProtocol &process = thread.GetProcess(); + NativeRegisterContext ®ister_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()) { + // try to get at least the size of next instruction to set breakpoint. + auto instr_size = emulator_up->GetLastInstrSize(); + if (!instr_size) + return Status("Read instruction failed!"); + bool success = false; + auto pc = emulator_up->ReadRegisterUnsigned(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC, + LLDB_INVALID_ADDRESS, &success); + if (!success) + return Status("Reading pc failed!"); + lldb::addr_t next_pc = pc + *instr_size; + auto result = + SetSoftwareBreakpointOnPC(arch, next_pc, /* next_flags */ 0x0, process); + m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc}); + return result; + } + + 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 = reg_info_flags == nullptr + ? baton.m_register_values.end() + : 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."); + } + auto result = SetSoftwareBreakpointOnPC(arch, next_pc, next_flags, process); + m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc}); + return result; +} 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..4bec3de58668 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp @@ -0,0 +1,470 @@ +//===-- 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/LLDBLog.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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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)); + + // Mask off ignored bits from watchpoint trap address. + trap_addr = FixWatchpointHitAddress(trap_addr); + + 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 = GetLog(LLDBLog::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 = GetLog(LLDBLog::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..f8246ff4d718 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h @@ -0,0 +1,89 @@ +//===-- 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. + /// Watchpoints: For a user requested size 4 at addr 0x1004, where BAS + /// watchpoints are at doubleword (8-byte) alignment. + /// \a real_addr is 0x1004 + /// \a address is 0x1000 + /// size is 8 + /// If a one-byte write to 0x1006 is the most recent watchpoint trap, + /// \a hit_addr is 0x1006 + 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; + virtual lldb::addr_t FixWatchpointHitAddress(lldb::addr_t hit_addr) { + return hit_addr; + } +}; + +} // 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..f5525e3e3cb3 --- /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/LLDBLog.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 1ULL << 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 1ULL << (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 3ULL << (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 static_cast<uint64_t>(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 static_cast<uint64_t>(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 = GetLog(LLDBLog::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..4ca288d9dff7 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h @@ -0,0 +1,54 @@ +//===-- 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: + // NB: This constructor is here only because gcc<=6.5 requires a virtual base + // class initializer on abstract class (even though it is never used). It can + // be deleted once we move to gcc>=7.0. + NativeRegisterContextDBReg_x86(NativeThreadProtocol &thread) + : NativeRegisterContextRegisterInfo(thread, nullptr) {} + + 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; + + virtual 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/NativeRegisterContextRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp new file mode 100644 index 000000000000..3a875f7bb39b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp @@ -0,0 +1,42 @@ +//===-- NativeRegisterContextRegisterInfo.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 "NativeRegisterContextRegisterInfo.h" +#include "lldb/lldb-private-forward.h" +#include "lldb/lldb-types.h" + +using namespace lldb_private; + +NativeRegisterContextRegisterInfo::NativeRegisterContextRegisterInfo( + NativeThreadProtocol &thread, + RegisterInfoInterface *register_info_interface) + : NativeRegisterContext(thread), + m_register_info_interface_up(register_info_interface) { + assert(register_info_interface && "null register_info_interface"); +} + +uint32_t NativeRegisterContextRegisterInfo::GetRegisterCount() const { + return m_register_info_interface_up->GetRegisterCount(); +} + +uint32_t NativeRegisterContextRegisterInfo::GetUserRegisterCount() const { + return m_register_info_interface_up->GetUserRegisterCount(); +} + +const RegisterInfo *NativeRegisterContextRegisterInfo::GetRegisterInfoAtIndex( + uint32_t reg_index) const { + if (reg_index <= GetRegisterCount()) + return m_register_info_interface_up->GetRegisterInfo() + reg_index; + else + return nullptr; +} + +const RegisterInfoInterface & +NativeRegisterContextRegisterInfo::GetRegisterInfoInterface() const { + return *m_register_info_interface_up; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h new file mode 100644 index 000000000000..0e96841fd909 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h @@ -0,0 +1,40 @@ +//===-- NativeRegisterContextRegisterInfo.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_NATIVEREGISTERCONTEXTREGISTERINFO_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H + +#include <memory> + +#include "RegisterInfoInterface.h" +#include "lldb/Host/common/NativeRegisterContext.h" + +namespace lldb_private { +class NativeRegisterContextRegisterInfo : public NativeRegisterContext { +public: + /// + /// Construct a NativeRegisterContextRegisterInfo, taking ownership + /// of the register_info_interface pointer. + /// + NativeRegisterContextRegisterInfo( + NativeThreadProtocol &thread, + RegisterInfoInterface *register_info_interface); + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; + + const RegisterInfo *GetRegisterInfoAtIndex(uint32_t reg_index) const override; + + const RegisterInfoInterface &GetRegisterInfoInterface() const; + +protected: + std::unique_ptr<RegisterInfoInterface> m_register_info_interface_up; +}; +} +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp new file mode 100644 index 000000000000..6e4e5038566b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp @@ -0,0 +1,99 @@ +//===-- NetBSDSignals.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 "NetBSDSignals.h" + +#ifdef __NetBSD__ +#include <csignal> + +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + static_assert(signal_name == signal_value, \ + "Value mismatch for signal number " #signal_name); \ + static_assert(code_name == code_value, \ + "Value mismatch for signal code " #code_name); \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#endif /* ifdef __NetBSD */ + +using namespace lldb_private; + +NetBSDSignals::NetBSDSignals() : UnixSignals() { Reset(); } + +void NetBSDSignals::Reset() { + UnixSignals::Reset(); + + // clang-format off + // SIGILL + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(SIGILL, 4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(SIGILL, 4, ILL_BADSTK, 8, "internal stack error"); + + // SIGFPE + ADD_SIGCODE(SIGFPE, 8, FPE_INTDIV, 1, "integer divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_INTOVF, 2, "integer overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTINV, 7, "invalid floating point operation"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTSUB, 8, "subscript out of range"); + + // SIGBUS + ADD_SIGCODE(SIGBUS, 10, BUS_ADRALN, 1, "invalid address alignment"); + ADD_SIGCODE(SIGBUS, 10, BUS_ADRERR, 2, "non-existent physical address"); + ADD_SIGCODE(SIGBUS, 10, BUS_OBJERR, 3, "object specific hardware error"); + + // SIGSEGV + ADD_SIGCODE(SIGSEGV, 11, SEGV_MAPERR, 1, "address not mapped to object", + SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_ACCERR, 2, "invalid permissions for mapped object", + SignalCodePrintOption::Address); + + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ===== ============== ======== ====== ====== ======================== + AddSignal(32, "SIGPWR", false, true, true, "power fail/restart (not reset when caught)"); + AddSignal(33, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(34, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(35, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(36, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(37, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(38, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(39, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(40, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(41, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(42, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(43, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(44, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(45, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(46, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(47, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(48, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(49, "SIGRTMIN-14", false, false, false, "real time signal 16"); + AddSignal(50, "SIGRTMAX-13", false, false, false, "real time signal 17"); + AddSignal(51, "SIGRTMAX-12", false, false, false, "real time signal 18"); + AddSignal(52, "SIGRTMAX-11", false, false, false, "real time signal 19"); + AddSignal(53, "SIGRTMAX-10", false, false, false, "real time signal 20"); + AddSignal(54, "SIGRTMAX-9", false, false, false, "real time signal 21"); + AddSignal(55, "SIGRTMAX-8", false, false, false, "real time signal 22"); + AddSignal(56, "SIGRTMAX-7", false, false, false, "real time signal 23"); + AddSignal(57, "SIGRTMAX-6", false, false, false, "real time signal 24"); + AddSignal(58, "SIGRTMAX-5", false, false, false, "real time signal 25"); + AddSignal(59, "SIGRTMAX-4", false, false, false, "real time signal 26"); + AddSignal(60, "SIGRTMAX-3", false, false, false, "real time signal 27"); + AddSignal(61, "SIGRTMAX-2", false, false, false, "real time signal 28"); + AddSignal(62, "SIGRTMAX-1", false, false, false, "real time signal 29"); + AddSignal(63, "SIGRTMAX", false, false, false, "real time signal 30"); + // clang-format on +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.h new file mode 100644 index 000000000000..94bad7c19a49 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.h @@ -0,0 +1,27 @@ +//===-- NetBSDSignals.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_NETBSDSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H + +#include "lldb/Target/UnixSignals.h" + +namespace lldb_private { + +/// NetBSD specific set of Unix signals. +class NetBSDSignals : public UnixSignals { +public: + NetBSDSignals(); + +private: + void Reset() override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h new file mode 100644 index 000000000000..21582df91fb0 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h @@ -0,0 +1,25 @@ +//===-- RegisterContextDarwinConstants.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_REGISTERCONTEXTDARWINCONSTANTS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H + +namespace lldb_private { + +/// Constants returned by various RegisterContextDarwin_*** functions. +#ifndef KERN_SUCCESS +#define KERN_SUCCESS 0 +#endif + +#ifndef KERN_INVALID_ARGUMENT +#define KERN_INVALID_ARGUMENT 4 +#endif + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp new file mode 100644 index 000000000000..c23e82a741a0 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -0,0 +1,1745 @@ +//===-- RegisterContextDarwin_arm.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 "RegisterContextDarwin_arm.h" +#include "RegisterContextDarwinConstants.h" + +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "Plugins/Process/Utility/InstructionUtils.h" + +#include <memory> + +#include "Utility/ARM_DWARF_Registers.h" +#include "Utility/ARM_ehframe_Registers.h" + +#include "llvm/ADT/STLExtras.h" + +using namespace lldb; +using namespace lldb_private; + +enum { + gpr_r0 = 0, + 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_r13, + gpr_sp = gpr_r13, + gpr_r14, + gpr_lr = gpr_r14, + gpr_r15, + gpr_pc = gpr_r15, + gpr_cpsr, + + 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, + + exc_exception, + exc_fsr, + exc_far, + + dbg_bvr0, + dbg_bvr1, + dbg_bvr2, + dbg_bvr3, + dbg_bvr4, + dbg_bvr5, + dbg_bvr6, + dbg_bvr7, + dbg_bvr8, + dbg_bvr9, + dbg_bvr10, + dbg_bvr11, + dbg_bvr12, + dbg_bvr13, + dbg_bvr14, + dbg_bvr15, + + dbg_bcr0, + dbg_bcr1, + dbg_bcr2, + dbg_bcr3, + dbg_bcr4, + dbg_bcr5, + dbg_bcr6, + dbg_bcr7, + dbg_bcr8, + dbg_bcr9, + dbg_bcr10, + dbg_bcr11, + dbg_bcr12, + dbg_bcr13, + dbg_bcr14, + dbg_bcr15, + + dbg_wvr0, + dbg_wvr1, + dbg_wvr2, + dbg_wvr3, + dbg_wvr4, + dbg_wvr5, + dbg_wvr6, + dbg_wvr7, + dbg_wvr8, + dbg_wvr9, + dbg_wvr10, + dbg_wvr11, + dbg_wvr12, + dbg_wvr13, + dbg_wvr14, + dbg_wvr15, + + dbg_wcr0, + dbg_wcr1, + dbg_wcr2, + dbg_wcr3, + dbg_wcr4, + dbg_wcr5, + dbg_wcr6, + dbg_wcr7, + dbg_wcr8, + dbg_wcr9, + dbg_wcr10, + dbg_wcr11, + dbg_wcr12, + dbg_wcr13, + dbg_wcr14, + dbg_wcr15, + + k_num_registers +}; + +#define GPR_OFFSET(idx) ((idx)*4) +#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR)) +#define EXC_OFFSET(idx) \ + ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) + \ + sizeof(RegisterContextDarwin_arm::FPU)) +#define DBG_OFFSET(reg) \ + ((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) + \ + sizeof(RegisterContextDarwin_arm::GPR) + \ + sizeof(RegisterContextDarwin_arm::FPU) + \ + sizeof(RegisterContextDarwin_arm::EXC))) + +#define DEFINE_DBG(reg, i) \ + #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]), \ + DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM }, \ + nullptr, nullptr, nullptr, +#define REG_CONTEXT_SIZE \ + (sizeof(RegisterContextDarwin_arm::GPR) + \ + sizeof(RegisterContextDarwin_arm::FPU) + \ + sizeof(RegisterContextDarwin_arm::EXC)) + +static RegisterInfo g_register_infos[] = { + // General purpose registers + // NAME ALT SZ OFFSET ENCODING FORMAT + // EH_FRAME DWARF GENERIC + // PROCESS PLUGIN LLDB NATIVE + // ====== ======= == ============= ============= ============ + // =============== =============== ========================= + // ===================== ============= + {"r0", + nullptr, + 4, + GPR_OFFSET(0), + eEncodingUint, + eFormatHex, + {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0}, + nullptr, + nullptr, + nullptr, + }, + {"r1", + nullptr, + 4, + GPR_OFFSET(1), + eEncodingUint, + eFormatHex, + {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1}, + nullptr, + nullptr, + nullptr, + }, + {"r2", + nullptr, + 4, + GPR_OFFSET(2), + eEncodingUint, + eFormatHex, + {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2}, + nullptr, + nullptr, + nullptr, + }, + {"r3", + nullptr, + 4, + GPR_OFFSET(3), + eEncodingUint, + eFormatHex, + {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3}, + nullptr, + nullptr, + nullptr, + }, + {"r4", + nullptr, + 4, + GPR_OFFSET(4), + eEncodingUint, + eFormatHex, + {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4}, + nullptr, + nullptr, + nullptr, + }, + {"r5", + nullptr, + 4, + GPR_OFFSET(5), + eEncodingUint, + eFormatHex, + {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5}, + nullptr, + nullptr, + nullptr, + }, + {"r6", + nullptr, + 4, + GPR_OFFSET(6), + eEncodingUint, + eFormatHex, + {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6}, + nullptr, + nullptr, + nullptr, + }, + {"r7", + nullptr, + 4, + GPR_OFFSET(7), + eEncodingUint, + eFormatHex, + {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + gpr_r7}, + nullptr, + nullptr, + nullptr, + }, + {"r8", + nullptr, + 4, + GPR_OFFSET(8), + eEncodingUint, + eFormatHex, + {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8}, + nullptr, + nullptr, + nullptr, + }, + {"r9", + nullptr, + 4, + GPR_OFFSET(9), + eEncodingUint, + eFormatHex, + {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9}, + nullptr, + nullptr, + nullptr, + }, + {"r10", + nullptr, + 4, + GPR_OFFSET(10), + eEncodingUint, + eFormatHex, + {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r10}, + nullptr, + nullptr, + nullptr, + }, + {"r11", + nullptr, + 4, + GPR_OFFSET(11), + eEncodingUint, + eFormatHex, + {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r11}, + nullptr, + nullptr, + nullptr, + }, + {"r12", + nullptr, + 4, + GPR_OFFSET(12), + eEncodingUint, + eFormatHex, + {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r12}, + nullptr, + nullptr, + nullptr, + }, + {"sp", + "r13", + 4, + GPR_OFFSET(13), + eEncodingUint, + eFormatHex, + {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + gpr_sp}, + nullptr, + nullptr, + nullptr, + }, + {"lr", + "r14", + 4, + GPR_OFFSET(14), + eEncodingUint, + eFormatHex, + {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, + gpr_lr}, + nullptr, + nullptr, + nullptr, + }, + {"pc", + "r15", + 4, + GPR_OFFSET(15), + eEncodingUint, + eFormatHex, + {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + gpr_pc}, + nullptr, + nullptr, + nullptr, + }, + {"cpsr", + "psr", + 4, + GPR_OFFSET(16), + eEncodingUint, + eFormatHex, + {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, + gpr_cpsr}, + nullptr, + nullptr, + nullptr, + }, + + {"s0", + nullptr, + 4, + FPU_OFFSET(0), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s0}, + nullptr, + nullptr, + nullptr, + }, + {"s1", + nullptr, + 4, + FPU_OFFSET(1), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s1}, + nullptr, + nullptr, + nullptr, + }, + {"s2", + nullptr, + 4, + FPU_OFFSET(2), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s2}, + nullptr, + nullptr, + nullptr, + }, + {"s3", + nullptr, + 4, + FPU_OFFSET(3), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s3}, + nullptr, + nullptr, + nullptr, + }, + {"s4", + nullptr, + 4, + FPU_OFFSET(4), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s4}, + nullptr, + nullptr, + nullptr, + }, + {"s5", + nullptr, + 4, + FPU_OFFSET(5), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s5}, + nullptr, + nullptr, + nullptr, + }, + {"s6", + nullptr, + 4, + FPU_OFFSET(6), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s6}, + nullptr, + nullptr, + nullptr, + }, + {"s7", + nullptr, + 4, + FPU_OFFSET(7), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s7}, + nullptr, + nullptr, + nullptr, + }, + {"s8", + nullptr, + 4, + FPU_OFFSET(8), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s8}, + nullptr, + nullptr, + nullptr, + }, + {"s9", + nullptr, + 4, + FPU_OFFSET(9), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s9}, + nullptr, + nullptr, + nullptr, + }, + {"s10", + nullptr, + 4, + FPU_OFFSET(10), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s10}, + nullptr, + nullptr, + nullptr, + }, + {"s11", + nullptr, + 4, + FPU_OFFSET(11), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s11}, + nullptr, + nullptr, + nullptr, + }, + {"s12", + nullptr, + 4, + FPU_OFFSET(12), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s12}, + nullptr, + nullptr, + nullptr, + }, + {"s13", + nullptr, + 4, + FPU_OFFSET(13), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s13}, + nullptr, + nullptr, + nullptr, + }, + {"s14", + nullptr, + 4, + FPU_OFFSET(14), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s14}, + nullptr, + nullptr, + nullptr, + }, + {"s15", + nullptr, + 4, + FPU_OFFSET(15), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s15}, + nullptr, + nullptr, + nullptr, + }, + {"s16", + nullptr, + 4, + FPU_OFFSET(16), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s16}, + nullptr, + nullptr, + nullptr, + }, + {"s17", + nullptr, + 4, + FPU_OFFSET(17), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s17}, + nullptr, + nullptr, + nullptr, + }, + {"s18", + nullptr, + 4, + FPU_OFFSET(18), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s18}, + nullptr, + nullptr, + nullptr, + }, + {"s19", + nullptr, + 4, + FPU_OFFSET(19), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s19}, + nullptr, + nullptr, + nullptr, + }, + {"s20", + nullptr, + 4, + FPU_OFFSET(20), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s20}, + nullptr, + nullptr, + nullptr, + }, + {"s21", + nullptr, + 4, + FPU_OFFSET(21), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s21}, + nullptr, + nullptr, + nullptr, + }, + {"s22", + nullptr, + 4, + FPU_OFFSET(22), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s22}, + nullptr, + nullptr, + nullptr, + }, + {"s23", + nullptr, + 4, + FPU_OFFSET(23), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s23}, + nullptr, + nullptr, + nullptr, + }, + {"s24", + nullptr, + 4, + FPU_OFFSET(24), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s24}, + nullptr, + nullptr, + nullptr, + }, + {"s25", + nullptr, + 4, + FPU_OFFSET(25), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s25}, + nullptr, + nullptr, + nullptr, + }, + {"s26", + nullptr, + 4, + FPU_OFFSET(26), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s26}, + nullptr, + nullptr, + nullptr, + }, + {"s27", + nullptr, + 4, + FPU_OFFSET(27), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s27}, + nullptr, + nullptr, + nullptr, + }, + {"s28", + nullptr, + 4, + FPU_OFFSET(28), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s28}, + nullptr, + nullptr, + nullptr, + }, + {"s29", + nullptr, + 4, + FPU_OFFSET(29), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s29}, + nullptr, + nullptr, + nullptr, + }, + {"s30", + nullptr, + 4, + FPU_OFFSET(30), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s30}, + nullptr, + nullptr, + nullptr, + }, + {"s31", + nullptr, + 4, + FPU_OFFSET(31), + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s31}, + nullptr, + nullptr, + nullptr, + }, + {"fpscr", + nullptr, + 4, + FPU_OFFSET(32), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fpscr}, + nullptr, + nullptr, + nullptr, + }, + + {"exception", + nullptr, + 4, + EXC_OFFSET(0), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_exception}, + nullptr, + nullptr, + nullptr, + }, + {"fsr", + nullptr, + 4, + EXC_OFFSET(1), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_fsr}, + nullptr, + nullptr, + nullptr, + }, + {"far", + nullptr, + 4, + EXC_OFFSET(2), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_far}, + nullptr, + nullptr, + nullptr, + }, + + {DEFINE_DBG(bvr, 0)}, + {DEFINE_DBG(bvr, 1)}, + {DEFINE_DBG(bvr, 2)}, + {DEFINE_DBG(bvr, 3)}, + {DEFINE_DBG(bvr, 4)}, + {DEFINE_DBG(bvr, 5)}, + {DEFINE_DBG(bvr, 6)}, + {DEFINE_DBG(bvr, 7)}, + {DEFINE_DBG(bvr, 8)}, + {DEFINE_DBG(bvr, 9)}, + {DEFINE_DBG(bvr, 10)}, + {DEFINE_DBG(bvr, 11)}, + {DEFINE_DBG(bvr, 12)}, + {DEFINE_DBG(bvr, 13)}, + {DEFINE_DBG(bvr, 14)}, + {DEFINE_DBG(bvr, 15)}, + + {DEFINE_DBG(bcr, 0)}, + {DEFINE_DBG(bcr, 1)}, + {DEFINE_DBG(bcr, 2)}, + {DEFINE_DBG(bcr, 3)}, + {DEFINE_DBG(bcr, 4)}, + {DEFINE_DBG(bcr, 5)}, + {DEFINE_DBG(bcr, 6)}, + {DEFINE_DBG(bcr, 7)}, + {DEFINE_DBG(bcr, 8)}, + {DEFINE_DBG(bcr, 9)}, + {DEFINE_DBG(bcr, 10)}, + {DEFINE_DBG(bcr, 11)}, + {DEFINE_DBG(bcr, 12)}, + {DEFINE_DBG(bcr, 13)}, + {DEFINE_DBG(bcr, 14)}, + {DEFINE_DBG(bcr, 15)}, + + {DEFINE_DBG(wvr, 0)}, + {DEFINE_DBG(wvr, 1)}, + {DEFINE_DBG(wvr, 2)}, + {DEFINE_DBG(wvr, 3)}, + {DEFINE_DBG(wvr, 4)}, + {DEFINE_DBG(wvr, 5)}, + {DEFINE_DBG(wvr, 6)}, + {DEFINE_DBG(wvr, 7)}, + {DEFINE_DBG(wvr, 8)}, + {DEFINE_DBG(wvr, 9)}, + {DEFINE_DBG(wvr, 10)}, + {DEFINE_DBG(wvr, 11)}, + {DEFINE_DBG(wvr, 12)}, + {DEFINE_DBG(wvr, 13)}, + {DEFINE_DBG(wvr, 14)}, + {DEFINE_DBG(wvr, 15)}, + + {DEFINE_DBG(wcr, 0)}, + {DEFINE_DBG(wcr, 1)}, + {DEFINE_DBG(wcr, 2)}, + {DEFINE_DBG(wcr, 3)}, + {DEFINE_DBG(wcr, 4)}, + {DEFINE_DBG(wcr, 5)}, + {DEFINE_DBG(wcr, 6)}, + {DEFINE_DBG(wcr, 7)}, + {DEFINE_DBG(wcr, 8)}, + {DEFINE_DBG(wcr, 9)}, + {DEFINE_DBG(wcr, 10)}, + {DEFINE_DBG(wcr, 11)}, + {DEFINE_DBG(wcr, 12)}, + {DEFINE_DBG(wcr, 13)}, + {DEFINE_DBG(wcr, 14)}, + {DEFINE_DBG(wcr, 15)}}; + +// General purpose registers +static uint32_t g_gpr_regnums[] = { + 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}; + +// Floating point registers +static uint32_t g_fpu_regnums[] = { + 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, +}; + +// Exception registers + +static uint32_t g_exc_regnums[] = { + exc_exception, exc_fsr, exc_far, +}; + +static size_t k_num_register_infos = std::size(g_register_infos); + +RegisterContextDarwin_arm::RegisterContextDarwin_arm( + Thread &thread, uint32_t concrete_frame_idx) + : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() { + uint32_t i; + for (i = 0; i < kNumErrors; i++) { + gpr_errs[i] = -1; + fpu_errs[i] = -1; + exc_errs[i] = -1; + } +} + +RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default; + +void RegisterContextDarwin_arm::InvalidateAllRegisters() { + InvalidateAllRegisterStates(); +} + +size_t RegisterContextDarwin_arm::GetRegisterCount() { + assert(k_num_register_infos == k_num_registers); + return k_num_registers; +} + +const RegisterInfo * +RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) { + assert(k_num_register_infos == k_num_registers); + if (reg < k_num_registers) + return &g_register_infos[reg]; + return nullptr; +} + +size_t RegisterContextDarwin_arm::GetRegisterInfosCount() { + return k_num_register_infos; +} + +const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() { + return g_register_infos; +} + +// Number of registers in each register set +const size_t k_num_gpr_registers = std::size(g_gpr_regnums); +const size_t k_num_fpu_registers = std::size(g_fpu_regnums); +const size_t k_num_exc_registers = std::size(g_exc_regnums); + +// Register set definitions. The first definitions at register set index of +// zero is for all registers, followed by other registers sets. The register +// information for the all register set need not be filled in. +static const RegisterSet g_reg_sets[] = { + { + "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, + }, + {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums}, + {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}}; + +const size_t k_num_regsets = std::size(g_reg_sets); + +size_t RegisterContextDarwin_arm::GetRegisterSetCount() { + return k_num_regsets; +} + +const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) { + if (reg_set < k_num_regsets) + return &g_reg_sets[reg_set]; + return nullptr; +} + +// Register information definitions for 32 bit i386. +int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) { + if (reg < fpu_s0) + return GPRRegSet; + else if (reg < exc_exception) + return FPURegSet; + else if (reg < k_num_registers) + return EXCRegSet; + return -1; +} + +int RegisterContextDarwin_arm::ReadGPR(bool force) { + int set = GPRRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); + } + return GetError(GPRRegSet, Read); +} + +int RegisterContextDarwin_arm::ReadFPU(bool force) { + int set = FPURegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); + } + return GetError(FPURegSet, Read); +} + +int RegisterContextDarwin_arm::ReadEXC(bool force) { + int set = EXCRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); + } + return GetError(EXCRegSet, Read); +} + +int RegisterContextDarwin_arm::ReadDBG(bool force) { + int set = DBGRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg)); + } + return GetError(DBGRegSet, Read); +} + +int RegisterContextDarwin_arm::WriteGPR() { + int set = GPRRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return KERN_INVALID_ARGUMENT; + } + SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr)); + SetError(set, Read, -1); + return GetError(GPRRegSet, Write); +} + +int RegisterContextDarwin_arm::WriteFPU() { + int set = FPURegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return KERN_INVALID_ARGUMENT; + } + SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu)); + SetError(set, Read, -1); + return GetError(FPURegSet, Write); +} + +int RegisterContextDarwin_arm::WriteEXC() { + int set = EXCRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return KERN_INVALID_ARGUMENT; + } + SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc)); + SetError(set, Read, -1); + return GetError(EXCRegSet, Write); +} + +int RegisterContextDarwin_arm::WriteDBG() { + int set = DBGRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return KERN_INVALID_ARGUMENT; + } + SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg)); + SetError(set, Read, -1); + return GetError(DBGRegSet, Write); +} + +int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) { + switch (set) { + case GPRRegSet: + return ReadGPR(force); + case GPRAltRegSet: + return ReadGPR(force); + case FPURegSet: + return ReadFPU(force); + case EXCRegSet: + return ReadEXC(force); + case DBGRegSet: + return ReadDBG(force); + default: + break; + } + return KERN_INVALID_ARGUMENT; +} + +int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) { + // Make sure we have a valid context to set. + if (RegisterSetIsCached(set)) { + switch (set) { + case GPRRegSet: + return WriteGPR(); + case GPRAltRegSet: + return WriteGPR(); + case FPURegSet: + return WriteFPU(); + case EXCRegSet: + return WriteEXC(); + case DBGRegSet: + return WriteDBG(); + default: + break; + } + } + return KERN_INVALID_ARGUMENT; +} + +void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) { + if (log) { + for (uint32_t i = 0; i < 16; i++) + LLDB_LOGF(log, + "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { " + "0x%8.8x, 0x%8.8x }", + i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]); + } +} + +bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info, + RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg); + + if (set == -1) + return false; + + if (ReadRegisterSet(set, false) != KERN_SUCCESS) + return false; + + switch (reg) { + case gpr_r0: + case gpr_r1: + case gpr_r2: + case gpr_r3: + case gpr_r4: + case gpr_r5: + case gpr_r6: + case gpr_r7: + case gpr_r8: + case gpr_r9: + case gpr_r10: + case gpr_r11: + case gpr_r12: + case gpr_sp: + case gpr_lr: + case gpr_pc: + value.SetUInt32(gpr.r[reg - gpr_r0]); + break; + case gpr_cpsr: + value.SetUInt32(gpr.cpsr); + break; + case fpu_s0: + case fpu_s1: + case fpu_s2: + case fpu_s3: + case fpu_s4: + case fpu_s5: + case fpu_s6: + case fpu_s7: + case fpu_s8: + case fpu_s9: + case fpu_s10: + case fpu_s11: + case fpu_s12: + case fpu_s13: + case fpu_s14: + case fpu_s15: + case fpu_s16: + case fpu_s17: + case fpu_s18: + case fpu_s19: + case fpu_s20: + case fpu_s21: + case fpu_s22: + case fpu_s23: + case fpu_s24: + case fpu_s25: + case fpu_s26: + case fpu_s27: + case fpu_s28: + case fpu_s29: + case fpu_s30: + case fpu_s31: + value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat); + break; + + case fpu_fpscr: + value.SetUInt32(fpu.fpscr); + break; + + case exc_exception: + value.SetUInt32(exc.exception); + break; + case exc_fsr: + value.SetUInt32(exc.fsr); + break; + case exc_far: + value.SetUInt32(exc.far); + break; + + default: + value.SetValueToInvalid(); + return false; + } + return true; +} + +bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info, + const RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + int set = GetSetForNativeRegNum(reg); + + if (set == -1) + return false; + + if (ReadRegisterSet(set, false) != KERN_SUCCESS) + return false; + + switch (reg) { + case gpr_r0: + case gpr_r1: + case gpr_r2: + case gpr_r3: + case gpr_r4: + case gpr_r5: + case gpr_r6: + case gpr_r7: + case gpr_r8: + case gpr_r9: + case gpr_r10: + case gpr_r11: + case gpr_r12: + case gpr_sp: + case gpr_lr: + case gpr_pc: + case gpr_cpsr: + gpr.r[reg - gpr_r0] = value.GetAsUInt32(); + break; + + case fpu_s0: + case fpu_s1: + case fpu_s2: + case fpu_s3: + case fpu_s4: + case fpu_s5: + case fpu_s6: + case fpu_s7: + case fpu_s8: + case fpu_s9: + case fpu_s10: + case fpu_s11: + case fpu_s12: + case fpu_s13: + case fpu_s14: + case fpu_s15: + case fpu_s16: + case fpu_s17: + case fpu_s18: + case fpu_s19: + case fpu_s20: + case fpu_s21: + case fpu_s22: + case fpu_s23: + case fpu_s24: + case fpu_s25: + case fpu_s26: + case fpu_s27: + case fpu_s28: + case fpu_s29: + case fpu_s30: + case fpu_s31: + fpu.floats.s[reg] = value.GetAsUInt32(); + break; + + case fpu_fpscr: + fpu.fpscr = value.GetAsUInt32(); + break; + + case exc_exception: + exc.exception = value.GetAsUInt32(); + break; + case exc_fsr: + exc.fsr = value.GetAsUInt32(); + break; + case exc_far: + exc.far = value.GetAsUInt32(); + break; + + default: + return false; + } + return WriteRegisterSet(set) == KERN_SUCCESS; +} + +bool RegisterContextDarwin_arm::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { + data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); + if (data_sp && ReadGPR(false) == KERN_SUCCESS && + ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) { + uint8_t *dst = data_sp->GetBytes(); + ::memcpy(dst, &gpr, sizeof(gpr)); + dst += sizeof(gpr); + + ::memcpy(dst, &fpu, sizeof(fpu)); + dst += sizeof(gpr); + + ::memcpy(dst, &exc, sizeof(exc)); + return true; + } + return false; +} + +bool RegisterContextDarwin_arm::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) { + const uint8_t *src = data_sp->GetBytes(); + ::memcpy(&gpr, src, sizeof(gpr)); + src += sizeof(gpr); + + ::memcpy(&fpu, src, sizeof(fpu)); + src += sizeof(gpr); + + ::memcpy(&exc, src, sizeof(exc)); + uint32_t success_count = 0; + if (WriteGPR() == KERN_SUCCESS) + ++success_count; + if (WriteFPU() == KERN_SUCCESS) + ++success_count; + if (WriteEXC() == KERN_SUCCESS) + ++success_count; + return success_count == 3; + } + return false; +} + +uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t reg) { + if (kind == eRegisterKindGeneric) { + switch (reg) { + case LLDB_REGNUM_GENERIC_PC: + return gpr_pc; + case LLDB_REGNUM_GENERIC_SP: + return gpr_sp; + case LLDB_REGNUM_GENERIC_FP: + return gpr_r7; + case LLDB_REGNUM_GENERIC_RA: + return gpr_lr; + case LLDB_REGNUM_GENERIC_FLAGS: + return gpr_cpsr; + default: + break; + } + } else if (kind == eRegisterKindDWARF) { + switch (reg) { + case dwarf_r0: + return gpr_r0; + case dwarf_r1: + return gpr_r1; + case dwarf_r2: + return gpr_r2; + case dwarf_r3: + return gpr_r3; + case dwarf_r4: + return gpr_r4; + case dwarf_r5: + return gpr_r5; + case dwarf_r6: + return gpr_r6; + case dwarf_r7: + return gpr_r7; + case dwarf_r8: + return gpr_r8; + case dwarf_r9: + return gpr_r9; + case dwarf_r10: + return gpr_r10; + case dwarf_r11: + return gpr_r11; + case dwarf_r12: + return gpr_r12; + case dwarf_sp: + return gpr_sp; + case dwarf_lr: + return gpr_lr; + case dwarf_pc: + return gpr_pc; + case dwarf_spsr: + return gpr_cpsr; + + case dwarf_s0: + return fpu_s0; + case dwarf_s1: + return fpu_s1; + case dwarf_s2: + return fpu_s2; + case dwarf_s3: + return fpu_s3; + case dwarf_s4: + return fpu_s4; + case dwarf_s5: + return fpu_s5; + case dwarf_s6: + return fpu_s6; + case dwarf_s7: + return fpu_s7; + case dwarf_s8: + return fpu_s8; + case dwarf_s9: + return fpu_s9; + case dwarf_s10: + return fpu_s10; + case dwarf_s11: + return fpu_s11; + case dwarf_s12: + return fpu_s12; + case dwarf_s13: + return fpu_s13; + case dwarf_s14: + return fpu_s14; + case dwarf_s15: + return fpu_s15; + case dwarf_s16: + return fpu_s16; + case dwarf_s17: + return fpu_s17; + case dwarf_s18: + return fpu_s18; + case dwarf_s19: + return fpu_s19; + case dwarf_s20: + return fpu_s20; + case dwarf_s21: + return fpu_s21; + case dwarf_s22: + return fpu_s22; + case dwarf_s23: + return fpu_s23; + case dwarf_s24: + return fpu_s24; + case dwarf_s25: + return fpu_s25; + case dwarf_s26: + return fpu_s26; + case dwarf_s27: + return fpu_s27; + case dwarf_s28: + return fpu_s28; + case dwarf_s29: + return fpu_s29; + case dwarf_s30: + return fpu_s30; + case dwarf_s31: + return fpu_s31; + + default: + break; + } + } else if (kind == eRegisterKindEHFrame) { + switch (reg) { + case ehframe_r0: + return gpr_r0; + case ehframe_r1: + return gpr_r1; + case ehframe_r2: + return gpr_r2; + case ehframe_r3: + return gpr_r3; + case ehframe_r4: + return gpr_r4; + case ehframe_r5: + return gpr_r5; + case ehframe_r6: + return gpr_r6; + case ehframe_r7: + return gpr_r7; + case ehframe_r8: + return gpr_r8; + case ehframe_r9: + return gpr_r9; + case ehframe_r10: + return gpr_r10; + case ehframe_r11: + return gpr_r11; + case ehframe_r12: + return gpr_r12; + case ehframe_sp: + return gpr_sp; + case ehframe_lr: + return gpr_lr; + case ehframe_pc: + return gpr_pc; + case ehframe_cpsr: + return gpr_cpsr; + } + } else if (kind == eRegisterKindLLDB) { + return reg; + } + return LLDB_INVALID_REGNUM; +} + +uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() { +#if defined(__APPLE__) && defined(__arm__) + // Set the init value to something that will let us know that we need to + // autodetect how many breakpoints are supported dynamically... + static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX; + if (g_num_supported_hw_breakpoints == UINT32_MAX) { + // Set this to zero in case we can't tell if there are any HW breakpoints + g_num_supported_hw_breakpoints = 0; + + uint32_t register_DBGDIDR; + + asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR)); + g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24); + // Zero is reserved for the BRP count, so don't increment it if it is zero + if (g_num_supported_hw_breakpoints > 0) + g_num_supported_hw_breakpoints++; + } + return g_num_supported_hw_breakpoints; +#else + // TODO: figure out remote case here! + return 6; +#endif +} + +uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr, + size_t size) { + // Make sure our address isn't bogus + if (addr & 1) + return LLDB_INVALID_INDEX32; + + int kret = ReadDBG(false); + + if (kret == KERN_SUCCESS) { + const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints(); + uint32_t i; + for (i = 0; i < num_hw_breakpoints; ++i) { + if ((dbg.bcr[i] & BCR_ENABLE) == 0) + break; // We found an available hw breakpoint slot (in i) + } + + // See if we found an available hw breakpoint slot above + if (i < num_hw_breakpoints) { + // Make sure bits 1:0 are clear in our address + dbg.bvr[i] = addr & ~((lldb::addr_t)3); + + if (size == 2 || addr & 2) { + uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1; + + // We have a thumb breakpoint + // We have an ARM breakpoint + dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address match + byte_addr_select | // Set the correct byte address select + // so we only trigger on the correct + // opcode + S_USER | // Which modes should this breakpoint stop in? + BCR_ENABLE; // Enable this hardware breakpoint + // if (log) log->Printf + // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( + // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / + // 0x%8.8x (Thumb)", + // addr, + // size, + // i, + // i, + // dbg.bvr[i], + // dbg.bcr[i]); + } else if (size == 4) { + // We have an ARM breakpoint + dbg.bcr[i] = + BCR_M_IMVA_MATCH | // Stop on address match + BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA + S_USER | // Which modes should this breakpoint stop in? + BCR_ENABLE; // Enable this hardware breakpoint + // if (log) log->Printf + // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( + // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / + // 0x%8.8x (ARM)", + // addr, + // size, + // i, + // i, + // dbg.bvr[i], + // dbg.bcr[i]); + } + + kret = WriteDBG(); + // if (log) log->Printf + // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() + // WriteDBG() => 0x%8.8x.", kret); + + if (kret == KERN_SUCCESS) + return i; + } + // else + // { + // if (log) log->Printf + // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = + // %8.8p, size = %u) => all hardware breakpoint resources are + // being used.", addr, size); + // } + } + + return LLDB_INVALID_INDEX32; +} + +bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) { + int kret = ReadDBG(false); + + const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); + if (kret == KERN_SUCCESS) { + if (hw_index < num_hw_points) { + dbg.bcr[hw_index] = 0; + // if (log) log->Printf + // ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - + // BVR%u = 0x%8.8x BCR%u = 0x%8.8x", + // hw_index, + // hw_index, + // dbg.bvr[hw_index], + // hw_index, + // dbg.bcr[hw_index]); + + kret = WriteDBG(); + + if (kret == KERN_SUCCESS) + return true; + } + } + return false; +} + +uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() { +#if defined(__APPLE__) && defined(__arm__) + // Set the init value to something that will let us know that we need to + // autodetect how many watchpoints are supported dynamically... + static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX; + if (g_num_supported_hw_watchpoints == UINT32_MAX) { + // Set this to zero in case we can't tell if there are any HW breakpoints + g_num_supported_hw_watchpoints = 0; + + uint32_t register_DBGDIDR; + asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR)); + g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1; + } + return g_num_supported_hw_watchpoints; +#else + // TODO: figure out remote case here! + return 2; +#endif +} + +uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr, + size_t size, + bool read, + bool write) { + const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); + + // Can't watch zero bytes + if (size == 0) + return LLDB_INVALID_INDEX32; + + // We must watch for either read or write + if (!read && !write) + return LLDB_INVALID_INDEX32; + + // Can't watch more than 4 bytes per WVR/WCR pair + if (size > 4) + return LLDB_INVALID_INDEX32; + + // We can only watch up to four bytes that follow a 4 byte aligned address + // per watchpoint register pair. Since we have at most so we can only watch + // until the next 4 byte boundary and we need to make sure we can properly + // encode this. + uint32_t addr_word_offset = addr % 4; + // if (log) log->Printf + // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - + // addr_word_offset = 0x%8.8x", addr_word_offset); + + uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; + // if (log) log->Printf + // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = + // 0x%8.8x", byte_mask); + if (byte_mask > 0xfu) + return LLDB_INVALID_INDEX32; + + // Read the debug state + int kret = ReadDBG(false); + + if (kret == KERN_SUCCESS) { + // Check to make sure we have the needed hardware support + uint32_t i = 0; + + for (i = 0; i < num_hw_watchpoints; ++i) { + if ((dbg.wcr[i] & WCR_ENABLE) == 0) + break; // We found an available hw breakpoint slot (in i) + } + + // See if we found an available hw breakpoint slot above + if (i < num_hw_watchpoints) { + // Make the byte_mask into a valid Byte Address Select mask + uint32_t byte_address_select = byte_mask << 5; + // Make sure bits 1:0 are clear in our address + dbg.wvr[i] = addr & ~((lldb::addr_t)3); + dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA + // that we will watch + S_USER | // Stop only in user mode + (read ? WCR_LOAD : 0) | // Stop on read access? + (write ? WCR_STORE : 0) | // Stop on write access? + WCR_ENABLE; // Enable this watchpoint; + + kret = WriteDBG(); + // if (log) log->Printf + // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() + // WriteDBG() => 0x%8.8x.", kret); + + if (kret == KERN_SUCCESS) + return i; + } else { + // if (log) log->Printf + // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All + // hardware resources (%u) are in use.", num_hw_watchpoints); + } + } + return LLDB_INVALID_INDEX32; +} + +bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) { + int kret = ReadDBG(false); + + const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); + if (kret == KERN_SUCCESS) { + if (hw_index < num_hw_points) { + dbg.wcr[hw_index] = 0; + // if (log) log->Printf + // ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - + // WVR%u = 0x%8.8x WCR%u = 0x%8.8x", + // hw_index, + // hw_index, + // dbg.wvr[hw_index], + // hw_index, + // dbg.wcr[hw_index]); + + kret = WriteDBG(); + + if (kret == KERN_SUCCESS) + return true; + } + } + return false; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h new file mode 100644 index 000000000000..7ff1bded81f4 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h @@ -0,0 +1,264 @@ +//===-- RegisterContextDarwin_arm.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_REGISTERCONTEXTDARWIN_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H + +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +// BCR address match type +#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21)) +#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21)) +#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21)) +#define BCR_M_RESERVED ((uint32_t)(3u << 21)) + +// Link a BVR/BCR or WVR/WCR pair to another +#define E_ENABLE_LINKING ((uint32_t)(1u << 20)) + +// Byte Address Select +#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5)) +#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6)) +#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7)) +#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8)) +#define BAS_IMVA_0_1 ((uint32_t)(3u << 5)) +#define BAS_IMVA_2_3 ((uint32_t)(3u << 7)) +#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5)) + +// Break only in privileged or user mode +#define S_RSVD ((uint32_t)(0u << 1)) +#define S_PRIV ((uint32_t)(1u << 1)) +#define S_USER ((uint32_t)(2u << 1)) +#define S_PRIV_USER ((S_PRIV) | (S_USER)) + +#define BCR_ENABLE ((uint32_t)(1u)) +#define WCR_ENABLE ((uint32_t)(1u)) + +// Watchpoint load/store +#define WCR_LOAD ((uint32_t)(1u << 3)) +#define WCR_STORE ((uint32_t)(1u << 4)) + +class RegisterContextDarwin_arm : public lldb_private::RegisterContext { +public: + RegisterContextDarwin_arm(lldb_private::Thread &thread, + uint32_t concrete_frame_idx); + + ~RegisterContextDarwin_arm() override; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue ®_value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue ®_value) override; + + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + uint32_t NumSupportedHardwareBreakpoints() override; + + uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override; + + bool ClearHardwareBreakpoint(uint32_t hw_idx) override; + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, + bool write) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + struct GPR { + uint32_t r[16]; // R0-R15 + uint32_t cpsr; // CPSR + }; + + 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; + }; + + // struct NeonReg + // { + // uint8_t bytes[16]; + // }; + // + // struct VFPv3 + // { + // union { + // uint32_t s[32]; + // uint64_t d[32]; + // NeonReg q[16]; + // } v3; + // uint32_t fpscr; + // }; + + struct EXC { + uint32_t exception; + uint32_t fsr; /* Fault status */ + uint32_t far; /* Virtual Fault Address */ + }; + + struct DBG { + uint32_t bvr[16]; + uint32_t bcr[16]; + uint32_t wvr[16]; + uint32_t wcr[16]; + }; + + static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg); + +protected: + enum { + GPRRegSet = 1, // ARM_THREAD_STATE + GPRAltRegSet = 9, // ARM_THREAD_STATE32 + FPURegSet = 2, // ARM_VFP_STATE + EXCRegSet = 3, // ARM_EXCEPTION_STATE + DBGRegSet = 4 // ARM_DEBUG_STATE + }; + + enum { + GPRWordCount = sizeof(GPR) / sizeof(uint32_t), + FPUWordCount = sizeof(FPU) / sizeof(uint32_t), + EXCWordCount = sizeof(EXC) / sizeof(uint32_t), + DBGWordCount = sizeof(DBG) / sizeof(uint32_t) + }; + + enum { Read = 0, Write = 1, kNumErrors = 2 }; + + GPR gpr; + FPU fpu; + EXC exc; + DBG dbg; + int gpr_errs[2]; // Read/Write errors + int fpu_errs[2]; // Read/Write errors + int exc_errs[2]; // Read/Write errors + int dbg_errs[2]; // Read/Write errors + + void InvalidateAllRegisterStates() { + SetError(GPRRegSet, Read, -1); + SetError(FPURegSet, Read, -1); + SetError(EXCRegSet, Read, -1); + } + + int GetError(int flavor, uint32_t err_idx) const { + if (err_idx < kNumErrors) { + switch (flavor) { + // When getting all errors, just OR all values together to see if + // we got any kind of error. + case GPRRegSet: + return gpr_errs[err_idx]; + case FPURegSet: + return fpu_errs[err_idx]; + case EXCRegSet: + return exc_errs[err_idx]; + case DBGRegSet: + return dbg_errs[err_idx]; + default: + break; + } + } + return -1; + } + + bool SetError(int flavor, uint32_t err_idx, int err) { + if (err_idx < kNumErrors) { + switch (flavor) { + case GPRRegSet: + gpr_errs[err_idx] = err; + return true; + + case FPURegSet: + fpu_errs[err_idx] = err; + return true; + + case EXCRegSet: + exc_errs[err_idx] = err; + return true; + + case DBGRegSet: + exc_errs[err_idx] = err; + return true; + + default: + break; + } + } + return false; + } + + bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; } + + int ReadGPR(bool force); + + int ReadFPU(bool force); + + int ReadEXC(bool force); + + int ReadDBG(bool force); + + int WriteGPR(); + + int WriteFPU(); + + int WriteEXC(); + + int WriteDBG(); + + // Subclasses override these to do the actual reading. + virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; } + + virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; + + virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; + + virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0; + + virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; + + virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; + + virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; + + virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0; + + int ReadRegisterSet(uint32_t set, bool force); + + int WriteRegisterSet(uint32_t set); + + static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); + + static int GetSetForNativeRegNum(int reg_num); + + static size_t GetRegisterInfosCount(); + + static const lldb_private::RegisterInfo *GetRegisterInfos(); +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp new file mode 100644 index 000000000000..3bcd9a28e3f1 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -0,0 +1,1041 @@ +//===-- RegisterContextDarwin_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 "RegisterContextDarwin_arm64.h" +#include "RegisterContextDarwinConstants.h" + +#include "lldb/Target/Process.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Compiler.h" + +#include "Plugins/Process/Utility/InstructionUtils.h" + +#include <memory> + +#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) +#include <sys/types.h> +#include <sys/sysctl.h> +#endif + +#include "Utility/ARM64_DWARF_Registers.h" + +using namespace lldb; +using namespace lldb_private; + +#define GPR_OFFSET(idx) ((idx)*8) +#define GPR_OFFSET_NAME(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::GPR, reg)) + +#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterContextDarwin_arm64::GPR)) +#define FPU_OFFSET_NAME(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::FPU, reg)) + +#define EXC_OFFSET_NAME(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::EXC, reg) + \ + sizeof(RegisterContextDarwin_arm64::GPR) + \ + sizeof(RegisterContextDarwin_arm64::FPU)) +#define DBG_OFFSET_NAME(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::DBG, reg) + \ + sizeof(RegisterContextDarwin_arm64::GPR) + \ + sizeof(RegisterContextDarwin_arm64::FPU) + \ + sizeof(RegisterContextDarwin_arm64::EXC)) + +#define DEFINE_DBG(reg, i) \ + #reg, NULL, \ + sizeof(((RegisterContextDarwin_arm64::DBG *) NULL)->reg[i]), \ + DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM }, \ + NULL, NULL, NULL +#define REG_CONTEXT_SIZE \ + (sizeof(RegisterContextDarwin_arm64::GPR) + \ + sizeof(RegisterContextDarwin_arm64::FPU) + \ + sizeof(RegisterContextDarwin_arm64::EXC)) + +// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure. +#define DECLARE_REGISTER_INFOS_ARM64_STRUCT +#include "RegisterInfos_arm64.h" +#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT + +// General purpose registers +static uint32_t g_gpr_regnums[] = { + gpr_x0, gpr_x1, gpr_x2, gpr_x3, gpr_x4, gpr_x5, gpr_x6, + gpr_x7, gpr_x8, gpr_x9, gpr_x10, gpr_x11, gpr_x12, gpr_x13, + gpr_x14, gpr_x15, gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20, + gpr_x21, gpr_x22, gpr_x23, gpr_x24, gpr_x25, gpr_x26, gpr_x27, + gpr_x28, gpr_fp, gpr_lr, gpr_sp, gpr_pc, gpr_cpsr}; + +// Floating point registers +static uint32_t g_fpu_regnums[] = { + fpu_v0, fpu_v1, fpu_v2, fpu_v3, fpu_v4, fpu_v5, fpu_v6, + fpu_v7, fpu_v8, fpu_v9, fpu_v10, fpu_v11, fpu_v12, fpu_v13, + fpu_v14, fpu_v15, fpu_v16, fpu_v17, fpu_v18, fpu_v19, fpu_v20, + fpu_v21, fpu_v22, fpu_v23, fpu_v24, fpu_v25, fpu_v26, fpu_v27, + fpu_v28, fpu_v29, fpu_v30, fpu_v31, fpu_fpsr, fpu_fpcr}; + +// Exception registers + +static uint32_t g_exc_regnums[] = {exc_far, exc_esr, exc_exception}; + +static size_t k_num_register_infos = std::size(g_register_infos_arm64_le); + +RegisterContextDarwin_arm64::RegisterContextDarwin_arm64( + Thread &thread, uint32_t concrete_frame_idx) + : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc(), dbg() { + uint32_t i; + for (i = 0; i < kNumErrors; i++) { + gpr_errs[i] = -1; + fpu_errs[i] = -1; + exc_errs[i] = -1; + } +} + +RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() = default; + +void RegisterContextDarwin_arm64::InvalidateAllRegisters() { + InvalidateAllRegisterStates(); +} + +size_t RegisterContextDarwin_arm64::GetRegisterCount() { + assert(k_num_register_infos == k_num_registers); + return k_num_registers; +} + +const RegisterInfo * +RegisterContextDarwin_arm64::GetRegisterInfoAtIndex(size_t reg) { + assert(k_num_register_infos == k_num_registers); + if (reg < k_num_registers) + return &g_register_infos_arm64_le[reg]; + return nullptr; +} + +size_t RegisterContextDarwin_arm64::GetRegisterInfosCount() { + return k_num_register_infos; +} + +const RegisterInfo *RegisterContextDarwin_arm64::GetRegisterInfos() { + return g_register_infos_arm64_le; +} + +// Number of registers in each register set +const size_t k_num_gpr_registers = std::size(g_gpr_regnums); +const size_t k_num_fpu_registers = std::size(g_fpu_regnums); +const size_t k_num_exc_registers = std::size(g_exc_regnums); + +// Register set definitions. The first definitions at register set index of +// zero is for all registers, followed by other registers sets. The register +// information for the all register set need not be filled in. +static const RegisterSet g_reg_sets[] = { + { + "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, + }, + {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums}, + {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}}; + +const size_t k_num_regsets = std::size(g_reg_sets); + +size_t RegisterContextDarwin_arm64::GetRegisterSetCount() { + return k_num_regsets; +} + +const RegisterSet *RegisterContextDarwin_arm64::GetRegisterSet(size_t reg_set) { + if (reg_set < k_num_regsets) + return &g_reg_sets[reg_set]; + return nullptr; +} + +// Register information definitions for arm64 +int RegisterContextDarwin_arm64::GetSetForNativeRegNum(int reg) { + if (reg < fpu_v0) + return GPRRegSet; + else if (reg < exc_far) + return FPURegSet; + else if (reg < k_num_registers) + return EXCRegSet; + return -1; +} + +int RegisterContextDarwin_arm64::ReadGPR(bool force) { + int set = GPRRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); + } + return GetError(GPRRegSet, Read); +} + +int RegisterContextDarwin_arm64::ReadFPU(bool force) { + int set = FPURegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); + } + return GetError(FPURegSet, Read); +} + +int RegisterContextDarwin_arm64::ReadEXC(bool force) { + int set = EXCRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); + } + return GetError(EXCRegSet, Read); +} + +int RegisterContextDarwin_arm64::ReadDBG(bool force) { + int set = DBGRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg)); + } + return GetError(DBGRegSet, Read); +} + +int RegisterContextDarwin_arm64::WriteGPR() { + int set = GPRRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return KERN_INVALID_ARGUMENT; + } + SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr)); + SetError(set, Read, -1); + return GetError(GPRRegSet, Write); +} + +int RegisterContextDarwin_arm64::WriteFPU() { + int set = FPURegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return KERN_INVALID_ARGUMENT; + } + SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu)); + SetError(set, Read, -1); + return GetError(FPURegSet, Write); +} + +int RegisterContextDarwin_arm64::WriteEXC() { + int set = EXCRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return KERN_INVALID_ARGUMENT; + } + SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc)); + SetError(set, Read, -1); + return GetError(EXCRegSet, Write); +} + +int RegisterContextDarwin_arm64::WriteDBG() { + int set = DBGRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return KERN_INVALID_ARGUMENT; + } + SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg)); + SetError(set, Read, -1); + return GetError(DBGRegSet, Write); +} + +int RegisterContextDarwin_arm64::ReadRegisterSet(uint32_t set, bool force) { + switch (set) { + case GPRRegSet: + return ReadGPR(force); + case FPURegSet: + return ReadFPU(force); + case EXCRegSet: + return ReadEXC(force); + case DBGRegSet: + return ReadDBG(force); + default: + break; + } + return KERN_INVALID_ARGUMENT; +} + +int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) { + // Make sure we have a valid context to set. + if (RegisterSetIsCached(set)) { + switch (set) { + case GPRRegSet: + return WriteGPR(); + case FPURegSet: + return WriteFPU(); + case EXCRegSet: + return WriteEXC(); + case DBGRegSet: + return WriteDBG(); + default: + break; + } + } + return KERN_INVALID_ARGUMENT; +} + +void RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) { + if (log) { + for (uint32_t i = 0; i < 16; i++) + LLDB_LOGF(log, + "BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 + " } WVR%-2u/WCR%-2u " + "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }", + i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]); + } +} + +bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info, + RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum(reg); + + if (set == -1) + return false; + + if (ReadRegisterSet(set, false) != KERN_SUCCESS) + return false; + + switch (reg) { + case gpr_x0: + case gpr_x1: + case gpr_x2: + case gpr_x3: + case gpr_x4: + case gpr_x5: + case gpr_x6: + case gpr_x7: + case gpr_x8: + case gpr_x9: + case gpr_x10: + case gpr_x11: + case gpr_x12: + case gpr_x13: + case gpr_x14: + case gpr_x15: + case gpr_x16: + case gpr_x17: + case gpr_x18: + case gpr_x19: + case gpr_x20: + case gpr_x21: + case gpr_x22: + case gpr_x23: + case gpr_x24: + case gpr_x25: + case gpr_x26: + case gpr_x27: + case gpr_x28: + value.SetUInt64(gpr.x[reg - gpr_x0]); + break; + case gpr_fp: + value.SetUInt64(gpr.fp); + break; + case gpr_sp: + value.SetUInt64(gpr.sp); + break; + case gpr_lr: + value.SetUInt64(gpr.lr); + break; + case gpr_pc: + value.SetUInt64(gpr.pc); + break; + case gpr_cpsr: + value.SetUInt64(gpr.cpsr); + break; + + case gpr_w0: + case gpr_w1: + case gpr_w2: + case gpr_w3: + case gpr_w4: + case gpr_w5: + case gpr_w6: + case gpr_w7: + case gpr_w8: + case gpr_w9: + case gpr_w10: + case gpr_w11: + case gpr_w12: + case gpr_w13: + case gpr_w14: + case gpr_w15: + case gpr_w16: + case gpr_w17: + case gpr_w18: + case gpr_w19: + case gpr_w20: + case gpr_w21: + case gpr_w22: + case gpr_w23: + case gpr_w24: + case gpr_w25: + case gpr_w26: + case gpr_w27: + case gpr_w28: { + ProcessSP process_sp(m_thread.GetProcess()); + if (process_sp.get()) { + DataExtractor regdata(&gpr.x[reg - gpr_w0], 8, process_sp->GetByteOrder(), + process_sp->GetAddressByteSize()); + offset_t offset = 0; + uint64_t retval = regdata.GetMaxU64(&offset, 8); + uint32_t retval_lower32 = static_cast<uint32_t>(retval & 0xffffffff); + value.SetUInt32(retval_lower32); + } + } break; + + case fpu_v0: + case fpu_v1: + case fpu_v2: + case fpu_v3: + case fpu_v4: + case fpu_v5: + case fpu_v6: + case fpu_v7: + case fpu_v8: + case fpu_v9: + case fpu_v10: + case fpu_v11: + case fpu_v12: + case fpu_v13: + case fpu_v14: + case fpu_v15: + case fpu_v16: + case fpu_v17: + case fpu_v18: + case fpu_v19: + case fpu_v20: + case fpu_v21: + case fpu_v22: + case fpu_v23: + case fpu_v24: + case fpu_v25: + case fpu_v26: + case fpu_v27: + case fpu_v28: + case fpu_v29: + case fpu_v30: + case fpu_v31: + value.SetBytes(fpu.v[reg - fpu_v0].bytes, reg_info->byte_size, + endian::InlHostByteOrder()); + break; + + case fpu_s0: + case fpu_s1: + case fpu_s2: + case fpu_s3: + case fpu_s4: + case fpu_s5: + case fpu_s6: + case fpu_s7: + case fpu_s8: + case fpu_s9: + case fpu_s10: + case fpu_s11: + case fpu_s12: + case fpu_s13: + case fpu_s14: + case fpu_s15: + case fpu_s16: + case fpu_s17: + case fpu_s18: + case fpu_s19: + case fpu_s20: + case fpu_s21: + case fpu_s22: + case fpu_s23: + case fpu_s24: + case fpu_s25: + case fpu_s26: + case fpu_s27: + case fpu_s28: + case fpu_s29: + case fpu_s30: + case fpu_s31: { + ProcessSP process_sp(m_thread.GetProcess()); + if (process_sp.get()) { + DataExtractor regdata(&fpu.v[reg - fpu_s0], 4, process_sp->GetByteOrder(), + process_sp->GetAddressByteSize()); + offset_t offset = 0; + value.SetFloat(regdata.GetFloat(&offset)); + } + } break; + + case fpu_d0: + case fpu_d1: + case fpu_d2: + case fpu_d3: + case fpu_d4: + case fpu_d5: + case fpu_d6: + case fpu_d7: + case fpu_d8: + case fpu_d9: + case fpu_d10: + case fpu_d11: + case fpu_d12: + case fpu_d13: + case fpu_d14: + case fpu_d15: + case fpu_d16: + case fpu_d17: + case fpu_d18: + case fpu_d19: + case fpu_d20: + case fpu_d21: + case fpu_d22: + case fpu_d23: + case fpu_d24: + case fpu_d25: + case fpu_d26: + case fpu_d27: + case fpu_d28: + case fpu_d29: + case fpu_d30: + case fpu_d31: { + ProcessSP process_sp(m_thread.GetProcess()); + if (process_sp.get()) { + DataExtractor regdata(&fpu.v[reg - fpu_d0], 8, process_sp->GetByteOrder(), + process_sp->GetAddressByteSize()); + offset_t offset = 0; + value.SetDouble(regdata.GetDouble(&offset)); + } + } break; + + case fpu_fpsr: + value.SetUInt32(fpu.fpsr); + break; + + case fpu_fpcr: + value.SetUInt32(fpu.fpcr); + break; + + case exc_exception: + value.SetUInt32(exc.exception); + break; + case exc_esr: + value.SetUInt32(exc.esr); + break; + case exc_far: + value.SetUInt64(exc.far); + break; + + default: + value.SetValueToInvalid(); + return false; + } + return true; +} + +bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info, + const RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + int set = GetSetForNativeRegNum(reg); + + if (set == -1) + return false; + + if (ReadRegisterSet(set, false) != KERN_SUCCESS) + return false; + + switch (reg) { + case gpr_x0: + case gpr_x1: + case gpr_x2: + case gpr_x3: + case gpr_x4: + case gpr_x5: + case gpr_x6: + case gpr_x7: + case gpr_x8: + case gpr_x9: + case gpr_x10: + case gpr_x11: + case gpr_x12: + case gpr_x13: + case gpr_x14: + case gpr_x15: + case gpr_x16: + case gpr_x17: + case gpr_x18: + case gpr_x19: + case gpr_x20: + case gpr_x21: + case gpr_x22: + case gpr_x23: + case gpr_x24: + case gpr_x25: + case gpr_x26: + case gpr_x27: + case gpr_x28: + case gpr_fp: + case gpr_sp: + case gpr_lr: + case gpr_pc: + case gpr_cpsr: + gpr.x[reg - gpr_x0] = value.GetAsUInt64(); + break; + + case fpu_v0: + case fpu_v1: + case fpu_v2: + case fpu_v3: + case fpu_v4: + case fpu_v5: + case fpu_v6: + case fpu_v7: + case fpu_v8: + case fpu_v9: + case fpu_v10: + case fpu_v11: + case fpu_v12: + case fpu_v13: + case fpu_v14: + case fpu_v15: + case fpu_v16: + case fpu_v17: + case fpu_v18: + case fpu_v19: + case fpu_v20: + case fpu_v21: + case fpu_v22: + case fpu_v23: + case fpu_v24: + case fpu_v25: + case fpu_v26: + case fpu_v27: + case fpu_v28: + case fpu_v29: + case fpu_v30: + case fpu_v31: + ::memcpy(fpu.v[reg - fpu_v0].bytes, value.GetBytes(), + value.GetByteSize()); + break; + + case fpu_fpsr: + fpu.fpsr = value.GetAsUInt32(); + break; + + case fpu_fpcr: + fpu.fpcr = value.GetAsUInt32(); + break; + + case exc_exception: + exc.exception = value.GetAsUInt32(); + break; + case exc_esr: + exc.esr = value.GetAsUInt32(); + break; + case exc_far: + exc.far = value.GetAsUInt64(); + break; + + default: + return false; + } + return WriteRegisterSet(set) == KERN_SUCCESS; +} + +bool RegisterContextDarwin_arm64::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { + data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); + if (ReadGPR(false) == KERN_SUCCESS && ReadFPU(false) == KERN_SUCCESS && + ReadEXC(false) == KERN_SUCCESS) { + uint8_t *dst = data_sp->GetBytes(); + ::memcpy(dst, &gpr, sizeof(gpr)); + dst += sizeof(gpr); + + ::memcpy(dst, &fpu, sizeof(fpu)); + dst += sizeof(gpr); + + ::memcpy(dst, &exc, sizeof(exc)); + return true; + } + return false; +} + +bool RegisterContextDarwin_arm64::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) { + const uint8_t *src = data_sp->GetBytes(); + ::memcpy(&gpr, src, sizeof(gpr)); + src += sizeof(gpr); + + ::memcpy(&fpu, src, sizeof(fpu)); + src += sizeof(gpr); + + ::memcpy(&exc, src, sizeof(exc)); + uint32_t success_count = 0; + if (WriteGPR() == KERN_SUCCESS) + ++success_count; + if (WriteFPU() == KERN_SUCCESS) + ++success_count; + if (WriteEXC() == KERN_SUCCESS) + ++success_count; + return success_count == 3; + } + return false; +} + +uint32_t RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber( + RegisterKind kind, uint32_t reg) { + if (kind == eRegisterKindGeneric) { + switch (reg) { + case LLDB_REGNUM_GENERIC_PC: + return gpr_pc; + case LLDB_REGNUM_GENERIC_SP: + return gpr_sp; + case LLDB_REGNUM_GENERIC_FP: + return gpr_fp; + case LLDB_REGNUM_GENERIC_RA: + return gpr_lr; + case LLDB_REGNUM_GENERIC_FLAGS: + return gpr_cpsr; + default: + break; + } + } else if (kind == eRegisterKindDWARF) { + switch (reg) { + case arm64_dwarf::x0: + return gpr_x0; + case arm64_dwarf::x1: + return gpr_x1; + case arm64_dwarf::x2: + return gpr_x2; + case arm64_dwarf::x3: + return gpr_x3; + case arm64_dwarf::x4: + return gpr_x4; + case arm64_dwarf::x5: + return gpr_x5; + case arm64_dwarf::x6: + return gpr_x6; + case arm64_dwarf::x7: + return gpr_x7; + case arm64_dwarf::x8: + return gpr_x8; + case arm64_dwarf::x9: + return gpr_x9; + case arm64_dwarf::x10: + return gpr_x10; + case arm64_dwarf::x11: + return gpr_x11; + case arm64_dwarf::x12: + return gpr_x12; + case arm64_dwarf::x13: + return gpr_x13; + case arm64_dwarf::x14: + return gpr_x14; + case arm64_dwarf::x15: + return gpr_x15; + case arm64_dwarf::x16: + return gpr_x16; + case arm64_dwarf::x17: + return gpr_x17; + case arm64_dwarf::x18: + return gpr_x18; + case arm64_dwarf::x19: + return gpr_x19; + case arm64_dwarf::x20: + return gpr_x20; + case arm64_dwarf::x21: + return gpr_x21; + case arm64_dwarf::x22: + return gpr_x22; + case arm64_dwarf::x23: + return gpr_x23; + case arm64_dwarf::x24: + return gpr_x24; + case arm64_dwarf::x25: + return gpr_x25; + case arm64_dwarf::x26: + return gpr_x26; + case arm64_dwarf::x27: + return gpr_x27; + case arm64_dwarf::x28: + return gpr_x28; + + case arm64_dwarf::fp: + return gpr_fp; + case arm64_dwarf::sp: + return gpr_sp; + case arm64_dwarf::lr: + return gpr_lr; + case arm64_dwarf::pc: + return gpr_pc; + case arm64_dwarf::cpsr: + return gpr_cpsr; + + case arm64_dwarf::v0: + return fpu_v0; + case arm64_dwarf::v1: + return fpu_v1; + case arm64_dwarf::v2: + return fpu_v2; + case arm64_dwarf::v3: + return fpu_v3; + case arm64_dwarf::v4: + return fpu_v4; + case arm64_dwarf::v5: + return fpu_v5; + case arm64_dwarf::v6: + return fpu_v6; + case arm64_dwarf::v7: + return fpu_v7; + case arm64_dwarf::v8: + return fpu_v8; + case arm64_dwarf::v9: + return fpu_v9; + case arm64_dwarf::v10: + return fpu_v10; + case arm64_dwarf::v11: + return fpu_v11; + case arm64_dwarf::v12: + return fpu_v12; + case arm64_dwarf::v13: + return fpu_v13; + case arm64_dwarf::v14: + return fpu_v14; + case arm64_dwarf::v15: + return fpu_v15; + case arm64_dwarf::v16: + return fpu_v16; + case arm64_dwarf::v17: + return fpu_v17; + case arm64_dwarf::v18: + return fpu_v18; + case arm64_dwarf::v19: + return fpu_v19; + case arm64_dwarf::v20: + return fpu_v20; + case arm64_dwarf::v21: + return fpu_v21; + case arm64_dwarf::v22: + return fpu_v22; + case arm64_dwarf::v23: + return fpu_v23; + case arm64_dwarf::v24: + return fpu_v24; + case arm64_dwarf::v25: + return fpu_v25; + case arm64_dwarf::v26: + return fpu_v26; + case arm64_dwarf::v27: + return fpu_v27; + case arm64_dwarf::v28: + return fpu_v28; + case arm64_dwarf::v29: + return fpu_v29; + case arm64_dwarf::v30: + return fpu_v30; + case arm64_dwarf::v31: + return fpu_v31; + + default: + break; + } + } else if (kind == eRegisterKindEHFrame) { + switch (reg) { + case arm64_ehframe::x0: + return gpr_x0; + case arm64_ehframe::x1: + return gpr_x1; + case arm64_ehframe::x2: + return gpr_x2; + case arm64_ehframe::x3: + return gpr_x3; + case arm64_ehframe::x4: + return gpr_x4; + case arm64_ehframe::x5: + return gpr_x5; + case arm64_ehframe::x6: + return gpr_x6; + case arm64_ehframe::x7: + return gpr_x7; + case arm64_ehframe::x8: + return gpr_x8; + case arm64_ehframe::x9: + return gpr_x9; + case arm64_ehframe::x10: + return gpr_x10; + case arm64_ehframe::x11: + return gpr_x11; + case arm64_ehframe::x12: + return gpr_x12; + case arm64_ehframe::x13: + return gpr_x13; + case arm64_ehframe::x14: + return gpr_x14; + case arm64_ehframe::x15: + return gpr_x15; + case arm64_ehframe::x16: + return gpr_x16; + case arm64_ehframe::x17: + return gpr_x17; + case arm64_ehframe::x18: + return gpr_x18; + case arm64_ehframe::x19: + return gpr_x19; + case arm64_ehframe::x20: + return gpr_x20; + case arm64_ehframe::x21: + return gpr_x21; + case arm64_ehframe::x22: + return gpr_x22; + case arm64_ehframe::x23: + return gpr_x23; + case arm64_ehframe::x24: + return gpr_x24; + case arm64_ehframe::x25: + return gpr_x25; + case arm64_ehframe::x26: + return gpr_x26; + case arm64_ehframe::x27: + return gpr_x27; + case arm64_ehframe::x28: + return gpr_x28; + case arm64_ehframe::fp: + return gpr_fp; + case arm64_ehframe::sp: + return gpr_sp; + case arm64_ehframe::lr: + return gpr_lr; + case arm64_ehframe::pc: + return gpr_pc; + case arm64_ehframe::cpsr: + return gpr_cpsr; + } + } else if (kind == eRegisterKindLLDB) { + return reg; + } + return LLDB_INVALID_REGNUM; +} + +uint32_t RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints() { +#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) + // autodetect how many watchpoints are supported dynamically... + static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX; + if (g_num_supported_hw_watchpoints == UINT32_MAX) { + size_t len; + uint32_t n = 0; + len = sizeof(n); + if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) { + g_num_supported_hw_watchpoints = n; + } + } + return g_num_supported_hw_watchpoints; +#else + // TODO: figure out remote case here! + return 2; +#endif +} + +uint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr, + size_t size, + bool read, + bool write) { + // if (log) log->Printf + // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, + // size = %u, read = %u, write = %u)", addr, size, read, write); + + const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); + + // Can't watch zero bytes + if (size == 0) + return LLDB_INVALID_INDEX32; + + // We must watch for either read or write + if (!read && !write) + return LLDB_INVALID_INDEX32; + + // Can't watch more than 4 bytes per WVR/WCR pair + if (size > 4) + return LLDB_INVALID_INDEX32; + + // We can only watch up to four bytes that follow a 4 byte aligned address + // per watchpoint register pair. Since we have at most so we can only watch + // until the next 4 byte boundary and we need to make sure we can properly + // encode this. + uint32_t addr_word_offset = addr % 4; + // if (log) log->Printf + // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - + // addr_word_offset = 0x%8.8x", addr_word_offset); + + uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; + // if (log) log->Printf + // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = + // 0x%8.8x", byte_mask); + if (byte_mask > 0xfu) + return LLDB_INVALID_INDEX32; + + // Read the debug state + int kret = ReadDBG(false); + + if (kret == KERN_SUCCESS) { + // Check to make sure we have the needed hardware support + uint32_t i = 0; + + for (i = 0; i < num_hw_watchpoints; ++i) { + if ((dbg.wcr[i] & WCR_ENABLE) == 0) + break; // We found an available hw breakpoint slot (in i) + } + + // See if we found an available hw breakpoint slot above + if (i < num_hw_watchpoints) { + // Make the byte_mask into a valid Byte Address Select mask + uint32_t byte_address_select = byte_mask << 5; + // Make sure bits 1:0 are clear in our address + dbg.wvr[i] = addr & ~((lldb::addr_t)3); + dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA + // that we will watch + S_USER | // Stop only in user mode + (read ? WCR_LOAD : 0) | // Stop on read access? + (write ? WCR_STORE : 0) | // Stop on write access? + WCR_ENABLE; // Enable this watchpoint; + + kret = WriteDBG(); + // if (log) log->Printf + // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() + // WriteDBG() => 0x%8.8x.", kret); + + if (kret == KERN_SUCCESS) + return i; + } else { + // if (log) log->Printf + // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): + // All hardware resources (%u) are in use.", + // num_hw_watchpoints); + } + } + return LLDB_INVALID_INDEX32; +} + +bool RegisterContextDarwin_arm64::ClearHardwareWatchpoint(uint32_t hw_index) { + int kret = ReadDBG(false); + + const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); + if (kret == KERN_SUCCESS) { + if (hw_index < num_hw_points) { + dbg.wcr[hw_index] = 0; + // if (log) log->Printf + // ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) + // - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", + // hw_index, + // hw_index, + // dbg.wvr[hw_index], + // hw_index, + // dbg.wcr[hw_index]); + + kret = WriteDBG(); + + if (kret == KERN_SUCCESS) + return true; + } + } + return false; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h new file mode 100644 index 000000000000..a0d7821ae9e8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h @@ -0,0 +1,231 @@ +//===-- RegisterContextDarwin_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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H + +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +// Break only in privileged or user mode +#define S_RSVD ((uint32_t)(0u << 1)) +#define S_PRIV ((uint32_t)(1u << 1)) +#define S_USER ((uint32_t)(2u << 1)) +#define S_PRIV_USER ((S_PRIV) | (S_USER)) + +#define WCR_ENABLE ((uint32_t)(1u)) + +// Watchpoint load/store +#define WCR_LOAD ((uint32_t)(1u << 3)) +#define WCR_STORE ((uint32_t)(1u << 4)) + +class RegisterContextDarwin_arm64 : public lldb_private::RegisterContext { +public: + RegisterContextDarwin_arm64(lldb_private::Thread &thread, + uint32_t concrete_frame_idx); + + ~RegisterContextDarwin_arm64() override; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue ®_value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue ®_value) override; + + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, + bool write) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + // mirrors <mach/arm/thread_status.h> arm_thread_state64_t + struct GPR { + uint64_t x[29]; // x0-x28 + uint64_t fp; // x29 + uint64_t lr; // x30 + uint64_t sp; // x31 + uint64_t pc; // pc + uint32_t cpsr; // cpsr + }; + + struct VReg { + alignas(16) char bytes[16]; + }; + + // mirrors <mach/arm/thread_status.h> arm_neon_state64_t + struct FPU { + VReg v[32]; + uint32_t fpsr; + uint32_t fpcr; + }; + + // mirrors <mach/arm/thread_status.h> arm_exception_state64_t + struct EXC { + uint64_t far; // Virtual Fault Address + uint32_t esr; // Exception syndrome + uint32_t exception; // number of arm exception token + }; + + // mirrors <mach/arm/thread_status.h> arm_debug_state64_t + struct DBG { + uint64_t bvr[16]; + uint64_t bcr[16]; + uint64_t wvr[16]; + uint64_t wcr[16]; + uint64_t mdscr_el1; + }; + + static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg); + +protected: + enum { + GPRRegSet = 6, // ARM_THREAD_STATE64 + FPURegSet = 17, // ARM_NEON_STATE64 + EXCRegSet = 7, // ARM_EXCEPTION_STATE64 + DBGRegSet = 15 // ARM_DEBUG_STATE64 + }; + + enum { + GPRWordCount = sizeof(GPR) / sizeof(uint32_t), // ARM_THREAD_STATE64_COUNT + FPUWordCount = sizeof(FPU) / sizeof(uint32_t), // ARM_NEON_STATE64_COUNT + EXCWordCount = + sizeof(EXC) / sizeof(uint32_t), // ARM_EXCEPTION_STATE64_COUNT + DBGWordCount = sizeof(DBG) / sizeof(uint32_t) // ARM_DEBUG_STATE64_COUNT + }; + + enum { Read = 0, Write = 1, kNumErrors = 2 }; + + GPR gpr; + FPU fpu; + EXC exc; + DBG dbg; + int gpr_errs[2]; // Read/Write errors + int fpu_errs[2]; // Read/Write errors + int exc_errs[2]; // Read/Write errors + int dbg_errs[2]; // Read/Write errors + + void InvalidateAllRegisterStates() { + SetError(GPRRegSet, Read, -1); + SetError(FPURegSet, Read, -1); + SetError(EXCRegSet, Read, -1); + } + + int GetError(int flavor, uint32_t err_idx) const { + if (err_idx < kNumErrors) { + switch (flavor) { + // When getting all errors, just OR all values together to see if + // we got any kind of error. + case GPRRegSet: + return gpr_errs[err_idx]; + case FPURegSet: + return fpu_errs[err_idx]; + case EXCRegSet: + return exc_errs[err_idx]; + case DBGRegSet: + return dbg_errs[err_idx]; + default: + break; + } + } + return -1; + } + + bool SetError(int flavor, uint32_t err_idx, int err) { + if (err_idx < kNumErrors) { + switch (flavor) { + case GPRRegSet: + gpr_errs[err_idx] = err; + return true; + + case FPURegSet: + fpu_errs[err_idx] = err; + return true; + + case EXCRegSet: + exc_errs[err_idx] = err; + return true; + + case DBGRegSet: + exc_errs[err_idx] = err; + return true; + + default: + break; + } + } + return false; + } + + bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; } + + int ReadGPR(bool force); + + int ReadFPU(bool force); + + int ReadEXC(bool force); + + int ReadDBG(bool force); + + int WriteGPR(); + + int WriteFPU(); + + int WriteEXC(); + + int WriteDBG(); + + // Subclasses override these to do the actual reading. + virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; } + + virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; + + virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; + + virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0; + + virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; + + virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; + + virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; + + virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0; + + int ReadRegisterSet(uint32_t set, bool force); + + int WriteRegisterSet(uint32_t set); + + static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); + + static int GetSetForNativeRegNum(int reg_num); + + static size_t GetRegisterInfosCount(); + + static const lldb_private::RegisterInfo *GetRegisterInfos(); +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp new file mode 100644 index 000000000000..bae34af43a92 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -0,0 +1,963 @@ +//===-- RegisterContextDarwin_i386.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 "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Compiler.h" + +#include <cstddef> + +#include <memory> + +#include "RegisterContextDarwin_i386.h" + +using namespace lldb; +using namespace lldb_private; + +enum { + gpr_eax = 0, + gpr_ebx, + gpr_ecx, + gpr_edx, + gpr_edi, + gpr_esi, + gpr_ebp, + gpr_esp, + gpr_ss, + gpr_eflags, + gpr_eip, + gpr_cs, + gpr_ds, + gpr_es, + gpr_fs, + gpr_gs, + + fpu_fcw, + fpu_fsw, + fpu_ftw, + fpu_fop, + fpu_ip, + fpu_cs, + fpu_dp, + fpu_ds, + fpu_mxcsr, + fpu_mxcsrmask, + fpu_stmm0, + fpu_stmm1, + fpu_stmm2, + fpu_stmm3, + fpu_stmm4, + fpu_stmm5, + fpu_stmm6, + fpu_stmm7, + fpu_xmm0, + fpu_xmm1, + fpu_xmm2, + fpu_xmm3, + fpu_xmm4, + fpu_xmm5, + fpu_xmm6, + fpu_xmm7, + + exc_trapno, + exc_err, + exc_faultvaddr, + + k_num_registers, + + // Aliases + fpu_fctrl = fpu_fcw, + fpu_fstat = fpu_fsw, + fpu_ftag = fpu_ftw, + fpu_fiseg = fpu_cs, + fpu_fioff = fpu_ip, + fpu_foseg = fpu_ds, + fpu_fooff = fpu_dp +}; + +enum { + ehframe_eax = 0, + ehframe_ecx, + ehframe_edx, + ehframe_ebx, + ehframe_ebp, + ehframe_esp, + ehframe_esi, + ehframe_edi, + ehframe_eip, + ehframe_eflags +}; + +enum { + dwarf_eax = 0, + dwarf_ecx, + dwarf_edx, + dwarf_ebx, + dwarf_esp, + dwarf_ebp, + dwarf_esi, + dwarf_edi, + dwarf_eip, + dwarf_eflags, + dwarf_stmm0 = 11, + dwarf_stmm1, + dwarf_stmm2, + dwarf_stmm3, + dwarf_stmm4, + dwarf_stmm5, + dwarf_stmm6, + dwarf_stmm7, + dwarf_xmm0 = 21, + dwarf_xmm1, + dwarf_xmm2, + dwarf_xmm3, + dwarf_xmm4, + dwarf_xmm5, + dwarf_xmm6, + dwarf_xmm7 +}; + +#define GPR_OFFSET(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::GPR, reg)) +#define FPU_OFFSET(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::FPU, reg) + \ + sizeof(RegisterContextDarwin_i386::GPR)) +#define EXC_OFFSET(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::EXC, reg) + \ + sizeof(RegisterContextDarwin_i386::GPR) + \ + sizeof(RegisterContextDarwin_i386::FPU)) + +// These macros will auto define the register name, alt name, register size, +// register offset, encoding, format and native register. This ensures that the +// register state structures are defined correctly and have the correct sizes +// and offsets. +#define DEFINE_GPR(reg, alt) \ + #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *) NULL)->reg), \ + GPR_OFFSET(reg), eEncodingUint, eFormatHex +#define DEFINE_FPU_UINT(reg) \ + #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg), \ + FPU_OFFSET(reg), eEncodingUint, eFormatHex +#define DEFINE_FPU_VECT(reg, i) \ + #reg #i, NULL, \ + sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg[i].bytes), \ + FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, dwarf_##reg##i, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + fpu_##reg##i }, \ + nullptr, nullptr, nullptr, + +#define DEFINE_EXC(reg) \ + #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg), \ + EXC_OFFSET(reg), eEncodingUint, eFormatHex +#define REG_CONTEXT_SIZE \ + (sizeof(RegisterContextDarwin_i386::GPR) + \ + sizeof(RegisterContextDarwin_i386::FPU) + \ + sizeof(RegisterContextDarwin_i386::EXC)) + +static RegisterInfo g_register_infos[] = { + // Macro auto defines most stuff eh_frame DWARF + // GENERIC PROCESS PLUGIN LLDB + // =============================== ======================= + // =================== ========================= ================== + // ================= + {DEFINE_GPR(eax, nullptr), + {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_eax}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(ebx, nullptr), + {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_ebx}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(ecx, nullptr), + {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_ecx}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(edx, nullptr), + {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_edx}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(edi, nullptr), + {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_edi}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(esi, nullptr), + {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_esi}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(ebp, "fp"), + {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + gpr_ebp}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(esp, "sp"), + {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + gpr_esp}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(ss, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_ss}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(eflags, "flags"), + {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS, + LLDB_INVALID_REGNUM, gpr_eflags}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(eip, "pc"), + {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + gpr_eip}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(cs, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_cs}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(ds, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_ds}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(es, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_es}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(fs, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_fs}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(gs, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_gs}, + nullptr, + nullptr, + nullptr, + }, + + {DEFINE_FPU_UINT(fcw), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fcw}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(fsw), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fsw}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(ftw), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_ftw}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(fop), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fop}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(ip), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_ip}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(cs), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_cs}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(dp), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_dp}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(ds), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_ds}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(mxcsr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_mxcsr}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(mxcsrmask), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_mxcsrmask}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_VECT(stmm, 0)}, + {DEFINE_FPU_VECT(stmm, 1)}, + {DEFINE_FPU_VECT(stmm, 2)}, + {DEFINE_FPU_VECT(stmm, 3)}, + {DEFINE_FPU_VECT(stmm, 4)}, + {DEFINE_FPU_VECT(stmm, 5)}, + {DEFINE_FPU_VECT(stmm, 6)}, + {DEFINE_FPU_VECT(stmm, 7)}, + {DEFINE_FPU_VECT(xmm, 0)}, + {DEFINE_FPU_VECT(xmm, 1)}, + {DEFINE_FPU_VECT(xmm, 2)}, + {DEFINE_FPU_VECT(xmm, 3)}, + {DEFINE_FPU_VECT(xmm, 4)}, + {DEFINE_FPU_VECT(xmm, 5)}, + {DEFINE_FPU_VECT(xmm, 6)}, + {DEFINE_FPU_VECT(xmm, 7)}, + + {DEFINE_EXC(trapno), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_trapno}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_EXC(err), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_err}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_EXC(faultvaddr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_faultvaddr}, + nullptr, + nullptr, + nullptr, + }}; + +static size_t k_num_register_infos = std::size(g_register_infos); + +RegisterContextDarwin_i386::RegisterContextDarwin_i386( + Thread &thread, uint32_t concrete_frame_idx) + : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() { + uint32_t i; + for (i = 0; i < kNumErrors; i++) { + gpr_errs[i] = -1; + fpu_errs[i] = -1; + exc_errs[i] = -1; + } +} + +RegisterContextDarwin_i386::~RegisterContextDarwin_i386() = default; + +void RegisterContextDarwin_i386::InvalidateAllRegisters() { + InvalidateAllRegisterStates(); +} + +size_t RegisterContextDarwin_i386::GetRegisterCount() { + assert(k_num_register_infos == k_num_registers); + return k_num_registers; +} + +const RegisterInfo * +RegisterContextDarwin_i386::GetRegisterInfoAtIndex(size_t reg) { + assert(k_num_register_infos == k_num_registers); + if (reg < k_num_registers) + return &g_register_infos[reg]; + return nullptr; +} + +size_t RegisterContextDarwin_i386::GetRegisterInfosCount() { + return k_num_register_infos; +} + +const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() { + return g_register_infos; +} + +// General purpose registers +static uint32_t g_gpr_regnums[] = { + gpr_eax, gpr_ebx, gpr_ecx, gpr_edx, gpr_edi, gpr_esi, gpr_ebp, gpr_esp, + gpr_ss, gpr_eflags, gpr_eip, gpr_cs, gpr_ds, gpr_es, gpr_fs, gpr_gs}; + +// Floating point registers +static uint32_t g_fpu_regnums[] = { + fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs, + fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1, + fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7, + fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5, + fpu_xmm6, fpu_xmm7}; + +// Exception registers + +static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr}; + +// Number of registers in each register set +const size_t k_num_gpr_registers = std::size(g_gpr_regnums); +const size_t k_num_fpu_registers = std::size(g_fpu_regnums); +const size_t k_num_exc_registers = std::size(g_exc_regnums); + +// Register set definitions. The first definitions at register set index of +// zero is for all registers, followed by other registers sets. The register +// information for the all register set need not be filled in. +static const RegisterSet g_reg_sets[] = { + { + "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, + }, + {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums}, + {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}}; + +const size_t k_num_regsets = std::size(g_reg_sets); + +size_t RegisterContextDarwin_i386::GetRegisterSetCount() { + return k_num_regsets; +} + +const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) { + if (reg_set < k_num_regsets) + return &g_reg_sets[reg_set]; + return nullptr; +} + +// Register information definitions for 32 bit i386. +int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) { + if (reg_num < fpu_fcw) + return GPRRegSet; + else if (reg_num < exc_trapno) + return FPURegSet; + else if (reg_num < k_num_registers) + return EXCRegSet; + return -1; +} + +void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) { + if (log) { + if (title) + LLDB_LOGF(log, "%s", title); + for (uint32_t i = 0; i < k_num_gpr_registers; i++) { + uint32_t reg = gpr_eax + i; + LLDB_LOGF(log, "%12s = 0x%8.8x", g_register_infos[reg].name, + (&gpr.eax)[reg]); + } + } +} + +int RegisterContextDarwin_i386::ReadGPR(bool force) { + int set = GPRRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); + } + return GetError(set, Read); +} + +int RegisterContextDarwin_i386::ReadFPU(bool force) { + int set = FPURegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); + } + return GetError(set, Read); +} + +int RegisterContextDarwin_i386::ReadEXC(bool force) { + int set = EXCRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); + } + return GetError(set, Read); +} + +int RegisterContextDarwin_i386::WriteGPR() { + int set = GPRRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return -1; + } + SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr)); + SetError(set, Read, -1); + return GetError(set, Write); +} + +int RegisterContextDarwin_i386::WriteFPU() { + int set = FPURegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return -1; + } + SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu)); + SetError(set, Read, -1); + return GetError(set, Write); +} + +int RegisterContextDarwin_i386::WriteEXC() { + int set = EXCRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return -1; + } + SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc)); + SetError(set, Read, -1); + return GetError(set, Write); +} + +int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) { + switch (set) { + case GPRRegSet: + return ReadGPR(force); + case FPURegSet: + return ReadFPU(force); + case EXCRegSet: + return ReadEXC(force); + default: + break; + } + return -1; +} + +int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) { + // Make sure we have a valid context to set. + if (RegisterSetIsCached(set)) { + switch (set) { + case GPRRegSet: + return WriteGPR(); + case FPURegSet: + return WriteFPU(); + case EXCRegSet: + return WriteEXC(); + default: + break; + } + } + return -1; +} + +bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info, + RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + int set = RegisterContextDarwin_i386::GetSetForNativeRegNum(reg); + + if (set == -1) + return false; + + if (ReadRegisterSet(set, false) != 0) + return false; + + switch (reg) { + case gpr_eax: + case gpr_ebx: + case gpr_ecx: + case gpr_edx: + case gpr_edi: + case gpr_esi: + case gpr_ebp: + case gpr_esp: + case gpr_ss: + case gpr_eflags: + case gpr_eip: + case gpr_cs: + case gpr_ds: + case gpr_es: + case gpr_fs: + case gpr_gs: + value = (&gpr.eax)[reg - gpr_eax]; + break; + + case fpu_fcw: + value = fpu.fcw; + break; + + case fpu_fsw: + value = fpu.fsw; + break; + + case fpu_ftw: + value = fpu.ftw; + break; + + case fpu_fop: + value = fpu.fop; + break; + + case fpu_ip: + value = fpu.ip; + break; + + case fpu_cs: + value = fpu.cs; + break; + + case fpu_dp: + value = fpu.dp; + break; + + case fpu_ds: + value = fpu.ds; + break; + + case fpu_mxcsr: + value = fpu.mxcsr; + break; + + case fpu_mxcsrmask: + value = fpu.mxcsrmask; + break; + + case fpu_stmm0: + case fpu_stmm1: + case fpu_stmm2: + case fpu_stmm3: + case fpu_stmm4: + case fpu_stmm5: + case fpu_stmm6: + case fpu_stmm7: + // These values don't fit into scalar types, + // RegisterContext::ReadRegisterBytes() must be used for these registers + //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes, + //10); + return false; + + case fpu_xmm0: + case fpu_xmm1: + case fpu_xmm2: + case fpu_xmm3: + case fpu_xmm4: + case fpu_xmm5: + case fpu_xmm6: + case fpu_xmm7: + // These values don't fit into scalar types, + // RegisterContext::ReadRegisterBytes() must be used for these registers + //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes, + //16); + return false; + + case exc_trapno: + value = exc.trapno; + break; + + case exc_err: + value = exc.err; + break; + + case exc_faultvaddr: + value = exc.faultvaddr; + break; + + default: + return false; + } + return true; +} + +bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info, + const RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + int set = GetSetForNativeRegNum(reg); + + if (set == -1) + return false; + + if (ReadRegisterSet(set, false) != 0) + return false; + + switch (reg) { + case gpr_eax: + case gpr_ebx: + case gpr_ecx: + case gpr_edx: + case gpr_edi: + case gpr_esi: + case gpr_ebp: + case gpr_esp: + case gpr_ss: + case gpr_eflags: + case gpr_eip: + case gpr_cs: + case gpr_ds: + case gpr_es: + case gpr_fs: + case gpr_gs: + (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32(); + break; + + case fpu_fcw: + fpu.fcw = value.GetAsUInt16(); + break; + + case fpu_fsw: + fpu.fsw = value.GetAsUInt16(); + break; + + case fpu_ftw: + fpu.ftw = value.GetAsUInt8(); + break; + + case fpu_fop: + fpu.fop = value.GetAsUInt16(); + break; + + case fpu_ip: + fpu.ip = value.GetAsUInt32(); + break; + + case fpu_cs: + fpu.cs = value.GetAsUInt16(); + break; + + case fpu_dp: + fpu.dp = value.GetAsUInt32(); + break; + + case fpu_ds: + fpu.ds = value.GetAsUInt16(); + break; + + case fpu_mxcsr: + fpu.mxcsr = value.GetAsUInt32(); + break; + + case fpu_mxcsrmask: + fpu.mxcsrmask = value.GetAsUInt32(); + break; + + case fpu_stmm0: + case fpu_stmm1: + case fpu_stmm2: + case fpu_stmm3: + case fpu_stmm4: + case fpu_stmm5: + case fpu_stmm6: + case fpu_stmm7: + // These values don't fit into scalar types, + // RegisterContext::ReadRegisterBytes() must be used for these registers + ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), + value.GetByteSize()); + return false; + + case fpu_xmm0: + case fpu_xmm1: + case fpu_xmm2: + case fpu_xmm3: + case fpu_xmm4: + case fpu_xmm5: + case fpu_xmm6: + case fpu_xmm7: + // These values don't fit into scalar types, + // RegisterContext::ReadRegisterBytes() must be used for these registers + ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), + value.GetByteSize()); + return false; + + case exc_trapno: + exc.trapno = value.GetAsUInt32(); + break; + + case exc_err: + exc.err = value.GetAsUInt32(); + break; + + case exc_faultvaddr: + exc.faultvaddr = value.GetAsUInt32(); + break; + + default: + return false; + } + return WriteRegisterSet(set) == 0; +} + +bool RegisterContextDarwin_i386::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { + data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); + if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) { + uint8_t *dst = data_sp->GetBytes(); + ::memcpy(dst, &gpr, sizeof(gpr)); + dst += sizeof(gpr); + + ::memcpy(dst, &fpu, sizeof(fpu)); + dst += sizeof(gpr); + + ::memcpy(dst, &exc, sizeof(exc)); + return true; + } + return false; +} + +bool RegisterContextDarwin_i386::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) { + const uint8_t *src = data_sp->GetBytes(); + ::memcpy(&gpr, src, sizeof(gpr)); + src += sizeof(gpr); + + ::memcpy(&fpu, src, sizeof(fpu)); + src += sizeof(gpr); + + ::memcpy(&exc, src, sizeof(exc)); + uint32_t success_count = 0; + if (WriteGPR() == 0) + ++success_count; + if (WriteFPU() == 0) + ++success_count; + if (WriteEXC() == 0) + ++success_count; + return success_count == 3; + } + return false; +} + +uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t reg) { + if (kind == eRegisterKindGeneric) { + switch (reg) { + case LLDB_REGNUM_GENERIC_PC: + return gpr_eip; + case LLDB_REGNUM_GENERIC_SP: + return gpr_esp; + case LLDB_REGNUM_GENERIC_FP: + return gpr_ebp; + case LLDB_REGNUM_GENERIC_FLAGS: + return gpr_eflags; + case LLDB_REGNUM_GENERIC_RA: + default: + break; + } + } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) { + switch (reg) { + case dwarf_eax: + return gpr_eax; + case dwarf_ecx: + return gpr_ecx; + case dwarf_edx: + return gpr_edx; + case dwarf_ebx: + return gpr_ebx; + case dwarf_esp: + return gpr_esp; + case dwarf_ebp: + return gpr_ebp; + case dwarf_esi: + return gpr_esi; + case dwarf_edi: + return gpr_edi; + case dwarf_eip: + return gpr_eip; + case dwarf_eflags: + return gpr_eflags; + case dwarf_stmm0: + return fpu_stmm0; + case dwarf_stmm1: + return fpu_stmm1; + case dwarf_stmm2: + return fpu_stmm2; + case dwarf_stmm3: + return fpu_stmm3; + case dwarf_stmm4: + return fpu_stmm4; + case dwarf_stmm5: + return fpu_stmm5; + case dwarf_stmm6: + return fpu_stmm6; + case dwarf_stmm7: + return fpu_stmm7; + case dwarf_xmm0: + return fpu_xmm0; + case dwarf_xmm1: + return fpu_xmm1; + case dwarf_xmm2: + return fpu_xmm2; + case dwarf_xmm3: + return fpu_xmm3; + case dwarf_xmm4: + return fpu_xmm4; + case dwarf_xmm5: + return fpu_xmm5; + case dwarf_xmm6: + return fpu_xmm6; + case dwarf_xmm7: + return fpu_xmm7; + default: + break; + } + } else if (kind == eRegisterKindLLDB) { + return reg; + } + return LLDB_INVALID_REGNUM; +} + +bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) { + if (ReadGPR(false) != 0) + return false; + + const uint32_t trace_bit = 0x100u; + if (enable) { + // If the trace bit is already set, there is nothing to do + if (gpr.eflags & trace_bit) + return true; + else + gpr.eflags |= trace_bit; + } else { + // If the trace bit is already cleared, there is nothing to do + if (gpr.eflags & trace_bit) + gpr.eflags &= ~trace_bit; + else + return true; + } + + return WriteGPR() == 0; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h new file mode 100644 index 000000000000..be933f3be266 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h @@ -0,0 +1,208 @@ +//===-- RegisterContextDarwin_i386.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_REGISTERCONTEXTDARWIN_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H + +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +class RegisterContextDarwin_i386 : public lldb_private::RegisterContext { +public: + RegisterContextDarwin_i386(lldb_private::Thread &thread, + uint32_t concrete_frame_idx); + + ~RegisterContextDarwin_i386() override; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) override; + + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + bool HardwareSingleStep(bool enable) override; + + struct GPR { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t esp; + uint32_t ss; + uint32_t eflags; + uint32_t eip; + uint32_t cs; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t gs; + }; + + struct MMSReg { + uint8_t bytes[10]; + uint8_t pad[6]; + }; + + struct XMMReg { + uint8_t bytes[16]; + }; + + struct FPU { + uint32_t pad[2]; + uint16_t fcw; + uint16_t fsw; + uint8_t ftw; + uint8_t pad1; + uint16_t fop; + uint32_t ip; + uint16_t cs; + uint16_t pad2; + uint32_t dp; + uint16_t ds; + uint16_t pad3; + uint32_t mxcsr; + uint32_t mxcsrmask; + MMSReg stmm[8]; + XMMReg xmm[8]; + uint8_t pad4[14 * 16]; + int pad5; + }; + + struct EXC { + uint32_t trapno; + uint32_t err; + uint32_t faultvaddr; + }; + +protected: + enum { GPRRegSet = 1, FPURegSet = 2, EXCRegSet = 3 }; + + enum { + GPRWordCount = sizeof(GPR) / sizeof(uint32_t), + FPUWordCount = sizeof(FPU) / sizeof(uint32_t), + EXCWordCount = sizeof(EXC) / sizeof(uint32_t) + }; + + enum { Read = 0, Write = 1, kNumErrors = 2 }; + + GPR gpr; + FPU fpu; + EXC exc; + int gpr_errs[2]; // Read/Write errors + int fpu_errs[2]; // Read/Write errors + int exc_errs[2]; // Read/Write errors + + void InvalidateAllRegisterStates() { + SetError(GPRRegSet, Read, -1); + SetError(FPURegSet, Read, -1); + SetError(EXCRegSet, Read, -1); + } + + int GetError(int flavor, uint32_t err_idx) const { + if (err_idx < kNumErrors) { + switch (flavor) { + // When getting all errors, just OR all values together to see if + // we got any kind of error. + case GPRRegSet: + return gpr_errs[err_idx]; + case FPURegSet: + return fpu_errs[err_idx]; + case EXCRegSet: + return exc_errs[err_idx]; + default: + break; + } + } + return -1; + } + + bool SetError(int flavor, uint32_t err_idx, int err) { + if (err_idx < kNumErrors) { + switch (flavor) { + case GPRRegSet: + gpr_errs[err_idx] = err; + return true; + + case FPURegSet: + fpu_errs[err_idx] = err; + return true; + + case EXCRegSet: + exc_errs[err_idx] = err; + return true; + + default: + break; + } + } + return false; + } + + bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; } + + void LogGPR(lldb_private::Log *log, const char *title); + + int ReadGPR(bool force); + + int ReadFPU(bool force); + + int ReadEXC(bool force); + + int WriteGPR(); + + int WriteFPU(); + + int WriteEXC(); + + // Subclasses override these to do the actual reading. + virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0; + + virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; + + virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; + + virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; + + virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; + + virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; + + int ReadRegisterSet(uint32_t set, bool force); + + int WriteRegisterSet(uint32_t set); + + static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); + + static int GetSetForNativeRegNum(int reg_num); + + static size_t GetRegisterInfosCount(); + + static const lldb_private::RegisterInfo *GetRegisterInfos(); +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp new file mode 100644 index 000000000000..08d84e827090 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -0,0 +1,1056 @@ +//===-- RegisterContextDarwin_x86_64.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 <cinttypes> +#include <cstdarg> +#include <cstddef> + +#include <memory> + +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextDarwin_x86_64.h" + +using namespace lldb; +using namespace lldb_private; + +enum { + gpr_rax = 0, + gpr_rbx, + gpr_rcx, + gpr_rdx, + gpr_rdi, + gpr_rsi, + gpr_rbp, + gpr_rsp, + gpr_r8, + gpr_r9, + gpr_r10, + gpr_r11, + gpr_r12, + gpr_r13, + gpr_r14, + gpr_r15, + gpr_rip, + gpr_rflags, + gpr_cs, + gpr_fs, + gpr_gs, + + fpu_fcw, + fpu_fsw, + fpu_ftw, + fpu_fop, + fpu_ip, + fpu_cs, + fpu_dp, + fpu_ds, + fpu_mxcsr, + fpu_mxcsrmask, + fpu_stmm0, + fpu_stmm1, + fpu_stmm2, + fpu_stmm3, + fpu_stmm4, + fpu_stmm5, + fpu_stmm6, + fpu_stmm7, + fpu_xmm0, + fpu_xmm1, + fpu_xmm2, + fpu_xmm3, + fpu_xmm4, + fpu_xmm5, + fpu_xmm6, + fpu_xmm7, + fpu_xmm8, + fpu_xmm9, + fpu_xmm10, + fpu_xmm11, + fpu_xmm12, + fpu_xmm13, + fpu_xmm14, + fpu_xmm15, + + exc_trapno, + exc_err, + exc_faultvaddr, + + k_num_registers, + + // Aliases + fpu_fctrl = fpu_fcw, + fpu_fstat = fpu_fsw, + fpu_ftag = fpu_ftw, + fpu_fiseg = fpu_cs, + fpu_fioff = fpu_ip, + fpu_foseg = fpu_ds, + fpu_fooff = fpu_dp +}; + +enum ehframe_dwarf_regnums { + ehframe_dwarf_gpr_rax = 0, + ehframe_dwarf_gpr_rdx, + ehframe_dwarf_gpr_rcx, + ehframe_dwarf_gpr_rbx, + ehframe_dwarf_gpr_rsi, + ehframe_dwarf_gpr_rdi, + ehframe_dwarf_gpr_rbp, + ehframe_dwarf_gpr_rsp, + ehframe_dwarf_gpr_r8, + ehframe_dwarf_gpr_r9, + ehframe_dwarf_gpr_r10, + ehframe_dwarf_gpr_r11, + ehframe_dwarf_gpr_r12, + ehframe_dwarf_gpr_r13, + ehframe_dwarf_gpr_r14, + ehframe_dwarf_gpr_r15, + ehframe_dwarf_gpr_rip, + ehframe_dwarf_fpu_xmm0, + ehframe_dwarf_fpu_xmm1, + ehframe_dwarf_fpu_xmm2, + ehframe_dwarf_fpu_xmm3, + ehframe_dwarf_fpu_xmm4, + ehframe_dwarf_fpu_xmm5, + ehframe_dwarf_fpu_xmm6, + ehframe_dwarf_fpu_xmm7, + ehframe_dwarf_fpu_xmm8, + ehframe_dwarf_fpu_xmm9, + ehframe_dwarf_fpu_xmm10, + ehframe_dwarf_fpu_xmm11, + ehframe_dwarf_fpu_xmm12, + ehframe_dwarf_fpu_xmm13, + ehframe_dwarf_fpu_xmm14, + ehframe_dwarf_fpu_xmm15, + ehframe_dwarf_fpu_stmm0, + ehframe_dwarf_fpu_stmm1, + ehframe_dwarf_fpu_stmm2, + ehframe_dwarf_fpu_stmm3, + ehframe_dwarf_fpu_stmm4, + ehframe_dwarf_fpu_stmm5, + ehframe_dwarf_fpu_stmm6, + ehframe_dwarf_fpu_stmm7 + +}; + +#define GPR_OFFSET(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::GPR, reg)) +#define FPU_OFFSET(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::FPU, reg) + \ + sizeof(RegisterContextDarwin_x86_64::GPR)) +#define EXC_OFFSET(reg) \ + (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::EXC, reg) + \ + sizeof(RegisterContextDarwin_x86_64::GPR) + \ + sizeof(RegisterContextDarwin_x86_64::FPU)) + +// These macros will auto define the register name, alt name, register size, +// register offset, encoding, format and native register. This ensures that the +// register state structures are defined correctly and have the correct sizes +// and offsets. +#define DEFINE_GPR(reg, alt) \ + #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg), \ + GPR_OFFSET(reg), eEncodingUint, eFormatHex +#define DEFINE_FPU_UINT(reg) \ + #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg), \ + FPU_OFFSET(reg), eEncodingUint, eFormatHex +#define DEFINE_FPU_VECT(reg, i) \ + #reg #i, NULL, \ + sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg[i].bytes), \ + FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {ehframe_dwarf_fpu_##reg##i, \ + ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpu_##reg##i }, \ + nullptr, nullptr, nullptr, +#define DEFINE_EXC(reg) \ + #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg), \ + EXC_OFFSET(reg), eEncodingUint, eFormatHex + +#define REG_CONTEXT_SIZE \ + (sizeof(RegisterContextDarwin_x86_64::GPR) + \ + sizeof(RegisterContextDarwin_x86_64::FPU) + \ + sizeof(RegisterContextDarwin_x86_64::EXC)) + +// General purpose registers for 64 bit +static RegisterInfo g_register_infos[] = { + // Macro auto defines most stuff EH_FRAME DWARF + // GENERIC PROCESS PLUGIN LLDB + // =============================== ====================== + // =================== ========================== ==================== + // =================== + {DEFINE_GPR(rax, nullptr), + {ehframe_dwarf_gpr_rax, ehframe_dwarf_gpr_rax, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_rax}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rbx, nullptr), + {ehframe_dwarf_gpr_rbx, ehframe_dwarf_gpr_rbx, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_rbx}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rcx, nullptr), + {ehframe_dwarf_gpr_rcx, ehframe_dwarf_gpr_rcx, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_rcx}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rdx, nullptr), + {ehframe_dwarf_gpr_rdx, ehframe_dwarf_gpr_rdx, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_rdx}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rdi, nullptr), + {ehframe_dwarf_gpr_rdi, ehframe_dwarf_gpr_rdi, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_rdi}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rsi, nullptr), + {ehframe_dwarf_gpr_rsi, ehframe_dwarf_gpr_rsi, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_rsi}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rbp, "fp"), + {ehframe_dwarf_gpr_rbp, ehframe_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP, + LLDB_INVALID_REGNUM, gpr_rbp}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rsp, "sp"), + {ehframe_dwarf_gpr_rsp, ehframe_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP, + LLDB_INVALID_REGNUM, gpr_rsp}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(r8, nullptr), + {ehframe_dwarf_gpr_r8, ehframe_dwarf_gpr_r8, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_r8}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(r9, nullptr), + {ehframe_dwarf_gpr_r9, ehframe_dwarf_gpr_r9, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_r9}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(r10, nullptr), + {ehframe_dwarf_gpr_r10, ehframe_dwarf_gpr_r10, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_r10}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(r11, nullptr), + {ehframe_dwarf_gpr_r11, ehframe_dwarf_gpr_r11, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_r11}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(r12, nullptr), + {ehframe_dwarf_gpr_r12, ehframe_dwarf_gpr_r12, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_r12}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(r13, nullptr), + {ehframe_dwarf_gpr_r13, ehframe_dwarf_gpr_r13, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_r13}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(r14, nullptr), + {ehframe_dwarf_gpr_r14, ehframe_dwarf_gpr_r14, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_r14}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(r15, nullptr), + {ehframe_dwarf_gpr_r15, ehframe_dwarf_gpr_r15, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_r15}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rip, "pc"), + {ehframe_dwarf_gpr_rip, ehframe_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC, + LLDB_INVALID_REGNUM, gpr_rip}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(rflags, "flags"), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, + LLDB_INVALID_REGNUM, gpr_rflags}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(cs, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_cs}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(fs, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_fs}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_GPR(gs, nullptr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, gpr_gs}, + nullptr, + nullptr, + nullptr, + }, + + {DEFINE_FPU_UINT(fcw), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fcw}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(fsw), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fsw}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(ftw), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_ftw}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(fop), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fop}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(ip), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_ip}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(cs), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_cs}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(dp), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_dp}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(ds), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_ds}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(mxcsr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_mxcsr}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_UINT(mxcsrmask), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_mxcsrmask}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_FPU_VECT(stmm, 0)}, + {DEFINE_FPU_VECT(stmm, 1)}, + {DEFINE_FPU_VECT(stmm, 2)}, + {DEFINE_FPU_VECT(stmm, 3)}, + {DEFINE_FPU_VECT(stmm, 4)}, + {DEFINE_FPU_VECT(stmm, 5)}, + {DEFINE_FPU_VECT(stmm, 6)}, + {DEFINE_FPU_VECT(stmm, 7)}, + {DEFINE_FPU_VECT(xmm, 0)}, + {DEFINE_FPU_VECT(xmm, 1)}, + {DEFINE_FPU_VECT(xmm, 2)}, + {DEFINE_FPU_VECT(xmm, 3)}, + {DEFINE_FPU_VECT(xmm, 4)}, + {DEFINE_FPU_VECT(xmm, 5)}, + {DEFINE_FPU_VECT(xmm, 6)}, + {DEFINE_FPU_VECT(xmm, 7)}, + {DEFINE_FPU_VECT(xmm, 8)}, + {DEFINE_FPU_VECT(xmm, 9)}, + {DEFINE_FPU_VECT(xmm, 10)}, + {DEFINE_FPU_VECT(xmm, 11)}, + {DEFINE_FPU_VECT(xmm, 12)}, + {DEFINE_FPU_VECT(xmm, 13)}, + {DEFINE_FPU_VECT(xmm, 14)}, + {DEFINE_FPU_VECT(xmm, 15)}, + + {DEFINE_EXC(trapno), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_trapno}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_EXC(err), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_err}, + nullptr, + nullptr, + nullptr, + }, + {DEFINE_EXC(faultvaddr), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_faultvaddr}, + nullptr, + nullptr, + nullptr, + }}; + +static size_t k_num_register_infos = std::size(g_register_infos); + +RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64( + Thread &thread, uint32_t concrete_frame_idx) + : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() { + uint32_t i; + for (i = 0; i < kNumErrors; i++) { + gpr_errs[i] = -1; + fpu_errs[i] = -1; + exc_errs[i] = -1; + } +} + +RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default; + +void RegisterContextDarwin_x86_64::InvalidateAllRegisters() { + InvalidateAllRegisterStates(); +} + +size_t RegisterContextDarwin_x86_64::GetRegisterCount() { + assert(k_num_register_infos == k_num_registers); + return k_num_registers; +} + +const RegisterInfo * +RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex(size_t reg) { + assert(k_num_register_infos == k_num_registers); + if (reg < k_num_registers) + return &g_register_infos[reg]; + return nullptr; +} + +size_t RegisterContextDarwin_x86_64::GetRegisterInfosCount() { + return k_num_register_infos; +} + +const lldb_private::RegisterInfo * +RegisterContextDarwin_x86_64::GetRegisterInfos() { + return g_register_infos; +} + +static uint32_t g_gpr_regnums[] = { + gpr_rax, gpr_rbx, gpr_rcx, gpr_rdx, gpr_rdi, gpr_rsi, gpr_rbp, + gpr_rsp, gpr_r8, gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_r13, + gpr_r14, gpr_r15, gpr_rip, gpr_rflags, gpr_cs, gpr_fs, gpr_gs}; + +static uint32_t g_fpu_regnums[] = { + fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs, + fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1, + fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7, + fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5, + fpu_xmm6, fpu_xmm7, fpu_xmm8, fpu_xmm9, fpu_xmm10, fpu_xmm11, + fpu_xmm12, fpu_xmm13, fpu_xmm14, fpu_xmm15}; + +static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr}; + +// Number of registers in each register set +const size_t k_num_gpr_registers = std::size(g_gpr_regnums); +const size_t k_num_fpu_registers = std::size(g_fpu_regnums); +const size_t k_num_exc_registers = std::size(g_exc_regnums); + +// Register set definitions. The first definitions at register set index of +// zero is for all registers, followed by other registers sets. The register +// information for the all register set need not be filled in. +static const RegisterSet g_reg_sets[] = { + { + "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, + }, + {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums}, + {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}}; + +const size_t k_num_regsets = std::size(g_reg_sets); + +size_t RegisterContextDarwin_x86_64::GetRegisterSetCount() { + return k_num_regsets; +} + +const RegisterSet * +RegisterContextDarwin_x86_64::GetRegisterSet(size_t reg_set) { + if (reg_set < k_num_regsets) + return &g_reg_sets[reg_set]; + return nullptr; +} + +int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) { + if (reg_num < fpu_fcw) + return GPRRegSet; + else if (reg_num < exc_trapno) + return FPURegSet; + else if (reg_num < k_num_registers) + return EXCRegSet; + return -1; +} + +int RegisterContextDarwin_x86_64::ReadGPR(bool force) { + int set = GPRRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); + } + return GetError(GPRRegSet, Read); +} + +int RegisterContextDarwin_x86_64::ReadFPU(bool force) { + int set = FPURegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); + } + return GetError(FPURegSet, Read); +} + +int RegisterContextDarwin_x86_64::ReadEXC(bool force) { + int set = EXCRegSet; + if (force || !RegisterSetIsCached(set)) { + SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); + } + return GetError(EXCRegSet, Read); +} + +int RegisterContextDarwin_x86_64::WriteGPR() { + int set = GPRRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return -1; + } + SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr)); + SetError(set, Read, -1); + return GetError(set, Write); +} + +int RegisterContextDarwin_x86_64::WriteFPU() { + int set = FPURegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return -1; + } + SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu)); + SetError(set, Read, -1); + return GetError(set, Write); +} + +int RegisterContextDarwin_x86_64::WriteEXC() { + int set = EXCRegSet; + if (!RegisterSetIsCached(set)) { + SetError(set, Write, -1); + return -1; + } + SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc)); + SetError(set, Read, -1); + return GetError(set, Write); +} + +int RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) { + switch (set) { + case GPRRegSet: + return ReadGPR(force); + case FPURegSet: + return ReadFPU(force); + case EXCRegSet: + return ReadEXC(force); + default: + break; + } + return -1; +} + +int RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) { + // Make sure we have a valid context to set. + switch (set) { + case GPRRegSet: + return WriteGPR(); + case FPURegSet: + return WriteFPU(); + case EXCRegSet: + return WriteEXC(); + default: + break; + } + return -1; +} + +bool RegisterContextDarwin_x86_64::ReadRegister(const RegisterInfo *reg_info, + RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg); + if (set == -1) + return false; + + if (ReadRegisterSet(set, false) != 0) + return false; + + switch (reg) { + case gpr_rax: + case gpr_rbx: + case gpr_rcx: + case gpr_rdx: + case gpr_rdi: + case gpr_rsi: + case gpr_rbp: + case gpr_rsp: + case gpr_r8: + case gpr_r9: + case gpr_r10: + case gpr_r11: + case gpr_r12: + case gpr_r13: + case gpr_r14: + case gpr_r15: + case gpr_rip: + case gpr_rflags: + case gpr_cs: + case gpr_fs: + case gpr_gs: + value = (&gpr.rax)[reg - gpr_rax]; + break; + + case fpu_fcw: + value = fpu.fcw; + break; + + case fpu_fsw: + value = fpu.fsw; + break; + + case fpu_ftw: + value = fpu.ftw; + break; + + case fpu_fop: + value = fpu.fop; + break; + + case fpu_ip: + value = fpu.ip; + break; + + case fpu_cs: + value = fpu.cs; + break; + + case fpu_dp: + value = fpu.dp; + break; + + case fpu_ds: + value = fpu.ds; + break; + + case fpu_mxcsr: + value = fpu.mxcsr; + break; + + case fpu_mxcsrmask: + value = fpu.mxcsrmask; + break; + + case fpu_stmm0: + case fpu_stmm1: + case fpu_stmm2: + case fpu_stmm3: + case fpu_stmm4: + case fpu_stmm5: + case fpu_stmm6: + case fpu_stmm7: + value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, + endian::InlHostByteOrder()); + break; + + case fpu_xmm0: + case fpu_xmm1: + case fpu_xmm2: + case fpu_xmm3: + case fpu_xmm4: + case fpu_xmm5: + case fpu_xmm6: + case fpu_xmm7: + case fpu_xmm8: + case fpu_xmm9: + case fpu_xmm10: + case fpu_xmm11: + case fpu_xmm12: + case fpu_xmm13: + case fpu_xmm14: + case fpu_xmm15: + value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, + endian::InlHostByteOrder()); + break; + + case exc_trapno: + value = exc.trapno; + break; + + case exc_err: + value = exc.err; + break; + + case exc_faultvaddr: + value = exc.faultvaddr; + break; + + default: + return false; + } + return true; +} + +bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info, + const RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg); + + if (set == -1) + return false; + + if (ReadRegisterSet(set, false) != 0) + return false; + + switch (reg) { + case gpr_rax: + case gpr_rbx: + case gpr_rcx: + case gpr_rdx: + case gpr_rdi: + case gpr_rsi: + case gpr_rbp: + case gpr_rsp: + case gpr_r8: + case gpr_r9: + case gpr_r10: + case gpr_r11: + case gpr_r12: + case gpr_r13: + case gpr_r14: + case gpr_r15: + case gpr_rip: + case gpr_rflags: + case gpr_cs: + case gpr_fs: + case gpr_gs: + (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64(); + break; + + case fpu_fcw: + fpu.fcw = value.GetAsUInt16(); + break; + + case fpu_fsw: + fpu.fsw = value.GetAsUInt16(); + break; + + case fpu_ftw: + fpu.ftw = value.GetAsUInt8(); + break; + + case fpu_fop: + fpu.fop = value.GetAsUInt16(); + break; + + case fpu_ip: + fpu.ip = value.GetAsUInt32(); + break; + + case fpu_cs: + fpu.cs = value.GetAsUInt16(); + break; + + case fpu_dp: + fpu.dp = value.GetAsUInt32(); + break; + + case fpu_ds: + fpu.ds = value.GetAsUInt16(); + break; + + case fpu_mxcsr: + fpu.mxcsr = value.GetAsUInt32(); + break; + + case fpu_mxcsrmask: + fpu.mxcsrmask = value.GetAsUInt32(); + break; + + case fpu_stmm0: + case fpu_stmm1: + case fpu_stmm2: + case fpu_stmm3: + case fpu_stmm4: + case fpu_stmm5: + case fpu_stmm6: + case fpu_stmm7: + ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), + value.GetByteSize()); + break; + + case fpu_xmm0: + case fpu_xmm1: + case fpu_xmm2: + case fpu_xmm3: + case fpu_xmm4: + case fpu_xmm5: + case fpu_xmm6: + case fpu_xmm7: + case fpu_xmm8: + case fpu_xmm9: + case fpu_xmm10: + case fpu_xmm11: + case fpu_xmm12: + case fpu_xmm13: + case fpu_xmm14: + case fpu_xmm15: + ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), + value.GetByteSize()); + return false; + + case exc_trapno: + exc.trapno = value.GetAsUInt32(); + break; + + case exc_err: + exc.err = value.GetAsUInt32(); + break; + + case exc_faultvaddr: + exc.faultvaddr = value.GetAsUInt64(); + break; + + default: + return false; + } + return WriteRegisterSet(set) == 0; +} + +bool RegisterContextDarwin_x86_64::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { + data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); + if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) { + uint8_t *dst = data_sp->GetBytes(); + ::memcpy(dst, &gpr, sizeof(gpr)); + dst += sizeof(gpr); + + ::memcpy(dst, &fpu, sizeof(fpu)); + dst += sizeof(gpr); + + ::memcpy(dst, &exc, sizeof(exc)); + return true; + } + return false; +} + +bool RegisterContextDarwin_x86_64::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) { + const uint8_t *src = data_sp->GetBytes(); + ::memcpy(&gpr, src, sizeof(gpr)); + src += sizeof(gpr); + + ::memcpy(&fpu, src, sizeof(fpu)); + src += sizeof(gpr); + + ::memcpy(&exc, src, sizeof(exc)); + uint32_t success_count = 0; + if (WriteGPR() == 0) + ++success_count; + if (WriteFPU() == 0) + ++success_count; + if (WriteEXC() == 0) + ++success_count; + return success_count == 3; + } + return false; +} + +uint32_t RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t reg) { + if (kind == eRegisterKindGeneric) { + switch (reg) { + case LLDB_REGNUM_GENERIC_PC: + return gpr_rip; + case LLDB_REGNUM_GENERIC_SP: + return gpr_rsp; + case LLDB_REGNUM_GENERIC_FP: + return gpr_rbp; + case LLDB_REGNUM_GENERIC_FLAGS: + return gpr_rflags; + case LLDB_REGNUM_GENERIC_RA: + default: + break; + } + } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) { + switch (reg) { + case ehframe_dwarf_gpr_rax: + return gpr_rax; + case ehframe_dwarf_gpr_rdx: + return gpr_rdx; + case ehframe_dwarf_gpr_rcx: + return gpr_rcx; + case ehframe_dwarf_gpr_rbx: + return gpr_rbx; + case ehframe_dwarf_gpr_rsi: + return gpr_rsi; + case ehframe_dwarf_gpr_rdi: + return gpr_rdi; + case ehframe_dwarf_gpr_rbp: + return gpr_rbp; + case ehframe_dwarf_gpr_rsp: + return gpr_rsp; + case ehframe_dwarf_gpr_r8: + return gpr_r8; + case ehframe_dwarf_gpr_r9: + return gpr_r9; + case ehframe_dwarf_gpr_r10: + return gpr_r10; + case ehframe_dwarf_gpr_r11: + return gpr_r11; + case ehframe_dwarf_gpr_r12: + return gpr_r12; + case ehframe_dwarf_gpr_r13: + return gpr_r13; + case ehframe_dwarf_gpr_r14: + return gpr_r14; + case ehframe_dwarf_gpr_r15: + return gpr_r15; + case ehframe_dwarf_gpr_rip: + return gpr_rip; + case ehframe_dwarf_fpu_xmm0: + return fpu_xmm0; + case ehframe_dwarf_fpu_xmm1: + return fpu_xmm1; + case ehframe_dwarf_fpu_xmm2: + return fpu_xmm2; + case ehframe_dwarf_fpu_xmm3: + return fpu_xmm3; + case ehframe_dwarf_fpu_xmm4: + return fpu_xmm4; + case ehframe_dwarf_fpu_xmm5: + return fpu_xmm5; + case ehframe_dwarf_fpu_xmm6: + return fpu_xmm6; + case ehframe_dwarf_fpu_xmm7: + return fpu_xmm7; + case ehframe_dwarf_fpu_xmm8: + return fpu_xmm8; + case ehframe_dwarf_fpu_xmm9: + return fpu_xmm9; + case ehframe_dwarf_fpu_xmm10: + return fpu_xmm10; + case ehframe_dwarf_fpu_xmm11: + return fpu_xmm11; + case ehframe_dwarf_fpu_xmm12: + return fpu_xmm12; + case ehframe_dwarf_fpu_xmm13: + return fpu_xmm13; + case ehframe_dwarf_fpu_xmm14: + return fpu_xmm14; + case ehframe_dwarf_fpu_xmm15: + return fpu_xmm15; + case ehframe_dwarf_fpu_stmm0: + return fpu_stmm0; + case ehframe_dwarf_fpu_stmm1: + return fpu_stmm1; + case ehframe_dwarf_fpu_stmm2: + return fpu_stmm2; + case ehframe_dwarf_fpu_stmm3: + return fpu_stmm3; + case ehframe_dwarf_fpu_stmm4: + return fpu_stmm4; + case ehframe_dwarf_fpu_stmm5: + return fpu_stmm5; + case ehframe_dwarf_fpu_stmm6: + return fpu_stmm6; + case ehframe_dwarf_fpu_stmm7: + return fpu_stmm7; + default: + break; + } + } else if (kind == eRegisterKindLLDB) { + return reg; + } + return LLDB_INVALID_REGNUM; +} + +bool RegisterContextDarwin_x86_64::HardwareSingleStep(bool enable) { + if (ReadGPR(true) != 0) + return false; + + const uint64_t trace_bit = 0x100ull; + if (enable) { + + if (gpr.rflags & trace_bit) + return true; // trace bit is already set, there is nothing to do + else + gpr.rflags |= trace_bit; + } else { + if (gpr.rflags & trace_bit) + gpr.rflags &= ~trace_bit; + else + return true; // trace bit is clear, there is nothing to do + } + + return WriteGPR() == 0; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h new file mode 100644 index 000000000000..a132f92d4d49 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h @@ -0,0 +1,213 @@ +//===-- RegisterContextDarwin_x86_64.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_REGISTERCONTEXTDARWIN_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H + +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext { +public: + RegisterContextDarwin_x86_64(lldb_private::Thread &thread, + uint32_t concrete_frame_idx); + + ~RegisterContextDarwin_x86_64() override; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) override; + + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + bool HardwareSingleStep(bool enable) override; + + struct GPR { + uint64_t rax; + uint64_t rbx; + uint64_t rcx; + uint64_t rdx; + uint64_t rdi; + uint64_t rsi; + uint64_t rbp; + uint64_t rsp; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t rip; + uint64_t rflags; + uint64_t cs; + uint64_t fs; + uint64_t gs; + }; + + struct MMSReg { + uint8_t bytes[10]; + uint8_t pad[6]; + }; + + struct XMMReg { + uint8_t bytes[16]; + }; + + struct FPU { + uint32_t pad[2]; + uint16_t fcw; // "fctrl" + uint16_t fsw; // "fstat" + uint8_t ftw; // "ftag" + uint8_t pad1; + uint16_t fop; // "fop" + uint32_t ip; // "fioff" + uint16_t cs; // "fiseg" + uint16_t pad2; + uint32_t dp; // "fooff" + uint16_t ds; // "foseg" + uint16_t pad3; + uint32_t mxcsr; + uint32_t mxcsrmask; + MMSReg stmm[8]; + XMMReg xmm[16]; + uint8_t pad4[6 * 16]; + int pad5; + }; + + struct EXC { + uint32_t trapno; + uint32_t err; + uint64_t faultvaddr; + }; + +protected: + enum { GPRRegSet = 4, FPURegSet = 5, EXCRegSet = 6 }; + + enum { + GPRWordCount = sizeof(GPR) / sizeof(uint32_t), + FPUWordCount = sizeof(FPU) / sizeof(uint32_t), + EXCWordCount = sizeof(EXC) / sizeof(uint32_t) + }; + + enum { Read = 0, Write = 1, kNumErrors = 2 }; + + GPR gpr; + FPU fpu; + EXC exc; + int gpr_errs[2]; // Read/Write errors + int fpu_errs[2]; // Read/Write errors + int exc_errs[2]; // Read/Write errors + + void InvalidateAllRegisterStates() { + SetError(GPRRegSet, Read, -1); + SetError(FPURegSet, Read, -1); + SetError(EXCRegSet, Read, -1); + } + + int GetError(int flavor, uint32_t err_idx) const { + if (err_idx < kNumErrors) { + switch (flavor) { + // When getting all errors, just OR all values together to see if + // we got any kind of error. + case GPRRegSet: + return gpr_errs[err_idx]; + case FPURegSet: + return fpu_errs[err_idx]; + case EXCRegSet: + return exc_errs[err_idx]; + default: + break; + } + } + return -1; + } + + bool SetError(int flavor, uint32_t err_idx, int err) { + if (err_idx < kNumErrors) { + switch (flavor) { + case GPRRegSet: + gpr_errs[err_idx] = err; + return true; + + case FPURegSet: + fpu_errs[err_idx] = err; + return true; + + case EXCRegSet: + exc_errs[err_idx] = err; + return true; + + default: + break; + } + } + return false; + } + + bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; } + + void LogGPR(lldb_private::Log *log, const char *format, ...); + + int ReadGPR(bool force); + + int ReadFPU(bool force); + + int ReadEXC(bool force); + + int WriteGPR(); + + int WriteFPU(); + + int WriteEXC(); + + // Subclasses override these to do the actual reading. + virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0; + + virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; + + virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; + + virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; + + virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; + + virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; + + int ReadRegisterSet(uint32_t set, bool force); + + int WriteRegisterSet(uint32_t set); + + static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); + + static int GetSetForNativeRegNum(int reg_num); + + static size_t GetRegisterInfosCount(); + + static const lldb_private::RegisterInfo *GetRegisterInfos(); +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp new file mode 100644 index 000000000000..f41aa2ca599e --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -0,0 +1,120 @@ +//===-- RegisterContextDummy.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 "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Value.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Symbol/FuncUnwinders.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/lldb-private.h" + +#include "RegisterContextDummy.h" + +using namespace lldb; +using namespace lldb_private; + +RegisterContextDummy::RegisterContextDummy(Thread &thread, + uint32_t concrete_frame_idx, + uint32_t address_byte_size) + : RegisterContext(thread, concrete_frame_idx) { + m_reg_set0.name = "General Purpose Registers"; + m_reg_set0.short_name = "GPR"; + m_reg_set0.num_registers = 1; + m_reg_set0.registers = new uint32_t(0); + + m_pc_reg_info.name = "pc"; + m_pc_reg_info.alt_name = "pc"; + m_pc_reg_info.byte_offset = 0; + m_pc_reg_info.byte_size = address_byte_size; + m_pc_reg_info.encoding = eEncodingUint; + m_pc_reg_info.format = eFormatPointer; + m_pc_reg_info.invalidate_regs = nullptr; + m_pc_reg_info.value_regs = nullptr; + m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM; + m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM; + m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; + m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM; + m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM; +} + +RegisterContextDummy::~RegisterContextDummy() { + delete m_reg_set0.registers; + delete m_pc_reg_info.invalidate_regs; + delete m_pc_reg_info.value_regs; +} + +void RegisterContextDummy::InvalidateAllRegisters() {} + +size_t RegisterContextDummy::GetRegisterCount() { return 1; } + +const lldb_private::RegisterInfo * +RegisterContextDummy::GetRegisterInfoAtIndex(size_t reg) { + if (reg) + return nullptr; + return &m_pc_reg_info; +} + +size_t RegisterContextDummy::GetRegisterSetCount() { return 1; } + +const lldb_private::RegisterSet * +RegisterContextDummy::GetRegisterSet(size_t reg_set) { + if (reg_set) + return nullptr; + return &m_reg_set0; +} + +bool RegisterContextDummy::ReadRegister( + const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) { + if (!reg_info) + return false; + uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric]; + if (reg_number == LLDB_REGNUM_GENERIC_PC) { + value.SetUInt(LLDB_INVALID_ADDRESS, reg_info->byte_size); + return true; + } + return false; +} + +bool RegisterContextDummy::WriteRegister( + const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) { + return false; +} + +bool RegisterContextDummy::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { + return false; +} + +bool RegisterContextDummy::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + return false; +} + +uint32_t RegisterContextDummy::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC) + return 0; + return LLDB_INVALID_REGNUM; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h new file mode 100644 index 000000000000..631ad30b16a8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h @@ -0,0 +1,65 @@ +//===-- RegisterContextDummy.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_REGISTERCONTEXTDUMMY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H + +#include <vector> + +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class RegisterContextDummy : public lldb_private::RegisterContext { +public: + typedef std::shared_ptr<RegisterContextDummy> SharedPtr; + + RegisterContextDummy(Thread &thread, uint32_t concrete_frame_idx, + uint32_t address_byte_size); + + ~RegisterContextDummy() override; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override; + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) override; + + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + +private: + // For RegisterContextLLDB only + + lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only) + lldb_private::RegisterInfo m_pc_reg_info; + + RegisterContextDummy(const RegisterContextDummy &) = delete; + const RegisterContextDummy &operator=(const RegisterContextDummy &) = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_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 new file mode 100644 index 000000000000..df6a82c11255 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp @@ -0,0 +1,83 @@ +//===-- RegisterContextFreeBSD_i386.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 "RegisterContextFreeBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" + +using namespace lldb_private; +using namespace lldb; + +// http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h +struct GPR { + uint32_t fs; + uint32_t es; + uint32_t ds; + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t isp; + uint32_t ebx; + uint32_t edx; + uint32_t ecx; + uint32_t eax; + uint32_t trapno; + uint32_t err; + uint32_t eip; + uint32_t cs; + uint32_t eflags; + uint32_t esp; + uint32_t ss; + uint32_t gs; +}; + +struct DBG { + uint32_t dr[8]; /* debug registers */ + /* Index 0-3: debug address registers */ + /* Index 4-5: reserved */ + /* Index 6: debug status */ + /* Index 7: debug control */ +}; + +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(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 +#include "RegisterInfos_i386.h" +#undef DECLARE_REGISTER_INFOS_I386_STRUCT + +RegisterContextFreeBSD_i386::RegisterContextFreeBSD_i386( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +size_t RegisterContextFreeBSD_i386::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextFreeBSD_i386::GetRegisterInfo() const { + switch (GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return g_register_infos_i386; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterContextFreeBSD_i386::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h new file mode 100644 index 000000000000..5a3e5b0551d6 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h @@ -0,0 +1,25 @@ +//===-- RegisterContextFreeBSD_i386.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_REGISTERCONTEXTFREEBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_I386_H + +#include "RegisterInfoInterface.h" + +class RegisterContextFreeBSD_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextFreeBSD_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp new file mode 100644 index 000000000000..1f52c09df12e --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp @@ -0,0 +1,179 @@ +//===-- RegisterContextFreeBSD_mips64.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 "RegisterContextFreeBSD_mips64.h" +#include "RegisterContextPOSIX_mips64.h" +#include "lldb-mips-freebsd-register-enums.h" +#include <vector> + +using namespace lldb_private; +using namespace lldb; + +static const uint32_t g_gp_regnums_mips64[] = { + gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64, + gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64, + gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64, + gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64, + gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64, + gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64, + gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64, + gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64, + gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64, + gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) - + 1 == + k_num_gpr_registers_mips64, + "g_gp_regnums_mips64 has wrong number of register infos"); + +const uint32_t g_fp_regnums_mips64[] = { + fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64, + fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64, + fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64, + fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64, + fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64, + fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64, + fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64, + fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64, + fpr_fcsr_mips64, fpr_fir_mips64, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) - + 1 == + k_num_fpr_registers_mips64, + "g_fp_regnums_mips64 has wrong number of register infos"); + +// Number of register sets provided by this context. +constexpr size_t k_num_register_sets = 2; + +static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64, + g_gp_regnums_mips64}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64, + g_fp_regnums_mips64}, +}; + +// http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h +typedef struct _GPR { + uint64_t zero; + uint64_t r1; + uint64_t r2; + uint64_t r3; + uint64_t r4; + uint64_t r5; + uint64_t r6; + uint64_t r7; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t r16; + uint64_t r17; + uint64_t r18; + uint64_t r19; + uint64_t r20; + uint64_t r21; + uint64_t r22; + uint64_t r23; + uint64_t r24; + uint64_t r25; + uint64_t r26; + uint64_t r27; + uint64_t gp; + uint64_t sp; + uint64_t r30; + uint64_t ra; + uint64_t sr; + uint64_t mullo; + uint64_t mulhi; + uint64_t badvaddr; + uint64_t cause; + uint64_t pc; + uint64_t ic; + uint64_t dummy; +} GPR_freebsd_mips; + +typedef struct _FPR { + uint64_t f0; + uint64_t f1; + uint64_t f2; + uint64_t f3; + uint64_t f4; + uint64_t f5; + uint64_t f6; + uint64_t f7; + uint64_t f8; + uint64_t f9; + uint64_t f10; + uint64_t f11; + uint64_t f12; + uint64_t f13; + uint64_t f14; + uint64_t f15; + uint64_t f16; + uint64_t f17; + uint64_t f18; + uint64_t f19; + uint64_t f20; + uint64_t f21; + uint64_t f22; + uint64_t f23; + uint64_t f24; + uint64_t f25; + uint64_t f26; + uint64_t f27; + uint64_t f28; + uint64_t f29; + uint64_t f30; + uint64_t f31; + uint64_t fcsr; + uint64_t fir; +} FPR_freebsd_mips; + +// Include RegisterInfos_mips64 to declare our g_register_infos_mips64 +// structure. +#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT +#include "RegisterInfos_mips64.h" +#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT + +RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +size_t RegisterContextFreeBSD_mips64::GetGPRSize() const { + return sizeof(GPR_freebsd_mips); +} + +const RegisterSet * +RegisterContextFreeBSD_mips64::GetRegisterSet(size_t set) const { + // Check if RegisterSet is available + if (set < k_num_register_sets) + return &g_reg_sets_mips64[set]; + return nullptr; +} + +size_t RegisterContextFreeBSD_mips64::GetRegisterSetCount() const { + return k_num_register_sets; +} + +const RegisterInfo *RegisterContextFreeBSD_mips64::GetRegisterInfo() const { + assert(GetTargetArchitecture().GetCore() == ArchSpec::eCore_mips64); + return g_register_infos_mips64; +} + +uint32_t RegisterContextFreeBSD_mips64::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_mips64) / + sizeof(g_register_infos_mips64[0])); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h new file mode 100644 index 000000000000..39968eacf475 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h @@ -0,0 +1,30 @@ +//===-- RegisterContextFreeBSD_mips64.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_REGISTERCONTEXTFREEBSD_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_MIPS64_H + +#include "RegisterInfoInterface.h" + +class RegisterContextFreeBSD_mips64 + : public lldb_private::RegisterInfoInterface { +public: + RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) const; + + size_t GetRegisterSetCount() const; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp new file mode 100644 index 000000000000..d8dfa434335b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp @@ -0,0 +1,233 @@ +//===-- RegisterContextFreeBSD_powerpc.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 "RegisterContextFreeBSD_powerpc.h" +#include "RegisterContextPOSIX_powerpc.h" +#include <vector> + +using namespace lldb_private; +using namespace lldb; + +// http://svnweb.freebsd.org/base/head/sys/powerpc/include/reg.h +typedef struct _GPR64 { + uint64_t r0; + uint64_t r1; + uint64_t r2; + uint64_t r3; + uint64_t r4; + uint64_t r5; + uint64_t r6; + uint64_t r7; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t r16; + uint64_t r17; + uint64_t r18; + uint64_t r19; + uint64_t r20; + uint64_t r21; + uint64_t r22; + uint64_t r23; + uint64_t r24; + uint64_t r25; + uint64_t r26; + uint64_t r27; + uint64_t r28; + uint64_t r29; + uint64_t r30; + uint64_t r31; + uint64_t lr; + uint64_t cr; + uint64_t xer; + uint64_t ctr; + uint64_t pc; +} GPR64; + +typedef struct _GPR32 { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t r13; + uint32_t r14; + uint32_t r15; + uint32_t r16; + uint32_t r17; + uint32_t r18; + uint32_t r19; + uint32_t r20; + uint32_t r21; + uint32_t r22; + uint32_t r23; + uint32_t r24; + uint32_t r25; + uint32_t r26; + uint32_t r27; + uint32_t r28; + uint32_t r29; + uint32_t r30; + uint32_t r31; + uint32_t lr; + uint32_t cr; + uint32_t xer; + uint32_t ctr; + uint32_t pc; +} GPR32; + +typedef struct _FPR { + uint64_t f0; + uint64_t f1; + uint64_t f2; + uint64_t f3; + uint64_t f4; + uint64_t f5; + uint64_t f6; + uint64_t f7; + uint64_t f8; + uint64_t f9; + uint64_t f10; + uint64_t f11; + uint64_t f12; + uint64_t f13; + uint64_t f14; + uint64_t f15; + uint64_t f16; + uint64_t f17; + uint64_t f18; + uint64_t f19; + uint64_t f20; + uint64_t f21; + uint64_t f22; + uint64_t f23; + uint64_t f24; + uint64_t f25; + uint64_t f26; + uint64_t f27; + uint64_t f28; + uint64_t f29; + uint64_t f30; + uint64_t f31; + uint64_t fpscr; +} FPR; + +typedef struct _VMX { + uint32_t v0[4]; + uint32_t v1[4]; + uint32_t v2[4]; + uint32_t v3[4]; + uint32_t v4[4]; + uint32_t v5[4]; + uint32_t v6[4]; + uint32_t v7[4]; + uint32_t v8[4]; + uint32_t v9[4]; + uint32_t v10[4]; + uint32_t v11[4]; + uint32_t v12[4]; + uint32_t v13[4]; + uint32_t v14[4]; + uint32_t v15[4]; + uint32_t v16[4]; + uint32_t v17[4]; + uint32_t v18[4]; + uint32_t v19[4]; + uint32_t v20[4]; + uint32_t v21[4]; + uint32_t v22[4]; + uint32_t v23[4]; + uint32_t v24[4]; + uint32_t v25[4]; + uint32_t v26[4]; + uint32_t v27[4]; + uint32_t v28[4]; + uint32_t v29[4]; + uint32_t v30[4]; + uint32_t v31[4]; + uint32_t pad[2]; + uint32_t vrsave; + uint32_t vscr; +} VMX; + +// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc +// structure. +#define DECLARE_REGISTER_INFOS_POWERPC_STRUCT +#include "RegisterInfos_powerpc.h" +#undef DECLARE_REGISTER_INFOS_POWERPC_STRUCT + +RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() = default; + +size_t RegisterContextFreeBSD_powerpc::GetGPRSize() const { + // This is an 'abstract' base, so no GPR struct. + return 0; +} + +const RegisterInfo *RegisterContextFreeBSD_powerpc::GetRegisterInfo() const { + llvm_unreachable("Abstract class!"); + return nullptr; +} + +uint32_t RegisterContextFreeBSD_powerpc::GetRegisterCount() const { return 0; } + +RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32( + const ArchSpec &target_arch) + : RegisterContextFreeBSD_powerpc(target_arch) {} + +RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() = default; + +size_t RegisterContextFreeBSD_powerpc32::GetGPRSize() const { + return sizeof(GPR32); +} + +const RegisterInfo *RegisterContextFreeBSD_powerpc32::GetRegisterInfo() const { + return g_register_infos_powerpc32; +} + +uint32_t RegisterContextFreeBSD_powerpc32::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_powerpc32) / + sizeof(g_register_infos_powerpc32[0])); +} + +RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64( + const ArchSpec &target_arch) + : RegisterContextFreeBSD_powerpc(target_arch) {} + +RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() = default; + +size_t RegisterContextFreeBSD_powerpc64::GetGPRSize() const { + return sizeof(GPR64); +} + +const RegisterInfo *RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const { + if (GetTargetArchitecture().GetMachine() == llvm::Triple::ppc) + return g_register_infos_powerpc64_32; + return g_register_infos_powerpc64; +} + +uint32_t RegisterContextFreeBSD_powerpc64::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_powerpc64) / + sizeof(g_register_infos_powerpc64[0])); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h new file mode 100644 index 000000000000..7e4c43ba908a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h @@ -0,0 +1,52 @@ +//===-- RegisterContextFreeBSD_powerpc.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_REGISTERCONTEXTFREEBSD_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H + +#include "RegisterInfoInterface.h" + +class RegisterContextFreeBSD_powerpc + : public lldb_private::RegisterInfoInterface { +public: + RegisterContextFreeBSD_powerpc(const lldb_private::ArchSpec &target_arch); + ~RegisterContextFreeBSD_powerpc() override; + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +class RegisterContextFreeBSD_powerpc32 : public RegisterContextFreeBSD_powerpc { +public: + RegisterContextFreeBSD_powerpc32(const lldb_private::ArchSpec &target_arch); + ~RegisterContextFreeBSD_powerpc32() override; + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +class RegisterContextFreeBSD_powerpc64 : public RegisterContextFreeBSD_powerpc { +public: + RegisterContextFreeBSD_powerpc64(const lldb_private::ArchSpec &target_arch); + ~RegisterContextFreeBSD_powerpc64() override; + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H 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 new file mode 100644 index 000000000000..e0f3971c6e27 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp @@ -0,0 +1,145 @@ +//===-- RegisterContextFreeBSD_x86_64.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 "RegisterContextFreeBSD_x86_64.h" +#include "RegisterContextFreeBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" +#include <vector> + +using namespace lldb_private; +using namespace lldb; + +// http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h +typedef struct _GPR { + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rdi; + uint64_t rsi; + uint64_t rbp; + uint64_t rbx; + uint64_t rdx; + uint64_t rcx; + uint64_t rax; + uint32_t trapno; + uint16_t fs; + uint16_t gs; + uint32_t err; + uint16_t es; + uint16_t ds; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +} GPR; + +struct DBG { + uint64_t dr[16]; /* debug registers */ + /* Index 0-3: debug address registers */ + /* Index 4-5: reserved */ + /* Index 6: debug status */ + /* Index 7: debug control */ + /* Index 8-15: reserved */ +}; + +struct UserArea { + GPR gpr; + FPR fpr; + DBG dbg; +}; + +#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. +#define DECLARE_REGISTER_INFOS_X86_64_STRUCT +#include "RegisterInfos_x86_64.h" +#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +static std::vector<lldb_private::RegisterInfo> &GetSharedRegisterInfoVector() { + static std::vector<lldb_private::RegisterInfo> register_infos; + return register_infos; +} + +static const RegisterInfo * +GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) { + static std::vector<lldb_private::RegisterInfo> g_register_infos( + GetSharedRegisterInfoVector()); + + // Allocate RegisterInfo only once + if (g_register_infos.empty()) { + // Copy the register information from base class + std::unique_ptr<RegisterContextFreeBSD_i386> reg_interface( + new RegisterContextFreeBSD_i386(arch)); + const RegisterInfo *base_info = reg_interface->GetRegisterInfo(); + g_register_infos.insert(g_register_infos.end(), &base_info[0], + &base_info[k_num_registers_i386]); + +// Include RegisterInfos_x86_64 to update the g_register_infos structure +// with x86_64 offsets. +#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS +#include "RegisterInfos_x86_64.h" +#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + } + + return &g_register_infos[0]; +} + +static const RegisterInfo * +PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return GetRegisterInfo_i386(target_arch); + case llvm::Triple::x86_64: + return g_register_infos_x86_64; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t +PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + // This vector should have already been filled. + assert(!GetSharedRegisterInfoVector().empty() && + "i386 register info vector not filled."); + return static_cast<uint32_t>(GetSharedRegisterInfoVector().size()); + case llvm::Triple::x86_64: + return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) / + sizeof(g_register_infos_x86_64[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch), + m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)), + m_register_count(PrivateGetRegisterCount(target_arch)) {} + +size_t RegisterContextFreeBSD_x86_64::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextFreeBSD_x86_64::GetRegisterInfo() const { + return m_register_info_p; +} + +uint32_t RegisterContextFreeBSD_x86_64::GetRegisterCount() const { + return m_register_count; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h new file mode 100644 index 000000000000..d0f69fde1817 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h @@ -0,0 +1,30 @@ +//===-- RegisterContextFreeBSD_x86_64.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_REGISTERCONTEXTFREEBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_X86_64_H + +#include "RegisterInfoInterface.h" + +class RegisterContextFreeBSD_x86_64 + : public lldb_private::RegisterInfoInterface { +public: + RegisterContextFreeBSD_x86_64(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + const uint32_t m_register_count; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp new file mode 100644 index 000000000000..f06af93cfa83 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -0,0 +1,121 @@ +//===-- RegisterContextHistory.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 "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Value.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Symbol/FuncUnwinders.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/lldb-private.h" + +#include "RegisterContextHistory.h" + +using namespace lldb; +using namespace lldb_private; + +RegisterContextHistory::RegisterContextHistory(Thread &thread, + uint32_t concrete_frame_idx, + uint32_t address_byte_size, + addr_t pc_value) + : RegisterContext(thread, concrete_frame_idx), m_pc_value(pc_value) { + m_reg_set0.name = "General Purpose Registers"; + m_reg_set0.short_name = "GPR"; + m_reg_set0.num_registers = 1; + m_reg_set0.registers = new uint32_t(0); + + m_pc_reg_info.name = "pc"; + m_pc_reg_info.alt_name = "pc"; + m_pc_reg_info.byte_offset = 0; + m_pc_reg_info.byte_size = address_byte_size; + m_pc_reg_info.encoding = eEncodingUint; + m_pc_reg_info.format = eFormatPointer; + m_pc_reg_info.invalidate_regs = nullptr; + m_pc_reg_info.value_regs = nullptr; + m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM; + m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM; + m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; + m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM; + m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM; +} + +RegisterContextHistory::~RegisterContextHistory() { + delete m_reg_set0.registers; + delete m_pc_reg_info.invalidate_regs; + delete m_pc_reg_info.value_regs; +} + +void RegisterContextHistory::InvalidateAllRegisters() {} + +size_t RegisterContextHistory::GetRegisterCount() { return 1; } + +const lldb_private::RegisterInfo * +RegisterContextHistory::GetRegisterInfoAtIndex(size_t reg) { + if (reg) + return nullptr; + return &m_pc_reg_info; +} + +size_t RegisterContextHistory::GetRegisterSetCount() { return 1; } + +const lldb_private::RegisterSet * +RegisterContextHistory::GetRegisterSet(size_t reg_set) { + if (reg_set) + return nullptr; + return &m_reg_set0; +} + +bool RegisterContextHistory::ReadRegister( + const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) { + if (!reg_info) + return false; + uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric]; + if (reg_number == LLDB_REGNUM_GENERIC_PC) { + value.SetUInt(m_pc_value, reg_info->byte_size); + return true; + } + return false; +} + +bool RegisterContextHistory::WriteRegister( + const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) { + return false; +} + +bool RegisterContextHistory::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { + return false; +} + +bool RegisterContextHistory::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + return false; +} + +uint32_t RegisterContextHistory::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC) + return 0; + return LLDB_INVALID_REGNUM; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h new file mode 100644 index 000000000000..a1eadac5d1b7 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h @@ -0,0 +1,67 @@ +//===-- RegisterContextHistory.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_REGISTERCONTEXTHISTORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H + +#include <vector> + +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class RegisterContextHistory : public lldb_private::RegisterContext { +public: + typedef std::shared_ptr<RegisterContextHistory> SharedPtr; + + RegisterContextHistory(Thread &thread, uint32_t concrete_frame_idx, + uint32_t address_byte_size, lldb::addr_t pc_value); + + ~RegisterContextHistory() override; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override; + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) override; + + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + +private: + // For RegisterContextLLDB only + + lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only) + lldb_private::RegisterInfo m_pc_reg_info; + + lldb::addr_t m_pc_value; + + RegisterContextHistory(const RegisterContextHistory &) = delete; + const RegisterContextHistory & + operator=(const RegisterContextHistory &) = delete; +}; +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp new file mode 100644 index 000000000000..9e022baa297b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp @@ -0,0 +1,125 @@ +//===-- RegisterContextLinux_i386.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 "RegisterContextLinux_i386.h" +#include "RegisterContextPOSIX_x86.h" + +using namespace lldb_private; +using namespace lldb; + +struct GPR { + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esi; + uint32_t edi; + uint32_t ebp; + uint32_t eax; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t gs; + uint32_t orig_eax; + uint32_t eip; + uint32_t cs; + uint32_t eflags; + uint32_t esp; + uint32_t ss; +}; + +struct FPR_i386 { + uint16_t fctrl; // FPU Control Word (fcw) + uint16_t fstat; // FPU Status Word (fsw) + uint16_t ftag; // FPU Tag Word (ftw) + uint16_t fop; // Last Instruction Opcode (fop) + union { + struct { + uint64_t fip; // Instruction Pointer + uint64_t fdp; // Data Pointer + } x86_64; + struct { + uint32_t fioff; // FPU IP Offset (fip) + uint32_t fiseg; // FPU IP Selector (fcs) + uint32_t fooff; // FPU Operand Pointer Offset (foo) + uint32_t foseg; // FPU Operand Pointer Selector (fos) + } i386_; // Added _ in the end to avoid error with gcc defining i386 in some + // cases + } ptr; + uint32_t mxcsr; // MXCSR Register State + uint32_t mxcsrmask; // MXCSR Mask + MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes + XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes + uint32_t padding[56]; +}; + +struct UserArea { + GPR regs; // General purpose registers. + int32_t fpvalid; // True if FPU is being used. + FPR_i386 i387; // FPU registers. + uint32_t tsize; // Text segment size. + uint32_t dsize; // Data segment size. + uint32_t ssize; // Stack segment size. + uint32_t start_code; // VM address of text. + uint32_t start_stack; // VM address of stack bottom (top in rsp). + int32_t signal; // Signal causing core dump. + int32_t reserved; // Unused. + uint32_t ar0; // Location of GPR's. + uint32_t fpstate; // Location of FPR's. Should be a FXSTATE *, but this + // has to be 32-bits even on 64-bit systems. + uint32_t magic; // Identifier for core dumps. + char u_comm[32]; // Command causing core dump. + uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7). +}; + +#define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0]) +#define DR_0_OFFSET 0xFC +#define DR_OFFSET(reg_index) (DR_0_OFFSET + (reg_index * 4)) +#define FPR_SIZE(reg) sizeof(((FPR_i386 *)NULL)->reg) + +// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. +#define DECLARE_REGISTER_INFOS_I386_STRUCT +#include "RegisterInfos_i386.h" +#undef DECLARE_REGISTER_INFOS_I386_STRUCT + +RegisterContextLinux_i386::RegisterContextLinux_i386( + const ArchSpec &target_arch) + : RegisterContextLinux_x86( + target_arch, + {"orig_eax", + nullptr, + sizeof(((GPR *)nullptr)->orig_eax), + (LLVM_EXTENSION offsetof(GPR, orig_eax)), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr}) {} + +size_t RegisterContextLinux_i386::GetGPRSizeStatic() { return sizeof(GPR); } + +const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const { + switch (GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + return g_register_infos_i386; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterContextLinux_i386::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])); +} + +uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const { + return static_cast<uint32_t>(k_num_user_registers_i386); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h new file mode 100644 index 000000000000..c10613993689 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h @@ -0,0 +1,29 @@ +//===-- RegisterContextLinux_i386.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_REGISTERCONTEXTLINUX_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H + +#include "Plugins/Process/Utility/RegisterContextLinux_x86.h" + +class RegisterContextLinux_i386 + : public lldb_private::RegisterContextLinux_x86 { +public: + RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch); + + static size_t GetGPRSizeStatic(); + size_t GetGPRSize() const override { return GetGPRSizeStatic(); } + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp new file mode 100644 index 000000000000..77627cfbdefe --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp @@ -0,0 +1,69 @@ +//===-- RegisterContextLinux_s390x.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 "RegisterContextLinux_s390x.h" +#include "RegisterContextPOSIX_s390x.h" + +using namespace lldb_private; +using namespace lldb; + +// Include RegisterInfos_s390x to declare our g_register_infos_s390x structure. +#define DECLARE_REGISTER_INFOS_S390X_STRUCT +#include "RegisterInfos_s390x.h" +#undef DECLARE_REGISTER_INFOS_S390X_STRUCT + +static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::systemz: + return g_register_infos_s390x; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::systemz: + return k_num_registers_s390x; + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::systemz: + return k_num_user_registers_s390x + k_num_linux_registers_s390x; + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterContextLinux_s390x::RegisterContextLinux_s390x( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch), + m_register_info_p(GetRegisterInfoPtr(target_arch)), + m_register_info_count(GetRegisterInfoCount(target_arch)), + m_user_register_count(GetUserRegisterInfoCount(target_arch)) {} + +const RegisterInfo *RegisterContextLinux_s390x::GetRegisterInfo() const { + return m_register_info_p; +} + +uint32_t RegisterContextLinux_s390x::GetRegisterCount() const { + return m_register_info_count; +} + +uint32_t RegisterContextLinux_s390x::GetUserRegisterCount() const { + return m_user_register_count; +} + +size_t RegisterContextLinux_s390x::GetGPRSize() const { return 0; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h new file mode 100644 index 000000000000..6bfe34de7acf --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h @@ -0,0 +1,32 @@ +//===-- RegisterContextLinux_s390x.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_REGISTERCONTEXTLINUX_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_S390X_H + +#include "RegisterInfoInterface.h" + +class RegisterContextLinux_s390x : public lldb_private::RegisterInfoInterface { +public: + RegisterContextLinux_s390x(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + uint32_t m_register_info_count; + uint32_t m_user_register_count; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86.h new file mode 100644 index 000000000000..0e1863864aa6 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86.h @@ -0,0 +1,30 @@ +//===-- RegisterContextLinux_i386.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_REGISTERCONTEXTLINUX_X86_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_H + +#include "RegisterInfoInterface.h" + +namespace lldb_private { + +class RegisterContextLinux_x86 : public RegisterInfoInterface { +public: + RegisterContextLinux_x86(const ArchSpec &target_arch, + RegisterInfo orig_ax_info) + : RegisterInfoInterface(target_arch), m_orig_ax_info(orig_ax_info) {} + + const RegisterInfo &GetOrigAxInfo() const { return m_orig_ax_info; } + +private: + lldb_private::RegisterInfo m_orig_ax_info; +}; + +} // namespace lldb_private + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp new file mode 100644 index 000000000000..63c034a858d7 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp @@ -0,0 +1,184 @@ +//===-- RegisterContextLinux_x86_64.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 "RegisterContextLinux_x86_64.h" +#include "RegisterContextLinux_i386.h" +#include "RegisterContextPOSIX_x86.h" +#include <vector> + +using namespace lldb_private; +using namespace lldb; + +typedef struct _GPR { + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t rbp; + uint64_t rbx; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rsi; + uint64_t rdi; + uint64_t orig_rax; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; + uint64_t fs_base; + uint64_t gs_base; + uint64_t ds; + uint64_t es; + uint64_t fs; + uint64_t gs; +} GPR; + +struct DBG { + uint64_t dr[8]; +}; + +struct UserArea { + GPR gpr; // General purpose registers. + int32_t fpvalid; // True if FPU is being used. + int32_t pad0; + FXSAVE fpr; // General purpose floating point registers (see FPR for extended + // register sets). + uint64_t tsize; // Text segment size. + uint64_t dsize; // Data segment size. + uint64_t ssize; // Stack segment size. + uint64_t start_code; // VM address of text. + uint64_t start_stack; // VM address of stack bottom (top in rsp). + int64_t signal; // Signal causing core dump. + int32_t reserved; // Unused. + int32_t pad1; + uint64_t ar0; // Location of GPR's. + FXSAVE *fpstate; // Location of FPR's. + uint64_t magic; // Identifier for core dumps. + char u_comm[32]; // Command causing core dump. + DBG dbg; // Debug registers. + uint64_t error_code; // CPU error code. + uint64_t fault_address; // Control register CR3. +}; + +#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_with_base +// structure. +#define DECLARE_REGISTER_INFOS_X86_64_STRUCT +#include "RegisterInfos_x86_64_with_base.h" +#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() { + static std::vector<lldb_private::RegisterInfo> g_register_infos; + return g_register_infos; +} + +static const RegisterInfo * +GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) { + std::vector<lldb_private::RegisterInfo> &g_register_infos = + GetPrivateRegisterInfoVector(); + + // Allocate RegisterInfo only once + if (g_register_infos.empty()) { + // Copy the register information from base class + std::unique_ptr<RegisterContextLinux_i386> reg_interface( + new RegisterContextLinux_i386(arch)); + const RegisterInfo *base_info = reg_interface->GetRegisterInfo(); + g_register_infos.insert(g_register_infos.end(), &base_info[0], + &base_info[k_num_registers_i386]); + +// Include RegisterInfos_x86_64 to update the g_register_infos structure +// with x86_64 offsets. +#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS +#include "RegisterInfos_x86_64_with_base.h" +#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + } + + return &g_register_infos[0]; +} + +static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return GetRegisterInfo_i386(target_arch); + case llvm::Triple::x86_64: + return g_register_infos_x86_64_with_base; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: { + assert(!GetPrivateRegisterInfoVector().empty() && + "i386 register info not yet filled."); + return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size()); + } + case llvm::Triple::x86_64: + return static_cast<uint32_t>(sizeof(g_register_infos_x86_64_with_base) / + sizeof(g_register_infos_x86_64_with_base[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return static_cast<uint32_t>(k_num_user_registers_i386); + case llvm::Triple::x86_64: + return static_cast<uint32_t>(x86_64_with_base::k_num_user_registers); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterContextLinux_x86_64::RegisterContextLinux_x86_64( + const ArchSpec &target_arch) + : lldb_private::RegisterContextLinux_x86( + target_arch, + {"orig_rax", + nullptr, + sizeof(((GPR *)nullptr)->orig_rax), + (LLVM_EXTENSION offsetof(GPR, orig_rax)), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr}), + m_register_info_p(GetRegisterInfoPtr(target_arch)), + m_register_info_count(GetRegisterInfoCount(target_arch)), + m_user_register_count(GetUserRegisterInfoCount(target_arch)) {} + +size_t RegisterContextLinux_x86_64::GetGPRSizeStatic() { return sizeof(GPR); } + +const RegisterInfo *RegisterContextLinux_x86_64::GetRegisterInfo() const { + return m_register_info_p; +} + +uint32_t RegisterContextLinux_x86_64::GetRegisterCount() const { + return m_register_info_count; +} + +uint32_t RegisterContextLinux_x86_64::GetUserRegisterCount() const { + return m_user_register_count; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h new file mode 100644 index 000000000000..d141ba66b4e2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h @@ -0,0 +1,34 @@ +//===-- RegisterContextLinux_x86_64.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_REGISTERCONTEXTLINUX_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H + +#include "Plugins/Process/Utility/RegisterContextLinux_x86.h" + +class RegisterContextLinux_x86_64 + : public lldb_private::RegisterContextLinux_x86 { +public: + RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch); + + static size_t GetGPRSizeStatic(); + size_t GetGPRSize() const override { return GetGPRSizeStatic(); } + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + uint32_t m_register_info_count; + uint32_t m_user_register_count; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp new file mode 100644 index 000000000000..067d1c3705e4 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp @@ -0,0 +1,74 @@ +//===-- RegisterContextMach_arm.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 +// +//===----------------------------------------------------------------------===// + +#if defined(__APPLE__) + +#include "RegisterContextMach_arm.h" + +#include <mach/mach_types.h> +#include <mach/thread_act.h> + + +using namespace lldb; +using namespace lldb_private; + +RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread, + uint32_t concrete_frame_idx) + : RegisterContextDarwin_arm(thread, concrete_frame_idx) {} + +RegisterContextMach_arm::~RegisterContextMach_arm() = default; + +int RegisterContextMach_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { + mach_msg_type_number_t count = GPRWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); +} + +int RegisterContextMach_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) { + mach_msg_type_number_t count = FPUWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); +} + +int RegisterContextMach_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) { + mach_msg_type_number_t count = EXCWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); +} + +int RegisterContextMach_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) { + mach_msg_type_number_t count = DBGWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&dbg, &count); +} + +int RegisterContextMach_arm::DoWriteGPR(lldb::tid_t tid, int flavor, + const GPR &gpr) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)), + GPRWordCount); +} + +int RegisterContextMach_arm::DoWriteFPU(lldb::tid_t tid, int flavor, + const FPU &fpu) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)), + FPUWordCount); +} + +int RegisterContextMach_arm::DoWriteEXC(lldb::tid_t tid, int flavor, + const EXC &exc) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)), + EXCWordCount); +} + +int RegisterContextMach_arm::DoWriteDBG(lldb::tid_t tid, int flavor, + const DBG &dbg) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<DBG *>(&dbg)), + DBGWordCount); +} + +#endif 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 new file mode 100644 index 000000000000..fedd0062c99c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h @@ -0,0 +1,39 @@ +//===-- RegisterContextMach_arm.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_REGISTERCONTEXTMACH_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H + +#include "RegisterContextDarwin_arm.h" + +class RegisterContextMach_arm : public RegisterContextDarwin_arm { +public: + RegisterContextMach_arm(lldb_private::Thread &thread, + uint32_t concrete_frame_idx); + + ~RegisterContextMach_arm() override; + +protected: + int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; + + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override; + + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override; + + int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override; + + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override; + + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override; + + int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override; + + 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.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp new file mode 100644 index 000000000000..fe5cecef1b0c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp @@ -0,0 +1,60 @@ +//===-- RegisterContextMach_i386.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 +// +//===----------------------------------------------------------------------===// + +#if defined(__APPLE__) + +#include <mach/thread_act.h> + +#include "RegisterContextMach_i386.h" + +using namespace lldb; +using namespace lldb_private; + +RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread, + uint32_t concrete_frame_idx) + : RegisterContextDarwin_i386(thread, concrete_frame_idx) {} + +RegisterContextMach_i386::~RegisterContextMach_i386() = default; + +int RegisterContextMach_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { + mach_msg_type_number_t count = GPRWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); +} + +int RegisterContextMach_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) { + mach_msg_type_number_t count = FPUWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); +} + +int RegisterContextMach_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) { + mach_msg_type_number_t count = EXCWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); +} + +int RegisterContextMach_i386::DoWriteGPR(lldb::tid_t tid, int flavor, + const GPR &gpr) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)), + GPRWordCount); +} + +int RegisterContextMach_i386::DoWriteFPU(lldb::tid_t tid, int flavor, + const FPU &fpu) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)), + FPUWordCount); +} + +int RegisterContextMach_i386::DoWriteEXC(lldb::tid_t tid, int flavor, + const EXC &exc) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)), + EXCWordCount); +} + +#endif 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 new file mode 100644 index 000000000000..8bdac083863d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h @@ -0,0 +1,35 @@ +//===-- RegisterContextMach_i386.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_REGISTERCONTEXTMACH_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H + +#include "RegisterContextDarwin_i386.h" + +class RegisterContextMach_i386 : public RegisterContextDarwin_i386 { +public: + RegisterContextMach_i386(lldb_private::Thread &thread, + uint32_t concrete_frame_idx); + + ~RegisterContextMach_i386() override; + +protected: + int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; + + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override; + + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override; + + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override; + + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override; + + 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.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp new file mode 100644 index 000000000000..a3d8c4f649d2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp @@ -0,0 +1,63 @@ +//===-- RegisterContextMach_x86_64.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 +// +//===----------------------------------------------------------------------===// + +#if defined(__APPLE__) + +#include <mach/thread_act.h> + +#include "RegisterContextMach_x86_64.h" + +using namespace lldb; +using namespace lldb_private; + +RegisterContextMach_x86_64::RegisterContextMach_x86_64( + Thread &thread, uint32_t concrete_frame_idx) + : RegisterContextDarwin_x86_64(thread, concrete_frame_idx) {} + +RegisterContextMach_x86_64::~RegisterContextMach_x86_64() = default; + +int RegisterContextMach_x86_64::DoReadGPR(lldb::tid_t tid, int flavor, + GPR &gpr) { + mach_msg_type_number_t count = GPRWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); +} + +int RegisterContextMach_x86_64::DoReadFPU(lldb::tid_t tid, int flavor, + FPU &fpu) { + mach_msg_type_number_t count = FPUWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); +} + +int RegisterContextMach_x86_64::DoReadEXC(lldb::tid_t tid, int flavor, + EXC &exc) { + mach_msg_type_number_t count = EXCWordCount; + return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); +} + +int RegisterContextMach_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor, + const GPR &gpr) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)), + GPRWordCount); +} + +int RegisterContextMach_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor, + const FPU &fpu) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)), + FPUWordCount); +} + +int RegisterContextMach_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor, + const EXC &exc) { + return ::thread_set_state( + tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)), + EXCWordCount); +} + +#endif 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 new file mode 100644 index 000000000000..99841a8e9a8d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h @@ -0,0 +1,36 @@ +//===-- RegisterContextMach_x86_64.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_REGISTERCONTEXTMACH_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H + +#include "RegisterContextDarwin_x86_64.h" + +class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64 { +public: + RegisterContextMach_x86_64(lldb_private::Thread &thread, + uint32_t concrete_frame_idx); + + ~RegisterContextMach_x86_64() override; + +protected: + int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override; + + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override; + + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override; + + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override; + + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override; + + 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/RegisterContextMemory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp new file mode 100644 index 000000000000..84a19d5b1303 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -0,0 +1,139 @@ +//===-- RegisterContextMemory.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 "RegisterContextMemory.h" + +#include "lldb/Target/Process.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +// RegisterContextMemory constructor +RegisterContextMemory::RegisterContextMemory(Thread &thread, + uint32_t concrete_frame_idx, + DynamicRegisterInfo ®_infos, + addr_t reg_data_addr) + : RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos), + m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) { + // Resize our vector of bools to contain one bool for every register. We will + // use these boolean values to know when a register value is valid in + // m_reg_data. + const size_t num_regs = reg_infos.GetNumRegisters(); + assert(num_regs > 0); + m_reg_valid.resize(num_regs); + + // Make a heap based buffer that is big enough to store all registers + m_data = + std::make_shared<DataBufferHeap>(reg_infos.GetRegisterDataByteSize(), 0); + m_reg_data.SetData(m_data); +} + +// Destructor +RegisterContextMemory::~RegisterContextMemory() = default; + +void RegisterContextMemory::InvalidateAllRegisters() { + if (m_reg_data_addr != LLDB_INVALID_ADDRESS) + SetAllRegisterValid(false); +} + +void RegisterContextMemory::SetAllRegisterValid(bool b) { + std::vector<bool>::iterator pos, end = m_reg_valid.end(); + for (pos = m_reg_valid.begin(); pos != end; ++pos) + *pos = b; +} + +size_t RegisterContextMemory::GetRegisterCount() { + return m_reg_infos.GetNumRegisters(); +} + +const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) { + return m_reg_infos.GetRegisterInfoAtIndex(reg); +} + +size_t RegisterContextMemory::GetRegisterSetCount() { + return m_reg_infos.GetNumRegisterSets(); +} + +const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) { + return m_reg_infos.GetRegisterSet(reg_set); +} + +uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num); +} + +bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; + if (!m_reg_valid[reg_num]) { + if (!ReadAllRegisterValues(m_data)) + return false; + } + const bool partial_data_ok = false; + return reg_value + .SetValueFromData(*reg_info, m_reg_data, reg_info->byte_offset, + partial_data_ok) + .Success(); +} + +bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) { + if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { + const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; + addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset; + Status error(WriteRegisterValueToMemory(reg_info, reg_addr, + reg_info->byte_size, reg_value)); + m_reg_valid[reg_num] = false; + return error.Success(); + } + return false; +} + +bool RegisterContextMemory::ReadAllRegisterValues( + WritableDataBufferSP &data_sp) { + if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { + ProcessSP process_sp(CalculateProcess()); + if (process_sp) { + Status error; + if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), + data_sp->GetByteSize(), + error) == data_sp->GetByteSize()) { + SetAllRegisterValid(true); + return true; + } + } + } + return false; +} + +bool RegisterContextMemory::WriteAllRegisterValues( + const DataBufferSP &data_sp) { + if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { + ProcessSP process_sp(CalculateProcess()); + if (process_sp) { + Status error; + SetAllRegisterValid(false); + if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), + data_sp->GetByteSize(), + error) == data_sp->GetByteSize()) + return true; + } + } + return false; +} + +void RegisterContextMemory::SetAllRegisterData( + const lldb::DataBufferSP &data_sp) { + m_reg_data.SetData(data_sp); + SetAllRegisterValid(true); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h new file mode 100644 index 000000000000..2aad99ec9b21 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -0,0 +1,75 @@ +//===-- RegisterContextMemory.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_REGISTERCONTEXTMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H + +#include <vector> + +#include "lldb/Target/DynamicRegisterInfo.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/lldb-private.h" + +class RegisterContextMemory : public lldb_private::RegisterContext { +public: + RegisterContextMemory(lldb_private::Thread &thread, + uint32_t concrete_frame_idx, + lldb_private::DynamicRegisterInfo ®_info, + lldb::addr_t reg_data_addr); + + ~RegisterContextMemory() override; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // If all of the thread register are in a contiguous buffer in + // memory, then the default ReadRegister/WriteRegister and + // ReadAllRegisterValues/WriteAllRegisterValues will work. If thread + // registers are not contiguous, clients will want to subclass this + // class and modify the read/write functions as needed. + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue ®_value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue ®_value) override; + + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + void SetAllRegisterData(const lldb::DataBufferSP &data_sp); + +protected: + void SetAllRegisterValid(bool b); + + lldb_private::DynamicRegisterInfo &m_reg_infos; + std::vector<bool> m_reg_valid; + lldb::WritableDataBufferSP m_data; + lldb_private::DataExtractor m_reg_data; + lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register + // context that is stored in memmory + +private: + RegisterContextMemory(const RegisterContextMemory &) = delete; + const RegisterContextMemory & + operator=(const RegisterContextMemory &) = delete; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp new file mode 100644 index 000000000000..a160c87db6cf --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp @@ -0,0 +1,96 @@ +//===-- RegisterContextNetBSD_i386.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 "RegisterContextNetBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" + +using namespace lldb_private; +using namespace lldb; + +// this needs to match 'struct reg' +struct GPR { + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t gs; +}; + +struct FPR_i386 { + uint16_t fctrl; // FPU Control Word (fcw) + uint16_t fstat; // FPU Status Word (fsw) + uint16_t ftag; // FPU Tag Word (ftw) + uint16_t fop; // Last Instruction Opcode (fop) + union { + struct { + uint64_t fip; // Instruction Pointer + uint64_t fdp; // Data Pointer + } x86_64; + struct { + uint32_t fioff; // FPU IP Offset (fip) + uint32_t fiseg; // FPU IP Selector (fcs) + uint32_t fooff; // FPU Operand Pointer Offset (foo) + uint32_t foseg; // FPU Operand Pointer Selector (fos) + } i386_; // Added _ in the end to avoid error with gcc defining i386 in some + // cases + } ptr; + uint32_t mxcsr; // MXCSR Register State + uint32_t mxcsrmask; // MXCSR Mask + MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes + XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes + uint32_t padding[56]; +}; + +struct UserArea { + GPR gpr; + FPR_i386 i387; + uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7). + uint32_t tlsbase; +}; + +#define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0]) +#define DR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index])) + +// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. +#define DECLARE_REGISTER_INFOS_I386_STRUCT +#include "RegisterInfos_i386.h" +#undef DECLARE_REGISTER_INFOS_I386_STRUCT + +RegisterContextNetBSD_i386::RegisterContextNetBSD_i386( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +size_t RegisterContextNetBSD_i386::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextNetBSD_i386::GetRegisterInfo() const { + switch (GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + return g_register_infos_i386; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterContextNetBSD_i386::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h new file mode 100644 index 000000000000..742bb18b8306 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h @@ -0,0 +1,25 @@ +//===-- RegisterContextNetBSD_i386.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_REGISTERCONTEXTNETBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_I386_H + +#include "RegisterInfoInterface.h" + +class RegisterContextNetBSD_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextNetBSD_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp new file mode 100644 index 000000000000..32bb7952820d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp @@ -0,0 +1,178 @@ +//===-- RegisterContextNetBSD_x86_64.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 "RegisterContextNetBSD_x86_64.h" +#include "RegisterContextNetBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" +#include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" +#include <cassert> +#include <cstddef> + +using namespace lldb_private; +using namespace lldb; + +// src/sys/arch/amd64/include/frame_regs.h +typedef struct _GPR { + uint64_t rdi; /* 0 */ + uint64_t rsi; /* 1 */ + uint64_t rdx; /* 2 */ + uint64_t rcx; /* 3 */ + uint64_t r8; /* 4 */ + uint64_t r9; /* 5 */ + uint64_t r10; /* 6 */ + uint64_t r11; /* 7 */ + uint64_t r12; /* 8 */ + uint64_t r13; /* 9 */ + uint64_t r14; /* 10 */ + uint64_t r15; /* 11 */ + uint64_t rbp; /* 12 */ + uint64_t rbx; /* 13 */ + uint64_t rax; /* 14 */ + uint64_t gs; /* 15 */ + uint64_t fs; /* 16 */ + uint64_t es; /* 17 */ + uint64_t ds; /* 18 */ + uint64_t trapno; /* 19 */ + uint64_t err; /* 20 */ + uint64_t rip; /* 21 */ + uint64_t cs; /* 22 */ + uint64_t rflags; /* 23 */ + uint64_t rsp; /* 24 */ + uint64_t ss; /* 25 */ +} GPR; + +struct DBG { + uint64_t dr[16]; /* debug registers */ + /* Index 0-3: debug address registers */ + /* Index 4-5: reserved */ + /* Index 6: debug status */ + /* Index 7: debug control */ + /* Index 8-15: reserved */ +}; + +/* + * src/sys/arch/amd64/include/mcontext.h + * + * typedef struct { + * __gregset_t __gregs; + * __greg_t _mc_tlsbase; + * __fpregset_t __fpregs; + * } mcontext_t; + */ + +struct UserArea { + GPR gpr; + uint64_t mc_tlsbase; + FPR fpr; + DBG dbg; +}; + +#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. +#define DECLARE_REGISTER_INFOS_X86_64_STRUCT +#include "RegisterInfos_x86_64.h" +#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() { + static std::vector<lldb_private::RegisterInfo> g_register_infos; + return g_register_infos; +} + +static const RegisterInfo * +GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) { + std::vector<lldb_private::RegisterInfo> &g_register_infos = + GetPrivateRegisterInfoVector(); + + // Allocate RegisterInfo only once + if (g_register_infos.empty()) { + // Copy the register information from base class + std::unique_ptr<RegisterContextNetBSD_i386> reg_interface( + new RegisterContextNetBSD_i386(arch)); + const RegisterInfo *base_info = reg_interface->GetRegisterInfo(); + g_register_infos.insert(g_register_infos.end(), &base_info[0], + &base_info[k_num_registers_i386]); + +// Include RegisterInfos_x86_64 to update the g_register_infos structure +// with x86_64 offsets. +#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS +#include "RegisterInfos_x86_64.h" +#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + } + + return &g_register_infos[0]; +} + +static const RegisterInfo * +PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return GetRegisterInfo_i386(target_arch); + case llvm::Triple::x86_64: + return g_register_infos_x86_64; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t +PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: { + assert(!GetPrivateRegisterInfoVector().empty() && + "i386 register info not yet filled."); + return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size()); + } + case llvm::Triple::x86_64: + return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) / + sizeof(g_register_infos_x86_64[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +static uint32_t +PrivateGetUserRegisterCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return static_cast<uint32_t>(k_num_user_registers_i386); + case llvm::Triple::x86_64: + return static_cast<uint32_t>(k_num_user_registers_x86_64); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch), + m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)), + m_register_count(PrivateGetRegisterCount(target_arch)), + m_user_register_count(PrivateGetUserRegisterCount(target_arch)) {} + +size_t RegisterContextNetBSD_x86_64::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextNetBSD_x86_64::GetRegisterInfo() const { + return m_register_info_p; +} + +uint32_t RegisterContextNetBSD_x86_64::GetRegisterCount() const { + return m_register_count; +} + +uint32_t RegisterContextNetBSD_x86_64::GetUserRegisterCount() const { + return m_user_register_count; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h new file mode 100644 index 000000000000..6f9787506013 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h @@ -0,0 +1,33 @@ +//===-- RegisterContextNetBSD_x86_64.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_REGISTERCONTEXTNETBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_X86_64_H + +#include "RegisterInfoInterface.h" + +class RegisterContextNetBSD_x86_64 + : public lldb_private::RegisterInfoInterface { +public: + RegisterContextNetBSD_x86_64(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + const uint32_t m_register_count; + const uint32_t m_user_register_count; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp new file mode 100644 index 000000000000..ddf6cc5c3c65 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp @@ -0,0 +1,77 @@ +//===-- RegisterContextOpenBSD_i386.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 "RegisterContextOpenBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" + +using namespace lldb_private; +using namespace lldb; + +// /usr/include/machine/reg.h +struct GPR { + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t gs; +}; + +struct dbreg { + uint32_t dr[8]; /* debug registers */ + /* Index 0-3: debug address registers */ + /* Index 4-5: reserved */ + /* Index 6: debug status */ + /* Index 7: debug control */ +}; + +using FPR_i386 = FXSAVE; + +struct UserArea { + GPR gpr; + FPR_i386 i387; +}; + +#define DR_SIZE sizeof(uint32_t) +#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(dbreg, dr[reg_index])) + +// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. +#define DECLARE_REGISTER_INFOS_I386_STRUCT +#include "RegisterInfos_i386.h" +#undef DECLARE_REGISTER_INFOS_I386_STRUCT + +RegisterContextOpenBSD_i386::RegisterContextOpenBSD_i386( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +size_t RegisterContextOpenBSD_i386::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextOpenBSD_i386::GetRegisterInfo() const { + switch (GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return g_register_infos_i386; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterContextOpenBSD_i386::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h new file mode 100644 index 000000000000..e6e24525b7fd --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h @@ -0,0 +1,25 @@ +//===-- RegisterContextOpenBSD_i386.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_REGISTERCONTEXTOPENBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_I386_H + +#include "RegisterInfoInterface.h" + +class RegisterContextOpenBSD_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextOpenBSD_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp new file mode 100644 index 000000000000..05c1f83efded --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp @@ -0,0 +1,104 @@ +//===-- RegisterContextOpenBSD_x86_64.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 "RegisterContextOpenBSD_x86_64.h" +#include "RegisterContextPOSIX_x86.h" +#include <vector> + +using namespace lldb_private; +using namespace lldb; + +// /usr/include/machine/reg.h +typedef struct _GPR { + uint64_t rdi; + uint64_t rsi; + uint64_t rdx; + uint64_t rcx; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t rbp; + uint64_t rbx; + uint64_t rax; + uint64_t rsp; + uint64_t rip; + uint64_t rflags; + uint64_t cs; + uint64_t ss; + uint64_t ds; + uint64_t es; + uint64_t fs; + uint64_t gs; +} GPR; + +struct DBG { + uint64_t dr[16]; /* debug registers */ + /* Index 0-3: debug address registers */ + /* Index 4-5: reserved */ + /* Index 6: debug status */ + /* Index 7: debug control */ + /* Index 8-15: reserved */ +}; + +struct UserArea { + GPR gpr; + FPR fpr; + DBG dbg; +}; + +#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index])) + +// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 +// structure. +#define DECLARE_REGISTER_INFOS_X86_64_STRUCT +#include "RegisterInfos_x86_64.h" +#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +static const RegisterInfo * +PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86_64: + return g_register_infos_x86_64; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t +PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86_64: + return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) / + sizeof(g_register_infos_x86_64[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterContextOpenBSD_x86_64::RegisterContextOpenBSD_x86_64( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch), + m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)), + m_register_count(PrivateGetRegisterCount(target_arch)) {} + +size_t RegisterContextOpenBSD_x86_64::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextOpenBSD_x86_64::GetRegisterInfo() const { + return m_register_info_p; +} + +uint32_t RegisterContextOpenBSD_x86_64::GetRegisterCount() const { + return m_register_count; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h new file mode 100644 index 000000000000..b399c721546a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h @@ -0,0 +1,30 @@ +//===-- RegisterContextOpenBSD_x86_64.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_REGISTERCONTEXTOPENBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_X86_64_H + +#include "RegisterInfoInterface.h" + +class RegisterContextOpenBSD_x86_64 + : public lldb_private::RegisterInfoInterface { +public: + RegisterContextOpenBSD_x86_64(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + const uint32_t m_register_count; +}; + +#endif 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 new file mode 100644 index 000000000000..684176bccdf0 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp @@ -0,0 +1,98 @@ +//===-- RegisterContextPOSIX_arm.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 <cerrno> +#include <cstdint> +#include <cstring> + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_arm.h" + +using namespace lldb; +using namespace lldb_private; + +bool RegisterContextPOSIX_arm::IsGPR(unsigned reg) { + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm::GPRegSet) + return true; + return false; +} + +bool RegisterContextPOSIX_arm::IsFPR(unsigned reg) { + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm::FPRegSet) + return true; + return false; +} + +RegisterContextPOSIX_arm::RegisterContextPOSIX_arm( + 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() = default; + +void RegisterContextPOSIX_arm::Invalidate() {} + +void RegisterContextPOSIX_arm::InvalidateAllRegisters() {} + +unsigned RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg) { + return m_register_info_up->GetRegisterInfo()[reg].byte_offset; +} + +unsigned RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg) { + return m_register_info_up->GetRegisterInfo()[reg].byte_size; +} + +size_t RegisterContextPOSIX_arm::GetRegisterCount() { + return m_register_info_up->GetRegisterCount(); +} + +size_t RegisterContextPOSIX_arm::GetGPRSize() { + return m_register_info_up->GetGPRSize(); +} + +const lldb_private::RegisterInfo *RegisterContextPOSIX_arm::GetRegisterInfo() { + // Commonly, this method is overridden and g_register_infos is copied and + // specialized. So, use GetRegisterInfo() rather than g_register_infos in + // this scope. + return m_register_info_up->GetRegisterInfo(); +} + +const lldb_private::RegisterInfo * +RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg) { + if (reg < GetRegisterCount()) + return &GetRegisterInfo()[reg]; + + return nullptr; +} + +size_t RegisterContextPOSIX_arm::GetRegisterSetCount() { + return m_register_info_up->GetRegisterSetCount(); +} + +const lldb_private::RegisterSet * +RegisterContextPOSIX_arm::GetRegisterSet(size_t set) { + return m_register_info_up->GetRegisterSet(set); +} + +const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) { + 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 new file mode 100644 index 000000000000..099c37d46f49 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h @@ -0,0 +1,62 @@ +//===-- RegisterContextPOSIX_arm.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_REGISTERCONTEXTPOSIX_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H + +#include "RegisterInfoInterface.h" +#include "RegisterInfoPOSIX_arm.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_arm : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_arm( + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_arm> register_info); + + ~RegisterContextPOSIX_arm() override; + + void Invalidate(); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + +protected: + std::unique_ptr<RegisterInfoPOSIX_arm> m_register_info_up; + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm::FPU); } + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H 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 new file mode 100644 index 000000000000..50e25568f2ae --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -0,0 +1,119 @@ +//===-- RegisterContextPOSIX_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 <cerrno> +#include <cstdint> +#include <cstring> + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_arm64.h" + +using namespace lldb; +using namespace lldb_private; + +bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg) { + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm64::GPRegSet) + return true; + return false; +} + +bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) { + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm64::FPRegSet) + return true; + return false; +} + +bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const { + return m_register_info_up->IsSVEReg(reg); +} + +bool RegisterContextPOSIX_arm64::IsSME(unsigned reg) const { + return m_register_info_up->IsSMEReg(reg); +} + +bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const { + return m_register_info_up->IsPAuthReg(reg); +} + +bool RegisterContextPOSIX_arm64::IsTLS(unsigned reg) const { + return m_register_info_up->IsTLSReg(reg); +} + +bool RegisterContextPOSIX_arm64::IsMTE(unsigned reg) const { + return m_register_info_up->IsMTEReg(reg); +} + +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)) {} + +RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() = default; + +void RegisterContextPOSIX_arm64::Invalidate() {} + +void RegisterContextPOSIX_arm64::InvalidateAllRegisters() {} + +unsigned RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg) { + return m_register_info_up->GetRegisterInfo()[reg].byte_offset; +} + +unsigned RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg) { + return m_register_info_up->GetRegisterInfo()[reg].byte_size; +} + +size_t RegisterContextPOSIX_arm64::GetRegisterCount() { + return m_register_info_up->GetRegisterCount(); +} + +size_t RegisterContextPOSIX_arm64::GetGPRSize() { + return m_register_info_up->GetGPRSize(); +} + +const lldb_private::RegisterInfo * +RegisterContextPOSIX_arm64::GetRegisterInfo() { + // Commonly, this method is overridden and g_register_infos is copied and + // specialized. So, use GetRegisterInfo() rather than g_register_infos in + // this scope. + return m_register_info_up->GetRegisterInfo(); +} + +const lldb_private::RegisterInfo * +RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) { + if (reg < GetRegisterCount()) + return &GetRegisterInfo()[reg]; + + return nullptr; +} + +size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() { + return m_register_info_up->GetRegisterSetCount(); +} + +const lldb_private::RegisterSet * +RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) { + return m_register_info_up->GetRegisterSet(set); +} + +const char *RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg) { + if (reg < GetRegisterCount()) + return GetRegisterInfo()[reg].name; + return nullptr; +} 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 new file mode 100644 index 000000000000..b1226b25b4be --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -0,0 +1,86 @@ +//===-- RegisterContextPOSIX_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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H + +#include "RegisterInfoInterface.h" +#include "RegisterInfoPOSIX_arm64.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_arm64( + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_arm64> register_info); + + ~RegisterContextPOSIX_arm64() override; + + void Invalidate(); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + +protected: + std::unique_ptr<RegisterInfoPOSIX_arm64> m_register_info_up; + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); } + + bool IsSVE(unsigned reg) const; + bool IsPAuth(unsigned reg) const; + bool IsTLS(unsigned reg) const; + bool IsSME(unsigned reg) const; + bool IsMTE(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); + } + bool IsSMEZA(unsigned reg) const { + return m_register_info_up->IsSMERegZA(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; + virtual bool WriteFPR() = 0; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp new file mode 100644 index 000000000000..a48a58f28f7a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp @@ -0,0 +1,82 @@ +//===-- RegisterContextPOSIX_loongarch64.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 "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_loongarch64.h" + +using namespace lldb; +using namespace lldb_private; + +RegisterContextPOSIX_loongarch64::RegisterContextPOSIX_loongarch64( + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_loongarch64> register_info) + : lldb_private::RegisterContext(thread, 0), + m_register_info_up(std::move(register_info)) {} + +RegisterContextPOSIX_loongarch64::~RegisterContextPOSIX_loongarch64() = default; + +void RegisterContextPOSIX_loongarch64::invalidate() {} + +void RegisterContextPOSIX_loongarch64::InvalidateAllRegisters() {} + +size_t RegisterContextPOSIX_loongarch64::GetRegisterCount() { + return m_register_info_up->GetRegisterCount(); +} + +size_t RegisterContextPOSIX_loongarch64::GetGPRSize() { + return m_register_info_up->GetGPRSize(); +} + +unsigned RegisterContextPOSIX_loongarch64::GetRegisterSize(unsigned int reg) { + return m_register_info_up->GetRegisterInfo()[reg].byte_size; +} + +unsigned RegisterContextPOSIX_loongarch64::GetRegisterOffset(unsigned int reg) { + return m_register_info_up->GetRegisterInfo()[reg].byte_offset; +} + +const lldb_private::RegisterInfo * +RegisterContextPOSIX_loongarch64::GetRegisterInfoAtIndex(size_t reg) { + if (reg < GetRegisterCount()) + return &GetRegisterInfo()[reg]; + + return nullptr; +} + +size_t RegisterContextPOSIX_loongarch64::GetRegisterSetCount() { + return m_register_info_up->GetRegisterCount(); +} + +const lldb_private::RegisterSet * +RegisterContextPOSIX_loongarch64::GetRegisterSet(size_t set) { + return m_register_info_up->GetRegisterSet(set); +} + +const lldb_private::RegisterInfo * +RegisterContextPOSIX_loongarch64::GetRegisterInfo() { + return m_register_info_up->GetRegisterInfo(); +} + +bool RegisterContextPOSIX_loongarch64::IsGPR(unsigned int reg) { + return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_loongarch64::GPRegSet; +} + +bool RegisterContextPOSIX_loongarch64::IsFPR(unsigned int reg) { + return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_loongarch64::FPRegSet; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h new file mode 100644 index 000000000000..95f93bb41f01 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h @@ -0,0 +1,63 @@ +//===-- RegisterContextPOSIX_loongarch64.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_REGISTERCONTEXTPOSIX_LOONGARCH64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_LOONGARCH64_H + +#include "RegisterInfoInterface.h" +#include "RegisterInfoPOSIX_loongarch64.h" +#include "lldb-loongarch-register-enums.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_loongarch64 : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_loongarch64( + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_loongarch64> register_info); + + ~RegisterContextPOSIX_loongarch64() override; + + void invalidate(); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + +protected: + std::unique_ptr<RegisterInfoPOSIX_loongarch64> m_register_info_up; + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + size_t GetFPRSize() { return sizeof(RegisterInfoPOSIX_loongarch64::FPR); } + + uint32_t GetRegNumFCSR() const { return fpr_fcsr_loongarch; } + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_LOONGARCH64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp new file mode 100644 index 000000000000..3685d6ac72ad --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp @@ -0,0 +1,138 @@ +//===-- RegisterContextPOSIX_mips64.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 <cerrno> +#include <cstdint> +#include <cstring> + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_mips64.h" +#include "RegisterContextFreeBSD_mips64.h" + +using namespace lldb_private; +using namespace lldb; + +bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg) { + return reg < m_registers_count[gpr_registers_count]; // GPR's come first. +} + +bool RegisterContextPOSIX_mips64::IsFPR(unsigned reg) { + int set = GetRegisterSetCount(); + if (set > 1) + return reg < (m_registers_count[fpr_registers_count] + + m_registers_count[gpr_registers_count]); + return false; +} + +RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64( + Thread &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) { + m_register_info_up.reset(register_info); + m_num_registers = GetRegisterCount(); + int set = GetRegisterSetCount(); + + const RegisterSet *reg_set_ptr; + for(int i = 0; i < set; ++i) { + reg_set_ptr = GetRegisterSet(i); + m_registers_count[i] = reg_set_ptr->num_registers; + } + + assert(m_num_registers == + static_cast<uint32_t>(m_registers_count[gpr_registers_count] + + m_registers_count[fpr_registers_count] + + m_registers_count[msa_registers_count])); +} + +RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() = default; + +void RegisterContextPOSIX_mips64::Invalidate() {} + +void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {} + +unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) { + assert(reg < m_num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) { + assert(reg < m_num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +size_t RegisterContextPOSIX_mips64::GetRegisterCount() { + return m_register_info_up->GetRegisterCount(); +} + +size_t RegisterContextPOSIX_mips64::GetGPRSize() { + return m_register_info_up->GetGPRSize(); +} + +const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() { + // Commonly, this method is overridden and g_register_infos is copied and + // specialized. So, use GetRegisterInfo() rather than g_register_infos in + // this scope. + return m_register_info_up->GetRegisterInfo(); +} + +const RegisterInfo * +RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) { + if (reg < m_num_registers) + return &GetRegisterInfo()[reg]; + else + return nullptr; +} + +size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() { + const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>( + m_register_info_up.get()); + return context->GetRegisterSetCount(); +} + +const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) { + const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>( + m_register_info_up.get()); + return context->GetRegisterSet(set); +} + +const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) { + assert(reg < m_num_registers && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) { + size_t num_sets = GetRegisterSetCount(); + + return (set_index < num_sets); +} + +// Used when parsing DWARF and EH frame information and any other object file +// sections that contain register numbers in them. +uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + const uint32_t num_regs = m_num_registers; + + assert(kind < kNumRegisterKinds); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); + + if (reg_info->kinds[kind] == num) + return reg_idx; + } + + return LLDB_INVALID_REGNUM; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h new file mode 100644 index 000000000000..b66dc3f44524 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h @@ -0,0 +1,78 @@ +//===-- RegisterContextPOSIX_mips64.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_REGISTERCONTEXTPOSIX_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H + +#include "RegisterContext_mips.h" +#include "RegisterInfoInterface.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext { +public: + + enum Register_count{ + gpr_registers_count = 0, + fpr_registers_count, + msa_registers_count, + register_set_count + }; + + RegisterContextPOSIX_mips64( + lldb_private::Thread &thread, uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + + ~RegisterContextPOSIX_mips64() override; + + void Invalidate(); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + +protected: + uint32_t m_num_registers; + uint8_t m_registers_count[register_set_count]; + 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); + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp new file mode 100644 index 000000000000..cffd2865e385 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -0,0 +1,164 @@ +//===-- RegisterContextPOSIX_powerpc.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 <cerrno> +#include <cstdint> +#include <cstring> + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_powerpc.h" + +using namespace lldb_private; +using namespace lldb; + +static const uint32_t g_gpr_regnums[] = { + gpr_r0_powerpc, gpr_r1_powerpc, gpr_r2_powerpc, gpr_r3_powerpc, + gpr_r4_powerpc, gpr_r5_powerpc, gpr_r6_powerpc, gpr_r7_powerpc, + gpr_r8_powerpc, gpr_r9_powerpc, gpr_r10_powerpc, gpr_r11_powerpc, + gpr_r12_powerpc, gpr_r13_powerpc, gpr_r14_powerpc, gpr_r15_powerpc, + gpr_r16_powerpc, gpr_r17_powerpc, gpr_r18_powerpc, gpr_r19_powerpc, + gpr_r20_powerpc, gpr_r21_powerpc, gpr_r22_powerpc, gpr_r23_powerpc, + gpr_r24_powerpc, gpr_r25_powerpc, gpr_r26_powerpc, gpr_r27_powerpc, + gpr_r28_powerpc, gpr_r29_powerpc, gpr_r30_powerpc, gpr_r31_powerpc, + gpr_lr_powerpc, gpr_cr_powerpc, gpr_xer_powerpc, gpr_ctr_powerpc, + gpr_pc_powerpc, +}; + +static const uint32_t g_fpr_regnums[] = { + fpr_f0_powerpc, fpr_f1_powerpc, fpr_f2_powerpc, fpr_f3_powerpc, + fpr_f4_powerpc, fpr_f5_powerpc, fpr_f6_powerpc, fpr_f7_powerpc, + fpr_f8_powerpc, fpr_f9_powerpc, fpr_f10_powerpc, fpr_f11_powerpc, + fpr_f12_powerpc, fpr_f13_powerpc, fpr_f14_powerpc, fpr_f15_powerpc, + fpr_f16_powerpc, fpr_f17_powerpc, fpr_f18_powerpc, fpr_f19_powerpc, + fpr_f20_powerpc, fpr_f21_powerpc, fpr_f22_powerpc, fpr_f23_powerpc, + fpr_f24_powerpc, fpr_f25_powerpc, fpr_f26_powerpc, fpr_f27_powerpc, + fpr_f28_powerpc, fpr_f29_powerpc, fpr_f30_powerpc, fpr_f31_powerpc, + fpr_fpscr_powerpc, +}; + +static const uint32_t g_vmx_regnums[] = { + vmx_v0_powerpc, vmx_v1_powerpc, vmx_v2_powerpc, vmx_v3_powerpc, + vmx_v4_powerpc, vmx_v5_powerpc, vmx_v6_powerpc, vmx_v7_powerpc, + vmx_v8_powerpc, vmx_v9_powerpc, vmx_v10_powerpc, vmx_v11_powerpc, + vmx_v12_powerpc, vmx_v13_powerpc, vmx_v14_powerpc, vmx_v15_powerpc, + vmx_v16_powerpc, vmx_v17_powerpc, vmx_v18_powerpc, vmx_v19_powerpc, + vmx_v20_powerpc, vmx_v21_powerpc, vmx_v22_powerpc, vmx_v23_powerpc, + vmx_v24_powerpc, vmx_v25_powerpc, vmx_v26_powerpc, vmx_v27_powerpc, + vmx_v28_powerpc, vmx_v29_powerpc, vmx_v30_powerpc, vmx_v31_powerpc, + vmx_vrsave_powerpc, vmx_vscr_powerpc, +}; + +// Number of register sets provided by this context. +enum { k_num_register_sets = 3 }; + +static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, + g_gpr_regnums}, + {"Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, + g_fpr_regnums}, + {"Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc, + g_vmx_regnums}, +}; + +static_assert(k_first_gpr_powerpc == 0, + "GPRs must index starting at 0, or fix IsGPR()"); +bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg) { + return (reg <= k_last_gpr_powerpc); // GPR's come first. +} + +bool RegisterContextPOSIX_powerpc::IsFPR(unsigned reg) { + return (reg >= k_first_fpr) && (reg <= k_last_fpr); +} + +bool RegisterContextPOSIX_powerpc::IsVMX(unsigned reg) { + return (reg >= k_first_vmx) && (reg <= k_last_vmx); +} + +RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc( + Thread &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) { + m_register_info_up.reset(register_info); +} + +RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() = default; + +void RegisterContextPOSIX_powerpc::Invalidate() {} + +void RegisterContextPOSIX_powerpc::InvalidateAllRegisters() {} + +unsigned RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg) { + assert(reg < k_num_registers_powerpc && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg) { + assert(reg < k_num_registers_powerpc && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +size_t RegisterContextPOSIX_powerpc::GetRegisterCount() { + size_t num_registers = k_num_registers_powerpc; + return num_registers; +} + +size_t RegisterContextPOSIX_powerpc::GetGPRSize() { + return m_register_info_up->GetGPRSize(); +} + +const RegisterInfo *RegisterContextPOSIX_powerpc::GetRegisterInfo() { + // Commonly, this method is overridden and g_register_infos is copied and + // specialized. So, use GetRegisterInfo() rather than g_register_infos in + // this scope. + return m_register_info_up->GetRegisterInfo(); +} + +const RegisterInfo * +RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_registers_powerpc) + return &GetRegisterInfo()[reg]; + else + return nullptr; +} + +size_t RegisterContextPOSIX_powerpc::GetRegisterSetCount() { + size_t sets = 0; + for (size_t set = 0; set < k_num_register_sets; ++set) { + if (IsRegisterSetAvailable(set)) + ++sets; + } + + return sets; +} + +const RegisterSet *RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set) { + if (IsRegisterSetAvailable(set)) + return &g_reg_sets_powerpc[set]; + else + return nullptr; +} + +const char *RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg) { + assert(reg < k_num_registers_powerpc && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +bool RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index) { + size_t num_sets = k_num_register_sets; + + return (set_index < num_sets); +} 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 new file mode 100644 index 000000000000..5dd8c890da6e --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h @@ -0,0 +1,195 @@ +//===-- RegisterContextPOSIX_powerpc.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_REGISTERCONTEXTPOSIX_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H + +#include "RegisterContext_powerpc.h" +#include "RegisterInfoInterface.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +// Internal codes for all powerpc registers. +enum { + k_first_gpr_powerpc, + gpr_r0_powerpc = k_first_gpr_powerpc, + gpr_r1_powerpc, + gpr_r2_powerpc, + gpr_r3_powerpc, + gpr_r4_powerpc, + gpr_r5_powerpc, + gpr_r6_powerpc, + gpr_r7_powerpc, + gpr_r8_powerpc, + gpr_r9_powerpc, + gpr_r10_powerpc, + gpr_r11_powerpc, + gpr_r12_powerpc, + gpr_r13_powerpc, + gpr_r14_powerpc, + gpr_r15_powerpc, + gpr_r16_powerpc, + gpr_r17_powerpc, + gpr_r18_powerpc, + gpr_r19_powerpc, + gpr_r20_powerpc, + gpr_r21_powerpc, + gpr_r22_powerpc, + gpr_r23_powerpc, + gpr_r24_powerpc, + gpr_r25_powerpc, + gpr_r26_powerpc, + gpr_r27_powerpc, + gpr_r28_powerpc, + gpr_r29_powerpc, + gpr_r30_powerpc, + gpr_r31_powerpc, + gpr_lr_powerpc, + gpr_cr_powerpc, + gpr_xer_powerpc, + gpr_ctr_powerpc, + gpr_pc_powerpc, + k_last_gpr_powerpc = gpr_pc_powerpc, + + k_first_fpr, + fpr_f0_powerpc = k_first_fpr, + fpr_f1_powerpc, + fpr_f2_powerpc, + fpr_f3_powerpc, + fpr_f4_powerpc, + fpr_f5_powerpc, + fpr_f6_powerpc, + fpr_f7_powerpc, + fpr_f8_powerpc, + fpr_f9_powerpc, + fpr_f10_powerpc, + fpr_f11_powerpc, + fpr_f12_powerpc, + fpr_f13_powerpc, + fpr_f14_powerpc, + fpr_f15_powerpc, + fpr_f16_powerpc, + fpr_f17_powerpc, + fpr_f18_powerpc, + fpr_f19_powerpc, + fpr_f20_powerpc, + fpr_f21_powerpc, + fpr_f22_powerpc, + fpr_f23_powerpc, + fpr_f24_powerpc, + fpr_f25_powerpc, + fpr_f26_powerpc, + fpr_f27_powerpc, + fpr_f28_powerpc, + fpr_f29_powerpc, + fpr_f30_powerpc, + fpr_f31_powerpc, + fpr_fpscr_powerpc, + k_last_fpr = fpr_fpscr_powerpc, + + k_first_vmx, + vmx_v0_powerpc = k_first_vmx, + vmx_v1_powerpc, + vmx_v2_powerpc, + vmx_v3_powerpc, + vmx_v4_powerpc, + vmx_v5_powerpc, + vmx_v6_powerpc, + vmx_v7_powerpc, + vmx_v8_powerpc, + vmx_v9_powerpc, + vmx_v10_powerpc, + vmx_v11_powerpc, + vmx_v12_powerpc, + vmx_v13_powerpc, + vmx_v14_powerpc, + vmx_v15_powerpc, + vmx_v16_powerpc, + vmx_v17_powerpc, + vmx_v18_powerpc, + vmx_v19_powerpc, + vmx_v20_powerpc, + vmx_v21_powerpc, + vmx_v22_powerpc, + vmx_v23_powerpc, + vmx_v24_powerpc, + vmx_v25_powerpc, + vmx_v26_powerpc, + vmx_v27_powerpc, + vmx_v28_powerpc, + vmx_v29_powerpc, + vmx_v30_powerpc, + vmx_v31_powerpc, + vmx_vrsave_powerpc, + vmx_vscr_powerpc, + k_last_vmx = vmx_vscr_powerpc, + + k_num_registers_powerpc, + k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1, + k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1, + k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1, +}; + +class RegisterContextPOSIX_powerpc : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_powerpc( + lldb_private::Thread &thread, uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + + ~RegisterContextPOSIX_powerpc() override; + + void Invalidate(); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + +protected: + uint64_t + m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers. + uint64_t + m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers. + uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4]; + 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); + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + bool IsVMX(unsigned reg); + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool ReadVMX() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; + virtual bool WriteVMX() = 0; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp new file mode 100644 index 000000000000..f70ddeba209c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp @@ -0,0 +1,183 @@ +//===-- RegisterContextPOSIX_ppc64le.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 <cerrno> +#include <cstdint> +#include <cstring> + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_ppc64le.h" + +using namespace lldb_private; +using namespace lldb; + +static const uint32_t g_gpr_regnums[] = { + gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le, + gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le, + gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le, + gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le, + gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le, + gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le, + gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le, + gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_ppc64le, + gpr_pc_ppc64le, gpr_msr_ppc64le, gpr_origr3_ppc64le, gpr_ctr_ppc64le, + gpr_lr_ppc64le, gpr_xer_ppc64le, gpr_cr_ppc64le, gpr_softe_ppc64le, + gpr_trap_ppc64le, +}; + +static const uint32_t g_fpr_regnums[] = { + fpr_f0_ppc64le, fpr_f1_ppc64le, fpr_f2_ppc64le, fpr_f3_ppc64le, + fpr_f4_ppc64le, fpr_f5_ppc64le, fpr_f6_ppc64le, fpr_f7_ppc64le, + fpr_f8_ppc64le, fpr_f9_ppc64le, fpr_f10_ppc64le, fpr_f11_ppc64le, + fpr_f12_ppc64le, fpr_f13_ppc64le, fpr_f14_ppc64le, fpr_f15_ppc64le, + fpr_f16_ppc64le, fpr_f17_ppc64le, fpr_f18_ppc64le, fpr_f19_ppc64le, + fpr_f20_ppc64le, fpr_f21_ppc64le, fpr_f22_ppc64le, fpr_f23_ppc64le, + fpr_f24_ppc64le, fpr_f25_ppc64le, fpr_f26_ppc64le, fpr_f27_ppc64le, + fpr_f28_ppc64le, fpr_f29_ppc64le, fpr_f30_ppc64le, fpr_f31_ppc64le, + fpr_fpscr_ppc64le, +}; + +static const uint32_t g_vmx_regnums[] = { + vmx_vr0_ppc64le, vmx_vr1_ppc64le, vmx_vr2_ppc64le, vmx_vr3_ppc64le, + vmx_vr4_ppc64le, vmx_vr5_ppc64le, vmx_vr6_ppc64le, vmx_vr7_ppc64le, + vmx_vr8_ppc64le, vmx_vr9_ppc64le, vmx_vr10_ppc64le, vmx_vr11_ppc64le, + vmx_vr12_ppc64le, vmx_vr13_ppc64le, vmx_vr14_ppc64le, vmx_vr15_ppc64le, + vmx_vr16_ppc64le, vmx_vr17_ppc64le, vmx_vr18_ppc64le, vmx_vr19_ppc64le, + vmx_vr20_ppc64le, vmx_vr21_ppc64le, vmx_vr22_ppc64le, vmx_vr23_ppc64le, + vmx_vr24_ppc64le, vmx_vr25_ppc64le, vmx_vr26_ppc64le, vmx_vr27_ppc64le, + vmx_vr28_ppc64le, vmx_vr29_ppc64le, vmx_vr30_ppc64le, vmx_vr31_ppc64le, + vmx_vscr_ppc64le, vmx_vrsave_ppc64le, +}; + +static const uint32_t g_vsx_regnums[] = { + vsx_vs0_ppc64le, vsx_vs1_ppc64le, vsx_vs2_ppc64le, vsx_vs3_ppc64le, + vsx_vs4_ppc64le, vsx_vs5_ppc64le, vsx_vs6_ppc64le, vsx_vs7_ppc64le, + vsx_vs8_ppc64le, vsx_vs9_ppc64le, vsx_vs10_ppc64le, vsx_vs11_ppc64le, + vsx_vs12_ppc64le, vsx_vs13_ppc64le, vsx_vs14_ppc64le, vsx_vs15_ppc64le, + vsx_vs16_ppc64le, vsx_vs17_ppc64le, vsx_vs18_ppc64le, vsx_vs19_ppc64le, + vsx_vs20_ppc64le, vsx_vs21_ppc64le, vsx_vs22_ppc64le, vsx_vs23_ppc64le, + vsx_vs24_ppc64le, vsx_vs25_ppc64le, vsx_vs26_ppc64le, vsx_vs27_ppc64le, + vsx_vs28_ppc64le, vsx_vs29_ppc64le, vsx_vs30_ppc64le, vsx_vs31_ppc64le, + vsx_vs32_ppc64le, vsx_vs33_ppc64le, vsx_vs34_ppc64le, vsx_vs35_ppc64le, + vsx_vs36_ppc64le, vsx_vs37_ppc64le, vsx_vs38_ppc64le, vsx_vs39_ppc64le, + vsx_vs40_ppc64le, vsx_vs41_ppc64le, vsx_vs42_ppc64le, vsx_vs43_ppc64le, + vsx_vs44_ppc64le, vsx_vs45_ppc64le, vsx_vs46_ppc64le, vsx_vs47_ppc64le, + vsx_vs48_ppc64le, vsx_vs49_ppc64le, vsx_vs50_ppc64le, vsx_vs51_ppc64le, + vsx_vs52_ppc64le, vsx_vs53_ppc64le, vsx_vs54_ppc64le, vsx_vs55_ppc64le, + vsx_vs56_ppc64le, vsx_vs57_ppc64le, vsx_vs58_ppc64le, vsx_vs59_ppc64le, + vsx_vs60_ppc64le, vsx_vs61_ppc64le, vsx_vs62_ppc64le, vsx_vs63_ppc64le, +}; + +// Number of register sets provided by this context. +enum { k_num_register_sets = 4 }; + +static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le, + g_gpr_regnums}, + {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64le, + g_fpr_regnums}, + {"Altivec/VMX Registers", "vmx", k_num_vmx_registers_ppc64le, + g_vmx_regnums}, + {"VSX Registers", "vsx", k_num_vsx_registers_ppc64le, g_vsx_regnums}, +}; + +bool RegisterContextPOSIX_ppc64le::IsGPR(unsigned reg) { + return (reg <= k_last_gpr_ppc64le); // GPR's come first. +} + +bool RegisterContextPOSIX_ppc64le::IsFPR(unsigned reg) { + return (reg >= k_first_fpr_ppc64le) && (reg <= k_last_fpr_ppc64le); +} + +bool RegisterContextPOSIX_ppc64le::IsVMX(unsigned reg) { + return (reg >= k_first_vmx_ppc64le) && (reg <= k_last_vmx_ppc64le); +} + +bool RegisterContextPOSIX_ppc64le::IsVSX(unsigned reg) { + return (reg >= k_first_vsx_ppc64le) && (reg <= k_last_vsx_ppc64le); +} + +RegisterContextPOSIX_ppc64le::RegisterContextPOSIX_ppc64le( + Thread &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) { + m_register_info_up.reset(register_info); +} + +void RegisterContextPOSIX_ppc64le::InvalidateAllRegisters() {} + +unsigned RegisterContextPOSIX_ppc64le::GetRegisterOffset(unsigned reg) { + assert(reg < k_num_registers_ppc64le && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned RegisterContextPOSIX_ppc64le::GetRegisterSize(unsigned reg) { + assert(reg < k_num_registers_ppc64le && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +size_t RegisterContextPOSIX_ppc64le::GetRegisterCount() { + size_t num_registers = k_num_registers_ppc64le; + return num_registers; +} + +size_t RegisterContextPOSIX_ppc64le::GetGPRSize() { + return m_register_info_up->GetGPRSize(); +} + +const RegisterInfo *RegisterContextPOSIX_ppc64le::GetRegisterInfo() { + // Commonly, this method is overridden and g_register_infos is copied and + // specialized. So, use GetRegisterInfo() rather than g_register_infos in + // this scope. + return m_register_info_up->GetRegisterInfo(); +} + +const RegisterInfo * +RegisterContextPOSIX_ppc64le::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_registers_ppc64le) + return &GetRegisterInfo()[reg]; + else + return nullptr; +} + +size_t RegisterContextPOSIX_ppc64le::GetRegisterSetCount() { + size_t sets = 0; + for (size_t set = 0; set < k_num_register_sets; ++set) { + if (IsRegisterSetAvailable(set)) + ++sets; + } + + return sets; +} + +const RegisterSet *RegisterContextPOSIX_ppc64le::GetRegisterSet(size_t set) { + if (IsRegisterSetAvailable(set)) + return &g_reg_sets_ppc64le[set]; + else + return nullptr; +} + +const char *RegisterContextPOSIX_ppc64le::GetRegisterName(unsigned reg) { + assert(reg < k_num_registers_ppc64le && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +bool RegisterContextPOSIX_ppc64le::IsRegisterSetAvailable(size_t set_index) { + size_t num_sets = k_num_register_sets; + + return (set_index < num_sets); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h new file mode 100644 index 000000000000..66794ec9e9ca --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h @@ -0,0 +1,73 @@ +//===-- RegisterContextPOSIX_ppc64le.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_REGISTERCONTEXTPOSIX_PPC64LE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H + +#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" +#include "RegisterInfoInterface.h" +#include "Utility/PPC64LE_DWARF_Registers.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_ppc64le : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_ppc64le( + lldb_private::Thread &thread, uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + +protected: + // 64-bit general purpose registers. + uint64_t m_gpr_ppc64le[k_num_gpr_registers_ppc64le]; + + // floating-point registers including extended register. + uint64_t m_fpr_ppc64le[k_num_fpr_registers_ppc64le]; + + // VMX registers. + uint64_t m_vmx_ppc64le[k_num_vmx_registers_ppc64le * 2]; + + // VSX registers. + uint64_t m_vsx_ppc64le[k_num_vsx_registers_ppc64le * 2]; + + std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_up; + + // Determines if an extended register set is supported on the processor + // running the inferior process. + virtual bool IsRegisterSetAvailable(size_t set_index); + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + bool IsVMX(unsigned reg); + + bool IsVSX(unsigned reg); + +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.cpp new file mode 100644 index 000000000000..035ce00e1162 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.cpp @@ -0,0 +1,82 @@ +//===-- RegisterContextPOSIX_riscv64.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 "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_riscv64.h" + +using namespace lldb; +using namespace lldb_private; + +RegisterContextPOSIX_riscv64::RegisterContextPOSIX_riscv64( + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_riscv64> register_info) + : lldb_private::RegisterContext(thread, 0), + m_register_info_up(std::move(register_info)) {} + +RegisterContextPOSIX_riscv64::~RegisterContextPOSIX_riscv64() = default; + +void RegisterContextPOSIX_riscv64::invalidate() {} + +void RegisterContextPOSIX_riscv64::InvalidateAllRegisters() {} + +size_t RegisterContextPOSIX_riscv64::GetRegisterCount() { + return m_register_info_up->GetRegisterCount(); +} + +size_t RegisterContextPOSIX_riscv64::GetGPRSize() { + return m_register_info_up->GetGPRSize(); +} + +unsigned RegisterContextPOSIX_riscv64::GetRegisterSize(unsigned int reg) { + return m_register_info_up->GetRegisterInfo()[reg].byte_size; +} + +unsigned RegisterContextPOSIX_riscv64::GetRegisterOffset(unsigned int reg) { + return m_register_info_up->GetRegisterInfo()[reg].byte_offset; +} + +const lldb_private::RegisterInfo * +RegisterContextPOSIX_riscv64::GetRegisterInfoAtIndex(size_t reg) { + if (reg < GetRegisterCount()) + return &GetRegisterInfo()[reg]; + + return nullptr; +} + +size_t RegisterContextPOSIX_riscv64::GetRegisterSetCount() { + return m_register_info_up->GetRegisterSetCount(); +} + +const lldb_private::RegisterSet * +RegisterContextPOSIX_riscv64::GetRegisterSet(size_t set) { + return m_register_info_up->GetRegisterSet(set); +} + +const lldb_private::RegisterInfo * +RegisterContextPOSIX_riscv64::GetRegisterInfo() { + return m_register_info_up->GetRegisterInfo(); +} + +bool RegisterContextPOSIX_riscv64::IsGPR(unsigned int reg) { + return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_riscv64::GPRegSet; +} + +bool RegisterContextPOSIX_riscv64::IsFPR(unsigned int reg) { + return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_riscv64::FPRegSet; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.h new file mode 100644 index 000000000000..2431ed6ab8c6 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.h @@ -0,0 +1,63 @@ +//===-- RegisterContextPOSIX_riscv64.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_REGISTERCONTEXTPOSIX_RISCV64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_RISCV64_H + +#include "RegisterInfoInterface.h" +#include "RegisterInfoPOSIX_riscv64.h" +#include "lldb-riscv-register-enums.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_riscv64 : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_riscv64( + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_riscv64> register_info); + + ~RegisterContextPOSIX_riscv64() override; + + void invalidate(); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + +protected: + std::unique_ptr<RegisterInfoPOSIX_riscv64> m_register_info_up; + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + size_t GetFPRSize() { return sizeof(RegisterInfoPOSIX_riscv64::FPR); } + + uint32_t GetRegNumFCSR() const { return fpr_fcsr_riscv; } + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_RISCV64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp new file mode 100644 index 000000000000..b85da39b4c45 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -0,0 +1,163 @@ +//===-- RegisterContextPOSIX_s390x.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 <cerrno> +#include <cstdint> +#include <cstring> + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_s390x.h" +#include "RegisterContext_s390x.h" + +using namespace lldb_private; +using namespace lldb; + +// s390x 64-bit general purpose registers. +static const uint32_t g_gpr_regnums_s390x[] = { + lldb_r0_s390x, lldb_r1_s390x, lldb_r2_s390x, lldb_r3_s390x, + lldb_r4_s390x, lldb_r5_s390x, lldb_r6_s390x, lldb_r7_s390x, + lldb_r8_s390x, lldb_r9_s390x, lldb_r10_s390x, lldb_r11_s390x, + lldb_r12_s390x, lldb_r13_s390x, lldb_r14_s390x, lldb_r15_s390x, + lldb_acr0_s390x, lldb_acr1_s390x, lldb_acr2_s390x, lldb_acr3_s390x, + lldb_acr4_s390x, lldb_acr5_s390x, lldb_acr6_s390x, lldb_acr7_s390x, + lldb_acr8_s390x, lldb_acr9_s390x, lldb_acr10_s390x, lldb_acr11_s390x, + lldb_acr12_s390x, lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x, + lldb_pswm_s390x, lldb_pswa_s390x, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - + 1 == + k_num_gpr_registers_s390x, + "g_gpr_regnums_s390x has wrong number of register infos"); + +// s390x 64-bit floating point registers. +static const uint32_t g_fpu_regnums_s390x[] = { + lldb_f0_s390x, lldb_f1_s390x, lldb_f2_s390x, lldb_f3_s390x, + lldb_f4_s390x, lldb_f5_s390x, lldb_f6_s390x, lldb_f7_s390x, + lldb_f8_s390x, lldb_f9_s390x, lldb_f10_s390x, lldb_f11_s390x, + lldb_f12_s390x, lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x, + lldb_fpc_s390x, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - + 1 == + k_num_fpr_registers_s390x, + "g_fpu_regnums_s390x has wrong number of register infos"); + +// Number of register sets provided by this context. +enum { k_num_register_sets = 2 }; + +// Register sets for s390x 64-bit. +static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x, + g_gpr_regnums_s390x}, + {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x, + g_fpu_regnums_s390x}, +}; + +bool RegisterContextPOSIX_s390x::IsGPR(unsigned reg) { + return reg <= m_reg_info.last_gpr; // GPRs come first. +} + +bool RegisterContextPOSIX_s390x::IsFPR(unsigned reg) { + return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); +} + +RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x( + Thread &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) { + m_register_info_up.reset(register_info); + + switch (register_info->GetTargetArchitecture().GetMachine()) { + case llvm::Triple::systemz: + m_reg_info.num_registers = k_num_registers_s390x; + m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x; + m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x; + m_reg_info.last_gpr = k_last_gpr_s390x; + m_reg_info.first_fpr = k_first_fpr_s390x; + m_reg_info.last_fpr = k_last_fpr_s390x; + break; + default: + assert(false && "Unhandled target architecture."); + break; + } +} + +RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() = default; + +void RegisterContextPOSIX_s390x::Invalidate() {} + +void RegisterContextPOSIX_s390x::InvalidateAllRegisters() {} + +const RegisterInfo *RegisterContextPOSIX_s390x::GetRegisterInfo() { + return m_register_info_up->GetRegisterInfo(); +} + +const RegisterInfo * +RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg) { + if (reg < m_reg_info.num_registers) + return &GetRegisterInfo()[reg]; + else + return nullptr; +} + +size_t RegisterContextPOSIX_s390x::GetRegisterCount() { + return m_reg_info.num_registers; +} + +unsigned RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg) { + assert(reg < m_reg_info.num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg) { + assert(reg < m_reg_info.num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +const char *RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg) { + assert(reg < m_reg_info.num_registers && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +bool RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index) { + return set_index < k_num_register_sets; +} + +size_t RegisterContextPOSIX_s390x::GetRegisterSetCount() { + size_t sets = 0; + for (size_t set = 0; set < k_num_register_sets; ++set) { + if (IsRegisterSetAvailable(set)) + ++sets; + } + + return sets; +} + +const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) { + if (IsRegisterSetAvailable(set)) { + switch (m_register_info_up->GetTargetArchitecture().GetMachine()) { + case llvm::Triple::systemz: + return &g_reg_sets_s390x[set]; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } + } + return nullptr; +} 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 new file mode 100644 index 000000000000..7027af04f0bb --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h @@ -0,0 +1,72 @@ +//===-- RegisterContextPOSIX_s390x.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_REGISTERCONTEXTPOSIX_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H + +#include "RegisterContext_s390x.h" +#include "RegisterInfoInterface.h" +#include "lldb-s390x-register-enums.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_s390x( + lldb_private::Thread &thread, uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + + ~RegisterContextPOSIX_s390x() override; + + void Invalidate(); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + +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; + }; + + RegInfo m_reg_info; + std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_up; + + virtual bool IsRegisterSetAvailable(size_t set_index); + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H 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 new file mode 100644 index 000000000000..c14eb135c7b1 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -0,0 +1,540 @@ +//===-- RegisterContextPOSIX_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 <cerrno> +#include <cstdint> +#include <cstring> + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_x86.h" +#include "RegisterContext_x86.h" + +using namespace lldb_private; +using namespace lldb; + +const uint32_t g_gpr_regnums_i386[] = { + lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386, + lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386, + lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386, + lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386, + lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386, + lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386, + lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386, + lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM, // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - + 1 == + k_num_gpr_registers_i386, + "g_gpr_regnums_i386 has wrong number of register infos"); + +const uint32_t g_lldb_regnums_i386[] = { + lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386, + lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386, + lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386, + lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386, + lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386, + lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386, + lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386, + lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386, + lldb_xmm6_i386, lldb_xmm7_i386, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) - + 1 == + k_num_fpr_registers_i386, + "g_lldb_regnums_i386 has wrong number of register infos"); + +const uint32_t g_avx_regnums_i386[] = { + lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386, + lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - + 1 == + k_num_avx_registers_i386, + " g_avx_regnums_i386 has wrong number of register infos"); + +static const uint32_t g_gpr_regnums_x86_64[] = { + lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64, + lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64, + lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64, + lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64, + lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64, + lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64, + lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64, + lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64, + lldb_r8d_x86_64, // Low 32 bits or r8 + lldb_r9d_x86_64, // Low 32 bits or r9 + lldb_r10d_x86_64, // Low 32 bits or r10 + lldb_r11d_x86_64, // Low 32 bits or r11 + lldb_r12d_x86_64, // Low 32 bits or r12 + lldb_r13d_x86_64, // Low 32 bits or r13 + lldb_r14d_x86_64, // Low 32 bits or r14 + lldb_r15d_x86_64, // Low 32 bits or r15 + lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64, + lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64, + lldb_r8w_x86_64, // Low 16 bits or r8 + lldb_r9w_x86_64, // Low 16 bits or r9 + lldb_r10w_x86_64, // Low 16 bits or r10 + lldb_r11w_x86_64, // Low 16 bits or r11 + lldb_r12w_x86_64, // Low 16 bits or r12 + lldb_r13w_x86_64, // Low 16 bits or r13 + lldb_r14w_x86_64, // Low 16 bits or r14 + lldb_r15w_x86_64, // Low 16 bits or r15 + lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64, + lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64, + lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64, + lldb_r8l_x86_64, // Low 8 bits or r8 + lldb_r9l_x86_64, // Low 8 bits or r9 + lldb_r10l_x86_64, // Low 8 bits or r10 + lldb_r11l_x86_64, // Low 8 bits or r11 + lldb_r12l_x86_64, // Low 8 bits or r12 + lldb_r13l_x86_64, // Low 8 bits or r13 + lldb_r14l_x86_64, // Low 8 bits or r14 + lldb_r15l_x86_64, // Low 8 bits or r15 + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - + 1 == + k_num_gpr_registers_x86_64, + "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_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. +}; +static_assert((sizeof(g_lldb_regnums_x86_64) / + sizeof(g_lldb_regnums_x86_64[0])) - + 1 == + k_num_fpr_registers_x86_64, + "g_lldb_regnums_x86_64 has wrong number of register infos"); + +static const uint32_t g_avx_regnums_x86_64[] = { + lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64, + lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64, + lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64, + lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - + 1 == + k_num_avx_registers_x86_64, + "g_avx_regnums_x86_64 has wrong number of register infos"); + +uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = {lldb_eax_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = {lldb_ebx_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = {lldb_ecx_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = {lldb_edx_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = {lldb_edi_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = {lldb_esi_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = {lldb_ebp_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = {lldb_esp_i386, + LLDB_INVALID_REGNUM}; + +uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = { + lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = { + lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = { + lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = { + lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = { + lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = { + lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = { + lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = { + lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = {lldb_rax_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = {lldb_rbx_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = {lldb_rcx_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = {lldb_rdx_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = {lldb_rdi_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = {lldb_rsi_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = {lldb_rbp_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = {lldb_rsp_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = {lldb_r8_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = {lldb_r9_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = {lldb_r10_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = {lldb_r11_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = {lldb_r12_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = {lldb_r13_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = {lldb_r14_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = {lldb_r15_x86_64, + LLDB_INVALID_REGNUM}; + +uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = { + lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64, + lldb_ah_x86_64, lldb_al_x86_64, LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = { + lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64, + lldb_bh_x86_64, lldb_bl_x86_64, LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = { + lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64, + lldb_ch_x86_64, lldb_cl_x86_64, LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = { + lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64, + lldb_dh_x86_64, lldb_dl_x86_64, LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = { + lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = { + lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = { + lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = { + lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = { + lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = { + lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = { + lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = { + lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = { + lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = { + lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64, + LLDB_INVALID_REGNUM}; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = { + lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64, + LLDB_INVALID_REGNUM}; +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 }; + +static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, + g_gpr_regnums_i386}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, + g_lldb_regnums_i386}, + {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386, + g_avx_regnums_i386}}; + +static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, + g_gpr_regnums_x86_64}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, + g_lldb_regnums_x86_64}, + {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, + g_avx_regnums_x86_64}}; + +bool RegisterContextPOSIX_x86::IsGPR(unsigned reg) { + return reg <= GetRegInfo().last_gpr; // GPR's come first. +} + +bool RegisterContextPOSIX_x86::IsFPR(unsigned reg) { + return (GetRegInfo().first_fpr <= reg && reg <= GetRegInfo().last_fpr); +} + +bool RegisterContextPOSIX_x86::IsAVX(unsigned reg) { + return (GetRegInfo().first_ymm <= reg && reg <= GetRegInfo().last_ymm); +} + +bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type) { + bool generic_fpr = IsFPR(reg); + + if (fpr_type == eXSAVE) + return generic_fpr || IsAVX(reg); + return generic_fpr; +} + +RegisterContextPOSIX_x86::RegisterContextPOSIX_x86( + Thread &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) { + m_register_info_up.reset(register_info); + + ::memset(&m_fpr, 0, sizeof(FPR)); + ::memset(&m_ymm_set, 0, sizeof(YMM)); + + m_fpr_type = eNotValid; +} + +RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() = default; + +RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() { + if (m_fpr_type == eNotValid) { + // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx + m_fpr_type = eXSAVE; // extended floating-point registers, if available + if (!ReadFPR()) + m_fpr_type = eFXSAVE; // assume generic floating-point registers + } + return m_fpr_type; +} + +void RegisterContextPOSIX_x86::Invalidate() {} + +void RegisterContextPOSIX_x86::InvalidateAllRegisters() {} + +unsigned RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg) { + assert(reg < GetRegInfo().num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +RegInfo &RegisterContextPOSIX_x86::GetRegInfo() { + return GetRegInfoShared( + m_register_info_up->GetTargetArchitecture().GetMachine(), + /*with_base=*/false); +} + +unsigned RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg) { + assert(reg < GetRegInfo().num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +size_t RegisterContextPOSIX_x86::GetRegisterCount() { + size_t num_registers = + GetRegInfo().num_gpr_registers + GetRegInfo().num_fpr_registers; + if (GetFPRType() == eXSAVE) + return num_registers + GetRegInfo().num_avx_registers; + return num_registers; +} + +size_t RegisterContextPOSIX_x86::GetGPRSize() { + return m_register_info_up->GetGPRSize(); +} + +size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() { + return GetRegisterInfo()[GetRegInfo().first_fpr].byte_offset; +} + +const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() { + // Commonly, this method is overridden and g_register_infos is copied and + // specialized. So, use GetRegisterInfo() rather than g_register_infos in + // this scope. + return m_register_info_up->GetRegisterInfo(); +} + +const RegisterInfo * +RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg) { + if (reg < GetRegInfo().num_registers) + return &GetRegisterInfo()[reg]; + else + return nullptr; +} + +size_t RegisterContextPOSIX_x86::GetRegisterSetCount() { + size_t sets = 0; + for (size_t set = 0; set < k_num_register_sets; ++set) { + if (IsRegisterSetAvailable(set)) + ++sets; + } + + return sets; +} + +const RegisterSet *RegisterContextPOSIX_x86::GetRegisterSet(size_t set) { + if (IsRegisterSetAvailable(set)) { + switch (m_register_info_up->GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return &g_reg_sets_i386[set]; + case llvm::Triple::x86_64: + return &g_reg_sets_x86_64[set]; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } + } + return nullptr; +} + +const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) { + assert(reg < GetRegInfo().num_registers && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +// Parse ymm registers and into xmm.bytes and ymmh.bytes. +bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg, + lldb::ByteOrder byte_order) { + if (!IsAVX(reg)) + return false; + + if (byte_order == eByteOrderLittle) { + uint32_t reg_no = reg - GetRegInfo().first_ymm; + YMMToXState(m_ymm_set.ymm[reg_no], m_fpr.fxsave.xmm[reg_no].bytes, + m_fpr.xsave.ymmh[reg_no].bytes); + return true; + } + + return false; // unsupported or invalid byte order +} + +// Concatenate xmm.bytes with ymmh.bytes +bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg, + lldb::ByteOrder byte_order) { + if (!IsAVX(reg)) + return false; + + if (byte_order == eByteOrderLittle) { + uint32_t reg_no = reg - GetRegInfo().first_ymm; + m_ymm_set.ymm[reg_no] = XStateToYMM(m_fpr.fxsave.xmm[reg_no].bytes, + m_fpr.xsave.ymmh[reg_no].bytes); + return true; + } + + return false; // unsupported or invalid byte order +} + +bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) { + // Note: Extended register sets are assumed to be at the end of g_reg_sets... + size_t num_sets = k_num_register_sets - k_num_extended_register_sets; + + if (GetFPRType() == eXSAVE) // ...and to start with AVX registers. + ++num_sets; + return (set_index < num_sets); +} 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 new file mode 100644 index 000000000000..9284f5cc07d9 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -0,0 +1,185 @@ +//===-- RegisterContextPOSIX_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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H + +#include "RegisterContext_x86.h" +#include "RegisterInfoInterface.h" +#include "RegisterInfos_x86_64_with_base_shared.h" +#include "lldb-x86-register-enums.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" + +class RegisterContextPOSIX_x86 : public lldb_private::RegisterContext { +public: + RegisterContextPOSIX_x86(lldb_private::Thread &thread, + uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + + ~RegisterContextPOSIX_x86() override; + + void Invalidate(); + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + virtual size_t GetGPRSize(); + + virtual size_t GetFXSAVEOffset(); + + virtual unsigned GetRegisterSize(unsigned reg); + + virtual unsigned GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + // Note: prefer kernel definitions over user-land + enum FPRType { + eNotValid = 0, + eFSAVE, // TODO + eFXSAVE, + eSOFT, // TODO + eXSAVE + }; + + static uint32_t g_contained_eax[]; + static uint32_t g_contained_ebx[]; + static uint32_t g_contained_ecx[]; + static uint32_t g_contained_edx[]; + static uint32_t g_contained_edi[]; + static uint32_t g_contained_esi[]; + static uint32_t g_contained_ebp[]; + static uint32_t g_contained_esp[]; + + static uint32_t g_invalidate_eax[]; + static uint32_t g_invalidate_ebx[]; + static uint32_t g_invalidate_ecx[]; + static uint32_t g_invalidate_edx[]; + static uint32_t g_invalidate_edi[]; + static uint32_t g_invalidate_esi[]; + static uint32_t g_invalidate_ebp[]; + static uint32_t g_invalidate_esp[]; + + static uint32_t g_contained_rax[]; + static uint32_t g_contained_rbx[]; + static uint32_t g_contained_rcx[]; + static uint32_t g_contained_rdx[]; + static uint32_t g_contained_rdi[]; + static uint32_t g_contained_rsi[]; + static uint32_t g_contained_rbp[]; + static uint32_t g_contained_rsp[]; + static uint32_t g_contained_r8[]; + static uint32_t g_contained_r9[]; + static uint32_t g_contained_r10[]; + static uint32_t g_contained_r11[]; + static uint32_t g_contained_r12[]; + static uint32_t g_contained_r13[]; + static uint32_t g_contained_r14[]; + static uint32_t g_contained_r15[]; + + static uint32_t g_invalidate_rax[]; + static uint32_t g_invalidate_rbx[]; + static uint32_t g_invalidate_rcx[]; + static uint32_t g_invalidate_rdx[]; + static uint32_t g_invalidate_rdi[]; + static uint32_t g_invalidate_rsi[]; + static uint32_t g_invalidate_rbp[]; + static uint32_t g_invalidate_rsp[]; + static uint32_t g_invalidate_r8[]; + static uint32_t g_invalidate_r9[]; + static uint32_t g_invalidate_r10[]; + static uint32_t g_invalidate_r11[]; + static uint32_t g_invalidate_r12[]; + static uint32_t g_invalidate_r13[]; + 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: + FPRType + m_fpr_type; // determines the type of data stored by union FPR, if any. + lldb_private::FPR m_fpr; // floating-point registers including extended + // register sets. + lldb_private::YMM m_ymm_set; // copy of ymmh and xmm register halves. + 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); + + virtual const lldb_private::RegisterInfo *GetRegisterInfo(); + + bool IsGPR(unsigned reg); + + bool IsFPR(unsigned reg); + + bool IsAVX(unsigned reg); + + bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order); + bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order); + bool IsFPR(unsigned reg, FPRType fpr_type); + FPRType GetFPRType(); + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; + virtual lldb_private::RegInfo &GetRegInfo(); +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp new file mode 100644 index 000000000000..b5f2b0d2212d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp @@ -0,0 +1,216 @@ +//===-- RegisterContextThreadMemory.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 "lldb/Target/OperatingSystem.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-private.h" + +#include "RegisterContextThreadMemory.h" + +using namespace lldb; +using namespace lldb_private; + +RegisterContextThreadMemory::RegisterContextThreadMemory( + Thread &thread, lldb::addr_t register_data_addr) + : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()), + m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {} + +RegisterContextThreadMemory::~RegisterContextThreadMemory() = default; + +void RegisterContextThreadMemory::UpdateRegisterContext() { + ThreadSP thread_sp(m_thread_wp.lock()); + if (thread_sp) { + ProcessSP process_sp(thread_sp->GetProcess()); + + if (process_sp) { + const uint32_t stop_id = process_sp->GetModID().GetStopID(); + if (m_stop_id != stop_id) { + m_stop_id = stop_id; + m_reg_ctx_sp.reset(); + } + if (!m_reg_ctx_sp) { + ThreadSP backing_thread_sp(thread_sp->GetBackingThread()); + if (backing_thread_sp) { + m_reg_ctx_sp = backing_thread_sp->GetRegisterContext(); + } else { + OperatingSystem *os = process_sp->GetOperatingSystem(); + if (os->IsOperatingSystemPluginThread(thread_sp)) + m_reg_ctx_sp = os->CreateRegisterContextForThread( + thread_sp.get(), m_register_data_addr); + } + } + } else { + m_reg_ctx_sp.reset(); + } + } else { + m_reg_ctx_sp.reset(); + } +} + +// Subclasses must override these functions +void RegisterContextThreadMemory::InvalidateAllRegisters() { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + m_reg_ctx_sp->InvalidateAllRegisters(); +} + +size_t RegisterContextThreadMemory::GetRegisterCount() { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->GetRegisterCount(); + return 0; +} + +const RegisterInfo * +RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg); + return nullptr; +} + +size_t RegisterContextThreadMemory::GetRegisterSetCount() { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->GetRegisterSetCount(); + return 0; +} + +const RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->GetRegisterSet(reg_set); + return nullptr; +} + +bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->ReadRegister(reg_info, reg_value); + return false; +} + +bool RegisterContextThreadMemory::WriteRegister( + const RegisterInfo *reg_info, const RegisterValue ®_value) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->WriteRegister(reg_info, reg_value); + return false; +} + +bool RegisterContextThreadMemory::ReadAllRegisterValues( + lldb::WritableDataBufferSP &data_sp) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->ReadAllRegisterValues(data_sp); + return false; +} + +bool RegisterContextThreadMemory::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->WriteAllRegisterValues(data_sp); + return false; +} + +bool RegisterContextThreadMemory::CopyFromRegisterContext( + lldb::RegisterContextSP reg_ctx_sp) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp); + return false; +} + +uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num); + return false; +} + +uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->NumSupportedHardwareBreakpoints(); + return false; +} + +uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr, + size_t size) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size); + return 0; +} + +bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx); + return false; +} + +uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->NumSupportedHardwareWatchpoints(); + return 0; +} + +uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr, + size_t size, + bool read, + bool write) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write); + return 0; +} + +bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index); + return false; +} + +bool RegisterContextThreadMemory::HardwareSingleStep(bool enable) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->HardwareSingleStep(enable); + return false; +} + +Status RegisterContextThreadMemory::ReadRegisterValueFromMemory( + const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, + uint32_t src_len, RegisterValue ®_value) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr, + src_len, reg_value); + Status error; + error.SetErrorString("invalid register context"); + return error; +} + +Status RegisterContextThreadMemory::WriteRegisterValueToMemory( + const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, + uint32_t dst_len, const RegisterValue ®_value) { + UpdateRegisterContext(); + if (m_reg_ctx_sp) + return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len, + reg_value); + Status error; + error.SetErrorString("invalid register context"); + return error; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h new file mode 100644 index 000000000000..0a7314528f0a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h @@ -0,0 +1,102 @@ +//===-- RegisterContextThreadMemory.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_REGISTERCONTEXTTHREADMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H + +#include <vector> + +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class RegisterContextThreadMemory : public lldb_private::RegisterContext { +public: + RegisterContextThreadMemory(Thread &thread, lldb::addr_t register_data_addr); + + ~RegisterContextThreadMemory() override; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const RegisterSet *GetRegisterSet(size_t reg_set) override; + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + // These two functions are used to implement "push" and "pop" of register + // states. They are used primarily + // for expression evaluation, where we need to push a new state (storing the + // old one in data_sp) and then + // restoring the original state by passing the data_sp we got from + // ReadAllRegisters to WriteAllRegisterValues. + // ReadAllRegisters will do what is necessary to return a coherent set of + // register values for this thread, which + // may mean e.g. interrupting a thread that is sitting in a kernel trap. That + // is a somewhat disruptive operation, + // so these API's should only be used when this behavior is needed. + + bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + bool CopyFromRegisterContext(lldb::RegisterContextSP context); + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + uint32_t NumSupportedHardwareBreakpoints() override; + + uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override; + + bool ClearHardwareBreakpoint(uint32_t hw_idx) override; + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, + bool write) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + bool HardwareSingleStep(bool enable) override; + + Status ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info, + lldb::addr_t src_addr, uint32_t src_len, + RegisterValue ®_value) override; + + Status WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info, + lldb::addr_t dst_addr, uint32_t dst_len, + const RegisterValue ®_value) override; + +protected: + void UpdateRegisterContext(); + + lldb::ThreadWP m_thread_wp; + lldb::RegisterContextSP m_reg_ctx_sp; + lldb::addr_t m_register_data_addr; + uint32_t m_stop_id; + +private: + RegisterContextThreadMemory(const RegisterContextThreadMemory &) = delete; + const RegisterContextThreadMemory & + operator=(const RegisterContextThreadMemory &) = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp new file mode 100644 index 000000000000..faf4021aa499 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp @@ -0,0 +1,89 @@ +//===-- RegisterContextWindows_i386.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 "RegisterContextWindows_i386.h" +#include "RegisterContext_x86.h" +#include "lldb-x86-register-enums.h" + +using namespace lldb_private; +using namespace lldb; + +namespace { +// Declare our g_register_infos structure. +typedef struct _GPR { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t esp; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + uint32_t fs; + uint32_t gs; + uint32_t ss; + uint32_t ds; + uint32_t es; +} GPR; + +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) + +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ +#reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ + eFormatHex, \ + {kind1, kind2, kind3, kind4, lldb_##reg##_i386 }, nullptr, nullptr, \ + nullptr, \ + } + +// clang-format off +static RegisterInfo g_register_infos_i386[] = { +// General purpose registers EH_Frame DWARF Generic Process Plugin +// =========================== ================== ================ ========================= ==================== + DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), +}; +// clang-format on +} // namespace + +RegisterContextWindows_i386::RegisterContextWindows_i386( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch) { + assert(target_arch.GetMachine() == llvm::Triple::x86); +} + +const RegisterInfo *RegisterContextWindows_i386::GetRegisterInfo() const { + return g_register_infos_i386; +} + +uint32_t RegisterContextWindows_i386::GetRegisterCount() const { + return std::size(g_register_infos_i386); +} + +uint32_t RegisterContextWindows_i386::GetUserRegisterCount() const { + return std::size(g_register_infos_i386); +} + +size_t RegisterContextWindows_i386::GetGPRSize() const { return sizeof(GPR); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h new file mode 100644 index 000000000000..6a5d3524300d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h @@ -0,0 +1,27 @@ +//===-- RegisterContextWindows_i386.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_REGISTERCONTEXTWINDOWS_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_I386_H + +#include "RegisterInfoInterface.h" + +class RegisterContextWindows_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextWindows_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp new file mode 100644 index 000000000000..c3fc2e0026bc --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp @@ -0,0 +1,152 @@ +//===-- RegisterContextWindows_x86_64.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 "RegisterContextWindows_x86_64.h" +#include "RegisterContext_x86.h" +#include "lldb-x86-register-enums.h" + +#include <vector> + +using namespace lldb_private; +using namespace lldb; + +namespace { +typedef struct _GPR { + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rbx; + uint64_t rsp; + uint64_t rbp; + uint64_t rsi; + uint64_t rdi; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t rip; + uint64_t rflags; + uint16_t cs; + uint16_t fs; + uint16_t gs; + uint16_t ss; + uint16_t ds; + uint16_t es; +} GPR; + +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ +#reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ + eFormatHex, \ + {kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, nullptr, nullptr, \ + nullptr, \ + } + +typedef struct _FPReg { + XMMReg xmm0; + XMMReg xmm1; + XMMReg xmm2; + XMMReg xmm3; + XMMReg xmm4; + XMMReg xmm5; + XMMReg xmm6; + XMMReg xmm7; + XMMReg xmm8; + XMMReg xmm9; + XMMReg xmm10; + XMMReg xmm11; + XMMReg xmm12; + XMMReg xmm13; + XMMReg xmm14; + XMMReg xmm15; +} FPReg; + +#define FPR_OFFSET(regname) \ + (sizeof(GPR) + LLVM_EXTENSION offsetof(FPReg, regname)) + +#define DEFINE_XMM(reg) \ + { \ +#reg, NULL, sizeof(((FPReg *)nullptr)->reg), FPR_OFFSET(reg), \ + eEncodingUint, eFormatVectorOfUInt64, \ + {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +// clang-format off +static RegisterInfo g_register_infos_x86_64[] = { +// General purpose registers EH_Frame DWARF Generic Process Plugin +// =========================== ================== ================ ========================= ==================== + DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rcx, nullptr, dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdx, nullptr, dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdi, nullptr, dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsi, nullptr, dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbp, nullptr, dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsp, nullptr, dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, nullptr, dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rip, nullptr, dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(rflags, nullptr, dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_XMM(xmm0), + DEFINE_XMM(xmm1), + DEFINE_XMM(xmm2), + DEFINE_XMM(xmm3), + DEFINE_XMM(xmm4), + DEFINE_XMM(xmm5), + DEFINE_XMM(xmm6), + DEFINE_XMM(xmm7), + DEFINE_XMM(xmm8), + DEFINE_XMM(xmm9), + DEFINE_XMM(xmm10), + DEFINE_XMM(xmm11), + DEFINE_XMM(xmm12), + DEFINE_XMM(xmm13), + DEFINE_XMM(xmm14), + DEFINE_XMM(xmm15) +}; +// clang-format on +} // namespace + +RegisterContextWindows_x86_64::RegisterContextWindows_x86_64( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch) { + assert(target_arch.GetMachine() == llvm::Triple::x86_64); +} + +const RegisterInfo *RegisterContextWindows_x86_64::GetRegisterInfo() const { + return g_register_infos_x86_64; +} + +uint32_t RegisterContextWindows_x86_64::GetRegisterCount() const { + return std::size(g_register_infos_x86_64); +} + +uint32_t RegisterContextWindows_x86_64::GetUserRegisterCount() const { + return std::size(g_register_infos_x86_64); +} + +size_t RegisterContextWindows_x86_64::GetGPRSize() const { return sizeof(GPR); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h new file mode 100644 index 000000000000..c29acf284841 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h @@ -0,0 +1,28 @@ +//===-- RegisterContextWindows_x86_64.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_REGISTERCONTEXTWINDOWS_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_X86_64_H + +#include "RegisterInfoInterface.h" + +class RegisterContextWindows_x86_64 + : public lldb_private::RegisterInfoInterface { +public: + RegisterContextWindows_x86_64(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h new file mode 100644 index 000000000000..15081f974c66 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h @@ -0,0 +1,374 @@ +//===-- RegisterContext_mips.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_REGISTERCONTEXT_MIPS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H + +#include <cstddef> +#include <cstdint> + +// eh_frame and DWARF Register numbers (eRegisterKindEHFrame & +// eRegisterKindDWARF) + +enum { + // GP Registers + dwarf_zero_mips = 0, + dwarf_r1_mips, + dwarf_r2_mips, + dwarf_r3_mips, + dwarf_r4_mips, + dwarf_r5_mips, + dwarf_r6_mips, + dwarf_r7_mips, + dwarf_r8_mips, + dwarf_r9_mips, + dwarf_r10_mips, + dwarf_r11_mips, + dwarf_r12_mips, + dwarf_r13_mips, + dwarf_r14_mips, + dwarf_r15_mips, + dwarf_r16_mips, + dwarf_r17_mips, + dwarf_r18_mips, + dwarf_r19_mips, + dwarf_r20_mips, + dwarf_r21_mips, + dwarf_r22_mips, + dwarf_r23_mips, + dwarf_r24_mips, + dwarf_r25_mips, + dwarf_r26_mips, + dwarf_r27_mips, + dwarf_gp_mips, + dwarf_sp_mips, + dwarf_r30_mips, + dwarf_ra_mips, + dwarf_sr_mips, + dwarf_lo_mips, + dwarf_hi_mips, + dwarf_bad_mips, + dwarf_cause_mips, + dwarf_pc_mips, + dwarf_f0_mips, + dwarf_f1_mips, + dwarf_f2_mips, + dwarf_f3_mips, + dwarf_f4_mips, + dwarf_f5_mips, + dwarf_f6_mips, + dwarf_f7_mips, + dwarf_f8_mips, + dwarf_f9_mips, + dwarf_f10_mips, + dwarf_f11_mips, + dwarf_f12_mips, + dwarf_f13_mips, + dwarf_f14_mips, + dwarf_f15_mips, + dwarf_f16_mips, + dwarf_f17_mips, + dwarf_f18_mips, + dwarf_f19_mips, + dwarf_f20_mips, + dwarf_f21_mips, + dwarf_f22_mips, + dwarf_f23_mips, + dwarf_f24_mips, + dwarf_f25_mips, + dwarf_f26_mips, + dwarf_f27_mips, + dwarf_f28_mips, + dwarf_f29_mips, + dwarf_f30_mips, + dwarf_f31_mips, + dwarf_fcsr_mips, + dwarf_fir_mips, + dwarf_w0_mips, + dwarf_w1_mips, + dwarf_w2_mips, + dwarf_w3_mips, + dwarf_w4_mips, + dwarf_w5_mips, + dwarf_w6_mips, + dwarf_w7_mips, + dwarf_w8_mips, + dwarf_w9_mips, + dwarf_w10_mips, + dwarf_w11_mips, + dwarf_w12_mips, + dwarf_w13_mips, + dwarf_w14_mips, + dwarf_w15_mips, + dwarf_w16_mips, + dwarf_w17_mips, + dwarf_w18_mips, + dwarf_w19_mips, + dwarf_w20_mips, + dwarf_w21_mips, + dwarf_w22_mips, + dwarf_w23_mips, + dwarf_w24_mips, + dwarf_w25_mips, + dwarf_w26_mips, + dwarf_w27_mips, + dwarf_w28_mips, + dwarf_w29_mips, + dwarf_w30_mips, + dwarf_w31_mips, + dwarf_mcsr_mips, + dwarf_mir_mips, + dwarf_config5_mips, + dwarf_ic_mips, + dwarf_dummy_mips +}; + +enum { + dwarf_zero_mips64 = 0, + dwarf_r1_mips64, + dwarf_r2_mips64, + dwarf_r3_mips64, + dwarf_r4_mips64, + dwarf_r5_mips64, + dwarf_r6_mips64, + dwarf_r7_mips64, + dwarf_r8_mips64, + dwarf_r9_mips64, + dwarf_r10_mips64, + dwarf_r11_mips64, + dwarf_r12_mips64, + dwarf_r13_mips64, + dwarf_r14_mips64, + dwarf_r15_mips64, + dwarf_r16_mips64, + dwarf_r17_mips64, + dwarf_r18_mips64, + dwarf_r19_mips64, + dwarf_r20_mips64, + dwarf_r21_mips64, + dwarf_r22_mips64, + dwarf_r23_mips64, + dwarf_r24_mips64, + dwarf_r25_mips64, + dwarf_r26_mips64, + dwarf_r27_mips64, + dwarf_gp_mips64, + dwarf_sp_mips64, + dwarf_r30_mips64, + dwarf_ra_mips64, + dwarf_sr_mips64, + dwarf_lo_mips64, + dwarf_hi_mips64, + dwarf_bad_mips64, + dwarf_cause_mips64, + dwarf_pc_mips64, + dwarf_f0_mips64, + dwarf_f1_mips64, + dwarf_f2_mips64, + dwarf_f3_mips64, + dwarf_f4_mips64, + dwarf_f5_mips64, + dwarf_f6_mips64, + dwarf_f7_mips64, + dwarf_f8_mips64, + dwarf_f9_mips64, + dwarf_f10_mips64, + dwarf_f11_mips64, + dwarf_f12_mips64, + dwarf_f13_mips64, + dwarf_f14_mips64, + dwarf_f15_mips64, + dwarf_f16_mips64, + dwarf_f17_mips64, + dwarf_f18_mips64, + dwarf_f19_mips64, + dwarf_f20_mips64, + dwarf_f21_mips64, + dwarf_f22_mips64, + dwarf_f23_mips64, + dwarf_f24_mips64, + dwarf_f25_mips64, + dwarf_f26_mips64, + dwarf_f27_mips64, + dwarf_f28_mips64, + dwarf_f29_mips64, + dwarf_f30_mips64, + dwarf_f31_mips64, + dwarf_fcsr_mips64, + dwarf_fir_mips64, + dwarf_ic_mips64, + dwarf_dummy_mips64, + dwarf_w0_mips64, + dwarf_w1_mips64, + dwarf_w2_mips64, + dwarf_w3_mips64, + dwarf_w4_mips64, + dwarf_w5_mips64, + dwarf_w6_mips64, + dwarf_w7_mips64, + dwarf_w8_mips64, + dwarf_w9_mips64, + dwarf_w10_mips64, + dwarf_w11_mips64, + dwarf_w12_mips64, + dwarf_w13_mips64, + dwarf_w14_mips64, + dwarf_w15_mips64, + dwarf_w16_mips64, + dwarf_w17_mips64, + dwarf_w18_mips64, + dwarf_w19_mips64, + dwarf_w20_mips64, + dwarf_w21_mips64, + dwarf_w22_mips64, + dwarf_w23_mips64, + dwarf_w24_mips64, + dwarf_w25_mips64, + dwarf_w26_mips64, + dwarf_w27_mips64, + dwarf_w28_mips64, + dwarf_w29_mips64, + dwarf_w30_mips64, + dwarf_w31_mips64, + dwarf_mcsr_mips64, + dwarf_mir_mips64, + dwarf_config5_mips64, +}; + +// GP registers +struct GPR_linux_mips { + uint64_t zero; + uint64_t r1; + uint64_t r2; + uint64_t r3; + uint64_t r4; + uint64_t r5; + uint64_t r6; + uint64_t r7; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t r16; + uint64_t r17; + uint64_t r18; + uint64_t r19; + uint64_t r20; + uint64_t r21; + uint64_t r22; + uint64_t r23; + uint64_t r24; + uint64_t r25; + uint64_t r26; + uint64_t r27; + uint64_t gp; + uint64_t sp; + uint64_t r30; + uint64_t ra; + uint64_t mullo; + uint64_t mulhi; + uint64_t pc; + uint64_t badvaddr; + uint64_t sr; + uint64_t cause; + uint64_t config5; +}; + +struct FPR_linux_mips { + uint64_t f0; + uint64_t f1; + uint64_t f2; + uint64_t f3; + uint64_t f4; + uint64_t f5; + uint64_t f6; + uint64_t f7; + uint64_t f8; + uint64_t f9; + uint64_t f10; + uint64_t f11; + uint64_t f12; + uint64_t f13; + uint64_t f14; + uint64_t f15; + uint64_t f16; + uint64_t f17; + uint64_t f18; + uint64_t f19; + uint64_t f20; + uint64_t f21; + uint64_t f22; + uint64_t f23; + uint64_t f24; + uint64_t f25; + uint64_t f26; + uint64_t f27; + uint64_t f28; + uint64_t f29; + uint64_t f30; + uint64_t f31; + uint32_t fcsr; + uint32_t fir; + uint32_t config5; +}; + +struct MSAReg { + uint8_t byte[16]; +}; + +struct MSA_linux_mips { + MSAReg w0; + MSAReg w1; + MSAReg w2; + MSAReg w3; + MSAReg w4; + MSAReg w5; + MSAReg w6; + MSAReg w7; + MSAReg w8; + MSAReg w9; + MSAReg w10; + MSAReg w11; + MSAReg w12; + MSAReg w13; + MSAReg w14; + MSAReg w15; + MSAReg w16; + MSAReg w17; + MSAReg w18; + MSAReg w19; + MSAReg w20; + MSAReg w21; + MSAReg w22; + MSAReg w23; + MSAReg w24; + MSAReg w25; + MSAReg w26; + MSAReg w27; + MSAReg w28; + MSAReg w29; + MSAReg w30; + MSAReg w31; + uint32_t fcsr; /* FPU control status register */ + uint32_t fir; /* FPU implementaion revision */ + uint32_t mcsr; /* MSA control status register */ + uint32_t mir; /* MSA implementation revision */ + uint32_t config5; /* Config5 register */ +}; + +struct UserArea { + GPR_linux_mips gpr; // General purpose registers. + FPR_linux_mips fpr; // Floating point registers. + MSA_linux_mips msa; // MSA registers. +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h new file mode 100644 index 000000000000..7407e2f402e0 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h @@ -0,0 +1,123 @@ +//===-- RegisterContext_powerpc.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_REGISTERCONTEXT_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H + +// eh_frame and DWARF Register numbers (eRegisterKindEHFrame & +// eRegisterKindDWARF) +enum { + dwarf_r0_powerpc = 0, + dwarf_r1_powerpc, + dwarf_r2_powerpc, + dwarf_r3_powerpc, + dwarf_r4_powerpc, + dwarf_r5_powerpc, + dwarf_r6_powerpc, + dwarf_r7_powerpc, + dwarf_r8_powerpc, + dwarf_r9_powerpc, + dwarf_r10_powerpc, + dwarf_r11_powerpc, + dwarf_r12_powerpc, + dwarf_r13_powerpc, + dwarf_r14_powerpc, + dwarf_r15_powerpc, + dwarf_r16_powerpc, + dwarf_r17_powerpc, + dwarf_r18_powerpc, + dwarf_r19_powerpc, + dwarf_r20_powerpc, + dwarf_r21_powerpc, + dwarf_r22_powerpc, + dwarf_r23_powerpc, + dwarf_r24_powerpc, + dwarf_r25_powerpc, + dwarf_r26_powerpc, + dwarf_r27_powerpc, + dwarf_r28_powerpc, + dwarf_r29_powerpc, + dwarf_r30_powerpc, + dwarf_r31_powerpc, + dwarf_f0_powerpc, + dwarf_f1_powerpc, + dwarf_f2_powerpc, + dwarf_f3_powerpc, + dwarf_f4_powerpc, + dwarf_f5_powerpc, + dwarf_f6_powerpc, + dwarf_f7_powerpc, + dwarf_f8_powerpc, + dwarf_f9_powerpc, + dwarf_f10_powerpc, + dwarf_f11_powerpc, + dwarf_f12_powerpc, + dwarf_f13_powerpc, + dwarf_f14_powerpc, + dwarf_f15_powerpc, + dwarf_f16_powerpc, + dwarf_f17_powerpc, + dwarf_f18_powerpc, + dwarf_f19_powerpc, + dwarf_f20_powerpc, + dwarf_f21_powerpc, + dwarf_f22_powerpc, + dwarf_f23_powerpc, + dwarf_f24_powerpc, + dwarf_f25_powerpc, + dwarf_f26_powerpc, + dwarf_f27_powerpc, + dwarf_f28_powerpc, + dwarf_f29_powerpc, + dwarf_f30_powerpc, + dwarf_f31_powerpc, + dwarf_cr_powerpc, + dwarf_fpscr_powerpc, + dwarf_msr_powerpc, + dwarf_vscr_powerpc, + dwarf_xer_powerpc = 101, + dwarf_lr_powerpc = 108, + dwarf_ctr_powerpc, + dwarf_pc_powerpc, + dwarf_vrsave_powerpc = 356, + dwarf_v0_powerpc = 1124, + dwarf_v1_powerpc, + dwarf_v2_powerpc, + dwarf_v3_powerpc, + dwarf_v4_powerpc, + dwarf_v5_powerpc, + dwarf_v6_powerpc, + dwarf_v7_powerpc, + dwarf_v8_powerpc, + dwarf_v9_powerpc, + dwarf_v10_powerpc, + dwarf_v11_powerpc, + dwarf_v12_powerpc, + dwarf_v13_powerpc, + dwarf_v14_powerpc, + dwarf_v15_powerpc, + dwarf_v16_powerpc, + dwarf_v17_powerpc, + dwarf_v18_powerpc, + dwarf_v19_powerpc, + dwarf_v20_powerpc, + dwarf_v21_powerpc, + dwarf_v22_powerpc, + dwarf_v23_powerpc, + dwarf_v24_powerpc, + dwarf_v25_powerpc, + dwarf_v26_powerpc, + dwarf_v27_powerpc, + dwarf_v28_powerpc, + dwarf_v29_powerpc, + dwarf_v30_powerpc, + dwarf_v31_powerpc, +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h new file mode 100644 index 000000000000..248b3bd0beac --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h @@ -0,0 +1,90 @@ +//===-- RegisterContext_s390x.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_REGISTERCONTEXT_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_S390X_H + +// SystemZ ehframe, dwarf regnums + +// EHFrame and DWARF Register numbers (eRegisterKindEHFrame & +// eRegisterKindDWARF) +enum { + // General Purpose Registers + dwarf_r0_s390x = 0, + dwarf_r1_s390x, + dwarf_r2_s390x, + dwarf_r3_s390x, + dwarf_r4_s390x, + dwarf_r5_s390x, + dwarf_r6_s390x, + dwarf_r7_s390x, + dwarf_r8_s390x, + dwarf_r9_s390x, + dwarf_r10_s390x, + dwarf_r11_s390x, + dwarf_r12_s390x, + dwarf_r13_s390x, + dwarf_r14_s390x, + dwarf_r15_s390x, + // Floating Point Registers / Vector Registers 0-15 + dwarf_f0_s390x = 16, + dwarf_f2_s390x, + dwarf_f4_s390x, + dwarf_f6_s390x, + dwarf_f1_s390x, + dwarf_f3_s390x, + dwarf_f5_s390x, + dwarf_f7_s390x, + dwarf_f8_s390x, + dwarf_f10_s390x, + dwarf_f12_s390x, + dwarf_f14_s390x, + dwarf_f9_s390x, + dwarf_f11_s390x, + dwarf_f13_s390x, + dwarf_f15_s390x, + // Access Registers + dwarf_acr0_s390x = 48, + dwarf_acr1_s390x, + dwarf_acr2_s390x, + dwarf_acr3_s390x, + dwarf_acr4_s390x, + dwarf_acr5_s390x, + dwarf_acr6_s390x, + dwarf_acr7_s390x, + dwarf_acr8_s390x, + dwarf_acr9_s390x, + dwarf_acr10_s390x, + dwarf_acr11_s390x, + dwarf_acr12_s390x, + dwarf_acr13_s390x, + dwarf_acr14_s390x, + dwarf_acr15_s390x, + // Program Status Word + dwarf_pswm_s390x = 64, + dwarf_pswa_s390x, + // Vector Registers 16-31 + dwarf_v16_s390x = 68, + dwarf_v18_s390x, + dwarf_v20_s390x, + dwarf_v22_s390x, + dwarf_v17_s390x, + dwarf_v19_s390x, + dwarf_v21_s390x, + dwarf_v23_s390x, + dwarf_v24_s390x, + dwarf_v26_s390x, + dwarf_v28_s390x, + dwarf_v30_s390x, + dwarf_v25_s390x, + dwarf_v27_s390x, + dwarf_v29_s390x, + dwarf_v31_s390x, +}; + +#endif 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 new file mode 100644 index 000000000000..e24da37b7261 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -0,0 +1,395 @@ +//===-- RegisterContext_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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H + +#include <cstddef> +#include <cstdint> + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" +#include "llvm/Support/Compiler.h" + +namespace lldb_private { +// i386 ehframe, dwarf regnums + +// Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems +// (non-Darwin) +// +enum { + ehframe_eax_i386 = 0, + ehframe_ecx_i386, + ehframe_edx_i386, + ehframe_ebx_i386, + + // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus + // dwarf's reg numbering). + // To be specific: + // i386+darwin eh_frame: 4 is ebp, 5 is esp + // i386+everyone else eh_frame: 4 is esp, 5 is ebp + // i386 dwarf: 4 is esp, 5 is ebp + // lldb will get the darwin-specific eh_frame reg numberings from debugserver, + // or the ABI, so we + // only encode the generally correct 4 == esp, 5 == ebp numbers in this + // generic header. + + ehframe_esp_i386, + ehframe_ebp_i386, + ehframe_esi_i386, + ehframe_edi_i386, + ehframe_eip_i386, + ehframe_eflags_i386, + ehframe_st0_i386 = 12, + ehframe_st1_i386, + ehframe_st2_i386, + ehframe_st3_i386, + ehframe_st4_i386, + ehframe_st5_i386, + ehframe_st6_i386, + ehframe_st7_i386, + ehframe_xmm0_i386 = 21, + ehframe_xmm1_i386, + ehframe_xmm2_i386, + ehframe_xmm3_i386, + ehframe_xmm4_i386, + ehframe_xmm5_i386, + ehframe_xmm6_i386, + ehframe_xmm7_i386, + ehframe_mm0_i386 = 29, + ehframe_mm1_i386, + ehframe_mm2_i386, + ehframe_mm3_i386, + ehframe_mm4_i386, + ehframe_mm5_i386, + ehframe_mm6_i386, + ehframe_mm7_i386, +}; + +// DWARF register numbers (eRegisterKindDWARF) +// Intel's x86 or IA-32 +enum { + // General Purpose Registers. + dwarf_eax_i386 = 0, + dwarf_ecx_i386, + dwarf_edx_i386, + dwarf_ebx_i386, + dwarf_esp_i386, + dwarf_ebp_i386, + dwarf_esi_i386, + dwarf_edi_i386, + dwarf_eip_i386, + dwarf_eflags_i386, + // Floating Point Registers + dwarf_st0_i386 = 11, + dwarf_st1_i386, + dwarf_st2_i386, + dwarf_st3_i386, + dwarf_st4_i386, + dwarf_st5_i386, + dwarf_st6_i386, + dwarf_st7_i386, + // SSE Registers + dwarf_xmm0_i386 = 21, + dwarf_xmm1_i386, + dwarf_xmm2_i386, + dwarf_xmm3_i386, + dwarf_xmm4_i386, + dwarf_xmm5_i386, + dwarf_xmm6_i386, + dwarf_xmm7_i386, + // MMX Registers + dwarf_mm0_i386 = 29, + dwarf_mm1_i386, + dwarf_mm2_i386, + dwarf_mm3_i386, + dwarf_mm4_i386, + dwarf_mm5_i386, + dwarf_mm6_i386, + dwarf_mm7_i386, + dwarf_fctrl_i386 = 37, // x87 control word + dwarf_fstat_i386 = 38, // x87 status word + dwarf_mxcsr_i386 = 39, + dwarf_es_i386 = 40, + dwarf_cs_i386 = 41, + dwarf_ss_i386 = 42, + dwarf_ds_i386 = 43, + dwarf_fs_i386 = 44, + dwarf_gs_i386 = 45, + + // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and + // then differentiate based on size of the register. + dwarf_bnd0_i386 = 101, + dwarf_bnd1_i386, + dwarf_bnd2_i386, + dwarf_bnd3_i386, +}; + +// AMD x86_64, AMD64, Intel EM64T, or Intel 64 ehframe, dwarf regnums + +// EHFrame and DWARF Register numbers (eRegisterKindEHFrame & +// eRegisterKindDWARF) +// This is the spec I used (as opposed to x86-64-abi-0.99.pdf): +// http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf +enum { + // GP Registers + dwarf_rax_x86_64 = 0, + dwarf_rdx_x86_64, + dwarf_rcx_x86_64, + dwarf_rbx_x86_64, + dwarf_rsi_x86_64, + dwarf_rdi_x86_64, + dwarf_rbp_x86_64, + dwarf_rsp_x86_64, + // Extended GP Registers + dwarf_r8_x86_64 = 8, + dwarf_r9_x86_64, + dwarf_r10_x86_64, + dwarf_r11_x86_64, + dwarf_r12_x86_64, + dwarf_r13_x86_64, + dwarf_r14_x86_64, + dwarf_r15_x86_64, + // Return Address (RA) mapped to RIP + dwarf_rip_x86_64 = 16, + // SSE Vector Registers + dwarf_xmm0_x86_64 = 17, + dwarf_xmm1_x86_64, + dwarf_xmm2_x86_64, + dwarf_xmm3_x86_64, + dwarf_xmm4_x86_64, + dwarf_xmm5_x86_64, + dwarf_xmm6_x86_64, + dwarf_xmm7_x86_64, + dwarf_xmm8_x86_64, + dwarf_xmm9_x86_64, + dwarf_xmm10_x86_64, + dwarf_xmm11_x86_64, + dwarf_xmm12_x86_64, + dwarf_xmm13_x86_64, + dwarf_xmm14_x86_64, + dwarf_xmm15_x86_64, + // Floating Point Registers + dwarf_st0_x86_64 = 33, + dwarf_st1_x86_64, + dwarf_st2_x86_64, + dwarf_st3_x86_64, + dwarf_st4_x86_64, + dwarf_st5_x86_64, + dwarf_st6_x86_64, + dwarf_st7_x86_64, + // MMX Registers + dwarf_mm0_x86_64 = 41, + dwarf_mm1_x86_64, + dwarf_mm2_x86_64, + dwarf_mm3_x86_64, + dwarf_mm4_x86_64, + dwarf_mm5_x86_64, + dwarf_mm6_x86_64, + dwarf_mm7_x86_64, + // Control and Status Flags Register + dwarf_rflags_x86_64 = 49, + // selector registers + dwarf_es_x86_64 = 50, + dwarf_cs_x86_64, + dwarf_ss_x86_64, + dwarf_ds_x86_64, + dwarf_fs_x86_64, + dwarf_gs_x86_64, + // Base registers + dwarf_fs_base_x86_64 = 58, + dwarf_gs_base_x86_64 = 59, + // Floating point control registers + dwarf_mxcsr_x86_64 = 64, // Media Control and Status + dwarf_fctrl_x86_64, // x87 control word + dwarf_fstat_x86_64, // x87 status word + // Upper Vector Registers + dwarf_ymm0h_x86_64 = 67, + dwarf_ymm1h_x86_64, + dwarf_ymm2h_x86_64, + dwarf_ymm3h_x86_64, + dwarf_ymm4h_x86_64, + dwarf_ymm5h_x86_64, + dwarf_ymm6h_x86_64, + dwarf_ymm7h_x86_64, + dwarf_ymm8h_x86_64, + dwarf_ymm9h_x86_64, + dwarf_ymm10h_x86_64, + dwarf_ymm11h_x86_64, + dwarf_ymm12h_x86_64, + dwarf_ymm13h_x86_64, + dwarf_ymm14h_x86_64, + dwarf_ymm15h_x86_64, + // MPX registers + dwarf_bnd0_x86_64 = 126, + dwarf_bnd1_x86_64, + dwarf_bnd2_x86_64, + dwarf_bnd3_x86_64, + // AVX2 Vector Mask Registers + // dwarf_k0_x86_64 = 118, + // dwarf_k1_x86_64, + // dwarf_k2_x86_64, + // dwarf_k3_x86_64, + // dwarf_k4_x86_64, + // dwarf_k5_x86_64, + // dwarf_k6_x86_64, + // dwarf_k7_x86_64, +}; + +// Generic floating-point registers + +LLVM_PACKED_START +struct MMSRegComp { + uint64_t mantissa; + uint16_t sign_exp; +}; + +struct MMSReg { + 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 +}; + +// i387_fxsave_struct +struct FXSAVE { + uint16_t fctrl; // FPU Control Word (fcw) + uint16_t fstat; // FPU Status Word (fsw) + uint16_t ftag; // FPU Tag Word (ftw) + uint16_t fop; // Last Instruction Opcode (fop) + union { + struct { + uint64_t fip; // Instruction Pointer + uint64_t fdp; // Data Pointer + } x86_64; + struct { + uint32_t fioff; // FPU IP Offset (fip) + uint32_t fiseg; // FPU IP Selector (fcs) + uint32_t fooff; // FPU Operand Pointer Offset (foo) + uint32_t foseg; // FPU Operand Pointer Selector (fos) + } i386_; // Added _ in the end to avoid error with gcc defining i386 in some + // cases + } ptr; + uint32_t mxcsr; // MXCSR Register State + uint32_t mxcsrmask; // MXCSR Mask + MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes + XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes + uint8_t padding1[48]; + uint64_t xcr0; + uint8_t padding2[40]; +}; + +// Extended floating-point registers + +struct YMMHReg { + uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register +}; + +struct YMMReg { + uint8_t bytes[32]; // 16 * 16 bits for each YMM register +}; + +struct YMM { + YMMReg ymm[16]; // assembled from ymmh and xmm registers +}; + +struct MPXReg { + uint8_t bytes[16]; // MPX 128 bit bound registers +}; + +struct MPXCsr { + uint8_t bytes[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively + // BNDCSR state) +}; + +struct MPX { + MPXReg mpxr[4]; + MPXCsr mpxc[2]; +}; + +LLVM_PACKED_START +struct XSAVE_HDR { + enum class XFeature : uint64_t { + FP = 1, + SSE = FP << 1, + YMM = SSE << 1, + BNDREGS = YMM << 1, + BNDCSR = BNDREGS << 1, + OPMASK = BNDCSR << 1, + ZMM_Hi256 = OPMASK << 1, + Hi16_ZMM = ZMM_Hi256 << 1, + PT = Hi16_ZMM << 1, + PKRU = PT << 1, + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ PKRU) + }; + + XFeature xstate_bv; // OS enabled xstate mask to determine the extended states + // supported by the processor + XFeature xcomp_bv; // Mask to indicate the format of the XSAVE area and of + // the XRSTOR instruction + uint64_t reserved1[1]; + uint64_t reserved2[5]; +}; +static_assert(sizeof(XSAVE_HDR) == 64, "XSAVE_HDR layout incorrect"); +LLVM_PACKED_END + +// x86 extensions to FXSAVE (i.e. for AVX and MPX processors) +LLVM_PACKED_START +struct XSAVE { + FXSAVE i387; // floating point registers typical in i387_fxsave_struct + XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the + // following extensions are usable + YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes + // are in FXSAVE.xmm for compatibility with SSE) + uint64_t reserved3[16]; + MPXReg mpxr[4]; // MPX BNDREG state, containing 128-bit bound registers + MPXCsr mpxc[2]; // MPX BNDCSR state, containing 64-bit BNDCFGU and + // BNDSTATUS registers +}; +LLVM_PACKED_END + +// Floating-point registers +union FPR { + FXSAVE fxsave; // Generic floating-point registers. + XSAVE xsave; // x86 extended processor state. +}; + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +// Convenience function to combine YMM register data from XSAVE-style input. +inline YMMReg XStateToYMM(const void* xmm_bytes, const void* ymmh_bytes) { + YMMReg ret; + + ::memcpy(ret.bytes, xmm_bytes, sizeof(XMMReg)); + ::memcpy(ret.bytes + sizeof(XMMReg), ymmh_bytes, sizeof(YMMHReg)); + + return ret; +} + +// Convenience function to copy YMM register data into XSAVE-style output. +inline void YMMToXState(const YMMReg& input, void* xmm_bytes, void* ymmh_bytes) { + ::memcpy(xmm_bytes, input.bytes, sizeof(XMMReg)); + ::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/RegisterFlagsDetector_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp new file mode 100644 index 000000000000..7c8dba368093 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp @@ -0,0 +1,217 @@ +//===-- RegisterFlagsDetector_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 "RegisterFlagsDetector_arm64.h" +#include "lldb/lldb-private-types.h" + +// This file is built on all systems because it is used by native processes and +// core files, so we manually define the needed HWCAP values here. +// These values are the same for Linux and FreeBSD. + +#define HWCAP_FPHP (1ULL << 9) +#define HWCAP_ASIMDHP (1ULL << 10) +#define HWCAP_DIT (1ULL << 24) +#define HWCAP_SSBS (1ULL << 28) + +#define HWCAP2_BTI (1ULL << 17) +#define HWCAP2_MTE (1ULL << 18) +#define HWCAP2_AFP (1ULL << 20) +#define HWCAP2_SME (1ULL << 23) +#define HWCAP2_EBF16 (1ULL << 32) + +using namespace lldb_private; + +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) { + (void)hwcap; + + if (!(hwcap2 & HWCAP2_SME)) + return {}; + + // Represents the pseudo register that lldb-server builds, which itself + // matches the architectural register SCVR. The fields match SVCR in the Arm + // manual. + return { + {"ZA", 1}, + {"SM", 0}, + }; +} + +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap, + uint64_t hwcap2) { + (void)hwcap; + + if (!(hwcap2 & HWCAP2_MTE)) + return {}; + + // Represents the contents of NT_ARM_TAGGED_ADDR_CTRL and the value passed + // to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines + // used to build the value. + + static const FieldEnum tcf_enum( + "tcf_enum", + {{0, "TCF_NONE"}, {1, "TCF_SYNC"}, {2, "TCF_ASYNC"}, {3, "TCF_ASYMM"}}); + return {{"TAGS", 3, 18}, // 16 bit bitfield shifted up by PR_MTE_TAG_SHIFT. + {"TCF", 1, 2, &tcf_enum}, + {"TAGGED_ADDR_ENABLE", 0}}; +} + +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) { + static const FieldEnum rmode_enum( + "rmode_enum", {{0, "RN"}, {1, "RP"}, {2, "RM"}, {3, "RZ"}}); + + std::vector<RegisterFlags::Field> fpcr_fields{ + {"AHP", 26}, {"DN", 25}, {"FZ", 24}, {"RMode", 22, 23, &rmode_enum}, + // Bits 21-20 are "Stride" which is unused in AArch64 state. + }; + + // FEAT_FP16 is indicated by the presence of FPHP (floating point half + // precision) and ASIMDHP (Advanced SIMD half precision) features. + if ((hwcap & HWCAP_FPHP) && (hwcap & HWCAP_ASIMDHP)) + fpcr_fields.push_back({"FZ16", 19}); + + // Bits 18-16 are "Len" which is unused in AArch64 state. + + fpcr_fields.push_back({"IDE", 15}); + + // Bit 14 is unused. + if (hwcap2 & HWCAP2_EBF16) + fpcr_fields.push_back({"EBF", 13}); + + fpcr_fields.push_back({"IXE", 12}); + fpcr_fields.push_back({"UFE", 11}); + fpcr_fields.push_back({"OFE", 10}); + fpcr_fields.push_back({"DZE", 9}); + fpcr_fields.push_back({"IOE", 8}); + // Bits 7-3 reserved. + + if (hwcap2 & HWCAP2_AFP) { + fpcr_fields.push_back({"NEP", 2}); + fpcr_fields.push_back({"AH", 1}); + fpcr_fields.push_back({"FIZ", 0}); + } + + return fpcr_fields; +} + +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) { + // fpsr's contents are constant. + (void)hwcap; + (void)hwcap2; + + return { + // Bits 31-28 are N/Z/C/V, only used by AArch32. + {"QC", 27}, + // Bits 26-8 reserved. + {"IDC", 7}, + // Bits 6-5 reserved. + {"IXC", 4}, + {"UFC", 3}, + {"OFC", 2}, + {"DZC", 1}, + {"IOC", 0}, + }; +} + +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) { + // The fields here are a combination of the Arm manual's SPSR_EL1, + // plus a few changes where Linux has decided not to make use of them at all, + // or at least not from userspace. + + // Status bits that are always present. + std::vector<RegisterFlags::Field> cpsr_fields{ + {"N", 31}, {"Z", 30}, {"C", 29}, {"V", 28}, + // Bits 27-26 reserved. + }; + + if (hwcap2 & HWCAP2_MTE) + cpsr_fields.push_back({"TCO", 25}); + if (hwcap & HWCAP_DIT) + cpsr_fields.push_back({"DIT", 24}); + + // UAO and PAN are bits 23 and 22 and have no meaning for userspace so + // are treated as reserved by the kernels. + + cpsr_fields.push_back({"SS", 21}); + cpsr_fields.push_back({"IL", 20}); + // Bits 19-14 reserved. + + // Bit 13, ALLINT, requires FEAT_NMI that isn't relevant to userspace, and we + // can't detect either, don't show this field. + if (hwcap & HWCAP_SSBS) + cpsr_fields.push_back({"SSBS", 12}); + if (hwcap2 & HWCAP2_BTI) + cpsr_fields.push_back({"BTYPE", 10, 11}); + + cpsr_fields.push_back({"D", 9}); + cpsr_fields.push_back({"A", 8}); + cpsr_fields.push_back({"I", 7}); + cpsr_fields.push_back({"F", 6}); + // Bit 5 reserved + // Called "M" in the ARMARM. + cpsr_fields.push_back({"nRW", 4}); + // This is a 4 bit field M[3:0] in the ARMARM, we split it into parts. + cpsr_fields.push_back({"EL", 2, 3}); + // Bit 1 is unused and expected to be 0. + cpsr_fields.push_back({"SP", 0}); + + return cpsr_fields; +} + +void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2) { + for (auto ® : m_registers) + reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2)); + m_has_detected = true; +} + +void Arm64RegisterFlagsDetector::UpdateRegisterInfo( + const RegisterInfo *reg_info, uint32_t num_regs) { + assert(m_has_detected && + "Must call DetectFields before updating register info."); + + // Register names will not be duplicated, so we do not want to compare against + // one if it has already been found. Each time we find one, we erase it from + // this list. + std::vector<std::pair<llvm::StringRef, const RegisterFlags *>> + search_registers; + for (const auto ® : m_registers) { + // It is possible that a register is all extension dependent fields, and + // none of them are present. + if (reg.m_flags.GetFields().size()) + search_registers.push_back({reg.m_name, ®.m_flags}); + } + + // Walk register information while there are registers we know need + // to be updated. Example: + // Register information: [a, b, c, d] + // To be patched: [b, c] + // * a != b, a != c, do nothing and move on. + // * b == b, patch b, new patch list is [c], move on. + // * c == c, patch c, patch list is empty, exit early without looking at d. + for (uint32_t idx = 0; idx < num_regs && search_registers.size(); + ++idx, ++reg_info) { + auto reg_it = std::find_if( + search_registers.cbegin(), search_registers.cend(), + [reg_info](auto reg) { return reg.first == reg_info->name; }); + + if (reg_it != search_registers.end()) { + // Attach the field information. + reg_info->flags_type = reg_it->second; + // We do not expect to see this name again so don't look for it again. + search_registers.erase(reg_it); + } + } + + // We do not assert that search_registers is empty here, because it may + // contain registers from optional extensions that are not present on the + // current target. +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h new file mode 100644 index 000000000000..a5bb38670b9c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h @@ -0,0 +1,86 @@ +//===-- RegisterFlagsDetector_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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H + +#include "lldb/Target/RegisterFlags.h" +#include "llvm/ADT/StringRef.h" +#include <functional> + +namespace lldb_private { + +struct RegisterInfo; + +/// This class manages the storage and detection of register field information. +/// The same register may have different fields on different CPUs. This class +/// abstracts out the field detection process so we can use it on live processes +/// and core files. +/// +/// The way to use this class is: +/// * Make an instance somewhere that will last as long as the debug session +/// (because your final register info will point to this instance). +/// * Read hardware capabilities from a core note, binary, prctl, etc. +/// * Pass those to DetectFields. +/// * Call UpdateRegisterInfo with your RegisterInfo to add pointers +/// to the detected fields for all registers listed in this class. +/// +/// This must be done in that order, and you should ensure that if multiple +/// threads will reference the information, a mutex is used to make sure only +/// one calls DetectFields. +class Arm64RegisterFlagsDetector { +public: + /// For the registers listed in this class, detect which fields are + /// present. Must be called before UpdateRegisterInfos. + /// If called more than once, fields will be redetected each time from + /// scratch. If the target would not have this register at all, the list of + /// fields will be left empty. + void DetectFields(uint64_t hwcap, uint64_t hwcap2); + + /// Add the field information of any registers named in this class, + /// to the relevant RegisterInfo instances. Note that this will be done + /// with a pointer to the instance of this class that you call this on, so + /// the lifetime of that instance must be at least that of the register info. + void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs); + + /// Returns true if field detection has been run at least once. + bool HasDetected() const { return m_has_detected; } + +private: + using Fields = std::vector<RegisterFlags::Field>; + using DetectorFn = std::function<Fields(uint64_t, uint64_t)>; + + static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2); + static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2); + static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2); + static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2); + static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2); + + struct RegisterEntry { + RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector) + : m_name(name), m_flags(std::string(name) + "_flags", size, {}), + m_detector(detector) {} + + llvm::StringRef m_name; + RegisterFlags m_flags; + DetectorFn m_detector; + } m_registers[5] = { + RegisterEntry("cpsr", 4, DetectCPSRFields), + RegisterEntry("fpsr", 4, DetectFPSRFields), + RegisterEntry("fpcr", 4, DetectFPCRFields), + RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields), + RegisterEntry("svcr", 8, DetectSVCRFields), + }; + + // Becomes true once field detection has been run for all registers. + bool m_has_detected = false; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h new file mode 100644 index 000000000000..7e569dc9ba78 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h @@ -0,0 +1,36 @@ +//===-- RegisterInfoAndSetInterface.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_REGISTERINFOANDSETINTERFACE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOANDSETINTERFACE_H + +#include "RegisterInfoInterface.h" + +#include "lldb/Utility/ArchSpec.h" +#include "lldb/lldb-private-types.h" +#include <vector> + +namespace lldb_private { + +class RegisterInfoAndSetInterface : public RegisterInfoInterface { +public: + RegisterInfoAndSetInterface(const lldb_private::ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + + virtual size_t GetFPRSize() const = 0; + + virtual const lldb_private::RegisterSet * + GetRegisterSet(size_t reg_set) const = 0; + + virtual size_t GetRegisterSetCount() const = 0; + + virtual size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const = 0; +}; +} // namespace lldb_private + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h new file mode 100644 index 000000000000..a79c5cc22b24 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h @@ -0,0 +1,49 @@ +//===-- RegisterInfoInterface.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_REGISTERINFOINTERFACE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOINTERFACE_H + +#include "lldb/Utility/ArchSpec.h" +#include "lldb/lldb-private-types.h" +#include <vector> + +namespace lldb_private { + +/// \class RegisterInfoInterface +/// +/// RegisterInfo interface to patch RegisterInfo structure for archs. +class RegisterInfoInterface { +public: + RegisterInfoInterface(const lldb_private::ArchSpec &target_arch) + : m_target_arch(target_arch) {} + virtual ~RegisterInfoInterface() = default; + + virtual size_t GetGPRSize() const = 0; + + virtual const lldb_private::RegisterInfo *GetRegisterInfo() const = 0; + + // Returns the number of registers including the user registers and the + // lldb internal registers also + virtual uint32_t GetRegisterCount() const = 0; + + // Returns the number of the user registers (excluding the registers + // kept for lldb internal use only). Subclasses should override it if + // they belongs to an architecture with lldb internal registers. + virtual uint32_t GetUserRegisterCount() const { return GetRegisterCount(); } + + const lldb_private::ArchSpec &GetTargetArchitecture() const { + return m_target_arch; + } + +private: + lldb_private::ArchSpec m_target_arch; +}; +} // 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 new file mode 100644 index 000000000000..d47647422ae2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp @@ -0,0 +1,193 @@ +//===-- RegisterInfoPOSIX_arm.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 <cassert> +#include <cstddef> +#include <vector> + +#include "lldb/lldb-defines.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterInfoPOSIX_arm.h" + +using namespace lldb; +using namespace lldb_private; + +// Based on RegisterContextDarwin_arm.cpp +#define GPR_OFFSET(idx) ((idx)*4) +#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR)) +#define FPSCR_OFFSET \ + (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::FPU, fpscr) + \ + sizeof(RegisterInfoPOSIX_arm::GPR)) +#define EXC_OFFSET(idx) \ + ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR) + \ + sizeof(RegisterInfoPOSIX_arm::FPU)) +#define DBG_OFFSET(reg) \ + ((LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::DBG, reg) + \ + sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \ + sizeof(RegisterInfoPOSIX_arm::EXC))) + +#define DEFINE_DBG(reg, i) \ + #reg, NULL, sizeof(((RegisterInfoPOSIX_arm::DBG *) NULL)->reg[i]), \ + DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + dbg_##reg##i }, \ + NULL, NULL, NULL, +#define REG_CONTEXT_SIZE \ + (sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \ + sizeof(RegisterInfoPOSIX_arm::EXC)) + +// Include RegisterInfos_arm to declare our g_register_infos_arm structure. +#define DECLARE_REGISTER_INFOS_ARM_STRUCT +#include "RegisterInfos_arm.h" +#undef DECLARE_REGISTER_INFOS_ARM_STRUCT + +static const lldb_private::RegisterInfo * +GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::arm: + return g_register_infos_arm; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t +GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::arm: + return static_cast<uint32_t>(sizeof(g_register_infos_arm) / + sizeof(g_register_infos_arm[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +// 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::RegisterInfoAndSetInterface(target_arch), + m_register_info_p(GetRegisterInfoPtr(target_arch)), + m_register_info_count(GetRegisterInfoCount(target_arch)) {} + +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 new file mode 100644 index 000000000000..db155d757ca8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h @@ -0,0 +1,72 @@ +//===-- RegisterInfoPOSIX_arm.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_REGISTERINFOPOSIX_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H + +#include "RegisterInfoAndSetInterface.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +class RegisterInfoPOSIX_arm : public lldb_private::RegisterInfoAndSetInterface { +public: + enum { GPRegSet = 0, FPRegSet}; + + struct GPR { + uint32_t r[16]; // R0-R15 + uint32_t cpsr; // CPSR + }; + + 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; + }; + struct EXC { + uint32_t exception; + uint32_t fsr; /* Fault status */ + uint32_t far; /* Virtual Fault Address */ + }; + + struct DBG { + uint32_t bvr[16]; + uint32_t bcr[16]; + uint32_t wvr[16]; + uint32_t wcr[16]; + }; + + RegisterInfoPOSIX_arm(const lldb_private::ArchSpec &target_arch); + + 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; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H 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 new file mode 100644 index 000000000000..054b7d9b2ec5 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp @@ -0,0 +1,561 @@ +//===-- RegisterInfoPOSIX_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 <cassert> +#include <cstddef> +#include <vector> + +#include "lldb/lldb-defines.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterInfoPOSIX_arm64.h" + +// Based on RegisterContextDarwin_arm64.cpp +#define GPR_OFFSET(idx) ((idx)*8) +#define GPR_OFFSET_NAME(reg) \ + (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::GPR, reg)) + +#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterInfoPOSIX_arm64::GPR)) +#define FPU_OFFSET_NAME(reg) \ + (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) + \ + sizeof(RegisterInfoPOSIX_arm64::FPU)) +#define DBG_OFFSET_NAME(reg) \ + (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::DBG, reg) + \ + sizeof(RegisterInfoPOSIX_arm64::GPR) + \ + sizeof(RegisterInfoPOSIX_arm64::FPU) + \ + sizeof(RegisterInfoPOSIX_arm64::EXC)) + +#define DEFINE_DBG(reg, i) \ + #reg, NULL, \ + sizeof(((RegisterInfoPOSIX_arm64::DBG *) NULL)->reg[i]), \ + DBG_OFFSET_NAME(reg[i]), lldb::eEncodingUint, lldb::eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + dbg_##reg##i }, \ + NULL, NULL, NULL, +#define REG_CONTEXT_SIZE \ + (sizeof(RegisterInfoPOSIX_arm64::GPR) + \ + sizeof(RegisterInfoPOSIX_arm64::FPU) + \ + sizeof(RegisterInfoPOSIX_arm64::EXC)) + +// 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 lldb_private::RegisterInfo g_register_infos_pauth[] = { + DEFINE_EXTENSION_REG(data_mask), DEFINE_EXTENSION_REG(code_mask)}; + +static lldb_private::RegisterInfo g_register_infos_mte[] = { + DEFINE_EXTENSION_REG(mte_ctrl)}; + +static lldb_private::RegisterInfo g_register_infos_tls[] = { + DEFINE_EXTENSION_REG(tpidr), + // Only present when SME is present + DEFINE_EXTENSION_REG(tpidr2)}; + +static lldb_private::RegisterInfo g_register_infos_sme[] = { + DEFINE_EXTENSION_REG(svcr), + DEFINE_EXTENSION_REG(svg), + // 16 is a default size we will change later. + {"za", nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, + KIND_ALL_INVALID, nullptr, nullptr, nullptr}}; + +static lldb_private::RegisterInfo g_register_infos_sme2[] = { + {"zt0", nullptr, 64, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, + KIND_ALL_INVALID, nullptr, nullptr, nullptr}}; + +// Number of register sets provided by this context. +enum { + k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, + k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1, + k_num_sve_registers = sve_ffr - sve_vg + 1, + k_num_mte_register = 1, + // Number of TLS registers is dynamic so it is not listed here. + k_num_pauth_register = 2, + // SME2's ZT0 will also be added to this set if present. So this number is + // only for SME1 registers. + k_num_sme_register = 3, + k_num_register_sets_default = 2, + k_num_register_sets = 3 +}; + +// ARM64 general purpose registers. +static const uint32_t g_gpr_regnums_arm64[] = { + gpr_x0, gpr_x1, gpr_x2, gpr_x3, + gpr_x4, gpr_x5, gpr_x6, gpr_x7, + gpr_x8, gpr_x9, gpr_x10, gpr_x11, + gpr_x12, gpr_x13, gpr_x14, gpr_x15, + gpr_x16, gpr_x17, gpr_x18, gpr_x19, + gpr_x20, gpr_x21, gpr_x22, gpr_x23, + gpr_x24, gpr_x25, gpr_x26, gpr_x27, + gpr_x28, gpr_fp, gpr_lr, gpr_sp, + gpr_pc, gpr_cpsr, gpr_w0, gpr_w1, + gpr_w2, gpr_w3, gpr_w4, gpr_w5, + gpr_w6, gpr_w7, gpr_w8, gpr_w9, + gpr_w10, gpr_w11, gpr_w12, gpr_w13, + gpr_w14, gpr_w15, gpr_w16, gpr_w17, + gpr_w18, gpr_w19, gpr_w20, gpr_w21, + gpr_w22, gpr_w23, gpr_w24, gpr_w25, + gpr_w26, gpr_w27, gpr_w28, LLDB_INVALID_REGNUM}; + +static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - + 1) == k_num_gpr_registers, + "g_gpr_regnums_arm64 has wrong number of register infos"); + +// ARM64 floating point registers. +static const uint32_t g_fpu_regnums_arm64[] = { + fpu_v0, fpu_v1, fpu_v2, + fpu_v3, fpu_v4, fpu_v5, + fpu_v6, fpu_v7, fpu_v8, + fpu_v9, fpu_v10, fpu_v11, + fpu_v12, fpu_v13, fpu_v14, + fpu_v15, fpu_v16, fpu_v17, + fpu_v18, fpu_v19, fpu_v20, + fpu_v21, fpu_v22, fpu_v23, + fpu_v24, fpu_v25, fpu_v26, + fpu_v27, fpu_v28, fpu_v29, + fpu_v30, fpu_v31, 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_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_fpsr, fpu_fpcr, LLDB_INVALID_REGNUM}; +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"); + +// 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}, + {"Scalable Vector Extension Registers", "sve", k_num_sve_registers, + g_sve_regnums_arm64}}; + +static const lldb_private::RegisterSet g_reg_set_pauth_arm64 = { + "Pointer Authentication Registers", "pauth", k_num_pauth_register, nullptr}; + +static const lldb_private::RegisterSet g_reg_set_mte_arm64 = { + "MTE Control Register", "mte", k_num_mte_register, nullptr}; + +// The size of the TLS set is dynamic, so not listed here. + +static const lldb_private::RegisterSet g_reg_set_sme_arm64 = { + "Scalable Matrix Extension Registers", "sme", k_num_sme_register, nullptr}; + +RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( + const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets) + : lldb_private::RegisterInfoAndSetInterface(target_arch), + m_opt_regsets(opt_regsets) { + switch (target_arch.GetMachine()) { + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: { + m_register_set_p = g_reg_sets_arm64; + m_register_set_count = k_num_register_sets_default; + m_per_regset_regnum_range[GPRegSet] = std::make_pair(gpr_x0, gpr_w28 + 1); + m_per_regset_regnum_range[FPRegSet] = std::make_pair(fpu_v0, fpu_fpcr + 1); + + // Now configure register sets supported by current target. If we have a + // dynamic register set like MTE, Pointer Authentication regset then we need + // to create dynamic register infos and regset array. Push back all optional + // register infos and regset and calculate register offsets accordingly. + if (m_opt_regsets.AnySet(eRegsetMaskSVE | eRegsetMaskSSVE)) { + m_register_info_p = g_register_infos_arm64_sve_le; + m_register_info_count = sve_ffr + 1; + m_per_regset_regnum_range[m_register_set_count++] = + std::make_pair(sve_vg, sve_ffr + 1); + } else { + m_register_info_p = g_register_infos_arm64_le; + m_register_info_count = fpu_fpcr + 1; + } + + if (m_opt_regsets.AnySet(eRegsetMaskDynamic)) { + llvm::ArrayRef<lldb_private::RegisterInfo> reg_infos_ref = + llvm::ArrayRef(m_register_info_p, m_register_info_count); + llvm::ArrayRef<lldb_private::RegisterSet> reg_sets_ref = + llvm::ArrayRef(m_register_set_p, m_register_set_count); + llvm::copy(reg_infos_ref, std::back_inserter(m_dynamic_reg_infos)); + llvm::copy(reg_sets_ref, std::back_inserter(m_dynamic_reg_sets)); + + if (m_opt_regsets.AllSet(eRegsetMaskPAuth)) + AddRegSetPAuth(); + + if (m_opt_regsets.AllSet(eRegsetMaskMTE)) + AddRegSetMTE(); + + // The TLS set always contains tpidr but only has tpidr2 when SME is + // present. + AddRegSetTLS(m_opt_regsets.AllSet(eRegsetMaskSSVE)); + + if (m_opt_regsets.AnySet(eRegsetMaskSSVE)) + AddRegSetSME(m_opt_regsets.AnySet(eRegsetMaskZT)); + + m_register_info_count = m_dynamic_reg_infos.size(); + m_register_info_p = m_dynamic_reg_infos.data(); + m_register_set_p = m_dynamic_reg_sets.data(); + m_register_set_count = m_dynamic_reg_sets.size(); + } + break; + } + default: + assert(false && "Unhandled target architecture."); + } +} + +uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { + return m_register_info_count; +} + +size_t RegisterInfoPOSIX_arm64::GetGPRSizeStatic() { + return sizeof(struct RegisterInfoPOSIX_arm64::GPR); +} + +size_t RegisterInfoPOSIX_arm64::GetFPRSize() const { + return sizeof(struct RegisterInfoPOSIX_arm64::FPU); +} + +const lldb_private::RegisterInfo * +RegisterInfoPOSIX_arm64::GetRegisterInfo() const { + return m_register_info_p; +} + +size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const { + return m_register_set_count; +} + +size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex( + uint32_t reg_index) const { + for (const auto ®set_range : m_per_regset_regnum_range) { + if (reg_index >= regset_range.second.first && + reg_index < regset_range.second.second) + return regset_range.first; + } + return LLDB_INVALID_REGNUM; +} + +const lldb_private::RegisterSet * +RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const { + if (set_index < GetRegisterSetCount()) + return &m_register_set_p[set_index]; + return nullptr; +} + +void RegisterInfoPOSIX_arm64::AddRegSetPAuth() { + uint32_t pa_regnum = m_dynamic_reg_infos.size(); + for (uint32_t i = 0; i < k_num_pauth_register; i++) { + pauth_regnum_collection.push_back(pa_regnum + i); + m_dynamic_reg_infos.push_back(g_register_infos_pauth[i]); + m_dynamic_reg_infos[pa_regnum + i].byte_offset = + m_dynamic_reg_infos[pa_regnum + i - 1].byte_offset + + m_dynamic_reg_infos[pa_regnum + i - 1].byte_size; + m_dynamic_reg_infos[pa_regnum + i].kinds[lldb::eRegisterKindLLDB] = + pa_regnum + i; + } + + m_per_regset_regnum_range[m_register_set_count] = + std::make_pair(pa_regnum, m_dynamic_reg_infos.size()); + m_dynamic_reg_sets.push_back(g_reg_set_pauth_arm64); + m_dynamic_reg_sets.back().registers = pauth_regnum_collection.data(); +} + +void RegisterInfoPOSIX_arm64::AddRegSetMTE() { + uint32_t mte_regnum = m_dynamic_reg_infos.size(); + m_mte_regnum_collection.push_back(mte_regnum); + m_dynamic_reg_infos.push_back(g_register_infos_mte[0]); + m_dynamic_reg_infos[mte_regnum].byte_offset = + m_dynamic_reg_infos[mte_regnum - 1].byte_offset + + m_dynamic_reg_infos[mte_regnum - 1].byte_size; + m_dynamic_reg_infos[mte_regnum].kinds[lldb::eRegisterKindLLDB] = mte_regnum; + + m_per_regset_regnum_range[m_register_set_count] = + std::make_pair(mte_regnum, mte_regnum + 1); + m_dynamic_reg_sets.push_back(g_reg_set_mte_arm64); + m_dynamic_reg_sets.back().registers = m_mte_regnum_collection.data(); +} + +void RegisterInfoPOSIX_arm64::AddRegSetTLS(bool has_tpidr2) { + uint32_t tls_regnum = m_dynamic_reg_infos.size(); + uint32_t num_regs = has_tpidr2 ? 2 : 1; + for (uint32_t i = 0; i < num_regs; i++) { + m_tls_regnum_collection.push_back(tls_regnum + i); + m_dynamic_reg_infos.push_back(g_register_infos_tls[i]); + m_dynamic_reg_infos[tls_regnum + i].byte_offset = + m_dynamic_reg_infos[tls_regnum + i - 1].byte_offset + + m_dynamic_reg_infos[tls_regnum + i - 1].byte_size; + m_dynamic_reg_infos[tls_regnum + i].kinds[lldb::eRegisterKindLLDB] = + tls_regnum + i; + } + + m_per_regset_regnum_range[m_register_set_count] = + std::make_pair(tls_regnum, m_dynamic_reg_infos.size()); + m_dynamic_reg_sets.push_back( + {"Thread Local Storage Registers", "tls", num_regs, nullptr}); + m_dynamic_reg_sets.back().registers = m_tls_regnum_collection.data(); +} + +void RegisterInfoPOSIX_arm64::AddRegSetSME(bool has_zt) { + const uint32_t first_sme_regnum = m_dynamic_reg_infos.size(); + uint32_t sme_regnum = first_sme_regnum; + + for (uint32_t i = 0; i < k_num_sme_register; ++i, ++sme_regnum) { + m_sme_regnum_collection.push_back(sme_regnum); + m_dynamic_reg_infos.push_back(g_register_infos_sme[i]); + m_dynamic_reg_infos[sme_regnum].byte_offset = + m_dynamic_reg_infos[sme_regnum - 1].byte_offset + + m_dynamic_reg_infos[sme_regnum - 1].byte_size; + m_dynamic_reg_infos[sme_regnum].kinds[lldb::eRegisterKindLLDB] = sme_regnum; + } + + lldb_private::RegisterSet sme_regset = g_reg_set_sme_arm64; + + if (has_zt) { + m_sme_regnum_collection.push_back(sme_regnum); + m_dynamic_reg_infos.push_back(g_register_infos_sme2[0]); + m_dynamic_reg_infos[sme_regnum].byte_offset = + m_dynamic_reg_infos[sme_regnum - 1].byte_offset + + m_dynamic_reg_infos[sme_regnum - 1].byte_size; + m_dynamic_reg_infos[sme_regnum].kinds[lldb::eRegisterKindLLDB] = sme_regnum; + + sme_regset.num_registers += 1; + } + + m_per_regset_regnum_range[m_register_set_count] = + std::make_pair(first_sme_regnum, m_dynamic_reg_infos.size()); + m_dynamic_reg_sets.push_back(sme_regset); + m_dynamic_reg_sets.back().registers = m_sme_regnum_collection.data(); + + // When vg is written during streaming mode, svg will also change, as vg and + // svg in this state are both showing the streaming vector length. + // We model this as vg invalidating svg. In non-streaming mode this doesn't + // happen but to keep things simple we will invalidate svg anyway. + // + // This must be added now, rather than when vg is defined because SME is a + // dynamic set that may or may not be present. + static uint32_t vg_invalidates[] = {sme_regnum + 1 /*svg*/, + LLDB_INVALID_REGNUM}; + m_dynamic_reg_infos[GetRegNumSVEVG()].invalidate_regs = vg_invalidates; +} + +uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLengthSVE(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) + return m_vector_reg_vq; + std::vector<lldb_private::RegisterInfo> ®_info_ref = + m_per_vq_reg_infos[sve_vq]; + + if (reg_info_ref.empty()) { + reg_info_ref = llvm::ArrayRef(m_register_info_p, 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; + } + + for (uint32_t it = sve_ffr + 1; it < m_register_info_count; it++) { + reg_info_ref[it].byte_offset = offset; + offset += reg_info_ref[it].byte_size; + } + + m_per_vq_reg_infos[sve_vq] = reg_info_ref; + } + + m_register_info_p = m_per_vq_reg_infos[sve_vq].data(); + return m_vector_reg_vq; +} + +void RegisterInfoPOSIX_arm64::ConfigureVectorLengthZA(uint32_t za_vq) { + if (!VectorSizeIsValid(za_vq) || m_za_reg_vq == za_vq) + return; + + m_za_reg_vq = za_vq; + + // For SVE changes, we replace m_register_info_p completely. ZA is in a + // dynamic set and is just 1 register so we make an exception to const here. + lldb_private::RegisterInfo *non_const_reginfo = + const_cast<lldb_private::RegisterInfo *>(m_register_info_p); + non_const_reginfo[m_sme_regnum_collection[2]].byte_size = + (za_vq * 16) * (za_vq * 16); +} + +bool RegisterInfoPOSIX_arm64::IsSVEReg(unsigned reg) const { + if (m_vector_reg_vq > eVectorQuadwordAArch64) + return (sve_vg <= reg && reg <= sve_ffr); + else + return false; +} + +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; +} + +bool RegisterInfoPOSIX_arm64::IsSMERegZA(unsigned reg) const { + return reg == m_sme_regnum_collection[2]; +} + +bool RegisterInfoPOSIX_arm64::IsSMERegZT(unsigned reg) const { + // ZT0 is part of the SME register set only if SME2 is present. + return m_sme_regnum_collection.size() >= 4 && + reg == m_sme_regnum_collection[3]; +} + +bool RegisterInfoPOSIX_arm64::IsPAuthReg(unsigned reg) const { + return llvm::is_contained(pauth_regnum_collection, reg); +} + +bool RegisterInfoPOSIX_arm64::IsMTEReg(unsigned reg) const { + return llvm::is_contained(m_mte_regnum_collection, reg); +} + +bool RegisterInfoPOSIX_arm64::IsTLSReg(unsigned reg) const { + return llvm::is_contained(m_tls_regnum_collection, reg); +} + +bool RegisterInfoPOSIX_arm64::IsSMEReg(unsigned reg) const { + return llvm::is_contained(m_sme_regnum_collection, 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; } + +uint32_t RegisterInfoPOSIX_arm64::GetRegNumSMESVG() const { + return m_sme_regnum_collection[1]; +} + +uint32_t RegisterInfoPOSIX_arm64::GetPAuthOffset() const { + return m_register_info_p[pauth_regnum_collection[0]].byte_offset; +} + +uint32_t RegisterInfoPOSIX_arm64::GetMTEOffset() const { + return m_register_info_p[m_mte_regnum_collection[0]].byte_offset; +} + +uint32_t RegisterInfoPOSIX_arm64::GetTLSOffset() const { + return m_register_info_p[m_tls_regnum_collection[0]].byte_offset; +} + +uint32_t RegisterInfoPOSIX_arm64::GetSMEOffset() const { + return m_register_info_p[m_sme_regnum_collection[0]].byte_offset; +} 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 new file mode 100644 index 000000000000..3b8171042c73 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h @@ -0,0 +1,186 @@ +//===-- RegisterInfoPOSIX_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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H + +#include "RegisterInfoAndSetInterface.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Flags.h" +#include "lldb/lldb-private.h" +#include <map> + +enum class SVEState : uint8_t { Unknown, Disabled, FPSIMD, Full, Streaming }; + +class RegisterInfoPOSIX_arm64 + : public lldb_private::RegisterInfoAndSetInterface { +public: + enum { GPRegSet = 0, FPRegSet }; + + // AArch64 register set mask value + enum { + eRegsetMaskDefault = 0, + eRegsetMaskSVE = 1, + eRegsetMaskSSVE = 2, + eRegsetMaskPAuth = 4, + eRegsetMaskMTE = 8, + eRegsetMaskTLS = 16, + eRegsetMaskZA = 32, + eRegsetMaskZT = 64, + eRegsetMaskDynamic = ~1, + }; + + // 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 + uint64_t lr; // x30 + uint64_t sp; // x31 + uint64_t pc; // pc + uint32_t cpsr; // cpsr + uint32_t pad; + }; + LLVM_PACKED_END + + // based on RegisterContextDarwin_arm64.h + struct VReg { + uint8_t bytes[16]; + }; + + // based on RegisterContextDarwin_arm64.h + struct FPU { + VReg v[32]; + uint32_t fpsr; + uint32_t fpcr; + }; + + // based on RegisterContextDarwin_arm64.h + struct EXC { + uint64_t far; // Virtual Fault Address + uint32_t esr; // Exception syndrome + uint32_t exception; // number of arm exception token + }; + + // based on RegisterContextDarwin_arm64.h + struct DBG { + uint64_t bvr[16]; + uint64_t bcr[16]; + uint64_t wvr[16]; + uint64_t wcr[16]; + uint64_t mdscr_el1; + }; + + RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch, + lldb_private::Flags opt_regsets); + + static size_t GetGPRSizeStatic(); + size_t GetGPRSize() const override { return GetGPRSizeStatic(); } + + 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; + + void AddRegSetPAuth(); + + void AddRegSetMTE(); + + void AddRegSetTLS(bool has_tpidr2); + + void AddRegSetSME(bool has_zt); + + uint32_t ConfigureVectorLengthSVE(uint32_t sve_vq); + + void ConfigureVectorLengthZA(uint32_t za_vq); + + bool VectorSizeIsValid(uint32_t vq) { + // coverity[unsigned_compare] + if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax) + return true; + return false; + } + + bool IsSVEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); } + bool IsSSVEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskSSVE); } + bool IsZAPresent() const { return m_opt_regsets.AnySet(eRegsetMaskZA); } + bool IsZTPresent() const { return m_opt_regsets.AnySet(eRegsetMaskZT); } + bool IsPAuthPresent() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); } + bool IsMTEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskMTE); } + bool IsTLSPresent() const { return m_opt_regsets.AnySet(eRegsetMaskTLS); } + + bool IsSVEReg(unsigned reg) const; + bool IsSVEZReg(unsigned reg) const; + bool IsSVEPReg(unsigned reg) const; + bool IsSVERegVG(unsigned reg) const; + bool IsPAuthReg(unsigned reg) const; + bool IsMTEReg(unsigned reg) const; + bool IsTLSReg(unsigned reg) const; + bool IsSMEReg(unsigned reg) const; + bool IsSMERegZA(unsigned reg) const; + bool IsSMERegZT(unsigned reg) const; + + uint32_t GetRegNumSVEZ0() const; + uint32_t GetRegNumSVEFFR() const; + uint32_t GetRegNumFPCR() const; + uint32_t GetRegNumFPSR() const; + uint32_t GetRegNumSVEVG() const; + uint32_t GetRegNumSMESVG() const; + uint32_t GetPAuthOffset() const; + uint32_t GetMTEOffset() const; + uint32_t GetTLSOffset() const; + uint32_t GetSMEOffset() const; + +private: + 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 m_vector_reg_vq = eVectorQuadwordAArch64; + uint32_t m_za_reg_vq = eVectorQuadwordAArch64; + + // In normal operation this is const. Only when SVE or SME registers change + // size is it either replaced or the content modified. + const lldb_private::RegisterInfo *m_register_info_p; + uint32_t m_register_info_count; + + const lldb_private::RegisterSet *m_register_set_p; + uint32_t m_register_set_count; + + // Contains pair of [start, end] register numbers of a register set with start + // and end included. + std::map<uint32_t, std::pair<uint32_t, uint32_t>> m_per_regset_regnum_range; + + lldb_private::Flags m_opt_regsets; + + std::vector<lldb_private::RegisterInfo> m_dynamic_reg_infos; + std::vector<lldb_private::RegisterSet> m_dynamic_reg_sets; + + std::vector<uint32_t> pauth_regnum_collection; + std::vector<uint32_t> m_mte_regnum_collection; + std::vector<uint32_t> m_tls_regnum_collection; + std::vector<uint32_t> m_sme_regnum_collection; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.cpp new file mode 100644 index 000000000000..6c723afe4b69 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.cpp @@ -0,0 +1,158 @@ +//===-- RegisterInfoPOSIX_loongarch64.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 <cassert> +#include <lldb/Utility/Flags.h> +#include <stddef.h> + +#include "lldb/lldb-defines.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterInfoPOSIX_loongarch64.h" + +#define GPR_OFFSET(idx) ((idx)*8 + 0) +#define FPR_OFFSET(idx) ((idx)*8 + sizeof(RegisterInfoPOSIX_loongarch64::GPR)) +#define FCC_OFFSET(idx) ((idx)*1 + 32 * 8 + sizeof(RegisterInfoPOSIX_loongarch64::GPR)) +#define FCSR_OFFSET (8 * 1 + 32 * 8 + sizeof(RegisterInfoPOSIX_loongarch64::GPR)) + +#define REG_CONTEXT_SIZE \ + (sizeof(RegisterInfoPOSIX_loongarch64::GPR) + \ + sizeof(RegisterInfoPOSIX_loongarch64::FPR)) + +#define DECLARE_REGISTER_INFOS_LOONGARCH64_STRUCT +#include "RegisterInfos_loongarch64.h" +#undef DECLARE_REGISTER_INFOS_LOONGARCH64_STRUCT + +const lldb_private::RegisterInfo * +RegisterInfoPOSIX_loongarch64::GetRegisterInfoPtr( + const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::loongarch64: + return g_register_infos_loongarch64; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterInfoPOSIX_loongarch64::GetRegisterInfoCount( + const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::loongarch64: + return static_cast<uint32_t>(sizeof(g_register_infos_loongarch64) / + sizeof(g_register_infos_loongarch64[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +// Number of register sets provided by this context. +enum { + k_num_gpr_registers = gpr_last_loongarch - gpr_first_loongarch + 1, + k_num_fpr_registers = fpr_last_loongarch - fpr_first_loongarch + 1, + k_num_register_sets = 2 +}; + +// LoongArch64 general purpose registers. +static const uint32_t g_gpr_regnums_loongarch64[] = { + gpr_r0_loongarch, gpr_r1_loongarch, gpr_r2_loongarch, + gpr_r3_loongarch, gpr_r4_loongarch, gpr_r5_loongarch, + gpr_r6_loongarch, gpr_r7_loongarch, gpr_r8_loongarch, + gpr_r9_loongarch, gpr_r10_loongarch, gpr_r11_loongarch, + gpr_r12_loongarch, gpr_r13_loongarch, gpr_r14_loongarch, + gpr_r15_loongarch, gpr_r16_loongarch, gpr_r17_loongarch, + gpr_r18_loongarch, gpr_r19_loongarch, gpr_r20_loongarch, + gpr_r21_loongarch, gpr_r22_loongarch, gpr_r23_loongarch, + gpr_r24_loongarch, gpr_r25_loongarch, gpr_r26_loongarch, + gpr_r27_loongarch, gpr_r28_loongarch, gpr_r29_loongarch, + gpr_r30_loongarch, gpr_r31_loongarch, gpr_orig_a0_loongarch, + gpr_pc_loongarch, gpr_badv_loongarch, gpr_reserved0_loongarch, + gpr_reserved1_loongarch, gpr_reserved2_loongarch, gpr_reserved3_loongarch, + gpr_reserved4_loongarch, gpr_reserved5_loongarch, gpr_reserved6_loongarch, + gpr_reserved7_loongarch, gpr_reserved8_loongarch, gpr_reserved9_loongarch, + LLDB_INVALID_REGNUM}; + +static_assert(((sizeof g_gpr_regnums_loongarch64 / + sizeof g_gpr_regnums_loongarch64[0]) - + 1) == k_num_gpr_registers, + "g_gpr_regnums_loongarch64 has wrong number of register infos"); + +// LoongArch64 floating point registers. +static const uint32_t g_fpr_regnums_loongarch64[] = { + fpr_f0_loongarch, fpr_f1_loongarch, fpr_f2_loongarch, + fpr_f3_loongarch, fpr_f4_loongarch, fpr_f5_loongarch, + fpr_f6_loongarch, fpr_f7_loongarch, fpr_f8_loongarch, + fpr_f9_loongarch, fpr_f10_loongarch, fpr_f11_loongarch, + fpr_f12_loongarch, fpr_f13_loongarch, fpr_f14_loongarch, + fpr_f15_loongarch, fpr_f16_loongarch, fpr_f17_loongarch, + fpr_f18_loongarch, fpr_f19_loongarch, fpr_f20_loongarch, + fpr_f21_loongarch, fpr_f22_loongarch, fpr_f23_loongarch, + fpr_f24_loongarch, fpr_f25_loongarch, fpr_f26_loongarch, + fpr_f27_loongarch, fpr_f28_loongarch, fpr_f29_loongarch, + fpr_f30_loongarch, fpr_f31_loongarch, fpr_fcc0_loongarch, + fpr_fcc1_loongarch, fpr_fcc2_loongarch, fpr_fcc3_loongarch, + fpr_fcc4_loongarch, fpr_fcc5_loongarch, fpr_fcc6_loongarch, + fpr_fcc7_loongarch, fpr_fcsr_loongarch, LLDB_INVALID_REGNUM}; + +static_assert(((sizeof g_fpr_regnums_loongarch64 / + sizeof g_fpr_regnums_loongarch64[0]) - + 1) == k_num_fpr_registers, + "g_fpr_regnums_loongarch64 has wrong number of register infos"); + +// Register sets for LoongArch64. +static const lldb_private::RegisterSet + g_reg_sets_loongarch64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers, + g_gpr_regnums_loongarch64}, + {"Floating Point Registers", "fpr", k_num_fpr_registers, + g_fpr_regnums_loongarch64}}; + +RegisterInfoPOSIX_loongarch64::RegisterInfoPOSIX_loongarch64( + const lldb_private::ArchSpec &target_arch, lldb_private::Flags flags) + : lldb_private::RegisterInfoAndSetInterface(target_arch), + m_register_info_p(GetRegisterInfoPtr(target_arch)), + m_register_info_count(GetRegisterInfoCount(target_arch)) {} + +uint32_t RegisterInfoPOSIX_loongarch64::GetRegisterCount() const { + return m_register_info_count; +} + +size_t RegisterInfoPOSIX_loongarch64::GetGPRSize() const { + return sizeof(struct RegisterInfoPOSIX_loongarch64::GPR); +} + +size_t RegisterInfoPOSIX_loongarch64::GetFPRSize() const { + return sizeof(struct RegisterInfoPOSIX_loongarch64::FPR); +} + +const lldb_private::RegisterInfo * +RegisterInfoPOSIX_loongarch64::GetRegisterInfo() const { + return m_register_info_p; +} + +size_t RegisterInfoPOSIX_loongarch64::GetRegisterSetCount() const { + return k_num_register_sets; +} + +size_t RegisterInfoPOSIX_loongarch64::GetRegisterSetFromRegisterIndex( + uint32_t reg_index) const { + // coverity[unsigned_compare] + if (reg_index >= gpr_first_loongarch && reg_index <= gpr_last_loongarch) + return GPRegSet; + if (reg_index >= fpr_first_loongarch && reg_index <= fpr_last_loongarch) + return FPRegSet; + return LLDB_INVALID_REGNUM; +} + +const lldb_private::RegisterSet * +RegisterInfoPOSIX_loongarch64::GetRegisterSet(size_t set_index) const { + if (set_index < GetRegisterSetCount()) + return &g_reg_sets_loongarch64[set_index]; + return nullptr; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h new file mode 100644 index 000000000000..a3338acbbc97 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h @@ -0,0 +1,69 @@ +//===-- RegisterInfoPOSIX_loongarch64.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_REGISTERINFOPOSIX_LOONGARCH64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_LOONGARCH64_H + +#include "RegisterInfoAndSetInterface.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" +#include <map> + +class RegisterInfoPOSIX_loongarch64 + : public lldb_private::RegisterInfoAndSetInterface { +public: + static const lldb_private::RegisterInfo * + GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch); + static uint32_t + GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch); + +public: + enum RegSetKind { + GPRegSet, + FPRegSet, + }; + + struct GPR { + uint64_t gpr[32]; + + uint64_t orig_a0; + uint64_t csr_era; + uint64_t csr_badv; + uint64_t reserved[10]; + }; + + struct FPR { + uint64_t fpr[32]; + uint64_t fcc; + uint32_t fcsr; + }; + + RegisterInfoPOSIX_loongarch64(const lldb_private::ArchSpec &target_arch, + lldb_private::Flags flags); + + 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; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp new file mode 100644 index 000000000000..159fd2856443 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp @@ -0,0 +1,63 @@ +//===-- RegisterInfoPOSIX_ppc64le.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 <cassert> +#include <cstddef> +#include <vector> + +#include "lldb/lldb-defines.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterInfoPOSIX_ppc64le.h" + +// Include RegisterInfoPOSIX_ppc64le to declare our g_register_infos_ppc64le +#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT +#include "RegisterInfos_ppc64le.h" +#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT + +static const lldb_private::RegisterInfo * +GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::ppc64le: + return g_register_infos_ppc64le; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t +GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::ppc64le: + return static_cast<uint32_t>(sizeof(g_register_infos_ppc64le) / + sizeof(g_register_infos_ppc64le[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterInfoPOSIX_ppc64le::RegisterInfoPOSIX_ppc64le( + const lldb_private::ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch), + m_register_info_p(GetRegisterInfoPtr(target_arch)), + m_register_info_count(GetRegisterInfoCount(target_arch)) {} + +size_t RegisterInfoPOSIX_ppc64le::GetGPRSize() const { + return sizeof(GPR); +} + +const lldb_private::RegisterInfo * +RegisterInfoPOSIX_ppc64le::GetRegisterInfo() const { + return m_register_info_p; +} + +uint32_t RegisterInfoPOSIX_ppc64le::GetRegisterCount() const { + return m_register_info_count; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h new file mode 100644 index 000000000000..98549ac0dda4 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h @@ -0,0 +1,31 @@ +//===-- RegisterInfoPOSIX_ppc64le.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_REGISTERINFOPOSIX_PPC64LE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_PPC64LE_H + +#include "RegisterInfoInterface.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" + +class RegisterInfoPOSIX_ppc64le : public lldb_private::RegisterInfoInterface { +public: + RegisterInfoPOSIX_ppc64le(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + uint32_t m_register_info_count; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.cpp new file mode 100644 index 000000000000..3819401c543b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.cpp @@ -0,0 +1,142 @@ +//===-- RegisterInfoPOSIX_riscv64.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 <cassert> +#include <lldb/Utility/Flags.h> +#include <stddef.h> + +#include "lldb/lldb-defines.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterInfoPOSIX_riscv64.h" + +#define GPR_OFFSET(idx) ((idx)*8 + 0) +#define FPR_OFFSET(idx) ((idx)*8 + sizeof(RegisterInfoPOSIX_riscv64::GPR)) + +#define REG_CONTEXT_SIZE \ + (sizeof(RegisterInfoPOSIX_riscv64::GPR) + \ + sizeof(RegisterInfoPOSIX_riscv64::FPR)) + +#define DECLARE_REGISTER_INFOS_RISCV64_STRUCT +#include "RegisterInfos_riscv64.h" +#undef DECLARE_REGISTER_INFOS_RISCV64_STRUCT + +const lldb_private::RegisterInfo *RegisterInfoPOSIX_riscv64::GetRegisterInfoPtr( + const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::riscv64: + return g_register_infos_riscv64_le; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterInfoPOSIX_riscv64::GetRegisterInfoCount( + const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::riscv64: + return static_cast<uint32_t>(sizeof(g_register_infos_riscv64_le) / + sizeof(g_register_infos_riscv64_le[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +// Number of register sets provided by this context. +enum { + k_num_gpr_registers = gpr_last_riscv - gpr_first_riscv + 1, + k_num_fpr_registers = fpr_last_riscv - fpr_first_riscv + 1, + k_num_register_sets = 2 +}; + +// RISC-V64 general purpose registers. +static const uint32_t g_gpr_regnums_riscv64[] = { + gpr_pc_riscv, gpr_ra_riscv, gpr_sp_riscv, gpr_x3_riscv, + gpr_x4_riscv, gpr_x5_riscv, gpr_x6_riscv, gpr_x7_riscv, + gpr_fp_riscv, gpr_x9_riscv, gpr_x10_riscv, gpr_x11_riscv, + gpr_x12_riscv, gpr_x13_riscv, gpr_x14_riscv, gpr_x15_riscv, + gpr_x16_riscv, gpr_x17_riscv, gpr_x18_riscv, gpr_x19_riscv, + gpr_x20_riscv, gpr_x21_riscv, gpr_x22_riscv, gpr_x23_riscv, + gpr_x24_riscv, gpr_x25_riscv, gpr_x26_riscv, gpr_x27_riscv, + gpr_x28_riscv, gpr_x29_riscv, gpr_x30_riscv, gpr_x31_riscv, + gpr_x0_riscv, LLDB_INVALID_REGNUM}; + +static_assert(((sizeof g_gpr_regnums_riscv64 / + sizeof g_gpr_regnums_riscv64[0]) - + 1) == k_num_gpr_registers, + "g_gpr_regnums_riscv64 has wrong number of register infos"); + +// RISC-V64 floating point registers. +static const uint32_t g_fpr_regnums_riscv64[] = { + fpr_f0_riscv, fpr_f1_riscv, fpr_f2_riscv, fpr_f3_riscv, + fpr_f4_riscv, fpr_f5_riscv, fpr_f6_riscv, fpr_f7_riscv, + fpr_f8_riscv, fpr_f9_riscv, fpr_f10_riscv, fpr_f11_riscv, + fpr_f12_riscv, fpr_f13_riscv, fpr_f14_riscv, fpr_f15_riscv, + fpr_f16_riscv, fpr_f17_riscv, fpr_f18_riscv, fpr_f19_riscv, + fpr_f20_riscv, fpr_f21_riscv, fpr_f22_riscv, fpr_f23_riscv, + fpr_f24_riscv, fpr_f25_riscv, fpr_f26_riscv, fpr_f27_riscv, + fpr_f28_riscv, fpr_f29_riscv, fpr_f30_riscv, fpr_f31_riscv, + fpr_fcsr_riscv, LLDB_INVALID_REGNUM}; + +static_assert(((sizeof g_fpr_regnums_riscv64 / + sizeof g_fpr_regnums_riscv64[0]) - + 1) == k_num_fpr_registers, + "g_fpr_regnums_riscv64 has wrong number of register infos"); + +// Register sets for RISC-V64. +static const lldb_private::RegisterSet g_reg_sets_riscv64[k_num_register_sets] = + {{"General Purpose Registers", "gpr", k_num_gpr_registers, + g_gpr_regnums_riscv64}, + {"Floating Point Registers", "fpr", k_num_fpr_registers, + g_fpr_regnums_riscv64}}; + +RegisterInfoPOSIX_riscv64::RegisterInfoPOSIX_riscv64( + const lldb_private::ArchSpec &target_arch, lldb_private::Flags flags) + : lldb_private::RegisterInfoAndSetInterface(target_arch), + m_register_info_p(GetRegisterInfoPtr(target_arch)), + m_register_info_count(GetRegisterInfoCount(target_arch)) {} + +uint32_t RegisterInfoPOSIX_riscv64::GetRegisterCount() const { + return m_register_info_count; +} + +size_t RegisterInfoPOSIX_riscv64::GetGPRSize() const { + return sizeof(struct RegisterInfoPOSIX_riscv64::GPR); +} + +size_t RegisterInfoPOSIX_riscv64::GetFPRSize() const { + return sizeof(struct RegisterInfoPOSIX_riscv64::FPR); +} + +const lldb_private::RegisterInfo * +RegisterInfoPOSIX_riscv64::GetRegisterInfo() const { + return m_register_info_p; +} + +size_t RegisterInfoPOSIX_riscv64::GetRegisterSetCount() const { + return k_num_register_sets; +} + +size_t RegisterInfoPOSIX_riscv64::GetRegisterSetFromRegisterIndex( + uint32_t reg_index) const { + // coverity[unsigned_compare] + if (reg_index >= gpr_first_riscv && reg_index <= gpr_last_riscv) + return GPRegSet; + if (reg_index >= fpr_first_riscv && reg_index <= fpr_last_riscv) + return FPRegSet; + return LLDB_INVALID_REGNUM; +} + +const lldb_private::RegisterSet * +RegisterInfoPOSIX_riscv64::GetRegisterSet(size_t set_index) const { + if (set_index < GetRegisterSetCount()) + return &g_reg_sets_riscv64[set_index]; + return nullptr; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h new file mode 100644 index 000000000000..4bf4bede0132 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h @@ -0,0 +1,66 @@ +//===-- RegisterInfoPOSIX_riscv64.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_REGISTERINFOPOSIX_RISCV64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_RISCV64_H + +#include "RegisterInfoAndSetInterface.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/lldb-private.h" +#include <map> + +class RegisterInfoPOSIX_riscv64 + : public lldb_private::RegisterInfoAndSetInterface { +public: + static const lldb_private::RegisterInfo * + GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch); + static uint32_t + GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch); + +public: + enum { GPRegSet = 0, FPRegSet }; + + struct GPR { + // note: gpr[0] is pc, not x0 + uint64_t gpr[32]; + }; + + struct FPR { + uint64_t fpr[32]; + uint32_t fcsr; + }; + + struct VPR { + // The size should be VLEN*32 in bits, but we don't have VLEN here. + void *vpr; + }; + + RegisterInfoPOSIX_riscv64(const lldb_private::ArchSpec &target_arch, + lldb_private::Flags flags); + + 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; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h new file mode 100644 index 000000000000..ae6a442d7a1d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h @@ -0,0 +1,800 @@ +//===-- RegisterInfos_arm.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_ARM_STRUCT + +#include <cstddef> + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private.h" + +#include "Utility/ARM_DWARF_Registers.h" +#include "Utility/ARM_ehframe_Registers.h" + +using namespace lldb; +using namespace lldb_private; + +#ifndef GPR_OFFSET +#error GPR_OFFSET must be defined before including this header file +#endif + +#ifndef FPU_OFFSET +#error FPU_OFFSET must be defined before including this header file +#endif + +#ifndef FPSCR_OFFSET +#error FPSCR_OFFSET must be defined before including this header file +#endif + +#ifndef EXC_OFFSET +#error EXC_OFFSET_NAME must be defined before including this header file +#endif + +#ifndef DEFINE_DBG +#error DEFINE_DBG must be defined before including this header file +#endif + +enum { + gpr_r0 = 0, + 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_r13, + gpr_sp = gpr_r13, + gpr_r14, + gpr_lr = gpr_r14, + gpr_r15, + gpr_pc = gpr_r15, + gpr_cpsr, + + 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, + + exc_exception, + exc_fsr, + exc_far, + + dbg_bvr0, + dbg_bvr1, + dbg_bvr2, + dbg_bvr3, + dbg_bvr4, + dbg_bvr5, + dbg_bvr6, + dbg_bvr7, + dbg_bvr8, + dbg_bvr9, + dbg_bvr10, + dbg_bvr11, + dbg_bvr12, + dbg_bvr13, + dbg_bvr14, + dbg_bvr15, + + dbg_bcr0, + dbg_bcr1, + dbg_bcr2, + dbg_bcr3, + dbg_bcr4, + dbg_bcr5, + dbg_bcr6, + dbg_bcr7, + dbg_bcr8, + dbg_bcr9, + dbg_bcr10, + dbg_bcr11, + dbg_bcr12, + dbg_bcr13, + dbg_bcr14, + dbg_bcr15, + + dbg_wvr0, + dbg_wvr1, + dbg_wvr2, + dbg_wvr3, + dbg_wvr4, + dbg_wvr5, + dbg_wvr6, + dbg_wvr7, + dbg_wvr8, + dbg_wvr9, + dbg_wvr10, + dbg_wvr11, + dbg_wvr12, + dbg_wvr13, + dbg_wvr14, + dbg_wvr15, + + dbg_wcr0, + dbg_wcr1, + dbg_wcr2, + dbg_wcr3, + dbg_wcr4, + dbg_wcr5, + dbg_wcr6, + dbg_wcr7, + dbg_wcr8, + dbg_wcr9, + dbg_wcr10, + dbg_wcr11, + dbg_wcr12, + dbg_wcr13, + dbg_wcr14, + dbg_wcr15, + + k_num_registers +}; + +static uint32_t g_s0_invalidates[] = {fpu_d0, fpu_q0, LLDB_INVALID_REGNUM}; +static uint32_t g_s1_invalidates[] = {fpu_d0, fpu_q0, LLDB_INVALID_REGNUM}; +static uint32_t g_s2_invalidates[] = {fpu_d1, fpu_q0, LLDB_INVALID_REGNUM}; +static uint32_t g_s3_invalidates[] = {fpu_d1, fpu_q0, LLDB_INVALID_REGNUM}; +static uint32_t g_s4_invalidates[] = {fpu_d2, fpu_q1, LLDB_INVALID_REGNUM}; +static uint32_t g_s5_invalidates[] = {fpu_d2, fpu_q1, LLDB_INVALID_REGNUM}; +static uint32_t g_s6_invalidates[] = {fpu_d3, fpu_q1, LLDB_INVALID_REGNUM}; +static uint32_t g_s7_invalidates[] = {fpu_d3, fpu_q1, LLDB_INVALID_REGNUM}; +static uint32_t g_s8_invalidates[] = {fpu_d4, fpu_q2, LLDB_INVALID_REGNUM}; +static uint32_t g_s9_invalidates[] = {fpu_d4, fpu_q2, LLDB_INVALID_REGNUM}; +static uint32_t g_s10_invalidates[] = {fpu_d5, fpu_q2, LLDB_INVALID_REGNUM}; +static uint32_t g_s11_invalidates[] = {fpu_d5, fpu_q2, LLDB_INVALID_REGNUM}; +static uint32_t g_s12_invalidates[] = {fpu_d6, fpu_q3, LLDB_INVALID_REGNUM}; +static uint32_t g_s13_invalidates[] = {fpu_d6, fpu_q3, LLDB_INVALID_REGNUM}; +static uint32_t g_s14_invalidates[] = {fpu_d7, fpu_q3, LLDB_INVALID_REGNUM}; +static uint32_t g_s15_invalidates[] = {fpu_d7, fpu_q3, LLDB_INVALID_REGNUM}; +static uint32_t g_s16_invalidates[] = {fpu_d8, fpu_q4, LLDB_INVALID_REGNUM}; +static uint32_t g_s17_invalidates[] = {fpu_d8, fpu_q4, LLDB_INVALID_REGNUM}; +static uint32_t g_s18_invalidates[] = {fpu_d9, fpu_q4, LLDB_INVALID_REGNUM}; +static uint32_t g_s19_invalidates[] = {fpu_d9, fpu_q4, LLDB_INVALID_REGNUM}; +static uint32_t g_s20_invalidates[] = {fpu_d10, fpu_q5, LLDB_INVALID_REGNUM}; +static uint32_t g_s21_invalidates[] = {fpu_d10, fpu_q5, LLDB_INVALID_REGNUM}; +static uint32_t g_s22_invalidates[] = {fpu_d11, fpu_q5, LLDB_INVALID_REGNUM}; +static uint32_t g_s23_invalidates[] = {fpu_d11, fpu_q5, LLDB_INVALID_REGNUM}; +static uint32_t g_s24_invalidates[] = {fpu_d12, fpu_q6, LLDB_INVALID_REGNUM}; +static uint32_t g_s25_invalidates[] = {fpu_d12, fpu_q6, LLDB_INVALID_REGNUM}; +static uint32_t g_s26_invalidates[] = {fpu_d13, fpu_q6, LLDB_INVALID_REGNUM}; +static uint32_t g_s27_invalidates[] = {fpu_d13, fpu_q6, LLDB_INVALID_REGNUM}; +static uint32_t g_s28_invalidates[] = {fpu_d14, fpu_q7, LLDB_INVALID_REGNUM}; +static uint32_t g_s29_invalidates[] = {fpu_d14, fpu_q7, LLDB_INVALID_REGNUM}; +static uint32_t g_s30_invalidates[] = {fpu_d15, fpu_q7, LLDB_INVALID_REGNUM}; +static uint32_t g_s31_invalidates[] = {fpu_d15, fpu_q7, LLDB_INVALID_REGNUM}; + +static uint32_t g_d0_invalidates[] = {fpu_q0, fpu_s0, fpu_s1, + LLDB_INVALID_REGNUM}; +static uint32_t g_d1_invalidates[] = {fpu_q0, fpu_s2, fpu_s3, + LLDB_INVALID_REGNUM}; +static uint32_t g_d2_invalidates[] = {fpu_q1, fpu_s4, fpu_s5, + LLDB_INVALID_REGNUM}; +static uint32_t g_d3_invalidates[] = {fpu_q1, fpu_s6, fpu_s7, + LLDB_INVALID_REGNUM}; +static uint32_t g_d4_invalidates[] = {fpu_q2, fpu_s8, fpu_s9, + LLDB_INVALID_REGNUM}; +static uint32_t g_d5_invalidates[] = {fpu_q2, fpu_s10, fpu_s11, + LLDB_INVALID_REGNUM}; +static uint32_t g_d6_invalidates[] = {fpu_q3, fpu_s12, fpu_s13, + LLDB_INVALID_REGNUM}; +static uint32_t g_d7_invalidates[] = {fpu_q3, fpu_s14, fpu_s15, + LLDB_INVALID_REGNUM}; +static uint32_t g_d8_invalidates[] = {fpu_q4, fpu_s16, fpu_s17, + LLDB_INVALID_REGNUM}; +static uint32_t g_d9_invalidates[] = {fpu_q4, fpu_s18, fpu_s19, + LLDB_INVALID_REGNUM}; +static uint32_t g_d10_invalidates[] = {fpu_q5, fpu_s20, fpu_s21, + LLDB_INVALID_REGNUM}; +static uint32_t g_d11_invalidates[] = {fpu_q5, fpu_s22, fpu_s23, + LLDB_INVALID_REGNUM}; +static uint32_t g_d12_invalidates[] = {fpu_q6, fpu_s24, fpu_s25, + LLDB_INVALID_REGNUM}; +static uint32_t g_d13_invalidates[] = {fpu_q6, fpu_s26, fpu_s27, + LLDB_INVALID_REGNUM}; +static uint32_t g_d14_invalidates[] = {fpu_q7, fpu_s28, fpu_s29, + LLDB_INVALID_REGNUM}; +static uint32_t g_d15_invalidates[] = {fpu_q7, fpu_s30, fpu_s31, + LLDB_INVALID_REGNUM}; +static uint32_t g_d16_invalidates[] = {fpu_q8, LLDB_INVALID_REGNUM}; +static uint32_t g_d17_invalidates[] = {fpu_q8, LLDB_INVALID_REGNUM}; +static uint32_t g_d18_invalidates[] = {fpu_q9, LLDB_INVALID_REGNUM}; +static uint32_t g_d19_invalidates[] = {fpu_q9, LLDB_INVALID_REGNUM}; +static uint32_t g_d20_invalidates[] = {fpu_q10, LLDB_INVALID_REGNUM}; +static uint32_t g_d21_invalidates[] = {fpu_q10, LLDB_INVALID_REGNUM}; +static uint32_t g_d22_invalidates[] = {fpu_q11, LLDB_INVALID_REGNUM}; +static uint32_t g_d23_invalidates[] = {fpu_q11, LLDB_INVALID_REGNUM}; +static uint32_t g_d24_invalidates[] = {fpu_q12, LLDB_INVALID_REGNUM}; +static uint32_t g_d25_invalidates[] = {fpu_q12, LLDB_INVALID_REGNUM}; +static uint32_t g_d26_invalidates[] = {fpu_q13, LLDB_INVALID_REGNUM}; +static uint32_t g_d27_invalidates[] = {fpu_q13, LLDB_INVALID_REGNUM}; +static uint32_t g_d28_invalidates[] = {fpu_q14, LLDB_INVALID_REGNUM}; +static uint32_t g_d29_invalidates[] = {fpu_q14, LLDB_INVALID_REGNUM}; +static uint32_t g_d30_invalidates[] = {fpu_q15, LLDB_INVALID_REGNUM}; +static uint32_t g_d31_invalidates[] = {fpu_q15, LLDB_INVALID_REGNUM}; + +static uint32_t g_q0_invalidates[] = { + fpu_d0, fpu_d1, fpu_s0, fpu_s1, fpu_s2, fpu_s3, LLDB_INVALID_REGNUM}; +static uint32_t g_q1_invalidates[] = { + fpu_d2, fpu_d3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, LLDB_INVALID_REGNUM}; +static uint32_t g_q2_invalidates[] = { + fpu_d4, fpu_d5, fpu_s8, fpu_s9, fpu_s10, fpu_s11, LLDB_INVALID_REGNUM}; +static uint32_t g_q3_invalidates[] = { + fpu_d6, fpu_d7, fpu_s12, fpu_s13, fpu_s14, fpu_s15, LLDB_INVALID_REGNUM}; +static uint32_t g_q4_invalidates[] = { + fpu_d8, fpu_d9, fpu_s16, fpu_s17, fpu_s18, fpu_s19, LLDB_INVALID_REGNUM}; +static uint32_t g_q5_invalidates[] = { + fpu_d10, fpu_d11, fpu_s20, fpu_s21, fpu_s22, fpu_s23, LLDB_INVALID_REGNUM}; +static uint32_t g_q6_invalidates[] = { + fpu_d12, fpu_d13, fpu_s24, fpu_s25, fpu_s26, fpu_s27, LLDB_INVALID_REGNUM}; +static uint32_t g_q7_invalidates[] = { + fpu_d14, fpu_d15, fpu_s28, fpu_s29, fpu_s30, fpu_s31, LLDB_INVALID_REGNUM}; +static uint32_t g_q8_invalidates[] = {fpu_d16, fpu_d17, LLDB_INVALID_REGNUM}; +static uint32_t g_q9_invalidates[] = {fpu_d18, fpu_d19, LLDB_INVALID_REGNUM}; +static uint32_t g_q10_invalidates[] = {fpu_d20, fpu_d21, LLDB_INVALID_REGNUM}; +static uint32_t g_q11_invalidates[] = {fpu_d22, fpu_d23, LLDB_INVALID_REGNUM}; +static uint32_t g_q12_invalidates[] = {fpu_d24, fpu_d25, LLDB_INVALID_REGNUM}; +static uint32_t g_q13_invalidates[] = {fpu_d26, fpu_d27, LLDB_INVALID_REGNUM}; +static uint32_t g_q14_invalidates[] = {fpu_d28, fpu_d29, LLDB_INVALID_REGNUM}; +static uint32_t g_q15_invalidates[] = {fpu_d30, fpu_d31, LLDB_INVALID_REGNUM}; + +static uint32_t g_q0_contained[] = {fpu_q0, LLDB_INVALID_REGNUM}; +static uint32_t g_q1_contained[] = {fpu_q1, LLDB_INVALID_REGNUM}; +static uint32_t g_q2_contained[] = {fpu_q2, LLDB_INVALID_REGNUM}; +static uint32_t g_q3_contained[] = {fpu_q3, LLDB_INVALID_REGNUM}; +static uint32_t g_q4_contained[] = {fpu_q4, LLDB_INVALID_REGNUM}; +static uint32_t g_q5_contained[] = {fpu_q5, LLDB_INVALID_REGNUM}; +static uint32_t g_q6_contained[] = {fpu_q6, LLDB_INVALID_REGNUM}; +static uint32_t g_q7_contained[] = {fpu_q7, LLDB_INVALID_REGNUM}; +static uint32_t g_q8_contained[] = {fpu_q8, LLDB_INVALID_REGNUM}; +static uint32_t g_q9_contained[] = {fpu_q9, LLDB_INVALID_REGNUM}; +static uint32_t g_q10_contained[] = {fpu_q10, LLDB_INVALID_REGNUM}; +static uint32_t g_q11_contained[] = {fpu_q11, LLDB_INVALID_REGNUM}; +static uint32_t g_q12_contained[] = {fpu_q12, LLDB_INVALID_REGNUM}; +static uint32_t g_q13_contained[] = {fpu_q13, LLDB_INVALID_REGNUM}; +static uint32_t g_q14_contained[] = {fpu_q14, LLDB_INVALID_REGNUM}; +static uint32_t g_q15_contained[] = {fpu_q15, LLDB_INVALID_REGNUM}; + +#define FPU_REG(name, size, offset, qreg) \ + { \ + #name, nullptr, size, FPU_OFFSET(offset), eEncodingIEEE754, eFormatFloat, \ + {LLDB_INVALID_REGNUM, dwarf_##name, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpu_##name }, \ + g_##qreg##_contained, g_##name##_invalidates, nullptr, \ + } + +#define FPU_QREG(name, offset) \ + { \ + #name, nullptr, 16, FPU_OFFSET(offset), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, dwarf_##name, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpu_##name }, \ + nullptr, g_##name##_invalidates, nullptr, \ + } + +static RegisterInfo g_register_infos_arm[] = { + // NAME ALT SZ OFFSET ENCODING FORMAT + // EH_FRAME DWARF GENERIC + // PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS + // =========== ======= == ============== ================ + // ==================== =================== =================== + // ========================== =================== ============= + // ============== ================= + { + "r0", + nullptr, + 4, + GPR_OFFSET(0), + eEncodingUint, + eFormatHex, + {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, + gpr_r0}, + nullptr, + nullptr, + nullptr, + }, + { + "r1", + nullptr, + 4, + GPR_OFFSET(1), + eEncodingUint, + eFormatHex, + {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, + gpr_r1}, + nullptr, + nullptr, + nullptr, + }, + { + "r2", + nullptr, + 4, + GPR_OFFSET(2), + eEncodingUint, + eFormatHex, + {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, + gpr_r2}, + nullptr, + nullptr, + nullptr, + }, + { + "r3", + nullptr, + 4, + GPR_OFFSET(3), + eEncodingUint, + eFormatHex, + {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, + gpr_r3}, + nullptr, + nullptr, + nullptr, + }, + { + "r4", + nullptr, + 4, + GPR_OFFSET(4), + eEncodingUint, + eFormatHex, + {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r4}, + nullptr, + nullptr, + nullptr, + }, + { + "r5", + nullptr, + 4, + GPR_OFFSET(5), + eEncodingUint, + eFormatHex, + {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r5}, + nullptr, + nullptr, + nullptr, + }, + { + "r6", + nullptr, + 4, + GPR_OFFSET(6), + eEncodingUint, + eFormatHex, + {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r6}, + nullptr, + nullptr, + nullptr, + }, + { + "r7", + nullptr, + 4, + GPR_OFFSET(7), + eEncodingUint, + eFormatHex, + {ehframe_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r7}, + nullptr, + nullptr, + nullptr, + }, + { + "r8", + nullptr, + 4, + GPR_OFFSET(8), + eEncodingUint, + eFormatHex, + {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r8}, + nullptr, + nullptr, + nullptr, + }, + { + "r9", + nullptr, + 4, + GPR_OFFSET(9), + eEncodingUint, + eFormatHex, + {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r9}, + nullptr, + nullptr, + nullptr, + }, + { + "r10", + nullptr, + 4, + GPR_OFFSET(10), + eEncodingUint, + eFormatHex, + {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r10}, + nullptr, + nullptr, + nullptr, + }, + { + "r11", + nullptr, + 4, + GPR_OFFSET(11), + eEncodingUint, + eFormatHex, + {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + gpr_r11}, + nullptr, + nullptr, + nullptr, + }, + { + "r12", + nullptr, + 4, + GPR_OFFSET(12), + eEncodingUint, + eFormatHex, + {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r12}, + nullptr, + nullptr, + nullptr, + }, + { + "sp", + "r13", + 4, + GPR_OFFSET(13), + eEncodingUint, + eFormatHex, + {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + gpr_sp}, + nullptr, + nullptr, + nullptr, + }, + { + "lr", + "r14", + 4, + GPR_OFFSET(14), + eEncodingUint, + eFormatHex, + {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, + gpr_lr}, + nullptr, + nullptr, + nullptr, + }, + { + "pc", + "r15", + 4, + GPR_OFFSET(15), + eEncodingUint, + eFormatHex, + {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + gpr_pc}, + nullptr, + nullptr, + nullptr, + }, + { + "cpsr", + "psr", + 4, + GPR_OFFSET(16), + eEncodingUint, + eFormatHex, + {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, + LLDB_INVALID_REGNUM, gpr_cpsr}, + nullptr, + nullptr, + nullptr, + }, + + FPU_REG(s0, 4, 0, q0), + FPU_REG(s1, 4, 1, q0), + FPU_REG(s2, 4, 2, q0), + FPU_REG(s3, 4, 3, q0), + FPU_REG(s4, 4, 4, q1), + FPU_REG(s5, 4, 5, q1), + FPU_REG(s6, 4, 6, q1), + FPU_REG(s7, 4, 7, q1), + FPU_REG(s8, 4, 8, q2), + FPU_REG(s9, 4, 9, q2), + FPU_REG(s10, 4, 10, q2), + FPU_REG(s11, 4, 11, q2), + FPU_REG(s12, 4, 12, q3), + FPU_REG(s13, 4, 13, q3), + FPU_REG(s14, 4, 14, q3), + FPU_REG(s15, 4, 15, q3), + FPU_REG(s16, 4, 16, q4), + FPU_REG(s17, 4, 17, q4), + FPU_REG(s18, 4, 18, q4), + FPU_REG(s19, 4, 19, q4), + FPU_REG(s20, 4, 20, q5), + FPU_REG(s21, 4, 21, q5), + FPU_REG(s22, 4, 22, q5), + FPU_REG(s23, 4, 23, q5), + FPU_REG(s24, 4, 24, q6), + FPU_REG(s25, 4, 25, q6), + FPU_REG(s26, 4, 26, q6), + FPU_REG(s27, 4, 27, q6), + FPU_REG(s28, 4, 28, q7), + FPU_REG(s29, 4, 29, q7), + FPU_REG(s30, 4, 30, q7), + FPU_REG(s31, 4, 31, q7), + + { + "fpscr", + nullptr, + 4, + FPSCR_OFFSET, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fpscr}, + nullptr, + nullptr, + nullptr, + }, + + FPU_REG(d0, 8, 0, q0), + FPU_REG(d1, 8, 2, q0), + FPU_REG(d2, 8, 4, q1), + FPU_REG(d3, 8, 6, q1), + FPU_REG(d4, 8, 8, q2), + FPU_REG(d5, 8, 10, q2), + FPU_REG(d6, 8, 12, q3), + FPU_REG(d7, 8, 14, q3), + FPU_REG(d8, 8, 16, q4), + FPU_REG(d9, 8, 18, q4), + FPU_REG(d10, 8, 20, q5), + FPU_REG(d11, 8, 22, q5), + FPU_REG(d12, 8, 24, q6), + FPU_REG(d13, 8, 26, q6), + FPU_REG(d14, 8, 28, q7), + FPU_REG(d15, 8, 30, q7), + FPU_REG(d16, 8, 32, q8), + FPU_REG(d17, 8, 34, q8), + FPU_REG(d18, 8, 36, q9), + FPU_REG(d19, 8, 38, q9), + FPU_REG(d20, 8, 40, q10), + FPU_REG(d21, 8, 42, q10), + FPU_REG(d22, 8, 44, q11), + FPU_REG(d23, 8, 46, q11), + FPU_REG(d24, 8, 48, q12), + FPU_REG(d25, 8, 50, q12), + FPU_REG(d26, 8, 52, q13), + FPU_REG(d27, 8, 54, q13), + FPU_REG(d28, 8, 56, q14), + FPU_REG(d29, 8, 58, q14), + FPU_REG(d30, 8, 60, q15), + FPU_REG(d31, 8, 62, q15), + + FPU_QREG(q0, 0), + FPU_QREG(q1, 4), + FPU_QREG(q2, 8), + FPU_QREG(q3, 12), + FPU_QREG(q4, 16), + FPU_QREG(q5, 20), + FPU_QREG(q6, 24), + FPU_QREG(q7, 28), + FPU_QREG(q8, 32), + FPU_QREG(q9, 36), + FPU_QREG(q10, 40), + FPU_QREG(q11, 44), + FPU_QREG(q12, 48), + FPU_QREG(q13, 52), + FPU_QREG(q14, 56), + FPU_QREG(q15, 60), + + { + "exception", + nullptr, + 4, + EXC_OFFSET(0), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_exception}, + nullptr, + nullptr, + nullptr, + }, + { + "fsr", + nullptr, + 4, + EXC_OFFSET(1), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_fsr}, + nullptr, + nullptr, + nullptr, + }, + { + "far", + nullptr, + 4, + EXC_OFFSET(2), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_far}, + nullptr, + nullptr, + nullptr, + }, + + {DEFINE_DBG(bvr, 0)}, + {DEFINE_DBG(bvr, 1)}, + {DEFINE_DBG(bvr, 2)}, + {DEFINE_DBG(bvr, 3)}, + {DEFINE_DBG(bvr, 4)}, + {DEFINE_DBG(bvr, 5)}, + {DEFINE_DBG(bvr, 6)}, + {DEFINE_DBG(bvr, 7)}, + {DEFINE_DBG(bvr, 8)}, + {DEFINE_DBG(bvr, 9)}, + {DEFINE_DBG(bvr, 10)}, + {DEFINE_DBG(bvr, 11)}, + {DEFINE_DBG(bvr, 12)}, + {DEFINE_DBG(bvr, 13)}, + {DEFINE_DBG(bvr, 14)}, + {DEFINE_DBG(bvr, 15)}, + + {DEFINE_DBG(bcr, 0)}, + {DEFINE_DBG(bcr, 1)}, + {DEFINE_DBG(bcr, 2)}, + {DEFINE_DBG(bcr, 3)}, + {DEFINE_DBG(bcr, 4)}, + {DEFINE_DBG(bcr, 5)}, + {DEFINE_DBG(bcr, 6)}, + {DEFINE_DBG(bcr, 7)}, + {DEFINE_DBG(bcr, 8)}, + {DEFINE_DBG(bcr, 9)}, + {DEFINE_DBG(bcr, 10)}, + {DEFINE_DBG(bcr, 11)}, + {DEFINE_DBG(bcr, 12)}, + {DEFINE_DBG(bcr, 13)}, + {DEFINE_DBG(bcr, 14)}, + {DEFINE_DBG(bcr, 15)}, + + {DEFINE_DBG(wvr, 0)}, + {DEFINE_DBG(wvr, 1)}, + {DEFINE_DBG(wvr, 2)}, + {DEFINE_DBG(wvr, 3)}, + {DEFINE_DBG(wvr, 4)}, + {DEFINE_DBG(wvr, 5)}, + {DEFINE_DBG(wvr, 6)}, + {DEFINE_DBG(wvr, 7)}, + {DEFINE_DBG(wvr, 8)}, + {DEFINE_DBG(wvr, 9)}, + {DEFINE_DBG(wvr, 10)}, + {DEFINE_DBG(wvr, 11)}, + {DEFINE_DBG(wvr, 12)}, + {DEFINE_DBG(wvr, 13)}, + {DEFINE_DBG(wvr, 14)}, + {DEFINE_DBG(wvr, 15)}, + + {DEFINE_DBG(wcr, 0)}, + {DEFINE_DBG(wcr, 1)}, + {DEFINE_DBG(wcr, 2)}, + {DEFINE_DBG(wcr, 3)}, + {DEFINE_DBG(wcr, 4)}, + {DEFINE_DBG(wcr, 5)}, + {DEFINE_DBG(wcr, 6)}, + {DEFINE_DBG(wcr, 7)}, + {DEFINE_DBG(wcr, 8)}, + {DEFINE_DBG(wcr, 9)}, + {DEFINE_DBG(wcr, 10)}, + {DEFINE_DBG(wcr, 11)}, + {DEFINE_DBG(wcr, 12)}, + {DEFINE_DBG(wcr, 13)}, + {DEFINE_DBG(wcr, 14)}, + {DEFINE_DBG(wcr, 15)}}; + +#endif // DECLARE_REGISTER_INFOS_ARM_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h new file mode 100644 index 000000000000..c9c4d7ceae55 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -0,0 +1,793 @@ +//===-- RegisterInfos_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 +// +//===----------------------------------------------------------------------===// + +#ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT + +#include <cstddef> + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private.h" + +#include "Utility/ARM64_DWARF_Registers.h" +#include "Utility/ARM64_ehframe_Registers.h" + +#ifndef GPR_OFFSET +#error GPR_OFFSET must be defined before including this header file +#endif + +#ifndef GPR_OFFSET_NAME +#error GPR_OFFSET_NAME must be defined before including this header file +#endif + +#ifndef FPU_OFFSET +#error FPU_OFFSET must be defined before including this header file +#endif + +#ifndef FPU_OFFSET_NAME +#error FPU_OFFSET_NAME must be defined before including this header file +#endif + +#ifndef EXC_OFFSET_NAME +#error EXC_OFFSET_NAME must be defined before including this header file +#endif + +#ifndef DBG_OFFSET_NAME +#error DBG_OFFSET_NAME must be defined before including this header file +#endif + +#ifndef DEFINE_DBG +#error DEFINE_DBG must be defined before including this header file +#endif + +// Offsets for a little-endian layout of the register context +#define GPR_W_PSEUDO_REG_ENDIAN_OFFSET 0 +#define FPU_S_PSEUDO_REG_ENDIAN_OFFSET 0 +#define FPU_D_PSEUDO_REG_ENDIAN_OFFSET 0 + +enum { + gpr_x0 = 0, + gpr_x1, + gpr_x2, + gpr_x3, + gpr_x4, + gpr_x5, + gpr_x6, + gpr_x7, + gpr_x8, + gpr_x9, + gpr_x10, + gpr_x11, + gpr_x12, + gpr_x13, + gpr_x14, + gpr_x15, + gpr_x16, + gpr_x17, + gpr_x18, + gpr_x19, + gpr_x20, + gpr_x21, + gpr_x22, + gpr_x23, + gpr_x24, + gpr_x25, + gpr_x26, + gpr_x27, + gpr_x28, + gpr_x29 = 29, + gpr_fp = gpr_x29, + gpr_x30 = 30, + gpr_lr = gpr_x30, + gpr_ra = gpr_x30, + gpr_x31 = 31, + gpr_sp = gpr_x31, + gpr_pc = 32, + gpr_cpsr, + + gpr_w0, + gpr_w1, + gpr_w2, + gpr_w3, + gpr_w4, + gpr_w5, + gpr_w6, + gpr_w7, + gpr_w8, + gpr_w9, + gpr_w10, + gpr_w11, + gpr_w12, + gpr_w13, + gpr_w14, + gpr_w15, + gpr_w16, + gpr_w17, + gpr_w18, + gpr_w19, + gpr_w20, + gpr_w21, + gpr_w22, + gpr_w23, + gpr_w24, + gpr_w25, + gpr_w26, + gpr_w27, + gpr_w28, + + fpu_v0, + fpu_v1, + fpu_v2, + fpu_v3, + fpu_v4, + fpu_v5, + fpu_v6, + fpu_v7, + fpu_v8, + fpu_v9, + fpu_v10, + fpu_v11, + fpu_v12, + fpu_v13, + fpu_v14, + fpu_v15, + fpu_v16, + fpu_v17, + fpu_v18, + fpu_v19, + fpu_v20, + fpu_v21, + fpu_v22, + fpu_v23, + fpu_v24, + fpu_v25, + fpu_v26, + fpu_v27, + fpu_v28, + fpu_v29, + fpu_v30, + fpu_v31, + + 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_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_fpsr, + fpu_fpcr, + + exc_far, + exc_esr, + exc_exception, + + dbg_bvr0, + dbg_bvr1, + dbg_bvr2, + dbg_bvr3, + dbg_bvr4, + dbg_bvr5, + dbg_bvr6, + dbg_bvr7, + dbg_bvr8, + dbg_bvr9, + dbg_bvr10, + dbg_bvr11, + dbg_bvr12, + dbg_bvr13, + dbg_bvr14, + dbg_bvr15, + + dbg_bcr0, + dbg_bcr1, + dbg_bcr2, + dbg_bcr3, + dbg_bcr4, + dbg_bcr5, + dbg_bcr6, + dbg_bcr7, + dbg_bcr8, + dbg_bcr9, + dbg_bcr10, + dbg_bcr11, + dbg_bcr12, + dbg_bcr13, + dbg_bcr14, + dbg_bcr15, + + dbg_wvr0, + dbg_wvr1, + dbg_wvr2, + dbg_wvr3, + dbg_wvr4, + dbg_wvr5, + dbg_wvr6, + dbg_wvr7, + dbg_wvr8, + dbg_wvr9, + dbg_wvr10, + dbg_wvr11, + dbg_wvr12, + dbg_wvr13, + dbg_wvr14, + dbg_wvr15, + + dbg_wcr0, + dbg_wcr1, + dbg_wcr2, + dbg_wcr3, + dbg_wcr4, + dbg_wcr5, + dbg_wcr6, + dbg_wcr7, + dbg_wcr8, + dbg_wcr9, + dbg_wcr10, + dbg_wcr11, + dbg_wcr12, + dbg_wcr13, + dbg_wcr14, + dbg_wcr15, + + k_num_registers +}; + +static uint32_t g_contained_x0[] = {gpr_x0, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x1[] = {gpr_x1, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x2[] = {gpr_x2, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x3[] = {gpr_x3, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x4[] = {gpr_x4, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x5[] = {gpr_x5, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x6[] = {gpr_x6, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x7[] = {gpr_x7, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x8[] = {gpr_x8, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x9[] = {gpr_x9, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x10[] = {gpr_x10, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x11[] = {gpr_x11, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x12[] = {gpr_x12, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x13[] = {gpr_x13, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x14[] = {gpr_x14, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x15[] = {gpr_x15, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x16[] = {gpr_x16, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x17[] = {gpr_x17, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x18[] = {gpr_x18, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x19[] = {gpr_x19, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x20[] = {gpr_x20, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x21[] = {gpr_x21, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x22[] = {gpr_x22, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x23[] = {gpr_x23, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x24[] = {gpr_x24, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x25[] = {gpr_x25, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x26[] = {gpr_x26, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x27[] = {gpr_x27, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_x28[] = {gpr_x28, LLDB_INVALID_REGNUM}; + +static uint32_t g_w0_invalidates[] = {gpr_x0, LLDB_INVALID_REGNUM}; +static uint32_t g_w1_invalidates[] = {gpr_x1, LLDB_INVALID_REGNUM}; +static uint32_t g_w2_invalidates[] = {gpr_x2, LLDB_INVALID_REGNUM}; +static uint32_t g_w3_invalidates[] = {gpr_x3, LLDB_INVALID_REGNUM}; +static uint32_t g_w4_invalidates[] = {gpr_x4, LLDB_INVALID_REGNUM}; +static uint32_t g_w5_invalidates[] = {gpr_x5, LLDB_INVALID_REGNUM}; +static uint32_t g_w6_invalidates[] = {gpr_x6, LLDB_INVALID_REGNUM}; +static uint32_t g_w7_invalidates[] = {gpr_x7, LLDB_INVALID_REGNUM}; +static uint32_t g_w8_invalidates[] = {gpr_x8, LLDB_INVALID_REGNUM}; +static uint32_t g_w9_invalidates[] = {gpr_x9, LLDB_INVALID_REGNUM}; +static uint32_t g_w10_invalidates[] = {gpr_x10, LLDB_INVALID_REGNUM}; +static uint32_t g_w11_invalidates[] = {gpr_x11, LLDB_INVALID_REGNUM}; +static uint32_t g_w12_invalidates[] = {gpr_x12, LLDB_INVALID_REGNUM}; +static uint32_t g_w13_invalidates[] = {gpr_x13, LLDB_INVALID_REGNUM}; +static uint32_t g_w14_invalidates[] = {gpr_x14, LLDB_INVALID_REGNUM}; +static uint32_t g_w15_invalidates[] = {gpr_x15, LLDB_INVALID_REGNUM}; +static uint32_t g_w16_invalidates[] = {gpr_x16, LLDB_INVALID_REGNUM}; +static uint32_t g_w17_invalidates[] = {gpr_x17, LLDB_INVALID_REGNUM}; +static uint32_t g_w18_invalidates[] = {gpr_x18, LLDB_INVALID_REGNUM}; +static uint32_t g_w19_invalidates[] = {gpr_x19, LLDB_INVALID_REGNUM}; +static uint32_t g_w20_invalidates[] = {gpr_x20, LLDB_INVALID_REGNUM}; +static uint32_t g_w21_invalidates[] = {gpr_x21, LLDB_INVALID_REGNUM}; +static uint32_t g_w22_invalidates[] = {gpr_x22, LLDB_INVALID_REGNUM}; +static uint32_t g_w23_invalidates[] = {gpr_x23, LLDB_INVALID_REGNUM}; +static uint32_t g_w24_invalidates[] = {gpr_x24, LLDB_INVALID_REGNUM}; +static uint32_t g_w25_invalidates[] = {gpr_x25, LLDB_INVALID_REGNUM}; +static uint32_t g_w26_invalidates[] = {gpr_x26, LLDB_INVALID_REGNUM}; +static uint32_t g_w27_invalidates[] = {gpr_x27, LLDB_INVALID_REGNUM}; +static uint32_t g_w28_invalidates[] = {gpr_x28, LLDB_INVALID_REGNUM}; + +static uint32_t g_contained_v0[] = {fpu_v0, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v1[] = {fpu_v1, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v2[] = {fpu_v2, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v3[] = {fpu_v3, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v4[] = {fpu_v4, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v5[] = {fpu_v5, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v6[] = {fpu_v6, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v7[] = {fpu_v7, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v8[] = {fpu_v8, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v9[] = {fpu_v9, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v10[] = {fpu_v10, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v11[] = {fpu_v11, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v12[] = {fpu_v12, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v13[] = {fpu_v13, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v14[] = {fpu_v14, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v15[] = {fpu_v15, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v16[] = {fpu_v16, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v17[] = {fpu_v17, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v18[] = {fpu_v18, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v19[] = {fpu_v19, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v20[] = {fpu_v20, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v21[] = {fpu_v21, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v22[] = {fpu_v22, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v23[] = {fpu_v23, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v24[] = {fpu_v24, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v25[] = {fpu_v25, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v26[] = {fpu_v26, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v27[] = {fpu_v27, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v28[] = {fpu_v28, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v29[] = {fpu_v29, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v30[] = {fpu_v30, LLDB_INVALID_REGNUM}; +static uint32_t g_contained_v31[] = {fpu_v31, LLDB_INVALID_REGNUM}; + +static uint32_t g_s0_invalidates[] = {fpu_v0, fpu_d0, LLDB_INVALID_REGNUM}; +static uint32_t g_s1_invalidates[] = {fpu_v1, fpu_d1, LLDB_INVALID_REGNUM}; +static uint32_t g_s2_invalidates[] = {fpu_v2, fpu_d2, LLDB_INVALID_REGNUM}; +static uint32_t g_s3_invalidates[] = {fpu_v3, fpu_d3, LLDB_INVALID_REGNUM}; +static uint32_t g_s4_invalidates[] = {fpu_v4, fpu_d4, LLDB_INVALID_REGNUM}; +static uint32_t g_s5_invalidates[] = {fpu_v5, fpu_d5, LLDB_INVALID_REGNUM}; +static uint32_t g_s6_invalidates[] = {fpu_v6, fpu_d6, LLDB_INVALID_REGNUM}; +static uint32_t g_s7_invalidates[] = {fpu_v7, fpu_d7, LLDB_INVALID_REGNUM}; +static uint32_t g_s8_invalidates[] = {fpu_v8, fpu_d8, LLDB_INVALID_REGNUM}; +static uint32_t g_s9_invalidates[] = {fpu_v9, fpu_d9, LLDB_INVALID_REGNUM}; +static uint32_t g_s10_invalidates[] = {fpu_v10, fpu_d10, LLDB_INVALID_REGNUM}; +static uint32_t g_s11_invalidates[] = {fpu_v11, fpu_d11, LLDB_INVALID_REGNUM}; +static uint32_t g_s12_invalidates[] = {fpu_v12, fpu_d12, LLDB_INVALID_REGNUM}; +static uint32_t g_s13_invalidates[] = {fpu_v13, fpu_d13, LLDB_INVALID_REGNUM}; +static uint32_t g_s14_invalidates[] = {fpu_v14, fpu_d14, LLDB_INVALID_REGNUM}; +static uint32_t g_s15_invalidates[] = {fpu_v15, fpu_d15, LLDB_INVALID_REGNUM}; +static uint32_t g_s16_invalidates[] = {fpu_v16, fpu_d16, LLDB_INVALID_REGNUM}; +static uint32_t g_s17_invalidates[] = {fpu_v17, fpu_d17, LLDB_INVALID_REGNUM}; +static uint32_t g_s18_invalidates[] = {fpu_v18, fpu_d18, LLDB_INVALID_REGNUM}; +static uint32_t g_s19_invalidates[] = {fpu_v19, fpu_d19, LLDB_INVALID_REGNUM}; +static uint32_t g_s20_invalidates[] = {fpu_v20, fpu_d20, LLDB_INVALID_REGNUM}; +static uint32_t g_s21_invalidates[] = {fpu_v21, fpu_d21, LLDB_INVALID_REGNUM}; +static uint32_t g_s22_invalidates[] = {fpu_v22, fpu_d22, LLDB_INVALID_REGNUM}; +static uint32_t g_s23_invalidates[] = {fpu_v23, fpu_d23, LLDB_INVALID_REGNUM}; +static uint32_t g_s24_invalidates[] = {fpu_v24, fpu_d24, LLDB_INVALID_REGNUM}; +static uint32_t g_s25_invalidates[] = {fpu_v25, fpu_d25, LLDB_INVALID_REGNUM}; +static uint32_t g_s26_invalidates[] = {fpu_v26, fpu_d26, LLDB_INVALID_REGNUM}; +static uint32_t g_s27_invalidates[] = {fpu_v27, fpu_d27, LLDB_INVALID_REGNUM}; +static uint32_t g_s28_invalidates[] = {fpu_v28, fpu_d28, LLDB_INVALID_REGNUM}; +static uint32_t g_s29_invalidates[] = {fpu_v29, fpu_d29, LLDB_INVALID_REGNUM}; +static uint32_t g_s30_invalidates[] = {fpu_v30, fpu_d30, LLDB_INVALID_REGNUM}; +static uint32_t g_s31_invalidates[] = {fpu_v31, fpu_d31, LLDB_INVALID_REGNUM}; + +static uint32_t g_d0_invalidates[] = {fpu_v0, fpu_s0, LLDB_INVALID_REGNUM}; +static uint32_t g_d1_invalidates[] = {fpu_v1, fpu_s1, LLDB_INVALID_REGNUM}; +static uint32_t g_d2_invalidates[] = {fpu_v2, fpu_s2, LLDB_INVALID_REGNUM}; +static uint32_t g_d3_invalidates[] = {fpu_v3, fpu_s3, LLDB_INVALID_REGNUM}; +static uint32_t g_d4_invalidates[] = {fpu_v4, fpu_s4, LLDB_INVALID_REGNUM}; +static uint32_t g_d5_invalidates[] = {fpu_v5, fpu_s5, LLDB_INVALID_REGNUM}; +static uint32_t g_d6_invalidates[] = {fpu_v6, fpu_s6, LLDB_INVALID_REGNUM}; +static uint32_t g_d7_invalidates[] = {fpu_v7, fpu_s7, LLDB_INVALID_REGNUM}; +static uint32_t g_d8_invalidates[] = {fpu_v8, fpu_s8, LLDB_INVALID_REGNUM}; +static uint32_t g_d9_invalidates[] = {fpu_v9, fpu_s9, LLDB_INVALID_REGNUM}; +static uint32_t g_d10_invalidates[] = {fpu_v10, fpu_s10, LLDB_INVALID_REGNUM}; +static uint32_t g_d11_invalidates[] = {fpu_v11, fpu_s11, LLDB_INVALID_REGNUM}; +static uint32_t g_d12_invalidates[] = {fpu_v12, fpu_s12, LLDB_INVALID_REGNUM}; +static uint32_t g_d13_invalidates[] = {fpu_v13, fpu_s13, LLDB_INVALID_REGNUM}; +static uint32_t g_d14_invalidates[] = {fpu_v14, fpu_s14, LLDB_INVALID_REGNUM}; +static uint32_t g_d15_invalidates[] = {fpu_v15, fpu_s15, LLDB_INVALID_REGNUM}; +static uint32_t g_d16_invalidates[] = {fpu_v16, fpu_s16, LLDB_INVALID_REGNUM}; +static uint32_t g_d17_invalidates[] = {fpu_v17, fpu_s17, LLDB_INVALID_REGNUM}; +static uint32_t g_d18_invalidates[] = {fpu_v18, fpu_s18, LLDB_INVALID_REGNUM}; +static uint32_t g_d19_invalidates[] = {fpu_v19, fpu_s19, LLDB_INVALID_REGNUM}; +static uint32_t g_d20_invalidates[] = {fpu_v20, fpu_s20, LLDB_INVALID_REGNUM}; +static uint32_t g_d21_invalidates[] = {fpu_v21, fpu_s21, LLDB_INVALID_REGNUM}; +static uint32_t g_d22_invalidates[] = {fpu_v22, fpu_s22, LLDB_INVALID_REGNUM}; +static uint32_t g_d23_invalidates[] = {fpu_v23, fpu_s23, LLDB_INVALID_REGNUM}; +static uint32_t g_d24_invalidates[] = {fpu_v24, fpu_s24, LLDB_INVALID_REGNUM}; +static uint32_t g_d25_invalidates[] = {fpu_v25, fpu_s25, LLDB_INVALID_REGNUM}; +static uint32_t g_d26_invalidates[] = {fpu_v26, fpu_s26, LLDB_INVALID_REGNUM}; +static uint32_t g_d27_invalidates[] = {fpu_v27, fpu_s27, LLDB_INVALID_REGNUM}; +static uint32_t g_d28_invalidates[] = {fpu_v28, fpu_s28, LLDB_INVALID_REGNUM}; +static uint32_t g_d29_invalidates[] = {fpu_v29, fpu_s29, LLDB_INVALID_REGNUM}; +static uint32_t g_d30_invalidates[] = {fpu_v30, fpu_s30, LLDB_INVALID_REGNUM}; +static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; + +// Generates register kinds array with DWARF, EH frame and generic kind +#define MISC_KIND(reg, type, generic_kind) \ + { \ + arm64_ehframe::reg, arm64_dwarf::reg, generic_kind, LLDB_INVALID_REGNUM, \ + type##_##reg \ + } + +// Generates register kinds array for registers with only lldb kind +#define LLDB_KIND(lldb_kind) \ + { \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_kind \ + } + +// Generates register kinds array for registers with only lldb kind +#define KIND_ALL_INVALID \ + { \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM \ + } + +// Generates register kinds array for vector registers +#define GPR64_KIND(reg, generic_kind) MISC_KIND(reg, gpr, generic_kind) +#define VREG_KIND(reg) MISC_KIND(reg, fpu, LLDB_INVALID_REGNUM) +#define MISC_GPR_KIND(lldb_kind) MISC_KIND(cpsr, gpr, LLDB_REGNUM_GENERIC_FLAGS) +#define MISC_FPU_KIND(lldb_kind) LLDB_KIND(lldb_kind) +#define MISC_EXC_KIND(lldb_kind) LLDB_KIND(lldb_kind) + +// clang-format off + +// Defines a 64-bit general purpose register +#define DEFINE_GPR64(reg, generic_kind) \ + { \ + #reg, nullptr, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \ + lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \ + nullptr, \ + } + +// Defines a 64-bit general purpose register +#define DEFINE_GPR64_ALT(reg, alt, generic_kind) \ + { \ + #reg, #alt, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \ + lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \ + nullptr, \ + } + +// Defines a 32-bit general purpose pseudo register +#define DEFINE_GPR32(wreg, xreg) \ + { \ + #wreg, nullptr, 4, \ + GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \ + lldb::eEncodingUint, lldb::eFormatHex, LLDB_KIND(gpr_##wreg), \ + g_contained_##xreg, g_##wreg##_invalidates, nullptr, \ + } + +// Defines a vector register with 16-byte size +#define DEFINE_VREG(reg) \ + { \ + #reg, nullptr, 16, FPU_OFFSET(fpu_##reg - fpu_v0), lldb::eEncodingVector, \ + lldb::eFormatVectorOfUInt8, VREG_KIND(reg), nullptr, nullptr, nullptr, \ + } + +// Defines S and D pseudo registers mapping over corresponding vector register +#define DEFINE_FPU_PSEUDO(reg, size, offset, vreg) \ + { \ + #reg, nullptr, size, FPU_OFFSET(fpu_##vreg - fpu_v0) + offset, \ + lldb::eEncodingIEEE754, lldb::eFormatFloat, LLDB_KIND(fpu_##reg), \ + g_contained_##vreg, g_##reg##_invalidates, nullptr, \ + } + +// Defines miscellaneous status and control registers like cpsr, fpsr etc +#define DEFINE_MISC_REGS(reg, size, TYPE, lldb_kind) \ + { \ + #reg, nullptr, size, TYPE##_OFFSET_NAME(reg), lldb::eEncodingUint, \ + lldb::eFormatHex, MISC_##TYPE##_KIND(lldb_kind), nullptr, nullptr, \ + nullptr, \ + } + +// Defines pointer authentication mask registers +#define DEFINE_EXTENSION_REG(reg) \ + { \ + #reg, nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \ + KIND_ALL_INVALID, nullptr, nullptr, nullptr, \ + } + +static lldb_private::RegisterInfo g_register_infos_arm64_le[] = { + // 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(name) + DEFINE_VREG(v0), + DEFINE_VREG(v1), + DEFINE_VREG(v2), + DEFINE_VREG(v3), + DEFINE_VREG(v4), + DEFINE_VREG(v5), + DEFINE_VREG(v6), + DEFINE_VREG(v7), + DEFINE_VREG(v8), + DEFINE_VREG(v9), + DEFINE_VREG(v10), + DEFINE_VREG(v11), + DEFINE_VREG(v12), + DEFINE_VREG(v13), + DEFINE_VREG(v14), + DEFINE_VREG(v15), + DEFINE_VREG(v16), + DEFINE_VREG(v17), + DEFINE_VREG(v18), + DEFINE_VREG(v19), + DEFINE_VREG(v20), + DEFINE_VREG(v21), + DEFINE_VREG(v22), + DEFINE_VREG(v23), + DEFINE_VREG(v24), + DEFINE_VREG(v25), + DEFINE_VREG(v26), + DEFINE_VREG(v27), + DEFINE_VREG(v28), + DEFINE_VREG(v29), + DEFINE_VREG(v30), + DEFINE_VREG(v31), + + // DEFINE_FPU_PSEUDO(name, size, ENDIAN OFFSET, parent register) + DEFINE_FPU_PSEUDO(s0, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v0), + DEFINE_FPU_PSEUDO(s1, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v1), + DEFINE_FPU_PSEUDO(s2, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v2), + DEFINE_FPU_PSEUDO(s3, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v3), + DEFINE_FPU_PSEUDO(s4, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v4), + DEFINE_FPU_PSEUDO(s5, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v5), + DEFINE_FPU_PSEUDO(s6, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v6), + DEFINE_FPU_PSEUDO(s7, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v7), + DEFINE_FPU_PSEUDO(s8, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v8), + DEFINE_FPU_PSEUDO(s9, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v9), + DEFINE_FPU_PSEUDO(s10, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v10), + DEFINE_FPU_PSEUDO(s11, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v11), + DEFINE_FPU_PSEUDO(s12, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v12), + DEFINE_FPU_PSEUDO(s13, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v13), + DEFINE_FPU_PSEUDO(s14, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v14), + DEFINE_FPU_PSEUDO(s15, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v15), + DEFINE_FPU_PSEUDO(s16, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v16), + DEFINE_FPU_PSEUDO(s17, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v17), + DEFINE_FPU_PSEUDO(s18, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v18), + DEFINE_FPU_PSEUDO(s19, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v19), + DEFINE_FPU_PSEUDO(s20, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v20), + DEFINE_FPU_PSEUDO(s21, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v21), + DEFINE_FPU_PSEUDO(s22, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v22), + DEFINE_FPU_PSEUDO(s23, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v23), + DEFINE_FPU_PSEUDO(s24, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v24), + DEFINE_FPU_PSEUDO(s25, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v25), + DEFINE_FPU_PSEUDO(s26, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v26), + DEFINE_FPU_PSEUDO(s27, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v27), + DEFINE_FPU_PSEUDO(s28, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v28), + DEFINE_FPU_PSEUDO(s29, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v29), + DEFINE_FPU_PSEUDO(s30, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v30), + DEFINE_FPU_PSEUDO(s31, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v31), + + DEFINE_FPU_PSEUDO(d0, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v0), + DEFINE_FPU_PSEUDO(d1, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v1), + DEFINE_FPU_PSEUDO(d2, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v2), + DEFINE_FPU_PSEUDO(d3, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v3), + DEFINE_FPU_PSEUDO(d4, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v4), + DEFINE_FPU_PSEUDO(d5, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v5), + DEFINE_FPU_PSEUDO(d6, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v6), + DEFINE_FPU_PSEUDO(d7, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v7), + DEFINE_FPU_PSEUDO(d8, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v8), + DEFINE_FPU_PSEUDO(d9, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v9), + DEFINE_FPU_PSEUDO(d10, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v10), + DEFINE_FPU_PSEUDO(d11, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v11), + DEFINE_FPU_PSEUDO(d12, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v12), + DEFINE_FPU_PSEUDO(d13, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v13), + DEFINE_FPU_PSEUDO(d14, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v14), + DEFINE_FPU_PSEUDO(d15, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v15), + DEFINE_FPU_PSEUDO(d16, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v16), + DEFINE_FPU_PSEUDO(d17, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v17), + DEFINE_FPU_PSEUDO(d18, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v18), + DEFINE_FPU_PSEUDO(d19, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v19), + DEFINE_FPU_PSEUDO(d20, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v20), + DEFINE_FPU_PSEUDO(d21, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v21), + DEFINE_FPU_PSEUDO(d22, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v22), + DEFINE_FPU_PSEUDO(d23, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v23), + DEFINE_FPU_PSEUDO(d24, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v24), + DEFINE_FPU_PSEUDO(d25, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v25), + DEFINE_FPU_PSEUDO(d26, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v26), + DEFINE_FPU_PSEUDO(d27, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v27), + DEFINE_FPU_PSEUDO(d28, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v28), + DEFINE_FPU_PSEUDO(d29, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v29), + DEFINE_FPU_PSEUDO(d30, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v30), + DEFINE_FPU_PSEUDO(d31, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v31), + + // 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(far, 8, EXC, exc_far), + DEFINE_MISC_REGS(esr, 4, EXC, exc_esr), + DEFINE_MISC_REGS(exception, 4, EXC, exc_exception), + + {DEFINE_DBG(bvr, 0)}, + {DEFINE_DBG(bvr, 1)}, + {DEFINE_DBG(bvr, 2)}, + {DEFINE_DBG(bvr, 3)}, + {DEFINE_DBG(bvr, 4)}, + {DEFINE_DBG(bvr, 5)}, + {DEFINE_DBG(bvr, 6)}, + {DEFINE_DBG(bvr, 7)}, + {DEFINE_DBG(bvr, 8)}, + {DEFINE_DBG(bvr, 9)}, + {DEFINE_DBG(bvr, 10)}, + {DEFINE_DBG(bvr, 11)}, + {DEFINE_DBG(bvr, 12)}, + {DEFINE_DBG(bvr, 13)}, + {DEFINE_DBG(bvr, 14)}, + {DEFINE_DBG(bvr, 15)}, + + {DEFINE_DBG(bcr, 0)}, + {DEFINE_DBG(bcr, 1)}, + {DEFINE_DBG(bcr, 2)}, + {DEFINE_DBG(bcr, 3)}, + {DEFINE_DBG(bcr, 4)}, + {DEFINE_DBG(bcr, 5)}, + {DEFINE_DBG(bcr, 6)}, + {DEFINE_DBG(bcr, 7)}, + {DEFINE_DBG(bcr, 8)}, + {DEFINE_DBG(bcr, 9)}, + {DEFINE_DBG(bcr, 10)}, + {DEFINE_DBG(bcr, 11)}, + {DEFINE_DBG(bcr, 12)}, + {DEFINE_DBG(bcr, 13)}, + {DEFINE_DBG(bcr, 14)}, + {DEFINE_DBG(bcr, 15)}, + + {DEFINE_DBG(wvr, 0)}, + {DEFINE_DBG(wvr, 1)}, + {DEFINE_DBG(wvr, 2)}, + {DEFINE_DBG(wvr, 3)}, + {DEFINE_DBG(wvr, 4)}, + {DEFINE_DBG(wvr, 5)}, + {DEFINE_DBG(wvr, 6)}, + {DEFINE_DBG(wvr, 7)}, + {DEFINE_DBG(wvr, 8)}, + {DEFINE_DBG(wvr, 9)}, + {DEFINE_DBG(wvr, 10)}, + {DEFINE_DBG(wvr, 11)}, + {DEFINE_DBG(wvr, 12)}, + {DEFINE_DBG(wvr, 13)}, + {DEFINE_DBG(wvr, 14)}, + {DEFINE_DBG(wvr, 15)}, + + {DEFINE_DBG(wcr, 0)}, + {DEFINE_DBG(wcr, 1)}, + {DEFINE_DBG(wcr, 2)}, + {DEFINE_DBG(wcr, 3)}, + {DEFINE_DBG(wcr, 4)}, + {DEFINE_DBG(wcr, 5)}, + {DEFINE_DBG(wcr, 6)}, + {DEFINE_DBG(wcr, 7)}, + {DEFINE_DBG(wcr, 8)}, + {DEFINE_DBG(wcr, 9)}, + {DEFINE_DBG(wcr, 10)}, + {DEFINE_DBG(wcr, 11)}, + {DEFINE_DBG(wcr, 12)}, + {DEFINE_DBG(wcr, 13)}, + {DEFINE_DBG(wcr, 14)}, + {DEFINE_DBG(wcr, 15)} +}; +// clang-format on + +#endif // DECLARE_REGISTER_INFOS_ARM64_STRUCT 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..283c4c17e760 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h @@ -0,0 +1,573 @@ +//===-- 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. + +// clang-format off + +// 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, \ + } + +// 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, \ + } + +// 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, \ + } + +// 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, \ + } + +static lldb_private::RegisterInfo g_register_infos_arm64_sve_le[] = { + // 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 new file mode 100644 index 000000000000..e9f8065bffd8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -0,0 +1,310 @@ +//===-- RegisterInfos_i386.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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Compiler.h" +#include <cstddef> +#include <cstdint> + + +#ifdef DECLARE_REGISTER_INFOS_I386_STRUCT + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) + +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(regname) \ + (LLVM_EXTENSION offsetof(UserArea, i387) + \ + LLVM_EXTENSION offsetof(FPR_i386, regname)) + +// Computes the offset of the YMM register assembled from register halves. +// Based on DNBArchImplI386.cpp from debugserver +#define YMM_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, i387) + \ + LLVM_EXTENSION offsetof(FPR, fxsave) + \ + LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \ + (32 * reg_index)) + +#define BNDR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, i387) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index])) + +#define BNDC_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, i387) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index])) + +// Number of bytes needed to represent a FPR. +#if !defined(FPR_SIZE) +#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg) +#endif + +// Number of bytes needed to represent the i'th FP register. +#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes) + +// Number of bytes needed to represent an XMM register. +#define XMM_SIZE sizeof(XMMReg) + +// Number of bytes needed to represent a YMM register. +#define YMM_SIZE sizeof(YMMReg) + +// Number of bytes needed to represent MPX registers. +#define BNDR_SIZE sizeof(MPXReg) +#define BNDC_SIZE sizeof(MPXCsr) + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((GPR *)nullptr)->reg), \ + GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, \ + lldb_##reg##_i386 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ + { \ + #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, \ + lldb_##name##_i386 }, \ + nullptr, nullptr, nullptr, \ + } + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +#define DEFINE_FP_ST(reg, i) \ + { \ + #reg #i, nullptr, FP_SIZE, \ + LLVM_EXTENSION FPR_OFFSET( \ + stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {ehframe_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_st##i##_i386 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FP_MM(reg, i, streg) \ + { \ + #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, \ + } + +#define DEFINE_XMM(reg, i) \ + { \ + #reg #i, nullptr, XMM_SIZE, \ + LLVM_EXTENSION FPR_OFFSET( \ + reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ + nullptr, nullptr, nullptr, \ + } + +// I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then +// differentiate based on register size. +#define DEFINE_YMM(reg, i) \ + { \ + #reg #i, nullptr, YMM_SIZE, \ + LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg##i##_i386 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDR(reg, i) \ + { \ + #reg #i, nullptr, BNDR_SIZE, \ + LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \ + {dwarf_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDC(name, i) \ + { \ + #name, nullptr, BNDC_SIZE, \ + LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##name##_i386 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_DR(reg, i) \ + { \ + #reg #i, nullptr, DR_SIZE, \ + DR_OFFSET(i), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg##i##_i386 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_16(reg16, reg32) \ + { \ + #reg16, nullptr, 2, \ + GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg16##_i386 }, \ + RegisterContextPOSIX_x86::g_contained_##reg32, \ + RegisterContextPOSIX_x86::g_invalidate_##reg32, \ + nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \ + { \ + #reg8, nullptr, 1, \ + GPR_OFFSET(reg32) + 1, eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg8##_i386 }, \ + RegisterContextPOSIX_x86::g_contained_##reg32, \ + RegisterContextPOSIX_x86::g_invalidate_##reg32, \ + nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \ + { \ + #reg8, nullptr, 1, \ + GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg8##_i386 }, \ + RegisterContextPOSIX_x86::g_contained_##reg32, \ + RegisterContextPOSIX_x86::g_invalidate_##reg32, \ + nullptr, \ + } + +static RegisterInfo g_register_infos_i386[] = { + // General purpose registers. + DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, + LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, + LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, + LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, + LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + DEFINE_GPR_PSEUDO_16(ax, eax), DEFINE_GPR_PSEUDO_16(bx, ebx), + DEFINE_GPR_PSEUDO_16(cx, ecx), DEFINE_GPR_PSEUDO_16(dx, edx), + DEFINE_GPR_PSEUDO_16(di, edi), DEFINE_GPR_PSEUDO_16(si, esi), + DEFINE_GPR_PSEUDO_16(bp, ebp), DEFINE_GPR_PSEUDO_16(sp, esp), + DEFINE_GPR_PSEUDO_8H(ah, eax), DEFINE_GPR_PSEUDO_8H(bh, ebx), + DEFINE_GPR_PSEUDO_8H(ch, ecx), DEFINE_GPR_PSEUDO_8H(dh, edx), + DEFINE_GPR_PSEUDO_8L(al, eax), DEFINE_GPR_PSEUDO_8L(bl, ebx), + DEFINE_GPR_PSEUDO_8L(cl, ecx), DEFINE_GPR_PSEUDO_8L(dl, edx), + + // i387 Floating point registers. + DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386, + 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(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386, + 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, 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), + DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), + DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), + + // Copy of YMM registers assembled from xmm and ymmh + DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), + DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), + DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), + + // MPX registers + DEFINE_BNDR(bnd, 0), + DEFINE_BNDR(bnd, 1), + DEFINE_BNDR(bnd, 2), + DEFINE_BNDR(bnd, 3), + + DEFINE_BNDC(bndcfgu, 0), + DEFINE_BNDC(bndstatus, 1), + + // Debug registers for lldb internal use + DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), + DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; + +static_assert((sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])) == k_num_registers_i386, + "g_register_infos_x86_64 has wrong number of register infos"); + +#undef GPR_OFFSET +#undef FPR_OFFSET +#undef YMM_OFFSET +#undef FPR_SIZE +#undef FP_SIZE +#undef XMM_SIZE +#undef YMM_SIZE +#undef DEFINE_GPR +#undef DEFINE_FPR +#undef DEFINE_FP +#undef DEFINE_XMM +#undef DEFINE_YMM +#undef DEFINE_BNDR +#undef DEFINE_BNDC +#undef DEFINE_DR +#undef DEFINE_GPR_PSEUDO_16 +#undef DEFINE_GPR_PSEUDO_8H +#undef DEFINE_GPR_PSEUDO_8L + +#endif // DECLARE_REGISTER_INFOS_I386_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h new file mode 100644 index 000000000000..3fb1e6a5fbef --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h @@ -0,0 +1,171 @@ +//===-- RegisterInfos_loongarch64.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_LOONGARCH64_STRUCT + +#include <stddef.h> + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private.h" + +#include "Utility/LoongArch_DWARF_Registers.h" +#include "lldb-loongarch-register-enums.h" + +#ifndef GPR_OFFSET +#error GPR_OFFSET must be defined before including this header file +#endif + +#ifndef FPR_OFFSET +#error FPR_OFFSET must be defined before including this header file +#endif + +using namespace loongarch_dwarf; + +// clang-format off + +// I suppose EHFrame and DWARF are the same. +#define KIND_HELPER(reg, generic_kind) \ + { \ + loongarch_dwarf::dwarf_##reg, loongarch_dwarf::dwarf_##reg, generic_kind, \ + LLDB_INVALID_REGNUM, reg##_loongarch \ + } + +// Generates register kinds array for generic purpose registers +#define GPR64_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) + +// Generates register kinds array for floating point registers +#define FPR64_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) + +// Defines a 64-bit general purpose register +#define DEFINE_GPR64(reg, generic_kind) DEFINE_GPR64_ALT(reg, reg, generic_kind) +#define DEFINE_GPR64_ALT(reg, alt, generic_kind) \ + { \ + #reg, #alt, 8, GPR_OFFSET(gpr_##reg##_loongarch - gpr_first_loongarch), \ + lldb::eEncodingUint, lldb::eFormatHex, \ + GPR64_KIND(gpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ + } + +// Defines a 64-bit floating point register +#define DEFINE_FPR64(reg, generic_kind) DEFINE_FPR64_ALT(reg, reg, generic_kind) +#define DEFINE_FPR64_ALT(reg, alt, generic_kind) \ + { \ + #reg, #alt, 8, FPR_OFFSET(fpr_##reg##_loongarch - fpr_first_loongarch), \ + lldb::eEncodingUint, lldb::eFormatHex, \ + FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FCC(reg, generic_kind) \ + { \ + #reg, nullptr, 1, FCC_OFFSET(fpr_##reg##_loongarch - fpr_fcc0_loongarch), \ + lldb::eEncodingUint, lldb::eFormatHex, \ + FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FCSR(reg, generic_kind) \ + { \ + #reg, nullptr, 4, FCSR_OFFSET, \ + lldb::eEncodingUint, lldb::eFormatHex, \ + FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ + } + +// clang-format on + +static lldb_private::RegisterInfo g_register_infos_loongarch64[] = { + DEFINE_GPR64_ALT(r0, zero, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r1, ra, LLDB_REGNUM_GENERIC_RA), + DEFINE_GPR64_ALT(r2, tp, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r3, sp, LLDB_REGNUM_GENERIC_SP), + DEFINE_GPR64_ALT(r4, a0, LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GPR64_ALT(r5, a1, LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GPR64_ALT(r6, a2, LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GPR64_ALT(r7, a3, LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GPR64_ALT(r8, a4, LLDB_REGNUM_GENERIC_ARG5), + DEFINE_GPR64_ALT(r9, a5, LLDB_REGNUM_GENERIC_ARG6), + DEFINE_GPR64_ALT(r10, a6, LLDB_REGNUM_GENERIC_ARG7), + DEFINE_GPR64_ALT(r11, a7, LLDB_REGNUM_GENERIC_ARG8), + DEFINE_GPR64_ALT(r12, t0, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r13, t1, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r14, t2, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r15, t3, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r16, t4, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r17, t5, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r18, t6, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r19, t7, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r20, t8, LLDB_INVALID_REGNUM), + DEFINE_GPR64(r21, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r22, fp, LLDB_REGNUM_GENERIC_FP), + DEFINE_GPR64_ALT(r23, s0, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r24, s1, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r25, s2, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r26, s3, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r27, s4, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r28, s5, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r29, s6, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r30, s7, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(r31, s8, LLDB_INVALID_REGNUM), + + DEFINE_GPR64(orig_a0, LLDB_INVALID_REGNUM), + DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC), + DEFINE_GPR64(badv, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved0, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved1, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved2, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved3, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved4, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved5, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved6, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved7, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved8, LLDB_INVALID_REGNUM), + DEFINE_GPR64(reserved9, LLDB_INVALID_REGNUM), + + DEFINE_FPR64_ALT(f0, fa0, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f1, fa1, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f2, fa2, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f3, fa3, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f4, fa4, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f5, fa5, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f6, fa6, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f7, fa7, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f8, ft0, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f9, ft1, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f10, ft2, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f11, ft3, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f12, ft4, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f13, ft5, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f14, ft6, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f15, ft7, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f16, ft8, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f17, ft9, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f18, ft10, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f19, ft11, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f20, ft12, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f21, ft13, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f22, ft14, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f23, ft15, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f24, fs0, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f25, fs1, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f26, fs2, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f27, fs3, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f28, fs4, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f29, fs5, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f30, fs6, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(f31, fs7, LLDB_INVALID_REGNUM), + + DEFINE_FCC(fcc0, LLDB_INVALID_REGNUM), + DEFINE_FCC(fcc1, LLDB_INVALID_REGNUM), + DEFINE_FCC(fcc2, LLDB_INVALID_REGNUM), + DEFINE_FCC(fcc3, LLDB_INVALID_REGNUM), + DEFINE_FCC(fcc4, LLDB_INVALID_REGNUM), + DEFINE_FCC(fcc5, LLDB_INVALID_REGNUM), + DEFINE_FCC(fcc6, LLDB_INVALID_REGNUM), + DEFINE_FCC(fcc7, LLDB_INVALID_REGNUM), + DEFINE_FCSR(fcsr, LLDB_INVALID_REGNUM), +}; + +#endif // DECLARE_REGISTER_INFOS_LOONGARCH64_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h new file mode 100644 index 000000000000..93f93d56fda2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h @@ -0,0 +1,305 @@ +//===-- RegisterInfos_mips.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 +// +//===---------------------------------------------------------------------===// + +#include <cstddef> + +#include "lldb/Core/dwarf.h" +#include "llvm/Support/Compiler.h" + + +#ifdef DECLARE_REGISTER_INFOS_MIPS_STRUCT + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) \ + (LLVM_EXTENSION offsetof(UserArea, gpr) + \ + LLVM_EXTENSION offsetof(GPR_linux_mips, regname)) + +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(regname) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR_linux_mips, regname)) + +// Computes the offset of the given MSA in the extended data area. +#define MSA_OFFSET(regname) \ + (LLVM_EXTENSION offsetof(UserArea, msa) + \ + LLVM_EXTENSION offsetof(MSA_linux_mips, regname)) + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3) \ + { \ + #reg, alt, sizeof(((GPR_linux_mips *) NULL)->reg) / 2, \ + GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, ptrace_##reg##_mips, \ + gpr_##reg##_mips }, \ + NULL, NULL, NULL, 0 \ + } + +const uint8_t dwarf_opcode_mips[] = { + llvm::dwarf::DW_OP_regx, dwarf_sr_mips, llvm::dwarf::DW_OP_lit1, + llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and, + llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr}; + +#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \ + { \ + #reg, alt, sizeof(((FPR_linux_mips *) NULL)->reg), \ + FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \ + {kind1, kind2, kind3, ptrace_##reg##_mips, \ + fpr_##reg##_mips }, \ + NULL, NULL, dwarf_opcode_mips, \ + sizeof(dwarf_opcode_mips) \ + } + +#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3) \ + { \ + #reg, alt, sizeof(((FPR_linux_mips *) NULL)->reg), \ + FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, ptrace_##reg##_mips, \ + fpr_##reg##_mips }, \ + NULL, NULL, NULL, 0 \ + } + +#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \ + MSA_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt8, \ + {kind1, kind2, kind3, kind4, \ + msa_##reg##_mips }, \ + NULL, NULL, NULL, 0 \ + } + +#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \ + MSA_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, \ + msa_##reg##_mips }, \ + NULL, NULL, NULL, 0 \ + } + +// RegisterKind: EH_Frame, DWARF, Generic, Procss Plugin, LLDB + +static RegisterInfo g_register_infos_mips[] = { + DEFINE_GPR(zero, "zero", dwarf_zero_mips, dwarf_zero_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r1, "at", dwarf_r1_mips, dwarf_r1_mips, LLDB_INVALID_REGNUM), + DEFINE_GPR(r2, nullptr, dwarf_r2_mips, dwarf_r2_mips, LLDB_INVALID_REGNUM), + DEFINE_GPR(r3, nullptr, dwarf_r3_mips, dwarf_r3_mips, LLDB_INVALID_REGNUM), + DEFINE_GPR(r4, nullptr, dwarf_r4_mips, dwarf_r4_mips, + LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GPR(r5, nullptr, dwarf_r5_mips, dwarf_r5_mips, + LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GPR(r6, nullptr, dwarf_r6_mips, dwarf_r6_mips, + LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GPR(r7, nullptr, dwarf_r7_mips, dwarf_r7_mips, + LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GPR(r8, nullptr, dwarf_r8_mips, dwarf_r8_mips, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_mips, dwarf_r9_mips, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, nullptr, dwarf_r10_mips, dwarf_r10_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, nullptr, dwarf_r11_mips, dwarf_r11_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r12, nullptr, dwarf_r12_mips, dwarf_r12_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, nullptr, dwarf_r13_mips, dwarf_r13_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, nullptr, dwarf_r14_mips, dwarf_r14_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, nullptr, dwarf_r15_mips, dwarf_r15_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r16, nullptr, dwarf_r16_mips, dwarf_r16_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r17, nullptr, dwarf_r17_mips, dwarf_r17_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r18, nullptr, dwarf_r18_mips, dwarf_r18_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r19, nullptr, dwarf_r19_mips, dwarf_r19_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r20, nullptr, dwarf_r20_mips, dwarf_r20_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r21, nullptr, dwarf_r21_mips, dwarf_r21_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r22, nullptr, dwarf_r22_mips, dwarf_r22_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r23, nullptr, dwarf_r23_mips, dwarf_r23_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r24, nullptr, dwarf_r24_mips, dwarf_r24_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r25, nullptr, dwarf_r25_mips, dwarf_r25_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r26, nullptr, dwarf_r26_mips, dwarf_r26_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r27, nullptr, dwarf_r27_mips, dwarf_r27_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(gp, "gp", dwarf_gp_mips, dwarf_gp_mips, LLDB_INVALID_REGNUM), + DEFINE_GPR(sp, "sp", dwarf_sp_mips, dwarf_sp_mips, LLDB_REGNUM_GENERIC_SP), + DEFINE_GPR(r30, "fp", dwarf_r30_mips, dwarf_r30_mips, + LLDB_REGNUM_GENERIC_FP), + DEFINE_GPR(ra, "ra", dwarf_ra_mips, dwarf_ra_mips, LLDB_REGNUM_GENERIC_RA), + DEFINE_GPR(sr, "status", dwarf_sr_mips, dwarf_sr_mips, + LLDB_REGNUM_GENERIC_FLAGS), + DEFINE_GPR(mullo, nullptr, dwarf_lo_mips, dwarf_lo_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips, dwarf_hi_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips, dwarf_bad_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(cause, nullptr, dwarf_cause_mips, dwarf_cause_mips, + LLDB_INVALID_REGNUM), + DEFINE_GPR(pc, nullptr, dwarf_pc_mips, dwarf_pc_mips, + LLDB_REGNUM_GENERIC_PC), + DEFINE_GPR(config5, nullptr, dwarf_config5_mips, dwarf_config5_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f0, nullptr, dwarf_f0_mips, dwarf_f0_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f1, nullptr, dwarf_f1_mips, dwarf_f1_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f2, nullptr, dwarf_f2_mips, dwarf_f2_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f3, nullptr, dwarf_f3_mips, dwarf_f3_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f4, nullptr, dwarf_f4_mips, dwarf_f4_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f5, nullptr, dwarf_f5_mips, dwarf_f5_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f6, nullptr, dwarf_f6_mips, dwarf_f6_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f7, nullptr, dwarf_f7_mips, dwarf_f7_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f8, nullptr, dwarf_f8_mips, dwarf_f8_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f9, nullptr, dwarf_f9_mips, dwarf_f9_mips, LLDB_INVALID_REGNUM), + DEFINE_FPR(f10, nullptr, dwarf_f10_mips, dwarf_f10_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f11, nullptr, dwarf_f11_mips, dwarf_f11_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f12, nullptr, dwarf_f12_mips, dwarf_f12_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f13, nullptr, dwarf_f13_mips, dwarf_f13_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f14, nullptr, dwarf_f14_mips, dwarf_f14_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f15, nullptr, dwarf_f15_mips, dwarf_f15_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f16, nullptr, dwarf_f16_mips, dwarf_f16_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f17, nullptr, dwarf_f17_mips, dwarf_f17_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f18, nullptr, dwarf_f18_mips, dwarf_f18_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f19, nullptr, dwarf_f19_mips, dwarf_f19_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f20, nullptr, dwarf_f20_mips, dwarf_f20_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f21, nullptr, dwarf_f21_mips, dwarf_f21_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f22, nullptr, dwarf_f22_mips, dwarf_f22_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f23, nullptr, dwarf_f23_mips, dwarf_f23_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f24, nullptr, dwarf_f24_mips, dwarf_f24_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f25, nullptr, dwarf_f25_mips, dwarf_f25_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f26, nullptr, dwarf_f26_mips, dwarf_f26_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f27, nullptr, dwarf_f27_mips, dwarf_f27_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f28, nullptr, dwarf_f28_mips, dwarf_f28_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f29, nullptr, dwarf_f29_mips, dwarf_f29_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f30, nullptr, dwarf_f30_mips, dwarf_f30_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f31, nullptr, dwarf_f31_mips, dwarf_f31_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR_INFO(fcsr, nullptr, dwarf_fcsr_mips, dwarf_fcsr_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR_INFO(fir, nullptr, dwarf_fir_mips, dwarf_fir_mips, + LLDB_INVALID_REGNUM), + DEFINE_FPR_INFO(config5, nullptr, dwarf_config5_mips, dwarf_config5_mips, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w0, nullptr, dwarf_w0_mips, dwarf_w0_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w1, nullptr, dwarf_w1_mips, dwarf_w1_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w2, nullptr, dwarf_w2_mips, dwarf_w2_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w3, nullptr, dwarf_w3_mips, dwarf_w3_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w4, nullptr, dwarf_w4_mips, dwarf_w4_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w5, nullptr, dwarf_w5_mips, dwarf_w5_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w6, nullptr, dwarf_w6_mips, dwarf_w6_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w7, nullptr, dwarf_w7_mips, dwarf_w7_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w8, nullptr, dwarf_w8_mips, dwarf_w8_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w9, nullptr, dwarf_w9_mips, dwarf_w9_mips, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_MSA(w10, nullptr, dwarf_w10_mips, dwarf_w10_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w11, nullptr, dwarf_w11_mips, dwarf_w11_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w12, nullptr, dwarf_w12_mips, dwarf_w12_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w13, nullptr, dwarf_w13_mips, dwarf_w13_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w14, nullptr, dwarf_w14_mips, dwarf_w14_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w15, nullptr, dwarf_w15_mips, dwarf_w15_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w16, nullptr, dwarf_w16_mips, dwarf_w16_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w17, nullptr, dwarf_w17_mips, dwarf_w17_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w18, nullptr, dwarf_w18_mips, dwarf_w18_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w19, nullptr, dwarf_w19_mips, dwarf_w19_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w20, nullptr, dwarf_w10_mips, dwarf_w20_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w21, nullptr, dwarf_w21_mips, dwarf_w21_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w22, nullptr, dwarf_w22_mips, dwarf_w22_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w23, nullptr, dwarf_w23_mips, dwarf_w23_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w24, nullptr, dwarf_w24_mips, dwarf_w24_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w25, nullptr, dwarf_w25_mips, dwarf_w25_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w26, nullptr, dwarf_w26_mips, dwarf_w26_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w27, nullptr, dwarf_w27_mips, dwarf_w27_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w28, nullptr, dwarf_w28_mips, dwarf_w28_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w29, nullptr, dwarf_w29_mips, dwarf_w29_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w30, nullptr, dwarf_w30_mips, dwarf_w30_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA(w31, nullptr, dwarf_w31_mips, dwarf_w31_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA_INFO(mcsr, nullptr, dwarf_mcsr_mips, dwarf_mcsr_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA_INFO(mir, nullptr, dwarf_mir_mips, dwarf_mir_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA_INFO(fcsr, nullptr, dwarf_fcsr_mips, dwarf_fcsr_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA_INFO(fir, nullptr, dwarf_fir_mips, dwarf_fir_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_MSA_INFO(config5, nullptr, dwarf_config5_mips, dwarf_config5_mips, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM)}; + +static_assert((sizeof(g_register_infos_mips) / + sizeof(g_register_infos_mips[0])) == k_num_registers_mips, + "g_register_infos_mips has wrong number of register infos"); + +#undef GPR_OFFSET +#undef FPR_OFFSET +#undef MSA_OFFSET +#undef DEFINE_GPR +#undef DEFINE_FPR +#undef DEFINE_FPR_INFO +#undef DEFINE_MSA +#undef DEFINE_MSA_INFO + +#endif // DECLARE_REGISTER_INFOS_MIPS_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h new file mode 100644 index 000000000000..0a382032ac8b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h @@ -0,0 +1,223 @@ +//===-- RegisterInfos_mips64.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 +// +//===----------------------------------------------------------------------===// + +#include <cstddef> + +#include "lldb/Core/dwarf.h" +#include "llvm/Support/Compiler.h" + +#ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname)) + +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(regname) \ + (sizeof(GPR_freebsd_mips) + \ + LLVM_EXTENSION offsetof(FPR_freebsd_mips, regname)) + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((GPR_freebsd_mips *) 0)->reg), \ + GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, \ + gpr_##reg##_mips64 }, \ + NULL, NULL, NULL, \ + } + +#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \ + { \ + #reg, alt, sizeof(((FPR_freebsd_mips *) 0)->reg), \ + FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \ + {kind1, kind2, kind3, LLDB_INVALID_REGNUM, \ + fpr_##reg##_mips64 }, \ + NULL, NULL, NULL, \ + } + +#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3) \ + { \ + #reg, alt, sizeof(((FPR_freebsd_mips *) 0)->reg), \ + FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, LLDB_INVALID_REGNUM, \ + fpr_##reg##_mips64 }, \ + NULL, NULL, NULL, \ + } + + +static RegisterInfo g_register_infos_mips64[] = { +// General purpose registers. EH_Frame, DWARF, +// Generic, Process Plugin + DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r2, nullptr, dwarf_r2_mips64, dwarf_r2_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r3, nullptr, dwarf_r3_mips64, dwarf_r3_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r4, nullptr, dwarf_r4_mips64, dwarf_r4_mips64, + LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), + DEFINE_GPR(r5, nullptr, dwarf_r5_mips64, dwarf_r5_mips64, + LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), + DEFINE_GPR(r6, nullptr, dwarf_r6_mips64, dwarf_r6_mips64, + LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), + DEFINE_GPR(r7, nullptr, dwarf_r7_mips64, dwarf_r7_mips64, + LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, nullptr, dwarf_r8_mips64, dwarf_r8_mips64, + LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_mips64, dwarf_r9_mips64, + LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, nullptr, dwarf_r10_mips64, dwarf_r10_mips64, + LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, nullptr, dwarf_r11_mips64, dwarf_r11_mips64, + LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM), + DEFINE_GPR(r12, nullptr, dwarf_r12_mips64, dwarf_r12_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, nullptr, dwarf_r13_mips64, dwarf_r13_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, nullptr, dwarf_r14_mips64, dwarf_r14_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, nullptr, dwarf_r15_mips64, dwarf_r15_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r16, nullptr, dwarf_r16_mips64, dwarf_r16_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r17, nullptr, dwarf_r17_mips64, dwarf_r17_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r18, nullptr, dwarf_r18_mips64, dwarf_r18_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r19, nullptr, dwarf_r19_mips64, dwarf_r19_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r20, nullptr, dwarf_r20_mips64, dwarf_r20_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r21, nullptr, dwarf_r21_mips64, dwarf_r21_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r22, nullptr, dwarf_r22_mips64, dwarf_r22_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r23, nullptr, dwarf_r23_mips64, dwarf_r23_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r24, nullptr, dwarf_r24_mips64, dwarf_r24_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r25, nullptr, dwarf_r25_mips64, dwarf_r25_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r26, nullptr, dwarf_r26_mips64, dwarf_r26_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r27, nullptr, dwarf_r27_mips64, dwarf_r27_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gp, "r28", dwarf_gp_mips64, dwarf_gp_mips64, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(sp, "r29", dwarf_sp_mips64, dwarf_sp_mips64, + LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(r30, nullptr, dwarf_r30_mips64, dwarf_r30_mips64, + LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(ra, "r31", dwarf_ra_mips64, dwarf_ra_mips64, + LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM), + DEFINE_GPR(sr, nullptr, dwarf_sr_mips64, dwarf_sr_mips64, + LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(mullo, nullptr, dwarf_lo_mips64, dwarf_lo_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips64, dwarf_hi_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips64, dwarf_bad_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(cause, nullptr, dwarf_cause_mips64, dwarf_cause_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(pc, "pc", dwarf_pc_mips64, dwarf_pc_mips64, + LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(ic, nullptr, dwarf_ic_mips64, dwarf_ic_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + DEFINE_FPR(f0, nullptr, dwarf_f0_mips64, dwarf_f0_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f1, nullptr, dwarf_f1_mips64, dwarf_f1_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f2, nullptr, dwarf_f2_mips64, dwarf_f2_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f3, nullptr, dwarf_f3_mips64, dwarf_f3_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f4, nullptr, dwarf_f4_mips64, dwarf_f4_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f5, nullptr, dwarf_f5_mips64, dwarf_f5_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f6, nullptr, dwarf_f6_mips64, dwarf_f6_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f7, nullptr, dwarf_f7_mips64, dwarf_f7_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f8, nullptr, dwarf_f8_mips64, dwarf_f8_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f9, nullptr, dwarf_f9_mips64, dwarf_f9_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f10, nullptr, dwarf_f10_mips64, dwarf_f10_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f11, nullptr, dwarf_f11_mips64, dwarf_f11_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f12, nullptr, dwarf_f12_mips64, dwarf_f12_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f13, nullptr, dwarf_f13_mips64, dwarf_f13_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f14, nullptr, dwarf_f14_mips64, dwarf_f14_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f15, nullptr, dwarf_f15_mips64, dwarf_f15_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f16, nullptr, dwarf_f16_mips64, dwarf_f16_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f17, nullptr, dwarf_f17_mips64, dwarf_f17_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f18, nullptr, dwarf_f18_mips64, dwarf_f18_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f19, nullptr, dwarf_f19_mips64, dwarf_f19_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f20, nullptr, dwarf_f20_mips64, dwarf_f20_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f21, nullptr, dwarf_f21_mips64, dwarf_f21_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f22, nullptr, dwarf_f22_mips64, dwarf_f22_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f23, nullptr, dwarf_f23_mips64, dwarf_f23_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f24, nullptr, dwarf_f24_mips64, dwarf_f24_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f25, nullptr, dwarf_f25_mips64, dwarf_f25_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f26, nullptr, dwarf_f26_mips64, dwarf_f26_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f27, nullptr, dwarf_f27_mips64, dwarf_f27_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f28, nullptr, dwarf_f28_mips64, dwarf_f28_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f29, nullptr, dwarf_f29_mips64, dwarf_f29_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f30, nullptr, dwarf_f30_mips64, dwarf_f30_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f31, nullptr, dwarf_f31_mips64, dwarf_f31_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64, + LLDB_INVALID_REGNUM), +}; + +static_assert((sizeof(g_register_infos_mips64) / + sizeof(g_register_infos_mips64[0])) == k_num_registers_mips64, + "g_register_infos_mips64 has wrong number of register infos"); + +#undef DEFINE_GPR +#undef DEFINE_GPR_INFO +#undef DEFINE_FPR +#undef DEFINE_FPR_INFO +#undef DEFINE_MSA +#undef DEFINE_MSA_INFO +#undef GPR_OFFSET +#undef FPR_OFFSET +#undef MSA_OFFSET + +#endif // DECLARE_REGISTER_INFOS_MIPS64_STRUCT 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 new file mode 100644 index 000000000000..31f79f537911 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h @@ -0,0 +1,228 @@ +//===-- RegisterInfos_powerpc.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 +// +//===---------------------------------------------------------------------===// + +#include <cstddef> + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) (offsetof(GPR, 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 + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, lldb_kind) \ + { \ + #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {dwarf_##reg##_powerpc, \ + dwarf_##reg##_powerpc, lldb_kind, \ + LLDB_INVALID_REGNUM, \ + gpr_##reg##_powerpc }, \ + NULL, NULL, NULL, \ + } +#define DEFINE_FPR(reg, lldb_kind) \ + { \ + #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \ + {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \ + lldb_kind, LLDB_INVALID_REGNUM, \ + fpr_##reg##_powerpc }, \ + NULL, NULL, NULL, \ + } +#define DEFINE_VMX(reg, lldb_kind) \ + { \ + #reg, NULL, 16, VMX_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt32, \ + {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \ + lldb_kind, LLDB_INVALID_REGNUM, \ + vmx_##reg##_powerpc }, \ + NULL, NULL, NULL, \ + } + +// General purpose registers. EH_Frame, DWARF, +// Generic, Process Plugin +#define POWERPC_REGS \ + DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \ + , DEFINE_GPR(r1, NULL, LLDB_REGNUM_GENERIC_SP), \ + DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r3, NULL, LLDB_REGNUM_GENERIC_ARG1), \ + DEFINE_GPR(r4, NULL, LLDB_REGNUM_GENERIC_ARG2), \ + DEFINE_GPR(r5, NULL, LLDB_REGNUM_GENERIC_ARG3), \ + DEFINE_GPR(r6, NULL, LLDB_REGNUM_GENERIC_ARG4), \ + DEFINE_GPR(r7, NULL, LLDB_REGNUM_GENERIC_ARG5), \ + DEFINE_GPR(r8, NULL, LLDB_REGNUM_GENERIC_ARG6), \ + DEFINE_GPR(r9, NULL, LLDB_REGNUM_GENERIC_ARG7), \ + DEFINE_GPR(r10, NULL, LLDB_REGNUM_GENERIC_ARG8), \ + DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(lr, NULL, LLDB_REGNUM_GENERIC_RA), \ + DEFINE_GPR(cr, NULL, LLDB_REGNUM_GENERIC_FLAGS), \ + DEFINE_GPR(xer, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(ctr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(pc, NULL, LLDB_REGNUM_GENERIC_PC), \ + DEFINE_FPR(f0, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f1, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f2, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f3, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f4, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f5, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f6, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f7, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f8, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f9, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f10, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f11, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f12, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f13, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f14, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f15, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f16, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f17, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f18, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f19, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f20, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f21, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f22, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f23, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f24, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f25, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f26, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f27, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f28, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \ + {"fpscr", \ + NULL, \ + 8, \ + FPR_OFFSET(fpscr), \ + eEncodingUint, \ + eFormatHex, \ + {dwarf_fpscr_powerpc, dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpr_fpscr_powerpc}, \ + NULL, \ + NULL, \ + NULL, \ + }, \ + DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v3, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v4, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v5, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v6, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v7, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v8, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v9, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v10, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v11, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v12, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v13, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v14, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v15, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v16, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v17, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v18, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v19, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v20, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v21, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v22, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v23, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v24, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v25, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v26, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v27, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v28, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v29, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v30, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(v31, LLDB_INVALID_REGNUM), \ + {"vrsave", \ + NULL, \ + 4, \ + VMX_OFFSET(vrsave), \ + eEncodingUint, \ + eFormatHex, \ + {dwarf_vrsave_powerpc, dwarf_vrsave_powerpc, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, vmx_vrsave_powerpc}, \ + NULL, \ + NULL, \ + NULL, \ + }, \ + {"vscr", \ + NULL, \ + 4, \ + VMX_OFFSET(vscr), \ + eEncodingUint, \ + eFormatHex, \ + {dwarf_vscr_powerpc, dwarf_vscr_powerpc, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, vmx_vscr_powerpc}, \ + NULL, \ + NULL, \ + NULL, \ + }, + +static RegisterInfo g_register_infos_powerpc64[] = { +#define GPR GPR64 + POWERPC_REGS +#undef GPR +}; + +static RegisterInfo g_register_infos_powerpc32[] = { +#define GPR GPR32 + POWERPC_REGS +#undef GPR +}; + +static RegisterInfo g_register_infos_powerpc64_32[] = { +#define GPR GPR64 +#undef GPR_SIZE +#define GPR_SIZE(reg) (sizeof(uint32_t)) +#undef GPR_OFFSET +#define GPR_OFFSET(regname) \ + (offsetof(GPR, regname) + (sizeof(((GPR *)NULL)->regname) - GPR_SIZE(reg))) + POWERPC_REGS +#undef GPR +}; + +static_assert((sizeof(g_register_infos_powerpc32) / + sizeof(g_register_infos_powerpc32[0])) == + k_num_registers_powerpc, + "g_register_infos_powerpc32 has wrong number of register infos"); +static_assert((sizeof(g_register_infos_powerpc64) / + sizeof(g_register_infos_powerpc64[0])) == + k_num_registers_powerpc, + "g_register_infos_powerpc64 has wrong number of register infos"); +static_assert(sizeof(g_register_infos_powerpc64_32) == + sizeof(g_register_infos_powerpc64), + "g_register_infos_powerpc64_32 doesn't match size of " + "g_register_infos_powerpc64"); + +#undef DEFINE_FPR +#undef DEFINE_GPR + +#endif // DECLARE_REGISTER_INFOS_POWERPC_STRUCT + +#undef GPR_OFFSET diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h new file mode 100644 index 000000000000..e15e1d5fc4a2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h @@ -0,0 +1,329 @@ +//===-- RegisterInfos_ppc64.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_PPC64_STRUCT + +#include <cstddef> + +// Computes the offset of the given GPR_PPC64 in the user data area. +#define GPR_PPC64_OFFSET(regname) (offsetof(GPR_PPC64, regname)) +#define FPR_PPC64_OFFSET(regname) (offsetof(FPR_PPC64, regname) \ + + sizeof(GPR_PPC64)) +#define VMX_PPC64_OFFSET(regname) (offsetof(VMX_PPC64, regname) \ + + sizeof(GPR_PPC64) + sizeof(FPR_PPC64)) +#define GPR_PPC64_SIZE(regname) (sizeof(((GPR_PPC64 *)NULL)->regname)) + +#include "Utility/PPC64_DWARF_Registers.h" +#include "lldb-ppc64-register-enums.h" + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR_PPC64(reg, alt, lldb_kind) \ + { \ + #reg, alt, GPR_PPC64_SIZE(reg), GPR_PPC64_OFFSET(reg), lldb::eEncodingUint,\ + lldb::eFormatHex, \ + {ppc64_dwarf::dwarf_##reg##_ppc64, \ + ppc64_dwarf::dwarf_##reg##_ppc64, \ + lldb_kind, \ + LLDB_INVALID_REGNUM, \ + gpr_##reg##_ppc64 }, \ + NULL, NULL, NULL, \ + } +#define DEFINE_FPR_PPC64(reg, alt, lldb_kind) \ + { \ +#reg, alt, 8, FPR_PPC64_OFFSET(reg), lldb::eEncodingIEEE754, \ + lldb::eFormatFloat, \ + {ppc64_dwarf::dwarf_##reg##_ppc64, \ + ppc64_dwarf::dwarf_##reg##_ppc64, lldb_kind, LLDB_INVALID_REGNUM, \ + fpr_##reg##_ppc64 }, \ + NULL, NULL, NULL, \ + } +#define DEFINE_VMX_PPC64(reg, lldb_kind) \ + { \ +#reg, NULL, 16, VMX_PPC64_OFFSET(reg), lldb::eEncodingVector, \ + lldb::eFormatVectorOfUInt32, \ + {ppc64_dwarf::dwarf_##reg##_ppc64, \ + ppc64_dwarf::dwarf_##reg##_ppc64, lldb_kind, LLDB_INVALID_REGNUM, \ + vmx_##reg##_ppc64 }, \ + NULL, NULL, NULL, \ + } + +// General purpose registers. +// EH_Frame, Generic, Process Plugin +#define PPC64_REGS \ + DEFINE_GPR_PPC64(r0, NULL, LLDB_INVALID_REGNUM) \ + , DEFINE_GPR_PPC64(r1, NULL, LLDB_REGNUM_GENERIC_SP), \ + DEFINE_GPR_PPC64(r2, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r3, NULL, LLDB_REGNUM_GENERIC_ARG1), \ + DEFINE_GPR_PPC64(r4, NULL, LLDB_REGNUM_GENERIC_ARG2), \ + DEFINE_GPR_PPC64(r5, NULL, LLDB_REGNUM_GENERIC_ARG3), \ + DEFINE_GPR_PPC64(r6, NULL, LLDB_REGNUM_GENERIC_ARG4), \ + DEFINE_GPR_PPC64(r7, NULL, LLDB_REGNUM_GENERIC_ARG5), \ + DEFINE_GPR_PPC64(r8, NULL, LLDB_REGNUM_GENERIC_ARG6), \ + DEFINE_GPR_PPC64(r9, NULL, LLDB_REGNUM_GENERIC_ARG7), \ + DEFINE_GPR_PPC64(r10, NULL, LLDB_REGNUM_GENERIC_ARG8), \ + DEFINE_GPR_PPC64(r11, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r12, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r13, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r14, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r15, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r16, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r17, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r18, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r19, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r20, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r21, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r22, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r23, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r24, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r25, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r26, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r27, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r28, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r29, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r30, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(r31, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(cr, NULL, LLDB_REGNUM_GENERIC_FLAGS), \ + DEFINE_GPR_PPC64(msr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(xer, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(lr, NULL, LLDB_REGNUM_GENERIC_RA), \ + DEFINE_GPR_PPC64(ctr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(pc, NULL, LLDB_REGNUM_GENERIC_PC), \ + DEFINE_FPR_PPC64(f0, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f1, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f2, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f3, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f4, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f5, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f6, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f7, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f8, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f9, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f10, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f11, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f12, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f13, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f14, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f15, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f16, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f17, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f18, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f19, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f20, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f21, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f22, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f23, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f24, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f25, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f26, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f27, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f28, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f29, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f30, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR_PPC64(f31, NULL, LLDB_INVALID_REGNUM), \ + {"fpscr", \ + NULL, \ + 8, \ + FPR_PPC64_OFFSET(fpscr), \ + lldb::eEncodingUint, \ + lldb::eFormatHex, \ + {ppc64_dwarf::dwarf_fpscr_ppc64, \ + ppc64_dwarf::dwarf_fpscr_ppc64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpr_fpscr_ppc64}, \ + NULL, \ + NULL, \ + NULL, \ + }, \ + DEFINE_VMX_PPC64(vr0, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr1, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr2, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr3, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr4, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr5, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr6, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr7, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr8, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr9, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr10, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr11, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr12, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr13, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr14, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr15, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr16, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr17, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr18, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr19, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr20, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr21, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr22, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr23, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr24, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr25, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr26, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr27, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr28, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr29, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr30, LLDB_INVALID_REGNUM), \ + DEFINE_VMX_PPC64(vr31, LLDB_INVALID_REGNUM), \ + {"vscr", \ + NULL, \ + 4, \ + VMX_PPC64_OFFSET(vscr), \ + lldb::eEncodingUint, \ + lldb::eFormatHex, \ + {ppc64_dwarf::dwarf_vscr_ppc64, ppc64_dwarf::dwarf_vscr_ppc64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64}, \ + NULL, \ + NULL, \ + NULL, \ + }, \ + {"vrsave", \ + NULL, \ + 4, \ + VMX_PPC64_OFFSET(vrsave), \ + lldb::eEncodingUint, \ + lldb::eFormatHex, \ + {ppc64_dwarf::dwarf_vrsave_ppc64, \ + ppc64_dwarf::dwarf_vrsave_ppc64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, vmx_vrsave_ppc64}, \ + NULL, \ + NULL, \ + NULL, \ + }, /* */ + +typedef struct _GPR_PPC64 { + uint64_t r0; + uint64_t r1; + uint64_t r2; + uint64_t r3; + uint64_t r4; + uint64_t r5; + uint64_t r6; + uint64_t r7; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t r16; + uint64_t r17; + uint64_t r18; + uint64_t r19; + uint64_t r20; + uint64_t r21; + uint64_t r22; + uint64_t r23; + uint64_t r24; + uint64_t r25; + uint64_t r26; + uint64_t r27; + uint64_t r28; + uint64_t r29; + uint64_t r30; + uint64_t r31; + uint64_t cr; + uint64_t msr; + uint64_t xer; + uint64_t lr; + uint64_t ctr; + uint64_t pc; + uint64_t pad[3]; +} GPR_PPC64; + +typedef struct _FPR_PPC64 { + uint64_t f0; + uint64_t f1; + uint64_t f2; + uint64_t f3; + uint64_t f4; + uint64_t f5; + uint64_t f6; + uint64_t f7; + uint64_t f8; + uint64_t f9; + uint64_t f10; + uint64_t f11; + uint64_t f12; + uint64_t f13; + uint64_t f14; + uint64_t f15; + uint64_t f16; + uint64_t f17; + uint64_t f18; + uint64_t f19; + uint64_t f20; + uint64_t f21; + uint64_t f22; + uint64_t f23; + uint64_t f24; + uint64_t f25; + uint64_t f26; + uint64_t f27; + uint64_t f28; + uint64_t f29; + uint64_t f30; + uint64_t f31; + uint64_t fpscr; +} FPR_PPC64; + +typedef struct _VMX_PPC64 { + uint32_t vr0[4]; + uint32_t vr1[4]; + uint32_t vr2[4]; + uint32_t vr3[4]; + uint32_t vr4[4]; + uint32_t vr5[4]; + uint32_t vr6[4]; + uint32_t vr7[4]; + uint32_t vr8[4]; + uint32_t vr9[4]; + uint32_t vr10[4]; + uint32_t vr11[4]; + uint32_t vr12[4]; + uint32_t vr13[4]; + uint32_t vr14[4]; + uint32_t vr15[4]; + uint32_t vr16[4]; + uint32_t vr17[4]; + uint32_t vr18[4]; + uint32_t vr19[4]; + uint32_t vr20[4]; + uint32_t vr21[4]; + uint32_t vr22[4]; + uint32_t vr23[4]; + uint32_t vr24[4]; + uint32_t vr25[4]; + uint32_t vr26[4]; + uint32_t vr27[4]; + uint32_t vr28[4]; + uint32_t vr29[4]; + uint32_t vr30[4]; + uint32_t vr31[4]; + uint32_t pad[2]; + uint32_t vscr[2]; + uint32_t vrsave; +} VMX_PPC64; + + +static lldb_private::RegisterInfo g_register_infos_ppc64[] = { + PPC64_REGS +}; + +static_assert((sizeof(g_register_infos_ppc64) / + sizeof(g_register_infos_ppc64[0])) == + k_num_registers_ppc64, + "g_register_infos_powerpc64 has wrong number of register infos"); + +#undef DEFINE_FPR_PPC64 +#undef DEFINE_GPR_PPC64 +#undef DEFINE_VMX_PPC64 + +#endif // DECLARE_REGISTER_INFOS_PPC64_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h new file mode 100644 index 000000000000..18489fb74f86 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h @@ -0,0 +1,474 @@ +//===-- RegisterInfos_ppc64le.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_PPC64LE_STRUCT + +#include <cstddef> + +// 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) + sizeof(GPR)) +#define VMX_OFFSET(regname) (offsetof(VMX, regname) + sizeof(GPR) + sizeof(FPR)) +#define VSX_OFFSET(regname) \ + (offsetof(VSX, regname) + sizeof(GPR) + sizeof(FPR) + sizeof(VMX)) +#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname)) + +#include "Utility/PPC64LE_DWARF_Registers.h" +#include "lldb-ppc64le-register-enums.h" + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, lldb_kind) \ + { \ + #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), lldb::eEncodingUint, \ + lldb::eFormatHex, \ + {ppc64le_dwarf::dwarf_##reg##_ppc64le,\ + ppc64le_dwarf::dwarf_##reg##_ppc64le,\ + lldb_kind, \ + LLDB_INVALID_REGNUM, \ + gpr_##reg##_ppc64le }, \ + NULL, NULL, NULL, \ + } +#define DEFINE_FPR(reg, alt, lldb_kind) \ + { \ +#reg, alt, 8, FPR_OFFSET(reg), lldb::eEncodingIEEE754, lldb::eFormatFloat, \ + {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ + ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ + fpr_##reg##_ppc64le }, \ + NULL, NULL, NULL, \ + } +#define DEFINE_VMX(reg, lldb_kind) \ + { \ +#reg, NULL, 16, VMX_OFFSET(reg), lldb::eEncodingVector, \ + lldb::eFormatVectorOfUInt32, \ + {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ + ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ + vmx_##reg##_ppc64le }, \ + NULL, NULL, NULL, \ + } +#define DEFINE_VSX(reg, lldb_kind) \ + { \ +#reg, NULL, 16, VSX_OFFSET(reg), lldb::eEncodingVector, \ + lldb::eFormatVectorOfUInt32, \ + {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ + ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ + vsx_##reg##_ppc64le }, \ + NULL, NULL, NULL, \ + } + +// General purpose registers. +// EH_Frame, Generic, Process Plugin +#define POWERPC_REGS \ + DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \ + , DEFINE_GPR(r1, NULL, LLDB_REGNUM_GENERIC_SP), \ + DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r3, NULL, LLDB_REGNUM_GENERIC_ARG1), \ + DEFINE_GPR(r4, NULL, LLDB_REGNUM_GENERIC_ARG2), \ + DEFINE_GPR(r5, NULL, LLDB_REGNUM_GENERIC_ARG3), \ + DEFINE_GPR(r6, NULL, LLDB_REGNUM_GENERIC_ARG4), \ + DEFINE_GPR(r7, NULL, LLDB_REGNUM_GENERIC_ARG5), \ + DEFINE_GPR(r8, NULL, LLDB_REGNUM_GENERIC_ARG6), \ + DEFINE_GPR(r9, NULL, LLDB_REGNUM_GENERIC_ARG7), \ + DEFINE_GPR(r10, NULL, LLDB_REGNUM_GENERIC_ARG8), \ + DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(pc, NULL, LLDB_REGNUM_GENERIC_PC), \ + DEFINE_GPR(msr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(origr3, "orig_r3", LLDB_INVALID_REGNUM), \ + DEFINE_GPR(ctr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(lr, NULL, LLDB_REGNUM_GENERIC_RA), \ + DEFINE_GPR(xer, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(cr, NULL, LLDB_REGNUM_GENERIC_FLAGS), \ + DEFINE_GPR(softe, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(trap, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f0, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f1, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f2, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f3, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f4, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f5, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f6, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f7, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f8, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f9, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f10, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f11, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f12, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f13, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f14, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f15, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f16, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f17, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f18, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f19, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f20, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f21, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f22, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f23, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f24, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f25, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f26, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f27, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f28, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f29, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f30, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f31, NULL, LLDB_INVALID_REGNUM), \ + {"fpscr", \ + NULL, \ + 8, \ + FPR_OFFSET(fpscr), \ + lldb::eEncodingUint, \ + lldb::eFormatHex, \ + {ppc64le_dwarf::dwarf_fpscr_ppc64le, \ + ppc64le_dwarf::dwarf_fpscr_ppc64le, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpr_fpscr_ppc64le}, \ + NULL, \ + NULL, \ + NULL, \ + }, \ + DEFINE_VMX(vr0, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr1, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr2, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr3, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr4, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr5, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr6, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr7, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr8, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr9, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr10, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr11, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr12, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr13, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr14, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr15, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr16, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr17, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr18, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr19, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr20, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr21, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr22, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr23, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr24, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr25, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr26, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr27, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr28, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr29, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr30, LLDB_INVALID_REGNUM), \ + DEFINE_VMX(vr31, LLDB_INVALID_REGNUM), \ + {"vscr", \ + NULL, \ + 4, \ + VMX_OFFSET(vscr), \ + lldb::eEncodingUint, \ + lldb::eFormatHex, \ + {ppc64le_dwarf::dwarf_vscr_ppc64le, ppc64le_dwarf::dwarf_vscr_ppc64le, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64le}, \ + NULL, \ + NULL, \ + NULL, \ + }, \ + {"vrsave", \ + NULL, \ + 4, \ + VMX_OFFSET(vrsave), \ + lldb::eEncodingUint, \ + lldb::eFormatHex, \ + {ppc64le_dwarf::dwarf_vrsave_ppc64le, \ + ppc64le_dwarf::dwarf_vrsave_ppc64le, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, vmx_vrsave_ppc64le}, \ + NULL, \ + NULL, \ + NULL, \ + }, \ + DEFINE_VSX(vs0, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs1, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs2, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs3, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs4, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs5, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs6, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs7, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs8, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs9, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs10, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs11, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs12, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs13, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs14, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs15, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs16, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs17, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs18, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs19, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs20, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs21, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs22, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs23, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs24, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs25, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs26, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs27, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs28, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs29, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs30, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs31, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs32, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs33, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs34, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs35, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs36, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs37, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs38, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs39, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs40, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs41, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs42, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs43, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs44, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs45, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs46, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs47, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs48, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs49, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs50, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs51, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs52, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs53, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs54, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs55, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs56, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs57, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs58, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs59, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs50, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs61, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs62, LLDB_INVALID_REGNUM), \ + DEFINE_VSX(vs63, LLDB_INVALID_REGNUM), /* */ + +typedef struct _GPR { + uint64_t r0; + uint64_t r1; + uint64_t r2; + uint64_t r3; + uint64_t r4; + uint64_t r5; + uint64_t r6; + uint64_t r7; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t r16; + uint64_t r17; + uint64_t r18; + uint64_t r19; + uint64_t r20; + uint64_t r21; + uint64_t r22; + uint64_t r23; + uint64_t r24; + uint64_t r25; + uint64_t r26; + uint64_t r27; + uint64_t r28; + uint64_t r29; + uint64_t r30; + uint64_t r31; + uint64_t pc; + uint64_t msr; + uint64_t origr3; + uint64_t ctr; + uint64_t lr; + uint64_t xer; + uint64_t cr; + uint64_t softe; + uint64_t trap; + uint64_t pad[3]; +} GPR; + +typedef struct _FPR { + uint64_t f0; + uint64_t f1; + uint64_t f2; + uint64_t f3; + uint64_t f4; + uint64_t f5; + uint64_t f6; + uint64_t f7; + uint64_t f8; + uint64_t f9; + uint64_t f10; + uint64_t f11; + uint64_t f12; + uint64_t f13; + uint64_t f14; + uint64_t f15; + uint64_t f16; + uint64_t f17; + uint64_t f18; + uint64_t f19; + uint64_t f20; + uint64_t f21; + uint64_t f22; + uint64_t f23; + uint64_t f24; + uint64_t f25; + uint64_t f26; + uint64_t f27; + uint64_t f28; + uint64_t f29; + uint64_t f30; + uint64_t f31; + uint64_t fpscr; +} FPR; + +typedef struct _VMX { + uint32_t vr0[4]; + uint32_t vr1[4]; + uint32_t vr2[4]; + uint32_t vr3[4]; + uint32_t vr4[4]; + uint32_t vr5[4]; + uint32_t vr6[4]; + uint32_t vr7[4]; + uint32_t vr8[4]; + uint32_t vr9[4]; + uint32_t vr10[4]; + uint32_t vr11[4]; + uint32_t vr12[4]; + uint32_t vr13[4]; + uint32_t vr14[4]; + uint32_t vr15[4]; + uint32_t vr16[4]; + uint32_t vr17[4]; + uint32_t vr18[4]; + uint32_t vr19[4]; + uint32_t vr20[4]; + uint32_t vr21[4]; + uint32_t vr22[4]; + uint32_t vr23[4]; + uint32_t vr24[4]; + uint32_t vr25[4]; + uint32_t vr26[4]; + uint32_t vr27[4]; + uint32_t vr28[4]; + uint32_t vr29[4]; + uint32_t vr30[4]; + uint32_t vr31[4]; + uint32_t pad[2]; + uint32_t vscr[2]; + uint32_t vrsave; +} VMX; + +typedef struct _VSX { + uint32_t vs0[4]; + uint32_t vs1[4]; + uint32_t vs2[4]; + uint32_t vs3[4]; + uint32_t vs4[4]; + uint32_t vs5[4]; + uint32_t vs6[4]; + uint32_t vs7[4]; + uint32_t vs8[4]; + uint32_t vs9[4]; + uint32_t vs10[4]; + uint32_t vs11[4]; + uint32_t vs12[4]; + uint32_t vs13[4]; + uint32_t vs14[4]; + uint32_t vs15[4]; + uint32_t vs16[4]; + uint32_t vs17[4]; + uint32_t vs18[4]; + uint32_t vs19[4]; + uint32_t vs20[4]; + uint32_t vs21[4]; + uint32_t vs22[4]; + uint32_t vs23[4]; + uint32_t vs24[4]; + uint32_t vs25[4]; + uint32_t vs26[4]; + uint32_t vs27[4]; + uint32_t vs28[4]; + uint32_t vs29[4]; + uint32_t vs30[4]; + uint32_t vs31[4]; + uint32_t vs32[4]; + uint32_t vs33[4]; + uint32_t vs34[4]; + uint32_t vs35[4]; + uint32_t vs36[4]; + uint32_t vs37[4]; + uint32_t vs38[4]; + uint32_t vs39[4]; + uint32_t vs40[4]; + uint32_t vs41[4]; + uint32_t vs42[4]; + uint32_t vs43[4]; + uint32_t vs44[4]; + uint32_t vs45[4]; + uint32_t vs46[4]; + uint32_t vs47[4]; + uint32_t vs48[4]; + uint32_t vs49[4]; + uint32_t vs50[4]; + uint32_t vs51[4]; + uint32_t vs52[4]; + uint32_t vs53[4]; + uint32_t vs54[4]; + uint32_t vs55[4]; + uint32_t vs56[4]; + uint32_t vs57[4]; + uint32_t vs58[4]; + uint32_t vs59[4]; + uint32_t vs60[4]; + uint32_t vs61[4]; + uint32_t vs62[4]; + uint32_t vs63[4]; +} VSX; + +static lldb_private::RegisterInfo g_register_infos_ppc64le[] = { + POWERPC_REGS +}; + +static_assert((sizeof(g_register_infos_ppc64le) / + sizeof(g_register_infos_ppc64le[0])) == + k_num_registers_ppc64le, + "g_register_infos_powerpc64 has wrong number of register infos"); + +#undef DEFINE_FPR +#undef DEFINE_GPR +#undef DEFINE_VMX +#undef DEFINE_VSX + +#endif // DECLARE_REGISTER_INFOS_PPC64LE_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h new file mode 100644 index 000000000000..720d900c7b97 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h @@ -0,0 +1,186 @@ +//===-- RegisterInfos_riscv64.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_RISCV64_STRUCT + +#include <stddef.h> + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private.h" + +#include "Utility/RISCV_DWARF_Registers.h" +#include "lldb-riscv-register-enums.h" + +#ifndef GPR_OFFSET +#error GPR_OFFSET must be defined before including this header file +#endif + +#ifndef FPR_OFFSET +#error FPR_OFFSET must be defined before including this header file +#endif + +using namespace riscv_dwarf; + +// clang-format off + +// I suppose EHFrame and DWARF are the same. +#define KIND_HELPER(reg, generic_kind) \ + { \ + riscv_dwarf::dwarf_##reg, riscv_dwarf::dwarf_##reg, generic_kind, \ + LLDB_INVALID_REGNUM, reg##_riscv \ + } + +// Generates register kinds array for vector registers +#define GPR64_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) + +// FPR register kinds array for vector registers +#define FPR64_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) + +// VPR register kinds array for vector registers +#define VPR_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) + +// Defines a 64-bit general purpose register +#define DEFINE_GPR64(reg, generic_kind) DEFINE_GPR64_ALT(reg, reg, generic_kind) + +// Defines a 64-bit general purpose register +#define DEFINE_GPR64_ALT(reg, alt, generic_kind) \ + { \ + #reg, #alt, 8, GPR_OFFSET(gpr_##reg##_riscv - gpr_first_riscv), \ + lldb::eEncodingUint, lldb::eFormatHex, \ + GPR64_KIND(gpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FPR64(reg, generic_kind) DEFINE_FPR64_ALT(reg, reg, generic_kind) + +#define DEFINE_FPR64_ALT(reg, alt, generic_kind) DEFINE_FPR_ALT(reg, alt, 8, generic_kind) + +#define DEFINE_FPR_ALT(reg, alt, size, generic_kind) \ + { \ + #reg, #alt, size, FPR_OFFSET(fpr_##reg##_riscv - fpr_first_riscv), \ + lldb::eEncodingUint, lldb::eFormatHex, \ + FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ + } + +#define DEFINE_VPR(reg, generic_kind) DEFINE_VPR_ALT(reg, reg, generic_kind) + +// Defines a scalable vector register, with default size 128 bits +// The byte offset 0 is a placeholder, which should be corrected at runtime. +#define DEFINE_VPR_ALT(reg, alt, generic_kind) \ + { \ + #reg, #alt, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \ + VPR_KIND(vpr_##reg, generic_kind), nullptr, nullptr, nullptr \ + } + +// clang-format on + +static lldb_private::RegisterInfo g_register_infos_riscv64_le[] = { + // DEFINE_GPR64(name, GENERIC KIND) + DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC), + DEFINE_GPR64_ALT(ra, x1, LLDB_REGNUM_GENERIC_RA), + DEFINE_GPR64_ALT(sp, x2, LLDB_REGNUM_GENERIC_SP), + DEFINE_GPR64_ALT(gp, x3, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(tp, x4, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(t0, x5, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(t1, x6, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(t2, x7, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(fp, x8, LLDB_REGNUM_GENERIC_FP), + DEFINE_GPR64_ALT(s1, x9, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(a0, x10, LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GPR64_ALT(a1, x11, LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GPR64_ALT(a2, x12, LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GPR64_ALT(a3, x13, LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GPR64_ALT(a4, x14, LLDB_REGNUM_GENERIC_ARG5), + DEFINE_GPR64_ALT(a5, x15, LLDB_REGNUM_GENERIC_ARG6), + DEFINE_GPR64_ALT(a6, x16, LLDB_REGNUM_GENERIC_ARG7), + DEFINE_GPR64_ALT(a7, x17, LLDB_REGNUM_GENERIC_ARG8), + DEFINE_GPR64_ALT(s2, x18, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s3, x19, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s4, x20, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s5, x21, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s6, x22, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s7, x23, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s8, x24, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s9, x25, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s10, x26, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(s11, x27, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(t3, x28, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(t4, x29, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(t5, x30, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(t6, x31, LLDB_INVALID_REGNUM), + DEFINE_GPR64_ALT(zero, x0, LLDB_INVALID_REGNUM), + + DEFINE_FPR64_ALT(ft0, f0, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft1, f1, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft2, f2, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft3, f3, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft4, f4, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft5, f5, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft6, f6, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft7, f7, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs0, f8, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs1, f9, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fa0, f10, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fa1, f11, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fa2, f12, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fa3, f13, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fa4, f14, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fa5, f15, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fa6, f16, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fa7, f17, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs2, f18, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs3, f19, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs4, f20, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs5, f21, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs6, f22, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs7, f23, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs8, f24, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs9, f25, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs10, f26, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(fs11, f27, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft8, f28, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft9, f29, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft10, f30, LLDB_INVALID_REGNUM), + DEFINE_FPR64_ALT(ft11, f31, LLDB_INVALID_REGNUM), + DEFINE_FPR_ALT(fcsr, nullptr, 4, LLDB_INVALID_REGNUM), + + DEFINE_VPR(v0, LLDB_INVALID_REGNUM), + DEFINE_VPR(v1, LLDB_INVALID_REGNUM), + DEFINE_VPR(v2, LLDB_INVALID_REGNUM), + DEFINE_VPR(v3, LLDB_INVALID_REGNUM), + DEFINE_VPR(v4, LLDB_INVALID_REGNUM), + DEFINE_VPR(v5, LLDB_INVALID_REGNUM), + DEFINE_VPR(v6, LLDB_INVALID_REGNUM), + DEFINE_VPR(v7, LLDB_INVALID_REGNUM), + DEFINE_VPR(v8, LLDB_INVALID_REGNUM), + DEFINE_VPR(v9, LLDB_INVALID_REGNUM), + DEFINE_VPR(v10, LLDB_INVALID_REGNUM), + DEFINE_VPR(v11, LLDB_INVALID_REGNUM), + DEFINE_VPR(v12, LLDB_INVALID_REGNUM), + DEFINE_VPR(v13, LLDB_INVALID_REGNUM), + DEFINE_VPR(v14, LLDB_INVALID_REGNUM), + DEFINE_VPR(v15, LLDB_INVALID_REGNUM), + DEFINE_VPR(v16, LLDB_INVALID_REGNUM), + DEFINE_VPR(v17, LLDB_INVALID_REGNUM), + DEFINE_VPR(v18, LLDB_INVALID_REGNUM), + DEFINE_VPR(v19, LLDB_INVALID_REGNUM), + DEFINE_VPR(v20, LLDB_INVALID_REGNUM), + DEFINE_VPR(v21, LLDB_INVALID_REGNUM), + DEFINE_VPR(v22, LLDB_INVALID_REGNUM), + DEFINE_VPR(v23, LLDB_INVALID_REGNUM), + DEFINE_VPR(v24, LLDB_INVALID_REGNUM), + DEFINE_VPR(v25, LLDB_INVALID_REGNUM), + DEFINE_VPR(v26, LLDB_INVALID_REGNUM), + DEFINE_VPR(v27, LLDB_INVALID_REGNUM), + DEFINE_VPR(v28, LLDB_INVALID_REGNUM), + DEFINE_VPR(v29, LLDB_INVALID_REGNUM), + DEFINE_VPR(v30, LLDB_INVALID_REGNUM), + DEFINE_VPR(v31, LLDB_INVALID_REGNUM), +}; + +#endif // DECLARE_REGISTER_INFOS_RISCV64_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h new file mode 100644 index 000000000000..7b5f204ebbad --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h @@ -0,0 +1,124 @@ +//===-- RegisterInfos_s390x.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 +// +//===----------------------------------------------------------------------===// + +#include <cstddef> + +#include "llvm/Support/Compiler.h" + + +#ifdef DECLARE_REGISTER_INFOS_S390X_STRUCT + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(num) (16 + 8 * num) +// Computes the offset of the given ACR in the user data area. +#define ACR_OFFSET(num) (16 + 8 * 16 + 4 * num) +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(num) (8 + 8 * num) + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +#define DEFINE_GPR(name, size, offset, alt, generic) \ + { \ + #name, alt, size, offset, eEncodingUint, eFormatHex, \ + {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \ + LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ + NULL, NULL, NULL, \ + } + +#define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \ + { \ + #name, alt, size, offset, eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, \ + LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ + NULL, NULL, NULL, \ + } + +#define DEFINE_FPR(name, size, offset) \ + { \ + #name, NULL, size, offset, eEncodingUint, eFormatHex, \ + {dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ + NULL, NULL, NULL, \ + } + +#define DEFINE_FPR_NODWARF(name, size, offset) \ + { \ + #name, NULL, size, offset, eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ + NULL, NULL, NULL, \ + } + +static RegisterInfo g_register_infos_s390x[] = { + // General purpose registers. + DEFINE_GPR(r0, 8, GPR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r1, 8, GPR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r2, 8, GPR_OFFSET(2), nullptr, LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GPR(r3, 8, GPR_OFFSET(3), nullptr, LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GPR(r4, 8, GPR_OFFSET(4), nullptr, LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GPR(r5, 8, GPR_OFFSET(5), nullptr, LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GPR(r6, 8, GPR_OFFSET(6), nullptr, LLDB_REGNUM_GENERIC_ARG5), + DEFINE_GPR(r7, 8, GPR_OFFSET(7), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, 8, GPR_OFFSET(8), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, 8, GPR_OFFSET(9), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, 8, GPR_OFFSET(10), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, 8, GPR_OFFSET(11), nullptr, LLDB_REGNUM_GENERIC_FP), + DEFINE_GPR(r12, 8, GPR_OFFSET(12), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, 8, GPR_OFFSET(13), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, 8, GPR_OFFSET(14), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, 8, GPR_OFFSET(15), nullptr, LLDB_REGNUM_GENERIC_SP), + DEFINE_GPR(acr0, 4, ACR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr1, 4, ACR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr2, 4, ACR_OFFSET(2), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr3, 4, ACR_OFFSET(3), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr4, 4, ACR_OFFSET(4), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr5, 4, ACR_OFFSET(5), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr6, 4, ACR_OFFSET(6), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr7, 4, ACR_OFFSET(7), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr8, 4, ACR_OFFSET(8), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr9, 4, ACR_OFFSET(9), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr10, 4, ACR_OFFSET(10), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr11, 4, ACR_OFFSET(11), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr12, 4, ACR_OFFSET(12), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr13, 4, ACR_OFFSET(13), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr14, 4, ACR_OFFSET(14), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr15, 4, ACR_OFFSET(15), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(pswm, 8, 0, nullptr, LLDB_REGNUM_GENERIC_FLAGS), + DEFINE_GPR(pswa, 8, 8, nullptr, LLDB_REGNUM_GENERIC_PC), + + // Floating point registers. + DEFINE_FPR(f0, 8, FPR_OFFSET(0)), DEFINE_FPR(f1, 8, FPR_OFFSET(1)), + DEFINE_FPR(f2, 8, FPR_OFFSET(2)), DEFINE_FPR(f3, 8, FPR_OFFSET(3)), + DEFINE_FPR(f4, 8, FPR_OFFSET(4)), DEFINE_FPR(f5, 8, FPR_OFFSET(5)), + DEFINE_FPR(f6, 8, FPR_OFFSET(6)), DEFINE_FPR(f7, 8, FPR_OFFSET(7)), + DEFINE_FPR(f8, 8, FPR_OFFSET(8)), DEFINE_FPR(f9, 8, FPR_OFFSET(9)), + DEFINE_FPR(f10, 8, FPR_OFFSET(10)), DEFINE_FPR(f11, 8, FPR_OFFSET(11)), + DEFINE_FPR(f12, 8, FPR_OFFSET(12)), DEFINE_FPR(f13, 8, FPR_OFFSET(13)), + DEFINE_FPR(f14, 8, FPR_OFFSET(14)), DEFINE_FPR(f15, 8, FPR_OFFSET(15)), + DEFINE_FPR_NODWARF(fpc, 4, 0), + + // Linux operating-specific info. + DEFINE_GPR_NODWARF(orig_r2, 8, 16 + 16 * 8 + 16 * 4, nullptr, + LLDB_INVALID_REGNUM), + DEFINE_GPR_NODWARF(last_break, 8, 0, nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR_NODWARF(system_call, 4, 0, nullptr, LLDB_INVALID_REGNUM), +}; + +static_assert((sizeof(g_register_infos_s390x) / + sizeof(g_register_infos_s390x[0])) == k_num_registers_s390x, + "g_register_infos_s390x has wrong number of register infos"); + +#undef GPR_OFFSET +#undef ACR_OFFSET +#undef FPR_OFFSET +#undef DEFINE_GPR +#undef DEFINE_GPR_NODWARF +#undef DEFINE_FPR +#undef DEFINE_FPR_NODWARF + +#endif // DECLARE_REGISTER_INFOS_S390X_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 new file mode 100644 index 000000000000..163438158155 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h @@ -0,0 +1,486 @@ +//===-- RegisterInfos_x86_64.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 +// +//===----------------------------------------------------------------------===// + +// This file is meant to be textually included. Do not #include modular +// headers here. + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) + +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(regname) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, fxsave) + \ + LLVM_EXTENSION offsetof(FXSAVE, regname)) + +// Computes the offset of the YMM register assembled from register halves. +// Based on DNBArchImplX86_64.cpp from debugserver +#define YMM_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index)) + +// Guarantees BNDR/BNDC offsets do not overlap with YMM offsets. +#define GDB_REMOTE_OFFSET 128 + +#define BNDR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]) + GDB_REMOTE_OFFSET) + +#define BNDC_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]) + GDB_REMOTE_OFFSET) + +#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +// Number of bytes needed to represent a FPR. +#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg) + +// Number of bytes needed to represent the i'th FP register. +#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes) + +// Number of bytes needed to represent an XMM register. +#define XMM_SIZE sizeof(XMMReg) + +// Number of bytes needed to represent a YMM register. +#define YMM_SIZE sizeof(YMMReg) + +// Number of bytes needed to represent MPX registers. +#define BNDR_SIZE sizeof(MPXReg) +#define BNDC_SIZE sizeof(MPXCsr) + +#define DR_SIZE sizeof(((DBG *)nullptr)->dr[0]) + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((GPR *)nullptr)->reg), \ + GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, \ + lldb_##reg##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ + { \ + #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, \ + lldb_##name##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FP_ST(reg, i) \ + { \ + #reg #i, nullptr, FP_SIZE, \ + LLVM_EXTENSION FPR_OFFSET( \ + stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +#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 }, \ + RegisterContextPOSIX_x86::g_contained_##streg##_64, \ + RegisterContextPOSIX_x86::g_invalidate_##streg##_64, \ + nullptr, \ + } + +#define DEFINE_XMM(reg, i) \ + { \ + #reg #i, nullptr, XMM_SIZE, \ + LLVM_EXTENSION FPR_OFFSET( \ + reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg##i##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_YMM(reg, i) \ + { \ + #reg #i, nullptr, YMM_SIZE, \ + LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_##reg##i##h_x86_64, \ + dwarf_##reg##i##h_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg##i##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDR(reg, i) \ + { \ + #reg #i, nullptr, BNDR_SIZE, \ + LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \ + {dwarf_##reg##i##_x86_64, \ + dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg##i##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDC(name, i) \ + { \ + #name, nullptr, BNDC_SIZE, \ + LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##name##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_DR(reg, i) \ + { \ + #reg #i, nullptr, DR_SIZE, \ + DR_OFFSET(i), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg##i##_x86_64 }, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ + { \ + #reg32, nullptr, 4, \ + GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg32##_x86_64 }, \ + RegisterContextPOSIX_x86::g_contained_##reg64, \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ + { \ + #reg16, nullptr, 2, \ + GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg16##_x86_64 }, \ + RegisterContextPOSIX_x86::g_contained_##reg64, \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ + { \ + #reg8, nullptr, 1, \ + GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg8##_x86_64 }, \ + RegisterContextPOSIX_x86::g_contained_##reg64, \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ + { \ + #reg8, nullptr, 1, \ + GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg8##_x86_64 }, \ + RegisterContextPOSIX_x86::g_contained_##reg64, \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr \ + } + +#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, \ + } + +// clang-format off +static RegisterInfo g_register_infos_x86_64[] = { +// General purpose registers EH_Frame DWARF Generic Process Plugin +// =========================== ================== ================ ========================= ==================== + DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rcx, nullptr, dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdx, nullptr, dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdi, nullptr, dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsi, nullptr, dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbp, nullptr, dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsp, nullptr, dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, nullptr, dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rip, nullptr, dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(rflags, nullptr, dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx), + DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx), + DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi), + DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp), + DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9), + DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11), + DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13), + DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15), + DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx), + DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx), + DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi), + DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp), + DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9), + DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11), + DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13), + DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15), + DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx), + DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx), + DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx), + DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx), + DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi), + DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp), + DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9), + DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11), + 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 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_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, 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), + DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), + DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8), + DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11), + DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14), + DEFINE_XMM(xmm, 15), + + // Copy of YMM registers assembled from xmm and ymmh + DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), + DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), + DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8), + DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11), + DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14), + DEFINE_YMM(ymm, 15), + + // MPX registers + DEFINE_BNDR(bnd, 0), + DEFINE_BNDR(bnd, 1), + DEFINE_BNDR(bnd, 2), + DEFINE_BNDR(bnd, 3), + + DEFINE_BNDC(bndcfgu, 0), + DEFINE_BNDC(bndstatus, 1), + + // Debug registers for lldb internal use + DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), + DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; + +// clang-format on + +static_assert((sizeof(g_register_infos_x86_64) / + sizeof(g_register_infos_x86_64[0])) == k_num_registers_x86_64, + "g_register_infos_x86_64 has wrong number of register infos"); + +#undef FPR_SIZE +#undef FP_SIZE +#undef XMM_SIZE +#undef YMM_SIZE +#undef DEFINE_GPR +#undef DEFINE_FPR +#undef DEFINE_FP +#undef DEFINE_XMM +#undef DEFINE_YMM +#undef DEFINE_BNDR +#undef DEFINE_BNDC +#undef DEFINE_DR +#undef DEFINE_GPR_PSEUDO_32 +#undef DEFINE_GPR_PSEUDO_16 +#undef DEFINE_GPR_PSEUDO_8H +#undef DEFINE_GPR_PSEUDO_8L + +#endif // DECLARE_REGISTER_INFOS_X86_64_STRUCT + +#ifdef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + +#define UPDATE_GPR_INFO(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \ + } while (false); + +#define UPDATE_GPR_INFO_8H(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \ + } while (false); + +#define UPDATE_FPR_INFO(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \ + } while (false); + +#define UPDATE_FP_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \ + } while (false); + +#define UPDATE_XMM_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \ + } while (false); + +#define UPDATE_YMM_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \ + } while (false); + +#define UPDATE_DR_INFO(reg_index) \ + do { \ + g_register_infos[lldb_dr##reg_index##_i386].byte_offset = \ + DR_OFFSET(reg_index); \ + } while (false); + +// Update the register offsets +UPDATE_GPR_INFO(eax, rax); +UPDATE_GPR_INFO(ebx, rbx); +UPDATE_GPR_INFO(ecx, rcx); +UPDATE_GPR_INFO(edx, rdx); +UPDATE_GPR_INFO(edi, rdi); +UPDATE_GPR_INFO(esi, rsi); +UPDATE_GPR_INFO(ebp, rbp); +UPDATE_GPR_INFO(esp, rsp); +UPDATE_GPR_INFO(eip, rip); +UPDATE_GPR_INFO(eflags, rflags); +UPDATE_GPR_INFO(cs, cs); +UPDATE_GPR_INFO(fs, fs); +UPDATE_GPR_INFO(gs, gs); +UPDATE_GPR_INFO(ss, ss); +UPDATE_GPR_INFO(ds, ds); +UPDATE_GPR_INFO(es, es); + +UPDATE_GPR_INFO(ax, rax); +UPDATE_GPR_INFO(bx, rbx); +UPDATE_GPR_INFO(cx, rcx); +UPDATE_GPR_INFO(dx, rdx); +UPDATE_GPR_INFO(di, rdi); +UPDATE_GPR_INFO(si, rsi); +UPDATE_GPR_INFO(bp, rbp); +UPDATE_GPR_INFO(sp, rsp); +UPDATE_GPR_INFO_8H(ah, rax); +UPDATE_GPR_INFO_8H(bh, rbx); +UPDATE_GPR_INFO_8H(ch, rcx); +UPDATE_GPR_INFO_8H(dh, rdx); +UPDATE_GPR_INFO(al, rax); +UPDATE_GPR_INFO(bl, rbx); +UPDATE_GPR_INFO(cl, rcx); +UPDATE_GPR_INFO(dl, rdx); + +UPDATE_FPR_INFO(fctrl, fctrl); +UPDATE_FPR_INFO(fstat, fstat); +UPDATE_FPR_INFO(ftag, ftag); +UPDATE_FPR_INFO(fop, fop); +UPDATE_FPR_INFO(fiseg, ptr.i386_.fiseg); +UPDATE_FPR_INFO(fioff, ptr.i386_.fioff); +UPDATE_FPR_INFO(fooff, ptr.i386_.fooff); +UPDATE_FPR_INFO(foseg, ptr.i386_.foseg); +UPDATE_FPR_INFO(mxcsr, mxcsr); +UPDATE_FPR_INFO(mxcsrmask, mxcsrmask); + +UPDATE_FP_INFO(st, 0); +UPDATE_FP_INFO(st, 1); +UPDATE_FP_INFO(st, 2); +UPDATE_FP_INFO(st, 3); +UPDATE_FP_INFO(st, 4); +UPDATE_FP_INFO(st, 5); +UPDATE_FP_INFO(st, 6); +UPDATE_FP_INFO(st, 7); +UPDATE_FP_INFO(mm, 0); +UPDATE_FP_INFO(mm, 1); +UPDATE_FP_INFO(mm, 2); +UPDATE_FP_INFO(mm, 3); +UPDATE_FP_INFO(mm, 4); +UPDATE_FP_INFO(mm, 5); +UPDATE_FP_INFO(mm, 6); +UPDATE_FP_INFO(mm, 7); + +UPDATE_XMM_INFO(xmm, 0); +UPDATE_XMM_INFO(xmm, 1); +UPDATE_XMM_INFO(xmm, 2); +UPDATE_XMM_INFO(xmm, 3); +UPDATE_XMM_INFO(xmm, 4); +UPDATE_XMM_INFO(xmm, 5); +UPDATE_XMM_INFO(xmm, 6); +UPDATE_XMM_INFO(xmm, 7); + +UPDATE_YMM_INFO(ymm, 0); +UPDATE_YMM_INFO(ymm, 1); +UPDATE_YMM_INFO(ymm, 2); +UPDATE_YMM_INFO(ymm, 3); +UPDATE_YMM_INFO(ymm, 4); +UPDATE_YMM_INFO(ymm, 5); +UPDATE_YMM_INFO(ymm, 6); +UPDATE_YMM_INFO(ymm, 7); + +UPDATE_DR_INFO(0); +UPDATE_DR_INFO(1); +UPDATE_DR_INFO(2); +UPDATE_DR_INFO(3); +UPDATE_DR_INFO(4); +UPDATE_DR_INFO(5); +UPDATE_DR_INFO(6); +UPDATE_DR_INFO(7); + +#undef UPDATE_GPR_INFO +#undef UPDATE_GPR_INFO_8H +#undef UPDATE_FPR_INFO +#undef UPDATE_FP_INFO +#undef UPDATE_XMM_INFO +#undef UPDATE_YMM_INFO +#undef UPDATE_DR_INFO + +#endif // UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + +#undef GPR_OFFSET +#undef FPR_OFFSET +#undef YMM_OFFSET diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h new file mode 100644 index 000000000000..b111d8f62d1f --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h @@ -0,0 +1,471 @@ +//===-- RegisterInfos_x86_64_with_base.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 +// +//===----------------------------------------------------------------------===// + +#include "RegisterInfos_x86_64_with_base_shared.h" + +// This file is meant to be textually included. Do not #include modular +// headers here. + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) + +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(regname) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, fxsave) + \ + LLVM_EXTENSION offsetof(FXSAVE, regname)) + +// Computes the offset of the YMM register assembled from register halves. +// Based on DNBArchImplX86_64.cpp from debugserver +#define YMM_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index)) + +// Guarantees BNDR/BNDC offsets do not overlap with YMM offsets. +#define GDB_REMOTE_OFFSET 128 + +#define BNDR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]) + GDB_REMOTE_OFFSET) + +#define BNDC_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]) + GDB_REMOTE_OFFSET) + +#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +// Number of bytes needed to represent a FPR. +#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg) + +// Number of bytes needed to represent the i'th FP register. +#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes) + +// Number of bytes needed to represent an XMM register. +#define XMM_SIZE sizeof(XMMReg) + +// Number of bytes needed to represent a YMM register. +#define YMM_SIZE sizeof(YMMReg) + +// Number of bytes needed to represent MPX registers. +#define BNDR_SIZE sizeof(MPXReg) +#define BNDC_SIZE sizeof(MPXCsr) + +#define DR_SIZE sizeof(((DBG *)nullptr)->dr[0]) + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ + eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##reg}, nullptr, \ + nullptr, nullptr, \ + } + +#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ + { \ + #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##name}, nullptr, \ + nullptr, nullptr, \ + } + +#define DEFINE_FP_ST(reg, i) \ + { \ + #reg #i, nullptr, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ + eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_st##i}, \ + nullptr, nullptr, nullptr, \ + } + +#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, x86_64_with_base::lldb_mm##i}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##streg##_64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##streg##_64, \ + nullptr, \ + } + +#define DEFINE_XMM(reg, i) \ + { \ + #reg #i, nullptr, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \ + eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_YMM(reg, i) \ + { \ + #reg #i, nullptr, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDR(reg, i) \ + { \ + #reg #i, nullptr, BNDR_SIZE, LLVM_EXTENSION BNDR_OFFSET(i), \ + eEncodingVector, eFormatVectorOfUInt64, \ + {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDC(name, i) \ + { \ + #name, nullptr, BNDC_SIZE, LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##name}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_DR(reg, i) \ + { \ + #reg #i, nullptr, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ + { \ + #reg32, nullptr, 4, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg32}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ + { \ + #reg16, nullptr, 2, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg16}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ + { \ + #reg8, nullptr, 1, GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg8}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ + { \ + #reg8, nullptr, 1, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg8}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr \ + } + +#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, x86_64_with_base::lldb_##name}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +// clang-format off +static RegisterInfo g_register_infos_x86_64_with_base[] = { +// General purpose registers EH_Frame DWARF Generic Process Plugin +// =========================== ================== ================ ========================= ==================== + DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rcx, nullptr, dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdx, nullptr, dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdi, nullptr, dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsi, nullptr, dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbp, nullptr, dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsp, nullptr, dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, nullptr, dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rip, nullptr, dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(rflags, nullptr, dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs_base,nullptr, dwarf_fs_base_x86_64, dwarf_fs_base_x86_64, LLDB_REGNUM_GENERIC_TP, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs_base,nullptr, dwarf_gs_base_x86_64, dwarf_gs_base_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx), + DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx), + DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi), + DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp), + DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9), + DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11), + DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13), + DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15), + DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx), + DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx), + DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi), + DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp), + DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9), + DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11), + DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13), + DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15), + DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx), + DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx), + DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx), + DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx), + DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi), + DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp), + DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9), + DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11), + 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 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_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, 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), + DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), + DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8), + DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11), + DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14), + DEFINE_XMM(xmm, 15), + + // Copy of YMM registers assembled from xmm and ymmh + DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), + DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), + DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8), + DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11), + DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14), + DEFINE_YMM(ymm, 15), + + // MPX registers + DEFINE_BNDR(bnd, 0), + DEFINE_BNDR(bnd, 1), + DEFINE_BNDR(bnd, 2), + DEFINE_BNDR(bnd, 3), + + DEFINE_BNDC(bndcfgu, 0), + DEFINE_BNDC(bndstatus, 1), + + // Debug registers for lldb internal use + DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), + DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; + +// clang-format on + +static_assert( + (sizeof(g_register_infos_x86_64_with_base) / + sizeof(g_register_infos_x86_64_with_base[0])) == + x86_64_with_base::k_num_registers, + "g_register_infos_x86_64_with_base has wrong number of register infos"); + +#undef FPR_SIZE +#undef FP_SIZE +#undef XMM_SIZE +#undef YMM_SIZE +#undef DEFINE_GPR +#undef DEFINE_FPR +#undef DEFINE_FP +#undef DEFINE_XMM +#undef DEFINE_YMM +#undef DEFINE_BNDR +#undef DEFINE_BNDC +#undef DEFINE_DR +#undef DEFINE_GPR_PSEUDO_32 +#undef DEFINE_GPR_PSEUDO_16 +#undef DEFINE_GPR_PSEUDO_8H +#undef DEFINE_GPR_PSEUDO_8L + +#endif // DECLARE_REGISTER_INFOS_X86_64_STRUCT + +#ifdef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + +#define UPDATE_GPR_INFO(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \ + } while (false); + +#define UPDATE_GPR_INFO_8H(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \ + } while (false); + +#define UPDATE_FPR_INFO(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \ + } while (false); + +#define UPDATE_FP_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \ + } while (false); + +#define UPDATE_XMM_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \ + } while (false); + +#define UPDATE_YMM_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \ + } while (false); + +#define UPDATE_DR_INFO(reg_index) \ + do { \ + g_register_infos[lldb_dr##reg_index##_i386].byte_offset = \ + DR_OFFSET(reg_index); \ + } while (false); + +// Update the register offsets +UPDATE_GPR_INFO(eax, rax); +UPDATE_GPR_INFO(ebx, rbx); +UPDATE_GPR_INFO(ecx, rcx); +UPDATE_GPR_INFO(edx, rdx); +UPDATE_GPR_INFO(edi, rdi); +UPDATE_GPR_INFO(esi, rsi); +UPDATE_GPR_INFO(ebp, rbp); +UPDATE_GPR_INFO(esp, rsp); +UPDATE_GPR_INFO(eip, rip); +UPDATE_GPR_INFO(eflags, rflags); +UPDATE_GPR_INFO(cs, cs); +UPDATE_GPR_INFO(fs, fs); +UPDATE_GPR_INFO(gs, gs); +UPDATE_GPR_INFO(ss, ss); +UPDATE_GPR_INFO(ds, ds); +UPDATE_GPR_INFO(es, es); + +UPDATE_GPR_INFO(ax, rax); +UPDATE_GPR_INFO(bx, rbx); +UPDATE_GPR_INFO(cx, rcx); +UPDATE_GPR_INFO(dx, rdx); +UPDATE_GPR_INFO(di, rdi); +UPDATE_GPR_INFO(si, rsi); +UPDATE_GPR_INFO(bp, rbp); +UPDATE_GPR_INFO(sp, rsp); +UPDATE_GPR_INFO_8H(ah, rax); +UPDATE_GPR_INFO_8H(bh, rbx); +UPDATE_GPR_INFO_8H(ch, rcx); +UPDATE_GPR_INFO_8H(dh, rdx); +UPDATE_GPR_INFO(al, rax); +UPDATE_GPR_INFO(bl, rbx); +UPDATE_GPR_INFO(cl, rcx); +UPDATE_GPR_INFO(dl, rdx); + +UPDATE_FPR_INFO(fctrl, fctrl); +UPDATE_FPR_INFO(fstat, fstat); +UPDATE_FPR_INFO(ftag, ftag); +UPDATE_FPR_INFO(fop, fop); +UPDATE_FPR_INFO(fiseg, ptr.i386_.fiseg); +UPDATE_FPR_INFO(fioff, ptr.i386_.fioff); +UPDATE_FPR_INFO(fooff, ptr.i386_.fooff); +UPDATE_FPR_INFO(foseg, ptr.i386_.foseg); +UPDATE_FPR_INFO(mxcsr, mxcsr); +UPDATE_FPR_INFO(mxcsrmask, mxcsrmask); + +UPDATE_FP_INFO(st, 0); +UPDATE_FP_INFO(st, 1); +UPDATE_FP_INFO(st, 2); +UPDATE_FP_INFO(st, 3); +UPDATE_FP_INFO(st, 4); +UPDATE_FP_INFO(st, 5); +UPDATE_FP_INFO(st, 6); +UPDATE_FP_INFO(st, 7); +UPDATE_FP_INFO(mm, 0); +UPDATE_FP_INFO(mm, 1); +UPDATE_FP_INFO(mm, 2); +UPDATE_FP_INFO(mm, 3); +UPDATE_FP_INFO(mm, 4); +UPDATE_FP_INFO(mm, 5); +UPDATE_FP_INFO(mm, 6); +UPDATE_FP_INFO(mm, 7); + +UPDATE_XMM_INFO(xmm, 0); +UPDATE_XMM_INFO(xmm, 1); +UPDATE_XMM_INFO(xmm, 2); +UPDATE_XMM_INFO(xmm, 3); +UPDATE_XMM_INFO(xmm, 4); +UPDATE_XMM_INFO(xmm, 5); +UPDATE_XMM_INFO(xmm, 6); +UPDATE_XMM_INFO(xmm, 7); + +UPDATE_YMM_INFO(ymm, 0); +UPDATE_YMM_INFO(ymm, 1); +UPDATE_YMM_INFO(ymm, 2); +UPDATE_YMM_INFO(ymm, 3); +UPDATE_YMM_INFO(ymm, 4); +UPDATE_YMM_INFO(ymm, 5); +UPDATE_YMM_INFO(ymm, 6); +UPDATE_YMM_INFO(ymm, 7); + +UPDATE_DR_INFO(0); +UPDATE_DR_INFO(1); +UPDATE_DR_INFO(2); +UPDATE_DR_INFO(3); +UPDATE_DR_INFO(4); +UPDATE_DR_INFO(5); +UPDATE_DR_INFO(6); +UPDATE_DR_INFO(7); + +#undef UPDATE_GPR_INFO +#undef UPDATE_GPR_INFO_8H +#undef UPDATE_FPR_INFO +#undef UPDATE_FP_INFO +#undef UPDATE_XMM_INFO +#undef UPDATE_YMM_INFO +#undef UPDATE_DR_INFO + +#endif // UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + +#undef GPR_OFFSET +#undef FPR_OFFSET +#undef YMM_OFFSET diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp new file mode 100644 index 000000000000..7b2d64de230f --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp @@ -0,0 +1,321 @@ +//===-- RegisterInfos_x86_64_with_base_shared.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 "RegisterInfos_x86_64_with_base_shared.h" + +#include "lldb/lldb-defines.h" +#include <mutex> + +using namespace lldb; + +namespace lldb_private { + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_eax[] = { + lldb_eax_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ebx[] = { + lldb_ebx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ecx[] = { + lldb_ecx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_edx[] = { + lldb_edx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_edi[] = { + lldb_edi_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_esi[] = { + lldb_esi_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ebp[] = { + lldb_ebp_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_esp[] = { + lldb_esp_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_eax[] = { + lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ebx[] = { + lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ecx[] = { + lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_edx[] = { + lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_edi[] = { + lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_esi[] = { + lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ebp[] = { + lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_esp[] = { + lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rax[] = { + x86_64_with_base::lldb_rax, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rbx[] = { + x86_64_with_base::lldb_rbx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rcx[] = { + x86_64_with_base::lldb_rcx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rdx[] = { + x86_64_with_base::lldb_rdx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rdi[] = { + x86_64_with_base::lldb_rdi, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rsi[] = { + x86_64_with_base::lldb_rsi, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rbp[] = { + x86_64_with_base::lldb_rbp, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rsp[] = { + x86_64_with_base::lldb_rsp, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r8[] = { + x86_64_with_base::lldb_r8, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r9[] = { + x86_64_with_base::lldb_r9, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r10[] = { + x86_64_with_base::lldb_r10, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r11[] = { + x86_64_with_base::lldb_r11, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r12[] = { + x86_64_with_base::lldb_r12, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r13[] = { + x86_64_with_base::lldb_r13, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r14[] = { + x86_64_with_base::lldb_r14, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r15[] = { + x86_64_with_base::lldb_r15, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rax[] = { + x86_64_with_base::lldb_rax, x86_64_with_base::lldb_eax, + x86_64_with_base::lldb_ax, x86_64_with_base::lldb_ah, + x86_64_with_base::lldb_al, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rbx[] = { + x86_64_with_base::lldb_rbx, x86_64_with_base::lldb_ebx, + x86_64_with_base::lldb_bx, x86_64_with_base::lldb_bh, + x86_64_with_base::lldb_bl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rcx[] = { + x86_64_with_base::lldb_rcx, x86_64_with_base::lldb_ecx, + x86_64_with_base::lldb_cx, x86_64_with_base::lldb_ch, + x86_64_with_base::lldb_cl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rdx[] = { + x86_64_with_base::lldb_rdx, x86_64_with_base::lldb_edx, + x86_64_with_base::lldb_dx, x86_64_with_base::lldb_dh, + x86_64_with_base::lldb_dl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rdi[] = { + x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_edi, + x86_64_with_base::lldb_di, x86_64_with_base::lldb_dil, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rsi[] = { + x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_esi, + x86_64_with_base::lldb_si, x86_64_with_base::lldb_sil, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rbp[] = { + x86_64_with_base::lldb_rbp, x86_64_with_base::lldb_ebp, + x86_64_with_base::lldb_bp, x86_64_with_base::lldb_bpl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rsp[] = { + x86_64_with_base::lldb_rsp, x86_64_with_base::lldb_esp, + x86_64_with_base::lldb_sp, x86_64_with_base::lldb_spl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r8[] = { + x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r8d, + x86_64_with_base::lldb_r8w, x86_64_with_base::lldb_r8l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r9[] = { + x86_64_with_base::lldb_r9, x86_64_with_base::lldb_r9d, + x86_64_with_base::lldb_r9w, x86_64_with_base::lldb_r9l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r10[] = { + x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r10d, + x86_64_with_base::lldb_r10w, x86_64_with_base::lldb_r10l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r11[] = { + x86_64_with_base::lldb_r11, x86_64_with_base::lldb_r11d, + x86_64_with_base::lldb_r11w, x86_64_with_base::lldb_r11l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r12[] = { + x86_64_with_base::lldb_r12, x86_64_with_base::lldb_r12d, + x86_64_with_base::lldb_r12w, x86_64_with_base::lldb_r12l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r13[] = { + x86_64_with_base::lldb_r13, x86_64_with_base::lldb_r13d, + x86_64_with_base::lldb_r13w, x86_64_with_base::lldb_r13l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r14[] = { + x86_64_with_base::lldb_r14, x86_64_with_base::lldb_r14d, + x86_64_with_base::lldb_r14w, x86_64_with_base::lldb_r14l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r15[] = { + x86_64_with_base::lldb_r15, x86_64_with_base::lldb_r15d, + x86_64_with_base::lldb_r15w, x86_64_with_base::lldb_r15l, + LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_fip[] = { + x86_64_with_base::lldb_fip, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_fdp[] = { + x86_64_with_base::lldb_fdp, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_fip[] = { + x86_64_with_base::lldb_fip, x86_64_with_base::lldb_fioff, + x86_64_with_base::lldb_fiseg, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_fdp[] = { + x86_64_with_base::lldb_fdp, x86_64_with_base::lldb_fooff, + x86_64_with_base::lldb_foseg, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st0_32[] = { + lldb_st0_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st1_32[] = { + lldb_st1_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st2_32[] = { + lldb_st2_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st3_32[] = { + lldb_st3_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st4_32[] = { + lldb_st4_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st5_32[] = { + lldb_st5_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st6_32[] = { + lldb_st6_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st7_32[] = { + lldb_st7_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st0_32[] = { + lldb_st0_i386, lldb_mm0_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st1_32[] = { + lldb_st1_i386, lldb_mm1_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st2_32[] = { + lldb_st2_i386, lldb_mm2_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st3_32[] = { + lldb_st3_i386, lldb_mm3_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st4_32[] = { + lldb_st4_i386, lldb_mm4_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st5_32[] = { + lldb_st5_i386, lldb_mm5_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st6_32[] = { + lldb_st6_i386, lldb_mm6_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st7_32[] = { + lldb_st7_i386, lldb_mm7_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st0_64[] = { + x86_64_with_base::lldb_st0, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st1_64[] = { + x86_64_with_base::lldb_st1, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st2_64[] = { + x86_64_with_base::lldb_st2, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st3_64[] = { + x86_64_with_base::lldb_st3, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st4_64[] = { + x86_64_with_base::lldb_st4, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st5_64[] = { + x86_64_with_base::lldb_st5, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st6_64[] = { + x86_64_with_base::lldb_st6, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st7_64[] = { + x86_64_with_base::lldb_st7, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st0_64[] = { + x86_64_with_base::lldb_st0, x86_64_with_base::lldb_mm0, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st1_64[] = { + x86_64_with_base::lldb_st1, x86_64_with_base::lldb_mm1, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st2_64[] = { + x86_64_with_base::lldb_st2, x86_64_with_base::lldb_mm2, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st3_64[] = { + x86_64_with_base::lldb_st3, x86_64_with_base::lldb_mm3, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st4_64[] = { + x86_64_with_base::lldb_st4, x86_64_with_base::lldb_mm4, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st5_64[] = { + x86_64_with_base::lldb_st5, x86_64_with_base::lldb_mm5, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st6_64[] = { + x86_64_with_base::lldb_st6, x86_64_with_base::lldb_mm6, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st7_64[] = { + x86_64_with_base::lldb_st7, x86_64_with_base::lldb_mm7, + LLDB_INVALID_REGNUM}; + +RegInfo &GetRegInfoShared(llvm::Triple::ArchType arch_type, bool with_base) { + static std::once_flag once_flag_x86, once_flag_x86_64, + once_flag_x86_64_with_base; + static RegInfo reg_info_x86, reg_info_x86_64, reg_info_x86_64_with_base, reg_info_invalid; + + switch (arch_type) { + case llvm::Triple::x86: + std::call_once(once_flag_x86, []() { + reg_info_x86.num_registers = k_num_registers_i386; + reg_info_x86.num_gpr_registers = k_num_gpr_registers_i386; + reg_info_x86.num_fpr_registers = k_num_fpr_registers_i386; + reg_info_x86.num_avx_registers = k_num_avx_registers_i386; + reg_info_x86.last_gpr = k_last_gpr_i386; + reg_info_x86.first_fpr = k_first_fpr_i386; + reg_info_x86.last_fpr = k_last_fpr_i386; + reg_info_x86.first_st = lldb_st0_i386; + reg_info_x86.last_st = lldb_st7_i386; + reg_info_x86.first_mm = lldb_mm0_i386; + reg_info_x86.last_mm = lldb_mm7_i386; + reg_info_x86.first_xmm = lldb_xmm0_i386; + reg_info_x86.last_xmm = lldb_xmm7_i386; + reg_info_x86.first_ymm = lldb_ymm0_i386; + reg_info_x86.last_ymm = lldb_ymm7_i386; + reg_info_x86.first_dr = lldb_dr0_i386; + reg_info_x86.gpr_flags = lldb_eflags_i386; + }); + + return reg_info_x86; + case llvm::Triple::x86_64: + if (with_base) { + std::call_once(once_flag_x86_64_with_base, []() { + reg_info_x86_64_with_base.num_registers = + x86_64_with_base::k_num_registers; + reg_info_x86_64_with_base.num_gpr_registers = + x86_64_with_base::k_num_gpr_registers; + reg_info_x86_64_with_base.num_fpr_registers = + x86_64_with_base::k_num_fpr_registers; + reg_info_x86_64_with_base.num_avx_registers = + x86_64_with_base::k_num_avx_registers; + reg_info_x86_64_with_base.last_gpr = x86_64_with_base::k_last_gpr; + reg_info_x86_64_with_base.first_fpr = x86_64_with_base::k_first_fpr; + reg_info_x86_64_with_base.last_fpr = x86_64_with_base::k_last_fpr; + reg_info_x86_64_with_base.first_st = x86_64_with_base::lldb_st0; + reg_info_x86_64_with_base.last_st = x86_64_with_base::lldb_st7; + reg_info_x86_64_with_base.first_mm = x86_64_with_base::lldb_mm0; + reg_info_x86_64_with_base.last_mm = x86_64_with_base::lldb_mm7; + reg_info_x86_64_with_base.first_xmm = x86_64_with_base::lldb_xmm0; + reg_info_x86_64_with_base.last_xmm = x86_64_with_base::lldb_xmm15; + reg_info_x86_64_with_base.first_ymm = x86_64_with_base::lldb_ymm0; + reg_info_x86_64_with_base.last_ymm = x86_64_with_base::lldb_ymm15; + reg_info_x86_64_with_base.first_dr = x86_64_with_base::lldb_dr0; + reg_info_x86_64_with_base.gpr_flags = x86_64_with_base::lldb_rflags; + }); + + return reg_info_x86_64_with_base; + } else { + std::call_once(once_flag_x86_64, []() { + reg_info_x86_64.num_registers = k_num_registers_x86_64; + reg_info_x86_64.num_gpr_registers = k_num_gpr_registers_x86_64; + reg_info_x86_64.num_fpr_registers = k_num_fpr_registers_x86_64; + reg_info_x86_64.num_avx_registers = k_num_avx_registers_x86_64; + reg_info_x86_64.last_gpr = k_last_gpr_x86_64; + reg_info_x86_64.first_fpr = k_first_fpr_x86_64; + reg_info_x86_64.last_fpr = k_last_fpr_x86_64; + reg_info_x86_64.first_st = lldb_st0_x86_64; + reg_info_x86_64.last_st = lldb_st7_x86_64; + reg_info_x86_64.first_mm = lldb_mm0_x86_64; + reg_info_x86_64.last_mm = lldb_mm7_x86_64; + reg_info_x86_64.first_xmm = lldb_xmm0_x86_64; + reg_info_x86_64.last_xmm = lldb_xmm15_x86_64; + reg_info_x86_64.first_ymm = lldb_ymm0_x86_64; + reg_info_x86_64.last_ymm = lldb_ymm15_x86_64; + reg_info_x86_64.first_dr = lldb_dr0_x86_64; + reg_info_x86_64.gpr_flags = lldb_rflags_x86_64; + }); + return reg_info_x86_64; + } + default: + assert(false && "Unhandled target architecture."); + return reg_info_invalid; + } +} + +} // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h new file mode 100644 index 000000000000..5e4406c1fa27 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h @@ -0,0 +1,142 @@ +//===-- RegisterInfos_x86_64_with_base_shared.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 +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Process/Utility/lldb-x86-register-enums.h" +#include <stdint.h> + +#ifndef lldb_RegisterInfos_x86_64_with_base_shared_h +#define lldb_RegisterInfos_x86_64_with_base_shared_h + +#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h" + +namespace lldb_private { + +struct RegisterInfos_x86_64_with_base_shared { + static uint32_t g_contained_eax[]; + static uint32_t g_contained_ebx[]; + static uint32_t g_contained_ecx[]; + static uint32_t g_contained_edx[]; + static uint32_t g_contained_edi[]; + static uint32_t g_contained_esi[]; + static uint32_t g_contained_ebp[]; + static uint32_t g_contained_esp[]; + + static uint32_t g_invalidate_eax[]; + static uint32_t g_invalidate_ebx[]; + static uint32_t g_invalidate_ecx[]; + static uint32_t g_invalidate_edx[]; + static uint32_t g_invalidate_edi[]; + static uint32_t g_invalidate_esi[]; + static uint32_t g_invalidate_ebp[]; + static uint32_t g_invalidate_esp[]; + + static uint32_t g_contained_rax[]; + static uint32_t g_contained_rbx[]; + static uint32_t g_contained_rcx[]; + static uint32_t g_contained_rdx[]; + static uint32_t g_contained_rdi[]; + static uint32_t g_contained_rsi[]; + static uint32_t g_contained_rbp[]; + static uint32_t g_contained_rsp[]; + static uint32_t g_contained_r8[]; + static uint32_t g_contained_r9[]; + static uint32_t g_contained_r10[]; + static uint32_t g_contained_r11[]; + static uint32_t g_contained_r12[]; + static uint32_t g_contained_r13[]; + static uint32_t g_contained_r14[]; + static uint32_t g_contained_r15[]; + + static uint32_t g_invalidate_rax[]; + static uint32_t g_invalidate_rbx[]; + static uint32_t g_invalidate_rcx[]; + static uint32_t g_invalidate_rdx[]; + static uint32_t g_invalidate_rdi[]; + static uint32_t g_invalidate_rsi[]; + static uint32_t g_invalidate_rbp[]; + static uint32_t g_invalidate_rsp[]; + static uint32_t g_invalidate_r8[]; + static uint32_t g_invalidate_r9[]; + static uint32_t g_invalidate_r10[]; + static uint32_t g_invalidate_r11[]; + static uint32_t g_invalidate_r12[]; + static uint32_t g_invalidate_r13[]; + 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[]; +}; + +struct RegInfo { + uint32_t num_registers; + uint32_t num_gpr_registers; + uint32_t num_fpr_registers; + uint32_t num_avx_registers; + + uint32_t last_gpr; + uint32_t first_fpr; + uint32_t last_fpr; + + uint32_t first_st; + uint32_t last_st; + uint32_t first_mm; + uint32_t last_mm; + uint32_t first_xmm; + uint32_t last_xmm; + uint32_t first_ymm; + uint32_t last_ymm; + + uint32_t first_dr; + uint32_t gpr_flags; +}; + +RegInfo &GetRegInfoShared(llvm::Triple::ArchType arch_type, bool with_base); + +} // namespace lldb_private + +#endif // ifndef lldb_RegisterInfos_x86_64_with_base_shared_h diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp new file mode 100644 index 000000000000..25cee369d7ee --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -0,0 +1,862 @@ +//===-- StopInfoMachException.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 "StopInfoMachException.h" + +#include "lldb/lldb-forward.h" + +#if defined(__APPLE__) +// Needed for the EXC_RESOURCE interpretation macros +#include <kern/exc_resource.h> +#endif + +#include "lldb/Breakpoint/Watchpoint.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" +#include <optional> + +using namespace lldb; +using namespace lldb_private; + +/// Information about a pointer-authentication related instruction. +struct PtrauthInstructionInfo { + bool IsAuthenticated; + bool IsLoad; + bool DoesBranch; +}; + +/// Get any pointer-authentication related information about the instruction +/// at address \p at_addr. +static std::optional<PtrauthInstructionInfo> +GetPtrauthInstructionInfo(Target &target, const ArchSpec &arch, + const Address &at_addr) { + const char *plugin_name = nullptr; + const char *flavor = nullptr; + AddressRange range_bounds(at_addr, 4); + const bool prefer_file_cache = true; + DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( + arch, plugin_name, flavor, target, range_bounds, prefer_file_cache); + if (!disassembler_sp) + return std::nullopt; + + InstructionList &insn_list = disassembler_sp->GetInstructionList(); + InstructionSP insn = insn_list.GetInstructionAtIndex(0); + if (!insn) + return std::nullopt; + + return PtrauthInstructionInfo{insn->IsAuthenticated(), insn->IsLoad(), + insn->DoesBranch()}; +} + +/// Describe the load address of \p addr using the format filename:line:col. +static void DescribeAddressBriefly(Stream &strm, const Address &addr, + Target &target) { + strm.Printf("at address=0x%" PRIx64, addr.GetLoadAddress(&target)); + StreamString s; + if (addr.GetDescription(s, target, eDescriptionLevelBrief)) + strm.Printf(" %s", s.GetString().data()); + strm.Printf(".\n"); +} + +bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext &exe_ctx) { + bool IsBreakpoint = m_value == 6; // EXC_BREAKPOINT + bool IsBadAccess = m_value == 1; // EXC_BAD_ACCESS + if (!IsBreakpoint && !IsBadAccess) + return false; + + // Check that we have a live process. + if (!exe_ctx.HasProcessScope() || !exe_ctx.HasThreadScope() || + !exe_ctx.HasTargetScope()) + return false; + + Thread &thread = *exe_ctx.GetThreadPtr(); + StackFrameSP current_frame = thread.GetStackFrameAtIndex(0); + if (!current_frame) + return false; + + Target &target = *exe_ctx.GetTargetPtr(); + Process &process = *exe_ctx.GetProcessPtr(); + const ArchSpec &arch = target.GetArchitecture(); + + // Check for a ptrauth-enabled target. + const bool ptrauth_enabled_target = + arch.GetCore() == ArchSpec::eCore_arm_arm64e; + if (!ptrauth_enabled_target) + return false; + + // Set up a stream we can write a diagnostic into. + StreamString strm; + auto emit_ptrauth_prologue = [&](uint64_t at_address) { + strm.Printf("EXC_BAD_ACCESS (code=%" PRIu64 ", address=0x%" PRIx64 ")\n", + m_exc_code, at_address); + strm.Printf("Note: Possible pointer authentication failure detected.\n"); + }; + + ABISP abi_sp = process.GetABI(); + assert(abi_sp && "Missing ABI info"); + + // Check if we have a "brk 0xc47x" trap, where the value that failed to + // authenticate is in x16. + Address current_address = current_frame->GetFrameCodeAddress(); + if (IsBreakpoint) { + RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); + if (!reg_ctx) + return false; + + const RegisterInfo *X16Info = reg_ctx->GetRegisterInfoByName("x16"); + RegisterValue X16Val; + if (!reg_ctx->ReadRegister(X16Info, X16Val)) + return false; + uint64_t bad_address = X16Val.GetAsUInt64(); + + uint64_t fixed_bad_address = abi_sp->FixCodeAddress(bad_address); + Address brk_address; + if (!target.ResolveLoadAddress(fixed_bad_address, brk_address)) + return false; + + auto brk_ptrauth_info = + GetPtrauthInstructionInfo(target, arch, current_address); + if (brk_ptrauth_info && brk_ptrauth_info->IsAuthenticated) { + emit_ptrauth_prologue(bad_address); + strm.Printf("Found value that failed to authenticate "); + DescribeAddressBriefly(strm, brk_address, target); + m_description = std::string(strm.GetString()); + return true; + } + return false; + } + + assert(IsBadAccess && "Handle EXC_BAD_ACCESS only after this point"); + + // Check that we have the "bad address" from an EXC_BAD_ACCESS. + if (m_exc_data_count < 2) + return false; + + // Ok, we know the Target is valid and that it describes a ptrauth-enabled + // device. Now, we need to determine whether this exception was caused by a + // ptrauth failure. + + uint64_t bad_address = m_exc_subcode; + uint64_t fixed_bad_address = abi_sp->FixCodeAddress(bad_address); + uint64_t current_pc = current_address.GetLoadAddress(&target); + + // Detect: LDRAA, LDRAB (Load Register, with pointer authentication). + // + // If an authenticated load results in an exception, the instruction at the + // current PC should be one of LDRAx. + if (bad_address != current_pc && fixed_bad_address != current_pc) { + auto ptrauth_info = + GetPtrauthInstructionInfo(target, arch, current_address); + if (ptrauth_info && ptrauth_info->IsAuthenticated && ptrauth_info->IsLoad) { + emit_ptrauth_prologue(bad_address); + strm.Printf("Found authenticated load instruction "); + DescribeAddressBriefly(strm, current_address, target); + m_description = std::string(strm.GetString()); + return true; + } + } + + // Detect: BLRAA, BLRAAZ, BLRAB, BLRABZ (Branch with Link to Register, with + // pointer authentication). + // + // TODO: Detect: BRAA, BRAAZ, BRAB, BRABZ (Branch to Register, with pointer + // authentication). At a minimum, this requires call site info support for + // indirect calls. + // + // If an authenticated call or tail call results in an exception, stripping + // the bad address should give the current PC, which points to the address + // we tried to branch to. + if (bad_address != current_pc && fixed_bad_address == current_pc) { + if (StackFrameSP parent_frame = thread.GetStackFrameAtIndex(1)) { + addr_t return_pc = + parent_frame->GetFrameCodeAddress().GetLoadAddress(&target); + Address blr_address; + if (!target.ResolveLoadAddress(return_pc - 4, blr_address)) + return false; + + auto blr_ptrauth_info = + GetPtrauthInstructionInfo(target, arch, blr_address); + if (blr_ptrauth_info && blr_ptrauth_info->IsAuthenticated && + blr_ptrauth_info->DoesBranch) { + emit_ptrauth_prologue(bad_address); + strm.Printf("Found authenticated indirect branch "); + DescribeAddressBriefly(strm, blr_address, target); + m_description = std::string(strm.GetString()); + return true; + } + } + } + + // TODO: Detect: RETAA, RETAB (Return from subroutine, with pointer + // authentication). + // + // Is there a motivating, non-malicious code snippet that corrupts LR? + + return false; +} + +const char *StopInfoMachException::GetDescription() { + if (!m_description.empty()) + return m_description.c_str(); + if (GetValue() == eStopReasonInvalid) + return "invalid stop reason!"; + + ExecutionContext exe_ctx(m_thread_wp.lock()); + Target *target = exe_ctx.GetTargetPtr(); + const llvm::Triple::ArchType cpu = + target ? target->GetArchitecture().GetMachine() + : llvm::Triple::UnknownArch; + + const char *exc_desc = nullptr; + const char *code_label = "code"; + const char *code_desc = nullptr; + const char *subcode_label = "subcode"; + const char *subcode_desc = nullptr; + +#if defined(__APPLE__) + char code_desc_buf[32]; + char subcode_desc_buf[32]; +#endif + + switch (m_value) { + case 1: // EXC_BAD_ACCESS + exc_desc = "EXC_BAD_ACCESS"; + subcode_label = "address"; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + switch (m_exc_code) { + case 0xd: + code_desc = "EXC_I386_GPFLT"; + m_exc_data_count = 1; + break; + } + break; + case llvm::Triple::arm: + case llvm::Triple::thumb: + switch (m_exc_code) { + case 0x101: + code_desc = "EXC_ARM_DA_ALIGN"; + break; + case 0x102: + code_desc = "EXC_ARM_DA_DEBUG"; + break; + } + break; + + case llvm::Triple::aarch64: + if (DeterminePtrauthFailure(exe_ctx)) + return m_description.c_str(); + break; + + default: + break; + } + break; + + case 2: // EXC_BAD_INSTRUCTION + exc_desc = "EXC_BAD_INSTRUCTION"; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + if (m_exc_code == 1) + code_desc = "EXC_I386_INVOP"; + break; + + case llvm::Triple::arm: + case llvm::Triple::thumb: + if (m_exc_code == 1) + code_desc = "EXC_ARM_UNDEFINED"; + break; + + default: + break; + } + break; + + case 3: // EXC_ARITHMETIC + exc_desc = "EXC_ARITHMETIC"; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + switch (m_exc_code) { + case 1: + code_desc = "EXC_I386_DIV"; + break; + case 2: + code_desc = "EXC_I386_INTO"; + break; + case 3: + code_desc = "EXC_I386_NOEXT"; + break; + case 4: + code_desc = "EXC_I386_EXTOVR"; + break; + case 5: + code_desc = "EXC_I386_EXTERR"; + break; + case 6: + code_desc = "EXC_I386_EMERR"; + break; + case 7: + code_desc = "EXC_I386_BOUND"; + break; + case 8: + code_desc = "EXC_I386_SSEEXTERR"; + break; + } + break; + + default: + break; + } + break; + + case 4: // EXC_EMULATION + exc_desc = "EXC_EMULATION"; + break; + + case 5: // EXC_SOFTWARE + exc_desc = "EXC_SOFTWARE"; + if (m_exc_code == 0x10003) { + subcode_desc = "EXC_SOFT_SIGNAL"; + subcode_label = "signo"; + } + break; + + case 6: // EXC_BREAKPOINT + { + exc_desc = "EXC_BREAKPOINT"; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + switch (m_exc_code) { + case 1: + code_desc = "EXC_I386_SGL"; + break; + case 2: + code_desc = "EXC_I386_BPT"; + break; + } + break; + + case llvm::Triple::arm: + case llvm::Triple::thumb: + switch (m_exc_code) { + case 0x101: + code_desc = "EXC_ARM_DA_ALIGN"; + break; + case 0x102: + code_desc = "EXC_ARM_DA_DEBUG"; + break; + case 1: + code_desc = "EXC_ARM_BREAKPOINT"; + break; + // FIXME temporary workaround, exc_code 0 does not really mean + // EXC_ARM_BREAKPOINT + case 0: + code_desc = "EXC_ARM_BREAKPOINT"; + break; + } + break; + + case llvm::Triple::aarch64: + if (DeterminePtrauthFailure(exe_ctx)) + return m_description.c_str(); + break; + + default: + break; + } + } break; + + case 7: + exc_desc = "EXC_SYSCALL"; + break; + + case 8: + exc_desc = "EXC_MACH_SYSCALL"; + break; + + case 9: + exc_desc = "EXC_RPC_ALERT"; + break; + + case 10: + exc_desc = "EXC_CRASH"; + break; + case 11: + exc_desc = "EXC_RESOURCE"; +#if defined(__APPLE__) + { + int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code); + + code_label = "limit"; + code_desc = code_desc_buf; + subcode_label = "observed"; + subcode_desc = subcode_desc_buf; + + switch (resource_type) { + case RESOURCE_TYPE_CPU: + exc_desc = + "EXC_RESOURCE (RESOURCE_TYPE_CPU: CPU usage monitor tripped)"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED( + m_exc_subcode)); + break; + case RESOURCE_TYPE_WAKEUPS: + exc_desc = "EXC_RESOURCE (RESOURCE_TYPE_WAKEUPS: idle wakeups monitor " + "tripped)"; + snprintf( + code_desc_buf, sizeof(code_desc_buf), "%d w/s", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED( + m_exc_subcode)); + break; + case RESOURCE_TYPE_MEMORY: + exc_desc = "EXC_RESOURCE (RESOURCE_TYPE_MEMORY: high watermark memory " + "limit exceeded)"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", + (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code)); + subcode_desc = nullptr; + subcode_label = nullptr; + break; +#if defined(RESOURCE_TYPE_IO) + // RESOURCE_TYPE_IO is introduced in macOS SDK 10.12. + case RESOURCE_TYPE_IO: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", + (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB", + (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode)); + ; + break; +#endif + } + } +#endif + break; + case 12: + exc_desc = "EXC_GUARD"; + break; + } + + StreamString strm; + + if (exc_desc) + strm.PutCString(exc_desc); + else + strm.Printf("EXC_??? (%" PRIu64 ")", m_value); + + if (m_exc_data_count >= 1) { + if (code_desc) + strm.Printf(" (%s=%s", code_label, code_desc); + else + strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code); + } + + if (m_exc_data_count >= 2) { + if (subcode_label && subcode_desc) + strm.Printf(", %s=%s", subcode_label, subcode_desc); + else if (subcode_label) + strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode); + } + + if (m_exc_data_count > 0) + strm.PutChar(')'); + + m_description = std::string(strm.GetString()); + return m_description.c_str(); +} + +static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target, + uint32_t exc_data_count, + uint64_t exc_sub_code, + uint64_t exc_sub_sub_code) { + // Try hardware watchpoint. + if (target) { + // The exc_sub_code indicates the data break address. + WatchpointResourceSP wp_rsrc_sp = + target->GetProcessSP()->GetWatchpointResourceList().FindByAddress( + (addr_t)exc_sub_code); + if (wp_rsrc_sp && wp_rsrc_sp->GetNumberOfConstituents() > 0) { + return StopInfo::CreateStopReasonWithWatchpointID( + thread, wp_rsrc_sp->GetConstituentAtIndex(0)->GetID()); + } + } + + // Try hardware breakpoint. + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + // The exc_sub_code indicates the data break address. + lldb::BreakpointSiteSP bp_sp = + process_sp->GetBreakpointSiteList().FindByAddress( + (lldb::addr_t)exc_sub_code); + if (bp_sp && bp_sp->IsEnabled()) { + return StopInfo::CreateStopReasonWithBreakpointSiteID(thread, + bp_sp->GetID()); + } + } + + return nullptr; +} + +#if defined(__APPLE__) +const char * +StopInfoMachException::MachException::Name(exception_type_t exc_type) { + switch (exc_type) { + case EXC_BAD_ACCESS: + return "EXC_BAD_ACCESS"; + case EXC_BAD_INSTRUCTION: + return "EXC_BAD_INSTRUCTION"; + case EXC_ARITHMETIC: + return "EXC_ARITHMETIC"; + case EXC_EMULATION: + return "EXC_EMULATION"; + case EXC_SOFTWARE: + return "EXC_SOFTWARE"; + case EXC_BREAKPOINT: + return "EXC_BREAKPOINT"; + case EXC_SYSCALL: + return "EXC_SYSCALL"; + case EXC_MACH_SYSCALL: + return "EXC_MACH_SYSCALL"; + case EXC_RPC_ALERT: + return "EXC_RPC_ALERT"; +#ifdef EXC_CRASH + case EXC_CRASH: + return "EXC_CRASH"; +#endif + case EXC_RESOURCE: + return "EXC_RESOURCE"; +#ifdef EXC_GUARD + case EXC_GUARD: + return "EXC_GUARD"; +#endif +#ifdef EXC_CORPSE_NOTIFY + case EXC_CORPSE_NOTIFY: + return "EXC_CORPSE_NOTIFY"; +#endif +#ifdef EXC_CORPSE_VARIANT_BIT + case EXC_CORPSE_VARIANT_BIT: + return "EXC_CORPSE_VARIANT_BIT"; +#endif + default: + break; + } + return NULL; +} + +std::optional<exception_type_t> +StopInfoMachException::MachException::ExceptionCode(const char *name) { + return llvm::StringSwitch<std::optional<exception_type_t>>(name) + .Case("EXC_BAD_ACCESS", EXC_BAD_ACCESS) + .Case("EXC_BAD_INSTRUCTION", EXC_BAD_INSTRUCTION) + .Case("EXC_ARITHMETIC", EXC_ARITHMETIC) + .Case("EXC_EMULATION", EXC_EMULATION) + .Case("EXC_SOFTWARE", EXC_SOFTWARE) + .Case("EXC_BREAKPOINT", EXC_BREAKPOINT) + .Case("EXC_SYSCALL", EXC_SYSCALL) + .Case("EXC_MACH_SYSCALL", EXC_MACH_SYSCALL) + .Case("EXC_RPC_ALERT", EXC_RPC_ALERT) +#ifdef EXC_CRASH + .Case("EXC_CRASH", EXC_CRASH) +#endif + .Case("EXC_RESOURCE", EXC_RESOURCE) +#ifdef EXC_GUARD + .Case("EXC_GUARD", EXC_GUARD) +#endif +#ifdef EXC_CORPSE_NOTIFY + .Case("EXC_CORPSE_NOTIFY", EXC_CORPSE_NOTIFY) +#endif + .Default(std::nullopt); +} +#endif + +StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( + Thread &thread, uint32_t exc_type, uint32_t exc_data_count, + uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, + bool pc_already_adjusted, bool adjust_pc_if_needed) { + if (exc_type == 0) + return StopInfoSP(); + + bool not_stepping_but_got_singlestep_exception = false; + uint32_t pc_decrement = 0; + ExecutionContext exe_ctx(thread.shared_from_this()); + Target *target = exe_ctx.GetTargetPtr(); + const llvm::Triple::ArchType cpu = + target ? target->GetArchitecture().GetMachine() + : llvm::Triple::UnknownArch; + + switch (exc_type) { + case 1: // EXC_BAD_ACCESS + case 2: // EXC_BAD_INSTRUCTION + case 3: // EXC_ARITHMETIC + case 4: // EXC_EMULATION + break; + + case 5: // EXC_SOFTWARE + if (exc_code == 0x10003) // EXC_SOFT_SIGNAL + { + if (exc_sub_code == 5) { + // On MacOSX, a SIGTRAP can signify that a process has called exec, + // so we should check with our dynamic loader to verify. + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader(); + if (dynamic_loader && dynamic_loader->ProcessDidExec()) { + // The program was re-exec'ed + return StopInfo::CreateStopReasonWithExec(thread); + } + } + } + return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code); + } + break; + + case 6: // EXC_BREAKPOINT + { + bool is_actual_breakpoint = false; + bool is_trace_if_actual_breakpoint_missing = false; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + if (exc_code == 1) // EXC_I386_SGL + { + if (!exc_sub_code) { + // This looks like a plain trap. + // Have to check if there is a breakpoint here as well. When you + // single-step onto a trap, the single step stops you not to trap. + // Since we also do that check below, let's just use that logic. + is_actual_breakpoint = true; + is_trace_if_actual_breakpoint_missing = true; + } else { + if (StopInfoSP stop_info = + GetStopInfoForHardwareBP(thread, target, exc_data_count, + exc_sub_code, exc_sub_sub_code)) + return stop_info; + } + } else if (exc_code == 2 || // EXC_I386_BPT + exc_code == 3) // EXC_I386_BPTFLT + { + // KDP returns EXC_I386_BPTFLT for trace breakpoints + if (exc_code == 3) + is_trace_if_actual_breakpoint_missing = true; + + is_actual_breakpoint = true; + if (!pc_already_adjusted) + pc_decrement = 1; + } + break; + + case llvm::Triple::arm: + case llvm::Triple::thumb: + if (exc_code == 0x102) // EXC_ARM_DA_DEBUG + { + // LWP_TODO: We need to find the WatchpointResource that matches + // the address, and evaluate its Watchpoints. + + // It's a watchpoint, then, if the exc_sub_code indicates a + // known/enabled data break address from our watchpoint list. + lldb::WatchpointSP wp_sp; + if (target) + wp_sp = target->GetWatchpointList().FindByAddress( + (lldb::addr_t)exc_sub_code); + if (wp_sp && wp_sp->IsEnabled()) { + return StopInfo::CreateStopReasonWithWatchpointID(thread, + wp_sp->GetID()); + } else { + is_actual_breakpoint = true; + is_trace_if_actual_breakpoint_missing = true; + } + } else if (exc_code == 1) // EXC_ARM_BREAKPOINT + { + is_actual_breakpoint = true; + is_trace_if_actual_breakpoint_missing = true; + } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel + // is currently returning this so accept it + // as indicating a breakpoint until the + // kernel is fixed + { + is_actual_breakpoint = true; + is_trace_if_actual_breakpoint_missing = true; + } + break; + + case llvm::Triple::aarch64_32: + case llvm::Triple::aarch64: { + // xnu describes three things with type EXC_BREAKPOINT: + // + // exc_code 0x102 [EXC_ARM_DA_DEBUG], exc_sub_code addr-of-insn + // Watchpoint access. exc_sub_code is the address of the + // instruction which trigged the watchpoint trap. + // debugserver may add the watchpoint number that was triggered + // in exc_sub_sub_code. + // + // exc_code 1 [EXC_ARM_BREAKPOINT], exc_sub_code 0 + // Instruction step has completed. + // + // exc_code 1 [EXC_ARM_BREAKPOINT], exc_sub_code address-of-instruction + // Software breakpoint instruction executed. + + if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT + { + // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 + // is set + is_actual_breakpoint = true; + is_trace_if_actual_breakpoint_missing = true; + if (thread.GetTemporaryResumeState() != eStateStepping) + not_stepping_but_got_singlestep_exception = true; + } + if (exc_code == 0x102) // EXC_ARM_DA_DEBUG + { + // LWP_TODO: We need to find the WatchpointResource that matches + // the address, and evaluate its Watchpoints. + + // It's a watchpoint, then, if the exc_sub_code indicates a + // known/enabled data break address from our watchpoint list. + lldb::WatchpointSP wp_sp; + if (target) + wp_sp = target->GetWatchpointList().FindByAddress( + (lldb::addr_t)exc_sub_code); + if (wp_sp && wp_sp->IsEnabled()) { + return StopInfo::CreateStopReasonWithWatchpointID(thread, + wp_sp->GetID()); + } + // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as + // EXC_BAD_ACCESS + if (thread.GetTemporaryResumeState() == eStateStepping) + return StopInfo::CreateStopReasonToTrace(thread); + } + // It looks like exc_sub_code has the 4 bytes of the instruction that + // triggered the exception, i.e. our breakpoint opcode + is_actual_breakpoint = exc_code == 1; + break; + } + + default: + break; + } + + if (is_actual_breakpoint) { + RegisterContextSP reg_ctx_sp(thread.GetRegisterContext()); + addr_t pc = reg_ctx_sp->GetPC() - pc_decrement; + + ProcessSP process_sp(thread.CalculateProcess()); + + lldb::BreakpointSiteSP bp_site_sp; + if (process_sp) + bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc); + if (bp_site_sp && bp_site_sp->IsEnabled()) { + // Update the PC if we were asked to do so, but only do so if we find + // a breakpoint that we know about cause this could be a trap + // instruction in the code + if (pc_decrement > 0 && adjust_pc_if_needed) + reg_ctx_sp->SetPC(pc); + + // If the breakpoint is for this thread, then we'll report the hit, + // but if it is for another thread, we can just report no reason. We + // don't need to worry about stepping over the breakpoint here, that + // will be taken care of when the thread resumes and notices that + // there's a breakpoint under the pc. If we have an operating system + // plug-in, we might have set a thread specific breakpoint using the + // operating system thread ID, so we can't make any assumptions about + // the thread ID so we must always report the breakpoint regardless + // of the thread. + if (bp_site_sp->ValidForThisThread(thread) || + thread.GetProcess()->GetOperatingSystem() != nullptr) + return StopInfo::CreateStopReasonWithBreakpointSiteID( + thread, bp_site_sp->GetID()); + else if (is_trace_if_actual_breakpoint_missing) + return StopInfo::CreateStopReasonToTrace(thread); + else + return StopInfoSP(); + } + + // Don't call this a trace if we weren't single stepping this thread. + if (is_trace_if_actual_breakpoint_missing && + thread.GetTemporaryResumeState() == eStateStepping) { + return StopInfo::CreateStopReasonToTrace(thread); + } + } + } break; + + case 7: // EXC_SYSCALL + case 8: // EXC_MACH_SYSCALL + case 9: // EXC_RPC_ALERT + case 10: // EXC_CRASH + break; + } + + return std::make_shared<StopInfoMachException>( + thread, exc_type, exc_data_count, exc_code, exc_sub_code, + not_stepping_but_got_singlestep_exception); +} + +// Detect an unusual situation on Darwin where: +// +// 0. We did an instruction-step before this. +// 1. We have a hardware breakpoint or watchpoint set. +// 2. We resumed the process, but not with an instruction-step. +// 3. The thread gets an "instruction-step completed" mach exception. +// 4. The pc has not advanced - it is the same as before. +// +// This method returns true for that combination of events. +bool StopInfoMachException::WasContinueInterrupted(Thread &thread) { + Log *log = GetLog(LLDBLog::Step); + + // We got an instruction-step completed mach exception but we were not + // doing an instruction step on this thread. + if (!m_not_stepping_but_got_singlestep_exception) + return false; + + RegisterContextSP reg_ctx_sp(thread.GetRegisterContext()); + std::optional<addr_t> prev_pc = thread.GetPreviousFrameZeroPC(); + if (!reg_ctx_sp || !prev_pc) + return false; + + // The previous pc value and current pc value are the same. + if (*prev_pc != reg_ctx_sp->GetPC()) + return false; + + // We have a watchpoint -- this is the kernel bug. + ProcessSP process_sp = thread.GetProcess(); + if (process_sp->GetWatchpointResourceList().GetSize()) { + LLDB_LOGF(log, + "Thread stopped with insn-step completed mach exception but " + "thread was not stepping; there is a hardware watchpoint set."); + return true; + } + + // We have a hardware breakpoint -- this is the kernel bug. + auto &bp_site_list = process_sp->GetBreakpointSiteList(); + for (auto &site : bp_site_list.Sites()) { + if (site->IsHardware() && site->IsEnabled()) { + LLDB_LOGF(log, + "Thread stopped with insn-step completed mach exception but " + "thread was not stepping; there is a hardware breakpoint set."); + return true; + } + } + + return false; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.h new file mode 100644 index 000000000000..c612ac400b4c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.h @@ -0,0 +1,76 @@ +//===-- StopInfoMachException.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_STOPINFOMACHEXCEPTION_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H + +#include <optional> +#include <string> + +#include "lldb/Target/StopInfo.h" + +#if defined(__APPLE__) +// Needed for the EXC_* defines +#include <mach/exception.h> +#endif + +namespace lldb_private { + +class StopInfoMachException : public StopInfo { + /// Determine the pointer-authentication related failure that caused this + /// exception. Returns true and fills out the failure description if there + /// is auth-related failure, and returns false otherwise. + bool DeterminePtrauthFailure(ExecutionContext &exe_ctx); + +public: + // Constructors and Destructors + StopInfoMachException(Thread &thread, uint32_t exc_type, + uint32_t exc_data_count, uint64_t exc_code, + uint64_t exc_subcode, + bool not_stepping_but_got_singlestep_exception) + : StopInfo(thread, exc_type), m_exc_data_count(exc_data_count), + m_exc_code(exc_code), m_exc_subcode(exc_subcode), + m_not_stepping_but_got_singlestep_exception( + not_stepping_but_got_singlestep_exception) {} + + ~StopInfoMachException() override = default; + + lldb::StopReason GetStopReason() const override { + return lldb::eStopReasonException; + } + + const char *GetDescription() override; + +#if defined(__APPLE__) + struct MachException { + static const char *Name(exception_type_t exc_type); + static std::optional<exception_type_t> ExceptionCode(const char *name); + }; +#endif + + // Since some mach exceptions will be reported as breakpoints, signals, + // or trace, we use this static accessor which will translate the mach + // exception into the correct StopInfo. + static lldb::StopInfoSP CreateStopReasonWithMachException( + Thread &thread, uint32_t exc_type, uint32_t exc_data_count, + uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, + bool pc_already_adjusted = true, bool adjust_pc_if_needed = false); + + bool WasContinueInterrupted(Thread &thread) override; + +protected: + uint32_t m_exc_data_count; + uint64_t m_exc_code; + uint64_t m_exc_subcode; + + bool m_not_stepping_but_got_singlestep_exception; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp new file mode 100644 index 000000000000..89ecc757a68f --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp @@ -0,0 +1,98 @@ +//===-- ThreadMemory.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 "Plugins/Process/Utility/ThreadMemory.h" + +#include "Plugins/Process/Utility/RegisterContextThreadMemory.h" +#include "lldb/Target/OperatingSystem.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/Unwind.h" + +#include <memory> + +using namespace lldb; +using namespace lldb_private; + +ThreadMemory::ThreadMemory(Process &process, tid_t tid, + const ValueObjectSP &thread_info_valobj_sp) + : Thread(process, tid), m_backing_thread_sp(), + m_thread_info_valobj_sp(thread_info_valobj_sp), m_name(), m_queue(), + m_register_data_addr(LLDB_INVALID_ADDRESS) {} + +ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid, + llvm::StringRef name, llvm::StringRef queue, + lldb::addr_t register_data_addr) + : Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(), + m_name(std::string(name)), m_queue(std::string(queue)), + m_register_data_addr(register_data_addr) {} + +ThreadMemory::~ThreadMemory() { DestroyThread(); } + +void ThreadMemory::WillResume(StateType resume_state) { + if (m_backing_thread_sp) + m_backing_thread_sp->WillResume(resume_state); +} + +void ThreadMemory::ClearStackFrames() { + if (m_backing_thread_sp) + m_backing_thread_sp->ClearStackFrames(); + Thread::ClearStackFrames(); +} + +RegisterContextSP ThreadMemory::GetRegisterContext() { + if (!m_reg_context_sp) + m_reg_context_sp = std::make_shared<RegisterContextThreadMemory>( + *this, m_register_data_addr); + return m_reg_context_sp; +} + +RegisterContextSP +ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) { + uint32_t concrete_frame_idx = 0; + + if (frame) + concrete_frame_idx = frame->GetConcreteFrameIndex(); + + if (concrete_frame_idx == 0) + return GetRegisterContext(); + return GetUnwinder().CreateRegisterContextForFrame(frame); +} + +bool ThreadMemory::CalculateStopInfo() { + if (m_backing_thread_sp) { + lldb::StopInfoSP backing_stop_info_sp( + m_backing_thread_sp->GetPrivateStopInfo()); + if (backing_stop_info_sp && + backing_stop_info_sp->IsValidForOperatingSystemThread(*this)) { + backing_stop_info_sp->SetThread(shared_from_this()); + SetStopInfo(backing_stop_info_sp); + return true; + } + } else { + ProcessSP process_sp(GetProcess()); + + if (process_sp) { + OperatingSystem *os = process_sp->GetOperatingSystem(); + if (os) { + SetStopInfo(os->CreateThreadStopReason(this)); + return true; + } + } + } + return false; +} + +void ThreadMemory::RefreshStateAfterStop() { + if (m_backing_thread_sp) + return m_backing_thread_sp->RefreshStateAfterStop(); + + if (m_reg_context_sp) + m_reg_context_sp->InvalidateAllRegisters(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ThreadMemory.h new file mode 100644 index 000000000000..d124f5780ea9 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ThreadMemory.h @@ -0,0 +1,107 @@ +//===-- ThreadMemory.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_THREADMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H + +#include <string> + +#include "lldb/Target/Thread.h" + +class ThreadMemory : public lldb_private::Thread { +public: + ThreadMemory(lldb_private::Process &process, lldb::tid_t tid, + const lldb::ValueObjectSP &thread_info_valobj_sp); + + ThreadMemory(lldb_private::Process &process, lldb::tid_t tid, + llvm::StringRef name, llvm::StringRef queue, + lldb::addr_t register_data_addr); + + ~ThreadMemory() override; + + lldb::RegisterContextSP GetRegisterContext() override; + + lldb::RegisterContextSP + CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; + + bool CalculateStopInfo() override; + + const char *GetInfo() override { + if (m_backing_thread_sp) + m_backing_thread_sp->GetInfo(); + return nullptr; + } + + const char *GetName() override { + if (!m_name.empty()) + return m_name.c_str(); + if (m_backing_thread_sp) + m_backing_thread_sp->GetName(); + return nullptr; + } + + const char *GetQueueName() override { + if (!m_queue.empty()) + return m_queue.c_str(); + if (m_backing_thread_sp) + m_backing_thread_sp->GetQueueName(); + return nullptr; + } + + void WillResume(lldb::StateType resume_state) override; + + void DidResume() override { + if (m_backing_thread_sp) + m_backing_thread_sp->DidResume(); + } + + lldb::user_id_t GetProtocolID() const override { + if (m_backing_thread_sp) + return m_backing_thread_sp->GetProtocolID(); + return Thread::GetProtocolID(); + } + + void RefreshStateAfterStop() override; + + lldb::ValueObjectSP &GetValueObject() { return m_thread_info_valobj_sp; } + + void ClearStackFrames() override; + + void ClearBackingThread() override { m_backing_thread_sp.reset(); } + + bool SetBackingThread(const lldb::ThreadSP &thread_sp) override { + // printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(), + // thread_sp->GetID()); + m_backing_thread_sp = thread_sp; + return (bool)thread_sp; + } + + lldb::ThreadSP GetBackingThread() const override { + return m_backing_thread_sp; + } + +protected: + bool IsOperatingSystemPluginThread() const override { return true; } + + // If this memory thread is actually represented by a thread from the + // lldb_private::Process subclass, then fill in the thread here and + // all APIs will be routed through this thread object. If m_backing_thread_sp + // is empty, then this thread is simply in memory with no representation + // through the process plug-in. + lldb::ThreadSP m_backing_thread_sp; + lldb::ValueObjectSP m_thread_info_valobj_sp; + std::string m_name; + std::string m_queue; + lldb::addr_t m_register_data_addr; + +private: + ThreadMemory(const ThreadMemory &) = delete; + const ThreadMemory &operator=(const ThreadMemory &) = delete; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h new file mode 100644 index 000000000000..8f0eed4f02c9 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h @@ -0,0 +1,199 @@ +//===-- lldb-arm-register-enums.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_LLDB_ARM_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H + +namespace lldb_private { +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all ARM registers. +enum { + k_first_gpr_arm = 0, + gpr_r0_arm = k_first_gpr_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_r13_arm, + gpr_sp_arm = gpr_r13_arm, + gpr_r14_arm, + gpr_lr_arm = gpr_r14_arm, + gpr_r15_arm, + gpr_pc_arm = gpr_r15_arm, + gpr_cpsr_arm, + + k_last_gpr_arm = gpr_cpsr_arm, + + k_first_fpr_arm, + fpu_s0_arm = k_first_fpr_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, + k_last_fpr_arm = fpu_q15_arm, + exc_exception_arm, + exc_fsr_arm, + exc_far_arm, + + dbg_bvr0_arm, + dbg_bvr1_arm, + dbg_bvr2_arm, + dbg_bvr3_arm, + dbg_bvr4_arm, + dbg_bvr5_arm, + dbg_bvr6_arm, + dbg_bvr7_arm, + dbg_bvr8_arm, + dbg_bvr9_arm, + dbg_bvr10_arm, + dbg_bvr11_arm, + dbg_bvr12_arm, + dbg_bvr13_arm, + dbg_bvr14_arm, + dbg_bvr15_arm, + dbg_bcr0_arm, + dbg_bcr1_arm, + dbg_bcr2_arm, + dbg_bcr3_arm, + dbg_bcr4_arm, + dbg_bcr5_arm, + dbg_bcr6_arm, + dbg_bcr7_arm, + dbg_bcr8_arm, + dbg_bcr9_arm, + dbg_bcr10_arm, + dbg_bcr11_arm, + dbg_bcr12_arm, + dbg_bcr13_arm, + dbg_bcr14_arm, + dbg_bcr15_arm, + dbg_wvr0_arm, + dbg_wvr1_arm, + dbg_wvr2_arm, + dbg_wvr3_arm, + dbg_wvr4_arm, + dbg_wvr5_arm, + dbg_wvr6_arm, + dbg_wvr7_arm, + dbg_wvr8_arm, + dbg_wvr9_arm, + dbg_wvr10_arm, + dbg_wvr11_arm, + dbg_wvr12_arm, + dbg_wvr13_arm, + dbg_wvr14_arm, + dbg_wvr15_arm, + dbg_wcr0_arm, + dbg_wcr1_arm, + dbg_wcr2_arm, + dbg_wcr3_arm, + dbg_wcr4_arm, + dbg_wcr5_arm, + dbg_wcr6_arm, + dbg_wcr7_arm, + dbg_wcr8_arm, + dbg_wcr9_arm, + dbg_wcr10_arm, + dbg_wcr11_arm, + dbg_wcr12_arm, + dbg_wcr13_arm, + dbg_wcr14_arm, + dbg_wcr15_arm, + + k_num_registers_arm, + k_num_gpr_registers_arm = k_last_gpr_arm - k_first_gpr_arm + 1, + k_num_fpr_registers_arm = k_last_fpr_arm - k_first_fpr_arm + 1 +}; +} + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h new file mode 100644 index 000000000000..39d47b8801cc --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h @@ -0,0 +1,264 @@ +//===-- lldb-arm64-register-enums.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_LLDB_ARM64_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H + +namespace lldb_private { +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all ARM64 registers. +enum { + k_first_gpr_arm64, + gpr_x0_arm64 = k_first_gpr_arm64, + gpr_x1_arm64, + gpr_x2_arm64, + gpr_x3_arm64, + gpr_x4_arm64, + gpr_x5_arm64, + gpr_x6_arm64, + gpr_x7_arm64, + gpr_x8_arm64, + gpr_x9_arm64, + gpr_x10_arm64, + gpr_x11_arm64, + gpr_x12_arm64, + gpr_x13_arm64, + gpr_x14_arm64, + gpr_x15_arm64, + gpr_x16_arm64, + gpr_x17_arm64, + gpr_x18_arm64, + gpr_x19_arm64, + gpr_x20_arm64, + gpr_x21_arm64, + gpr_x22_arm64, + gpr_x23_arm64, + gpr_x24_arm64, + gpr_x25_arm64, + gpr_x26_arm64, + gpr_x27_arm64, + gpr_x28_arm64, + gpr_fp_arm64, + gpr_lr_arm64, + gpr_sp_arm64, + gpr_pc_arm64, + gpr_cpsr_arm64, + + gpr_w0_arm64, + gpr_w1_arm64, + gpr_w2_arm64, + gpr_w3_arm64, + gpr_w4_arm64, + gpr_w5_arm64, + gpr_w6_arm64, + gpr_w7_arm64, + gpr_w8_arm64, + gpr_w9_arm64, + gpr_w10_arm64, + gpr_w11_arm64, + gpr_w12_arm64, + gpr_w13_arm64, + gpr_w14_arm64, + gpr_w15_arm64, + gpr_w16_arm64, + gpr_w17_arm64, + gpr_w18_arm64, + gpr_w19_arm64, + gpr_w20_arm64, + gpr_w21_arm64, + gpr_w22_arm64, + gpr_w23_arm64, + gpr_w24_arm64, + gpr_w25_arm64, + gpr_w26_arm64, + gpr_w27_arm64, + gpr_w28_arm64, + + k_last_gpr_arm64 = gpr_w28_arm64, + + k_first_fpr_arm64, + fpu_v0_arm64 = k_first_fpr_arm64, + fpu_v1_arm64, + fpu_v2_arm64, + fpu_v3_arm64, + fpu_v4_arm64, + fpu_v5_arm64, + fpu_v6_arm64, + fpu_v7_arm64, + fpu_v8_arm64, + fpu_v9_arm64, + fpu_v10_arm64, + fpu_v11_arm64, + fpu_v12_arm64, + fpu_v13_arm64, + fpu_v14_arm64, + fpu_v15_arm64, + fpu_v16_arm64, + fpu_v17_arm64, + fpu_v18_arm64, + fpu_v19_arm64, + fpu_v20_arm64, + fpu_v21_arm64, + fpu_v22_arm64, + fpu_v23_arm64, + fpu_v24_arm64, + fpu_v25_arm64, + fpu_v26_arm64, + fpu_v27_arm64, + fpu_v28_arm64, + fpu_v29_arm64, + fpu_v30_arm64, + fpu_v31_arm64, + + fpu_s0_arm64, + fpu_s1_arm64, + fpu_s2_arm64, + fpu_s3_arm64, + fpu_s4_arm64, + fpu_s5_arm64, + fpu_s6_arm64, + fpu_s7_arm64, + fpu_s8_arm64, + fpu_s9_arm64, + fpu_s10_arm64, + fpu_s11_arm64, + fpu_s12_arm64, + fpu_s13_arm64, + fpu_s14_arm64, + fpu_s15_arm64, + fpu_s16_arm64, + fpu_s17_arm64, + fpu_s18_arm64, + fpu_s19_arm64, + fpu_s20_arm64, + fpu_s21_arm64, + fpu_s22_arm64, + fpu_s23_arm64, + fpu_s24_arm64, + fpu_s25_arm64, + fpu_s26_arm64, + fpu_s27_arm64, + fpu_s28_arm64, + fpu_s29_arm64, + fpu_s30_arm64, + fpu_s31_arm64, + + fpu_d0_arm64, + fpu_d1_arm64, + fpu_d2_arm64, + fpu_d3_arm64, + fpu_d4_arm64, + fpu_d5_arm64, + fpu_d6_arm64, + fpu_d7_arm64, + fpu_d8_arm64, + fpu_d9_arm64, + fpu_d10_arm64, + fpu_d11_arm64, + fpu_d12_arm64, + fpu_d13_arm64, + fpu_d14_arm64, + fpu_d15_arm64, + fpu_d16_arm64, + fpu_d17_arm64, + fpu_d18_arm64, + fpu_d19_arm64, + fpu_d20_arm64, + fpu_d21_arm64, + fpu_d22_arm64, + fpu_d23_arm64, + fpu_d24_arm64, + fpu_d25_arm64, + fpu_d26_arm64, + fpu_d27_arm64, + fpu_d28_arm64, + fpu_d29_arm64, + fpu_d30_arm64, + fpu_d31_arm64, + + fpu_fpsr_arm64, + fpu_fpcr_arm64, + k_last_fpr_arm64 = fpu_fpcr_arm64, + + exc_far_arm64, + exc_esr_arm64, + exc_exception_arm64, + + dbg_bvr0_arm64, + dbg_bvr1_arm64, + dbg_bvr2_arm64, + dbg_bvr3_arm64, + dbg_bvr4_arm64, + dbg_bvr5_arm64, + dbg_bvr6_arm64, + dbg_bvr7_arm64, + dbg_bvr8_arm64, + dbg_bvr9_arm64, + dbg_bvr10_arm64, + dbg_bvr11_arm64, + dbg_bvr12_arm64, + dbg_bvr13_arm64, + dbg_bvr14_arm64, + dbg_bvr15_arm64, + dbg_bcr0_arm64, + dbg_bcr1_arm64, + dbg_bcr2_arm64, + dbg_bcr3_arm64, + dbg_bcr4_arm64, + dbg_bcr5_arm64, + dbg_bcr6_arm64, + dbg_bcr7_arm64, + dbg_bcr8_arm64, + dbg_bcr9_arm64, + dbg_bcr10_arm64, + dbg_bcr11_arm64, + dbg_bcr12_arm64, + dbg_bcr13_arm64, + dbg_bcr14_arm64, + dbg_bcr15_arm64, + dbg_wvr0_arm64, + dbg_wvr1_arm64, + dbg_wvr2_arm64, + dbg_wvr3_arm64, + dbg_wvr4_arm64, + dbg_wvr5_arm64, + dbg_wvr6_arm64, + dbg_wvr7_arm64, + dbg_wvr8_arm64, + dbg_wvr9_arm64, + dbg_wvr10_arm64, + dbg_wvr11_arm64, + dbg_wvr12_arm64, + dbg_wvr13_arm64, + dbg_wvr14_arm64, + dbg_wvr15_arm64, + dbg_wcr0_arm64, + dbg_wcr1_arm64, + dbg_wcr2_arm64, + dbg_wcr3_arm64, + dbg_wcr4_arm64, + dbg_wcr5_arm64, + dbg_wcr6_arm64, + dbg_wcr7_arm64, + dbg_wcr8_arm64, + dbg_wcr9_arm64, + dbg_wcr10_arm64, + dbg_wcr11_arm64, + dbg_wcr12_arm64, + dbg_wcr13_arm64, + dbg_wcr14_arm64, + dbg_wcr15_arm64, + + k_num_registers_arm64, + k_num_gpr_registers_arm64 = k_last_gpr_arm64 - k_first_gpr_arm64 + 1, + k_num_fpr_registers_arm64 = k_last_fpr_arm64 - k_first_fpr_arm64 + 1 +}; +} + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-loongarch-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-loongarch-register-enums.h new file mode 100644 index 000000000000..f55c807f86c0 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-loongarch-register-enums.h @@ -0,0 +1,178 @@ +//===-- lldb-loongarch-register-enums.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_LLDB_LOONGARCH_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_LOONGARCH_REGISTER_ENUMS_H + +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all loongarch registers. +enum { + // The same order as user_regs_struct in <asm/ptrace.h> + // note: these enum values are used as byte_offset + gpr_first_loongarch = 0, + gpr_r0_loongarch = gpr_first_loongarch, + gpr_r1_loongarch, + gpr_r2_loongarch, + gpr_r3_loongarch, + gpr_r4_loongarch, + gpr_r5_loongarch, + gpr_r6_loongarch, + gpr_r7_loongarch, + gpr_r8_loongarch, + gpr_r9_loongarch, + gpr_r10_loongarch, + gpr_r11_loongarch, + gpr_r12_loongarch, + gpr_r13_loongarch, + gpr_r14_loongarch, + gpr_r15_loongarch, + gpr_r16_loongarch, + gpr_r17_loongarch, + gpr_r18_loongarch, + gpr_r19_loongarch, + gpr_r20_loongarch, + gpr_r21_loongarch, + gpr_r22_loongarch, + gpr_r23_loongarch, + gpr_r24_loongarch, + gpr_r25_loongarch, + gpr_r26_loongarch, + gpr_r27_loongarch, + gpr_r28_loongarch, + gpr_r29_loongarch, + gpr_r30_loongarch, + gpr_r31_loongarch, + gpr_orig_a0_loongarch, + gpr_pc_loongarch, + gpr_badv_loongarch, + gpr_reserved0_loongarch, + gpr_reserved1_loongarch, + gpr_reserved2_loongarch, + gpr_reserved3_loongarch, + gpr_reserved4_loongarch, + gpr_reserved5_loongarch, + gpr_reserved6_loongarch, + gpr_reserved7_loongarch, + gpr_reserved8_loongarch, + gpr_reserved9_loongarch, + gpr_last_loongarch = 44, + + gpr_zero_loongarch = gpr_r0_loongarch, + gpr_ra_loongarch = gpr_r1_loongarch, + gpr_tp_loongarch = gpr_r2_loongarch, + gpr_sp_loongarch = gpr_r3_loongarch, + gpr_a0_loongarch = gpr_r4_loongarch, + gpr_a1_loongarch = gpr_r5_loongarch, + gpr_a2_loongarch = gpr_r6_loongarch, + gpr_a3_loongarch = gpr_r7_loongarch, + gpr_a4_loongarch = gpr_r8_loongarch, + gpr_a5_loongarch = gpr_r9_loongarch, + gpr_a6_loongarch = gpr_r10_loongarch, + gpr_a7_loongarch = gpr_r11_loongarch, + gpr_t0_loongarch = gpr_r12_loongarch, + gpr_t1_loongarch = gpr_r13_loongarch, + gpr_t2_loongarch = gpr_r14_loongarch, + gpr_t3_loongarch = gpr_r15_loongarch, + gpr_t4_loongarch = gpr_r16_loongarch, + gpr_t5_loongarch = gpr_r17_loongarch, + gpr_t6_loongarch = gpr_r18_loongarch, + gpr_t7_loongarch = gpr_r19_loongarch, + gpr_t8_loongarch = gpr_r20_loongarch, + gpr_fp_loongarch = gpr_r22_loongarch, + gpr_s0_loongarch = gpr_r23_loongarch, + gpr_s1_loongarch = gpr_r24_loongarch, + gpr_s2_loongarch = gpr_r25_loongarch, + gpr_s3_loongarch = gpr_r26_loongarch, + gpr_s4_loongarch = gpr_r27_loongarch, + gpr_s5_loongarch = gpr_r28_loongarch, + gpr_s6_loongarch = gpr_r29_loongarch, + gpr_s7_loongarch = gpr_r30_loongarch, + gpr_s8_loongarch = gpr_r31_loongarch, + + fpr_first_loongarch = 45, + fpr_f0_loongarch = fpr_first_loongarch, + fpr_f1_loongarch, + fpr_f2_loongarch, + fpr_f3_loongarch, + fpr_f4_loongarch, + fpr_f5_loongarch, + fpr_f6_loongarch, + fpr_f7_loongarch, + fpr_f8_loongarch, + fpr_f9_loongarch, + fpr_f10_loongarch, + fpr_f11_loongarch, + fpr_f12_loongarch, + fpr_f13_loongarch, + fpr_f14_loongarch, + fpr_f15_loongarch, + fpr_f16_loongarch, + fpr_f17_loongarch, + fpr_f18_loongarch, + fpr_f19_loongarch, + fpr_f20_loongarch, + fpr_f21_loongarch, + fpr_f22_loongarch, + fpr_f23_loongarch, + fpr_f24_loongarch, + fpr_f25_loongarch, + fpr_f26_loongarch, + fpr_f27_loongarch, + fpr_f28_loongarch, + fpr_f29_loongarch, + fpr_f30_loongarch, + fpr_f31_loongarch, + fpr_fcc0_loongarch, + fpr_fcc1_loongarch, + fpr_fcc2_loongarch, + fpr_fcc3_loongarch, + fpr_fcc4_loongarch, + fpr_fcc5_loongarch, + fpr_fcc6_loongarch, + fpr_fcc7_loongarch, + fpr_fcsr_loongarch, + fpr_last_loongarch = fpr_fcsr_loongarch, + + fpr_fa0_loongarch = fpr_f0_loongarch, + fpr_fa1_loongarch = fpr_f1_loongarch, + fpr_fa2_loongarch = fpr_f2_loongarch, + fpr_fa3_loongarch = fpr_f3_loongarch, + fpr_fa4_loongarch = fpr_f4_loongarch, + fpr_fa5_loongarch = fpr_f5_loongarch, + fpr_fa6_loongarch = fpr_f6_loongarch, + fpr_fa7_loongarch = fpr_f7_loongarch, + fpr_ft0_loongarch = fpr_f8_loongarch, + fpr_ft1_loongarch = fpr_f9_loongarch, + fpr_ft2_loongarch = fpr_f10_loongarch, + fpr_ft3_loongarch = fpr_f11_loongarch, + fpr_ft4_loongarch = fpr_f12_loongarch, + fpr_ft5_loongarch = fpr_f13_loongarch, + fpr_ft6_loongarch = fpr_f14_loongarch, + fpr_ft7_loongarch = fpr_f15_loongarch, + fpr_ft8_loongarch = fpr_f16_loongarch, + fpr_ft9_loongarch = fpr_f17_loongarch, + fpr_ft10_loongarch = fpr_f18_loongarch, + fpr_ft11_loongarch = fpr_f19_loongarch, + fpr_ft12_loongarch = fpr_f20_loongarch, + fpr_ft13_loongarch = fpr_f21_loongarch, + fpr_ft14_loongarch = fpr_f22_loongarch, + fpr_ft15_loongarch = fpr_f23_loongarch, + fpr_fs0_loongarch = fpr_f24_loongarch, + fpr_fs1_loongarch = fpr_f25_loongarch, + fpr_fs2_loongarch = fpr_f26_loongarch, + fpr_fs3_loongarch = fpr_f27_loongarch, + fpr_fs4_loongarch = fpr_f28_loongarch, + fpr_fs5_loongarch = fpr_f29_loongarch, + fpr_fs6_loongarch = fpr_f30_loongarch, + fpr_fs7_loongarch = fpr_f31_loongarch, + + k_num_registers_loongarch +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_LOONGARCH_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h new file mode 100644 index 000000000000..000f6e3847e7 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h @@ -0,0 +1,103 @@ +//===-- lldb-mips-freebsd-register-enums.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_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H + +namespace lldb_private { +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all mips registers. +enum { + k_first_gpr_mips64, + gpr_zero_mips64 = k_first_gpr_mips64, + gpr_r1_mips64, + gpr_r2_mips64, + gpr_r3_mips64, + gpr_r4_mips64, + gpr_r5_mips64, + gpr_r6_mips64, + gpr_r7_mips64, + gpr_r8_mips64, + gpr_r9_mips64, + gpr_r10_mips64, + gpr_r11_mips64, + gpr_r12_mips64, + gpr_r13_mips64, + gpr_r14_mips64, + gpr_r15_mips64, + gpr_r16_mips64, + gpr_r17_mips64, + gpr_r18_mips64, + gpr_r19_mips64, + gpr_r20_mips64, + gpr_r21_mips64, + gpr_r22_mips64, + gpr_r23_mips64, + gpr_r24_mips64, + gpr_r25_mips64, + gpr_r26_mips64, + gpr_r27_mips64, + gpr_gp_mips64, + gpr_sp_mips64, + gpr_r30_mips64, + gpr_ra_mips64, + gpr_sr_mips64, + gpr_mullo_mips64, + gpr_mulhi_mips64, + gpr_badvaddr_mips64, + gpr_cause_mips64, + gpr_pc_mips64, + gpr_ic_mips64, + gpr_dummy_mips64, + k_last_gpr_mips64 = gpr_dummy_mips64, + + k_first_fpr_mips64, + fpr_f0_mips64 = k_first_fpr_mips64, + fpr_f1_mips64, + fpr_f2_mips64, + fpr_f3_mips64, + fpr_f4_mips64, + fpr_f5_mips64, + fpr_f6_mips64, + fpr_f7_mips64, + fpr_f8_mips64, + fpr_f9_mips64, + fpr_f10_mips64, + fpr_f11_mips64, + fpr_f12_mips64, + fpr_f13_mips64, + fpr_f14_mips64, + fpr_f15_mips64, + fpr_f16_mips64, + fpr_f17_mips64, + fpr_f18_mips64, + fpr_f19_mips64, + fpr_f20_mips64, + fpr_f21_mips64, + fpr_f22_mips64, + fpr_f23_mips64, + fpr_f24_mips64, + fpr_f25_mips64, + fpr_f26_mips64, + fpr_f27_mips64, + fpr_f28_mips64, + fpr_f29_mips64, + fpr_f30_mips64, + fpr_f31_mips64, + fpr_fcsr_mips64, + fpr_fir_mips64, + k_last_fpr_mips64 = fpr_fir_mips64, + + k_num_registers_mips64, + + k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1, + k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1, +}; +} // namespace lldb_private +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h new file mode 100644 index 000000000000..40a75c006d84 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h @@ -0,0 +1,136 @@ +//===-- lldb-ppc64-register-enums.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_LLDB_PPC64_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H + +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all ppc64 registers. +enum { + k_first_gpr_ppc64, + gpr_r0_ppc64 = k_first_gpr_ppc64, + gpr_r1_ppc64, + gpr_r2_ppc64, + gpr_r3_ppc64, + gpr_r4_ppc64, + gpr_r5_ppc64, + gpr_r6_ppc64, + gpr_r7_ppc64, + gpr_r8_ppc64, + gpr_r9_ppc64, + gpr_r10_ppc64, + gpr_r11_ppc64, + gpr_r12_ppc64, + gpr_r13_ppc64, + gpr_r14_ppc64, + gpr_r15_ppc64, + gpr_r16_ppc64, + gpr_r17_ppc64, + gpr_r18_ppc64, + gpr_r19_ppc64, + gpr_r20_ppc64, + gpr_r21_ppc64, + gpr_r22_ppc64, + gpr_r23_ppc64, + gpr_r24_ppc64, + gpr_r25_ppc64, + gpr_r26_ppc64, + gpr_r27_ppc64, + gpr_r28_ppc64, + gpr_r29_ppc64, + gpr_r30_ppc64, + gpr_r31_ppc64, + gpr_cr_ppc64, + gpr_msr_ppc64, + gpr_xer_ppc64, + gpr_lr_ppc64, + gpr_ctr_ppc64, + gpr_pc_ppc64, + k_last_gpr_ppc64 = gpr_pc_ppc64, + + k_first_fpr_ppc64, + fpr_f0_ppc64 = k_first_fpr_ppc64, + fpr_f1_ppc64, + fpr_f2_ppc64, + fpr_f3_ppc64, + fpr_f4_ppc64, + fpr_f5_ppc64, + fpr_f6_ppc64, + fpr_f7_ppc64, + fpr_f8_ppc64, + fpr_f9_ppc64, + fpr_f10_ppc64, + fpr_f11_ppc64, + fpr_f12_ppc64, + fpr_f13_ppc64, + fpr_f14_ppc64, + fpr_f15_ppc64, + fpr_f16_ppc64, + fpr_f17_ppc64, + fpr_f18_ppc64, + fpr_f19_ppc64, + fpr_f20_ppc64, + fpr_f21_ppc64, + fpr_f22_ppc64, + fpr_f23_ppc64, + fpr_f24_ppc64, + fpr_f25_ppc64, + fpr_f26_ppc64, + fpr_f27_ppc64, + fpr_f28_ppc64, + fpr_f29_ppc64, + fpr_f30_ppc64, + fpr_f31_ppc64, + fpr_fpscr_ppc64, + k_last_fpr_ppc64 = fpr_fpscr_ppc64, + + k_first_vmx_ppc64, + vmx_vr0_ppc64 = k_first_vmx_ppc64, + vmx_vr1_ppc64, + vmx_vr2_ppc64, + vmx_vr3_ppc64, + vmx_vr4_ppc64, + vmx_vr5_ppc64, + vmx_vr6_ppc64, + vmx_vr7_ppc64, + vmx_vr8_ppc64, + vmx_vr9_ppc64, + vmx_vr10_ppc64, + vmx_vr11_ppc64, + vmx_vr12_ppc64, + vmx_vr13_ppc64, + vmx_vr14_ppc64, + vmx_vr15_ppc64, + vmx_vr16_ppc64, + vmx_vr17_ppc64, + vmx_vr18_ppc64, + vmx_vr19_ppc64, + vmx_vr20_ppc64, + vmx_vr21_ppc64, + vmx_vr22_ppc64, + vmx_vr23_ppc64, + vmx_vr24_ppc64, + vmx_vr25_ppc64, + vmx_vr26_ppc64, + vmx_vr27_ppc64, + vmx_vr28_ppc64, + vmx_vr29_ppc64, + vmx_vr30_ppc64, + vmx_vr31_ppc64, + vmx_vscr_ppc64, + vmx_vrsave_ppc64, + k_last_vmx_ppc64 = vmx_vrsave_ppc64, + + k_num_registers_ppc64, + k_num_gpr_registers_ppc64 = k_last_gpr_ppc64 - k_first_gpr_ppc64 + 1, + k_num_fpr_registers_ppc64 = k_last_fpr_ppc64 - k_first_fpr_ppc64 + 1, + k_num_vmx_registers_ppc64 = k_last_vmx_ppc64 - k_first_vmx_ppc64 + 1, +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h new file mode 100644 index 000000000000..a7b5bc5ad9e3 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h @@ -0,0 +1,207 @@ +//===-- lldb-ppc64le-register-enums.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_LLDB_PPC64LE_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H + +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all ppc64le registers. +enum { + k_first_gpr_ppc64le, + gpr_r0_ppc64le = k_first_gpr_ppc64le, + gpr_r1_ppc64le, + gpr_r2_ppc64le, + gpr_r3_ppc64le, + gpr_r4_ppc64le, + gpr_r5_ppc64le, + gpr_r6_ppc64le, + gpr_r7_ppc64le, + gpr_r8_ppc64le, + gpr_r9_ppc64le, + gpr_r10_ppc64le, + gpr_r11_ppc64le, + gpr_r12_ppc64le, + gpr_r13_ppc64le, + gpr_r14_ppc64le, + gpr_r15_ppc64le, + gpr_r16_ppc64le, + gpr_r17_ppc64le, + gpr_r18_ppc64le, + gpr_r19_ppc64le, + gpr_r20_ppc64le, + gpr_r21_ppc64le, + gpr_r22_ppc64le, + gpr_r23_ppc64le, + gpr_r24_ppc64le, + gpr_r25_ppc64le, + gpr_r26_ppc64le, + gpr_r27_ppc64le, + gpr_r28_ppc64le, + gpr_r29_ppc64le, + gpr_r30_ppc64le, + gpr_r31_ppc64le, + gpr_pc_ppc64le, + gpr_msr_ppc64le, + gpr_origr3_ppc64le, + gpr_ctr_ppc64le, + gpr_lr_ppc64le, + gpr_xer_ppc64le, + gpr_cr_ppc64le, + gpr_softe_ppc64le, + gpr_trap_ppc64le, + k_last_gpr_ppc64le = gpr_trap_ppc64le, + + k_first_fpr_ppc64le, + fpr_f0_ppc64le = k_first_fpr_ppc64le, + fpr_f1_ppc64le, + fpr_f2_ppc64le, + fpr_f3_ppc64le, + fpr_f4_ppc64le, + fpr_f5_ppc64le, + fpr_f6_ppc64le, + fpr_f7_ppc64le, + fpr_f8_ppc64le, + fpr_f9_ppc64le, + fpr_f10_ppc64le, + fpr_f11_ppc64le, + fpr_f12_ppc64le, + fpr_f13_ppc64le, + fpr_f14_ppc64le, + fpr_f15_ppc64le, + fpr_f16_ppc64le, + fpr_f17_ppc64le, + fpr_f18_ppc64le, + fpr_f19_ppc64le, + fpr_f20_ppc64le, + fpr_f21_ppc64le, + fpr_f22_ppc64le, + fpr_f23_ppc64le, + fpr_f24_ppc64le, + fpr_f25_ppc64le, + fpr_f26_ppc64le, + fpr_f27_ppc64le, + fpr_f28_ppc64le, + fpr_f29_ppc64le, + fpr_f30_ppc64le, + fpr_f31_ppc64le, + fpr_fpscr_ppc64le, + k_last_fpr_ppc64le = fpr_fpscr_ppc64le, + + k_first_vmx_ppc64le, + vmx_vr0_ppc64le = k_first_vmx_ppc64le, + vmx_vr1_ppc64le, + vmx_vr2_ppc64le, + vmx_vr3_ppc64le, + vmx_vr4_ppc64le, + vmx_vr5_ppc64le, + vmx_vr6_ppc64le, + vmx_vr7_ppc64le, + vmx_vr8_ppc64le, + vmx_vr9_ppc64le, + vmx_vr10_ppc64le, + vmx_vr11_ppc64le, + vmx_vr12_ppc64le, + vmx_vr13_ppc64le, + vmx_vr14_ppc64le, + vmx_vr15_ppc64le, + vmx_vr16_ppc64le, + vmx_vr17_ppc64le, + vmx_vr18_ppc64le, + vmx_vr19_ppc64le, + vmx_vr20_ppc64le, + vmx_vr21_ppc64le, + vmx_vr22_ppc64le, + vmx_vr23_ppc64le, + vmx_vr24_ppc64le, + vmx_vr25_ppc64le, + vmx_vr26_ppc64le, + vmx_vr27_ppc64le, + vmx_vr28_ppc64le, + vmx_vr29_ppc64le, + vmx_vr30_ppc64le, + vmx_vr31_ppc64le, + vmx_vscr_ppc64le, + vmx_vrsave_ppc64le, + k_last_vmx_ppc64le = vmx_vrsave_ppc64le, + + k_first_vsx_ppc64le, + vsx_vs0_ppc64le = k_first_vsx_ppc64le, + vsx_vs1_ppc64le, + vsx_vs2_ppc64le, + vsx_vs3_ppc64le, + vsx_vs4_ppc64le, + vsx_vs5_ppc64le, + vsx_vs6_ppc64le, + vsx_vs7_ppc64le, + vsx_vs8_ppc64le, + vsx_vs9_ppc64le, + vsx_vs10_ppc64le, + vsx_vs11_ppc64le, + vsx_vs12_ppc64le, + vsx_vs13_ppc64le, + vsx_vs14_ppc64le, + vsx_vs15_ppc64le, + vsx_vs16_ppc64le, + vsx_vs17_ppc64le, + vsx_vs18_ppc64le, + vsx_vs19_ppc64le, + vsx_vs20_ppc64le, + vsx_vs21_ppc64le, + vsx_vs22_ppc64le, + vsx_vs23_ppc64le, + vsx_vs24_ppc64le, + vsx_vs25_ppc64le, + vsx_vs26_ppc64le, + vsx_vs27_ppc64le, + vsx_vs28_ppc64le, + vsx_vs29_ppc64le, + vsx_vs30_ppc64le, + vsx_vs31_ppc64le, + vsx_vs32_ppc64le, + vsx_vs33_ppc64le, + vsx_vs34_ppc64le, + vsx_vs35_ppc64le, + vsx_vs36_ppc64le, + vsx_vs37_ppc64le, + vsx_vs38_ppc64le, + vsx_vs39_ppc64le, + vsx_vs40_ppc64le, + vsx_vs41_ppc64le, + vsx_vs42_ppc64le, + vsx_vs43_ppc64le, + vsx_vs44_ppc64le, + vsx_vs45_ppc64le, + vsx_vs46_ppc64le, + vsx_vs47_ppc64le, + vsx_vs48_ppc64le, + vsx_vs49_ppc64le, + vsx_vs50_ppc64le, + vsx_vs51_ppc64le, + vsx_vs52_ppc64le, + vsx_vs53_ppc64le, + vsx_vs54_ppc64le, + vsx_vs55_ppc64le, + vsx_vs56_ppc64le, + vsx_vs57_ppc64le, + vsx_vs58_ppc64le, + vsx_vs59_ppc64le, + vsx_vs60_ppc64le, + vsx_vs61_ppc64le, + vsx_vs62_ppc64le, + vsx_vs63_ppc64le, + k_last_vsx_ppc64le = vsx_vs63_ppc64le, + + k_num_registers_ppc64le, + k_num_gpr_registers_ppc64le = k_last_gpr_ppc64le - k_first_gpr_ppc64le + 1, + k_num_fpr_registers_ppc64le = k_last_fpr_ppc64le - k_first_fpr_ppc64le + 1, + k_num_vmx_registers_ppc64le = k_last_vmx_ppc64le - k_first_vmx_ppc64le + 1, + k_num_vsx_registers_ppc64le = k_last_vsx_ppc64le - k_first_vsx_ppc64le + 1, +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-riscv-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-riscv-register-enums.h new file mode 100644 index 000000000000..caec313750ab --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-riscv-register-enums.h @@ -0,0 +1,193 @@ +//===-- lldb-riscv-register-enums.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_LLDB_RISCV_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_RISCV_REGISTER_ENUMS_H + +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all riscv registers. +enum { + // The same order as user_regs_struct in <asm/ptrace.h> + // note: these enum values are used as byte_offset + gpr_first_riscv = 0, + gpr_pc_riscv = gpr_first_riscv, + gpr_x1_riscv, + gpr_x2_riscv, + gpr_x3_riscv, + gpr_x4_riscv, + gpr_x5_riscv, + gpr_x6_riscv, + gpr_x7_riscv, + gpr_x8_riscv, + gpr_x9_riscv, + gpr_x10_riscv, + gpr_x11_riscv, + gpr_x12_riscv, + gpr_x13_riscv, + gpr_x14_riscv, + gpr_x15_riscv, + gpr_x16_riscv, + gpr_x17_riscv, + gpr_x18_riscv, + gpr_x19_riscv, + gpr_x20_riscv, + gpr_x21_riscv, + gpr_x22_riscv, + gpr_x23_riscv, + gpr_x24_riscv, + gpr_x25_riscv, + gpr_x26_riscv, + gpr_x27_riscv, + gpr_x28_riscv, + gpr_x29_riscv, + gpr_x30_riscv, + gpr_x31_riscv, + gpr_x0_riscv, + gpr_zero_riscv = gpr_x0_riscv, + gpr_ra_riscv = gpr_x1_riscv, + gpr_sp_riscv = gpr_x2_riscv, + gpr_gp_riscv = gpr_x3_riscv, + gpr_tp_riscv = gpr_x4_riscv, + gpr_t0_riscv = gpr_x5_riscv, + gpr_t1_riscv = gpr_x6_riscv, + gpr_t2_riscv = gpr_x7_riscv, + gpr_fp_riscv = gpr_x8_riscv, + gpr_s1_riscv = gpr_x9_riscv, + gpr_a0_riscv = gpr_x10_riscv, + gpr_a1_riscv = gpr_x11_riscv, + gpr_a2_riscv = gpr_x12_riscv, + gpr_a3_riscv = gpr_x13_riscv, + gpr_a4_riscv = gpr_x14_riscv, + gpr_a5_riscv = gpr_x15_riscv, + gpr_a6_riscv = gpr_x16_riscv, + gpr_a7_riscv = gpr_x17_riscv, + gpr_s2_riscv = gpr_x18_riscv, + gpr_s3_riscv = gpr_x19_riscv, + gpr_s4_riscv = gpr_x20_riscv, + gpr_s5_riscv = gpr_x21_riscv, + gpr_s6_riscv = gpr_x22_riscv, + gpr_s7_riscv = gpr_x23_riscv, + gpr_s8_riscv = gpr_x24_riscv, + gpr_s9_riscv = gpr_x25_riscv, + gpr_s10_riscv = gpr_x26_riscv, + gpr_s11_riscv = gpr_x27_riscv, + gpr_t3_riscv = gpr_x28_riscv, + gpr_t4_riscv = gpr_x29_riscv, + gpr_t5_riscv = gpr_x30_riscv, + gpr_t6_riscv = gpr_x31_riscv, + gpr_last_riscv = gpr_x0_riscv, + + fpr_first_riscv = 33, + fpr_f0_riscv = fpr_first_riscv, + fpr_f1_riscv, + fpr_f2_riscv, + fpr_f3_riscv, + fpr_f4_riscv, + fpr_f5_riscv, + fpr_f6_riscv, + fpr_f7_riscv, + fpr_f8_riscv, + fpr_f9_riscv, + fpr_f10_riscv, + fpr_f11_riscv, + fpr_f12_riscv, + fpr_f13_riscv, + fpr_f14_riscv, + fpr_f15_riscv, + fpr_f16_riscv, + fpr_f17_riscv, + fpr_f18_riscv, + fpr_f19_riscv, + fpr_f20_riscv, + fpr_f21_riscv, + fpr_f22_riscv, + fpr_f23_riscv, + fpr_f24_riscv, + fpr_f25_riscv, + fpr_f26_riscv, + fpr_f27_riscv, + fpr_f28_riscv, + fpr_f29_riscv, + fpr_f30_riscv, + fpr_f31_riscv, + + fpr_fcsr_riscv, + fpr_ft0_riscv = fpr_f0_riscv, + fpr_ft1_riscv = fpr_f1_riscv, + fpr_ft2_riscv = fpr_f2_riscv, + fpr_ft3_riscv = fpr_f3_riscv, + fpr_ft4_riscv = fpr_f4_riscv, + fpr_ft5_riscv = fpr_f5_riscv, + fpr_ft6_riscv = fpr_f6_riscv, + fpr_ft7_riscv = fpr_f7_riscv, + fpr_fs0_riscv = fpr_f8_riscv, + fpr_fs1_riscv = fpr_f9_riscv, + fpr_fa0_riscv = fpr_f10_riscv, + fpr_fa1_riscv = fpr_f11_riscv, + fpr_fa2_riscv = fpr_f12_riscv, + fpr_fa3_riscv = fpr_f13_riscv, + fpr_fa4_riscv = fpr_f14_riscv, + fpr_fa5_riscv = fpr_f15_riscv, + fpr_fa6_riscv = fpr_f16_riscv, + fpr_fa7_riscv = fpr_f17_riscv, + fpr_fs2_riscv = fpr_f18_riscv, + fpr_fs3_riscv = fpr_f19_riscv, + fpr_fs4_riscv = fpr_f20_riscv, + fpr_fs5_riscv = fpr_f21_riscv, + fpr_fs6_riscv = fpr_f22_riscv, + fpr_fs7_riscv = fpr_f23_riscv, + fpr_fs8_riscv = fpr_f24_riscv, + fpr_fs9_riscv = fpr_f25_riscv, + fpr_fs10_riscv = fpr_f26_riscv, + fpr_fs11_riscv = fpr_f27_riscv, + fpr_ft8_riscv = fpr_f28_riscv, + fpr_ft9_riscv = fpr_f29_riscv, + fpr_ft10_riscv = fpr_f30_riscv, + fpr_ft11_riscv = fpr_f31_riscv, + fpr_last_riscv = fpr_fcsr_riscv, + + vpr_first_riscv = 66, + vpr_v0_riscv = vpr_first_riscv, + vpr_v1_riscv, + vpr_v2_riscv, + vpr_v3_riscv, + vpr_v4_riscv, + vpr_v5_riscv, + vpr_v6_riscv, + vpr_v7_riscv, + vpr_v8_riscv, + vpr_v9_riscv, + vpr_v10_riscv, + vpr_v11_riscv, + vpr_v12_riscv, + vpr_v13_riscv, + vpr_v14_riscv, + vpr_v15_riscv, + vpr_v16_riscv, + vpr_v17_riscv, + vpr_v18_riscv, + vpr_v19_riscv, + vpr_v20_riscv, + vpr_v21_riscv, + vpr_v22_riscv, + vpr_v23_riscv, + vpr_v24_riscv, + vpr_v25_riscv, + vpr_v26_riscv, + vpr_v27_riscv, + vpr_v28_riscv, + vpr_v29_riscv, + vpr_v30_riscv, + vpr_v31_riscv, + vpr_last_riscv = vpr_v31_riscv, + + k_num_registers_riscv +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_RISCV_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h new file mode 100644 index 000000000000..23c441e1c803 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h @@ -0,0 +1,90 @@ +//===-- lldb-s390x-register-enums.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_LLDB_S390X_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H + +namespace lldb_private { +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all s390x registers. +enum { + k_first_gpr_s390x, + lldb_r0_s390x = k_first_gpr_s390x, + lldb_r1_s390x, + lldb_r2_s390x, + lldb_r3_s390x, + lldb_r4_s390x, + lldb_r5_s390x, + lldb_r6_s390x, + lldb_r7_s390x, + lldb_r8_s390x, + lldb_r9_s390x, + lldb_r10_s390x, + lldb_r11_s390x, + lldb_r12_s390x, + lldb_r13_s390x, + lldb_r14_s390x, + lldb_r15_s390x, + lldb_acr0_s390x, + lldb_acr1_s390x, + lldb_acr2_s390x, + lldb_acr3_s390x, + lldb_acr4_s390x, + lldb_acr5_s390x, + lldb_acr6_s390x, + lldb_acr7_s390x, + lldb_acr8_s390x, + lldb_acr9_s390x, + lldb_acr10_s390x, + lldb_acr11_s390x, + lldb_acr12_s390x, + lldb_acr13_s390x, + lldb_acr14_s390x, + lldb_acr15_s390x, + lldb_pswm_s390x, + lldb_pswa_s390x, + k_last_gpr_s390x = lldb_pswa_s390x, + + k_first_fpr_s390x, + lldb_f0_s390x = k_first_fpr_s390x, + lldb_f1_s390x, + lldb_f2_s390x, + lldb_f3_s390x, + lldb_f4_s390x, + lldb_f5_s390x, + lldb_f6_s390x, + lldb_f7_s390x, + lldb_f8_s390x, + lldb_f9_s390x, + lldb_f10_s390x, + lldb_f11_s390x, + lldb_f12_s390x, + lldb_f13_s390x, + lldb_f14_s390x, + lldb_f15_s390x, + lldb_fpc_s390x, + k_last_fpr_s390x = lldb_fpc_s390x, + + // These are only available on Linux. + k_first_linux_s390x, + lldb_orig_r2_s390x = k_first_linux_s390x, + lldb_last_break_s390x, + lldb_system_call_s390x, + k_last_linux_s390x = lldb_system_call_s390x, + + k_num_registers_s390x, + k_num_gpr_registers_s390x = k_last_gpr_s390x - k_first_gpr_s390x + 1, + k_num_fpr_registers_s390x = k_last_fpr_s390x - k_first_fpr_s390x + 1, + k_num_linux_registers_s390x = k_last_linux_s390x - k_first_linux_s390x + 1, + k_num_user_registers_s390x = + k_num_gpr_registers_s390x + k_num_fpr_registers_s390x, +}; +} + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H 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 new file mode 100644 index 000000000000..85aa254d6621 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -0,0 +1,517 @@ +//===-- lldb-x86-register-enums.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_LLDB_X86_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H + +namespace lldb_private { +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +// Internal codes for all i386 registers. +enum { + k_first_gpr_i386, + lldb_eax_i386 = k_first_gpr_i386, + lldb_ebx_i386, + lldb_ecx_i386, + lldb_edx_i386, + lldb_edi_i386, + lldb_esi_i386, + lldb_ebp_i386, + lldb_esp_i386, + lldb_eip_i386, + lldb_eflags_i386, + lldb_cs_i386, + lldb_fs_i386, + lldb_gs_i386, + lldb_ss_i386, + lldb_ds_i386, + lldb_es_i386, + + k_first_alias_i386, + lldb_ax_i386 = k_first_alias_i386, + lldb_bx_i386, + lldb_cx_i386, + lldb_dx_i386, + lldb_di_i386, + lldb_si_i386, + lldb_bp_i386, + lldb_sp_i386, + lldb_ah_i386, + lldb_bh_i386, + lldb_ch_i386, + lldb_dh_i386, + lldb_al_i386, + lldb_bl_i386, + lldb_cl_i386, + lldb_dl_i386, + k_last_alias_i386 = lldb_dl_i386, + + k_last_gpr_i386 = k_last_alias_i386, + + k_first_fpr_i386, + lldb_fctrl_i386 = k_first_fpr_i386, + lldb_fstat_i386, + lldb_ftag_i386, + lldb_fop_i386, + lldb_fiseg_i386, + lldb_fioff_i386, + lldb_foseg_i386, + lldb_fooff_i386, + lldb_mxcsr_i386, + lldb_mxcsrmask_i386, + lldb_st0_i386, + lldb_st1_i386, + lldb_st2_i386, + lldb_st3_i386, + lldb_st4_i386, + lldb_st5_i386, + lldb_st6_i386, + lldb_st7_i386, + lldb_mm0_i386, + lldb_mm1_i386, + lldb_mm2_i386, + lldb_mm3_i386, + lldb_mm4_i386, + lldb_mm5_i386, + lldb_mm6_i386, + lldb_mm7_i386, + lldb_xmm0_i386, + lldb_xmm1_i386, + lldb_xmm2_i386, + lldb_xmm3_i386, + lldb_xmm4_i386, + lldb_xmm5_i386, + lldb_xmm6_i386, + lldb_xmm7_i386, + k_last_fpr_i386 = lldb_xmm7_i386, + + k_first_avx_i386, + lldb_ymm0_i386 = k_first_avx_i386, + lldb_ymm1_i386, + lldb_ymm2_i386, + lldb_ymm3_i386, + lldb_ymm4_i386, + lldb_ymm5_i386, + lldb_ymm6_i386, + lldb_ymm7_i386, + k_last_avx_i386 = lldb_ymm7_i386, + + k_first_mpxr_i386, + lldb_bnd0_i386 = k_first_mpxr_i386, + lldb_bnd1_i386, + lldb_bnd2_i386, + lldb_bnd3_i386, + k_last_mpxr_i386 = lldb_bnd3_i386, + + k_first_mpxc_i386, + lldb_bndcfgu_i386 = k_first_mpxc_i386, + lldb_bndstatus_i386, + k_last_mpxc_i386 = lldb_bndstatus_i386, + + k_first_dbr_i386, + lldb_dr0_i386 = k_first_dbr_i386, + lldb_dr1_i386, + lldb_dr2_i386, + lldb_dr3_i386, + lldb_dr4_i386, + lldb_dr5_i386, + lldb_dr6_i386, + lldb_dr7_i386, + k_last_dbr_i386 = lldb_dr7_i386, + + k_num_registers_i386, + k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1, + k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1, + k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1, + k_num_mpx_registers_i386 = k_last_mpxc_i386 - k_first_mpxr_i386 + 1, + k_num_user_registers_i386 = k_num_gpr_registers_i386 + + k_num_fpr_registers_i386 + + k_num_avx_registers_i386 + + k_num_mpx_registers_i386, + k_num_dbr_registers_i386 = k_last_dbr_i386 - k_first_dbr_i386 + 1, +}; + +// Internal codes for all x86_64 registers. +enum { + k_first_gpr_x86_64, + lldb_rax_x86_64 = k_first_gpr_x86_64, + lldb_rbx_x86_64, + lldb_rcx_x86_64, + lldb_rdx_x86_64, + lldb_rdi_x86_64, + lldb_rsi_x86_64, + lldb_rbp_x86_64, + lldb_rsp_x86_64, + lldb_r8_x86_64, + lldb_r9_x86_64, + lldb_r10_x86_64, + lldb_r11_x86_64, + lldb_r12_x86_64, + lldb_r13_x86_64, + lldb_r14_x86_64, + lldb_r15_x86_64, + lldb_rip_x86_64, + lldb_rflags_x86_64, + lldb_cs_x86_64, + lldb_fs_x86_64, + lldb_gs_x86_64, + lldb_ss_x86_64, + lldb_ds_x86_64, + lldb_es_x86_64, + + k_first_alias_x86_64, + lldb_eax_x86_64 = k_first_alias_x86_64, + lldb_ebx_x86_64, + lldb_ecx_x86_64, + lldb_edx_x86_64, + lldb_edi_x86_64, + lldb_esi_x86_64, + lldb_ebp_x86_64, + lldb_esp_x86_64, + lldb_r8d_x86_64, // Low 32 bits of r8 + lldb_r9d_x86_64, // Low 32 bits of r9 + lldb_r10d_x86_64, // Low 32 bits of r10 + lldb_r11d_x86_64, // Low 32 bits of r11 + lldb_r12d_x86_64, // Low 32 bits of r12 + lldb_r13d_x86_64, // Low 32 bits of r13 + lldb_r14d_x86_64, // Low 32 bits of r14 + lldb_r15d_x86_64, // Low 32 bits of r15 + lldb_ax_x86_64, + lldb_bx_x86_64, + lldb_cx_x86_64, + lldb_dx_x86_64, + lldb_di_x86_64, + lldb_si_x86_64, + lldb_bp_x86_64, + lldb_sp_x86_64, + lldb_r8w_x86_64, // Low 16 bits of r8 + lldb_r9w_x86_64, // Low 16 bits of r9 + lldb_r10w_x86_64, // Low 16 bits of r10 + lldb_r11w_x86_64, // Low 16 bits of r11 + lldb_r12w_x86_64, // Low 16 bits of r12 + lldb_r13w_x86_64, // Low 16 bits of r13 + lldb_r14w_x86_64, // Low 16 bits of r14 + lldb_r15w_x86_64, // Low 16 bits of r15 + lldb_ah_x86_64, + lldb_bh_x86_64, + lldb_ch_x86_64, + lldb_dh_x86_64, + lldb_al_x86_64, + lldb_bl_x86_64, + lldb_cl_x86_64, + lldb_dl_x86_64, + lldb_dil_x86_64, + lldb_sil_x86_64, + lldb_bpl_x86_64, + lldb_spl_x86_64, + lldb_r8l_x86_64, // Low 8 bits of r8 + lldb_r9l_x86_64, // Low 8 bits of r9 + lldb_r10l_x86_64, // Low 8 bits of r10 + lldb_r11l_x86_64, // Low 8 bits of r11 + lldb_r12l_x86_64, // Low 8 bits of r12 + lldb_r13l_x86_64, // Low 8 bits of r13 + lldb_r14l_x86_64, // Low 8 bits of r14 + lldb_r15l_x86_64, // Low 8 bits of r15 + k_last_alias_x86_64 = lldb_r15l_x86_64, + + k_last_gpr_x86_64 = k_last_alias_x86_64, + + k_first_fpr_x86_64, + lldb_fctrl_x86_64 = k_first_fpr_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, + k_last_fpr_x86_64 = lldb_xmm15_x86_64, + + k_first_avx_x86_64, + lldb_ymm0_x86_64 = k_first_avx_x86_64, + lldb_ymm1_x86_64, + lldb_ymm2_x86_64, + lldb_ymm3_x86_64, + lldb_ymm4_x86_64, + lldb_ymm5_x86_64, + lldb_ymm6_x86_64, + lldb_ymm7_x86_64, + lldb_ymm8_x86_64, + lldb_ymm9_x86_64, + lldb_ymm10_x86_64, + lldb_ymm11_x86_64, + lldb_ymm12_x86_64, + lldb_ymm13_x86_64, + lldb_ymm14_x86_64, + lldb_ymm15_x86_64, + k_last_avx_x86_64 = lldb_ymm15_x86_64, + + k_first_mpxr_x86_64, + lldb_bnd0_x86_64 = k_first_mpxr_x86_64, + lldb_bnd1_x86_64, + lldb_bnd2_x86_64, + lldb_bnd3_x86_64, + k_last_mpxr_x86_64 = lldb_bnd3_x86_64, + + k_first_mpxc_x86_64, + lldb_bndcfgu_x86_64 = k_first_mpxc_x86_64, + lldb_bndstatus_x86_64, + k_last_mpxc_x86_64 = lldb_bndstatus_x86_64, + + k_first_dbr_x86_64, + lldb_dr0_x86_64 = k_first_dbr_x86_64, + lldb_dr1_x86_64, + lldb_dr2_x86_64, + lldb_dr3_x86_64, + lldb_dr4_x86_64, + lldb_dr5_x86_64, + lldb_dr6_x86_64, + lldb_dr7_x86_64, + k_last_dbr_x86_64 = lldb_dr7_x86_64, + + k_num_registers_x86_64, + k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1, + k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1, + k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1, + k_num_mpx_registers_x86_64 = k_last_mpxc_x86_64 - k_first_mpxr_x86_64 + 1, + k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 + + k_num_fpr_registers_x86_64 + + k_num_avx_registers_x86_64 + + k_num_mpx_registers_x86_64, + k_num_dbr_registers_x86_64 = k_last_dbr_x86_64 - k_first_dbr_x86_64 + 1, +}; + +// For platform that supports fs_base/gs_base registers. +namespace x86_64_with_base { +enum { + k_first_gpr, + lldb_rax = k_first_gpr, + lldb_rbx, + lldb_rcx, + lldb_rdx, + lldb_rdi, + lldb_rsi, + lldb_rbp, + lldb_rsp, + lldb_r8, + lldb_r9, + lldb_r10, + lldb_r11, + lldb_r12, + lldb_r13, + lldb_r14, + lldb_r15, + lldb_rip, + lldb_rflags, + lldb_cs, + lldb_fs, + lldb_gs, + lldb_ss, + lldb_fs_base, + lldb_gs_base, + lldb_ds, + lldb_es, + + k_first_alias, + lldb_eax = k_first_alias, + lldb_ebx, + lldb_ecx, + lldb_edx, + lldb_edi, + lldb_esi, + lldb_ebp, + lldb_esp, + lldb_r8d, // Low 32 bits of r8 + lldb_r9d, // Low 32 bits of r9 + lldb_r10d, // Low 32 bits of r10 + lldb_r11d, // Low 32 bits of r11 + lldb_r12d, // Low 32 bits of r12 + lldb_r13d, // Low 32 bits of r13 + lldb_r14d, // Low 32 bits of r14 + lldb_r15d, // Low 32 bits of r15 + lldb_ax, + lldb_bx, + lldb_cx, + lldb_dx, + lldb_di, + lldb_si, + lldb_bp, + lldb_sp, + lldb_r8w, // Low 16 bits of r8 + lldb_r9w, // Low 16 bits of r9 + lldb_r10w, // Low 16 bits of r10 + lldb_r11w, // Low 16 bits of r11 + lldb_r12w, // Low 16 bits of r12 + lldb_r13w, // Low 16 bits of r13 + lldb_r14w, // Low 16 bits of r14 + lldb_r15w, // Low 16 bits of r15 + lldb_ah, + lldb_bh, + lldb_ch, + lldb_dh, + lldb_al, + lldb_bl, + lldb_cl, + lldb_dl, + lldb_dil, + lldb_sil, + lldb_bpl, + lldb_spl, + lldb_r8l, // Low 8 bits of r8 + lldb_r9l, // Low 8 bits of r9 + lldb_r10l, // Low 8 bits of r10 + lldb_r11l, // Low 8 bits of r11 + lldb_r12l, // Low 8 bits of r12 + lldb_r13l, // Low 8 bits of r13 + lldb_r14l, // Low 8 bits of r14 + lldb_r15l, // Low 8 bits of r15 + k_last_alias = lldb_r15l, + + k_last_gpr = k_last_alias, + + k_first_fpr, + lldb_fctrl = k_first_fpr, + lldb_fstat, + lldb_ftag, + lldb_fop, + lldb_fiseg, + lldb_fioff, + lldb_fip, + lldb_foseg, + lldb_fooff, + lldb_fdp, + lldb_mxcsr, + lldb_mxcsrmask, + lldb_st0, + lldb_st1, + lldb_st2, + lldb_st3, + lldb_st4, + lldb_st5, + lldb_st6, + lldb_st7, + lldb_mm0, + lldb_mm1, + lldb_mm2, + lldb_mm3, + lldb_mm4, + lldb_mm5, + lldb_mm6, + lldb_mm7, + lldb_xmm0, + lldb_xmm1, + lldb_xmm2, + lldb_xmm3, + lldb_xmm4, + lldb_xmm5, + lldb_xmm6, + lldb_xmm7, + lldb_xmm8, + lldb_xmm9, + lldb_xmm10, + lldb_xmm11, + lldb_xmm12, + lldb_xmm13, + lldb_xmm14, + lldb_xmm15, + k_last_fpr = lldb_xmm15, + + k_first_avx, + lldb_ymm0 = k_first_avx, + lldb_ymm1, + lldb_ymm2, + lldb_ymm3, + lldb_ymm4, + lldb_ymm5, + lldb_ymm6, + lldb_ymm7, + lldb_ymm8, + lldb_ymm9, + lldb_ymm10, + lldb_ymm11, + lldb_ymm12, + lldb_ymm13, + lldb_ymm14, + lldb_ymm15, + k_last_avx = lldb_ymm15, + + k_first_mpxr, + lldb_bnd0 = k_first_mpxr, + lldb_bnd1, + lldb_bnd2, + lldb_bnd3, + k_last_mpxr = lldb_bnd3, + + k_first_mpxc, + lldb_bndcfgu = k_first_mpxc, + lldb_bndstatus, + k_last_mpxc = lldb_bndstatus, + + k_first_dbr, + lldb_dr0 = k_first_dbr, + lldb_dr1, + lldb_dr2, + lldb_dr3, + lldb_dr4, + lldb_dr5, + lldb_dr6, + lldb_dr7, + k_last_dbr = lldb_dr7, + + k_num_registers, + k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, + k_num_fpr_registers = k_last_fpr - k_first_fpr + 1, + k_num_avx_registers = k_last_avx - k_first_avx + 1, + k_num_mpx_registers = k_last_mpxc - k_first_mpxr + 1, + k_num_user_registers = k_num_gpr_registers + + k_num_fpr_registers + + k_num_avx_registers + + k_num_mpx_registers, + k_num_dbr_registers = k_last_dbr - k_first_dbr + 1, +}; +} // namespace x86_64_with_base + +} + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H |