124 #include <sys/signal.h>
132 #include "arch/vtophys.hh"
136 #include "config/the_isa.hh"
140 #include "debug/GDBAll.hh"
148 using namespace TheISA;
163 static int current_debugger = -1;
164 if (current_debugger >= 0 && current_debugger < (
int)
debuggers.size()) {
204 return gdb->
name() +
".listener";
211 warn_once(
"Sockets disabled, not accepting gdb connections");
229 ccprintf(cerr,
"%d: %s: listening for remote gdb #%d on port %d\n",
232 ccprintf(cerr,
"%d: %s: listening for remote gdb on port %d\n",
241 panic(
"GDBListener::accept(): cannot accept if we're not listening!");
260 if (gdb->trapEvent.scheduled()) {
261 warn(
"GDB trap event has already been scheduled! "
262 "Ignoring this input event.");
266 if (revent & POLLIN) {
267 gdb->trapEvent.type(SIGILL);
268 gdb->scheduleInstCommitEvent(&gdb->trapEvent, 0);
269 }
else if (revent & POLLNVAL) {
270 gdb->descheduleInstCommitEvent(&gdb->trapEvent);
284 if (!gdb->singleStepEvent.scheduled())
285 gdb->scheduleInstCommitEvent(&gdb->singleStepEvent, 1);
345 if (::
read(
fd, &b,
sizeof(b)) ==
sizeof(b))
348 throw BadClient(
"Couldn't read data from debugger.");
354 if (::
write(
fd, &b,
sizeof(b)) ==
sizeof(b))
357 throw BadClient(
"Couldn't write data to the debugger.");
367 DPRINTF(GDBSend,
"send: %s\n", bp);
374 for (csum = 0; (c = *
p); p++) {
386 }
while ((c & 0x7f) ==
GDBBadP);
406 while (len < maxlen) {
439 memcpy(bp, bp+3, len);
447 DPRINTF(GDBRecv,
"recv: %s\n", bp);
456 static Addr lastaddr = 0;
457 static size_t lastsize = 0;
460 DPRINTF(GDBRead,
"read: reading memory location zero!\n");
461 vaddr = lastaddr + lastsize;
464 DPRINTF(GDBRead,
"read: addr=%#x, size=%d", vaddr, size);
468 proxy.
readBlob(vaddr, (uint8_t*)data, size);
471 proxy.
readBlob(vaddr, (uint8_t*)data, size);
492 static Addr lastaddr = 0;
493 static size_t lastsize = 0;
496 DPRINTF(GDBWrite,
"write: writing memory location zero!\n");
497 vaddr = lastaddr + lastsize;
501 DPRINTFN(
"write: addr=%#x, size=%d", vaddr, size);
511 proxy.
writeBlob(vaddr, (uint8_t*)data, size);
514 proxy.
writeBlob(vaddr, (uint8_t*)data, size);
535 return &
system->pcEventQueue;
568 :
PCEvent(_gdb->getPcEventQueue(),
"HardBreakpoint Event", pc),
569 gdb(_gdb), refcount(0)
571 DPRINTF(GDBMisc,
"creating hardware breakpoint at %#x\n",
evpc);
577 DPRINTF(GDBMisc,
"handling hardware breakpoint at %#x\n",
pc());
579 if (tc == gdb->context)
587 throw BadClient(
"Invalid breakpoint length\n");
596 throw BadClient(
"Invalid breakpoint length.\n");
605 throw BadClient(
"Invalid breakpoint length\n");
607 DPRINTF(GDBMisc,
"Inserting hardware breakpoint at %#x\n", addr);
620 throw BadClient(
"Invalid breakpoint length\n");
622 DPRINTF(GDBMisc,
"Removing hardware breakpoint at %#x\n", addr);
638 DPRINTF(GDBMisc,
"setTempBreakpoint: addr=%#x\n", bkpt);
645 DPRINTF(GDBMisc,
"setTempBreakpoint: addr=%#x\n", bkpt);
662 case GdbSoftBp:
return "software breakpoint";
663 case GdbHardBp:
return "hardware breakpoint";
665 case GdbReadWp:
return "read watchpoint";
666 case GdbAccWp:
return "access watchpoint";
667 default:
return "unknown breakpoint/watchpoint";
748 const char *
p = ctx.
data;
760 const char *
p = ctx.
data;
790 const char *
p = ctx.
data;
792 if (p == NULL || *p !=
'\0')
804 const char *
p = ctx.
data + 1;
814 const char *
p = ctx.
data;
825 if (!
read(addr, len, buf))
828 char temp[2 * len + 1];
829 temp[2 *
len] =
'\0';
838 const char *
p = ctx.
data;
845 if (len * 2 > ctx.
len - (p - ctx.
data))
848 p = (
char *)
hex2mem(buf, p, len);
853 if (!
write(addr, len, buf))
862 if (
string(ctx.
data, ctx.
len - 1) !=
"C")
871 const char *
p = ctx.
data;
885 const char *
p = ctx.
data;
896 const char *
p = ctx.
data;
905 DPRINTF(GDBMisc,
"clear %s, addr=%#x, len=%d\n",
929 const char *
p = ctx.
data;
938 DPRINTF(GDBMisc,
"set %s, addr=%#x, len=%d\n",
1000 cmdCtx.
data = &data[1];
1004 size_t datalen =
recv(data,
sizeof(data));
1010 cmdCtx.
len = datalen - 1;
1014 DPRINTF(GDBMisc,
"Unknown command: %c(%#x)\n",
1018 cmdCtx.
cmd = &(cmdIt->second);
1020 if (!(this->*(cmdCtx.
cmd->
func))(cmdCtx))
1033 panic(
"Unrecognzied GDB exception.");
1045 if (c >=
'0' && c <=
'9')
1047 else if (c >=
'a' && c <=
'f')
1048 return (c -
'a' + 10);
1049 else if (c >=
'A' && c <=
'F')
1050 return (c -
'A' + 10);
1059 return (
"0123456789abcdef"[n & 0x0f]);
1067 const char *src = vsrc;
1086 while (*src && maxlen--) {
1093 *dst++ = (msb << 4) | lsb;
1104 const char *src = *srcp;
1108 while ((nibble =
digit2i(*src)) >= 0) {
virtual void setRegs(ThreadContext *) const =0
Set the ThreadContext's registers from the values in the raw buffer.
friend class HardBreakpoint
void ccprintf(cp::Print &print)
A TranslatingPortProxy in FS mode translates a virtual address to a physical address and then calls t...
void removeSoftBreak(Addr addr, size_t len)
void descheduleInstCommitEvent(Event *ev)
Deschedule an instruction count based event.
virtual bool read(Addr addr, size_t size, char *data)
int recv(char *data, int len)
HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr)
virtual bool listen(int port, bool reuse=true)
void insertSoftBreak(Addr addr, size_t len)
void deschedule(Event *event)
Deschedule the specified event.
void send(const char *data)
void clearTempBreakpoint(Addr &bkpt)
break_map_t::iterator break_iter_t
SingleStepEvent singleStepEvent
bool cmd_async_cont(GdbCommand::Context &ctx)
bool cmd_reg_r(GdbCommand::Context &ctx)
bool scheduled() const
Determine if the current event is scheduled.
#define DDUMP(x, data, count)
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
void setTempBreakpoint(Addr bkpt)
virtual void readBlob(Addr addr, uint8_t *p, int size) const
Read size bytes memory at address and store in p.
virtual BaseCPU * getCpuPtr()=0
GDBListener(BaseRemoteGDB *g, int p)
virtual TheISA::PCState pcState()=0
bool cmd_reg_w(GdbCommand::Context &ctx)
ThreadContext is the external interface to all thread state for anything outside of the CPU...
virtual char * data() const =0
Return the pointer to the raw bytes buffer containing the register values.
virtual void readBlob(Addr addr, uint8_t *p, int size) const
Version of readblob that translates virt->phys and deals with page boundries.
void schedule(PollEvent *event)
void scheduleInstCommitEvent(Event *ev, int delta)
Schedule an event which will be triggered "delta" instructions later.
bool cmd_detach(GdbCommand::Context &ctx)
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Version of writeBlob that translates virt->phys and deals with page boundries.
BaseGdbRegCache * regCachePtr
Tick curTick()
The current simulated tick.
std::string csprintf(const char *format, const Args &...args)
static const char GDBGoodP
static bool allDisabled()
Queue of events sorted in time order.
bool cmd_query_var(GdbCommand::Context &ctx)
Exception to throw when an error needs to be reported to the client.
static const char GDBStart
bool cmd_cont(GdbCommand::Context &ctx)
virtual bool acc(Addr addr, size_t len)=0
bool cmd_set_thread(GdbCommand::Context &ctx)
Exception to throw when something isn't supported.
virtual const char * hex2mem(char *, const char *, int)
bool cmd_set_hw_bkpt(GdbCommand::Context &ctx)
virtual bool checkBpLen(size_t len)
virtual int accept(bool nodelay=false)
virtual SETranslatingPortProxy & getMemProxy()=0
virtual const char * break_type(char c)
virtual void getRegs(ThreadContext *)=0
Fill the raw buffer from the registers in the ThreadContext.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
virtual bool write(Addr addr, size_t size, const char *data)
virtual BaseGdbRegCache * gdbRegs()=0
Addr hex2i(const char **)
static const char GDBBadP
bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx)
EventQueue * getComInstEventQueue()
virtual FSTranslatingPortProxy & getVirtProxy()=0
vector< BaseRemoteGDB * > debuggers
virtual const std::string name() const
bool cmd_unsupported(GdbCommand::Context &ctx)
bool cmd_mem_w(GdbCommand::Context &ctx)
void remove(PollEvent *event)
bool cmd_mem_r(GdbCommand::Context &ctx)
virtual int threadId() const =0
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
TranslatingPortProxy Object Declaration for FS.
TranslatingPortProxy Object Declaration for SE.
bool cmd_async_step(GdbCommand::Context &ctx)
virtual void mem2hex(char *, const char *, int)
Exception to throw when the connection to the client is broken.
bool cmd_signal(GdbCommand::Context &ctx)
PCEventQueue * getPcEventQueue()
static std::map< char, GdbCommand > command_map
static const int GDBPacketBufLen
bool cmd_step(GdbCommand::Context &ctx)
BaseRemoteGDB(System *system, ThreadContext *context)
void removeHardBreak(Addr addr, size_t len)
virtual void insertHardBreak(Addr addr, size_t len)
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 void process(ThreadContext *tc)
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Write size bytes from p to address.