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