remote_gdb.hh revision 2632:1bb2f91485ea
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  protected:
47    typedef TheISA::MachInst MachInst;
48  private:
49    friend void debugger();
50    friend class GDBListener;
51
52  protected:
53    class Event : public PollEvent
54    {
55      protected:
56        RemoteGDB *gdb;
57
58      public:
59        Event(RemoteGDB *g, int fd, int e);
60        void process(int revent);
61    };
62
63    friend class Event;
64    Event *event;
65    GDBListener *listener;
66    int number;
67
68  protected:
69    int fd;
70    uint64_t gdbregs[KGDB_NUMREGS];
71
72  protected:
73#ifdef notyet
74    label_t recover;
75#endif
76    bool active;
77    bool attached;
78
79    System *system;
80    PhysicalMemory *pmem;
81    ExecContext *context;
82
83  protected:
84    uint8_t getbyte();
85    void putbyte(uint8_t b);
86
87    int recv(char *data, int len);
88    void send(const char *data);
89
90  protected:
91    // Machine memory
92    bool read(Addr addr, size_t size, char *data);
93    bool write(Addr addr, size_t size, const char *data);
94
95    template <class T> T read(Addr addr);
96    template <class T> void write(Addr addr, T data);
97
98  public:
99    RemoteGDB(System *system, ExecContext *context);
100    ~RemoteGDB();
101
102    void replaceExecContext(ExecContext *xc) { context = xc; }
103
104    void attach(int fd);
105    void detach();
106    bool isattached();
107
108    bool acc(Addr addr, size_t len);
109    static int signal(int type);
110    bool trap(int type);
111
112  protected:
113    void getregs();
114    void setregs();
115
116    void clearSingleStep();
117    void setSingleStep();
118
119    PCEventQueue *getPcEventQueue();
120
121  protected:
122    class HardBreakpoint : public PCEvent
123    {
124      private:
125        RemoteGDB *gdb;
126
127      public:
128        int refcount;
129
130      public:
131        HardBreakpoint(RemoteGDB *_gdb, Addr addr);
132        std::string name() { return gdb->name() + ".hwbkpt"; }
133
134        virtual void process(ExecContext *xc);
135    };
136    friend class HardBreakpoint;
137
138    typedef std::map<Addr, HardBreakpoint *> break_map_t;
139    typedef break_map_t::iterator break_iter_t;
140    break_map_t hardBreakMap;
141
142    bool insertSoftBreak(Addr addr, size_t len);
143    bool removeSoftBreak(Addr addr, size_t len);
144    bool insertHardBreak(Addr addr, size_t len);
145    bool removeHardBreak(Addr addr, size_t len);
146
147  protected:
148    struct TempBreakpoint {
149        Addr	address;		// set here
150        MachInst	bkpt_inst;		// saved instruction at bkpt
151        int		init_count;		// number of times to skip bkpt
152        int		count;			// current count
153    };
154
155    TempBreakpoint notTakenBkpt;
156    TempBreakpoint takenBkpt;
157
158    void clearTempBreakpoint(TempBreakpoint &bkpt);
159    void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr);
160
161  public:
162    std::string name();
163};
164
165template <class T>
166inline T
167RemoteGDB::read(Addr addr)
168{
169    T temp;
170    read(addr, sizeof(T), (char *)&temp);
171    return temp;
172}
173
174template <class T>
175inline void
176RemoteGDB::write(Addr addr, T data)
177{ write(addr, sizeof(T), (const char *)&data); }
178
179class GDBListener
180{
181  protected:
182    class Event : public PollEvent
183    {
184      protected:
185        GDBListener *listener;
186
187      public:
188        Event(GDBListener *l, int fd, int e);
189        void process(int revent);
190    };
191
192    friend class Event;
193    Event *event;
194
195  protected:
196    ListenSocket listener;
197    RemoteGDB *gdb;
198    int port;
199
200  public:
201    GDBListener(RemoteGDB *g, int p);
202    ~GDBListener();
203
204    void accept();
205    void listen();
206    std::string name();
207};
208
209#endif /* __REMOTE_GDB_H__ */
210