diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index bfceafaee1..6c5ea25b1b 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1840,10 +1840,18 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept } } - fmt::append(msg, "Instruction address: %p.\n", pExp->ContextRecord->Rip); +#if defined(ARCH_X64) +#define RIP(ctx) ctx->Rip +#elif defined(ARCH_ARM64) +#define RIP(ctx) ctx->Pc +#else +#error "Unimplemented exception handling for this architecture" +#endif + + fmt::append(msg, "Instruction address: %p.\n", RIP(pExp->ContextRecord)); DWORD64 unwind_base; - if (const auto rtf = RtlLookupFunctionEntry(pExp->ContextRecord->Rip, &unwind_base, nullptr)) + if (const auto rtf = RtlLookupFunctionEntry(RIP(pExp->ContextRecord), &unwind_base, nullptr)) { // Get function address const DWORD64 func_addr = rtf->BeginAddress + unwind_base; @@ -1860,7 +1868,7 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept { const DWORD64 base = reinterpret_cast(info.lpBaseOfDll); - if (pExp->ContextRecord->Rip >= base && pExp->ContextRecord->Rip < base + info.SizeOfImage) + if (RIP(pExp->ContextRecord) >= base && RIP(pExp->ContextRecord) < base + info.SizeOfImage) { std::string module_name; for (DWORD size = 15; module_name.size() != size;) diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 1aab60481f..bc5efd79c7 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -510,15 +510,19 @@ class named_thread final : public Context, result_storage, thread_base #if defined(ARCH_X64) static inline thread::native_entry trampoline = thread::make_trampoline(entry_point); +#else +#ifdef _WIN32 + static uint trampoline(void* arg) #else static void* trampoline(void* arg) +#endif { if (const auto next = thread_base::finalize(entry_point(static_cast(arg)))) { return next(thread_ctrl::get_current()); } - return nullptr; + return 0; } #endif diff --git a/Utilities/stack_trace.cpp b/Utilities/stack_trace.cpp index 5247c75916..9ca20387af 100644 --- a/Utilities/stack_trace.cpp +++ b/Utilities/stack_trace.cpp @@ -41,12 +41,18 @@ namespace utils RtlCaptureContext(&context); STACKFRAME64 stack = {}; - stack.AddrPC.Offset = context.Rip; stack.AddrPC.Mode = AddrModeFlat; - stack.AddrStack.Offset = context.Rsp; stack.AddrStack.Mode = AddrModeFlat; - stack.AddrFrame.Offset = context.Rbp; stack.AddrFrame.Mode = AddrModeFlat; +#if defined(ARCH_X64) + stack.AddrPC.Offset = context.Rip; + stack.AddrStack.Offset = context.Rsp; + stack.AddrFrame.Offset = context.Rbp; +#elif defined(ARCH_ARM64) + stack.AddrPC.Offset = context.Pc; + stack.AddrStack.Offset = context.Sp; + stack.AddrFrame.Offset = context.Fp; +#endif while (max_depth--) { diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index 226a126f26..97a19447d2 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -114,7 +114,7 @@ if(UNIX) endif() if(WIN32) - target_link_libraries(rpcs3 PRIVATE ws2_32 Iphlpapi Winmm Psapi gdi32 setupapi pdh) + target_link_libraries(rpcs3 PRIVATE bcrypt ws2_32 Iphlpapi Winmm Psapi gdi32 setupapi pdh c++) else() target_link_libraries(rpcs3 PRIVATE ${CMAKE_DL_LIBS}) endif() diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index c05fbdcb2f..ea91dd1dec 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -389,7 +389,7 @@ target_sources(rpcs3_emu PRIVATE CPU/CPUTranslator.cpp ) -if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64") +if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|arm64|aarch64") target_sources(rpcs3_emu PRIVATE CPU/Backends/AArch64/AArch64ASM.cpp CPU/Backends/AArch64/AArch64Common.cpp diff --git a/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.h b/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.h index eba782af6c..ed743ff9ba 100644 --- a/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.h +++ b/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.h @@ -1,7 +1,12 @@ #pragma once #include + +#ifndef _WIN32 #include +#else +using ucontext_t = void; +#endif namespace aarch64 { diff --git a/rpcs3/Emu/CPU/sse2neon.h b/rpcs3/Emu/CPU/sse2neon.h index d863c0ca73..02889d2eea 100644 --- a/rpcs3/Emu/CPU/sse2neon.h +++ b/rpcs3/Emu/CPU/sse2neon.h @@ -132,6 +132,25 @@ #include #endif +#if defined(_WIN32) +static inline int posix_memalign(void** memptr, size_t alignment, size_t size) { + // Check for valid alignment (must be a power of two and multiple of sizeof(void*)) + if (alignment == 0 || (alignment & (alignment - 1)) != 0 || alignment % sizeof(void*) != 0) { + return EINVAL; + } + + // Allocate memory using _aligned_malloc + void* ptr = _aligned_malloc(size, alignment); + if (ptr == NULL) { + return ENOMEM; + } + + // Set the output pointer + *memptr = ptr; + return 0; // Success +} +#endif + /* "__has_builtin" can be used to query support for built-in functions * provided by gcc/clang and other compilers that support it. */ diff --git a/rpcs3/util/sysinfo.cpp b/rpcs3/util/sysinfo.cpp index 6f37614d75..bad59aba8f 100755 --- a/rpcs3/util/sysinfo.cpp +++ b/rpcs3/util/sysinfo.cpp @@ -68,6 +68,15 @@ namespace Darwin_ProcessInfo } #endif +#if defined(ARCH_ARM64) && defined (_WIN32) && !defined(_MSC_VER) +static inline u64 __readx18qword(int offset) +{ + u64* peb = nullptr; + __asm__ volatile("mov %0, x18" : "=r"(peb)); + return peb[offset]; +} +#endif + bool utils::has_ssse3() { #if defined(ARCH_X64) @@ -583,7 +592,11 @@ std::string utils::get_OS_version() // So we're forced to read PEB instead to get Windows version info. It's ugly but works. const DWORD peb_offset = 0x60; +#if defined(ARCH_X64) const INT_PTR peb = __readgsqword(peb_offset); +#elif defined(_M_ARM64) + const INT_PTR peb = __readx18qword(peb_offset); +#endif const DWORD version_major = *reinterpret_cast(peb + 0x118); const DWORD version_minor = *reinterpret_cast(peb + 0x11c);