106c3fb27SDimitry Andric //===--- OHOS.cpp - OHOS ToolChain Implementations --------*- C++ -*-===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric 906c3fb27SDimitry Andric #include "OHOS.h" 1006c3fb27SDimitry Andric #include "Arch/ARM.h" 1106c3fb27SDimitry Andric #include "CommonArgs.h" 1206c3fb27SDimitry Andric #include "clang/Config/config.h" 1306c3fb27SDimitry Andric #include "clang/Driver/Compilation.h" 1406c3fb27SDimitry Andric #include "clang/Driver/Driver.h" 1506c3fb27SDimitry Andric #include "clang/Driver/DriverDiagnostic.h" 1606c3fb27SDimitry Andric #include "clang/Driver/Options.h" 1706c3fb27SDimitry Andric #include "clang/Driver/SanitizerArgs.h" 1806c3fb27SDimitry Andric #include "llvm/Option/ArgList.h" 1906c3fb27SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 2006c3fb27SDimitry Andric #include "llvm/Support/FileSystem.h" 2106c3fb27SDimitry Andric #include "llvm/Support/Path.h" 2206c3fb27SDimitry Andric #include "llvm/Support/VirtualFileSystem.h" 2306c3fb27SDimitry Andric #include "llvm/Support/ScopedPrinter.h" 2406c3fb27SDimitry Andric 2506c3fb27SDimitry Andric using namespace clang::driver; 2606c3fb27SDimitry Andric using namespace clang::driver::toolchains; 2706c3fb27SDimitry Andric using namespace clang::driver::tools; 2806c3fb27SDimitry Andric using namespace clang; 2906c3fb27SDimitry Andric using namespace llvm::opt; 3006c3fb27SDimitry Andric using namespace clang::driver::tools::arm; 3106c3fb27SDimitry Andric 3206c3fb27SDimitry Andric using tools::addMultilibFlag; 3306c3fb27SDimitry Andric using tools::addPathIfExists; 3406c3fb27SDimitry Andric 3506c3fb27SDimitry Andric static bool findOHOSMuslMultilibs(const Multilib::flags_list &Flags, 3606c3fb27SDimitry Andric DetectedMultilibs &Result) { 3706c3fb27SDimitry Andric MultilibSet Multilibs; 3806c3fb27SDimitry Andric Multilibs.push_back(Multilib()); 3906c3fb27SDimitry Andric // -mcpu=cortex-a7 4006c3fb27SDimitry Andric // -mfloat-abi=soft -mfloat-abi=softfp -mfloat-abi=hard 4106c3fb27SDimitry Andric // -mfpu=neon-vfpv4 4206c3fb27SDimitry Andric Multilibs.push_back( 4306c3fb27SDimitry Andric Multilib("/a7_soft", {}, {}, {"-mcpu=cortex-a7", "-mfloat-abi=soft"})); 4406c3fb27SDimitry Andric 4506c3fb27SDimitry Andric Multilibs.push_back( 4606c3fb27SDimitry Andric Multilib("/a7_softfp_neon-vfpv4", {}, {}, 4706c3fb27SDimitry Andric {"-mcpu=cortex-a7", "-mfloat-abi=softfp", "-mfpu=neon-vfpv4"})); 4806c3fb27SDimitry Andric 4906c3fb27SDimitry Andric Multilibs.push_back( 5006c3fb27SDimitry Andric Multilib("/a7_hard_neon-vfpv4", {}, {}, 5106c3fb27SDimitry Andric {"-mcpu=cortex-a7", "-mfloat-abi=hard", "-mfpu=neon-vfpv4"})); 5206c3fb27SDimitry Andric 5306c3fb27SDimitry Andric if (Multilibs.select(Flags, Result.SelectedMultilibs)) { 5406c3fb27SDimitry Andric Result.Multilibs = Multilibs; 5506c3fb27SDimitry Andric return true; 5606c3fb27SDimitry Andric } 5706c3fb27SDimitry Andric return false; 5806c3fb27SDimitry Andric } 5906c3fb27SDimitry Andric 6006c3fb27SDimitry Andric static bool findOHOSMultilibs(const Driver &D, 6106c3fb27SDimitry Andric const ToolChain &TC, 6206c3fb27SDimitry Andric const llvm::Triple &TargetTriple, 6306c3fb27SDimitry Andric StringRef Path, const ArgList &Args, 6406c3fb27SDimitry Andric DetectedMultilibs &Result) { 6506c3fb27SDimitry Andric Multilib::flags_list Flags; 6606c3fb27SDimitry Andric bool IsA7 = false; 6706c3fb27SDimitry Andric if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 6806c3fb27SDimitry Andric IsA7 = A->getValue() == StringRef("cortex-a7"); 6906c3fb27SDimitry Andric addMultilibFlag(IsA7, "-mcpu=cortex-a7", Flags); 7006c3fb27SDimitry Andric 7106c3fb27SDimitry Andric bool IsMFPU = false; 7206c3fb27SDimitry Andric if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) 7306c3fb27SDimitry Andric IsMFPU = A->getValue() == StringRef("neon-vfpv4"); 7406c3fb27SDimitry Andric addMultilibFlag(IsMFPU, "-mfpu=neon-vfpv4", Flags); 7506c3fb27SDimitry Andric 7606c3fb27SDimitry Andric tools::arm::FloatABI ARMFloatABI = getARMFloatABI(D, TargetTriple, Args); 7706c3fb27SDimitry Andric addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Soft), 7806c3fb27SDimitry Andric "-mfloat-abi=soft", Flags); 7906c3fb27SDimitry Andric addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::SoftFP), 8006c3fb27SDimitry Andric "-mfloat-abi=softfp", Flags); 8106c3fb27SDimitry Andric addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Hard), 8206c3fb27SDimitry Andric "-mfloat-abi=hard", Flags); 8306c3fb27SDimitry Andric 8406c3fb27SDimitry Andric return findOHOSMuslMultilibs(Flags, Result); 8506c3fb27SDimitry Andric } 8606c3fb27SDimitry Andric 8706c3fb27SDimitry Andric std::string OHOS::getMultiarchTriple(const llvm::Triple &T) const { 8806c3fb27SDimitry Andric // For most architectures, just use whatever we have rather than trying to be 8906c3fb27SDimitry Andric // clever. 9006c3fb27SDimitry Andric switch (T.getArch()) { 9106c3fb27SDimitry Andric default: 9206c3fb27SDimitry Andric break; 9306c3fb27SDimitry Andric 9406c3fb27SDimitry Andric // We use the existence of '/lib/<triple>' as a directory to detect some 9506c3fb27SDimitry Andric // common linux triples that don't quite match the Clang triple for both 9606c3fb27SDimitry Andric // 32-bit and 64-bit targets. Multiarch fixes its install triples to these 9706c3fb27SDimitry Andric // regardless of what the actual target triple is. 9806c3fb27SDimitry Andric case llvm::Triple::arm: 9906c3fb27SDimitry Andric case llvm::Triple::thumb: 10006c3fb27SDimitry Andric return T.isOSLiteOS() ? "arm-liteos-ohos" : "arm-linux-ohos"; 10106c3fb27SDimitry Andric case llvm::Triple::riscv32: 10206c3fb27SDimitry Andric return "riscv32-linux-ohos"; 10306c3fb27SDimitry Andric case llvm::Triple::riscv64: 10406c3fb27SDimitry Andric return "riscv64-linux-ohos"; 10506c3fb27SDimitry Andric case llvm::Triple::mipsel: 10606c3fb27SDimitry Andric return "mipsel-linux-ohos"; 10706c3fb27SDimitry Andric case llvm::Triple::x86: 10806c3fb27SDimitry Andric return "i686-linux-ohos"; 10906c3fb27SDimitry Andric case llvm::Triple::x86_64: 11006c3fb27SDimitry Andric return "x86_64-linux-ohos"; 11106c3fb27SDimitry Andric case llvm::Triple::aarch64: 11206c3fb27SDimitry Andric return "aarch64-linux-ohos"; 11306c3fb27SDimitry Andric } 11406c3fb27SDimitry Andric return T.str(); 11506c3fb27SDimitry Andric } 11606c3fb27SDimitry Andric 11706c3fb27SDimitry Andric std::string OHOS::getMultiarchTriple(const Driver &D, 11806c3fb27SDimitry Andric const llvm::Triple &TargetTriple, 11906c3fb27SDimitry Andric StringRef SysRoot) const { 12006c3fb27SDimitry Andric return getMultiarchTriple(TargetTriple); 12106c3fb27SDimitry Andric } 12206c3fb27SDimitry Andric 12306c3fb27SDimitry Andric static std::string makePath(const std::initializer_list<std::string> &IL) { 12406c3fb27SDimitry Andric SmallString<128> P; 12506c3fb27SDimitry Andric for (const auto &S : IL) 12606c3fb27SDimitry Andric llvm::sys::path::append(P, S); 12706c3fb27SDimitry Andric return static_cast<std::string>(P.str()); 12806c3fb27SDimitry Andric } 12906c3fb27SDimitry Andric 13006c3fb27SDimitry Andric /// OHOS Toolchain 13106c3fb27SDimitry Andric OHOS::OHOS(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 13206c3fb27SDimitry Andric : Generic_ELF(D, Triple, Args) { 13306c3fb27SDimitry Andric std::string SysRoot = computeSysRoot(); 13406c3fb27SDimitry Andric 13506c3fb27SDimitry Andric // Select the correct multilib according to the given arguments. 13606c3fb27SDimitry Andric DetectedMultilibs Result; 13706c3fb27SDimitry Andric findOHOSMultilibs(D, *this, Triple, "", Args, Result); 13806c3fb27SDimitry Andric Multilibs = Result.Multilibs; 13906c3fb27SDimitry Andric SelectedMultilibs = Result.SelectedMultilibs; 14006c3fb27SDimitry Andric if (!SelectedMultilibs.empty()) { 14106c3fb27SDimitry Andric SelectedMultilib = SelectedMultilibs.back(); 14206c3fb27SDimitry Andric } 14306c3fb27SDimitry Andric 14406c3fb27SDimitry Andric getFilePaths().clear(); 14506c3fb27SDimitry Andric for (const auto &CandidateLibPath : getArchSpecificLibPaths()) 14606c3fb27SDimitry Andric if (getVFS().exists(CandidateLibPath)) 14706c3fb27SDimitry Andric getFilePaths().push_back(CandidateLibPath); 14806c3fb27SDimitry Andric 14906c3fb27SDimitry Andric getLibraryPaths().clear(); 15006c3fb27SDimitry Andric for (auto &Path : getRuntimePaths()) 15106c3fb27SDimitry Andric if (getVFS().exists(Path)) 15206c3fb27SDimitry Andric getLibraryPaths().push_back(Path); 15306c3fb27SDimitry Andric 15406c3fb27SDimitry Andric // OHOS sysroots contain a library directory for each supported OS 15506c3fb27SDimitry Andric // version as well as some unversioned libraries in the usual multiarch 15606c3fb27SDimitry Andric // directory. Support --target=aarch64-linux-ohosX.Y.Z or 15706c3fb27SDimitry Andric // --target=aarch64-linux-ohosX.Y or --target=aarch64-linux-ohosX 15806c3fb27SDimitry Andric path_list &Paths = getFilePaths(); 15906c3fb27SDimitry Andric std::string SysRootLibPath = makePath({SysRoot, "usr", "lib"}); 16006c3fb27SDimitry Andric std::string MultiarchTriple = getMultiarchTriple(getTriple()); 16106c3fb27SDimitry Andric addPathIfExists(D, makePath({SysRootLibPath, SelectedMultilib.gccSuffix()}), 16206c3fb27SDimitry Andric Paths); 16306c3fb27SDimitry Andric addPathIfExists(D, 16406c3fb27SDimitry Andric makePath({D.Dir, "..", "lib", MultiarchTriple, 16506c3fb27SDimitry Andric SelectedMultilib.gccSuffix()}), 16606c3fb27SDimitry Andric Paths); 16706c3fb27SDimitry Andric 16806c3fb27SDimitry Andric addPathIfExists( 16906c3fb27SDimitry Andric D, 17006c3fb27SDimitry Andric makePath({SysRootLibPath, MultiarchTriple, SelectedMultilib.gccSuffix()}), 17106c3fb27SDimitry Andric Paths); 17206c3fb27SDimitry Andric } 17306c3fb27SDimitry Andric 17406c3fb27SDimitry Andric ToolChain::RuntimeLibType OHOS::GetRuntimeLibType( 17506c3fb27SDimitry Andric const ArgList &Args) const { 17606c3fb27SDimitry Andric if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) { 17706c3fb27SDimitry Andric StringRef Value = A->getValue(); 17806c3fb27SDimitry Andric if (Value != "compiler-rt") 17906c3fb27SDimitry Andric getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name) 18006c3fb27SDimitry Andric << A->getAsString(Args); 18106c3fb27SDimitry Andric } 18206c3fb27SDimitry Andric 18306c3fb27SDimitry Andric return ToolChain::RLT_CompilerRT; 18406c3fb27SDimitry Andric } 18506c3fb27SDimitry Andric 18606c3fb27SDimitry Andric ToolChain::CXXStdlibType 18706c3fb27SDimitry Andric OHOS::GetCXXStdlibType(const ArgList &Args) const { 18806c3fb27SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 18906c3fb27SDimitry Andric StringRef Value = A->getValue(); 19006c3fb27SDimitry Andric if (Value != "libc++") 19106c3fb27SDimitry Andric getDriver().Diag(diag::err_drv_invalid_stdlib_name) 19206c3fb27SDimitry Andric << A->getAsString(Args); 19306c3fb27SDimitry Andric } 19406c3fb27SDimitry Andric 19506c3fb27SDimitry Andric return ToolChain::CST_Libcxx; 19606c3fb27SDimitry Andric } 19706c3fb27SDimitry Andric 19806c3fb27SDimitry Andric void OHOS::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 19906c3fb27SDimitry Andric ArgStringList &CC1Args) const { 20006c3fb27SDimitry Andric const Driver &D = getDriver(); 20106c3fb27SDimitry Andric const llvm::Triple &Triple = getTriple(); 20206c3fb27SDimitry Andric std::string SysRoot = computeSysRoot(); 20306c3fb27SDimitry Andric 20406c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdinc)) 20506c3fb27SDimitry Andric return; 20606c3fb27SDimitry Andric 20706c3fb27SDimitry Andric if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 20806c3fb27SDimitry Andric SmallString<128> P(D.ResourceDir); 20906c3fb27SDimitry Andric llvm::sys::path::append(P, "include"); 21006c3fb27SDimitry Andric addSystemInclude(DriverArgs, CC1Args, P); 21106c3fb27SDimitry Andric } 21206c3fb27SDimitry Andric 21306c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 21406c3fb27SDimitry Andric return; 21506c3fb27SDimitry Andric 21606c3fb27SDimitry Andric // Check for configure-time C include directories. 21706c3fb27SDimitry Andric StringRef CIncludeDirs(C_INCLUDE_DIRS); 21806c3fb27SDimitry Andric if (CIncludeDirs != "") { 21906c3fb27SDimitry Andric SmallVector<StringRef, 5> dirs; 22006c3fb27SDimitry Andric CIncludeDirs.split(dirs, ":"); 22106c3fb27SDimitry Andric for (StringRef dir : dirs) { 22206c3fb27SDimitry Andric StringRef Prefix = 22306c3fb27SDimitry Andric llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; 22406c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); 22506c3fb27SDimitry Andric } 22606c3fb27SDimitry Andric return; 22706c3fb27SDimitry Andric } 22806c3fb27SDimitry Andric 22906c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, 23006c3fb27SDimitry Andric SysRoot + "/usr/include/" + 23106c3fb27SDimitry Andric getMultiarchTriple(Triple)); 23206c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); 23306c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); 23406c3fb27SDimitry Andric } 23506c3fb27SDimitry Andric 23606c3fb27SDimitry Andric void OHOS::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 23706c3fb27SDimitry Andric ArgStringList &CC1Args) const { 23806c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 23906c3fb27SDimitry Andric DriverArgs.hasArg(options::OPT_nostdincxx)) 24006c3fb27SDimitry Andric return; 24106c3fb27SDimitry Andric 24206c3fb27SDimitry Andric switch (GetCXXStdlibType(DriverArgs)) { 24306c3fb27SDimitry Andric case ToolChain::CST_Libcxx: { 24406c3fb27SDimitry Andric std::string IncPath = makePath({getDriver().Dir, "..", "include"}); 24506c3fb27SDimitry Andric std::string IncTargetPath = 24606c3fb27SDimitry Andric makePath({IncPath, getMultiarchTriple(getTriple()), "c++", "v1"}); 24706c3fb27SDimitry Andric if (getVFS().exists(IncTargetPath)) { 24806c3fb27SDimitry Andric addSystemInclude(DriverArgs, CC1Args, makePath({IncPath, "c++", "v1"})); 24906c3fb27SDimitry Andric addSystemInclude(DriverArgs, CC1Args, IncTargetPath); 25006c3fb27SDimitry Andric } 25106c3fb27SDimitry Andric break; 25206c3fb27SDimitry Andric } 25306c3fb27SDimitry Andric 25406c3fb27SDimitry Andric default: 25506c3fb27SDimitry Andric llvm_unreachable("invalid stdlib name"); 25606c3fb27SDimitry Andric } 25706c3fb27SDimitry Andric } 25806c3fb27SDimitry Andric 25906c3fb27SDimitry Andric void OHOS::AddCXXStdlibLibArgs(const ArgList &Args, 26006c3fb27SDimitry Andric ArgStringList &CmdArgs) const { 26106c3fb27SDimitry Andric switch (GetCXXStdlibType(Args)) { 26206c3fb27SDimitry Andric case ToolChain::CST_Libcxx: 26306c3fb27SDimitry Andric CmdArgs.push_back("-lc++"); 26406c3fb27SDimitry Andric CmdArgs.push_back("-lc++abi"); 26506c3fb27SDimitry Andric CmdArgs.push_back("-lunwind"); 26606c3fb27SDimitry Andric break; 26706c3fb27SDimitry Andric 26806c3fb27SDimitry Andric case ToolChain::CST_Libstdcxx: 26906c3fb27SDimitry Andric llvm_unreachable("invalid stdlib name"); 27006c3fb27SDimitry Andric } 27106c3fb27SDimitry Andric } 27206c3fb27SDimitry Andric 27306c3fb27SDimitry Andric std::string OHOS::computeSysRoot() const { 27406c3fb27SDimitry Andric std::string SysRoot = 27506c3fb27SDimitry Andric !getDriver().SysRoot.empty() 27606c3fb27SDimitry Andric ? getDriver().SysRoot 277*0fca6ea1SDimitry Andric : makePath({getDriver().Dir, "..", "..", "sysroot"}); 27806c3fb27SDimitry Andric if (!llvm::sys::fs::exists(SysRoot)) 27906c3fb27SDimitry Andric return std::string(); 28006c3fb27SDimitry Andric 28106c3fb27SDimitry Andric std::string ArchRoot = makePath({SysRoot, getMultiarchTriple(getTriple())}); 28206c3fb27SDimitry Andric return llvm::sys::fs::exists(ArchRoot) ? ArchRoot : SysRoot; 28306c3fb27SDimitry Andric } 28406c3fb27SDimitry Andric 28506c3fb27SDimitry Andric ToolChain::path_list OHOS::getRuntimePaths() const { 28606c3fb27SDimitry Andric SmallString<128> P; 28706c3fb27SDimitry Andric path_list Paths; 28806c3fb27SDimitry Andric const Driver &D = getDriver(); 28906c3fb27SDimitry Andric const llvm::Triple &Triple = getTriple(); 29006c3fb27SDimitry Andric 29106c3fb27SDimitry Andric // First try the triple passed to driver as --target=<triple>. 29206c3fb27SDimitry Andric P.assign(D.ResourceDir); 29306c3fb27SDimitry Andric llvm::sys::path::append(P, "lib", D.getTargetTriple(), SelectedMultilib.gccSuffix()); 29406c3fb27SDimitry Andric Paths.push_back(P.c_str()); 29506c3fb27SDimitry Andric 29606c3fb27SDimitry Andric // Second try the normalized triple. 29706c3fb27SDimitry Andric P.assign(D.ResourceDir); 29806c3fb27SDimitry Andric llvm::sys::path::append(P, "lib", Triple.str(), SelectedMultilib.gccSuffix()); 29906c3fb27SDimitry Andric Paths.push_back(P.c_str()); 30006c3fb27SDimitry Andric 30106c3fb27SDimitry Andric // Third try the effective triple. 30206c3fb27SDimitry Andric P.assign(D.ResourceDir); 30306c3fb27SDimitry Andric std::string SysRoot = computeSysRoot(); 30406c3fb27SDimitry Andric llvm::sys::path::append(P, "lib", getMultiarchTriple(Triple), 30506c3fb27SDimitry Andric SelectedMultilib.gccSuffix()); 30606c3fb27SDimitry Andric Paths.push_back(P.c_str()); 30706c3fb27SDimitry Andric 30806c3fb27SDimitry Andric return Paths; 30906c3fb27SDimitry Andric } 31006c3fb27SDimitry Andric 31106c3fb27SDimitry Andric std::string OHOS::getDynamicLinker(const ArgList &Args) const { 31206c3fb27SDimitry Andric const llvm::Triple &Triple = getTriple(); 31306c3fb27SDimitry Andric const llvm::Triple::ArchType Arch = getArch(); 31406c3fb27SDimitry Andric 31506c3fb27SDimitry Andric assert(Triple.isMusl()); 31606c3fb27SDimitry Andric std::string ArchName; 31706c3fb27SDimitry Andric bool IsArm = false; 31806c3fb27SDimitry Andric 31906c3fb27SDimitry Andric switch (Arch) { 32006c3fb27SDimitry Andric case llvm::Triple::arm: 32106c3fb27SDimitry Andric case llvm::Triple::thumb: 32206c3fb27SDimitry Andric ArchName = "arm"; 32306c3fb27SDimitry Andric IsArm = true; 32406c3fb27SDimitry Andric break; 32506c3fb27SDimitry Andric case llvm::Triple::armeb: 32606c3fb27SDimitry Andric case llvm::Triple::thumbeb: 32706c3fb27SDimitry Andric ArchName = "armeb"; 32806c3fb27SDimitry Andric IsArm = true; 32906c3fb27SDimitry Andric break; 33006c3fb27SDimitry Andric default: 33106c3fb27SDimitry Andric ArchName = Triple.getArchName().str(); 33206c3fb27SDimitry Andric } 33306c3fb27SDimitry Andric if (IsArm && 33406c3fb27SDimitry Andric (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)) 33506c3fb27SDimitry Andric ArchName += "hf"; 33606c3fb27SDimitry Andric 33706c3fb27SDimitry Andric return "/lib/ld-musl-" + ArchName + ".so.1"; 33806c3fb27SDimitry Andric } 33906c3fb27SDimitry Andric 34006c3fb27SDimitry Andric std::string OHOS::getCompilerRT(const ArgList &Args, StringRef Component, 34106c3fb27SDimitry Andric FileType Type) const { 34206c3fb27SDimitry Andric SmallString<128> Path(getDriver().ResourceDir); 34306c3fb27SDimitry Andric llvm::sys::path::append(Path, "lib", getMultiarchTriple(getTriple()), 34406c3fb27SDimitry Andric SelectedMultilib.gccSuffix()); 34506c3fb27SDimitry Andric const char *Prefix = 34606c3fb27SDimitry Andric Type == ToolChain::FT_Object ? "" : "lib"; 34706c3fb27SDimitry Andric const char *Suffix; 34806c3fb27SDimitry Andric switch (Type) { 34906c3fb27SDimitry Andric case ToolChain::FT_Object: 35006c3fb27SDimitry Andric Suffix = ".o"; 35106c3fb27SDimitry Andric break; 35206c3fb27SDimitry Andric case ToolChain::FT_Static: 35306c3fb27SDimitry Andric Suffix = ".a"; 35406c3fb27SDimitry Andric break; 35506c3fb27SDimitry Andric case ToolChain::FT_Shared: 35606c3fb27SDimitry Andric Suffix = ".so"; 35706c3fb27SDimitry Andric break; 35806c3fb27SDimitry Andric } 35906c3fb27SDimitry Andric llvm::sys::path::append( 36006c3fb27SDimitry Andric Path, Prefix + Twine("clang_rt.") + Component + Suffix); 36106c3fb27SDimitry Andric return static_cast<std::string>(Path.str()); 36206c3fb27SDimitry Andric } 36306c3fb27SDimitry Andric 36406c3fb27SDimitry Andric void OHOS::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { 36506c3fb27SDimitry Andric CmdArgs.push_back("-z"); 36606c3fb27SDimitry Andric CmdArgs.push_back("now"); 36706c3fb27SDimitry Andric CmdArgs.push_back("-z"); 36806c3fb27SDimitry Andric CmdArgs.push_back("relro"); 36906c3fb27SDimitry Andric CmdArgs.push_back("-z"); 37006c3fb27SDimitry Andric CmdArgs.push_back("max-page-size=4096"); 37106c3fb27SDimitry Andric // .gnu.hash section is not compatible with the MIPS target 37206c3fb27SDimitry Andric if (getArch() != llvm::Triple::mipsel) 37306c3fb27SDimitry Andric CmdArgs.push_back("--hash-style=both"); 37406c3fb27SDimitry Andric #ifdef ENABLE_LINKER_BUILD_ID 37506c3fb27SDimitry Andric CmdArgs.push_back("--build-id"); 37606c3fb27SDimitry Andric #endif 37706c3fb27SDimitry Andric CmdArgs.push_back("--enable-new-dtags"); 37806c3fb27SDimitry Andric } 37906c3fb27SDimitry Andric 38006c3fb27SDimitry Andric SanitizerMask OHOS::getSupportedSanitizers() const { 38106c3fb27SDimitry Andric SanitizerMask Res = ToolChain::getSupportedSanitizers(); 38206c3fb27SDimitry Andric Res |= SanitizerKind::Address; 38306c3fb27SDimitry Andric Res |= SanitizerKind::PointerCompare; 38406c3fb27SDimitry Andric Res |= SanitizerKind::PointerSubtract; 38506c3fb27SDimitry Andric Res |= SanitizerKind::Fuzzer; 38606c3fb27SDimitry Andric Res |= SanitizerKind::FuzzerNoLink; 38706c3fb27SDimitry Andric Res |= SanitizerKind::Memory; 38806c3fb27SDimitry Andric Res |= SanitizerKind::Vptr; 38906c3fb27SDimitry Andric Res |= SanitizerKind::SafeStack; 39006c3fb27SDimitry Andric Res |= SanitizerKind::Scudo; 39106c3fb27SDimitry Andric // TODO: kASAN for liteos ?? 39206c3fb27SDimitry Andric // TODO: Support TSAN and HWASAN and update mask. 39306c3fb27SDimitry Andric return Res; 39406c3fb27SDimitry Andric } 39506c3fb27SDimitry Andric 39606c3fb27SDimitry Andric // TODO: Make a base class for Linux and OHOS and move this there. 39706c3fb27SDimitry Andric void OHOS::addProfileRTLibs(const llvm::opt::ArgList &Args, 39806c3fb27SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 39906c3fb27SDimitry Andric // Add linker option -u__llvm_profile_runtime to cause runtime 40006c3fb27SDimitry Andric // initialization module to be linked in. 40106c3fb27SDimitry Andric if (needsProfileRT(Args)) 40206c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString( 40306c3fb27SDimitry Andric Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); 40406c3fb27SDimitry Andric ToolChain::addProfileRTLibs(Args, CmdArgs); 40506c3fb27SDimitry Andric } 40606c3fb27SDimitry Andric 40706c3fb27SDimitry Andric ToolChain::path_list OHOS::getArchSpecificLibPaths() const { 40806c3fb27SDimitry Andric ToolChain::path_list Paths; 40906c3fb27SDimitry Andric llvm::Triple Triple = getTriple(); 41006c3fb27SDimitry Andric Paths.push_back( 41106c3fb27SDimitry Andric makePath({getDriver().ResourceDir, "lib", getMultiarchTriple(Triple)})); 41206c3fb27SDimitry Andric return Paths; 41306c3fb27SDimitry Andric } 41406c3fb27SDimitry Andric 41506c3fb27SDimitry Andric ToolChain::UnwindLibType OHOS::GetUnwindLibType(const llvm::opt::ArgList &Args) const { 41606c3fb27SDimitry Andric if (Args.getLastArg(options::OPT_unwindlib_EQ)) 41706c3fb27SDimitry Andric return Generic_ELF::GetUnwindLibType(Args); 41806c3fb27SDimitry Andric return GetDefaultUnwindLibType(); 41906c3fb27SDimitry Andric } 420