/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 */

/*
 * Copyright (c) 1990, 1993 The Regents of the University of California
 * All rights reserved
 *
 * This software was developed by the Computer Systems Engineering group
 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
 * contributed to Berkeley.
 *
 * All advertising materials mentioning features or use of this software
 * must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Lawrence Berkeley Laboratories.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
 */

/*-
 * Copyright (c) 2001 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the NetBSD
 *      Foundation, Inc. and its contributors.
 * 4. Neither the name of The NetBSD Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
 *
 * Taken from NetBSD
 *
 * "Stub" to allow remote cpu to debug over a serial line using gdb.
 */

#include <signal.h>
#include <sys/signal.h>
#include <unistd.h>

#include <cstdio>
#include <string>

#include "arch/vtophys.hh"
#include "base/intmath.hh"
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "debug/GDBAll.hh"
#include "mem/port.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "mem/se_translating_port_proxy.hh"
#include "sim/full_system.hh"
#include "sim/system.hh"

using namespace std;
using namespace Debug;
using namespace TheISA;

#ifndef NDEBUG
vector<BaseRemoteGDB *> debuggers;

void
debugger()
{
    static int current_debugger = -1;
    if (current_debugger >= 0 && current_debugger < (int)debuggers.size()) {
        BaseRemoteGDB *gdb = debuggers[current_debugger];
        if (!gdb->isattached())
            gdb->listener->accept();
        if (gdb->isattached())
            gdb->trap(SIGILL);
    }
}
#endif

///////////////////////////////////////////////////////////
//
//
//

GDBListener::Event::Event(GDBListener *l, int fd, int e)
    : PollEvent(fd, e), listener(l)
{}

void
GDBListener::Event::process(int revent)
{
    listener->accept();
}

GDBListener::GDBListener(BaseRemoteGDB *g, int p)
    : event(NULL), gdb(g), port(p)
{
    assert(!gdb->listener);
    gdb->listener = this;
}

GDBListener::~GDBListener()
{
    if (event)
        delete event;
}

string
GDBListener::name()
{
    return gdb->name() + ".listener";
}

void
GDBListener::listen()
{
    if (ListenSocket::allDisabled()) {
        warn_once("Sockets disabled, not accepting gdb connections");
        return;
    }

    while (!listener.listen(port, true)) {
        DPRINTF(GDBMisc, "Can't bind port %d\n", port);
        port++;
    }

    event = new Event(this, listener.getfd(), POLLIN);
    pollQueue.schedule(event);

#ifndef NDEBUG
    gdb->number = debuggers.size();
    debuggers.push_back(gdb);
#endif

#ifndef NDEBUG
    ccprintf(cerr, "%d: %s: listening for remote gdb #%d on port %d\n",
             curTick(), name(), gdb->number, port);
#else
    ccprintf(cerr, "%d: %s: listening for remote gdb on port %d\n",
             curTick(), name(), port);
#endif
}

void
GDBListener::accept()
{
    if (!listener.islistening())
        panic("GDBListener::accept(): cannot accept if we're not listening!");

    int sfd = listener.accept(true);

    if (sfd != -1) {
        if (gdb->isattached())
            close(sfd);
        else
            gdb->attach(sfd);
    }
}

BaseRemoteGDB::Event::Event(BaseRemoteGDB *g, int fd, int e)
    : PollEvent(fd, e), gdb(g)
{}

void
BaseRemoteGDB::Event::process(int revent)
{
    if (revent & POLLIN)
        gdb->trap(SIGILL);
    else if (revent & POLLNVAL)
        gdb->detach();
}

BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, size_t cacheSize)
    : event(NULL), listener(NULL), number(-1), fd(-1),
      active(false), attached(false),
      system(_system), context(c),
      gdbregs(cacheSize)
{
    memset(gdbregs.regs, 0, gdbregs.bytes());
}

BaseRemoteGDB::~BaseRemoteGDB()
{
    if (event)
        delete event;
}

string
BaseRemoteGDB::name()
{
    return system->name() + ".remote_gdb";
}

bool
BaseRemoteGDB::isattached()
{ return attached; }

void
BaseRemoteGDB::attach(int f)
{
    fd = f;

    event = new Event(this, fd, POLLIN);
    pollQueue.schedule(event);

    attached = true;
    DPRINTFN("remote gdb attached\n");
}

void
BaseRemoteGDB::detach()
{
    attached = false;
    close(fd);
    fd = -1;

    pollQueue.remove(event);
    DPRINTFN("remote gdb detached\n");
}

const char *
BaseRemoteGDB::gdb_command(char cmd)
{
    switch (cmd) {
      case GDBSignal: return "KGDB_SIGNAL";
      case GDBSetBaud: return "KGDB_SET_BAUD";
      case GDBSetBreak: return "KGDB_SET_BREAK";
      case GDBCont: return "KGDB_CONT";
      case GDBAsyncCont: return "KGDB_ASYNC_CONT";
      case GDBDebug: return "KGDB_DEBUG";
      case GDBDetach: return "KGDB_DETACH";
      case GDBRegR: return "KGDB_REG_R";
      case GDBRegW: return "KGDB_REG_W";
      case GDBSetThread: return "KGDB_SET_THREAD";
      case GDBCycleStep: return "KGDB_CYCLE_STEP";
      case GDBSigCycleStep: return "KGDB_SIG_CYCLE_STEP";
      case GDBKill: return "KGDB_KILL";
      case GDBMemW: return "KGDB_MEM_W";
      case GDBMemR: return "KGDB_MEM_R";
      case GDBSetReg: return "KGDB_SET_REG";
      case GDBReadReg: return "KGDB_READ_REG";
      case GDBQueryVar: return "KGDB_QUERY_VAR";
      case GDBSetVar: return "KGDB_SET_VAR";
      case GDBReset: return "KGDB_RESET";
      case GDBStep: return "KGDB_STEP";
      case GDBAsyncStep: return "KGDB_ASYNC_STEP";
      case GDBThreadAlive: return "KGDB_THREAD_ALIVE";
      case GDBTargetExit: return "KGDB_TARGET_EXIT";
      case GDBBinaryDload: return "KGDB_BINARY_DLOAD";
      case GDBClrHwBkpt: return "KGDB_CLR_HW_BKPT";
      case GDBSetHwBkpt: return "KGDB_SET_HW_BKPT";
      case GDBStart: return "KGDB_START";
      case GDBEnd: return "KGDB_END";
      case GDBGoodP: return "KGDB_GOODP";
      case GDBBadP: return "KGDB_BADP";
      default: return "KGDB_UNKNOWN";
    }
}

/////////////////////////
//
//

uint8_t
BaseRemoteGDB::getbyte()
{
    uint8_t b;
    if (::read(fd, &b, 1) != 1)
        warn("could not read byte from debugger");
    return b;
}

void
BaseRemoteGDB::putbyte(uint8_t b)
{
    if (::write(fd, &b, 1) != 1)
        warn("could not write byte to debugger");
}

// Send a packet to gdb
void
BaseRemoteGDB::send(const char *bp)
{
    const char *p;
    uint8_t csum, c;

    DPRINTF(GDBSend, "send:  %s\n", bp);

    do {
        p = bp;
        //Start sending a packet
        putbyte(GDBStart);
        //Send the contents, and also keep a check sum.
        for (csum = 0; (c = *p); p++) {
            putbyte(c);
            csum += c;
        }
        //Send the ending character.
        putbyte(GDBEnd);
        //Sent the checksum.
        putbyte(i2digit(csum >> 4));
        putbyte(i2digit(csum));
        //Try transmitting over and over again until the other end doesn't send an
        //error back.
    } while ((c = getbyte() & 0x7f) == GDBBadP);
}

// Receive a packet from gdb
int
BaseRemoteGDB::recv(char *bp, int maxlen)
{
    char *p;
    int c, csum;
    int len;

    do {
        p = bp;
        csum = len = 0;
        //Find the beginning of a packet
        while ((c = getbyte()) != GDBStart)
            ;

        //Read until you find the end of the data in the packet, and keep
        //track of the check sum.
        while ((c = getbyte()) != GDBEnd && len < maxlen) {
            c &= 0x7f;
            csum += c;
            *p++ = c;
            len++;
        }

        //Mask the check sum, and terminate the command string.
        csum &= 0xff;
        *p = '\0';

        //If the command was too long, report an error.
        if (len >= maxlen) {
            putbyte(GDBBadP);
            continue;
        }

        //Bring in the checksum. If the check sum matches, csum will be 0.
        csum -= digit2i(getbyte()) * 16;
        csum -= digit2i(getbyte());

        //If the check sum was correct
        if (csum == 0) {
            //Report that the packet was received correctly
            putbyte(GDBGoodP);
            // Sequence present?
            if (bp[2] == ':') {
                putbyte(bp[0]);
                putbyte(bp[1]);
                len -= 3;
                memcpy(bp, bp+3, len);
            }
            break;
        }
        //Otherwise, report that there was a mistake.
        putbyte(GDBBadP);
    } while (1);

    DPRINTF(GDBRecv, "recv:  %s: %s\n", gdb_command(*bp), bp);

    return (len);
}

// Read bytes from kernel address space for debugger.
bool
BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
{
    static Addr lastaddr = 0;
    static size_t lastsize = 0;

    if (vaddr < 10) {
      DPRINTF(GDBRead, "read:  reading memory location zero!\n");
      vaddr = lastaddr + lastsize;
    }

    DPRINTF(GDBRead, "read:  addr=%#x, size=%d", vaddr, size);

    if (FullSystem) {
        FSTranslatingPortProxy &proxy = context->getVirtProxy();
        proxy.readBlob(vaddr, (uint8_t*)data, size);
    } else {
        SETranslatingPortProxy &proxy = context->getMemProxy();
        proxy.readBlob(vaddr, (uint8_t*)data, size);
    }

#if TRACING_ON
    if (DTRACE(GDBRead)) {
        if (DTRACE(GDBExtra)) {
            char buf[1024];
            mem2hex(buf, data, size);
            DPRINTFNR(": %s\n", buf);
        } else
            DPRINTFNR("\n");
    }
#endif

    return true;
}

// Write bytes to kernel address space for debugger.
bool
BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
{
    static Addr lastaddr = 0;
    static size_t lastsize = 0;

    if (vaddr < 10) {
      DPRINTF(GDBWrite, "write: writing memory location zero!\n");
      vaddr = lastaddr + lastsize;
    }

    if (DTRACE(GDBWrite)) {
        DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
        if (DTRACE(GDBExtra)) {
            char buf[1024];
            mem2hex(buf, data, size);
            DPRINTFNR(": %s\n", buf);
        } else
            DPRINTFNR("\n");
    }
    if (FullSystem) {
        FSTranslatingPortProxy &proxy = context->getVirtProxy();
        proxy.writeBlob(vaddr, (uint8_t*)data, size);
    } else {
        SETranslatingPortProxy &proxy = context->getMemProxy();
        proxy.writeBlob(vaddr, (uint8_t*)data, size);
    }

    return true;
}

PCEventQueue *BaseRemoteGDB::getPcEventQueue()
{
    return &system->pcEventQueue;
}

BaseRemoteGDB::HardBreakpoint::HardBreakpoint(BaseRemoteGDB *_gdb, Addr pc)
    : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc),
      gdb(_gdb), refcount(0)
{
    DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
}

void
BaseRemoteGDB::HardBreakpoint::process(ThreadContext *tc)
{
    DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());

    if (tc == gdb->context)
        gdb->trap(SIGTRAP);
}

bool
BaseRemoteGDB::insertSoftBreak(Addr addr, size_t len)
{
    if (len != sizeof(TheISA::MachInst))
        panic("invalid length\n");

    return insertHardBreak(addr, len);
}

bool
BaseRemoteGDB::removeSoftBreak(Addr addr, size_t len)
{
    if (len != sizeof(MachInst))
        panic("invalid length\n");

    return removeHardBreak(addr, len);
}

bool
BaseRemoteGDB::insertHardBreak(Addr addr, size_t len)
{
    if (len != sizeof(MachInst))
        panic("invalid length\n");

    DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr);

    HardBreakpoint *&bkpt = hardBreakMap[addr];
    if (bkpt == 0)
        bkpt = new HardBreakpoint(this, addr);

    bkpt->refcount++;

    return true;
}

bool
BaseRemoteGDB::removeHardBreak(Addr addr, size_t len)
{
    if (len != sizeof(MachInst))
        panic("invalid length\n");

    DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr);

    break_iter_t i = hardBreakMap.find(addr);
    if (i == hardBreakMap.end())
        return false;

    HardBreakpoint *hbp = (*i).second;
    if (--hbp->refcount == 0) {
        delete hbp;
        hardBreakMap.erase(i);
    }

    return true;
}

void
BaseRemoteGDB::setTempBreakpoint(Addr bkpt)
{
    DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
    insertHardBreak(bkpt, sizeof(TheISA::MachInst));
}

void
BaseRemoteGDB::clearTempBreakpoint(Addr &bkpt)
{
    DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
    removeHardBreak(bkpt, sizeof(TheISA::MachInst));
    bkpt = 0;
}

const char *
BaseRemoteGDB::break_type(char c)
{
    switch(c) {
      case '0': return "software breakpoint";
      case '1': return "hardware breakpoint";
      case '2': return "write watchpoint";
      case '3': return "read watchpoint";
      case '4': return "access watchpoint";
      default: return "unknown breakpoint/watchpoint";
    }
}

// This function does all command processing for interfacing to a
// remote gdb.  Note that the error codes are ignored by gdb at
// present, but might eventually become meaningful. (XXX) It might
// makes sense to use POSIX errno values, because that is what the
// gdb/remote.c functions want to return.
bool
BaseRemoteGDB::trap(int type)
{
    uint64_t val;
    size_t datalen, len;
    char data[GDBPacketBufLen + 1];
    char *buffer;
    size_t bufferSize;
    const char *p;
    char command, subcmd;
    string var;
    bool ret;

    if (!attached)
        return false;

    bufferSize = gdbregs.bytes() * 2 + 256;
    buffer = (char*)malloc(bufferSize);

    DPRINTF(GDBMisc, "trap: PC=%s\n", context->pcState());

    clearSingleStep();

    /*
     * The first entry to this function is normally through
     * a breakpoint trap in kgdb_connect(), in which case we
     * must advance past the breakpoint because gdb will not.
     *
     * On the first entry here, we expect that gdb is not yet
     * listening to us, so just enter the interaction loop.
     * After the debugger is "active" (connected) it will be
     * waiting for a "signaled" message from us.
     */
    if (!active)
        active = true;
    else
        // Tell remote host that an exception has occurred.
        snprintf((char *)buffer, bufferSize, "S%02x", type);
        send(buffer);

    // Stick frame regs into our reg cache.
    getregs();

    for (;;) {
        datalen = recv(data, sizeof(data));
        data[sizeof(data) - 1] = 0; // Sentinel
        command = data[0];
        subcmd = 0;
        p = data + 1;
        switch (command) {

          case GDBSignal:
            // if this command came from a running gdb, answer it --
            // the other guy has no way of knowing if we're in or out
            // of this loop when he issues a "remote-signal".
            snprintf((char *)buffer, bufferSize,
                    "S%02x", type);
            send(buffer);
            continue;

          case GDBRegR:
            if (2 * gdbregs.bytes() > bufferSize)
                panic("buffer too small");

            mem2hex(buffer, gdbregs.regs, gdbregs.bytes());
            send(buffer);
            continue;

          case GDBRegW:
            p = hex2mem(gdbregs.regs, p, gdbregs.bytes());
            if (p == NULL || *p != '\0')
                send("E01");
            else {
                setregs();
                send("OK");
            }
            continue;

#if 0
          case GDBSetReg:
            val = hex2i(&p);
            if (*p++ != '=') {
                send("E01");
                continue;
            }
            if (val < 0 && val >= KGDB_NUMREGS) {
                send("E01");
                continue;
            }

            gdbregs.regs[val] = hex2i(&p);
            setregs();
            send("OK");

            continue;
#endif

          case GDBMemR:
            val = hex2i(&p);
            if (*p++ != ',') {
                send("E02");
                continue;
            }
            len = hex2i(&p);
            if (*p != '\0') {
                send("E03");
                continue;
            }
            if (len > bufferSize) {
                send("E04");
                continue;
            }
            if (!acc(val, len)) {
                send("E05");
                continue;
            }

            if (read(val, (size_t)len, (char *)buffer)) {
               // variable length array would be nice, but C++ doesn't
               // officially support those...
               char *temp = new char[2*len+1];
               mem2hex(temp, buffer, len);
               send(temp);
               delete [] temp;
            } else {
               send("E05");
            }
            continue;

          case GDBMemW:
            val = hex2i(&p);
            if (*p++ != ',') {
                send("E06");
                continue;
            }
            len = hex2i(&p);
            if (*p++ != ':') {
                send("E07");
                continue;
            }
            if (len > datalen - (p - data)) {
                send("E08");
                continue;
            }
            p = hex2mem(buffer, p, bufferSize);
            if (p == NULL) {
                send("E09");
                continue;
            }
            if (!acc(val, len)) {
                send("E0A");
                continue;
            }
            if (write(val, (size_t)len, (char *)buffer))
              send("OK");
            else
              send("E0B");
            continue;

          case GDBSetThread:
            subcmd = *p++;
            val = hex2i(&p);
            if (val == 0)
                send("OK");
            else
                send("E01");
            continue;

          case GDBDetach:
          case GDBKill:
            active = false;
            clearSingleStep();
            detach();
            goto out;

          case GDBAsyncCont:
            subcmd = hex2i(&p);
            if (*p++ == ';') {
                val = hex2i(&p);
                context->pcState(val);
            }
            clearSingleStep();
            goto out;

          case GDBCont:
            if (p - data < (ptrdiff_t)datalen) {
                val = hex2i(&p);
                context->pcState(val);
            }
            clearSingleStep();
            goto out;

          case GDBAsyncStep:
            subcmd = hex2i(&p);
            if (*p++ == ';') {
                val = hex2i(&p);
                context->pcState(val);
            }
            setSingleStep();
            goto out;

          case GDBStep:
            if (p - data < (ptrdiff_t)datalen) {
                val = hex2i(&p);
                context->pcState(val);
            }
            setSingleStep();
            goto out;

          case GDBClrHwBkpt:
            subcmd = *p++;
            if (*p++ != ',') send("E0D");
            val = hex2i(&p);
            if (*p++ != ',') send("E0D");
            len = hex2i(&p);

            DPRINTF(GDBMisc, "clear %s, addr=%#x, len=%d\n",
                    break_type(subcmd), val, len);

            ret = false;

            switch (subcmd) {
              case '0': // software breakpoint
                ret = removeSoftBreak(val, len);
                break;

              case '1': // hardware breakpoint
                ret = removeHardBreak(val, len);
                break;

              case '2': // write watchpoint
              case '3': // read watchpoint
              case '4': // access watchpoint
              default: // unknown
                send("");
                break;
            }

            send(ret ? "OK" : "E0C");
            continue;

          case GDBSetHwBkpt:
            subcmd = *p++;
            if (*p++ != ',') send("E0D");
            val = hex2i(&p);
            if (*p++ != ',') send("E0D");
            len = hex2i(&p);

            DPRINTF(GDBMisc, "set %s, addr=%#x, len=%d\n",
                    break_type(subcmd), val, len);

            ret = false;

            switch (subcmd) {
              case '0': // software breakpoint
                ret = insertSoftBreak(val, len);
                break;

              case '1': // hardware breakpoint
                ret = insertHardBreak(val, len);
                break;

              case '2': // write watchpoint
              case '3': // read watchpoint
              case '4': // access watchpoint
              default: // unknown
                send("");
                break;
            }

            send(ret ? "OK" : "E0C");
            continue;

          case GDBQueryVar:
            var = string(p, datalen - 1);
            if (var == "C")
                send("QC0");
            else
                send("");
            continue;

          case GDBSetBaud:
          case GDBSetBreak:
          case GDBDebug:
          case GDBCycleStep:
          case GDBSigCycleStep:
          case GDBReadReg:
          case GDBSetVar:
          case GDBReset:
          case GDBThreadAlive:
          case GDBTargetExit:
          case GDBBinaryDload:
            // Unsupported command
            DPRINTF(GDBMisc, "Unsupported command: %s\n",
                    gdb_command(command));
            DDUMP(GDBMisc, (uint8_t *)data, datalen);
            send("");
            continue;

          default:
            // Unknown command.
            DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
                    command, command);
            send("");
            continue;


        }
    }

  out:
    free(buffer);
    return true;
}

// Convert a hex digit into an integer.
// This returns -1 if the argument passed is no valid hex digit.
int
BaseRemoteGDB::digit2i(char c)
{
    if (c >= '0' && c <= '9')
        return (c - '0');
    else if (c >= 'a' && c <= 'f')
        return (c - 'a' + 10);
    else if (c >= 'A' && c <= 'F')

        return (c - 'A' + 10);
    else
        return (-1);
}

// Convert the low 4 bits of an integer into an hex digit.
char
BaseRemoteGDB::i2digit(int n)
{
    return ("0123456789abcdef"[n & 0x0f]);
}

// Convert a byte array into an hex string.
void
BaseRemoteGDB::mem2hex(void *vdst, const void *vsrc, int len)
{
    char *dst = (char *)vdst;
    const char *src = (const char *)vsrc;

    while (len--) {
        *dst++ = i2digit(*src >> 4);
        *dst++ = i2digit(*src++);
    }
    *dst = '\0';
}

// Convert an hex string into a byte array.
// This returns a pointer to the character following the last valid
// hex digit. If the string ends in the middle of a byte, NULL is
// returned.
const char *
BaseRemoteGDB::hex2mem(void *vdst, const char *src, int maxlen)
{
    char *dst = (char *)vdst;
    int msb, lsb;

    while (*src && maxlen--) {
        msb = digit2i(*src++);
        if (msb < 0)
            return (src - 1);
        lsb = digit2i(*src++);
        if (lsb < 0)
            return (NULL);
        *dst++ = (msb << 4) | lsb;
    }
    return (src);
}

// Convert an hex string into an integer.
// This returns a pointer to the character following the last valid
// hex digit.
Addr
BaseRemoteGDB::hex2i(const char **srcp)
{
    const char *src = *srcp;
    Addr r = 0;
    int nibble;

    while ((nibble = digit2i(*src)) >= 0) {
        r *= 16;
        r += nibble;
        src++;
    }
    *srcp = src;
    return (r);
}

