#include <fstream>
#include <limits.h>
#include <stdlib.h>
+#include <set>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
#include "log.h"
#include "launcher_env.h"
return absPath;
}
+static bool isFileExist(const std::string& path)
+{
+ struct stat sb;
+ return stat(path.c_str(), &sb) == 0;
+}
+
+static std::string replaceAll(const std::string& str, const std::string& pattern, const std::string& replace)
+{
+ std::string result = str;
+ std::string::size_type pos = 0;
+ std::string::size_type offset = 0;
+
+ while ((pos = result.find(pattern, offset)) != std::string::npos) {
+ result.replace(result.begin() + pos, result.begin() + pos + pattern.size(), replace);
+ offset = pos + replace.size();
+ }
+
+ return result;
+}
+
+static std::string findDllPath(const std::string& filename)
+{
+ const std::string netcoreappDir = "/usr/share/dotnet.tizen/netcoreapp/";
+ const std::string frameworkDir = "/usr/share/dotnet.tizen/framework/";
+
+ std::string result;
+
+ // check whether the target file exist under netcoreapp directory
+ result = netcoreappDir + filename;
+ if (isFileExist(result)) {
+ return result;
+ }
+
+ // check whether the target file exist under framework directory
+ result = frameworkDir + filename;
+ if (isFileExist(result)) {
+ return result;
+ }
+
+ // dll file is not found. return empty string
+ result.clear();
+
+ return result;
+}
+
static void preloadAssemblies()
{
#ifdef USE_DEFAULT_BASE_ADDR
return;
}
- std::ifstream preloadList(AOT_PRELOAD_PATH);
- if (preloadList) {
- std::string path;
- while (getline(preloadList, path)) {
- int st = preloadAssembly(absolutePath(path).c_str());
- if (st != 0) {
- _DBG("preload of %s failed! (0x%08x)", path.c_str(), st);
- } else {
- _DBG("preload of %s succeded", path.c_str());
+ const std::string preloadDir = "/usr/share/dotnet.tizen/preload/";
+
+ // get file list from preload directory
+ // file is sorted by std::set
+ std::set<std::string> preloadFiles;
+ DIR* dirp = opendir(preloadDir.c_str());
+ struct dirent * dp;
+ while ((dp = readdir(dirp)) != NULL) {
+ if (dp->d_type != DT_DIR) {
+ // Make sure that the file name follows naming conventions.
+ if (dp->d_name &&
+ isdigit(dp->d_name[0]) &&
+ isdigit(dp->d_name[1]) &&
+ (dp->d_name[2] == '.')) {
+ preloadFiles.insert(preloadDir + dp->d_name);
}
}
}
+ closedir(dirp);
+
+ // get dll list from each preload file, and preload dll.
+ std::set<std::string> dllList;
+ std::ifstream ifs;
+ std::string in_line;
+ for (const auto& pf: preloadFiles) {
+ ifs.open(pf);
+ if (!ifs.is_open()) {
+ _ERR("failed to open preload file (%s)", pf.c_str());
+ continue;
+ }
+
+ while (std::getline(ifs, in_line)) {
+ in_line = in_line.substr(0, in_line.find_first_of(" ", 0));
+
+ // select dll file case
+ if (in_line[0] == '#' ||
+ in_line[0] == ' ' ||
+ in_line.empty() ||
+ (in_line.find(".dll") == std::string::npos)) {
+ continue;
+ }
+
+ // only native image should be passed as a parameter of coreclr_preload_assembly.
+ if (in_line.find(".ni.dll") == std::string::npos &&
+ in_line.compare("System.Private.CoreLib.dll")) {
+ in_line = replaceAll(in_line, ".dll", ".ni.dll");
+ }
+
+ // coreclr_preload_assembly cannot ignore duplicate loading.
+ // Therefore, only one dll should be preloaded.
+ // dllList is used to ignore duplicated loading request
+ if (dllList.insert(in_line).second) {
+ // check whether the target file exist under netcoreapp directory
+ std::string path = findDllPath(in_line);
+ if (!path.empty()) {
+ int st = preloadAssembly(absolutePath(path).c_str());
+ if (st != 0) {
+ _ERR("preload of %s failed! (0x%08x)", path.c_str(), st);
+ } else {
+ _INFO("preload of %s succeeded", path.c_str());
+ }
+ } else {
+ _ERR("preload failed : file (%s) does not eixst", in_line.c_str());
+ }
+ }
+ }
+
+ ifs.close();
+ }
}
int main(int argc, char** argv)