[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 ®ctx = 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