cpu: Fix the usage of const DynInstPtr
[gem5.git] / src / base / remote_gdb.cc
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
9 * met: redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer;
11 * redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution;
14 * neither the name of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Authors: Nathan Binkert
31 * Boris Shingarov
32 */
33
34 /*
35 * Copyright (c) 1990, 1993 The Regents of the University of California
36 * All rights reserved
37 *
38 * This software was developed by the Computer Systems Engineering group
39 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
40 * contributed to Berkeley.
41 *
42 * All advertising materials mentioning features or use of this software
43 * must display the following acknowledgement:
44 * This product includes software developed by the University of
45 * California, Lawrence Berkeley Laboratories.
46 *
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
49 * are met:
50 * 1. Redistributions of source code must retain the above copyright
51 * notice, this list of conditions and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution.
55 * 3. All advertising materials mentioning features or use of this software
56 * must display the following acknowledgement:
57 * This product includes software developed by the University of
58 * California, Berkeley and its contributors.
59 * 4. Neither the name of the University nor the names of its contributors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * SUCH DAMAGE.
74 *
75 * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
76 */
77
78 /*-
79 * Copyright (c) 2001 The NetBSD Foundation, Inc.
80 * All rights reserved.
81 *
82 * This code is derived from software contributed to The NetBSD Foundation
83 * by Jason R. Thorpe.
84 *
85 * Redistribution and use in source and binary forms, with or without
86 * modification, are permitted provided that the following conditions
87 * are met:
88 * 1. Redistributions of source code must retain the above copyright
89 * notice, this list of conditions and the following disclaimer.
90 * 2. Redistributions in binary form must reproduce the above copyright
91 * notice, this list of conditions and the following disclaimer in the
92 * documentation and/or other materials provided with the distribution.
93 * 3. All advertising materials mentioning features or use of this software
94 * must display the following acknowledgement:
95 * This product includes software developed by the NetBSD
96 * Foundation, Inc. and its contributors.
97 * 4. Neither the name of The NetBSD Foundation nor the names of its
98 * contributors may be used to endorse or promote products derived
99 * from this software without specific prior written permission.
100 *
101 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
102 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
103 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
104 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
105 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
106 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
107 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
108 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
109 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
110 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
111 * POSSIBILITY OF SUCH DAMAGE.
112 */
113
114 /*
115 * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
116 *
117 * Taken from NetBSD
118 *
119 * "Stub" to allow remote cpu to debug over a serial line using gdb.
120 */
121
122 #include "base/remote_gdb.hh"
123
124 #include <sys/signal.h>
125 #include <unistd.h>
126
127 #include <csignal>
128 #include <cstdint>
129 #include <cstdio>
130 #include <string>
131
132 #include "arch/vtophys.hh"
133 #include "base/intmath.hh"
134 #include "base/socket.hh"
135 #include "base/trace.hh"
136 #include "config/the_isa.hh"
137 #include "cpu/base.hh"
138 #include "cpu/static_inst.hh"
139 #include "cpu/thread_context.hh"
140 #include "debug/GDBAll.hh"
141 #include "mem/fs_translating_port_proxy.hh"
142 #include "mem/port.hh"
143 #include "mem/se_translating_port_proxy.hh"
144 #include "sim/full_system.hh"
145 #include "sim/system.hh"
146
147 using namespace std;
148 using namespace TheISA;
149
150 static const char GDBStart = '$';
151 static const char GDBEnd = '#';
152 static const char GDBGoodP = '+';
153 static const char GDBBadP = '-';
154
155 static const int GDBPacketBufLen = 1024;
156
157 vector<BaseRemoteGDB *> debuggers;
158
159 class 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 override { 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
187 namespace {
188
189 // Exception to throw when the connection to the client is broken.
190 struct 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.
198 struct CmdError
199 {
200 string error;
201 CmdError(std::string _error) : error(_error)
202 {}
203 };
204
205 // Exception to throw when something isn't supported.
206 class Unsupported {};
207
208 // Convert a hex digit into an integer.
209 // This returns -1 if the argument passed is no valid hex digit.
210 int
211 digit2i(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.
224 char
225 i2digit(int n)
226 {
227 return ("0123456789abcdef"[n & 0x0f]);
228 }
229
230 // Convert a byte array into an hex string.
231 void
232 mem2hex(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.
248 const char *
249 hex2mem(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.
269 Addr
270 hex2i(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
285 enum GdbBreakpointType {
286 GdbSoftBp = '0',
287 GdbHardBp = '1',
288 GdbWriteWp = '2',
289 GdbReadWp = '3',
290 GdbAccWp = '4',
291 };
292
293 #ifndef NDEBUG
294 const char *
295 break_type(char c)
296 {
297 switch(c) {
298 case GdbSoftBp: return "software breakpoint";
299 case GdbHardBp: return "hardware breakpoint";
300 case GdbWriteWp: return "write watchpoint";
301 case GdbReadWp: return "read watchpoint";
302 case GdbAccWp: return "access watchpoint";
303 default: return "unknown breakpoint/watchpoint";
304 }
305 }
306 #endif
307
308 std::map<Addr, HardBreakpoint *> hardBreakMap;
309
310 EventQueue *
311 getComInstEventQueue(ThreadContext *tc)
312 {
313 return tc->getCpuPtr()->comInstEventQueue[tc->threadId()];
314 }
315
316 }
317
318 BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, int _port) :
319 connectEvent(nullptr), dataEvent(nullptr), _port(_port), fd(-1),
320 active(false), attached(false), sys(_system), tc(c),
321 trapEvent(this), singleStepEvent(*this)
322 {
323 debuggers.push_back(this);
324 }
325
326 BaseRemoteGDB::~BaseRemoteGDB()
327 {
328 delete connectEvent;
329 delete dataEvent;
330 }
331
332 string
333 BaseRemoteGDB::name()
334 {
335 return sys->name() + ".remote_gdb";
336 }
337
338 void
339 BaseRemoteGDB::listen()
340 {
341 if (ListenSocket::allDisabled()) {
342 warn_once("Sockets disabled, not accepting gdb connections");
343 return;
344 }
345
346 while (!listener.listen(_port, true)) {
347 DPRINTF(GDBMisc, "Can't bind port %d\n", _port);
348 _port++;
349 }
350
351 connectEvent = new ConnectEvent(this, listener.getfd(), POLLIN);
352 pollQueue.schedule(connectEvent);
353
354 ccprintf(cerr, "%d: %s: listening for remote gdb on port %d\n",
355 curTick(), name(), _port);
356 }
357
358 void
359 BaseRemoteGDB::connect()
360 {
361 panic_if(!listener.islistening(),
362 "Cannot accept GDB connections if we're not listening!");
363
364 int sfd = listener.accept(true);
365
366 if (sfd != -1) {
367 if (isAttached())
368 close(sfd);
369 else
370 attach(sfd);
371 }
372 }
373
374 int
375 BaseRemoteGDB::port() const
376 {
377 panic_if(!listener.islistening(),
378 "Remote GDB port is unknown until listen() has been called.\n");
379 return _port;
380 }
381
382 void
383 BaseRemoteGDB::attach(int f)
384 {
385 fd = f;
386
387 dataEvent = new DataEvent(this, fd, POLLIN);
388 pollQueue.schedule(dataEvent);
389
390 attached = true;
391 DPRINTFN("remote gdb attached\n");
392 }
393
394 void
395 BaseRemoteGDB::detach()
396 {
397 attached = false;
398 active = false;
399 clearSingleStep();
400 close(fd);
401 fd = -1;
402
403 pollQueue.remove(dataEvent);
404 DPRINTFN("remote gdb detached\n");
405 }
406
407 // This function does all command processing for interfacing to a
408 // remote gdb. Note that the error codes are ignored by gdb at
409 // present, but might eventually become meaningful. (XXX) It might
410 // makes sense to use POSIX errno values, because that is what the
411 // gdb/remote.c functions want to return.
412 bool
413 BaseRemoteGDB::trap(int type)
414 {
415
416 if (!attached)
417 return false;
418
419 DPRINTF(GDBMisc, "trap: PC=%s\n", tc->pcState());
420
421 clearSingleStep();
422
423 /*
424 * The first entry to this function is normally through
425 * a breakpoint trap in kgdb_connect(), in which case we
426 * must advance past the breakpoint because gdb will not.
427 *
428 * On the first entry here, we expect that gdb is not yet
429 * listening to us, so just enter the interaction loop.
430 * After the debugger is "active" (connected) it will be
431 * waiting for a "signaled" message from us.
432 */
433 if (!active) {
434 active = true;
435 } else {
436 // Tell remote host that an exception has occurred.
437 send(csprintf("S%02x", type).c_str());
438 }
439
440 // Stick frame regs into our reg cache.
441 regCachePtr = gdbRegs();
442 regCachePtr->getRegs(tc);
443
444 char data[GDBPacketBufLen + 1];
445 GdbCommand::Context cmdCtx;
446 cmdCtx.type = type;
447 cmdCtx.data = &data[1];
448
449 for (;;) {
450 try {
451 size_t datalen = recv(data, sizeof(data));
452 if (datalen < 1)
453 throw BadClient();
454
455 data[datalen] = 0; // Sentinel
456 cmdCtx.cmd_byte = data[0];
457 cmdCtx.len = datalen - 1;
458
459 auto cmdIt = command_map.find(cmdCtx.cmd_byte);
460 if (cmdIt == command_map.end()) {
461 DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
462 cmdCtx.cmd_byte, cmdCtx.cmd_byte);
463 throw Unsupported();
464 }
465 cmdCtx.cmd = &(cmdIt->second);
466
467 if (!(this->*(cmdCtx.cmd->func))(cmdCtx))
468 break;
469
470 } catch (BadClient &e) {
471 if (e.warning)
472 warn(e.warning);
473 detach();
474 break;
475 } catch (Unsupported &e) {
476 send("");
477 } catch (CmdError &e) {
478 send(e.error.c_str());
479 } catch (...) {
480 panic("Unrecognzied GDB exception.");
481 }
482 }
483
484 return true;
485 }
486
487 void
488 BaseRemoteGDB::incomingData(int revent)
489 {
490 if (trapEvent.scheduled()) {
491 warn("GDB trap event has already been scheduled!");
492 return;
493 }
494
495 if (revent & POLLIN) {
496 trapEvent.type(SIGILL);
497 scheduleInstCommitEvent(&trapEvent, 0);
498 } else if (revent & POLLNVAL) {
499 descheduleInstCommitEvent(&trapEvent);
500 detach();
501 }
502 }
503
504 uint8_t
505 BaseRemoteGDB::getbyte()
506 {
507 uint8_t b;
508 if (::read(fd, &b, sizeof(b)) == sizeof(b))
509 return b;
510
511 throw BadClient("Couldn't read data from debugger.");
512 }
513
514 void
515 BaseRemoteGDB::putbyte(uint8_t b)
516 {
517 if (::write(fd, &b, sizeof(b)) == sizeof(b))
518 return;
519
520 throw BadClient("Couldn't write data to the debugger.");
521 }
522
523 // Receive a packet from gdb
524 int
525 BaseRemoteGDB::recv(char *bp, int maxlen)
526 {
527 char *p;
528 uint8_t c;
529 int csum;
530 int len;
531
532 do {
533 p = bp;
534 csum = len = 0;
535 // Find the beginning of a packet
536 while ((c = getbyte()) != GDBStart);
537
538 // Read until you find the end of the data in the packet, and keep
539 // track of the check sum.
540 while (len < maxlen) {
541 c = getbyte();
542 if (c == GDBEnd)
543 break;
544 c &= 0x7f;
545 csum += c;
546 *p++ = c;
547 len++;
548 }
549
550 // Mask the check sum, and terminate the command string.
551 csum &= 0xff;
552 *p = '\0';
553
554 // If the command was too long, report an error.
555 if (len >= maxlen) {
556 putbyte(GDBBadP);
557 continue;
558 }
559
560 // Bring in the checksum. If the check sum matches, csum will be 0.
561 csum -= digit2i(getbyte()) * 16;
562 csum -= digit2i(getbyte());
563
564 // If the check sum was correct
565 if (csum == 0) {
566 // Report that the packet was received correctly
567 putbyte(GDBGoodP);
568 // Sequence present?
569 if (bp[2] == ':') {
570 putbyte(bp[0]);
571 putbyte(bp[1]);
572 len -= 3;
573 memcpy(bp, bp+3, len);
574 }
575 break;
576 }
577 // Otherwise, report that there was a mistake.
578 putbyte(GDBBadP);
579 } while (1);
580
581 DPRINTF(GDBRecv, "recv: %s\n", bp);
582
583 return len;
584 }
585
586 // Send a packet to gdb
587 void
588 BaseRemoteGDB::send(const char *bp)
589 {
590 const char *p;
591 uint8_t csum, c;
592
593 DPRINTF(GDBSend, "send: %s\n", bp);
594
595 do {
596 p = bp;
597 // Start sending a packet
598 putbyte(GDBStart);
599 // Send the contents, and also keep a check sum.
600 for (csum = 0; (c = *p); p++) {
601 putbyte(c);
602 csum += c;
603 }
604 // Send the ending character.
605 putbyte(GDBEnd);
606 // Send the checksum.
607 putbyte(i2digit(csum >> 4));
608 putbyte(i2digit(csum));
609 // Try transmitting over and over again until the other end doesn't
610 // send an error back.
611 c = getbyte();
612 } while ((c & 0x7f) == GDBBadP);
613 }
614
615 // Read bytes from kernel address space for debugger.
616 bool
617 BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
618 {
619 static Addr lastaddr = 0;
620 static size_t lastsize = 0;
621
622 if (vaddr < 10) {
623 DPRINTF(GDBRead, "read: reading memory location zero!\n");
624 vaddr = lastaddr + lastsize;
625 }
626
627 DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
628
629 if (FullSystem) {
630 FSTranslatingPortProxy &proxy = tc->getVirtProxy();
631 proxy.readBlob(vaddr, (uint8_t*)data, size);
632 } else {
633 SETranslatingPortProxy &proxy = tc->getMemProxy();
634 proxy.readBlob(vaddr, (uint8_t*)data, size);
635 }
636
637 #if TRACING_ON
638 if (DTRACE(GDBRead)) {
639 if (DTRACE(GDBExtra)) {
640 char buf[1024];
641 mem2hex(buf, data, size);
642 DPRINTFNR(": %s\n", buf);
643 } else
644 DPRINTFNR("\n");
645 }
646 #endif
647
648 return true;
649 }
650
651 // Write bytes to kernel address space for debugger.
652 bool
653 BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
654 {
655 static Addr lastaddr = 0;
656 static size_t lastsize = 0;
657
658 if (vaddr < 10) {
659 DPRINTF(GDBWrite, "write: writing memory location zero!\n");
660 vaddr = lastaddr + lastsize;
661 }
662
663 if (DTRACE(GDBWrite)) {
664 DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
665 if (DTRACE(GDBExtra)) {
666 char buf[1024];
667 mem2hex(buf, data, size);
668 DPRINTFNR(": %s\n", buf);
669 } else
670 DPRINTFNR("\n");
671 }
672 if (FullSystem) {
673 FSTranslatingPortProxy &proxy = tc->getVirtProxy();
674 proxy.writeBlob(vaddr, (uint8_t*)data, size);
675 } else {
676 SETranslatingPortProxy &proxy = tc->getMemProxy();
677 proxy.writeBlob(vaddr, (uint8_t*)data, size);
678 }
679
680 return true;
681 }
682
683 void
684 BaseRemoteGDB::singleStep()
685 {
686 if (!singleStepEvent.scheduled())
687 scheduleInstCommitEvent(&singleStepEvent, 1);
688 trap(SIGTRAP);
689 }
690
691 void
692 BaseRemoteGDB::clearSingleStep()
693 {
694 descheduleInstCommitEvent(&singleStepEvent);
695 }
696
697 void
698 BaseRemoteGDB::setSingleStep()
699 {
700 if (!singleStepEvent.scheduled())
701 scheduleInstCommitEvent(&singleStepEvent, 1);
702 }
703
704 void
705 BaseRemoteGDB::insertSoftBreak(Addr addr, size_t len)
706 {
707 if (!checkBpLen(len))
708 throw BadClient("Invalid breakpoint length\n");
709
710 return insertHardBreak(addr, len);
711 }
712
713 void
714 BaseRemoteGDB::removeSoftBreak(Addr addr, size_t len)
715 {
716 if (!checkBpLen(len))
717 throw BadClient("Invalid breakpoint length.\n");
718
719 return removeHardBreak(addr, len);
720 }
721
722 void
723 BaseRemoteGDB::insertHardBreak(Addr addr, size_t len)
724 {
725 if (!checkBpLen(len))
726 throw BadClient("Invalid breakpoint length\n");
727
728 DPRINTF(GDBMisc, "Inserting hardware breakpoint at %#x\n", addr);
729
730 HardBreakpoint *&bkpt = hardBreakMap[addr];
731 if (bkpt == 0)
732 bkpt = new HardBreakpoint(this, &sys->pcEventQueue, addr);
733
734 bkpt->refcount++;
735 }
736
737 void
738 BaseRemoteGDB::removeHardBreak(Addr addr, size_t len)
739 {
740 if (!checkBpLen(len))
741 throw BadClient("Invalid breakpoint length\n");
742
743 DPRINTF(GDBMisc, "Removing hardware breakpoint at %#x\n", addr);
744
745 auto i = hardBreakMap.find(addr);
746 if (i == hardBreakMap.end())
747 throw CmdError("E0C");
748
749 HardBreakpoint *hbp = (*i).second;
750 if (--hbp->refcount == 0) {
751 delete hbp;
752 hardBreakMap.erase(i);
753 }
754 }
755
756 void
757 BaseRemoteGDB::clearTempBreakpoint(Addr &bkpt)
758 {
759 DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
760 removeHardBreak(bkpt, sizeof(TheISA::MachInst));
761 bkpt = 0;
762 }
763
764 void
765 BaseRemoteGDB::setTempBreakpoint(Addr bkpt)
766 {
767 DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
768 insertHardBreak(bkpt, sizeof(TheISA::MachInst));
769 }
770
771 void
772 BaseRemoteGDB::scheduleInstCommitEvent(Event *ev, int delta)
773 {
774 EventQueue *eq = getComInstEventQueue(tc);
775 // Here "ticks" aren't simulator ticks which measure time, they're
776 // instructions committed by the CPU.
777 eq->schedule(ev, eq->getCurTick() + delta);
778 }
779
780 void
781 BaseRemoteGDB::descheduleInstCommitEvent(Event *ev)
782 {
783 if (ev->scheduled())
784 getComInstEventQueue(tc)->deschedule(ev);
785 }
786
787 std::map<char, BaseRemoteGDB::GdbCommand> BaseRemoteGDB::command_map = {
788 // last signal
789 { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmd_signal } },
790 // set baud (deprecated)
791 { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmd_unsupported } },
792 // set breakpoint (deprecated)
793 { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmd_unsupported } },
794 // resume
795 { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmd_cont } },
796 // continue with signal
797 { 'C', { "KGDB_ASYNC_CONT", &BaseRemoteGDB::cmd_async_cont } },
798 // toggle debug flags (deprecated)
799 { 'd', { "KGDB_DEBUG", &BaseRemoteGDB::cmd_unsupported } },
800 // detach remote gdb
801 { 'D', { "KGDB_DETACH", &BaseRemoteGDB::cmd_detach } },
802 // read general registers
803 { 'g', { "KGDB_REG_R", &BaseRemoteGDB::cmd_reg_r } },
804 // write general registers
805 { 'G', { "KGDB_REG_W", &BaseRemoteGDB::cmd_reg_w } },
806 // set thread
807 { 'H', { "KGDB_SET_THREAD", &BaseRemoteGDB::cmd_set_thread } },
808 // step a single cycle
809 { 'i', { "KGDB_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported } },
810 // signal then cycle step
811 { 'I', { "KGDB_SIG_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported } },
812 // kill program
813 { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmd_detach } },
814 // read memory
815 { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmd_mem_r } },
816 // write memory
817 { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmd_mem_w } },
818 // read register
819 { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmd_unsupported } },
820 // write register
821 { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmd_unsupported } },
822 // query variable
823 { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmd_query_var } },
824 // set variable
825 { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmd_unsupported } },
826 // reset system (deprecated)
827 { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmd_unsupported } },
828 // step
829 { 's', { "KGDB_STEP", &BaseRemoteGDB::cmd_step } },
830 // signal and step
831 { 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmd_async_step } },
832 // find out if the thread is alive
833 { 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmd_unsupported } },
834 // target exited
835 { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmd_unsupported } },
836 // write memory
837 { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmd_unsupported } },
838 // remove breakpoint or watchpoint
839 { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmd_clr_hw_bkpt } },
840 // insert breakpoint or watchpoint
841 { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmd_set_hw_bkpt } },
842 };
843
844 bool
845 BaseRemoteGDB::checkBpLen(size_t len)
846 {
847 return len == sizeof(MachInst);
848 }
849
850 bool
851 BaseRemoteGDB::cmd_unsupported(GdbCommand::Context &ctx)
852 {
853 DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
854 DDUMP(GDBMisc, ctx.data, ctx.len);
855 throw Unsupported();
856 }
857
858
859 bool
860 BaseRemoteGDB::cmd_signal(GdbCommand::Context &ctx)
861 {
862 send(csprintf("S%02x", ctx.type).c_str());
863 return true;
864 }
865
866 bool
867 BaseRemoteGDB::cmd_cont(GdbCommand::Context &ctx)
868 {
869 const char *p = ctx.data;
870 if (ctx.len) {
871 Addr newPc = hex2i(&p);
872 tc->pcState(newPc);
873 }
874 clearSingleStep();
875 return false;
876 }
877
878 bool
879 BaseRemoteGDB::cmd_async_cont(GdbCommand::Context &ctx)
880 {
881 const char *p = ctx.data;
882 hex2i(&p);
883 if (*p++ == ';') {
884 Addr newPc = hex2i(&p);
885 tc->pcState(newPc);
886 }
887 clearSingleStep();
888 return false;
889 }
890
891 bool
892 BaseRemoteGDB::cmd_detach(GdbCommand::Context &ctx)
893 {
894 detach();
895 return false;
896 }
897
898 bool
899 BaseRemoteGDB::cmd_reg_r(GdbCommand::Context &ctx)
900 {
901 char buf[2 * regCachePtr->size() + 1];
902 buf[2 * regCachePtr->size()] = '\0';
903 mem2hex(buf, regCachePtr->data(), regCachePtr->size());
904 send(buf);
905 return true;
906 }
907
908 bool
909 BaseRemoteGDB::cmd_reg_w(GdbCommand::Context &ctx)
910 {
911 const char *p = ctx.data;
912 p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
913 if (p == NULL || *p != '\0')
914 throw CmdError("E01");
915
916 regCachePtr->setRegs(tc);
917 send("OK");
918
919 return true;
920 }
921
922 bool
923 BaseRemoteGDB::cmd_set_thread(GdbCommand::Context &ctx)
924 {
925 const char *p = ctx.data + 1; // Ignore the subcommand byte.
926 if (hex2i(&p) != 0)
927 throw CmdError("E01");
928 send("OK");
929 return true;
930 }
931
932 bool
933 BaseRemoteGDB::cmd_mem_r(GdbCommand::Context &ctx)
934 {
935 const char *p = ctx.data;
936 Addr addr = hex2i(&p);
937 if (*p++ != ',')
938 throw CmdError("E02");
939 size_t len = hex2i(&p);
940 if (*p != '\0')
941 throw CmdError("E03");
942 if (!acc(addr, len))
943 throw CmdError("E05");
944
945 char buf[len];
946 if (!read(addr, len, buf))
947 throw CmdError("E05");
948
949 char temp[2 * len + 1];
950 temp[2 * len] = '\0';
951 mem2hex(temp, buf, len);
952 send(temp);
953 return true;
954 }
955
956 bool
957 BaseRemoteGDB::cmd_mem_w(GdbCommand::Context &ctx)
958 {
959 const char *p = ctx.data;
960 Addr addr = hex2i(&p);
961 if (*p++ != ',')
962 throw CmdError("E06");
963 size_t len = hex2i(&p);
964 if (*p++ != ':')
965 throw CmdError("E07");
966 if (len * 2 > ctx.len - (p - ctx.data))
967 throw CmdError("E08");
968 char buf[len];
969 p = (char *)hex2mem(buf, p, len);
970 if (p == NULL)
971 throw CmdError("E09");
972 if (!acc(addr, len))
973 throw CmdError("E0A");
974 if (!write(addr, len, buf))
975 throw CmdError("E0B");
976 send("OK");
977 return true;
978 }
979
980 bool
981 BaseRemoteGDB::cmd_query_var(GdbCommand::Context &ctx)
982 {
983 if (string(ctx.data, ctx.len - 1) != "C")
984 throw Unsupported();
985 send("QC0");
986 return true;
987 }
988
989 bool
990 BaseRemoteGDB::cmd_async_step(GdbCommand::Context &ctx)
991 {
992 const char *p = ctx.data;
993 hex2i(&p); // Ignore the subcommand byte.
994 if (*p++ == ';') {
995 Addr newPc = hex2i(&p);
996 tc->pcState(newPc);
997 }
998 setSingleStep();
999 return false;
1000 }
1001
1002 bool
1003 BaseRemoteGDB::cmd_step(GdbCommand::Context &ctx)
1004 {
1005 if (ctx.len) {
1006 const char *p = ctx.data;
1007 Addr newPc = hex2i(&p);
1008 tc->pcState(newPc);
1009 }
1010 setSingleStep();
1011 return false;
1012 }
1013
1014 bool
1015 BaseRemoteGDB::cmd_clr_hw_bkpt(GdbCommand::Context &ctx)
1016 {
1017 const char *p = ctx.data;
1018 char subcmd = *p++;
1019 if (*p++ != ',')
1020 throw CmdError("E0D");
1021 Addr addr = hex2i(&p);
1022 if (*p++ != ',')
1023 throw CmdError("E0D");
1024 size_t len = hex2i(&p);
1025
1026 DPRINTF(GDBMisc, "clear %s, addr=%#x, len=%d\n",
1027 break_type(subcmd), addr, len);
1028
1029 switch (subcmd) {
1030 case GdbSoftBp:
1031 removeSoftBreak(addr, len);
1032 break;
1033 case GdbHardBp:
1034 removeHardBreak(addr, len);
1035 break;
1036 case GdbWriteWp:
1037 case GdbReadWp:
1038 case GdbAccWp:
1039 default: // unknown
1040 throw Unsupported();
1041 }
1042 send("OK");
1043
1044 return true;
1045 }
1046
1047 bool
1048 BaseRemoteGDB::cmd_set_hw_bkpt(GdbCommand::Context &ctx)
1049 {
1050 const char *p = ctx.data;
1051 char subcmd = *p++;
1052 if (*p++ != ',')
1053 throw CmdError("E0D");
1054 Addr addr = hex2i(&p);
1055 if (*p++ != ',')
1056 throw CmdError("E0D");
1057 size_t len = hex2i(&p);
1058
1059 DPRINTF(GDBMisc, "set %s, addr=%#x, len=%d\n",
1060 break_type(subcmd), addr, len);
1061
1062 switch (subcmd) {
1063 case GdbSoftBp:
1064 insertSoftBreak(addr, len);
1065 break;
1066 case GdbHardBp:
1067 insertHardBreak(addr, len);
1068 break;
1069 case GdbWriteWp:
1070 case GdbReadWp:
1071 case GdbAccWp:
1072 default: // unknown
1073 throw Unsupported();
1074 }
1075 send("OK");
1076
1077 return true;
1078 }