diff --git a/thermosphere/src/gdb/hvisor_gdb_comms.cpp b/thermosphere/src/gdb/hvisor_gdb_comms.cpp index f22fb1eb5..a4efd8865 100644 --- a/thermosphere/src/gdb/hvisor_gdb_comms.cpp +++ b/thermosphere/src/gdb/hvisor_gdb_comms.cpp @@ -87,11 +87,12 @@ namespace ams::hvisor::gdb { } size_t delimPos = transportInterfaceReadDataUntil(iface, m_buffer + 1, 4 + GDB_BUF_LEN - 1, '#'); - if (m_buffer[delimPos] != '#') { - // The packet is malformed, send a nack + if (m_buffer[delimPos] != '#' || delimPos == 1) { + // The packet is malformed, send a nack. Refuse empty packets return WriteNack(iface); } + m_commandLetter = m_buffer[1]; m_commandData = std::string_view{m_buffer + 1, delimPos}; // Read the checksum @@ -107,6 +108,9 @@ namespace ams::hvisor::gdb { WriteAck(iface); } + // Remove command letter + m_commandData.remove_prefix(1); + // State transitions... if (m_state < State::Attached) { DEBUG("Received connection from GDB, now attaching...\n"); diff --git a/thermosphere/src/gdb/hvisor_gdb_stop_points.cpp b/thermosphere/src/gdb/hvisor_gdb_stop_points.cpp new file mode 100644 index 000000000..57ef54d7d --- /dev/null +++ b/thermosphere/src/gdb/hvisor_gdb_stop_points.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* +* This file is part of Luma3DS. +* Copyright (C) 2016-2019 Aurora Wright, TuxSH +* +* SPDX-License-Identifier: (MIT OR GPL-2.0-or-later) +*/ + +#include "hvisor_gdb_defines_internal.hpp" +#include "hvisor_gdb_packet_data.hpp" + +#include "../breakpoints.h" +#include "../software_breakpoints.h" +#include "../watchpoints.h" + +namespace ams::hvisor::gdb { + + GDB_DEFINE_HANDLER(ToggleStopPoint) + { + bool add = m_commandLetter == 'Z'; + + auto [nread, kind, addr, size] = ParseHexIntegerList<3>(m_commandData, ';'); + if (nread == 0) { + return ReplyErrno(EILSEQ); + } + m_commandData.remove_prefix(nread); + + // We don't support cond_list + bool persist = m_commandData == "cmds:1"; + + // In theory we should reject leading zeroes in "kind". Oh well... + + int res; + static const WatchpointLoadStoreControl kinds[3] = { + WatchpointLoadStoreControl_Store, + WatchpointLoadStoreControl_Load, + WatchpointLoadStoreControl_LoadStore, + }; + + switch(kind) { + // Software breakpoint + case 0: { + if(size != 4) { + return ReplyErrno(EINVAL); + } + res = add ? addSoftwareBreakpoint(addr, persist) : removeSoftwareBreakpoint(addr, false); + return res == 0 ? ReplyOk() : ReplyErrno(-res); + } + + // Hardware breakpoint + case 1: { + if(size != 4) { + return ReplyErrno(EINVAL); + } + res = add ? addBreakpoint(addr) : removeBreakpoint(addr); + return res == 0 ? ReplyOk() : ReplyErrno(-res); + } + + // Watchpoints + case 2: + case 3: + case 4: { + res = add ? addWatchpoint(addr, size, kinds[kind - 2]) : removeWatchpoint(addr, size, kinds[kind - 2]); + return res == 0 ? ReplyOk() : ReplyErrno(-res); + } + default: { + return ReplyEmpty(); + } + } + } + +} diff --git a/thermosphere/src/gdb/stop_points.c b/thermosphere/src/gdb/stop_points.c deleted file mode 100644 index 9adf42a18..000000000 --- a/thermosphere/src/gdb/stop_points.c +++ /dev/null @@ -1,70 +0,0 @@ -/* -* This file is part of Luma3DS. -* Copyright (C) 2016-2019 Aurora Wright, TuxSH -* -* SPDX-License-Identifier: (MIT OR GPL-2.0-or-later) -*/ - -#include - -#include "context.h" -#include "net.h" - -#include "../breakpoints.h" -#include "../software_breakpoints.h" -#include "../watchpoints.h" - -GDB_DECLARE_HANDLER(ToggleStopPoint) -{ - bool add = ctx->commandData[-1] == 'Z'; - unsigned long lst[3]; - - const char *pos = GDB_ParseHexIntegerList(lst, ctx->commandData, 3, ';'); - if (pos == NULL) { - return GDB_ReplyErrno(ctx, EILSEQ); - } - bool persist = *pos != 0 && strncmp(pos, ";cmds:1", 7) == 0; - - // In theory we should reject leading zeroes in "kind". Oh well... - unsigned long kind = lst[0]; - uintptr_t addr = lst[1]; - size_t size = lst[2]; - - int res; - static const WatchpointLoadStoreControl kinds[3] = { - WatchpointLoadStoreControl_Store, - WatchpointLoadStoreControl_Load, - WatchpointLoadStoreControl_LoadStore, - }; - - switch(kind) { - // Software breakpoint - case 0: { - if(size != 4) { - return GDB_ReplyErrno(ctx, EINVAL); - } - res = add ? addSoftwareBreakpoint(addr, persist) : removeSoftwareBreakpoint(addr, false); - return res == 0 ? GDB_ReplyOk(ctx) : GDB_ReplyErrno(ctx, -res); - } - - // Hardware breakpoint - case 1: { - if(size != 4) { - return GDB_ReplyErrno(ctx, EINVAL); - } - res = add ? addBreakpoint(addr) : removeBreakpoint(addr); - return res == 0 ? GDB_ReplyOk(ctx) : GDB_ReplyErrno(ctx, -res); - } - - // Watchpoints - case 2: - case 3: - case 4: { - res = add ? addWatchpoint(addr, size, kinds[kind - 2]) : removeWatchpoint(addr, size, kinds[kind - 2]); - return res == 0 ? GDB_ReplyOk(ctx) : GDB_ReplyErrno(ctx, -res); - } - default: { - return GDB_ReplyEmpty(ctx); - } - } -} diff --git a/thermosphere/src/gdb/stop_points.h b/thermosphere/src/gdb/stop_points.h deleted file mode 100644 index 37e8f86b5..000000000 --- a/thermosphere/src/gdb/stop_points.h +++ /dev/null @@ -1,12 +0,0 @@ -/* -* This file is part of Luma3DS. -* Copyright (C) 2016-2019 Aurora Wright, TuxSH -* -* SPDX-License-Identifier: (MIT OR GPL-2.0-or-later) -*/ - -#pragma once - -#include "context.h" - -GDB_DECLARE_HANDLER(ToggleStopPoint);