From: 조웅석/Common Platform Lab(SR)/삼성전자 Date: Fri, 29 Apr 2022 00:37:07 +0000 (+0900) Subject: Set base address at native image (#400) X-Git-Tag: submit/tizen/20220429.002649^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6ce548d772fb85c5b06c153886b447c3a57510e3;p=platform%2Fcore%2Fdotnet%2Flauncher.git Set base address at native image (#400) --imagebase option is added to set base address at native imaage to avoid relocatoin. Note! this feature is enabled --no-pipeline mode only --- diff --git a/NativeLauncher/tool/ni_common.cc b/NativeLauncher/tool/ni_common.cc index 199426f..80f1f6c 100644 --- a/NativeLauncher/tool/ni_common.cc +++ b/NativeLauncher/tool/ni_common.cc @@ -111,6 +111,94 @@ static void waitInterval() } } +#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 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. @@ -483,6 +571,13 @@ static ni_error_e crossgen2NoPipeLine(const std::vector& dllList, c 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) @@ -496,6 +591,11 @@ static ni_error_e crossgen2NoPipeLine(const std::vector& dllList, c 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."); @@ -506,6 +606,16 @@ static ni_error_e crossgen2NoPipeLine(const std::vector& dllList, c std::vector 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());