[llvm-branch-commits] [lldb] d5317b4 - [Process/NetBSD] Copy changes from FreeBSDRemote and reformat

Michał Górny via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Jan 2 10:19:11 PST 2021


Author: Michał Górny
Date: 2021-01-02T19:15:12+01:00
New Revision: d5317b41c5857df4d4b2a382abcd58b81d2dcb18

URL: https://github.com/llvm/llvm-project/commit/d5317b41c5857df4d4b2a382abcd58b81d2dcb18
DIFF: https://github.com/llvm/llvm-project/commit/d5317b41c5857df4d4b2a382abcd58b81d2dcb18.diff

LOG: [Process/NetBSD] Copy changes from FreeBSDRemote and reformat

Copy changes, including:

- NativeProcessNetBSD::GetLoadedModuleFileSpec()
  and NativeProcessNetBSD::GetFileLoadAddress() methods

- split x86 register sets by CPU extensions

- use offset/size-based register reading/writing

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

Added: 
    

Modified: 
    lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
    lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
    lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
    lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
    lldb/test/API/python_api/lldbutil/iter/TestRegistersIterator.py
    lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
    lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 75d0d0a37fae..57f0eb3cceb6 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -213,7 +213,7 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
 
   LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}, si_code = {2}", pid,
            info.psi_lwpid, info.psi_siginfo.si_code);
-  NativeThreadNetBSD* thread = nullptr;
+  NativeThreadNetBSD *thread = nullptr;
 
   if (info.psi_lwpid > 0) {
     for (const auto &t : m_threads) {
@@ -224,8 +224,7 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
       static_cast<NativeThreadNetBSD *>(t.get())->SetStoppedWithNoReason();
     }
     if (!thread)
-      LLDB_LOG(log,
-               "thread not found in m_threads, pid = {0}, LWP = {1}", pid,
+      LLDB_LOG(log, "thread not found in m_threads, pid = {0}, LWP = {1}", pid,
                info.psi_lwpid);
   }
 
@@ -266,30 +265,27 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
     }
 
     switch (pst.pe_report_event) {
-      case PTRACE_LWP_CREATE: {
-        LLDB_LOG(log,
-                 "monitoring new thread, pid = {0}, LWP = {1}", pid,
-                 pst.pe_lwp);
-        NativeThreadNetBSD& t = AddThread(pst.pe_lwp);
-        error = t.CopyWatchpointsFrom(
-            static_cast<NativeThreadNetBSD &>(*GetCurrentThread()));
-        if (error.Fail()) {
-          LLDB_LOG(log,
-                   "failed to copy watchpoints to new thread {0}: {1}",
-                   pst.pe_lwp, error);
-          SetState(StateType::eStateInvalid);
-          return;
-        }
-      } break;
-      case PTRACE_LWP_EXIT:
-        LLDB_LOG(log,
-                 "removing exited thread, pid = {0}, LWP = {1}", pid,
-                 pst.pe_lwp);
-        RemoveThread(pst.pe_lwp);
-        break;
+    case PTRACE_LWP_CREATE: {
+      LLDB_LOG(log, "monitoring new thread, pid = {0}, LWP = {1}", pid,
+               pst.pe_lwp);
+      NativeThreadNetBSD &t = AddThread(pst.pe_lwp);
+      error = t.CopyWatchpointsFrom(
+          static_cast<NativeThreadNetBSD &>(*GetCurrentThread()));
+      if (error.Fail()) {
+        LLDB_LOG(log, "failed to copy watchpoints to new thread {0}: {1}",
+                 pst.pe_lwp, error);
+        SetState(StateType::eStateInvalid);
+        return;
+      }
+    } break;
+    case PTRACE_LWP_EXIT:
+      LLDB_LOG(log, "removing exited thread, pid = {0}, LWP = {1}", pid,
+               pst.pe_lwp);
+      RemoveThread(pst.pe_lwp);
+      break;
     }
 
-    error = PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void*>(1), 0);
+    error = PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
     if (error.Fail())
       SetState(StateType::eStateInvalid);
     return;
@@ -301,12 +297,13 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
     auto &regctx = static_cast<NativeRegisterContextNetBSD &>(
         thread->GetRegisterContext());
     uint32_t wp_index = LLDB_INVALID_INDEX32;
-    Status error = regctx.GetWatchpointHitIndex(wp_index,
-        (uintptr_t)info.psi_siginfo.si_addr);
+    Status error = regctx.GetWatchpointHitIndex(
+        wp_index, (uintptr_t)info.psi_siginfo.si_addr);
     if (error.Fail())
       LLDB_LOG(log,
                "received error while checking for watchpoint hits, pid = "
-               "{0}, LWP = {1}, error = {2}", pid, info.psi_lwpid, error);
+               "{0}, LWP = {1}, error = {2}",
+               pid, info.psi_lwpid, error);
     if (wp_index != LLDB_INVALID_INDEX32) {
       thread->SetStoppedByWatchpoint(wp_index);
       regctx.ClearWatchpointHit(wp_index);
@@ -494,16 +491,14 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
     signal = siginfo->psi_siginfo.si_signo;
   }
 
-  ret = PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1),
-                      signal);
+  ret =
+      PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), signal);
   if (ret.Success())
     SetState(eStateRunning, true);
   return ret;
 }
 
-Status NativeProcessNetBSD::Halt() {
-  return PtraceWrapper(PT_STOP, GetID());
-}
+Status NativeProcessNetBSD::Halt() { return PtraceWrapper(PT_STOP, GetID()); }
 
 Status NativeProcessNetBSD::Detach() {
   Status error;
@@ -667,8 +662,8 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
     if (vm[i].kve_path[0])
       info.SetName(vm[i].kve_path);
 
-    m_mem_region_cache.emplace_back(
-        info, FileSpec(info.GetName().GetCString()));
+    m_mem_region_cache.emplace_back(info,
+                                    FileSpec(info.GetName().GetCString()));
   }
   free(vm);
 
@@ -706,21 +701,47 @@ Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
 
 Status NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path,
                                                     FileSpec &file_spec) {
-  return Status("Unimplemented");
+  Status error = PopulateMemoryRegionCache();
+  if (error.Fail())
+    return error;
+
+  FileSpec module_file_spec(module_path);
+  FileSystem::Instance().Resolve(module_file_spec);
+
+  file_spec.Clear();
+  for (const auto &it : m_mem_region_cache) {
+    if (it.second.GetFilename() == module_file_spec.GetFilename()) {
+      file_spec = it.second;
+      return Status();
+    }
+  }
+  return Status("Module file (%s) not found in process' memory map!",
+                module_file_spec.GetFilename().AsCString());
 }
 
 Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
                                                lldb::addr_t &load_addr) {
   load_addr = LLDB_INVALID_ADDRESS;
-  return Status();
+  Status error = PopulateMemoryRegionCache();
+  if (error.Fail())
+    return error;
+
+  FileSpec file(file_name);
+  for (const auto &it : m_mem_region_cache) {
+    if (it.second == file) {
+      load_addr = it.first.GetRange().GetRangeBase();
+      return Status();
+    }
+  }
+  return Status("No load address found for file %s.", file_name.str().c_str());
 }
 
 void NativeProcessNetBSD::SigchldHandler() {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
   // Process all pending waitpid notifications.
   int status;
-  ::pid_t wait_pid =
-      llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WALLSIG | WNOHANG);
+  ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status,
+                                                 WALLSIG | WNOHANG);
 
   if (wait_pid == 0)
     return; // We are done.
@@ -802,8 +823,8 @@ Status NativeProcessNetBSD::Attach() {
   int wstatus;
   // Need to use WALLSIG otherwise we receive an error with errno=ECHLD At this
   // point we should have a thread stopped if waitpid succeeds.
-  if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid,
-          m_pid, nullptr, WALLSIG)) < 0)
+  if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid, m_pid, nullptr,
+                                             WALLSIG)) < 0)
     return Status(errno, eErrorTypePOSIX);
 
   // Initialize threads and tracing status
@@ -911,7 +932,8 @@ NativeProcessNetBSD::GetAuxvData() const {
 Status NativeProcessNetBSD::SetupTrace() {
   // Enable event reporting
   ptrace_event_t events;
-  Status status = PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
+  Status status =
+      PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
   // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN?

diff  --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index bf35a6a23b9a..3d59a4f72e94 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -69,9 +69,13 @@ class NativeProcessNetBSD : public NativeProcessELF {
   Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
                        bool hardware) override;
 
+  // The two following methods are probably not necessary and probably
+  // will never be called.  Nevertheless, we implement them right now
+  // to reduce the 
diff erences between 
diff erent platforms and reduce
+  // the risk of the lack of implementation actually breaking something,
+  // at least for the time being.
   Status GetLoadedModuleFileSpec(const char *module_path,
                                  FileSpec &file_spec) override;
-
   Status GetFileLoadAddress(const llvm::StringRef &file_name,
                             lldb::addr_t &load_addr) override;
 

diff  --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index 038dc125c853..ed1884c94a4b 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -36,6 +36,7 @@
 using namespace lldb_private;
 using namespace lldb_private::process_netbsd;
 
+// x86 64-bit general purpose registers.
 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,
@@ -81,41 +82,58 @@ static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
                   k_num_gpr_registers_x86_64,
               "g_gpr_regnums_x86_64 has wrong number of register infos");
 
-// x86 64-bit registers available via XState.
-static const uint32_t g_xstate_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_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,
+// x86 64-bit floating point registers.
+static const uint32_t g_fpu_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 need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
+                      1 ==
+                  k_num_fpr_registers_x86_64,
+              "g_fpu_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 need to end with this flag
+};
+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");
+
+static const uint32_t g_mpx_regnums_x86_64[] = {
     // Note: we currently do not provide them but this is needed to avoid
     // unnamed groups in SBFrame::GetRegisterContext().
-    lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64, lldb_bnd3_x86_64,
-    lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
+    lldb_bnd0_x86_64,   lldb_bnd1_x86_64,    lldb_bnd2_x86_64,
+    lldb_bnd3_x86_64,   lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
     LLDB_INVALID_REGNUM // register sets need to end with this flag
 };
-static_assert((sizeof(g_xstate_regnums_x86_64) /
-               sizeof(g_xstate_regnums_x86_64[0])) -
+static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
                       1 ==
-                  k_num_fpr_registers_x86_64 + k_num_avx_registers_x86_64 +
-                      k_num_mpx_registers_x86_64,
-              "g_xstate_regnums_x86_64 has wrong number of register infos");
+                  k_num_mpx_registers_x86_64,
+              "g_mpx_regnums_x86_64 has wrong number of register infos");
 
 // x86 debug registers.
 static const uint32_t g_dbr_regnums_x86_64[] = {
-    lldb_dr0_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,
+    lldb_dr0_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,
     LLDB_INVALID_REGNUM // register sets need to end with this flag
 };
 static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) -
@@ -140,8 +158,8 @@ static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
                   k_num_gpr_registers_i386,
               "g_gpr_regnums_i386 has wrong number of register infos");
 
-// x86 32-bit registers available via XState.
-static const uint32_t g_xstate_regnums_i386[] = {
+// x86 32-bit floating point registers.
+static const uint32_t g_fpu_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,
@@ -151,23 +169,39 @@ static const uint32_t g_xstate_regnums_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_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 need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
+                      1 ==
+                  k_num_fpr_registers_i386,
+              "g_fpu_regnums_i386 has wrong number of register infos");
+
+static 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 need to end with this flag
+};
+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_mpx_regnums_i386[] = {
     // Note: we currently do not provide them but this is needed to avoid
     // unnamed groups in SBFrame::GetRegisterContext().
-    lldb_bnd0_i386,      lldb_bnd1_i386,    lldb_bnd2_i386,
-    lldb_bnd3_i386,      lldb_bndcfgu_i386, lldb_bndstatus_i386,
+    lldb_bnd0_i386,     lldb_bnd1_i386,    lldb_bnd2_i386,
+    lldb_bnd3_i386,     lldb_bndcfgu_i386, lldb_bndstatus_i386,
     LLDB_INVALID_REGNUM // register sets need to end with this flag
 };
-static_assert((sizeof(g_xstate_regnums_i386) / sizeof(g_xstate_regnums_i386[0])) -
+static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
                       1 ==
-                  k_num_fpr_registers_i386 + k_num_avx_registers_i386 + k_num_mpx_registers_i386,
-              "g_xstate_regnums_i386 has wrong number of register infos");
+                  k_num_mpx_registers_i386,
+              "g_mpx_regnums_i386 has wrong number of register infos");
 
 // x86 debug registers.
 static const uint32_t g_dbr_regnums_i386[] = {
-    lldb_dr0_i386,   lldb_dr1_i386,  lldb_dr2_i386,  lldb_dr3_i386,
-    lldb_dr4_i386,   lldb_dr5_i386,  lldb_dr6_i386,  lldb_dr7_i386,
+    lldb_dr0_i386,      lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386,
+    lldb_dr4_i386,      lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386,
     LLDB_INVALID_REGNUM // register sets need to end with this flag
 };
 static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) -
@@ -175,30 +209,34 @@ static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) -
                   k_num_dbr_registers_i386,
               "g_dbr_regnums_i386 has wrong number of register infos");
 
-
 // Number of register sets provided by this context.
-enum { k_num_register_sets = 4 };
+enum { k_num_register_sets = 5 };
 
 // Register sets for x86 32-bit.
 static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
     {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
      g_gpr_regnums_i386},
-    {"Extended State Registers", "xstate",
-     k_num_avx_registers_i386 + k_num_mpx_registers_i386,
-     g_xstate_regnums_i386},
-    {"Debug Registers", "dbr", k_num_dbr_registers_i386,
-     g_dbr_regnums_i386},
+    {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
+     g_fpu_regnums_i386},
+    {"Debug Registers", "dbr", k_num_dbr_registers_i386, g_dbr_regnums_i386},
+    {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
+     g_avx_regnums_i386},
+    {"Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
+     g_mpx_regnums_i386},
 };
 
 // Register sets for x86 64-bit.
 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},
-    {"Extended State Registers", "xstate",
-     k_num_avx_registers_x86_64 + k_num_mpx_registers_x86_64,
-     g_xstate_regnums_x86_64},
+    {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
+     g_fpu_regnums_x86_64},
     {"Debug Registers", "dbr", k_num_dbr_registers_x86_64,
      g_dbr_regnums_x86_64},
+    {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
+     g_avx_regnums_x86_64},
+    {"Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64,
+     g_mpx_regnums_x86_64},
 };
 
 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize())
@@ -219,8 +257,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
   } else {
     assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
            "Register setting path assumes this is a 64-bit host");
-    // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64
-    // register context.
+    // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
+    // x86_64 register context.
     return new RegisterContextNetBSD_x86_64(target_arch);
   }
 }
@@ -229,18 +267,31 @@ NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
     : NativeRegisterContextRegisterInfo(
           native_thread, CreateRegisterInfoInterface(target_arch)),
-      m_gpr(), m_xstate(), m_dbr() {}
+      m_regset_offsets({0}) {
+  assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize());
+  std::array<uint32_t, MaxRegularRegSet + 1> first_regnos;
 
-// CONSIDER after local and llgs debugging are merged, register set support can
-// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
-uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const {
-  uint32_t sets = 0;
-  for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
-    if (GetSetForNativeRegNum(set_index) != -1)
-      ++sets;
+  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+  case llvm::Triple::x86:
+    first_regnos[FPRegSet] = lldb_fctrl_i386;
+    first_regnos[DBRegSet] = lldb_dr0_i386;
+    break;
+  case llvm::Triple::x86_64:
+    first_regnos[FPRegSet] = lldb_fctrl_x86_64;
+    first_regnos[DBRegSet] = lldb_dr0_x86_64;
+    break;
+  default:
+    llvm_unreachable("Unhandled target architecture.");
   }
 
-  return sets;
+  for (int i : {FPRegSet, DBRegSet})
+    m_regset_offsets[i] = GetRegisterInfoInterface()
+                              .GetRegisterInfo()[first_regnos[i]]
+                              .byte_offset;
+}
+
+uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const {
+  return k_num_register_sets;
 }
 
 const RegisterSet *
@@ -255,133 +306,21 @@ NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
   }
 }
 
-static constexpr int RegNumX86ToX86_64(int regnum) {
-  switch (regnum) {
-  case lldb_eax_i386:
-    return lldb_rax_x86_64;
-  case lldb_ebx_i386:
-    return lldb_rbx_x86_64;
-  case lldb_ecx_i386:
-    return lldb_rcx_x86_64;
-  case lldb_edx_i386:
-    return lldb_rdx_x86_64;
-  case lldb_edi_i386:
-    return lldb_rdi_x86_64;
-  case lldb_esi_i386:
-    return lldb_rsi_x86_64;
-  case lldb_ebp_i386:
-    return lldb_rbp_x86_64;
-  case lldb_esp_i386:
-    return lldb_rsp_x86_64;
-  case lldb_eip_i386:
-    return lldb_rip_x86_64;
-  case lldb_eflags_i386:
-    return lldb_rflags_x86_64;
-  case lldb_cs_i386:
-    return lldb_cs_x86_64;
-  case lldb_fs_i386:
-    return lldb_fs_x86_64;
-  case lldb_gs_i386:
-    return lldb_gs_x86_64;
-  case lldb_ss_i386:
-    return lldb_ss_x86_64;
-  case lldb_ds_i386:
-    return lldb_ds_x86_64;
-  case lldb_es_i386:
-    return lldb_es_x86_64;
-  case lldb_fctrl_i386:
-    return lldb_fctrl_x86_64;
-  case lldb_fstat_i386:
-    return lldb_fstat_x86_64;
-  case lldb_ftag_i386:
-    return lldb_ftag_x86_64;
-  case lldb_fop_i386:
-    return lldb_fop_x86_64;
-  case lldb_fiseg_i386:
-    return lldb_fiseg_x86_64;
-  case lldb_fioff_i386:
-    return lldb_fioff_x86_64;
-  case lldb_foseg_i386:
-    return lldb_foseg_x86_64;
-  case lldb_fooff_i386:
-    return lldb_fooff_x86_64;
-  case lldb_mxcsr_i386:
-    return lldb_mxcsr_x86_64;
-  case lldb_mxcsrmask_i386:
-    return lldb_mxcsrmask_x86_64;
-  case lldb_st0_i386:
-  case lldb_st1_i386:
-  case lldb_st2_i386:
-  case lldb_st3_i386:
-  case lldb_st4_i386:
-  case lldb_st5_i386:
-  case lldb_st6_i386:
-  case lldb_st7_i386:
-    return lldb_st0_x86_64 + regnum - lldb_st0_i386;
-  case lldb_mm0_i386:
-  case lldb_mm1_i386:
-  case lldb_mm2_i386:
-  case lldb_mm3_i386:
-  case lldb_mm4_i386:
-  case lldb_mm5_i386:
-  case lldb_mm6_i386:
-  case lldb_mm7_i386:
-    return lldb_mm0_x86_64 + regnum - lldb_mm0_i386;
-  case lldb_xmm0_i386:
-  case lldb_xmm1_i386:
-  case lldb_xmm2_i386:
-  case lldb_xmm3_i386:
-  case lldb_xmm4_i386:
-  case lldb_xmm5_i386:
-  case lldb_xmm6_i386:
-  case lldb_xmm7_i386:
-    return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386;
-  case lldb_ymm0_i386:
-  case lldb_ymm1_i386:
-  case lldb_ymm2_i386:
-  case lldb_ymm3_i386:
-  case lldb_ymm4_i386:
-  case lldb_ymm5_i386:
-  case lldb_ymm6_i386:
-  case lldb_ymm7_i386:
-    return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386;
-  case lldb_bnd0_i386:
-  case lldb_bnd1_i386:
-  case lldb_bnd2_i386:
-  case lldb_bnd3_i386:
-    return lldb_bnd0_x86_64 + regnum - lldb_bnd0_i386;
-  case lldb_bndcfgu_i386:
-    return lldb_bndcfgu_x86_64;
-  case lldb_bndstatus_i386:
-    return lldb_bndstatus_x86_64;
-  case lldb_dr0_i386:
-  case lldb_dr1_i386:
-  case lldb_dr2_i386:
-  case lldb_dr3_i386:
-  case lldb_dr4_i386:
-  case lldb_dr5_i386:
-  case lldb_dr6_i386:
-  case lldb_dr7_i386:
-    return lldb_dr0_x86_64 + regnum - lldb_dr0_i386;
-  default:
-    llvm_unreachable("Unhandled i386 register.");
-  }
-}
-
-int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
-    int reg_num) const {
+llvm::Optional<NativeRegisterContextNetBSD_x86_64::RegSetKind>
+NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
+    uint32_t reg_num) const {
   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
   case llvm::Triple::x86:
     if (reg_num >= k_first_gpr_i386 && reg_num <= k_last_gpr_i386)
       return GPRegSet;
     if (reg_num >= k_first_fpr_i386 && reg_num <= k_last_fpr_i386)
-      return XStateRegSet;
+      return FPRegSet;
     if (reg_num >= k_first_avx_i386 && reg_num <= k_last_avx_i386)
-      return XStateRegSet; // AVX
+      return YMMRegSet;
     if (reg_num >= k_first_mpxr_i386 && reg_num <= k_last_mpxr_i386)
-      return -1; // MPXR
+      return llvm::None; // MPXR
     if (reg_num >= k_first_mpxc_i386 && reg_num <= k_last_mpxc_i386)
-      return -1; // MPXC
+      return llvm::None; // MPXC
     if (reg_num >= k_first_dbr_i386 && reg_num <= k_last_dbr_i386)
       return DBRegSet; // DBR
     break;
@@ -389,13 +328,13 @@ int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
     if (reg_num >= k_first_gpr_x86_64 && reg_num <= k_last_gpr_x86_64)
       return GPRegSet;
     if (reg_num >= k_first_fpr_x86_64 && reg_num <= k_last_fpr_x86_64)
-      return XStateRegSet;
+      return FPRegSet;
     if (reg_num >= k_first_avx_x86_64 && reg_num <= k_last_avx_x86_64)
-      return XStateRegSet; // AVX
+      return YMMRegSet;
     if (reg_num >= k_first_mpxr_x86_64 && reg_num <= k_last_mpxr_x86_64)
-      return -1; // MPXR
+      return llvm::None; // MPXR
     if (reg_num >= k_first_mpxc_x86_64 && reg_num <= k_last_mpxc_x86_64)
-      return -1; // MPXC
+      return llvm::None; // MPXC
     if (reg_num >= k_first_dbr_x86_64 && reg_num <= k_last_dbr_x86_64)
       return DBRegSet; // DBR
     break;
@@ -406,27 +345,33 @@ int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
   llvm_unreachable("Register does not belong to any register set");
 }
 
-Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) {
+Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(RegSetKind set) {
   switch (set) {
   case GPRegSet:
-    return DoRegisterSet(PT_GETREGS, &m_gpr);
+    return DoRegisterSet(PT_GETREGS, m_gpr.data());
   case DBRegSet:
-    return DoRegisterSet(PT_GETDBREGS, &m_dbr);
-  case XStateRegSet: {
-    struct iovec iov = {&m_xstate, sizeof(m_xstate)};
-    return DoRegisterSet(PT_GETXSTATE, &iov);
+    return DoRegisterSet(PT_GETDBREGS, m_dbr.data());
+  case FPRegSet:
+  case YMMRegSet:
+  case MPXRegSet: {
+    struct iovec iov = {m_xstate.data(), m_xstate.size()};
+    Status ret = DoRegisterSet(PT_GETXSTATE, &iov);
+    assert(reinterpret_cast<xstate *>(m_xstate.data())->xs_rfbm & XCR0_X87);
+    return ret;
   }
   }
   llvm_unreachable("NativeRegisterContextNetBSD_x86_64::ReadRegisterSet");
 }
 
-Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) {
+Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(RegSetKind set) {
   switch (set) {
   case GPRegSet:
-    return DoRegisterSet(PT_SETREGS, &m_gpr);
+    return DoRegisterSet(PT_SETREGS, m_gpr.data());
   case DBRegSet:
-    return DoRegisterSet(PT_SETDBREGS, &m_dbr);
-  case XStateRegSet: {
+    return DoRegisterSet(PT_SETDBREGS, m_dbr.data());
+  case FPRegSet:
+  case YMMRegSet:
+  case MPXRegSet: {
     struct iovec iov = {&m_xstate, sizeof(m_xstate)};
     return DoRegisterSet(PT_SETXSTATE, &iov);
   }
@@ -454,8 +399,8 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
     return error;
   }
 
-  int set = GetSetForNativeRegNum(reg);
-  if (set == -1) {
+  llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+  if (!opt_set) {
     // This is likely an internal register for lldb use only and should not be
     // directly queried.
     error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
@@ -463,271 +408,39 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
     return error;
   }
 
-  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
-  case llvm::Triple::x86_64:
-    break;
-  case llvm::Triple::x86:
-    reg = RegNumX86ToX86_64(reg);
-    break;
-  default:
-    llvm_unreachable("Unhandled target architecture.");
-  }
-
+  RegSetKind set = opt_set.getValue();
   error = ReadRegisterSet(set);
   if (error.Fail())
     return error;
 
-  switch (reg) {
-#if defined(__x86_64__)
-  case lldb_rax_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RAX];
-    break;
-  case lldb_rbx_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RBX];
-    break;
-  case lldb_rcx_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RCX];
-    break;
-  case lldb_rdx_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RDX];
-    break;
-  case lldb_rdi_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RDI];
-    break;
-  case lldb_rsi_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RSI];
-    break;
-  case lldb_rbp_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RBP];
-    break;
-  case lldb_rsp_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RSP];
-    break;
-  case lldb_r8_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_R8];
-    break;
-  case lldb_r9_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_R9];
-    break;
-  case lldb_r10_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_R10];
-    break;
-  case lldb_r11_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_R11];
-    break;
-  case lldb_r12_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_R12];
-    break;
-  case lldb_r13_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_R13];
-    break;
-  case lldb_r14_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_R14];
-    break;
-  case lldb_r15_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_R15];
-    break;
-  case lldb_rip_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RIP];
-    break;
-  case lldb_rflags_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS];
-    break;
-  case lldb_cs_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_CS];
-    break;
-  case lldb_fs_x86_64:
-    reg_value = (uint16_t)m_gpr.regs[_REG_FS];
-    break;
-  case lldb_gs_x86_64:
-    reg_value = (uint16_t)m_gpr.regs[_REG_GS];
-    break;
-  case lldb_ss_x86_64:
-    reg_value = (uint64_t)m_gpr.regs[_REG_SS];
-    break;
-  case lldb_ds_x86_64:
-    reg_value = (uint16_t)m_gpr.regs[_REG_DS];
-    break;
-  case lldb_es_x86_64:
-    reg_value = (uint16_t)m_gpr.regs[_REG_ES];
-    break;
-#else
-  case lldb_rax_x86_64:
-    reg_value = (uint32_t)m_gpr.r_eax;
-    break;
-  case lldb_rbx_x86_64:
-    reg_value = (uint32_t)m_gpr.r_ebx;
-    break;
-  case lldb_rcx_x86_64:
-    reg_value = (uint32_t)m_gpr.r_ecx;
-    break;
-  case lldb_rdx_x86_64:
-    reg_value = (uint32_t)m_gpr.r_edx;
-    break;
-  case lldb_rdi_x86_64:
-    reg_value = (uint32_t)m_gpr.r_edi;
-    break;
-  case lldb_rsi_x86_64:
-    reg_value = (uint32_t)m_gpr.r_esi;
-    break;
-  case lldb_rsp_x86_64:
-    reg_value = (uint32_t)m_gpr.r_esp;
-    break;
-  case lldb_rbp_x86_64:
-    reg_value = (uint32_t)m_gpr.r_ebp;
-    break;
-  case lldb_rip_x86_64:
-    reg_value = (uint32_t)m_gpr.r_eip;
-    break;
-  case lldb_rflags_x86_64:
-    reg_value = (uint32_t)m_gpr.r_eflags;
-    break;
-  case lldb_cs_x86_64:
-    reg_value = (uint32_t)m_gpr.r_cs;
-    break;
-  case lldb_fs_x86_64:
-    reg_value = (uint16_t)m_gpr.r_fs;
-    break;
-  case lldb_gs_x86_64:
-    reg_value = (uint16_t)m_gpr.r_gs;
-    break;
-  case lldb_ss_x86_64:
-    reg_value = (uint32_t)m_gpr.r_ss;
-    break;
-  case lldb_ds_x86_64:
-    reg_value = (uint16_t)m_gpr.r_ds;
-    break;
-  case lldb_es_x86_64:
-    reg_value = (uint16_t)m_gpr.r_es;
-    break;
-#endif
-  case lldb_fctrl_x86_64:
-    reg_value = (uint16_t)m_xstate.xs_fxsave.fx_cw;
-    break;
-  case lldb_fstat_x86_64:
-    reg_value = (uint16_t)m_xstate.xs_fxsave.fx_sw;
-    break;
-  case lldb_ftag_x86_64: {
-    llvm::ArrayRef<MMSReg> st_regs{
-        reinterpret_cast<MMSReg *>(m_xstate.xs_fxsave.fx_87_ac), 8};
-    reg_value = (uint16_t)AbridgedToFullTagWord(
-        m_xstate.xs_fxsave.fx_tw, m_xstate.xs_fxsave.fx_sw, st_regs);
+  switch (set) {
+  case GPRegSet:
+  case FPRegSet:
+  case DBRegSet: {
+    void *data = GetOffsetRegSetData(set, reg_info->byte_offset);
+    FXSAVE *fpr = reinterpret_cast<FXSAVE *>(m_xstate.data() +
+                                             offsetof(xstate, xs_fxsave));
+    if (data == &fpr->ftag) // ftag
+      reg_value.SetUInt16(
+          AbridgedToFullTagWord(fpr->ftag, fpr->fstat, fpr->stmm));
+    else
+      reg_value.SetBytes(data, reg_info->byte_size, endian::InlHostByteOrder());
     break;
   }
-  case lldb_fop_x86_64:
-    reg_value = (uint64_t)m_xstate.xs_fxsave.fx_opcode;
-    break;
-  case lldb_fiseg_x86_64:
-    reg_value = (uint32_t)m_xstate.xs_fxsave.fx_ip.fa_32.fa_seg;
-    break;
-  case lldb_fioff_x86_64:
-    reg_value = (uint32_t)m_xstate.xs_fxsave.fx_ip.fa_32.fa_off;
-    break;
-  case lldb_fip_x86_64:
-    reg_value = (uint64_t)m_xstate.xs_fxsave.fx_ip.fa_64;
-    break;
-  case lldb_foseg_x86_64:
-    reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg;
-    break;
-  case lldb_fooff_x86_64:
-    reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_off;
-    break;
-  case lldb_fdp_x86_64:
-    reg_value = (uint64_t)m_xstate.xs_fxsave.fx_dp.fa_64;
-    break;
-  case lldb_mxcsr_x86_64:
-    reg_value = (uint32_t)m_xstate.xs_fxsave.fx_mxcsr;
-    break;
-  case lldb_mxcsrmask_x86_64:
-    reg_value = (uint32_t)m_xstate.xs_fxsave.fx_mxcsr_mask;
-    break;
-  case lldb_st0_x86_64:
-  case lldb_st1_x86_64:
-  case lldb_st2_x86_64:
-  case lldb_st3_x86_64:
-  case lldb_st4_x86_64:
-  case lldb_st5_x86_64:
-  case lldb_st6_x86_64:
-  case lldb_st7_x86_64:
-    reg_value.SetBytes(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_st0_x86_64],
-                       reg_info->byte_size, endian::InlHostByteOrder());
-    break;
-  case lldb_mm0_x86_64:
-  case lldb_mm1_x86_64:
-  case lldb_mm2_x86_64:
-  case lldb_mm3_x86_64:
-  case lldb_mm4_x86_64:
-  case lldb_mm5_x86_64:
-  case lldb_mm6_x86_64:
-  case lldb_mm7_x86_64:
-    reg_value.SetBytes(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_mm0_x86_64],
-                       reg_info->byte_size, endian::InlHostByteOrder());
-    break;
-  case lldb_xmm0_x86_64:
-  case lldb_xmm1_x86_64:
-  case lldb_xmm2_x86_64:
-  case lldb_xmm3_x86_64:
-  case lldb_xmm4_x86_64:
-  case lldb_xmm5_x86_64:
-  case lldb_xmm6_x86_64:
-  case lldb_xmm7_x86_64:
-  case lldb_xmm8_x86_64:
-  case lldb_xmm9_x86_64:
-  case lldb_xmm10_x86_64:
-  case lldb_xmm11_x86_64:
-  case lldb_xmm12_x86_64:
-  case lldb_xmm13_x86_64:
-  case lldb_xmm14_x86_64:
-  case lldb_xmm15_x86_64:
-    if (!(m_xstate.xs_rfbm & XCR0_SSE)) {
+  case YMMRegSet: {
+    llvm::Optional<YMMSplitPtr> ymm_reg = GetYMMSplitReg(reg);
+    if (!ymm_reg) {
       error.SetErrorStringWithFormat(
           "register \"%s\" not supported by CPU/kernel", reg_info->name);
     } else {
-      reg_value.SetBytes(&m_xstate.xs_fxsave.fx_xmm[reg - lldb_xmm0_x86_64],
-                         reg_info->byte_size, endian::InlHostByteOrder());
-    }
-    break;
-  case lldb_ymm0_x86_64:
-  case lldb_ymm1_x86_64:
-  case lldb_ymm2_x86_64:
-  case lldb_ymm3_x86_64:
-  case lldb_ymm4_x86_64:
-  case lldb_ymm5_x86_64:
-  case lldb_ymm6_x86_64:
-  case lldb_ymm7_x86_64:
-  case lldb_ymm8_x86_64:
-  case lldb_ymm9_x86_64:
-  case lldb_ymm10_x86_64:
-  case lldb_ymm11_x86_64:
-  case lldb_ymm12_x86_64:
-  case lldb_ymm13_x86_64:
-  case lldb_ymm14_x86_64:
-  case lldb_ymm15_x86_64:
-    if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
-        !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
-      error.SetErrorStringWithFormat(
-          "register \"%s\" not supported by CPU/kernel", reg_info->name);
-    } else {
-      uint32_t reg_index = reg - lldb_ymm0_x86_64;
-      YMMReg ymm =
-          XStateToYMM(m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
-                      m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
+      YMMReg ymm = XStateToYMM(ymm_reg->xmm, ymm_reg->ymm_hi);
       reg_value.SetBytes(ymm.bytes, reg_info->byte_size,
                          endian::InlHostByteOrder());
     }
     break;
-  case lldb_dr0_x86_64:
-  case lldb_dr1_x86_64:
-  case lldb_dr2_x86_64:
-  case lldb_dr3_x86_64:
-  case lldb_dr4_x86_64:
-  case lldb_dr5_x86_64:
-  case lldb_dr6_x86_64:
-  case lldb_dr7_x86_64:
-    reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64];
-    break;
-  default:
-    llvm_unreachable("Reading unknown/unsupported register");
+  }
+  case MPXRegSet:
+    llvm_unreachable("MPX regset should have returned error");
   }
 
   return error;
@@ -753,8 +466,8 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
     return error;
   }
 
-  int set = GetSetForNativeRegNum(reg);
-  if (set == -1) {
+  llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+  if (!opt_set) {
     // This is likely an internal register for lldb use only and should not be
     // directly queried.
     error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
@@ -762,277 +475,54 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
     return error;
   }
 
-  uint64_t new_xstate_bv = XCR0_X87;  // the most common case
-
-  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
-  case llvm::Triple::x86_64:
-    break;
-  case llvm::Triple::x86:
-    reg = RegNumX86ToX86_64(reg);
-    break;
-  default:
-    llvm_unreachable("Unhandled target architecture.");
-  }
+  RegSetKind set = opt_set.getValue();
+  uint64_t new_xstate_bv = 0;
 
   error = ReadRegisterSet(set);
   if (error.Fail())
     return error;
 
-  switch (reg) {
-#if defined(__x86_64__)
-  case lldb_rax_x86_64:
-    m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rbx_x86_64:
-    m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rcx_x86_64:
-    m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rdx_x86_64:
-    m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rdi_x86_64:
-    m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rsi_x86_64:
-    m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rbp_x86_64:
-    m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rsp_x86_64:
-    m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64();
-    break;
-  case lldb_r8_x86_64:
-    m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64();
-    break;
-  case lldb_r9_x86_64:
-    m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64();
-    break;
-  case lldb_r10_x86_64:
-    m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64();
-    break;
-  case lldb_r11_x86_64:
-    m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64();
-    break;
-  case lldb_r12_x86_64:
-    m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64();
-    break;
-  case lldb_r13_x86_64:
-    m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64();
-    break;
-  case lldb_r14_x86_64:
-    m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64();
-    break;
-  case lldb_r15_x86_64:
-    m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rip_x86_64:
-    m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64();
-    break;
-  case lldb_rflags_x86_64:
-    m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64();
-    break;
-  case lldb_cs_x86_64:
-    m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64();
-    break;
-  case lldb_fs_x86_64:
-    m_gpr.regs[_REG_FS] = reg_value.GetAsUInt16();
-    break;
-  case lldb_gs_x86_64:
-    m_gpr.regs[_REG_GS] = reg_value.GetAsUInt16();
-    break;
-  case lldb_ss_x86_64:
-    m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64();
-    break;
-  case lldb_ds_x86_64:
-    m_gpr.regs[_REG_DS] = reg_value.GetAsUInt16();
-    break;
-  case lldb_es_x86_64:
-    m_gpr.regs[_REG_ES] = reg_value.GetAsUInt16();
-    break;
-#else
-  case lldb_rax_x86_64:
-    m_gpr.r_eax = reg_value.GetAsUInt32();
-    break;
-  case lldb_rbx_x86_64:
-    m_gpr.r_ebx = reg_value.GetAsUInt32();
-    break;
-  case lldb_rcx_x86_64:
-    m_gpr.r_ecx = reg_value.GetAsUInt32();
-    break;
-  case lldb_rdx_x86_64:
-    m_gpr.r_edx = reg_value.GetAsUInt32();
-    break;
-  case lldb_rdi_x86_64:
-    m_gpr.r_edi = reg_value.GetAsUInt32();
-    break;
-  case lldb_rsi_x86_64:
-    m_gpr.r_esi = reg_value.GetAsUInt32();
-    break;
-  case lldb_rsp_x86_64:
-    m_gpr.r_esp = reg_value.GetAsUInt32();
-    break;
-  case lldb_rbp_x86_64:
-    m_gpr.r_ebp = reg_value.GetAsUInt32();
-    break;
-  case lldb_rip_x86_64:
-    m_gpr.r_eip = reg_value.GetAsUInt32();
-    break;
-  case lldb_rflags_x86_64:
-    m_gpr.r_eflags = reg_value.GetAsUInt32();
-    break;
-  case lldb_cs_x86_64:
-    m_gpr.r_cs = reg_value.GetAsUInt32();
-    break;
-  case lldb_fs_x86_64:
-    m_gpr.r_fs = reg_value.GetAsUInt16();
-    break;
-  case lldb_gs_x86_64:
-    m_gpr.r_gs = reg_value.GetAsUInt16();
-    break;
-  case lldb_ss_x86_64:
-    m_gpr.r_ss = reg_value.GetAsUInt32();
-    break;
-  case lldb_ds_x86_64:
-    m_gpr.r_ds = reg_value.GetAsUInt16();
-    break;
-  case lldb_es_x86_64:
-    m_gpr.r_es = reg_value.GetAsUInt16();
-    break;
-#endif
-  case lldb_fctrl_x86_64:
-    m_xstate.xs_fxsave.fx_cw = reg_value.GetAsUInt16();
-    break;
-  case lldb_fstat_x86_64:
-    m_xstate.xs_fxsave.fx_sw = reg_value.GetAsUInt16();
-    break;
-  case lldb_ftag_x86_64:
-    m_xstate.xs_fxsave.fx_tw = FullToAbridgedTagWord(reg_value.GetAsUInt16());
-    break;
-  case lldb_fop_x86_64:
-    m_xstate.xs_fxsave.fx_opcode = reg_value.GetAsUInt16();
-    break;
-  case lldb_fiseg_x86_64:
-    m_xstate.xs_fxsave.fx_ip.fa_32.fa_seg = reg_value.GetAsUInt32();
-    break;
-  case lldb_fioff_x86_64:
-    m_xstate.xs_fxsave.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
-    break;
-  case lldb_fip_x86_64:
-    m_xstate.xs_fxsave.fx_ip.fa_64 = reg_value.GetAsUInt64();
-    break;
-  case lldb_foseg_x86_64:
-    m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg = reg_value.GetAsUInt32();
-    break;
-  case lldb_fooff_x86_64:
-    m_xstate.xs_fxsave.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
-    break;
-  case lldb_fdp_x86_64:
-    m_xstate.xs_fxsave.fx_dp.fa_64 = reg_value.GetAsUInt64();
-    break;
-  case lldb_mxcsr_x86_64:
-    m_xstate.xs_fxsave.fx_mxcsr = reg_value.GetAsUInt32();
-    new_xstate_bv = XCR0_SSE;
-    break;
-  case lldb_mxcsrmask_x86_64:
-    m_xstate.xs_fxsave.fx_mxcsr_mask = reg_value.GetAsUInt32();
-    new_xstate_bv = XCR0_SSE;
-    break;
-  case lldb_st0_x86_64:
-  case lldb_st1_x86_64:
-  case lldb_st2_x86_64:
-  case lldb_st3_x86_64:
-  case lldb_st4_x86_64:
-  case lldb_st5_x86_64:
-  case lldb_st6_x86_64:
-  case lldb_st7_x86_64:
-    ::memcpy(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_st0_x86_64],
-             reg_value.GetBytes(), reg_value.GetByteSize());
-    break;
-  case lldb_mm0_x86_64:
-  case lldb_mm1_x86_64:
-  case lldb_mm2_x86_64:
-  case lldb_mm3_x86_64:
-  case lldb_mm4_x86_64:
-  case lldb_mm5_x86_64:
-  case lldb_mm6_x86_64:
-  case lldb_mm7_x86_64:
-    ::memcpy(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_mm0_x86_64],
+  switch (set) {
+  case GPRegSet:
+  case DBRegSet:
+    ::memcpy(GetOffsetRegSetData(set, reg_info->byte_offset),
              reg_value.GetBytes(), reg_value.GetByteSize());
     break;
-  case lldb_xmm0_x86_64:
-  case lldb_xmm1_x86_64:
-  case lldb_xmm2_x86_64:
-  case lldb_xmm3_x86_64:
-  case lldb_xmm4_x86_64:
-  case lldb_xmm5_x86_64:
-  case lldb_xmm6_x86_64:
-  case lldb_xmm7_x86_64:
-  case lldb_xmm8_x86_64:
-  case lldb_xmm9_x86_64:
-  case lldb_xmm10_x86_64:
-  case lldb_xmm11_x86_64:
-  case lldb_xmm12_x86_64:
-  case lldb_xmm13_x86_64:
-  case lldb_xmm14_x86_64:
-  case lldb_xmm15_x86_64:
-    if (!(m_xstate.xs_rfbm & XCR0_SSE)) {
-      error.SetErrorStringWithFormat(
-          "register \"%s\" not supported by CPU/kernel", reg_info->name);
-    } else {
-      ::memcpy(&m_xstate.xs_fxsave.fx_xmm[reg - lldb_xmm0_x86_64],
-               reg_value.GetBytes(), reg_value.GetByteSize());
-      new_xstate_bv = XCR0_SSE;
-    }
+  case FPRegSet: {
+    void *data = GetOffsetRegSetData(set, reg_info->byte_offset);
+    FXSAVE *fpr = reinterpret_cast<FXSAVE *>(m_xstate.data() +
+                                             offsetof(xstate, xs_fxsave));
+    if (data == &fpr->ftag) // ftag
+      fpr->ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());
+    else
+      ::memcpy(data, reg_value.GetBytes(), reg_value.GetByteSize());
+    if (data >= &fpr->xmm)
+      new_xstate_bv |= XCR0_SSE;
+    else if (data >= &fpr->mxcsr && data < &fpr->stmm)
+      new_xstate_bv |= XCR0_SSE;
+    else
+      new_xstate_bv |= XCR0_X87;
     break;
-  case lldb_ymm0_x86_64:
-  case lldb_ymm1_x86_64:
-  case lldb_ymm2_x86_64:
-  case lldb_ymm3_x86_64:
-  case lldb_ymm4_x86_64:
-  case lldb_ymm5_x86_64:
-  case lldb_ymm6_x86_64:
-  case lldb_ymm7_x86_64:
-  case lldb_ymm8_x86_64:
-  case lldb_ymm9_x86_64:
-  case lldb_ymm10_x86_64:
-  case lldb_ymm11_x86_64:
-  case lldb_ymm12_x86_64:
-  case lldb_ymm13_x86_64:
-  case lldb_ymm14_x86_64:
-  case lldb_ymm15_x86_64:
-    if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
-        !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
+  }
+  case YMMRegSet: {
+    llvm::Optional<YMMSplitPtr> ymm_reg = GetYMMSplitReg(reg);
+    if (!ymm_reg) {
       error.SetErrorStringWithFormat(
           "register \"%s\" not supported by CPU/kernel", reg_info->name);
     } else {
-      uint32_t reg_index = reg - lldb_ymm0_x86_64;
       YMMReg ymm;
       ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
-      YMMToXState(ymm, m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
-                  m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
-      new_xstate_bv = XCR0_SSE | XCR0_YMM_Hi128;
+      YMMToXState(ymm, ymm_reg->xmm, ymm_reg->ymm_hi);
+      new_xstate_bv |= XCR0_SSE | XCR0_YMM_Hi128;
     }
     break;
-  case lldb_dr0_x86_64:
-  case lldb_dr1_x86_64:
-  case lldb_dr2_x86_64:
-  case lldb_dr3_x86_64:
-  case lldb_dr4_x86_64:
-  case lldb_dr5_x86_64:
-  case lldb_dr6_x86_64:
-  case lldb_dr7_x86_64:
-    m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
-    break;
-  default:
-    llvm_unreachable("Reading unknown/unsupported register");
+  }
+  case MPXRegSet:
+    llvm_unreachable("MPX regset should have returned error");
   }
 
-  if (set == XStateRegSet)
-    m_xstate.xs_xstate_bv |= new_xstate_bv;
-
+  if (new_xstate_bv != 0)
+    reinterpret_cast<xstate *>(m_xstate.data())->xs_xstate_bv |= new_xstate_bv;
   return WriteRegisterSet(set);
 }
 
@@ -1046,7 +536,7 @@ Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues(
     return error;
 
   uint8_t *dst = data_sp->GetBytes();
-  ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
+  ::memcpy(dst, m_gpr.data(), GetRegisterInfoInterface().GetGPRSize());
   dst += GetRegisterInfoInterface().GetGPRSize();
 
   return error;
@@ -1079,7 +569,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
                                    __FUNCTION__);
     return error;
   }
-  ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
+  ::memcpy(m_gpr.data(), src, GetRegisterInfoInterface().GetGPRSize());
 
   error = WriteRegisterSet(GPRegSet);
   if (error.Fail())
@@ -1089,25 +579,15 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
   return error;
 }
 
-int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const {
-  assert(num >= 0 && num <= 7);
-  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
-  case llvm::Triple::x86:
-    return lldb_dr0_i386 + num;
-  case llvm::Triple::x86_64:
-    return lldb_dr0_x86_64 + num;
-  default:
-    llvm_unreachable("Unhandled target architecture.");
-  }
-}
-
 llvm::Error NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
     NativeRegisterContextNetBSD &source) {
-  auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source);
-  Status res = r_source.ReadRegisterSet(DBRegSet);
+  auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64 &>(source);
+  // NB: This implicitly reads the whole dbreg set.
+  RegisterValue dr7;
+  Status res = r_source.ReadRegister(GetDR(7), dr7);
   if (!res.Fail()) {
     // copy dbregs only if any watchpoints were set
-    if ((r_source.m_dbr.dr[7] & 0xFF) == 0)
+    if ((dr7.GetAsUInt64() & 0xFF) == 0)
       return llvm::Error::success();
 
     m_dbr = r_source.m_dbr;
@@ -1116,4 +596,49 @@ llvm::Error NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
   return res.ToError();
 }
 
+uint8_t *
+NativeRegisterContextNetBSD_x86_64::GetOffsetRegSetData(RegSetKind set,
+                                                        size_t reg_offset) {
+  uint8_t *base;
+  switch (set) {
+  case GPRegSet:
+    base = m_gpr.data();
+    break;
+  case FPRegSet:
+    base = m_xstate.data() + offsetof(xstate, xs_fxsave);
+    break;
+  case DBRegSet:
+    base = m_dbr.data();
+    break;
+  case YMMRegSet:
+    llvm_unreachable("GetRegSetData() is unsuitable for this regset.");
+  case MPXRegSet:
+    llvm_unreachable("MPX regset should have returned error");
+  }
+  assert(reg_offset >= m_regset_offsets[set]);
+  return base + (reg_offset - m_regset_offsets[set]);
+}
+
+llvm::Optional<NativeRegisterContextNetBSD_x86_64::YMMSplitPtr>
+NativeRegisterContextNetBSD_x86_64::GetYMMSplitReg(uint32_t reg) {
+  auto xst = reinterpret_cast<xstate *>(m_xstate.data());
+  if (!(xst->xs_rfbm & XCR0_SSE) || !(xst->xs_rfbm & XCR0_YMM_Hi128))
+    return llvm::None;
+
+  uint32_t reg_index;
+  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+  case llvm::Triple::x86:
+    reg_index = reg - lldb_ymm0_i386;
+    break;
+  case llvm::Triple::x86_64:
+    reg_index = reg - lldb_ymm0_x86_64;
+    break;
+  default:
+    llvm_unreachable("Unhandled target architecture.");
+  }
+
+  return YMMSplitPtr{&xst->xs_fxsave.fx_xmm[reg_index],
+                     &xst->xs_ymm_hi128.xs_ymm[reg_index]};
+}
+
 #endif // defined(__x86_64__)

diff  --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
index 38edfa400c65..d20fd67cdc5d 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
@@ -18,6 +18,8 @@
 #include <machine/reg.h>
 // clang-format on
 
+#include <array>
+
 #include "Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h"
 #include "Plugins/Process/Utility/RegisterContext_x86.h"
 #include "Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h"
@@ -53,18 +55,34 @@ class NativeRegisterContextNetBSD_x86_64
 
 private:
   // Private member types.
-  enum { GPRegSet, XStateRegSet, DBRegSet };
+  enum RegSetKind {
+    GPRegSet,
+    FPRegSet,
+    DBRegSet,
+    MaxRegularRegSet = DBRegSet,
+    YMMRegSet,
+    MPXRegSet,
+    MaxRegSet = MPXRegSet,
+  };
 
   // Private member variables.
-  struct reg m_gpr;
-  struct xstate m_xstate;
-  struct dbreg m_dbr;
+  std::array<uint8_t, sizeof(struct reg)> m_gpr;
+  std::array<uint8_t, sizeof(struct xstate)> m_xstate;
+  std::array<uint8_t, sizeof(struct dbreg)> m_dbr;
+  std::array<size_t, MaxRegularRegSet + 1> m_regset_offsets;
+
+  llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const;
+
+  Status ReadRegisterSet(RegSetKind set);
+  Status WriteRegisterSet(RegSetKind set);
 
-  int GetSetForNativeRegNum(int reg_num) const;
-  int GetDR(int num) const;
+  uint8_t *GetOffsetRegSetData(RegSetKind set, size_t reg_offset);
 
-  Status ReadRegisterSet(uint32_t set);
-  Status WriteRegisterSet(uint32_t set);
+  struct YMMSplitPtr {
+    void *xmm;
+    void *ymm_hi;
+  };
+  llvm::Optional<YMMSplitPtr> GetYMMSplitReg(uint32_t reg);
 };
 
 } // namespace process_netbsd

diff  --git a/lldb/test/API/python_api/lldbutil/iter/TestRegistersIterator.py b/lldb/test/API/python_api/lldbutil/iter/TestRegistersIterator.py
index 399c983aef78..fbb8bff41287 100644
--- a/lldb/test/API/python_api/lldbutil/iter/TestRegistersIterator.py
+++ b/lldb/test/API/python_api/lldbutil/iter/TestRegistersIterator.py
@@ -23,7 +23,6 @@ def setUp(self):
             'main.cpp', '// Set break point at this line.')
 
     @add_test_categories(['pyapi'])
-    @expectedFailureNetBSD
     def test_iter_registers(self):
         """Test iterator works correctly for lldbutil.iter_registers()."""
         self.build()

diff  --git a/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py b/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
index e92b056d3b09..e26a8210d254 100644
--- a/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
+++ b/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
@@ -208,7 +208,6 @@ def targetHasAVX(self):
         return " avx " in cpuinfo
 
     @expectedFailureAll(oslist=["windows"]) # no avx for now.
-    @expectedFailureAll(oslist=["netbsd"])
     @add_test_categories(["llgs"])
     def test_qRegisterInfo_contains_avx_registers(self):
         self.build()
@@ -294,7 +293,6 @@ def test_qThreadInfo_matches_qC_attach(self):
         self.set_inferior_startup_attach()
         self.qThreadInfo_matches_qC()
 
-    @expectedFailureAll(oslist=["netbsd"])
     def test_p_returns_correct_data_size_for_each_qRegisterInfo_launch(self):
         self.build()
         self.set_inferior_startup_launch()

diff  --git a/lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py b/lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
index 3e8951ce6941..cce22b7643b6 100644
--- a/lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
+++ b/lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
@@ -12,7 +12,6 @@ class TestGdbRemoteTargetXmlPacket(gdbremote_testcase.GdbRemoteTestCaseBase):
 
     mydir = TestBase.compute_mydir(__file__)
 
-    @expectedFailureNetBSD
     @llgs_test
     def test_g_target_xml_returns_correct_data(self):
         self.build()


        


More information about the llvm-branch-commits mailing list