remote_gdb.cc revision 12125:0066d9926c1a
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
253int
254GDBListener::getPort() const
255{
256    panic_if(!listener.islistening(),
257             "Remote GDB port is unknown until GDBListener::listen() has "
258             "been called.\n");
259
260    return port;
261}
262
263BaseRemoteGDB::InputEvent::InputEvent(BaseRemoteGDB *g, int fd, int e)
264    : PollEvent(fd, e), gdb(g)
265{}
266
267void
268BaseRemoteGDB::InputEvent::process(int revent)
269{
270    if (gdb->trapEvent.scheduled()) {
271        warn("GDB trap event has already been scheduled! "
272             "Ignoring this input event.");
273        return;
274    }
275
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);
281        gdb->detach();
282    }
283}
284
285void
286BaseRemoteGDB::TrapEvent::process()
287{
288    gdb->trap(_type);
289}
290
291void
292BaseRemoteGDB::processSingleStepEvent()
293{
294    if (!singleStepEvent.scheduled())
295        scheduleInstCommitEvent(&singleStepEvent, 1);
296    trap(SIGTRAP);
297}
298
299BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c) :
300        inputEvent(NULL), trapEvent(this), listener(NULL), number(-1),
301        fd(-1), active(false), attached(false), system(_system),
302        context(c),
303        singleStepEvent([this]{ processSingleStepEvent(); }, name())
304{
305}
306
307BaseRemoteGDB::~BaseRemoteGDB()
308{
309    if (inputEvent)
310        delete inputEvent;
311}
312
313string
314BaseRemoteGDB::name()
315{
316    return system->name() + ".remote_gdb";
317}
318
319bool
320BaseRemoteGDB::isattached()
321{ return attached; }
322
323void
324BaseRemoteGDB::attach(int f)
325{
326    fd = f;
327
328    inputEvent = new InputEvent(this, fd, POLLIN);
329    pollQueue.schedule(inputEvent);
330
331    attached = true;
332    DPRINTFN("remote gdb attached\n");
333}
334
335void
336BaseRemoteGDB::detach()
337{
338    attached = false;
339    active = false;
340    clearSingleStep();
341    close(fd);
342    fd = -1;
343
344    pollQueue.remove(inputEvent);
345    DPRINTFN("remote gdb detached\n");
346}
347
348/////////////////////////
349//
350//
351
352uint8_t
353BaseRemoteGDB::getbyte()
354{
355    uint8_t b;
356    if (::read(fd, &b, sizeof(b)) == sizeof(b))
357        return b;
358
359    throw BadClient("Couldn't read data from debugger.");
360}
361
362void
363BaseRemoteGDB::putbyte(uint8_t b)
364{
365    if (::write(fd, &b, sizeof(b)) == sizeof(b))
366        return;
367
368    throw BadClient("Couldn't write data to the debugger.");
369}
370
371// Send a packet to gdb
372void
373BaseRemoteGDB::send(const char *bp)
374{
375    const char *p;
376    uint8_t csum, c;
377
378    DPRINTF(GDBSend, "send:  %s\n", bp);
379
380    do {
381        p = bp;
382        // Start sending a packet
383        putbyte(GDBStart);
384        // Send the contents, and also keep a check sum.
385        for (csum = 0; (c = *p); p++) {
386            putbyte(c);
387            csum += c;
388        }
389        // Send the ending character.
390        putbyte(GDBEnd);
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.
396        c = getbyte();
397    } while ((c & 0x7f) == GDBBadP);
398}
399
400// Receive a packet from gdb
401int
402BaseRemoteGDB::recv(char *bp, int maxlen)
403{
404    char *p;
405    uint8_t c;
406    int csum;
407    int len;
408
409    do {
410        p = bp;
411        csum = len = 0;
412        // Find the beginning of a packet
413        while ((c = getbyte()) != GDBStart);
414
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) {
418            c = getbyte();
419            if (c == GDBEnd)
420                break;
421            c &= 0x7f;
422            csum += c;
423            *p++ = c;
424            len++;
425        }
426
427        // Mask the check sum, and terminate the command string.
428        csum &= 0xff;
429        *p = '\0';
430
431        // If the command was too long, report an error.
432        if (len >= maxlen) {
433            putbyte(GDBBadP);
434            continue;
435        }
436
437        // Bring in the checksum. If the check sum matches, csum will be 0.
438        csum -= digit2i(getbyte()) * 16;
439        csum -= digit2i(getbyte());
440
441        // If the check sum was correct
442        if (csum == 0) {
443            // Report that the packet was received correctly
444            putbyte(GDBGoodP);
445            // Sequence present?
446            if (bp[2] == ':') {
447                putbyte(bp[0]);
448                putbyte(bp[1]);
449                len -= 3;
450                memcpy(bp, bp+3, len);
451            }
452            break;
453        }
454        // Otherwise, report that there was a mistake.
455        putbyte(GDBBadP);
456    } while (1);
457
458    DPRINTF(GDBRecv, "recv:  %s\n", bp);
459
460    return len;
461}
462
463// Read bytes from kernel address space for debugger.
464bool
465BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
466{
467    static Addr lastaddr = 0;
468    static size_t lastsize = 0;
469
470    if (vaddr < 10) {
471      DPRINTF(GDBRead, "read:  reading memory location zero!\n");
472      vaddr = lastaddr + lastsize;
473    }
474
475    DPRINTF(GDBRead, "read:  addr=%#x, size=%d", vaddr, size);
476
477    if (FullSystem) {
478        FSTranslatingPortProxy &proxy = context->getVirtProxy();
479        proxy.readBlob(vaddr, (uint8_t*)data, size);
480    } else {
481        SETranslatingPortProxy &proxy = context->getMemProxy();
482        proxy.readBlob(vaddr, (uint8_t*)data, size);
483    }
484
485#if TRACING_ON
486    if (DTRACE(GDBRead)) {
487        if (DTRACE(GDBExtra)) {
488            char buf[1024];
489            mem2hex(buf, data, size);
490            DPRINTFNR(": %s\n", buf);
491        } else
492            DPRINTFNR("\n");
493    }
494#endif
495
496    return true;
497}
498
499// Write bytes to kernel address space for debugger.
500bool
501BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
502{
503    static Addr lastaddr = 0;
504    static size_t lastsize = 0;
505
506    if (vaddr < 10) {
507      DPRINTF(GDBWrite, "write: writing memory location zero!\n");
508      vaddr = lastaddr + lastsize;
509    }
510
511    if (DTRACE(GDBWrite)) {
512        DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
513        if (DTRACE(GDBExtra)) {
514            char buf[1024];
515            mem2hex(buf, data, size);
516            DPRINTFNR(": %s\n", buf);
517        } else
518            DPRINTFNR("\n");
519    }
520    if (FullSystem) {
521        FSTranslatingPortProxy &proxy = context->getVirtProxy();
522        proxy.writeBlob(vaddr, (uint8_t*)data, size);
523    } else {
524        SETranslatingPortProxy &proxy = context->getMemProxy();
525        proxy.writeBlob(vaddr, (uint8_t*)data, size);
526    }
527
528    return true;
529}
530
531void
532BaseRemoteGDB::clearSingleStep()
533{
534    descheduleInstCommitEvent(&singleStepEvent);
535}
536
537void
538BaseRemoteGDB::setSingleStep()
539{
540    if (!singleStepEvent.scheduled())
541        scheduleInstCommitEvent(&singleStepEvent, 1);
542}
543
544PCEventQueue *BaseRemoteGDB::getPcEventQueue()
545{
546    return &system->pcEventQueue;
547}
548
549EventQueue *
550BaseRemoteGDB::getComInstEventQueue()
551{
552    BaseCPU *cpu = context->getCpuPtr();
553    return cpu->comInstEventQueue[context->threadId()];
554}
555
556void
557BaseRemoteGDB::scheduleInstCommitEvent(Event *ev, int delta)
558{
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);
563}
564
565void
566BaseRemoteGDB::descheduleInstCommitEvent(Event *ev)
567{
568    if (ev->scheduled())
569        getComInstEventQueue()->deschedule(ev);
570}
571
572bool
573BaseRemoteGDB::checkBpLen(size_t len)
574{
575    return len == sizeof(MachInst);
576}
577
578BaseRemoteGDB::HardBreakpoint::HardBreakpoint(BaseRemoteGDB *_gdb, Addr pc)
579    : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc),
580      gdb(_gdb), refcount(0)
581{
582    DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
583}
584
585void
586BaseRemoteGDB::HardBreakpoint::process(ThreadContext *tc)
587{
588    DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
589
590    if (tc == gdb->context)
591        gdb->trap(SIGTRAP);
592}
593
594void
595BaseRemoteGDB::insertSoftBreak(Addr addr, size_t len)
596{
597    if (!checkBpLen(len))
598        throw BadClient("Invalid breakpoint length\n");
599
600    return insertHardBreak(addr, len);
601}
602
603void
604BaseRemoteGDB::removeSoftBreak(Addr addr, size_t len)
605{
606    if (!checkBpLen(len))
607        throw BadClient("Invalid breakpoint length.\n");
608
609    return removeHardBreak(addr, len);
610}
611
612void
613BaseRemoteGDB::insertHardBreak(Addr addr, size_t len)
614{
615    if (!checkBpLen(len))
616        throw BadClient("Invalid breakpoint length\n");
617
618    DPRINTF(GDBMisc, "Inserting hardware breakpoint at %#x\n", addr);
619
620    HardBreakpoint *&bkpt = hardBreakMap[addr];
621    if (bkpt == 0)
622        bkpt = new HardBreakpoint(this, addr);
623
624    bkpt->refcount++;
625}
626
627void
628BaseRemoteGDB::removeHardBreak(Addr addr, size_t len)
629{
630    if (!checkBpLen(len))
631        throw BadClient("Invalid breakpoint length\n");
632
633    DPRINTF(GDBMisc, "Removing hardware breakpoint at %#x\n", addr);
634
635    break_iter_t i = hardBreakMap.find(addr);
636    if (i == hardBreakMap.end())
637        throw CmdError("E0C");
638
639    HardBreakpoint *hbp = (*i).second;
640    if (--hbp->refcount == 0) {
641        delete hbp;
642        hardBreakMap.erase(i);
643    }
644}
645
646void
647BaseRemoteGDB::setTempBreakpoint(Addr bkpt)
648{
649    DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
650    insertHardBreak(bkpt, sizeof(TheISA::MachInst));
651}
652
653void
654BaseRemoteGDB::clearTempBreakpoint(Addr &bkpt)
655{
656    DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
657    removeHardBreak(bkpt, sizeof(TheISA::MachInst));
658    bkpt = 0;
659}
660
661enum GdbBreakpointType {
662    GdbSoftBp = '0',
663    GdbHardBp = '1',
664    GdbWriteWp = '2',
665    GdbReadWp = '3',
666    GdbAccWp = '4',
667};
668
669const char *
670BaseRemoteGDB::break_type(char c)
671{
672    switch(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";
679    }
680}
681
682std::map<char, GdbCommand> BaseRemoteGDB::command_map = {
683    // last signal
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 } },
689    // resume
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 } },
695    // detach remote gdb
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 } },
701    // set thread
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 } },
707    // kill program
708    { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmd_detach } },
709    // read memory
710    { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmd_mem_r } },
711    // write memory
712    { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmd_mem_w } },
713    // read register
714    { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmd_unsupported } },
715    // write register
716    { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmd_unsupported } },
717    // query variable
718    { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmd_query_var } },
719    // set variable
720    { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmd_unsupported } },
721    // reset system (deprecated)
722    { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmd_unsupported } },
723    // step
724    { 's', { "KGDB_STEP", &BaseRemoteGDB::cmd_step } },
725    // signal and 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 } },
729    // target exited
730    { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmd_unsupported } },
731    // write memory
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 } },
737};
738
739
740bool
741BaseRemoteGDB::cmd_unsupported(GdbCommand::Context &ctx)
742{
743    DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
744    DDUMP(GDBMisc, ctx.data, ctx.len);
745    throw Unsupported();
746}
747
748
749bool
750BaseRemoteGDB::cmd_signal(GdbCommand::Context &ctx)
751{
752    send(csprintf("S%02x", ctx.type).c_str());
753    return true;
754}
755
756bool
757BaseRemoteGDB::cmd_cont(GdbCommand::Context &ctx)
758{
759    const char *p = ctx.data;
760    if (ctx.len) {
761        Addr newPc = hex2i(&p);
762        context->pcState(newPc);
763    }
764    clearSingleStep();
765    return false;
766}
767
768bool
769BaseRemoteGDB::cmd_async_cont(GdbCommand::Context &ctx)
770{
771    const char *p = ctx.data;
772    hex2i(&p);
773    if (*p++ == ';') {
774        Addr newPc = hex2i(&p);
775        context->pcState(newPc);
776    }
777    clearSingleStep();
778    return false;
779}
780
781bool
782BaseRemoteGDB::cmd_detach(GdbCommand::Context &ctx)
783{
784    detach();
785    return false;
786}
787
788bool
789BaseRemoteGDB::cmd_reg_r(GdbCommand::Context &ctx)
790{
791    char buf[2 * regCachePtr->size() + 1];
792    buf[2 * regCachePtr->size()] = '\0';
793    mem2hex(buf, regCachePtr->data(), regCachePtr->size());
794    send(buf);
795    return true;
796}
797
798bool
799BaseRemoteGDB::cmd_reg_w(GdbCommand::Context &ctx)
800{
801    const char *p = ctx.data;
802    p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
803    if (p == NULL || *p != '\0')
804        throw CmdError("E01");
805
806    regCachePtr->setRegs(context);
807    send("OK");
808
809    return true;
810}
811
812bool
813BaseRemoteGDB::cmd_set_thread(GdbCommand::Context &ctx)
814{
815    const char *p = ctx.data + 1; // Ignore the subcommand byte.
816    if (hex2i(&p) != 0)
817        throw CmdError("E01");
818    send("OK");
819    return true;
820}
821
822bool
823BaseRemoteGDB::cmd_mem_r(GdbCommand::Context &ctx)
824{
825    const char *p = ctx.data;
826    Addr addr = hex2i(&p);
827    if (*p++ != ',')
828        throw CmdError("E02");
829    size_t len = hex2i(&p);
830    if (*p != '\0')
831        throw CmdError("E03");
832    if (!acc(addr, len))
833        throw CmdError("E05");
834
835    char buf[len];
836    if (!read(addr, len, buf))
837        throw CmdError("E05");
838
839    char temp[2 * len + 1];
840    temp[2 * len] = '\0';
841    mem2hex(temp, buf, len);
842    send(temp);
843    return true;
844}
845
846bool
847BaseRemoteGDB::cmd_mem_w(GdbCommand::Context &ctx)
848{
849    const char *p = ctx.data;
850    Addr addr = hex2i(&p);
851    if (*p++ != ',')
852        throw CmdError("E06");
853    size_t len = hex2i(&p);
854    if (*p++ != ':')
855        throw CmdError("E07");
856    if (len * 2 > ctx.len - (p - ctx.data))
857        throw CmdError("E08");
858    char buf[len];
859    p = (char *)hex2mem(buf, p, len);
860    if (p == NULL)
861        throw CmdError("E09");
862    if (!acc(addr, len))
863        throw CmdError("E0A");
864    if (!write(addr, len, buf))
865        throw CmdError("E0B");
866    send("OK");
867    return true;
868}
869
870bool
871BaseRemoteGDB::cmd_query_var(GdbCommand::Context &ctx)
872{
873    if (string(ctx.data, ctx.len - 1) != "C")
874        throw Unsupported();
875    send("QC0");
876    return true;
877}
878
879bool
880BaseRemoteGDB::cmd_async_step(GdbCommand::Context &ctx)
881{
882    const char *p = ctx.data;
883    hex2i(&p); // Ignore the subcommand byte.
884    if (*p++ == ';') {
885        Addr newPc = hex2i(&p);
886        context->pcState(newPc);
887    }
888    setSingleStep();
889    return false;
890}
891
892bool
893BaseRemoteGDB::cmd_step(GdbCommand::Context &ctx)
894{
895    if (ctx.len) {
896        const char *p = ctx.data;
897        Addr newPc = hex2i(&p);
898        context->pcState(newPc);
899    }
900    setSingleStep();
901    return false;
902}
903
904bool
905BaseRemoteGDB::cmd_clr_hw_bkpt(GdbCommand::Context &ctx)
906{
907    const char *p = ctx.data;
908    char subcmd = *p++;
909    if (*p++ != ',')
910        throw CmdError("E0D");
911    Addr addr = hex2i(&p);
912    if (*p++ != ',')
913        throw CmdError("E0D");
914    size_t len = hex2i(&p);
915
916    DPRINTF(GDBMisc, "clear %s, addr=%#x, len=%d\n",
917            break_type(subcmd), addr, len);
918
919    switch (subcmd) {
920      case GdbSoftBp:
921        removeSoftBreak(addr, len);
922        break;
923      case GdbHardBp:
924        removeHardBreak(addr, len);
925        break;
926      case GdbWriteWp:
927      case GdbReadWp:
928      case GdbAccWp:
929      default: // unknown
930        throw Unsupported();
931    }
932    send("OK");
933
934    return true;
935}
936
937bool
938BaseRemoteGDB::cmd_set_hw_bkpt(GdbCommand::Context &ctx)
939{
940    const char *p = ctx.data;
941    char subcmd = *p++;
942    if (*p++ != ',')
943        throw CmdError("E0D");
944    Addr addr = hex2i(&p);
945    if (*p++ != ',')
946        throw CmdError("E0D");
947    size_t len = hex2i(&p);
948
949    DPRINTF(GDBMisc, "set %s, addr=%#x, len=%d\n",
950            break_type(subcmd), addr, len);
951
952    switch (subcmd) {
953      case GdbSoftBp:
954        insertSoftBreak(addr, len);
955        break;
956      case GdbHardBp:
957        insertHardBreak(addr, len);
958        break;
959      case GdbWriteWp:
960      case GdbReadWp:
961      case GdbAccWp:
962      default: // unknown
963        throw Unsupported();
964    }
965    send("OK");
966
967    return true;
968}
969
970
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.
976bool
977BaseRemoteGDB::trap(int type)
978{
979
980    if (!attached)
981        return false;
982
983    DPRINTF(GDBMisc, "trap: PC=%s\n", context->pcState());
984
985    clearSingleStep();
986
987    /*
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.
991     *
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.
996     */
997    if (!active) {
998        active = true;
999    } else {
1000        // Tell remote host that an exception has occurred.
1001        send(csprintf("S%02x", type).c_str());
1002    }
1003
1004    // Stick frame regs into our reg cache.
1005    regCachePtr = gdbRegs();
1006    regCachePtr->getRegs(context);
1007
1008    char data[GDBPacketBufLen + 1];
1009    GdbCommand::Context cmdCtx;
1010    cmdCtx.type = type;
1011    cmdCtx.data = &data[1];
1012
1013    for (;;) {
1014        try {
1015            size_t datalen = recv(data, sizeof(data));
1016            if (datalen < 1)
1017                throw BadClient();
1018
1019            data[datalen] = 0; // Sentinel
1020            cmdCtx.cmd_byte = data[0];
1021            cmdCtx.len = datalen - 1;
1022
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();
1028            }
1029            cmdCtx.cmd = &(cmdIt->second);
1030
1031            if (!(this->*(cmdCtx.cmd->func))(cmdCtx))
1032                break;
1033
1034        } catch (BadClient &e) {
1035            if (e.warning)
1036                warn(e.warning);
1037            detach();
1038            break;
1039        } catch (Unsupported &e) {
1040            send("");
1041        } catch (CmdError &e) {
1042            send(e.error.c_str());
1043        } catch (...) {
1044            panic("Unrecognzied GDB exception.");
1045        }
1046    }
1047
1048    return true;
1049}
1050
1051// Convert a hex digit into an integer.
1052// This returns -1 if the argument passed is no valid hex digit.
1053int
1054BaseRemoteGDB::digit2i(char c)
1055{
1056    if (c >= '0' && c <= '9')
1057        return (c - '0');
1058    else if (c >= 'a' && c <= 'f')
1059        return (c - 'a' + 10);
1060    else if (c >= 'A' && c <= 'F')
1061        return (c - 'A' + 10);
1062    else
1063        return (-1);
1064}
1065
1066// Convert the low 4 bits of an integer into an hex digit.
1067char
1068BaseRemoteGDB::i2digit(int n)
1069{
1070    return ("0123456789abcdef"[n & 0x0f]);
1071}
1072
1073// Convert a byte array into an hex string.
1074void
1075BaseRemoteGDB::mem2hex(char *vdst, const char *vsrc, int len)
1076{
1077    char *dst = vdst;
1078    const char *src = vsrc;
1079
1080    while (len--) {
1081        *dst++ = i2digit(*src >> 4);
1082        *dst++ = i2digit(*src++);
1083    }
1084    *dst = '\0';
1085}
1086
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
1090// returned.
1091const char *
1092BaseRemoteGDB::hex2mem(char *vdst, const char *src, int maxlen)
1093{
1094    char *dst = vdst;
1095    int msb, lsb;
1096
1097    while (*src && maxlen--) {
1098        msb = digit2i(*src++);
1099        if (msb < 0)
1100            return (src - 1);
1101        lsb = digit2i(*src++);
1102        if (lsb < 0)
1103            return (NULL);
1104        *dst++ = (msb << 4) | lsb;
1105    }
1106    return src;
1107}
1108
1109// Convert an hex string into an integer.
1110// This returns a pointer to the character following the last valid
1111// hex digit.
1112Addr
1113BaseRemoteGDB::hex2i(const char **srcp)
1114{
1115    const char *src = *srcp;
1116    Addr r = 0;
1117    int nibble;
1118
1119    while ((nibble = digit2i(*src)) >= 0) {
1120        r *= 16;
1121        r += nibble;
1122        src++;
1123    }
1124    *srcp = src;
1125    return r;
1126}
1127