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