From d9570d9d901308999477df894e89637674aca1fc Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 4 Jun 2019 15:33:46 -0700 Subject: [PATCH 1/2] Export unmangled name for get_hostfxr_path on nethost --- src/corehost/cli/nethost/nethost.cpp | 3 ++ .../cli/test/nativehost/nativehost.cpp | 49 ++++++++++++++--- .../NativeHosting/Nethost.cs | 54 ++++++++++++------- 3 files changed, 80 insertions(+), 26 deletions(-) diff --git a/src/corehost/cli/nethost/nethost.cpp b/src/corehost/cli/nethost/nethost.cpp index 351d49335d..b66aab5b0b 100644 --- a/src/corehost/cli/nethost/nethost.cpp +++ b/src/corehost/cli/nethost/nethost.cpp @@ -18,6 +18,9 @@ namespace } } +#if defined(_WIN32) && defined(_TARGET_X86_) + #pragma comment(linker, "/export:get_hostfxr_path=_get_hostfxr_path@12") +#endif NETHOST_API int NETHOST_CALLTYPE get_hostfxr_path( char_t * buffer, size_t * buffer_size, diff --git a/src/corehost/cli/test/nativehost/nativehost.cpp b/src/corehost/cli/test/nativehost/nativehost.cpp index dec19ad991..5b0b39ecc6 100644 --- a/src/corehost/cli/test/nativehost/nativehost.cpp +++ b/src/corehost/cli/test/nativehost/nativehost.cpp @@ -9,6 +9,7 @@ #include "comhost_test.h" #include #include "host_context_test.h" +#include namespace { @@ -35,14 +36,18 @@ int main(const int argc, const pal::char_t *argv[]) const pal::char_t *command = argv[1]; if (pal::strcmp(command, _X("get_hostfxr_path")) == 0) { - // args: ... [] [] - const pal::char_t *assembly_path = nullptr; + // args: ... [] [] [] + bool explicit_load = false; if (argc >= 3) - assembly_path = argv[2]; + explicit_load = pal::strcmp(pal::to_lower(pal::string_t{argv[2]}).c_str(), _X("true")) == 0; + const pal::char_t *assembly_path = nullptr; if (argc >= 4) + assembly_path = argv[3]; + + if (argc >= 5) { - pal::string_t to_load = argv[3]; + pal::string_t to_load = argv[4]; pal::dll_t fxr; if (!pal::load_library(&to_load, &fxr)) { @@ -51,13 +56,45 @@ int main(const int argc, const pal::char_t *argv[]) } } + decltype(&get_hostfxr_path) get_hostfxr_path_fn; + if (explicit_load) + { + pal::string_t nethost_path; + if (!pal::get_own_executable_path(&nethost_path) || !pal::realpath(&nethost_path)) + { + std::cout << "Failed to get path to current executable" << std::endl; + return EXIT_FAILURE; + } + + nethost_path = get_directory(nethost_path); + nethost_path.append(MAKE_LIBNAME("nethost")); + + pal::dll_t nethost; + if (!pal::load_library(&nethost_path, &nethost)) + { + std::cout << "Failed to load library: " << tostr(nethost_path).data() << std::endl; + return EXIT_FAILURE; + } + + get_hostfxr_path_fn = (decltype(get_hostfxr_path_fn))pal::get_symbol(nethost, "get_hostfxr_path"); + if (get_hostfxr_path_fn == nullptr) + { + std::cout << "Failed to get get_hostfxr_path export from nethost" << std::endl; + return EXIT_FAILURE; + } + } + else + { + get_hostfxr_path_fn = get_hostfxr_path; + } + pal::string_t fxr_path; size_t len = fxr_path.size(); - int res = get_hostfxr_path(nullptr, &len, assembly_path); + int res = get_hostfxr_path_fn(nullptr, &len, assembly_path); if (static_cast(res) == StatusCode::HostApiBufferTooSmall) { fxr_path.resize(len); - res = get_hostfxr_path(&fxr_path[0], &len, assembly_path); + res = get_hostfxr_path_fn(&fxr_path[0], &len, assembly_path); } if (static_cast(res) == StatusCode::Success) diff --git a/src/test/HostActivationTests/NativeHosting/Nethost.cs b/src/test/HostActivationTests/NativeHosting/Nethost.cs index bd27320a3a..8a59ccd76f 100644 --- a/src/test/HostActivationTests/NativeHosting/Nethost.cs +++ b/src/test/HostActivationTests/NativeHosting/Nethost.cs @@ -23,14 +23,18 @@ public Nethost(SharedTestState sharedTestState) } [Theory] - [InlineData(false, true)] - [InlineData(false, false)] - [InlineData(true, true)] - [InlineData(true, false)] - public void GetHostFxrPath_DotNetRootEnvironment(bool useAssemblyPath, bool isValid) + [InlineData(true, false, true)] + [InlineData(true, false, false)] + [InlineData(true, true, true)] + [InlineData(true, true, false)] + [InlineData(false, false, true)] + [InlineData(false, false, false)] + [InlineData(false, true, true)] + [InlineData(false, true, false)] + public void GetHostFxrPath_DotNetRootEnvironment(bool explicitLoad, bool useAssemblyPath, bool isValid) { string dotNetRoot = isValid ? Path.Combine(sharedState.ValidInstallRoot, "dotnet") : sharedState.InvalidInstallRoot; - CommandResult result = Command.Create(sharedState.NativeHostPath, $"{GetHostFxrPath} {(useAssemblyPath ? sharedState.TestAssemblyPath : string.Empty)}") + CommandResult result = Command.Create(sharedState.NativeHostPath, $"{GetHostFxrPath} {explicitLoad} {(useAssemblyPath ? sharedState.TestAssemblyPath : string.Empty)}") .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable("COREHOST_TRACE", "1") @@ -55,15 +59,23 @@ public void GetHostFxrPath_DotNetRootEnvironment(bool useAssemblyPath, bool isVa } [Theory] - [InlineData(false, true, false)] - [InlineData(false, true, true)] - [InlineData(false, false, false)] - [InlineData(false, false, true)] - [InlineData(true, true, false)] - [InlineData(true, true, true)] - [InlineData(true, false, false)] - [InlineData(true, false, true)] - public void GetHostFxrPath_GlobalInstallation(bool useAssemblyPath, bool useRegisteredLocation, bool isValid) + [InlineData(true, false, true, false)] + [InlineData(true, false, true, true)] + [InlineData(true, false, false, false)] + [InlineData(true, false, false, true)] + [InlineData(true, true, true, false)] + [InlineData(true, true, true, true)] + [InlineData(true, true, false, false)] + [InlineData(true, true, false, true)] + [InlineData(false, false, true, false)] + [InlineData(false, false, true, true)] + [InlineData(false, false, false, false)] + [InlineData(false, false, false, true)] + [InlineData(false, true, true, false)] + [InlineData(false, true, true, true)] + [InlineData(false, true, false, false)] + [InlineData(false, true, false, true)] + public void GetHostFxrPath_GlobalInstallation(bool explicitLoad, bool useAssemblyPath, bool useRegisteredLocation, bool isValid) { // Overide the registry key for self-registered global installs. // If using the registered location, set the install location value to the valid/invalid root. @@ -78,7 +90,7 @@ public void GetHostFxrPath_GlobalInstallation(bool useAssemblyPath, bool useRegi registeredInstallLocationOverride.SetInstallLocation(installLocation, sharedState.RepoDirectories.BuildArchitecture); } - result = Command.Create(sharedState.NativeHostPath, $"{GetHostFxrPath} {(useAssemblyPath ? sharedState.TestAssemblyPath : string.Empty)}") + result = Command.Create(sharedState.NativeHostPath, $"{GetHostFxrPath} {explicitLoad} {(useAssemblyPath ? sharedState.TestAssemblyPath : string.Empty)}") .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable("COREHOST_TRACE", "1") @@ -105,8 +117,10 @@ public void GetHostFxrPath_GlobalInstallation(bool useAssemblyPath, bool useRegi } } - [Fact] - public void GetHostFxrPath_WithAssemblyPath_AppLocalFxr() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetHostFxrPath_WithAssemblyPath_AppLocalFxr(bool explicitLoad) { string appLocalFxrDir = Path.Combine(sharedState.BaseDirectory, "appLocalFxr"); Directory.CreateDirectory(appLocalFxrDir); @@ -115,7 +129,7 @@ public void GetHostFxrPath_WithAssemblyPath_AppLocalFxr() File.WriteAllText(assemblyPath, string.Empty); File.WriteAllText(hostFxrPath, string.Empty); - Command.Create(sharedState.NativeHostPath, $"{GetHostFxrPath} {assemblyPath}") + Command.Create(sharedState.NativeHostPath, $"{GetHostFxrPath} {explicitLoad} {assemblyPath}") .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable("COREHOST_TRACE", "1") @@ -127,7 +141,7 @@ public void GetHostFxrPath_WithAssemblyPath_AppLocalFxr() [Fact] public void GetHostFxrPath_HostFxrAlreadyLoaded() { - Command.Create(sharedState.NativeHostPath, $"{GetHostFxrPath} {sharedState.TestAssemblyPath} {sharedState.ProductHostFxrPath}") + Command.Create(sharedState.NativeHostPath, $"{GetHostFxrPath} false {sharedState.TestAssemblyPath} {sharedState.ProductHostFxrPath}") .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable("COREHOST_TRACE", "1") From a1532c08acf9a944a7522a9cf5116ff0b1d2221c Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Wed, 5 Jun 2019 10:57:39 -0700 Subject: [PATCH 2/2] Use .def file for exports --- src/corehost/cli/nethost/CMakeLists.txt | 5 +++++ src/corehost/cli/nethost/Exports.def | 2 ++ src/corehost/cli/nethost/nethost.cpp | 3 --- 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 src/corehost/cli/nethost/Exports.def diff --git a/src/corehost/cli/nethost/CMakeLists.txt b/src/corehost/cli/nethost/CMakeLists.txt index 8528cf3cb3..b56650bfac 100644 --- a/src/corehost/cli/nethost/CMakeLists.txt +++ b/src/corehost/cli/nethost/CMakeLists.txt @@ -17,6 +17,11 @@ set(SOURCES ../fxr/fx_ver.cpp ) +if(WIN32) + list(APPEND SOURCES + Exports.def) +endif() + include(../lib.cmake) add_definitions(-DFEATURE_LIBHOST=1) diff --git a/src/corehost/cli/nethost/Exports.def b/src/corehost/cli/nethost/Exports.def new file mode 100644 index 0000000000..d1cf53157a --- /dev/null +++ b/src/corehost/cli/nethost/Exports.def @@ -0,0 +1,2 @@ +EXPORTS + get_hostfxr_path \ No newline at end of file diff --git a/src/corehost/cli/nethost/nethost.cpp b/src/corehost/cli/nethost/nethost.cpp index b66aab5b0b..351d49335d 100644 --- a/src/corehost/cli/nethost/nethost.cpp +++ b/src/corehost/cli/nethost/nethost.cpp @@ -18,9 +18,6 @@ namespace } } -#if defined(_WIN32) && defined(_TARGET_X86_) - #pragma comment(linker, "/export:get_hostfxr_path=_get_hostfxr_path@12") -#endif NETHOST_API int NETHOST_CALLTYPE get_hostfxr_path( char_t * buffer, size_t * buffer_size,