Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Port https://github.com/dotnet/runtime/pull/36257 #8152

Merged
merged 1 commit into from
May 12, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -323,33 +323,47 @@ internal static unsafe void FixupModuleCell(ModuleFixupCell* pCell)
internal static unsafe void FixupMethodCell(IntPtr hModule, MethodFixupCell* pCell)
{
byte* methodName = (byte*)pCell->MethodName;
IntPtr pTarget;

#if TARGET_WINDOWS
pCell->Target = GetProcAddress(hModule, methodName, pCell->CharSetMangling);
CharSet charSetMangling = pCell->CharSetMangling;
if (charSetMangling == 0)
{
// Look for the user-provided entry point name only
pTarget = Interop.mincore.GetProcAddress(hModule, methodName);
}
else
if (charSetMangling == CharSet.Ansi)
{
// For ANSI, look for the user-provided entry point name first.
// If that does not exist, try the charset suffix.
pTarget = Interop.mincore.GetProcAddress(hModule, methodName);
if (pTarget == IntPtr.Zero)
pTarget = GetProcAddressWithSuffix(hModule, methodName, (byte)'A');
}
else
{
// For Unicode, look for the entry point name with the charset suffix first.
// The 'W' API takes precedence over the undecorated one.
pTarget = GetProcAddressWithSuffix(hModule, methodName, (byte)'W');
if (pTarget == IntPtr.Zero)
pTarget = Interop.mincore.GetProcAddress(hModule, methodName);
}
#else
pCell->Target = Interop.Sys.GetProcAddress(hModule, methodName);
pTarget = Interop.Sys.GetProcAddress(hModule, methodName);
#endif
if (pCell->Target == IntPtr.Zero)
if (pTarget == IntPtr.Zero)
{
string entryPointName = Encoding.UTF8.GetString(methodName, string.strlen(methodName));
throw new EntryPointNotFoundException(SR.Format(SR.Arg_EntryPointNotFoundExceptionParameterized, entryPointName, GetModuleName(pCell->Module)));
}

pCell->Target = pTarget;
}

#if TARGET_WINDOWS
private static unsafe IntPtr GetProcAddress(IntPtr hModule, byte* methodName, CharSet charSetMangling)
private static unsafe IntPtr GetProcAddressWithSuffix(IntPtr hModule, byte* methodName, byte suffix)
{
// 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 = string.strlen(methodName);

// We need to add an extra byte for the suffix, and an extra byte for the null terminator
Expand All @@ -362,15 +376,9 @@ private static unsafe IntPtr GetProcAddress(IntPtr hModule, byte* methodName, Ch

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;
}
probedMethodName[nameLength] = suffix;

return exactMatch;
return Interop.mincore.GetProcAddress(hModule, probedMethodName);
}
#endif

Expand Down