[Lldb-commits] [lldb] r374866 - [LLDB] [Windows] Initial support for ARM64 register contexts

Martin Storsjo via lldb-commits lldb-commits at lists.llvm.org
Tue Oct 15 01:31:52 PDT 2019


Author: mstorsjo
Date: Tue Oct 15 01:31:52 2019
New Revision: 374866

URL: http://llvm.org/viewvc/llvm-project?rev=374866&view=rev
Log:
[LLDB] [Windows] Initial support for ARM64 register contexts

Differential Revision: https://reviews.llvm.org/D67954

Added:
    lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h
    lldb/trunk/source/Plugins/Process/Windows/Common/arm64/
    lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.h
    lldb/trunk/test/Shell/Register/Inputs/aarch64-fp-read.cpp
    lldb/trunk/test/Shell/Register/Inputs/aarch64-gp-read.cpp
    lldb/trunk/test/Shell/Register/aarch64-fp-read.test
    lldb/trunk/test/Shell/Register/aarch64-gp-read.test
Modified:
    lldb/trunk/source/Plugins/Process/Windows/Common/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/CMakeLists.txt?rev=374866&r1=374865&r2=374866&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/CMakeLists.txt Tue Oct 15 01:31:52 2019
@@ -4,6 +4,7 @@ add_lldb_library(lldbPluginProcessWindow
   LocalDebugDelegate.cpp
   NativeProcessWindows.cpp
   NativeRegisterContextWindows.cpp
+  NativeRegisterContextWindows_arm64.cpp
   NativeRegisterContextWindows_i386.cpp
   NativeRegisterContextWindows_WoW64.cpp
   NativeRegisterContextWindows_x86_64.cpp
@@ -13,9 +14,10 @@ add_lldb_library(lldbPluginProcessWindow
   ProcessWindowsLog.cpp
   RegisterContextWindows.cpp
   TargetThreadWindows.cpp
+  arm64/RegisterContextWindows_arm64.cpp
   x64/RegisterContextWindows_x64.cpp
   x86/RegisterContextWindows_x86.cpp
-  # TODO add support for ARM (NT) and ARM64
+  # TODO add support for ARM (NT)
 
   LINK_LIBS
     lldbCore

Added: lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp?rev=374866&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp Tue Oct 15 01:31:52 2019
@@ -0,0 +1,755 @@
+//===-- NativeRegisterContextWindows_arm64.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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+
+#include "NativeRegisterContextWindows_arm64.h"
+#include "NativeThreadWindows.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "ProcessWindowsLog.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/windows/HostThreadWindows.h"
+#include "lldb/Host/windows/windows.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+#define REG_CONTEXT_SIZE sizeof(::CONTEXT)
+
+namespace {
+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 set must be terminated 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");
+
+static const uint32_t g_fpr_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 set must be terminated with this flag
+};
+static_assert(((sizeof g_fpr_regnums_arm64 / sizeof g_fpr_regnums_arm64[0]) -
+               1) == k_num_fpr_registers_arm64,
+              "g_fpu_regnums_arm64 has wrong number of register infos");
+
+static const RegisterSet g_reg_sets_arm64[] = {
+    {"General Purpose Registers", "gpr",
+     llvm::array_lengthof(g_gpr_regnums_arm64) - 1, g_gpr_regnums_arm64},
+    {"Floating Point Registers", "fpr",
+     llvm::array_lengthof(g_fpr_regnums_arm64) - 1, g_fpr_regnums_arm64},
+};
+
+enum { k_num_register_sets = 2 };
+
+} // namespace
+
+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 Status GetThreadContextHelper(lldb::thread_t thread_handle,
+                                     PCONTEXT context_ptr,
+                                     const DWORD control_flag) {
+  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
+  Status error;
+
+  memset(context_ptr, 0, sizeof(::CONTEXT));
+  context_ptr->ContextFlags = control_flag;
+  if (!::GetThreadContext(thread_handle, context_ptr)) {
+    error.SetError(GetLastError(), eErrorTypeWin32);
+    LLDB_LOG(log, "{0} GetThreadContext failed with error {1}", __FUNCTION__,
+             error);
+    return error;
+  }
+  return Status();
+}
+
+static Status SetThreadContextHelper(lldb::thread_t thread_handle,
+                                     PCONTEXT context_ptr) {
+  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
+  Status error;
+  // It's assumed that the thread has stopped.
+  if (!::SetThreadContext(thread_handle, context_ptr)) {
+    error.SetError(GetLastError(), eErrorTypeWin32);
+    LLDB_LOG(log, "{0} SetThreadContext failed with error {1}", __FUNCTION__,
+             error);
+    return error;
+  }
+  return Status();
+}
+
+std::unique_ptr<NativeRegisterContextWindows>
+NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+  // TODO: Register context for a WoW64 application?
+
+  // Register context for a native 64-bit application.
+  return std::make_unique<NativeRegisterContextWindows_arm64>(target_arch,
+                                                              native_thread);
+}
+
+NativeRegisterContextWindows_arm64::NativeRegisterContextWindows_arm64(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+    : NativeRegisterContextWindows(native_thread,
+                                   CreateRegisterInfoInterface(target_arch)) {}
+
+bool NativeRegisterContextWindows_arm64::IsGPR(uint32_t reg_index) const {
+  return (reg_index >= k_first_gpr_arm64 && reg_index <= k_last_gpr_arm64);
+}
+
+bool NativeRegisterContextWindows_arm64::IsFPR(uint32_t reg_index) const {
+  return (reg_index >= k_first_fpr_arm64 && reg_index <= k_last_fpr_arm64);
+}
+
+uint32_t NativeRegisterContextWindows_arm64::GetRegisterSetCount() const {
+  return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextWindows_arm64::GetRegisterSet(uint32_t set_index) const {
+  if (set_index >= k_num_register_sets)
+    return nullptr;
+  return &g_reg_sets_arm64[set_index];
+}
+
+Status NativeRegisterContextWindows_arm64::GPRRead(const uint32_t reg,
+                                                   RegisterValue &reg_value) {
+  ::CONTEXT tls_context;
+  DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
+  Status error =
+      GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
+  if (error.Fail())
+    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.SetUInt64(tls_context.X[reg - gpr_x0_arm64]);
+    break;
+
+  case gpr_fp_arm64:
+    reg_value.SetUInt64(tls_context.Fp);
+    break;
+  case gpr_sp_arm64:
+    reg_value.SetUInt64(tls_context.Sp);
+    break;
+  case gpr_lr_arm64:
+    reg_value.SetUInt64(tls_context.Lr);
+    break;
+  case gpr_pc_arm64:
+    reg_value.SetUInt64(tls_context.Pc);
+    break;
+  case gpr_cpsr_arm64:
+    reg_value.SetUInt64(tls_context.Cpsr);
+    break;
+
+  case gpr_w0_arm64:
+  case gpr_w1_arm64:
+  case gpr_w2_arm64:
+  case gpr_w3_arm64:
+  case gpr_w4_arm64:
+  case gpr_w5_arm64:
+  case gpr_w6_arm64:
+  case gpr_w7_arm64:
+  case gpr_w8_arm64:
+  case gpr_w9_arm64:
+  case gpr_w10_arm64:
+  case gpr_w11_arm64:
+  case gpr_w12_arm64:
+  case gpr_w13_arm64:
+  case gpr_w14_arm64:
+  case gpr_w15_arm64:
+  case gpr_w16_arm64:
+  case gpr_w17_arm64:
+  case gpr_w18_arm64:
+  case gpr_w19_arm64:
+  case gpr_w20_arm64:
+  case gpr_w21_arm64:
+  case gpr_w22_arm64:
+  case gpr_w23_arm64:
+  case gpr_w24_arm64:
+  case gpr_w25_arm64:
+  case gpr_w26_arm64:
+  case gpr_w27_arm64:
+  case gpr_w28_arm64:
+    reg_value.SetUInt32(
+        static_cast<uint32_t>(tls_context.X[reg - gpr_w0_arm64] & 0xffffffff));
+    break;
+  }
+
+  return error;
+}
+
+Status
+NativeRegisterContextWindows_arm64::GPRWrite(const uint32_t reg,
+                                             const RegisterValue &reg_value) {
+  ::CONTEXT tls_context;
+  DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
+  auto thread_handle = GetThreadHandle();
+  Status error =
+      GetThreadContextHelper(thread_handle, &tls_context, context_flag);
+  if (error.Fail())
+    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:
+    tls_context.X[reg - gpr_x0_arm64] = reg_value.GetAsUInt64();
+    break;
+
+  case gpr_fp_arm64:
+    tls_context.Fp = reg_value.GetAsUInt64();
+    break;
+  case gpr_sp_arm64:
+    tls_context.Sp = reg_value.GetAsUInt64();
+    break;
+  case gpr_lr_arm64:
+    tls_context.Lr = reg_value.GetAsUInt64();
+    break;
+  case gpr_pc_arm64:
+    tls_context.Pc = reg_value.GetAsUInt64();
+    break;
+  case gpr_cpsr_arm64:
+    tls_context.Cpsr = reg_value.GetAsUInt64();
+    break;
+
+  case gpr_w0_arm64:
+  case gpr_w1_arm64:
+  case gpr_w2_arm64:
+  case gpr_w3_arm64:
+  case gpr_w4_arm64:
+  case gpr_w5_arm64:
+  case gpr_w6_arm64:
+  case gpr_w7_arm64:
+  case gpr_w8_arm64:
+  case gpr_w9_arm64:
+  case gpr_w10_arm64:
+  case gpr_w11_arm64:
+  case gpr_w12_arm64:
+  case gpr_w13_arm64:
+  case gpr_w14_arm64:
+  case gpr_w15_arm64:
+  case gpr_w16_arm64:
+  case gpr_w17_arm64:
+  case gpr_w18_arm64:
+  case gpr_w19_arm64:
+  case gpr_w20_arm64:
+  case gpr_w21_arm64:
+  case gpr_w22_arm64:
+  case gpr_w23_arm64:
+  case gpr_w24_arm64:
+  case gpr_w25_arm64:
+  case gpr_w26_arm64:
+  case gpr_w27_arm64:
+  case gpr_w28_arm64:
+    tls_context.X[reg - gpr_w0_arm64] = reg_value.GetAsUInt32();
+    break;
+  }
+
+  return SetThreadContextHelper(thread_handle, &tls_context);
+}
+
+Status NativeRegisterContextWindows_arm64::FPRRead(const uint32_t reg,
+                                                   RegisterValue &reg_value) {
+  ::CONTEXT tls_context;
+  DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
+  Status error =
+      GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
+  if (error.Fail())
+    return error;
+
+  switch (reg) {
+  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.SetBytes(tls_context.V[reg - fpu_v0_arm64].B, 16,
+                       endian::InlHostByteOrder());
+    break;
+
+  case fpu_s0_arm64:
+  case fpu_s1_arm64:
+  case fpu_s2_arm64:
+  case fpu_s3_arm64:
+  case fpu_s4_arm64:
+  case fpu_s5_arm64:
+  case fpu_s6_arm64:
+  case fpu_s7_arm64:
+  case fpu_s8_arm64:
+  case fpu_s9_arm64:
+  case fpu_s10_arm64:
+  case fpu_s11_arm64:
+  case fpu_s12_arm64:
+  case fpu_s13_arm64:
+  case fpu_s14_arm64:
+  case fpu_s15_arm64:
+  case fpu_s16_arm64:
+  case fpu_s17_arm64:
+  case fpu_s18_arm64:
+  case fpu_s19_arm64:
+  case fpu_s20_arm64:
+  case fpu_s21_arm64:
+  case fpu_s22_arm64:
+  case fpu_s23_arm64:
+  case fpu_s24_arm64:
+  case fpu_s25_arm64:
+  case fpu_s26_arm64:
+  case fpu_s27_arm64:
+  case fpu_s28_arm64:
+  case fpu_s29_arm64:
+  case fpu_s30_arm64:
+  case fpu_s31_arm64:
+    reg_value.SetFloat(tls_context.V[reg - fpu_s0_arm64].S[0]);
+    break;
+
+  case fpu_d0_arm64:
+  case fpu_d1_arm64:
+  case fpu_d2_arm64:
+  case fpu_d3_arm64:
+  case fpu_d4_arm64:
+  case fpu_d5_arm64:
+  case fpu_d6_arm64:
+  case fpu_d7_arm64:
+  case fpu_d8_arm64:
+  case fpu_d9_arm64:
+  case fpu_d10_arm64:
+  case fpu_d11_arm64:
+  case fpu_d12_arm64:
+  case fpu_d13_arm64:
+  case fpu_d14_arm64:
+  case fpu_d15_arm64:
+  case fpu_d16_arm64:
+  case fpu_d17_arm64:
+  case fpu_d18_arm64:
+  case fpu_d19_arm64:
+  case fpu_d20_arm64:
+  case fpu_d21_arm64:
+  case fpu_d22_arm64:
+  case fpu_d23_arm64:
+  case fpu_d24_arm64:
+  case fpu_d25_arm64:
+  case fpu_d26_arm64:
+  case fpu_d27_arm64:
+  case fpu_d28_arm64:
+  case fpu_d29_arm64:
+  case fpu_d30_arm64:
+  case fpu_d31_arm64:
+    reg_value.SetDouble(tls_context.V[reg - fpu_d0_arm64].D[0]);
+    break;
+
+  case fpu_fpsr_arm64:
+    reg_value.SetUInt32(tls_context.Fpsr);
+    break;
+
+  case fpu_fpcr_arm64:
+    reg_value.SetUInt32(tls_context.Fpcr);
+    break;
+  }
+
+  return error;
+}
+
+Status
+NativeRegisterContextWindows_arm64::FPRWrite(const uint32_t reg,
+                                             const RegisterValue &reg_value) {
+  ::CONTEXT tls_context;
+  DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
+  auto thread_handle = GetThreadHandle();
+  Status error =
+      GetThreadContextHelper(thread_handle, &tls_context, context_flag);
+  if (error.Fail())
+    return error;
+
+  switch (reg) {
+  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:
+    memcpy(tls_context.V[reg - fpu_v0_arm64].B, reg_value.GetBytes(), 16);
+    break;
+
+  case fpu_s0_arm64:
+  case fpu_s1_arm64:
+  case fpu_s2_arm64:
+  case fpu_s3_arm64:
+  case fpu_s4_arm64:
+  case fpu_s5_arm64:
+  case fpu_s6_arm64:
+  case fpu_s7_arm64:
+  case fpu_s8_arm64:
+  case fpu_s9_arm64:
+  case fpu_s10_arm64:
+  case fpu_s11_arm64:
+  case fpu_s12_arm64:
+  case fpu_s13_arm64:
+  case fpu_s14_arm64:
+  case fpu_s15_arm64:
+  case fpu_s16_arm64:
+  case fpu_s17_arm64:
+  case fpu_s18_arm64:
+  case fpu_s19_arm64:
+  case fpu_s20_arm64:
+  case fpu_s21_arm64:
+  case fpu_s22_arm64:
+  case fpu_s23_arm64:
+  case fpu_s24_arm64:
+  case fpu_s25_arm64:
+  case fpu_s26_arm64:
+  case fpu_s27_arm64:
+  case fpu_s28_arm64:
+  case fpu_s29_arm64:
+  case fpu_s30_arm64:
+  case fpu_s31_arm64:
+    tls_context.V[reg - fpu_s0_arm64].S[0] = reg_value.GetAsFloat();
+    break;
+
+  case fpu_d0_arm64:
+  case fpu_d1_arm64:
+  case fpu_d2_arm64:
+  case fpu_d3_arm64:
+  case fpu_d4_arm64:
+  case fpu_d5_arm64:
+  case fpu_d6_arm64:
+  case fpu_d7_arm64:
+  case fpu_d8_arm64:
+  case fpu_d9_arm64:
+  case fpu_d10_arm64:
+  case fpu_d11_arm64:
+  case fpu_d12_arm64:
+  case fpu_d13_arm64:
+  case fpu_d14_arm64:
+  case fpu_d15_arm64:
+  case fpu_d16_arm64:
+  case fpu_d17_arm64:
+  case fpu_d18_arm64:
+  case fpu_d19_arm64:
+  case fpu_d20_arm64:
+  case fpu_d21_arm64:
+  case fpu_d22_arm64:
+  case fpu_d23_arm64:
+  case fpu_d24_arm64:
+  case fpu_d25_arm64:
+  case fpu_d26_arm64:
+  case fpu_d27_arm64:
+  case fpu_d28_arm64:
+  case fpu_d29_arm64:
+  case fpu_d30_arm64:
+  case fpu_d31_arm64:
+    tls_context.V[reg - fpu_d0_arm64].D[0] = reg_value.GetAsDouble();
+    break;
+
+  case fpu_fpsr_arm64:
+    tls_context.Fpsr = reg_value.GetAsUInt32();
+    break;
+
+  case fpu_fpcr_arm64:
+    tls_context.Fpcr = reg_value.GetAsUInt32();
+    break;
+  }
+
+  return SetThreadContextHelper(thread_handle, &tls_context);
+}
+
+Status
+NativeRegisterContextWindows_arm64::ReadRegister(const RegisterInfo *reg_info,
+                                                 RegisterValue &reg_value) {
+  Status error;
+  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;
+  }
+
+  if (IsGPR(reg))
+    return GPRRead(reg, reg_value);
+
+  if (IsFPR(reg))
+    return FPRRead(reg, reg_value);
+
+  return Status("unimplemented");
+}
+
+Status NativeRegisterContextWindows_arm64::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+  Status error;
+
+  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 written.
+    error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+                                   "register, cannot write directly",
+                                   reg_info->name);
+    return error;
+  }
+
+  if (IsGPR(reg))
+    return GPRWrite(reg, reg_value);
+
+  if (IsFPR(reg))
+    return FPRWrite(reg, reg_value);
+
+  return Status("unimplemented");
+}
+
+Status NativeRegisterContextWindows_arm64::ReadAllRegisterValues(
+    lldb::DataBufferSP &data_sp) {
+  const size_t data_size = REG_CONTEXT_SIZE;
+  data_sp = std::make_shared<DataBufferHeap>(data_size, 0);
+  ::CONTEXT tls_context;
+  Status error =
+      GetThreadContextHelper(GetThreadHandle(), &tls_context, CONTEXT_ALL);
+  if (error.Fail())
+    return error;
+
+  uint8_t *dst = data_sp->GetBytes();
+  ::memcpy(dst, &tls_context, data_size);
+  return error;
+}
+
+Status NativeRegisterContextWindows_arm64::WriteAllRegisterValues(
+    const lldb::DataBufferSP &data_sp) {
+  Status error;
+  const size_t data_size = REG_CONTEXT_SIZE;
+  if (!data_sp) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextWindows_arm64::%s invalid data_sp provided",
+        __FUNCTION__);
+    return error;
+  }
+
+  if (data_sp->GetByteSize() != data_size) {
+    error.SetErrorStringWithFormatv(
+        "data_sp contained mismatched data size, expected {0}, actual {1}",
+        data_size, data_sp->GetByteSize());
+    return error;
+  }
+
+  ::CONTEXT tls_context;
+  memcpy(&tls_context, data_sp->GetBytes(), data_size);
+  return SetThreadContextHelper(GetThreadHandle(), &tls_context);
+}
+
+Status NativeRegisterContextWindows_arm64::IsWatchpointHit(uint32_t wp_index,
+                                                           bool &is_hit) {
+  return Status("unimplemented");
+}
+
+Status NativeRegisterContextWindows_arm64::GetWatchpointHitIndex(
+    uint32_t &wp_index, lldb::addr_t trap_addr) {
+  return Status("unimplemented");
+}
+
+Status NativeRegisterContextWindows_arm64::IsWatchpointVacant(uint32_t wp_index,
+                                                              bool &is_vacant) {
+  return Status("unimplemented");
+}
+
+Status NativeRegisterContextWindows_arm64::SetHardwareWatchpointWithIndex(
+    lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+  return Status("unimplemented");
+}
+
+bool NativeRegisterContextWindows_arm64::ClearHardwareWatchpoint(
+    uint32_t wp_index) {
+  return false;
+}
+
+Status NativeRegisterContextWindows_arm64::ClearAllHardwareWatchpoints() {
+  return Status("unimplemented");
+}
+
+uint32_t NativeRegisterContextWindows_arm64::SetHardwareWatchpoint(
+    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+  return LLDB_INVALID_INDEX32;
+}
+
+lldb::addr_t
+NativeRegisterContextWindows_arm64::GetWatchpointAddress(uint32_t wp_index) {
+  return LLDB_INVALID_ADDRESS;
+}
+
+uint32_t NativeRegisterContextWindows_arm64::NumSupportedHardwareWatchpoints() {
+  // Not implemented
+  return 0;
+}
+
+#endif // defined(__aarch64__) || defined(_M_ARM64)

Added: lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h?rev=374866&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h Tue Oct 15 01:31:52 2019
@@ -0,0 +1,80 @@
+//===-- NativeRegisterContextWindows_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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+#ifndef liblldb_NativeRegisterContextWindows_arm64_h_
+#define liblldb_NativeRegisterContextWindows_arm64_h_
+
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
+
+#include "NativeRegisterContextWindows.h"
+
+namespace lldb_private {
+
+class NativeThreadWindows;
+
+class NativeRegisterContextWindows_arm64 : public NativeRegisterContextWindows {
+public:
+  NativeRegisterContextWindows_arm64(const ArchSpec &target_arch,
+                                     NativeThreadProtocol &native_thread);
+
+  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;
+
+  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 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;
+
+protected:
+  Status GPRRead(const uint32_t reg, RegisterValue &reg_value);
+
+  Status GPRWrite(const uint32_t reg, const RegisterValue &reg_value);
+
+  Status FPRRead(const uint32_t reg, RegisterValue &reg_value);
+
+  Status FPRWrite(const uint32_t reg, const RegisterValue &reg_value);
+
+private:
+  bool IsGPR(uint32_t reg_index) const;
+
+  bool IsFPR(uint32_t reg_index) const;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_NativeRegisterContextWindows_arm64_h_
+#endif // defined(__aarch64__) || defined(_M_ARM64)

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp?rev=374866&r1=374865&r2=374866&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp Tue Oct 15 01:31:52 2019
@@ -20,11 +20,13 @@
 #include "ProcessWindowsLog.h"
 #include "TargetThreadWindows.h"
 
-// TODO support _M_ARM and _M_ARM64
+// TODO support _M_ARM
 #if defined(__x86_64__) || defined(_M_AMD64)
 #include "x64/RegisterContextWindows_x64.h"
 #elif defined(__i386__) || defined(_M_IX86)
 #include "x86/RegisterContextWindows_x86.h"
+#elif defined(__aarch64__) || defined(_M_ARM64)
+#include "arm64/RegisterContextWindows_arm64.h"
 #endif
 
 using namespace lldb;
@@ -73,7 +75,12 @@ TargetThreadWindows::CreateRegisterConte
         break;
 
       case llvm::Triple::aarch64:
-        LLDB_LOG(log, "debugging ARM64 targets is currently unsupported");
+#if defined(__aarch64__) || defined(_M_ARM64)
+        m_thread_reg_ctx_sp.reset(
+            new RegisterContextWindows_arm64(*this, concrete_frame_idx));
+#else
+        LLDB_LOG(log, "debugging foreign targets is currently unsupported");
+#endif
         break;
 
       case llvm::Triple::x86:

Added: lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp?rev=374866&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp Tue Oct 15 01:31:52 2019
@@ -0,0 +1,442 @@
+//===-- RegisterContextWindows_arm64.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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+
+#include "lldb/Host/windows/HostThreadWindows.h"
+#include "lldb/Host/windows/windows.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-private-types.h"
+
+#include "RegisterContextWindows_arm64.h"
+#include "TargetThreadWindows.h"
+
+#include "llvm/ADT/STLExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+#define GPR_OFFSET(idx) 0
+#define GPR_OFFSET_NAME(reg) 0
+
+#define FPU_OFFSET(idx) 0
+#define FPU_OFFSET_NAME(reg) 0
+
+#define EXC_OFFSET_NAME(reg) 0
+#define DBG_OFFSET_NAME(reg) 0
+
+#define DEFINE_DBG(reg, i)                                                     \
+  #reg, NULL,                                                                  \
+      0, 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, 0
+
+// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
+#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
+#include "Plugins/Process/Utility/RegisterInfos_arm64.h"
+#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
+
+static size_t k_num_register_infos =
+    llvm::array_lengthof(g_register_infos_arm64_le);
+
+// Array of lldb register numbers used to define the set of all General Purpose
+// Registers
+uint32_t g_gpr_reg_indices[] = {
+    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,
+};
+
+uint32_t g_fpu_reg_indices[] = {
+    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,
+};
+
+RegisterSet g_register_sets[] = {
+    {"General Purpose Registers", "gpr",
+     llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
+    {"Floating Point Registers", "fpu", llvm::array_lengthof(g_fpu_reg_indices),
+     g_fpu_reg_indices},
+};
+
+// Constructors and Destructors
+RegisterContextWindows_arm64::RegisterContextWindows_arm64(
+    Thread &thread, uint32_t concrete_frame_idx)
+    : RegisterContextWindows(thread, concrete_frame_idx) {}
+
+RegisterContextWindows_arm64::~RegisterContextWindows_arm64() {}
+
+size_t RegisterContextWindows_arm64::GetRegisterCount() {
+  return llvm::array_lengthof(g_register_infos_arm64_le);
+}
+
+const RegisterInfo *
+RegisterContextWindows_arm64::GetRegisterInfoAtIndex(size_t reg) {
+  if (reg < k_num_register_infos)
+    return &g_register_infos_arm64_le[reg];
+  return NULL;
+}
+
+size_t RegisterContextWindows_arm64::GetRegisterSetCount() {
+  return llvm::array_lengthof(g_register_sets);
+}
+
+const RegisterSet *
+RegisterContextWindows_arm64::GetRegisterSet(size_t reg_set) {
+  return &g_register_sets[reg_set];
+}
+
+bool RegisterContextWindows_arm64::ReadRegister(const RegisterInfo *reg_info,
+                                                RegisterValue &reg_value) {
+  if (!CacheAllRegisterValues())
+    return false;
+
+  if (reg_info == nullptr)
+    return false;
+
+  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+  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:
+    reg_value.SetUInt64(m_context.X[reg - gpr_x0]);
+    break;
+
+  case gpr_fp:
+    reg_value.SetUInt64(m_context.Fp);
+    break;
+  case gpr_sp:
+    reg_value.SetUInt64(m_context.Sp);
+    break;
+  case gpr_lr:
+    reg_value.SetUInt64(m_context.Lr);
+    break;
+  case gpr_pc:
+    reg_value.SetUInt64(m_context.Pc);
+    break;
+  case gpr_cpsr:
+    reg_value.SetUInt64(m_context.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:
+    reg_value.SetUInt32(
+        static_cast<uint32_t>(m_context.X[reg - gpr_w0] & 0xffffffff));
+    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:
+    reg_value.SetBytes(m_context.V[reg - fpu_v0].B, 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:
+    reg_value.SetFloat(m_context.V[reg - fpu_s0].S[0]);
+    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:
+    reg_value.SetDouble(m_context.V[reg - fpu_d0].D[0]);
+    break;
+
+  case fpu_fpsr:
+    reg_value.SetUInt32(m_context.Fpsr);
+    break;
+
+  case fpu_fpcr:
+    reg_value.SetUInt32(m_context.Fpcr);
+    break;
+
+  default:
+    reg_value.SetValueToInvalid();
+    return false;
+  }
+  return true;
+}
+
+bool RegisterContextWindows_arm64::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+  // Since we cannot only write a single register value to the inferior, we
+  // need to make sure our cached copy of the register values are fresh.
+  // Otherwise when writing one register, we may also overwrite some other
+  // register with a stale value.
+  if (!CacheAllRegisterValues())
+    return false;
+
+  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+  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:
+    m_context.X[reg - gpr_x0] = reg_value.GetAsUInt64();
+    break;
+
+  case gpr_fp:
+    m_context.Fp = reg_value.GetAsUInt64();
+    break;
+  case gpr_sp:
+    m_context.Sp = reg_value.GetAsUInt64();
+    break;
+  case gpr_lr:
+    m_context.Lr = reg_value.GetAsUInt64();
+    break;
+  case gpr_pc:
+    m_context.Pc = reg_value.GetAsUInt64();
+    break;
+  case gpr_cpsr:
+    m_context.Cpsr = reg_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(m_context.V[reg - fpu_v0].B, reg_value.GetBytes(), 16);
+    break;
+
+  case fpu_fpsr:
+    m_context.Fpsr = reg_value.GetAsUInt32();
+    break;
+
+  case fpu_fpcr:
+    m_context.Fpcr = reg_value.GetAsUInt32();
+    break;
+
+  default:
+    return false;
+  }
+
+  // Physically update the registers in the target process.
+  return ApplyAllRegisterValues();
+}
+
+#endif // defined(__aarch64__) || defined(_M_ARM64)

Added: lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.h?rev=374866&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.h Tue Oct 15 01:31:52 2019
@@ -0,0 +1,47 @@
+//===-- RegisterContextWindows_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 liblldb_RegisterContextWindows_arm64_H_
+#define liblldb_RegisterContextWindows_arm64_H_
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+
+#include "RegisterContextWindows.h"
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private {
+
+class Thread;
+
+class RegisterContextWindows_arm64 : public RegisterContextWindows {
+public:
+  // Constructors and Destructors
+  RegisterContextWindows_arm64(Thread &thread, uint32_t concrete_frame_idx);
+
+  virtual ~RegisterContextWindows_arm64();
+
+  // Subclasses must override these functions
+  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 &reg_value) override;
+
+  bool WriteRegister(const RegisterInfo *reg_info,
+                     const RegisterValue &reg_value) override;
+};
+} // namespace lldb_private
+
+#endif // defined(__aarch64__) || defined(_M_ARM64)
+
+#endif // #ifndef liblldb_RegisterContextWindows_arm64_H_

Added: lldb/trunk/test/Shell/Register/Inputs/aarch64-fp-read.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Register/Inputs/aarch64-fp-read.cpp?rev=374866&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Register/Inputs/aarch64-fp-read.cpp (added)
+++ lldb/trunk/test/Shell/Register/Inputs/aarch64-fp-read.cpp Tue Oct 15 01:31:52 2019
@@ -0,0 +1,19 @@
+int main() {
+  asm volatile(
+    "fmov     d0,  #0.5\n\t"
+    "fmov     d1,  #1.5\n\t"
+    "fmov     d2,  #2.5\n\t"
+    "fmov     d3,  #3.5\n\t"
+    "fmov     s4,  #4.5\n\t"
+    "fmov     s5,  #5.5\n\t"
+    "fmov     s6,  #6.5\n\t"
+    "fmov     s7,  #7.5\n\t"
+    "\n\t"
+    "brk      #0\n\t"
+    :
+    :
+    : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
+  );
+
+  return 0;
+}

Added: lldb/trunk/test/Shell/Register/Inputs/aarch64-gp-read.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Register/Inputs/aarch64-gp-read.cpp?rev=374866&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Register/Inputs/aarch64-gp-read.cpp (added)
+++ lldb/trunk/test/Shell/Register/Inputs/aarch64-gp-read.cpp Tue Oct 15 01:31:52 2019
@@ -0,0 +1,47 @@
+#include <cstdint>
+
+struct alignas(16) vec_t {
+  uint64_t a, b;
+};
+
+int main() {
+  constexpr uint64_t gprs[] = {
+    0x0001020304050607,
+    0x1011121314151617,
+    0x2021222324252627,
+    0x3031323334353637,
+    0x4041424344454647,
+    0x5051525354555657,
+    0x6061626364656667,
+    0x7071727374757677,
+  };
+
+  constexpr vec_t vecs[] = {
+    { 0x0F0E0D0C0B0A0908, 0x1716151413121110, },
+    { 0x100F0E0D0C0B0A09, 0x1817161514131211, },
+    { 0x11100F0E0D0C0B0A, 0x1918171615141312, },
+    { 0x1211100F0E0D0C0B, 0x1A19181716151413, },
+    { 0x131211100F0E0D0C, 0x1B1A191817161514, },
+    { 0x14131211100F0E0D, 0x1C1B1A1918171615, },
+    { 0x1514131211100F0E, 0x1D1C1B1A19181716, },
+    { 0x161514131211100F, 0x1E1D1C1B1A191817, },
+  };
+
+  asm volatile(
+    "ldp      x0,  x1,  [%0]\n\t"
+    "ldp      x2,  x3,  [%0, #16]\n\t"
+    "ldp      x4,  x5,  [%0, #32]\n\t"
+    "ldp      x6,  x7,  [%0, #48]\n\t"
+    "\n\t"
+    "ld1      {v0.2d, v1.2d, v2.2d, v3.2d}, [%1], #64\n\t"
+    "ld1      {v4.2d, v5.2d, v6.2d, v7.2d}, [%1], #64\n\t"
+    "\n\t"
+    "brk      #0\n\t"
+    :
+    : "r"(gprs), "r"(vecs)
+    : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
+      "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
+  );
+
+  return 0;
+}

Added: lldb/trunk/test/Shell/Register/aarch64-fp-read.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Register/aarch64-fp-read.test?rev=374866&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Register/aarch64-fp-read.test (added)
+++ lldb/trunk/test/Shell/Register/aarch64-fp-read.test Tue Oct 15 01:31:52 2019
@@ -0,0 +1,21 @@
+# REQUIRES: native && target-aarch64
+# RUN: %clangxx -fomit-frame-pointer %p/Inputs/aarch64-fp-read.cpp -o %t
+# RUN: %lldb -b -s %s %t | FileCheck %s
+process launch
+
+register read d0
+register read d1
+register read d2
+register read d3
+register read s4
+register read s5
+register read s6
+register read s7
+# CHECK-DAG: d0 = 0.5
+# CHECK-DAG: d1 = 1.5
+# CHECK-DAG: d2 = 2.5
+# CHECK-DAG: d3 = 3.5
+# CHECK-DAG: s4 = 4.5
+# CHECK-DAG: s5 = 5.5
+# CHECK-DAG: s6 = 6.5
+# CHECK-DAG: s7 = 7.5

Added: lldb/trunk/test/Shell/Register/aarch64-gp-read.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Register/aarch64-gp-read.test?rev=374866&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Register/aarch64-gp-read.test (added)
+++ lldb/trunk/test/Shell/Register/aarch64-gp-read.test Tue Oct 15 01:31:52 2019
@@ -0,0 +1,24 @@
+# REQUIRES: native && target-aarch64
+# RUN: %clangxx -fomit-frame-pointer %p/Inputs/aarch64-gp-read.cpp -o %t
+# RUN: %lldb -b -s %s %t | FileCheck %s
+process launch
+
+register read --all
+# CHECK-DAG: x0 = 0x0001020304050607
+# CHECK-DAG: x1 = 0x1011121314151617
+# CHECK-DAG: x2 = 0x2021222324252627
+# CHECK-DAG: x3 = 0x3031323334353637
+# CHECK-DAG: x4 = 0x4041424344454647
+# CHECK-DAG: x5 = 0x5051525354555657
+# CHECK-DAG: x6 = 0x6061626364656667
+# CHECK-DAG: x7 = 0x7071727374757677
+# CHECK-DAG: w0 = 0x04050607
+
+# CHECK-DAG: v0 = {0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17}
+# CHECK-DAG: v1 = {0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18}
+# CHECK-DAG: v2 = {0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19}
+# CHECK-DAG: v3 = {0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a}
+# CHECK-DAG: v4 = {0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b}
+# CHECK-DAG: v5 = {0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c}
+# CHECK-DAG: v6 = {0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d}
+# CHECK-DAG: v7 = {0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e}




More information about the lldb-commits mailing list