diff --git a/thermosphere/src/gdb/hvisor_gdb_context.hpp b/thermosphere/src/gdb/hvisor_gdb_context.hpp index 9e4647c44..4245cc30f 100644 --- a/thermosphere/src/gdb/hvisor_gdb_context.hpp +++ b/thermosphere/src/gdb/hvisor_gdb_context.hpp @@ -35,6 +35,7 @@ #define DECLARE_HANDLER(name) int Handle##name() #define DECLARE_QUERY_HANDLER(name) DECLARE_HANDLER(Query##name) #define DECLARE_VERBOSE_HANDLER(name) DECLARE_HANDLER(Verbose##name) +#define DECLARE_REMOTE_HANDLER(name) DECLARE_HANDLER(Remote##name) #define DECLARE_XFER_HANDLER(name) DECLARE_HANDLER(Xfer##name) namespace ams::hvisor::gdb { @@ -211,4 +212,5 @@ namespace ams::hvisor::gdb { #undef DECLARE_HANDLER #undef DECLARE_QUERY_HANDLER #undef DECLARE_VERBOSE_HANDLER +#undef DECLARE_REMOTE_HANDLER #undef DECLARE_XFER_HANDLER diff --git a/thermosphere/src/gdb/hvisor_gdb_defines_internal.hpp b/thermosphere/src/gdb/hvisor_gdb_defines_internal.hpp index 9b48fb2b9..4bfc7e6cf 100644 --- a/thermosphere/src/gdb/hvisor_gdb_defines_internal.hpp +++ b/thermosphere/src/gdb/hvisor_gdb_defines_internal.hpp @@ -36,9 +36,11 @@ #define GDB_HANDLER(name) Handle##name #define GDB_QUERY_HANDLER(name) GDB_HANDLER(Query##name) #define GDB_VERBOSE_HANDLER(name) GDB_HANDLER(Verbose##name) +#define GDB_REMOTE_COMMAND_HANDLER(name) GDB_HANDLER(RemoteCommand##name) #define GDB_XFER_HANDLER(name) GDB_HANDLER(Xfer##name) -#define GDB_DEFINE_HANDLER(name) int Context::GDB_HANDLER(name)() -#define GDB_DEFINE_QUERY_HANDLER(name) GDB_DEFINE_HANDLER(Query##name) -#define GDB_DECLARE_VERBOSE_HANDLER(name) GDB_DEFINE_HANDLER(Verbose##name) -#define GDB_DECLARE_XFER_HANDLER(name) GDB_DEFINE_HANDLER(Xfer##name) +#define GDB_DEFINE_HANDLER(name) int Context::GDB_HANDLER(name)() +#define GDB_DEFINE_QUERY_HANDLER(name) GDB_DEFINE_HANDLER(Query##name) +#define GDB_DEFINE_VERBOSE_HANDLER(name) GDB_DEFINE_HANDLER(Verbose##name) +#define GDB_DEFINE_REMOTE_COMMAND_HANDLER(name) GDB_DEFINE_HANDLER(RemoteCommand##name) +#define GDB_DECLARE_XFER_HANDLER(name) GDB_DEFINE_HANDLER(Xfer##name) diff --git a/thermosphere/src/gdb/hvisor_gdb_remote_command.cpp b/thermosphere/src/gdb/hvisor_gdb_remote_command.cpp new file mode 100644 index 000000000..42a88db27 --- /dev/null +++ b/thermosphere/src/gdb/hvisor_gdb_remote_command.cpp @@ -0,0 +1,75 @@ +/* + * 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" + +namespace { + + constexpr std::string_view SkipSpaces(std::string_view str) + { + size_t n = str.find_first_not_of("\t\v\n\f\r "); + if (n == std::string_view::npos) { + return {}; + } else { + str.remove_prefix(n); + return str; + } + } + +} + +namespace ams::hvisor::gdb { + + GDB_DEFINE_QUERY_HANDLER(Rcmd) + { + char *buf = GetInPlaceOutputBuffer(); + size_t encodedLen = m_commandData.size(); + if (encodedLen == 0 || encodedLen % 2 != 0) { + ReplyErrno(EILSEQ); + } + + // Decode in place + if (DecodeHex(buf, m_commandData) != encodedLen / 2) { + ReplyErrno(EILSEQ); + } + + // Extract command name, data + m_commandData = std::string_view{buf, encodedLen / 2}; + size_t nameSize = m_commandData.find_first_of("\t\v\n\f\r "); + std::string_view commandName = m_commandData; + if (nameSize != std::string_view::npos) { + commandName.remove_suffix(commandName.size() - nameSize); + m_commandData.remove_prefix(nameSize); + m_commandData = SkipSpaces(m_commandData); + } else { + m_commandData = std::string_view{}; + } + + // Nothing implemented yet + (void)commandName; + + return SendHexPacket("Unrecognized command.\n"); + } + +} diff --git a/thermosphere/src/gdb/remote_command.c b/thermosphere/src/gdb/remote_command.c deleted file mode 100644 index cb36a9bd0..000000000 --- a/thermosphere/src/gdb/remote_command.c +++ /dev/null @@ -1,51 +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 "remote_command.h" -#include "net.h" -struct -{ - const char *name; - GDBCommandHandler handler; -} remoteCommandHandlers[] = { -}; - -static const char *GDB_SkipSpaces(const char *pos) -{ - const char *nextpos; - for (nextpos = pos; *nextpos != 0 && ((*nextpos >= 9 && *nextpos <= 13) || *nextpos == ' '); nextpos++); - return nextpos; -} - -GDB_DECLARE_QUERY_HANDLER(Rcmd) -{ - char commandData[GDB_BUF_LEN / 2 + 1]; - char *endpos; - const char *errstr = "Unrecognized command.\n"; - size_t len = strlen(ctx->commandData); - - if(len == 0 || (len % 2) == 1 || GDB_DecodeHex(commandData, ctx->commandData, len / 2) != len / 2) { - return GDB_ReplyErrno(ctx, EILSEQ); - } - commandData[len / 2] = 0; - - for (endpos = commandData; !(*endpos >= 9 && *endpos <= 13) && *endpos != ' ' && *endpos != 0; endpos++); - - char *nextpos = (char *)GDB_SkipSpaces(endpos); - *endpos = 0; - - for (size_t i = 0; i < sizeof(remoteCommandHandlers) / sizeof(remoteCommandHandlers[0]); i++) { - if (strcmp(commandData, remoteCommandHandlers[i].name) == 0) { - ctx->commandData = nextpos; - return remoteCommandHandlers[i].handler(ctx); - } - } - - return GDB_SendHexPacket(ctx, errstr, strlen(errstr)); -} diff --git a/thermosphere/src/gdb/remote_command.h b/thermosphere/src/gdb/remote_command.h deleted file mode 100644 index be89bea6a..000000000 --- a/thermosphere/src/gdb/remote_command.h +++ /dev/null @@ -1,15 +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" - -#define GDB_REMOTE_COMMAND_HANDLER(name) GDB_HANDLER(RemoteCommand##name) -#define GDB_DECLARE_REMOTE_COMMAND_HANDLER(name) GDB_DECLARE_HANDLER(RemoteCommand##name) - -GDB_DECLARE_QUERY_HANDLER(Rcmd);