diff options
Diffstat (limited to 'lldb/source/Plugins/Process/MacOSX-Kernel')
3 files changed, 139 insertions, 256 deletions
| diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp index c3ac577febd..1790ee7f808 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp @@ -16,6 +16,7 @@  // C++ Includes  // Other libraries and framework includes +#include "lldb/Core/DataExtractor.h"  #include "lldb/Core/Log.h"  #include "lldb/Core/StreamString.h"  #include "lldb/Host/FileSpec.h" @@ -41,7 +42,9 @@ CommunicationKDP::CommunicationKDP (const char *comm_name) :      m_sequence_mutex (Mutex::eMutexTypeRecursive),      m_public_is_running (false),      m_private_is_running (false), -    m_send_acks (true) +    m_session_key (0), +    m_request_sequence_id (0), +    m_exception_sequence_id (0)  {  } @@ -56,110 +59,68 @@ CommunicationKDP::~CommunicationKDP()      }  } -char -CommunicationKDP::CalculcateChecksum (const char *payload, size_t payload_length) -{ -    int checksum = 0; - -    // We only need to compute the checksum if we are sending acks -    if (GetSendAcks ()) -    { -        for (size_t i = 0; i < payload_length; ++i) -            checksum += payload[i]; -    } -    return checksum & 255; -} - -size_t -CommunicationKDP::SendAck () -{ -    LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); -    if (log) -        log->Printf ("send packet: +"); -    ConnectionStatus status = eConnectionStatusSuccess; -    char ack_char = '+'; -    return Write (&ack_char, 1, status, NULL); -} - -size_t -CommunicationKDP::SendNack () -{ -    LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); -    if (log) -        log->Printf ("send packet: -"); -    ConnectionStatus status = eConnectionStatusSuccess; -    char nack_char = '-'; -    return Write (&nack_char, 1, status, NULL); -} - -size_t -CommunicationKDP::SendPacket (lldb_private::StreamString &payload) +bool +CommunicationKDP::SendRequestPacket (const StreamString &request_packet)  {      Mutex::Locker locker(m_sequence_mutex); -    const std::string &p (payload.GetString()); -    return SendPacketNoLock (p.c_str(), p.size()); +    return SendRequestPacketNoLock (request_packet);  } -size_t -CommunicationKDP::SendPacket (const char *payload) +void +CommunicationKDP::MakeRequestPacketHeader (RequestType request_type,  +                                           StreamString &request_packet)  { -    Mutex::Locker locker(m_sequence_mutex); -    return SendPacketNoLock (payload, ::strlen (payload)); +    request_packet.Clear(); +    request_packet.PutHex32 (request_type);             // Set the request type +    request_packet.PutHex8  (ePacketTypeRequest);       // Set the packet type +    request_packet.PutHex8  (++m_request_sequence_id);  // Sequence number +    request_packet.PutHex16 (0);                        // Pad1 and Pad2 bytes +    request_packet.PutHex32 (m_session_key);            // Session key  } -size_t -CommunicationKDP::SendPacket (const char *payload, size_t payload_length) -{ -    Mutex::Locker locker(m_sequence_mutex); -    return SendPacketNoLock (payload, payload_length); -} -size_t -CommunicationKDP::SendPacketNoLock (const char *payload, size_t payload_length) +bool +CommunicationKDP::SendRequestPacketNoLock (const StreamString &request_packet)  {      if (IsConnected())      { -        StreamString packet(0, 4, eByteOrderBig); - -        packet.PutChar('$'); -        packet.Write (payload, payload_length); -        packet.PutChar('#'); -        packet.PutHex8(CalculcateChecksum (payload, payload_length)); +        const char *packet_data = request_packet.GetData(); +        const size_t packet_size = request_packet.GetSize();          LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));          if (log) -            log->Printf ("send packet: %.*s", (int)packet.GetSize(), packet.GetData()); -        ConnectionStatus status = eConnectionStatusSuccess; -        size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL); -        if (bytes_written == packet.GetSize()) -        { -            if (GetSendAcks ()) -            { -                if (GetAck () != '+') -                { -                    printf("get ack failed..."); -                    return 0; -                } -            } -        } -        else          { -            LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); -            if (log) -                log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData()); +            StreamString log_strm; +            DataExtractor data (packet_data,  +                                packet_size, +                                request_packet.GetByteOrder(), +                                request_packet.GetAddressByteSize()); +            data.Dump (&log_strm,  +                       0,  +                       eFormatBytes, +                       1,  +                       packet_size, +                       32,  // Num bytes per line +                       0,   // Base address +                       0,  +                       0); +             +            log->Printf("request packet: <%u>\n%s", packet_size, log_strm.GetString().c_str());          } -        return bytes_written; -    } -    return 0; -} +        ConnectionStatus status = eConnectionStatusSuccess; -char -CommunicationKDP::GetAck () -{ -    StringExtractor packet; -    if (WaitForPacketWithTimeoutMicroSeconds (packet, GetPacketTimeoutInMicroSeconds ()) == 1) -        return packet.GetChar(); -    return 0; +        size_t bytes_written = Write (packet_data,  +                                      packet_size,  +                                      status,  +                                      NULL); + +        if (bytes_written == packet_size) +            return true; +         +        if (log) +            log->Printf ("error: failed to send packet entire packet %zu of %zu bytes sent", bytes_written, packet_size); +    } +    return false;  }  bool @@ -262,142 +223,30 @@ CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, StringExtr      // Parse up the packets into gdb remote packets      if (!m_bytes.empty())      { -        // end_idx must be one past the last valid packet byte. Start -        // it off with an invalid value that is the same as the current -        // index. -        size_t content_start = 0; -        size_t content_length = 0; -        size_t total_length = 0; -        size_t checksum_idx = std::string::npos; - -        switch (m_bytes[0]) -        { -            case '+':       // Look for ack -            case '-':       // Look for cancel -            case '\x03':    // ^C to halt target -                content_length = total_length = 1;  // The command is one byte long... -                break; - -            case '$': -                // Look for a standard gdb packet? -                { -                    size_t hash_pos = m_bytes.find('#'); -                    if (hash_pos != std::string::npos) -                    { -                        if (hash_pos + 2 < m_bytes.size()) -                        { -                            checksum_idx = hash_pos + 1; -                            // Skip the dollar sign -                            content_start = 1;  -                            // Don't include the # in the content or the $ in the content length -                            content_length = hash_pos - 1;   -                             -                            total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes -                        } -                        else -                        { -                            // Checksum bytes aren't all here yet -                            content_length = std::string::npos; -                        } -                    } -                } -                break; - -            default: -                { -                    // We have an unexpected byte and we need to flush all bad  -                    // data that is in m_bytes, so we need to find the first -                    // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt), -                    // or '$' character (start of packet header) or of course, -                    // the end of the data in m_bytes... -                    const size_t bytes_len = m_bytes.size(); -                    bool done = false; -                    uint32_t idx; -                    for (idx = 1; !done && idx < bytes_len; ++idx) -                    { -                        switch (m_bytes[idx]) -                        { -                        case '+': -                        case '-': -                        case '\x03': -                        case '$': -                            done = true; -                            break; -                                 -                        default: -                            break; -                        } -                    } -                    if (log) -                        log->Printf ("CommunicationKDP::%s tossing %u junk bytes: '%.*s'", -                                     __FUNCTION__, idx, idx, m_bytes.c_str()); -                    m_bytes.erase(0, idx); -                } -                break; -        } - -        if (content_length == std::string::npos) -        { -            packet.Clear(); -            return false; -        } -        else if (total_length > 0) -        { - -            // We have a valid packet... -            assert (content_length <= m_bytes.size()); -            assert (total_length <= m_bytes.size()); -            assert (content_length <= total_length); -             -            bool success = true; -            std::string &packet_str = packet.GetStringRef(); -            packet_str.assign (m_bytes, content_start, content_length); -            if (m_bytes[0] == '$') -            { -                assert (checksum_idx < m_bytes.size()); -                if (::isxdigit (m_bytes[checksum_idx+0]) ||  -                    ::isxdigit (m_bytes[checksum_idx+1])) -                { -                    if (GetSendAcks ()) -                    { -                        const char *packet_checksum_cstr = &m_bytes[checksum_idx]; -                        char packet_checksum = strtol (packet_checksum_cstr, NULL, 16); -                        char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size()); -                        success = packet_checksum == actual_checksum; -                        if (!success) -                        { -                            if (log) -                                log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",  -                                             (int)(total_length),  -                                             m_bytes.c_str(), -                                             (uint8_t)packet_checksum, -                                             (uint8_t)actual_checksum); -                        } -                        // Send the ack or nack if needed -                        if (!success) -                            SendNack(); -                        else -                            SendAck(); -                    } -                    if (success) -                    { -                        if (log) -                            log->Printf ("read packet: %.*s", (int)(total_length), m_bytes.c_str()); -                    } -                } -                else -                { -                    success = false; -                    if (log) -                        log->Printf ("error: invalid checksum in packet: '%s'\n", (int)(total_length), m_bytes.c_str()); -                } -            } -            m_bytes.erase(0, total_length); -            packet.SetFilePos(0); -            return success; -        } +        // TODO: Figure out if we have a full packet reply      }      packet.Clear();      return false;  } + +CommunicationKDP::ErrorType +CommunicationKDP::Connect (uint16_t reply_port,  +                           uint16_t exc_port,  +                           const char *greeting) +{ +    StreamString request_packet (Stream::eBinary, 4, eByteOrderLittle); +    MakeRequestPacketHeader (eRequestTypeConnect, request_packet); +    request_packet.PutHex16(reply_port); +    request_packet.PutHex16(exc_port); +    request_packet.PutCString(greeting); +     +    return eErrorUnimplemented; +} + +CommunicationKDP::ErrorType +CommunicationKDP::Disconnect () +{ +    return eErrorUnimplemented; +} + diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h index ee626a69824..c04083c2028 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h @@ -33,6 +33,53 @@ public:      {          eBroadcastBitRunPacketSent = kLoUserBroadcastBit      }; +     +    const static uint32_t kMaxPacketSize = 1200; +    const static uint32_t kMaxDataSize = 1024; +     +    typedef enum  +    { +        eRequestTypeConnect = 0u, +        eRequestTypeDisconnect, +        eRequestTypeHostInfo, +        eRequestTypeVersion, +        eRequestTypeMaxBytes, +        eRequestTypeReadMemory, +        eRequestTypeWriteMemory, +        eRequestTypeReadRegisters, +        eRequestTypeWriteRegisters, +        eRequestTypeLoad, +        eRequestTypeImagePath, +        eRequestTypeSuspend, +        eRequestTypeResume, +        eRequestTypeException, +        eRequestTypeTermination, +        eRequestTypeBreakpointSet, +        eRequestTypeBreakpointRemove, +        eRequestTypeRegions, +        eRequestTypeReattach, +        eRequestTypeHostReboot, +        eRequestTypeReadMemory64, +        eRequestTypeWriteMemory64, +        eRequestTypeBreakpointSet64, +        eRequestTypeBreakpointRemove64, +        eRequestTypeKernelVersion +    } RequestType; + +    typedef enum  +    { +        eErrorSuccess = 0, +        eErrorAlreadyConnected, +        eErrorPacketToBig, +        eErrorInvalidRegisterFlavor, +        eErrorUnimplemented +    } ErrorType; +     +    typedef enum +    { +        ePacketTypeRequest  = 0u, +        ePacketTypeReply    = 1u +    } PacketType;      //------------------------------------------------------------------      // Constructors and Destructors      //------------------------------------------------------------------ @@ -41,34 +88,14 @@ public:      virtual      ~CommunicationKDP(); -    size_t -    SendPacket (const char *payload); - -    size_t -    SendPacket (const char *payload, -                size_t payload_length); - -    size_t -    SendPacket (lldb_private::StreamString &response); +    bool +    SendRequestPacket (const lldb_private::StreamString &request_packet);      // Wait for a packet within 'nsec' seconds      size_t      WaitForPacketWithTimeoutMicroSeconds (StringExtractor &response,                                            uint32_t usec); -    char -    GetAck (); - -    size_t -    SendAck (); - -    size_t -    SendNack (); - -    char -    CalculcateChecksum (const char *payload, -                        size_t payload_length); -      bool      GetSequenceMutex(lldb_private::Mutex::Locker& locker); @@ -82,12 +109,6 @@ public:          return m_public_is_running.GetValue();      } -    bool -    GetSendAcks () -    { -        return m_send_acks; -    } -      //------------------------------------------------------------------      // Set the global packet timeout.      // @@ -119,12 +140,19 @@ public:                               lldb_private::ProcessLaunchInfo &launch_info);  +    ErrorType +    Connect (uint16_t reply_port,  +             uint16_t exc_port,  +             const char *greeting); + +    ErrorType +    Disconnect (); +  protected:      typedef std::list<std::string> packet_collection; -    size_t -    SendPacketNoLock (const char *payload,  -                      size_t payload_length); +    bool +    SendRequestPacketNoLock (const lldb_private::StreamString &request_packet);      size_t      WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractor &response,  @@ -133,6 +161,10 @@ protected:      bool      WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr); +    void +    MakeRequestPacketHeader (RequestType request_type,  +                             lldb_private::StreamString &request_packet); +      //------------------------------------------------------------------      // Classes that inherit from CommunicationKDP can see and modify these      //------------------------------------------------------------------ @@ -140,8 +172,9 @@ protected:      lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time      lldb_private::Predicate<bool> m_public_is_running;      lldb_private::Predicate<bool> m_private_is_running; -    bool m_send_acks; - +    uint32_t m_session_key; +    uint8_t m_request_sequence_id; +    uint8_t m_exception_sequence_id;  private:      //------------------------------------------------------------------      // For CommunicationKDP only diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 9ae965ec84f..d7ec4b7ab34 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -16,6 +16,7 @@  #include "lldb/Core/PluginManager.h"  #include "lldb/Core/State.h"  #include "lldb/Host/Host.h" +#include "lldb/Target/Target.h"  // Project includes  #include "ProcessKDP.h" @@ -414,7 +415,7 @@ ProcessKDP::DoDetach()      m_thread_list.DiscardThreadPlans(); -    size_t response_size = m_comm.SendPacket ("D", 1); +    size_t response_size = m_comm.Disconnect ();      if (log)      {          if (response_size) | 

