Deleted Added
sdiff udiff text old ( 12125:0066d9926c1a ) new ( 12449:2260f4a68210 )
full compact
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

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

149
150static const char GDBStart = '$';
151static const char GDBEnd = '#';
152static const char GDBGoodP = '+';
153static const char GDBBadP = '-';
154
155static const int GDBPacketBufLen = 1024;
156
157vector<BaseRemoteGDB *> debuggers;
158
159class HardBreakpoint : public PCEvent
160{
161 private:
162 BaseRemoteGDB *gdb;
163
164 public:
165 int refcount;
166
167 public:
168 HardBreakpoint(BaseRemoteGDB *_gdb, PCEventQueue *q, Addr pc)
169 : PCEvent(q, "HardBreakpoint Event", pc),
170 gdb(_gdb), refcount(0)
171 {
172 DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
173 }
174
175 const std::string name() const { return gdb->name() + ".hwbkpt"; }
176
177 void
178 process(ThreadContext *tc) override
179 {
180 DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
181
182 if (tc == gdb->tc)
183 gdb->trap(SIGTRAP);
184 }
185};
186
187namespace {
188
189// Exception to throw when the connection to the client is broken.
190struct BadClient
191{
192 const char *warning;
193 BadClient(const char *_warning=NULL) : warning(_warning)
194 {}
195};
196
197// Exception to throw when an error needs to be reported to the client.
198struct CmdError
199{
200 string error;
201 CmdError(std::string _error) : error(_error)
202 {}
203};
204
205// Exception to throw when something isn't supported.
206class Unsupported {};
207
208// Convert a hex digit into an integer.
209// This returns -1 if the argument passed is no valid hex digit.
210int
211digit2i(char c)
212{
213 if (c >= '0' && c <= '9')
214 return (c - '0');
215 else if (c >= 'a' && c <= 'f')
216 return (c - 'a' + 10);
217 else if (c >= 'A' && c <= 'F')
218 return (c - 'A' + 10);
219 else
220 return (-1);
221}
222
223// Convert the low 4 bits of an integer into an hex digit.
224char
225i2digit(int n)
226{
227 return ("0123456789abcdef"[n & 0x0f]);
228}
229
230// Convert a byte array into an hex string.
231void
232mem2hex(char *vdst, const char *vsrc, int len)
233{
234 char *dst = vdst;
235 const char *src = vsrc;
236
237 while (len--) {
238 *dst++ = i2digit(*src >> 4);
239 *dst++ = i2digit(*src++);
240 }
241 *dst = '\0';
242}
243
244// Convert an hex string into a byte array.
245// This returns a pointer to the character following the last valid
246// hex digit. If the string ends in the middle of a byte, NULL is
247// returned.
248const char *
249hex2mem(char *vdst, const char *src, int maxlen)
250{
251 char *dst = vdst;
252 int msb, lsb;
253
254 while (*src && maxlen--) {
255 msb = digit2i(*src++);
256 if (msb < 0)
257 return (src - 1);
258 lsb = digit2i(*src++);
259 if (lsb < 0)
260 return (NULL);
261 *dst++ = (msb << 4) | lsb;
262 }
263 return src;
264}
265
266// Convert an hex string into an integer.
267// This returns a pointer to the character following the last valid
268// hex digit.
269Addr
270hex2i(const char **srcp)
271{
272 const char *src = *srcp;
273 Addr r = 0;
274 int nibble;
275
276 while ((nibble = digit2i(*src)) >= 0) {
277 r *= 16;
278 r += nibble;
279 src++;
280 }
281 *srcp = src;
282 return r;
283}
284
285enum GdbBreakpointType {
286 GdbSoftBp = '0',
287 GdbHardBp = '1',
288 GdbWriteWp = '2',
289 GdbReadWp = '3',
290 GdbAccWp = '4',
291};
292
293const char *
294break_type(char c)
295{
296 switch(c) {
297 case GdbSoftBp: return "software breakpoint";
298 case GdbHardBp: return "hardware breakpoint";
299 case GdbWriteWp: return "write watchpoint";
300 case GdbReadWp: return "read watchpoint";
301 case GdbAccWp: return "access watchpoint";
302 default: return "unknown breakpoint/watchpoint";
303 }
304}
305
306std::map<Addr, HardBreakpoint *> hardBreakMap;
307
308EventQueue *
309getComInstEventQueue(ThreadContext *tc)
310{
311 return tc->getCpuPtr()->comInstEventQueue[tc->threadId()];
312}
313
314}
315
316BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, int _port) :
317 connectEvent(nullptr), dataEvent(nullptr), _port(_port), fd(-1),
318 active(false), attached(false), sys(_system), tc(c),
319 trapEvent(this), singleStepEvent(*this)
320{
321 debuggers.push_back(this);
322}
323
324BaseRemoteGDB::~BaseRemoteGDB()
325{
326 delete connectEvent;
327 delete dataEvent;
328}
329
330string
331BaseRemoteGDB::name()
332{
333 return sys->name() + ".remote_gdb";
334}
335
336void
337BaseRemoteGDB::listen()
338{
339 if (ListenSocket::allDisabled()) {
340 warn_once("Sockets disabled, not accepting gdb connections");
341 return;
342 }
343
344 while (!listener.listen(_port, true)) {
345 DPRINTF(GDBMisc, "Can't bind port %d\n", _port);
346 _port++;
347 }
348
349 connectEvent = new ConnectEvent(this, listener.getfd(), POLLIN);
350 pollQueue.schedule(connectEvent);
351
352 ccprintf(cerr, "%d: %s: listening for remote gdb on port %d\n",
353 curTick(), name(), _port);
354}
355
356void
357BaseRemoteGDB::connect()
358{
359 panic_if(!listener.islistening(),
360 "Cannot accept GDB connections if we're not listening!");
361
362 int sfd = listener.accept(true);
363
364 if (sfd != -1) {
365 if (isAttached())
366 close(sfd);
367 else
368 attach(sfd);
369 }
370}
371
372int
373BaseRemoteGDB::port() const
374{
375 panic_if(!listener.islistening(),
376 "Remote GDB port is unknown until listen() has been called.\n");
377 return _port;
378}
379
380void
381BaseRemoteGDB::attach(int f)
382{
383 fd = f;
384
385 dataEvent = new DataEvent(this, fd, POLLIN);
386 pollQueue.schedule(dataEvent);
387
388 attached = true;
389 DPRINTFN("remote gdb attached\n");
390}
391
392void
393BaseRemoteGDB::detach()
394{
395 attached = false;
396 active = false;
397 clearSingleStep();
398 close(fd);
399 fd = -1;
400
401 pollQueue.remove(dataEvent);
402 DPRINTFN("remote gdb detached\n");
403}
404
405// This function does all command processing for interfacing to a
406// remote gdb. Note that the error codes are ignored by gdb at
407// present, but might eventually become meaningful. (XXX) It might
408// makes sense to use POSIX errno values, because that is what the
409// gdb/remote.c functions want to return.
410bool
411BaseRemoteGDB::trap(int type)
412{
413
414 if (!attached)
415 return false;
416
417 DPRINTF(GDBMisc, "trap: PC=%s\n", tc->pcState());
418
419 clearSingleStep();
420
421 /*
422 * The first entry to this function is normally through
423 * a breakpoint trap in kgdb_connect(), in which case we
424 * must advance past the breakpoint because gdb will not.
425 *
426 * On the first entry here, we expect that gdb is not yet
427 * listening to us, so just enter the interaction loop.
428 * After the debugger is "active" (connected) it will be
429 * waiting for a "signaled" message from us.
430 */
431 if (!active) {
432 active = true;
433 } else {
434 // Tell remote host that an exception has occurred.
435 send(csprintf("S%02x", type).c_str());
436 }
437
438 // Stick frame regs into our reg cache.
439 regCachePtr = gdbRegs();
440 regCachePtr->getRegs(tc);
441
442 char data[GDBPacketBufLen + 1];
443 GdbCommand::Context cmdCtx;
444 cmdCtx.type = type;
445 cmdCtx.data = &data[1];
446
447 for (;;) {
448 try {
449 size_t datalen = recv(data, sizeof(data));
450 if (datalen < 1)
451 throw BadClient();
452
453 data[datalen] = 0; // Sentinel
454 cmdCtx.cmd_byte = data[0];
455 cmdCtx.len = datalen - 1;
456
457 auto cmdIt = command_map.find(cmdCtx.cmd_byte);
458 if (cmdIt == command_map.end()) {
459 DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
460 cmdCtx.cmd_byte, cmdCtx.cmd_byte);
461 throw Unsupported();
462 }
463 cmdCtx.cmd = &(cmdIt->second);
464
465 if (!(this->*(cmdCtx.cmd->func))(cmdCtx))
466 break;
467
468 } catch (BadClient &e) {
469 if (e.warning)
470 warn(e.warning);
471 detach();
472 break;
473 } catch (Unsupported &e) {
474 send("");
475 } catch (CmdError &e) {
476 send(e.error.c_str());
477 } catch (...) {
478 panic("Unrecognzied GDB exception.");
479 }
480 }
481
482 return true;
483}
484
485void
486BaseRemoteGDB::incomingData(int revent)
487{
488 if (trapEvent.scheduled()) {
489 warn("GDB trap event has already been scheduled!");
490 return;
491 }
492
493 if (revent & POLLIN) {
494 trapEvent.type(SIGILL);
495 scheduleInstCommitEvent(&trapEvent, 0);
496 } else if (revent & POLLNVAL) {
497 descheduleInstCommitEvent(&trapEvent);
498 detach();
499 }
500}
501
502uint8_t
503BaseRemoteGDB::getbyte()
504{
505 uint8_t b;
506 if (::read(fd, &b, sizeof(b)) == sizeof(b))
507 return b;
508
509 throw BadClient("Couldn't read data from debugger.");
510}
511
512void
513BaseRemoteGDB::putbyte(uint8_t b)
514{
515 if (::write(fd, &b, sizeof(b)) == sizeof(b))
516 return;
517
518 throw BadClient("Couldn't write data to the debugger.");
519}
520
521// Receive a packet from gdb
522int
523BaseRemoteGDB::recv(char *bp, int maxlen)
524{
525 char *p;
526 uint8_t c;
527 int csum;
528 int len;

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

576 putbyte(GDBBadP);
577 } while (1);
578
579 DPRINTF(GDBRecv, "recv: %s\n", bp);
580
581 return len;
582}
583
584// Send a packet to gdb
585void
586BaseRemoteGDB::send(const char *bp)
587{
588 const char *p;
589 uint8_t csum, c;
590
591 DPRINTF(GDBSend, "send: %s\n", bp);
592
593 do {
594 p = bp;
595 // Start sending a packet
596 putbyte(GDBStart);
597 // Send the contents, and also keep a check sum.
598 for (csum = 0; (c = *p); p++) {
599 putbyte(c);
600 csum += c;
601 }
602 // Send the ending character.
603 putbyte(GDBEnd);
604 // Send the checksum.
605 putbyte(i2digit(csum >> 4));
606 putbyte(i2digit(csum));
607 // Try transmitting over and over again until the other end doesn't
608 // send an error back.
609 c = getbyte();
610 } while ((c & 0x7f) == GDBBadP);
611}
612
613// Read bytes from kernel address space for debugger.
614bool
615BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
616{
617 static Addr lastaddr = 0;
618 static size_t lastsize = 0;
619
620 if (vaddr < 10) {
621 DPRINTF(GDBRead, "read: reading memory location zero!\n");
622 vaddr = lastaddr + lastsize;
623 }
624
625 DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
626
627 if (FullSystem) {
628 FSTranslatingPortProxy &proxy = tc->getVirtProxy();
629 proxy.readBlob(vaddr, (uint8_t*)data, size);
630 } else {
631 SETranslatingPortProxy &proxy = tc->getMemProxy();
632 proxy.readBlob(vaddr, (uint8_t*)data, size);
633 }
634
635#if TRACING_ON
636 if (DTRACE(GDBRead)) {
637 if (DTRACE(GDBExtra)) {
638 char buf[1024];
639 mem2hex(buf, data, size);

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

663 if (DTRACE(GDBExtra)) {
664 char buf[1024];
665 mem2hex(buf, data, size);
666 DPRINTFNR(": %s\n", buf);
667 } else
668 DPRINTFNR("\n");
669 }
670 if (FullSystem) {
671 FSTranslatingPortProxy &proxy = tc->getVirtProxy();
672 proxy.writeBlob(vaddr, (uint8_t*)data, size);
673 } else {
674 SETranslatingPortProxy &proxy = tc->getMemProxy();
675 proxy.writeBlob(vaddr, (uint8_t*)data, size);
676 }
677
678 return true;
679}
680
681void
682BaseRemoteGDB::singleStep()
683{
684 if (!singleStepEvent.scheduled())
685 scheduleInstCommitEvent(&singleStepEvent, 1);
686 trap(SIGTRAP);
687}
688
689void
690BaseRemoteGDB::clearSingleStep()
691{
692 descheduleInstCommitEvent(&singleStepEvent);
693}
694
695void
696BaseRemoteGDB::setSingleStep()
697{
698 if (!singleStepEvent.scheduled())
699 scheduleInstCommitEvent(&singleStepEvent, 1);
700}
701
702void
703BaseRemoteGDB::insertSoftBreak(Addr addr, size_t len)
704{
705 if (!checkBpLen(len))
706 throw BadClient("Invalid breakpoint length\n");
707
708 return insertHardBreak(addr, len);
709}
710

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

722{
723 if (!checkBpLen(len))
724 throw BadClient("Invalid breakpoint length\n");
725
726 DPRINTF(GDBMisc, "Inserting hardware breakpoint at %#x\n", addr);
727
728 HardBreakpoint *&bkpt = hardBreakMap[addr];
729 if (bkpt == 0)
730 bkpt = new HardBreakpoint(this, &sys->pcEventQueue, addr);
731
732 bkpt->refcount++;
733}
734
735void
736BaseRemoteGDB::removeHardBreak(Addr addr, size_t len)
737{
738 if (!checkBpLen(len))
739 throw BadClient("Invalid breakpoint length\n");
740
741 DPRINTF(GDBMisc, "Removing hardware breakpoint at %#x\n", addr);
742
743 auto i = hardBreakMap.find(addr);
744 if (i == hardBreakMap.end())
745 throw CmdError("E0C");
746
747 HardBreakpoint *hbp = (*i).second;
748 if (--hbp->refcount == 0) {
749 delete hbp;
750 hardBreakMap.erase(i);
751 }
752}
753
754void
755BaseRemoteGDB::clearTempBreakpoint(Addr &bkpt)
756{
757 DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
758 removeHardBreak(bkpt, sizeof(TheISA::MachInst));
759 bkpt = 0;
760}
761
762void
763BaseRemoteGDB::setTempBreakpoint(Addr bkpt)
764{
765 DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
766 insertHardBreak(bkpt, sizeof(TheISA::MachInst));
767}
768
769void
770BaseRemoteGDB::scheduleInstCommitEvent(Event *ev, int delta)
771{
772 EventQueue *eq = getComInstEventQueue(tc);
773 // Here "ticks" aren't simulator ticks which measure time, they're
774 // instructions committed by the CPU.
775 eq->schedule(ev, eq->getCurTick() + delta);
776}
777
778void
779BaseRemoteGDB::descheduleInstCommitEvent(Event *ev)
780{
781 if (ev->scheduled())
782 getComInstEventQueue(tc)->deschedule(ev);
783}
784
785std::map<char, BaseRemoteGDB::GdbCommand> BaseRemoteGDB::command_map = {
786 // last signal
787 { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmd_signal } },
788 // set baud (deprecated)
789 { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmd_unsupported } },
790 // set breakpoint (deprecated)
791 { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmd_unsupported } },
792 // resume
793 { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmd_cont } },

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

834 // write memory
835 { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmd_unsupported } },
836 // remove breakpoint or watchpoint
837 { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmd_clr_hw_bkpt } },
838 // insert breakpoint or watchpoint
839 { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmd_set_hw_bkpt } },
840};
841
842bool
843BaseRemoteGDB::checkBpLen(size_t len)
844{
845 return len == sizeof(MachInst);
846}
847
848bool
849BaseRemoteGDB::cmd_unsupported(GdbCommand::Context &ctx)
850{
851 DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
852 DDUMP(GDBMisc, ctx.data, ctx.len);
853 throw Unsupported();
854}

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

862}
863
864bool
865BaseRemoteGDB::cmd_cont(GdbCommand::Context &ctx)
866{
867 const char *p = ctx.data;
868 if (ctx.len) {
869 Addr newPc = hex2i(&p);
870 tc->pcState(newPc);
871 }
872 clearSingleStep();
873 return false;
874}
875
876bool
877BaseRemoteGDB::cmd_async_cont(GdbCommand::Context &ctx)
878{
879 const char *p = ctx.data;
880 hex2i(&p);
881 if (*p++ == ';') {
882 Addr newPc = hex2i(&p);
883 tc->pcState(newPc);
884 }
885 clearSingleStep();
886 return false;
887}
888
889bool
890BaseRemoteGDB::cmd_detach(GdbCommand::Context &ctx)
891{

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

906bool
907BaseRemoteGDB::cmd_reg_w(GdbCommand::Context &ctx)
908{
909 const char *p = ctx.data;
910 p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
911 if (p == NULL || *p != '\0')
912 throw CmdError("E01");
913
914 regCachePtr->setRegs(tc);
915 send("OK");
916
917 return true;
918}
919
920bool
921BaseRemoteGDB::cmd_set_thread(GdbCommand::Context &ctx)
922{

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

986
987bool
988BaseRemoteGDB::cmd_async_step(GdbCommand::Context &ctx)
989{
990 const char *p = ctx.data;
991 hex2i(&p); // Ignore the subcommand byte.
992 if (*p++ == ';') {
993 Addr newPc = hex2i(&p);
994 tc->pcState(newPc);
995 }
996 setSingleStep();
997 return false;
998}
999
1000bool
1001BaseRemoteGDB::cmd_step(GdbCommand::Context &ctx)
1002{
1003 if (ctx.len) {
1004 const char *p = ctx.data;
1005 Addr newPc = hex2i(&p);
1006 tc->pcState(newPc);
1007 }
1008 setSingleStep();
1009 return false;
1010}
1011
1012bool
1013BaseRemoteGDB::cmd_clr_hw_bkpt(GdbCommand::Context &ctx)
1014{

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

1069 case GdbAccWp:
1070 default: // unknown
1071 throw Unsupported();
1072 }
1073 send("OK");
1074
1075 return true;
1076}