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

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotas authored May 12, 2020
1 parent 2c6a83f commit c2e918f
Showing 1 changed file with 31 additions and 23 deletions.
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

0 comments on commit c2e918f

Please sign in to comment.