remote_gdb.hh (12125:0066d9926c1a) remote_gdb.hh (12449:2260f4a68210)
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

--- 35 unchanged lines hidden (view full) ---

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
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

--- 35 unchanged lines hidden (view full) ---

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