remote_gdb.cc revision 12031:46116545e745
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
147using namespace std;
148using namespace TheISA;
149
150static const char GDBStart = '$';
151static const char GDBEnd = '#';
152static const char GDBGoodP = '+';
153static const char GDBBadP = '-';
154
155static const int GDBPacketBufLen = 1024;
156
157#ifndef NDEBUG
158vector<BaseRemoteGDB *> debuggers;
159
160void
161debugger()
162{
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())
169            gdb->trap(SIGILL);
170    }
171}
172#endif
173
174///////////////////////////////////////////////////////////
175//
176//
177//
178
179GDBListener::InputEvent::InputEvent(GDBListener *l, int fd, int e)
180    : PollEvent(fd, e), listener(l)
181{}
182
183void
184GDBListener::InputEvent::process(int revent)
185{
186    listener->accept();
187}
188
189GDBListener::GDBListener(BaseRemoteGDB *g, int p)
190    : inputEvent(NULL), gdb(g), port(p)
191{
192    assert(!gdb->listener);
193    gdb->listener = this;
194}
195
196GDBListener::~GDBListener()
197{
198    delete inputEvent;
199}
200
201string
202GDBListener::name()
203{
204    return gdb->name() + ".listener";
205}
206
207void
208GDBListener::listen()
209{
210    if (ListenSocket::allDisabled()) {
211        warn_once("Sockets disabled, not accepting gdb connections");
212        return;
213    }
214
215    while (!listener.listen(port, true)) {
216        DPRINTF(GDBMisc, "Can't bind port %d\n", port);
217        port++;
218    }
219
220    inputEvent = new InputEvent(this, listener.getfd(), POLLIN);
221    pollQueue.schedule(inputEvent);
222
223#ifndef NDEBUG
224    gdb->number = debuggers.size();
225    debuggers.push_back(gdb);
226#endif
227
228#ifndef NDEBUG
229    ccprintf(cerr, "%d: %s: listening for remote gdb #%d on port %d\n",
230             curTick(), name(), gdb->number, port);
231#else
232    ccprintf(cerr, "%d: %s: listening for remote gdb on port %d\n",
233             curTick(), name(), port);
234#endif
235}
236
237void
238GDBListener::accept()
239{
240    if (!listener.islistening())
241        panic("GDBListener::accept(): cannot accept if we're not listening!");
242
243    int sfd = listener.accept(true);
244
245    if (sfd != -1) {
246        if (gdb->isattached())
247            close(sfd);
248        else
249            gdb->attach(sfd);
250    }
251}
252
253BaseRemoteGDB::InputEvent::InputEvent(BaseRemoteGDB *g, int fd, int e)
254    : PollEvent(fd, e), gdb(g)
255{}
256
257void
258BaseRemoteGDB::InputEvent::process(int revent)
259{
260    if (gdb->trapEvent.scheduled()) {
261        warn("GDB trap event has already been scheduled! "
262             "Ignoring this input event.");
263        return;
264    }
265
266    if (revent & POLLIN) {
267        gdb->trapEvent.type(SIGILL);
268        gdb->scheduleInstCommitEvent(&gdb->trapEvent, 0);
269    } else if (revent & POLLNVAL) {
270        gdb->descheduleInstCommitEvent(&gdb->trapEvent);
271        gdb->detach();
272    }
273}
274
275void
276BaseRemoteGDB::TrapEvent::process()
277{
278    gdb->trap(_type);
279}
280
281void
282BaseRemoteGDB::SingleStepEvent::process()
283{
284    if (!gdb->singleStepEvent.scheduled())
285        gdb->scheduleInstCommitEvent(&gdb->singleStepEvent, 1);
286    gdb->trap(SIGTRAP);
287}
288
289BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c) :
290        inputEvent(NULL), trapEvent(this), listener(NULL),
291        number(-1), fd(-1), active(false), attached(false), system(_system),
292        context(c), singleStepEvent(this)
293{
294}
295
296BaseRemoteGDB::~BaseRemoteGDB()
297{
298    if (inputEvent)
299        delete inputEvent;
300}
301
302string
303BaseRemoteGDB::name()
304{
305    return system->name() + ".remote_gdb";
306}
307
308bool
309BaseRemoteGDB::isattached()
310{ return attached; }
311
312void
313BaseRemoteGDB::attach(int f)
314{
315    fd = f;
316
317    inputEvent = new InputEvent(this, fd, POLLIN);
318    pollQueue.schedule(inputEvent);
319
320    attached = true;
321    DPRINTFN("remote gdb attached\n");
322}
323
324void
325BaseRemoteGDB::detach()
326{
327    attached = false;
328    active = false;
329    clearSingleStep();
330    close(fd);
331    fd = -1;
332
333    pollQueue.remove(inputEvent);
334    DPRINTFN("remote gdb detached\n");
335}
336
337/////////////////////////
338//
339//
340
341uint8_t
342BaseRemoteGDB::getbyte()
343{
344    uint8_t b;
345    if (::read(fd, &b, sizeof(b)) == sizeof(b))
346        return b;
347
348    throw BadClient("Couldn't read data from debugger.");
349}
350
351void
352BaseRemoteGDB::putbyte(uint8_t b)
353{
354    if (::write(fd, &b, sizeof(b)) == sizeof(b))
355        return;
356
357    throw BadClient("Couldn't write data to the debugger.");
358}
359
360// Send a packet to gdb
361void
362BaseRemoteGDB::send(const char *bp)
363{
364    const char *p;
365    uint8_t csum, c;
366
367    DPRINTF(GDBSend, "send:  %s\n", bp);
368
369    do {
370        p = bp;
371        // Start sending a packet
372        putbyte(GDBStart);
373        // Send the contents, and also keep a check sum.
374        for (csum = 0; (c = *p); p++) {
375            putbyte(c);
376            csum += c;
377        }
378        // Send the ending character.
379        putbyte(GDBEnd);
380        // Send the checksum.
381        putbyte(i2digit(csum >> 4));
382        putbyte(i2digit(csum));
383        // Try transmitting over and over again until the other end doesn't
384        // send an error back.
385        c = getbyte();
386    } while ((c & 0x7f) == GDBBadP);
387}
388
389// Receive a packet from gdb
390int
391BaseRemoteGDB::recv(char *bp, int maxlen)
392{
393    char *p;
394    uint8_t c;
395    int csum;
396    int len;
397
398    do {
399        p = bp;
400        csum = len = 0;
401        // Find the beginning of a packet
402        while ((c = getbyte()) != GDBStart);
403
404        // Read until you find the end of the data in the packet, and keep
405        // track of the check sum.
406        while (len < maxlen) {
407            c = getbyte();
408            if (c == GDBEnd)
409                break;
410            c &= 0x7f;
411            csum += c;
412            *p++ = c;
413            len++;
414        }
415
416        // Mask the check sum, and terminate the command string.
417        csum &= 0xff;
418        *p = '\0';
419
420        // If the command was too long, report an error.
421        if (len >= maxlen) {
422            putbyte(GDBBadP);
423            continue;
424        }
425
426        // Bring in the checksum. If the check sum matches, csum will be 0.
427        csum -= digit2i(getbyte()) * 16;
428        csum -= digit2i(getbyte());
429
430        // If the check sum was correct
431        if (csum == 0) {
432            // Report that the packet was received correctly
433            putbyte(GDBGoodP);
434            // Sequence present?
435            if (bp[2] == ':') {
436                putbyte(bp[0]);
437                putbyte(bp[1]);
438                len -= 3;
439                memcpy(bp, bp+3, len);
440            }
441            break;
442        }
443        // Otherwise, report that there was a mistake.
444        putbyte(GDBBadP);
445    } while (1);
446
447    DPRINTF(GDBRecv, "recv:  %s\n", bp);
448
449    return len;
450}
451
452// Read bytes from kernel address space for debugger.
453bool
454BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
455{
456    static Addr lastaddr = 0;
457    static size_t lastsize = 0;
458
459    if (vaddr < 10) {
460      DPRINTF(GDBRead, "read:  reading memory location zero!\n");
461      vaddr = lastaddr + lastsize;
462    }
463
464    DPRINTF(GDBRead, "read:  addr=%#x, size=%d", vaddr, size);
465
466    if (FullSystem) {
467        FSTranslatingPortProxy &proxy = context->getVirtProxy();
468        proxy.readBlob(vaddr, (uint8_t*)data, size);
469    } else {
470        SETranslatingPortProxy &proxy = context->getMemProxy();
471        proxy.readBlob(vaddr, (uint8_t*)data, size);
472    }
473
474#if TRACING_ON
475    if (DTRACE(GDBRead)) {
476        if (DTRACE(GDBExtra)) {
477            char buf[1024];
478            mem2hex(buf, data, size);
479            DPRINTFNR(": %s\n", buf);
480        } else
481            DPRINTFNR("\n");
482    }
483#endif
484
485    return true;
486}
487
488// Write bytes to kernel address space for debugger.
489bool
490BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
491{
492    static Addr lastaddr = 0;
493    static size_t lastsize = 0;
494
495    if (vaddr < 10) {
496      DPRINTF(GDBWrite, "write: writing memory location zero!\n");
497      vaddr = lastaddr + lastsize;
498    }
499
500    if (DTRACE(GDBWrite)) {
501        DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
502        if (DTRACE(GDBExtra)) {
503            char buf[1024];
504            mem2hex(buf, data, size);
505            DPRINTFNR(": %s\n", buf);
506        } else
507            DPRINTFNR("\n");
508    }
509    if (FullSystem) {
510        FSTranslatingPortProxy &proxy = context->getVirtProxy();
511        proxy.writeBlob(vaddr, (uint8_t*)data, size);
512    } else {
513        SETranslatingPortProxy &proxy = context->getMemProxy();
514        proxy.writeBlob(vaddr, (uint8_t*)data, size);
515    }
516
517    return true;
518}
519
520void
521BaseRemoteGDB::clearSingleStep()
522{
523    descheduleInstCommitEvent(&singleStepEvent);
524}
525
526void
527BaseRemoteGDB::setSingleStep()
528{
529    if (!singleStepEvent.scheduled())
530        scheduleInstCommitEvent(&singleStepEvent, 1);
531}
532
533PCEventQueue *BaseRemoteGDB::getPcEventQueue()
534{
535    return &system->pcEventQueue;
536}
537
538EventQueue *
539BaseRemoteGDB::getComInstEventQueue()
540{
541    BaseCPU *cpu = context->getCpuPtr();
542    return cpu->comInstEventQueue[context->threadId()];
543}
544
545void
546BaseRemoteGDB::scheduleInstCommitEvent(Event *ev, int delta)
547{
548    EventQueue *eq = getComInstEventQueue();
549    // Here "ticks" aren't simulator ticks which measure time, they're
550    // instructions committed by the CPU.
551    eq->schedule(ev, eq->getCurTick() + delta);
552}
553
554void
555BaseRemoteGDB::descheduleInstCommitEvent(Event *ev)
556{
557    if (ev->scheduled())
558        getComInstEventQueue()->deschedule(ev);
559}
560
561bool
562BaseRemoteGDB::checkBpLen(size_t len)
563{
564    return len == sizeof(MachInst);
565}
566
567BaseRemoteGDB::HardBreakpoint::HardBreakpoint(BaseRemoteGDB *_gdb, Addr pc)
568    : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc),
569      gdb(_gdb), refcount(0)
570{
571    DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
572}
573
574void
575BaseRemoteGDB::HardBreakpoint::process(ThreadContext *tc)
576{
577    DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
578
579    if (tc == gdb->context)
580        gdb->trap(SIGTRAP);
581}
582
583void
584BaseRemoteGDB::insertSoftBreak(Addr addr, size_t len)
585{
586    if (!checkBpLen(len))
587        throw BadClient("Invalid breakpoint length\n");
588
589    return insertHardBreak(addr, len);
590}
591
592void
593BaseRemoteGDB::removeSoftBreak(Addr addr, size_t len)
594{
595    if (!checkBpLen(len))
596        throw BadClient("Invalid breakpoint length.\n");
597
598    return removeHardBreak(addr, len);
599}
600
601void
602BaseRemoteGDB::insertHardBreak(Addr addr, size_t len)
603{
604    if (!checkBpLen(len))
605        throw BadClient("Invalid breakpoint length\n");
606
607    DPRINTF(GDBMisc, "Inserting hardware breakpoint at %#x\n", addr);
608
609    HardBreakpoint *&bkpt = hardBreakMap[addr];
610    if (bkpt == 0)
611        bkpt = new HardBreakpoint(this, addr);
612
613    bkpt->refcount++;
614}
615
616void
617BaseRemoteGDB::removeHardBreak(Addr addr, size_t len)
618{
619    if (!checkBpLen(len))
620        throw BadClient("Invalid breakpoint length\n");
621
622    DPRINTF(GDBMisc, "Removing hardware breakpoint at %#x\n", addr);
623
624    break_iter_t i = hardBreakMap.find(addr);
625    if (i == hardBreakMap.end())
626        throw CmdError("E0C");
627
628    HardBreakpoint *hbp = (*i).second;
629    if (--hbp->refcount == 0) {
630        delete hbp;
631        hardBreakMap.erase(i);
632    }
633}
634
635void
636BaseRemoteGDB::setTempBreakpoint(Addr bkpt)
637{
638    DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
639    insertHardBreak(bkpt, sizeof(TheISA::MachInst));
640}
641
642void
643BaseRemoteGDB::clearTempBreakpoint(Addr &bkpt)
644{
645    DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
646    removeHardBreak(bkpt, sizeof(TheISA::MachInst));
647    bkpt = 0;
648}
649
650enum GdbBreakpointType {
651    GdbSoftBp = '0',
652    GdbHardBp = '1',
653    GdbWriteWp = '2',
654    GdbReadWp = '3',
655    GdbAccWp = '4',
656};
657
658const char *
659BaseRemoteGDB::break_type(char c)
660{
661    switch(c) {
662      case GdbSoftBp: return "software breakpoint";
663      case GdbHardBp: return "hardware breakpoint";
664      case GdbWriteWp: return "write watchpoint";
665      case GdbReadWp: return "read watchpoint";
666      case GdbAccWp: return "access watchpoint";
667      default: return "unknown breakpoint/watchpoint";
668    }
669}
670
671std::map<char, GdbCommand> BaseRemoteGDB::command_map = {
672    // last signal
673    { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmd_signal } },
674    // set baud (deprecated)
675    { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmd_unsupported } },
676    // set breakpoint (deprecated)
677    { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmd_unsupported } },
678    // resume
679    { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmd_cont } },
680    // continue with signal
681    { 'C', { "KGDB_ASYNC_CONT", &BaseRemoteGDB::cmd_async_cont } },
682    // toggle debug flags (deprecated)
683    { 'd', { "KGDB_DEBUG", &BaseRemoteGDB::cmd_unsupported } },
684    // detach remote gdb
685    { 'D', { "KGDB_DETACH", &BaseRemoteGDB::cmd_detach } },
686    // read general registers
687    { 'g', { "KGDB_REG_R", &BaseRemoteGDB::cmd_reg_r } },
688    // write general registers
689    { 'G', { "KGDB_REG_W", &BaseRemoteGDB::cmd_reg_w } },
690    // set thread
691    { 'H', { "KGDB_SET_THREAD", &BaseRemoteGDB::cmd_set_thread } },
692    // step a single cycle
693    { 'i', { "KGDB_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported } },
694    // signal then cycle step
695    { 'I', { "KGDB_SIG_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported } },
696    // kill program
697    { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmd_detach } },
698    // read memory
699    { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmd_mem_r } },
700    // write memory
701    { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmd_mem_w } },
702    // read register
703    { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmd_unsupported } },
704    // write register
705    { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmd_unsupported } },
706    // query variable
707    { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmd_query_var } },
708    // set variable
709    { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmd_unsupported } },
710    // reset system (deprecated)
711    { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmd_unsupported } },
712    // step
713    { 's', { "KGDB_STEP", &BaseRemoteGDB::cmd_step } },
714    // signal and step
715    { 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmd_async_step } },
716    // find out if the thread is alive
717    { 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmd_unsupported } },
718    // target exited
719    { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmd_unsupported } },
720    // write memory
721    { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmd_unsupported } },
722    // remove breakpoint or watchpoint
723    { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmd_clr_hw_bkpt } },
724    // insert breakpoint or watchpoint
725    { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmd_set_hw_bkpt } },
726};
727
728
729bool
730BaseRemoteGDB::cmd_unsupported(GdbCommand::Context &ctx)
731{
732    DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
733    DDUMP(GDBMisc, ctx.data, ctx.len);
734    throw Unsupported();
735}
736
737
738bool
739BaseRemoteGDB::cmd_signal(GdbCommand::Context &ctx)
740{
741    send(csprintf("S%02x", ctx.type).c_str());
742    return true;
743}
744
745bool
746BaseRemoteGDB::cmd_cont(GdbCommand::Context &ctx)
747{
748    const char *p = ctx.data;
749    if (ctx.len) {
750        Addr newPc = hex2i(&p);
751        context->pcState(newPc);
752    }
753    clearSingleStep();
754    return false;
755}
756
757bool
758BaseRemoteGDB::cmd_async_cont(GdbCommand::Context &ctx)
759{
760    const char *p = ctx.data;
761    hex2i(&p);
762    if (*p++ == ';') {
763        Addr newPc = hex2i(&p);
764        context->pcState(newPc);
765    }
766    clearSingleStep();
767    return false;
768}
769
770bool
771BaseRemoteGDB::cmd_detach(GdbCommand::Context &ctx)
772{
773    detach();
774    return false;
775}
776
777bool
778BaseRemoteGDB::cmd_reg_r(GdbCommand::Context &ctx)
779{
780    char buf[2 * regCachePtr->size() + 1];
781    buf[2 * regCachePtr->size()] = '\0';
782    mem2hex(buf, regCachePtr->data(), regCachePtr->size());
783    send(buf);
784    return true;
785}
786
787bool
788BaseRemoteGDB::cmd_reg_w(GdbCommand::Context &ctx)
789{
790    const char *p = ctx.data;
791    p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
792    if (p == NULL || *p != '\0')
793        throw CmdError("E01");
794
795    regCachePtr->setRegs(context);
796    send("OK");
797
798    return true;
799}
800
801bool
802BaseRemoteGDB::cmd_set_thread(GdbCommand::Context &ctx)
803{
804    const char *p = ctx.data + 1; // Ignore the subcommand byte.
805    if (hex2i(&p) != 0)
806        throw CmdError("E01");
807    send("OK");
808    return true;
809}
810
811bool
812BaseRemoteGDB::cmd_mem_r(GdbCommand::Context &ctx)
813{
814    const char *p = ctx.data;
815    Addr addr = hex2i(&p);
816    if (*p++ != ',')
817        throw CmdError("E02");
818    size_t len = hex2i(&p);
819    if (*p != '\0')
820        throw CmdError("E03");
821    if (!acc(addr, len))
822        throw CmdError("E05");
823
824    char buf[len];
825    if (!read(addr, len, buf))
826        throw CmdError("E05");
827
828    char temp[2 * len + 1];
829    temp[2 * len] = '\0';
830    mem2hex(temp, buf, len);
831    send(temp);
832    return true;
833}
834
835bool
836BaseRemoteGDB::cmd_mem_w(GdbCommand::Context &ctx)
837{
838    const char *p = ctx.data;
839    Addr addr = hex2i(&p);
840    if (*p++ != ',')
841        throw CmdError("E06");
842    size_t len = hex2i(&p);
843    if (*p++ != ':')
844        throw CmdError("E07");
845    if (len * 2 > ctx.len - (p - ctx.data))
846        throw CmdError("E08");
847    char buf[len];
848    p = (char *)hex2mem(buf, p, len);
849    if (p == NULL)
850        throw CmdError("E09");
851    if (!acc(addr, len))
852        throw CmdError("E0A");
853    if (!write(addr, len, buf))
854        throw CmdError("E0B");
855    send("OK");
856    return true;
857}
858
859bool
860BaseRemoteGDB::cmd_query_var(GdbCommand::Context &ctx)
861{
862    if (string(ctx.data, ctx.len - 1) != "C")
863        throw Unsupported();
864    send("QC0");
865    return true;
866}
867
868bool
869BaseRemoteGDB::cmd_async_step(GdbCommand::Context &ctx)
870{
871    const char *p = ctx.data;
872    hex2i(&p); // Ignore the subcommand byte.
873    if (*p++ == ';') {
874        Addr newPc = hex2i(&p);
875        context->pcState(newPc);
876    }
877    setSingleStep();
878    return false;
879}
880
881bool
882BaseRemoteGDB::cmd_step(GdbCommand::Context &ctx)
883{
884    if (ctx.len) {
885        const char *p = ctx.data;
886        Addr newPc = hex2i(&p);
887        context->pcState(newPc);
888    }
889    setSingleStep();
890    return false;
891}
892
893bool
894BaseRemoteGDB::cmd_clr_hw_bkpt(GdbCommand::Context &ctx)
895{
896    const char *p = ctx.data;
897    char subcmd = *p++;
898    if (*p++ != ',')
899        throw CmdError("E0D");
900    Addr addr = hex2i(&p);
901    if (*p++ != ',')
902        throw CmdError("E0D");
903    size_t len = hex2i(&p);
904
905    DPRINTF(GDBMisc, "clear %s, addr=%#x, len=%d\n",
906            break_type(subcmd), addr, len);
907
908    switch (subcmd) {
909      case GdbSoftBp:
910        removeSoftBreak(addr, len);
911        break;
912      case GdbHardBp:
913        removeHardBreak(addr, len);
914        break;
915      case GdbWriteWp:
916      case GdbReadWp:
917      case GdbAccWp:
918      default: // unknown
919        throw Unsupported();
920    }
921    send("OK");
922
923    return true;
924}
925
926bool
927BaseRemoteGDB::cmd_set_hw_bkpt(GdbCommand::Context &ctx)
928{
929    const char *p = ctx.data;
930    char subcmd = *p++;
931    if (*p++ != ',')
932        throw CmdError("E0D");
933    Addr addr = hex2i(&p);
934    if (*p++ != ',')
935        throw CmdError("E0D");
936    size_t len = hex2i(&p);
937
938    DPRINTF(GDBMisc, "set %s, addr=%#x, len=%d\n",
939            break_type(subcmd), addr, len);
940
941    switch (subcmd) {
942      case GdbSoftBp:
943        insertSoftBreak(addr, len);
944        break;
945      case GdbHardBp:
946        insertHardBreak(addr, len);
947        break;
948      case GdbWriteWp:
949      case GdbReadWp:
950      case GdbAccWp:
951      default: // unknown
952        throw Unsupported();
953    }
954    send("OK");
955
956    return true;
957}
958
959
960// This function does all command processing for interfacing to a
961// remote gdb.  Note that the error codes are ignored by gdb at
962// present, but might eventually become meaningful. (XXX) It might
963// makes sense to use POSIX errno values, because that is what the
964// gdb/remote.c functions want to return.
965bool
966BaseRemoteGDB::trap(int type)
967{
968
969    if (!attached)
970        return false;
971
972    DPRINTF(GDBMisc, "trap: PC=%s\n", context->pcState());
973
974    clearSingleStep();
975
976    /*
977     * The first entry to this function is normally through
978     * a breakpoint trap in kgdb_connect(), in which case we
979     * must advance past the breakpoint because gdb will not.
980     *
981     * On the first entry here, we expect that gdb is not yet
982     * listening to us, so just enter the interaction loop.
983     * After the debugger is "active" (connected) it will be
984     * waiting for a "signaled" message from us.
985     */
986    if (!active) {
987        active = true;
988    } else {
989        // Tell remote host that an exception has occurred.
990        send(csprintf("S%02x", type).c_str());
991    }
992
993    // Stick frame regs into our reg cache.
994    regCachePtr = gdbRegs();
995    regCachePtr->getRegs(context);
996
997    char data[GDBPacketBufLen + 1];
998    GdbCommand::Context cmdCtx;
999    cmdCtx.type = type;
1000    cmdCtx.data = &data[1];
1001
1002    for (;;) {
1003        try {
1004            size_t datalen = recv(data, sizeof(data));
1005            if (datalen < 1)
1006                throw BadClient();
1007
1008            data[datalen] = 0; // Sentinel
1009            cmdCtx.cmd_byte = data[0];
1010            cmdCtx.len = datalen - 1;
1011
1012            auto cmdIt = command_map.find(cmdCtx.cmd_byte);
1013            if (cmdIt == command_map.end()) {
1014                DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
1015                        cmdCtx.cmd_byte, cmdCtx.cmd_byte);
1016                throw Unsupported();
1017            }
1018            cmdCtx.cmd = &(cmdIt->second);
1019
1020            if (!(this->*(cmdCtx.cmd->func))(cmdCtx))
1021                break;
1022
1023        } catch (BadClient &e) {
1024            if (e.warning)
1025                warn(e.warning);
1026            detach();
1027            break;
1028        } catch (Unsupported &e) {
1029            send("");
1030        } catch (CmdError &e) {
1031            send(e.error.c_str());
1032        } catch (...) {
1033            panic("Unrecognzied GDB exception.");
1034        }
1035    }
1036
1037    return true;
1038}
1039
1040// Convert a hex digit into an integer.
1041// This returns -1 if the argument passed is no valid hex digit.
1042int
1043BaseRemoteGDB::digit2i(char c)
1044{
1045    if (c >= '0' && c <= '9')
1046        return (c - '0');
1047    else if (c >= 'a' && c <= 'f')
1048        return (c - 'a' + 10);
1049    else if (c >= 'A' && c <= 'F')
1050        return (c - 'A' + 10);
1051    else
1052        return (-1);
1053}
1054
1055// Convert the low 4 bits of an integer into an hex digit.
1056char
1057BaseRemoteGDB::i2digit(int n)
1058{
1059    return ("0123456789abcdef"[n & 0x0f]);
1060}
1061
1062// Convert a byte array into an hex string.
1063void
1064BaseRemoteGDB::mem2hex(char *vdst, const char *vsrc, int len)
1065{
1066    char *dst = vdst;
1067    const char *src = vsrc;
1068
1069    while (len--) {
1070        *dst++ = i2digit(*src >> 4);
1071        *dst++ = i2digit(*src++);
1072    }
1073    *dst = '\0';
1074}
1075
1076// Convert an hex string into a byte array.
1077// This returns a pointer to the character following the last valid
1078// hex digit. If the string ends in the middle of a byte, NULL is
1079// returned.
1080const char *
1081BaseRemoteGDB::hex2mem(char *vdst, const char *src, int maxlen)
1082{
1083    char *dst = vdst;
1084    int msb, lsb;
1085
1086    while (*src && maxlen--) {
1087        msb = digit2i(*src++);
1088        if (msb < 0)
1089            return (src - 1);
1090        lsb = digit2i(*src++);
1091        if (lsb < 0)
1092            return (NULL);
1093        *dst++ = (msb << 4) | lsb;
1094    }
1095    return src;
1096}
1097
1098// Convert an hex string into an integer.
1099// This returns a pointer to the character following the last valid
1100// hex digit.
1101Addr
1102BaseRemoteGDB::hex2i(const char **srcp)
1103{
1104    const char *src = *srcp;
1105    Addr r = 0;
1106    int nibble;
1107
1108    while ((nibble = digit2i(*src)) >= 0) {
1109        r *= 16;
1110        r += nibble;
1111        src++;
1112    }
1113    *srcp = src;
1114    return r;
1115}
1116
1117