778 lines · cpp
1//===-- GDBRemoteRegisterContext.cpp --------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "GDBRemoteRegisterContext.h"10 11#include "ProcessGDBRemote.h"12#include "ProcessGDBRemoteLog.h"13#include "ThreadGDBRemote.h"14#include "Utility/ARM_DWARF_Registers.h"15#include "Utility/ARM_ehframe_Registers.h"16#include "lldb/Core/Architecture.h"17#include "lldb/Target/ExecutionContext.h"18#include "lldb/Target/Target.h"19#include "lldb/Utility/DataBufferHeap.h"20#include "lldb/Utility/DataExtractor.h"21#include "lldb/Utility/RegisterValue.h"22#include "lldb/Utility/Scalar.h"23#include "lldb/Utility/StreamString.h"24#include "lldb/Utility/StringExtractorGDBRemote.h"25 26#include <memory>27 28using namespace lldb;29using namespace lldb_private;30using namespace lldb_private::process_gdb_remote;31 32// GDBRemoteRegisterContext constructor33GDBRemoteRegisterContext::GDBRemoteRegisterContext(34 ThreadGDBRemote &thread, uint32_t concrete_frame_idx,35 GDBRemoteDynamicRegisterInfoSP reg_info_sp, bool read_all_at_once,36 bool write_all_at_once)37 : RegisterContext(thread, concrete_frame_idx),38 m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(),39 m_read_all_at_once(read_all_at_once),40 m_write_all_at_once(write_all_at_once), m_gpacket_cached(false) {41 // Resize our vector of bools to contain one bool for every register. We will42 // use these boolean values to know when a register value is valid in43 // m_reg_data.44 m_reg_valid.resize(m_reg_info_sp->GetNumRegisters());45 46 // Make a heap based buffer that is big enough to store all registers47 DataBufferSP reg_data_sp(48 new DataBufferHeap(m_reg_info_sp->GetRegisterDataByteSize(), 0));49 m_reg_data.SetData(reg_data_sp);50 m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());51}52 53// Destructor54GDBRemoteRegisterContext::~GDBRemoteRegisterContext() = default;55 56void GDBRemoteRegisterContext::InvalidateAllRegisters() {57 SetAllRegisterValid(false);58}59 60void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {61 m_gpacket_cached = b;62 std::vector<bool>::iterator pos, end = m_reg_valid.end();63 for (pos = m_reg_valid.begin(); pos != end; ++pos)64 *pos = b;65}66 67size_t GDBRemoteRegisterContext::GetRegisterCount() {68 return m_reg_info_sp->GetNumRegisters();69}70 71const RegisterInfo *72GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {73 return m_reg_info_sp->GetRegisterInfoAtIndex(reg);74}75 76size_t GDBRemoteRegisterContext::GetRegisterSetCount() {77 return m_reg_info_sp->GetNumRegisterSets();78}79 80const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {81 return m_reg_info_sp->GetRegisterSet(reg_set);82}83 84bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,85 RegisterValue &value) {86 // Read the register87 if (ReadRegisterBytes(reg_info)) {88 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];89 if (m_reg_valid[reg] == false)90 return false;91 if (reg_info->value_regs &&92 reg_info->value_regs[0] != LLDB_INVALID_REGNUM &&93 reg_info->value_regs[1] != LLDB_INVALID_REGNUM) {94 std::vector<char> combined_data;95 uint32_t offset = 0;96 for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {97 const RegisterInfo *parent_reg = GetRegisterInfo(98 eRegisterKindLLDB, reg_info->value_regs[i]);99 if (!parent_reg)100 return false;101 combined_data.resize(offset + parent_reg->byte_size);102 if (m_reg_data.CopyData(parent_reg->byte_offset, parent_reg->byte_size,103 combined_data.data() + offset) !=104 parent_reg->byte_size)105 return false;106 offset += parent_reg->byte_size;107 }108 109 Status error;110 return value.SetFromMemoryData(111 *reg_info, combined_data.data(), combined_data.size(),112 m_reg_data.GetByteOrder(), error) == combined_data.size();113 } else {114 const bool partial_data_ok = false;115 Status error(value.SetValueFromData(116 *reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));117 return error.Success();118 }119 }120 return false;121}122 123bool GDBRemoteRegisterContext::PrivateSetRegisterValue(124 uint32_t reg, llvm::ArrayRef<uint8_t> data) {125 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);126 if (reg_info == nullptr)127 return false;128 129 // Invalidate if needed130 InvalidateIfNeeded(false);131 132 const size_t reg_byte_size = reg_info->byte_size;133 memcpy(const_cast<uint8_t *>(134 m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)),135 data.data(), std::min(data.size(), reg_byte_size));136 bool success = data.size() >= reg_byte_size;137 if (success) {138 SetRegisterIsValid(reg, true);139 } else if (data.size() > 0) {140 // Only set register is valid to false if we copied some bytes, else leave141 // it as it was.142 SetRegisterIsValid(reg, false);143 }144 return success;145}146 147bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,148 uint64_t new_reg_val) {149 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);150 if (reg_info == nullptr)151 return false;152 153 // Early in process startup, we can get a thread that has an invalid byte154 // order because the process hasn't been completely set up yet (see the ctor155 // where the byte order is setfrom the process). If that's the case, we156 // can't set the value here.157 if (m_reg_data.GetByteOrder() == eByteOrderInvalid) {158 return false;159 }160 161 // Invalidate if needed162 InvalidateIfNeeded(false);163 164 DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));165 DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));166 167 // If our register context and our register info disagree, which should never168 // happen, don't overwrite past the end of the buffer.169 if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)170 return false;171 172 // Grab a pointer to where we are going to put this register173 uint8_t *dst = const_cast<uint8_t *>(174 m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));175 176 if (dst == nullptr)177 return false;178 179 if (data.CopyByteOrderedData(0, // src offset180 reg_info->byte_size, // src length181 dst, // dst182 reg_info->byte_size, // dst length183 m_reg_data.GetByteOrder())) // dst byte order184 {185 SetRegisterIsValid(reg, true);186 return true;187 }188 return false;189}190 191// Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().192bool GDBRemoteRegisterContext::GetPrimordialRegister(193 const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {194 const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];195 const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];196 197 if (DataBufferSP buffer_sp =198 gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))199 return PrivateSetRegisterValue(200 lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(),201 buffer_sp->GetByteSize()));202 return false;203}204 205bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info) {206 ExecutionContext exe_ctx(CalculateThread());207 208 Process *process = exe_ctx.GetProcessPtr();209 Thread *thread = exe_ctx.GetThreadPtr();210 if (process == nullptr || thread == nullptr)211 return false;212 213 GDBRemoteCommunicationClient &gdb_comm(214 ((ProcessGDBRemote *)process)->GetGDBRemote());215 216 InvalidateIfNeeded(false);217 218 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];219 220 if (!GetRegisterIsValid(reg)) {221 if (m_read_all_at_once && !m_gpacket_cached) {222 if (DataBufferSP buffer_sp =223 gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {224 memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),225 buffer_sp->GetBytes(),226 std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));227 if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {228 SetAllRegisterValid(true);229 return true;230 } else if (buffer_sp->GetByteSize() > 0) {231 for (auto x : llvm::enumerate(232 m_reg_info_sp->registers<233 DynamicRegisterInfo::reg_collection_const_range>())) {234 const struct RegisterInfo ®info = x.value();235 m_reg_valid[x.index()] =236 (reginfo.byte_offset + reginfo.byte_size <=237 buffer_sp->GetByteSize());238 }239 240 m_gpacket_cached = true;241 if (GetRegisterIsValid(reg))242 return true;243 } else {244 Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));245 LLDB_LOGF(246 log,247 "error: GDBRemoteRegisterContext::ReadRegisterBytes tried "248 "to read the "249 "entire register context at once, expected at least %" PRId64250 " bytes "251 "but only got %" PRId64 " bytes.",252 m_reg_data.GetByteSize(), buffer_sp->GetByteSize());253 return false;254 }255 }256 }257 if (reg_info->value_regs) {258 // Process this composite register request by delegating to the259 // constituent primordial registers.260 261 // Index of the primordial register.262 bool success = true;263 for (uint32_t idx = 0; success; ++idx) {264 const uint32_t prim_reg = reg_info->value_regs[idx];265 if (prim_reg == LLDB_INVALID_REGNUM)266 break;267 // We have a valid primordial register as our constituent. Grab the268 // corresponding register info.269 const RegisterInfo *prim_reg_info =270 GetRegisterInfo(eRegisterKindLLDB, prim_reg);271 if (prim_reg_info == nullptr)272 success = false;273 else {274 // Read the containing register if it hasn't already been read275 if (!GetRegisterIsValid(prim_reg))276 success = GetPrimordialRegister(prim_reg_info, gdb_comm);277 }278 }279 280 if (success) {281 // If we reach this point, all primordial register requests have282 // succeeded. Validate this composite register.283 SetRegisterIsValid(reg_info, true);284 }285 } else {286 // Get each register individually287 GetPrimordialRegister(reg_info, gdb_comm);288 }289 290 // Make sure we got a valid register value after reading it291 if (!GetRegisterIsValid(reg))292 return false;293 }294 295 return true;296}297 298bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info,299 const RegisterValue &value) {300 DataExtractor data;301 if (value.GetData(data)) {302 if (reg_info->value_regs &&303 reg_info->value_regs[0] != LLDB_INVALID_REGNUM &&304 reg_info->value_regs[1] != LLDB_INVALID_REGNUM) {305 uint32_t combined_size = 0;306 for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {307 const RegisterInfo *parent_reg = GetRegisterInfo(308 eRegisterKindLLDB, reg_info->value_regs[i]);309 if (!parent_reg)310 return false;311 combined_size += parent_reg->byte_size;312 }313 314 if (data.GetByteSize() < combined_size)315 return false;316 317 uint32_t offset = 0;318 for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {319 const RegisterInfo *parent_reg = GetRegisterInfo(320 eRegisterKindLLDB, reg_info->value_regs[i]);321 assert(parent_reg);322 323 DataExtractor parent_data{data, offset, parent_reg->byte_size};324 if (!WriteRegisterBytes(parent_reg, parent_data, 0))325 return false;326 offset += parent_reg->byte_size;327 }328 assert(offset == combined_size);329 return true;330 } else331 return WriteRegisterBytes(reg_info, data, 0);332 }333 return false;334}335 336// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().337bool GDBRemoteRegisterContext::SetPrimordialRegister(338 const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {339 StreamString packet;340 StringExtractorGDBRemote response;341 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];342 // Invalidate just this register343 SetRegisterIsValid(reg, false);344 345 return gdb_comm.WriteRegister(346 m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],347 {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),348 reg_info->byte_size});349}350 351bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,352 DataExtractor &data,353 uint32_t data_offset) {354 ExecutionContext exe_ctx(CalculateThread());355 356 Process *process = exe_ctx.GetProcessPtr();357 Thread *thread = exe_ctx.GetThreadPtr();358 if (process == nullptr || thread == nullptr)359 return false;360 361 GDBRemoteCommunicationClient &gdb_comm(362 ((ProcessGDBRemote *)process)->GetGDBRemote());363 364 assert(m_reg_data.GetByteSize() >=365 reg_info->byte_offset + reg_info->byte_size);366 367 // If our register context and our register info disagree, which should never368 // happen, don't overwrite past the end of the buffer.369 if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)370 return false;371 372 // Grab a pointer to where we are going to put this register373 uint8_t *dst = const_cast<uint8_t *>(374 m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));375 376 if (dst == nullptr)377 return false;378 379 const bool should_reconfigure_registers =380 RegisterWriteCausesReconfigure(reg_info->name);381 382 if (data.CopyByteOrderedData(data_offset, // src offset383 reg_info->byte_size, // src length384 dst, // dst385 reg_info->byte_size, // dst length386 m_reg_data.GetByteOrder())) // dst byte order387 {388 GDBRemoteClientBase::Lock lock(gdb_comm);389 if (lock) {390 if (m_write_all_at_once) {391 // Invalidate all register values392 InvalidateIfNeeded(true);393 394 // Set all registers in one packet395 if (gdb_comm.WriteAllRegisters(396 m_thread.GetProtocolID(),397 {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))398 399 {400 if (should_reconfigure_registers)401 ReconfigureRegisterInfo();402 403 InvalidateAllRegisters();404 405 return true;406 }407 } else {408 bool success = true;409 410 if (reg_info->value_regs) {411 // This register is part of another register. In this case we read412 // the actual register data for any "value_regs", and once all that413 // data is read, we will have enough data in our register context414 // bytes for the value of this register415 416 // Invalidate this composite register first.417 418 for (uint32_t idx = 0; success; ++idx) {419 const uint32_t reg = reg_info->value_regs[idx];420 if (reg == LLDB_INVALID_REGNUM)421 break;422 // We have a valid primordial register as our constituent. Grab the423 // corresponding register info.424 const RegisterInfo *value_reg_info =425 GetRegisterInfo(eRegisterKindLLDB, reg);426 if (value_reg_info == nullptr)427 success = false;428 else429 success = SetPrimordialRegister(value_reg_info, gdb_comm);430 }431 } else {432 // This is an actual register, write it433 success = SetPrimordialRegister(reg_info, gdb_comm);434 }435 436 // Check if writing this register will invalidate any other register437 // values? If so, invalidate them438 if (reg_info->invalidate_regs) {439 for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];440 reg != LLDB_INVALID_REGNUM;441 reg = reg_info->invalidate_regs[++idx])442 SetRegisterIsValid(ConvertRegisterKindToRegisterNumber(443 eRegisterKindLLDB, reg),444 false);445 }446 447 if (success && should_reconfigure_registers &&448 ReconfigureRegisterInfo())449 InvalidateAllRegisters();450 451 return success;452 }453 } else {454 Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));455 if (log) {456 if (log->GetVerbose()) {457 StreamString strm;458 process->DumpPluginHistory(strm);459 LLDB_LOGF(log,460 "error: failed to get packet sequence mutex, not sending "461 "write register for \"%s\":\n%s",462 reg_info->name, strm.GetData());463 } else464 LLDB_LOGF(log,465 "error: failed to get packet sequence mutex, not sending "466 "write register for \"%s\"",467 reg_info->name);468 }469 }470 }471 return false;472}473 474bool GDBRemoteRegisterContext::ReadAllRegisterValues(475 RegisterCheckpoint ®_checkpoint) {476 ExecutionContext exe_ctx(CalculateThread());477 478 Process *process = exe_ctx.GetProcessPtr();479 Thread *thread = exe_ctx.GetThreadPtr();480 if (process == nullptr || thread == nullptr)481 return false;482 483 GDBRemoteCommunicationClient &gdb_comm(484 ((ProcessGDBRemote *)process)->GetGDBRemote());485 486 uint32_t save_id = 0;487 if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) {488 reg_checkpoint.SetID(save_id);489 reg_checkpoint.GetData().reset();490 return true;491 } else {492 reg_checkpoint.SetID(0); // Invalid save ID is zero493 return ReadAllRegisterValues(reg_checkpoint.GetData());494 }495}496 497bool GDBRemoteRegisterContext::WriteAllRegisterValues(498 const RegisterCheckpoint ®_checkpoint) {499 uint32_t save_id = reg_checkpoint.GetID();500 if (save_id != 0) {501 ExecutionContext exe_ctx(CalculateThread());502 503 Process *process = exe_ctx.GetProcessPtr();504 Thread *thread = exe_ctx.GetThreadPtr();505 if (process == nullptr || thread == nullptr)506 return false;507 508 GDBRemoteCommunicationClient &gdb_comm(509 ((ProcessGDBRemote *)process)->GetGDBRemote());510 511 return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);512 } else {513 return WriteAllRegisterValues(reg_checkpoint.GetData());514 }515}516 517bool GDBRemoteRegisterContext::ReadAllRegisterValues(518 lldb::WritableDataBufferSP &data_sp) {519 ExecutionContext exe_ctx(CalculateThread());520 521 Process *process = exe_ctx.GetProcessPtr();522 Thread *thread = exe_ctx.GetThreadPtr();523 if (process == nullptr || thread == nullptr)524 return false;525 526 GDBRemoteCommunicationClient &gdb_comm(527 ((ProcessGDBRemote *)process)->GetGDBRemote());528 529 const bool use_g_packet =530 !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);531 532 GDBRemoteClientBase::Lock lock(gdb_comm);533 if (lock) {534 if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))535 InvalidateAllRegisters();536 537 if (use_g_packet) {538 if (DataBufferSP data_buffer =539 gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {540 data_sp = std::make_shared<DataBufferHeap>(*data_buffer);541 return true;542 }543 }544 545 // We're going to read each register546 // individually and store them as binary data in a buffer.547 const RegisterInfo *reg_info;548 549 for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;550 i++) {551 if (reg_info552 ->value_regs) // skip registers that are slices of real registers553 continue;554 ReadRegisterBytes(reg_info);555 // ReadRegisterBytes saves the contents of the register in to the556 // m_reg_data buffer557 }558 data_sp = std::make_shared<DataBufferHeap>(559 m_reg_data.GetDataStart(), m_reg_info_sp->GetRegisterDataByteSize());560 return true;561 } else {562 563 Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));564 if (log) {565 if (log->GetVerbose()) {566 StreamString strm;567 process->DumpPluginHistory(strm);568 LLDB_LOGF(log,569 "error: failed to get packet sequence mutex, not sending "570 "read all registers:\n%s",571 strm.GetData());572 } else573 LLDB_LOGF(log,574 "error: failed to get packet sequence mutex, not sending "575 "read all registers");576 }577 }578 579 data_sp.reset();580 return false;581}582 583bool GDBRemoteRegisterContext::WriteAllRegisterValues(584 const lldb::DataBufferSP &data_sp) {585 if (!data_sp || data_sp->GetBytes() == nullptr || data_sp->GetByteSize() == 0)586 return false;587 588 ExecutionContext exe_ctx(CalculateThread());589 590 Process *process = exe_ctx.GetProcessPtr();591 Thread *thread = exe_ctx.GetThreadPtr();592 if (process == nullptr || thread == nullptr)593 return false;594 595 GDBRemoteCommunicationClient &gdb_comm(596 ((ProcessGDBRemote *)process)->GetGDBRemote());597 598 const bool use_g_packet =599 !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);600 601 GDBRemoteClientBase::Lock lock(gdb_comm);602 if (lock) {603 // The data_sp contains the G response packet.604 if (use_g_packet) {605 if (gdb_comm.WriteAllRegisters(606 m_thread.GetProtocolID(),607 {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))608 return true;609 610 uint32_t num_restored = 0;611 // We need to manually go through all of the registers and restore them612 // manually613 DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),614 m_reg_data.GetAddressByteSize());615 616 const RegisterInfo *reg_info;617 618 // The g packet contents may either include the slice registers619 // (registers defined in terms of other registers, e.g. eax is a subset620 // of rax) or not. The slice registers should NOT be in the g packet,621 // but some implementations may incorrectly include them.622 //623 // If the slice registers are included in the packet, we must step over624 // the slice registers when parsing the packet -- relying on the625 // RegisterInfo byte_offset field would be incorrect. If the slice626 // registers are not included, then using the byte_offset values into the627 // data buffer is the best way to find individual register values.628 629 uint64_t size_including_slice_registers = 0;630 uint64_t size_not_including_slice_registers = 0;631 uint64_t size_by_highest_offset = 0;632 633 for (uint32_t reg_idx = 0;634 (reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr; ++reg_idx) {635 size_including_slice_registers += reg_info->byte_size;636 if (reg_info->value_regs == nullptr)637 size_not_including_slice_registers += reg_info->byte_size;638 if (reg_info->byte_offset >= size_by_highest_offset)639 size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;640 }641 642 bool use_byte_offset_into_buffer;643 if (size_by_highest_offset == restore_data.GetByteSize()) {644 // The size of the packet agrees with the highest offset: + size in the645 // register file646 use_byte_offset_into_buffer = true;647 } else if (size_not_including_slice_registers ==648 restore_data.GetByteSize()) {649 // The size of the packet is the same as concatenating all of the650 // registers sequentially, skipping the slice registers651 use_byte_offset_into_buffer = true;652 } else if (size_including_slice_registers == restore_data.GetByteSize()) {653 // The slice registers are present in the packet (when they shouldn't654 // be). Don't try to use the RegisterInfo byte_offset into the655 // restore_data, it will point to the wrong place.656 use_byte_offset_into_buffer = false;657 } else {658 // None of our expected sizes match the actual g packet data we're659 // looking at. The most conservative approach here is to use the660 // running total byte offset.661 use_byte_offset_into_buffer = false;662 }663 664 // In case our register definitions don't include the correct offsets,665 // keep track of the size of each reg & compute offset based on that.666 uint32_t running_byte_offset = 0;667 for (uint32_t reg_idx = 0;668 (reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr;669 ++reg_idx, running_byte_offset += reg_info->byte_size) {670 // Skip composite aka slice registers (e.g. eax is a slice of rax).671 if (reg_info->value_regs)672 continue;673 674 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];675 676 uint32_t register_offset;677 if (use_byte_offset_into_buffer) {678 register_offset = reg_info->byte_offset;679 } else {680 register_offset = running_byte_offset;681 }682 683 const uint32_t reg_byte_size = reg_info->byte_size;684 685 const uint8_t *restore_src =686 restore_data.PeekData(register_offset, reg_byte_size);687 if (restore_src) {688 SetRegisterIsValid(reg, false);689 if (gdb_comm.WriteRegister(690 m_thread.GetProtocolID(),691 reg_info->kinds[eRegisterKindProcessPlugin],692 {restore_src, reg_byte_size}))693 ++num_restored;694 }695 }696 return num_restored > 0;697 } else {698 // For the use_g_packet == false case, we're going to write each register699 // individually. The data buffer is binary data in this case, instead of700 // ascii characters.701 702 bool arm64_debugserver = false;703 if (m_thread.GetProcess().get()) {704 const ArchSpec &arch =705 m_thread.GetProcess()->GetTarget().GetArchitecture();706 if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64 ||707 arch.GetMachine() == llvm::Triple::aarch64_32) &&708 arch.GetTriple().getVendor() == llvm::Triple::Apple &&709 arch.GetTriple().getOS() == llvm::Triple::IOS) {710 arm64_debugserver = true;711 }712 }713 uint32_t num_restored = 0;714 const RegisterInfo *reg_info;715 for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;716 i++) {717 if (reg_info->value_regs) // skip registers that are slices of real718 // registers719 continue;720 // Skip the fpsr and fpcr floating point status/control register721 // writing to work around a bug in an older version of debugserver that722 // would lead to register context corruption when writing fpsr/fpcr.723 if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||724 strcmp(reg_info->name, "fpcr") == 0)) {725 continue;726 }727 728 SetRegisterIsValid(reg_info, false);729 if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),730 reg_info->kinds[eRegisterKindProcessPlugin],731 {data_sp->GetBytes() + reg_info->byte_offset,732 reg_info->byte_size}))733 ++num_restored;734 }735 return num_restored > 0;736 }737 } else {738 Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));739 if (log) {740 if (log->GetVerbose()) {741 StreamString strm;742 process->DumpPluginHistory(strm);743 LLDB_LOGF(log,744 "error: failed to get packet sequence mutex, not sending "745 "write all registers:\n%s",746 strm.GetData());747 } else748 LLDB_LOGF(log,749 "error: failed to get packet sequence mutex, not sending "750 "write all registers");751 }752 }753 return false;754}755 756uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(757 lldb::RegisterKind kind, uint32_t num) {758 return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);759}760 761bool GDBRemoteRegisterContext::RegisterWriteCausesReconfigure(762 const llvm::StringRef name) {763 ExecutionContext exe_ctx(CalculateThread());764 const Architecture *architecture =765 exe_ctx.GetProcessRef().GetTarget().GetArchitecturePlugin();766 return architecture && architecture->RegisterWriteCausesReconfigure(name);767}768 769bool GDBRemoteRegisterContext::ReconfigureRegisterInfo() {770 ExecutionContext exe_ctx(CalculateThread());771 const Architecture *architecture =772 exe_ctx.GetProcessRef().GetTarget().GetArchitecturePlugin();773 if (architecture)774 return architecture->ReconfigureRegisterInfo(*(m_reg_info_sp.get()),775 m_reg_data, *this);776 return false;777}778