Home | History | Annotate | Download | only in MacOSX-Kernel
      1 //===-- CommunicationKDP.h --------------------------------------*- 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 #ifndef liblldb_CommunicationKDP_h_
     11 #define liblldb_CommunicationKDP_h_
     12 
     13 // C Includes
     14 // C++ Includes
     15 #include <list>
     16 #include <string>
     17 
     18 // Other libraries and framework includes
     19 // Project includes
     20 #include "lldb/lldb-private.h"
     21 #include "lldb/Core/Communication.h"
     22 #include "lldb/Core/Listener.h"
     23 #include "lldb/Core/StreamBuffer.h"
     24 #include "lldb/Host/Mutex.h"
     25 #include "lldb/Host/Predicate.h"
     26 #include "lldb/Host/TimeValue.h"
     27 
     28 class CommunicationKDP : public lldb_private::Communication
     29 {
     30 public:
     31     enum
     32     {
     33         eBroadcastBitRunPacketSent = kLoUserBroadcastBit
     34     };
     35 
     36     const static uint32_t kMaxPacketSize = 1200;
     37     const static uint32_t kMaxDataSize = 1024;
     38     typedef lldb_private::StreamBuffer<1024> PacketStreamType;
     39     typedef enum
     40     {
     41         KDP_CONNECT = 0u,
     42         KDP_DISCONNECT,
     43         KDP_HOSTINFO,
     44         KDP_VERSION,
     45         KDP_MAXBYTES,
     46         KDP_READMEM,
     47         KDP_WRITEMEM,
     48         KDP_READREGS,
     49         KDP_WRITEREGS,
     50         KDP_LOAD,
     51         KDP_IMAGEPATH,
     52         KDP_SUSPEND,
     53         KDP_RESUMECPUS,
     54         KDP_EXCEPTION,
     55         KDP_TERMINATION,
     56         KDP_BREAKPOINT_SET,
     57         KDP_BREAKPOINT_REMOVE,
     58         KDP_REGIONS,
     59         KDP_REATTACH,
     60         KDP_HOSTREBOOT,
     61         KDP_READMEM64,
     62         KDP_WRITEMEM64,
     63         KDP_BREAKPOINT_SET64,
     64         KDP_BREAKPOINT_REMOVE64,
     65         KDP_KERNELVERSION,
     66         KDP_READPHYSMEM64,
     67         KDP_WRITEPHYSMEM64,
     68         KDP_READIOPORT,
     69         KDP_WRITEIOPORT,
     70         KDP_READMSR64,
     71         KDP_WRITEMSR64,
     72         KDP_DUMPINFO
     73     } CommandType;
     74 
     75     enum
     76     {
     77         KDP_FEATURE_BP = (1u << 0)
     78     };
     79 
     80     typedef enum
     81     {
     82         KDP_PROTERR_SUCCESS = 0,
     83         KDP_PROTERR_ALREADY_CONNECTED,
     84         KDP_PROTERR_BAD_NBYTES,
     85         KDP_PROTERR_BADFLAVOR
     86     } KDPError;
     87 
     88     typedef enum
     89     {
     90         ePacketTypeRequest  = 0x00u,
     91         ePacketTypeReply    = 0x80u,
     92         ePacketTypeMask     = 0x80u,
     93         eCommandTypeMask    = 0x7fu
     94     } PacketType;
     95     //------------------------------------------------------------------
     96     // Constructors and Destructors
     97     //------------------------------------------------------------------
     98     CommunicationKDP (const char *comm_name);
     99 
    100     virtual
    101     ~CommunicationKDP();
    102 
    103     bool
    104     SendRequestPacket (const PacketStreamType &request_packet);
    105 
    106     // Wait for a packet within 'nsec' seconds
    107     size_t
    108     WaitForPacketWithTimeoutMicroSeconds (lldb_private::DataExtractor &response,
    109                                           uint32_t usec);
    110 
    111     bool
    112     GetSequenceMutex(lldb_private::Mutex::Locker& locker);
    113 
    114     bool
    115     CheckForPacket (const uint8_t *src,
    116                     size_t src_len,
    117                     lldb_private::DataExtractor &packet);
    118     bool
    119     IsRunning() const
    120     {
    121         return m_is_running.GetValue();
    122     }
    123 
    124     //------------------------------------------------------------------
    125     // Set the global packet timeout.
    126     //
    127     // For clients, this is the timeout that gets used when sending
    128     // packets and waiting for responses. For servers, this might not
    129     // get used, and if it doesn't this should be moved to the
    130     // CommunicationKDPClient.
    131     //------------------------------------------------------------------
    132     uint32_t
    133     SetPacketTimeout (uint32_t packet_timeout)
    134     {
    135         const uint32_t old_packet_timeout = m_packet_timeout;
    136         m_packet_timeout = packet_timeout;
    137         return old_packet_timeout;
    138     }
    139 
    140     uint32_t
    141     GetPacketTimeoutInMicroSeconds () const
    142     {
    143         return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
    144     }
    145     //------------------------------------------------------------------
    146     // Start a debugserver instance on the current host using the
    147     // supplied connection URL.
    148     //------------------------------------------------------------------
    149     lldb_private::Error
    150     StartDebugserverProcess (const char *connect_url,
    151                              const char *unix_socket_name,
    152                              lldb_private::ProcessLaunchInfo &launch_info);
    153 
    154 
    155     //------------------------------------------------------------------
    156     // Public Request Packets
    157     //------------------------------------------------------------------
    158     bool
    159     SendRequestConnect (uint16_t reply_port,
    160                         uint16_t exc_port,
    161                         const char *greeting);
    162 
    163     bool
    164     SendRequestReattach (uint16_t reply_port);
    165 
    166     bool
    167     SendRequestDisconnect ();
    168 
    169     uint32_t
    170     SendRequestReadMemory (lldb::addr_t addr,
    171                            void *dst,
    172                            uint32_t dst_size,
    173                            lldb_private::Error &error);
    174 
    175     uint32_t
    176     SendRequestWriteMemory (lldb::addr_t addr,
    177                             const void *src,
    178                             uint32_t src_len,
    179                             lldb_private::Error &error);
    180 
    181     bool
    182     SendRawRequest (uint8_t command_byte,
    183                     const void *src,
    184                     uint32_t src_len,
    185                     lldb_private::DataExtractor &reply,
    186                     lldb_private::Error &error);
    187 
    188     uint32_t
    189     SendRequestReadRegisters (uint32_t cpu,
    190                               uint32_t flavor,
    191                               void *dst,
    192                               uint32_t dst_size,
    193                               lldb_private::Error &error);
    194 
    195     uint32_t
    196     SendRequestWriteRegisters (uint32_t cpu,
    197                                uint32_t flavor,
    198                                const void *src,
    199                                uint32_t src_size,
    200                                lldb_private::Error &error);
    201 
    202     const char *
    203     GetKernelVersion ();
    204 
    205     // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
    206     // const char *
    207     // GetImagePath ();
    208 
    209     uint32_t
    210     GetVersion ();
    211 
    212     uint32_t
    213     GetFeatureFlags ();
    214 
    215     bool
    216     LocalBreakpointsAreSupported ()
    217     {
    218         return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
    219     }
    220 
    221     uint32_t
    222     GetCPUMask ();
    223 
    224     uint32_t
    225     GetCPUType ();
    226 
    227     uint32_t
    228     GetCPUSubtype ();
    229 
    230     lldb_private::UUID
    231     GetUUID ();
    232 
    233     bool
    234     RemoteIsEFI ();
    235 
    236     bool
    237     RemoteIsDarwinKernel ();
    238 
    239     lldb::addr_t
    240     GetLoadAddress ();
    241 
    242     bool
    243     SendRequestResume ();
    244 
    245     bool
    246     SendRequestSuspend ();
    247 
    248     bool
    249     SendRequestBreakpoint (bool set, lldb::addr_t addr);
    250 
    251 protected:
    252 
    253     bool
    254     SendRequestPacketNoLock (const PacketStreamType &request_packet);
    255 
    256     size_t
    257     WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response,
    258                                                 uint32_t timeout_usec);
    259 
    260     bool
    261     WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
    262 
    263     void
    264     MakeRequestPacketHeader (CommandType request_type,
    265                              PacketStreamType &request_packet,
    266                              uint16_t request_length);
    267 
    268     //------------------------------------------------------------------
    269     // Protected Request Packets (use public accessors which will cache
    270     // results.
    271     //------------------------------------------------------------------
    272     bool
    273     SendRequestVersion ();
    274 
    275     bool
    276     SendRequestHostInfo ();
    277 
    278     bool
    279     SendRequestKernelVersion ();
    280 
    281     // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
    282     //bool
    283     //SendRequestImagePath ();
    284 
    285     void
    286     DumpPacket (lldb_private::Stream &s,
    287                 const void *data,
    288                 uint32_t data_len);
    289 
    290     void
    291     DumpPacket (lldb_private::Stream &s,
    292                 const lldb_private::DataExtractor& extractor);
    293 
    294     bool
    295     VersionIsValid() const
    296     {
    297         return m_kdp_version_version != 0;
    298     }
    299 
    300     bool
    301     HostInfoIsValid() const
    302     {
    303         return m_kdp_hostinfo_cpu_type != 0;
    304     }
    305 
    306     bool
    307     ExtractIsReply (uint8_t first_packet_byte) const
    308     {
    309         // TODO: handle big endian...
    310         return (first_packet_byte & ePacketTypeMask) != 0;
    311     }
    312 
    313     CommandType
    314     ExtractCommand (uint8_t first_packet_byte) const
    315     {
    316         // TODO: handle big endian...
    317         return (CommandType)(first_packet_byte & eCommandTypeMask);
    318     }
    319 
    320     static const char *
    321     GetCommandAsCString (uint8_t command);
    322 
    323     void
    324     ClearKDPSettings ();
    325 
    326     bool
    327     SendRequestAndGetReply (const CommandType command,
    328                             const PacketStreamType &request_packet,
    329                             lldb_private::DataExtractor &reply_packet);
    330     //------------------------------------------------------------------
    331     // Classes that inherit from CommunicationKDP can see and modify these
    332     //------------------------------------------------------------------
    333     uint32_t m_addr_byte_size;
    334     lldb::ByteOrder m_byte_order;
    335     uint32_t m_packet_timeout;
    336     lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
    337     lldb_private::Predicate<bool> m_is_running;
    338     uint32_t m_session_key;
    339     uint8_t m_request_sequence_id;
    340     uint8_t m_exception_sequence_id;
    341     uint32_t m_kdp_version_version;
    342     uint32_t m_kdp_version_feature;
    343     uint32_t m_kdp_hostinfo_cpu_mask;
    344     uint32_t m_kdp_hostinfo_cpu_type;
    345     uint32_t m_kdp_hostinfo_cpu_subtype;
    346     std::string m_kernel_version;
    347     //std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
    348     lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
    349 private:
    350     //------------------------------------------------------------------
    351     // For CommunicationKDP only
    352     //------------------------------------------------------------------
    353     DISALLOW_COPY_AND_ASSIGN (CommunicationKDP);
    354 };
    355 
    356 #endif  // liblldb_CommunicationKDP_h_
    357