remote_gdb.hh revision 1910
1/*
2 * Copyright (c) 2002-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __REMOTE_GDB_HH__
30#define __REMOTE_GDB_HH__
31
32#include <map>
33
34#include "base/kgdb.h"
35#include "cpu/pc_event.hh"
36#include "base/pollevent.hh"
37#include "base/socket.hh"
38
39class System;
40class ExecContext;
41class PhysicalMemory;
42
43class GDBListener;
44class RemoteGDB
45{
46  private:
47    friend void debugger();
48    friend class GDBListener;
49
50  protected:
51    class Event : public PollEvent
52    {
53      protected:
54        RemoteGDB *gdb;
55
56      public:
57        Event(RemoteGDB *g, int fd, int e);
58        void process(int revent);
59    };
60
61    friend class Event;
62    Event *event;
63    GDBListener *listener;
64    int number;
65
66  protected:
67    int fd;
68    uint64_t gdbregs[KGDB_NUMREGS];
69
70  protected:
71#ifdef notyet
72    label_t recover;
73#endif
74    bool active;
75    bool attached;
76
77    System *system;
78    PhysicalMemory *pmem;
79    ExecContext *context;
80
81  protected:
82    uint8_t getbyte();
83    void putbyte(uint8_t b);
84
85    int recv(char *data, int len);
86    void send(const char *data);
87
88  protected:
89    // Machine memory
90    bool read(Addr addr, size_t size, char *data);
91    bool write(Addr addr, size_t size, const char *data);
92
93    template <class T> T read(Addr addr);
94    template <class T> void write(Addr addr, T data);
95
96  public:
97    RemoteGDB(System *system, ExecContext *context);
98    ~RemoteGDB();
99
100    void replaceExecContext(ExecContext *xc) { context = xc; }
101
102    void attach(int fd);
103    void detach();
104    bool isattached();
105
106    bool acc(Addr addr, size_t len);
107    static int signal(int type);
108    bool trap(int type);
109
110  protected:
111    void getregs();
112    void setregs();
113
114    void clearSingleStep();
115    void setSingleStep();
116
117    PCEventQueue *getPcEventQueue();
118
119  protected:
120    class HardBreakpoint : public PCEvent
121    {
122      private:
123        RemoteGDB *gdb;
124
125      public:
126        int refcount;
127
128      public:
129        HardBreakpoint(RemoteGDB *_gdb, Addr addr);
130        std::string name() { return gdb->name() + ".hwbkpt"; }
131
132        virtual void process(ExecContext *xc);
133    };
134    friend class HardBreakpoint;
135
136    typedef std::map<Addr, HardBreakpoint *> break_map_t;
137    typedef break_map_t::iterator break_iter_t;
138    break_map_t hardBreakMap;
139
140    bool insertSoftBreak(Addr addr, size_t len);
141    bool removeSoftBreak(Addr addr, size_t len);
142    bool insertHardBreak(Addr addr, size_t len);
143    bool removeHardBreak(Addr addr, size_t len);
144
145  protected:
146    struct TempBreakpoint {
147        Addr	address;		// set here
148        MachInst	bkpt_inst;		// saved instruction at bkpt
149        int		init_count;		// number of times to skip bkpt
150        int		count;			// current count
151    };
152
153    TempBreakpoint notTakenBkpt;
154    TempBreakpoint takenBkpt;
155
156    void clearTempBreakpoint(TempBreakpoint &bkpt);
157    void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr);
158
159  public:
160    std::string name();
161};
162
163template <class T>
164inline T
165RemoteGDB::read(Addr addr)
166{
167    T temp;
168    read(addr, sizeof(T), (char *)&temp);
169    return temp;
170}
171
172template <class T>
173inline void
174RemoteGDB::write(Addr addr, T data)
175{ write(addr, sizeof(T), (const char *)&data); }
176
177class GDBListener
178{
179  protected:
180    class Event : public PollEvent
181    {
182      protected:
183        GDBListener *listener;
184
185      public:
186        Event(GDBListener *l, int fd, int e);
187        void process(int revent);
188    };
189
190    friend class Event;
191    Event *event;
192
193  protected:
194    ListenSocket listener;
195    RemoteGDB *gdb;
196    int port;
197
198  public:
199    GDBListener(RemoteGDB *g, int p);
200    ~GDBListener();
201
202    void accept();
203    void listen();
204    std::string name();
205};
206
207#endif /* __REMOTE_GDB_H__ */
208