remote_gdb.hh revision 12125:0066d9926c1a
1/*
2 * Copyright 2015 LabWare
3 * Copyright 2014 Google, Inc.
4 * Copyright (c) 2002-2005 The Regents of The University of Michigan
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met: redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer;
11 * redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution;
14 * neither the name of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Authors: Nathan Binkert
31 *          Boris Shingarov
32 */
33
34#ifndef __REMOTE_GDB_HH__
35#define __REMOTE_GDB_HH__
36
37#include <sys/signal.h>
38
39#include <exception>
40#include <map>
41#include <string>
42
43#include "arch/types.hh"
44#include "base/intmath.hh"
45#include "base/pollevent.hh"
46#include "base/socket.hh"
47#include "cpu/pc_event.hh"
48
49class System;
50class ThreadContext;
51
52class GDBListener;
53
54class BaseRemoteGDB;
55
56struct GdbCommand
57{
58  public:
59    struct Context
60    {
61        const GdbCommand *cmd;
62        char cmd_byte;
63        int type;
64        char *data;
65        int len;
66    };
67
68    typedef bool (BaseRemoteGDB::*Func)(Context &ctx);
69
70    const char * const name;
71    const Func func;
72
73    GdbCommand(const char *_name, Func _func) : name(_name), func(_func)
74    {}
75};
76
77class BaseRemoteGDB
78{
79  private:
80    friend void debugger();
81    friend class GDBListener;
82
83  protected:
84    /// Exception to throw when the connection to the client is broken.
85    struct BadClient
86    {
87        const char *warning;
88        BadClient(const char *_warning=NULL) : warning(_warning)
89        {}
90    };
91    /// Exception to throw when an error needs to be reported to the client.
92    struct CmdError
93    {
94        std::string error;
95        CmdError(std::string _error) : error(_error)
96        {}
97    };
98    /// Exception to throw when something isn't supported.
99    class Unsupported {};
100
101    // Helper functions
102  protected:
103    int digit2i(char);
104    char i2digit(int);
105    Addr hex2i(const char **);
106    // Address formats, break types, and gdb commands may change
107    // between architectures, so they're defined as virtual
108    // functions.
109    virtual void mem2hex(char *, const char *, int);
110    virtual const char * hex2mem(char *, const char *, int);
111    virtual const char * break_type(char c);
112
113  protected:
114    static std::map<char, GdbCommand> command_map;
115
116    bool cmd_unsupported(GdbCommand::Context &ctx);
117
118    bool cmd_signal(GdbCommand::Context &ctx);
119    bool cmd_cont(GdbCommand::Context &ctx);
120    bool cmd_async_cont(GdbCommand::Context &ctx);
121    bool cmd_detach(GdbCommand::Context &ctx);
122    bool cmd_reg_r(GdbCommand::Context &ctx);
123    bool cmd_reg_w(GdbCommand::Context &ctx);
124    bool cmd_set_thread(GdbCommand::Context &ctx);
125    bool cmd_mem_r(GdbCommand::Context &ctx);
126    bool cmd_mem_w(GdbCommand::Context &ctx);
127    bool cmd_query_var(GdbCommand::Context &ctx);
128    bool cmd_step(GdbCommand::Context &ctx);
129    bool cmd_async_step(GdbCommand::Context &ctx);
130    bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx);
131    bool cmd_set_hw_bkpt(GdbCommand::Context &ctx);
132
133  protected:
134    class InputEvent : public PollEvent
135    {
136      protected:
137        BaseRemoteGDB *gdb;
138
139      public:
140        InputEvent(BaseRemoteGDB *g, int fd, int e);
141        void process(int revent);
142    };
143
144    class TrapEvent : public Event
145    {
146      protected:
147        int _type;
148        BaseRemoteGDB *gdb;
149
150      public:
151        TrapEvent(BaseRemoteGDB *g) : gdb(g)
152        {}
153
154        void type(int t) { _type = t; }
155        void process();
156    };
157
158    friend class InputEvent;
159    InputEvent *inputEvent;
160    TrapEvent trapEvent;
161    GDBListener *listener;
162    int number;
163
164  protected:
165    // The socket commands come in through
166    int fd;
167
168  protected:
169    bool active;
170    bool attached;
171
172    System *system;
173    ThreadContext *context;
174
175  protected:
176    /**
177     * Concrete subclasses of this abstract class represent how the
178     * register values are transmitted on the wire.  Usually each
179     * architecture should define one subclass, but there can be more
180     * if there is more than one possible wire format.  For example,
181     * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache.
182     */
183    class BaseGdbRegCache
184    {
185      public:
186
187        /**
188         * Return the pointer to the raw bytes buffer containing the
189         * register values.  Each byte of this buffer is literally
190         * encoded as two hex digits in the g or G RSP packet.
191         */
192        virtual char *data() const = 0;
193
194        /**
195         * Return the size of the raw buffer, in bytes
196         * (i.e., half of the number of digits in the g/G packet).
197         */
198        virtual size_t size() const = 0;
199
200        /**
201         * Fill the raw buffer from the registers in the ThreadContext.
202         */
203        virtual void getRegs(ThreadContext*) = 0;
204
205        /**
206         * Set the ThreadContext's registers from the values
207         * in the raw buffer.
208         */
209        virtual void setRegs(ThreadContext*) const = 0;
210
211        /**
212         * Return the name to use in places like DPRINTF.
213         * Having each concrete superclass redefine this member
214         * is useful in situations where the class of the regCache
215         * can change on the fly.
216         */
217        virtual const std::string name() const = 0;
218
219        BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g)
220        {}
221        virtual ~BaseGdbRegCache()
222        {}
223
224      protected:
225        BaseRemoteGDB *gdb;
226    };
227
228    BaseGdbRegCache *regCachePtr;
229
230  protected:
231    uint8_t getbyte();
232    void putbyte(uint8_t b);
233
234    int recv(char *data, int len);
235    void send(const char *data);
236
237  protected:
238    // Machine memory
239    virtual bool read(Addr addr, size_t size, char *data);
240    virtual bool write(Addr addr, size_t size, const char *data);
241
242    template <class T> T read(Addr addr);
243    template <class T> void write(Addr addr, T data);
244
245  public:
246    BaseRemoteGDB(System *system, ThreadContext *context);
247    virtual ~BaseRemoteGDB();
248    virtual BaseGdbRegCache *gdbRegs() = 0;
249
250    void replaceThreadContext(ThreadContext *tc) { context = tc; }
251
252    void attach(int fd);
253    void detach();
254    bool isattached();
255
256    virtual bool acc(Addr addr, size_t len) = 0;
257    bool trap(int type);
258    virtual bool breakpoint()
259    {
260        return trap(SIGTRAP);
261    }
262
263    void processSingleStepEvent();
264    EventFunctionWrapper singleStepEvent;
265
266    void clearSingleStep();
267    void setSingleStep();
268
269    PCEventQueue *getPcEventQueue();
270    EventQueue *getComInstEventQueue();
271
272    /// Schedule an event which will be triggered "delta" instructions later.
273    void scheduleInstCommitEvent(Event *ev, int delta);
274    /// Deschedule an instruction count based event.
275    void descheduleInstCommitEvent(Event *ev);
276
277  protected:
278    virtual bool checkBpLen(size_t len);
279
280    class HardBreakpoint : public PCEvent
281    {
282      private:
283        BaseRemoteGDB *gdb;
284
285      public:
286        int refcount;
287
288      public:
289        HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr);
290        const std::string name() const { return gdb->name() + ".hwbkpt"; }
291
292        virtual void process(ThreadContext *tc);
293    };
294    friend class HardBreakpoint;
295
296    typedef std::map<Addr, HardBreakpoint *> break_map_t;
297    typedef break_map_t::iterator break_iter_t;
298    break_map_t hardBreakMap;
299
300    void insertSoftBreak(Addr addr, size_t len);
301    void removeSoftBreak(Addr addr, size_t len);
302    virtual void insertHardBreak(Addr addr, size_t len);
303    void removeHardBreak(Addr addr, size_t len);
304
305  protected:
306    void clearTempBreakpoint(Addr &bkpt);
307    void setTempBreakpoint(Addr bkpt);
308
309  public:
310    std::string name();
311};
312
313template <class T>
314inline T
315BaseRemoteGDB::read(Addr addr)
316{
317    T temp;
318    read(addr, sizeof(T), (char *)&temp);
319    return temp;
320}
321
322template <class T>
323inline void
324BaseRemoteGDB::write(Addr addr, T data)
325{ write(addr, sizeof(T), (const char *)&data); }
326
327class GDBListener
328{
329  protected:
330    class InputEvent : public PollEvent
331    {
332      protected:
333        GDBListener *listener;
334
335      public:
336        InputEvent(GDBListener *l, int fd, int e);
337        void process(int revent);
338    };
339
340    friend class InputEvent;
341    InputEvent *inputEvent;
342
343  protected:
344    ListenSocket listener;
345    BaseRemoteGDB *gdb;
346    int port;
347
348  public:
349    GDBListener(BaseRemoteGDB *g, int p);
350    ~GDBListener();
351
352    void accept();
353    void listen();
354    std::string name();
355
356    int getPort() const;
357};
358
359#endif /* __REMOTE_GDB_H__ */
360