2 * Copyright (c) 2018 ARM Limited
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.
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.
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.
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.
43 * Copyright (c) 1990, 1993 The Regents of the University of California
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.
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.
55 * Redistribution and use in source and binary forms, with or without
56 * modification, are permitted provided that the following conditions
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.
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
83 * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
87 * Copyright (c) 2001 The NetBSD Foundation, Inc.
88 * All rights reserved.
90 * This code is derived from software contributed to The NetBSD Foundation
93 * Redistribution and use in source and binary forms, with or without
94 * modification, are permitted provided that the following conditions
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.
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.
123 * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
127 * "Stub" to allow remote cpu to debug over a serial line using gdb.
130 #include "base/remote_gdb.hh"
132 #include <sys/signal.h>
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"
153 static const char GDBStart
= '$';
154 static const char GDBEnd
= '#';
155 static const char GDBGoodP
= '+';
156 static const char GDBBadP
= '-';
158 std::vector
<BaseRemoteGDB
*> debuggers
;
160 class HardBreakpoint
: public PCEvent
169 HardBreakpoint(BaseRemoteGDB
*_gdb
, PCEventScope
*s
, Addr pc
)
170 : PCEvent(s
, "HardBreakpoint Event", pc
),
171 gdb(_gdb
), refcount(0)
173 DPRINTF(GDBMisc
, "creating hardware breakpoint at %#x\n", evpc
);
176 const std::string
name() const override
{ return gdb
->name() + ".hwbkpt"; }
179 process(ThreadContext
*tc
) override
181 DPRINTF(GDBMisc
, "handling hardware breakpoint at %#x\n", pc());
190 // Exception to throw when the connection to the client is broken.
194 BadClient(const char *_warning
=NULL
) : warning(_warning
)
198 // Exception to throw when an error needs to be reported to the client.
202 CmdError(std::string _error
) : error(_error
)
206 // Exception to throw when something isn't supported.
207 class Unsupported
{};
209 // Convert a hex digit into an integer.
210 // This returns -1 if the argument passed is no valid hex digit.
214 if (c
>= '0' && c
<= '9')
216 else if (c
>= 'a' && c
<= 'f')
217 return (c
- 'a' + 10);
218 else if (c
>= 'A' && c
<= 'F')
219 return (c
- 'A' + 10);
224 // Convert the low 4 bits of an integer into an hex digit.
228 return ("0123456789abcdef"[n
& 0x0f]);
231 // Convert a byte array into an hex string.
233 mem2hex(char *vdst
, const char *vsrc
, int len
)
236 const char *src
= vsrc
;
239 *dst
++ = i2digit(*src
>> 4);
240 *dst
++ = i2digit(*src
++);
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
250 hex2mem(char *vdst
, const char *src
, int maxlen
)
255 while (*src
&& maxlen
--) {
256 msb
= digit2i(*src
++);
259 lsb
= digit2i(*src
++);
262 *dst
++ = (msb
<< 4) | lsb
;
267 // Convert an hex string into an integer.
268 // This returns a pointer to the character following the last valid
271 hex2i(const char **srcp
)
273 const char *src
= *srcp
;
277 while ((nibble
= digit2i(*src
)) >= 0) {
286 enum GdbBreakpointType
{
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";
309 std::map
<Addr
, HardBreakpoint
*> hardBreakMap
;
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)
318 debuggers
.push_back(this);
321 BaseRemoteGDB::~BaseRemoteGDB()
328 BaseRemoteGDB::name()
330 return sys
->name() + ".remote_gdb";
334 BaseRemoteGDB::listen()
336 if (ListenSocket::allDisabled()) {
337 warn_once("Sockets disabled, not accepting gdb connections");
341 while (!listener
.listen(_port
, true)) {
342 DPRINTF(GDBMisc
, "Can't bind port %d\n", _port
);
346 connectEvent
= new ConnectEvent(this, listener
.getfd(), POLLIN
);
347 pollQueue
.schedule(connectEvent
);
349 ccprintf(std::cerr
, "%d: %s: listening for remote gdb on port %d\n",
350 curTick(), name(), _port
);
354 BaseRemoteGDB::connect()
356 panic_if(!listener
.islistening(),
357 "Cannot accept GDB connections if we're not listening!");
359 int sfd
= listener
.accept(true);
370 BaseRemoteGDB::port() const
372 panic_if(!listener
.islistening(),
373 "Remote GDB port is unknown until listen() has been called.\n");
378 BaseRemoteGDB::attach(int f
)
382 dataEvent
= new DataEvent(this, fd
, POLLIN
);
383 pollQueue
.schedule(dataEvent
);
386 DPRINTFN("remote gdb attached\n");
390 BaseRemoteGDB::detach()
398 pollQueue
.remove(dataEvent
);
399 DPRINTFN("remote gdb detached\n");
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.
408 BaseRemoteGDB::trap(int type
)
414 DPRINTF(GDBMisc
, "trap: PC=%s\n", tc
->pcState());
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.
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.
431 // Tell remote host that an exception has occurred.
432 send(csprintf("S%02x", type
).c_str());
435 // Stick frame regs into our reg cache.
436 regCachePtr
= gdbRegs();
437 regCachePtr
->getRegs(tc
);
439 GdbCommand::Context cmdCtx
;
441 std::vector
<char> data
;
446 if (data
.size() == 1)
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;
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
);
459 cmdCtx
.cmd
= &(cmdIt
->second
);
461 if (!(this->*(cmdCtx
.cmd
->func
))(cmdCtx
))
464 } catch (BadClient
&e
) {
469 } catch (Unsupported
&e
) {
471 } catch (CmdError
&e
) {
472 send(e
.error
.c_str());
474 panic("Unrecognzied GDB exception.");
482 BaseRemoteGDB::incomingData(int revent
)
484 if (trapEvent
.scheduled()) {
485 warn("GDB trap event has already been scheduled!");
489 if (revent
& POLLIN
) {
490 trapEvent
.type(SIGILL
);
491 scheduleInstCommitEvent(&trapEvent
, 0);
492 } else if (revent
& POLLNVAL
) {
493 descheduleInstCommitEvent(&trapEvent
);
499 BaseRemoteGDB::getbyte()
502 if (::read(fd
, &b
, sizeof(b
)) == sizeof(b
))
505 throw BadClient("Couldn't read data from debugger.");
509 BaseRemoteGDB::putbyte(uint8_t b
)
511 if (::write(fd
, &b
, sizeof(b
)) == sizeof(b
))
514 throw BadClient("Couldn't write data to the debugger.");
517 // Receive a packet from gdb
519 BaseRemoteGDB::recv(std::vector
<char>& bp
)
527 // Find the beginning of a packet
528 while ((c
= getbyte()) != GDBStart
);
530 // Read until you find the end of the data in the packet, and keep
531 // track of the check sum.
541 // Mask the check sum.
544 // Bring in the checksum. If the check sum matches, csum will be 0.
545 csum
-= digit2i(getbyte()) * 16;
546 csum
-= digit2i(getbyte());
548 // If the check sum was correct
550 // Report that the packet was received correctly
553 if (bp
.size() > 2 && bp
[2] == ':') {
556 auto begin
= std::begin(bp
);
557 bp
.erase(begin
, std::next(begin
, 3));
561 // Otherwise, report that there was a mistake.
566 DPRINTF(GDBRecv
, "recv: %s\n", bp
.data());
569 // Send a packet to gdb
571 BaseRemoteGDB::send(const char *bp
)
576 DPRINTF(GDBSend
, "send: %s\n", bp
);
580 // Start sending a packet
582 // Send the contents, and also keep a check sum.
583 for (csum
= 0; (c
= *p
); p
++) {
587 // Send the ending character.
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.
595 } while ((c
& 0x7f) == GDBBadP
);
598 // Read bytes from kernel address space for debugger.
600 BaseRemoteGDB::read(Addr vaddr
, size_t size
, char *data
)
602 DPRINTF(GDBRead
, "read: addr=%#x, size=%d", vaddr
, size
);
604 PortProxy
&proxy
= tc
->getVirtProxy();
605 proxy
.readBlob(vaddr
, data
, size
);
608 if (DTRACE(GDBRead
)) {
609 if (DTRACE(GDBExtra
)) {
611 mem2hex(buf
, data
, size
);
612 DPRINTFNR(": %s\n", buf
);
621 // Write bytes to kernel address space for debugger.
623 BaseRemoteGDB::write(Addr vaddr
, size_t size
, const char *data
)
625 if (DTRACE(GDBWrite
)) {
626 DPRINTFN("write: addr=%#x, size=%d", vaddr
, size
);
627 if (DTRACE(GDBExtra
)) {
629 mem2hex(buf
, data
, size
);
630 DPRINTFNR(": %s\n", buf
);
634 PortProxy
&proxy
= tc
->getVirtProxy();
635 proxy
.writeBlob(vaddr
, data
, size
);
641 BaseRemoteGDB::singleStep()
643 if (!singleStepEvent
.scheduled())
644 scheduleInstCommitEvent(&singleStepEvent
, 1);
649 BaseRemoteGDB::clearSingleStep()
651 descheduleInstCommitEvent(&singleStepEvent
);
655 BaseRemoteGDB::setSingleStep()
657 if (!singleStepEvent
.scheduled())
658 scheduleInstCommitEvent(&singleStepEvent
, 1);
662 BaseRemoteGDB::insertSoftBreak(Addr addr
, size_t len
)
664 if (!checkBpLen(len
))
665 throw BadClient("Invalid breakpoint length\n");
667 return insertHardBreak(addr
, len
);
671 BaseRemoteGDB::removeSoftBreak(Addr addr
, size_t len
)
673 if (!checkBpLen(len
))
674 throw BadClient("Invalid breakpoint length.\n");
676 return removeHardBreak(addr
, len
);
680 BaseRemoteGDB::insertHardBreak(Addr addr
, size_t len
)
682 if (!checkBpLen(len
))
683 throw BadClient("Invalid breakpoint length\n");
685 DPRINTF(GDBMisc
, "Inserting hardware breakpoint at %#x\n", addr
);
687 HardBreakpoint
*&bkpt
= hardBreakMap
[addr
];
689 bkpt
= new HardBreakpoint(this, sys
, addr
);
695 BaseRemoteGDB::removeHardBreak(Addr addr
, size_t len
)
697 if (!checkBpLen(len
))
698 throw BadClient("Invalid breakpoint length\n");
700 DPRINTF(GDBMisc
, "Removing hardware breakpoint at %#x\n", addr
);
702 auto i
= hardBreakMap
.find(addr
);
703 if (i
== hardBreakMap
.end())
704 throw CmdError("E0C");
706 HardBreakpoint
*hbp
= (*i
).second
;
707 if (--hbp
->refcount
== 0) {
709 hardBreakMap
.erase(i
);
714 BaseRemoteGDB::scheduleInstCommitEvent(Event
*ev
, int delta
)
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
);
722 BaseRemoteGDB::descheduleInstCommitEvent(Event
*ev
)
725 tc
->descheduleInstCountEvent(ev
);
728 std::map
<char, BaseRemoteGDB::GdbCommand
> BaseRemoteGDB::command_map
= {
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
} },
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
} },
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
} },
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
} },
754 { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmd_detach
} },
756 { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmd_mem_r
} },
758 { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmd_mem_w
} },
760 { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmd_unsupported
} },
762 { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmd_unsupported
} },
764 { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmd_query_var
} },
766 { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmd_unsupported
} },
767 // reset system (deprecated)
768 { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmd_unsupported
} },
770 { 's', { "KGDB_STEP", &BaseRemoteGDB::cmd_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
} },
776 { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmd_unsupported
} },
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
} },
786 BaseRemoteGDB::checkBpLen(size_t len
)
792 BaseRemoteGDB::cmd_unsupported(GdbCommand::Context
&ctx
)
794 DPRINTF(GDBMisc
, "Unsupported command: %s\n", ctx
.cmd
->name
);
795 DDUMP(GDBMisc
, ctx
.data
, ctx
.len
);
801 BaseRemoteGDB::cmd_signal(GdbCommand::Context
&ctx
)
803 send(csprintf("S%02x", ctx
.type
).c_str());
808 BaseRemoteGDB::cmd_cont(GdbCommand::Context
&ctx
)
810 const char *p
= ctx
.data
;
812 Addr newPc
= hex2i(&p
);
820 BaseRemoteGDB::cmd_async_cont(GdbCommand::Context
&ctx
)
822 const char *p
= ctx
.data
;
825 Addr newPc
= hex2i(&p
);
833 BaseRemoteGDB::cmd_detach(GdbCommand::Context
&ctx
)
840 BaseRemoteGDB::cmd_reg_r(GdbCommand::Context
&ctx
)
842 char buf
[2 * regCachePtr
->size() + 1];
843 buf
[2 * regCachePtr
->size()] = '\0';
844 mem2hex(buf
, regCachePtr
->data(), regCachePtr
->size());
850 BaseRemoteGDB::cmd_reg_w(GdbCommand::Context
&ctx
)
852 const char *p
= ctx
.data
;
853 p
= hex2mem(regCachePtr
->data(), p
, regCachePtr
->size());
854 if (p
== NULL
|| *p
!= '\0')
855 throw CmdError("E01");
857 regCachePtr
->setRegs(tc
);
864 BaseRemoteGDB::cmd_set_thread(GdbCommand::Context
&ctx
)
866 const char *p
= ctx
.data
+ 1; // Ignore the subcommand byte.
868 throw CmdError("E01");
874 BaseRemoteGDB::cmd_mem_r(GdbCommand::Context
&ctx
)
876 const char *p
= ctx
.data
;
877 Addr addr
= hex2i(&p
);
879 throw CmdError("E02");
880 size_t len
= hex2i(&p
);
882 throw CmdError("E03");
884 throw CmdError("E05");
887 if (!read(addr
, len
, buf
))
888 throw CmdError("E05");
890 char temp
[2 * len
+ 1];
891 temp
[2 * len
] = '\0';
892 mem2hex(temp
, buf
, len
);
898 BaseRemoteGDB::cmd_mem_w(GdbCommand::Context
&ctx
)
900 const char *p
= ctx
.data
;
901 Addr addr
= hex2i(&p
);
903 throw CmdError("E06");
904 size_t len
= hex2i(&p
);
906 throw CmdError("E07");
907 if (len
* 2 > ctx
.len
- (p
- ctx
.data
))
908 throw CmdError("E08");
910 p
= (char *)hex2mem(buf
, p
, len
);
912 throw CmdError("E09");
914 throw CmdError("E0A");
915 if (!write(addr
, len
, buf
))
916 throw CmdError("E0B");
922 BaseRemoteGDB::cmd_query_var(GdbCommand::Context
&ctx
)
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");
943 if (!getXferFeaturesRead(value_string
.substr(0, colon_pos
), annex
))
944 throw CmdError("E00");
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");
956 encodeXferResponse(annex
, encoded
, offset
, length
);
957 send(encoded
.c_str());
958 } else if (s
== "C") {
966 std::vector
<std::string
>
967 BaseRemoteGDB::availableFeatures() const
973 BaseRemoteGDB::getXferFeaturesRead(
974 const std::string
&annex
, std::string
&output
)
980 BaseRemoteGDB::encodeBinaryData(
981 const std::string
&unencoded
, std::string
&encoded
) const
983 for (const char& c
: unencoded
) {
984 if (c
== '$' || c
== '#' || c
== '}' || c
== '*') {
994 BaseRemoteGDB::encodeXferResponse(const std::string
&unencoded
,
995 std::string
&encoded
, size_t offset
, size_t unencoded_length
) const
997 if (offset
+ unencoded_length
< unencoded
.length())
1001 encodeBinaryData(unencoded
.substr(offset
, unencoded_length
), encoded
);
1005 BaseRemoteGDB::cmd_async_step(GdbCommand::Context
&ctx
)
1007 const char *p
= ctx
.data
;
1008 hex2i(&p
); // Ignore the subcommand byte.
1010 Addr newPc
= hex2i(&p
);
1018 BaseRemoteGDB::cmd_step(GdbCommand::Context
&ctx
)
1021 const char *p
= ctx
.data
;
1022 Addr newPc
= hex2i(&p
);
1030 BaseRemoteGDB::cmd_clr_hw_bkpt(GdbCommand::Context
&ctx
)
1032 const char *p
= ctx
.data
;
1035 throw CmdError("E0D");
1036 Addr addr
= hex2i(&p
);
1038 throw CmdError("E0D");
1039 size_t len
= hex2i(&p
);
1041 DPRINTF(GDBMisc
, "clear %s, addr=%#x, len=%d\n",
1042 break_type(subcmd
), addr
, len
);
1046 removeSoftBreak(addr
, len
);
1049 removeHardBreak(addr
, len
);
1055 throw Unsupported();
1063 BaseRemoteGDB::cmd_set_hw_bkpt(GdbCommand::Context
&ctx
)
1065 const char *p
= ctx
.data
;
1068 throw CmdError("E0D");
1069 Addr addr
= hex2i(&p
);
1071 throw CmdError("E0D");
1072 size_t len
= hex2i(&p
);
1074 DPRINTF(GDBMisc
, "set %s, addr=%#x, len=%d\n",
1075 break_type(subcmd
), addr
, len
);
1079 insertSoftBreak(addr
, len
);
1082 insertHardBreak(addr
, len
);
1088 throw Unsupported();