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::WritableDataBufferSP &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       if (DataBufferSP data_buffer =
541               gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
542         data_sp = std::make_shared<DataBufferHeap>(*data_buffer);
543         return true;
544       }
545     }
546 
547     // We're going to read each register
548     // individually and store them as binary data in a buffer.
549     const RegisterInfo *reg_info;
550 
551     for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;
552          i++) {
553       if (reg_info
554               ->value_regs) // skip registers that are slices of real registers
555         continue;
556       ReadRegisterBytes(reg_info);
557       // ReadRegisterBytes saves the contents of the register in to the
558       // m_reg_data buffer
559     }
560     data_sp = std::make_shared<DataBufferHeap>(
561         m_reg_data.GetDataStart(), m_reg_info_sp->GetRegisterDataByteSize());
562     return true;
563   } else {
564 
565     Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
566     if (log) {
567       if (log->GetVerbose()) {
568         StreamString strm;
569         gdb_comm.DumpHistory(strm);
570         LLDB_LOGF(log,
571                   "error: failed to get packet sequence mutex, not sending "
572                   "read all registers:\n%s",
573                   strm.GetData());
574       } else
575         LLDB_LOGF(log,
576                   "error: failed to get packet sequence mutex, not sending "
577                   "read all registers");
578     }
579   }
580 
581   data_sp.reset();
582   return false;
583 }
584 
585 bool GDBRemoteRegisterContext::WriteAllRegisterValues(
586     const lldb::DataBufferSP &data_sp) {
587   if (!data_sp || data_sp->GetBytes() == nullptr || data_sp->GetByteSize() == 0)
588     return false;
589 
590   ExecutionContext exe_ctx(CalculateThread());
591 
592   Process *process = exe_ctx.GetProcessPtr();
593   Thread *thread = exe_ctx.GetThreadPtr();
594   if (process == nullptr || thread == nullptr)
595     return false;
596 
597   GDBRemoteCommunicationClient &gdb_comm(
598       ((ProcessGDBRemote *)process)->GetGDBRemote());
599 
600   const bool use_g_packet =
601       !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
602 
603   GDBRemoteClientBase::Lock lock(gdb_comm);
604   if (lock) {
605     // The data_sp contains the G response packet.
606     if (use_g_packet) {
607       if (gdb_comm.WriteAllRegisters(
608               m_thread.GetProtocolID(),
609               {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))
610         return true;
611 
612       uint32_t num_restored = 0;
613       // We need to manually go through all of the registers and restore them
614       // manually
615       DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),
616                                  m_reg_data.GetAddressByteSize());
617 
618       const RegisterInfo *reg_info;
619 
620       // The g packet contents may either include the slice registers
621       // (registers defined in terms of other registers, e.g. eax is a subset
622       // of rax) or not.  The slice registers should NOT be in the g packet,
623       // but some implementations may incorrectly include them.
624       //
625       // If the slice registers are included in the packet, we must step over
626       // the slice registers when parsing the packet -- relying on the
627       // RegisterInfo byte_offset field would be incorrect. If the slice
628       // registers are not included, then using the byte_offset values into the
629       // data buffer is the best way to find individual register values.
630 
631       uint64_t size_including_slice_registers = 0;
632       uint64_t size_not_including_slice_registers = 0;
633       uint64_t size_by_highest_offset = 0;
634 
635       for (uint32_t reg_idx = 0;
636            (reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr; ++reg_idx) {
637         size_including_slice_registers += reg_info->byte_size;
638         if (reg_info->value_regs == nullptr)
639           size_not_including_slice_registers += reg_info->byte_size;
640         if (reg_info->byte_offset >= size_by_highest_offset)
641           size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
642       }
643 
644       bool use_byte_offset_into_buffer;
645       if (size_by_highest_offset == restore_data.GetByteSize()) {
646         // The size of the packet agrees with the highest offset: + size in the
647         // register file
648         use_byte_offset_into_buffer = true;
649       } else if (size_not_including_slice_registers ==
650                  restore_data.GetByteSize()) {
651         // The size of the packet is the same as concatenating all of the
652         // registers sequentially, skipping the slice registers
653         use_byte_offset_into_buffer = true;
654       } else if (size_including_slice_registers == restore_data.GetByteSize()) {
655         // The slice registers are present in the packet (when they shouldn't
656         // be). Don't try to use the RegisterInfo byte_offset into the
657         // restore_data, it will point to the wrong place.
658         use_byte_offset_into_buffer = false;
659       } else {
660         // None of our expected sizes match the actual g packet data we're
661         // looking at. The most conservative approach here is to use the
662         // running total byte offset.
663         use_byte_offset_into_buffer = false;
664       }
665 
666       // In case our register definitions don't include the correct offsets,
667       // keep track of the size of each reg & compute offset based on that.
668       uint32_t running_byte_offset = 0;
669       for (uint32_t reg_idx = 0;
670            (reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr;
671            ++reg_idx, running_byte_offset += reg_info->byte_size) {
672         // Skip composite aka slice registers (e.g. eax is a slice of rax).
673         if (reg_info->value_regs)
674           continue;
675 
676         const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
677 
678         uint32_t register_offset;
679         if (use_byte_offset_into_buffer) {
680           register_offset = reg_info->byte_offset;
681         } else {
682           register_offset = running_byte_offset;
683         }
684 
685         const uint32_t reg_byte_size = reg_info->byte_size;
686 
687         const uint8_t *restore_src =
688             restore_data.PeekData(register_offset, reg_byte_size);
689         if (restore_src) {
690           SetRegisterIsValid(reg, false);
691           if (gdb_comm.WriteRegister(
692                   m_thread.GetProtocolID(),
693                   reg_info->kinds[eRegisterKindProcessPlugin],
694                   {restore_src, reg_byte_size}))
695             ++num_restored;
696         }
697       }
698       return num_restored > 0;
699     } else {
700       // For the use_g_packet == false case, we're going to write each register
701       // individually.  The data buffer is binary data in this case, instead of
702       // ascii characters.
703 
704       bool arm64_debugserver = false;
705       if (m_thread.GetProcess().get()) {
706         const ArchSpec &arch =
707             m_thread.GetProcess()->GetTarget().GetArchitecture();
708         if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64 ||
709                                arch.GetMachine() == llvm::Triple::aarch64_32) &&
710             arch.GetTriple().getVendor() == llvm::Triple::Apple &&
711             arch.GetTriple().getOS() == llvm::Triple::IOS) {
712           arm64_debugserver = true;
713         }
714       }
715       uint32_t num_restored = 0;
716       const RegisterInfo *reg_info;
717       for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;
718            i++) {
719         if (reg_info->value_regs) // skip registers that are slices of real
720                                   // registers
721           continue;
722         // Skip the fpsr and fpcr floating point status/control register
723         // writing to work around a bug in an older version of debugserver that
724         // would lead to register context corruption when writing fpsr/fpcr.
725         if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||
726                                   strcmp(reg_info->name, "fpcr") == 0)) {
727           continue;
728         }
729 
730         SetRegisterIsValid(reg_info, false);
731         if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),
732                                    reg_info->kinds[eRegisterKindProcessPlugin],
733                                    {data_sp->GetBytes() + reg_info->byte_offset,
734                                     reg_info->byte_size}))
735           ++num_restored;
736       }
737       return num_restored > 0;
738     }
739   } else {
740     Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
741     if (log) {
742       if (log->GetVerbose()) {
743         StreamString strm;
744         gdb_comm.DumpHistory(strm);
745         LLDB_LOGF(log,
746                   "error: failed to get packet sequence mutex, not sending "
747                   "write all registers:\n%s",
748                   strm.GetData());
749       } else
750         LLDB_LOGF(log,
751                   "error: failed to get packet sequence mutex, not sending "
752                   "write all registers");
753     }
754   }
755   return false;
756 }
757 
758 uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
759     lldb::RegisterKind kind, uint32_t num) {
760   return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);
761 }
762 
763 bool GDBRemoteRegisterContext::AArch64SVEReconfigure() {
764   if (!m_reg_info_sp)
765     return false;
766 
767   const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("vg");
768   if (!reg_info)
769     return false;
770 
771   uint64_t fail_value = LLDB_INVALID_ADDRESS;
772   uint32_t vg_reg_num = reg_info->kinds[eRegisterKindLLDB];
773   uint64_t vg_reg_value = ReadRegisterAsUnsigned(vg_reg_num, fail_value);
774 
775   if (vg_reg_value != fail_value && vg_reg_value <= 32) {
776     const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("p0");
777     if (!reg_info || vg_reg_value == reg_info->byte_size)
778       return false;
779 
780     if (m_reg_info_sp->UpdateARM64SVERegistersInfos(vg_reg_value)) {
781       // Make a heap based buffer that is big enough to store all registers
782       m_reg_data.SetData(std::make_shared<DataBufferHeap>(
783           m_reg_info_sp->GetRegisterDataByteSize(), 0));
784       m_reg_data.SetByteOrder(GetByteOrder());
785 
786       InvalidateAllRegisters();
787 
788       return true;
789     }
790   }
791 
792   return false;
793 }
794 
795 bool GDBRemoteDynamicRegisterInfo::UpdateARM64SVERegistersInfos(uint64_t vg) {
796   // SVE Z register size is vg x 8 bytes.
797   uint32_t z_reg_byte_size = vg * 8;
798 
799   // SVE vector length has changed, accordingly set size of Z, P and FFR
800   // registers. Also invalidate register offsets it will be recalculated
801   // after SVE register size update.
802   for (auto &reg : m_regs) {
803     if (reg.value_regs == nullptr) {
804       if (reg.name[0] == 'z' && isdigit(reg.name[1]))
805         reg.byte_size = z_reg_byte_size;
806       else if (reg.name[0] == 'p' && isdigit(reg.name[1]))
807         reg.byte_size = vg;
808       else if (strcmp(reg.name, "ffr") == 0)
809         reg.byte_size = vg;
810     }
811     reg.byte_offset = LLDB_INVALID_INDEX32;
812   }
813 
814   // Re-calculate register offsets
815   ConfigureOffsets();
816   return true;
817 }
818