xref: /freebsd-src/contrib/llvm-project/clang/lib/Driver/ToolChains/OHOS.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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