Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
96381 views
//===-- GDBRemoteRegisterContext.cpp --------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "GDBRemoteRegisterContext.h"910#include "ProcessGDBRemote.h"11#include "ProcessGDBRemoteLog.h"12#include "ThreadGDBRemote.h"13#include "Utility/ARM_DWARF_Registers.h"14#include "Utility/ARM_ehframe_Registers.h"15#include "lldb/Core/Architecture.h"16#include "lldb/Target/ExecutionContext.h"17#include "lldb/Target/Target.h"18#include "lldb/Utility/DataBufferHeap.h"19#include "lldb/Utility/DataExtractor.h"20#include "lldb/Utility/RegisterValue.h"21#include "lldb/Utility/Scalar.h"22#include "lldb/Utility/StreamString.h"23#include "lldb/Utility/StringExtractorGDBRemote.h"2425#include <memory>2627using namespace lldb;28using namespace lldb_private;29using namespace lldb_private::process_gdb_remote;3031// GDBRemoteRegisterContext constructor32GDBRemoteRegisterContext::GDBRemoteRegisterContext(33ThreadGDBRemote &thread, uint32_t concrete_frame_idx,34GDBRemoteDynamicRegisterInfoSP reg_info_sp, bool read_all_at_once,35bool write_all_at_once)36: RegisterContext(thread, concrete_frame_idx),37m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(),38m_read_all_at_once(read_all_at_once),39m_write_all_at_once(write_all_at_once), m_gpacket_cached(false) {40// Resize our vector of bools to contain one bool for every register. We will41// use these boolean values to know when a register value is valid in42// m_reg_data.43m_reg_valid.resize(m_reg_info_sp->GetNumRegisters());4445// Make a heap based buffer that is big enough to store all registers46DataBufferSP reg_data_sp(47new DataBufferHeap(m_reg_info_sp->GetRegisterDataByteSize(), 0));48m_reg_data.SetData(reg_data_sp);49m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());50}5152// Destructor53GDBRemoteRegisterContext::~GDBRemoteRegisterContext() = default;5455void GDBRemoteRegisterContext::InvalidateAllRegisters() {56SetAllRegisterValid(false);57}5859void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {60m_gpacket_cached = b;61std::vector<bool>::iterator pos, end = m_reg_valid.end();62for (pos = m_reg_valid.begin(); pos != end; ++pos)63*pos = b;64}6566size_t GDBRemoteRegisterContext::GetRegisterCount() {67return m_reg_info_sp->GetNumRegisters();68}6970const RegisterInfo *71GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {72return m_reg_info_sp->GetRegisterInfoAtIndex(reg);73}7475size_t GDBRemoteRegisterContext::GetRegisterSetCount() {76return m_reg_info_sp->GetNumRegisterSets();77}7879const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {80return m_reg_info_sp->GetRegisterSet(reg_set);81}8283bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,84RegisterValue &value) {85// Read the register86if (ReadRegisterBytes(reg_info)) {87const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];88if (m_reg_valid[reg] == false)89return false;90if (reg_info->value_regs &&91reg_info->value_regs[0] != LLDB_INVALID_REGNUM &&92reg_info->value_regs[1] != LLDB_INVALID_REGNUM) {93std::vector<char> combined_data;94uint32_t offset = 0;95for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {96const RegisterInfo *parent_reg = GetRegisterInfo(97eRegisterKindLLDB, reg_info->value_regs[i]);98if (!parent_reg)99return false;100combined_data.resize(offset + parent_reg->byte_size);101if (m_reg_data.CopyData(parent_reg->byte_offset, parent_reg->byte_size,102combined_data.data() + offset) !=103parent_reg->byte_size)104return false;105offset += parent_reg->byte_size;106}107108Status error;109return value.SetFromMemoryData(110*reg_info, combined_data.data(), combined_data.size(),111m_reg_data.GetByteOrder(), error) == combined_data.size();112} else {113const bool partial_data_ok = false;114Status error(value.SetValueFromData(115*reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));116return error.Success();117}118}119return false;120}121122bool GDBRemoteRegisterContext::PrivateSetRegisterValue(123uint32_t reg, llvm::ArrayRef<uint8_t> data) {124const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);125if (reg_info == nullptr)126return false;127128// Invalidate if needed129InvalidateIfNeeded(false);130131const size_t reg_byte_size = reg_info->byte_size;132memcpy(const_cast<uint8_t *>(133m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)),134data.data(), std::min(data.size(), reg_byte_size));135bool success = data.size() >= reg_byte_size;136if (success) {137SetRegisterIsValid(reg, true);138} else if (data.size() > 0) {139// Only set register is valid to false if we copied some bytes, else leave140// it as it was.141SetRegisterIsValid(reg, false);142}143return success;144}145146bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,147uint64_t new_reg_val) {148const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);149if (reg_info == nullptr)150return false;151152// Early in process startup, we can get a thread that has an invalid byte153// order because the process hasn't been completely set up yet (see the ctor154// where the byte order is setfrom the process). If that's the case, we155// can't set the value here.156if (m_reg_data.GetByteOrder() == eByteOrderInvalid) {157return false;158}159160// Invalidate if needed161InvalidateIfNeeded(false);162163DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));164DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));165166// If our register context and our register info disagree, which should never167// happen, don't overwrite past the end of the buffer.168if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)169return false;170171// Grab a pointer to where we are going to put this register172uint8_t *dst = const_cast<uint8_t *>(173m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));174175if (dst == nullptr)176return false;177178if (data.CopyByteOrderedData(0, // src offset179reg_info->byte_size, // src length180dst, // dst181reg_info->byte_size, // dst length182m_reg_data.GetByteOrder())) // dst byte order183{184SetRegisterIsValid(reg, true);185return true;186}187return false;188}189190// Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().191bool GDBRemoteRegisterContext::GetPrimordialRegister(192const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {193const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];194const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];195196if (DataBufferSP buffer_sp =197gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))198return PrivateSetRegisterValue(199lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(),200buffer_sp->GetByteSize()));201return false;202}203204bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info) {205ExecutionContext exe_ctx(CalculateThread());206207Process *process = exe_ctx.GetProcessPtr();208Thread *thread = exe_ctx.GetThreadPtr();209if (process == nullptr || thread == nullptr)210return false;211212GDBRemoteCommunicationClient &gdb_comm(213((ProcessGDBRemote *)process)->GetGDBRemote());214215InvalidateIfNeeded(false);216217const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];218219if (!GetRegisterIsValid(reg)) {220if (m_read_all_at_once && !m_gpacket_cached) {221if (DataBufferSP buffer_sp =222gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {223memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),224buffer_sp->GetBytes(),225std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));226if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {227SetAllRegisterValid(true);228return true;229} else if (buffer_sp->GetByteSize() > 0) {230for (auto x : llvm::enumerate(231m_reg_info_sp->registers<232DynamicRegisterInfo::reg_collection_const_range>())) {233const struct RegisterInfo ®info = x.value();234m_reg_valid[x.index()] =235(reginfo.byte_offset + reginfo.byte_size <=236buffer_sp->GetByteSize());237}238239m_gpacket_cached = true;240if (GetRegisterIsValid(reg))241return true;242} else {243Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));244LLDB_LOGF(245log,246"error: GDBRemoteRegisterContext::ReadRegisterBytes tried "247"to read the "248"entire register context at once, expected at least %" PRId64249" bytes "250"but only got %" PRId64 " bytes.",251m_reg_data.GetByteSize(), buffer_sp->GetByteSize());252return false;253}254}255}256if (reg_info->value_regs) {257// Process this composite register request by delegating to the258// constituent primordial registers.259260// Index of the primordial register.261bool success = true;262for (uint32_t idx = 0; success; ++idx) {263const uint32_t prim_reg = reg_info->value_regs[idx];264if (prim_reg == LLDB_INVALID_REGNUM)265break;266// We have a valid primordial register as our constituent. Grab the267// corresponding register info.268const RegisterInfo *prim_reg_info =269GetRegisterInfo(eRegisterKindLLDB, prim_reg);270if (prim_reg_info == nullptr)271success = false;272else {273// Read the containing register if it hasn't already been read274if (!GetRegisterIsValid(prim_reg))275success = GetPrimordialRegister(prim_reg_info, gdb_comm);276}277}278279if (success) {280// If we reach this point, all primordial register requests have281// succeeded. Validate this composite register.282SetRegisterIsValid(reg_info, true);283}284} else {285// Get each register individually286GetPrimordialRegister(reg_info, gdb_comm);287}288289// Make sure we got a valid register value after reading it290if (!GetRegisterIsValid(reg))291return false;292}293294return true;295}296297bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info,298const RegisterValue &value) {299DataExtractor data;300if (value.GetData(data)) {301if (reg_info->value_regs &&302reg_info->value_regs[0] != LLDB_INVALID_REGNUM &&303reg_info->value_regs[1] != LLDB_INVALID_REGNUM) {304uint32_t combined_size = 0;305for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {306const RegisterInfo *parent_reg = GetRegisterInfo(307eRegisterKindLLDB, reg_info->value_regs[i]);308if (!parent_reg)309return false;310combined_size += parent_reg->byte_size;311}312313if (data.GetByteSize() < combined_size)314return false;315316uint32_t offset = 0;317for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {318const RegisterInfo *parent_reg = GetRegisterInfo(319eRegisterKindLLDB, reg_info->value_regs[i]);320assert(parent_reg);321322DataExtractor parent_data{data, offset, parent_reg->byte_size};323if (!WriteRegisterBytes(parent_reg, parent_data, 0))324return false;325offset += parent_reg->byte_size;326}327assert(offset == combined_size);328return true;329} else330return WriteRegisterBytes(reg_info, data, 0);331}332return false;333}334335// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().336bool GDBRemoteRegisterContext::SetPrimordialRegister(337const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {338StreamString packet;339StringExtractorGDBRemote response;340const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];341// Invalidate just this register342SetRegisterIsValid(reg, false);343344return gdb_comm.WriteRegister(345m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],346{m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),347reg_info->byte_size});348}349350bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,351DataExtractor &data,352uint32_t data_offset) {353ExecutionContext exe_ctx(CalculateThread());354355Process *process = exe_ctx.GetProcessPtr();356Thread *thread = exe_ctx.GetThreadPtr();357if (process == nullptr || thread == nullptr)358return false;359360GDBRemoteCommunicationClient &gdb_comm(361((ProcessGDBRemote *)process)->GetGDBRemote());362363assert(m_reg_data.GetByteSize() >=364reg_info->byte_offset + reg_info->byte_size);365366// If our register context and our register info disagree, which should never367// happen, don't overwrite past the end of the buffer.368if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)369return false;370371// Grab a pointer to where we are going to put this register372uint8_t *dst = const_cast<uint8_t *>(373m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));374375if (dst == nullptr)376return false;377378const bool should_reconfigure_registers =379RegisterWriteCausesReconfigure(reg_info->name);380381if (data.CopyByteOrderedData(data_offset, // src offset382reg_info->byte_size, // src length383dst, // dst384reg_info->byte_size, // dst length385m_reg_data.GetByteOrder())) // dst byte order386{387GDBRemoteClientBase::Lock lock(gdb_comm);388if (lock) {389if (m_write_all_at_once) {390// Invalidate all register values391InvalidateIfNeeded(true);392393// Set all registers in one packet394if (gdb_comm.WriteAllRegisters(395m_thread.GetProtocolID(),396{m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))397398{399if (should_reconfigure_registers)400ReconfigureRegisterInfo();401402InvalidateAllRegisters();403404return true;405}406} else {407bool success = true;408409if (reg_info->value_regs) {410// This register is part of another register. In this case we read411// the actual register data for any "value_regs", and once all that412// data is read, we will have enough data in our register context413// bytes for the value of this register414415// Invalidate this composite register first.416417for (uint32_t idx = 0; success; ++idx) {418const uint32_t reg = reg_info->value_regs[idx];419if (reg == LLDB_INVALID_REGNUM)420break;421// We have a valid primordial register as our constituent. Grab the422// corresponding register info.423const RegisterInfo *value_reg_info =424GetRegisterInfo(eRegisterKindLLDB, reg);425if (value_reg_info == nullptr)426success = false;427else428success = SetPrimordialRegister(value_reg_info, gdb_comm);429}430} else {431// This is an actual register, write it432success = SetPrimordialRegister(reg_info, gdb_comm);433}434435// Check if writing this register will invalidate any other register436// values? If so, invalidate them437if (reg_info->invalidate_regs) {438for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];439reg != LLDB_INVALID_REGNUM;440reg = reg_info->invalidate_regs[++idx])441SetRegisterIsValid(ConvertRegisterKindToRegisterNumber(442eRegisterKindLLDB, reg),443false);444}445446if (success && should_reconfigure_registers &&447ReconfigureRegisterInfo())448InvalidateAllRegisters();449450return success;451}452} else {453Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));454if (log) {455if (log->GetVerbose()) {456StreamString strm;457process->DumpPluginHistory(strm);458LLDB_LOGF(log,459"error: failed to get packet sequence mutex, not sending "460"write register for \"%s\":\n%s",461reg_info->name, strm.GetData());462} else463LLDB_LOGF(log,464"error: failed to get packet sequence mutex, not sending "465"write register for \"%s\"",466reg_info->name);467}468}469}470return false;471}472473bool GDBRemoteRegisterContext::ReadAllRegisterValues(474RegisterCheckpoint ®_checkpoint) {475ExecutionContext exe_ctx(CalculateThread());476477Process *process = exe_ctx.GetProcessPtr();478Thread *thread = exe_ctx.GetThreadPtr();479if (process == nullptr || thread == nullptr)480return false;481482GDBRemoteCommunicationClient &gdb_comm(483((ProcessGDBRemote *)process)->GetGDBRemote());484485uint32_t save_id = 0;486if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) {487reg_checkpoint.SetID(save_id);488reg_checkpoint.GetData().reset();489return true;490} else {491reg_checkpoint.SetID(0); // Invalid save ID is zero492return ReadAllRegisterValues(reg_checkpoint.GetData());493}494}495496bool GDBRemoteRegisterContext::WriteAllRegisterValues(497const RegisterCheckpoint ®_checkpoint) {498uint32_t save_id = reg_checkpoint.GetID();499if (save_id != 0) {500ExecutionContext exe_ctx(CalculateThread());501502Process *process = exe_ctx.GetProcessPtr();503Thread *thread = exe_ctx.GetThreadPtr();504if (process == nullptr || thread == nullptr)505return false;506507GDBRemoteCommunicationClient &gdb_comm(508((ProcessGDBRemote *)process)->GetGDBRemote());509510return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);511} else {512return WriteAllRegisterValues(reg_checkpoint.GetData());513}514}515516bool GDBRemoteRegisterContext::ReadAllRegisterValues(517lldb::WritableDataBufferSP &data_sp) {518ExecutionContext exe_ctx(CalculateThread());519520Process *process = exe_ctx.GetProcessPtr();521Thread *thread = exe_ctx.GetThreadPtr();522if (process == nullptr || thread == nullptr)523return false;524525GDBRemoteCommunicationClient &gdb_comm(526((ProcessGDBRemote *)process)->GetGDBRemote());527528const bool use_g_packet =529!gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);530531GDBRemoteClientBase::Lock lock(gdb_comm);532if (lock) {533if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))534InvalidateAllRegisters();535536if (use_g_packet) {537if (DataBufferSP data_buffer =538gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {539data_sp = std::make_shared<DataBufferHeap>(*data_buffer);540return true;541}542}543544// We're going to read each register545// individually and store them as binary data in a buffer.546const RegisterInfo *reg_info;547548for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;549i++) {550if (reg_info551->value_regs) // skip registers that are slices of real registers552continue;553ReadRegisterBytes(reg_info);554// ReadRegisterBytes saves the contents of the register in to the555// m_reg_data buffer556}557data_sp = std::make_shared<DataBufferHeap>(558m_reg_data.GetDataStart(), m_reg_info_sp->GetRegisterDataByteSize());559return true;560} else {561562Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));563if (log) {564if (log->GetVerbose()) {565StreamString strm;566process->DumpPluginHistory(strm);567LLDB_LOGF(log,568"error: failed to get packet sequence mutex, not sending "569"read all registers:\n%s",570strm.GetData());571} else572LLDB_LOGF(log,573"error: failed to get packet sequence mutex, not sending "574"read all registers");575}576}577578data_sp.reset();579return false;580}581582bool GDBRemoteRegisterContext::WriteAllRegisterValues(583const lldb::DataBufferSP &data_sp) {584if (!data_sp || data_sp->GetBytes() == nullptr || data_sp->GetByteSize() == 0)585return false;586587ExecutionContext exe_ctx(CalculateThread());588589Process *process = exe_ctx.GetProcessPtr();590Thread *thread = exe_ctx.GetThreadPtr();591if (process == nullptr || thread == nullptr)592return false;593594GDBRemoteCommunicationClient &gdb_comm(595((ProcessGDBRemote *)process)->GetGDBRemote());596597const bool use_g_packet =598!gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);599600GDBRemoteClientBase::Lock lock(gdb_comm);601if (lock) {602// The data_sp contains the G response packet.603if (use_g_packet) {604if (gdb_comm.WriteAllRegisters(605m_thread.GetProtocolID(),606{data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))607return true;608609uint32_t num_restored = 0;610// We need to manually go through all of the registers and restore them611// manually612DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),613m_reg_data.GetAddressByteSize());614615const RegisterInfo *reg_info;616617// The g packet contents may either include the slice registers618// (registers defined in terms of other registers, e.g. eax is a subset619// of rax) or not. The slice registers should NOT be in the g packet,620// but some implementations may incorrectly include them.621//622// If the slice registers are included in the packet, we must step over623// the slice registers when parsing the packet -- relying on the624// RegisterInfo byte_offset field would be incorrect. If the slice625// registers are not included, then using the byte_offset values into the626// data buffer is the best way to find individual register values.627628uint64_t size_including_slice_registers = 0;629uint64_t size_not_including_slice_registers = 0;630uint64_t size_by_highest_offset = 0;631632for (uint32_t reg_idx = 0;633(reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr; ++reg_idx) {634size_including_slice_registers += reg_info->byte_size;635if (reg_info->value_regs == nullptr)636size_not_including_slice_registers += reg_info->byte_size;637if (reg_info->byte_offset >= size_by_highest_offset)638size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;639}640641bool use_byte_offset_into_buffer;642if (size_by_highest_offset == restore_data.GetByteSize()) {643// The size of the packet agrees with the highest offset: + size in the644// register file645use_byte_offset_into_buffer = true;646} else if (size_not_including_slice_registers ==647restore_data.GetByteSize()) {648// The size of the packet is the same as concatenating all of the649// registers sequentially, skipping the slice registers650use_byte_offset_into_buffer = true;651} else if (size_including_slice_registers == restore_data.GetByteSize()) {652// The slice registers are present in the packet (when they shouldn't653// be). Don't try to use the RegisterInfo byte_offset into the654// restore_data, it will point to the wrong place.655use_byte_offset_into_buffer = false;656} else {657// None of our expected sizes match the actual g packet data we're658// looking at. The most conservative approach here is to use the659// running total byte offset.660use_byte_offset_into_buffer = false;661}662663// In case our register definitions don't include the correct offsets,664// keep track of the size of each reg & compute offset based on that.665uint32_t running_byte_offset = 0;666for (uint32_t reg_idx = 0;667(reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr;668++reg_idx, running_byte_offset += reg_info->byte_size) {669// Skip composite aka slice registers (e.g. eax is a slice of rax).670if (reg_info->value_regs)671continue;672673const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];674675uint32_t register_offset;676if (use_byte_offset_into_buffer) {677register_offset = reg_info->byte_offset;678} else {679register_offset = running_byte_offset;680}681682const uint32_t reg_byte_size = reg_info->byte_size;683684const uint8_t *restore_src =685restore_data.PeekData(register_offset, reg_byte_size);686if (restore_src) {687SetRegisterIsValid(reg, false);688if (gdb_comm.WriteRegister(689m_thread.GetProtocolID(),690reg_info->kinds[eRegisterKindProcessPlugin],691{restore_src, reg_byte_size}))692++num_restored;693}694}695return num_restored > 0;696} else {697// For the use_g_packet == false case, we're going to write each register698// individually. The data buffer is binary data in this case, instead of699// ascii characters.700701bool arm64_debugserver = false;702if (m_thread.GetProcess().get()) {703const ArchSpec &arch =704m_thread.GetProcess()->GetTarget().GetArchitecture();705if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64 ||706arch.GetMachine() == llvm::Triple::aarch64_32) &&707arch.GetTriple().getVendor() == llvm::Triple::Apple &&708arch.GetTriple().getOS() == llvm::Triple::IOS) {709arm64_debugserver = true;710}711}712uint32_t num_restored = 0;713const RegisterInfo *reg_info;714for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;715i++) {716if (reg_info->value_regs) // skip registers that are slices of real717// registers718continue;719// Skip the fpsr and fpcr floating point status/control register720// writing to work around a bug in an older version of debugserver that721// would lead to register context corruption when writing fpsr/fpcr.722if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||723strcmp(reg_info->name, "fpcr") == 0)) {724continue;725}726727SetRegisterIsValid(reg_info, false);728if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),729reg_info->kinds[eRegisterKindProcessPlugin],730{data_sp->GetBytes() + reg_info->byte_offset,731reg_info->byte_size}))732++num_restored;733}734return num_restored > 0;735}736} else {737Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));738if (log) {739if (log->GetVerbose()) {740StreamString strm;741process->DumpPluginHistory(strm);742LLDB_LOGF(log,743"error: failed to get packet sequence mutex, not sending "744"write all registers:\n%s",745strm.GetData());746} else747LLDB_LOGF(log,748"error: failed to get packet sequence mutex, not sending "749"write all registers");750}751}752return false;753}754755uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(756lldb::RegisterKind kind, uint32_t num) {757return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);758}759760bool GDBRemoteRegisterContext::RegisterWriteCausesReconfigure(761const llvm::StringRef name) {762ExecutionContext exe_ctx(CalculateThread());763const Architecture *architecture =764exe_ctx.GetProcessRef().GetTarget().GetArchitecturePlugin();765return architecture && architecture->RegisterWriteCausesReconfigure(name);766}767768bool GDBRemoteRegisterContext::ReconfigureRegisterInfo() {769ExecutionContext exe_ctx(CalculateThread());770const Architecture *architecture =771exe_ctx.GetProcessRef().GetTarget().GetArchitecturePlugin();772if (architecture)773return architecture->ReconfigureRegisterInfo(*(m_reg_info_sp.get()),774m_reg_data, *this);775return false;776}777778779