1*06c3fb27SDimitry Andric //===--- OHOS.cpp - OHOS ToolChain Implementations --------*- C++ -*-===// 2*06c3fb27SDimitry Andric // 3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06c3fb27SDimitry Andric // 7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 8*06c3fb27SDimitry Andric 9*06c3fb27SDimitry Andric #include "OHOS.h" 10*06c3fb27SDimitry Andric #include "Arch/ARM.h" 11*06c3fb27SDimitry Andric #include "CommonArgs.h" 12*06c3fb27SDimitry Andric #include "clang/Config/config.h" 13*06c3fb27SDimitry Andric #include "clang/Driver/Compilation.h" 14*06c3fb27SDimitry Andric #include "clang/Driver/Driver.h" 15*06c3fb27SDimitry Andric #include "clang/Driver/DriverDiagnostic.h" 16*06c3fb27SDimitry Andric #include "clang/Driver/Options.h" 17*06c3fb27SDimitry Andric #include "clang/Driver/SanitizerArgs.h" 18*06c3fb27SDimitry Andric #include "llvm/Option/ArgList.h" 19*06c3fb27SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 20*06c3fb27SDimitry Andric #include "llvm/Support/FileSystem.h" 21*06c3fb27SDimitry Andric #include "llvm/Support/Path.h" 22*06c3fb27SDimitry Andric #include "llvm/Support/VirtualFileSystem.h" 23*06c3fb27SDimitry Andric #include "llvm/Support/ScopedPrinter.h" 24*06c3fb27SDimitry Andric 25*06c3fb27SDimitry Andric using namespace clang::driver; 26*06c3fb27SDimitry Andric using namespace clang::driver::toolchains; 27*06c3fb27SDimitry Andric using namespace clang::driver::tools; 28*06c3fb27SDimitry Andric using namespace clang; 29*06c3fb27SDimitry Andric using namespace llvm::opt; 30*06c3fb27SDimitry Andric using namespace clang::driver::tools::arm; 31*06c3fb27SDimitry Andric 32*06c3fb27SDimitry Andric using tools::addMultilibFlag; 33*06c3fb27SDimitry Andric using tools::addPathIfExists; 34*06c3fb27SDimitry Andric 35*06c3fb27SDimitry Andric static bool findOHOSMuslMultilibs(const Multilib::flags_list &Flags, 36*06c3fb27SDimitry Andric DetectedMultilibs &Result) { 37*06c3fb27SDimitry Andric MultilibSet Multilibs; 38*06c3fb27SDimitry Andric Multilibs.push_back(Multilib()); 39*06c3fb27SDimitry Andric // -mcpu=cortex-a7 40*06c3fb27SDimitry Andric // -mfloat-abi=soft -mfloat-abi=softfp -mfloat-abi=hard 41*06c3fb27SDimitry Andric // -mfpu=neon-vfpv4 42*06c3fb27SDimitry Andric Multilibs.push_back( 43*06c3fb27SDimitry Andric Multilib("/a7_soft", {}, {}, {"-mcpu=cortex-a7", "-mfloat-abi=soft"})); 44*06c3fb27SDimitry Andric 45*06c3fb27SDimitry Andric Multilibs.push_back( 46*06c3fb27SDimitry Andric Multilib("/a7_softfp_neon-vfpv4", {}, {}, 47*06c3fb27SDimitry Andric {"-mcpu=cortex-a7", "-mfloat-abi=softfp", "-mfpu=neon-vfpv4"})); 48*06c3fb27SDimitry Andric 49*06c3fb27SDimitry Andric Multilibs.push_back( 50*06c3fb27SDimitry Andric Multilib("/a7_hard_neon-vfpv4", {}, {}, 51*06c3fb27SDimitry Andric {"-mcpu=cortex-a7", "-mfloat-abi=hard", "-mfpu=neon-vfpv4"})); 52*06c3fb27SDimitry Andric 53*06c3fb27SDimitry Andric if (Multilibs.select(Flags, Result.SelectedMultilibs)) { 54*06c3fb27SDimitry Andric Result.Multilibs = Multilibs; 55*06c3fb27SDimitry Andric return true; 56*06c3fb27SDimitry Andric } 57*06c3fb27SDimitry Andric return false; 58*06c3fb27SDimitry Andric } 59*06c3fb27SDimitry Andric 60*06c3fb27SDimitry Andric static bool findOHOSMultilibs(const Driver &D, 61*06c3fb27SDimitry Andric const ToolChain &TC, 62*06c3fb27SDimitry Andric const llvm::Triple &TargetTriple, 63*06c3fb27SDimitry Andric StringRef Path, const ArgList &Args, 64*06c3fb27SDimitry Andric DetectedMultilibs &Result) { 65*06c3fb27SDimitry Andric Multilib::flags_list Flags; 66*06c3fb27SDimitry Andric bool IsA7 = false; 67*06c3fb27SDimitry Andric if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 68*06c3fb27SDimitry Andric IsA7 = A->getValue() == StringRef("cortex-a7"); 69*06c3fb27SDimitry Andric addMultilibFlag(IsA7, "-mcpu=cortex-a7", Flags); 70*06c3fb27SDimitry Andric 71*06c3fb27SDimitry Andric bool IsMFPU = false; 72*06c3fb27SDimitry Andric if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) 73*06c3fb27SDimitry Andric IsMFPU = A->getValue() == StringRef("neon-vfpv4"); 74*06c3fb27SDimitry Andric addMultilibFlag(IsMFPU, "-mfpu=neon-vfpv4", Flags); 75*06c3fb27SDimitry Andric 76*06c3fb27SDimitry Andric tools::arm::FloatABI ARMFloatABI = getARMFloatABI(D, TargetTriple, Args); 77*06c3fb27SDimitry Andric addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Soft), 78*06c3fb27SDimitry Andric "-mfloat-abi=soft", Flags); 79*06c3fb27SDimitry Andric addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::SoftFP), 80*06c3fb27SDimitry Andric "-mfloat-abi=softfp", Flags); 81*06c3fb27SDimitry Andric addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Hard), 82*06c3fb27SDimitry Andric "-mfloat-abi=hard", Flags); 83*06c3fb27SDimitry Andric 84*06c3fb27SDimitry Andric return findOHOSMuslMultilibs(Flags, Result); 85*06c3fb27SDimitry Andric } 86*06c3fb27SDimitry Andric 87*06c3fb27SDimitry Andric std::string OHOS::getMultiarchTriple(const llvm::Triple &T) const { 88*06c3fb27SDimitry Andric // For most architectures, just use whatever we have rather than trying to be 89*06c3fb27SDimitry Andric // clever. 90*06c3fb27SDimitry Andric switch (T.getArch()) { 91*06c3fb27SDimitry Andric default: 92*06c3fb27SDimitry Andric break; 93*06c3fb27SDimitry Andric 94*06c3fb27SDimitry Andric // We use the existence of '/lib/<triple>' as a directory to detect some 95*06c3fb27SDimitry Andric // common linux triples that don't quite match the Clang triple for both 96*06c3fb27SDimitry Andric // 32-bit and 64-bit targets. Multiarch fixes its install triples to these 97*06c3fb27SDimitry Andric // regardless of what the actual target triple is. 98*06c3fb27SDimitry Andric case llvm::Triple::arm: 99*06c3fb27SDimitry Andric case llvm::Triple::thumb: 100*06c3fb27SDimitry Andric return T.isOSLiteOS() ? "arm-liteos-ohos" : "arm-linux-ohos"; 101*06c3fb27SDimitry Andric case llvm::Triple::riscv32: 102*06c3fb27SDimitry Andric return "riscv32-linux-ohos"; 103*06c3fb27SDimitry Andric case llvm::Triple::riscv64: 104*06c3fb27SDimitry Andric return "riscv64-linux-ohos"; 105*06c3fb27SDimitry Andric case llvm::Triple::mipsel: 106*06c3fb27SDimitry Andric return "mipsel-linux-ohos"; 107*06c3fb27SDimitry Andric case llvm::Triple::x86: 108*06c3fb27SDimitry Andric return "i686-linux-ohos"; 109*06c3fb27SDimitry Andric case llvm::Triple::x86_64: 110*06c3fb27SDimitry Andric return "x86_64-linux-ohos"; 111*06c3fb27SDimitry Andric case llvm::Triple::aarch64: 112*06c3fb27SDimitry Andric return "aarch64-linux-ohos"; 113*06c3fb27SDimitry Andric } 114*06c3fb27SDimitry Andric return T.str(); 115*06c3fb27SDimitry Andric } 116*06c3fb27SDimitry Andric 117*06c3fb27SDimitry Andric std::string OHOS::getMultiarchTriple(const Driver &D, 118*06c3fb27SDimitry Andric const llvm::Triple &TargetTriple, 119*06c3fb27SDimitry Andric StringRef SysRoot) const { 120*06c3fb27SDimitry Andric return getMultiarchTriple(TargetTriple); 121*06c3fb27SDimitry Andric } 122*06c3fb27SDimitry Andric 123*06c3fb27SDimitry Andric static std::string makePath(const std::initializer_list<std::string> &IL) { 124*06c3fb27SDimitry Andric SmallString<128> P; 125*06c3fb27SDimitry Andric for (const auto &S : IL) 126*06c3fb27SDimitry Andric llvm::sys::path::append(P, S); 127*06c3fb27SDimitry Andric return static_cast<std::string>(P.str()); 128*06c3fb27SDimitry Andric } 129*06c3fb27SDimitry Andric 130*06c3fb27SDimitry Andric /// OHOS Toolchain 131*06c3fb27SDimitry Andric OHOS::OHOS(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 132*06c3fb27SDimitry Andric : Generic_ELF(D, Triple, Args) { 133*06c3fb27SDimitry Andric std::string SysRoot = computeSysRoot(); 134*06c3fb27SDimitry Andric 135*06c3fb27SDimitry Andric // Select the correct multilib according to the given arguments. 136*06c3fb27SDimitry Andric DetectedMultilibs Result; 137*06c3fb27SDimitry Andric findOHOSMultilibs(D, *this, Triple, "", Args, Result); 138*06c3fb27SDimitry Andric Multilibs = Result.Multilibs; 139*06c3fb27SDimitry Andric SelectedMultilibs = Result.SelectedMultilibs; 140*06c3fb27SDimitry Andric if (!SelectedMultilibs.empty()) { 141*06c3fb27SDimitry Andric SelectedMultilib = SelectedMultilibs.back(); 142*06c3fb27SDimitry Andric } 143*06c3fb27SDimitry Andric 144*06c3fb27SDimitry Andric getFilePaths().clear(); 145*06c3fb27SDimitry Andric for (const auto &CandidateLibPath : getArchSpecificLibPaths()) 146*06c3fb27SDimitry Andric if (getVFS().exists(CandidateLibPath)) 147*06c3fb27SDimitry Andric getFilePaths().push_back(CandidateLibPath); 148*06c3fb27SDimitry Andric 149*06c3fb27SDimitry Andric getLibraryPaths().clear(); 150*06c3fb27SDimitry Andric for (auto &Path : getRuntimePaths()) 151*06c3fb27SDimitry Andric if (getVFS().exists(Path)) 152*06c3fb27SDimitry Andric getLibraryPaths().push_back(Path); 153*06c3fb27SDimitry Andric 154*06c3fb27SDimitry Andric // OHOS sysroots contain a library directory for each supported OS 155*06c3fb27SDimitry Andric // version as well as some unversioned libraries in the usual multiarch 156*06c3fb27SDimitry Andric // directory. Support --target=aarch64-linux-ohosX.Y.Z or 157*06c3fb27SDimitry Andric // --target=aarch64-linux-ohosX.Y or --target=aarch64-linux-ohosX 158*06c3fb27SDimitry Andric path_list &Paths = getFilePaths(); 159*06c3fb27SDimitry Andric std::string SysRootLibPath = makePath({SysRoot, "usr", "lib"}); 160*06c3fb27SDimitry Andric std::string MultiarchTriple = getMultiarchTriple(getTriple()); 161*06c3fb27SDimitry Andric addPathIfExists(D, makePath({SysRootLibPath, SelectedMultilib.gccSuffix()}), 162*06c3fb27SDimitry Andric Paths); 163*06c3fb27SDimitry Andric addPathIfExists(D, 164*06c3fb27SDimitry Andric makePath({D.Dir, "..", "lib", MultiarchTriple, 165*06c3fb27SDimitry Andric SelectedMultilib.gccSuffix()}), 166*06c3fb27SDimitry Andric Paths); 167*06c3fb27SDimitry Andric 168*06c3fb27SDimitry Andric addPathIfExists( 169*06c3fb27SDimitry Andric D, 170*06c3fb27SDimitry Andric makePath({SysRootLibPath, MultiarchTriple, SelectedMultilib.gccSuffix()}), 171*06c3fb27SDimitry Andric Paths); 172*06c3fb27SDimitry Andric } 173*06c3fb27SDimitry Andric 174*06c3fb27SDimitry Andric ToolChain::RuntimeLibType OHOS::GetRuntimeLibType( 175*06c3fb27SDimitry Andric const ArgList &Args) const { 176*06c3fb27SDimitry Andric if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) { 177*06c3fb27SDimitry Andric StringRef Value = A->getValue(); 178*06c3fb27SDimitry Andric if (Value != "compiler-rt") 179*06c3fb27SDimitry Andric getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name) 180*06c3fb27SDimitry Andric << A->getAsString(Args); 181*06c3fb27SDimitry Andric } 182*06c3fb27SDimitry Andric 183*06c3fb27SDimitry Andric return ToolChain::RLT_CompilerRT; 184*06c3fb27SDimitry Andric } 185*06c3fb27SDimitry Andric 186*06c3fb27SDimitry Andric ToolChain::CXXStdlibType 187*06c3fb27SDimitry Andric OHOS::GetCXXStdlibType(const ArgList &Args) const { 188*06c3fb27SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 189*06c3fb27SDimitry Andric StringRef Value = A->getValue(); 190*06c3fb27SDimitry Andric if (Value != "libc++") 191*06c3fb27SDimitry Andric getDriver().Diag(diag::err_drv_invalid_stdlib_name) 192*06c3fb27SDimitry Andric << A->getAsString(Args); 193*06c3fb27SDimitry Andric } 194*06c3fb27SDimitry Andric 195*06c3fb27SDimitry Andric return ToolChain::CST_Libcxx; 196*06c3fb27SDimitry Andric } 197*06c3fb27SDimitry Andric 198*06c3fb27SDimitry Andric void OHOS::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 199*06c3fb27SDimitry Andric ArgStringList &CC1Args) const { 200*06c3fb27SDimitry Andric const Driver &D = getDriver(); 201*06c3fb27SDimitry Andric const llvm::Triple &Triple = getTriple(); 202*06c3fb27SDimitry Andric std::string SysRoot = computeSysRoot(); 203*06c3fb27SDimitry Andric 204*06c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdinc)) 205*06c3fb27SDimitry Andric return; 206*06c3fb27SDimitry Andric 207*06c3fb27SDimitry Andric if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 208*06c3fb27SDimitry Andric SmallString<128> P(D.ResourceDir); 209*06c3fb27SDimitry Andric llvm::sys::path::append(P, "include"); 210*06c3fb27SDimitry Andric addSystemInclude(DriverArgs, CC1Args, P); 211*06c3fb27SDimitry Andric } 212*06c3fb27SDimitry Andric 213*06c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 214*06c3fb27SDimitry Andric return; 215*06c3fb27SDimitry Andric 216*06c3fb27SDimitry Andric // Check for configure-time C include directories. 217*06c3fb27SDimitry Andric StringRef CIncludeDirs(C_INCLUDE_DIRS); 218*06c3fb27SDimitry Andric if (CIncludeDirs != "") { 219*06c3fb27SDimitry Andric SmallVector<StringRef, 5> dirs; 220*06c3fb27SDimitry Andric CIncludeDirs.split(dirs, ":"); 221*06c3fb27SDimitry Andric for (StringRef dir : dirs) { 222*06c3fb27SDimitry Andric StringRef Prefix = 223*06c3fb27SDimitry Andric llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; 224*06c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); 225*06c3fb27SDimitry Andric } 226*06c3fb27SDimitry Andric return; 227*06c3fb27SDimitry Andric } 228*06c3fb27SDimitry Andric 229*06c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, 230*06c3fb27SDimitry Andric SysRoot + "/usr/include/" + 231*06c3fb27SDimitry Andric getMultiarchTriple(Triple)); 232*06c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); 233*06c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); 234*06c3fb27SDimitry Andric } 235*06c3fb27SDimitry Andric 236*06c3fb27SDimitry Andric void OHOS::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 237*06c3fb27SDimitry Andric ArgStringList &CC1Args) const { 238*06c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 239*06c3fb27SDimitry Andric DriverArgs.hasArg(options::OPT_nostdincxx)) 240*06c3fb27SDimitry Andric return; 241*06c3fb27SDimitry Andric 242*06c3fb27SDimitry Andric switch (GetCXXStdlibType(DriverArgs)) { 243*06c3fb27SDimitry Andric case ToolChain::CST_Libcxx: { 244*06c3fb27SDimitry Andric std::string IncPath = makePath({getDriver().Dir, "..", "include"}); 245*06c3fb27SDimitry Andric std::string IncTargetPath = 246*06c3fb27SDimitry Andric makePath({IncPath, getMultiarchTriple(getTriple()), "c++", "v1"}); 247*06c3fb27SDimitry Andric if (getVFS().exists(IncTargetPath)) { 248*06c3fb27SDimitry Andric addSystemInclude(DriverArgs, CC1Args, makePath({IncPath, "c++", "v1"})); 249*06c3fb27SDimitry Andric addSystemInclude(DriverArgs, CC1Args, IncTargetPath); 250*06c3fb27SDimitry Andric } 251*06c3fb27SDimitry Andric break; 252*06c3fb27SDimitry Andric } 253*06c3fb27SDimitry Andric 254*06c3fb27SDimitry Andric default: 255*06c3fb27SDimitry Andric llvm_unreachable("invalid stdlib name"); 256*06c3fb27SDimitry Andric } 257*06c3fb27SDimitry Andric } 258*06c3fb27SDimitry Andric 259*06c3fb27SDimitry Andric void OHOS::AddCXXStdlibLibArgs(const ArgList &Args, 260*06c3fb27SDimitry Andric ArgStringList &CmdArgs) const { 261*06c3fb27SDimitry Andric switch (GetCXXStdlibType(Args)) { 262*06c3fb27SDimitry Andric case ToolChain::CST_Libcxx: 263*06c3fb27SDimitry Andric CmdArgs.push_back("-lc++"); 264*06c3fb27SDimitry Andric CmdArgs.push_back("-lc++abi"); 265*06c3fb27SDimitry Andric CmdArgs.push_back("-lunwind"); 266*06c3fb27SDimitry Andric break; 267*06c3fb27SDimitry Andric 268*06c3fb27SDimitry Andric case ToolChain::CST_Libstdcxx: 269*06c3fb27SDimitry Andric llvm_unreachable("invalid stdlib name"); 270*06c3fb27SDimitry Andric } 271*06c3fb27SDimitry Andric } 272*06c3fb27SDimitry Andric 273*06c3fb27SDimitry Andric std::string OHOS::computeSysRoot() const { 274*06c3fb27SDimitry Andric std::string SysRoot = 275*06c3fb27SDimitry Andric !getDriver().SysRoot.empty() 276*06c3fb27SDimitry Andric ? getDriver().SysRoot 277*06c3fb27SDimitry Andric : makePath({getDriver().getInstalledDir(), "..", "..", "sysroot"}); 278*06c3fb27SDimitry Andric if (!llvm::sys::fs::exists(SysRoot)) 279*06c3fb27SDimitry Andric return std::string(); 280*06c3fb27SDimitry Andric 281*06c3fb27SDimitry Andric std::string ArchRoot = makePath({SysRoot, getMultiarchTriple(getTriple())}); 282*06c3fb27SDimitry Andric return llvm::sys::fs::exists(ArchRoot) ? ArchRoot : SysRoot; 283*06c3fb27SDimitry Andric } 284*06c3fb27SDimitry Andric 285*06c3fb27SDimitry Andric ToolChain::path_list OHOS::getRuntimePaths() const { 286*06c3fb27SDimitry Andric SmallString<128> P; 287*06c3fb27SDimitry Andric path_list Paths; 288*06c3fb27SDimitry Andric const Driver &D = getDriver(); 289*06c3fb27SDimitry Andric const llvm::Triple &Triple = getTriple(); 290*06c3fb27SDimitry Andric 291*06c3fb27SDimitry Andric // First try the triple passed to driver as --target=<triple>. 292*06c3fb27SDimitry Andric P.assign(D.ResourceDir); 293*06c3fb27SDimitry Andric llvm::sys::path::append(P, "lib", D.getTargetTriple(), SelectedMultilib.gccSuffix()); 294*06c3fb27SDimitry Andric Paths.push_back(P.c_str()); 295*06c3fb27SDimitry Andric 296*06c3fb27SDimitry Andric // Second try the normalized triple. 297*06c3fb27SDimitry Andric P.assign(D.ResourceDir); 298*06c3fb27SDimitry Andric llvm::sys::path::append(P, "lib", Triple.str(), SelectedMultilib.gccSuffix()); 299*06c3fb27SDimitry Andric Paths.push_back(P.c_str()); 300*06c3fb27SDimitry Andric 301*06c3fb27SDimitry Andric // Third try the effective triple. 302*06c3fb27SDimitry Andric P.assign(D.ResourceDir); 303*06c3fb27SDimitry Andric std::string SysRoot = computeSysRoot(); 304*06c3fb27SDimitry Andric llvm::sys::path::append(P, "lib", getMultiarchTriple(Triple), 305*06c3fb27SDimitry Andric SelectedMultilib.gccSuffix()); 306*06c3fb27SDimitry Andric Paths.push_back(P.c_str()); 307*06c3fb27SDimitry Andric 308*06c3fb27SDimitry Andric return Paths; 309*06c3fb27SDimitry Andric } 310*06c3fb27SDimitry Andric 311*06c3fb27SDimitry Andric std::string OHOS::getDynamicLinker(const ArgList &Args) const { 312*06c3fb27SDimitry Andric const llvm::Triple &Triple = getTriple(); 313*06c3fb27SDimitry Andric const llvm::Triple::ArchType Arch = getArch(); 314*06c3fb27SDimitry Andric 315*06c3fb27SDimitry Andric assert(Triple.isMusl()); 316*06c3fb27SDimitry Andric std::string ArchName; 317*06c3fb27SDimitry Andric bool IsArm = false; 318*06c3fb27SDimitry Andric 319*06c3fb27SDimitry Andric switch (Arch) { 320*06c3fb27SDimitry Andric case llvm::Triple::arm: 321*06c3fb27SDimitry Andric case llvm::Triple::thumb: 322*06c3fb27SDimitry Andric ArchName = "arm"; 323*06c3fb27SDimitry Andric IsArm = true; 324*06c3fb27SDimitry Andric break; 325*06c3fb27SDimitry Andric case llvm::Triple::armeb: 326*06c3fb27SDimitry Andric case llvm::Triple::thumbeb: 327*06c3fb27SDimitry Andric ArchName = "armeb"; 328*06c3fb27SDimitry Andric IsArm = true; 329*06c3fb27SDimitry Andric break; 330*06c3fb27SDimitry Andric default: 331*06c3fb27SDimitry Andric ArchName = Triple.getArchName().str(); 332*06c3fb27SDimitry Andric } 333*06c3fb27SDimitry Andric if (IsArm && 334*06c3fb27SDimitry Andric (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)) 335*06c3fb27SDimitry Andric ArchName += "hf"; 336*06c3fb27SDimitry Andric 337*06c3fb27SDimitry Andric return "/lib/ld-musl-" + ArchName + ".so.1"; 338*06c3fb27SDimitry Andric } 339*06c3fb27SDimitry Andric 340*06c3fb27SDimitry Andric std::string OHOS::getCompilerRT(const ArgList &Args, StringRef Component, 341*06c3fb27SDimitry Andric FileType Type) const { 342*06c3fb27SDimitry Andric SmallString<128> Path(getDriver().ResourceDir); 343*06c3fb27SDimitry Andric llvm::sys::path::append(Path, "lib", getMultiarchTriple(getTriple()), 344*06c3fb27SDimitry Andric SelectedMultilib.gccSuffix()); 345*06c3fb27SDimitry Andric const char *Prefix = 346*06c3fb27SDimitry Andric Type == ToolChain::FT_Object ? "" : "lib"; 347*06c3fb27SDimitry Andric const char *Suffix; 348*06c3fb27SDimitry Andric switch (Type) { 349*06c3fb27SDimitry Andric case ToolChain::FT_Object: 350*06c3fb27SDimitry Andric Suffix = ".o"; 351*06c3fb27SDimitry Andric break; 352*06c3fb27SDimitry Andric case ToolChain::FT_Static: 353*06c3fb27SDimitry Andric Suffix = ".a"; 354*06c3fb27SDimitry Andric break; 355*06c3fb27SDimitry Andric case ToolChain::FT_Shared: 356*06c3fb27SDimitry Andric Suffix = ".so"; 357*06c3fb27SDimitry Andric break; 358*06c3fb27SDimitry Andric } 359*06c3fb27SDimitry Andric llvm::sys::path::append( 360*06c3fb27SDimitry Andric Path, Prefix + Twine("clang_rt.") + Component + Suffix); 361*06c3fb27SDimitry Andric return static_cast<std::string>(Path.str()); 362*06c3fb27SDimitry Andric } 363*06c3fb27SDimitry Andric 364*06c3fb27SDimitry Andric void OHOS::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { 365*06c3fb27SDimitry Andric CmdArgs.push_back("-z"); 366*06c3fb27SDimitry Andric CmdArgs.push_back("now"); 367*06c3fb27SDimitry Andric CmdArgs.push_back("-z"); 368*06c3fb27SDimitry Andric CmdArgs.push_back("relro"); 369*06c3fb27SDimitry Andric CmdArgs.push_back("-z"); 370*06c3fb27SDimitry Andric CmdArgs.push_back("max-page-size=4096"); 371*06c3fb27SDimitry Andric // .gnu.hash section is not compatible with the MIPS target 372*06c3fb27SDimitry Andric if (getArch() != llvm::Triple::mipsel) 373*06c3fb27SDimitry Andric CmdArgs.push_back("--hash-style=both"); 374*06c3fb27SDimitry Andric #ifdef ENABLE_LINKER_BUILD_ID 375*06c3fb27SDimitry Andric CmdArgs.push_back("--build-id"); 376*06c3fb27SDimitry Andric #endif 377*06c3fb27SDimitry Andric CmdArgs.push_back("--enable-new-dtags"); 378*06c3fb27SDimitry Andric } 379*06c3fb27SDimitry Andric 380*06c3fb27SDimitry Andric SanitizerMask OHOS::getSupportedSanitizers() const { 381*06c3fb27SDimitry Andric SanitizerMask Res = ToolChain::getSupportedSanitizers(); 382*06c3fb27SDimitry Andric Res |= SanitizerKind::Address; 383*06c3fb27SDimitry Andric Res |= SanitizerKind::PointerCompare; 384*06c3fb27SDimitry Andric Res |= SanitizerKind::PointerSubtract; 385*06c3fb27SDimitry Andric Res |= SanitizerKind::Fuzzer; 386*06c3fb27SDimitry Andric Res |= SanitizerKind::FuzzerNoLink; 387*06c3fb27SDimitry Andric Res |= SanitizerKind::Memory; 388*06c3fb27SDimitry Andric Res |= SanitizerKind::Vptr; 389*06c3fb27SDimitry Andric Res |= SanitizerKind::SafeStack; 390*06c3fb27SDimitry Andric Res |= SanitizerKind::Scudo; 391*06c3fb27SDimitry Andric // TODO: kASAN for liteos ?? 392*06c3fb27SDimitry Andric // TODO: Support TSAN and HWASAN and update mask. 393*06c3fb27SDimitry Andric return Res; 394*06c3fb27SDimitry Andric } 395*06c3fb27SDimitry Andric 396*06c3fb27SDimitry Andric // TODO: Make a base class for Linux and OHOS and move this there. 397*06c3fb27SDimitry Andric void OHOS::addProfileRTLibs(const llvm::opt::ArgList &Args, 398*06c3fb27SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 399*06c3fb27SDimitry Andric // Add linker option -u__llvm_profile_runtime to cause runtime 400*06c3fb27SDimitry Andric // initialization module to be linked in. 401*06c3fb27SDimitry Andric if (needsProfileRT(Args)) 402*06c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString( 403*06c3fb27SDimitry Andric Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); 404*06c3fb27SDimitry Andric ToolChain::addProfileRTLibs(Args, CmdArgs); 405*06c3fb27SDimitry Andric } 406*06c3fb27SDimitry Andric 407*06c3fb27SDimitry Andric ToolChain::path_list OHOS::getArchSpecificLibPaths() const { 408*06c3fb27SDimitry Andric ToolChain::path_list Paths; 409*06c3fb27SDimitry Andric llvm::Triple Triple = getTriple(); 410*06c3fb27SDimitry Andric Paths.push_back( 411*06c3fb27SDimitry Andric makePath({getDriver().ResourceDir, "lib", getMultiarchTriple(Triple)})); 412*06c3fb27SDimitry Andric return Paths; 413*06c3fb27SDimitry Andric } 414*06c3fb27SDimitry Andric 415*06c3fb27SDimitry Andric ToolChain::UnwindLibType OHOS::GetUnwindLibType(const llvm::opt::ArgList &Args) const { 416*06c3fb27SDimitry Andric if (Args.getLastArg(options::OPT_unwindlib_EQ)) 417*06c3fb27SDimitry Andric return Generic_ELF::GetUnwindLibType(Args); 418*06c3fb27SDimitry Andric return GetDefaultUnwindLibType(); 419*06c3fb27SDimitry Andric } 420