gem5  v22.1.0.0
remote_gdb.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 ARM Limited
3  *
4  * The license below extends only to copyright in the software and shall
5  * not be construed as granting a license to any other intellectual
6  * property including but not limited to intellectual property relating
7  * to a hardware implementation of the functionality of the software
8  * licensed hereunder. You may use the software subject to the license
9  * terms below provided that you ensure that this notice is replicated
10  * unmodified and in its entirety in all distributions of the software,
11  * modified or unmodified, in source code or in binary form.
12  *
13  * Copyright 2015, 2021 LabWare
14  * Copyright 2014 Google, Inc.
15  * Copyright (c) 2002-2005 The Regents of The University of Michigan
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 #ifndef __REMOTE_GDB_HH__
43 #define __REMOTE_GDB_HH__
44 
45 #include <sys/signal.h>
46 
47 #include <cstdint>
48 #include <exception>
49 #include <map>
50 #include <string>
51 #include <vector>
52 
53 #include "arch/generic/pcstate.hh"
54 #include "base/cprintf.hh"
55 #include "base/pollevent.hh"
56 #include "base/socket.hh"
57 #include "base/types.hh"
58 #include "cpu/pc_event.hh"
59 #include "sim/debug.hh"
60 #include "sim/eventq.hh"
61 
62 /*
63  * This file implements a client for the GDB remote serial protocol as
64  * described in this official documentation:
65  *
66  * https://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Protocol.html
67  */
68 
69 namespace gem5
70 {
71 
72 class System;
73 class ThreadContext;
74 
75 class BaseRemoteGDB;
76 class HardBreakpoint;
77 
86 {
87  public:
88 
96  virtual char *data() const = 0;
97 
104  virtual size_t size() const = 0;
105 
111  virtual void getRegs(ThreadContext*) = 0;
112 
119  virtual void setRegs(ThreadContext*) const = 0;
120 
129  virtual const std::string name() const = 0;
130 
135  {}
137  {}
138 
139  protected:
141 };
142 
143 class BaseRemoteGDB
144 {
145  friend class HardBreakpoint;
146  public:
147 
157  virtual ~BaseRemoteGDB();
158 
159  std::string name();
160 
161  void listen();
162  void connect();
163 
164  int port() const;
165 
166  void attach(int fd);
167  void detach();
168  bool isAttached() { return attached; }
169 
170  void addThreadContext(ThreadContext *_tc);
173 
174  void trap(ContextID id, int signum,const std::string& stopReason="");
175  bool sendMessage(std::string message);
176  //schedule a trap event with these properties
177  void scheduleTrapEvent(ContextID id,int type, int delta,
178  std::string stopReason); // end of api_remote_gdb
180 
181  template <class GDBStub, class ...Args>
182  static BaseRemoteGDB *
183  build(int port, Args... args)
184  {
185  if (port)
186  return new GDBStub(args..., port);
187  else
188  return nullptr;
189  }
190 
191  private:
192  /*
193  * Connection to the external GDB.
194  */
195 
196  /*
197  * Asynchronous socket events and event handlers.
198  *
199  * These events occur asynchronously and are handled asynchronously
200  * to main simulation loop - therefore they *shall not* interact with
201  * rest of gem5.
202  *
203  * The only thing they do is to schedule a synchronous event at instruction
204  * boundary to deal with the request.
205  */
206  void incomingData(int revent);
207  void incomingConnection(int revent);
208 
209  template <void (BaseRemoteGDB::*F)(int revent)>
210  class SocketEvent : public PollEvent
211  {
212  protected:
214 
215  public:
217  PollEvent(fd, e), gdb(gdb)
218  {}
219 
220  void process(int revent) { (gdb->*F)(revent); }
221  };
222 
223  typedef SocketEvent<&BaseRemoteGDB::incomingConnection>
227 
230 
233 
235  int _port;
236 
237  // The socket commands come in through.
238  int fd;
239 
240  // Transfer data to/from GDB.
241  uint8_t getbyte();
242  bool try_getbyte(uint8_t* c,int timeout=-1);//return true if successful
243  void putbyte(uint8_t b);
244 
245  void recv(std::vector<char> &bp);
246  void send(const char *data);
247  void send(const std::string &data) { send(data.c_str()); }
248 
249  template <typename ...Args>
250  void
251  send(const char *format, const Args &...args)
252  {
253  send(csprintf(format, args...));
254  }
255 
256  /*
257  * Process commands from remote GDB. If simulation has been
258  * stopped because of some kind of fault (as segmentation violation,
259  * or SW trap), 'signum' is the signal value reported back to GDB
260  * in "S" packet (this is done in trap()).
261  */
262  void processCommands(int signum=0);
263 
264  /*
265  * Simulator side debugger state.
266  */
267  bool attached = false;
268  bool threadSwitching = false;
269 
271 
272  std::map<ContextID, ThreadContext *> threads;
273  ThreadContext *tc = nullptr;
274 
276 
279 
280  class TrapEvent : public Event
281  {
282  protected:
283  int _type;
285  std::string _stopReason;
287 
288  public:
290  {}
291 
292  void type(int t) { _type = t; }
293  void stopReason(std::string s) {_stopReason = s; }
294  void id(ContextID id) { _id = id; }
297 
298  /*
299  * The interface to the simulated system.
300  */
301  virtual bool readBlob(Addr vaddr, size_t size, char *data);
302  virtual bool writeBlob(Addr vaddr, size_t size, const char *data);
303  bool read(Addr vaddr, size_t size, char *data);
304  bool write(Addr vaddr, size_t size, const char *data);
305 
306  template <class T> T read(Addr addr);
307  template <class T> void write(Addr addr, T data);
308 
309  // Single step.
310  void singleStep();
312 
313  void clearSingleStep();
314  void setSingleStep();
315 
317  void scheduleInstCommitEvent(Event *ev, int delta,ThreadContext* _tc);
318  void scheduleInstCommitEvent(Event *ev, int delta){
319  scheduleInstCommitEvent(ev, delta,tc);
320  };
323 
324  // Breakpoints.
325  void insertSoftBreak(Addr addr, size_t kind);
326  void removeSoftBreak(Addr addr, size_t kind);
327  void insertHardBreak(Addr addr, size_t kind);
328  void removeHardBreak(Addr addr, size_t kind);
329 
330  void sendTPacket(int errnum, ContextID id,const std::string& stopReason);
331  void sendSPacket(int errnum);
332  //The OPacket allow to send string to be displayed by the remote GDB
333  void sendOPacket(const std::string message);
334  /*
335  * GDB commands.
336  */
337  struct GdbCommand
338  {
339  public:
340  struct Context
341  {
342  const GdbCommand *cmd;
343  char cmdByte;
344  int type;
345  char *data;
346  int len;
347  };
348 
349  typedef bool (BaseRemoteGDB::*Func)(Context &ctx);
350 
351  const char * const name;
352  const Func func;
353 
354  GdbCommand(const char *_name, Func _func) : name(_name), func(_func) {}
355  };
356 
357  static std::map<char, GdbCommand> commandMap;
358 
360  {
361  public:
362  struct Context
363  {
365  std::string cmdTxt;
366  int type;
367  char *data;
368  int len;
369  };
370 
371  typedef bool (BaseRemoteGDB::*Func)(Context &ctx);
372 
373  const char * const name;
374  const Func func;
375 
376  GdbMultiLetterCommand(const char *_name, Func _func) :
377  name(_name), func(_func) {}
378  };
379 
380 
381  static std::map<std::string, GdbMultiLetterCommand> multiLetterMap;
382 
384 
385  bool cmdSignal(GdbCommand::Context &ctx);
386  bool cmdCont(GdbCommand::Context &ctx);
388  bool cmdDetach(GdbCommand::Context &ctx);
389  bool cmdRegR(GdbCommand::Context &ctx);
390  bool cmdRegW(GdbCommand::Context &ctx);
393  bool cmdMemR(GdbCommand::Context &ctx);
394  bool cmdMemW(GdbCommand::Context &ctx);
395  bool cmdQueryVar(GdbCommand::Context &ctx);
396  bool cmdStep(GdbCommand::Context &ctx);
402 
403  //Multi letter command
405 
408 
410  {
411  struct Context
412  {
413  const std::string &name;
415 
416  Context(const std::string &_name) : name(_name) {}
417  };
418 
419  using Func = void (BaseRemoteGDB::*)(Context &ctx);
420 
421  const char * const argSep;
422  const Func func;
423 
424  QuerySetCommand(Func _func, const char *_argSep=nullptr) :
425  argSep(_argSep), func(_func)
426  {}
427  };
428 
429  static std::map<std::string, QuerySetCommand> queryMap;
430 
431  void queryC(QuerySetCommand::Context &ctx);
436 
437  size_t threadInfoIdx = 0;
440 
441  protected:
442  ThreadContext *context() { return tc; }
443  System *system() { return sys; }
444 
445  void encodeBinaryData(const std::string &unencoded,
446  std::string &encoded) const;
447 
448  void encodeXferResponse(const std::string &unencoded,
449  std::string &encoded, size_t offset, size_t unencoded_length) const;
450 
451  // checkBpKind checks if a kind of breakpoint is legal. This function should
452  // be implemented by subclasses by arch. The "kind" is considered to be
453  // breakpoint size in some arch.
454  virtual bool checkBpKind(size_t kind);
455 
456  virtual BaseGdbRegCache *gdbRegs() = 0;
457 
458  virtual bool acc(Addr addr, size_t len) = 0;
459 
461 
469  virtual bool getXferFeaturesRead(const std::string &annex,
470  std::string &output);
471 };
472 
473 template <class T>
474 inline T
476 {
477  T temp;
478  read(addr, sizeof(T), (char *)&temp);
479  return temp;
480 }
481 
482 template <class T>
483 inline void
485 {
486  write(addr, sizeof(T), (const char *)&data);
487 }
488 
489 } // namespace gem5
490 
491 #endif /* __REMOTE_GDB_H__ */
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
const char data[]
Concrete subclasses of this abstract class represent how the register values are transmitted on the w...
Definition: remote_gdb.hh:86
BaseRemoteGDB * gdb
Definition: remote_gdb.hh:140
virtual ~BaseGdbRegCache()
Definition: remote_gdb.hh:136
SocketEvent(BaseRemoteGDB *gdb, int fd, int e)
Definition: remote_gdb.hh:216
void stopReason(std::string s)
Definition: remote_gdb.hh:293
TrapEvent(BaseRemoteGDB *g)
Definition: remote_gdb.hh:289
void removeHardBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:935
std::map< ContextID, ThreadContext * > threads
Definition: remote_gdb.hh:272
void querySymbol(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1396
bool cmdQueryVar(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1436
ThreadContext * tc
Definition: remote_gdb.hh:273
bool cmdCont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1090
virtual bool checkBpKind(size_t kind)
Definition: remote_gdb.cc:1068
EventWrapper< BaseRemoteGDB, &BaseRemoteGDB::connect > connectEvent
Definition: remote_gdb.hh:277
bool cmdDetach(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1115
EventWrapper< BaseRemoteGDB, &BaseRemoteGDB::detach > disconnectEvent
Definition: remote_gdb.hh:278
bool cmdReplyEmpty(GdbMultiLetterCommand::Context &ctx)
Definition: remote_gdb.cc:1287
EventWrapper< BaseRemoteGDB, &BaseRemoteGDB::singleStep > singleStepEvent
Definition: remote_gdb.hh:311
static std::map< std::string, GdbMultiLetterCommand > multiLetterMap
Definition: remote_gdb.hh:381
void send(const char *data)
Definition: remote_gdb.cc:738
void incomingConnection(int revent)
Definition: remote_gdb.cc:595
IncomingConnectionEvent * incomingConnectionEvent
Definition: remote_gdb.hh:231
void queryXfer(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1356
void encodeBinaryData(const std::string &unencoded, std::string &encoded) const
Definition: remote_gdb.cc:1484
void insertSoftBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:902
static std::map< std::string, QuerySetCommand > queryMap
Definition: remote_gdb.hh:429
virtual bool writeBlob(Addr vaddr, size_t size, const char *data)
Definition: remote_gdb.cc:829
bool cmdMemW(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1226
void processCommands(int signum=0)
Definition: remote_gdb.cc:769
IncomingDataEvent * incomingDataEvent
Definition: remote_gdb.hh:232
void putbyte(uint8_t b)
Definition: remote_gdb.cc:676
bool cmdSetThread(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1146
bool cmdClrHwBkpt(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1541
bool cmdDumpPageTable(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1509
static std::map< char, GdbCommand > commandMap
Definition: remote_gdb.hh:357
bool trap(ContextID id, int type)
Definition: remote_gdb.hh:55
void incomingData(int revent)
Definition: remote_gdb.cc:608
bool try_getbyte(uint8_t *c, int timeout=-1)
Definition: remote_gdb.cc:632
void sendSPacket(int errnum)
Definition: remote_gdb.cc:964
bool cmdAsyncStep(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1516
virtual std::vector< std::string > availableFeatures() const
Definition: remote_gdb.cc:1471
friend IncomingConnectionEvent
Definition: remote_gdb.hh:228
void queryFThreadInfo(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1416
SocketEvent<&BaseRemoteGDB::incomingData > IncomingDataEvent
Definition: remote_gdb.hh:226
void send(const char *format, const Args &...args)
Definition: remote_gdb.hh:251
void send(const std::string &data)
Definition: remote_gdb.hh:247
bool cmdSetHwBkpt(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1574
void scheduleInstCommitEvent(Event *ev, int delta)
Definition: remote_gdb.hh:318
bool cmdStep(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1529
void recv(std::vector< char > &bp)
Definition: remote_gdb.cc:686
virtual bool getXferFeaturesRead(const std::string &annex, std::string &output)
Get an XML target description.
Definition: remote_gdb.cc:1477
bool cmdRegW(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1132
void queryAttached(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1403
void encodeXferResponse(const std::string &unencoded, std::string &encoded, size_t offset, size_t unencoded_length) const
Definition: remote_gdb.cc:1498
bool cmdSignal(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1083
bool cmdMemR(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1202
void descheduleInstCommitEvent(Event *ev)
Deschedule an instruction count based event.
Definition: remote_gdb.cc:1000
bool read(Addr vaddr, size_t size, char *data)
Definition: remote_gdb.cc:841
void querySThreadInfo(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1423
SocketEvent<&BaseRemoteGDB::incomingConnection > IncomingConnectionEvent
Definition: remote_gdb.hh:224
bool cmdRegR(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1122
bool cmdIsThreadAlive(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1186
void scheduleInstCommitEvent(Event *ev, int delta, ThreadContext *_tc)
Schedule an event which will be triggered "delta" instructions later.
Definition: remote_gdb.cc:985
virtual bool readBlob(Addr vaddr, size_t size, char *data)
Definition: remote_gdb.cc:818
void queryC(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1337
virtual bool acc(Addr addr, size_t len)=0
gem5::BaseRemoteGDB::TrapEvent trapEvent
bool write(Addr vaddr, size_t size, const char *data)
Definition: remote_gdb.cc:866
bool cmdMultiUnsupported(GdbMultiLetterCommand::Context &ctx)
Definition: remote_gdb.cc:1302
void querySupported(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1343
bool cmdUnsupported(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1074
void sendTPacket(int errnum, ContextID id, const std::string &stopReason)
Definition: remote_gdb.cc:954
bool cmdMultiLetter(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1250
bool cmdVKill(GdbMultiLetterCommand::Context &ctx)
Definition: remote_gdb.cc:1294
BaseGdbRegCache * regCachePtr
Definition: remote_gdb.hh:275
bool cmdAsyncCont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1102
void sendOPacket(const std::string message)
Definition: remote_gdb.cc:968
ThreadContext * context()
Definition: remote_gdb.hh:442
void removeSoftBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:911
void insertHardBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:920
static BaseRemoteGDB * build(int port, Args... args)
Definition: remote_gdb.hh:183
ListenSocket listener
Definition: remote_gdb.hh:234
virtual BaseGdbRegCache * gdbRegs()=0
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual ~BaseRemoteGDB()
void attach(int fd)
Definition: remote_gdb.cc:460
virtual const std::string name() const =0
Return the name to use in places like DPRINTF.
BaseGdbRegCache(BaseRemoteGDB *g)
Definition: remote_gdb.hh:134
bool sendMessage(std::string message)
Definition: remote_gdb.cc:585
virtual char * data() const =0
Return the pointer to the raw bytes buffer containing the register values.
virtual void getRegs(ThreadContext *)=0
Fill the raw buffer from the registers in the ThreadContext.
std::string name()
Definition: remote_gdb.cc:407
virtual void setRegs(ThreadContext *) const =0
Set the ThreadContext's registers from the values in the raw buffer.
void replaceThreadContext(ThreadContext *_tc)
virtual size_t size() const =0
Return the size of the raw buffer, in bytes (i.e., half of the number of digits in the g/G packet).
void addThreadContext(ThreadContext *_tc)
Definition: remote_gdb.cc:510
BaseRemoteGDB(System *system, int _port)
Interface to other parts of the simulator.
Definition: remote_gdb.cc:393
void scheduleTrapEvent(ContextID id, int type, int delta, std::string stopReason)
Definition: remote_gdb.cc:973
int port() const
Definition: remote_gdb.cc:452
bool selectThreadContext(ContextID id)
Definition: remote_gdb.cc:533
uint16_t len
Definition: helpers.cc:62
Bitfield< 7 > b
Definition: misc_types.hh:388
Bitfield< 23, 0 > offset
Definition: types.hh:144
Bitfield< 9 > e
Definition: misc_types.hh:65
Bitfield< 31, 29 > format
Definition: misc_types.hh:653
Bitfield< 4 > g
Definition: dt_constants.hh:86
Bitfield< 1 > s
Definition: pagetable.hh:64
Bitfield< 2 > c
Definition: pagetable.hh:63
Bitfield< 51 > t
Definition: pagetable.hh:56
Bitfield< 3 > addr
Definition: types.hh:84
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
static void output(const char *filename)
Definition: debug.cc:60
int ContextID
Globally unique thread context ID.
Definition: types.hh:239
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
bool(BaseRemoteGDB::* Func)(Context &ctx)
Definition: remote_gdb.hh:349
GdbCommand(const char *_name, Func _func)
Definition: remote_gdb.hh:354
GdbMultiLetterCommand(const char *_name, Func _func)
Definition: remote_gdb.hh:376
bool(BaseRemoteGDB::* Func)(Context &ctx)
Definition: remote_gdb.hh:371
void(BaseRemoteGDB::*)(Context &ctx) Func
Definition: remote_gdb.hh:419
QuerySetCommand(Func _func, const char *_argSep=nullptr)
Definition: remote_gdb.hh:424

Generated on Wed Dec 21 2022 10:22:25 for gem5 by doxygen 1.9.1