/*
 * Copyright 2015 LabWare
 * Copyright 2014 Google, Inc.
 * 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
 *          Boris Shingarov
 */

/*
 * 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 "base/remote_gdb.hh"

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

#include <csignal>
#include <cstdio>
#include <string>

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

using namespace std;
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::InputEvent::InputEvent(GDBListener *l, int fd, int e)
    : PollEvent(fd, e), listener(l)
{}

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

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

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

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++;
    }

    inputEvent = new InputEvent(this, listener.getfd(), POLLIN);
    pollQueue.schedule(inputEvent);

#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::InputEvent::InputEvent(BaseRemoteGDB *g, int fd, int e)
    : PollEvent(fd, e), gdb(g)
{}

void
BaseRemoteGDB::InputEvent::process(int revent)
{
    if (gdb->trapEvent.scheduled()) {
        warn("GDB trap event has already been scheduled! "
             "Ignoring this input event.");
        return;
    }

    if (revent & POLLIN) {
        gdb->trapEvent.type(SIGILL);
        gdb->scheduleInstCommitEvent(&gdb->trapEvent, 0);
    } else if (revent & POLLNVAL) {
        gdb->descheduleInstCommitEvent(&gdb->trapEvent);
        gdb->detach();
    }
}

void
BaseRemoteGDB::TrapEvent::process()
{
    gdb->trap(_type);
}

void
BaseRemoteGDB::SingleStepEvent::process()
{
    if (!gdb->singleStepEvent.scheduled())
        gdb->scheduleInstCommitEvent(&gdb->singleStepEvent, 1);
    gdb->trap(SIGTRAP);
}

BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c) :
        inputEvent(NULL), trapEvent(this), listener(NULL),
        number(-1), fd(-1), active(false), attached(false), system(_system),
        context(c), singleStepEvent(this)
{
}

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

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

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

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

    inputEvent = new InputEvent(this, fd, POLLIN);
    pollQueue.schedule(inputEvent);

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

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

    pollQueue.remove(inputEvent);
    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;
}

void
BaseRemoteGDB::clearSingleStep()
{
    descheduleInstCommitEvent(&singleStepEvent);
}

void
BaseRemoteGDB::setSingleStep()
{
    if (!singleStepEvent.scheduled())
        scheduleInstCommitEvent(&singleStepEvent, 1);
}

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

EventQueue *
BaseRemoteGDB::getComInstEventQueue()
{
    BaseCPU *cpu = context->getCpuPtr();
    return cpu->comInstEventQueue[context->threadId()];
}

void
BaseRemoteGDB::scheduleInstCommitEvent(Event *ev, int delta)
{
    EventQueue *eq = getComInstEventQueue();
    // Here "ticks" aren't simulator ticks which measure time, they're
    // instructions committed by the CPU.
    eq->schedule(ev, eq->getCurTick() + delta);
}

void
BaseRemoteGDB::descheduleInstCommitEvent(Event *ev)
{
    if (ev->scheduled())
        getComInstEventQueue()->deschedule(ev);
}

bool
BaseRemoteGDB::checkBpLen(size_t len)
{
    return len == sizeof(MachInst);
}

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 (!checkBpLen(len))
        panic("invalid length\n");

    return insertHardBreak(addr, len);
}

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

    return removeHardBreak(addr, len);
}

bool
BaseRemoteGDB::insertHardBreak(Addr addr, size_t len)
{
    if (!checkBpLen(len))
        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 (!checkBpLen(len))
        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;

    unique_ptr<BaseRemoteGDB::BaseGdbRegCache> regCache(gdbRegs());

    bufferSize = regCache->size() * 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(buffer, bufferSize, "S%02x", type);
        send(buffer);
    }

    // Stick frame regs into our reg cache.
    regCache->getRegs(context);

    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(buffer, bufferSize,
                    "S%02x", type);
            send(buffer);
            continue;

          case GDBRegR:
            if (2 * regCache->size() > bufferSize)
                panic("buffer too small");

            mem2hex(buffer, regCache->data(), regCache->size());
            send(buffer);
            continue;

          case GDBRegW:
            p = hex2mem(regCache->data(), p, regCache->size());
            if (p == NULL || *p != '\0')
                send("E01");
            else {
                regCache->setRegs(context);
                send("OK");
            }
            continue;

          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, 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, 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(char *vdst, const char *vsrc, int len)
{
    char *dst = vdst;
    const char *src = 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(char *vdst, const char *src, int maxlen)
{
    char *dst = 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);
}

