add_subdirectory(src/pal)
add_subdirectory(src/coreclr/hosts/unixcorerun)
add_subdirectory(src/corefx)
+ add_subdirectory(src/coreclr/hosts/unixcoreconsole)
endif(CLR_CMAKE_PLATFORM_UNIX)
# Add this subdir. We install the headers for the jit.
include_directories("${LLDB_H}")
include_directories(${CLR_DIR}/src/debug/inc)
include_directories(${CLR_DIR}/src/inc)
+include_directories(${CLR_DIR}/src/coreclr/hosts/unixcoreruncommon)
set(SOURCES
sosplugin.cpp
--- /dev/null
+This folder will be mirrored by the Git-TFS Mirror recursively.
\ No newline at end of file
--- /dev/null
+project(unixcoreconsole)
+
+include_directories(../unixcoreruncommon)
+
+set(CORECONSOLE_SOURCES
+ ../unixcoreruncommon/coreruncommon.cpp
+ coreconsole.cpp
+)
+
+add_executable(coreconsole
+ ${CORECONSOLE_SOURCES}
+)
+
+# FreeBSD implements dlopen in libc
+if(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ target_link_libraries(coreconsole
+ dl
+ )
+endif(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+
+# FreeBSD requires pthread to be loaded by the executable process
+if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ target_link_libraries(coreconsole
+ pthread
+ )
+endif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+
+add_dependencies(coreconsole
+ coreclr
+)
+
+install (TARGETS coreconsole DESTINATION .)
--- /dev/null
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+//
+// A simple CoreCLR host that runs a managed binary with the same name as this executable but with the *.dll extension
+// The dll binary must contain a main entry point.
+//
+
+#include <coreruncommon.h>
+#include <string>
+#include <string.h>
+#include <sys/stat.h>
+
+// Display the help text
+void DisplayUsage()
+{
+ fprintf(
+ stderr,
+ "Runs executables on CoreCLR\n\n"
+ "Usage: <program> [OPTIONS] [ARGUMENTS]\n"
+ "Runs <program>.dll on CoreCLR.\n\n"
+ "Options:\n"
+ "-_c path to libcoreclr.so and the managed CLR assemblies.\n"
+ "-_h show this help message. \n");
+}
+
+// Parse the command line arguments
+bool ParseArguments(
+ const int argc,
+ const char* argv[],
+ const char** clrFilesPath,
+ int* managedAssemblyArgc,
+ const char*** managedAssemblyArgv)
+{
+ bool success = true;
+
+ *clrFilesPath = nullptr;
+ *managedAssemblyArgv = nullptr;
+ *managedAssemblyArgc = 0;
+
+ for (int i = 1; i < argc; i++)
+ {
+ // Check for options. Options to the Unix coreconsole are prefixed with '-_' to match the convention
+ // used in the Windows version of coreconsole.
+ if (strncmp(argv[i], "-_", 2) == 0)
+ {
+ // Path to the libcoreclr.so and the managed CLR assemblies
+ if (strcmp(argv[i], "-_c") == 0)
+ {
+ i++;
+ if (i < argc)
+ {
+ *clrFilesPath = argv[i];
+ }
+ else
+ {
+ fprintf(stderr, "Option %s: missing path\n", argv[i - 1]);
+ success = false;
+ break;
+ }
+ }
+ else if (strcmp(argv[i], "-_h") == 0)
+ {
+ DisplayUsage();
+ success = false;
+ break;
+ }
+ else
+ {
+ fprintf(stderr, "Unknown option %s\n", argv[i]);
+ success = false;
+ break;
+ }
+ }
+ else
+ {
+ // We treat everything starting from the first non-option argument as arguments
+ // to the managed assembly.
+ *managedAssemblyArgc = argc - i;
+ if (*managedAssemblyArgc != 0)
+ {
+ *managedAssemblyArgv = &argv[i];
+ }
+
+ break;
+ }
+ }
+
+ return success;
+}
+
+int main(const int argc, const char* argv[])
+{
+ // Make sure we have a full path for argv[0].
+ std::string argv0AbsolutePath;
+ if (!GetAbsolutePath(argv[0], argv0AbsolutePath))
+ {
+ perror("Could not get full path to current executable");
+ return -1;
+ }
+
+ // We will try to load the managed assembly with the same name as this executable
+ // but with the .dll extension.
+ std::string programPath(argv0AbsolutePath);
+ programPath.append(".dll");
+ const char* managedAssemblyAbsolutePath = programPath.c_str();
+
+ // Check if the specified managed assembly file exists
+ struct stat sb;
+ if (stat(managedAssemblyAbsolutePath, &sb) == -1)
+ {
+ perror("Managed assembly not found");
+ return -1;
+ }
+
+ // Verify that the managed assembly path points to a file
+ if (!S_ISREG(sb.st_mode))
+ {
+ fprintf(stderr, "The specified managed assembly is not a file\n");
+ return -1;
+ }
+
+ const char* clrFilesPath;
+ const char** managedAssemblyArgv;
+ int managedAssemblyArgc;
+
+ if (!ParseArguments(
+ argc,
+ argv,
+ &clrFilesPath,
+ &managedAssemblyArgc,
+ &managedAssemblyArgv
+ ))
+ {
+ // Invalid command line
+ return -1;
+ }
+
+ std::string clrFilesAbsolutePath;
+ if(!GetClrFilesAbsolutePath(argv0AbsolutePath.c_str(), clrFilesPath, clrFilesAbsolutePath))
+ {
+ return -1;
+ }
+
+ int exitCode = ExecuteManagedAssembly(
+ argv0AbsolutePath.c_str(),
+ clrFilesAbsolutePath.c_str(),
+ managedAssemblyAbsolutePath,
+ managedAssemblyArgc,
+ managedAssemblyArgv);
+
+ return exitCode;
+}
project(unixcorerun)
+include_directories(../unixcoreruncommon)
+
set(CORERUN_SOURCES
+ ../unixcoreruncommon/coreruncommon.cpp
corerun.cpp
)
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
-#include <assert.h>
-#include <dlfcn.h>
-#include <dirent.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include <coreruncommon.h>
+#include <string>
#include <string.h>
#include <sys/stat.h>
-#include <sys/types.h>
-#include <string>
-#include <set>
-
-// The name of the CoreCLR native runtime DLL.
-#if defined(__APPLE__)
-static const char * const coreClrDll = "libcoreclr.dylib";
-#else
-static const char * const coreClrDll = "libcoreclr.so";
-#endif
-
-// Windows types used by the ExecuteAssembly function
-typedef unsigned int DWORD;
-typedef const char16_t* LPCWSTR;
-typedef const char* LPCSTR;
-typedef int32_t HRESULT;
-
-#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
-
-// Prototype of the ExecuteAssembly function from the libcoreclr.do
-typedef HRESULT (*ExecuteAssemblyFunction)(
- LPCSTR exePath,
- LPCSTR coreClrPath,
- LPCSTR appDomainFriendlyName,
- int propertyCount,
- LPCSTR* propertyKeys,
- LPCSTR* propertyValues,
- int argc,
- LPCSTR* argv,
- LPCSTR managedAssemblyPath,
- LPCSTR entryPointAssemblyName,
- LPCSTR entryPointTypeName,
- LPCSTR entryPointMethodsName,
- DWORD* exitCode);
// Display the command line options
void DisplayUsage()
"-c, --clr-path path to the libcoreclr.so and the managed CLR assemblies\n");
}
-// Get absolute path from the specified path.
-// Return true in case of a success, false otherwise.
-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);
- // The 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;
-}
-
// Parse the command line arguments
bool ParseArguments(
const int argc,
return success;
}
-// 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)
-{
- 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 (int 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)
- {
- // We are interested in files only
- switch (entry->d_type)
- {
- 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);
-}
-
-//
-// Execute the specified managed assembly.
-//
-// Parameters:
-// currentExePath - Path of the current executable
-// clrFilesAbsolutePath - Absolute path of a 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)
-{
- // Indicates failure
- int exitCode = -1;
-
- 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 nativeDllSearchDirs(appPath);
- nativeDllSearchDirs.append(":");
- nativeDllSearchDirs.append(clrFilesAbsolutePath);
-
- std::string tpaList;
- AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList);
-
- void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL);
- if (coreclrLib != nullptr)
- {
- ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly");
- if (executeAssembly != nullptr)
- {
- // 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",
- "AppDomainCompatSwitch"
- };
- 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(),
- // AppDomainCompatSwitch
- "UseLatestBehaviorWhenTFMNotSpecified"
- };
-
- HRESULT st = executeAssembly(
- currentExeAbsolutePath,
- coreClrDllPath.c_str(),
- "unixcorerun",
- sizeof(propertyKeys) / sizeof(propertyKeys[0]),
- propertyKeys,
- propertyValues,
- managedAssemblyArgc,
- managedAssemblyArgv,
- managedAssemblyAbsolutePath,
- NULL,
- NULL,
- NULL,
- (DWORD*)&exitCode);
-
- if (!SUCCEEDED(st))
- {
- fprintf(stderr, "ExecuteAssembly failed - status: 0x%08x\n", st);
- }
- }
- else
- {
- fprintf(stderr, "Function ExecuteAssembly not found in the libcoreclr.so\n");
- }
-
- if (dlclose(coreclrLib) != 0)
- {
- fprintf(stderr, "Warning - dlclose failed\n");
- }
- }
- else
- {
- char* error = dlerror();
- fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error);
- }
-
- return exitCode;
-}
-
int corerun(const int argc, const char* argv[])
{
const char* clrFilesPath;
fprintf(stderr, "The specified managed assembly is not a file\n");
return -1;
}
-
+
// Make sure we have a full path for argv[0].
std::string argv0AbsolutePath;
if (!GetAbsolutePath(argv[0], argv0AbsolutePath))
return -1;
}
- // Convert the specified path to CLR files to an absolute path since the libcoreclr.so
- // requires it.
std::string clrFilesAbsolutePath;
- std::string clrFilesRelativePath;
-
- if (clrFilesPath == nullptr)
+ if(!GetClrFilesAbsolutePath(argv0AbsolutePath.c_str(), clrFilesPath, clrFilesAbsolutePath))
{
- // There was no CLR files path specified, use the folder of the corerun
- if (!GetDirectory(argv0AbsolutePath.c_str(), clrFilesRelativePath))
- {
- perror("Failed to get directory from argv[0]");
- return -1;
- }
- clrFilesPath = 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(clrFilesPath, clrFilesAbsolutePath))
- {
- perror("Failed to convert CLR files path to absolute path");
return -1;
}
perror("Failed to convert managed assembly path to absolute path");
return -1;
}
-
+
int exitCode = ExecuteManagedAssembly(
argv0AbsolutePath.c_str(),
clrFilesAbsolutePath.c_str(),
managedAssemblyAbsolutePath.c_str(),
managedAssemblyArgc,
managedAssemblyArgv);
+
return exitCode;
}
--- /dev/null
+Only contents of this folder, excluding subfolders, will be mirrored by the Git-TFS Mirror.
\ No newline at end of file
--- /dev/null
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+//
+// Code that is used by both the Unix corerun and coreconsole.
+//
+
+#include <assert.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <limits.h>
+#include <set>
+#include <string>
+#include <string.h>
+#include <sys/stat.h>
+
+// The name of the CoreCLR native runtime DLL
+#if defined(__APPLE__)
+static const char * const coreClrDll = "libcoreclr.dylib";
+#else
+static const char * const coreClrDll = "libcoreclr.so";
+#endif
+
+// Windows types used by the ExecuteAssembly function
+typedef unsigned int DWORD;
+typedef const char16_t* LPCWSTR;
+typedef const char* LPCSTR;
+typedef int32_t HRESULT;
+
+#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
+
+// Prototype of the ExecuteAssembly function from the libcoreclr.do
+typedef HRESULT (*ExecuteAssemblyFunction)(
+ LPCSTR exePath,
+ LPCSTR coreClrPath,
+ LPCSTR appDomainFriendlyName,
+ int propertyCount,
+ LPCSTR* propertyKeys,
+ LPCSTR* propertyValues,
+ int argc,
+ LPCSTR* argv,
+ LPCSTR managedAssemblyPath,
+ LPCSTR entryPointAssemblyName,
+ LPCSTR entryPointTypeName,
+ LPCSTR entryPointMethodsName,
+ DWORD* exitCode);
+
+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 (int 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)
+ {
+ // We are interested in files only
+ switch (entry->d_type)
+ {
+ 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);
+}
+
+int ExecuteManagedAssembly(
+ const char* currentExeAbsolutePath,
+ const char* clrFilesAbsolutePath,
+ const char* managedAssemblyAbsolutePath,
+ int managedAssemblyArgc,
+ const char** managedAssemblyArgv)
+{
+ // Indicates failure
+ int exitCode = -1;
+
+ 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 nativeDllSearchDirs(appPath);
+ nativeDllSearchDirs.append(":");
+ nativeDllSearchDirs.append(clrFilesAbsolutePath);
+
+ std::string tpaList;
+ AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList);
+
+ void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL);
+ if (coreclrLib != nullptr)
+ {
+ ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly");
+ if (executeAssembly != nullptr)
+ {
+ // 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",
+ "AppDomainCompatSwitch"
+ };
+ 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(),
+ // AppDomainCompatSwitch
+ "UseLatestBehaviorWhenTFMNotSpecified"
+ };
+
+ HRESULT st = executeAssembly(
+ currentExeAbsolutePath,
+ coreClrDllPath.c_str(),
+ "unixcorerun",
+ sizeof(propertyKeys) / sizeof(propertyKeys[0]),
+ propertyKeys,
+ propertyValues,
+ managedAssemblyArgc,
+ managedAssemblyArgv,
+ managedAssemblyAbsolutePath,
+ NULL,
+ NULL,
+ NULL,
+ (DWORD*)&exitCode);
+
+ if (!SUCCEEDED(st))
+ {
+ fprintf(stderr, "ExecuteAssembly failed - status: 0x%08x\n", st);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Function ExecuteAssembly not found in the libcoreclr.so\n");
+ }
+
+ if (dlclose(coreclrLib) != 0)
+ {
+ fprintf(stderr, "Warning - dlclose failed\n");
+ }
+ }
+ else
+ {
+ char* error = dlerror();
+ fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error);
+ }
+
+ return exitCode;
+}
--- /dev/null
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+#include <string>
+
+// 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);
+