diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj b/Dalamud.Boot/Dalamud.Boot.vcxproj index 2fa9255f4..5955eac56 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj @@ -32,6 +32,8 @@ obj\$(Configuration)\ + + Level3 @@ -81,21 +83,38 @@ - - - - - - + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + Create + Create + + + Use + Use + + + Use + Use + + + Use + Use + - - + diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters index 1f8a03bbe..0106f0589 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters @@ -1,63 +1,59 @@  - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - {18be40ac-9367-46ff-b848-4c528aa97a8d} lib + + {dc468303-865e-43bd-908f-a3542c4bb669} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + - Source Files + Dalamud.Boot DLL - - Source Files - - - Source Files - - - Source Files + + Dalamud.Boot DLL - Source Files + Dalamud.Boot DLL - Source Files + Dalamud.Boot DLL + + + CoreCLR + + + CoreCLR - - Header Files - - - Header Files - - - Header Files - - Header Files - - - Header Files - - - Header Files + CoreCLR - Header Files + CoreCLR + + + CoreCLR + + + CoreCLR + + + CoreCLR - Header Files + Dalamud.Boot DLL + + + Dalamud.Boot DLL diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp index 377ed088c..1226bd278 100644 --- a/Dalamud.Boot/dllmain.cpp +++ b/Dalamud.Boot/dllmain.cpp @@ -1,10 +1,5 @@ -#define WIN32_LEAN_AND_MEAN -#define DllExport extern "C" __declspec(dllexport) +#include "pch.h" -#include -#include -#include "..\lib\CoreCLR\CoreCLR.h" -#include "..\lib\CoreCLR\boot.h" #include "veh.h" HMODULE g_hModule; @@ -69,7 +64,7 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam) std::wstring runtimeconfig_path = _wcsdup(fs_module_path.replace_filename(L"Dalamud.runtimeconfig.json").c_str()); std::wstring module_path = _wcsdup(fs_module_path.replace_filename(L"Dalamud.dll").c_str()); - // =========================================================================== // + // ============================== CLR ========================================= // void* entrypoint_vfn; int result = InitializeClrAndGetEntryPoint( @@ -86,10 +81,6 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam) typedef void (CORECLR_DELEGATE_CALLTYPE* custom_component_entry_point_fn)(LPVOID); custom_component_entry_point_fn entrypoint_fn = reinterpret_cast(entrypoint_vfn); - printf("Initializing Dalamud... "); - entrypoint_fn(lpParam); - printf("Done!\n"); - // ============================== VEH ======================================== // printf("Initializing VEH... "); @@ -108,7 +99,11 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam) printf("VEH was disabled manually\n"); } - // =========================================================================== // + // ============================== Dalamud ==================================== // + + printf("Initializing Dalamud... "); + entrypoint_fn(lpParam); + printf("Done!\n"); #ifndef NDEBUG fclose(stdin); diff --git a/lib/CoreCLR/pch.cpp b/Dalamud.Boot/pch.cpp similarity index 100% rename from lib/CoreCLR/pch.cpp rename to Dalamud.Boot/pch.cpp diff --git a/Dalamud.Boot/pch.h b/Dalamud.Boot/pch.h new file mode 100644 index 000000000..3c2bd6c4b --- /dev/null +++ b/Dalamud.Boot/pch.h @@ -0,0 +1,41 @@ +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +// Exclude rarely-used stuff from Windows headers +#define WIN32_LEAN_AND_MEAN + +// Windows Header Files +#include +#include +#include +#include +#include +#include + +// C++ Standard Libraries +#include +#include +#include +#include +#include +#include +#include + +// https://github.com/dotnet/coreclr +#include "..\lib\CoreCLR\CoreCLR.h" +#include "..\lib\CoreCLR\boot.h" + +// Commonly used macros +#define DllExport extern "C" __declspec(dllexport) + +// Global variables +extern HMODULE g_hModule; +extern std::optional g_clr; + +#endif //PCH_H diff --git a/Dalamud.Boot/rewrite_entrypoint.cpp b/Dalamud.Boot/rewrite_entrypoint.cpp index 589942e6f..93df1d93e 100644 --- a/Dalamud.Boot/rewrite_entrypoint.cpp +++ b/Dalamud.Boot/rewrite_entrypoint.cpp @@ -1,15 +1,5 @@ -#define WIN32_LEAN_AND_MEAN -#define DllExport extern "C" __declspec(dllexport) +#include "pch.h" -#include -#include -#include - -#include -#include -#include - -extern HMODULE g_hModule; DllExport DWORD WINAPI Initialize(LPVOID lpParam); struct RewrittenEntryPointParameters { diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp index 7f080b7e2..16ea2ab8f 100644 --- a/Dalamud.Boot/veh.cpp +++ b/Dalamud.Boot/veh.cpp @@ -1,12 +1,6 @@ -#define WIN32_LEAN_AND_MEAN +#include "pch.h" + #include "veh.h" -#include -#include -#include -#include -#include -#include -#include bool is_whitelist_exception(const DWORD code) { @@ -51,14 +45,16 @@ bool is_whitelist_exception(const DWORD code) } -bool get_module_file_and_base(const DWORD64 address, DWORD64* module_base, std::filesystem::path& module_file) +bool get_module_file_and_base(const DWORD64 address, DWORD64& module_base, std::filesystem::path& module_file) { HMODULE handle; if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(address), &handle)) { - if (wchar_t path[1024]; GetModuleFileNameW(handle, path, sizeof path / 2) > 0) + std::wstring path(PATHCCH_MAX_CCH, L'\0'); + path.resize(GetModuleFileNameW(handle, &path[0], static_cast(path.size()))); + if (!path.empty()) { - *module_base = reinterpret_cast(handle); + module_base = reinterpret_cast(handle); module_file = path; return true; } @@ -70,22 +66,24 @@ bool get_module_file_and_base(const DWORD64 address, DWORD64* module_base, std:: bool is_ffxiv_address(const DWORD64 address) { DWORD64 module_base; - if (std::filesystem::path module_path; get_module_file_and_base(address, &module_base, module_path)) + if (std::filesystem::path module_path; get_module_file_and_base(address, module_base, module_path)) return _wcsicmp(module_path.filename().c_str(), L"ffxiv_dx11.exe") == 0; return false; } -bool get_sym_from_addr(const DWORD64 address, DWORD64* displacement, std::wstring& symbol_name) +bool get_sym_from_addr(const DWORD64 address, DWORD64& displacement, std::wstring& symbol_name) { - char buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(wchar_t)]; - auto symbol = reinterpret_cast(buffer); - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = MAX_SYM_NAME; + union { + char buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(wchar_t)]{}; + SYMBOL_INFOW symbol; + }; + symbol.SizeOfStruct = sizeof(SYMBOL_INFO); + symbol.MaxNameLen = MAX_SYM_NAME; - if (SymFromAddrW(GetCurrentProcess(), address, displacement, symbol)) + if (SymFromAddrW(GetCurrentProcess(), address, &displacement, &symbol) && symbol.Name[0]) { - symbol_name.assign(_wcsdup(symbol->Name)); + symbol_name = symbol.Name; return true; } return false; @@ -96,7 +94,7 @@ std::wstring to_address_string(const DWORD64 address, const bool try_ptrderef = { DWORD64 module_base; std::filesystem::path module_path; - bool is_mod_addr = get_module_file_and_base(address, &module_base, module_path); + bool is_mod_addr = get_module_file_and_base(address, module_base, module_path); DWORD64 value = 0; if(try_ptrderef && address > 0x10000 && address < 0x7FFFFFFE0000) @@ -109,14 +107,32 @@ std::wstring to_address_string(const DWORD64 address, const bool try_ptrderef = std::format(L"{:X}", address); DWORD64 displacement; - if (std::wstring symbol; get_sym_from_addr(address, &displacement, symbol)) + if (std::wstring symbol; get_sym_from_addr(address, displacement, symbol)) return std::format(L"{}\t({})", addr_str, displacement != 0 ? std::format(L"{}+0x{:X}", symbol, displacement) : std::format(L"{}", symbol)); return value != 0 ? std::format(L"{} [{}]", addr_str, to_address_string(value, false)) : addr_str; } -void print_exception_info(const EXCEPTION_POINTERS* ex, std::wofstream& log) +void print_exception_info(const EXCEPTION_POINTERS* ex, std::wostringstream& log) { + size_t rec_index = 0; + for (auto rec = ex->ExceptionRecord; rec; rec = rec->ExceptionRecord) + { + log << std::format(L"\nException Info #{}\n", ++rec_index); + log << std::format(L"Address: {:X}\n", rec->ExceptionCode); + log << std::format(L"Flags: {:X}\n", rec->ExceptionFlags); + log << std::format(L"Address: {:X}\n", reinterpret_cast(rec->ExceptionAddress)); + if (!rec->NumberParameters) + continue; + log << L"Parameters: "; + for (DWORD i = 0; i < rec->NumberParameters; ++i) + { + if (i != 0) + log << L", "; + log << std::format(L"{:X}", rec->ExceptionInformation[i]); + } + } + log << L"\nCall Stack\n{"; STACKFRAME64 sf; @@ -140,7 +156,7 @@ void print_exception_info(const EXCEPTION_POINTERS* ex, std::wofstream& log) } while (sf.AddrReturn.Offset != 0 && sf.AddrPC.Offset != sf.AddrReturn.Offset); - log << L"\n}" << std::endl; + log << L"\n}\n"; ctx = *ex->ContextRecord; @@ -167,15 +183,15 @@ void print_exception_info(const EXCEPTION_POINTERS* ex, std::wofstream& log) log << L"\n}" << std::endl; - if(ctx.Rsp <= 0x10000 || ctx.Rsp >= 0x7FFFFFFE0000) - return; + if(0x10000 < ctx.Rsp && ctx.Rsp < 0x7FFFFFFE0000) + { + log << L"\nStack\n{"; - log << L"\nStack\n{"; + for(DWORD64 i = 0; i < 16; i++) + log << std::format(L"\n [RSP+{:X}]\t{}", i * 8, to_address_string(*reinterpret_cast(ctx.Rsp + i * 8ull))); - for(DWORD64 i = 0; i < 16; i++) - log << std::format(L"\n [RSP+{:X}]\t{}", i * 8, to_address_string(*reinterpret_cast(ctx.Rsp + i * 8ull))); - - log << L"\n}" << std::endl; + log << L"\n}\n"; + } log << L"\nModules\n{"; @@ -194,17 +210,12 @@ void print_exception_info(const EXCEPTION_POINTERS* ex, std::wofstream& log) CloseHandle(snap); } - log << L"\n}" << std::endl; + log << L"\n}\n"; } - -bool g_veh_message_open; - LONG exception_handler(EXCEPTION_POINTERS* ex) { - //block any further exceptions while the message box is open - if (g_veh_message_open) - for (;;) Sleep(1); + static std::mutex s_exception_handler_mutex; if (!is_whitelist_exception(ex->ExceptionRecord->ExceptionCode)) return EXCEPTION_CONTINUE_SEARCH; @@ -212,20 +223,21 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) if (!is_ffxiv_address(ex->ContextRecord->Rip)) return EXCEPTION_CONTINUE_SEARCH; + // block any other exceptions hitting the veh while the messagebox is open + const auto lock = std::lock_guard(s_exception_handler_mutex); + DWORD64 module_base; std::filesystem::path module_path; - get_module_file_and_base(reinterpret_cast(&exception_handler), &module_base, module_path); + get_module_file_and_base(reinterpret_cast(&exception_handler), module_base, module_path); #ifndef NDEBUG - std::wstring dmp_path = _wcsdup(module_path.replace_filename(L"dalamud_appcrashd.dmp").wstring().c_str()); + std::wstring dmp_path = module_path.replace_filename(L"dalamud_appcrashd.dmp").wstring(); #else - std::wstring dmp_path = _wcsdup(module_path.replace_filename(L"dalamud_appcrash.dmp").wstring().c_str()); + std::wstring dmp_path = module_path.replace_filename(L"dalamud_appcrash.dmp").wstring(); #endif - std::wstring log_path = _wcsdup(module_path.replace_filename(L"dalamud_appcrash.log").wstring().c_str()); - - std::wofstream log; - log.open(log_path, std::ios::trunc); + std::wstring log_path = module_path.replace_filename(L"dalamud_appcrash.log").wstring(); + std::wostringstream log; log << std::format(L"Unhandled native exception occurred at {}", to_address_string(ex->ContextRecord->Rip, false)) << std::endl; log << std::format(L"Code: {:X}", ex->ExceptionRecord->ExceptionCode) << std::endl; log << std::format(L"Dump at: {}", dmp_path) << std::endl; @@ -234,8 +246,6 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) SymRefreshModuleList(GetCurrentProcess()); print_exception_info(ex, log); - log.close(); - MINIDUMP_EXCEPTION_INFORMATION ex_info; ex_info.ClientPointers = false; ex_info.ExceptionPointers = ex; @@ -244,32 +254,43 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) HANDLE file = CreateFileW(dmp_path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpWithDataSegs, &ex_info, nullptr, nullptr); CloseHandle(file); + + void* fn; + if (const auto err = static_cast(g_clr->get_function_pointer( + L"Dalamud.EntryPoint, Dalamud", + L"VehCallback", + L"Dalamud.EntryPoint+VehDelegate, Dalamud", + nullptr, nullptr, &fn))) + { + const auto msg = L"An error within the game has occurred.\n\n" + L"This may be caused by a faulty plugin, a broken TexTools modification, any other third-party tool or simply a bug in the game.\n" + L"Please try \"Start Over\" or \"Download Index Backup\" in TexTools, an integrity check in the XIVLauncher settings, and disabling plugins you don't need.\n\n" + L"The log file is located at:\n" + L"{1}\n\n" + L"Press OK to exit the application.\n\nFailed to read stack trace: {2:08x}"; - auto msg = L"An error within the game has occurred.\n\n" - L"This may be caused by a faulty plugin, a broken TexTools modification, any other third-party tool or simply a bug in the game.\n" - L"Please try \"Start Over\" in TexTools, an integrity check in the XIVLauncher settings and disabling plugins you don't need.\n\n" - L"The log file is located at:\n" - L"{1}\n\n" - L"Press OK to exit the application."; - - auto formatted = std::format(msg, dmp_path, log_path); - - // block any other exceptions hitting the veh while the messagebox is open - g_veh_message_open = true; - MessageBoxW(nullptr, formatted.c_str(), L"Dalamud Error", MB_OK | MB_ICONERROR | MB_TOPMOST); - g_veh_message_open = false; + // show in another thread to prevent messagebox from pumping messages of current thread + std::thread([&]() { + MessageBoxW(nullptr, std::format(msg, dmp_path, log_path, err).c_str(), L"Dalamud Error", MB_OK | MB_ICONERROR | MB_TOPMOST); + }).join(); + } + else + { + ((void(__stdcall*)(const void*, const void*, const void*))fn)(dmp_path.c_str(), log_path.c_str(), log.str().c_str()); + } return EXCEPTION_CONTINUE_SEARCH; } -PVOID g_veh_handle; +PVOID g_veh_handle = nullptr; bool veh::add_handler() { if (g_veh_handle) return false; - g_veh_handle = AddVectoredExceptionHandler(0, exception_handler); + g_veh_handle = AddVectoredExceptionHandler(1, exception_handler); + SetUnhandledExceptionFilter(nullptr); return g_veh_handle != nullptr; } diff --git a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj index b035ba848..66b55feb2 100644 --- a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj +++ b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj @@ -90,15 +90,12 @@ - - - @@ -110,4 +107,4 @@ - + \ No newline at end of file diff --git a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj.filters b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj.filters index 47f80ab3e..45bf1b970 100644 --- a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj.filters +++ b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj.filters @@ -31,9 +31,6 @@ Source Files - - Source Files - Source Files @@ -42,15 +39,9 @@ - - Header Files - Header Files - - Header Files - Header Files diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index e9df6be92..37cbcb473 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -34,6 +34,14 @@ namespace Dalamud /// Pointer to a serialized data. public delegate void InitDelegate(IntPtr infoPtr); + /// + /// A delegate used from VEH handler on exception which CoreCLR will fast fail by default. + /// + /// Path to minidump file created in UTF-16. + /// Path to log file to create in UTF-16. + /// Log text in UTF-16. + public delegate void VehDelegate(IntPtr dumpPath, IntPtr logPath, IntPtr log); + /// /// Initialize Dalamud. /// @@ -46,6 +54,57 @@ namespace Dalamud new Thread(() => RunThread(info)).Start(); } + /// + /// Show error message along with stack trace and exit. + /// + /// Path to minidump file created in UTF-16. + /// Path to log file to create in UTF-16. + /// Log text in UTF-16. + public static void VehCallback(IntPtr dumpPath, IntPtr logPath, IntPtr log) + { + string stackTrace; + try + { + stackTrace = Environment.StackTrace; + } + catch (Exception e) + { + stackTrace = "Fail: " + e.ToString(); + } + + var msg = "An error within the game has occurred.\n\n" + + "This may be caused by a faulty plugin, a broken TexTools modification, any other third-party tool or simply a bug in the game.\n" + + "Please try \"Start Over\" or \"Download Index Backup\" in TexTools, an integrity check in the XIVLauncher settings, and disabling plugins you don't need.\n\n" + + "The log file is located at:\n" + + "{1}\n\n" + + "Press OK to exit the application.\n\nStack trace:\n{2}"; + + try + { + File.WriteAllText( + Marshal.PtrToStringUni(logPath), + "Stack trace:\n" + stackTrace + "\n\n" + Marshal.PtrToStringUni(log)); + } + catch (Exception e) + { + msg += "\n\nAdditionally, failed to write file: " + e.ToString(); + } + + // Show in another thread to prevent messagebox from pumping messages of current thread. + var msgThread = new Thread(() => + { + Utility.Util.Fatal( + msg.Format( + Marshal.PtrToStringUni(dumpPath), + Marshal.PtrToStringUni(logPath), + stackTrace), + "Dalamud Error", + false); + }); + msgThread.Start(); + msgThread.Join(); + } + /// /// Initialize all Dalamud subsystems and start running on the main thread. /// diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index ba7822f5e..fb2d53c3f 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -326,12 +326,14 @@ namespace Dalamud.Utility /// /// MessageBox body. /// MessageBox caption (title). - public static void Fatal(string message, string caption) + /// Specify whether to exit immediately. + public static void Fatal(string message, string caption, bool exit = true) { - var flags = NativeFunctions.MessageBoxType.Ok | NativeFunctions.MessageBoxType.IconError; + var flags = NativeFunctions.MessageBoxType.Ok | NativeFunctions.MessageBoxType.IconError | NativeFunctions.MessageBoxType.Topmost; _ = NativeFunctions.MessageBoxW(Process.GetCurrentProcess().MainWindowHandle, message, caption, flags); - Environment.Exit(-1); + if (exit) + Environment.Exit(-1); } /// diff --git a/lib/CoreCLR/CoreCLR.cpp b/lib/CoreCLR/CoreCLR.cpp index ec8e548cd..6f4d337b8 100644 --- a/lib/CoreCLR/CoreCLR.cpp +++ b/lib/CoreCLR/CoreCLR.cpp @@ -72,7 +72,17 @@ bool CoreCLR::load_runtime(const std::wstring& runtime_config_path, const struct hdt_load_assembly_and_get_function_pointer, reinterpret_cast(&m_load_assembly_and_get_function_pointer_fptr)); - if (result != 0 || m_load_assembly_and_get_function_pointer_fptr == nullptr) + if (result != 0 || m_load_assembly_and_get_function_pointer_fptr == nullptr) { + m_hostfxr_close_fptr(context); + return result; + } + + result = m_hostfxr_get_runtime_delegate_fptr( + context, + hdt_get_function_pointer, + reinterpret_cast(&m_get_function_pointer_fptr)); + + if (result != 0 || m_get_function_pointer_fptr == nullptr) { m_hostfxr_close_fptr(context); return result; @@ -99,6 +109,22 @@ int CoreCLR::load_assembly_and_get_function_pointer( return result; }; +int CoreCLR::get_function_pointer( + const wchar_t* type_name, + const wchar_t* method_name, + const wchar_t* delegate_type_name, + void* load_context, + void* reserved, + void** delegate) const +{ + int result = m_get_function_pointer_fptr(type_name, method_name, delegate_type_name, load_context, reserved, delegate); + + if (result != 0) + delegate = nullptr; + + return result; +} + /* Helpers */ uint64_t CoreCLR::load_library(const wchar_t* path) { diff --git a/lib/CoreCLR/CoreCLR.h b/lib/CoreCLR/CoreCLR.h index c2395d07d..235bf9923 100644 --- a/lib/CoreCLR/CoreCLR.h +++ b/lib/CoreCLR/CoreCLR.h @@ -24,12 +24,20 @@ class CoreCLR { const wchar_t* delegate_type_name, void* reserved, void** delegate) const; + int get_function_pointer( + const wchar_t* type_name, + const wchar_t* method_name, + const wchar_t* delegate_type_name, + void* load_context, + void* reserved, + void** delegate) const; private: /* HostFXR delegates. */ hostfxr_initialize_for_runtime_config_fn m_hostfxr_initialize_for_runtime_config_fptr{}; hostfxr_get_runtime_delegate_fn m_hostfxr_get_runtime_delegate_fptr{}; hostfxr_close_fn m_hostfxr_close_fptr{}; + get_function_pointer_fn m_get_function_pointer_fptr = nullptr; load_assembly_and_get_function_pointer_fn m_load_assembly_and_get_function_pointer_fptr = nullptr; /* Helper functions. */ diff --git a/lib/CoreCLR/boot.cpp b/lib/CoreCLR/boot.cpp index d6fc0f604..2fde7e221 100644 --- a/lib/CoreCLR/boot.cpp +++ b/lib/CoreCLR/boot.cpp @@ -23,6 +23,8 @@ void ConsoleTeardown() FreeConsole(); } +std::optional g_clr; + int InitializeClrAndGetEntryPoint( std::wstring runtimeconfig_path, std::wstring module_path, @@ -31,8 +33,9 @@ int InitializeClrAndGetEntryPoint( std::wstring entrypoint_delegate_type_name, void** entrypoint_fn) { + g_clr = CoreCLR(); + int result; - CoreCLR clr; SetEnvironmentVariable(L"DOTNET_MULTILEVEL_LOOKUP", L"0"); //SetEnvironmentVariable(L"COMPlus_legacyCorruptedStateExceptionsPolicy", L"1"); SetEnvironmentVariable(L"DOTNET_legacyCorruptedStateExceptionsPolicy", L"1"); @@ -85,7 +88,7 @@ int InitializeClrAndGetEntryPoint( }; printf("Loading hostfxr... "); - if ((result = clr.load_hostfxr(&init_parameters)) != 0) + if ((result = g_clr->load_hostfxr(&init_parameters)) != 0) { printf("\nError: Failed to load the `hostfxr` library (err=%d)\n", result); return result; @@ -102,7 +105,7 @@ int InitializeClrAndGetEntryPoint( }; printf("Loading coreclr... ");; - if ((result = clr.load_runtime(runtimeconfig_path, &runtime_parameters)) != 0) + if ((result = g_clr->load_runtime(runtimeconfig_path, &runtime_parameters)) != 0) { printf("\nError: Failed to load coreclr (err=%d)\n", result); return result; @@ -112,7 +115,7 @@ int InitializeClrAndGetEntryPoint( // =========================================================================== // printf("Loading module... "); - if ((result = clr.load_assembly_and_get_function_pointer( + if ((result = g_clr->load_assembly_and_get_function_pointer( module_path.c_str(), entrypoint_assembly_name.c_str(), entrypoint_method_name.c_str(), diff --git a/lib/CoreCLR/framework.h b/lib/CoreCLR/framework.h deleted file mode 100644 index 8bb54776a..000000000 --- a/lib/CoreCLR/framework.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -// Exclude rarely-used stuff from Windows headers -#define WIN32_LEAN_AND_MEAN - -// Windows Header Files -#include diff --git a/lib/CoreCLR/pch.h b/lib/CoreCLR/pch.h deleted file mode 100644 index 885d5d62e..000000000 --- a/lib/CoreCLR/pch.h +++ /dev/null @@ -1,13 +0,0 @@ -// pch.h: This is a precompiled header file. -// Files listed below are compiled only once, improving build performance for future builds. -// This also affects IntelliSense performance, including code completion and many code browsing features. -// However, files listed here are ALL re-compiled if any one of them is updated between builds. -// Do not add files here that you will be updating frequently as this negates the performance advantage. - -#ifndef PCH_H -#define PCH_H - -// add headers that you want to pre-compile here -#include "framework.h" - -#endif //PCH_H