support launcher plugin
[platform/core/dotnet/launcher.git] / NativeLauncher / launcher / dotnet / dotnet_launcher.cc
index d3df80e..6724558 100644 (file)
@@ -26,6 +26,8 @@
 #include "launcher.h"
 #include "dotnet_launcher.h"
 
+#define PLUGIN_PATH "/usr/share/dotnet.tizen/lib/libdotnet_plugin.so"
+
 namespace tizen {
 namespace runtime {
 namespace dotnetcore {
@@ -39,7 +41,14 @@ CoreRuntime::CoreRuntime() :
        __hostHandle(nullptr),
        __domainId(-1),
        preparedFunction(nullptr),
-       launchFunction(nullptr)
+       launchFunction(nullptr),
+       __pluginLib(nullptr),
+       pluginInitialize(nullptr),
+       pluginPreload(nullptr),
+       pluginSetAppInfo(nullptr),
+       pluginGetDllPath(nullptr),
+       pluginBeforeExecute(nullptr),
+       pluginFinalize(nullptr)
 {
 #define __XSTR(x) #x
 #define __STR(x) __XSTR(x)
@@ -63,6 +72,22 @@ CoreRuntime::CoreRuntime() :
 #undef __STR
 #undef __XSTR
 
+       // support launcher plugin
+       if (!fileNotExist(PLUGIN_PATH)) {
+               __pluginLib = dlopen(PLUGIN_PATH, RTLD_NOW | RTLD_LOCAL);
+               if (__pluginLib) {
+                       pluginInitialize  = (plugin_initialize_ptr)dlsym(__pluginLib, "plugin_initialize");
+                       pluginPreload  = (plugin_preload_ptr)dlsym(__pluginLib, "plugin_preload");
+                       pluginSetAppInfo  = (plugin_set_app_info_ptr)dlsym(__pluginLib, "plugin_set_app_info");
+                       pluginGetDllPath  = (plugin_get_dll_path_ptr)dlsym(__pluginLib, "plugin_get_dll_path");
+                       pluginBeforeExecute  = (plugin_before_execute_ptr)dlsym(__pluginLib, "plugin_before_execute");
+                       pluginFinalize  = (plugin_finalize_ptr)dlsym(__pluginLib, "plugin_finalize");
+               }
+       }
+
+       if (pluginInitialize)
+               pluginInitialize();
+
        _DBG("Constructor called!!");
 }
 
@@ -73,6 +98,20 @@ CoreRuntime::~CoreRuntime()
 
 int CoreRuntime::initialize(bool standalone)
 {
+#ifdef __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/coreclr/issues/6698
+       //
+       // 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 // __arm__
+
        if (standalone) {
                const char *deviceApiDirectory = getenv("__deviceAPIDirectory");
                const char *runtimeDirectory = getenv("__runtimeDirectory");
@@ -102,6 +141,9 @@ int CoreRuntime::initialize(bool standalone)
                __runtimeDirectory = absolutePath(__runtimeDirectory);
        }
 
+       // set Reference API directory
+       __refAPIDirectory = __deviceAPIDirectory + "/ref";
+
 #ifdef USE_MANAGED_LAUNCHER
        if (__launcherAssembly.empty()) {
                _ERR("Empty Launcher Assembly");
@@ -142,6 +184,9 @@ int CoreRuntime::initialize(bool standalone)
        _DBG("this addr : %x", this);
        _DBG("coreclr_initialize : %x", initializeClr);
 
+       if (!standalone && pluginPreload)
+               pluginPreload();
+
        return 0;
 }
 
@@ -239,6 +284,22 @@ void CoreRuntime::dispose()
 
        __coreclrLib = nullptr;
 
+       if (pluginFinalize)
+               pluginFinalize();
+
+       if (__pluginLib != nullptr) {
+               if (dlclose(__pluginLib) != 0)
+                       _ERR("libdotnet_plugin.so close failed");
+
+               __pluginLib = nullptr;
+               pluginInitialize = nullptr;
+               pluginPreload = nullptr;
+               pluginSetAppInfo = nullptr;
+               pluginGetDllPath = nullptr;
+               pluginBeforeExecute = nullptr;
+               pluginFinalize = nullptr;
+       }
+
        _DBG("Dotnet runtime disposed");
 }
 
@@ -254,6 +315,9 @@ int CoreRuntime::launch(const char* appId, const char* root, const char* path, i
                return 1;
        }
 
+       if (pluginSetAppInfo)
+               pluginSetAppInfo(appId, path);
+
        std::string tpa;
        std::string appRoot = root;
        std::string appBin = concatPath(appRoot, "bin");
@@ -263,14 +327,25 @@ int CoreRuntime::launch(const char* appId, const char* root, const char* path, i
        std::vector<std::string> searchDirectories;
        searchDirectories.push_back(appBin);
        searchDirectories.push_back(appLib);
+       if (pluginGetDllPath) {
+               std::string pluginPath = pluginGetDllPath();
+               if (!pluginPath.empty()) {
+                       probePath = probePath + ":" + pluginPath;
+                       searchDirectories.push_back(pluginPath);
+               }
+       }
        searchDirectories.push_back(__runtimeDirectory);
        searchDirectories.push_back(__deviceAPIDirectory);
+       searchDirectories.push_back(__refAPIDirectory);
 #ifdef USE_MANAGED_LAUNCHER
        searchDirectories.push_back(baseName(__launcherAssembly));
 #endif
 
        assembliesInDirectory(searchDirectories, tpa);
 
+       if (pluginBeforeExecute)
+               pluginBeforeExecute();
+
 #ifdef USE_MANAGED_LAUNCHER
        runManagedLauncher(appId, probePath.c_str(), tpa.c_str());