remote_gdb.hh (11274:d9a0136ab8cc) remote_gdb.hh (12019:65939e37768a)
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:
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);
206 bool getbyte(uint8_t &b);
207 bool putbyte(uint8_t b);
208
209 int recv(char *data, int len);
208
209 int recv(char *data, int len);
210 void send(const char *data);
210 ssize_t 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__ */
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__ */