From d6abbc7e37f269695626a81c4a9ad117ee672541 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 27 Apr 2025 17:40:51 +0200 Subject: [PATCH] Prepare flatbuffer support --- .gitmodules | 3 + deps/CMakeLists.txt | 4 +- deps/flatbuffers | 1 + src/debugger/CMakeLists.txt | 2 +- src/debugger/event_handler.cpp | 56 +++++++++++++++ src/debugger/event_handler.hpp | 14 ++++ src/debugger/events.fbs | 0 src/debugger/events.hpp | 38 ++++++++++ src/debugger/main.cpp | 103 +-------------------------- src/debugger/message_transmitter.cpp | 91 +++++++++++++++++++++++ src/debugger/message_transmitter.hpp | 10 +++ 11 files changed, 220 insertions(+), 102 deletions(-) create mode 160000 deps/flatbuffers create mode 100644 src/debugger/event_handler.cpp create mode 100644 src/debugger/event_handler.hpp create mode 100644 src/debugger/events.fbs create mode 100644 src/debugger/events.hpp create mode 100644 src/debugger/message_transmitter.cpp create mode 100644 src/debugger/message_transmitter.hpp diff --git a/.gitmodules b/.gitmodules index 5571083f..6ced4c9d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ path = deps/json url = https://github.com/nlohmann/json.git branch = master +[submodule "deps/flatbuffers"] + path = deps/flatbuffers + url = https://github.com/google/flatbuffers.git diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 28155aed..7476ce45 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -3,7 +3,9 @@ add_subdirectory(unicorn) ########################################## -add_subdirectory(json) +option(FLATBUFFERS_BUILD_TESTS "" OFF) +option(FLATBUFFERS_INSTALL "" OFF) +add_subdirectory(flatbuffers) ########################################## diff --git a/deps/flatbuffers b/deps/flatbuffers new file mode 160000 index 00000000..609c72ca --- /dev/null +++ b/deps/flatbuffers @@ -0,0 +1 @@ +Subproject commit 609c72ca1a7526f444a109bc04f861ad578e833d diff --git a/src/debugger/CMakeLists.txt b/src/debugger/CMakeLists.txt index bc63c072..ae580125 100644 --- a/src/debugger/CMakeLists.txt +++ b/src/debugger/CMakeLists.txt @@ -16,7 +16,7 @@ endif() target_link_libraries(debugger PRIVATE windows-emulator - nlohmann_json + flatbuffers ) set_property(GLOBAL PROPERTY VS_STARTUP_PROJECT debugger) diff --git a/src/debugger/event_handler.cpp b/src/debugger/event_handler.cpp new file mode 100644 index 00000000..6655ec79 --- /dev/null +++ b/src/debugger/event_handler.cpp @@ -0,0 +1,56 @@ +#include "event_handler.hpp" +#include "events.hpp" + +#include "message_transmitter.hpp" + +namespace debugger +{ + namespace + { + void handle_event(event_context& c, const event& e, const nlohmann::json& obj) + { + switch (e.type) + { + case event_type::pause: + c.win_emu.emu().stop(); + break; + + case event_type::run: + c.resume = true; + break; + + default: + break; + } + } + + void handle_object(event_context& c, const nlohmann::json& obj) + { + try + { + const auto e = obj.get(); + handle_event(c, e, obj); + } + catch (const std::exception& e) + { + puts(e.what()); + } + } + } + + void handle_events(event_context& c) + { + while (true) + { + suspend_execution(0ms); + + const auto obj = receive_object(); + if (obj.is_null()) + { + break; + } + + handle_object(c, obj); + } + } +} \ No newline at end of file diff --git a/src/debugger/event_handler.hpp b/src/debugger/event_handler.hpp new file mode 100644 index 00000000..acdb3fa3 --- /dev/null +++ b/src/debugger/event_handler.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace debugger +{ + struct event_context + { + windows_emulator& win_emu; + bool resume{false}; + }; + + void handle_events(event_context& c); +} diff --git a/src/debugger/events.fbs b/src/debugger/events.fbs new file mode 100644 index 00000000..e69de29b diff --git a/src/debugger/events.hpp b/src/debugger/events.hpp new file mode 100644 index 00000000..da334375 --- /dev/null +++ b/src/debugger/events.hpp @@ -0,0 +1,38 @@ +#pragma once + +namespace debugger +{ + enum class event_type + { + invalid = 0, + pause = 1, + run = 2, + register_request = 3, + register_response = 4, + write_memory_request = 5, + write_memory_response = 6, + read_memory_request = 7, + read_memory_response = 8, + }; + + struct event + { + event_type type{event_type::invalid}; + }; + + template + struct typed_event : event + { + typed_event() + : event{ + .type = Type, + } + { + } + }; + + using pause_event = typed_event; + using run_event = typed_event; + + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(event, type); +} diff --git a/src/debugger/main.cpp b/src/debugger/main.cpp index 2cfcab79..24726083 100644 --- a/src/debugger/main.cpp +++ b/src/debugger/main.cpp @@ -2,110 +2,12 @@ #include #include -#include - -#ifdef OS_EMSCRIPTEN -#include -#endif +#include "event_handler.hpp" #include namespace { - void suspend_execution(const std::chrono::milliseconds ms = 0ms) - { -#ifdef OS_EMSCRIPTEN - emscripten_sleep(static_cast(ms.count())); -#else - if (ms > 0ms) - { - std::this_thread::sleep_for(ms); - } - else - { - std::this_thread::yield(); - } -#endif - } - - void send_message(const std::string& message) - { -#ifdef OS_EMSCRIPTEN - // clang-format off - EM_ASM_({ - handleMessage(UTF8ToString($0)); - }, message.c_str()); - // clang-format on -#else - (void)message; -#endif - } - - std::string receive_message() - { -#ifdef OS_EMSCRIPTEN - // clang-format off - auto* ptr = EM_ASM_PTR({ - var message = getMessageFromQueue(); - if (!message || message.length == 0) - { - return null; - } - - const length = lengthBytesUTF8(message) + 1; - const buffer = _malloc(length); - stringToUTF8(message, buffer, length); - return buffer; - }); - // clang-format on - - if (!ptr) - { - return {}; - } - - const auto _ = utils::finally([&] { - free(ptr); // - }); - - return {reinterpret_cast(ptr)}; -#else - return {}; -#endif - } - - void send_object(const nlohmann::json& json) - { - const std::string res = json.dump(); - send_message(res); - } - - nlohmann::json receive_object() - { - auto message = receive_message(); - if (message.empty()) - { - return {}; - } - - return nlohmann::json::parse(message); - } - - void handle_messages(windows_emulator& win_emu) - { - while (true) - { - suspend_execution(0ms); - const auto message = receive_object(); - if (message.is_null()) - { - break; - } - - puts(message.dump().c_str()); - } - } - bool run_emulation(windows_emulator& win_emu) { try @@ -162,7 +64,8 @@ namespace windows_emulator win_emu{app_settings, settings}; win_emu.callbacks.on_thread_switch = [&] { - handle_messages(win_emu); // + debugger::event_context c{.win_emu = win_emu}; + debugger::handle_events(c); // }; return run_emulation(win_emu); diff --git a/src/debugger/message_transmitter.cpp b/src/debugger/message_transmitter.cpp new file mode 100644 index 00000000..d44df3b4 --- /dev/null +++ b/src/debugger/message_transmitter.cpp @@ -0,0 +1,91 @@ +#include "message_transmitter.hpp" +#include + +#ifdef OS_EMSCRIPTEN +#include +#endif + +namespace debugger +{ + namespace + { + void send_message(const std::string& message) + { +#ifdef OS_EMSCRIPTEN + // clang-format off + EM_ASM_({ + handleMessage(UTF8ToString($0)); + }, message.c_str()); + // clang-format on +#else + (void)message; +#endif + } + + std::string receive_message() + { +#ifdef OS_EMSCRIPTEN + // clang-format off + auto* ptr = EM_ASM_PTR({ + var message = getMessageFromQueue(); + if (!message || message.length == 0) + { + return null; + } + + const length = lengthBytesUTF8(message) + 1; + const buffer = _malloc(length); + stringToUTF8(message, buffer, length); + return buffer; + }); + // clang-format on + + if (!ptr) + { + return {}; + } + + const auto _ = utils::finally([&] { + free(ptr); // + }); + + return {reinterpret_cast(ptr)}; +#else + return {}; +#endif + } + + void send_object(const nlohmann::json& json) + { + const std::string res = json.dump(); + send_message(res); + } + + nlohmann::json receive_object() + { + auto message = receive_message(); + if (message.empty()) + { + return {}; + } + + return nlohmann::json::parse(message); + } + + void suspend_execution(const std::chrono::milliseconds ms) + { +#ifdef OS_EMSCRIPTEN + emscripten_sleep(static_cast(ms.count())); +#else + if (ms > 0ms) + { + std::this_thread::sleep_for(ms); + } + else + { + std::this_thread::yield(); + } +#endif + } + } + } \ No newline at end of file diff --git a/src/debugger/message_transmitter.hpp b/src/debugger/message_transmitter.hpp new file mode 100644 index 00000000..cb30b444 --- /dev/null +++ b/src/debugger/message_transmitter.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace debugger +{ + void suspend_execution(const std::chrono::milliseconds ms = 0ms); + void send_object(const nlohmann::json& json); + nlohmann::json receive_object(); +}