remote_gdb.hh revision 11274:d9a0136ab8cc
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 <map>
40
41#include "arch/types.hh"
42#include "base/intmath.hh"
43#include "base/pollevent.hh"
44#include "base/socket.hh"
45#include "cpu/pc_event.hh"
46
47class System;
48class ThreadContext;
49
50class GDBListener;
51
52enum GDBCommands
53{
54    GDBSignal              = '?', // last signal
55    GDBSetBaud             = 'b', // set baud (depracated)
56    GDBSetBreak            = 'B', // set breakpoint (depracated)
57    GDBCont                = 'c', // resume
58    GDBAsyncCont           = 'C', // continue with signal
59    GDBDebug               = 'd', // toggle debug flags (deprecated)
60    GDBDetach              = 'D', // detach remote gdb
61    GDBRegR                = 'g', // read general registers
62    GDBRegW                = 'G', // write general registers
63    GDBSetThread           = 'H', // set thread
64    GDBCycleStep           = 'i', // step a single cycle
65    GDBSigCycleStep        = 'I', // signal then cycle step
66    GDBKill                = 'k', // kill program
67    GDBMemR                = 'm', // read memory
68    GDBMemW                = 'M', // write memory
69    GDBReadReg             = 'p', // read register
70    GDBSetReg              = 'P', // write register
71    GDBQueryVar            = 'q', // query variable
72    GDBSetVar              = 'Q', // set variable
73    GDBReset               = 'r', // reset system.  (Deprecated)
74    GDBStep                = 's', // step
75    GDBAsyncStep           = 'S', // signal and step
76    GDBThreadAlive         = 'T', // find out if the thread is alive
77    GDBTargetExit          = 'W', // target exited
78    GDBBinaryDload         = 'X', // write memory
79    GDBClrHwBkpt           = 'z', // remove breakpoint or watchpoint
80    GDBSetHwBkpt           = 'Z'  // insert breakpoint or watchpoint
81};
82
83const char GDBStart = '$';
84const char GDBEnd = '#';
85const char GDBGoodP = '+';
86const char GDBBadP = '-';
87
88const int GDBPacketBufLen = 1024;
89
90class BaseRemoteGDB
91{
92  private:
93    friend void debugger();
94    friend class GDBListener;
95
96    //Helper functions
97  protected:
98    int digit2i(char);
99    char i2digit(int);
100    Addr hex2i(const char **);
101    //Address formats, break types, and gdb commands may change
102    //between architectures, so they're defined as virtual
103    //functions.
104    virtual void mem2hex(char *, const char *, int);
105    virtual const char * hex2mem(char *, const char *, int);
106    virtual const char * break_type(char c);
107    virtual const char * gdb_command(char cmd);
108
109  protected:
110    class InputEvent : public PollEvent
111    {
112      protected:
113        BaseRemoteGDB *gdb;
114
115      public:
116        InputEvent(BaseRemoteGDB *g, int fd, int e);
117        void process(int revent);
118    };
119
120    class TrapEvent : public Event
121    {
122      protected:
123        int _type;
124        BaseRemoteGDB *gdb;
125
126      public:
127        TrapEvent(BaseRemoteGDB *g) : gdb(g)
128        {}
129
130        void type(int t) { _type = t; }
131        void process();
132    };
133
134    friend class InputEvent;
135    InputEvent *inputEvent;
136    TrapEvent trapEvent;
137    GDBListener *listener;
138    int number;
139
140  protected:
141    //The socket commands come in through
142    int fd;
143
144  protected:
145#ifdef notyet
146    label_t recover;
147#endif
148    bool active;
149    bool attached;
150
151    System *system;
152    ThreadContext *context;
153
154  protected:
155    /**
156     * Concrete subclasses of this abstract class represent how the
157     * register values are transmitted on the wire.  Usually each
158     * architecture should define one subclass, but there can be more
159     * if there is more than one possible wire format.  For example,
160     * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache.
161     */
162    class BaseGdbRegCache
163    {
164      public:
165
166        /**
167         * Return the pointer to the raw bytes buffer containing the
168         * register values.  Each byte of this buffer is literally
169         * encoded as two hex digits in the g or G RSP packet.
170         */
171        virtual char *data() const = 0;
172
173        /**
174         * Return the size of the raw buffer, in bytes
175         * (i.e., half of the number of digits in the g/G packet).
176         */
177        virtual size_t size() const = 0;
178
179        /**
180         * Fill the raw buffer from the registers in the ThreadContext.
181         */
182        virtual void getRegs(ThreadContext*) = 0;
183
184        /**
185         * Set the ThreadContext's registers from the values
186         * in the raw buffer.
187         */
188        virtual void setRegs(ThreadContext*) const = 0;
189
190        /**
191         * Return the name to use in places like DPRINTF.
192         * Having each concrete superclass redefine this member
193         * is useful in situations where the class of the regCache
194         * can change on the fly.
195         */
196        virtual const std::string name() const = 0;
197
198        BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g)
199        {}
200
201      protected:
202        BaseRemoteGDB *gdb;
203    };
204
205  protected:
206    uint8_t getbyte();
207    void putbyte(uint8_t b);
208
209    int recv(char *data, int len);
210    void send(const char *data);
211
212  protected:
213    // Machine memory
214    virtual bool read(Addr addr, size_t size, char *data);
215    virtual bool write(Addr addr, size_t size, const char *data);
216
217    template <class T> T read(Addr addr);
218    template <class T> void write(Addr addr, T data);
219
220  public:
221    BaseRemoteGDB(System *system, ThreadContext *context);
222    virtual ~BaseRemoteGDB();
223    virtual BaseGdbRegCache *gdbRegs() = 0;
224
225    void replaceThreadContext(ThreadContext *tc) { context = tc; }
226
227    void attach(int fd);
228    void detach();
229    bool isattached();
230
231    virtual bool acc(Addr addr, size_t len) = 0;
232    bool trap(int type);
233    virtual bool breakpoint()
234    {
235        return trap(SIGTRAP);
236    }
237
238  protected:
239    class SingleStepEvent : public Event
240    {
241      protected:
242        BaseRemoteGDB *gdb;
243
244      public:
245        SingleStepEvent(BaseRemoteGDB *g) : gdb(g)
246        {}
247
248        void process();
249    };
250
251    SingleStepEvent singleStepEvent;
252
253    void clearSingleStep();
254    void setSingleStep();
255
256    PCEventQueue *getPcEventQueue();
257    EventQueue *getComInstEventQueue();
258
259    /// Schedule an event which will be triggered "delta" instructions later.
260    void scheduleInstCommitEvent(Event *ev, int delta);
261    /// Deschedule an instruction count based event.
262    void descheduleInstCommitEvent(Event *ev);
263
264  protected:
265    virtual bool checkBpLen(size_t len);
266
267    class HardBreakpoint : public PCEvent
268    {
269      private:
270        BaseRemoteGDB *gdb;
271
272      public:
273        int refcount;
274
275      public:
276        HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr);
277        const std::string name() const { return gdb->name() + ".hwbkpt"; }
278
279        virtual void process(ThreadContext *tc);
280    };
281    friend class HardBreakpoint;
282
283    typedef std::map<Addr, HardBreakpoint *> break_map_t;
284    typedef break_map_t::iterator break_iter_t;
285    break_map_t hardBreakMap;
286
287    bool insertSoftBreak(Addr addr, size_t len);
288    bool removeSoftBreak(Addr addr, size_t len);
289    virtual bool insertHardBreak(Addr addr, size_t len);
290    bool removeHardBreak(Addr addr, size_t len);
291
292  protected:
293    void clearTempBreakpoint(Addr &bkpt);
294    void setTempBreakpoint(Addr bkpt);
295
296  public:
297    std::string name();
298};
299
300template <class T>
301inline T
302BaseRemoteGDB::read(Addr addr)
303{
304    T temp;
305    read(addr, sizeof(T), (char *)&temp);
306    return temp;
307}
308
309template <class T>
310inline void
311BaseRemoteGDB::write(Addr addr, T data)
312{ write(addr, sizeof(T), (const char *)&data); }
313
314class GDBListener
315{
316  protected:
317    class InputEvent : public PollEvent
318    {
319      protected:
320        GDBListener *listener;
321
322      public:
323        InputEvent(GDBListener *l, int fd, int e);
324        void process(int revent);
325    };
326
327    friend class InputEvent;
328    InputEvent *inputEvent;
329
330  protected:
331    ListenSocket listener;
332    BaseRemoteGDB *gdb;
333    int port;
334
335  public:
336    GDBListener(BaseRemoteGDB *g, int p);
337    ~GDBListener();
338
339    void accept();
340    void listen();
341    std::string name();
342};
343
344#endif /* __REMOTE_GDB_H__ */
345