gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
46#include <cstdint>
47#include <exception>
48#include <map>
49#include <string>
50#include <vector>
51
53#include "base/cprintf.hh"
54#include "base/pollevent.hh"
55#include "base/socket.hh"
56#include "base/types.hh"
57#include "cpu/pc_event.hh"
58#include "gdbremote/signals.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
69namespace gem5
70{
71
72class System;
73class ThreadContext;
74
75class BaseRemoteGDB;
76class 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
137 {}
138
139 protected:
141};
142
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 const ListenSocket &hostSocket() const;
165
166 void attach(int fd);
167 void detach();
168 bool isAttached() { return attached; }
169
173
174 void trap(ContextID id, GDBSignal sig,const std::string& stopReason="");
175 bool sendMessage(std::string message);
176 //schedule a trap event with these properties
177 void scheduleTrapEvent(ContextID id,GDBSignal type, int delta,
178 std::string stopReason);
179 // end of api_remote_gdb
180
181 template <class GDBStub, class ...Args>
182 static BaseRemoteGDB *
183 build(ListenSocketConfig listen_config, Args... args)
184 {
185 if (listen_config)
186 return new GDBStub(args..., listen_config);
187 else
188 return nullptr;
189 }
190
191 protected:
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
236 // The socket commands come in through.
237 int fd;
238
239 // Transfer data to/from GDB.
240 uint8_t getbyte();
241 bool try_getbyte(uint8_t* c,int timeout=-1);//return true if successful
242 void putbyte(uint8_t b);
243
244 void recv(std::vector<char> &bp);
245 void send(const char *data);
246 void send(const std::string &data) { send(data.c_str()); }
247
248 template <typename ...Args>
249 void
250 send(const char *format, const Args &...args)
251 {
252 send(csprintf(format, args...));
253 }
254
255 /*
256 * Process commands from remote GDB. If simulation has been
257 * stopped because of some kind of fault (as segmentation violation,
258 * or SW trap), 'signum' is the signal value reported back to GDB
259 * in "S" packet (this is done in trap()).
260 */
261 void processCommands(GDBSignal sig=GDBSignal::ZERO);
262
263 /*
264 * Simulator side debugger state.
265 */
266 bool attached = false;
267 bool threadSwitching = false;
268
270
271 std::map<ContextID, ThreadContext *> threads;
272 ThreadContext *tc = nullptr;
273
275
278
279 class TrapEvent : public Event
280 {
281 protected:
282 GDBSignal _type;
284 std::string _stopReason;
286
287 public:
290
291 void type(GDBSignal t) { _type = t; }
292 void stopReason(std::string s) {_stopReason = s; }
293 void id(ContextID id) { _id = id; }
296
297 /*
298 * The interface to the simulated system.
299 */
300 virtual bool readBlob(Addr vaddr, size_t size, char *data);
301 virtual bool writeBlob(Addr vaddr, size_t size, const char *data);
302 bool read(Addr vaddr, size_t size, char *data);
303 bool write(Addr vaddr, size_t size, const char *data);
304
305 template <class T> T read(Addr addr);
306 template <class T> void write(Addr addr, T data);
307
308 // Single step.
309 void singleStep();
311
312 void clearSingleStep();
313 void setSingleStep();
314
316 void scheduleInstCommitEvent(Event *ev, int delta,ThreadContext* _tc);
317 void scheduleInstCommitEvent(Event *ev, int delta){
318 scheduleInstCommitEvent(ev, delta,tc);
319 };
322
323 // Breakpoints.
324 void insertSoftBreak(Addr addr, size_t kind);
325 void removeSoftBreak(Addr addr, size_t kind);
326 void insertHardBreak(Addr addr, size_t kind);
327 void removeHardBreak(Addr addr, size_t kind);
328
329 void sendTPacket(GDBSignal sig, ContextID id,
330 const std::string& stopReason);
331 void sendSPacket(GDBSignal sig);
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 */
338 {
339 public:
340 struct Context
341 {
344 GDBSignal 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 GDBSignal 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
386 bool cmdCont(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);
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 = bool (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
437
438 size_t threadInfoIdx = 0;
441
442 protected:
443 ThreadContext *context() { return tc; }
444 System *system() { return sys; }
445
446 void encodeBinaryData(const std::string &unencoded,
447 std::string &encoded) const;
448
449 void encodeXferResponse(const std::string &unencoded,
450 std::string &encoded, size_t offset, size_t unencoded_length) const;
451
452 // checkBpKind checks if a kind of breakpoint is legal. This function should
453 // be implemented by subclasses by arch. The "kind" is considered to be
454 // breakpoint size in some arch.
455 virtual bool checkBpKind(size_t kind);
456
457 virtual BaseGdbRegCache *gdbRegs() = 0;
458
459 virtual bool acc(Addr addr, size_t len) = 0;
460
462
470 virtual bool getXferFeaturesRead(const std::string &annex,
471 std::string &output);
472};
473
474template <class T>
475inline T
477{
478 T temp;
479 read(addr, sizeof(T), (char *)&temp);
480 return temp;
481}
482
483template <class T>
484inline void
486{
487 write(addr, sizeof(T), (const char *)&data);
488}
489
490} // namespace gem5
491
492#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
SocketEvent(BaseRemoteGDB *gdb, int fd, int e)
void stopReason(std::string s)
void removeHardBreak(Addr addr, size_t kind)
bool queryAttached(QuerySetCommand::Context &ctx)
std::map< ContextID, ThreadContext * > threads
ListenSocketPtr listener
bool cmdQueryVar(GdbCommand::Context &ctx)
ThreadContext * tc
bool cmdCont(GdbCommand::Context &ctx)
virtual bool checkBpKind(size_t kind)
MemberEventWrapper<&BaseRemoteGDB::singleStep > singleStepEvent
bool cmdDetach(GdbCommand::Context &ctx)
bool cmdReplyEmpty(GdbMultiLetterCommand::Context &ctx)
static std::map< std::string, GdbMultiLetterCommand > multiLetterMap
void send(const char *data)
void incomingConnection(int revent)
IncomingConnectionEvent * incomingConnectionEvent
void encodeBinaryData(const std::string &unencoded, std::string &encoded) const
void insertSoftBreak(Addr addr, size_t kind)
static std::map< std::string, QuerySetCommand > queryMap
virtual bool writeBlob(Addr vaddr, size_t size, const char *data)
bool cmdMemW(GdbCommand::Context &ctx)
bool querySupported(QuerySetCommand::Context &ctx)
bool queryRcmd(QuerySetCommand::Context &ctx)
IncomingDataEvent * incomingDataEvent
void putbyte(uint8_t b)
bool cmdSetThread(GdbCommand::Context &ctx)
bool cmdClrHwBkpt(GdbCommand::Context &ctx)
bool cmdDumpPageTable(GdbCommand::Context &ctx)
static std::map< char, GdbCommand > commandMap
bool trap(ContextID id, int type)
Definition remote_gdb.hh:55
void incomingData(int revent)
bool try_getbyte(uint8_t *c, int timeout=-1)
bool cmdAsyncStep(GdbCommand::Context &ctx)
virtual std::vector< std::string > availableFeatures() const
MemberEventWrapper<&BaseRemoteGDB::connect > connectEvent
friend IncomingConnectionEvent
void sendTPacket(GDBSignal sig, ContextID id, const std::string &stopReason)
MemberEventWrapper<&BaseRemoteGDB::detach > disconnectEvent
SocketEvent<&BaseRemoteGDB::incomingData > IncomingDataEvent
void send(const char *format, const Args &...args)
void send(const std::string &data)
bool cmdSetHwBkpt(GdbCommand::Context &ctx)
void scheduleInstCommitEvent(Event *ev, int delta)
bool querySThreadInfo(QuerySetCommand::Context &ctx)
bool cmdStep(GdbCommand::Context &ctx)
void recv(std::vector< char > &bp)
virtual bool getXferFeaturesRead(const std::string &annex, std::string &output)
Get an XML target description.
ThreadContext * context()
bool cmdRegW(GdbCommand::Context &ctx)
void encodeXferResponse(const std::string &unencoded, std::string &encoded, size_t offset, size_t unencoded_length) const
bool cmdSignal(GdbCommand::Context &ctx)
void sendSPacket(GDBSignal sig)
bool cmdMemR(GdbCommand::Context &ctx)
void descheduleInstCommitEvent(Event *ev)
Deschedule an instruction count based event.
bool read(Addr vaddr, size_t size, char *data)
SocketEvent<&BaseRemoteGDB::incomingConnection > IncomingConnectionEvent
bool cmdRegR(GdbCommand::Context &ctx)
bool cmdIsThreadAlive(GdbCommand::Context &ctx)
void scheduleInstCommitEvent(Event *ev, int delta, ThreadContext *_tc)
Schedule an event which will be triggered "delta" instructions later.
virtual bool readBlob(Addr vaddr, size_t size, char *data)
virtual bool acc(Addr addr, size_t len)=0
virtual BaseGdbRegCache * gdbRegs()=0
gem5::BaseRemoteGDB::TrapEvent trapEvent
bool write(Addr vaddr, size_t size, const char *data)
bool cmdMultiUnsupported(GdbMultiLetterCommand::Context &ctx)
bool cmdUnsupported(GdbCommand::Context &ctx)
bool cmdMultiLetter(GdbCommand::Context &ctx)
bool queryXfer(QuerySetCommand::Context &ctx)
bool cmdVKill(GdbMultiLetterCommand::Context &ctx)
BaseGdbRegCache * regCachePtr
bool cmdAsyncCont(GdbCommand::Context &ctx)
void sendOPacket(const std::string message)
bool querySymbol(QuerySetCommand::Context &ctx)
bool queryFThreadInfo(QuerySetCommand::Context &ctx)
void removeSoftBreak(Addr addr, size_t kind)
void processCommands(GDBSignal sig=GDBSignal::ZERO)
bool queryC(QuerySetCommand::Context &ctx)
void insertHardBreak(Addr addr, size_t kind)
static BaseRemoteGDB * build(ListenSocketConfig listen_config, Args... args)
Wrap a member function inside MemberEventWrapper to use it as an event callback.
Definition eventq.hh:1092
ThreadContext is the external interface to all thread state for anything outside of the CPU.
STL vector class.
Definition stl.hh:37
virtual ~BaseRemoteGDB()
void attach(int fd)
virtual const std::string name() const =0
Return the name to use in places like DPRINTF.
BaseGdbRegCache(BaseRemoteGDB *g)
bool sendMessage(std::string message)
virtual void getRegs(ThreadContext *)=0
Fill the raw buffer from the registers in the ThreadContext.
std::string name()
virtual void setRegs(ThreadContext *) const =0
Set the ThreadContext's registers from the values in the raw buffer.
void replaceThreadContext(ThreadContext *_tc)
const ListenSocket & hostSocket() const
void scheduleTrapEvent(ContextID id, GDBSignal type, int delta, std::string stopReason)
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).
virtual char * data() const =0
Return the pointer to the raw bytes buffer containing the register values.
void addThreadContext(ThreadContext *_tc)
BaseRemoteGDB(System *system, ListenSocketConfig _listen_config)
Interface to other parts of the simulator.
bool selectThreadContext(ContextID id)
Bitfield< 18, 16 > len
Bitfield< 5 > t
Definition misc_types.hh:71
Bitfield< 4 > s
Bitfield< 7 > b
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 31, 29 > format
Bitfield< 29 > c
Definition misc_types.hh:53
Bitfield< 4 > g
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
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
std::unique_ptr< ListenSocket > ListenSocketPtr
Definition socket.hh:112
bool(BaseRemoteGDB::* Func)(Context &ctx)
GdbCommand(const char *_name, Func _func)
GdbMultiLetterCommand(const char *_name, Func _func)
bool(BaseRemoteGDB::* Func)(Context &ctx)
QuerySetCommand(Func _func, const char *_argSep=nullptr)
bool(BaseRemoteGDB::*)(Context &ctx) Func

Generated on Tue Jun 18 2024 16:23:59 for gem5 by doxygen 1.11.0