diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 72280927471f8..013b2bbc0e67f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -434,11 +434,6 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, } else { // This is an actual register, write it success = SetPrimordialRegister(reg_info, gdb_comm); - - if (success && do_reconfigure_arm64_sve) { - AArch64Reconfigure(); - InvalidateAllRegisters(); - } } // Check if writing this register will invalidate any other register @@ -452,6 +447,11 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, false); } + if (success && do_reconfigure_arm64_sve) { + AArch64Reconfigure(); + InvalidateAllRegisters(); + } + return success; } } else { @@ -772,8 +772,6 @@ void GDBRemoteRegisterContext::AArch64Reconfigure() { std::optional vg_reg_value; const RegisterInfo *vg_reg_info = m_reg_info_sp->GetRegisterInfo("vg"); if (vg_reg_info) { - // Make sure we get the latest value of vg from the remote. - SetRegisterIsValid(vg_reg_info, false); uint32_t vg_reg_num = vg_reg_info->kinds[eRegisterKindLLDB]; uint64_t reg_value = ReadRegisterAsUnsigned(vg_reg_num, fail_value); if (reg_value != fail_value && reg_value <= 32) @@ -783,11 +781,6 @@ void GDBRemoteRegisterContext::AArch64Reconfigure() { std::optional svg_reg_value; const RegisterInfo *svg_reg_info = m_reg_info_sp->GetRegisterInfo("svg"); if (svg_reg_info) { - // When vg is written it is automatically made invalid. Writing vg will also - // change svg if we're in streaming mode but it will not be made invalid - // so do this manually so the following read gets the latest svg value. - SetRegisterIsValid(svg_reg_info, false); - uint32_t svg_reg_num = svg_reg_info->kinds[eRegisterKindLLDB]; uint64_t reg_value = ReadRegisterAsUnsigned(svg_reg_num, fail_value); if (reg_value != fail_value && reg_value <= 32) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 16b3ba661d071..c50ac5de77904 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1612,6 +1612,22 @@ bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) { return false; } +void ProcessGDBRemote::ParseExpeditedRegisters( + ExpeditedRegisterMap &expedited_register_map, ThreadSP thread_sp) { + ThreadGDBRemote *gdb_thread = static_cast(thread_sp.get()); + RegisterContextSP gdb_reg_ctx_sp(gdb_thread->GetRegisterContext()); + + for (const auto &pair : expedited_register_map) { + StringExtractor reg_value_extractor(pair.second); + WritableDataBufferSP buffer_sp( + new DataBufferHeap(reg_value_extractor.GetStringRef().size() / 2, 0)); + reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc'); + uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber( + eRegisterKindProcessPlugin, pair.first); + gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData()); + } +} + ThreadSP ProcessGDBRemote::SetThreadStopInfo( lldb::tid_t tid, ExpeditedRegisterMap &expedited_register_map, uint8_t signo, const std::string &thread_name, const std::string &reason, @@ -1646,32 +1662,35 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( reg_ctx_sp->InvalidateIfNeeded(true); + auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid); + if (iter != m_thread_ids.end()) + SetThreadPc(thread_sp, iter - m_thread_ids.begin()); + + ParseExpeditedRegisters(expedited_register_map, thread_sp); + // AArch64 SVE/SME specific code below updates SVE and ZA register sizes and // offsets if value of VG or SVG registers has changed since last stop. const ArchSpec &arch = GetTarget().GetArchitecture(); if (arch.IsValid() && arch.GetTriple().isAArch64()) { - GDBRemoteRegisterContext *gdb_remote_reg_ctx = - static_cast(reg_ctx_sp.get()); + GDBRemoteRegisterContext *reg_ctx_sp = + static_cast( + gdb_thread->GetRegisterContext().get()); - if (gdb_remote_reg_ctx) { - gdb_remote_reg_ctx->AArch64Reconfigure(); - gdb_remote_reg_ctx->InvalidateAllRegisters(); + if (reg_ctx_sp) { + reg_ctx_sp->AArch64Reconfigure(); + // Now we have changed the offsets of all the registers, so the values + // will be corrupted. + reg_ctx_sp->InvalidateAllRegisters(); + + // Expedited registers values will never contain registers that would be + // resized by AArch64Reconfigure. So we are safe to continue using these + // values. These values include vg, svg and useful general purpose + // registers so this saves a few read packets each time we make use of + // them. + ParseExpeditedRegisters(expedited_register_map, thread_sp); } } - auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid); - if (iter != m_thread_ids.end()) - SetThreadPc(thread_sp, iter - m_thread_ids.begin()); - - for (const auto &pair : expedited_register_map) { - StringExtractor reg_value_extractor(pair.second); - WritableDataBufferSP buffer_sp( - new DataBufferHeap(reg_value_extractor.GetStringRef().size() / 2, 0)); - reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc'); - uint32_t lldb_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( - eRegisterKindProcessPlugin, pair.first); - gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData()); - } thread_sp->SetName(thread_name.empty() ? nullptr : thread_name.c_str()); gdb_thread->SetThreadDispatchQAddr(thread_dispatch_qaddr); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index f0ead4c38c237..f3787e7169047 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -470,6 +470,9 @@ class ProcessGDBRemote : public Process, void DidForkSwitchSoftwareBreakpoints(bool enable); void DidForkSwitchHardwareTraps(bool enable); + void ParseExpeditedRegisters(ExpeditedRegisterMap &expedited_register_map, + lldb::ThreadSP thread_sp); + // Lists of register fields generated from the remote's target XML. // Pointers to these RegisterFlags will be set in the register info passed // back to the upper levels of lldb. Doing so is safe because this class will