-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add Per-assembly Load Native Library callbacks #21555
Conversation
@@ -32,6 +32,11 @@ public static partial class Marshal | |||
internal static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); | |||
#endif //FEATURE_COMINTEROP | |||
|
|||
static Marshal() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An explicit static constructor is bad for performance and in this case also causes an infinite loop during startup. Maybe nativeDllResolveMap
should be lazy-initialized on first use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree
That's not the usual process... |
/// Therefore, this table uses weak assembly pointers to indirectly achieve | ||
/// similar behavior. | ||
/// </summary> | ||
public static ConditionalWeakTable<Assembly, Func<string, Assembly, DllImportSearchPath?, IntPtr>> nativeDllResolveMap; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md: prefix static fields with s_
internal static IntPtr LoadLibraryCallbackStub(string libraryName, Assembly assembly, | ||
bool hasDllImportSearchPathFlags, uint dllImportSearchPathFlags) | ||
{ | ||
Func<string, Assembly, DllImportSearchPath?, IntPtr> callBack; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
callback
is one word. B
should be lowercase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(multiple places)
src/vm/dllimport.cpp
Outdated
@@ -6280,23 +6280,32 @@ INT_PTR NDirect::GetNativeLibraryExport(NATIVE_LIBRARY_HANDLE handle, LPCWSTR sy | |||
return address; | |||
} | |||
|
|||
#ifndef PLATFORM_UNIX | |||
BOOL IsWindowsAPI(PCWSTR wszLibName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not return whether the name is Windows API. It returns whether the name is Windows API set. Change the name to IsWindowsAPISet
?
src/vm/dllimport.cpp
Outdated
NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaCallBack(NDirectMethodDesc * pMD, LPCWSTR wszLibName) | ||
{ | ||
#ifndef PLATFORM_UNIX | ||
if (IsWindowsAPI(wszLibName)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the rationale behind blocking this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My only concern with not blocking this is the scenario where we deploy Windows API sets on downlevel Windows SKUs (i.e. Windows 7). The issue here would be why are we looking in the system if they are app local? This is largely a hedge about not trusting Windows to deploy API sets that are guaranteed backwards compatible. I think that is a fair assumption the API sets will always be backwards compat, but note that the behavior will be different on different platforms if we rely on a system API set in some cases and our applocal version of the API sets in others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When it comes to Windows 7, API sets are incompatible mess. Note that there are no officially shipped API sets for Windows 7, except for the few that support universal CRT. We learned this hard-way during the .NET Core 1.0 days when we were using API sets everywhere, only to find out that there is no way to make things work well with Windows 7 if you do that.
If somebody wants to resolve API sets on their own to make stuff work, we should not stand in the way.
src/vm/callhelpers.h
Outdated
@@ -566,6 +566,7 @@ enum DispatchCallSimpleFlags | |||
#define STRINGREF_TO_ARGHOLDER(x) (LPVOID)STRINGREFToObject(x) | |||
#define PTR_TO_ARGHOLDER(x) (LPVOID)x | |||
#define DWORD_TO_ARGHOLDER(x) (LPVOID)(SIZE_T)x | |||
#define BOOL_TO_ARGHOLDER(x) DWORD_TO_ARGHOLDER(x) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not quite right. Assuming the managed argument is going to be bool
, this value should be normalized, e.g. using !!
src/vm/dllimport.cpp
Outdated
|
||
Assembly* pAssembly = pMD->GetMethodTable()->GetAssembly(); | ||
protect.libNameRef = StringObject::NewString(wszLibName); | ||
protect.assemblyRef = pAssembly->GetExposedObject(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has GC hole. You are assigning object references without them being protected.
This exact situation is described in "Your first GC hole" in https://github.com/dotnet/coreclr/blob/master/Documentation/coding-guidelines/clr-code-guide.md#2.1.2.
src/vm/dllimport.cpp
Outdated
@@ -6362,6 +6371,55 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaHost(NDirectMethodDesc * pMD, | |||
return (NATIVE_LIBRARY_HANDLE)hmod; | |||
} | |||
|
|||
NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaCallBack(NDirectMethodDesc * pMD, LPCWSTR wszLibName) | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add contracts to all new methods.
return false; | ||
} | ||
|
||
nativeDllResolveMap.Add(assembly, callBack); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has race condition: if the method is called from multiple threads on same assembly, we may end up throwing here.
/// and returns | ||
/// - The handle to the loaded native library (on success) or null (on failure) | ||
/// The parameters on this callback are such that they can be directly passed to | ||
/// Marhall.LoadLibrary(libraryName, assembly, dllImportSearchPath) to approximately achieve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Marhall.LoadLibrary(libraryName, assembly, dllImportSearchPath) to approximately achieve | |
/// Marhal.LoadLibrary(libraryName, assembly, dllImportSearchPath) to approximately achieve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marshal
?
82c8738
to
7751a17
Compare
@jkotas @AaronRobinsonMSFT @pentp I have addressed your feedback in the new commit. |
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
886fc14
to
f84249e
Compare
@dotnet-bot test Windows_NT x64 Release CoreFX Tests |
The "OSX10.12 x64 Checked Innerloop Build and Test" failure seems unrelated. It is failing on all runs. |
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
This Change implements the Native Library resolution Call-backs proposed in https://github.com/dotnet/corefx/issues/32015
Looks good to me, but it can use a second pair of eyes. I have looked at this too many times... |
@jkotas I will take another look. |
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs
Outdated
Show resolved
Hide resolved
Thanks for the feedback @AaronRobinsonMSFT. |
@dotnet-bot test Ubuntu arm Cross Checked no_tiered_compilation_innerloop Build and Test |
Add Per-assembly Load Native Library callbacks This Change implements the Native Library resolution Call-backs proposed in https://github.com/dotnet/corefx/issues/32015 Commit migrated from dotnet/coreclr@732f892
This Change implements the Native Library resolution
Call-backs proposed in dotnet/corefx#32015