/*
 * Copyright (c) 2018 ARM Limited
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright 2015, 2021 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.
 */

/*
 * 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/select.h>
#include <sys/time.h>
#include <unistd.h>

#include <cassert>
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <iterator>
#include <sstream>
#include <string>
#include <utility>

#include "base/cprintf.hh"
#include "base/intmath.hh"
#include "base/logging.hh"
#include "base/socket.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "debug/GDBAll.hh"
#include "mem/port.hh"
#include "mem/port_proxy.hh"
#include "mem/se_translating_port_proxy.hh"
#include "mem/translating_port_proxy.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
#include "sim/sim_events.hh"
#include "sim/system.hh"

namespace gem5
{

static const char GDBStart = '$';
static const char GDBEnd = '#';
static const char GDBGoodP = '+';
static const char GDBBadP = '-';

class HardBreakpoint : public PCEvent
{
  private:
    BaseRemoteGDB *gdb;

  public:
    int refcount;

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

    const std::string name() const override { return gdb->name() + ".hwbkpt"; }

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

        if (tc == gdb->tc)
            gdb->trap(tc->contextId(), GDBSignal::TRAP,"");
    }
};

namespace {

// Exception to throw when the connection to the client is broken.
struct BadClient
{
    const char *warning;
    BadClient(const char *_warning=NULL) : warning(_warning)
    {}
};

// Exception to throw when an error needs to be reported to the client.
struct CmdError
{
    std::string error;
    CmdError(std::string _error) : error(_error)
    {}
};

// Exception to throw when something isn't supported.
class Unsupported {};

// Convert a hex digit into an integer.
// This returns -1 if the argument passed is no valid hex digit.
int
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 a hex to a char
char
hex2c(char c0,char c1)
{
   char temp[3] = {c0,c1,'\0'};
   return std::stoi(temp,0,16);
}

//this function will be used in a future patch
//convert a encoded string to a string
std::string
hexS2string(std::string hex_in)
{
   std::string out="";
   for (unsigned int i = 0; i + 1 < hex_in.length();i += 2){
       out.push_back(hex2c(hex_in[i],hex_in[i+1]));
   }
   return out;
}

//convert a string to a hex encoded string
std::string
string2hexS(std::string in)
{
   std::string out = "";
   for (auto ch : in){
       char temp[3] = "  ";
        std::snprintf(temp,3,"%02hhx",ch);
        out.append(temp);
   }
   return out;
}

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

// Convert a byte array into an hex string.
void
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 *
hex2mem(char *vdst, const char *src, int max_len)
{
    char *dst = vdst;
    int msb, lsb;

    while (*src && max_len--) {
        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
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;
}

bool
parseThreadId(const char **srcp, bool &all, bool &any, ContextID &tid)
{
    all = any = false;
    tid = 0;
    const char *src = *srcp;
    if (*src == '-') {
        // This could be the start of -1, which means all threads.
        src++;
        if (*src++ != '1')
            return false;
        *srcp += 2;
        all = true;
        return true;
    }
    tid = hex2i(srcp);
    // If *srcp still points to src, no characters were consumed and no thread
    // id was found. Without this check, we can't tell the difference between
    // zero and a parsing error.
    if (*srcp == src)
        return false;

    if (tid == 0)
        any = true;

    tid--;

    return true;
}

int
encodeThreadId(ContextID id)
{
    // Thread ID 0 is reserved and means "pick any thread".
    return id + 1;
}

enum GdbBreakpointType
{
    GdbSoftBp = '0',
    GdbHardBp = '1',
    GdbWriteWp = '2',
    GdbReadWp = '3',
    GdbAccWp = '4',
};

const char *
breakType(char c)
{
    switch(c) {
      case GdbSoftBp: return "software breakpoint";
      case GdbHardBp: return "hardware breakpoint";
      case GdbWriteWp: return "write watchpoint";
      case GdbReadWp: return "read watchpoint";
      case GdbAccWp: return "access watchpoint";
      default: return "unknown breakpoint/watchpoint";
    }
}

std::map<Addr, HardBreakpoint *> hardBreakMap;

}

BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) :
        incomingConnectionEvent(nullptr), incomingDataEvent(nullptr),
        fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this),
        trapEvent(this), singleStepEvent(*this)
{
    listener = listenSocketInetConfig(_port).build(name());
}

BaseRemoteGDB::~BaseRemoteGDB()
{
    delete incomingConnectionEvent;
    delete incomingDataEvent;
}

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

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

    listener->listen();

    incomingConnectionEvent =
            new IncomingConnectionEvent(this, listener->getfd(), POLLIN);
    pollQueue.schedule(incomingConnectionEvent);
}

void
BaseRemoteGDB::connect()
{
    panic_if(!listener->islistening(),
             "Can't accept GDB connections without any threads!");

    pollQueue.remove(incomingConnectionEvent);

    int sfd = listener->accept();

    if (sfd != -1) {
        if (isAttached())
            close(sfd);
        else
            attach(sfd);
    }
}

const ListenSocket &
BaseRemoteGDB::hostSocket() const
{
    panic_if(!listener->islistening(),
             "Remote GDB socket is unknown until listen() has been called.");
    return *listener;
}

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

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

    processCommands();

    if (isAttached()) {
        // At this point an initial communication with GDB is handled
        // and we're ready to continue. Here we arrange IncomingDataEvent
        // to get notified when GDB breaks in.
        //
        // However, GDB can decide to disconnect during that initial
        // communication. In that case, we cannot arrange data event because
        // the socket is already closed (not that it makes any sense, anyways).
        //
        // Hence the check above.
        incomingDataEvent = new IncomingDataEvent(this, fd, POLLIN);
        pollQueue.schedule(incomingDataEvent);
    }
}

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

    if (incomingDataEvent) {
        // incomingDataEvent gets scheduled in attach() after
        // initial communication with GDB is handled and GDB tells
        // gem5 to continue.
        //
        // GDB can disconnect before that in which case `incomingDataEvent`
        // is NULL.
        //
        // Hence the check above.

        pollQueue.remove(incomingDataEvent);
        incomingDataEvent = nullptr;
    }
    pollQueue.schedule(incomingConnectionEvent);
    DPRINTFN("remote gdb detached\n");
}

void
BaseRemoteGDB::addThreadContext(ThreadContext *_tc)
{
    [[maybe_unused]] auto it_success = threads.insert({_tc->contextId(), _tc});
    assert(it_success.second);
    // If no ThreadContext is current selected, select this one.
    if (!tc)
        assert(selectThreadContext(_tc->contextId()));

    // Now that we have a thread, we can start listening.
    if (!listener->islistening())
        listen();
}

void
BaseRemoteGDB::replaceThreadContext(ThreadContext *_tc)
{
    auto it = threads.find(_tc->contextId());
    panic_if(it == threads.end(), "No context with ID %d found.",
            _tc->contextId());
    it->second = _tc;
}

bool
BaseRemoteGDB::selectThreadContext(ContextID id)
{
    auto it = threads.find(id);
    if (it == threads.end())
        return false;

    tc = it->second;
    // Update the register cache for the new thread context, if there is one.
    if (regCachePtr)
        regCachePtr->getRegs(tc);
    return true;
}

// 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.
void
BaseRemoteGDB::trap(ContextID id, GDBSignal sig,const std::string& stopReason)
{
    if (!attached)
        return;

    if (tc->contextId() != id) {
        //prevent thread switch when single stepping
        if (singleStepEvent.scheduled()){
            return;
        }
        DPRINTF(GDBMisc, "Finishing thread switch");
        if (!selectThreadContext(id))
            return;
    }


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

    clearSingleStep();
    if (stopReason=="monitor_return"){
        //should wnot send any Tpacket here
        send("OK");
    }else if (threadSwitching) {
        threadSwitching = false;
        // Tell GDB the thread switch has completed.
        send("OK");
    } else {
        // Tell remote host that an exception has occurred.
        sendTPacket(sig,id,stopReason);
    }

    processCommands(sig);
}

bool
BaseRemoteGDB::sendMessage(std::string message)
{
    if (!attached)
        return false;
    DPRINTF(GDBMisc, "passing message %s\n", message);
    sendOPacket(message);
    return true;
}

void
BaseRemoteGDB::incomingConnection(int revent)
{
    if (connectEvent.scheduled()) {
        warn("GDB connect event has already been scheduled!");
        return;
    }

    if (revent & POLLIN) {
        scheduleInstCommitEvent(&connectEvent, 0);
    }
}

void
BaseRemoteGDB::incomingData(int revent)
{
    if (trapEvent.scheduled()) {
        warn("GDB trap event has already been scheduled!");
        return;
    }

    if (revent & POLLIN) {
        scheduleTrapEvent(tc->contextId(),GDBSignal::ILL,0,"");
    } else if (revent & POLLNVAL) {
        descheduleInstCommitEvent(&trapEvent);
        scheduleInstCommitEvent(&disconnectEvent, 0);
    }
}

uint8_t
BaseRemoteGDB::getbyte()
{
    uint8_t b;
    while (!try_getbyte(&b,-1));//no timeout
   return b;
}

bool
BaseRemoteGDB::try_getbyte(uint8_t* c,int timeout_ms)
{
    if (!c)
        panic("try_getbyte called with a null pointer as c");
    int res,retval;
    //Allow read to fail if it was interrupted by a signal (EINTR).
    errno = 0;
    //preparing fd_sets
    fd_set rfds;
    FD_ZERO(&rfds);
    FD_SET(fd, &rfds);

    //setting up a timeout if timeout_ms is positive
    struct timeval tv;struct timeval* tv_ptr;
    if (timeout_ms >= 0){
        tv.tv_sec = timeout_ms/1000;
        tv.tv_usec = timeout_ms%1000;
        tv_ptr = &tv;
    }else{
        tv_ptr = NULL;
    }
    //Using select to check if the FD is ready to be read.
    while(true){
        do {
            errno = 0;
            retval = ::select(fd + 1, &rfds, NULL, NULL, tv_ptr);
            if (retval < 0 && errno != EINTR){//error
                DPRINTF(GDBMisc,"getbyte failed errno=%i retval=%i\n",
                    errno,retval);
                throw BadClient("Couldn't read data from debugger.");
            }
        //a EINTR error means that the select call was interrupted
        //by another signal
        }while (errno == EINTR);
        if (retval == 0)
            return false;//timed out
        //reading (retval>0)
        res = ::read(fd, c, sizeof(*c));
        if (res == sizeof(*c))
            return true;//read successfully
        //read failed (?) retrying select
    }
}
void
BaseRemoteGDB::putbyte(uint8_t b)
{
    if (::write(fd, &b, sizeof(b)) == sizeof(b))
        return;

    throw BadClient("Couldn't write data to the debugger.");
}

// Receive a packet from gdb
void
BaseRemoteGDB::recv(std::vector<char>& bp)
{
    uint8_t c;
    int csum;
    bp.resize(0);

    do {
        csum = 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 (true) {
            c = getbyte();
            if (c == GDBEnd)
                break;
            c &= 0x7f;
            csum += c;
            bp.push_back(c);
        }

        // Mask the check sum.
        csum &= 0xff;

        // 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.size() > 2 && bp[2] == ':') {
                putbyte(bp[0]);
                putbyte(bp[1]);
                auto begin = std::begin(bp);
                bp.erase(begin, std::next(begin, 3));
            }
            break;
        }
        // Otherwise, report that there was a mistake.
        putbyte(GDBBadP);
    } while (1);
    // Sentinel.
    bp.push_back('\0');
    DPRINTF(GDBRecv, "recv:  %s\n", bp.data());
}

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

    DPRINTF(GDBSend, "send:  %s\n", bp);
    //removing GDBBadP that could be waiting in the buffer
    while (try_getbyte(&c,0));
    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);
        // Send 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.
        c = getbyte();
        if ((c & 0x7f) == GDBBadP)
            DPRINTF(GDBSend, "PacketError\n");
    } while ((c & 0x7f) == GDBBadP);
}

void
BaseRemoteGDB::processCommands(GDBSignal sig)
{
    // Stick frame regs into our reg cache.
    regCachePtr = gdbRegs();
    regCachePtr->getRegs(tc);

    GdbCommand::Context cmd_ctx;
    cmd_ctx.type = sig;
    std::vector<char> data;

    for (;;) {
        try {
            recv(data);
            if (data.size() == 1)
                throw BadClient();
            cmd_ctx.cmdByte = data[0];
            cmd_ctx.data = data.data() + 1;
            // One for sentinel, one for cmdByte.
            cmd_ctx.len = data.size() - 2;

            auto cmd_it = commandMap.find(cmd_ctx.cmdByte);
            if (cmd_it == commandMap.end()) {
                DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
                        cmd_ctx.cmdByte, cmd_ctx.cmdByte);
                throw Unsupported();
            }
            cmd_ctx.cmd = &(cmd_it->second);

            if (!(this->*(cmd_ctx.cmd->func))(cmd_ctx))
                break;

        } catch (BadClient &e) {
            if (e.warning)
                warn(e.warning);
            detach();
            break;
        } catch (Unsupported &e) {
            send("");
        } catch (CmdError &e) {
            send(e.error);
        } catch (std::exception &e) {
            panic("Unrecognized GDB exception: %s", e.what());
        } catch (...) {
            panic("Unrecognized GDB exception.");
        }
    }
}

bool
BaseRemoteGDB::readBlob(Addr vaddr, size_t size, char *data)
{
    TranslatingPortProxy fs_proxy(tc);
    SETranslatingPortProxy se_proxy(tc);
    PortProxy &virt_proxy = FullSystem ? fs_proxy : se_proxy;

    virt_proxy.readBlob(vaddr, data, size);
    return true;
}

bool
BaseRemoteGDB::writeBlob(Addr vaddr, size_t size, const char *data)
{
    TranslatingPortProxy fs_proxy(tc);
    SETranslatingPortProxy se_proxy(tc);
    PortProxy &virt_proxy = FullSystem ? fs_proxy : se_proxy;

    virt_proxy.writeBlob(vaddr, data, size);
    return true;
}

// Read bytes from kernel address space for debugger.
bool
BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
{
    DPRINTF(GDBRead, "read:  addr=%#x, size=%d", vaddr, size);

    bool res = readBlob(vaddr, size, data);

    if (!res)
        return false;

#if TRACING_ON
    if (debug::GDBRead) {
        if (debug::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)
{
    if (debug::GDBWrite) {
        DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
        if (debug::GDBExtra) {
            char buf[1024];
            mem2hex(buf, data, size);
            DPRINTFNR(": %s\n", buf);
        } else
            DPRINTFNR("\n");
    }
    return writeBlob(vaddr, size, data);
}

void
BaseRemoteGDB::singleStep()
{
    if (!singleStepEvent.scheduled())
        scheduleInstCommitEvent(&singleStepEvent, 1);
    trap(tc->contextId(), GDBSignal::TRAP);
}

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

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

void
BaseRemoteGDB::insertSoftBreak(Addr addr, size_t kind)
{
    if (!checkBpKind(kind))
        throw BadClient("Invalid breakpoint kind.\n");

    return insertHardBreak(addr, kind);
}

void
BaseRemoteGDB::removeSoftBreak(Addr addr, size_t kind)
{
    if (!checkBpKind(kind))
        throw BadClient("Invalid breakpoint kind.\n");

    return removeHardBreak(addr, kind);
}

void
BaseRemoteGDB::insertHardBreak(Addr addr, size_t kind)
{
    if (!checkBpKind(kind))
        throw BadClient("Invalid breakpoint kind.\n");

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

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

    bkpt->refcount++;
}

void
BaseRemoteGDB::removeHardBreak(Addr addr, size_t kind)
{
    if (!checkBpKind(kind))
        throw BadClient("Invalid breakpoint kind.\n");

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

    auto i = hardBreakMap.find(addr);
    if (i == hardBreakMap.end())
        throw CmdError("E0C");

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

void
BaseRemoteGDB::sendTPacket(GDBSignal sig, ContextID id,
    const std::string& stopReason)
{
    if (!stopReason.empty()){
        send("T%02xcore:%x;thread:%x;%s;",
            (uint8_t)sig,id + 1,id + 1,stopReason);
    }else{
        send("T%02xcore:%x;thread:%x;",
            (uint8_t)sig,id + 1,id + 1);
    }
}
void
BaseRemoteGDB::sendSPacket(GDBSignal sig){
       send("S%02x",(uint8_t)sig);
}
void
BaseRemoteGDB::sendOPacket(const std::string message){
   send("O" + string2hexS(message));
}

void
BaseRemoteGDB::scheduleTrapEvent(ContextID id,GDBSignal sig,int delta,
    std::string stopReason){
    ThreadContext* _tc = threads[id];
    panic_if(_tc == nullptr, "Unknown context id :%i",id);
    trapEvent.id(id);
    trapEvent.type(sig);
    trapEvent.stopReason(stopReason);
    if (!trapEvent.scheduled())
        scheduleInstCommitEvent(&trapEvent,delta,_tc);
}

void
BaseRemoteGDB::scheduleInstCommitEvent(Event *ev, int delta,ThreadContext* _tc)
{
    if (delta == 0 && _tc->status() != ThreadContext::Active) {
        // If delta is zero, we're just trying to wait for an instruction
        // boundary. If the CPU is not active, assume we're already at a
        // boundary without waiting for the CPU to eventually wake up.
        ev->process();
    } else {
        // Here "ticks" aren't simulator ticks which measure time, they're
        // instructions committed by the CPU.
        _tc->scheduleInstCountEvent(ev, _tc->getCurrentInstCount() + delta);
    }
}

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

std::map<char, BaseRemoteGDB::GdbCommand> BaseRemoteGDB::commandMap = {
    // last signal
    { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmdSignal } },
    // set baud (deprecated)
    { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmdUnsupported } },
    // set breakpoint (deprecated)
    { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmdUnsupported } },
    // resume
    { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmdCont } },
    // continue with signal
    { 'C', { "KGDB_ASYNC_CONT", &BaseRemoteGDB::cmdAsyncCont } },
    // toggle debug flags (deprecated)
    { 'd', { "KGDB_DEBUG", &BaseRemoteGDB::cmdUnsupported } },
    // detach remote gdb
    { 'D', { "KGDB_DETACH", &BaseRemoteGDB::cmdDetach } },
    // read general registers
    { 'g', { "KGDB_REG_R", &BaseRemoteGDB::cmdRegR } },
    // write general registers
    { 'G', { "KGDB_REG_W", &BaseRemoteGDB::cmdRegW } },
    // set thread
    { 'H', { "KGDB_SET_THREAD", &BaseRemoteGDB::cmdSetThread } },
    // step a single cycle
    { 'i', { "KGDB_CYCLE_STEP", &BaseRemoteGDB::cmdUnsupported } },
    // signal then cycle step
    { 'I', { "KGDB_SIG_CYCLE_STEP", &BaseRemoteGDB::cmdUnsupported } },
    // kill program
    { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmdDetach } },
    // read memory
    { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmdMemR } },
    // write memory
    { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmdMemW } },
    // read register
    { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmdUnsupported } },
    // write register
    { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmdUnsupported } },
    // query variable
    { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmdQueryVar } },
    // set variable
    { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmdUnsupported } },
    // reset system (deprecated)
    { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmdUnsupported } },
    // step
    { 's', { "KGDB_STEP", &BaseRemoteGDB::cmdStep } },
    // signal and step
    { 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmdAsyncStep } },
    // find out if the thread is alive
    { 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmdIsThreadAlive } },
    //multi letter command
    { 'v', { "KGDB_MULTI_LETTER", &BaseRemoteGDB::cmdMultiLetter } },
    // target exited
    { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmdUnsupported } },
    // write memory
    { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmdUnsupported } },
    // remove breakpoint or watchpoint
    { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmdClrHwBkpt } },
    // insert breakpoint or watchpoint
    { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmdSetHwBkpt } },
    // non-standard RSP extension: dump page table
    { '.', { "GET_PAGE_TABLE", &BaseRemoteGDB::cmdDumpPageTable } },
};

bool
BaseRemoteGDB::checkBpKind(size_t kind)
{
    return true;
}

bool
BaseRemoteGDB::cmdUnsupported(GdbCommand::Context &ctx)
{
    DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
    DDUMP(GDBMisc, ctx.data, ctx.len);
    throw Unsupported();
}


bool
BaseRemoteGDB::cmdSignal(GdbCommand::Context &ctx)
{
    sendTPacket(ctx.type,tc->contextId(),"");
    return true;
}

bool
BaseRemoteGDB::cmdCont(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    if (ctx.len) {
        Addr new_pc = hex2i(&p);
        tc->pcState(new_pc);
    }
    clearSingleStep();
    return false;
}

bool
BaseRemoteGDB::cmdAsyncCont(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    hex2i(&p);
    if (*p++ == ';') {
        Addr new_pc = hex2i(&p);
        tc->pcState(new_pc);
    }
    clearSingleStep();
    return false;
}

bool
BaseRemoteGDB::cmdDetach(GdbCommand::Context &ctx)
{
    detach();
    return false;
}

bool
BaseRemoteGDB::cmdRegR(GdbCommand::Context &ctx)
{
    char buf[2 * regCachePtr->size() + 1];
    buf[2 * regCachePtr->size()] = '\0';
    mem2hex(buf, regCachePtr->data(), regCachePtr->size());
    send(buf);
    return true;
}

bool
BaseRemoteGDB::cmdRegW(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
    if (p == NULL || *p != '\0')
        throw CmdError("E01");

    regCachePtr->setRegs(tc);
    send("OK");

    return true;
}

bool
BaseRemoteGDB::cmdSetThread(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    char subcommand = *p++;
    int tid = 0;
    bool all, any;
    if (!parseThreadId(&p, all, any, tid))
        throw CmdError("E01");

    if (subcommand == 'c') {
        // We can only single step or continue all threads at once, since we
        // stop time itself and not individual threads.
        if (!all)
            throw CmdError("E02");
    } else if (subcommand == 'g') {
        // We don't currently support reading registers, memory, etc, from all
        // threads at once. GDB may never ask for this, but if it does we
        // should complain.
        if (all)
            throw CmdError("E03");

        // If GDB doesn't care which thread we're using, keep using the
        // current one, otherwise switch.
        if (!any && tid != tc->contextId()) {
            if (!selectThreadContext(tid))
                throw CmdError("E04");
            // Line up on an instruction boundary in the new thread.
            threadSwitching = true;
            scheduleTrapEvent(tid,GDBSignal::ZERO,0,"");
            return false;
        }
    } else {
        throw CmdError("E05");
    }

    send("OK");
    return true;
}

bool
BaseRemoteGDB::cmdIsThreadAlive(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    int tid = 0;
    bool all, any;
    if (!parseThreadId(&p, all, any, tid))
        throw CmdError("E01");
    if (all)
            throw CmdError("E03");
    if (threads.find(tid) == threads.end())
            throw CmdError("E04");
    send("OK");
    return true;
}

bool
BaseRemoteGDB::cmdMemR(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    Addr addr = hex2i(&p);
    if (*p++ != ',')
        throw CmdError("E02");
    size_t len = hex2i(&p);
    if (*p != '\0')
        throw CmdError("E03");
    if (!acc(addr, len))
        throw CmdError("E05");

    char buf[len];
    if (!read(addr, len, buf))
        throw CmdError("E05");

    char temp[2 * len + 1];
    temp[2 * len] = '\0';
    mem2hex(temp, buf, len);
    send(temp);
    return true;
}

bool
BaseRemoteGDB::cmdMemW(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    Addr addr = hex2i(&p);
    if (*p++ != ',')
        throw CmdError("E06");
    size_t len = hex2i(&p);
    if (*p++ != ':')
        throw CmdError("E07");
    if (len * 2 > ctx.len - (p - ctx.data))
        throw CmdError("E08");
    char buf[len];
    p = (char *)hex2mem(buf, p, len);
    if (p == NULL)
        throw CmdError("E09");
    if (!acc(addr, len))
        throw CmdError("E0A");
    if (!write(addr, len, buf))
        throw CmdError("E0B");
    send("OK");
    return true;
}

bool
BaseRemoteGDB::cmdMultiLetter(GdbCommand::Context &ctx)
{
    GdbMultiLetterCommand::Context new_ctx;
    new_ctx.type = ctx.type;
    strtok(ctx.data,";?");
    char* sep = strtok(NULL,";:?");

    int txt_len = (sep != NULL) ? (sep - ctx.data) : strlen(ctx.data);
    DPRINTF(GDBMisc, "Multi-letter: %s , len=%i\n", ctx.data,txt_len);
    new_ctx.cmdTxt = std::string(ctx.data,txt_len);
    new_ctx.data = sep;
    new_ctx.len = ctx.len - txt_len;
    try {
        auto cmd_it = multiLetterMap.find(new_ctx.cmdTxt);
        if (cmd_it == multiLetterMap.end()) {
            DPRINTF(GDBMisc, "Unknown command: %s\n", new_ctx.cmdTxt);
            throw Unsupported();
        }
        new_ctx.cmd = &(cmd_it->second);

        return (this->*(new_ctx.cmd->func))(new_ctx);
    //catching errors: we don't need to catch anything else
    //as it will be handled by processCommands
    } catch (CmdError &e) {
        send(e.error);
    }
    return false;
}

std::map<std::string, BaseRemoteGDB::GdbMultiLetterCommand>
BaseRemoteGDB::multiLetterMap = {
    { "MustReplyEmpty", { "KGDB_REPLY_EMPTY", &BaseRemoteGDB::cmdReplyEmpty}},
    { "Kill", { "KGDB_VKILL", &BaseRemoteGDB::cmdVKill}},
};


bool
BaseRemoteGDB::cmdReplyEmpty(GdbMultiLetterCommand::Context &ctx)
{
    send("");
    return true;
}

bool
BaseRemoteGDB::cmdVKill(GdbMultiLetterCommand::Context &ctx)
{
    warn("GDB command for kill received detaching instead");
    detach();
    return false;
}

bool
BaseRemoteGDB::cmdMultiUnsupported(GdbMultiLetterCommand::Context &ctx)
{
    DPRINTF(GDBMisc, "Unsupported Multi name command : %s\n",
        ctx.cmd->name);
    DDUMP(GDBMisc, ctx.data, ctx.len);
    throw Unsupported();
}

namespace {

std::pair<std::string, std::string>
splitAt(std::string str, const char * const delim)
{
    size_t pos = str.find_first_of(delim);
    if (pos == std::string::npos)
        return std::pair<std::string, std::string>(str, "");
    else
        return std::pair<std::string, std::string>(
                str.substr(0, pos), str.substr(pos + 1));
}

} // anonymous namespace

std::map<std::string, BaseRemoteGDB::QuerySetCommand>
        BaseRemoteGDB::queryMap = {
    { "C", { &BaseRemoteGDB::queryC } },
    { "Rcmd", { &BaseRemoteGDB::queryRcmd} },
    { "Attached", { &BaseRemoteGDB::queryAttached} },
    { "Supported", { &BaseRemoteGDB::querySupported, ";" } },
    { "Xfer", { &BaseRemoteGDB::queryXfer } },
    { "Symbol", { &BaseRemoteGDB::querySymbol  ,":" } },
    { "fThreadInfo", { &BaseRemoteGDB::queryFThreadInfo } },
    { "sThreadInfo", { &BaseRemoteGDB::querySThreadInfo } },
};

bool
BaseRemoteGDB::queryC(QuerySetCommand::Context &ctx)
{
    send("QC%x", encodeThreadId(tc->contextId()));
    return true;
}

bool
BaseRemoteGDB::querySupported(QuerySetCommand::Context &ctx)
{
    std::ostringstream oss;
    // This reply field mandatory. We can receive arbitrarily
    // long packets, so we could choose it to be arbitrarily large.
    // This is just an arbitrary filler value that seems to work.
    oss << "PacketSize=1024";
    for (const auto& feature : availableFeatures())
        oss << ';' << feature;
    send(oss.str());
    return true;
}

bool
BaseRemoteGDB::queryXfer(QuerySetCommand::Context &ctx)
{
    auto split = splitAt(ctx.args.at(0), ":");
    auto object = split.first;

    split = splitAt(split.second, ":");
    auto operation = split.first;

    // Only the "features" object and "read"ing are supported currently.
    if (object != "features" || operation != "read")
        throw Unsupported();

    // Extract the annex name.
    split = splitAt(split.second, ":");
    auto annex = split.first;

    // Read the contents of the annex.
    std::string content;
    if (!getXferFeaturesRead(annex, content))
        throw CmdError("E00");

    // Extract the offset and length.
    split = splitAt(split.second, ",");
    auto offset_str = split.first;
    auto length_str = split.second;

    const char *offset_ptr = offset_str.c_str();
    const char *length_ptr = length_str.c_str();
    auto offset = hex2i(&offset_ptr);
    auto length = hex2i(&length_ptr);
    if (offset_ptr != offset_str.c_str() + offset_str.length() ||
            length_ptr != length_str.c_str() + length_str.length()) {
        throw CmdError("E00");
    }

    std::string encoded;
    encodeXferResponse(content, encoded, offset, length);
    send(encoded);
    return true;
}
bool
BaseRemoteGDB::querySymbol(QuerySetCommand::Context &ctx)
{
    //The target does not need to look up any (more) symbols.
    send("OK");
    return true;
}
bool
BaseRemoteGDB::queryAttached(QuerySetCommand::Context &ctx)
{
    std::string pid="";
    if (!ctx.args.empty() && !ctx.args[0].empty()){
         pid=ctx.args[0];
    }
    DPRINTF(GDBMisc, "QAttached : pid=%s\n",pid);
    //The remote server is attached to an existing process.
    send("1");
    return true;
}

class MonitorCallEvent : public GlobalSimLoopExitEvent
{
    BaseRemoteGDB& gdb;
    ContextID id;
    public:
    MonitorCallEvent(BaseRemoteGDB& gdb,ContextID id,const std::string &_cause,
                  int code):
                  GlobalSimLoopExitEvent(_cause,code), gdb(gdb),id(id)
                  {};
    void process() override{
        GlobalSimLoopExitEvent::process();
    }
    void clean() override{
        //trapping now
        //this is the only point in time when we can call trap
        //before any breakpoint triggers
        gdb.trap(id,GDBSignal::ZERO,"monitor_return");
        delete this;
    }
    ~MonitorCallEvent(){
        DPRINTF(Event,"MonitorCallEvent destructed\n");;
    }
};

bool
BaseRemoteGDB::queryRcmd(QuerySetCommand::Context &ctx){
    std::string message=hexS2string(ctx.args[0]);
    DPRINTF(GDBMisc, "Rcmd Query: %s => %s\n", ctx.args[0],message);
    //Tick when = curTick();
    new MonitorCallEvent(*this,tc->contextId(),"GDB_MONITOR:"+ message, 0);
    return false;
}

bool
BaseRemoteGDB::queryFThreadInfo(QuerySetCommand::Context &ctx)
{
    threadInfoIdx = 0;
    querySThreadInfo(ctx);
    return true;
}

bool
BaseRemoteGDB::querySThreadInfo(QuerySetCommand::Context &ctx)
{
    if (threadInfoIdx >= threads.size()) {
        threadInfoIdx = 0;
        send("l");
    } else {
        auto it = threads.begin();
        std::advance(it, threadInfoIdx++);
        send("m%x", encodeThreadId(it->second->contextId()));
    }
    return true;
}

bool
BaseRemoteGDB::cmdQueryVar(GdbCommand::Context &ctx)
{
    // The query command goes until the first ':', or the end of the string.
    std::string s(ctx.data, ctx.len);
    auto query_split = splitAt({ ctx.data, (size_t)ctx.len }, ":,");
    const auto &query_str = query_split.first;

    // Look up the query command, and report if it isn't found.
    auto query_it = queryMap.find(query_str);
    if (query_it == queryMap.end()) {
        DPRINTF(GDBMisc, "Unknown query %s\n", s);
        throw Unsupported();
    }

    // If it was found, construct a context.
    QuerySetCommand::Context qctx(query_str);

    const auto &query = query_it->second;
    auto remaining = std::move(query_split.second);
    if (!query.argSep) {
        qctx.args.emplace_back(std::move(remaining));
    } else {
        while (remaining != "") {
            auto arg_split = splitAt(remaining, query.argSep);
            qctx.args.emplace_back(std::move(arg_split.first));
            remaining = std::move(arg_split.second);
        }
    }
    //returning true if the query want to pursue GDB command processing
    //false means that the command processing stop until it's trigger again.
    return (this->*(query.func))(qctx);
}

std::vector<std::string>
BaseRemoteGDB::availableFeatures() const
{
    return {};
};

bool
BaseRemoteGDB::getXferFeaturesRead(
    const std::string &annex, std::string &output)
{
    return false;
}

void
BaseRemoteGDB::encodeBinaryData(
    const std::string &unencoded, std::string &encoded) const
{
    for (const char& c : unencoded) {
        if (c == '$' || c == '#' || c == '}' || c == '*') {
            encoded += '}';
            encoded += c ^ 0x20;
        } else {
            encoded += c;
        }
    }
}

void
BaseRemoteGDB::encodeXferResponse(const std::string &unencoded,
    std::string &encoded, size_t offset, size_t unencoded_length) const
{
    if (offset + unencoded_length < unencoded.length())
        encoded += 'm';
    else
        encoded += 'l';
    encodeBinaryData(unencoded.substr(offset, unencoded_length), encoded);
}

bool
BaseRemoteGDB::cmdDumpPageTable(GdbCommand::Context &ctx)
{
    send(tc->getProcessPtr()->pTable->externalize().c_str());
    return true;
}

bool
BaseRemoteGDB::cmdAsyncStep(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    hex2i(&p); // Ignore the subcommand byte.
    if (*p++ == ';') {
        Addr new_pc = hex2i(&p);
        tc->pcState(new_pc);
    }
    setSingleStep();
    return false;
}

bool
BaseRemoteGDB::cmdStep(GdbCommand::Context &ctx)
{
    if (ctx.len) {
        const char *p = ctx.data;
        Addr new_pc = hex2i(&p);
        tc->pcState(new_pc);
    }
    setSingleStep();
    return false;
}

bool
BaseRemoteGDB::cmdClrHwBkpt(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    char sub_cmd = *p++;
    if (*p++ != ',')
        throw CmdError("E0D");
    Addr addr = hex2i(&p);
    if (*p++ != ',')
        throw CmdError("E0D");
    size_t kind = hex2i(&p);

    DPRINTF(GDBMisc, "clear %s, addr=%#x, kind=%d\n",
            breakType(sub_cmd), addr, kind);

    switch (sub_cmd) {
      case GdbSoftBp:
        removeSoftBreak(addr, kind);
        break;
      case GdbHardBp:
        removeHardBreak(addr, kind);
        break;
      case GdbWriteWp:
      case GdbReadWp:
      case GdbAccWp:
      default: // unknown
        throw Unsupported();
    }
    send("OK");

    return true;
}

bool
BaseRemoteGDB::cmdSetHwBkpt(GdbCommand::Context &ctx)
{
    const char *p = ctx.data;
    char sub_cmd = *p++;
    if (*p++ != ',')
        throw CmdError("E0D");
    Addr addr = hex2i(&p);
    if (*p++ != ',')
        throw CmdError("E0D");
    size_t kind = hex2i(&p);

    DPRINTF(GDBMisc, "set %s, addr=%#x, kind=%d\n",
            breakType(sub_cmd), addr, kind);

    switch (sub_cmd) {
      case GdbSoftBp:
        insertSoftBreak(addr, kind);
        break;
      case GdbHardBp:
        insertHardBreak(addr, kind);
        break;
      case GdbWriteWp:
      case GdbReadWp:
      case GdbAccWp:
      default: // unknown
        throw Unsupported();
    }
    send("OK");

    return true;
}

} // namespace gem5
