From bf5c361ed5ff57c077bb3b45d794325e8bdadc9a Mon Sep 17 00:00:00 2001 From: Oxore Date: Sun, 25 Sep 2022 15:22:07 +0300 Subject: Use switch-case for handling GDB commands --- emulator.cpp | 165 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 98 insertions(+), 67 deletions(-) diff --git a/emulator.cpp b/emulator.cpp index 5dd266a..7a1dffa 100644 --- a/emulator.cpp +++ b/emulator.cpp @@ -109,83 +109,114 @@ static std::string CreateResponse( { using namespace GDBRemote; // TODO use switch-case - if (0) { - } else if (packet.type == PacketType::kQueryHaltReason) { + switch (packet.type) { + case PacketType::kNone: + break; + case PacketType::kQuerySupported: + break; + case PacketType::kQueryHaltReason: return "S05"; // TODO real reason - } else if (packet.type == PacketType::kStep) { - m68k_execute(1); - return "S05"; // TODO real reason - } else if (packet.type == PacketType::kContinue) { - m68k_debug.SetRunning(true); + case PacketType::kQueryC: + break; + case PacketType::kQueryFThreadInfo: + break; + case PacketType::kQuerySThreadInfo: + break; + case PacketType::kQueryRTOSThreadInfo: + break; + case PacketType::kQueryAttached: + return "1"; + case PacketType::kQueryTraceStatus: + break; + case PacketType::kQueryRcmd: + { + const auto * const packet_data = + static_cast(packet.data.get()); + if (IsReset(packet_data->data)) { + m68k_pulse_reset(); + // I don't want to skip reset cycles here, because GDB does not + // re-read registers every time, and if we skip reset cycles + // here, the consequent "stepi" in gdb will end up on second + // instruction of reset handler. If we don't skip reset cycles, + // the first "stepi" after "monitor reset" will land us on the + // first instruction in reset handler - I'd prefer this exact + // behavior for now. + return "OK"; + } + } + break; + case PacketType::kSetThreadForCont: return "OK"; - } else if (packet.type == PacketType::kInterrupt) { + case PacketType::kSetThreadForOps: + break; + case PacketType::kVMustReplyEmpty: + break; + case PacketType::kEnableExtendedMode: + break; + case PacketType::kInterrupt: m68k_debug.SetRunning(false); return "S05"; // TODO real reason - } else if (packet.type == PacketType::kSetThreadForCont) { + case PacketType::kContinue: + m68k_debug.SetRunning(true); return "OK"; - } else if (packet.type == PacketType::kQueryAttached) { - return "1"; - } else if (packet.type == PacketType::kQueryRcmd) { - const auto * const packet_data = - static_cast(packet.data.get()); - if (IsReset(packet_data->data)) { - m68k_pulse_reset(); - // I don't want to skip reset cycles here, because GDB does not - // re-read registers every time, and if we skip reset cycles here, - // the consequent "stepi" in gdb will end up on second instruction - // of reset handler. If we don't skip reset cycles, the first - // "stepi" after "monitor reset" will land us on the first - // instruction in reset handler - I'd prefer this exact behavior for - // now. - return "OK"; + case PacketType::kContinueAskSupported: + return "vCont:c:s"; + case PacketType::kReadGeneralRegisters: + { + const M68KCPUState state = m68k_debug.GetCPUState(); + std::string result{}; + for (size_t i = 0; i < state.registers_count ;i++) + { + constexpr size_t value_size = std::string_view("12345678").length(); + char value[value_size + 1]{}; + const int ret = snprintf(value, value_size + 1, "%08x", state.registers[i]); + assert(ret == value_size); + result += std::string(value, value_size); + } + return result; } - } else if (packet.type == PacketType::kInterrupt) { - return "OK"; - } else if (packet.type == PacketType::kSetBreakpoint) { - const auto * const bkpt_data = - static_cast(packet.data.get()); - m68k_debug.SetBreakpoint(bkpt_data->type, bkpt_data->offset, bkpt_data->length); - return "OK"; - } else if (packet.type == PacketType::kDeleteBreakpoint) { - const auto * const bkpt_data = - static_cast(packet.data.get()); - m68k_debug.RemoveBreakpoint(bkpt_data->type, bkpt_data->offset, bkpt_data->length); - return "OK"; - } else if (packet.type == PacketType::kReadMemory) { - const auto * const data = - static_cast(packet.data.get()); - const uint32_t offset = data->offset; - const uint32_t length = data->length; - auto ret_data = std::string(length * 2, '\0'); - for (uint32_t i = 0; i < length; i++) { - const uint8_t byte = m68k_debug.Read8(i + offset); - Utils::ConvertByteToHex(byte, &ret_data[i*2]); + case PacketType::kReadMemory: + { + const auto * const data = + static_cast(packet.data.get()); + const uint32_t offset = data->offset; + const uint32_t length = data->length; + auto ret_data = std::string(length * 2, '\0'); + for (uint32_t i = 0; i < length; i++) { + const uint8_t byte = m68k_debug.Read8(i + offset); + Utils::ConvertByteToHex(byte, &ret_data[i*2]); + } + return ret_data; } - return ret_data; - } else if (packet.type == PacketType::kWriteMemory) { - const auto * const packet_data = - static_cast(packet.data.get()); - const uint32_t offset = packet_data->offset; - const uint32_t length = packet_data->length; - const auto write_data = packet_data->data; - for (uint32_t i = 0; i < length; i++) { - m68k_debug.Write8(i + offset, write_data[i]); + case PacketType::kWriteMemory: + { + const auto * const packet_data = + static_cast(packet.data.get()); + const uint32_t offset = packet_data->offset; + const uint32_t length = packet_data->length; + const auto write_data = packet_data->data; + for (uint32_t i = 0; i < length; i++) { + m68k_debug.Write8(i + offset, write_data[i]); + } + return "OK"; } - return "OK"; - } else if (packet.type == PacketType::kReadGeneralRegisters) { - const M68KCPUState state = m68k_debug.GetCPUState(); - std::string result{}; - for (size_t i = 0; i < state.registers_count ;i++) + case PacketType::kStep: + m68k_execute(1); + return "S05"; // TODO real reason + case PacketType::kSetBreakpoint: { - constexpr size_t value_size = 8; - char value[value_size + 1]{}; - const int ret = snprintf(value, value_size + 1, "%08x", state.registers[i]); - assert(ret == value_size); - result += std::string(value, value_size); + const auto * const bkpt_data = + static_cast(packet.data.get()); + m68k_debug.SetBreakpoint(bkpt_data->type, bkpt_data->offset, bkpt_data->length); + return "OK"; + } + case PacketType::kDeleteBreakpoint: + { + const auto * const bkpt_data = + static_cast(packet.data.get()); + m68k_debug.RemoveBreakpoint(bkpt_data->type, bkpt_data->offset, bkpt_data->length); + return "OK"; } - return result; - } else if (packet.type == PacketType::kContinueAskSupported) { - return "vCont:c:s"; } return ""; } -- cgit v1.2.3