remote_gdb.hh (12031:46116545e745) remote_gdb.hh (12122:20512f6810d7)
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 <exception>
40#include <map>
41#include <string>
42
43#include "arch/types.hh"
44#include "base/intmath.hh"
45#include "base/pollevent.hh"
46#include "base/socket.hh"
47#include "cpu/pc_event.hh"
48
49class System;
50class ThreadContext;
51
52class GDBListener;
53
54class BaseRemoteGDB;
55
56struct GdbCommand
57{
58 public:
59 struct Context
60 {
61 const GdbCommand *cmd;
62 char cmd_byte;
63 int type;
64 char *data;
65 int len;
66 };
67
68 typedef bool (BaseRemoteGDB::*Func)(Context &ctx);
69
70 const char * const name;
71 const Func func;
72
73 GdbCommand(const char *_name, Func _func) : name(_name), func(_func)
74 {}
75};
76
77class BaseRemoteGDB
78{
79 private:
80 friend void debugger();
81 friend class GDBListener;
82
83 protected:
84 /// Exception to throw when the connection to the client is broken.
85 struct BadClient
86 {
87 const char *warning;
88 BadClient(const char *_warning=NULL) : warning(_warning)
89 {}
90 };
91 /// Exception to throw when an error needs to be reported to the client.
92 struct CmdError
93 {
94 std::string error;
95 CmdError(std::string _error) : error(_error)
96 {}
97 };
98 /// Exception to throw when something isn't supported.
99 class Unsupported {};
100
101 // Helper functions
102 protected:
103 int digit2i(char);
104 char i2digit(int);
105 Addr hex2i(const char **);
106 // Address formats, break types, and gdb commands may change
107 // between architectures, so they're defined as virtual
108 // functions.
109 virtual void mem2hex(char *, const char *, int);
110 virtual const char * hex2mem(char *, const char *, int);
111 virtual const char * break_type(char c);
112
113 protected:
114 static std::map<char, GdbCommand> command_map;
115
116 bool cmd_unsupported(GdbCommand::Context &ctx);
117
118 bool cmd_signal(GdbCommand::Context &ctx);
119 bool cmd_cont(GdbCommand::Context &ctx);
120 bool cmd_async_cont(GdbCommand::Context &ctx);
121 bool cmd_detach(GdbCommand::Context &ctx);
122 bool cmd_reg_r(GdbCommand::Context &ctx);
123 bool cmd_reg_w(GdbCommand::Context &ctx);
124 bool cmd_set_thread(GdbCommand::Context &ctx);
125 bool cmd_mem_r(GdbCommand::Context &ctx);
126 bool cmd_mem_w(GdbCommand::Context &ctx);
127 bool cmd_query_var(GdbCommand::Context &ctx);
128 bool cmd_step(GdbCommand::Context &ctx);
129 bool cmd_async_step(GdbCommand::Context &ctx);
130 bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx);
131 bool cmd_set_hw_bkpt(GdbCommand::Context &ctx);
132
133 protected:
134 class InputEvent : public PollEvent
135 {
136 protected:
137 BaseRemoteGDB *gdb;
138
139 public:
140 InputEvent(BaseRemoteGDB *g, int fd, int e);
141 void process(int revent);
142 };
143
144 class TrapEvent : public Event
145 {
146 protected:
147 int _type;
148 BaseRemoteGDB *gdb;
149
150 public:
151 TrapEvent(BaseRemoteGDB *g) : gdb(g)
152 {}
153
154 void type(int t) { _type = t; }
155 void process();
156 };
157
158 friend class InputEvent;
159 InputEvent *inputEvent;
160 TrapEvent trapEvent;
161 GDBListener *listener;
162 int number;
163
164 protected:
165 // The socket commands come in through
166 int fd;
167
168 protected:
169 bool active;
170 bool attached;
171
172 System *system;
173 ThreadContext *context;
174
175 protected:
176 /**
177 * Concrete subclasses of this abstract class represent how the
178 * register values are transmitted on the wire. Usually each
179 * architecture should define one subclass, but there can be more
180 * if there is more than one possible wire format. For example,
181 * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache.
182 */
183 class BaseGdbRegCache
184 {
185 public:
186
187 /**
188 * Return the pointer to the raw bytes buffer containing the
189 * register values. Each byte of this buffer is literally
190 * encoded as two hex digits in the g or G RSP packet.
191 */
192 virtual char *data() const = 0;
193
194 /**
195 * Return the size of the raw buffer, in bytes
196 * (i.e., half of the number of digits in the g/G packet).
197 */
198 virtual size_t size() const = 0;
199
200 /**
201 * Fill the raw buffer from the registers in the ThreadContext.
202 */
203 virtual void getRegs(ThreadContext*) = 0;
204
205 /**
206 * Set the ThreadContext's registers from the values
207 * in the raw buffer.
208 */
209 virtual void setRegs(ThreadContext*) const = 0;
210
211 /**
212 * Return the name to use in places like DPRINTF.
213 * Having each concrete superclass redefine this member
214 * is useful in situations where the class of the regCache
215 * can change on the fly.
216 */
217 virtual const std::string name() const = 0;
218
219 BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g)
220 {}
221 virtual ~BaseGdbRegCache()
222 {}
223
224 protected:
225 BaseRemoteGDB *gdb;
226 };
227
228 BaseGdbRegCache *regCachePtr;
229
230 protected:
231 uint8_t getbyte();
232 void putbyte(uint8_t b);
233
234 int recv(char *data, int len);
235 void send(const char *data);
236
237 protected:
238 // Machine memory
239 virtual bool read(Addr addr, size_t size, char *data);
240 virtual bool write(Addr addr, size_t size, const char *data);
241
242 template <class T> T read(Addr addr);
243 template <class T> void write(Addr addr, T data);
244
245 public:
246 BaseRemoteGDB(System *system, ThreadContext *context);
247 virtual ~BaseRemoteGDB();
248 virtual BaseGdbRegCache *gdbRegs() = 0;
249
250 void replaceThreadContext(ThreadContext *tc) { context = tc; }
251
252 void attach(int fd);
253 void detach();
254 bool isattached();
255
256 virtual bool acc(Addr addr, size_t len) = 0;
257 bool trap(int type);
258 virtual bool breakpoint()
259 {
260 return trap(SIGTRAP);
261 }
262
263 protected:
264 class SingleStepEvent : public Event
265 {
266 protected:
267 BaseRemoteGDB *gdb;
268
269 public:
270 SingleStepEvent(BaseRemoteGDB *g) : gdb(g)
271 {}
272
273 void process();
274 };
275
276 SingleStepEvent singleStepEvent;
277
278 void clearSingleStep();
279 void setSingleStep();
280
281 PCEventQueue *getPcEventQueue();
282 EventQueue *getComInstEventQueue();
283
284 /// Schedule an event which will be triggered "delta" instructions later.
285 void scheduleInstCommitEvent(Event *ev, int delta);
286 /// Deschedule an instruction count based event.
287 void descheduleInstCommitEvent(Event *ev);
288
289 protected:
290 virtual bool checkBpLen(size_t len);
291
292 class HardBreakpoint : public PCEvent
293 {
294 private:
295 BaseRemoteGDB *gdb;
296
297 public:
298 int refcount;
299
300 public:
301 HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr);
302 const std::string name() const { return gdb->name() + ".hwbkpt"; }
303
304 virtual void process(ThreadContext *tc);
305 };
306 friend class HardBreakpoint;
307
308 typedef std::map<Addr, HardBreakpoint *> break_map_t;
309 typedef break_map_t::iterator break_iter_t;
310 break_map_t hardBreakMap;
311
312 void insertSoftBreak(Addr addr, size_t len);
313 void removeSoftBreak(Addr addr, size_t len);
314 virtual void insertHardBreak(Addr addr, size_t len);
315 void removeHardBreak(Addr addr, size_t len);
316
317 protected:
318 void clearTempBreakpoint(Addr &bkpt);
319 void setTempBreakpoint(Addr bkpt);
320
321 public:
322 std::string name();
323};
324
325template <class T>
326inline T
327BaseRemoteGDB::read(Addr addr)
328{
329 T temp;
330 read(addr, sizeof(T), (char *)&temp);
331 return temp;
332}
333
334template <class T>
335inline void
336BaseRemoteGDB::write(Addr addr, T data)
337{ write(addr, sizeof(T), (const char *)&data); }
338
339class GDBListener
340{
341 protected:
342 class InputEvent : public PollEvent
343 {
344 protected:
345 GDBListener *listener;
346
347 public:
348 InputEvent(GDBListener *l, int fd, int e);
349 void process(int revent);
350 };
351
352 friend class InputEvent;
353 InputEvent *inputEvent;
354
355 protected:
356 ListenSocket listener;
357 BaseRemoteGDB *gdb;
358 int port;
359
360 public:
361 GDBListener(BaseRemoteGDB *g, int p);
362 ~GDBListener();
363
364 void accept();
365 void listen();
366 std::string name();
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 <exception>
40#include <map>
41#include <string>
42
43#include "arch/types.hh"
44#include "base/intmath.hh"
45#include "base/pollevent.hh"
46#include "base/socket.hh"
47#include "cpu/pc_event.hh"
48
49class System;
50class ThreadContext;
51
52class GDBListener;
53
54class BaseRemoteGDB;
55
56struct GdbCommand
57{
58 public:
59 struct Context
60 {
61 const GdbCommand *cmd;
62 char cmd_byte;
63 int type;
64 char *data;
65 int len;
66 };
67
68 typedef bool (BaseRemoteGDB::*Func)(Context &ctx);
69
70 const char * const name;
71 const Func func;
72
73 GdbCommand(const char *_name, Func _func) : name(_name), func(_func)
74 {}
75};
76
77class BaseRemoteGDB
78{
79 private:
80 friend void debugger();
81 friend class GDBListener;
82
83 protected:
84 /// Exception to throw when the connection to the client is broken.
85 struct BadClient
86 {
87 const char *warning;
88 BadClient(const char *_warning=NULL) : warning(_warning)
89 {}
90 };
91 /// Exception to throw when an error needs to be reported to the client.
92 struct CmdError
93 {
94 std::string error;
95 CmdError(std::string _error) : error(_error)
96 {}
97 };
98 /// Exception to throw when something isn't supported.
99 class Unsupported {};
100
101 // Helper functions
102 protected:
103 int digit2i(char);
104 char i2digit(int);
105 Addr hex2i(const char **);
106 // Address formats, break types, and gdb commands may change
107 // between architectures, so they're defined as virtual
108 // functions.
109 virtual void mem2hex(char *, const char *, int);
110 virtual const char * hex2mem(char *, const char *, int);
111 virtual const char * break_type(char c);
112
113 protected:
114 static std::map<char, GdbCommand> command_map;
115
116 bool cmd_unsupported(GdbCommand::Context &ctx);
117
118 bool cmd_signal(GdbCommand::Context &ctx);
119 bool cmd_cont(GdbCommand::Context &ctx);
120 bool cmd_async_cont(GdbCommand::Context &ctx);
121 bool cmd_detach(GdbCommand::Context &ctx);
122 bool cmd_reg_r(GdbCommand::Context &ctx);
123 bool cmd_reg_w(GdbCommand::Context &ctx);
124 bool cmd_set_thread(GdbCommand::Context &ctx);
125 bool cmd_mem_r(GdbCommand::Context &ctx);
126 bool cmd_mem_w(GdbCommand::Context &ctx);
127 bool cmd_query_var(GdbCommand::Context &ctx);
128 bool cmd_step(GdbCommand::Context &ctx);
129 bool cmd_async_step(GdbCommand::Context &ctx);
130 bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx);
131 bool cmd_set_hw_bkpt(GdbCommand::Context &ctx);
132
133 protected:
134 class InputEvent : public PollEvent
135 {
136 protected:
137 BaseRemoteGDB *gdb;
138
139 public:
140 InputEvent(BaseRemoteGDB *g, int fd, int e);
141 void process(int revent);
142 };
143
144 class TrapEvent : public Event
145 {
146 protected:
147 int _type;
148 BaseRemoteGDB *gdb;
149
150 public:
151 TrapEvent(BaseRemoteGDB *g) : gdb(g)
152 {}
153
154 void type(int t) { _type = t; }
155 void process();
156 };
157
158 friend class InputEvent;
159 InputEvent *inputEvent;
160 TrapEvent trapEvent;
161 GDBListener *listener;
162 int number;
163
164 protected:
165 // The socket commands come in through
166 int fd;
167
168 protected:
169 bool active;
170 bool attached;
171
172 System *system;
173 ThreadContext *context;
174
175 protected:
176 /**
177 * Concrete subclasses of this abstract class represent how the
178 * register values are transmitted on the wire. Usually each
179 * architecture should define one subclass, but there can be more
180 * if there is more than one possible wire format. For example,
181 * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache.
182 */
183 class BaseGdbRegCache
184 {
185 public:
186
187 /**
188 * Return the pointer to the raw bytes buffer containing the
189 * register values. Each byte of this buffer is literally
190 * encoded as two hex digits in the g or G RSP packet.
191 */
192 virtual char *data() const = 0;
193
194 /**
195 * Return the size of the raw buffer, in bytes
196 * (i.e., half of the number of digits in the g/G packet).
197 */
198 virtual size_t size() const = 0;
199
200 /**
201 * Fill the raw buffer from the registers in the ThreadContext.
202 */
203 virtual void getRegs(ThreadContext*) = 0;
204
205 /**
206 * Set the ThreadContext's registers from the values
207 * in the raw buffer.
208 */
209 virtual void setRegs(ThreadContext*) const = 0;
210
211 /**
212 * Return the name to use in places like DPRINTF.
213 * Having each concrete superclass redefine this member
214 * is useful in situations where the class of the regCache
215 * can change on the fly.
216 */
217 virtual const std::string name() const = 0;
218
219 BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g)
220 {}
221 virtual ~BaseGdbRegCache()
222 {}
223
224 protected:
225 BaseRemoteGDB *gdb;
226 };
227
228 BaseGdbRegCache *regCachePtr;
229
230 protected:
231 uint8_t getbyte();
232 void putbyte(uint8_t b);
233
234 int recv(char *data, int len);
235 void send(const char *data);
236
237 protected:
238 // Machine memory
239 virtual bool read(Addr addr, size_t size, char *data);
240 virtual bool write(Addr addr, size_t size, const char *data);
241
242 template <class T> T read(Addr addr);
243 template <class T> void write(Addr addr, T data);
244
245 public:
246 BaseRemoteGDB(System *system, ThreadContext *context);
247 virtual ~BaseRemoteGDB();
248 virtual BaseGdbRegCache *gdbRegs() = 0;
249
250 void replaceThreadContext(ThreadContext *tc) { context = tc; }
251
252 void attach(int fd);
253 void detach();
254 bool isattached();
255
256 virtual bool acc(Addr addr, size_t len) = 0;
257 bool trap(int type);
258 virtual bool breakpoint()
259 {
260 return trap(SIGTRAP);
261 }
262
263 protected:
264 class SingleStepEvent : public Event
265 {
266 protected:
267 BaseRemoteGDB *gdb;
268
269 public:
270 SingleStepEvent(BaseRemoteGDB *g) : gdb(g)
271 {}
272
273 void process();
274 };
275
276 SingleStepEvent singleStepEvent;
277
278 void clearSingleStep();
279 void setSingleStep();
280
281 PCEventQueue *getPcEventQueue();
282 EventQueue *getComInstEventQueue();
283
284 /// Schedule an event which will be triggered "delta" instructions later.
285 void scheduleInstCommitEvent(Event *ev, int delta);
286 /// Deschedule an instruction count based event.
287 void descheduleInstCommitEvent(Event *ev);
288
289 protected:
290 virtual bool checkBpLen(size_t len);
291
292 class HardBreakpoint : public PCEvent
293 {
294 private:
295 BaseRemoteGDB *gdb;
296
297 public:
298 int refcount;
299
300 public:
301 HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr);
302 const std::string name() const { return gdb->name() + ".hwbkpt"; }
303
304 virtual void process(ThreadContext *tc);
305 };
306 friend class HardBreakpoint;
307
308 typedef std::map<Addr, HardBreakpoint *> break_map_t;
309 typedef break_map_t::iterator break_iter_t;
310 break_map_t hardBreakMap;
311
312 void insertSoftBreak(Addr addr, size_t len);
313 void removeSoftBreak(Addr addr, size_t len);
314 virtual void insertHardBreak(Addr addr, size_t len);
315 void removeHardBreak(Addr addr, size_t len);
316
317 protected:
318 void clearTempBreakpoint(Addr &bkpt);
319 void setTempBreakpoint(Addr bkpt);
320
321 public:
322 std::string name();
323};
324
325template <class T>
326inline T
327BaseRemoteGDB::read(Addr addr)
328{
329 T temp;
330 read(addr, sizeof(T), (char *)&temp);
331 return temp;
332}
333
334template <class T>
335inline void
336BaseRemoteGDB::write(Addr addr, T data)
337{ write(addr, sizeof(T), (const char *)&data); }
338
339class GDBListener
340{
341 protected:
342 class InputEvent : public PollEvent
343 {
344 protected:
345 GDBListener *listener;
346
347 public:
348 InputEvent(GDBListener *l, int fd, int e);
349 void process(int revent);
350 };
351
352 friend class InputEvent;
353 InputEvent *inputEvent;
354
355 protected:
356 ListenSocket listener;
357 BaseRemoteGDB *gdb;
358 int port;
359
360 public:
361 GDBListener(BaseRemoteGDB *g, int p);
362 ~GDBListener();
363
364 void accept();
365 void listen();
366 std::string name();
367
368 int getPort() const;
367};
368
369#endif /* __REMOTE_GDB_H__ */
369};
370
371#endif /* __REMOTE_GDB_H__ */