xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (revision 1fd87a682ad7442327078e1eeb63edc4258f9815)
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "GDBRemoteRegisterContext.h"
10 
11 #include "lldb/Target/ExecutionContext.h"
12 #include "lldb/Target/Target.h"
13 #include "lldb/Utility/DataBufferHeap.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "lldb/Utility/RegisterValue.h"
16 #include "lldb/Utility/Scalar.h"
17 #include "lldb/Utility/StreamString.h"
18 #include "ProcessGDBRemote.h"
19 #include "ProcessGDBRemoteLog.h"
20 #include "ThreadGDBRemote.h"
21 #include "Utility/ARM_DWARF_Registers.h"
22 #include "Utility/ARM_ehframe_Registers.h"
23 #include "lldb/Utility/StringExtractorGDBRemote.h"
24 
25 #include <memory>
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 using namespace lldb_private::process_gdb_remote;
30 
31 // GDBRemoteRegisterContext constructor
32 GDBRemoteRegisterContext::GDBRemoteRegisterContext(
33     ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
34     GDBRemoteDynamicRegisterInfoSP reg_info_sp, bool read_all_at_once,
35     bool write_all_at_once)
36     : RegisterContext(thread, concrete_frame_idx),
37       m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(),
38       m_read_all_at_once(read_all_at_once),
39       m_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 will
41   // use these boolean values to know when a register value is valid in
42   // m_reg_data.
43   m_reg_valid.resize(m_reg_info_sp->GetNumRegisters());
44 
45   // Make a heap based buffer that is big enough to store all registers
46   DataBufferSP reg_data_sp(
47       new DataBufferHeap(m_reg_info_sp->GetRegisterDataByteSize(), 0));
48   m_reg_data.SetData(reg_data_sp);
49   m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
50 }
51 
52 // Destructor
53 GDBRemoteRegisterContext::~GDBRemoteRegisterContext() = default;
54 
55 void GDBRemoteRegisterContext::InvalidateAllRegisters() {
56   SetAllRegisterValid(false);
57 }
58 
59 void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
60   m_gpacket_cached = b;
61   std::vector<bool>::iterator pos, end = m_reg_valid.end();
62   for (pos = m_reg_valid.begin(); pos != end; ++pos)
63     *pos = b;
64 }
65 
66 size_t GDBRemoteRegisterContext::GetRegisterCount() {
67   return m_reg_info_sp->GetNumRegisters();
68 }
69 
70 const RegisterInfo *
71 GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
72   return m_reg_info_sp->GetRegisterInfoAtIndex(reg);
73 }
74 
75 size_t GDBRemoteRegisterContext::GetRegisterSetCount() {
76   return m_reg_info_sp->GetNumRegisterSets();
77 }
78 
79 const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {
80   return m_reg_info_sp->GetRegisterSet(reg_set);
81 }
82 
83 bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
84                                             RegisterValue &value) {
85   // Read the register
86   if (ReadRegisterBytes(reg_info)) {
87     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
88     if (m_reg_valid[reg] == false)
89       return false;
90     if (reg_info->value_regs &&
91         reg_info->value_regs[0] != LLDB_INVALID_REGNUM &&
92         reg_info->value_regs[1] != LLDB_INVALID_REGNUM) {
93       std::vector<char> combined_data;
94       uint32_t offset = 0;
95       for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {
96         const RegisterInfo *parent_reg = GetRegisterInfo(
97             eRegisterKindLLDB, reg_info->value_regs[i]);
98         if (!parent_reg)
99           return false;
100         combined_data.resize(offset + parent_reg->byte_size);
101         if (m_reg_data.CopyData(parent_reg->byte_offset, parent_reg->byte_size,
102                                 combined_data.data() + offset) !=
103             parent_reg->byte_size)
104           return false;
105         offset += parent_reg->byte_size;
106       }
107 
108       Status error;
109       return value.SetFromMemoryData(
110                  reg_info, combined_data.data(), combined_data.size(),
111                  m_reg_data.GetByteOrder(), error) == combined_data.size();
112     } else {
113       const bool partial_data_ok = false;
114       Status error(value.SetValueFromData(
115           reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));
116       return error.Success();
117     }
118   }
119   return false;
120 }
121 
122 bool GDBRemoteRegisterContext::PrivateSetRegisterValue(
123     uint32_t reg, llvm::ArrayRef<uint8_t> data) {
124   const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
125   if (reg_info == nullptr)
126     return false;
127 
128   // Invalidate if needed
129   InvalidateIfNeeded(false);
130 
131   const size_t reg_byte_size = reg_info->byte_size;
132   memcpy(const_cast<uint8_t *>(
133              m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)),
134          data.data(), std::min(data.size(), reg_byte_size));
135   bool success = data.size() >= reg_byte_size;
136   if (success) {
137     SetRegisterIsValid(reg, true);
138   } else if (data.size() > 0) {
139     // Only set register is valid to false if we copied some bytes, else leave
140     // it as it was.
141     SetRegisterIsValid(reg, false);
142   }
143   return success;
144 }
145 
146 bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
147                                                        uint64_t new_reg_val) {
148   const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
149   if (reg_info == nullptr)
150     return false;
151 
152   // Early in process startup, we can get a thread that has an invalid byte
153   // order because the process hasn't been completely set up yet (see the ctor
154   // where the byte order is setfrom the process).  If that's the case, we
155   // can't set the value here.
156   if (m_reg_data.GetByteOrder() == eByteOrderInvalid) {
157     return false;
158   }
159 
160   // Invalidate if needed
161   InvalidateIfNeeded(false);
162 
163   DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));
164   DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
165 
166   // If our register context and our register info disagree, which should never
167   // happen, don't overwrite past the end of the buffer.
168   if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
169     return false;
170 
171   // Grab a pointer to where we are going to put this register
172   uint8_t *dst = const_cast<uint8_t *>(
173       m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
174 
175   if (dst == nullptr)
176     return false;
177 
178   if (data.CopyByteOrderedData(0,                          // src offset
179                                reg_info->byte_size,        // src length
180                                dst,                        // dst
181                                reg_info->byte_size,        // dst length
182                                m_reg_data.GetByteOrder())) // dst byte order
183   {
184     SetRegisterIsValid(reg, true);
185     return true;
186   }
187   return false;
188 }
189 
190 // Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().
191 bool GDBRemoteRegisterContext::GetPrimordialRegister(
192     const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
193   const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
194   const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
195 
196   if (DataBufferSP buffer_sp =
197           gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
198     return PrivateSetRegisterValue(
199         lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(),
200                                           buffer_sp->GetByteSize()));
201   return false;
202 }
203 
204 bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info) {
205   ExecutionContext exe_ctx(CalculateThread());
206 
207   Process *process = exe_ctx.GetProcessPtr();
208   Thread *thread = exe_ctx.GetThreadPtr();
209   if (process == nullptr || thread == nullptr)
210     return false;
211 
212   GDBRemoteCommunicationClient &gdb_comm(
213       ((ProcessGDBRemote *)process)->GetGDBRemote());
214 
215   InvalidateIfNeeded(false);
216 
217   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
218 
219   if (!GetRegisterIsValid(reg)) {
220     if (m_read_all_at_once && !m_gpacket_cached) {
221       if (DataBufferSP buffer_sp =
222               gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
223         memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),
224                buffer_sp->GetBytes(),
225                std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));
226         if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {
227           SetAllRegisterValid(true);
228           return true;
229         } else if (buffer_sp->GetByteSize() > 0) {
230           for (auto x : llvm::enumerate(m_reg_info_sp->registers())) {
231             const struct RegisterInfo &reginfo = x.value();
232             m_reg_valid[x.index()] =
233                 (reginfo.byte_offset + reginfo.byte_size <=
234                  buffer_sp->GetByteSize());
235           }
236 
237           m_gpacket_cached = true;
238           if (GetRegisterIsValid(reg))
239             return true;
240         } else {
241           Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
242           LLDB_LOGF(
243               log,
244               "error: GDBRemoteRegisterContext::ReadRegisterBytes tried "
245               "to read the "
246               "entire register context at once, expected at least %" PRId64
247               " bytes "
248               "but only got %" PRId64 " bytes.",
249               m_reg_data.GetByteSize(), buffer_sp->GetByteSize());
250           return false;
251         }
252       }
253     }
254     if (reg_info->value_regs) {
255       // Process this composite register request by delegating to the
256       // constituent primordial registers.
257 
258       // Index of the primordial register.
259       bool success = true;
260       for (uint32_t idx = 0; success; ++idx) {
261         const uint32_t prim_reg = reg_info->value_regs[idx];
262         if (prim_reg == LLDB_INVALID_REGNUM)
263           break;
264         // We have a valid primordial register as our constituent. Grab the
265         // corresponding register info.
266         const RegisterInfo *prim_reg_info =
267             GetRegisterInfo(eRegisterKindLLDB, prim_reg);
268         if (prim_reg_info == nullptr)
269           success = false;
270         else {
271           // Read the containing register if it hasn't already been read
272           if (!GetRegisterIsValid(prim_reg))
273             success = GetPrimordialRegister(prim_reg_info, gdb_comm);
274         }
275       }
276 
277       if (success) {
278         // If we reach this point, all primordial register requests have
279         // succeeded. Validate this composite register.
280         SetRegisterIsValid(reg_info, true);
281       }
282     } else {
283       // Get each register individually
284       GetPrimordialRegister(reg_info, gdb_comm);
285     }
286 
287     // Make sure we got a valid register value after reading it
288     if (!GetRegisterIsValid(reg))
289       return false;
290   }
291 
292   return true;
293 }
294 
295 bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info,
296                                              const RegisterValue &value) {
297   DataExtractor data;
298   if (value.GetData(data)) {
299     if (reg_info->value_regs &&
300         reg_info->value_regs[0] != LLDB_INVALID_REGNUM &&
301         reg_info->value_regs[1] != LLDB_INVALID_REGNUM) {
302       uint32_t combined_size = 0;
303       for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {
304         const RegisterInfo *parent_reg = GetRegisterInfo(
305             eRegisterKindLLDB, reg_info->value_regs[i]);
306         if (!parent_reg)
307           return false;
308         combined_size += parent_reg->byte_size;
309       }
310 
311       if (data.GetByteSize() < combined_size)
312         return false;
313 
314       uint32_t offset = 0;
315       for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {
316         const RegisterInfo *parent_reg = GetRegisterInfo(
317             eRegisterKindLLDB, reg_info->value_regs[i]);
318         assert(parent_reg);
319 
320         DataExtractor parent_data{data, offset, parent_reg->byte_size};
321         if (!WriteRegisterBytes(parent_reg, parent_data, 0))
322           return false;
323         offset += parent_reg->byte_size;
324       }
325       assert(offset == combined_size);
326       return true;
327     } else
328       return WriteRegisterBytes(reg_info, data, 0);
329   }
330   return false;
331 }
332 
333 // Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
334 bool GDBRemoteRegisterContext::SetPrimordialRegister(
335     const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
336   StreamString packet;
337   StringExtractorGDBRemote response;
338   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
339   // Invalidate just this register
340   SetRegisterIsValid(reg, false);
341 
342   return gdb_comm.WriteRegister(
343       m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],
344       {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
345        reg_info->byte_size});
346 }
347 
348 bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
349                                                   DataExtractor &data,
350                                                   uint32_t data_offset) {
351   ExecutionContext exe_ctx(CalculateThread());
352 
353   Process *process = exe_ctx.GetProcessPtr();
354   Thread *thread = exe_ctx.GetThreadPtr();
355   if (process == nullptr || thread == nullptr)
356     return false;
357 
358   GDBRemoteCommunicationClient &gdb_comm(
359       ((ProcessGDBRemote *)process)->GetGDBRemote());
360 
361   assert(m_reg_data.GetByteSize() >=
362          reg_info->byte_offset + reg_info->byte_size);
363 
364   // If our register context and our register info disagree, which should never
365   // happen, don't overwrite past the end of the buffer.
366   if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
367     return false;
368 
369   // Grab a pointer to where we are going to put this register
370   uint8_t *dst = const_cast<uint8_t *>(
371       m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
372 
373   if (dst == nullptr)
374     return false;
375 
376   // Code below is specific to AArch64 target in SVE state
377   // If vector granule (vg) register is being written then thread's
378   // register context reconfiguration is triggered on success.
379   bool do_reconfigure_arm64_sve = false;
380   const ArchSpec &arch = process->GetTarget().GetArchitecture();
381   if (arch.IsValid() && arch.GetTriple().isAArch64())
382     if (strcmp(reg_info->name, "vg") == 0)
383       do_reconfigure_arm64_sve = true;
384 
385   if (data.CopyByteOrderedData(data_offset,                // src offset
386                                reg_info->byte_size,        // src length
387                                dst,                        // dst
388                                reg_info->byte_size,        // dst length
389                                m_reg_data.GetByteOrder())) // dst byte order
390   {
391     GDBRemoteClientBase::Lock lock(gdb_comm);
392     if (lock) {
393       if (m_write_all_at_once) {
394         // Invalidate all register values
395         InvalidateIfNeeded(true);
396 
397         // Set all registers in one packet
398         if (gdb_comm.WriteAllRegisters(
399                 m_thread.GetProtocolID(),
400                 {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
401 
402         {
403           SetAllRegisterValid(false);
404 
405           if (do_reconfigure_arm64_sve)
406             AArch64SVEReconfigure();
407 
408           return true;
409         }
410       } else {
411         bool success = true;
412 
413         if (reg_info->value_regs) {
414           // This register is part of another register. In this case we read
415           // the actual register data for any "value_regs", and once all that
416           // data is read, we will have enough data in our register context
417           // bytes for the value of this register
418 
419           // Invalidate this composite register first.
420 
421           for (uint32_t idx = 0; success; ++idx) {
422             const uint32_t reg = reg_info->value_regs[idx];
423             if (reg == LLDB_INVALID_REGNUM)
424               break;
425             // We have a valid primordial register as our constituent. Grab the
426             // corresponding register info.
427             const RegisterInfo *value_reg_info =
428                 GetRegisterInfo(eRegisterKindLLDB, reg);
429             if (value_reg_info == nullptr)
430               success = false;
431             else
432               success = SetPrimordialRegister(value_reg_info, gdb_comm);
433           }
434         } else {
435           // This is an actual register, write it
436           success = SetPrimordialRegister(reg_info, gdb_comm);
437 
438           if (success && do_reconfigure_arm64_sve)
439             AArch64SVEReconfigure();
440         }
441 
442         // Check if writing this register will invalidate any other register
443         // values? If so, invalidate them
444         if (reg_info->invalidate_regs) {
445           for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
446                reg != LLDB_INVALID_REGNUM;
447                reg = reg_info->invalidate_regs[++idx])
448             SetRegisterIsValid(ConvertRegisterKindToRegisterNumber(
449                                    eRegisterKindLLDB, reg),
450                                false);
451         }
452 
453         return success;
454       }
455     } else {
456       Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
457       if (log) {
458         if (log->GetVerbose()) {
459           StreamString strm;
460           gdb_comm.DumpHistory(strm);
461           LLDB_LOGF(log,
462                     "error: failed to get packet sequence mutex, not sending "
463                     "write register for \"%s\":\n%s",
464                     reg_info->name, strm.GetData());
465         } else
466           LLDB_LOGF(log,
467                     "error: failed to get packet sequence mutex, not sending "
468                     "write register for \"%s\"",
469                     reg_info->name);
470       }
471     }
472   }
473   return false;
474 }
475 
476 bool GDBRemoteRegisterContext::ReadAllRegisterValues(
477     RegisterCheckpoint &reg_checkpoint) {
478   ExecutionContext exe_ctx(CalculateThread());
479 
480   Process *process = exe_ctx.GetProcessPtr();
481   Thread *thread = exe_ctx.GetThreadPtr();
482   if (process == nullptr || thread == nullptr)
483     return false;
484 
485   GDBRemoteCommunicationClient &gdb_comm(
486       ((ProcessGDBRemote *)process)->GetGDBRemote());
487 
488   uint32_t save_id = 0;
489   if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) {
490     reg_checkpoint.SetID(save_id);
491     reg_checkpoint.GetData().reset();
492     return true;
493   } else {
494     reg_checkpoint.SetID(0); // Invalid save ID is zero
495     return ReadAllRegisterValues(reg_checkpoint.GetData());
496   }
497 }
498 
499 bool GDBRemoteRegisterContext::WriteAllRegisterValues(
500     const RegisterCheckpoint &reg_checkpoint) {
501   uint32_t save_id = reg_checkpoint.GetID();
502   if (save_id != 0) {
503     ExecutionContext exe_ctx(CalculateThread());
504 
505     Process *process = exe_ctx.GetProcessPtr();
506     Thread *thread = exe_ctx.GetThreadPtr();
507     if (process == nullptr || thread == nullptr)
508       return false;
509 
510     GDBRemoteCommunicationClient &gdb_comm(
511         ((ProcessGDBRemote *)process)->GetGDBRemote());
512 
513     return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
514   } else {
515     return WriteAllRegisterValues(reg_checkpoint.GetData());
516   }
517 }
518 
519 bool GDBRemoteRegisterContext::ReadAllRegisterValues(
520     lldb::DataBufferSP &data_sp) {
521   ExecutionContext exe_ctx(CalculateThread());
522 
523   Process *process = exe_ctx.GetProcessPtr();
524   Thread *thread = exe_ctx.GetThreadPtr();
525   if (process == nullptr || thread == nullptr)
526     return false;
527 
528   GDBRemoteCommunicationClient &gdb_comm(
529       ((ProcessGDBRemote *)process)->GetGDBRemote());
530 
531   const bool use_g_packet =
532       !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
533 
534   GDBRemoteClientBase::Lock lock(gdb_comm);
535   if (lock) {
536     if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
537       InvalidateAllRegisters();
538 
539     if (use_g_packet &&
540         (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())))
541       return true;
542 
543     // We're going to read each register
544     // individually and store them as binary data in a buffer.
545     const RegisterInfo *reg_info;
546 
547     for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;
548          i++) {
549       if (reg_info
550               ->value_regs) // skip registers that are slices of real registers
551         continue;
552       ReadRegisterBytes(reg_info);
553       // ReadRegisterBytes saves the contents of the register in to the
554       // m_reg_data buffer
555     }
556     data_sp = std::make_shared<DataBufferHeap>(
557         m_reg_data.GetDataStart(), m_reg_info_sp->GetRegisterDataByteSize());
558     return true;
559   } else {
560 
561     Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
562     if (log) {
563       if (log->GetVerbose()) {
564         StreamString strm;
565         gdb_comm.DumpHistory(strm);
566         LLDB_LOGF(log,
567                   "error: failed to get packet sequence mutex, not sending "
568                   "read all registers:\n%s",
569                   strm.GetData());
570       } else
571         LLDB_LOGF(log,
572                   "error: failed to get packet sequence mutex, not sending "
573                   "read all registers");
574     }
575   }
576 
577   data_sp.reset();
578   return false;
579 }
580 
581 bool GDBRemoteRegisterContext::WriteAllRegisterValues(
582     const lldb::DataBufferSP &data_sp) {
583   if (!data_sp || data_sp->GetBytes() == nullptr || data_sp->GetByteSize() == 0)
584     return false;
585 
586   ExecutionContext exe_ctx(CalculateThread());
587 
588   Process *process = exe_ctx.GetProcessPtr();
589   Thread *thread = exe_ctx.GetThreadPtr();
590   if (process == nullptr || thread == nullptr)
591     return false;
592 
593   GDBRemoteCommunicationClient &gdb_comm(
594       ((ProcessGDBRemote *)process)->GetGDBRemote());
595 
596   const bool use_g_packet =
597       !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
598 
599   GDBRemoteClientBase::Lock lock(gdb_comm);
600   if (lock) {
601     // The data_sp contains the G response packet.
602     if (use_g_packet) {
603       if (gdb_comm.WriteAllRegisters(
604               m_thread.GetProtocolID(),
605               {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))
606         return true;
607 
608       uint32_t num_restored = 0;
609       // We need to manually go through all of the registers and restore them
610       // manually
611       DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),
612                                  m_reg_data.GetAddressByteSize());
613 
614       const RegisterInfo *reg_info;
615 
616       // The g packet contents may either include the slice registers
617       // (registers defined in terms of other registers, e.g. eax is a subset
618       // of rax) or not.  The slice registers should NOT be in the g packet,
619       // but some implementations may incorrectly include them.
620       //
621       // If the slice registers are included in the packet, we must step over
622       // the slice registers when parsing the packet -- relying on the
623       // RegisterInfo byte_offset field would be incorrect. If the slice
624       // registers are not included, then using the byte_offset values into the
625       // data buffer is the best way to find individual register values.
626 
627       uint64_t size_including_slice_registers = 0;
628       uint64_t size_not_including_slice_registers = 0;
629       uint64_t size_by_highest_offset = 0;
630 
631       for (uint32_t reg_idx = 0;
632            (reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr; ++reg_idx) {
633         size_including_slice_registers += reg_info->byte_size;
634         if (reg_info->value_regs == nullptr)
635           size_not_including_slice_registers += reg_info->byte_size;
636         if (reg_info->byte_offset >= size_by_highest_offset)
637           size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
638       }
639 
640       bool use_byte_offset_into_buffer;
641       if (size_by_highest_offset == restore_data.GetByteSize()) {
642         // The size of the packet agrees with the highest offset: + size in the
643         // register file
644         use_byte_offset_into_buffer = true;
645       } else if (size_not_including_slice_registers ==
646                  restore_data.GetByteSize()) {
647         // The size of the packet is the same as concatenating all of the
648         // registers sequentially, skipping the slice registers
649         use_byte_offset_into_buffer = true;
650       } else if (size_including_slice_registers == restore_data.GetByteSize()) {
651         // The slice registers are present in the packet (when they shouldn't
652         // be). Don't try to use the RegisterInfo byte_offset into the
653         // restore_data, it will point to the wrong place.
654         use_byte_offset_into_buffer = false;
655       } else {
656         // None of our expected sizes match the actual g packet data we're
657         // looking at. The most conservative approach here is to use the
658         // running total byte offset.
659         use_byte_offset_into_buffer = false;
660       }
661 
662       // In case our register definitions don't include the correct offsets,
663       // keep track of the size of each reg & compute offset based on that.
664       uint32_t running_byte_offset = 0;
665       for (uint32_t reg_idx = 0;
666            (reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr;
667            ++reg_idx, running_byte_offset += reg_info->byte_size) {
668         // Skip composite aka slice registers (e.g. eax is a slice of rax).
669         if (reg_info->value_regs)
670           continue;
671 
672         const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
673 
674         uint32_t register_offset;
675         if (use_byte_offset_into_buffer) {
676           register_offset = reg_info->byte_offset;
677         } else {
678           register_offset = running_byte_offset;
679         }
680 
681         const uint32_t reg_byte_size = reg_info->byte_size;
682 
683         const uint8_t *restore_src =
684             restore_data.PeekData(register_offset, reg_byte_size);
685         if (restore_src) {
686           SetRegisterIsValid(reg, false);
687           if (gdb_comm.WriteRegister(
688                   m_thread.GetProtocolID(),
689                   reg_info->kinds[eRegisterKindProcessPlugin],
690                   {restore_src, reg_byte_size}))
691             ++num_restored;
692         }
693       }
694       return num_restored > 0;
695     } else {
696       // For the use_g_packet == false case, we're going to write each register
697       // individually.  The data buffer is binary data in this case, instead of
698       // ascii characters.
699 
700       bool arm64_debugserver = false;
701       if (m_thread.GetProcess().get()) {
702         const ArchSpec &arch =
703             m_thread.GetProcess()->GetTarget().GetArchitecture();
704         if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64 ||
705                                arch.GetMachine() == llvm::Triple::aarch64_32) &&
706             arch.GetTriple().getVendor() == llvm::Triple::Apple &&
707             arch.GetTriple().getOS() == llvm::Triple::IOS) {
708           arm64_debugserver = true;
709         }
710       }
711       uint32_t num_restored = 0;
712       const RegisterInfo *reg_info;
713       for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;
714            i++) {
715         if (reg_info->value_regs) // skip registers that are slices of real
716                                   // registers
717           continue;
718         // Skip the fpsr and fpcr floating point status/control register
719         // writing to work around a bug in an older version of debugserver that
720         // would lead to register context corruption when writing fpsr/fpcr.
721         if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||
722                                   strcmp(reg_info->name, "fpcr") == 0)) {
723           continue;
724         }
725 
726         SetRegisterIsValid(reg_info, false);
727         if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),
728                                    reg_info->kinds[eRegisterKindProcessPlugin],
729                                    {data_sp->GetBytes() + reg_info->byte_offset,
730                                     reg_info->byte_size}))
731           ++num_restored;
732       }
733       return num_restored > 0;
734     }
735   } else {
736     Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
737     if (log) {
738       if (log->GetVerbose()) {
739         StreamString strm;
740         gdb_comm.DumpHistory(strm);
741         LLDB_LOGF(log,
742                   "error: failed to get packet sequence mutex, not sending "
743                   "write all registers:\n%s",
744                   strm.GetData());
745       } else
746         LLDB_LOGF(log,
747                   "error: failed to get packet sequence mutex, not sending "
748                   "write all registers");
749     }
750   }
751   return false;
752 }
753 
754 uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
755     lldb::RegisterKind kind, uint32_t num) {
756   return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);
757 }
758 
759 bool GDBRemoteRegisterContext::AArch64SVEReconfigure() {
760   if (!m_reg_info_sp)
761     return false;
762 
763   const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("vg");
764   if (!reg_info)
765     return false;
766 
767   uint64_t fail_value = LLDB_INVALID_ADDRESS;
768   uint32_t vg_reg_num = reg_info->kinds[eRegisterKindLLDB];
769   uint64_t vg_reg_value = ReadRegisterAsUnsigned(vg_reg_num, fail_value);
770 
771   if (vg_reg_value != fail_value && vg_reg_value <= 32) {
772     const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("p0");
773     if (!reg_info || vg_reg_value == reg_info->byte_size)
774       return false;
775 
776     if (m_reg_info_sp->UpdateARM64SVERegistersInfos(vg_reg_value)) {
777       // Make a heap based buffer that is big enough to store all registers
778       m_reg_data.SetData(std::make_shared<DataBufferHeap>(
779           m_reg_info_sp->GetRegisterDataByteSize(), 0));
780       m_reg_data.SetByteOrder(GetByteOrder());
781 
782       InvalidateAllRegisters();
783 
784       return true;
785     }
786   }
787 
788   return false;
789 }
790 
791 bool GDBRemoteDynamicRegisterInfo::UpdateARM64SVERegistersInfos(uint64_t vg) {
792   // SVE Z register size is vg x 8 bytes.
793   uint32_t z_reg_byte_size = vg * 8;
794 
795   // SVE vector length has changed, accordingly set size of Z, P and FFR
796   // registers. Also invalidate register offsets it will be recalculated
797   // after SVE register size update.
798   for (auto &reg : m_regs) {
799     if (reg.value_regs == nullptr) {
800       if (reg.name[0] == 'z' && isdigit(reg.name[1]))
801         reg.byte_size = z_reg_byte_size;
802       else if (reg.name[0] == 'p' && isdigit(reg.name[1]))
803         reg.byte_size = vg;
804       else if (strcmp(reg.name, "ffr") == 0)
805         reg.byte_size = vg;
806     }
807     reg.byte_offset = LLDB_INVALID_INDEX32;
808   }
809 
810   // Re-calculate register offsets
811   ConfigureOffsets();
812   return true;
813 }
814