Share unix getexepath() definition via src/native (#44999)
authorAdeel Mujahid <3840695+am11@users.noreply.github.com>
Thu, 26 Nov 2020 12:24:13 +0000 (14:24 +0200)
committerGitHub <noreply@github.com>
Thu, 26 Nov 2020 12:24:13 +0000 (13:24 +0100)
* Share unix getexepath() definition via src/native

* Address CR feedback

* Remove duplicate property

* Inline variable with single usage

* Fix include path in tests

* Remove unixcoreruncommon static lib dependency

* Merge coreruncommon.{cpp,h} into corerun.cpp

* Include local headers before the first use

* Remove Unix case from (Win32 only) corerun

* Use realpath in getauxval case

* Delete obsolete comment

31 files changed:
eng/native/build-commons.sh
eng/native/configurepaths.cmake [new file with mode: 0644]
src/coreclr/CMakeLists.txt
src/coreclr/build-runtime.cmd
src/coreclr/build-runtime.sh
src/coreclr/src/hosts/CMakeLists.txt
src/coreclr/src/hosts/corerun/CMakeLists.txt
src/coreclr/src/hosts/unixcorerun/CMakeLists.txt
src/coreclr/src/hosts/unixcorerun/config.h.in [moved from src/coreclr/src/hosts/unixcoreruncommon/config.h.in with 100% similarity]
src/coreclr/src/hosts/unixcorerun/configure.cmake [moved from src/coreclr/src/hosts/unixcoreruncommon/configure.cmake with 100% similarity]
src/coreclr/src/hosts/unixcorerun/corerun.cpp
src/coreclr/src/hosts/unixcoreruncommon/CMakeLists.txt [deleted file]
src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp [deleted file]
src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.h [deleted file]
src/coreclr/src/pal/src/CMakeLists.txt
src/coreclr/src/pal/src/config.h.in
src/coreclr/src/pal/src/init/pal.cpp
src/installer/corehost/CMakeLists.txt
src/installer/corehost/build.cmd
src/installer/corehost/cli/hostmisc/config.h.in
src/installer/corehost/cli/hostmisc/configure.cmake
src/installer/corehost/cli/hostmisc/hostmisc.cmake
src/installer/corehost/cli/hostmisc/pal.unix.cpp
src/libraries/Native/Unix/CMakeLists.txt
src/libraries/Native/Unix/Common/pal_config.h.in
src/libraries/Native/Unix/System.Native/CMakeLists.txt
src/libraries/Native/Unix/System.Native/pal_process.c
src/libraries/Native/Unix/configure.cmake
src/native/common/getexepath.h [new file with mode: 0644]
src/tests/CMakeLists.txt
src/tests/build.cmd

index bf2863e..0b2caf9 100755 (executable)
@@ -146,9 +146,7 @@ EOF
             scan_build=scan-build
         fi
 
-        engNativeDir="$__RepoRootDir/eng/native"
-        cmakeArgs="-DCLR_ENG_NATIVE_DIR=\"$engNativeDir\" $cmakeArgs"
-        nextCommand="\"$engNativeDir/gen-buildsys.sh\" \"$cmakeDir\" \"$tryrunDir\" \"$intermediatesDir\" $platformArch $__Compiler \"$__CompilerMajorVersion\" \"$__CompilerMinorVersion\" $__BuildType \"$generator\" $scan_build $cmakeArgs"
+        nextCommand="\"$__RepoRootDir/eng/native/gen-buildsys.sh\" \"$cmakeDir\" \"$tryrunDir\" \"$intermediatesDir\" $platformArch $__Compiler \"$__CompilerMajorVersion\" \"$__CompilerMinorVersion\" $__BuildType \"$generator\" $scan_build $cmakeArgs"
         echo "Invoking $nextCommand"
         eval $nextCommand
 
diff --git a/eng/native/configurepaths.cmake b/eng/native/configurepaths.cmake
new file mode 100644 (file)
index 0000000..e19b95a
--- /dev/null
@@ -0,0 +1,7 @@
+get_filename_component(CLR_REPO_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../.. ABSOLUTE)
+set(CLR_ENG_NATIVE_DIR ${CMAKE_CURRENT_LIST_DIR})
+get_filename_component(CLR_SRC_NATIVE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../src/native ABSOLUTE)
+
+# TO_NATIVE_PATH so it uses backslashes in Windows to avoid getting error,
+# as CLR_SRC_NATIVE_DIR is used to specify source files.
+file (TO_NATIVE_PATH ${CLR_SRC_NATIVE_DIR} CLR_SRC_NATIVE_DIR)
index e6495e0..ddd5734 100644 (file)
@@ -8,6 +8,7 @@ endif()
 # Set the project name
 project(CoreCLR)
 
+include(../../eng/native/configurepaths.cmake)
 include(${CLR_ENG_NATIVE_DIR}/configurecompiler.cmake)
 
 if(MSVC)
index ca32712..dd14dce 100644 (file)
@@ -450,10 +450,10 @@ if %__BuildCrossArchNative% EQU 1 (
     set "__CMakeBinDir=!__CMakeBinDir:\=/!"
 
     if %__Ninja% EQU 1 (
-        set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" 
+        set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!"
     )
 
-    set __ExtraCmakeArgs=!__ExtraCmakeArgs! %__CMakeClrBuildSubsetArgs% "-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__TargetOS%" "-DCLR_CMAKE_PGO_INSTRUMENT=0" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=0" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" "-DCLR_REPO_ROOT_DIR=%__RepoRootDir%" %__CMakeArgs%
+    set __ExtraCmakeArgs=!__ExtraCmakeArgs! %__CMakeClrBuildSubsetArgs% "-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__TargetOS%" "-DCLR_CMAKE_PGO_INSTRUMENT=0" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=0" %__CMakeArgs%
     call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectDir%" "%__CrossCompIntermediatesDir%" %__VSVersion% %__CrossArch% !__ExtraCmakeArgs!
 
     if not !errorlevel! == 0 (
@@ -512,22 +512,22 @@ if %__BuildCrossArchNative% EQU 1 (
 
         if /i "%__CrossArch2%" == "x86" ( set __VCBuildArch=x86 )
         if /i "%__CrossArch2%" == "x64" ( set __VCBuildArch=x86_amd64 )
-        
+
         echo %__MsgPrefix%Using environment: "%__VCToolsRoot%\vcvarsall.bat" !__VCBuildArch!
         call                                 "%__VCToolsRoot%\vcvarsall.bat" !__VCBuildArch!
         @if defined _echo @echo on
-        
+
         if not exist "%__CrossComp2IntermediatesDir%" md "%__CrossComp2IntermediatesDir%"
         if defined __SkipConfigure goto SkipConfigureCrossBuild2
 
         set __CMakeBinDir="%__CrossComponent2BinDir%"
         set "__CMakeBinDir=!__CMakeBinDir:\=/!"
-        
+
         if %__Ninja% EQU 1 (
-            set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" 
+            set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!"
         )
 
-        set __ExtraCmakeArgs=!__ExtraCmakeArgs! %__CMakeClrBuildSubsetArgs% "-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__TargetOS%" "-DCLR_CMAKE_PGO_INSTRUMENT=0" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=0" "-DCMAKE_SYSTEM_VERSION=10.0" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" "-DCLR_REPO_ROOT_DIR=%__RepoRootDir%" %__CMakeArgs%
+        set __ExtraCmakeArgs=!__ExtraCmakeArgs! %__CMakeClrBuildSubsetArgs% "-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__TargetOS%" "-DCLR_CMAKE_PGO_INSTRUMENT=0" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=0" "-DCMAKE_SYSTEM_VERSION=10.0" %__CMakeArgs%
         call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectDir%" "%__CrossComp2IntermediatesDir%" %__VSVersion% %__CrossArch2% !__ExtraCmakeArgs!
 
         if not !errorlevel! == 0 (
@@ -620,10 +620,10 @@ if %__BuildNative% EQU 1 (
     echo %__MsgPrefix%Regenerating the Visual Studio solution
 
     if %__Ninja% EQU 1 (
-        set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" 
+        set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!"
     )
 
-    set __ExtraCmakeArgs=!__ExtraCmakeArgs! !___CrossBuildDefine! %__CMakeClrBuildSubsetArgs% "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" "-DCLR_REPO_ROOT_DIR=%__RepoRootDir%" %__CMakeArgs%
+    set __ExtraCmakeArgs=!__ExtraCmakeArgs! !___CrossBuildDefine! %__CMakeClrBuildSubsetArgs% "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%" %__CMakeArgs%
     call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectDir%" "%__IntermediatesDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs!
     if not !errorlevel! == 0 (
         echo %__ErrMsgPrefix%%__MsgPrefix%Error: failed to generate native component build project!
index a2e7313..91c0b44 100755 (executable)
@@ -246,7 +246,7 @@ check_prereqs
 restore_optdata
 
 # Build the coreclr (native) components.
-__CMakeArgs="-DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument -DCLR_CMAKE_OPTDATA_PATH=$__PgoOptDataPath -DCLR_CMAKE_PGO_OPTIMIZE=$__PgoOptimize -DCLR_REPO_ROOT_DIR=\"$__RepoRootDir\" $__CMakeArgs"
+__CMakeArgs="-DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument -DCLR_CMAKE_OPTDATA_PATH=$__PgoOptDataPath -DCLR_CMAKE_PGO_OPTIMIZE=$__PgoOptimize $__CMakeArgs"
 __CMakeArgs="-DCLR_CMAKE_BUILD_SUBSET_JIT=$__BuildJit -DCLR_CMAKE_BUILD_SUBSET_ALLJITS=$__BuildAllJits -DCLR_CMAKE_BUILD_SUBSET_RUNTIME=$__BuildRuntime $__CMakeArgs"
 __CMakeArgs="-DCLR_CMAKE_BUILD_TESTS=$__BuildPALTests $__CMakeArgs"
 
index 6cf6866..e7afb6d 100644 (file)
@@ -5,6 +5,5 @@ if(CLR_CMAKE_HOST_WIN32)
   add_subdirectory(coreshim)
 else(CLR_CMAKE_HOST_WIN32)
   add_definitions(-D_FILE_OFFSET_BITS=64)
-  add_subdirectory(unixcoreruncommon)
   add_subdirectory(unixcorerun)
 endif(CLR_CMAKE_HOST_WIN32)
index d8fb5ff..f149bb9 100644 (file)
@@ -1,38 +1,21 @@
 project(CoreRun)
 
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CoreRun_SOURCES corerun.cpp logger.cpp)
-set(CoreRun_RESOURCES native.rc)
-
 add_definitions(-DFX_VER_INTERNALNAME_STR=CoreRun.exe)
 
-if(CLR_CMAKE_HOST_UNIX)
-    # This does not compile on Linux yet
-    if(CAN_BE_COMPILED_ON_LINUX)
-        _add_executable(CoreRun
-          ${CoreRun_SOURCES}
-          ${CoreRun_RESOURCES}
-        )
-    endif(CAN_BE_COMPILED_ON_LINUX)
-
-else()
-    _add_executable(CoreRun
-      ${CoreRun_SOURCES}
-      ${CoreRun_RESOURCES}
-    )
-
-    target_link_libraries(CoreRun
-        utilcodestaticnohost
-        advapi32.lib
-        oleaut32.lib
-        uuid.lib
-        user32.lib
-        ${STATIC_MT_CRT_LIB}
-        ${STATIC_MT_VCRT_LIB}
-    )
-
-    # Can't compile on linux yet so only add for windows
-    install_clr(TARGETS CoreRun)
-
-endif(CLR_CMAKE_HOST_UNIX)
+_add_executable(CoreRun
+  corerun.cpp logger.cpp
+  native.rc
+)
+
+target_link_libraries(CoreRun
+    utilcodestaticnohost
+    advapi32.lib
+    oleaut32.lib
+    uuid.lib
+    user32.lib
+    ${STATIC_MT_CRT_LIB}
+    ${STATIC_MT_VCRT_LIB}
+)
+
+install_clr(TARGETS CoreRun)
index 53d9e52..9e768f9 100644 (file)
@@ -1,33 +1,17 @@
 project(unixcorerun)
 
-include_directories(../unixcoreruncommon)
+include_directories("${CLR_SRC_NATIVE_DIR}/common")
+include(configure.cmake)
 
-set(CORERUN_SOURCES
-    corerun.cpp
-)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
-_add_executable(corerun
-    ${CORERUN_SOURCES}
-)
+_add_executable(corerun corerun.cpp)
 
-# FreeBSD and NetBSD implement dlopen(3) in libc
-if(NOT CLR_CMAKE_TARGET_FREEBSD AND NOT CLR_CMAKE_TARGET_NETBSD)
-    target_link_libraries(corerun
-        dl
-    )
-endif(NOT CLR_CMAKE_TARGET_FREEBSD AND NOT CLR_CMAKE_TARGET_NETBSD)
-
-# Libc turns locks into no-ops if pthread was not loaded into process yet. Loading
-# pthread by the process executable ensures that all locks are initialized properly.
-target_link_libraries(corerun
-    unixcoreruncommon
-)
+target_link_libraries(corerun ${CMAKE_DL_LIBS})
 
 # Android implements pthread natively
 if(NOT CLR_CMAKE_TARGET_ANDROID)
-  target_link_libraries(corerun
-    pthread
-  )
+  target_link_libraries(corerun pthread)
 endif()
 
 install_clr(TARGETS corerun)
index c96ec8b..8e00aea 100644 (file)
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-#include <coreruncommon.h>
+#include <cstdlib>
+#include <cstring>
+#include <assert.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <limits.h>
+#include <set>
 #include <string>
 #include <string.h>
 #include <sys/stat.h>
+#include "coreclrhost.h"
+#include <unistd.h>
+#ifndef SUCCEEDED
+#define SUCCEEDED(Status) ((Status) >= 0)
+#endif // !SUCCEEDED
+
+#include <config.h>
+#include <getexepath.h>
+
+#if !HAVE_DIRENT_D_TYPE
+#define DT_UNKNOWN 0
+#define DT_DIR 4
+#define DT_REG 8
+#define DT_LNK 10
+#endif
+
+// Name of the environment variable controlling server GC.
+// If set to 1, server GC is enabled on startup. If 0, server GC is
+// disabled. Server GC is off by default.
+static const char* serverGcVar = "COMPlus_gcServer";
+
+// Name of environment variable to control "System.Globalization.Invariant"
+// Set to 1 for Globalization Invariant mode to be true. Default is false.
+static const char* globalizationInvariantVar = "CORECLR_GLOBAL_INVARIANT";
+
+bool GetAbsolutePath(const char* path, std::string& absolutePath)
+{
+    bool result = false;
+
+    char realPath[PATH_MAX];
+    if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
+    {
+        absolutePath.assign(realPath);
+        // realpath should return canonicalized path without the trailing slash
+        assert(absolutePath.back() != '/');
+
+        result = true;
+    }
+
+    return result;
+}
+
+bool GetDirectory(const char* absolutePath, std::string& directory)
+{
+    directory.assign(absolutePath);
+    size_t lastSlash = directory.rfind('/');
+    if (lastSlash != std::string::npos)
+    {
+        directory.erase(lastSlash);
+        return true;
+    }
+
+    return false;
+}
+
+bool GetClrFilesAbsolutePath(const char* currentExePath, const char* clrFilesPath, std::string& clrFilesAbsolutePath)
+{
+    std::string clrFilesRelativePath;
+    const char* clrFilesPathLocal = clrFilesPath;
+    if (clrFilesPathLocal == nullptr)
+    {
+        // There was no CLR files path specified, use the folder of the corerun/coreconsole
+        if (!GetDirectory(currentExePath, clrFilesRelativePath))
+        {
+            perror("Failed to get directory from argv[0]");
+            return false;
+        }
+
+        clrFilesPathLocal = clrFilesRelativePath.c_str();
+
+        // TODO: consider using an env variable (if defined) as a fall-back.
+        // The windows version of the corerun uses core_root env variable
+    }
+
+    if (!GetAbsolutePath(clrFilesPathLocal, clrFilesAbsolutePath))
+    {
+        perror("Failed to convert CLR files path to absolute path");
+        return false;
+    }
+
+    return true;
+}
+
+void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList)
+{
+    const char * const tpaExtensions[] = {
+                ".ni.dll",      // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
+                ".dll",
+                ".ni.exe",
+                ".exe",
+                };
+
+    DIR* dir = opendir(directory);
+    if (dir == nullptr)
+    {
+        return;
+    }
+
+    std::set<std::string> addedAssemblies;
+
+    // Walk the directory for each extension separately so that we first get files with .ni.dll extension,
+    // then files with .dll extension, etc.
+    for (size_t extIndex = 0; extIndex < sizeof(tpaExtensions) / sizeof(tpaExtensions[0]); extIndex++)
+    {
+        const char* ext = tpaExtensions[extIndex];
+        int extLength = strlen(ext);
+
+        struct dirent* entry;
+
+        // For all entries in the directory
+        while ((entry = readdir(dir)) != nullptr)
+        {
+#if HAVE_DIRENT_D_TYPE
+            int dirEntryType = entry->d_type;
+#else
+            int dirEntryType = DT_UNKNOWN;
+#endif
+
+            // We are interested in files only
+            switch (dirEntryType)
+            {
+            case DT_REG:
+                break;
+
+            // Handle symlinks and file systems that do not support d_type
+            case DT_LNK:
+            case DT_UNKNOWN:
+                {
+                    std::string fullFilename;
+
+                    fullFilename.append(directory);
+                    fullFilename.append("/");
+                    fullFilename.append(entry->d_name);
+
+                    struct stat sb;
+                    if (stat(fullFilename.c_str(), &sb) == -1)
+                    {
+                        continue;
+                    }
+
+                    if (!S_ISREG(sb.st_mode))
+                    {
+                        continue;
+                    }
+                }
+                break;
+
+            default:
+                continue;
+            }
+
+            std::string filename(entry->d_name);
+
+            // Check if the extension matches the one we are looking for
+            int extPos = filename.length() - extLength;
+            if ((extPos <= 0) || (filename.compare(extPos, extLength, ext) != 0))
+            {
+                continue;
+            }
+
+            std::string filenameWithoutExt(filename.substr(0, extPos));
+
+            // Make sure if we have an assembly with multiple extensions present,
+            // we insert only one version of it.
+            if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end())
+            {
+                addedAssemblies.insert(filenameWithoutExt);
+
+                tpaList.append(directory);
+                tpaList.append("/");
+                tpaList.append(filename);
+                tpaList.append(":");
+            }
+        }
+
+        // Rewind the directory stream to be able to iterate over it for the next extension
+        rewinddir(dir);
+    }
+
+    closedir(dir);
+}
+
+const char* GetEnvValueBoolean(const char* envVariable)
+{
+    const char* envValue = std::getenv(envVariable);
+    if (envValue == nullptr)
+    {
+        envValue = "0";
+    }
+    // CoreCLR expects strings "true" and "false" instead of "1" and "0".
+    return (std::strcmp(envValue, "1") == 0 || strcasecmp(envValue, "true") == 0) ? "true" : "false";
+}
+
+static void *TryLoadHostPolicy(const char *hostPolicyPath)
+{
+#if defined(__APPLE__)
+    static const char LibrarySuffix[] = ".dylib";
+#else // Various Linux-related OS-es
+    static const char LibrarySuffix[] = ".so";
+#endif
+
+    std::string hostPolicyCompletePath(hostPolicyPath);
+    hostPolicyCompletePath.append(LibrarySuffix);
+
+    void *libraryPtr = dlopen(hostPolicyCompletePath.c_str(), RTLD_LAZY);
+    if (libraryPtr == nullptr)
+    {
+        fprintf(stderr, "Failed to load mock hostpolicy at path '%s'. Error: %s", hostPolicyCompletePath.c_str(), dlerror());
+    }
+
+    return libraryPtr;
+}
+
+int ExecuteManagedAssembly(
+            const char* currentExeAbsolutePath,
+            const char* clrFilesAbsolutePath,
+            const char* managedAssemblyAbsolutePath,
+            int managedAssemblyArgc,
+            const char** managedAssemblyArgv)
+{
+    // Indicates failure
+    int exitCode = -1;
+
+#ifdef HOST_ARM
+    // libunwind library is used to unwind stack frame, but libunwind for ARM
+    // does not support ARM vfpv3/NEON registers in DWARF format correctly.
+    // Therefore let's disable stack unwinding using DWARF information
+    // See https://github.com/dotnet/runtime/issues/6479
+    //
+    // libunwind use following methods to unwind stack frame.
+    // UNW_ARM_METHOD_ALL          0xFF
+    // UNW_ARM_METHOD_DWARF        0x01
+    // UNW_ARM_METHOD_FRAME        0x02
+    // UNW_ARM_METHOD_EXIDX        0x04
+    putenv(const_cast<char *>("UNW_ARM_UNWIND_METHOD=6"));
+#endif // HOST_ARM
+
+#if defined(__APPLE__)
+    static const char* const coreClrDll = "libcoreclr.dylib";
+#else
+    static const char* const coreClrDll = "libcoreclr.so";
+#endif
+
+    std::string coreClrDllPath(clrFilesAbsolutePath);
+    coreClrDllPath.append("/");
+    coreClrDllPath.append(coreClrDll);
+
+    if (coreClrDllPath.length() >= PATH_MAX)
+    {
+        fprintf(stderr, "Absolute path to libcoreclr.so too long\n");
+        return -1;
+    }
+
+    // Get just the path component of the managed assembly path
+    std::string appPath;
+    GetDirectory(managedAssemblyAbsolutePath, appPath);
+
+    std::string tpaList;
+    // Construct native search directory paths
+    std::string nativeDllSearchDirs(appPath);
+    char *coreLibraries = getenv("CORE_LIBRARIES");
+    if (coreLibraries)
+    {
+        nativeDllSearchDirs.append(":");
+        nativeDllSearchDirs.append(coreLibraries);
+        if (std::strcmp(coreLibraries, clrFilesAbsolutePath) != 0)
+        {
+            AddFilesFromDirectoryToTpaList(coreLibraries, tpaList);
+        }
+    }
+    nativeDllSearchDirs.append(":");
+    nativeDllSearchDirs.append(clrFilesAbsolutePath);
+
+    void* hostpolicyLib = nullptr;
+    char* mockHostpolicyPath = getenv("MOCK_HOSTPOLICY");
+    if (mockHostpolicyPath)
+    {
+        hostpolicyLib = TryLoadHostPolicy(mockHostpolicyPath);
+        if (hostpolicyLib == nullptr)
+        {
+            return -1;
+        }
+    }
+
+    AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList);
+
+    void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL);
+    if (coreclrLib != nullptr)
+    {
+        coreclr_initialize_ptr initializeCoreCLR = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize");
+        coreclr_execute_assembly_ptr executeAssembly = (coreclr_execute_assembly_ptr)dlsym(coreclrLib, "coreclr_execute_assembly");
+        coreclr_shutdown_2_ptr shutdownCoreCLR = (coreclr_shutdown_2_ptr)dlsym(coreclrLib, "coreclr_shutdown_2");
+
+        if (initializeCoreCLR == nullptr)
+        {
+            fprintf(stderr, "Function coreclr_initialize not found in the libcoreclr.so\n");
+        }
+        else if (executeAssembly == nullptr)
+        {
+            fprintf(stderr, "Function coreclr_execute_assembly not found in the libcoreclr.so\n");
+        }
+        else if (shutdownCoreCLR == nullptr)
+        {
+            fprintf(stderr, "Function coreclr_shutdown_2 not found in the libcoreclr.so\n");
+        }
+        else
+        {
+            // Check whether we are enabling server GC (off by default)
+            const char* useServerGc = GetEnvValueBoolean(serverGcVar);
+
+            // Check Globalization Invariant mode (false by default)
+            const char* globalizationInvariant = GetEnvValueBoolean(globalizationInvariantVar);
+
+            // Allowed property names:
+            // APPBASE
+            // - The base path of the application from which the exe and other assemblies will be loaded
+            //
+            // TRUSTED_PLATFORM_ASSEMBLIES
+            // - The list of complete paths to each of the fully trusted assemblies
+            //
+            // APP_PATHS
+            // - The list of paths which will be probed by the assembly loader
+            //
+            // APP_NI_PATHS
+            // - The list of additional paths that the assembly loader will probe for ngen images
+            //
+            // NATIVE_DLL_SEARCH_DIRECTORIES
+            // - The list of paths that will be probed for native DLLs called by PInvoke
+            //
+            const char *propertyKeys[] = {
+                "TRUSTED_PLATFORM_ASSEMBLIES",
+                "APP_PATHS",
+                "APP_NI_PATHS",
+                "NATIVE_DLL_SEARCH_DIRECTORIES",
+                "System.GC.Server",
+                "System.Globalization.Invariant",
+            };
+            const char *propertyValues[] = {
+                // TRUSTED_PLATFORM_ASSEMBLIES
+                tpaList.c_str(),
+                // APP_PATHS
+                appPath.c_str(),
+                // APP_NI_PATHS
+                appPath.c_str(),
+                // NATIVE_DLL_SEARCH_DIRECTORIES
+                nativeDllSearchDirs.c_str(),
+                // System.GC.Server
+                useServerGc,
+                // System.Globalization.Invariant
+                globalizationInvariant,
+            };
+
+            void* hostHandle;
+            unsigned int domainId;
+
+            int st = initializeCoreCLR(
+                        currentExeAbsolutePath,
+                        "unixcorerun",
+                        sizeof(propertyKeys) / sizeof(propertyKeys[0]),
+                        propertyKeys,
+                        propertyValues,
+                        &hostHandle,
+                        &domainId);
+
+            if (!SUCCEEDED(st))
+            {
+                fprintf(stderr, "coreclr_initialize failed - status: 0x%08x\n", st);
+                exitCode = -1;
+            }
+            else
+            {
+                st = executeAssembly(
+                        hostHandle,
+                        domainId,
+                        managedAssemblyArgc,
+                        managedAssemblyArgv,
+                        managedAssemblyAbsolutePath,
+                        (unsigned int*)&exitCode);
+
+                if (!SUCCEEDED(st))
+                {
+                    fprintf(stderr, "coreclr_execute_assembly failed - status: 0x%08x\n", st);
+                    exitCode = -1;
+                }
+
+                int latchedExitCode = 0;
+                st = shutdownCoreCLR(hostHandle, domainId, &latchedExitCode);
+                if (!SUCCEEDED(st))
+                {
+                    fprintf(stderr, "coreclr_shutdown failed - status: 0x%08x\n", st);
+                    exitCode = -1;
+                }
+
+                if (exitCode != -1)
+                {
+                    exitCode = latchedExitCode;
+                }
+            }
+        }
+    }
+    else
+    {
+        const char* error = dlerror();
+        fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error);
+    }
+
+    if (hostpolicyLib)
+    {
+        if(dlclose(hostpolicyLib) != 0)
+        {
+            fprintf(stderr, "Warning - dlclose of mock hostpolicy failed.\n");
+        }
+    }
+
+    return exitCode;
+}
 
 // Display the command line options
 void DisplayUsage()
@@ -125,13 +547,16 @@ int main(const int argc, const char* argv[])
     }
 
     // Make sure we have a full path for argv[0].
-    std::string argv0AbsolutePath;
-    if (!GetEntrypointExecutableAbsolutePath(argv0AbsolutePath))
+    char* path = getexepath();
+    if (!path)
     {
         perror("Could not get full path");
         return -1;
     }
 
+    std::string argv0AbsolutePath(path);
+    free(path);
+
     std::string clrFilesAbsolutePath;
     if(!GetClrFilesAbsolutePath(argv0AbsolutePath.c_str(), clrFilesPath, clrFilesAbsolutePath))
     {
diff --git a/src/coreclr/src/hosts/unixcoreruncommon/CMakeLists.txt b/src/coreclr/src/hosts/unixcoreruncommon/CMakeLists.txt
deleted file mode 100644 (file)
index 7e6930f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-project(unixcoreruncommon)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-include(configure.cmake)
-
-_add_library(unixcoreruncommon
-    STATIC
-    coreruncommon.cpp
-)
-
-if(CLR_CMAKE_HOST_LINUX)
-  target_link_libraries(unixcoreruncommon dl)
-endif(CLR_CMAKE_HOST_LINUX)
diff --git a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp
deleted file mode 100644 (file)
index 5971175..0000000
+++ /dev/null
@@ -1,550 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-//
-// Code that is used by both the Unix corerun and coreconsole.
-//
-
-#include "config.h"
-
-#include <cstdlib>
-#include <cstring>
-#include <assert.h>
-#include <dirent.h>
-#include <dlfcn.h>
-#include <limits.h>
-#include <set>
-#include <string>
-#include <string.h>
-#include <sys/stat.h>
-#if defined(__FreeBSD__)
-#include <sys/types.h>
-#include <sys/param.h>
-#endif
-#if HAVE_GETAUXVAL
-#include <sys/auxv.h>
-#endif
-#if defined(HAVE_SYS_SYSCTL_H) || defined(__FreeBSD__)
-#include <sys/sysctl.h>
-#endif
-#include "coreruncommon.h"
-#include "coreclrhost.h"
-#include <unistd.h>
-#ifndef SUCCEEDED
-#define SUCCEEDED(Status) ((Status) >= 0)
-#endif // !SUCCEEDED
-
-#if !HAVE_DIRENT_D_TYPE
-#define DT_UNKNOWN 0
-#define DT_DIR 4
-#define DT_REG 8
-#define DT_LNK 10
-#endif
-
-// Name of the environment variable controlling server GC.
-// If set to 1, server GC is enabled on startup. If 0, server GC is
-// disabled. Server GC is off by default.
-static const char* serverGcVar = "COMPlus_gcServer";
-
-// Name of environment variable to control "System.Globalization.Invariant"
-// Set to 1 for Globalization Invariant mode to be true. Default is false.
-static const char* globalizationInvariantVar = "CORECLR_GLOBAL_INVARIANT";
-
-#if defined(__linux__)
-#define symlinkEntrypointExecutable "/proc/self/exe"
-#elif !defined(__APPLE__)
-#define symlinkEntrypointExecutable "/proc/curproc/exe"
-#endif
-
-bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable)
-{
-    bool result = false;
-
-    entrypointExecutable.clear();
-
-    // Get path to the executable for the current process using
-    // platform specific means.
-#if defined(__APPLE__)
-
-    // On Mac, we ask the OS for the absolute path to the entrypoint executable
-    uint32_t lenActualPath = 0;
-    if (_NSGetExecutablePath(nullptr, &lenActualPath) == -1)
-    {
-        // OSX has placed the actual path length in lenActualPath,
-        // so re-attempt the operation
-        std::string resizedPath(lenActualPath, '\0');
-        char *pResizedPath = const_cast<char *>(resizedPath.c_str());
-        if (_NSGetExecutablePath(pResizedPath, &lenActualPath) == 0)
-        {
-            entrypointExecutable.assign(pResizedPath);
-            result = true;
-        }
-    }
-#elif defined (__FreeBSD__)
-    static const int name[] = {
-        CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1
-    };
-    char path[PATH_MAX];
-    size_t len;
-
-    len = sizeof(path);
-    if (sysctl(name, 4, path, &len, nullptr, 0) == 0)
-    {
-        entrypointExecutable.assign(path);
-        result = true;
-    }
-    else
-    {
-        // ENOMEM
-        result = false;
-    }
-#elif defined(__NetBSD__) && defined(KERN_PROC_PATHNAME)
-    static const int name[] = {
-        CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
-    };
-    char path[MAXPATHLEN];
-    size_t len;
-
-    len = sizeof(path);
-    if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1)
-    {
-        entrypointExecutable.assign(path);
-        result = true;
-    }
-    else
-    {
-        result = false;
-    }
-#elif defined(__sun)
-    const char *path;
-    if ((path = getexecname()) == NULL)
-    {
-        result = false;
-    }
-    else if (*path != '/')
-    {
-        char *cwd;
-        if ((cwd = getcwd(NULL, PATH_MAX)) == NULL)
-        {
-            result = false;
-        }
-        else
-        {
-            entrypointExecutable
-                .assign(cwd)
-                .append("/")
-                .append(path);
-            result = true;
-            free(cwd);
-        }
-    }
-    else
-    {
-        entrypointExecutable.assign(path);
-        result = true;
-    }
-#else
-
-#if HAVE_GETAUXVAL && defined(AT_EXECFN)
-    const char *execfn = (const char *)getauxval(AT_EXECFN);
-
-    if (execfn)
-    {
-        entrypointExecutable.assign(execfn);
-        result = true;
-    }
-    else
-#endif
-    // On other OSs, return the symlink that will be resolved by GetAbsolutePath
-    // to fetch the entrypoint EXE absolute path, inclusive of filename.
-    result = GetAbsolutePath(symlinkEntrypointExecutable, entrypointExecutable);
-#endif
-
-    return result;
-}
-
-bool GetAbsolutePath(const char* path, std::string& absolutePath)
-{
-    bool result = false;
-
-    char realPath[PATH_MAX];
-    if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
-    {
-        absolutePath.assign(realPath);
-        // realpath should return canonicalized path without the trailing slash
-        assert(absolutePath.back() != '/');
-
-        result = true;
-    }
-
-    return result;
-}
-
-bool GetDirectory(const char* absolutePath, std::string& directory)
-{
-    directory.assign(absolutePath);
-    size_t lastSlash = directory.rfind('/');
-    if (lastSlash != std::string::npos)
-    {
-        directory.erase(lastSlash);
-        return true;
-    }
-
-    return false;
-}
-
-bool GetClrFilesAbsolutePath(const char* currentExePath, const char* clrFilesPath, std::string& clrFilesAbsolutePath)
-{
-    std::string clrFilesRelativePath;
-    const char* clrFilesPathLocal = clrFilesPath;
-    if (clrFilesPathLocal == nullptr)
-    {
-        // There was no CLR files path specified, use the folder of the corerun/coreconsole
-        if (!GetDirectory(currentExePath, clrFilesRelativePath))
-        {
-            perror("Failed to get directory from argv[0]");
-            return false;
-        }
-
-        clrFilesPathLocal = clrFilesRelativePath.c_str();
-
-        // TODO: consider using an env variable (if defined) as a fall-back.
-        // The windows version of the corerun uses core_root env variable
-    }
-
-    if (!GetAbsolutePath(clrFilesPathLocal, clrFilesAbsolutePath))
-    {
-        perror("Failed to convert CLR files path to absolute path");
-        return false;
-    }
-
-    return true;
-}
-
-void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList)
-{
-    const char * const tpaExtensions[] = {
-                ".ni.dll",      // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
-                ".dll",
-                ".ni.exe",
-                ".exe",
-                };
-
-    DIR* dir = opendir(directory);
-    if (dir == nullptr)
-    {
-        return;
-    }
-
-    std::set<std::string> addedAssemblies;
-
-    // Walk the directory for each extension separately so that we first get files with .ni.dll extension,
-    // then files with .dll extension, etc.
-    for (size_t extIndex = 0; extIndex < sizeof(tpaExtensions) / sizeof(tpaExtensions[0]); extIndex++)
-    {
-        const char* ext = tpaExtensions[extIndex];
-        int extLength = strlen(ext);
-
-        struct dirent* entry;
-
-        // For all entries in the directory
-        while ((entry = readdir(dir)) != nullptr)
-        {
-#if HAVE_DIRENT_D_TYPE
-            int dirEntryType = entry->d_type;
-#else
-            int dirEntryType = DT_UNKNOWN;
-#endif
-
-            // We are interested in files only
-            switch (dirEntryType)
-            {
-            case DT_REG:
-                break;
-
-            // Handle symlinks and file systems that do not support d_type
-            case DT_LNK:
-            case DT_UNKNOWN:
-                {
-                    std::string fullFilename;
-
-                    fullFilename.append(directory);
-                    fullFilename.append("/");
-                    fullFilename.append(entry->d_name);
-
-                    struct stat sb;
-                    if (stat(fullFilename.c_str(), &sb) == -1)
-                    {
-                        continue;
-                    }
-
-                    if (!S_ISREG(sb.st_mode))
-                    {
-                        continue;
-                    }
-                }
-                break;
-
-            default:
-                continue;
-            }
-
-            std::string filename(entry->d_name);
-
-            // Check if the extension matches the one we are looking for
-            int extPos = filename.length() - extLength;
-            if ((extPos <= 0) || (filename.compare(extPos, extLength, ext) != 0))
-            {
-                continue;
-            }
-
-            std::string filenameWithoutExt(filename.substr(0, extPos));
-
-            // Make sure if we have an assembly with multiple extensions present,
-            // we insert only one version of it.
-            if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end())
-            {
-                addedAssemblies.insert(filenameWithoutExt);
-
-                tpaList.append(directory);
-                tpaList.append("/");
-                tpaList.append(filename);
-                tpaList.append(":");
-            }
-        }
-
-        // Rewind the directory stream to be able to iterate over it for the next extension
-        rewinddir(dir);
-    }
-
-    closedir(dir);
-}
-
-const char* GetEnvValueBoolean(const char* envVariable)
-{
-    const char* envValue = std::getenv(envVariable);
-    if (envValue == nullptr)
-    {
-        envValue = "0";
-    }
-    // CoreCLR expects strings "true" and "false" instead of "1" and "0".
-    return (std::strcmp(envValue, "1") == 0 || strcasecmp(envValue, "true") == 0) ? "true" : "false";
-}
-
-static void *TryLoadHostPolicy(const char *hostPolicyPath)
-{
-#if defined(__APPLE__)
-    static const char LibrarySuffix[] = ".dylib";
-#else // Various Linux-related OS-es
-    static const char LibrarySuffix[] = ".so";
-#endif
-
-    std::string hostPolicyCompletePath(hostPolicyPath);
-    hostPolicyCompletePath.append(LibrarySuffix);
-
-    void *libraryPtr = dlopen(hostPolicyCompletePath.c_str(), RTLD_LAZY);
-    if (libraryPtr == nullptr)
-    {
-        fprintf(stderr, "Failed to load mock hostpolicy at path '%s'. Error: %s", hostPolicyCompletePath.c_str(), dlerror());
-    }
-
-    return libraryPtr;
-}
-
-int ExecuteManagedAssembly(
-            const char* currentExeAbsolutePath,
-            const char* clrFilesAbsolutePath,
-            const char* managedAssemblyAbsolutePath,
-            int managedAssemblyArgc,
-            const char** managedAssemblyArgv)
-{
-    // Indicates failure
-    int exitCode = -1;
-
-#ifdef HOST_ARM
-    // libunwind library is used to unwind stack frame, but libunwind for ARM
-    // does not support ARM vfpv3/NEON registers in DWARF format correctly.
-    // Therefore let's disable stack unwinding using DWARF information
-    // See https://github.com/dotnet/runtime/issues/6479
-    //
-    // libunwind use following methods to unwind stack frame.
-    // UNW_ARM_METHOD_ALL          0xFF
-    // UNW_ARM_METHOD_DWARF        0x01
-    // UNW_ARM_METHOD_FRAME        0x02
-    // UNW_ARM_METHOD_EXIDX        0x04
-    putenv(const_cast<char *>("UNW_ARM_UNWIND_METHOD=6"));
-#endif // HOST_ARM
-
-    std::string coreClrDllPath(clrFilesAbsolutePath);
-    coreClrDllPath.append("/");
-    coreClrDllPath.append(coreClrDll);
-
-    if (coreClrDllPath.length() >= PATH_MAX)
-    {
-        fprintf(stderr, "Absolute path to libcoreclr.so too long\n");
-        return -1;
-    }
-
-    // Get just the path component of the managed assembly path
-    std::string appPath;
-    GetDirectory(managedAssemblyAbsolutePath, appPath);
-
-    std::string tpaList;
-    // Construct native search directory paths
-    std::string nativeDllSearchDirs(appPath);
-    char *coreLibraries = getenv("CORE_LIBRARIES");
-    if (coreLibraries)
-    {
-        nativeDllSearchDirs.append(":");
-        nativeDllSearchDirs.append(coreLibraries);
-        if (std::strcmp(coreLibraries, clrFilesAbsolutePath) != 0)
-        {
-            AddFilesFromDirectoryToTpaList(coreLibraries, tpaList);
-        }
-    }
-    nativeDllSearchDirs.append(":");
-    nativeDllSearchDirs.append(clrFilesAbsolutePath);
-
-    void* hostpolicyLib = nullptr;
-    char* mockHostpolicyPath = getenv("MOCK_HOSTPOLICY");
-    if (mockHostpolicyPath)
-    {
-        hostpolicyLib = TryLoadHostPolicy(mockHostpolicyPath);
-        if (hostpolicyLib == nullptr)
-        {
-            return -1;
-        }
-    }
-
-    AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList);
-
-    void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL);
-    if (coreclrLib != nullptr)
-    {
-        coreclr_initialize_ptr initializeCoreCLR = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize");
-        coreclr_execute_assembly_ptr executeAssembly = (coreclr_execute_assembly_ptr)dlsym(coreclrLib, "coreclr_execute_assembly");
-        coreclr_shutdown_2_ptr shutdownCoreCLR = (coreclr_shutdown_2_ptr)dlsym(coreclrLib, "coreclr_shutdown_2");
-
-        if (initializeCoreCLR == nullptr)
-        {
-            fprintf(stderr, "Function coreclr_initialize not found in the libcoreclr.so\n");
-        }
-        else if (executeAssembly == nullptr)
-        {
-            fprintf(stderr, "Function coreclr_execute_assembly not found in the libcoreclr.so\n");
-        }
-        else if (shutdownCoreCLR == nullptr)
-        {
-            fprintf(stderr, "Function coreclr_shutdown_2 not found in the libcoreclr.so\n");
-        }
-        else
-        {
-            // Check whether we are enabling server GC (off by default)
-            const char* useServerGc = GetEnvValueBoolean(serverGcVar);
-
-            // Check Globalization Invariant mode (false by default)
-            const char* globalizationInvariant = GetEnvValueBoolean(globalizationInvariantVar);
-
-            // Allowed property names:
-            // APPBASE
-            // - The base path of the application from which the exe and other assemblies will be loaded
-            //
-            // TRUSTED_PLATFORM_ASSEMBLIES
-            // - The list of complete paths to each of the fully trusted assemblies
-            //
-            // APP_PATHS
-            // - The list of paths which will be probed by the assembly loader
-            //
-            // APP_NI_PATHS
-            // - The list of additional paths that the assembly loader will probe for ngen images
-            //
-            // NATIVE_DLL_SEARCH_DIRECTORIES
-            // - The list of paths that will be probed for native DLLs called by PInvoke
-            //
-            const char *propertyKeys[] = {
-                "TRUSTED_PLATFORM_ASSEMBLIES",
-                "APP_PATHS",
-                "APP_NI_PATHS",
-                "NATIVE_DLL_SEARCH_DIRECTORIES",
-                "System.GC.Server",
-                "System.Globalization.Invariant",
-            };
-            const char *propertyValues[] = {
-                // TRUSTED_PLATFORM_ASSEMBLIES
-                tpaList.c_str(),
-                // APP_PATHS
-                appPath.c_str(),
-                // APP_NI_PATHS
-                appPath.c_str(),
-                // NATIVE_DLL_SEARCH_DIRECTORIES
-                nativeDllSearchDirs.c_str(),
-                // System.GC.Server
-                useServerGc,
-                // System.Globalization.Invariant
-                globalizationInvariant,
-            };
-
-            void* hostHandle;
-            unsigned int domainId;
-
-            int st = initializeCoreCLR(
-                        currentExeAbsolutePath,
-                        "unixcorerun",
-                        sizeof(propertyKeys) / sizeof(propertyKeys[0]),
-                        propertyKeys,
-                        propertyValues,
-                        &hostHandle,
-                        &domainId);
-
-            if (!SUCCEEDED(st))
-            {
-                fprintf(stderr, "coreclr_initialize failed - status: 0x%08x\n", st);
-                exitCode = -1;
-            }
-            else
-            {
-                st = executeAssembly(
-                        hostHandle,
-                        domainId,
-                        managedAssemblyArgc,
-                        managedAssemblyArgv,
-                        managedAssemblyAbsolutePath,
-                        (unsigned int*)&exitCode);
-
-                if (!SUCCEEDED(st))
-                {
-                    fprintf(stderr, "coreclr_execute_assembly failed - status: 0x%08x\n", st);
-                    exitCode = -1;
-                }
-
-                int latchedExitCode = 0;
-                st = shutdownCoreCLR(hostHandle, domainId, &latchedExitCode);
-                if (!SUCCEEDED(st))
-                {
-                    fprintf(stderr, "coreclr_shutdown failed - status: 0x%08x\n", st);
-                    exitCode = -1;
-                }
-
-                if (exitCode != -1)
-                {
-                    exitCode = latchedExitCode;
-                }
-            }
-        }
-    }
-    else
-    {
-        const char* error = dlerror();
-        fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error);
-    }
-
-    if (hostpolicyLib)
-    {
-        if(dlclose(hostpolicyLib) != 0)
-        {
-            fprintf(stderr, "Warning - dlclose of mock hostpolicy failed.\n");
-        }
-    }
-
-    return exitCode;
-}
diff --git a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.h b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.h
deleted file mode 100644 (file)
index b6bc17b..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#include <string>
-
-// Get the path to entrypoint executable
-bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable);
-
-// Get absolute path from the specified path.
-// Return true in case of a success, false otherwise.
-bool GetAbsolutePath(const char* path, std::string& absolutePath);
-
-// Get directory of the specified path.
-// Return true in case of a success, false otherwise.
-bool GetDirectory(const char* absolutePath, std::string& directory);
-
-//
-// Get the absolute path to use to locate libcoreclr.so and the CLR assemblies are stored. If clrFilesPath is provided,
-// this function will return the absolute path to it. Otherwise, the directory of the current executable is used.
-//
-// Return true in case of a success, false otherwise.
-//
-bool GetClrFilesAbsolutePath(const char* currentExePath, const char* clrFilesPath, std::string& clrFilesAbsolutePath);
-
-// Add all *.dll, *.ni.dll, *.exe, and *.ni.exe files from the specified directory to the tpaList string.
-void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList);
-
-//
-// Execute the specified managed assembly.
-//
-// Parameters:
-//  currentExePath          - Path to the current executable
-//  clrFilesAbsolutePath    - Absolute path to the folder where the libcoreclr.so and CLR managed assemblies are stored
-//  managedAssemblyPath     - Path to the managed assembly to execute
-//  managedAssemblyArgc     - Number of arguments passed to the executed assembly
-//  managedAssemblyArgv     - Array of arguments passed to the executed assembly
-//
-// Returns:
-//  ExitCode of the assembly
-//
-int ExecuteManagedAssembly(
-            const char* currentExeAbsolutePath,
-            const char* clrFilesAbsolutePath,
-            const char* managedAssemblyAbsolutePath,
-            int managedAssemblyArgc,
-            const char** managedAssemblyArgv);
-
-
-#if defined(__APPLE__)
-#include <mach-o/dyld.h>
-static const char * const coreClrDll = "libcoreclr.dylib";
-#else
-static const char * const coreClrDll = "libcoreclr.so";
-#endif
-
index a47da80..890d440 100644 (file)
@@ -117,6 +117,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
   add_compile_options(-Wa,--divide)
 endif()
 
+include_directories("${CLR_SRC_NATIVE_DIR}/common")
+
 set(SOURCES
   cruntime/file.cpp
   cruntime/filecrt.cpp
index 728c49d..7b097c9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _PAL_CONFIG_H_INCLUDED
-#define _PAL_CONFIG_H_INCLUDED 1
+#ifndef PAL_CONFIG_H_INCLUDED
+#define PAL_CONFIG_H_INCLUDED
 
 #cmakedefine01 HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY
 #cmakedefine01 HAVE_MAP_HUGETLB
 #define SIGWAIT_FAILS_WHEN_PASSED_FULL_SIGSET 0
 #define WRITE_0_BYTES_HANGS_TTY 0
 #define HAVE_FTRUNCATE_LARGE_LENGTH_SUPPORT 1
-#endif
+
+#endif // PAL_CONFIG_H_INCLUDED
index 708d369..fee6957 100644 (file)
@@ -3,8 +3,6 @@
 
 /*++
 
-
-
 Module Name:
 
     init/pal.cpp
@@ -13,8 +11,6 @@ Abstract:
 
     Implementation of PAL exported functions not part of the Win32 API.
 
-
-
 --*/
 
 #include "pal/dbgmsg.h"
@@ -43,6 +39,7 @@ SET_DEFAULT_DEBUG_CHANNEL(PAL); // some headers have code with asserts, so do th
 #include "pal/numa.h"
 #include "pal/stackstring.hpp"
 #include "pal/cgroup.h"
+#include <getexepath.h>
 
 #if HAVE_MACH_EXCEPTIONS
 #include "../exception/machexception.h"
@@ -91,15 +88,6 @@ int CacheLineSize;
 #endif
 #endif
 
-#if defined(__FreeBSD__)
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#endif
-#if HAVE_GETAUXVAL
-#include <sys/auxv.h>
-#endif
-
 #include <algorithm>
 
 using namespace CorUnix;
@@ -378,7 +366,7 @@ Initialize(
         gPID = getpid();
         gSID = getsid(gPID);
 
-        // Initialize the thread local storage  
+        // Initialize the thread local storage
         if (FALSE == TLSInitialize())
         {
             palError = ERROR_PALINIT_TLS;
@@ -1266,139 +1254,6 @@ static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv)
     return retval;
 }
 
-#if defined(__linux__)
-#define symlinkEntrypointExecutable "/proc/self/exe"
-#elif !defined(__APPLE__)
-#define symlinkEntrypointExecutable "/proc/curproc/exe"
-#endif
-
-bool GetAbsolutePath(const char* path, PathCharString& absolutePath)
-{
-    bool result = false;
-
-    char realPath[PATH_MAX];
-    if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
-    {
-        absolutePath.Set(realPath, strlen(realPath));
-        // realpath should return canonicalized path without the trailing slash
-        _ASSERTE(absolutePath[absolutePath.GetCount() - 1] != '/');
-
-        result = true;
-    }
-
-    return result;
-}
-
-bool GetEntrypointExecutableAbsolutePath(PathCharString& entrypointExecutable)
-{
-    bool result = false;
-
-    entrypointExecutable.Clear();
-
-    // Get path to the executable for the current process using
-    // platform specific means.
-#if defined(__APPLE__)
-
-    // On Mac, we ask the OS for the absolute path to the entrypoint executable
-    uint32_t lenActualPath = 0;
-    if (_NSGetExecutablePath(nullptr, &lenActualPath) == -1)
-    {
-        // OSX has placed the actual path length in lenActualPath,
-        // so re-attempt the operation
-        PathCharString resizedPath;
-        char *pResizedPath = resizedPath.OpenStringBuffer(lenActualPath);
-        if (_NSGetExecutablePath(pResizedPath, &lenActualPath) == 0)
-        {
-            resizedPath.CloseBuffer(lenActualPath - 1);
-            entrypointExecutable.Set(resizedPath);
-            result = true;
-        }
-    }
-#elif defined (__FreeBSD__)
-    static const int name[] =
-    {
-        CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1
-    };
-    char path[PATH_MAX];
-    size_t len;
-
-    len = sizeof(path);
-    if (sysctl(name, 4, path, &len, nullptr, 0) == 0)
-    {
-        entrypointExecutable.Set(path, len);
-        result = true;
-    }
-    else
-    {
-        // ENOMEM
-        result = false;
-    }
-#elif defined(__NetBSD__) && defined(KERN_PROC_PATHNAME)
-    static const int name[] =
-    {
-        CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
-    };
-    char path[MAXPATHLEN];
-    size_t len;
-
-    len = sizeof(path);
-    if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1)
-    {
-        entrypointExecutable.Set(path, len);
-        result = true;
-    }
-    else
-    {
-        result = false;
-    }
-#elif defined(__sun)
-    const char *path;
-    if ((path = getexecname()) == NULL)
-    {
-        result = false;
-    }
-    else if (*path != '/')
-    {
-        char *cwd;
-        if ((cwd = getcwd(NULL, PATH_MAX)) == NULL)
-        {
-            result = false;
-        }
-        else
-        {
-            entrypointExecutable.Set(cwd, strlen(cwd));
-            entrypointExecutable.Append('/');
-            entrypointExecutable.Append(path, strlen(path));
-
-            result = true;
-            free(cwd);
-        }
-    }
-    else
-    {
-        entrypointExecutable.Set(path, strlen(path));
-        result = true;
-    }
-#else
-
-#if HAVE_GETAUXVAL && defined(AT_EXECFN)
-    const char *execfn = (const char *)getauxval(AT_EXECFN);
-
-    if (execfn)
-    {
-        entrypointExecutable.Set(execfn, strlen(execfn));
-        result = true;
-    }
-    else
-#endif
-    // On other OSs, return the symlink that will be resolved by GetAbsolutePath
-    // to fetch the entrypoint EXE absolute path, inclusive of filename.
-    result = GetAbsolutePath(symlinkEntrypointExecutable, entrypointExecutable);
-#endif
-
-    return result;
-}
-
 /*++
 Function:
   INIT_GetCurrentEXEPath
@@ -1413,16 +1268,20 @@ Return:
 --*/
 static LPWSTR INIT_GetCurrentEXEPath()
 {
-    PathCharString real_path;
     LPWSTR return_value;
     INT return_size;
 
-    if (!GetEntrypointExecutableAbsolutePath(real_path))
+    char* path = getexepath();
+    if (!path)
     {
         ERROR( "Cannot get current exe path\n" );
         return NULL;
     }
 
+    PathCharString real_path;
+    real_path.Set(path, strlen(path));
+    free(path);
+
     return_size = MultiByteToWideChar(CP_ACP, 0, real_path, -1, NULL, 0);
     if (0 == return_size)
     {
index 546f17b..e8ba7ae 100644 (file)
@@ -6,6 +6,7 @@ endif()
 
 project(corehost)
 
+include(../../../eng/native/configurepaths.cmake)
 include(${CLR_ENG_NATIVE_DIR}/configurecompiler.cmake)
 
 if(MSVC)
index ba6e4e0..91adf50 100644 (file)
@@ -154,9 +154,9 @@ echo "Computed RID for native build is %cm_BaseRid%"
 
 set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCLI_CMAKE_HOST_VER=%__HostVersion%" "-DCLI_CMAKE_COMMON_HOST_VER=%__AppHostVersion%" "-DCLI_CMAKE_HOST_FXR_VER=%__HostFxrVersion%"
 set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCLI_CMAKE_HOST_POLICY_VER=%__HostPolicyVersion%" "-DCLI_CMAKE_PKG_RID=%cm_BaseRid%" "-DCLI_CMAKE_COMMIT_HASH=%__CommitSha%"
-set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCORECLR_ARTIFACTS=%__CoreClrArtifacts% " "-DRUNTIME_CONFIG=%__RuntimeConfiguration%" "-DNATIVE_LIBS_ARTIFACTS=%__NativeLibsArtifacts%" 
+set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCORECLR_ARTIFACTS=%__CoreClrArtifacts% " "-DRUNTIME_CONFIG=%__RuntimeConfiguration%" "-DNATIVE_LIBS_ARTIFACTS=%__NativeLibsArtifacts%"
 set __ExtraCmakeParams=%__ExtraCmakeParams% "-DRUNTIME_FLAVOR=%__RuntimeFlavor% "
-set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCLI_CMAKE_RESOURCE_DIR=%__ResourcesDir%" "-DCLR_ENG_NATIVE_DIR=%__engNativeDir%" "-DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%"
+set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCLI_CMAKE_RESOURCE_DIR=%__ResourcesDir%" "-DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%"
 
 :: Regenerate the native build files
 echo Calling "%__engNativeDir%\gen-buildsys.cmd "%__sourceDir%" "%__IntermediatesDir%" %__VSVersion% %__BuildArch% %__ExtraCmakeParams%"
index 3b1dc14..1c94adc 100644 (file)
@@ -1,6 +1,7 @@
-#ifndef _PAL_CONFIG_H_INCLUDED
-#define _PAL_CONFIG_H_INCLUDED 1
+#ifndef PAL_HOST_MISC_CONFIG_H_INCLUDED
+#define PAL_HOST_MISC_CONFIG_H_INCLUDED
 
 #cmakedefine01 HAVE_DIRENT_D_TYPE
+#cmakedefine01 HAVE_GETAUXVAL
 
-#endif
+#endif // PAL_HOST_MISC_CONFIG_H_INCLUDED
index 1998dc6..f5828c7 100644 (file)
@@ -1,5 +1,7 @@
 include(CheckStructHasMember)
+include(CheckSymbolExists)
 
 check_struct_has_member("struct dirent" d_type dirent.h HAVE_DIRENT_D_TYPE)
 
 configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL)
index 55670fc..2eb250b 100644 (file)
@@ -3,6 +3,7 @@
 
 include(${CMAKE_CURRENT_LIST_DIR}/configure.cmake)
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
+include_directories("${CLR_SRC_NATIVE_DIR}/common")
 
 if(CLR_CMAKE_TARGET_OS_ILLUMOS)
     add_definitions(-DTARGET_ILLUMOS)
index 20774cb..6883dcd 100644 (file)
@@ -5,6 +5,7 @@
 #define _WITH_GETLINE
 #endif
 
+#include <getexepath.h>
 #include "pal.h"
 #include "utils.h"
 #include "trace.h"
 #include <sys/utsname.h>
 #endif
 
-#if defined(TARGET_LINUX)
-#define symlinkEntrypointExecutable "/proc/self/exe"
-#elif !defined(TARGET_OSX)
-#define symlinkEntrypointExecutable "/proc/curproc/exe"
-#endif
-
 #if !HAVE_DIRENT_D_TYPE
 #define DT_UNKNOWN 0
 #define DT_DIR 4
@@ -793,90 +788,18 @@ pal::string_t pal::get_current_os_rid_platform()
 }
 #endif
 
-#if defined(TARGET_OSX)
-bool pal::get_own_executable_path(pal::string_t* recv)
-{
-    uint32_t path_length = 0;
-    if (_NSGetExecutablePath(nullptr, &path_length) == -1)
-    {
-        char path_buf[path_length];
-        if (_NSGetExecutablePath(path_buf, &path_length) == 0)
-        {
-            recv->assign(path_buf);
-            return true;
-        }
-    }
-    return false;
-}
-#elif defined(TARGET_FREEBSD)
-bool pal::get_own_executable_path(pal::string_t* recv)
-{
-    int mib[4];
-    mib[0] = CTL_KERN;
-    mib[1] = KERN_PROC;
-    mib[2] = KERN_PROC_PATHNAME;
-    mib[3] = -1;
-    char buf[PATH_MAX];
-    size_t cb = sizeof(buf);
-    int error_code = 0;
-    error_code = sysctl(mib, 4, buf, &cb, NULL, 0);
-    if (error_code == 0)
-    {
-        recv->assign(buf);
-        return true;
-    }
-
-    // ENOMEM
-    if (error_code == ENOMEM)
-    {
-        size_t len = sysctl(mib, 4, NULL, NULL, NULL, 0);
-        std::unique_ptr<char[]> buffer (new (std::nothrow) char[len]);
-
-        if (buffer == NULL)
-        {
-            return false;
-        }
-
-        error_code = sysctl(mib, 4, buffer.get(), &len, NULL, 0);
-        if (error_code == 0)
-        {
-            recv->assign(buffer.get());
-            return true;
-        }
-    }
-    return false;
-}
-#elif defined(__sun)
 bool pal::get_own_executable_path(pal::string_t* recv)
 {
-    const char *path;
-    if ((path = getexecname()) == NULL)
+    char* path = getexepath();
+    if (!path)
     {
         return false;
     }
-    else if (*path != '/')
-    {
-        if (!getcwd(recv))
-        {
-            return false;
-        }
-
-        recv->append("/").append(path);
-        return true;
-    }
 
     recv->assign(path);
+    free(path);
     return true;
 }
-#else
-bool pal::get_own_executable_path(pal::string_t* recv)
-{
-    // Just return the symlink to the exe from /proc
-    // We'll call realpath on it later
-    recv->assign(symlinkEntrypointExecutable);
-    return true;
-}
-#endif
 
 bool pal::get_own_module_path(string_t* recv)
 {
index e86ffd8..3bc41e4 100644 (file)
@@ -1,18 +1,19 @@
 cmake_minimum_required(VERSION 3.6.2)
 include(CheckCCompilerFlag)
 
-if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) 
-     # CMake 3.14.5 contains bug fixes for iOS 
-     cmake_minimum_required(VERSION 3.14.5) 
- endif() 
+if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
+     # CMake 3.14.5 contains bug fixes for iOS
+     cmake_minimum_required(VERSION 3.14.5)
+ endif()
 cmake_policy(SET CMP0042 NEW)
 
 project(CoreFX C)
 
+include(../../../../eng/native/configurepaths.cmake)
 include(${CLR_ENG_NATIVE_DIR}/configuretools.cmake)
 
 set(CMAKE_MACOSX_RPATH ON)
-if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) 
+if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
     set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON)
     set(CMAKE_INSTALL_NAME_DIR "@rpath")
 endif()
index 792e695..0439c89 100644 (file)
@@ -94,6 +94,7 @@
 #cmakedefine01 HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
 #cmakedefine01 HAVE_HEIMDAL_HEADERS
 #cmakedefine01 HAVE_NSGETENVIRON
+#cmakedefine01 HAVE_GETAUXVAL
 #cmakedefine01 HAVE_CRT_EXTERNS_H
 #cmakedefine01 HAVE_GETDOMAINNAME
 #cmakedefine01 HAVE_UNAME
index c7a34a8..517628d 100644 (file)
@@ -4,6 +4,8 @@ if (NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS)
     add_definitions(-DHAS_CONSOLE_SIGNALS)
 endif ()
 
+include_directories("${CLR_SRC_NATIVE_DIR}/common")
+
 set(NATIVE_SOURCES
     pal_errno.c
     pal_interfaceaddresses.c
index fce3c5f..94c74e0 100644 (file)
@@ -38,6 +38,8 @@
 #include <sys/sysctl.h>
 #endif
 
+#include <getexepath.h>
+
 // Validate that our SysLogPriority values are correct for the platform
 c_static_assert(PAL_LOG_EMERG == LOG_EMERG);
 c_static_assert(PAL_LOG_ALERT == LOG_ALERT);
@@ -868,56 +870,7 @@ int32_t SystemNative_SchedGetAffinity(int32_t pid, intptr_t* mask)
 }
 #endif
 
-// Returns the full path to the executable for the current process, resolving symbolic links.
-// The caller is responsible for releasing the buffer. Returns null on error.
 char* SystemNative_GetProcessPath()
 {
-#if defined(__APPLE__)
-    uint32_t path_length = 0;
-    if (_NSGetExecutablePath(NULL, &path_length) != -1)
-    {
-        errno = EINVAL;
-        return NULL;
-    }
-
-    char path_buf[path_length];
-    if (_NSGetExecutablePath(path_buf, &path_length) != 0)
-    {
-        errno = EINVAL;
-        return NULL;
-    }
-
-    return realpath(path_buf, NULL);
-#elif defined(__FreeBSD__)
-    static const int name[] =
-    {
-        CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1
-    };
-
-    char path[PATH_MAX];
-    size_t len;
-
-    len = sizeof(path);
-    if (sysctl(name, 4, path, &len, NULL, 0) != 0)
-    {
-        return NULL;
-    }
-
-    return strdup(path);
-#elif defined(__sun)
-    const char* path = getexecname();
-    if (path == NULL)
-        return NULL;
-    return realpath(path, NULL);
-#else
-
-#ifdef __linux__
-    const char* symlinkEntrypointExecutable = "/proc/self/exe";
-#else
-    const char* symlinkEntrypointExecutable = "/proc/curproc/exe";
-#endif
-
-    // Resolve the symlink to the executable from /proc
-    return realpath(symlinkEntrypointExecutable, NULL);
-#endif
+    return getexepath();
 }
index eef61c4..a0d547d 100644 (file)
@@ -938,6 +938,7 @@ else ()
         HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X)
 endif ()
 
+check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL)
 check_include_files(crt_externs.h HAVE_CRT_EXTERNS_H)
 
 if (HAVE_CRT_EXTERNS_H)
diff --git a/src/native/common/getexepath.h b/src/native/common/getexepath.h
new file mode 100644 (file)
index 0000000..e918dad
--- /dev/null
@@ -0,0 +1,85 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#ifndef GETEXEPATH_H
+#define GETEXEPATH_H
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#if defined(__APPLE__)
+#include <mach-o/dyld.h>
+#elif defined(__FreeBSD__)
+#include <string.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Returns the full path to the executable for the current process, resolving symbolic links.
+// The caller is responsible for releasing the buffer. Returns null on error.
+extern inline char* getexepath(void)
+{
+#if defined(__APPLE__)
+    uint32_t path_length = 0;
+    if (_NSGetExecutablePath(NULL, &path_length) != -1)
+    {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    char path_buf[path_length];
+    if (_NSGetExecutablePath(path_buf, &path_length) != 0)
+    {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    return realpath(path_buf, NULL);
+#elif defined(__FreeBSD__)
+    static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+    char path[PATH_MAX];
+    size_t len = sizeof(path);
+    if (sysctl(name, 4, path, &len, NULL, 0) != 0)
+    {
+        return NULL;
+    }
+
+    return strdup(path);
+#elif defined(__sun)
+    const char* path = getexecname();
+    if (path == NULL)
+    {
+        return NULL;
+    }
+
+    return realpath(path, NULL);
+#else
+#if HAVE_GETAUXVAL && defined(AT_EXECFN)
+    const char* path = (const char *)getauxval(AT_EXECFN);
+    if (path)
+    {
+        return realpath(path, NULL);
+    }
+#endif // HAVE_GETAUXVAL && defined(AT_EXECFN)
+#ifdef __linux__
+    const char* symlinkEntrypointExecutable = "/proc/self/exe";
+#else
+    const char* symlinkEntrypointExecutable = "/proc/curproc/exe";
+#endif
+
+    // Resolve the symlink to the executable from /proc
+    return realpath(symlinkEntrypointExecutable, NULL);
+#endif // defined(__APPLE__)
+}
+
+#ifdef __cplusplus
+}
+#endif // extern "C"
+
+#endif // GETEXEPATH_H
index 421f0fd..9eccdfd 100644 (file)
@@ -6,6 +6,7 @@ if (CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15)
 endif()
 project(Tests)
 
+include(../../eng/native/configurepaths.cmake)
 include(${CLR_ENG_NATIVE_DIR}/configurecompiler.cmake)
 
 # Add this subdir. We install the headers for the jit.
index 3dca37a..02ba6b5 100644 (file)
@@ -223,7 +223,7 @@ if not defined VSINSTALLDIR (
 )
 if not exist "%VSINSTALLDIR%DIA SDK" goto NoDIA
 
-set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native"
+set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0"
 call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectFilesDir%" "%__NativeTestIntermediatesDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs!
 
 if not !errorlevel! == 0 (