From b2c7585ba82a2248e7d0afb956c3f17cfbb6d6e7 Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Wed, 29 Jul 2020 02:47:49 -0700 Subject: [PATCH] Redirect DllImport of hostpolicy to the main executable when it's embedded (#40014) --- src/coreclr/src/dlls/mscoree/unixinterface.cpp | 17 +++++++++++++++-- src/coreclr/src/vm/ceemain.cpp | 4 ++++ src/coreclr/src/vm/dllimport.cpp | 18 ++++++++++++++++++ .../corehost/cli/hostpolicy/coreclr.cpp | 3 ++- .../corehost/cli/hostpolicy/coreclr.h | 1 + .../cli/hostpolicy/hostpolicy_context.cpp | 14 +++++++++++++- .../cli/hostpolicy/static/CMakeLists.txt | 2 ++ 7 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/dlls/mscoree/unixinterface.cpp b/src/coreclr/src/dlls/mscoree/unixinterface.cpp index def8772653126..e23ece9872244 100644 --- a/src/coreclr/src/dlls/mscoree/unixinterface.cpp +++ b/src/coreclr/src/dlls/mscoree/unixinterface.cpp @@ -27,6 +27,9 @@ typedef NewArrayHolder ConstWStringHolder; // Specifies whether coreclr is embedded or standalone extern bool g_coreclr_embedded; +// Specifies whether hostpolicy is embedded in executable or standalone +extern bool g_hostpolicy_embedded; + // Holder for array of wide strings class ConstWStringArrayHolder : public NewArrayHolder { @@ -116,7 +119,8 @@ static void ConvertConfigPropertiesToUnicode( int propertyCount, LPCWSTR** propertyKeysWRef, LPCWSTR** propertyValuesWRef, - BundleProbe** bundleProbe) + BundleProbe** bundleProbe, + bool* hostPolicyEmbedded) { LPCWSTR* propertyKeysW = new (nothrow) LPCWSTR[propertyCount]; ASSERTE_ALL_BUILDS(propertyKeysW != nullptr); @@ -135,6 +139,11 @@ static void ConvertConfigPropertiesToUnicode( // is passed in as the value of "BUNDLE_PROBE" property (encoded as a string). *bundleProbe = (BundleProbe*)_wcstoui64(propertyValuesW[propertyIndex], nullptr, 0); } + else if (strcmp(propertyKeys[propertyIndex], "HOSTPOLICY_EMBEDDED") == 0) + { + // The HOSTPOLICY_EMBEDDED property indicates if the executable has hostpolicy statically linked in + *hostPolicyEmbedded = (wcscmp(propertyValuesW[propertyIndex], W("true")) == 0); + } } *propertyKeysWRef = propertyKeysW; @@ -177,6 +186,7 @@ int coreclr_initialize( LPCWSTR* propertyKeysW; LPCWSTR* propertyValuesW; BundleProbe* bundleProbe = nullptr; + bool hostPolicyEmbedded = false; ConvertConfigPropertiesToUnicode( propertyKeys, @@ -184,7 +194,8 @@ int coreclr_initialize( propertyCount, &propertyKeysW, &propertyValuesW, - &bundleProbe); + &bundleProbe, + &hostPolicyEmbedded); #ifdef TARGET_UNIX DWORD error = PAL_InitializeCoreCLR(exePath, g_coreclr_embedded); @@ -198,6 +209,8 @@ int coreclr_initialize( } #endif + g_hostpolicy_embedded = hostPolicyEmbedded; + ReleaseHolder host; hr = CorHost2::CreateObject(IID_ICLRRuntimeHost4, (void**)&host); diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index 4da222caca083..962ba0d2298ac 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -240,10 +240,14 @@ extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface); #endif // !CROSSGEN_COMPILE // g_coreclr_embedded indicates that coreclr is linked directly into the program +// g_hostpolicy_embedded indicates that the hostpolicy library is linked directly into the executable +// Note: that it can happen that the hostpolicy is embedded but coreclr isn't (on Windows singlefilehost is built that way) #ifdef CORECLR_EMBEDDED bool g_coreclr_embedded = true; +bool g_hostpolicy_embedded = true; // We always embed hostpolicy if coreclr is also embedded #else bool g_coreclr_embedded = false; +bool g_hostpolicy_embedded = false; // In this case the value may come from a runtime property and may change #endif // Remember how the last startup of EE went. diff --git a/src/coreclr/src/vm/dllimport.cpp b/src/coreclr/src/vm/dllimport.cpp index 1802705362adf..9a99718582fde 100644 --- a/src/coreclr/src/vm/dllimport.cpp +++ b/src/coreclr/src/vm/dllimport.cpp @@ -54,6 +54,9 @@ using namespace clr::fs; // Specifies whether coreclr is embedded or standalone extern bool g_coreclr_embedded; +// Specifies whether hostpolicy is embedded in executable or standalone +extern bool g_hostpolicy_embedded; + // remove when we get an updated SDK #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 @@ -6331,6 +6334,21 @@ namespace } #endif + if (g_hostpolicy_embedded) + { +#ifdef TARGET_WINDOWS + if (wcscmp(wszLibName, W("hostpolicy.dll")) == 0) + { + return WszGetModuleHandle(NULL); + } +#else + if (wcscmp(wszLibName, W("libhostpolicy")) == 0) + { + return PAL_LoadLibraryDirect(NULL); + } +#endif + } + AppDomain* pDomain = GetAppDomain(); DWORD loadWithAlteredPathFlags = GetLoadWithAlteredSearchPathFlag(); bool libNameIsRelativePath = Path::IsRelative(wszLibName); diff --git a/src/installer/corehost/cli/hostpolicy/coreclr.cpp b/src/installer/corehost/cli/hostpolicy/coreclr.cpp index a54d04e8714fc..d9564ac8fa676 100644 --- a/src/installer/corehost/cli/hostpolicy/coreclr.cpp +++ b/src/installer/corehost/cli/hostpolicy/coreclr.cpp @@ -147,7 +147,8 @@ namespace _X("APP_PATHS"), _X("APP_NI_PATHS"), _X("RUNTIME_IDENTIFIER"), - _X("BUNDLE_PROBE") + _X("BUNDLE_PROBE"), + _X("HOSTPOLICY_EMBEDDED") }; static_assert((sizeof(PropertyNameMapping) / sizeof(*PropertyNameMapping)) == static_cast(common_property::Last), "Invalid property count"); diff --git a/src/installer/corehost/cli/hostpolicy/coreclr.h b/src/installer/corehost/cli/hostpolicy/coreclr.h index 9567fb9cab724..c086ba56e10b2 100644 --- a/src/installer/corehost/cli/hostpolicy/coreclr.h +++ b/src/installer/corehost/cli/hostpolicy/coreclr.h @@ -66,6 +66,7 @@ enum class common_property AppNIPaths, RuntimeIdentifier, BundleProbe, + HostPolicyEmbedded, // Sentinel value - new values should be defined above Last }; diff --git a/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp b/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp index 05c61bb780646..f7daa5d845870 100644 --- a/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp +++ b/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp @@ -231,8 +231,20 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a pal::stringstream_t ptr_stream; ptr_stream << "0x" << std::hex << (size_t)(&bundle_probe); - coreclr_properties.add(common_property::BundleProbe, ptr_stream.str().c_str()); + if (!coreclr_properties.add(common_property::BundleProbe, ptr_stream.str().c_str())) + { + log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks)); + return StatusCode::LibHostDuplicateProperty; + } + } + +#if defined(HOSTPOLICY_EMBEDDED) + if (!coreclr_properties.add(common_property::HostPolicyEmbedded, _X("true"))) + { + log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks)); + return StatusCode::LibHostDuplicateProperty; } +#endif return StatusCode::Success; } diff --git a/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt index 3ee012f475dd5..fcf95656f5fb1 100644 --- a/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt +++ b/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt @@ -46,3 +46,5 @@ set(HEADERS set(SKIP_VERSIONING 1) set(BUILD_OBJECT_LIBRARY 1) include(../../lib_static.cmake) + +add_definitions(-DHOSTPOLICY_EMBEDDED)