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