}
}
+#ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
+static uintptr_t getFileSize(const std::string& path)
+{
+ struct stat sb;
+
+ if (stat(path.c_str(), &sb) == 0) {
+ return sb.st_size;
+ }
+
+ return 0;
+}
+
+// Get next base address to be used for system ni image from file
+// __SYSTEM_BASE_FILE should be checked for existance before calling this function
+static uintptr_t getNextBaseAddrFromFile()
+{
+ FILE *pFile = fopen(__SYSTEM_BASE_FILE, "r");
+ if (pFile == NULL) {
+ _SERR("Failed to open %s", __SYSTEM_BASE_FILE);
+ return 0;
+ }
+
+ uintptr_t addr = 0;
+ uintptr_t size = 0;
+
+ while (fscanf(pFile, "%" SCNxPTR " %" SCNuPTR "", &addr, &size) != EOF) {
+ }
+
+ fclose(pFile);
+
+ return addr + size;
+}
+
+// Get next base address to be used for system ni image
+static uintptr_t getNextBaseAddr()
+{
+ uintptr_t baseAddr = 0;
+
+ if (!isFile(__SYSTEM_BASE_FILE)) {
+ // This is the starting address for all default base addresses
+ baseAddr = DEFAULT_BASE_ADDR_START;
+ } else {
+ baseAddr = getNextBaseAddrFromFile();
+
+ // Round to a multple of 64K (see ZapImage::CalculateZapBaseAddress in CoreCLR)
+ uintptr_t BASE_ADDRESS_ALIGNMENT = 0xffff;
+ baseAddr = (baseAddr + BASE_ADDRESS_ALIGNMENT) & ~BASE_ADDRESS_ALIGNMENT;
+ }
+
+ return baseAddr;
+}
+
+// Save base address of system ni image to file
+static void updateBaseAddrFile(const std::string& absNIPath, uintptr_t baseAddr)
+{
+ uintptr_t niSize = getFileSize(absNIPath);
+ if (niSize == 0) {
+ _SERR("File %s doesn't exist", absNIPath.c_str());
+ return;
+ }
+
+ // Write new entry to the file
+ FILE *pFile = fopen(__SYSTEM_BASE_FILE, "a");
+ if (pFile == NULL) {
+ _SERR("Failed to open %s", __SYSTEM_BASE_FILE);
+ return;
+ }
+
+ fprintf(pFile, "%" PRIxPTR " %" PRIuPTR "\n", baseAddr, niSize);
+ fclose(pFile);
+}
+
+// check if dll is listed in TPA
+static bool isTPADll(const std::string& dllPath)
+{
+ std::string absPath = getBaseName(getAbsolutePath(dllPath));
+
+ std::vector<std::string> paths = __pm->getPlatformAssembliesPaths();
+ for (unsigned int i = 0; i < paths.size(); i++) {
+ if (paths[i].find(getBaseName(absPath)) != std::string::npos) {
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif
+
/**
* @brief create the directory including parents directory, and
* copy ownership and smack labels to the created directory.
niPath = getNIFilePath(dllPath);
}
+#ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
+ uintptr_t baseAddr = 0;
+ if (isTPADll(dllPath)) {
+ baseAddr = getNextBaseAddr();
+ }
+#endif
+
// fork crossgen2
pid_t pid = fork();
if (pid == -1)
if (ret != NI_ERROR_NONE) {
return ret;
}
+#ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
+ if (baseAddr != 0) {
+ updateBaseAddrFile(niPath, baseAddr);
+ }
+#endif
} else {
_SERR("Failed. Forked process terminated abnormally");
_SERR("Crossgen2 was terminated by the OOM killer. Please check the system.");
std::vector<const char*> argv;
makeArgs(argv, refPaths, opt);
+#ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
+ std::string baseAddrString;
+ if (baseAddr != 0) {
+ argv.push_back("--imagebase");
+ std::stringstream ss;
+ ss << "0x" << std::hex << baseAddr;
+ baseAddrString = ss.str();
+ argv.push_back(baseAddrString.c_str());
+ }
+#endif
argv.push_back("-o");
argv.push_back(niPath.c_str());