1 //===-- GDBRemoteRegisterContext.cpp ----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "GDBRemoteRegisterContext.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 #include "lldb/Core/DataBufferHeap.h"
16 #include "lldb/Core/DataExtractor.h"
17 #include "lldb/Core/RegisterValue.h"
18 #include "lldb/Core/Scalar.h"
19 #include "lldb/Core/StreamString.h"
20 #include "lldb/Target/ExecutionContext.h"
21 #include "lldb/Utility/Utils.h"
22 // Project includes
23 #include "Utility/StringExtractorGDBRemote.h"
24 #include "ProcessGDBRemote.h"
25 #include "ProcessGDBRemoteLog.h"
26 #include "ThreadGDBRemote.h"
27 #include "Utility/ARM_GCC_Registers.h"
28 #include "Utility/ARM_DWARF_Registers.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 //----------------------------------------------------------------------
34 // GDBRemoteRegisterContext constructor
35 //----------------------------------------------------------------------
36 GDBRemoteRegisterContext::GDBRemoteRegisterContext
37 (
38     ThreadGDBRemote &thread,
39     uint32_t concrete_frame_idx,
40     GDBRemoteDynamicRegisterInfo &reg_info,
41     bool read_all_at_once
42 ) :
43     RegisterContext (thread, concrete_frame_idx),
44     m_reg_info (reg_info),
45     m_reg_valid (),
46     m_reg_data (),
47     m_read_all_at_once (read_all_at_once)
48 {
49     // Resize our vector of bools to contain one bool for every register.
50     // We will use these boolean values to know when a register value
51     // is valid in m_reg_data.
52     m_reg_valid.resize (reg_info.GetNumRegisters());
53 
54     // Make a heap based buffer that is big enough to store all registers
55     DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0));
56     m_reg_data.SetData (reg_data_sp);
57 
58 }
59 
60 //----------------------------------------------------------------------
61 // Destructor
62 //----------------------------------------------------------------------
63 GDBRemoteRegisterContext::~GDBRemoteRegisterContext()
64 {
65 }
66 
67 void
68 GDBRemoteRegisterContext::InvalidateAllRegisters ()
69 {
70     SetAllRegisterValid (false);
71 }
72 
73 void
74 GDBRemoteRegisterContext::SetAllRegisterValid (bool b)
75 {
76     std::vector<bool>::iterator pos, end = m_reg_valid.end();
77     for (pos = m_reg_valid.begin(); pos != end; ++pos)
78         *pos = b;
79 }
80 
81 size_t
82 GDBRemoteRegisterContext::GetRegisterCount ()
83 {
84     return m_reg_info.GetNumRegisters ();
85 }
86 
87 const RegisterInfo *
88 GDBRemoteRegisterContext::GetRegisterInfoAtIndex (uint32_t reg)
89 {
90     return m_reg_info.GetRegisterInfoAtIndex (reg);
91 }
92 
93 size_t
94 GDBRemoteRegisterContext::GetRegisterSetCount ()
95 {
96     return m_reg_info.GetNumRegisterSets ();
97 }
98 
99 
100 
101 const RegisterSet *
102 GDBRemoteRegisterContext::GetRegisterSet (uint32_t reg_set)
103 {
104     return m_reg_info.GetRegisterSet (reg_set);
105 }
106 
107 
108 
109 bool
110 GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
111 {
112     // Read the register
113     if (ReadRegisterBytes (reg_info, m_reg_data))
114     {
115         const bool partial_data_ok = false;
116         Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));
117         return error.Success();
118     }
119     return false;
120 }
121 
122 bool
123 GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
124 {
125     const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
126     if (reg_info == NULL)
127         return false;
128 
129     // Invalidate if needed
130     InvalidateIfNeeded(false);
131 
132     const uint32_t reg_byte_size = reg_info->byte_size;
133     const size_t bytes_copied = response.GetHexBytes (const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), reg_byte_size, '\xcc');
134     bool success = bytes_copied == reg_byte_size;
135     if (success)
136     {
137         m_reg_valid[reg] = true;
138     }
139     else if (bytes_copied > 0)
140     {
141         // Only set register is valid to false if we copied some bytes, else
142         // leave it as it was.
143         m_reg_valid[reg] = false;
144     }
145     return success;
146 }
147 
148 // Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().
149 bool
150 GDBRemoteRegisterContext::GetPrimordialRegister(const lldb_private::RegisterInfo *reg_info,
151                                                 GDBRemoteCommunicationClient &gdb_comm)
152 {
153     char packet[64];
154     StringExtractorGDBRemote response;
155     int packet_len = 0;
156     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
157     if (gdb_comm.GetThreadSuffixSupported())
158         packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4llx;", reg, m_thread.GetID());
159     else
160         packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
161     assert (packet_len < (sizeof(packet) - 1));
162     if (gdb_comm.SendPacketAndWaitForResponse(packet, response, false))
163         return PrivateSetRegisterValue (reg, response);
164 
165     return false;
166 }
167 bool
168 GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data)
169 {
170     ExecutionContext exe_ctx (CalculateThread());
171 
172     Process *process = exe_ctx.GetProcessPtr();
173     Thread *thread = exe_ctx.GetThreadPtr();
174     if (process == NULL || thread == NULL)
175         return false;
176 
177     GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
178 
179     InvalidateIfNeeded(false);
180 
181     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
182 
183     if (!m_reg_valid[reg])
184     {
185         Mutex::Locker locker;
186         if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read register."))
187         {
188             const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
189             ProcessSP process_sp (m_thread.GetProcess());
190             if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
191             {
192                 char packet[64];
193                 StringExtractorGDBRemote response;
194                 int packet_len = 0;
195                 if (m_read_all_at_once)
196                 {
197                     // Get all registers in one packet
198                     if (thread_suffix_supported)
199                         packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4llx;", m_thread.GetID());
200                     else
201                         packet_len = ::snprintf (packet, sizeof(packet), "g");
202                     assert (packet_len < (sizeof(packet) - 1));
203                     if (gdb_comm.SendPacketAndWaitForResponse(packet, response, false))
204                     {
205                         if (response.IsNormalResponse())
206                             if (response.GetHexBytes ((void *)m_reg_data.GetDataStart(), m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize())
207                                 SetAllRegisterValid (true);
208                     }
209                 }
210                 else if (!reg_info->value_regs)
211                 {
212                     // Get each register individually
213                     GetPrimordialRegister(reg_info, gdb_comm);
214                 }
215                 else
216                 {
217                     // Process this composite register request by delegating to the constituent
218                     // primordial registers.
219 
220                     // Index of the primordial register.
221                     uint32_t prim_reg_idx;
222                     bool success = true;
223                     for (uint32_t idx = 0;
224                          (prim_reg_idx = reg_info->value_regs[idx]) != LLDB_INVALID_REGNUM;
225                          ++idx)
226                     {
227                         // We have a valid primordial regsiter as our constituent.
228                         // Grab the corresponding register info.
229                         const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
230                         if (!GetPrimordialRegister(prim_reg_info, gdb_comm))
231                         {
232                             success = false;
233                             // Some failure occurred.  Let's break out of the for loop.
234                             break;
235                         }
236                     }
237                     if (success)
238                     {
239                         // If we reach this point, all primordial register requests have succeeded.
240                         // Validate this composite register.
241                         m_reg_valid[reg_info->kinds[eRegisterKindLLDB]] = true;
242                     }
243                 }
244             }
245         }
246         else
247         {
248             LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
249 #if LLDB_CONFIGURATION_DEBUG
250             StreamString strm;
251             gdb_comm.DumpHistory(strm);
252             Host::SetCrashDescription (strm.GetData());
253             assert (!"Didn't get sequence mutex for read register.");
254 #else
255             if (log)
256             {
257                 if (log->GetVerbose())
258                 {
259                     StreamString strm;
260                     gdb_comm.DumpHistory(strm);
261                     log->Printf("error: failed to get packet sequence mutex, not sending read register for \"%s\":\n%s", reg_info->name, strm.GetData());
262                 }
263                 else
264                 {
265                     log->Printf("error: failed to get packet sequence mutex, not sending read register for \"%s\"", reg_info->name);
266                 }
267             }
268 #endif
269         }
270 
271         // Make sure we got a valid register value after reading it
272         if (!m_reg_valid[reg])
273             return false;
274     }
275 
276     if (&data != &m_reg_data)
277     {
278         // If we aren't extracting into our own buffer (which
279         // only happens when this function is called from
280         // ReadRegisterValue(uint32_t, Scalar&)) then
281         // we transfer bytes from our buffer into the data
282         // buffer that was passed in
283         data.SetByteOrder (m_reg_data.GetByteOrder());
284         data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size);
285     }
286     return true;
287 }
288 
289 bool
290 GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info,
291                                          const RegisterValue &value)
292 {
293     DataExtractor data;
294     if (value.GetData (data))
295         return WriteRegisterBytes (reg_info, data, 0);
296     return false;
297 }
298 
299 // Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
300 bool
301 GDBRemoteRegisterContext::SetPrimordialRegister(const lldb_private::RegisterInfo *reg_info,
302                                                 GDBRemoteCommunicationClient &gdb_comm)
303 {
304     StreamString packet;
305     StringExtractorGDBRemote response;
306     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
307     packet.Printf ("P%x=", reg);
308     packet.PutBytesAsRawHex8 (m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
309                               reg_info->byte_size,
310                               lldb::endian::InlHostByteOrder(),
311                               lldb::endian::InlHostByteOrder());
312 
313     if (gdb_comm.GetThreadSuffixSupported())
314         packet.Printf (";thread:%4.4llx;", m_thread.GetID());
315 
316     // Invalidate just this register
317     m_reg_valid[reg] = false;
318     if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
319                                               packet.GetString().size(),
320                                               response,
321                                               false))
322     {
323         if (response.IsOKResponse())
324             return true;
325     }
326     return false;
327 }
328 
329 void
330 GDBRemoteRegisterContext::SyncThreadState(Process *process)
331 {
332     // NB.  We assume our caller has locked the sequence mutex.
333 
334     GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *) process)->GetGDBRemote());
335     if (!gdb_comm.GetSyncThreadStateSupported())
336         return;
337 
338     StreamString packet;
339     StringExtractorGDBRemote response;
340     packet.Printf ("QSyncThreadState:%4.4llx;", m_thread.GetID());
341     if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
342                                               packet.GetString().size(),
343                                               response,
344                                               false))
345     {
346         if (response.IsOKResponse())
347             InvalidateAllRegisters();
348     }
349 }
350 
351 bool
352 GDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset)
353 {
354     ExecutionContext exe_ctx (CalculateThread());
355 
356     Process *process = exe_ctx.GetProcessPtr();
357     Thread *thread = exe_ctx.GetThreadPtr();
358     if (process == NULL || thread == NULL)
359         return false;
360 
361     GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
362 // FIXME: This check isn't right because IsRunning checks the Public state, but this
363 // is work you need to do - for instance in ShouldStop & friends - before the public
364 // state has been changed.
365 //    if (gdb_comm.IsRunning())
366 //        return false;
367 
368     // Grab a pointer to where we are going to put this register
369     uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
370 
371     if (dst == NULL)
372         return false;
373 
374 
375     if (data.CopyByteOrderedData (data_offset,                  // src offset
376                                   reg_info->byte_size,          // src length
377                                   dst,                          // dst
378                                   reg_info->byte_size,          // dst length
379                                   m_reg_data.GetByteOrder()))   // dst byte order
380     {
381         Mutex::Locker locker;
382         if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write register."))
383         {
384             const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
385             ProcessSP process_sp (m_thread.GetProcess());
386             if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
387             {
388                 StreamString packet;
389                 StringExtractorGDBRemote response;
390                 if (m_read_all_at_once)
391                 {
392                     // Set all registers in one packet
393                     packet.PutChar ('G');
394                     packet.PutBytesAsRawHex8 (m_reg_data.GetDataStart(),
395                                               m_reg_data.GetByteSize(),
396                                               lldb::endian::InlHostByteOrder(),
397                                               lldb::endian::InlHostByteOrder());
398 
399                     if (thread_suffix_supported)
400                         packet.Printf (";thread:%4.4llx;", m_thread.GetID());
401 
402                     // Invalidate all register values
403                     InvalidateIfNeeded (true);
404 
405                     if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
406                                                               packet.GetString().size(),
407                                                               response,
408                                                               false))
409                     {
410                         SetAllRegisterValid (false);
411                         if (response.IsOKResponse())
412                         {
413                             return true;
414                         }
415                     }
416                 }
417                 else if (!reg_info->value_regs)
418                 {
419                     // Set each register individually
420                     return SetPrimordialRegister(reg_info, gdb_comm);
421                 }
422                 else
423                 {
424                     // Process this composite register request by delegating to the constituent
425                     // primordial registers.
426 
427                     // Invalidate this composite register first.
428                     m_reg_valid[reg_info->kinds[eRegisterKindLLDB]] = false;
429 
430                     // Index of the primordial register.
431                     uint32_t prim_reg_idx;
432                     // For loop index.
433                     uint32_t idx;
434 
435                     // Invalidate the invalidate_regs, if present.
436                     if (reg_info->invalidate_regs)
437                     {
438                         for (idx = 0;
439                              (prim_reg_idx = reg_info->invalidate_regs[idx]) != LLDB_INVALID_REGNUM;
440                              ++idx)
441                         {
442                             // Grab the invalidate register info.
443                             const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
444                             m_reg_valid[prim_reg_info->kinds[eRegisterKindLLDB]] = false;
445                         }
446                     }
447 
448                     bool success = true;
449                     for (idx = 0;
450                          (prim_reg_idx = reg_info->value_regs[idx]) != LLDB_INVALID_REGNUM;
451                          ++idx)
452                     {
453                         // We have a valid primordial regsiter as our constituent.
454                         // Grab the corresponding register info.
455                         const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
456                         if (!SetPrimordialRegister(prim_reg_info, gdb_comm))
457                         {
458                             success = false;
459                             // Some failure occurred.  Let's break out of the for loop.
460                             break;
461                         }
462                     }
463                     return success;
464                 }
465             }
466         }
467         else
468         {
469             LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
470             if (log)
471             {
472                 if (log->GetVerbose())
473                 {
474                     StreamString strm;
475                     gdb_comm.DumpHistory(strm);
476                     log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData());
477                 }
478                 else
479                     log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name);
480             }
481         }
482     }
483     return false;
484 }
485 
486 
487 bool
488 GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
489 {
490     ExecutionContext exe_ctx (CalculateThread());
491 
492     Process *process = exe_ctx.GetProcessPtr();
493     Thread *thread = exe_ctx.GetThreadPtr();
494     if (process == NULL || thread == NULL)
495         return false;
496 
497     GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
498 
499     StringExtractorGDBRemote response;
500 
501     Mutex::Locker locker;
502     if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read all registers."))
503     {
504         SyncThreadState(process);
505 
506         char packet[32];
507         const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
508         ProcessSP process_sp (m_thread.GetProcess());
509         if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
510         {
511             int packet_len = 0;
512             if (thread_suffix_supported)
513                 packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4llx", m_thread.GetID());
514             else
515                 packet_len = ::snprintf (packet, sizeof(packet), "g");
516             assert (packet_len < (sizeof(packet) - 1));
517 
518             if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
519             {
520                 if (response.IsErrorResponse())
521                     return false;
522 
523                 std::string &response_str = response.GetStringRef();
524                 if (isxdigit(response_str[0]))
525                 {
526                     response_str.insert(0, 1, 'G');
527                     if (thread_suffix_supported)
528                     {
529                         char thread_id_cstr[64];
530                         ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4llx;", m_thread.GetID());
531                         response_str.append (thread_id_cstr);
532                     }
533                     data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size()));
534                     return true;
535                 }
536             }
537         }
538     }
539     else
540     {
541         LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
542         if (log)
543         {
544             if (log->GetVerbose())
545             {
546                 StreamString strm;
547                 gdb_comm.DumpHistory(strm);
548                 log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData());
549             }
550             else
551                 log->Printf("error: failed to get packet sequence mutex, not sending read all registers");
552         }
553     }
554 
555     data_sp.reset();
556     return false;
557 }
558 
559 bool
560 GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
561 {
562     if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
563         return false;
564 
565     ExecutionContext exe_ctx (CalculateThread());
566 
567     Process *process = exe_ctx.GetProcessPtr();
568     Thread *thread = exe_ctx.GetThreadPtr();
569     if (process == NULL || thread == NULL)
570         return false;
571 
572     GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
573 
574     StringExtractorGDBRemote response;
575     Mutex::Locker locker;
576     if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write all registers."))
577     {
578         const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
579         ProcessSP process_sp (m_thread.GetProcess());
580         if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
581         {
582             // The data_sp contains the entire G response packet including the
583             // G, and if the thread suffix is supported, it has the thread suffix
584             // as well.
585             const char *G_packet = (const char *)data_sp->GetBytes();
586             size_t G_packet_len = data_sp->GetByteSize();
587             if (gdb_comm.SendPacketAndWaitForResponse (G_packet,
588                                                        G_packet_len,
589                                                        response,
590                                                        false))
591             {
592                 if (response.IsOKResponse())
593                     return true;
594                 else if (response.IsErrorResponse())
595                 {
596                     uint32_t num_restored = 0;
597                     // We need to manually go through all of the registers and
598                     // restore them manually
599 
600                     response.GetStringRef().assign (G_packet, G_packet_len);
601                     response.SetFilePos(1); // Skip the leading 'G'
602                     DataBufferHeap buffer (m_reg_data.GetByteSize(), 0);
603                     DataExtractor restore_data (buffer.GetBytes(),
604                                                 buffer.GetByteSize(),
605                                                 m_reg_data.GetByteOrder(),
606                                                 m_reg_data.GetAddressByteSize());
607 
608                     const uint32_t bytes_extracted = response.GetHexBytes ((void *)restore_data.GetDataStart(),
609                                                                            restore_data.GetByteSize(),
610                                                                            '\xcc');
611 
612                     if (bytes_extracted < restore_data.GetByteSize())
613                         restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder());
614 
615                     //ReadRegisterBytes (const RegisterInfo *reg_info, RegisterValue &value, DataExtractor &data)
616                     const RegisterInfo *reg_info;
617                     // We have to march the offset of each register along in the
618                     // buffer to make sure we get the right offset.
619                     uint32_t reg_byte_offset = 0;
620                     for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx, reg_byte_offset += reg_info->byte_size)
621                     {
622                         const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
623 
624                         // Skip composite registers.
625                         if (reg_info->value_regs)
626                             continue;
627 
628                         // Only write down the registers that need to be written
629                         // if we are going to be doing registers individually.
630                         bool write_reg = true;
631                         const uint32_t reg_byte_size = reg_info->byte_size;
632 
633                         const char *restore_src = (const char *)restore_data.PeekData(reg_byte_offset, reg_byte_size);
634                         if (restore_src)
635                         {
636                             if (m_reg_valid[reg])
637                             {
638                                 const char *current_src = (const char *)m_reg_data.PeekData(reg_byte_offset, reg_byte_size);
639                                 if (current_src)
640                                     write_reg = memcmp (current_src, restore_src, reg_byte_size) != 0;
641                             }
642 
643                             if (write_reg)
644                             {
645                                 StreamString packet;
646                                 packet.Printf ("P%x=", reg);
647                                 packet.PutBytesAsRawHex8 (restore_src,
648                                                           reg_byte_size,
649                                                           lldb::endian::InlHostByteOrder(),
650                                                           lldb::endian::InlHostByteOrder());
651 
652                                 if (thread_suffix_supported)
653                                     packet.Printf (";thread:%4.4llx;", m_thread.GetID());
654 
655                                 m_reg_valid[reg] = false;
656                                 if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
657                                                                           packet.GetString().size(),
658                                                                           response,
659                                                                           false))
660                                 {
661                                     if (response.IsOKResponse())
662                                         ++num_restored;
663                                 }
664                             }
665                         }
666                     }
667                     return num_restored > 0;
668                 }
669             }
670         }
671     }
672     else
673     {
674         LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
675         if (log)
676         {
677             if (log->GetVerbose())
678             {
679                 StreamString strm;
680                 gdb_comm.DumpHistory(strm);
681                 log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData());
682             }
683             else
684                 log->Printf("error: failed to get packet sequence mutex, not sending write all registers");
685         }
686     }
687     return false;
688 }
689 
690 
691 uint32_t
692 GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
693 {
694     return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num);
695 }
696 
697 void
698 GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch)
699 {
700     // For Advanced SIMD and VFP register mapping.
701     static uint32_t g_d0_regs[] =  { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1)
702     static uint32_t g_d1_regs[] =  { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3)
703     static uint32_t g_d2_regs[] =  { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5)
704     static uint32_t g_d3_regs[] =  { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7)
705     static uint32_t g_d4_regs[] =  { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9)
706     static uint32_t g_d5_regs[] =  { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11)
707     static uint32_t g_d6_regs[] =  { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13)
708     static uint32_t g_d7_regs[] =  { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15)
709     static uint32_t g_d8_regs[] =  { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17)
710     static uint32_t g_d9_regs[] =  { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19)
711     static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21)
712     static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23)
713     static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25)
714     static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27)
715     static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29)
716     static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31)
717     static uint32_t g_q0_regs[] =  { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3)
718     static uint32_t g_q1_regs[] =  { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7)
719     static uint32_t g_q2_regs[] =  { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11)
720     static uint32_t g_q3_regs[] =  { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15)
721     static uint32_t g_q4_regs[] =  { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19)
722     static uint32_t g_q5_regs[] =  { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23)
723     static uint32_t g_q6_regs[] =  { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27)
724     static uint32_t g_q7_regs[] =  { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31)
725     static uint32_t g_q8_regs[] =  { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17)
726     static uint32_t g_q9_regs[] =  { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19)
727     static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21)
728     static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23)
729     static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25)
730     static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27)
731     static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29)
732     static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31)
733 
734     // This is our array of composite registers, with each element coming from the above register mappings.
735     static uint32_t *g_composites[] = {
736         g_d0_regs, g_d1_regs,  g_d2_regs,  g_d3_regs,  g_d4_regs,  g_d5_regs,  g_d6_regs,  g_d7_regs,
737         g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs,
738         g_q0_regs, g_q1_regs,  g_q2_regs,  g_q3_regs,  g_q4_regs,  g_q5_regs,  g_q6_regs,  g_q7_regs,
739         g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, g_q14_regs, g_q15_regs
740     };
741 
742     static RegisterInfo g_register_infos[] = {
743 //   NAME    ALT    SZ  OFF  ENCODING          FORMAT          COMPILER             DWARF                GENERIC                 GDB    LLDB      VALUE REGS    INVALIDATE REGS
744 //   ======  ====== === ===  =============     ============    ===================  ===================  ======================  ===    ====      ==========    ===============
745     { "r0", "arg1",   4,   0, eEncodingUint,    eFormatHex,   { gcc_r0,              dwarf_r0,            LLDB_REGNUM_GENERIC_ARG1,0,      0 },        NULL,              NULL},
746     { "r1", "arg2",   4,   0, eEncodingUint,    eFormatHex,   { gcc_r1,              dwarf_r1,            LLDB_REGNUM_GENERIC_ARG2,1,      1 },        NULL,              NULL},
747     { "r2", "arg3",   4,   0, eEncodingUint,    eFormatHex,   { gcc_r2,              dwarf_r2,            LLDB_REGNUM_GENERIC_ARG3,2,      2 },        NULL,              NULL},
748     { "r3", "arg4",   4,   0, eEncodingUint,    eFormatHex,   { gcc_r3,              dwarf_r3,            LLDB_REGNUM_GENERIC_ARG4,3,      3 },        NULL,              NULL},
749     { "r4",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r4,              dwarf_r4,            LLDB_INVALID_REGNUM,     4,      4 },        NULL,              NULL},
750     { "r5",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r5,              dwarf_r5,            LLDB_INVALID_REGNUM,     5,      5 },        NULL,              NULL},
751     { "r6",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r6,              dwarf_r6,            LLDB_INVALID_REGNUM,     6,      6 },        NULL,              NULL},
752     { "r7",   "fp",   4,   0, eEncodingUint,    eFormatHex,   { gcc_r7,              dwarf_r7,            LLDB_REGNUM_GENERIC_FP,  7,      7 },        NULL,              NULL},
753     { "r8",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r8,              dwarf_r8,            LLDB_INVALID_REGNUM,     8,      8 },        NULL,              NULL},
754     { "r9",   NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r9,              dwarf_r9,            LLDB_INVALID_REGNUM,     9,      9 },        NULL,              NULL},
755     { "r10",  NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r10,             dwarf_r10,           LLDB_INVALID_REGNUM,    10,     10 },        NULL,              NULL},
756     { "r11",  NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r11,             dwarf_r11,           LLDB_INVALID_REGNUM,    11,     11 },        NULL,              NULL},
757     { "r12",  NULL,   4,   0, eEncodingUint,    eFormatHex,   { gcc_r12,             dwarf_r12,           LLDB_INVALID_REGNUM,    12,     12 },        NULL,              NULL},
758     { "sp",   "r13",  4,   0, eEncodingUint,    eFormatHex,   { gcc_sp,              dwarf_sp,            LLDB_REGNUM_GENERIC_SP, 13,     13 },        NULL,              NULL},
759     { "lr",   "r14",  4,   0, eEncodingUint,    eFormatHex,   { gcc_lr,              dwarf_lr,            LLDB_REGNUM_GENERIC_RA, 14,     14 },        NULL,              NULL},
760     { "pc",   "r15",  4,   0, eEncodingUint,    eFormatHex,   { gcc_pc,              dwarf_pc,            LLDB_REGNUM_GENERIC_PC, 15,     15 },        NULL,              NULL},
761     { "f0",   NULL,  12,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    16,     16 },        NULL,              NULL},
762     { "f1",   NULL,  12,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    17,     17 },        NULL,              NULL},
763     { "f2",   NULL,  12,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    18,     18 },        NULL,              NULL},
764     { "f3",   NULL,  12,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    19,     19 },        NULL,              NULL},
765     { "f4",   NULL,  12,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    20,     20 },        NULL,              NULL},
766     { "f5",   NULL,  12,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    21,     21 },        NULL,              NULL},
767     { "f6",   NULL,  12,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    22,     22 },        NULL,              NULL},
768     { "f7",   NULL,  12,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    23,     23 },        NULL,              NULL},
769     { "fps",  NULL,   4,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    24,     24 },        NULL,              NULL},
770     { "cpsr","flags", 4,   0, eEncodingUint,    eFormatHex,   { gcc_cpsr,            dwarf_cpsr,          LLDB_INVALID_REGNUM,    25,     25 },        NULL,              NULL},
771     { "s0",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0,            LLDB_INVALID_REGNUM,    26,     26 },        NULL,              NULL},
772     { "s1",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1,            LLDB_INVALID_REGNUM,    27,     27 },        NULL,              NULL},
773     { "s2",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2,            LLDB_INVALID_REGNUM,    28,     28 },        NULL,              NULL},
774     { "s3",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3,            LLDB_INVALID_REGNUM,    29,     29 },        NULL,              NULL},
775     { "s4",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4,            LLDB_INVALID_REGNUM,    30,     30 },        NULL,              NULL},
776     { "s5",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5,            LLDB_INVALID_REGNUM,    31,     31 },        NULL,              NULL},
777     { "s6",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6,            LLDB_INVALID_REGNUM,    32,     32 },        NULL,              NULL},
778     { "s7",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7,            LLDB_INVALID_REGNUM,    33,     33 },        NULL,              NULL},
779     { "s8",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8,            LLDB_INVALID_REGNUM,    34,     34 },        NULL,              NULL},
780     { "s9",   NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9,            LLDB_INVALID_REGNUM,    35,     35 },        NULL,              NULL},
781     { "s10",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10,           LLDB_INVALID_REGNUM,    36,     36 },        NULL,              NULL},
782     { "s11",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11,           LLDB_INVALID_REGNUM,    37,     37 },        NULL,              NULL},
783     { "s12",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12,           LLDB_INVALID_REGNUM,    38,     38 },        NULL,              NULL},
784     { "s13",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13,           LLDB_INVALID_REGNUM,    39,     39 },        NULL,              NULL},
785     { "s14",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14,           LLDB_INVALID_REGNUM,    40,     40 },        NULL,              NULL},
786     { "s15",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15,           LLDB_INVALID_REGNUM,    41,     41 },        NULL,              NULL},
787     { "s16",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16,           LLDB_INVALID_REGNUM,    42,     42 },        NULL,              NULL},
788     { "s17",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17,           LLDB_INVALID_REGNUM,    43,     43 },        NULL,              NULL},
789     { "s18",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18,           LLDB_INVALID_REGNUM,    44,     44 },        NULL,              NULL},
790     { "s19",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19,           LLDB_INVALID_REGNUM,    45,     45 },        NULL,              NULL},
791     { "s20",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20,           LLDB_INVALID_REGNUM,    46,     46 },        NULL,              NULL},
792     { "s21",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21,           LLDB_INVALID_REGNUM,    47,     47 },        NULL,              NULL},
793     { "s22",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22,           LLDB_INVALID_REGNUM,    48,     48 },        NULL,              NULL},
794     { "s23",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23,           LLDB_INVALID_REGNUM,    49,     49 },        NULL,              NULL},
795     { "s24",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24,           LLDB_INVALID_REGNUM,    50,     50 },        NULL,              NULL},
796     { "s25",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25,           LLDB_INVALID_REGNUM,    51,     51 },        NULL,              NULL},
797     { "s26",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26,           LLDB_INVALID_REGNUM,    52,     52 },        NULL,              NULL},
798     { "s27",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27,           LLDB_INVALID_REGNUM,    53,     53 },        NULL,              NULL},
799     { "s28",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28,           LLDB_INVALID_REGNUM,    54,     54 },        NULL,              NULL},
800     { "s29",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29,           LLDB_INVALID_REGNUM,    55,     55 },        NULL,              NULL},
801     { "s30",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30,           LLDB_INVALID_REGNUM,    56,     56 },        NULL,              NULL},
802     { "s31",  NULL,   4,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31,           LLDB_INVALID_REGNUM,    57,     57 },        NULL,              NULL},
803     { "fpscr",NULL,   4,   0, eEncodingUint,    eFormatHex,   { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    58,     58 },        NULL,              NULL},
804     { "d16",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16,           LLDB_INVALID_REGNUM,    59,     59 },        NULL,              NULL},
805     { "d17",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17,           LLDB_INVALID_REGNUM,    60,     60 },        NULL,              NULL},
806     { "d18",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18,           LLDB_INVALID_REGNUM,    61,     61 },        NULL,              NULL},
807     { "d19",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19,           LLDB_INVALID_REGNUM,    62,     62 },        NULL,              NULL},
808     { "d20",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20,           LLDB_INVALID_REGNUM,    63,     63 },        NULL,              NULL},
809     { "d21",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21,           LLDB_INVALID_REGNUM,    64,     64 },        NULL,              NULL},
810     { "d22",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22,           LLDB_INVALID_REGNUM,    65,     65 },        NULL,              NULL},
811     { "d23",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23,           LLDB_INVALID_REGNUM,    66,     66 },        NULL,              NULL},
812     { "d24",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24,           LLDB_INVALID_REGNUM,    67,     67 },        NULL,              NULL},
813     { "d25",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25,           LLDB_INVALID_REGNUM,    68,     68 },        NULL,              NULL},
814     { "d26",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26,           LLDB_INVALID_REGNUM,    69,     69 },        NULL,              NULL},
815     { "d27",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27,           LLDB_INVALID_REGNUM,    70,     70 },        NULL,              NULL},
816     { "d28",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28,           LLDB_INVALID_REGNUM,    71,     71 },        NULL,              NULL},
817     { "d29",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29,           LLDB_INVALID_REGNUM,    72,     72 },        NULL,              NULL},
818     { "d30",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30,           LLDB_INVALID_REGNUM,    73,     73 },        NULL,              NULL},
819     { "d31",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31,           LLDB_INVALID_REGNUM,    74,     74 },        NULL,              NULL},
820     { "d0",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0,            LLDB_INVALID_REGNUM,    75,     75 },   g_d0_regs,              NULL},
821     { "d1",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1,            LLDB_INVALID_REGNUM,    76,     76 },   g_d1_regs,              NULL},
822     { "d2",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2,            LLDB_INVALID_REGNUM,    77,     77 },   g_d2_regs,              NULL},
823     { "d3",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3,            LLDB_INVALID_REGNUM,    78,     78 },   g_d3_regs,              NULL},
824     { "d4",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4,            LLDB_INVALID_REGNUM,    79,     79 },   g_d4_regs,              NULL},
825     { "d5",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5,            LLDB_INVALID_REGNUM,    80,     80 },   g_d5_regs,              NULL},
826     { "d6",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6,            LLDB_INVALID_REGNUM,    81,     81 },   g_d6_regs,              NULL},
827     { "d7",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7,            LLDB_INVALID_REGNUM,    82,     82 },   g_d7_regs,              NULL},
828     { "d8",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8,            LLDB_INVALID_REGNUM,    83,     83 },   g_d8_regs,              NULL},
829     { "d9",   NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9,            LLDB_INVALID_REGNUM,    84,     84 },   g_d9_regs,              NULL},
830     { "d10",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10,           LLDB_INVALID_REGNUM,    85,     85 },  g_d10_regs,              NULL},
831     { "d11",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11,           LLDB_INVALID_REGNUM,    86,     86 },  g_d11_regs,              NULL},
832     { "d12",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12,           LLDB_INVALID_REGNUM,    87,     87 },  g_d12_regs,              NULL},
833     { "d13",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13,           LLDB_INVALID_REGNUM,    88,     88 },  g_d13_regs,              NULL},
834     { "d14",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14,           LLDB_INVALID_REGNUM,    89,     89 },  g_d14_regs,              NULL},
835     { "d15",  NULL,   8,   0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15,           LLDB_INVALID_REGNUM,    90,     90 },  g_d15_regs,              NULL},
836     { "q0",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0,    LLDB_INVALID_REGNUM,    91,     91 },   g_q0_regs,              NULL},
837     { "q1",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1,    LLDB_INVALID_REGNUM,    92,     92 },   g_q1_regs,              NULL},
838     { "q2",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2,    LLDB_INVALID_REGNUM,    93,     93 },   g_q2_regs,              NULL},
839     { "q3",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3,    LLDB_INVALID_REGNUM,    94,     94 },   g_q3_regs,              NULL},
840     { "q4",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4,    LLDB_INVALID_REGNUM,    95,     95 },   g_q4_regs,              NULL},
841     { "q5",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5,    LLDB_INVALID_REGNUM,    96,     96 },   g_q5_regs,              NULL},
842     { "q6",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6,    LLDB_INVALID_REGNUM,    97,     97 },   g_q6_regs,              NULL},
843     { "q7",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7,    LLDB_INVALID_REGNUM,    98,     98 },   g_q7_regs,              NULL},
844     { "q8",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8,    LLDB_INVALID_REGNUM,    99,     99 },   g_q8_regs,              NULL},
845     { "q9",   NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9,    LLDB_INVALID_REGNUM,   100,    100 },   g_q9_regs,              NULL},
846     { "q10",  NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10,   LLDB_INVALID_REGNUM,   101,    101 },  g_q10_regs,              NULL},
847     { "q11",  NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11,   LLDB_INVALID_REGNUM,   102,    102 },  g_q11_regs,              NULL},
848     { "q12",  NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12,   LLDB_INVALID_REGNUM,   103,    103 },  g_q12_regs,              NULL},
849     { "q13",  NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13,   LLDB_INVALID_REGNUM,   104,    104 },  g_q13_regs,              NULL},
850     { "q14",  NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14,   LLDB_INVALID_REGNUM,   105,    105 },  g_q14_regs,              NULL},
851     { "q15",  NULL,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15,   LLDB_INVALID_REGNUM,   106,    106 },  g_q15_regs,              NULL}
852     };
853 
854     static const uint32_t num_registers = llvm::array_lengthof(g_register_infos);
855     static ConstString gpr_reg_set ("General Purpose Registers");
856     static ConstString sfp_reg_set ("Software Floating Point Registers");
857     static ConstString vfp_reg_set ("Floating Point Registers");
858     uint32_t i;
859     if (from_scratch)
860     {
861         // Calculate the offsets of the registers
862         // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the
863         // "primordial" registers is important.  This enables us to calculate the offset of the composite
864         // register by using the offset of its first primordial register.  For example, to calculate the
865         // offset of q0, use s0's offset.
866         if (g_register_infos[2].byte_offset == 0)
867         {
868             uint32_t byte_offset = 0;
869             for (i=0; i<num_registers; ++i)
870             {
871                 // For primordial registers, increment the byte_offset by the byte_size to arrive at the
872                 // byte_offset for the next register.  Otherwise, we have a composite register whose
873                 // offset can be calculated by consulting the offset of its first primordial register.
874                 if (!g_register_infos[i].value_regs)
875                 {
876                     g_register_infos[i].byte_offset = byte_offset;
877                     byte_offset += g_register_infos[i].byte_size;
878                 }
879                 else
880                 {
881                     const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0];
882                     g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset;
883                 }
884             }
885         }
886         for (i=0; i<num_registers; ++i)
887         {
888             ConstString name;
889             ConstString alt_name;
890             if (g_register_infos[i].name && g_register_infos[i].name[0])
891                 name.SetCString(g_register_infos[i].name);
892             if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
893                 alt_name.SetCString(g_register_infos[i].alt_name);
894 
895             if (i <= 15 || i == 25)
896                 AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set);
897             else if (i <= 24)
898                 AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set);
899             else
900                 AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set);
901         }
902     }
903     else
904     {
905         // Add composite registers to our primordial registers, then.
906         const uint32_t num_composites = llvm::array_lengthof(g_composites);
907         const uint32_t num_primordials = GetNumRegisters();
908         RegisterInfo *g_comp_register_infos = g_register_infos + (num_registers - num_composites);
909         for (i=0; i<num_composites; ++i)
910         {
911             ConstString name;
912             ConstString alt_name;
913             const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0];
914             const char *reg_name = g_register_infos[first_primordial_reg].name;
915             if (reg_name && reg_name[0])
916             {
917                 for (uint32_t j = 0; j < num_primordials; ++j)
918                 {
919                     const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
920                     // Find a matching primordial register info entry.
921                     if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0)
922                     {
923                         // The name matches the existing primordial entry.
924                         // Find and assign the offset, and then add this composite register entry.
925                         g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
926                         name.SetCString(g_comp_register_infos[i].name);
927                         AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set);
928                     }
929                 }
930             }
931         }
932     }
933 }
934 
935 void
936 GDBRemoteDynamicRegisterInfo::Addx86_64ConvenienceRegisters()
937 {
938     // For eax, ebx, ecx, edx, esi, edi, ebp, esp register mapping.
939     static const char* g_mapped_names[] = {
940         "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp",
941         "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp",
942         "rax", "rbx", "rcx", "rdx",
943         "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp"
944     };
945 
946     // These value regs are to be populated with the corresponding primordial register index.
947     // For example,
948     static uint32_t g_eax_regs[] =  { 0, LLDB_INVALID_REGNUM }; // 0 is to be replaced with rax's index.
949     static uint32_t g_ebx_regs[] =  { 0, LLDB_INVALID_REGNUM };
950     static uint32_t g_ecx_regs[] =  { 0, LLDB_INVALID_REGNUM };
951     static uint32_t g_edx_regs[] =  { 0, LLDB_INVALID_REGNUM };
952     static uint32_t g_edi_regs[] =  { 0, LLDB_INVALID_REGNUM };
953     static uint32_t g_esi_regs[] =  { 0, LLDB_INVALID_REGNUM };
954     static uint32_t g_ebp_regs[] =  { 0, LLDB_INVALID_REGNUM };
955     static uint32_t g_esp_regs[] =  { 0, LLDB_INVALID_REGNUM };
956 
957     static RegisterInfo g_conv_register_infos[] =
958     {
959 //    NAME      ALT      SZ OFF ENCODING         FORMAT                COMPILER              DWARF                 GENERIC                      GDB                   LLDB NATIVE            VALUE REGS    INVALIDATE REGS
960 //    ======    =======  == === =============    ============          ===================== ===================== ============================ ====================  ====================== ==========    ===============
961     { "eax"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs,              NULL},
962     { "ebx"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs,              NULL},
963     { "ecx"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs,              NULL},
964     { "edx"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs,              NULL},
965     { "edi"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs,              NULL},
966     { "esi"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs,              NULL},
967     { "ebp"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs,              NULL},
968     { "esp"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs,              NULL},
969     { "ax"    , NULL,    2,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs,              NULL},
970     { "bx"    , NULL,    2,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs,              NULL},
971     { "cx"    , NULL,    2,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs,              NULL},
972     { "dx"    , NULL,    2,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs,              NULL},
973     { "di"    , NULL,    2,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs,              NULL},
974     { "si"    , NULL,    2,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs,              NULL},
975     { "bp"    , NULL,    2,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs,              NULL},
976     { "sp"    , NULL,    2,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs,              NULL},
977     { "ah"    , NULL,    1,  1, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs,              NULL},
978     { "bh"    , NULL,    1,  1, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs,              NULL},
979     { "ch"    , NULL,    1,  1, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs,              NULL},
980     { "dh"    , NULL,    1,  1, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs,              NULL},
981     { "al"    , NULL,    1,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs,              NULL},
982     { "bl"    , NULL,    1,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs,              NULL},
983     { "cl"    , NULL,    1,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs,              NULL},
984     { "dl"    , NULL,    1,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs,              NULL},
985     { "dil"   , NULL,    1,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs,              NULL},
986     { "sil"   , NULL,    1,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs,              NULL},
987     { "bpl"   , NULL,    1,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs,              NULL},
988     { "spl"   , NULL,    1,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs,              NULL}
989     };
990 
991     static const uint32_t num_conv_regs = llvm::array_lengthof(g_mapped_names);
992     static ConstString gpr_reg_set ("General Purpose Registers");
993 
994     // Add convenience registers to our primordial registers.
995     const uint32_t num_primordials = GetNumRegisters();
996     uint32_t reg_kind = num_primordials;
997     for (uint32_t i=0; i<num_conv_regs; ++i)
998     {
999         ConstString name;
1000         ConstString alt_name;
1001         const char *prim_reg_name = g_mapped_names[i];
1002         if (prim_reg_name && prim_reg_name[0])
1003         {
1004             for (uint32_t j = 0; j < num_primordials; ++j)
1005             {
1006                 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
1007                 // Find a matching primordial register info entry.
1008                 if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, prim_reg_name) == 0)
1009                 {
1010                     // The name matches the existing primordial entry.
1011                     // Find and assign the offset, and then add this composite register entry.
1012                     g_conv_register_infos[i].byte_offset = reg_info->byte_offset + g_conv_register_infos[i].byte_offset;
1013                     // Update the value_regs and the kinds fields in order to delegate to the primordial register.
1014                     g_conv_register_infos[i].value_regs[0] = j;
1015                     g_conv_register_infos[i].kinds[eRegisterKindLLDB] = ++reg_kind;
1016                     name.SetCString(g_conv_register_infos[i].name);
1017                     AddRegister(g_conv_register_infos[i], name, alt_name, gpr_reg_set);
1018                 }
1019             }
1020         }
1021     }
1022 }
1023 
1024