From c4e8aa47b451d52ed635f33c48f509140f8337c9 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Wed, 23 Apr 2025 12:31:37 +0200 Subject: [PATCH] Prepare web debugger --- cmake/compiler-env.cmake | 1 + page/public/emulator-worker.js | 4 + src/CMakeLists.txt | 1 + src/debugger/CMakeLists.txt | 23 +++++ src/debugger/main.cpp | 153 ++++++++++++++++++++++++++++++++ src/debugger/resource.rc | 101 +++++++++++++++++++++ src/debugger/resources/icon.ico | Bin 0 -> 5072 bytes src/debugger/std_include.hpp | 31 +++++++ 8 files changed, 314 insertions(+) create mode 100644 src/debugger/CMakeLists.txt create mode 100644 src/debugger/main.cpp create mode 100644 src/debugger/resource.rc create mode 100644 src/debugger/resources/icon.ico create mode 100644 src/debugger/std_include.hpp diff --git a/cmake/compiler-env.cmake b/cmake/compiler-env.cmake index d582dd00..8da06684 100644 --- a/cmake/compiler-env.cmake +++ b/cmake/compiler-env.cmake @@ -92,6 +92,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Emscripten") momo_add_c_and_cxx_compile_options( -fexceptions -ftrivial-auto-var-init=zero + -Wno-dollar-in-identifier-extension ) add_link_options( diff --git a/page/public/emulator-worker.js b/page/public/emulator-worker.js index 4bead2a3..02ee4e87 100644 --- a/page/public/emulator-worker.js +++ b/page/public/emulator-worker.js @@ -32,6 +32,10 @@ function notifyExit(code) { self.close(); } +function getMessageFromQueue() { + return ""; +} + function runEmulation(filesystem, file, options) { globalThis.Module = { arguments: [...options, "-e", "./root", file], diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4492d05c..870f20e1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ momo_targets_set_folder("backends" ${BACKEND_TARGETS}) if (NOT MOMO_BUILD_AS_LIBRARY) add_subdirectory(analyzer) + add_subdirectory(debugger) add_subdirectory(fuzzing-engine) add_subdirectory(fuzzer) add_subdirectory(windows-emulator-test) diff --git a/src/debugger/CMakeLists.txt b/src/debugger/CMakeLists.txt new file mode 100644 index 00000000..ac49ed03 --- /dev/null +++ b/src/debugger/CMakeLists.txt @@ -0,0 +1,23 @@ +file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS + *.cpp + *.hpp + *.rc +) + +list(SORT SRC_FILES) + +add_executable(debugger ${SRC_FILES}) + +momo_assign_source_group(${SRC_FILES}) + +if(NOT MOMO_ENABLE_CLANG_TIDY) + target_precompile_headers(debugger PRIVATE std_include.hpp) +endif() + +target_link_libraries(debugger PRIVATE + windows-emulator +) + +set_property(GLOBAL PROPERTY VS_STARTUP_PROJECT debugger) + +momo_strip_target(debugger) diff --git a/src/debugger/main.cpp b/src/debugger/main.cpp new file mode 100644 index 00000000..ef857bed --- /dev/null +++ b/src/debugger/main.cpp @@ -0,0 +1,153 @@ +#include "std_include.hpp" + +#include +#include + +#ifdef OS_EMSCRIPTEN +#include +#endif + +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 sendMessage(const std::string& message) + { +#ifdef OS_EMSCRIPTEN + EM_ASM_( + { + // JavaScript code to handle the message + console.log('Received message from C++: ' + UTF8ToString($0)); + // You can post the message to a message queue or handle it as needed + }, + message.c_str()); +#else + (void)message; +#endif + } + + // Function to receive a message from JavaScript + std::string receiveMessage() + { + /*#ifdef OS_EMSCRIPTEN + // Allocate a buffer to receive the message + char* buffer = (char*)malloc(256); // Adjust size as needed + EM_ASM_( + { + // JavaScript code to retrieve the message + var message = getMessageFromQueue(); // Implement this function in JavaScript + if (message && message.length > 0) + { + stringToUTF8($0, _malloc(lengthBytesUTF8(message) + 1), lengthBytesUTF8(message) + 1); + } + }, + buffer); + + std::string result(buffer); + free(buffer); + return result; + #else*/ + return {}; + // #endif + } + + bool run_emulation(windows_emulator& win_emu) + { + try + { + win_emu.start(); + } + catch (const std::exception& e) + { + win_emu.log.error("Emulation failed at: 0x%" PRIx64 " - %s\n", win_emu.emu().read_instruction_pointer(), + e.what()); + throw; + } + catch (...) + { + win_emu.log.error("Emulation failed at: 0x%" PRIx64 "\n", win_emu.emu().read_instruction_pointer()); + throw; + } + + const auto exit_status = win_emu.process.exit_status; + if (!exit_status.has_value()) + { + win_emu.log.error("Emulation terminated without status!\n"); + return false; + } + + const auto success = *exit_status == STATUS_SUCCESS; + + win_emu.log.disable_output(false); + win_emu.log.print(success ? color::green : color::red, "Emulation terminated with status: %X\n", *exit_status); + + return success; + } + + bool run() + { + (void)&run_emulation; + + for (size_t i = 0; i < 10; ++i) + { + sendMessage("PING"); + + while (true) + { + suspend_execution(0ms); + const auto message = receiveMessage(); + if (message.empty()) + { + puts("EMPTY MSG"); + break; + } + + puts(message.c_str()); + } + + suspend_execution(1s); + } + + return true; + } +} + +int main(const int, char**) +{ + try + { + const auto result = run(); + return result ? 0 : 1; + } + catch (std::exception& e) + { + puts(e.what()); + +#if defined(_WIN32) && 0 + MessageBoxA(nullptr, e.what(), "ERROR", MB_ICONERROR); +#endif + } + + return 1; +} + +#ifdef _WIN32 +int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int) +{ + return main(__argc, __argv); +} +#endif diff --git a/src/debugger/resource.rc b/src/debugger/resource.rc new file mode 100644 index 00000000..8da94cc0 --- /dev/null +++ b/src/debugger/resource.rc @@ -0,0 +1,101 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "momo5502" + VALUE "FileDescription", "Windows Emulator" + VALUE "FileVersion", "1.0.0.0" + VALUE "InternalName", "emulator" + VALUE "LegalCopyright", "All rights reserved." + VALUE "OriginalFilename", "emulator.exe" + VALUE "ProductName", "emulator" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +///////////////////////////////////////////////////////////////////////////// +// +// Binary Data +// + +GLFW_ICON ICON "resources/icon.ico" + + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/debugger/resources/icon.ico b/src/debugger/resources/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b4afb19bf6e0a5ed68896c8e8ddb6c26805835d9 GIT binary patch literal 5072 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +// NOLINTNEXTLINE(google-global-names-in-headers) +using namespace std::literals;