summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
blob: 051fa445ff16b9aaf29238e03dba3d7763fd8dba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
//===-- GDBRemoteCommunication.h --------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_GDBRemoteCommunication_h_
#define liblldb_GDBRemoteCommunication_h_

// C Includes
// C++ Includes
#include <list>
#include <string>

// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Listener.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"

#include "StringExtractorGDBRemote.h"

class ProcessGDBRemote;

class GDBRemoteCommunication :
    public lldb_private::Communication
{
public:
    //------------------------------------------------------------------
    // Constructors and Destructors
    //------------------------------------------------------------------
    GDBRemoteCommunication();

    virtual
    ~GDBRemoteCommunication();

    size_t
    SendPacket (const char *payload);

    size_t
    SendPacket (const char *payload,
                size_t payload_length);

    size_t
    SendPacketAndWaitForResponse (const char *send_payload,
                                  StringExtractorGDBRemote &response,
                                  uint32_t timeout_seconds,
                                  bool send_async);

    size_t
    SendPacketAndWaitForResponse (const char *send_payload,
                                  size_t send_length,
                                  StringExtractorGDBRemote &response,
                                  uint32_t timeout_seconds,
                                  bool send_async);

    lldb::StateType
    SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process,
                                          const char *packet_payload,
                                          size_t packet_length,
                                          StringExtractorGDBRemote &response);

    // Wait for a packet within 'nsec' seconds
    size_t
    WaitForPacket (StringExtractorGDBRemote &response,
                   uint32_t nsec);

    // Wait for a packet with an absolute timeout time. If 'timeout' is NULL
    // wait indefinitely.
    size_t
    WaitForPacket (StringExtractorGDBRemote &response,
                   lldb_private::TimeValue* timeout);

    char
    GetAck (uint32_t timeout_seconds);

    size_t
    SendAck (char ack_char);

    char
    CalculcateChecksum (const char *payload,
                        size_t payload_length);

    void
    SetAckMode (bool enabled)
    {
        m_send_acks = enabled;
    }

    bool
    SendAsyncSignal (int signo);

    bool
    SendInterrupt (uint32_t seconds_to_wait_for_stop, bool *timed_out = NULL);

    bool
    GetSequenceMutex(lldb_private::Mutex::Locker& locker);

    //------------------------------------------------------------------
    // Communication overrides
    //------------------------------------------------------------------
    virtual void
    AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast);


    lldb::pid_t
    GetCurrentProcessID (uint32_t timeout_seconds);

    bool
    GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str);

    //------------------------------------------------------------------
    /// Sends a GDB remote protocol 'A' packet that delivers program
    /// arguments to the remote server.
    ///
    /// @param[in] argv
    ///     A NULL terminated array of const C strings to use as the
    ///     arguments.
    ///
    /// @param[in] timeout_seconds
    ///     The number of seconds to wait for a response from the remote
    ///     server.
    ///
    /// @return
    ///     Zero if the response was "OK", a positive value if the
    ///     the response was "Exx" where xx are two hex digits, or
    ///     -1 if the call is unsupported or any other unexpected
    ///     response was received.
    //------------------------------------------------------------------
    int
    SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds);

    //------------------------------------------------------------------
    /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
    /// environment that will get used when launching an application
    /// in conjunction with the 'A' packet. This function can be called
    /// multiple times in a row in order to pass on the desired
    /// environment that the inferior should be launched with.
    ///
    /// @param[in] name_equal_value
    ///     A NULL terminated C string that contains a single enironment
    ///     in the format "NAME=VALUE".
    ///
    /// @param[in] timeout_seconds
    ///     The number of seconds to wait for a response from the remote
    ///     server.
    ///
    /// @return
    ///     Zero if the response was "OK", a positive value if the
    ///     the response was "Exx" where xx are two hex digits, or
    ///     -1 if the call is unsupported or any other unexpected
    ///     response was received.
    //------------------------------------------------------------------
    int
    SendEnvironmentPacket (char const *name_equal_value,
                           uint32_t timeout_seconds);

    //------------------------------------------------------------------
    /// Sends a "vAttach:PID" where PID is in hex. 
    ///
    /// @param[in] pid
    ///     A process ID for the remote gdb server to attach to.
    ///
    /// @param[in] timeout_seconds
    ///     The number of seconds to wait for a response from the remote
    ///     server.
    ///
    /// @param[out] response
    ///     The response received from the gdb server. If the return
    ///     value is zero, \a response will contain a stop reply 
    ///     packet.
    ///
    /// @return
    ///     Zero if the attach was successful, or an error indicating
    ///     an error code.
    //------------------------------------------------------------------
    int
    SendAttach (lldb::pid_t pid, 
                uint32_t timeout_seconds, 
                StringExtractorGDBRemote& response);


    lldb::addr_t
    AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds);

    bool
    DeallocateMemory (lldb::addr_t addr, uint32_t timeout_seconds);

    bool
    IsRunning() const
    {
        return m_is_running.GetValue();
    }
    
    bool
    GetHostInfo (uint32_t timeout_seconds);

    bool 
    HostInfoIsValid () const
    {
        return m_pointer_byte_size != 0;
    }

    const lldb_private::ArchSpec &
    GetHostArchitecture ();
    
    const lldb_private::ConstString &
    GetOSString ();
    
    const lldb_private::ConstString &
    GetVendorString();
    
    lldb::ByteOrder
    GetByteOrder ();

    uint32_t
    GetAddressByteSize ();

protected:
    typedef std::list<std::string> packet_collection;

    size_t
    SendPacketNoLock (const char *payload, 
                      size_t payload_length);

    size_t
    WaitForPacketNoLock (StringExtractorGDBRemote &response, 
                         lldb_private::TimeValue* timeout_time_ptr);

    //------------------------------------------------------------------
    // Classes that inherit from GDBRemoteCommunication can see and modify these
    //------------------------------------------------------------------
    bool m_send_acks;
    lldb_private::Listener m_rx_packet_listener;
    lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
    lldb_private::Predicate<bool> m_is_running;

    // If we need to send a packet while the target is running, the m_async_XXX
    // member variables take care of making this happen.
    lldb_private::Mutex m_async_mutex;
    lldb_private::Predicate<bool> m_async_packet_predicate;
    std::string m_async_packet;
    StringExtractorGDBRemote m_async_response;
    uint32_t m_async_timeout;
    int m_async_signal; // We were asked to deliver a signal to the inferior process.
    
    lldb_private::ArchSpec m_arch;      // Results from the qHostInfo call
    uint32_t m_cpusubtype;              // Results from the qHostInfo call
    lldb_private::ConstString m_os;     // Results from the qHostInfo call
    lldb_private::ConstString m_vendor; // Results from the qHostInfo call
    lldb::ByteOrder m_byte_order;       // Results from the qHostInfo call
    uint32_t m_pointer_byte_size;       // Results from the qHostInfo call
    
    
private:
    //------------------------------------------------------------------
    // For GDBRemoteCommunication only
    //------------------------------------------------------------------
    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
};

#endif  // liblldb_GDBRemoteCommunication_h_
OpenPOWER on IntegriCloud