Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs')
-rw-r--r--src/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs67
1 files changed, 54 insertions, 13 deletions
diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs b/src/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs
index ad79c2510..dc598bbb7 100644
--- a/src/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs
+++ b/src/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs
@@ -3,10 +3,11 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Text;
-using System.Runtime.InteropServices;
using System.Diagnostics;
-using Interlocked = System.Threading.Interlocked;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
namespace Internal.Runtime.CompilerHelpers
{
@@ -15,7 +16,7 @@ namespace Internal.Runtime.CompilerHelpers
/// </summary>
internal static class InteropHelpers
{
- internal static unsafe byte* StringToAnsiString(String str, bool bestFit, bool throwOnUnmappableChar)
+ internal static unsafe byte* StringToAnsiString(string str, bool bestFit, bool throwOnUnmappableChar)
{
return PInvokeMarshal.StringToAnsiString(str, bestFit, throwOnUnmappableChar);
}
@@ -37,7 +38,7 @@ namespace Internal.Runtime.CompilerHelpers
return PInvokeMarshal.ByValAnsiStringToString(buffer, length);
}
- internal static unsafe void StringToUnicodeFixedArray(String str, UInt16* buffer, int length)
+ internal static unsafe void StringToUnicodeFixedArray(string str, ushort* buffer, int length)
{
if (buffer == null)
return;
@@ -58,16 +59,16 @@ namespace Internal.Runtime.CompilerHelpers
}
}
- internal static unsafe string UnicodeToStringFixedArray(UInt16* buffer, int length)
+ internal static unsafe string UnicodeToStringFixedArray(ushort* buffer, int length)
{
if (buffer == null)
- return String.Empty;
+ return string.Empty;
- string result = String.Empty;
+ string result = string.Empty;
if (length > 0)
{
- result = new String(' ', length);
+ result = new string(' ', length);
fixed (char* pTemp = result)
{
@@ -78,7 +79,7 @@ namespace Internal.Runtime.CompilerHelpers
return result;
}
- internal static unsafe char* StringToUnicodeBuffer(String str)
+ internal static unsafe char* StringToUnicodeBuffer(string str)
{
if (str == null)
return null;
@@ -98,7 +99,7 @@ namespace Internal.Runtime.CompilerHelpers
public static unsafe string UnicodeBufferToString(char* buffer)
{
- return new String(buffer);
+ return new string(buffer);
}
public static unsafe byte* AllocMemoryForAnsiStringBuilder(StringBuilder sb)
@@ -208,6 +209,7 @@ namespace Internal.Runtime.CompilerHelpers
return ResolvePInvokeSlow(pCell);
}
+ [MethodImpl(MethodImplOptions.NoInlining)]
internal static unsafe IntPtr ResolvePInvokeSlow(MethodFixupCell* pCell)
{
ModuleFixupCell* pModuleCell = pCell->Module;
@@ -304,8 +306,8 @@ namespace Internal.Runtime.CompilerHelpers
{
byte* methodName = (byte*)pCell->MethodName;
-#if !PLATFORM_UNIX
- pCell->Target = Interop.mincore.GetProcAddress(hModule, methodName);
+#if PLATFORM_WINDOWS
+ pCell->Target = GetProcAddress(hModule, methodName, pCell->CharSetMangling);
#else
pCell->Target = Interop.Sys.GetProcAddress(hModule, methodName);
#endif
@@ -316,6 +318,44 @@ namespace Internal.Runtime.CompilerHelpers
}
}
+#if PLATFORM_WINDOWS
+ private static unsafe IntPtr GetProcAddress(IntPtr hModule, byte* methodName, CharSet charSetMangling)
+ {
+ // First look for the unmangled name. If it is unicode function, we are going
+ // to need to check for the 'W' API because it takes precedence over the
+ // unmangled one (on NT some APIs have unmangled ANSI exports).
+
+ var exactMatch = Interop.mincore.GetProcAddress(hModule, methodName);
+
+ if ((charSetMangling == CharSet.Ansi && exactMatch != IntPtr.Zero) || charSetMangling == 0)
+ {
+ return exactMatch;
+ }
+
+ int nameLength = strlen(methodName);
+
+ // We need to add an extra byte for the suffix, and an extra byte for the null terminator
+ byte* probedMethodName = stackalloc byte[nameLength + 2];
+
+ for (int i = 0; i < nameLength; i++)
+ {
+ probedMethodName[i] = methodName[i];
+ }
+
+ probedMethodName[nameLength + 1] = 0;
+
+ probedMethodName[nameLength] = (charSetMangling == CharSet.Ansi) ? (byte)'A' : (byte)'W';
+
+ IntPtr probedMethod = Interop.mincore.GetProcAddress(hModule, probedMethodName);
+ if (probedMethod != IntPtr.Zero)
+ {
+ return probedMethod;
+ }
+
+ return exactMatch;
+ }
+#endif
+
internal static unsafe int strlen(byte* pString)
{
byte* p = pString;
@@ -379,6 +419,7 @@ namespace Internal.Runtime.CompilerHelpers
public IntPtr Target;
public IntPtr MethodName;
public ModuleFixupCell* Module;
+ public CharSet CharSetMangling;
}
}
}