From ecc55fe82e43daaafac20ce0b63a55c32eb4f68f Mon Sep 17 00:00:00 2001 From: Mateo Torres-Ruiz Date: Wed, 20 Oct 2021 18:00:30 +0000 Subject: [PATCH 1/2] Use x64 directory if running x64 process on arm64 apphost Backport of #59890 --- src/native/corehost/hostmisc/pal.h | 1 + src/native/corehost/hostmisc/pal.unix.cpp | 24 ++++++++++++ src/native/corehost/hostmisc/pal.windows.cpp | 41 ++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/native/corehost/hostmisc/pal.h b/src/native/corehost/hostmisc/pal.h index 0932e0db5b60e3..69cf8353800830 100644 --- a/src/native/corehost/hostmisc/pal.h +++ b/src/native/corehost/hostmisc/pal.h @@ -310,6 +310,7 @@ namespace pal void unload_library(dll_t library); bool is_running_in_wow64(); + bool is_emulating_x64(); bool are_paths_equal_with_normalized_casing(const string_t& path1, const string_t& path2); } diff --git a/src/native/corehost/hostmisc/pal.unix.cpp b/src/native/corehost/hostmisc/pal.unix.cpp index 59597646e03730..3524cc6256ad7c 100644 --- a/src/native/corehost/hostmisc/pal.unix.cpp +++ b/src/native/corehost/hostmisc/pal.unix.cpp @@ -505,6 +505,10 @@ bool pal::get_default_installation_dir(pal::string_t* recv) #if defined(TARGET_OSX) recv->assign(_X("/usr/local/share/dotnet")); + if (pal::is_emulating_x64()) + { + append_path(recv, _X("x64")); + } #else recv->assign(_X("/usr/share/dotnet")); #endif @@ -979,6 +983,26 @@ bool pal::is_running_in_wow64() return false; } +bool pal::is_emulating_x64() +{ + int is_translated_process = 0; +#if defined(TARGET_OSX) + size_t size = sizeof(is_translated_process); + if (sysctlbyname("sysctl.proc_translated", &is_translated_process, &size, NULL, 0) == -1) + { + trace::info(_X("Could not determine whether the current process is running under Rosetta.")); + if (errno != ENOENT) + { + trace::info(_X("Call to sysctlbyname failed: %s"), strerror(errno)); + } + + return false; + } +#endif + + return is_translated_process == 1; +} + bool pal::are_paths_equal_with_normalized_casing(const string_t& path1, const string_t& path2) { #if defined(TARGET_OSX) diff --git a/src/native/corehost/hostmisc/pal.windows.cpp b/src/native/corehost/hostmisc/pal.windows.cpp index 6ce65baae47916..d235fd431de4ae 100644 --- a/src/native/corehost/hostmisc/pal.windows.cpp +++ b/src/native/corehost/hostmisc/pal.windows.cpp @@ -292,6 +292,11 @@ bool pal::get_default_installation_dir(pal::string_t* recv) } append_path(recv, _X("dotnet")); + if (pal::is_emulating_x64()) + { + // Install location for emulated x64 should be %ProgramFiles%\dotnet\x64. + append_path(recv, _X("x64")); + } return true; } @@ -783,6 +788,42 @@ bool pal::is_running_in_wow64() return (fWow64Process != FALSE); } +typedef BOOL (WINAPI* is_wow64_process2)( + HANDLE hProcess, + USHORT *pProcessMachine, + USHORT *pNativeMachine +); + +bool pal::is_emulating_x64() +{ + USHORT pProcessMachine, pNativeMachine; + auto kernel32 = LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (kernel32) + { + is_wow64_process2 isWow64Process2Func = (is_wow64_process2)GetProcAddress(kernel32, "IsWow64Process2"); + if (!isWow64Process2Func) + { + // Could not find IsWow64Process2. + return false; + } + + if (!isWow64Process2Func(GetCurrentProcess(), &pProcessMachine, &pNativeMachine)) + { + // IsWow64Process2 failed. Log the error and continue. + trace::info(_X("Call to IsWow64Process2 failed: %s"), GetLastError()); + return false; + } + + // Check if we are running an x64 process on a non-x64 windows machine. + return pProcessMachine != pNativeMachine && pProcessMachine == IMAGE_FILE_MACHINE_AMD64; + } + + // Loading kernel32.dll failed, log the error and continue. + trace::info(_X("Could not load 'kernel32.dll': %s"), GetLastError()); + + return false; +} + bool pal::are_paths_equal_with_normalized_casing(const string_t& path1, const string_t& path2) { // On Windows, paths are case-insensitive From 7f853182c8a3d8f307c87307a13c9232f62febde Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Fri, 29 Apr 2022 09:31:11 -0700 Subject: [PATCH 2/2] Fix is_emulating_x64 on Windows (#68671) --- src/native/corehost/hostmisc/pal.windows.cpp | 48 +++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/native/corehost/hostmisc/pal.windows.cpp b/src/native/corehost/hostmisc/pal.windows.cpp index d235fd431de4ae..c613d4240d34a6 100644 --- a/src/native/corehost/hostmisc/pal.windows.cpp +++ b/src/native/corehost/hostmisc/pal.windows.cpp @@ -789,39 +789,43 @@ bool pal::is_running_in_wow64() } typedef BOOL (WINAPI* is_wow64_process2)( - HANDLE hProcess, - USHORT *pProcessMachine, - USHORT *pNativeMachine + HANDLE hProcess, + USHORT *pProcessMachine, + USHORT *pNativeMachine ); bool pal::is_emulating_x64() { - USHORT pProcessMachine, pNativeMachine; +#if defined(TARGET_AMD64) auto kernel32 = LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); - if (kernel32) + if (kernel32 == nullptr) { - is_wow64_process2 isWow64Process2Func = (is_wow64_process2)GetProcAddress(kernel32, "IsWow64Process2"); - if (!isWow64Process2Func) - { - // Could not find IsWow64Process2. - return false; - } - - if (!isWow64Process2Func(GetCurrentProcess(), &pProcessMachine, &pNativeMachine)) - { - // IsWow64Process2 failed. Log the error and continue. - trace::info(_X("Call to IsWow64Process2 failed: %s"), GetLastError()); - return false; - } + // Loading kernel32.dll failed, log the error and continue. + trace::info(_X("Could not load 'kernel32.dll': %u"), GetLastError()); + return false; + } - // Check if we are running an x64 process on a non-x64 windows machine. - return pProcessMachine != pNativeMachine && pProcessMachine == IMAGE_FILE_MACHINE_AMD64; + is_wow64_process2 is_wow64_process2_func = (is_wow64_process2)::GetProcAddress(kernel32, "IsWow64Process2"); + if (is_wow64_process2_func == nullptr) + { + // Could not find IsWow64Process2. + return false; } - // Loading kernel32.dll failed, log the error and continue. - trace::info(_X("Could not load 'kernel32.dll': %s"), GetLastError()); + USHORT process_machine; + USHORT native_machine; + if (!is_wow64_process2_func(GetCurrentProcess(), &process_machine, &native_machine)) + { + // IsWow64Process2 failed. Log the error and continue. + trace::info(_X("Call to IsWow64Process2 failed: %u"), GetLastError()); + return false; + } + // If we are running targeting x64 on a non-x64 machine, we are emulating + return native_machine != IMAGE_FILE_MACHINE_AMD64; +#else return false; +#endif } bool pal::are_paths_equal_with_normalized_casing(const string_t& path1, const string_t& path2)