bool CoreClrEmbedding::LoadCoreClrAtPath(const char* loadPath, void** libCoreClrPointer) { std::string coreClrDllPath(loadPath); DBG("CoreClrEmbedding::LoadCoreClrAtPath - Trying to load %s from %s", LIBCORECLR_NAME, loadPath); #ifdef EDGE_PLATFORM_WINDOWS coreClrDllPath.append("\\"); #else coreClrDllPath.append("/"); #endif coreClrDllPath.append(LIBCORECLR_NAME); #ifdef EDGE_PLATFORM_WINDOWS *libCoreClrPointer = LoadLibrary(coreClrDllPath.c_str()); #else *libCoreClrPointer = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_GLOBAL); #endif if (*libCoreClrPointer == NULL ) { DBG("CoreClrEmbedding::LoadCoreClrAtPath - Errors loading %s from %s: %s", LIBCORECLR_NAME, loadPath, GetLoadError()); } else { DBG("CoreClrEmbedding::LoadCoreClrAtPath - Load of %s succeeded", LIBCORECLR_NAME); } return *libCoreClrPointer != NULL; }
extern "C" HRESULT CallApplicationMain(PCALL_APPLICATION_MAIN_DATA data) { HRESULT hr = S_OK; size_t cchTrustedPlatformAssemblies = 0; std::string runtimeDirectory; if (data->runtimeDirectory) { runtimeDirectory = data->runtimeDirectory; } else { // TODO: This should get the directory that this library is in, not the CWD. char szCurrentDirectory[PATH_MAX]; if (!getcwd(szCurrentDirectory, PATH_MAX)) { return E_FAIL; } runtimeDirectory = std::string(szCurrentDirectory); } std::string coreClrDirectory; void* coreClr = LoadCoreClr(coreClrDirectory); if (!coreClr) { char* error = dlerror(); fprintf(stderr, "failed to locate coreclr.dll with error %s\n", error); return E_FAIL; } const char* property_keys[] = { "APPBASE", "TRUSTED_PLATFORM_ASSEMBLIES", "APP_PATHS", }; std::string trustedPlatformAssemblies; // Try native images first if (!GetTrustedPlatformAssembliesList(coreClrDirectory.c_str(), true, trustedPlatformAssemblies)) { if (!GetTrustedPlatformAssembliesList(coreClrDirectory.c_str(), false, trustedPlatformAssemblies)) { fprintf(stderr, "Failed to find files in the coreclr directory\n"); hr = E_FAIL; return hr; } } // Add the assembly containing the app domain manager to the trusted list trustedPlatformAssemblies.append(runtimeDirectory); trustedPlatformAssemblies.append("dnx.coreclr.managed.dll"); std::string appPaths(runtimeDirectory); appPaths.append(":"); appPaths.append(coreClrDirectory); appPaths.append(":"); const char* property_values[] = { // APPBASE data->applicationBase, // TRUESTED_PLATFORM_ASSEMBLIES trustedPlatformAssemblies.c_str(), // APP_PATHS appPaths.c_str(), }; ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreClr, "ExecuteAssembly"); if (!executeAssembly) { fprintf(stderr, "Could not find ExecuteAssembly entrypoint in coreclr.\n"); return E_FAIL; } setenv("DNX_FRAMEWORK", "dnxcore50", 1); std::string coreClrDllPath(coreClrDirectory); coreClrDllPath.append("/"); coreClrDllPath.append("libcoreclr.so"); char pathToBootstrapper[PATH_MAX]; ssize_t pathLen = readlink("/proc/self/exe", pathToBootstrapper, PATH_MAX - 1); if (pathLen == -1) { fprintf(stderr, "Could not locate full bootstrapper path.\n"); return E_FAIL; } pathToBootstrapper[pathLen] = '\0'; hr = executeAssembly(pathToBootstrapper, coreClrDllPath.c_str(), "dnx.coreclr.managed", sizeof(property_keys) / sizeof(property_keys[0]), property_keys, property_values, data->argc, (const char**)data->argv, nullptr, "dnx.coreclr.managed, Version=0.1.0.0", "DomainManager", "Execute", (DWORD*)&(data->exitcode)); dlclose(coreClr); return hr; }
int initializeCoreCLR(const char* exePath, const char* appDomainFriendlyName, int propertyCount, const char* mergedPropertyKeys, const char* mergedPropertyValues, const char* managedAssemblyAbsolutePath, const char* clrFilesAbsolutePath) { printf("initializeCoreCLR()\n"); std::string coreClrDllPath(clrFilesAbsolutePath); coreClrDllPath.append("/"); coreClrDllPath.append(coreClrDll); if (coreClrDllPath.length() >= PATH_MAX) { fprintf(stderr, "Absolute path to libcoreclr.so too long\n"); } std::string appPath; if( managedAssemblyAbsolutePath[0] == '\0' ) { printf("Expecting to run a standard .exe\n"); } else { printf("Expecting to load an assembly and invoke arbitrary methods.\n"); GetDirectory(managedAssemblyAbsolutePath, appPath); }; // Construct native search directory paths std::string nativeDllSearchDirs(appPath); char *coreLibraries = getenv("CORE_LIBRARIES"); if (coreLibraries) { nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(coreLibraries); } nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(clrFilesAbsolutePath); std::string tpaList; AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList); coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL); if (coreclrLib != nullptr) { initialize_core_clr = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize"); execute_assembly = (coreclr_execute_assembly_ptr)dlsym(coreclrLib, "coreclr_execute_assembly"); shutdown_core_clr= (coreclr_shutdown_ptr)dlsym(coreclrLib, "coreclr_shutdown"); create_delegate = (coreclr_create_delegate_ptr)dlsym(coreclrLib, "coreclr_create_delegate"); if (initialize_core_clr == nullptr) { fprintf(stderr, "Function coreclr_initialize not found in the libcoreclr.so\n"); return -1; } else if (execute_assembly == nullptr) { fprintf(stderr, "Function coreclr_execute_assembly not found in the libcoreclr.so\n"); return -1; } else if (shutdown_core_clr == nullptr) { fprintf(stderr, "Function coreclr_shutdown not found in the libcoreclr.so\n"); return -1; } else { if(useServerGc == NULL) { std::getenv(serverGcVar); if (useServerGc == nullptr) { useServerGc = "0"; } } useServerGc = std::strcmp(useServerGc, "1") == 0 ? "true" : "false"; char *keys[propertyCount]; char *values[propertyCount]; parseValues(mergedPropertyKeys, keys, propertyCount); parseValues(mergedPropertyValues, values, propertyCount); int st = initialize_core_clr( exePath, appDomainFriendlyName, propertyCount, (const char**)keys, (const char**)values, &hostHandle, &domainId); if (SUCCEEDED(st)) { printf("coreclr_initialize ok\n"); } else { fprintf(stderr, "coreclr_initialize failed - status: 0x%08x\n", st); }; } } return 0; }
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); // Construct native search directory paths std::string nativeDllSearchDirs(appPath); char *coreLibraries = getenv("CORE_LIBRARIES"); if (coreLibraries) { nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(coreLibraries); } nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(clrFilesAbsolutePath); std::string tpaList; 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_ptr shutdownCoreCLR = (coreclr_shutdown_ptr)dlsym(coreclrLib, "coreclr_shutdown"); 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 not found in the libcoreclr.so\n"); } else { // Check whether we are enabling server GC (off by default) const char* useServerGc = std::getenv(serverGcVar); if (useServerGc == nullptr) { useServerGc = "0"; } // CoreCLR expects strings "true" and "false" instead of "1" and "0". useServerGc = std::strcmp(useServerGc, "1") == 0 ? "true" : "false"; // 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", "System.GC.Server", }; 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", // System.GC.Server useServerGc, }; 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; } st = shutdownCoreCLR(hostHandle, domainId); if (!SUCCEEDED(st)) { fprintf(stderr, "coreclr_shutdown failed - status: 0x%08x\n", st); exitCode = -1; } } } 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 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); exitCode = -1; } } 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; }