2 * Copyright 2015 LabWare
3 * Copyright 2014 Google, Inc.
4 * Copyright (c) 2002-2005 The Regents of The University of Michigan
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.
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.
30 * Authors: Nathan Binkert
35 * Copyright (c) 1990, 1993 The Regents of the University of California
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.
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.
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
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.
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
75 * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
79 * Copyright (c) 2001 The NetBSD Foundation, Inc.
80 * All rights reserved.
82 * This code is derived from software contributed to The NetBSD Foundation
85 * Redistribution and use in source and binary forms, with or without
86 * modification, are permitted provided that the following conditions
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.
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.
115 * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
119 * "Stub" to allow remote cpu to debug over a serial line using gdb.
122 #include "base/remote_gdb.hh"
124 #include <sys/signal.h>
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"
148 using namespace TheISA
;
150 static const char GDBStart
= '$';
151 static const char GDBEnd
= '#';
152 static const char GDBGoodP
= '+';
153 static const char GDBBadP
= '-';
155 static const int GDBPacketBufLen
= 1024;
158 vector
<BaseRemoteGDB
*> debuggers
;
163 static int current_debugger
= -1;
164 if (current_debugger
>= 0 && current_debugger
< (int)debuggers
.size()) {
165 BaseRemoteGDB
*gdb
= debuggers
[current_debugger
];
166 if (!gdb
->isattached())
167 gdb
->listener
->accept();
168 if (gdb
->isattached())
174 ///////////////////////////////////////////////////////////
179 GDBListener::InputEvent::InputEvent(GDBListener
*l
, int fd
, int e
)
180 : PollEvent(fd
, e
), listener(l
)
184 GDBListener::InputEvent::process(int revent
)
189 GDBListener::GDBListener(BaseRemoteGDB
*g
, int p
)
190 : inputEvent(NULL
), gdb(g
), port(p
)
192 assert(!gdb
->listener
);
193 gdb
->listener
= this;
196 GDBListener::~GDBListener()
204 return gdb
->name() + ".listener";
208 GDBListener::listen()
210 if (ListenSocket::allDisabled()) {
211 warn_once("Sockets disabled, not accepting gdb connections");
215 while (!listener
.listen(port
, true)) {
216 DPRINTF(GDBMisc
, "Can't bind port %d\n", port
);
220 inputEvent
= new InputEvent(this, listener
.getfd(), POLLIN
);
221 pollQueue
.schedule(inputEvent
);
224 gdb
->number
= debuggers
.size();
225 debuggers
.push_back(gdb
);
229 ccprintf(cerr
, "%d: %s: listening for remote gdb #%d on port %d\n",
230 curTick(), name(), gdb
->number
, port
);
232 ccprintf(cerr
, "%d: %s: listening for remote gdb on port %d\n",
233 curTick(), name(), port
);
238 GDBListener::accept()
240 if (!listener
.islistening())
241 panic("GDBListener::accept(): cannot accept if we're not listening!");
243 int sfd
= listener
.accept(true);
246 if (gdb
->isattached())
254 GDBListener::getPort() const
256 panic_if(!listener
.islistening(),
257 "Remote GDB port is unknown until GDBListener::listen() has "
263 BaseRemoteGDB::InputEvent::InputEvent(BaseRemoteGDB
*g
, int fd
, int e
)
264 : PollEvent(fd
, e
), gdb(g
)
268 BaseRemoteGDB::InputEvent::process(int revent
)
270 if (gdb
->trapEvent
.scheduled()) {
271 warn("GDB trap event has already been scheduled! "
272 "Ignoring this input event.");
276 if (revent
& POLLIN
) {
277 gdb
->trapEvent
.type(SIGILL
);
278 gdb
->scheduleInstCommitEvent(&gdb
->trapEvent
, 0);
279 } else if (revent
& POLLNVAL
) {
280 gdb
->descheduleInstCommitEvent(&gdb
->trapEvent
);
286 BaseRemoteGDB::TrapEvent::process()
292 BaseRemoteGDB::processSingleStepEvent()
294 if (!singleStepEvent
.scheduled())
295 scheduleInstCommitEvent(&singleStepEvent
, 1);
299 BaseRemoteGDB::BaseRemoteGDB(System
*_system
, ThreadContext
*c
) :
300 inputEvent(NULL
), trapEvent(this), listener(NULL
), number(-1),
301 fd(-1), active(false), attached(false), system(_system
),
303 singleStepEvent([this]{ processSingleStepEvent(); }, name())
307 BaseRemoteGDB::~BaseRemoteGDB()
314 BaseRemoteGDB::name()
316 return system
->name() + ".remote_gdb";
320 BaseRemoteGDB::isattached()
324 BaseRemoteGDB::attach(int f
)
328 inputEvent
= new InputEvent(this, fd
, POLLIN
);
329 pollQueue
.schedule(inputEvent
);
332 DPRINTFN("remote gdb attached\n");
336 BaseRemoteGDB::detach()
344 pollQueue
.remove(inputEvent
);
345 DPRINTFN("remote gdb detached\n");
348 /////////////////////////
353 BaseRemoteGDB::getbyte()
356 if (::read(fd
, &b
, sizeof(b
)) == sizeof(b
))
359 throw BadClient("Couldn't read data from debugger.");
363 BaseRemoteGDB::putbyte(uint8_t b
)
365 if (::write(fd
, &b
, sizeof(b
)) == sizeof(b
))
368 throw BadClient("Couldn't write data to the debugger.");
371 // Send a packet to gdb
373 BaseRemoteGDB::send(const char *bp
)
378 DPRINTF(GDBSend
, "send: %s\n", bp
);
382 // Start sending a packet
384 // Send the contents, and also keep a check sum.
385 for (csum
= 0; (c
= *p
); p
++) {
389 // Send the ending character.
391 // Send the checksum.
392 putbyte(i2digit(csum
>> 4));
393 putbyte(i2digit(csum
));
394 // Try transmitting over and over again until the other end doesn't
395 // send an error back.
397 } while ((c
& 0x7f) == GDBBadP
);
400 // Receive a packet from gdb
402 BaseRemoteGDB::recv(char *bp
, int maxlen
)
412 // Find the beginning of a packet
413 while ((c
= getbyte()) != GDBStart
);
415 // Read until you find the end of the data in the packet, and keep
416 // track of the check sum.
417 while (len
< maxlen
) {
427 // Mask the check sum, and terminate the command string.
431 // If the command was too long, report an error.
437 // Bring in the checksum. If the check sum matches, csum will be 0.
438 csum
-= digit2i(getbyte()) * 16;
439 csum
-= digit2i(getbyte());
441 // If the check sum was correct
443 // Report that the packet was received correctly
450 memcpy(bp
, bp
+3, len
);
454 // Otherwise, report that there was a mistake.
458 DPRINTF(GDBRecv
, "recv: %s\n", bp
);
463 // Read bytes from kernel address space for debugger.
465 BaseRemoteGDB::read(Addr vaddr
, size_t size
, char *data
)
467 static Addr lastaddr
= 0;
468 static size_t lastsize
= 0;
471 DPRINTF(GDBRead
, "read: reading memory location zero!\n");
472 vaddr
= lastaddr
+ lastsize
;
475 DPRINTF(GDBRead
, "read: addr=%#x, size=%d", vaddr
, size
);
478 FSTranslatingPortProxy
&proxy
= context
->getVirtProxy();
479 proxy
.readBlob(vaddr
, (uint8_t*)data
, size
);
481 SETranslatingPortProxy
&proxy
= context
->getMemProxy();
482 proxy
.readBlob(vaddr
, (uint8_t*)data
, size
);
486 if (DTRACE(GDBRead
)) {
487 if (DTRACE(GDBExtra
)) {
489 mem2hex(buf
, data
, size
);
490 DPRINTFNR(": %s\n", buf
);
499 // Write bytes to kernel address space for debugger.
501 BaseRemoteGDB::write(Addr vaddr
, size_t size
, const char *data
)
503 static Addr lastaddr
= 0;
504 static size_t lastsize
= 0;
507 DPRINTF(GDBWrite
, "write: writing memory location zero!\n");
508 vaddr
= lastaddr
+ lastsize
;
511 if (DTRACE(GDBWrite
)) {
512 DPRINTFN("write: addr=%#x, size=%d", vaddr
, size
);
513 if (DTRACE(GDBExtra
)) {
515 mem2hex(buf
, data
, size
);
516 DPRINTFNR(": %s\n", buf
);
521 FSTranslatingPortProxy
&proxy
= context
->getVirtProxy();
522 proxy
.writeBlob(vaddr
, (uint8_t*)data
, size
);
524 SETranslatingPortProxy
&proxy
= context
->getMemProxy();
525 proxy
.writeBlob(vaddr
, (uint8_t*)data
, size
);
532 BaseRemoteGDB::clearSingleStep()
534 descheduleInstCommitEvent(&singleStepEvent
);
538 BaseRemoteGDB::setSingleStep()
540 if (!singleStepEvent
.scheduled())
541 scheduleInstCommitEvent(&singleStepEvent
, 1);
544 PCEventQueue
*BaseRemoteGDB::getPcEventQueue()
546 return &system
->pcEventQueue
;
550 BaseRemoteGDB::getComInstEventQueue()
552 BaseCPU
*cpu
= context
->getCpuPtr();
553 return cpu
->comInstEventQueue
[context
->threadId()];
557 BaseRemoteGDB::scheduleInstCommitEvent(Event
*ev
, int delta
)
559 EventQueue
*eq
= getComInstEventQueue();
560 // Here "ticks" aren't simulator ticks which measure time, they're
561 // instructions committed by the CPU.
562 eq
->schedule(ev
, eq
->getCurTick() + delta
);
566 BaseRemoteGDB::descheduleInstCommitEvent(Event
*ev
)
569 getComInstEventQueue()->deschedule(ev
);
573 BaseRemoteGDB::checkBpLen(size_t len
)
575 return len
== sizeof(MachInst
);
578 BaseRemoteGDB::HardBreakpoint::HardBreakpoint(BaseRemoteGDB
*_gdb
, Addr pc
)
579 : PCEvent(_gdb
->getPcEventQueue(), "HardBreakpoint Event", pc
),
580 gdb(_gdb
), refcount(0)
582 DPRINTF(GDBMisc
, "creating hardware breakpoint at %#x\n", evpc
);
586 BaseRemoteGDB::HardBreakpoint::process(ThreadContext
*tc
)
588 DPRINTF(GDBMisc
, "handling hardware breakpoint at %#x\n", pc());
590 if (tc
== gdb
->context
)
595 BaseRemoteGDB::insertSoftBreak(Addr addr
, size_t len
)
597 if (!checkBpLen(len
))
598 throw BadClient("Invalid breakpoint length\n");
600 return insertHardBreak(addr
, len
);
604 BaseRemoteGDB::removeSoftBreak(Addr addr
, size_t len
)
606 if (!checkBpLen(len
))
607 throw BadClient("Invalid breakpoint length.\n");
609 return removeHardBreak(addr
, len
);
613 BaseRemoteGDB::insertHardBreak(Addr addr
, size_t len
)
615 if (!checkBpLen(len
))
616 throw BadClient("Invalid breakpoint length\n");
618 DPRINTF(GDBMisc
, "Inserting hardware breakpoint at %#x\n", addr
);
620 HardBreakpoint
*&bkpt
= hardBreakMap
[addr
];
622 bkpt
= new HardBreakpoint(this, addr
);
628 BaseRemoteGDB::removeHardBreak(Addr addr
, size_t len
)
630 if (!checkBpLen(len
))
631 throw BadClient("Invalid breakpoint length\n");
633 DPRINTF(GDBMisc
, "Removing hardware breakpoint at %#x\n", addr
);
635 break_iter_t i
= hardBreakMap
.find(addr
);
636 if (i
== hardBreakMap
.end())
637 throw CmdError("E0C");
639 HardBreakpoint
*hbp
= (*i
).second
;
640 if (--hbp
->refcount
== 0) {
642 hardBreakMap
.erase(i
);
647 BaseRemoteGDB::setTempBreakpoint(Addr bkpt
)
649 DPRINTF(GDBMisc
, "setTempBreakpoint: addr=%#x\n", bkpt
);
650 insertHardBreak(bkpt
, sizeof(TheISA::MachInst
));
654 BaseRemoteGDB::clearTempBreakpoint(Addr
&bkpt
)
656 DPRINTF(GDBMisc
, "setTempBreakpoint: addr=%#x\n", bkpt
);
657 removeHardBreak(bkpt
, sizeof(TheISA::MachInst
));
661 enum GdbBreakpointType
{
670 BaseRemoteGDB::break_type(char c
)
673 case GdbSoftBp
: return "software breakpoint";
674 case GdbHardBp
: return "hardware breakpoint";
675 case GdbWriteWp
: return "write watchpoint";
676 case GdbReadWp
: return "read watchpoint";
677 case GdbAccWp
: return "access watchpoint";
678 default: return "unknown breakpoint/watchpoint";
682 std::map
<char, GdbCommand
> BaseRemoteGDB::command_map
= {
684 { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmd_signal
} },
685 // set baud (deprecated)
686 { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmd_unsupported
} },
687 // set breakpoint (deprecated)
688 { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmd_unsupported
} },
690 { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmd_cont
} },
691 // continue with signal
692 { 'C', { "KGDB_ASYNC_CONT", &BaseRemoteGDB::cmd_async_cont
} },
693 // toggle debug flags (deprecated)
694 { 'd', { "KGDB_DEBUG", &BaseRemoteGDB::cmd_unsupported
} },
696 { 'D', { "KGDB_DETACH", &BaseRemoteGDB::cmd_detach
} },
697 // read general registers
698 { 'g', { "KGDB_REG_R", &BaseRemoteGDB::cmd_reg_r
} },
699 // write general registers
700 { 'G', { "KGDB_REG_W", &BaseRemoteGDB::cmd_reg_w
} },
702 { 'H', { "KGDB_SET_THREAD", &BaseRemoteGDB::cmd_set_thread
} },
703 // step a single cycle
704 { 'i', { "KGDB_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported
} },
705 // signal then cycle step
706 { 'I', { "KGDB_SIG_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported
} },
708 { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmd_detach
} },
710 { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmd_mem_r
} },
712 { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmd_mem_w
} },
714 { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmd_unsupported
} },
716 { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmd_unsupported
} },
718 { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmd_query_var
} },
720 { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmd_unsupported
} },
721 // reset system (deprecated)
722 { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmd_unsupported
} },
724 { 's', { "KGDB_STEP", &BaseRemoteGDB::cmd_step
} },
726 { 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmd_async_step
} },
727 // find out if the thread is alive
728 { 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmd_unsupported
} },
730 { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmd_unsupported
} },
732 { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmd_unsupported
} },
733 // remove breakpoint or watchpoint
734 { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmd_clr_hw_bkpt
} },
735 // insert breakpoint or watchpoint
736 { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmd_set_hw_bkpt
} },
741 BaseRemoteGDB::cmd_unsupported(GdbCommand::Context
&ctx
)
743 DPRINTF(GDBMisc
, "Unsupported command: %s\n", ctx
.cmd
->name
);
744 DDUMP(GDBMisc
, ctx
.data
, ctx
.len
);
750 BaseRemoteGDB::cmd_signal(GdbCommand::Context
&ctx
)
752 send(csprintf("S%02x", ctx
.type
).c_str());
757 BaseRemoteGDB::cmd_cont(GdbCommand::Context
&ctx
)
759 const char *p
= ctx
.data
;
761 Addr newPc
= hex2i(&p
);
762 context
->pcState(newPc
);
769 BaseRemoteGDB::cmd_async_cont(GdbCommand::Context
&ctx
)
771 const char *p
= ctx
.data
;
774 Addr newPc
= hex2i(&p
);
775 context
->pcState(newPc
);
782 BaseRemoteGDB::cmd_detach(GdbCommand::Context
&ctx
)
789 BaseRemoteGDB::cmd_reg_r(GdbCommand::Context
&ctx
)
791 char buf
[2 * regCachePtr
->size() + 1];
792 buf
[2 * regCachePtr
->size()] = '\0';
793 mem2hex(buf
, regCachePtr
->data(), regCachePtr
->size());
799 BaseRemoteGDB::cmd_reg_w(GdbCommand::Context
&ctx
)
801 const char *p
= ctx
.data
;
802 p
= hex2mem(regCachePtr
->data(), p
, regCachePtr
->size());
803 if (p
== NULL
|| *p
!= '\0')
804 throw CmdError("E01");
806 regCachePtr
->setRegs(context
);
813 BaseRemoteGDB::cmd_set_thread(GdbCommand::Context
&ctx
)
815 const char *p
= ctx
.data
+ 1; // Ignore the subcommand byte.
817 throw CmdError("E01");
823 BaseRemoteGDB::cmd_mem_r(GdbCommand::Context
&ctx
)
825 const char *p
= ctx
.data
;
826 Addr addr
= hex2i(&p
);
828 throw CmdError("E02");
829 size_t len
= hex2i(&p
);
831 throw CmdError("E03");
833 throw CmdError("E05");
836 if (!read(addr
, len
, buf
))
837 throw CmdError("E05");
839 char temp
[2 * len
+ 1];
840 temp
[2 * len
] = '\0';
841 mem2hex(temp
, buf
, len
);
847 BaseRemoteGDB::cmd_mem_w(GdbCommand::Context
&ctx
)
849 const char *p
= ctx
.data
;
850 Addr addr
= hex2i(&p
);
852 throw CmdError("E06");
853 size_t len
= hex2i(&p
);
855 throw CmdError("E07");
856 if (len
* 2 > ctx
.len
- (p
- ctx
.data
))
857 throw CmdError("E08");
859 p
= (char *)hex2mem(buf
, p
, len
);
861 throw CmdError("E09");
863 throw CmdError("E0A");
864 if (!write(addr
, len
, buf
))
865 throw CmdError("E0B");
871 BaseRemoteGDB::cmd_query_var(GdbCommand::Context
&ctx
)
873 if (string(ctx
.data
, ctx
.len
- 1) != "C")
880 BaseRemoteGDB::cmd_async_step(GdbCommand::Context
&ctx
)
882 const char *p
= ctx
.data
;
883 hex2i(&p
); // Ignore the subcommand byte.
885 Addr newPc
= hex2i(&p
);
886 context
->pcState(newPc
);
893 BaseRemoteGDB::cmd_step(GdbCommand::Context
&ctx
)
896 const char *p
= ctx
.data
;
897 Addr newPc
= hex2i(&p
);
898 context
->pcState(newPc
);
905 BaseRemoteGDB::cmd_clr_hw_bkpt(GdbCommand::Context
&ctx
)
907 const char *p
= ctx
.data
;
910 throw CmdError("E0D");
911 Addr addr
= hex2i(&p
);
913 throw CmdError("E0D");
914 size_t len
= hex2i(&p
);
916 DPRINTF(GDBMisc
, "clear %s, addr=%#x, len=%d\n",
917 break_type(subcmd
), addr
, len
);
921 removeSoftBreak(addr
, len
);
924 removeHardBreak(addr
, len
);
938 BaseRemoteGDB::cmd_set_hw_bkpt(GdbCommand::Context
&ctx
)
940 const char *p
= ctx
.data
;
943 throw CmdError("E0D");
944 Addr addr
= hex2i(&p
);
946 throw CmdError("E0D");
947 size_t len
= hex2i(&p
);
949 DPRINTF(GDBMisc
, "set %s, addr=%#x, len=%d\n",
950 break_type(subcmd
), addr
, len
);
954 insertSoftBreak(addr
, len
);
957 insertHardBreak(addr
, len
);
971 // This function does all command processing for interfacing to a
972 // remote gdb. Note that the error codes are ignored by gdb at
973 // present, but might eventually become meaningful. (XXX) It might
974 // makes sense to use POSIX errno values, because that is what the
975 // gdb/remote.c functions want to return.
977 BaseRemoteGDB::trap(int type
)
983 DPRINTF(GDBMisc
, "trap: PC=%s\n", context
->pcState());
988 * The first entry to this function is normally through
989 * a breakpoint trap in kgdb_connect(), in which case we
990 * must advance past the breakpoint because gdb will not.
992 * On the first entry here, we expect that gdb is not yet
993 * listening to us, so just enter the interaction loop.
994 * After the debugger is "active" (connected) it will be
995 * waiting for a "signaled" message from us.
1000 // Tell remote host that an exception has occurred.
1001 send(csprintf("S%02x", type
).c_str());
1004 // Stick frame regs into our reg cache.
1005 regCachePtr
= gdbRegs();
1006 regCachePtr
->getRegs(context
);
1008 char data
[GDBPacketBufLen
+ 1];
1009 GdbCommand::Context cmdCtx
;
1011 cmdCtx
.data
= &data
[1];
1015 size_t datalen
= recv(data
, sizeof(data
));
1019 data
[datalen
] = 0; // Sentinel
1020 cmdCtx
.cmd_byte
= data
[0];
1021 cmdCtx
.len
= datalen
- 1;
1023 auto cmdIt
= command_map
.find(cmdCtx
.cmd_byte
);
1024 if (cmdIt
== command_map
.end()) {
1025 DPRINTF(GDBMisc
, "Unknown command: %c(%#x)\n",
1026 cmdCtx
.cmd_byte
, cmdCtx
.cmd_byte
);
1027 throw Unsupported();
1029 cmdCtx
.cmd
= &(cmdIt
->second
);
1031 if (!(this->*(cmdCtx
.cmd
->func
))(cmdCtx
))
1034 } catch (BadClient
&e
) {
1039 } catch (Unsupported
&e
) {
1041 } catch (CmdError
&e
) {
1042 send(e
.error
.c_str());
1044 panic("Unrecognzied GDB exception.");
1051 // Convert a hex digit into an integer.
1052 // This returns -1 if the argument passed is no valid hex digit.
1054 BaseRemoteGDB::digit2i(char c
)
1056 if (c
>= '0' && c
<= '9')
1058 else if (c
>= 'a' && c
<= 'f')
1059 return (c
- 'a' + 10);
1060 else if (c
>= 'A' && c
<= 'F')
1061 return (c
- 'A' + 10);
1066 // Convert the low 4 bits of an integer into an hex digit.
1068 BaseRemoteGDB::i2digit(int n
)
1070 return ("0123456789abcdef"[n
& 0x0f]);
1073 // Convert a byte array into an hex string.
1075 BaseRemoteGDB::mem2hex(char *vdst
, const char *vsrc
, int len
)
1078 const char *src
= vsrc
;
1081 *dst
++ = i2digit(*src
>> 4);
1082 *dst
++ = i2digit(*src
++);
1087 // Convert an hex string into a byte array.
1088 // This returns a pointer to the character following the last valid
1089 // hex digit. If the string ends in the middle of a byte, NULL is
1092 BaseRemoteGDB::hex2mem(char *vdst
, const char *src
, int maxlen
)
1097 while (*src
&& maxlen
--) {
1098 msb
= digit2i(*src
++);
1101 lsb
= digit2i(*src
++);
1104 *dst
++ = (msb
<< 4) | lsb
;
1109 // Convert an hex string into an integer.
1110 // This returns a pointer to the character following the last valid
1113 BaseRemoteGDB::hex2i(const char **srcp
)
1115 const char *src
= *srcp
;
1119 while ((nibble
= digit2i(*src
)) >= 0) {