[corlib] Properly implement Environment.Is64BitOperatingSystem
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Tue, 12 Jan 2016 15:51:13 +0000 (16:51 +0100)
committerAlexander Köplinger <alex.koeplinger@outlook.com>
Wed, 13 Jan 2016 01:46:37 +0000 (02:46 +0100)
Before we only checked if IntPtr.Size == 8, but this returns false for a 32bit Mono running on a 64bit OS.
Added an icall that gets the correct value from the runtime instead.

Note: this currently only whitelists x86_64, aarch64 and ppc64 as 64-bit platforms.

Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=37414

mcs/class/corlib/System/Environment.cs
mono/metadata/icall-def.h
mono/metadata/icall.c

index a930e5355adffd83814f182d7c2ce894dd433027..2c74fa24ae50d10da2034dca17d9f0b0136884ee 100644 (file)
@@ -900,8 +900,11 @@ namespace System {
                        throw new NotImplementedException ();
                }
 
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern static bool GetIs64BitOperatingSystem ();
+
                public static bool Is64BitOperatingSystem {
-                       get { return IntPtr.Size == 8; } // FIXME: is this good enough?
+                       get { return GetIs64BitOperatingSystem (); }
                }
 
                public static int SystemPageSize {
index 88fb2539e83319225eda11d4e5f8247949b2eee9..e0a1d585d8be8117f8c9aea3440620da3162128b 100644 (file)
@@ -228,6 +228,7 @@ ICALL_TYPE(ENV, "System.Environment", ENV_1)
 ICALL(ENV_1, "Exit", ves_icall_System_Environment_Exit)
 ICALL(ENV_2, "GetCommandLineArgs", mono_runtime_get_main_args)
 ICALL(ENV_3, "GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames)
+ICALL(ENV_31, "GetIs64BitOperatingSystem", ves_icall_System_Environment_GetIs64BitOperatingSystem)
 ICALL(ENV_4, "GetLogicalDrivesInternal", ves_icall_System_Environment_GetLogicalDrives )
 ICALL(ENV_5, "GetMachineConfigPath", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path)
 ICALL(ENV_51, "GetNewLine", ves_icall_System_Environment_get_NewLine)
index 69c89e9faf12d6832c0b7a47ab4f3a4744bcc9f4..b54b469fea80b693630edfca17ddbc9ac25cce15 100644 (file)
 #include "decimal-ms.h"
 #include "number-ms.h"
 
+#if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
+#include <sys/utsname.h>
+#endif
+
 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
 
 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
@@ -5888,6 +5892,28 @@ ves_icall_System_Environment_get_NewLine (void)
 #endif
 }
 
+ICALL_EXPORT MonoBoolean
+ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
+{
+#if SIZEOF_VOID_P == 8
+       return TRUE;
+#else
+#ifdef HOST_WIN32
+       gboolean isWow64Process = FALSE;
+       if (IsWow64Process (GetCurrentProcess (), &isWow64Process)) {
+               return (MonoBoolean)isWow64Process;
+       }
+#elif defined(HAVE_SYS_UTSNAME_H)
+       struct utsname name;
+
+       if (uname (&name) >= 0) {
+               return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
+       }
+#endif
+       return FALSE;
+#endif
+}
+
 ICALL_EXPORT MonoString *
 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
 {