summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authormortimer <mortimer@cvs.openbsd.org>2019-12-21 13:16:26 +0000
committermortimer <mortimer@cvs.openbsd.org>2019-12-21 13:16:26 +0000
commit7d09ab9b8befdc71207ad220cfebffb0eae8312a (patch)
tree133b3577c57b7d8fb5cabff4f628cce57fb42d90 /gnu
parent3a0c705d9da46d8a64799f227c61bc81e7047540 (diff)
Add arm64 support for lldb.
"Go for it" kettenis@
Diffstat (limited to 'gnu')
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt1
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.cpp562
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.h87
-rw-r--r--gnu/usr.bin/clang/liblldbPluginProcess/Makefile3
4 files changed, 652 insertions, 1 deletions
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt
index 4eb5697ab83..0c24116b57a 100644
--- a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt
@@ -2,6 +2,7 @@ add_lldb_library(lldbPluginProcessOpenBSD PLUGIN
NativeProcessOpenBSD.cpp
NativeRegisterContextOpenBSD.cpp
NativeRegisterContextOpenBSD_x86_64.cpp
+ NativeRegisterContextOpenBSD_arm64.cpp
NativeThreadOpenBSD.cpp
LINK_LIBS
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.cpp
new file mode 100644
index 00000000000..d00d67b4acf
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.cpp
@@ -0,0 +1,562 @@
+//===-- NativeRegisterContextOpenBSD_arm64.cpp ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm64__) || defined(__aarch64__)
+
+#include <elf.h>
+#include <err.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "NativeRegisterContextOpenBSD_arm64.h"
+
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/ADT/APInt.h"
+
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <machine/cpu.h>
+// clang-format on
+
+using namespace lldb_private;
+using namespace lldb_private::process_openbsd;
+
+#define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
+
+// ARM64 general purpose registers.
+static const uint32_t g_gpr_regnums_arm64[] = {
+ gpr_x0_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,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
+ 1) == k_num_gpr_registers_arm64,
+ "g_gpr_regnums_arm64 has wrong number of register infos");
+
+// ARM64 floating point registers.
+static const uint32_t g_fpu_regnums_arm64[] = {
+ fpu_v0_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,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
+ 1) == k_num_fpr_registers_arm64,
+ "g_fpu_regnums_arm64 has wrong number of register infos");
+
+namespace {
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 2 };
+}
+
+// Register sets for ARM64.
+static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64,
+ g_gpr_regnums_arm64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
+ g_fpu_regnums_arm64}};
+
+NativeRegisterContextOpenBSD *
+NativeRegisterContextOpenBSD::CreateHostNativeRegisterContextOpenBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextOpenBSD_arm64(target_arch, native_thread);
+}
+
+// ----------------------------------------------------------------------------
+// NativeRegisterContextOpenBSD_arm64 members.
+// ----------------------------------------------------------------------------
+
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ return new RegisterInfoPOSIX_arm64(target_arch);
+}
+
+static llvm::APInt uint128ToAPInt(__uint128_t in) {
+ uint64_t *pair = (uint64_t *)&in;
+ llvm::APInt out(128, 2, pair);
+ return out;
+}
+
+static __uint128_t APIntTouint128(llvm::APInt in) {
+ assert(in.getBitWidth() == 128);
+ __uint128_t out = 0;
+ const uint64_t *data = in.getRawData();
+ ::memcpy((uint64_t *)&out, data, sizeof(__uint128_t));
+ return out;
+}
+
+NativeRegisterContextOpenBSD_arm64::NativeRegisterContextOpenBSD_arm64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextOpenBSD(native_thread,
+ CreateRegisterInfoInterface(target_arch)),
+ m_gpr(), m_fpr() {}
+
+uint32_t NativeRegisterContextOpenBSD_arm64::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ count += g_reg_sets_arm64[set_index].num_registers;
+ return count;
+}
+
+uint32_t NativeRegisterContextOpenBSD_arm64::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextOpenBSD_arm64::GetRegisterSet(uint32_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_arm64[set_index];
+
+ return nullptr;
+}
+
+Status
+NativeRegisterContextOpenBSD_arm64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
+
+ int set = GetSetForNativeRegNum(reg);
+ if (set == -1) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ if (ReadRegisterSet(set) != 0) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat(
+ "reading register set for register \"%s\" failed", reg_info->name);
+ return error;
+ }
+
+ switch (reg) {
+ case gpr_x0_arm64:
+ case gpr_x1_arm64:
+ case gpr_x2_arm64:
+ case gpr_x3_arm64:
+ case gpr_x4_arm64:
+ case gpr_x5_arm64:
+ case gpr_x6_arm64:
+ case gpr_x7_arm64:
+ case gpr_x8_arm64:
+ case gpr_x9_arm64:
+ case gpr_x10_arm64:
+ case gpr_x11_arm64:
+ case gpr_x12_arm64:
+ case gpr_x13_arm64:
+ case gpr_x14_arm64:
+ case gpr_x15_arm64:
+ case gpr_x16_arm64:
+ case gpr_x17_arm64:
+ case gpr_x18_arm64:
+ case gpr_x19_arm64:
+ case gpr_x20_arm64:
+ case gpr_x21_arm64:
+ case gpr_x22_arm64:
+ case gpr_x23_arm64:
+ case gpr_x24_arm64:
+ case gpr_x25_arm64:
+ case gpr_x26_arm64:
+ case gpr_x27_arm64:
+ case gpr_x28_arm64:
+ reg_value = (uint64_t)m_gpr.r_reg[reg - gpr_x0_arm64];
+ break;
+ case gpr_fp_arm64:
+ reg_value = (uint64_t)m_gpr.r_reg[29];
+ break;
+ case gpr_lr_arm64:
+ reg_value = (uint64_t)m_gpr.r_lr;
+ break;
+ case gpr_sp_arm64:
+ reg_value = (uint64_t)m_gpr.r_sp;
+ break;
+ case gpr_pc_arm64:
+ reg_value = (uint64_t)m_gpr.r_pc;
+ break;
+ case gpr_cpsr_arm64:
+ reg_value = (uint64_t)m_gpr.r_spsr;
+ break;
+ case fpu_v0_arm64:
+ case fpu_v1_arm64:
+ case fpu_v2_arm64:
+ case fpu_v3_arm64:
+ case fpu_v4_arm64:
+ case fpu_v5_arm64:
+ case fpu_v6_arm64:
+ case fpu_v7_arm64:
+ case fpu_v8_arm64:
+ case fpu_v9_arm64:
+ case fpu_v10_arm64:
+ case fpu_v11_arm64:
+ case fpu_v12_arm64:
+ case fpu_v13_arm64:
+ case fpu_v14_arm64:
+ case fpu_v15_arm64:
+ case fpu_v16_arm64:
+ case fpu_v17_arm64:
+ case fpu_v18_arm64:
+ case fpu_v19_arm64:
+ case fpu_v20_arm64:
+ case fpu_v21_arm64:
+ case fpu_v22_arm64:
+ case fpu_v23_arm64:
+ case fpu_v24_arm64:
+ case fpu_v25_arm64:
+ case fpu_v26_arm64:
+ case fpu_v27_arm64:
+ case fpu_v28_arm64:
+ case fpu_v29_arm64:
+ case fpu_v30_arm64:
+ case fpu_v31_arm64:
+ reg_value = uint128ToAPInt(m_fpr.fp_reg[reg - fpu_v0_arm64]);
+ break;
+ case fpu_fpsr_arm64:
+ reg_value = (uint32_t)m_fpr.fp_sr;
+ break;
+ case fpu_fpcr_arm64:
+ reg_value = (uint32_t)m_fpr.fp_cr;
+ break;
+ default:
+ log->Printf("Requested read to unhandled reg: %u", reg);
+ break;
+ }
+
+ if (reg_value.GetByteSize() > reg_info->byte_size) {
+ reg_value.SetType(reg_info);
+ }
+
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_arm64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+
+ Status error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
+
+ int set = GetSetForNativeRegNum(reg);
+ if (set == -1) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ if (ReadRegisterSet(set) != 0) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat(
+ "reading register set for register \"%s\" failed", reg_info->name);
+ return error;
+ }
+
+ switch (reg) {
+ case gpr_x0_arm64:
+ case gpr_x1_arm64:
+ case gpr_x2_arm64:
+ case gpr_x3_arm64:
+ case gpr_x4_arm64:
+ case gpr_x5_arm64:
+ case gpr_x6_arm64:
+ case gpr_x7_arm64:
+ case gpr_x8_arm64:
+ case gpr_x9_arm64:
+ case gpr_x10_arm64:
+ case gpr_x11_arm64:
+ case gpr_x12_arm64:
+ case gpr_x13_arm64:
+ case gpr_x14_arm64:
+ case gpr_x15_arm64:
+ case gpr_x16_arm64:
+ case gpr_x17_arm64:
+ case gpr_x18_arm64:
+ case gpr_x19_arm64:
+ case gpr_x20_arm64:
+ case gpr_x21_arm64:
+ case gpr_x22_arm64:
+ case gpr_x23_arm64:
+ case gpr_x24_arm64:
+ case gpr_x25_arm64:
+ case gpr_x26_arm64:
+ case gpr_x27_arm64:
+ case gpr_x28_arm64:
+ m_gpr.r_reg[reg - gpr_x0_arm64] = reg_value.GetAsUInt64();
+ break;
+ case gpr_fp_arm64:
+ m_gpr.r_reg[29] = reg_value.GetAsUInt64();
+ break;
+ case gpr_lr_arm64:
+ m_gpr.r_lr = reg_value.GetAsUInt64();
+ break;
+ case gpr_sp_arm64:
+ m_gpr.r_sp = reg_value.GetAsUInt64();
+ break;
+ case gpr_pc_arm64:
+ m_gpr.r_pc = reg_value.GetAsUInt64();
+ break;
+ case gpr_cpsr_arm64:
+ m_gpr.r_spsr = reg_value.GetAsUInt64();
+ break;
+ case fpu_v0_arm64:
+ case fpu_v1_arm64:
+ case fpu_v2_arm64:
+ case fpu_v3_arm64:
+ case fpu_v4_arm64:
+ case fpu_v5_arm64:
+ case fpu_v6_arm64:
+ case fpu_v7_arm64:
+ case fpu_v8_arm64:
+ case fpu_v9_arm64:
+ case fpu_v10_arm64:
+ case fpu_v11_arm64:
+ case fpu_v12_arm64:
+ case fpu_v13_arm64:
+ case fpu_v14_arm64:
+ case fpu_v15_arm64:
+ case fpu_v16_arm64:
+ case fpu_v17_arm64:
+ case fpu_v18_arm64:
+ case fpu_v19_arm64:
+ case fpu_v20_arm64:
+ case fpu_v21_arm64:
+ case fpu_v22_arm64:
+ case fpu_v23_arm64:
+ case fpu_v24_arm64:
+ case fpu_v25_arm64:
+ case fpu_v26_arm64:
+ case fpu_v27_arm64:
+ case fpu_v28_arm64:
+ case fpu_v29_arm64:
+ case fpu_v30_arm64:
+ case fpu_v31_arm64:
+ m_fpr.fp_reg[reg - fpu_v0_arm64] =
+ APIntTouint128(reg_value.GetAsUInt128(llvm::APInt(128, 0, false)));
+ break;
+ case fpu_fpsr_arm64:
+ m_fpr.fp_sr = reg_value.GetAsUInt32();
+ break;
+ case fpu_fpcr_arm64:
+ m_fpr.fp_cr = reg_value.GetAsUInt32();
+ break;
+ default:
+ log->Printf("Requested write of unhandled reg: %u", reg);
+ break;
+ }
+
+ if (WriteRegisterSet(set) != 0)
+ error.SetErrorStringWithFormat("failed to write register set");
+
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "failed to allocate DataBufferHeap instance of size %zu",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %zu"
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ ::memcpy(dst, &m_gpr, GetGPRSize());
+ dst += GetGPRSize();
+
+ ::memcpy(dst, &m_fpr, GetFPRSize());
+ dst += GetFPRSize();
+
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextOpenBSD_arm64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextOpenBSD_arm64::%s data_sp contained mismatched "
+ "data size, expected %zu, actual %llu",
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextOpenBSD_arm64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ // TODO ?
+ // Do we need to make a custom RegisterInfoOpenBSD_arm64
+ // because the RegisterInfoPOSIX_arm64 doesn't quite match
+ // our machine/reg.h?
+ ::memcpy(&m_gpr, src, GetGPRSize());
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
+ src += GetGPRSize();
+
+ ::memcpy(&m_fpr, src, GetFPRSize());
+ error = WriteFPR();
+ if (error.Fail())
+ return error;
+ src += GetFPRSize();
+
+ return error;
+}
+
+int NativeRegisterContextOpenBSD_arm64::GetSetForNativeRegNum(
+ int reg_num) const {
+ if (reg_num >= k_first_gpr_arm64 && reg_num <= k_last_gpr_arm64)
+ return GPRegSet;
+ else if (reg_num >= k_first_fpr_arm64 && reg_num <= k_last_fpr_arm64)
+ return FPRegSet;
+ else
+ return -1;
+}
+
+int NativeRegisterContextOpenBSD_arm64::ReadRegisterSet(uint32_t set) {
+ switch (set) {
+ case GPRegSet:
+ ReadGPR();
+ return 0;
+ case FPRegSet:
+ ReadFPR();
+ return 0;
+ default:
+ break;
+ }
+ return -1;
+}
+
+int NativeRegisterContextOpenBSD_arm64::WriteRegisterSet(uint32_t set) {
+ switch (set) {
+ case GPRegSet:
+ WriteGPR();
+ return 0;
+ case FPRegSet:
+ WriteFPR();
+ return 0;
+ default:
+ break;
+ }
+ return -1;
+}
+
+#endif // defined(__arm64__) || defined(__aarch64__)
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.h b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.h
new file mode 100644
index 00000000000..8dc482c61c0
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_arm64.h
@@ -0,0 +1,87 @@
+//===-- NativeRegisterContextOpenBSD_arm64.h --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm64__) || defined(__aarch64__)
+
+#ifndef lldb_NativeRegisterContextOpenBSD_arm64_h
+#define lldb_NativeRegisterContextOpenBSD_arm64_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.h"
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
+
+namespace lldb_private {
+namespace process_openbsd {
+
+class NativeProcessOpenBSD;
+
+class NativeRegisterContextOpenBSD_arm64 : public NativeRegisterContextOpenBSD {
+public:
+ NativeRegisterContextOpenBSD_arm64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+ // NativeRegisterContextOpenBSD_arm64 subclasses NativeRegisterContextOpenBSD,
+ // which is a subclass of NativeRegisterContextRegisterInfo, which is a
+ // subclass of NativeRegisterContext.
+ //
+ // NativeRegisterContextOpenBSD defines an interface for reading and writing
+ // registers using the system ptrace API. Subclasses of NativeRegisterContextOpenBSD
+ // do not need to implement any of the interface defined by NativeRegisterContextOpenBSD,
+ // since it is not machine dependent, but they do have to implement a bunch
+ // of stuff from the NativeRegisterContext. Some of this is handled by a
+ // generic implementation in NativeRegisterContextRegisterInfo, but most of
+ // but most of it has to be implemented here.
+
+ size_t GetGPRSize() override { return sizeof(m_gpr); }
+ size_t GetFPRSize() override { return sizeof(m_fpr); }
+
+ uint32_t GetUserRegisterCount() const override;
+
+ uint32_t GetRegisterSetCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+protected:
+ void *GetGPRBuffer() override { return &m_gpr; }
+ void *GetFPRBuffer() override { return &m_fpr; }
+
+private:
+ // Private member types.
+ enum { GPRegSet, FPRegSet };
+
+ // Private member variables.
+ struct reg m_gpr;
+ struct fpreg m_fpr;
+
+ int GetSetForNativeRegNum(int reg_num) const;
+
+ int ReadRegisterSet(uint32_t set);
+ int WriteRegisterSet(uint32_t set);
+};
+
+} // namespace process_openbsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextOpenBSD_arm64_h
+
+#endif // defined(__arm64__) || defined(__aarch64__)
diff --git a/gnu/usr.bin/clang/liblldbPluginProcess/Makefile b/gnu/usr.bin/clang/liblldbPluginProcess/Makefile
index 6754da12412..4dd1a5c3aaf 100644
--- a/gnu/usr.bin/clang/liblldbPluginProcess/Makefile
+++ b/gnu/usr.bin/clang/liblldbPluginProcess/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.5 2019/11/27 17:25:03 mortimer Exp $
+# $OpenBSD: Makefile,v 1.6 2019/12/21 13:16:25 mortimer Exp $
LIB= lldbPluginProcess
NOPIC=
@@ -30,6 +30,7 @@ SRCS= CrashReason.cpp \
NativeProcessOpenBSD.cpp \
NativeRegisterContextOpenBSD.cpp \
NativeRegisterContextOpenBSD_x86_64.cpp \
+ NativeRegisterContextOpenBSD_arm64.cpp \
NativeRegisterContextRegisterInfo.cpp \
NativeThreadOpenBSD.cpp \
NetBSDSignals.cpp \