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 00000000..b4afb19b Binary files /dev/null and b/src/debugger/resources/icon.ico differ diff --git a/src/debugger/std_include.hpp b/src/debugger/std_include.hpp new file mode 100644 index 00000000..9719ff6b --- /dev/null +++ b/src/debugger/std_include.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#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;