Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lldb][AArch64] Simplify handing of scalable registers using vg and svg #70914

Merged
merged 1 commit into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -452,6 +447,11 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
false);
}

if (success && do_reconfigure_arm64_sve) {
AArch64Reconfigure();
InvalidateAllRegisters();
}

return success;
}
} else {
Expand Down Expand Up @@ -772,8 +772,6 @@ void GDBRemoteRegisterContext::AArch64Reconfigure() {
std::optional<uint64_t> 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)
Expand All @@ -783,11 +781,6 @@ void GDBRemoteRegisterContext::AArch64Reconfigure() {
std::optional<uint64_t> 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)
Expand Down
55 changes: 37 additions & 18 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ThreadGDBRemote *>(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,
Expand Down Expand Up @@ -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<GDBRemoteRegisterContext *>(reg_ctx_sp.get());
GDBRemoteRegisterContext *reg_ctx_sp =
static_cast<GDBRemoteRegisterContext *>(
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);
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading