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