1//===-- CommunicationKDP.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
11#include "CommunicationKDP.h"
12
13// C Includes
14#include <errno.h>
15#include <limits.h>
16#include <string.h>
17
18// C++ Includes
19#include "llvm/Support/MachO.h"
20
21// Other libraries and framework includes
22#include "lldb/Core/DataBufferHeap.h"
23#include "lldb/Core/DataExtractor.h"
24#include "lldb/Core/Log.h"
25#include "lldb/Core/State.h"
26#include "lldb/Core/UUID.h"
27#include "lldb/Host/FileSpec.h"
28#include "lldb/Host/Host.h"
29#include "lldb/Host/TimeValue.h"
30#include "lldb/Target/Process.h"
31
32// Project includes
33#include "ProcessKDPLog.h"
34
35using namespace lldb;
36using namespace lldb_private;
37
38//----------------------------------------------------------------------
39// CommunicationKDP constructor
40//----------------------------------------------------------------------
41CommunicationKDP::CommunicationKDP (const char *comm_name) :
42    Communication(comm_name),
43    m_addr_byte_size (4),
44    m_byte_order (eByteOrderLittle),
45    m_packet_timeout (5),
46    m_sequence_mutex (Mutex::eMutexTypeRecursive),
47    m_is_running (false),
48    m_session_key (0u),
49    m_request_sequence_id (0u),
50    m_exception_sequence_id (0u),
51    m_kdp_version_version (0u),
52    m_kdp_version_feature (0u),
53    m_kdp_hostinfo_cpu_mask (0u),
54    m_kdp_hostinfo_cpu_type (0u),
55    m_kdp_hostinfo_cpu_subtype (0u)
56{
57}
58
59//----------------------------------------------------------------------
60// Destructor
61//----------------------------------------------------------------------
62CommunicationKDP::~CommunicationKDP()
63{
64    if (IsConnected())
65    {
66        Disconnect();
67    }
68}
69
70bool
71CommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet)
72{
73    Mutex::Locker locker(m_sequence_mutex);
74    return SendRequestPacketNoLock (request_packet);
75}
76
77#if 0
78typedef struct {
79	uint8_t     request;	// Either: CommandType | ePacketTypeRequest, or CommandType | ePacketTypeReply
80	uint8_t     sequence;
81	uint16_t    length;		// Length of entire packet including this header
82	uint32_t	key;		// Session key
83} kdp_hdr_t;
84#endif
85
86void
87CommunicationKDP::MakeRequestPacketHeader (CommandType request_type,
88                                           PacketStreamType &request_packet,
89                                           uint16_t request_length)
90{
91    request_packet.Clear();
92    request_packet.PutHex8 (request_type | ePacketTypeRequest); // Set the request type
93    request_packet.PutHex8 (m_request_sequence_id++);           // Sequence number
94    request_packet.PutHex16 (request_length);                   // Length of the packet including this header
95    request_packet.PutHex32 (m_session_key);                    // Session key
96}
97
98bool
99CommunicationKDP::SendRequestAndGetReply (const CommandType command,
100                                          const PacketStreamType &request_packet,
101                                          DataExtractor &reply_packet)
102{
103    if (IsRunning())
104    {
105        Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
106        if (log)
107        {
108            PacketStreamType log_strm;
109            DumpPacket (log_strm, request_packet.GetData(), request_packet.GetSize());
110            log->Printf("error: kdp running, not sending packet: %.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
111        }
112        return false;
113    }
114
115    Mutex::Locker locker(m_sequence_mutex);
116#ifdef LLDB_CONFIGURATION_DEBUG
117    // NOTE: this only works for packets that are in native endian byte order
118    assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2)));
119#endif
120    lldb::offset_t offset = 1;
121    const uint32_t num_retries = 3;
122    for (uint32_t i=0; i<num_retries; ++i)
123    {
124        if (SendRequestPacketNoLock(request_packet))
125        {
126            const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
127            while (1)
128            {
129                if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
130                {
131                    offset = 0;
132                    const uint8_t reply_command = reply_packet.GetU8 (&offset);
133                    const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
134                    if (request_sequence_id == reply_sequence_id)
135                    {
136                        // The sequent ID was correct, now verify we got the response we were looking for
137                        if ((reply_command & eCommandTypeMask) == command)
138                        {
139                            // Success
140                            if (command == KDP_RESUMECPUS)
141                                m_is_running.SetValue(true, eBroadcastAlways);
142                            return true;
143                        }
144                        else
145                        {
146                            // Failed to get the correct response, bail
147                            reply_packet.Clear();
148                            return false;
149                        }
150                    }
151                    else if (reply_sequence_id > request_sequence_id)
152                    {
153                        // Sequence ID was greater than the sequence ID of the packet we sent, something
154                        // is really wrong...
155                        reply_packet.Clear();
156                        return false;
157                    }
158                    else
159                    {
160                        // The reply sequence ID was less than our current packet's sequence ID
161                        // so we should keep trying to get a response because this was a response
162                        // for a previous packet that we must have retried.
163                    }
164                }
165                else
166                {
167                    // Break and retry sending the packet as we didn't get a response due to timeout
168                    break;
169                }
170            }
171        }
172    }
173    reply_packet.Clear();
174    return false;
175}
176
177bool
178CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packet)
179{
180    if (IsConnected())
181    {
182        const char *packet_data = request_packet.GetData();
183        const size_t packet_size = request_packet.GetSize();
184
185        Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
186        if (log)
187        {
188            PacketStreamType log_strm;
189            DumpPacket (log_strm, packet_data, packet_size);
190            log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
191        }
192        ConnectionStatus status = eConnectionStatusSuccess;
193
194        size_t bytes_written = Write (packet_data,
195                                      packet_size,
196                                      status,
197                                      NULL);
198
199        if (bytes_written == packet_size)
200            return true;
201
202        if (log)
203            log->Printf ("error: failed to send packet entire packet %" PRIu64 " of %" PRIu64 " bytes sent", (uint64_t)bytes_written, (uint64_t)packet_size);
204    }
205    return false;
206}
207
208bool
209CommunicationKDP::GetSequenceMutex (Mutex::Locker& locker)
210{
211    return locker.TryLock (m_sequence_mutex);
212}
213
214
215bool
216CommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
217{
218    return m_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
219}
220
221size_t
222CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec)
223{
224    Mutex::Locker locker(m_sequence_mutex);
225    return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
226}
227
228size_t
229CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec)
230{
231    uint8_t buffer[8192];
232    Error error;
233
234    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE));
235
236    // Check for a packet from our cache first without trying any reading...
237    if (CheckForPacket (NULL, 0, packet))
238        return packet.GetByteSize();
239
240    bool timed_out = false;
241    while (IsConnected() && !timed_out)
242    {
243        lldb::ConnectionStatus status = eConnectionStatusNoConnection;
244        size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
245
246        if (log)
247            log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
248                         __PRETTY_FUNCTION__,
249                         timeout_usec,
250                         Communication::ConnectionStatusAsCString (status),
251                         error.AsCString(),
252                         (uint64_t)bytes_read);
253
254        if (bytes_read > 0)
255        {
256            if (CheckForPacket (buffer, bytes_read, packet))
257                return packet.GetByteSize();
258        }
259        else
260        {
261            switch (status)
262            {
263            case eConnectionStatusTimedOut:
264                timed_out = true;
265                break;
266            case eConnectionStatusSuccess:
267                //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
268                break;
269
270            case eConnectionStatusEndOfFile:
271            case eConnectionStatusNoConnection:
272            case eConnectionStatusLostConnection:
273            case eConnectionStatusError:
274                Disconnect();
275                break;
276            }
277        }
278    }
279    packet.Clear ();
280    return 0;
281}
282
283bool
284CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet)
285{
286    // Put the packet data into the buffer in a thread safe fashion
287    Mutex::Locker locker(m_bytes_mutex);
288
289    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
290
291    if (src && src_len > 0)
292    {
293        if (log && log->GetVerbose())
294        {
295            PacketStreamType log_strm;
296            DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
297            log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
298                         __FUNCTION__,
299                         (uint32_t)src_len,
300                         log_strm.GetData());
301        }
302        m_bytes.append ((const char *)src, src_len);
303    }
304
305    // Make sure we at least have enough bytes for a packet header
306    const size_t bytes_available = m_bytes.size();
307    if (bytes_available >= 8)
308    {
309        packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
310        lldb::offset_t offset = 0;
311        uint8_t reply_command = packet.GetU8(&offset);
312        switch (reply_command)
313        {
314        case ePacketTypeRequest | KDP_EXCEPTION:
315        case ePacketTypeRequest | KDP_TERMINATION:
316            // We got an exception request, so be sure to send an ACK
317            {
318                PacketStreamType request_ack_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
319                // Set the reply but and make the ACK packet
320                request_ack_packet.PutHex8 (reply_command | ePacketTypeReply);
321                request_ack_packet.PutHex8 (packet.GetU8(&offset));
322                request_ack_packet.PutHex16 (packet.GetU16(&offset));
323                request_ack_packet.PutHex32 (packet.GetU32(&offset));
324                m_is_running.SetValue(false, eBroadcastAlways);
325                // Ack to the exception or termination
326                SendRequestPacketNoLock (request_ack_packet);
327            }
328            // Fall through to case below to get packet contents
329        case ePacketTypeReply | KDP_CONNECT:
330        case ePacketTypeReply | KDP_DISCONNECT:
331        case ePacketTypeReply | KDP_HOSTINFO:
332        case ePacketTypeReply | KDP_VERSION:
333        case ePacketTypeReply | KDP_MAXBYTES:
334        case ePacketTypeReply | KDP_READMEM:
335        case ePacketTypeReply | KDP_WRITEMEM:
336        case ePacketTypeReply | KDP_READREGS:
337        case ePacketTypeReply | KDP_WRITEREGS:
338        case ePacketTypeReply | KDP_LOAD:
339        case ePacketTypeReply | KDP_IMAGEPATH:
340        case ePacketTypeReply | KDP_SUSPEND:
341        case ePacketTypeReply | KDP_RESUMECPUS:
342        case ePacketTypeReply | KDP_BREAKPOINT_SET:
343        case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
344        case ePacketTypeReply | KDP_REGIONS:
345        case ePacketTypeReply | KDP_REATTACH:
346        case ePacketTypeReply | KDP_HOSTREBOOT:
347        case ePacketTypeReply | KDP_READMEM64:
348        case ePacketTypeReply | KDP_WRITEMEM64:
349        case ePacketTypeReply | KDP_BREAKPOINT_SET64:
350        case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
351        case ePacketTypeReply | KDP_KERNELVERSION:
352        case ePacketTypeReply | KDP_READPHYSMEM64:
353        case ePacketTypeReply | KDP_WRITEPHYSMEM64:
354        case ePacketTypeReply | KDP_READIOPORT:
355        case ePacketTypeReply | KDP_WRITEIOPORT:
356        case ePacketTypeReply | KDP_READMSR64:
357        case ePacketTypeReply | KDP_WRITEMSR64:
358        case ePacketTypeReply | KDP_DUMPINFO:
359            {
360                offset = 2;
361                const uint16_t length = packet.GetU16 (&offset);
362                if (length <= bytes_available)
363                {
364                    // We have an entire packet ready, we need to copy the data
365                    // bytes into a buffer that will be owned by the packet and
366                    // erase the bytes from our communcation buffer "m_bytes"
367                    packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
368                    m_bytes.erase (0, length);
369
370                    if (log)
371                    {
372                        PacketStreamType log_strm;
373                        DumpPacket (log_strm, packet);
374
375                        log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
376                    }
377                    return true;
378                }
379            }
380            break;
381
382        default:
383            // Unrecognized reply command byte, erase this byte and try to get back on track
384            if (log)
385                log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
386                             __FUNCTION__,
387                             (uint8_t)m_bytes[0]);
388            m_bytes.erase(0, 1);
389            break;
390        }
391    }
392    packet.Clear();
393    return false;
394}
395
396
397bool
398CommunicationKDP::SendRequestConnect (uint16_t reply_port,
399                                      uint16_t exc_port,
400                                      const char *greeting)
401{
402    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
403    if (greeting == NULL)
404        greeting = "";
405
406    const CommandType command = KDP_CONNECT;
407    // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
408    const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
409    MakeRequestPacketHeader (command, request_packet, command_length);
410    // Always send connect ports as little endian
411    request_packet.SetByteOrder (eByteOrderLittle);
412    request_packet.PutHex16 (reply_port);
413    request_packet.PutHex16 (exc_port);
414    request_packet.SetByteOrder (m_byte_order);
415    request_packet.PutCString (greeting);
416    DataExtractor reply_packet;
417    return SendRequestAndGetReply (command, request_packet, reply_packet);
418}
419
420void
421CommunicationKDP::ClearKDPSettings ()
422{
423    m_request_sequence_id = 0;
424    m_kdp_version_version = 0;
425    m_kdp_version_feature = 0;
426    m_kdp_hostinfo_cpu_mask = 0;
427    m_kdp_hostinfo_cpu_type = 0;
428    m_kdp_hostinfo_cpu_subtype = 0;
429}
430
431bool
432CommunicationKDP::SendRequestReattach (uint16_t reply_port)
433{
434    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
435    const CommandType command = KDP_REATTACH;
436    // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
437    const uint32_t command_length = 8 + 2;
438    MakeRequestPacketHeader (command, request_packet, command_length);
439    // Always send connect ports as little endian
440    request_packet.SetByteOrder (eByteOrderLittle);
441    request_packet.PutHex16(reply_port);
442    request_packet.SetByteOrder (m_byte_order);
443    DataExtractor reply_packet;
444    if (SendRequestAndGetReply (command, request_packet, reply_packet))
445    {
446        // Reset the sequence ID to zero for reattach
447        ClearKDPSettings ();
448        lldb::offset_t offset = 4;
449        m_session_key = reply_packet.GetU32 (&offset);
450        return true;
451    }
452    return false;
453}
454
455uint32_t
456CommunicationKDP::GetVersion ()
457{
458    if (!VersionIsValid())
459        SendRequestVersion();
460    return m_kdp_version_version;
461}
462
463uint32_t
464CommunicationKDP::GetFeatureFlags ()
465{
466    if (!VersionIsValid())
467        SendRequestVersion();
468    return m_kdp_version_feature;
469}
470
471bool
472CommunicationKDP::SendRequestVersion ()
473{
474    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
475    const CommandType command = KDP_VERSION;
476    const uint32_t command_length = 8;
477    MakeRequestPacketHeader (command, request_packet, command_length);
478    DataExtractor reply_packet;
479    if (SendRequestAndGetReply (command, request_packet, reply_packet))
480    {
481        lldb::offset_t offset = 8;
482        m_kdp_version_version = reply_packet.GetU32 (&offset);
483        m_kdp_version_feature = reply_packet.GetU32 (&offset);
484        return true;
485    }
486    return false;
487}
488
489#if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
490const char *
491CommunicationKDP::GetImagePath ()
492{
493    if (m_image_path.empty())
494        SendRequestImagePath();
495    return m_image_path.c_str();
496}
497
498bool
499CommunicationKDP::SendRequestImagePath ()
500{
501    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
502    const CommandType command = KDP_IMAGEPATH;
503    const uint32_t command_length = 8;
504    MakeRequestPacketHeader (command, request_packet, command_length);
505    DataExtractor reply_packet;
506    if (SendRequestAndGetReply (command, request_packet, reply_packet))
507    {
508        const char *path = reply_packet.PeekCStr(8);
509        if (path && path[0])
510            m_kernel_version.assign (path);
511        return true;
512    }
513    return false;
514}
515#endif
516
517uint32_t
518CommunicationKDP::GetCPUMask ()
519{
520    if (!HostInfoIsValid())
521        SendRequestHostInfo();
522    return m_kdp_hostinfo_cpu_mask;
523}
524
525uint32_t
526CommunicationKDP::GetCPUType ()
527{
528    if (!HostInfoIsValid())
529        SendRequestHostInfo();
530    return m_kdp_hostinfo_cpu_type;
531}
532
533uint32_t
534CommunicationKDP::GetCPUSubtype ()
535{
536    if (!HostInfoIsValid())
537        SendRequestHostInfo();
538    return m_kdp_hostinfo_cpu_subtype;
539}
540
541lldb_private::UUID
542CommunicationKDP::GetUUID ()
543{
544    UUID uuid;
545    if (GetKernelVersion() == NULL)
546        return uuid;
547
548    if (m_kernel_version.find("UUID=") == std::string::npos)
549        return uuid;
550
551    size_t p = m_kernel_version.find("UUID=") + strlen ("UUID=");
552    std::string uuid_str = m_kernel_version.substr(p, 36);
553    if (uuid_str.size() < 32)
554        return uuid;
555
556    if (uuid.SetFromCString (uuid_str.c_str()) == 0)
557    {
558        UUID invalid_uuid;
559        return invalid_uuid;
560    }
561
562    return uuid;
563}
564
565bool
566CommunicationKDP::RemoteIsEFI ()
567{
568    if (GetKernelVersion() == NULL)
569        return false;
570    if (strncmp (m_kernel_version.c_str(), "EFI", 3) == 0)
571        return true;
572    else
573        return false;
574}
575
576bool
577CommunicationKDP::RemoteIsDarwinKernel ()
578{
579    if (GetKernelVersion() == NULL)
580        return false;
581    if (m_kernel_version.find("Darwin Kernel") != std::string::npos)
582        return true;
583    else
584        return false;
585}
586
587lldb::addr_t
588CommunicationKDP::GetLoadAddress ()
589{
590    if (GetKernelVersion() == NULL)
591        return LLDB_INVALID_ADDRESS;
592
593    if (m_kernel_version.find("stext=") == std::string::npos)
594        return LLDB_INVALID_ADDRESS;
595    size_t p = m_kernel_version.find("stext=") + strlen ("stext=");
596    if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
597        return LLDB_INVALID_ADDRESS;
598
599    addr_t kernel_load_address;
600    errno = 0;
601    kernel_load_address = ::strtoul (m_kernel_version.c_str() + p, NULL, 16);
602    if (errno != 0 || kernel_load_address == 0)
603        return LLDB_INVALID_ADDRESS;
604
605    return kernel_load_address;
606}
607
608bool
609CommunicationKDP::SendRequestHostInfo ()
610{
611    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
612    const CommandType command = KDP_HOSTINFO;
613    const uint32_t command_length = 8;
614    MakeRequestPacketHeader (command, request_packet, command_length);
615    DataExtractor reply_packet;
616    if (SendRequestAndGetReply (command, request_packet, reply_packet))
617    {
618        lldb::offset_t offset = 8;
619        m_kdp_hostinfo_cpu_mask     = reply_packet.GetU32 (&offset);
620        m_kdp_hostinfo_cpu_type     = reply_packet.GetU32 (&offset);
621        m_kdp_hostinfo_cpu_subtype  = reply_packet.GetU32 (&offset);
622
623        ArchSpec kernel_arch;
624        kernel_arch.SetArchitecture (eArchTypeMachO,
625                                     m_kdp_hostinfo_cpu_type,
626                                     m_kdp_hostinfo_cpu_subtype);
627
628        m_addr_byte_size = kernel_arch.GetAddressByteSize();
629        m_byte_order = kernel_arch.GetByteOrder();
630        return true;
631    }
632    return false;
633}
634
635const char *
636CommunicationKDP::GetKernelVersion ()
637{
638    if (m_kernel_version.empty())
639        SendRequestKernelVersion ();
640    return m_kernel_version.c_str();
641}
642
643bool
644CommunicationKDP::SendRequestKernelVersion ()
645{
646    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
647    const CommandType command = KDP_KERNELVERSION;
648    const uint32_t command_length = 8;
649    MakeRequestPacketHeader (command, request_packet, command_length);
650    DataExtractor reply_packet;
651    if (SendRequestAndGetReply (command, request_packet, reply_packet))
652    {
653        const char *kernel_version_cstr = reply_packet.PeekCStr(8);
654        if (kernel_version_cstr && kernel_version_cstr[0])
655            m_kernel_version.assign (kernel_version_cstr);
656        return true;
657    }
658    return false;
659}
660
661bool
662CommunicationKDP::SendRequestDisconnect ()
663{
664    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
665    const CommandType command = KDP_DISCONNECT;
666    const uint32_t command_length = 8;
667    MakeRequestPacketHeader (command, request_packet, command_length);
668    DataExtractor reply_packet;
669    if (SendRequestAndGetReply (command, request_packet, reply_packet))
670    {
671        // Are we supposed to get a reply for disconnect?
672    }
673    ClearKDPSettings ();
674    return true;
675}
676
677uint32_t
678CommunicationKDP::SendRequestReadMemory (lldb::addr_t addr,
679                                         void *dst,
680                                         uint32_t dst_len,
681                                         Error &error)
682{
683    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
684    bool use_64 = (GetVersion() >= 11);
685    uint32_t command_addr_byte_size = use_64 ? 8 : 4;
686    const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
687    // Size is header + address size + uint32_t length
688    const uint32_t command_length = 8 + command_addr_byte_size + 4;
689    MakeRequestPacketHeader (command, request_packet, command_length);
690    request_packet.PutMaxHex64 (addr, command_addr_byte_size);
691    request_packet.PutHex32 (dst_len);
692    DataExtractor reply_packet;
693    if (SendRequestAndGetReply (command, request_packet, reply_packet))
694    {
695        lldb::offset_t offset = 8;
696        uint32_t kdp_error = reply_packet.GetU32 (&offset);
697        uint32_t src_len = reply_packet.GetByteSize() - 12;
698
699        if (src_len > 0)
700        {
701            const void *src = reply_packet.GetData(&offset, src_len);
702            if (src)
703            {
704                ::memcpy (dst, src, src_len);
705                error.Clear();
706                return src_len;
707            }
708        }
709        if (kdp_error)
710            error.SetErrorStringWithFormat ("kdp read memory failed (error %u)", kdp_error);
711        else
712            error.SetErrorString ("kdp read memory failed");
713    }
714    else
715    {
716        error.SetErrorString ("failed to send packet");
717    }
718    return 0;
719}
720
721
722uint32_t
723CommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr,
724                                          const void *src,
725                                          uint32_t src_len,
726                                          Error &error)
727{
728    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
729    bool use_64 = (GetVersion() >= 11);
730    uint32_t command_addr_byte_size = use_64 ? 8 : 4;
731    const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
732    // Size is header + address size + uint32_t length
733    const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
734    MakeRequestPacketHeader (command, request_packet, command_length);
735    request_packet.PutMaxHex64 (addr, command_addr_byte_size);
736    request_packet.PutHex32 (src_len);
737    request_packet.PutRawBytes(src, src_len);
738
739    DataExtractor reply_packet;
740    if (SendRequestAndGetReply (command, request_packet, reply_packet))
741    {
742        lldb::offset_t offset = 8;
743        uint32_t kdp_error = reply_packet.GetU32 (&offset);
744        if (kdp_error)
745            error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error);
746        else
747        {
748            error.Clear();
749            return src_len;
750        }
751    }
752    else
753    {
754        error.SetErrorString ("failed to send packet");
755    }
756    return 0;
757}
758
759bool
760CommunicationKDP::SendRawRequest (uint8_t command_byte,
761                                  const void *src,  // Raw packet payload bytes
762                                  uint32_t src_len, // Raw packet payload length
763                                  DataExtractor &reply_packet,
764                                  Error &error)
765{
766    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
767    // Size is header + address size + uint32_t length
768    const uint32_t command_length = 8 + src_len;
769    const CommandType command = (CommandType)command_byte;
770    MakeRequestPacketHeader (command, request_packet, command_length);
771    request_packet.PutRawBytes(src, src_len);
772
773    if (SendRequestAndGetReply (command, request_packet, reply_packet))
774    {
775        lldb::offset_t offset = 8;
776        uint32_t kdp_error = reply_packet.GetU32 (&offset);
777        if (kdp_error  && (command_byte != KDP_DUMPINFO))
778            error.SetErrorStringWithFormat ("request packet 0x%8.8x failed (error %u)", command_byte, kdp_error);
779        else
780        {
781            error.Clear();
782            return true;
783        }
784    }
785    else
786    {
787        error.SetErrorString ("failed to send packet");
788    }
789    return false;
790}
791
792
793const char *
794CommunicationKDP::GetCommandAsCString (uint8_t command)
795{
796    switch (command)
797    {
798    case KDP_CONNECT:               return "KDP_CONNECT";
799    case KDP_DISCONNECT:            return "KDP_DISCONNECT";
800    case KDP_HOSTINFO:              return "KDP_HOSTINFO";
801    case KDP_VERSION:               return "KDP_VERSION";
802    case KDP_MAXBYTES:              return "KDP_MAXBYTES";
803    case KDP_READMEM:               return "KDP_READMEM";
804    case KDP_WRITEMEM:              return "KDP_WRITEMEM";
805    case KDP_READREGS:              return "KDP_READREGS";
806    case KDP_WRITEREGS:             return "KDP_WRITEREGS";
807    case KDP_LOAD:                  return "KDP_LOAD";
808    case KDP_IMAGEPATH:             return "KDP_IMAGEPATH";
809    case KDP_SUSPEND:               return "KDP_SUSPEND";
810    case KDP_RESUMECPUS:            return "KDP_RESUMECPUS";
811    case KDP_EXCEPTION:             return "KDP_EXCEPTION";
812    case KDP_TERMINATION:           return "KDP_TERMINATION";
813    case KDP_BREAKPOINT_SET:        return "KDP_BREAKPOINT_SET";
814    case KDP_BREAKPOINT_REMOVE:     return "KDP_BREAKPOINT_REMOVE";
815    case KDP_REGIONS:               return "KDP_REGIONS";
816    case KDP_REATTACH:              return "KDP_REATTACH";
817    case KDP_HOSTREBOOT:            return "KDP_HOSTREBOOT";
818    case KDP_READMEM64:             return "KDP_READMEM64";
819    case KDP_WRITEMEM64:            return "KDP_WRITEMEM64";
820    case KDP_BREAKPOINT_SET64:      return "KDP_BREAKPOINT64_SET";
821    case KDP_BREAKPOINT_REMOVE64:   return "KDP_BREAKPOINT64_REMOVE";
822    case KDP_KERNELVERSION:         return "KDP_KERNELVERSION";
823    case KDP_READPHYSMEM64:         return "KDP_READPHYSMEM64";
824    case KDP_WRITEPHYSMEM64:        return "KDP_WRITEPHYSMEM64";
825    case KDP_READIOPORT:            return "KDP_READIOPORT";
826    case KDP_WRITEIOPORT:           return "KDP_WRITEIOPORT";
827    case KDP_READMSR64:             return "KDP_READMSR64";
828    case KDP_WRITEMSR64:            return "KDP_WRITEMSR64";
829    case KDP_DUMPINFO:              return "KDP_DUMPINFO";
830    }
831    return NULL;
832}
833
834void
835CommunicationKDP::DumpPacket (Stream &s, const void *data, uint32_t data_len)
836{
837    DataExtractor extractor (data, data_len, m_byte_order, m_addr_byte_size);
838    DumpPacket (s, extractor);
839}
840
841void
842CommunicationKDP::DumpPacket (Stream &s, const DataExtractor& packet)
843{
844    const char *error_desc = NULL;
845    if (packet.GetByteSize() < 8)
846    {
847        error_desc = "error: invalid packet (too short): ";
848    }
849    else
850    {
851        lldb::offset_t offset = 0;
852        const uint8_t first_packet_byte = packet.GetU8 (&offset);
853        const uint8_t sequence_id = packet.GetU8 (&offset);
854        const uint16_t length = packet.GetU16 (&offset);
855        const uint32_t key = packet.GetU32 (&offset);
856        const CommandType command = ExtractCommand (first_packet_byte);
857        const char *command_name = GetCommandAsCString (command);
858        if (command_name)
859        {
860            const bool is_reply = ExtractIsReply(first_packet_byte);
861            s.Printf ("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
862                      IsRunning(),
863                      is_reply ? "<--" : "-->",
864                      command_name,
865                      first_packet_byte,
866                      sequence_id,
867                      length,
868                      key);
869
870            if (is_reply)
871            {
872                // Dump request reply packets
873                switch (command)
874                {
875                    // Commands that return a single 32 bit error
876                    case KDP_CONNECT:
877                    case KDP_WRITEMEM:
878                    case KDP_WRITEMEM64:
879                    case KDP_BREAKPOINT_SET:
880                    case KDP_BREAKPOINT_REMOVE:
881                    case KDP_BREAKPOINT_SET64:
882                    case KDP_BREAKPOINT_REMOVE64:
883                    case KDP_WRITEREGS:
884                    case KDP_LOAD:
885                    case KDP_WRITEIOPORT:
886                    case KDP_WRITEMSR64:
887                        {
888                            const uint32_t error = packet.GetU32 (&offset);
889                            s.Printf(" (error=0x%8.8x)", error);
890                        }
891                        break;
892
893                    case KDP_DISCONNECT:
894                    case KDP_REATTACH:
895                    case KDP_HOSTREBOOT:
896                    case KDP_SUSPEND:
897                    case KDP_RESUMECPUS:
898                    case KDP_EXCEPTION:
899                    case KDP_TERMINATION:
900                        // No return value for the reply, just the header to ack
901                        s.PutCString(" ()");
902                        break;
903
904                    case KDP_HOSTINFO:
905                        {
906                            const uint32_t cpu_mask = packet.GetU32 (&offset);
907                            const uint32_t cpu_type = packet.GetU32 (&offset);
908                            const uint32_t cpu_subtype = packet.GetU32 (&offset);
909                            s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", cpu_mask, cpu_type, cpu_subtype);
910                        }
911                        break;
912
913                    case KDP_VERSION:
914                        {
915                            const uint32_t version = packet.GetU32 (&offset);
916                            const uint32_t feature = packet.GetU32 (&offset);
917                            s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
918                        }
919                        break;
920
921                    case KDP_REGIONS:
922                        {
923                            const uint32_t region_count = packet.GetU32 (&offset);
924                            s.Printf(" (count = %u", region_count);
925                            for (uint32_t i=0; i<region_count; ++i)
926                            {
927                                const addr_t region_addr = packet.GetPointer (&offset);
928                                const uint32_t region_size = packet.GetU32 (&offset);
929                                const uint32_t region_prot = packet.GetU32 (&offset);
930                                s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot));
931                            }
932                        }
933                        break;
934
935                    case KDP_READMEM:
936                    case KDP_READMEM64:
937                    case KDP_READPHYSMEM64:
938                        {
939                            const uint32_t error = packet.GetU32 (&offset);
940                            const uint32_t count = packet.GetByteSize() - offset;
941                            s.Printf(" (error = 0x%8.8x:\n", error);
942                            if (count > 0)
943                                packet.Dump (&s,                        // Stream to dump to
944                                             offset,                    // Offset within "packet"
945                                             eFormatBytesWithASCII,     // Format to use
946                                             1,                         // Size of each item in bytes
947                                             count,                     // Number of items
948                                             16,                        // Number per line
949                                             m_last_read_memory_addr,   // Don't show addresses before each line
950                                             0, 0);                     // No bitfields
951                        }
952                        break;
953
954                    case KDP_READREGS:
955                        {
956                            const uint32_t error = packet.GetU32 (&offset);
957                            const uint32_t count = packet.GetByteSize() - offset;
958                            s.Printf(" (error = 0x%8.8x regs:\n", error);
959                            if (count > 0)
960                                packet.Dump (&s,                        // Stream to dump to
961                                             offset,                    // Offset within "packet"
962                                             eFormatHex,                // Format to use
963                                             m_addr_byte_size,          // Size of each item in bytes
964                                             count / m_addr_byte_size,  // Number of items
965                                             16 / m_addr_byte_size,     // Number per line
966                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
967                                             0, 0);                     // No bitfields
968                        }
969                        break;
970
971                    case KDP_KERNELVERSION:
972                        {
973                            const char *kernel_version = packet.PeekCStr(8);
974                            s.Printf(" (version = \"%s\")", kernel_version);
975                        }
976                        break;
977
978                    case KDP_MAXBYTES:
979                        {
980                            const uint32_t max_bytes = packet.GetU32 (&offset);
981                            s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
982                        }
983                        break;
984                    case KDP_IMAGEPATH:
985                        {
986                            const char *path = packet.GetCStr(&offset);
987                            s.Printf(" (path = \"%s\")", path);
988                        }
989                        break;
990
991                    case KDP_READIOPORT:
992                    case KDP_READMSR64:
993                        {
994                            const uint32_t error = packet.GetU32 (&offset);
995                            const uint32_t count = packet.GetByteSize() - offset;
996                            s.Printf(" (error = 0x%8.8x io:\n", error);
997                            if (count > 0)
998                                packet.Dump (&s,                        // Stream to dump to
999                                             offset,                    // Offset within "packet"
1000                                             eFormatHex,                // Format to use
1001                                             1,                         // Size of each item in bytes
1002                                             count,                     // Number of items
1003                                             16,                        // Number per line
1004                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1005                                             0, 0);                     // No bitfields
1006                        }
1007                        break;
1008                    case KDP_DUMPINFO:
1009                        {
1010                            const uint32_t count = packet.GetByteSize() - offset;
1011                            s.Printf(" (count = %u, bytes = \n", count);
1012                            if (count > 0)
1013                                packet.Dump (&s,                        // Stream to dump to
1014                                             offset,                    // Offset within "packet"
1015                                             eFormatHex,                // Format to use
1016                                             1,                         // Size of each item in bytes
1017                                             count,                     // Number of items
1018                                             16,                        // Number per line
1019                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1020                                             0, 0);                     // No bitfields
1021
1022                        }
1023                        break;
1024
1025                    default:
1026                        s.Printf(" (add support for dumping this packet reply!!!");
1027                        break;
1028
1029                }
1030            }
1031            else
1032            {
1033                // Dump request packets
1034                switch (command)
1035                {
1036                    case KDP_CONNECT:
1037                        {
1038                            const uint16_t reply_port = packet.GetU16 (&offset);
1039                            const uint16_t exc_port = packet.GetU16 (&offset);
1040                            s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", reply_port, exc_port, packet.GetCStr(&offset));
1041                        }
1042                        break;
1043
1044                    case KDP_DISCONNECT:
1045                    case KDP_HOSTREBOOT:
1046                    case KDP_HOSTINFO:
1047                    case KDP_VERSION:
1048                    case KDP_REGIONS:
1049                    case KDP_KERNELVERSION:
1050                    case KDP_MAXBYTES:
1051                    case KDP_IMAGEPATH:
1052                    case KDP_SUSPEND:
1053                        // No args, just the header in the request...
1054                        s.PutCString(" ()");
1055                        break;
1056
1057                    case KDP_RESUMECPUS:
1058                        {
1059                            const uint32_t cpu_mask = packet.GetU32 (&offset);
1060                            s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
1061                        }
1062                        break;
1063
1064                    case KDP_READMEM:
1065                        {
1066                            const uint32_t addr = packet.GetU32 (&offset);
1067                            const uint32_t size = packet.GetU32 (&offset);
1068                            s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
1069                            m_last_read_memory_addr = addr;
1070                        }
1071                        break;
1072
1073                    case KDP_WRITEMEM:
1074                        {
1075                            const uint32_t addr = packet.GetU32 (&offset);
1076                            const uint32_t size = packet.GetU32 (&offset);
1077                            s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
1078                            if (size > 0)
1079                                DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
1080                        }
1081                        break;
1082
1083                    case KDP_READMEM64:
1084                        {
1085                            const uint64_t addr = packet.GetU64 (&offset);
1086                            const uint32_t size = packet.GetU32 (&offset);
1087                            s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
1088                            m_last_read_memory_addr = addr;
1089                        }
1090                        break;
1091
1092                    case KDP_READPHYSMEM64:
1093                        {
1094                            const uint64_t addr = packet.GetU64 (&offset);
1095                            const uint32_t size = packet.GetU32 (&offset);
1096                            const uint32_t lcpu = packet.GetU16 (&offset);
1097                            s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, lcpu);
1098                            m_last_read_memory_addr = addr;
1099                        }
1100                        break;
1101
1102                    case KDP_WRITEMEM64:
1103                        {
1104                            const uint64_t addr = packet.GetU64 (&offset);
1105                            const uint32_t size = packet.GetU32 (&offset);
1106                            s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr, size);
1107                            if (size > 0)
1108                                DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
1109                        }
1110                        break;
1111
1112                    case KDP_WRITEPHYSMEM64:
1113                        {
1114                            const uint64_t addr = packet.GetU64 (&offset);
1115                            const uint32_t size = packet.GetU32 (&offset);
1116                            const uint32_t lcpu = packet.GetU16 (&offset);
1117                            s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", addr, size, lcpu);
1118                            if (size > 0)
1119                                DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
1120                        }
1121                        break;
1122
1123                    case KDP_READREGS:
1124                        {
1125                            const uint32_t cpu = packet.GetU32 (&offset);
1126                            const uint32_t flavor = packet.GetU32 (&offset);
1127                            s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
1128                        }
1129                        break;
1130
1131                    case KDP_WRITEREGS:
1132                        {
1133                            const uint32_t cpu = packet.GetU32 (&offset);
1134                            const uint32_t flavor = packet.GetU32 (&offset);
1135                            const uint32_t nbytes = packet.GetByteSize() - offset;
1136                            s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
1137                            if (nbytes > 0)
1138                                packet.Dump (&s,                        // Stream to dump to
1139                                             offset,                    // Offset within "packet"
1140                                             eFormatHex,                // Format to use
1141                                             m_addr_byte_size,          // Size of each item in bytes
1142                                             nbytes / m_addr_byte_size, // Number of items
1143                                             16 / m_addr_byte_size,     // Number per line
1144                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1145                                             0, 0);                     // No bitfields
1146                        }
1147                        break;
1148
1149
1150                    case KDP_BREAKPOINT_SET:
1151                    case KDP_BREAKPOINT_REMOVE:
1152                        {
1153                            const uint32_t addr = packet.GetU32 (&offset);
1154                            s.Printf(" (addr = 0x%8.8x)", addr);
1155                        }
1156                        break;
1157
1158                    case KDP_BREAKPOINT_SET64:
1159                    case KDP_BREAKPOINT_REMOVE64:
1160                        {
1161                            const uint64_t addr = packet.GetU64 (&offset);
1162                            s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
1163                        }
1164                        break;
1165
1166
1167                    case KDP_LOAD:
1168                        {
1169                            const char *path = packet.GetCStr(&offset);
1170                            s.Printf(" (path = \"%s\")", path);
1171                        }
1172                        break;
1173
1174                    case KDP_EXCEPTION:
1175                        {
1176                            const uint32_t count = packet.GetU32 (&offset);
1177
1178                            for (uint32_t i=0; i<count; ++i)
1179                            {
1180                                const uint32_t cpu = packet.GetU32 (&offset);
1181                                const uint32_t exc = packet.GetU32 (&offset);
1182                                const uint32_t code = packet.GetU32 (&offset);
1183                                const uint32_t subcode = packet.GetU32 (&offset);
1184                                const char *exc_cstr = NULL;
1185                                switch (exc)
1186                                {
1187                                    case 1:  exc_cstr = "EXC_BAD_ACCESS"; break;
1188                                    case 2:  exc_cstr = "EXC_BAD_INSTRUCTION"; break;
1189                                    case 3:  exc_cstr = "EXC_ARITHMETIC"; break;
1190                                    case 4:  exc_cstr = "EXC_EMULATION"; break;
1191                                    case 5:  exc_cstr = "EXC_SOFTWARE"; break;
1192                                    case 6:  exc_cstr = "EXC_BREAKPOINT"; break;
1193                                    case 7:  exc_cstr = "EXC_SYSCALL"; break;
1194                                    case 8:  exc_cstr = "EXC_MACH_SYSCALL"; break;
1195                                    case 9:  exc_cstr = "EXC_RPC_ALERT"; break;
1196                                    case 10: exc_cstr = "EXC_CRASH"; break;
1197                                    default:
1198                                        break;
1199                                }
1200
1201                                s.Printf ("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), subcode = %u (0x%8.8x)} ",
1202                                          cpu, exc_cstr, exc, code, code, subcode, subcode);
1203                            }
1204                        }
1205                        break;
1206
1207                    case KDP_TERMINATION:
1208                        {
1209                            const uint32_t term_code = packet.GetU32 (&offset);
1210                            const uint32_t exit_code = packet.GetU32 (&offset);
1211                            s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", term_code, term_code, exit_code, exit_code);
1212                        }
1213                        break;
1214
1215                    case KDP_REATTACH:
1216                        {
1217                            const uint16_t reply_port = packet.GetU16 (&offset);
1218                            s.Printf(" (reply_port = %u)", reply_port);
1219                        }
1220                        break;
1221
1222                    case KDP_READMSR64:
1223                        {
1224                            const uint32_t address = packet.GetU32 (&offset);
1225                            const uint16_t lcpu = packet.GetU16 (&offset);
1226                            s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
1227                        }
1228                        break;
1229
1230                    case KDP_WRITEMSR64:
1231                        {
1232                            const uint32_t address = packet.GetU32 (&offset);
1233                            const uint16_t lcpu = packet.GetU16 (&offset);
1234                            const uint32_t nbytes = packet.GetByteSize() - offset;
1235                            s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes);
1236                            if (nbytes > 0)
1237                                packet.Dump (&s,                        // Stream to dump to
1238                                             offset,                    // Offset within "packet"
1239                                             eFormatHex,                // Format to use
1240                                             1,                         // Size of each item in bytes
1241                                             nbytes,                    // Number of items
1242                                             16,                        // Number per line
1243                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1244                                             0, 0);                     // No bitfields
1245                        }
1246                        break;
1247
1248                    case KDP_READIOPORT:
1249                        {
1250                            const uint16_t lcpu = packet.GetU16 (&offset);
1251                            const uint16_t address = packet.GetU16 (&offset);
1252                            const uint16_t nbytes = packet.GetU16 (&offset);
1253                            s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, nbytes);
1254                        }
1255                        break;
1256
1257                    case KDP_WRITEIOPORT:
1258                         {
1259                            const uint16_t lcpu = packet.GetU16 (&offset);
1260                            const uint16_t address = packet.GetU16 (&offset);
1261                            const uint16_t nbytes = packet.GetU16 (&offset);
1262                            s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes);
1263                            if (nbytes > 0)
1264                                packet.Dump (&s,                        // Stream to dump to
1265                                             offset,                    // Offset within "packet"
1266                                             eFormatHex,                // Format to use
1267                                             1,                         // Size of each item in bytes
1268                                             nbytes,                    // Number of items
1269                                             16,                        // Number per line
1270                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1271                                             0, 0);                     // No bitfields
1272                        }
1273                        break;
1274
1275                    case KDP_DUMPINFO:
1276                        {
1277                            const uint32_t count = packet.GetByteSize() - offset;
1278                            s.Printf(" (count = %u, bytes = \n", count);
1279                            if (count > 0)
1280                                packet.Dump (&s,                        // Stream to dump to
1281                                             offset,                    // Offset within "packet"
1282                                             eFormatHex,                // Format to use
1283                                             1,                         // Size of each item in bytes
1284                                             count,                     // Number of items
1285                                             16,                        // Number per line
1286                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1287                                             0, 0);                     // No bitfields
1288
1289                        }
1290                        break;
1291
1292               }
1293            }
1294        }
1295        else
1296        {
1297            error_desc = "error: invalid packet command: ";
1298        }
1299    }
1300
1301    if (error_desc)
1302    {
1303        s.PutCString (error_desc);
1304
1305        packet.Dump (&s,                    // Stream to dump to
1306                     0,                     // Offset into "packet"
1307                     eFormatBytes,          // Dump as hex bytes
1308                     1,                     // Size of each item is 1 for single bytes
1309                     packet.GetByteSize(),  // Number of bytes
1310                     UINT32_MAX,            // Num bytes per line
1311                     LLDB_INVALID_ADDRESS,  // Base address
1312                     0, 0);                 // Bitfield info set to not do anything bitfield related
1313    }
1314}
1315
1316uint32_t
1317CommunicationKDP::SendRequestReadRegisters (uint32_t cpu,
1318                                            uint32_t flavor,
1319                                            void *dst,
1320                                            uint32_t dst_len,
1321                                            Error &error)
1322{
1323    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1324    const CommandType command = KDP_READREGS;
1325    // Size is header + 4 byte cpu and 4 byte flavor
1326    const uint32_t command_length = 8 + 4 + 4;
1327    MakeRequestPacketHeader (command, request_packet, command_length);
1328    request_packet.PutHex32 (cpu);
1329    request_packet.PutHex32 (flavor);
1330    DataExtractor reply_packet;
1331    if (SendRequestAndGetReply (command, request_packet, reply_packet))
1332    {
1333        lldb::offset_t offset = 8;
1334        uint32_t kdp_error = reply_packet.GetU32 (&offset);
1335        uint32_t src_len = reply_packet.GetByteSize() - 12;
1336
1337        if (src_len > 0)
1338        {
1339            const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
1340            const void *src = reply_packet.GetData(&offset, bytes_to_copy);
1341            if (src)
1342            {
1343                ::memcpy (dst, src, bytes_to_copy);
1344                error.Clear();
1345                // Return the number of bytes we could have returned regardless if
1346                // we copied them or not, just so we know when things don't match up
1347                return src_len;
1348            }
1349        }
1350        if (kdp_error)
1351            error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
1352        else
1353            error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
1354    }
1355    else
1356    {
1357        error.SetErrorString ("failed to send packet");
1358    }
1359    return 0;
1360}
1361
1362uint32_t
1363CommunicationKDP::SendRequestWriteRegisters (uint32_t cpu,
1364                                             uint32_t flavor,
1365                                             const void *src,
1366                                             uint32_t src_len,
1367                                             Error &error)
1368{
1369    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1370    const CommandType command = KDP_WRITEREGS;
1371    // Size is header + 4 byte cpu and 4 byte flavor
1372    const uint32_t command_length = 8 + 4 + 4 + src_len;
1373    MakeRequestPacketHeader (command, request_packet, command_length);
1374    request_packet.PutHex32 (cpu);
1375    request_packet.PutHex32 (flavor);
1376    request_packet.Write(src, src_len);
1377    DataExtractor reply_packet;
1378    if (SendRequestAndGetReply (command, request_packet, reply_packet))
1379    {
1380        lldb::offset_t offset = 8;
1381        uint32_t kdp_error = reply_packet.GetU32 (&offset);
1382        if (kdp_error == 0)
1383            return src_len;
1384        error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
1385    }
1386    else
1387    {
1388        error.SetErrorString ("failed to send packet");
1389    }
1390    return 0;
1391}
1392
1393
1394bool
1395CommunicationKDP::SendRequestResume ()
1396{
1397    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1398    const CommandType command = KDP_RESUMECPUS;
1399    const uint32_t command_length = 12;
1400    MakeRequestPacketHeader (command, request_packet, command_length);
1401    request_packet.PutHex32(GetCPUMask());
1402
1403    DataExtractor reply_packet;
1404    if (SendRequestAndGetReply (command, request_packet, reply_packet))
1405        return true;
1406    return false;
1407}
1408
1409bool
1410CommunicationKDP::SendRequestBreakpoint (bool set, addr_t addr)
1411{
1412    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1413    bool use_64 = (GetVersion() >= 11);
1414    uint32_t command_addr_byte_size = use_64 ? 8 : 4;
1415    const CommandType command = set ? (use_64 ? KDP_BREAKPOINT_SET64    : KDP_BREAKPOINT_SET   ):
1416                                      (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
1417
1418    const uint32_t command_length = 8 + command_addr_byte_size;
1419    MakeRequestPacketHeader (command, request_packet, command_length);
1420    request_packet.PutMaxHex64 (addr, command_addr_byte_size);
1421
1422    DataExtractor reply_packet;
1423    if (SendRequestAndGetReply (command, request_packet, reply_packet))
1424    {
1425        lldb::offset_t offset = 8;
1426        uint32_t kdp_error = reply_packet.GetU32 (&offset);
1427        if (kdp_error == 0)
1428            return true;
1429    }
1430    return false;
1431}
1432
1433bool
1434CommunicationKDP::SendRequestSuspend ()
1435{
1436    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1437    const CommandType command = KDP_SUSPEND;
1438    const uint32_t command_length = 8;
1439    MakeRequestPacketHeader (command, request_packet, command_length);
1440    DataExtractor reply_packet;
1441    if (SendRequestAndGetReply (command, request_packet, reply_packet))
1442        return true;
1443    return false;
1444}
1445
1446