diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..7b91e1e2f440ad8877dc39552625f8751ab8f19d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,8 @@ +variables: + TOOLCHAIN_MANIFEST: 'huawei/dev-open-harmonyos' + TOOLCHAIN_NAME: 'HOS-OS' + +include: + - project: 'rus-os-team/compilers/testing/automation/llvm-ci' + ref: 'master-opensource-llvm-15' + file: '/pipelines/llvm/ohos/main.yml' diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index d61f3583281d1dd55fb1f7ed665af1bd96869fce..68f0841c51bddbf8637506bdc4e41af65f3cf6d0 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -901,6 +901,7 @@ def Availability : InheritableAttr { .Case("maccatalyst", "macCatalyst") .Case("maccatalyst_app_extension", "macCatalyst (App Extension)") .Case("swift", "Swift") + .Case("ohos", "OpenHOS") .Default(llvm::StringRef()); } static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) { diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 39dee7e683ff9f7b1232ff451bfaae5234d1bc88..ad5815180c48cfeab0dddf8cec7243edabf4b266 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -308,6 +308,7 @@ def err_target_unsupported_abi_for_triple : Error< def err_unsupported_abi_for_opt : Error<"'%0' can only be used with the '%1' ABI">; def err_mips_fp64_req : Error< "'%0' can only be used if the target supports the mfhc1 and mthc1 instructions">; +def err_unsupported_fpxx_ohos : Error<"fpxx is currently unsupported on OHOS">; def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">; def err_target_unsupported_fpmath : Error< "the '%0' unit is not supported with this instruction set">; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3cab37b21aaf3f4bee4daecb21bd90d3cb5cf069..07d89546eb104f19deb815b77c17107da27b9189 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2910,6 +2910,8 @@ def ffinite_loops: Flag<["-"], "ffinite-loops">, Group, def fno_finite_loops: Flag<["-"], "fno-finite-loops">, Group, HelpText<"Do not assume that any loop is finite.">, Flags<[CC1Option]>; +def fenable_merge_functions : Flag<["-"], "fenable-merge-functions">, Group, + HelpText<"Enables Merge Functions optimization">; def ftrigraphs : Flag<["-"], "ftrigraphs">, Group, HelpText<"Process trigraph sequences">, Flags<[CC1Option]>; def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index f20ab164531b8274a4ac574699d99c644107ac94..4f9d52ad9be16732fbc829523fc02f91449e8597 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -482,7 +482,8 @@ public: // Returns /lib//. This is used by runtimes (such // as OpenMP) to find arch-specific libraries. - std::string getArchSpecificLibPath() const; + // OHOS specific: make this function virtual to override in OHOS.cpp + virtual std::string getArchSpecificLibPath() const; // Returns part of above. virtual StringRef getOSLibName() const; diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 6685145ea6d2e4004d0a830215919f6034ec1e7b..b4b1af20a64d26132ab0cd41cff66ead60f49c3c 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -71,7 +71,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html. // This alignment guarantee also applies to Windows and Android. On Darwin // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems. - if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid()) + if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() || T.isOHOSFamily()) NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; else if (T.isOSDarwin() || T.isOSOpenBSD()) NewAlign = 128; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 2d6ef998485ae1404e561dc12f962ce1bef2996d..d2eac5cae7b6ae9cd9fe044a2e2ca317b00f52cd 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -146,7 +146,12 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Fuchsia: return new FuchsiaTargetInfo(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } case llvm::Triple::NetBSD: return new NetBSDTargetInfo(Triple, Opts); case llvm::Triple::OpenBSD: @@ -186,7 +191,14 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::CloudABI: return new CloudABITargetInfo(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } + case llvm::Triple::LiteOS: + return new OHOSTargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo(Triple, Opts); case llvm::Triple::NetBSD: @@ -261,7 +273,12 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::mipsel: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } case llvm::Triple::RTEMS: return new RTEMSTargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: @@ -421,7 +438,12 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Fuchsia: return new FuchsiaTargetInfo(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } default: return new RISCV64TargetInfo(Triple, Opts); } @@ -559,6 +581,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo(Triple, Opts); case llvm::Triple::Android: return new AndroidX86_64TargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSX86_64TargetInfo(Triple, Opts); } } case llvm::Triple::DragonFly: diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index b2f61cff81c9586f0cf31cb0e3c938f9f258d761..fd005a6570fb545172ad11a51cbb5334bbc96f03 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -317,7 +317,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, default: if (IsNetBSD) setABI("apcs-gnu"); - else if (IsOpenBSD) + else if (IsOpenBSD || Triple.isOHOSFamily()) setABI("aapcs-linux"); else setABI("aapcs"); diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index 39246f650cce26cd8e4d7ad53826296adddb07b4..706e0826f764b4ab935ac82fdaa4bd5d70efdd80 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -269,6 +269,12 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { return false; } + // TODO: remove this if entry when fpxx is supported on OHOS + if (getTriple().isOpenHOS() && FPMode == FPXX) { + Diags.Report(diag::err_unsupported_fpxx_ohos); + return false; + } + // -fpxx is valid only for the o32 ABI if (FPMode == FPXX && (ABI == "n32" || ABI == "n64")) { Diags.Report(diag::err_unsupported_abi_for_opt) << "-mfpxx" << "o32"; diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index b54d36e1c95f2b74fc2023733e774dfa35aa549a..966def9632ad2df661d27bc85787630eed70765a 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -86,7 +86,10 @@ public: } bool isFP64Default() const { - return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64"; + // TODO: remove getTriple().isOpenHOS() case + // when fpxx is supported on OHOS + return getTriple().isOpenHOS() || CPU == "mips32r6" || ABI == "n32" || + ABI == "n64" || ABI == "64"; } bool isNan2008() const override { return IsNan2008; } diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index a814f681b1468c7628daf6f5c9c6d723155821b0..878efbf48317c74f9ddc9648335e289ff087e79a 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -1013,6 +1013,68 @@ public: } }; +// OHOS target +template +class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + // Linux defines; list based off of gcc output + DefineStd(Builder, "unix", Opts); + + Builder.defineMacro("__ELF__"); + + // Generic OHOS target defines + if (Triple.isOHOSFamily()) { + Builder.defineMacro("__OHOS_FAMILY__", "1"); + + auto Version = Triple.getEnvironmentVersion(); + this->PlatformName = "ohos"; + this->PlatformMinVersion = Version; + Builder.defineMacro("__OHOS_Major__", Twine(Version.getMajor())); + if (auto Minor = Version.getMinor()) + Builder.defineMacro("__OHOS_Minor__", Twine(*Minor)); + if (auto Subminor = Version.getSubminor()) + Builder.defineMacro("__OHOS_Micro__", Twine(*Subminor)); + } + + if (Triple.isOpenHOS()) + Builder.defineMacro("__OHOS__"); + + if (Triple.isOSLinux()) { + DefineStd(Builder, "linux", Opts); + } else if (Triple.isOSLiteOS()) { + Builder.defineMacro("__LITEOS__"); + } + + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); + } + +public: + OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo(Triple, Opts) { + this->WIntType = TargetInfo::UnsignedInt; + + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->HasFloat128 = true; + break; + } + } + + const char *getStaticInitSectionSpecifier() const override { + return ".text.startup"; + } +}; + } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index ed0864aec6d2d2c986b994472a89f2dc08b23f8e..0d5d068741a5d5b7fd689ea93c1a6a66219775bb 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -943,6 +943,28 @@ public: LongDoubleFormat = &llvm::APFloat::IEEEquad(); } }; + +// x86_32 OHOS target +class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo + : public OHOSTargetInfo { +public: + OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OHOSTargetInfo(Triple, Opts) { + SuitableAlign = 32; + LongDoubleWidth = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } +}; + +// x86_64 OHOS target +class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo + : public OHOSTargetInfo { +public: + OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OHOSTargetInfo(Triple, Opts) { + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } +}; } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h index c1eb8a9757962a63d22dbe0681ea56b743404419..250272fb8d238ccef8ae55de2a8b24e04a150077 100644 --- a/clang/lib/CodeGen/ABIInfo.h +++ b/clang/lib/CodeGen/ABIInfo.h @@ -85,6 +85,7 @@ namespace CodeGen { QualType Ty) const = 0; bool isAndroid() const; + bool isOHOSFamily() const; /// Emit the target dependent code to load a value of /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 36e10e4df4c192335533a6bc1103d055fc39579e..3e667abc6f1c269dfe25ddca83eff27807551828 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -231,6 +231,10 @@ const CodeGenOptions &ABIInfo::getCodeGenOpts() const { bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); } +bool ABIInfo::isOHOSFamily() const { + return getTarget().getTriple().isOHOSFamily(); +} + bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { return false; } @@ -5726,7 +5730,7 @@ ABIArgInfo AArch64ABIInfo::coerceIllegalVector(QualType Ty) const { uint64_t Size = getContext().getTypeSize(Ty); // Android promotes <2 x i8> to i16, not i32 - if (isAndroid() && (Size <= 16)) { + if ((isAndroid() || isOHOSFamily()) && (Size <= 16)) { llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext()); return ABIArgInfo::getDirect(ResType); } @@ -6323,7 +6327,7 @@ public: case llvm::Triple::MuslEABIHF: return true; default: - return false; + return getTarget().getTriple().isOHOSFamily(); } } diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 18c9b2d042f6c6e27382a4c72119250533e93482..7be7f959e896f7c3eb6b0bc30b639607a090a51b 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -71,6 +71,7 @@ add_clang_library(clangDriver ToolChains/Myriad.cpp ToolChains/NaCl.cpp ToolChains/NetBSD.cpp + ToolChains/OHOS.cpp ToolChains/OpenBSD.cpp ToolChains/PS4CPU.cpp ToolChains/RISCVToolchain.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 3f29afd359718a1c21e9c9911f0e6ad5f1002a3a..cbd2ff494de91b77695f271efc6a7f434c79064d 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -40,6 +40,7 @@ #include "ToolChains/Myriad.h" #include "ToolChains/NaCl.h" #include "ToolChains/NetBSD.h" +#include "ToolChains/OHOS.h" #include "ToolChains/OpenBSD.h" #include "ToolChains/PPCFreeBSD.h" #include "ToolChains/PPCLinux.h" @@ -5999,7 +6000,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, Args); else if (Target.getArch() == llvm::Triple::ve) TC = std::make_unique(*this, Target, Args); - + else if (Target.isOHOSFamily()) + TC = std::make_unique(*this, Target, Args); else TC = std::make_unique(*this, Target, Args); break; @@ -6060,6 +6062,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Hurd: TC = std::make_unique(*this, Target, Args); break; + case llvm::Triple::LiteOS: + TC = std::make_unique(*this, Target, Args); + break; case llvm::Triple::ZOS: TC = std::make_unique(*this, Target, Args); break; diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index cf7e201b4972cc913a8e5d7f7468e04736fc65f3..b497c14b79023a06392a8eda128ba6604b363704 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -608,7 +608,7 @@ fp16_fml_fallthrough: Features.push_back("+fix-cortex-a53-835769"); else Features.push_back("-fix-cortex-a53-835769"); - } else if (Triple.isAndroid()) { + } else if (Triple.isAndroid() || Triple.isOHOSFamily()) { // Enabled A53 errata (835769) workaround by default on android Features.push_back("+fix-cortex-a53-835769"); } diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index a64909d9a6e77a126a249b083d674afaf73df2bb..1f199fcd8d834ce08d98043157460ae3559ecfce 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -276,6 +276,11 @@ void arm::setArchNameInTriple(const Driver &D, const ArgList &Args, void arm::setFloatABIInTriple(const Driver &D, const ArgList &Args, llvm::Triple &Triple) { + if (Triple.isOSLiteOS()) { + Triple.setEnvironment(llvm::Triple::OpenHOS); + return; + } + bool isHardFloat = (arm::getARMFloatABI(D, Triple, Args) == arm::FloatABI::Hard); @@ -295,6 +300,8 @@ void arm::setFloatABIInTriple(const Driver &D, const ArgList &Args, Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF : llvm::Triple::MuslEABI); break; + case llvm::Triple::OpenHOS: + break; default: { arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple); if (DefaultABI != arm::FloatABI::Invalid && @@ -364,6 +371,8 @@ arm::FloatABI arm::getDefaultFloatABI(const llvm::Triple &Triple) { return FloatABI::SoftFP; default: + if (Triple.isOHOSFamily()) + return FloatABI::Soft; switch (Triple.getEnvironment()) { case llvm::Triple::GNUEABIHF: case llvm::Triple::MuslEABIHF: diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp index c374d745da384daa11e8592c625ee058d881d54f..68a86974e6f18f32a7a0123d6bfcf905857acefc 100644 --- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp @@ -362,6 +362,9 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, } else if (mips::isFP64ADefault(Triple, CPUName)) { Features.push_back("+fp64"); Features.push_back("+nooddspreg"); + } else if (Triple.isOpenHOS()) { + // TODO: remove this else if entry when fpxx is supported on OHOS + Features.push_back("+fp64"); } AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg, @@ -467,6 +470,10 @@ bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) { bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName, StringRef ABIName, mips::FloatABI FloatABI) { + // TODO: remove this if entry when fpxx is supported on OHOS + if (Triple.isOpenHOS()) + return false; + if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies && Triple.getVendor() != llvm::Triple::MipsTechnologies && !Triple.isAndroid()) diff --git a/clang/lib/Driver/ToolChains/BareMetal.h b/clang/lib/Driver/ToolChains/BareMetal.h index dc718e09ad43eafc593bdba52aa66f36ee479b73..95970f7421ca53901bced3ab8eda979ae2b89175 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.h +++ b/clang/lib/Driver/ToolChains/BareMetal.h @@ -39,7 +39,7 @@ protected: bool AddArch = true) const override; public: - bool useIntegratedAs() const override { return true; } + bool IsIntegratedAssemblerDefault() const override { return true; } bool isCrossCompiling() const override { return true; } bool isPICDefault() const override { return false; } bool isPIEDefault(const llvm::opt::ArgList &Args) const override { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3704ed8586682677882acb8e1b82bfc14b1d07a5..3d5ddba6c0fbefa82f5d5be8bd47e803b2a14790 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6264,6 +6264,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fstrict_flex_arrays_EQ); + if (Args.hasArg(options::OPT_fenable_merge_functions)) + CmdArgs.push_back(Args.MakeArgString("-fmerge-functions")); + Args.AddLastArg(CmdArgs, options::OPT_pthread); if (Args.hasFlag(options::OPT_mspeculative_load_hardening, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 443725f7d8a8df1aa5a809b9e70399217c6a4831..84946b9e6d258baf029eb686a86d111fd80e36e4 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -828,7 +828,7 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, CmdArgs.push_back(getAsNeededOption(TC, false)); // There's no libpthread or librt on RTEMS & Android. if (TC.getTriple().getOS() != llvm::Triple::RTEMS && - !TC.getTriple().isAndroid()) { + !TC.getTriple().isAndroid() && !TC.getTriple().isOHOSFamily()) { CmdArgs.push_back("-lpthread"); if (!TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lrt"); @@ -1243,6 +1243,18 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { } } + // OHOS-specific defaults for PIC/PIE + if (Triple.isOHOSFamily()) { + switch (Triple.getArch()) { + case llvm::Triple::aarch64: + PIC = true; // "-fpic" + break; + + default: + break; + } + } + // OpenBSD-specific defaults for PIE if (Triple.isOSOpenBSD()) { switch (ToolChain.getArch()) { @@ -1505,6 +1517,11 @@ static LibGccType getLibGccType(const ToolChain &TC, const Driver &D, static void AddUnwindLibrary(const ToolChain &TC, const Driver &D, ArgStringList &CmdArgs, const ArgList &Args) { ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args); + if (TC.getTriple().isOHOSFamily() && UNW != ToolChain::UNW_None) { + CmdArgs.push_back("-l:libunwind.a"); + return; + } + // Targets that don't use unwind libraries. if ((TC.getTriple().isAndroid() && UNW == ToolChain::UNW_Libgcc) || TC.getTriple().isOSIAMCU() || TC.getTriple().isOSBinFormatWasm() || diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index f203cae1d329ffb81cc29e5583c4da4a6911695e..4cb7cbcf3c2156646d516376530cfe74a7954c90 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -398,6 +398,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); const llvm::Triple::ArchType Arch = ToolChain.getArch(); + const bool isOHOSFamily = ToolChain.getTriple().isOHOSFamily(); const bool isAndroid = ToolChain.getTriple().isAndroid(); const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); const bool IsVE = ToolChain.getTriple().isVE(); @@ -448,7 +449,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Most Android ARM64 targets should enable the linker fix for erratum // 843419. Only non-Cortex-A53 devices are allowed to skip this flag. - if (Arch == llvm::Triple::aarch64 && isAndroid) { + if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) { std::string CPU = getCPUName(D, Args, Triple); if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53") CmdArgs.push_back("--fix-cortex-a53-843419"); @@ -641,7 +642,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--pop-state"); } - if (WantPthread && !isAndroid) + // We don't need libpthread neither for bionic nor for musl + if (WantPthread && !isAndroid && !isOHOSFamily) CmdArgs.push_back("-lpthread"); if (Args.hasArg(options::OPT_fsplit_stack)) @@ -2239,7 +2241,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"}; static const char *const MIPSELLibDirs[] = {"/libo32", "/lib"}; static const char *const MIPSELTriples[] = { - "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu"}; + "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu", + "mipsel-linux-ohos"}; static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"}; static const char *const MIPS64Triples[] = { diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp new file mode 100644 index 0000000000000000000000000000000000000000..64dcec7bb1f299c8b3c9a26f7e1da93866f06cec --- /dev/null +++ b/clang/lib/Driver/ToolChains/OHOS.cpp @@ -0,0 +1,421 @@ +//===--- OHOS.cpp - OHOS ToolChain Implementations --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "OHOS.h" +#include "Arch/ARM.h" +#include "CommonArgs.h" +#include "clang/Config/config.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" +#include "llvm/Option/ArgList.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" +#include "llvm/Support/ScopedPrinter.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; +using namespace clang::driver::tools::arm; + +using tools::addMultilibFlag; +using tools::addPathIfExists; + +static bool findOHOSMuslMultilibs(const Multilib::flags_list &Flags, + DetectedMultilibs &Result) { + MultilibSet Multilibs; + Multilibs.push_back(Multilib()); + // -mcpu=cortex-a7 + // -mfloat-abi=soft -mfloat-abi=softfp -mfloat-abi=hard + // -mfpu=neon-vfpv4 + Multilibs.push_back(Multilib("a7_soft", {}, {}, 1) + .flag("+mcpu=cortex-a7") + .flag("+mfloat-abi=soft")); + + Multilibs.push_back(Multilib("a7_softfp_neon-vfpv4", {}, {}, 1) + .flag("+mcpu=cortex-a7") + .flag("+mfloat-abi=softfp") + .flag("+mfpu=neon-vfpv4")); + + Multilibs.push_back(Multilib("a7_hard_neon-vfpv4", {}, {}, 1) + .flag("+mcpu=cortex-a7") + .flag("+mfloat-abi=hard") + .flag("+mfpu=neon-vfpv4")); + + if (Multilibs.select(Flags, Result.SelectedMultilib)) { + Result.Multilibs = Multilibs; + return true; + } + return false; +} + +static bool findOHOSMultilibs(const Driver &D, + const ToolChain &TC, + const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + DetectedMultilibs &Result) { + Multilib::flags_list Flags; + bool IsA7 = false; + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + IsA7 = A->getValue() == StringRef("cortex-a7"); + addMultilibFlag(IsA7, "mcpu=cortex-a7", Flags); + + bool IsMFPU = false; + if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) + IsMFPU = A->getValue() == StringRef("neon-vfpv4"); + addMultilibFlag(IsMFPU, "mfpu=neon-vfpv4", Flags); + + tools::arm::FloatABI ARMFloatABI = getARMFloatABI(D, TargetTriple, Args); + addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Soft), + "mfloat-abi=soft", Flags); + addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::SoftFP), + "mfloat-abi=softfp", Flags); + addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Hard), + "mfloat-abi=hard", Flags); + + return findOHOSMuslMultilibs(Flags, Result); +} + +std::string OHOS::getMultiarchTriple(const llvm::Triple &T) const { + // For most architectures, just use whatever we have rather than trying to be + // clever. + switch (T.getArch()) { + default: + break; + + // We use the existence of '/lib/' as a directory to detect some + // common linux triples that don't quite match the Clang triple for both + // 32-bit and 64-bit targets. Multiarch fixes its install triples to these + // regardless of what the actual target triple is. + case llvm::Triple::arm: + case llvm::Triple::thumb: + return T.isOSLiteOS() ? "arm-liteos-ohos" : "arm-linux-ohos"; + case llvm::Triple::riscv32: + return "riscv32-liteos-ohos"; + case llvm::Triple::riscv64: + return "riscv64-linux-ohos"; + case llvm::Triple::mipsel: + return "mipsel-linux-ohos"; + case llvm::Triple::x86: + return "i686-linux-ohos"; + case llvm::Triple::x86_64: + return "x86_64-linux-ohos"; + case llvm::Triple::aarch64: + return "aarch64-linux-ohos"; + } + return T.str(); +} + +std::string OHOS::getMultiarchTriple(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef SysRoot) const { + return getMultiarchTriple(TargetTriple); +} + +static std::string makePath(const std::initializer_list &IL) { + SmallString<128> P; + for (const auto &S : IL) + llvm::sys::path::append(P, S); + return static_cast(P.str()); +} + +/// OHOS Toolchain +OHOS::OHOS(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + std::string SysRoot = computeSysRoot(); + + // Select the correct multilib according to the given arguments. + DetectedMultilibs Result; + findOHOSMultilibs(D, *this, Triple, "", Args, Result); + Multilibs = Result.Multilibs; + SelectedMultilib = Result.SelectedMultilib; + + getFilePaths().clear(); + std::string CandidateLibPath = getArchSpecificLibPath(); + if (getVFS().exists(CandidateLibPath)) + getFilePaths().push_back(CandidateLibPath); + + getLibraryPaths().clear(); + for (auto &Path : getRuntimePaths()) + if (getVFS().exists(Path)) + getLibraryPaths().push_back(Path); + + // OHOS sysroots contain a library directory for each supported OS + // version as well as some unversioned libraries in the usual multiarch + // directory. Support --target=aarch64-linux-ohosX.Y.Z or + // --target=aarch64-linux-ohosX.Y or --target=aarch64-linux-ohosX + path_list &Paths = getFilePaths(); + std::string SysRootLibPath = makePath({SysRoot, "usr", "lib"}); + std::string MultiarchTriple = getMultiarchTriple(getTriple()); + addPathIfExists(D, makePath({SysRootLibPath, SelectedMultilib.gccSuffix()}), + Paths); + addPathIfExists(D, + makePath({D.Dir, "..", "lib", MultiarchTriple, + SelectedMultilib.gccSuffix()}), + Paths); + + // For compatibility with arm-liteos sysroot + // FIXME: Remove this when we'll use arm-liteos sysroot produced by build.py. + addPathIfExists( + D, + makePath({SysRootLibPath, MultiarchTriple, SelectedMultilib.gccSuffix()}), + Paths); +} + +ToolChain::RuntimeLibType OHOS::GetRuntimeLibType( + const ArgList &Args) const { + if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) { + StringRef Value = A->getValue(); + if (Value != "compiler-rt") + getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name) + << A->getAsString(Args); + } + + return ToolChain::RLT_CompilerRT; +} + +ToolChain::CXXStdlibType +OHOS::GetCXXStdlibType(const ArgList &Args) const { + if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { + StringRef Value = A->getValue(); + if (Value != "libc++") + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); + } + + return ToolChain::CST_Libcxx; +} + +void OHOS::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + const llvm::Triple &Triple = getTriple(); + std::string SysRoot = computeSysRoot(); + + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; + addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); + } + return; + } + + addExternCSystemInclude(DriverArgs, CC1Args, + SysRoot + "/usr/include/" + + getMultiarchTriple(Triple)); + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); +} + +void OHOS::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + switch (GetCXXStdlibType(DriverArgs)) { + case ToolChain::CST_Libcxx: { + std::string IncPath = makePath({getDriver().Dir, "..", "include"}); + std::string IncTargetPath = + makePath({IncPath, getMultiarchTriple(getTriple()), "c++", "v1"}); + if (getVFS().exists(IncTargetPath)) { + addSystemInclude(DriverArgs, CC1Args, makePath({IncPath, "c++", "v1"})); + addSystemInclude(DriverArgs, CC1Args, IncTargetPath); + } + break; + } + + default: + llvm_unreachable("invalid stdlib name"); + } +} + +void OHOS::AddCXXStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + switch (GetCXXStdlibType(Args)) { + case ToolChain::CST_Libcxx: + CmdArgs.push_back("-lc++"); + CmdArgs.push_back("-lc++abi"); + CmdArgs.push_back("-lunwind"); + break; + + case ToolChain::CST_Libstdcxx: + llvm_unreachable("invalid stdlib name"); + } +} + +std::string OHOS::computeSysRoot() const { + std::string SysRoot = + !getDriver().SysRoot.empty() + ? getDriver().SysRoot + : makePath({getDriver().getInstalledDir(), "..", "..", "sysroot"}); + if (!llvm::sys::fs::exists(SysRoot)) + return std::string(); + + std::string ArchRoot = makePath({SysRoot, getMultiarchTriple(getTriple())}); + return llvm::sys::fs::exists(ArchRoot) ? ArchRoot : SysRoot; +} + +ToolChain::path_list OHOS::getRuntimePaths() const { + SmallString<128> P; + path_list Paths; + const Driver &D = getDriver(); + const llvm::Triple &Triple = getTriple(); + + // First try the triple passed to driver as --target=. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, "lib", D.getTargetTriple(), SelectedMultilib.gccSuffix()); + Paths.push_back(P.c_str()); + + // Second try the normalized triple. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, "lib", Triple.str(), SelectedMultilib.gccSuffix()); + Paths.push_back(P.c_str()); + + // Third try the effective triple. + P.assign(D.ResourceDir); + std::string SysRoot = computeSysRoot(); + llvm::sys::path::append(P, "lib", getMultiarchTriple(Triple), + SelectedMultilib.gccSuffix()); + Paths.push_back(P.c_str()); + + return Paths; +} + +std::string OHOS::getDynamicLinker(const ArgList &Args) const { + const llvm::Triple &Triple = getTriple(); + const llvm::Triple::ArchType Arch = getArch(); + + assert(Triple.isMusl()); + std::string ArchName; + bool IsArm = false; + + switch (Arch) { + case llvm::Triple::arm: + case llvm::Triple::thumb: + ArchName = "arm"; + IsArm = true; + break; + case llvm::Triple::armeb: + case llvm::Triple::thumbeb: + ArchName = "armeb"; + IsArm = true; + break; + default: + ArchName = Triple.getArchName().str(); + } + if (IsArm && + (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)) + ArchName += "hf"; + + return "/lib/ld-musl-" + ArchName + ".so.1"; +} + +std::string OHOS::getCompilerRT(const ArgList &Args, StringRef Component, + FileType Type) const { + SmallString<128> Path(getDriver().ResourceDir); + llvm::sys::path::append(Path, "lib", getMultiarchTriple(getTriple()), + SelectedMultilib.gccSuffix()); + const char *Prefix = + Type == ToolChain::FT_Object ? "" : "lib"; + const char *Suffix; + switch (Type) { + case ToolChain::FT_Object: + Suffix = ".o"; + break; + case ToolChain::FT_Static: + Suffix = ".a"; + break; + case ToolChain::FT_Shared: + Suffix = ".so"; + break; + } + llvm::sys::path::append( + Path, Prefix + Twine("clang_rt.") + Component + Suffix); + return static_cast(Path.str()); +} + +void OHOS::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + CmdArgs.push_back("-z"); + CmdArgs.push_back("now"); + CmdArgs.push_back("-z"); + CmdArgs.push_back("relro"); + CmdArgs.push_back("-z"); + CmdArgs.push_back("max-page-size=4096"); + // .gnu.hash section is not compatible with the MIPS target + if (getArch() != llvm::Triple::mipsel) { + CmdArgs.push_back("--hash-style=gnu"); + // FIXME: gnu or both??? + CmdArgs.push_back("--hash-style=both"); + } +#ifdef ENABLE_LINKER_BUILD_ID + CmdArgs.push_back("--build-id"); +#endif + CmdArgs.push_back("--enable-new-dtags"); +} + +SanitizerMask OHOS::getSupportedSanitizers() const { + SanitizerMask Res = ToolChain::getSupportedSanitizers(); + Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; + Res |= SanitizerKind::Fuzzer; + Res |= SanitizerKind::FuzzerNoLink; + Res |= SanitizerKind::Memory; + Res |= SanitizerKind::Vptr; + Res |= SanitizerKind::SafeStack; + Res |= SanitizerKind::Scudo; + // TODO: kASAN for liteos ?? + // TODO: Support TSAN and HWASAN and update mask. + return Res; +} + +// TODO: Make a base class for Linux and OHOS and move this there. +void OHOS::addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + // Add linker option -u__llvm_profile_runtime to cause runtime + // initialization module to be linked in. + if (needsProfileRT(Args)) + CmdArgs.push_back(Args.MakeArgString( + Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); + ToolChain::addProfileRTLibs(Args, CmdArgs); +} + +std::string OHOS::getArchSpecificLibPath() const { + llvm::Triple Triple = getTriple(); + return makePath({getDriver().ResourceDir, "lib", getMultiarchTriple(Triple)}); +} + +ToolChain::UnwindLibType OHOS::GetUnwindLibType(const llvm::opt::ArgList &Args) const { + if (const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ)) + return Generic_ELF::GetUnwindLibType(Args); + return GetDefaultUnwindLibType(); +} diff --git a/clang/lib/Driver/ToolChains/OHOS.h b/clang/lib/Driver/ToolChains/OHOS.h new file mode 100644 index 0000000000000000000000000000000000000000..1d826122e239739db26a5af03560fd6372171700 --- /dev/null +++ b/clang/lib/Driver/ToolChains/OHOS.h @@ -0,0 +1,97 @@ +//===--- OHOS.h - OHOS ToolChain Implementations ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H + +#include "Linux.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY OHOS : public Generic_ELF { +public: + OHOS(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + + bool HasNativeLLVMSupport() const override { return true; } + bool IsIntegratedAssemblerDefault() const override { return true; } + bool IsMathErrnoDefault() const override { return false; } + RuntimeLibType GetDefaultRuntimeLibType() const override { + return ToolChain::RLT_CompilerRT; + } + CXXStdlibType GetDefaultCXXStdlibType() const override { + return ToolChain::CST_Libcxx; + } + // Not add -funwind-tables by default + bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override { + return false; + } + bool isPICDefault() const override { return false; } + bool isPIEDefault(const llvm::opt::ArgList &Args) const override { return true; } + bool isPICDefaultForced() const override { return false; } + bool useRelaxRelocations() const override { return false; } + UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override; + UnwindLibType GetDefaultUnwindLibType() const override { return UNW_CompilerRT; } + + RuntimeLibType + GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; + CXXStdlibType + GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; + + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void + AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + + std::string computeSysRoot() const override; + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + std::string + getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, + FileType Type = ToolChain::FT_Static) const override; + + const char *getDefaultLinker() const override { + return "ld.lld"; + } + + Tool *buildLinker() const override { + return new tools::gnutools::Linker(*this); + } + Tool *buildAssembler() const override { + return new tools::gnutools::Assembler(*this); + } + + path_list getRuntimePaths() const; + +protected: + std::string getMultiarchTriple(const llvm::Triple &T) const; + std::string getMultiarchTriple(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef SysRoot) const override; + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; + SanitizerMask getSupportedSanitizers() const override; + void addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + std::string getArchSpecificLibPath() const override; +private: + Multilib SelectedMultilib; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H diff --git a/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c b/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c index 3ce5b9d122176e68c3b69a4b0d49919509fd248c..3d1a2c7aceb1f1ab633d3f59c9dd201565a0089b 100644 --- a/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c +++ b/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c @@ -7,6 +7,8 @@ // RUN: %clang -O3 -target aarch64-android-eabi %s -S -o- \ // RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s +// RUN: %clang -O3 -target aarch64-linux-ohos %s -S -o- \ +// RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s // RUN: %clang -O3 -target aarch64-android-eabi -mfix-cortex-a53-835769 %s -S -o- \ // RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s // RUN: %clang -O3 -target aarch64-android-eabi -mno-fix-cortex-a53-835769 %s -S -o- \ diff --git a/clang/test/CodeGen/arm64-abi-vector.c b/clang/test/CodeGen/arm64-abi-vector.c index 10f721ab1f2f928e972884a77980eca0359dcdfb..677639bb3c1da5041ddd95f136f1a4f19bba4f27 100644 --- a/clang/test/CodeGen/arm64-abi-vector.c +++ b/clang/test/CodeGen/arm64-abi-vector.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios7 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -no-opaque-pointers -triple aarch64-linux-android -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s +// RUN: %clang_cc1 -no-opaque-pointers -triple aarch64-linux-ohos -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s #include diff --git a/clang/test/CodeGen/merge-functions.c b/clang/test/CodeGen/merge-functions.c new file mode 100644 index 0000000000000000000000000000000000000000..7e382853cc7c35b62139ee0ba2adcae3284d2d11 --- /dev/null +++ b/clang/test/CodeGen/merge-functions.c @@ -0,0 +1,22 @@ +// Check that code gen really activates function merging. In this case +// just check a trivial functions merging case. + +// RUN: %clang_cc1 -emit-llvm %s -fmerge-functions -o - | FileCheck %s + +void foo1() {} +void foo2() {} + +int main() { + + // If merge functions pass is enabled, + // then second and first calls will refer to foo1 + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo1(); + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo2(); + + return 0; +} + diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/bin/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/bin/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/include/c++/v1/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/include/c++/v1/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libc++.so new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_soft/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_soft/libc++.so new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libc++.so new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/libc++.so new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtbegin.o new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtend.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtend.o new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.profile.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.profile.a new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtbegin.o new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtend.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtend.o new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.profile.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.profile.a new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtbegin.o new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtend.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtend.o new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.profile.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.profile.a new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtbegin.o new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtend.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtend.o new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.builtins.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.builtins.a new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.profile.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.profile.a new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/arm-liteos-ohos/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/arm-liteos-ohos/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_soft/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_soft/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Driver/as-fno-integrated-as.c b/clang/test/Driver/as-fno-integrated-as.c new file mode 100644 index 0000000000000000000000000000000000000000..866cc421e5221e4eef64e34021401e942201f6ad --- /dev/null +++ b/clang/test/Driver/as-fno-integrated-as.c @@ -0,0 +1,3 @@ +// Make sure that for BareMetal toolchain, we able to +// disable the use of integrated assembler. +// RUN: %clang -Werror --target="arm-none-eabi" -fno-integrated-as -c %s diff --git a/clang/test/Driver/fenable-merge-functions.cpp b/clang/test/Driver/fenable-merge-functions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f45cdd3b09e9bbb4eab2029344f6eec92d99261e --- /dev/null +++ b/clang/test/Driver/fenable-merge-functions.cpp @@ -0,0 +1,28 @@ +// First. Check that option is passed into clangcc1 +// RUN: %clang -fenable-merge-functions -### %s 2>&1 | FileCheck %s -check-prefix=CHECK_CC1 +// CHECK_CC1: "-cc1" {{.*}} "-fmerge-functions" + +// Second. Check that code gen really activates function merging. In this case +// just check a trivial functions merging case. +// One may say, that this is an superfluous check, +// for it is covered by clang/test/CodeGen/merge-functions.c +// But it is worth keeping, because it also checks whole driver + clang interaction chain. + +// RUN: %clang -emit-llvm %s -fenable-merge-functions -c -S -o - | FileCheck %s + +void foo1() {} +void foo2() {} + +int main() { + + // If merge functions pass is enabled, + // then second and first calls will refer to foo1 + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo1(); + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo2(); + + return 0; +} diff --git a/clang/test/Driver/ohos.c b/clang/test/Driver/ohos.c new file mode 100644 index 0000000000000000000000000000000000000000..480519c54112d5e012351ef19cd3e5616ac2ae01 --- /dev/null +++ b/clang/test/Driver/ohos.c @@ -0,0 +1,241 @@ +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-liteos \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARM %s +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-liteos \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARM-A7-SOFT %s +// CHECK: {{.*}}clang{{.*}}" "-cc1" +// CHECK-NOT: "--mrelax-relocations" +// CHECK-NOT: "-munwind-tables" +// CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" +// CHECK-NOT: "-fsanitize=safe-stack" +// CHECK-NOT: "-stack-protector" "2" +// CHECK-NOT: "-fno-common" +// CHECK: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-NOT: "--sysroot=[[SYSROOT]]" +// CHECK: "-pie" +// CHECK-NOT: "--build-id" +// CHECK: "--hash-style=gnu" +// CHECK: "--hash-style=both" +// CHECK: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK: Scrt1.o +// CHECK: crti.o +// CHECK: clang_rt.crtbegin.o +// CHECK-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" +// CHECK-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" +// CHECK-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-ARM-A7-SOFT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos/a7_soft{{/|\\\\}}libclang_rt.builtins.a" +// CHECK: "-lc" +// CHECK: clang_rt.crtend.o +// CHECK: crtn.o + +// RUN: %clang %s -### --target=arm-liteos -rtlib=libgcc -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RTLIB +// CHECK-RTLIB: error: invalid runtime library name in argument '-rtlib=libgcc' + +// RUN: %clang %s -### --target=arm-liteos -static -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC +// CHECK-STATIC: "-static" +// CHECK-STATIC-NOT: "-Bdynamic" +// CHECK-STATIC: "-l:libunwind.a" +// CHECK-STATIC: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -shared -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-SHARED +// CHECK-SHARED-NOT: "-pie" +// CHECK-SHARED: "-shared" +// CHECK-SHARED: "-lc" +// CHECK-SHARED: "-l:libunwind.a" + +// RUN: %clang %s -### --target=arm-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// RUN: %clang %s -### --target=aarch64-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// RUN: %clang %s -### --target=mipsel-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// RUN: %clang %s -### --target=x86_64-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// CHECK-RUNTIME: "{{.*}}/libclang_rt.builtins.a" +// CHECK-RUNTIME: "-l:libunwind.a" +// CHECK-LIBM: "-lm" + +// RUN: %clang %s -### --target=arm-liteos -r -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RELOCATABLE +// CHECK-RELOCATABLE-NOT: "-pie" +// CHECK-RELOCATABLE-NOT: "--build-id" +// CHECK-RELOCATABLE: "-r" + +// RUN: %clang %s -### --target=arm-liteos -nodefaultlibs -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NODEFAULTLIBS +// CHECK-NODEFAULTLIBS: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NODEFAULTLIBS-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NODEFAULTLIBS-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -nostdlib -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIB +// CHECK-NOSTDLIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOSTDLIB-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NOSTDLIB-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -nolibc -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOLIBC +// CHECK-NOLIBC: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOLIBC: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NOLIBC-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=safe-stack 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SAFESTACK +// CHECK-SAFESTACK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SAFESTACK: "-fsanitize=safe-stack" +// CHECK-SAFESTACK: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.safestack.a" +// CHECK-SAFESTACK: "__safestack_init" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=address 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-ARM +// CHECK-ASAN-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-ASAN-ARM: "-fsanitize=address" +// CHECK-ASAN-ARM: "-fsanitize-address-use-after-scope" +// CHECK-ASAN-ARM: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-ASAN-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan.a" +// CHECK-ASAN-ARM-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan-preinit.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=address -fPIC -shared 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -shared-libsan \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-SHARED +// CHECK-ASAN-SHARED: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-ASAN-SHARED: "-fsanitize=address" +// CHECK-ASAN-SHARED: "-fsanitize-address-use-after-scope" +// CHECK-ASAN-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan.so" +// CHECK-ASAN-SHARED-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan-preinit.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=fuzzer 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-FUZZER-ARM +// CHECK-FUZZER-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-FUZZER-ARM: "-fsanitize=fuzzer,fuzzer-no-link" +// CHECK-FUZZER-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.fuzzer.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=scudo 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SCUDO-ARM +// CHECK-SCUDO-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SCUDO-ARM: "-fsanitize=scudo" +// CHECK-SCUDO-ARM: "-pie" +// CHECK-SCUDO-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.scudo.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=scudo -fPIC -shared 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -shared-libsan \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SCUDO-SHARED +// CHECK-SCUDO-SHARED: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SCUDO-SHARED: "-fsanitize=scudo" +// CHECK-SCUDO-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.scudo.so" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fxray-instrument -fxray-modes=xray-basic \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-XRAY-ARM +// CHECK-XRAY-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-XRAY-ARM: "-fxray-instrument" +// CHECK-XRAY-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.xray.a" +// CHECK-XRAY-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.xray-basic.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -O3 -flto -mcpu=cortex-a53 2>&1 \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-LTO +// CHECK-LTO: "-plugin-opt=mcpu=cortex-a53" +// CHECK-LTO: "-plugin-opt=O3" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -flto=thin -flto-jobs=8 -mcpu=cortex-a7 2>&1 \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-THINLTO +// CHECK-THINLTO: "-plugin-opt=mcpu=cortex-a7" +// CHECK-THINLTO: "-plugin-opt=thinlto" +// CHECK-THINLTO: "-plugin-opt=jobs=8" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFT +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFTFP +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-HF,CHECK-MULTILIB-ARM-A7-HARD +// CHECK-MULTILIB: {{.*}}clang{{.*}}" "-cc1" +// CHECK-MULTILIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-MULTILIB: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-MULTILIB: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-MULTILIB-SF: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-MULTILIB-HF: "-dynamic-linker" "/lib/ld-musl-armhf.so.1" + +// CHECK-MULTILIB-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" + +// CHECK-MULTILIB-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" + +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4" + +// CHECK-MULTILIB-ARM-A7-HARD: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4" + +// CHECK-MULTILIB-ARM: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFT: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-HARD: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a" + +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-linux-ohos -fprofile-instr-generate -v \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK-PROFILE-RTLIB %s + +// CHECK-PROFILE-RTLIB: -u__llvm_profile_runtime +// CHECK-PROFILE-RTLIB: libclang_rt.profile + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: --target=arm64-linux-ohos -pthread \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -shared \ +// RUN: | FileCheck --check-prefix=CHECK-OHOS-PTHREAD %s + +// CHECK-OHOS-PTHREAD-NOT: -lpthread + diff --git a/clang/test/Driver/ohos.cpp b/clang/test/Driver/ohos.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b822350898c8be2eb5a41740b3e279d18a9ca2e --- /dev/null +++ b/clang/test/Driver/ohos.cpp @@ -0,0 +1,121 @@ +// RUN: %clangxx %s -### -no-canonical-prefixes --target=arm-liteos -march=armv7-a \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld 2>&1 | FileCheck %s +// CHECK: {{.*}}clang{{.*}}" "-cc1" +// CHECK: "-triple" "armv7-unknown-liteos-ohos" +// CHECK-NOT: "-fuse-init-array" +// CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" +// CHECK: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK: "-pie" +// CHECK-NOT: "--build-id" +// CHECK: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK: Scrt1.o +// CHECK: crti.o +// CHECK: clang_rt.crtbegin.o +// CHECK: "-L{{.*[/\\]}}lib/arm-liteos-ohos/" +// CHECK-NOT: "--push-state" +// CHECK-NOT: "--as-needed" +// CHECK: "-lc++" +// CHECK: "-lm" +// CHECK-NOT: "--pop-state" +// CHECK: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK: "-lc" +// CHECK: clang_rt.crtend.o +// CHECK: crtn.o + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -stdlib=libstdc++ \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STDLIB +// CHECK-STDLIB: error: invalid library name in argument '-stdlib=libstdc++' + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -static-libstdc++ \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC +// CHECK-STATIC-NOT: "--push-state" +// CHECK-STATIC-NOT: "--as-needed" +// CHECK-STATIC: "-Bstatic" +// CHECK-STATIC: "-lc++" +// CHECK-STATIC: "-Bdynamic" +// CHECK-STATIC: "-lm" +// CHECK-STATIC-NOT: "--pop-state" +// CHECK-STATIC: "-lc" + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -static \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC1 +// CHECK-STATIC1-NOT: "-fuse-init-array" +// CHECK-STATIC1: "-static" +// CHECK-STATIC1: "-lc++" +// CHECK-STATIC1: "-lc++abi" +// CHECK-STATIC1: "-lunwind" +// CHECK-STATIC1: "-lm" +// CHECK-STATIC1: "-lc" + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -march=armv7-a -mfloat-abi=soft -static -fPIE -fPIC -fpic -pie \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC2 +// CHECK-STATIC2: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-STATIC2: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-STATIC2: "-static" +// CHECK-STATIC2: "-lc++" +// CHECK-STATIC2: "-lc++abi" +// CHECK-STATIC2: "-lunwind" +// CHECK-STATIC2: "-lm" +// CHECK-STATIC2: "-lc" + +// RUN: %clangxx %s -### --target=arm-liteos -nostdlib++ -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIBXX +// CHECK-NOSTDLIBXX-NOT: "-lc++" +// CHECK-NOSTDLIBXX: "-lm" +// CHECK-NOSTDLIBXX: "-lc" + +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFT +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFTFP +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-HF,CHECK-MULTILIB-ARM-A7-HARD +// CHECK-MULTILIB: {{.*}}clang{{.*}}" "-cc1" +// CHECK-MULTILIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-MULTILIB: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-MULTILIB: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-MULTILIB-SF: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-MULTILIB-HF: "-dynamic-linker" "/lib/ld-musl-armhf.so.1" + +// CHECK-MULTILIB-ARM: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}" +// CHECK-MULTILIB-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" + +// CHECK-MULTILIB-ARM-A7-SOFT: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}a7_soft" +// CHECK-MULTILIB-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" + +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}a7_softfp_neon-vfpv4" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4" + +// CHECK-MULTILIB-ARM-A7-HARD: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}a7_hard_neon-vfpv4" +// CHECK-MULTILIB-ARM-A7-HARD: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4" + +// CHECK-MULTILIB-ARM: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFT: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-HARD: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a" diff --git a/clang/test/Preprocessor/init-mips.c b/clang/test/Preprocessor/init-mips.c index a07cee64e6848d2a891739c9cc9c34eeb1e24693..40d8d3a80027cb84d206d124f6da737aa2c87c40 100644 --- a/clang/test/Preprocessor/init-mips.c +++ b/clang/test/Preprocessor/init-mips.c @@ -1,4 +1,7 @@ +// RUN: %clang_cc1 -E -dM -triple=mipsel-linux-ohos < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32EL-OHOS %s // +// MIPS32EL-OHOS:#define __mips_fpr 64 + // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=mips-none-none < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32BE -check-prefix MIPS32BE-C %s // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=mips-none-none < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32BE -check-prefix MIPS32BE-CXX %s // @@ -1697,6 +1700,11 @@ // RUN: | FileCheck -match-full-lines -check-prefix MIPS64-NOFP %s // MIPS64-NOFP:#define __mips_fpr 64 +// RUN: not %clang_cc1 -target-feature +fpxx \ +// RUN: -E -dM -triple=mipsel-linux-ohos < /dev/null 2>&1 \ +// RUN: | FileCheck -match-full-lines -check-prefix MIPS32EL-OHOS-MFPXX %s +// MIPS32EL-OHOS-MFPXX:error: fpxx is currently unsupported on OHOS + // RUN: not %clang_cc1 -target-feature -fp64 \ // RUN: -E -dM -triple=mips64-none-none < /dev/null 2>&1 \ // RUN: | FileCheck -match-full-lines -check-prefix MIPS64-MFP32 %s diff --git a/clang/test/Preprocessor/ohos.c b/clang/test/Preprocessor/ohos.c new file mode 100644 index 0000000000000000000000000000000000000000..0c435c7ed5ab471e97d2358640d8ef838cd47955 --- /dev/null +++ b/clang/test/Preprocessor/ohos.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=aarch64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM64-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=riscv64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=RISCV64-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=mipsel-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=MIPSEL-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=x86_64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=X86_64-OHOS-CXX +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -check-prefix=OHOS-DEFS + +// ARM-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U +// ARM64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// RISCV64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// MIPSEL-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U +// X86_64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// OHOS-DEFS: __OHOS_FAMILY__ +// OHOS-DEFS: __OHOS__ +// OHOS-DEFS-NOT: __OHOS__ diff --git a/clang/unittests/CMakeLists.txt b/clang/unittests/CMakeLists.txt index 51fe5de9ce644838cc0c6beb2799df1250cb209c..37a2a167c38df4ae403e516000b5eb6cac579390 100644 --- a/clang/unittests/CMakeLists.txt +++ b/clang/unittests/CMakeLists.txt @@ -41,7 +41,9 @@ add_subdirectory(Interpreter) if(NOT WIN32 AND CLANG_TOOL_LIBCLANG_BUILD) add_subdirectory(libclang) endif() -add_subdirectory(DirectoryWatcher) +if (NOT APPLE) + add_subdirectory(DirectoryWatcher) +endif() add_subdirectory(Rename) add_subdirectory(Index) add_subdirectory(Serialization) diff --git a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt index 9f6ed2eb4fe7da0be749e018caebcf23bfca472f..b10af074635e3d1e3b7de9d1c849077131eb222a 100644 --- a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt +++ b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt @@ -13,6 +13,7 @@ set(LLVM_LINK_COMPONENTS add_clang_unittest(ClangReplInterpreterExceptionTests InterpreterExceptionTest.cpp ) +set_property(TARGET ClangReplInterpreterExceptionTests APPEND_STRING PROPERTY LINK_FLAGS " -static-libstdc++ -l:libc++abi.a") llvm_update_compile_flags(ClangReplInterpreterExceptionTests) target_link_libraries(ClangReplInterpreterExceptionTests PUBLIC diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 62737735695f2d268a56fce1a00e0a632b9a8e44..c72f90709cb5ad3b7694e56ad9502111775c3e8f 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -116,7 +116,14 @@ if ("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES ".*android.*") string(REGEX MATCH "-target(=| +)[^ ]+android[a-z]*([0-9]+)" ANDROID_API_LEVEL "${CMAKE_C_FLAGS}") set(ANDROID_API_LEVEL ${CMAKE_MATCH_2}) endif() + +# We define OHOS for ohos targets for now +if (OHOS) + set(OHOS_FAMILY 1) +endif() + pythonize_bool(ANDROID) +pythonize_bool(OHOS_FAMILY) set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -127,7 +134,7 @@ pythonize_bool(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR) # and target a UNIX-like system or Windows. # We can run tests on Android even when we are cross-compiling. if(("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}" AND (UNIX OR WIN32)) OR ANDROID - OR COMPILER_RT_EMULATOR) + OR COMPILER_RT_EMULATOR OR OHOS) option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" ON) else() option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" OFF) @@ -258,7 +265,7 @@ cmake_dependent_option(COMPILER_RT_STATIC_CXX_LIBRARY "COMPILER_RT_CXX_LIBRARY" OFF) set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY OFF) -if (FUCHSIA) +if (FUCHSIA OR OHOS) set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY ON) endif() @@ -477,7 +484,9 @@ append_list_if(MINGW -fms-extensions SANITIZER_COMMON_CFLAGS) # TODO: We should consider using the same model as libc++, that is use either # -nostdlib++ and --unwindlib=none if supported, or -nodefaultlibs otherwise. append_list_if(C_SUPPORTS_NODEFAULTLIBS_FLAG -nodefaultlibs SANITIZER_COMMON_LINK_FLAGS) -append_list_if(COMPILER_RT_HAS_Z_TEXT -Wl,-z,text SANITIZER_COMMON_LINK_FLAGS) +if (NOT __MIPS) + append_list_if(COMPILER_RT_HAS_Z_TEXT -Wl,-z,text SANITIZER_COMMON_LINK_FLAGS) +endif() # Only necessary for 32-bit SPARC. Solaris 11.2+ ld uses -z ignore/-z record # natively, but supports --as-needed/--no-as-needed for GNU ld compatibility. @@ -510,24 +519,9 @@ if (SANITIZER_NO_UNDEFINED_SYMBOLS) list(APPEND SANITIZER_COMMON_LINK_FLAGS -Wl,-z,defs) endif() -# TODO: COMPILER_RT_COMMON_CFLAGS and COMPILER_RT_COMMON_LINK_FLAGS are -# intended for use in non-sanitizer runtimes such as libFuzzer, profile or XRay, -# move these higher to include common flags, then derive SANITIZER_COMMON_CFLAGS -# and SANITIZER_COMMON_LINK_FLAGS from those and append sanitizer-specific flags. -set(COMPILER_RT_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS}) -set(COMPILER_RT_COMMON_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS}) - -# We don't use the C++ standard library, so avoid including it by mistake. -append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ SANITIZER_COMMON_CFLAGS) -append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ SANITIZER_COMMON_LINK_FLAGS) - -# Remove -stdlib= which is unused when passing -nostdinc++... -string(REGEX MATCHALL "-stdlib=[a-zA-Z+]*" stdlib_flag "${CMAKE_CXX_FLAGS}") -string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - -# ...we need it to build some runtimes and tests so readd it where appropriate. -list(APPEND COMPILER_RT_COMMON_CFLAGS ${stdlib_flag}) -list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag}) +if (OHOS) + list(APPEND SANITIZER_COMMON_LINK_LIBS unwind) +endif() # TODO: There's a lot of duplication across lib/*/tests/CMakeLists.txt files, # move some of the common flags to COMPILER_RT_UNITTEST_CFLAGS. diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake index 00bb892be595a225e44677e31b3af04d34e8bd81..c0adcbc0a3586d4e804914b94972c0d572982791 100644 --- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake +++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake @@ -282,9 +282,6 @@ function(add_compiler_rt_runtime name type) NOT name STREQUAL "clang_rt.builtins") get_compiler_rt_target(${arch} target) find_compiler_rt_library(builtins builtins_${libname} TARGET ${target}) - if(builtins_${libname} STREQUAL "NOTFOUND") - message(FATAL_ERROR "Cannot find builtins library for the target architecture") - endif() endif() set(sources_${libname} ${LIB_SOURCES}) format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS}) diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake index a1da35b0ac4b586efe84ad970ad7e231c3bf4b42..4612e4d8b9af7d41a9ab925f52224e4263e7f4a9 100644 --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -41,7 +41,7 @@ if(OS_NAME MATCHES "Linux") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${S390X}) elseif (OS_NAME MATCHES "Windows") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64}) -elseif(OS_NAME MATCHES "Android") +elseif(OS_NAME MATCHES "Android|OHOS") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}) else() set(ALL_FUZZER_SUPPORTED_ARCH ${X86_64} ${ARM64}) diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index e322af89a0427139837e07bbfe8d15ef5cfe79e2..8675f5689b99fb6f9c271b56b4aec3579385c053 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -182,7 +182,7 @@ macro(detect_target_arch) elseif(__MIPS64) # must be checked before __MIPS add_default_target_arch(mips64) elseif(__MIPS) - add_default_target_arch(mips) + add_default_target_arch(mipsel) elseif(__PPC64) # must be checked before __PPC add_default_target_arch(powerpc64) elseif(__PPC64LE) @@ -497,7 +497,11 @@ endfunction() function(get_compiler_rt_install_dir arch install_dir) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) get_compiler_rt_target(${arch} target) - set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR}/${target} PARENT_SCOPE) + if(OHOS) + set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR}/${target}/${LLVM_TARGET_MULTILIB_SUFFIX} PARENT_SCOPE) + else() + set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR}/${target} PARENT_SCOPE) + endif() else() set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR} PARENT_SCOPE) endif() @@ -506,7 +510,11 @@ endfunction() function(get_compiler_rt_output_dir arch output_dir) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) get_compiler_rt_target(${arch} target) - set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/${target} PARENT_SCOPE) + if(OHOS) + set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/${target}/${LLVM_TARGET_MULTILIB_SUFFIX} PARENT_SCOPE) + else() + set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/${target} PARENT_SCOPE) + endif() else() set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR} PARENT_SCOPE) endif() diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index 8a6219568b3f454dc8756bf605414d9b15c09d22..f61b962bdb248d64ccddf5bce85a6e6e2748fb0d 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -191,6 +191,9 @@ macro(test_targets) # Examine compiler output to determine target architecture. detect_target_arch() set(COMPILER_RT_OS_SUFFIX "-android") + elseif(OHOS) + detect_target_arch() + set(COMPILER_RT_OS_SUFFIX "") elseif(NOT APPLE) # Supported archs for Apple platforms are generated later if(COMPILER_RT_DEFAULT_TARGET_ONLY) add_default_target_arch(${COMPILER_RT_DEFAULT_TARGET_ARCH}) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index cd45176cf2ba761667793903daccd5f02b0e690c..a631ae4e86c334d605340753a17b03fdad8eba8b 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -61,6 +61,8 @@ if (C_SUPPORTS_NODEFAULTLIBS_FLAG) shell32 user32 kernel32 mingw32 ${MINGW_RUNTIME} moldname mingwex msvcrt) list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) + elseif (OHOS) + list(APPEND CMAKE_REQUIRED_LIBRARIES unwind) endif() endif () @@ -148,9 +150,13 @@ check_include_files("sys/auxv.h" COMPILER_RT_HAS_AUXV) # Libraries. check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL) -check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) +if (NOT OHOS) + check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) +endif() check_library_exists(m pow "" COMPILER_RT_HAS_LIBM) -check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) +if (NOT OHOS) + check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) +endif() check_library_exists(execinfo backtrace "" COMPILER_RT_HAS_LIBEXECINFO) # Look for terminfo library, used in unittests that depend on LLVMSupport. @@ -692,7 +698,7 @@ set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}") if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS" OR + (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS|OHOS" OR (OS_NAME MATCHES "Windows" AND NOT CYGWIN AND (NOT MINGW OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")))) set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE) @@ -712,7 +718,7 @@ else() set(COMPILER_RT_HAS_ASAN FALSE) endif() -if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS") +if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS|OHOS") set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE) else() set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE) @@ -742,7 +748,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Android|Fuchsia") + OS_NAME MATCHES "Linux|Android|Fuchsia|OHOS") set(COMPILER_RT_HAS_HWASAN TRUE) else() set(COMPILER_RT_HAS_HWASAN FALSE) @@ -756,14 +762,14 @@ else() endif() if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|OHOS") set(COMPILER_RT_HAS_PROFILE TRUE) else() set(COMPILER_RT_HAS_PROFILE FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH) - if (OS_NAME MATCHES "Linux|Darwin|FreeBSD|NetBSD") + if (OS_NAME MATCHES "Linux|Darwin|FreeBSD|NetBSD|OHOS") set(COMPILER_RT_HAS_TSAN TRUE) elseif (OS_NAME MATCHES "Android" AND ANDROID_PLATFORM_LEVEL GREATER 23) set(COMPILER_RT_HAS_TSAN TRUE) @@ -781,14 +787,14 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS|OHOS") set(COMPILER_RT_HAS_UBSAN TRUE) else() set(COMPILER_RT_HAS_UBSAN FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin") + OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin|OHOS") set(COMPILER_RT_HAS_UBSAN_MINIMAL TRUE) else() set(COMPILER_RT_HAS_UBSAN_MINIMAL FALSE) @@ -816,7 +822,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SCUDO_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Fuchsia") + OS_NAME MATCHES "Linux|Fuchsia|OHOS") set(COMPILER_RT_HAS_SCUDO TRUE) else() set(COMPILER_RT_HAS_SCUDO FALSE) @@ -836,14 +842,14 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND FUZZER_SUPPORTED_ARCH AND - OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|Fuchsia|Windows") + OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|Fuchsia|Windows|OHOS") set(COMPILER_RT_HAS_FUZZER TRUE) else() set(COMPILER_RT_HAS_FUZZER FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SHADOWCALLSTACK_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Android") + OS_NAME MATCHES "Linux|Android|OHOS") set(COMPILER_RT_HAS_SHADOWCALLSTACK TRUE) else() set(COMPILER_RT_HAS_SHADOWCALLSTACK FALSE) diff --git a/compiler-rt/cmake/crt-config-ix.cmake b/compiler-rt/cmake/crt-config-ix.cmake index 78d1a0de1c8a7caab9d30cc8f445d5d8c485dfc0..f737e4eba82248617a989a9b1aadc102ad2d062e 100644 --- a/compiler-rt/cmake/crt-config-ix.cmake +++ b/compiler-rt/cmake/crt-config-ix.cmake @@ -30,7 +30,7 @@ set(RISCV64 riscv64) set(VE ve) set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} - ${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON}) + ${PPC64} ${MIPS32} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON}) include(CompilerRTUtils) @@ -43,7 +43,7 @@ if(NOT APPLE) message(STATUS "Supported architectures for crt: ${CRT_SUPPORTED_ARCH}") endif() -if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER) +if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|OHOS" AND NOT LLVM_USE_SANITIZER) set(COMPILER_RT_HAS_CRT TRUE) else() set(COMPILER_RT_HAS_CRT FALSE) diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h index 27d826fb613ae9f686804b0f8bddf420f8aa80d7..893aa834bb8cd08e29b807b1e28aaedcea6adf0c 100644 --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -126,7 +126,7 @@ typedef DefaultSizeClassMap SizeClassMap; const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; -# elif defined(__aarch64__) && SANITIZER_ANDROID +#elif defined(__aarch64__) && (SANITIZER_ANDROID || SANITIZER_OHOS) // Android needs to support 39, 42 and 48 bit VMA. const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x2000000000ULL; // 128G. diff --git a/compiler-rt/lib/asan/asan_errors.h b/compiler-rt/lib/asan/asan_errors.h index c6ac88f6dc2ae4204b8fa4b6b409ffe452aa30bb..df9868c6a38237f55417a865ddfa617e90085592 100644 --- a/compiler-rt/lib/asan/asan_errors.h +++ b/compiler-rt/lib/asan/asan_errors.h @@ -339,10 +339,13 @@ struct ErrorODRViolation : ErrorBase { ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_, const __asan_global *g2, u32 stack_id2_) : ErrorBase(tid, 10, "odr-violation"), - global1(*g1), - global2(*g2), stack_id1(stack_id1_), - stack_id2(stack_id2_) {} + stack_id2(stack_id2_) { + // HUAWEI: We must avoid memcpy intrinsic, because memory for g2 + // is poisoned. + internal_memcpy(&global1, g1, sizeof(*g1)); + internal_memcpy(&global2, g2, sizeof(*g2)); + } void Print(); }; diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index 9c46f225116ee557d924dcaabaa4293d3d9975c3..b5c56251d2d461169243723e1f8d808b84a6c968 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -35,7 +35,7 @@ // If set, values like allocator chunk size, as well as defaults for some flags // will be changed towards less memory overhead. #ifndef ASAN_LOW_MEMORY -# if SANITIZER_IOS || SANITIZER_ANDROID +# if SANITIZER_IOS || SANITIZER_ANDROID || SANITIZER_OHOS # define ASAN_LOW_MEMORY 1 # else # define ASAN_LOW_MEMORY 0 diff --git a/compiler-rt/lib/asan/asan_linux.cpp b/compiler-rt/lib/asan/asan_linux.cpp index 89450fc120a0411e5e799de79ac7105ee71ef74a..35682cdb52fba2494657eaea4507d3e4ae63102a 100644 --- a/compiler-rt/lib/asan/asan_linux.cpp +++ b/compiler-rt/lib/asan/asan_linux.cpp @@ -45,7 +45,8 @@ #include #endif -#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS +#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS || \ + SANITIZER_OHOS #include extern "C" void* _DYNAMIC; #elif SANITIZER_NETBSD @@ -121,7 +122,7 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) { ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size)); } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS // FIXME: should we do anything for Android? void AsanCheckDynamicRTPrereqs() {} void AsanCheckIncompatibleRT() {} @@ -208,7 +209,7 @@ void AsanCheckIncompatibleRT() { } #endif // SANITIZER_ANDROID -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS void ReadContextStack(void *context, uptr *stack, uptr *ssize) { ucontext_t *ucp = (ucontext_t*)context; *stack = (uptr)ucp->uc_stack.ss_sp; diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt index a0c6d2910d6f8c4766e2a28665d7e8c160d6f13d..7bbe9c2a36e816c2750034b8d0078decef01bcca 100644 --- a/compiler-rt/lib/asan/tests/CMakeLists.txt +++ b/compiler-rt/lib/asan/tests/CMakeLists.txt @@ -168,8 +168,13 @@ function(add_asan_tests arch test_runtime) # selection. Each configuration expects the test binaries in a corresponding # subdirectory. Generate subdirectory names based on the architecture name. string(TOUPPER ${arch} ARCH_UPPER_CASE) - set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) - set(CONFIG_NAME_DYNAMIC ${ARCH_UPPER_CASE}${OS_NAME}DynamicConfig) + if (OHOS) + set(CONFIG_NAME default) + set(CONFIG_NAME_DYNAMIC dynamic) + else() + set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) + set(CONFIG_NAME_DYNAMIC ${ARCH_UPPER_CASE}${OS_NAME}DynamicConfig) + endif() # Closure to keep the values. function(generate_asan_tests test_objects test_suite testname) diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp index eb61410d768fe50885e9c2a52d30ff4a5181008d..e392ea90dbc2aa0f2b0d7ea2b946f85f7f0ba143 100644 --- a/compiler-rt/lib/asan/tests/asan_test.cpp +++ b/compiler-rt/lib/asan/tests/asan_test.cpp @@ -1322,7 +1322,9 @@ TEST(AddressSanitizer, LongDoubleNegativeTest) { memcpy(Ident(&c), Ident(&b), sizeof(long double)); } -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(__OHOS__) +// On OHOS/Musl sched_param is not int. +// See __interceptor_pthread_getschedparam TEST(AddressSanitizer, pthread_getschedparam) { int policy; struct sched_param param; diff --git a/compiler-rt/lib/builtins/divtf3.c b/compiler-rt/lib/builtins/divtf3.c index 5bcc9a8e4aa1843a5542aaae5a31abe1609797eb..809c5a4f4adb1b534e0ebd485c5af0dd607d71ff 100644 --- a/compiler-rt/lib/builtins/divtf3.c +++ b/compiler-rt/lib/builtins/divtf3.c @@ -16,7 +16,7 @@ #if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) -#define NUMBER_OF_HALF_ITERATIONS 4 +#define NUMBER_OF_HALF_ITERATIONS 5 #define NUMBER_OF_FULL_ITERATIONS 1 #include "fp_div_impl.inc" diff --git a/compiler-rt/lib/builtins/fp_div_impl.inc b/compiler-rt/lib/builtins/fp_div_impl.inc index 29bcd1920edfb4c5ec59f2e4201548b0339f217e..b49a6fd2bd73721a906bf8cc66addee777a45e70 100644 --- a/compiler-rt/lib/builtins/fp_div_impl.inc +++ b/compiler-rt/lib/builtins/fp_div_impl.inc @@ -325,7 +325,7 @@ static __inline fp_t __divXf3__(fp_t a, fp_t b) { #define RECIPROCAL_PRECISION REP_C(10) #elif defined(DOUBLE_PRECISION) && NUMBER_OF_HALF_ITERATIONS == 3 && NUMBER_OF_FULL_ITERATIONS == 1 #define RECIPROCAL_PRECISION REP_C(220) -#elif defined(QUAD_PRECISION) && NUMBER_OF_HALF_ITERATIONS == 4 && NUMBER_OF_FULL_ITERATIONS == 1 +#elif defined(QUAD_PRECISION) && NUMBER_OF_HALF_ITERATIONS == 5 && NUMBER_OF_FULL_ITERATIONS == 1 #define RECIPROCAL_PRECISION REP_C(13922) #else #error Invalid number of iterations diff --git a/compiler-rt/lib/builtins/int_util.h b/compiler-rt/lib/builtins/int_util.h index c372c2edc637137d28926ad9af948f31766907ba..32b66732f8f7514391b6b7ce0dc6f6f4e78045da 100644 --- a/compiler-rt/lib/builtins/int_util.h +++ b/compiler-rt/lib/builtins/int_util.h @@ -40,6 +40,9 @@ NORETURN void __compilerrt_abort_impl(const char *file, int line, #define REPEAT_4_TIMES(code_to_repeat) \ REPEAT_3_TIMES(code_to_repeat) \ code_to_repeat +#define REPEAT_5_TIMES(code_to_repeat) \ + REPEAT_4_TIMES(code_to_repeat) \ + code_to_repeat #define REPEAT_N_TIMES_(N, code_to_repeat) REPEAT_##N##_TIMES(code_to_repeat) #define REPEAT_N_TIMES(N, code_to_repeat) REPEAT_N_TIMES_(N, code_to_repeat) diff --git a/compiler-rt/lib/cfi/CMakeLists.txt b/compiler-rt/lib/cfi/CMakeLists.txt index 2197fa4a5c758d8da9c856ba7a6bbfd83556a6d3..cf8479d39c25e09a0fbdac54ea9b029d28d717ae 100644 --- a/compiler-rt/lib/cfi/CMakeLists.txt +++ b/compiler-rt/lib/cfi/CMakeLists.txt @@ -1,6 +1,6 @@ add_compiler_rt_component(cfi) -if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetBSD") +if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetBSD" OR OS_NAME MATCHES "OHOS") set(CFI_SOURCES cfi.cpp ) diff --git a/compiler-rt/lib/fuzzer/CMakeLists.txt b/compiler-rt/lib/fuzzer/CMakeLists.txt index a9a10f724d1aa353ed52fdef17cc6c349429d712..a0532c838c27abf954e6123e6a960858bdbcd73b 100644 --- a/compiler-rt/lib/fuzzer/CMakeLists.txt +++ b/compiler-rt/lib/fuzzer/CMakeLists.txt @@ -147,7 +147,7 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir") file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir}) add_custom_command(TARGET clang_rt.${name}-${arch} POST_BUILD - COMMAND ${CMAKE_CXX_COMPILER} ${target_cflags} -Wl,--whole-archive "$" -Wl,--no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o + COMMAND ${CMAKE_CXX_COMPILER} ${target_cflags} -Wl,--whole-archive "$" -Wl,--no-whole-archive ${dir}/lib/libc++.a -nodefaultlibs -r -o ${name}.o COMMAND ${CMAKE_OBJCOPY} --localize-hidden ${name}.o COMMAND ${CMAKE_COMMAND} -E remove "$" COMMAND ${CMAKE_AR} qcs "$" ${name}.o diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp index b771025cb93d319183e26e619182c0aa5e44ca1e..235aa73740af811a8d25785f087179835fb08100 100644 --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -83,7 +83,7 @@ static void InitializeFlags() { cf.intercept_tls_get_addr = true; cf.exitcode = 99; // 8 shadow pages ~512kB, small enough to cover common stack sizes. - cf.clear_shadow_mmap_threshold = 4096 * (SANITIZER_ANDROID ? 2 : 8); + cf.clear_shadow_mmap_threshold = 4096 * ((SANITIZER_ANDROID) ? 2 : 8); // Sigtrap is used in error reporting. cf.handle_sigtrap = kHandleSignalExclusive; diff --git a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp index 7642ba6c0bf08fddee2f820a2b4016b6deec0488..bf69694a5476277e0f1e02ecfa002c6f10451f56 100644 --- a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp +++ b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp @@ -26,7 +26,7 @@ // The code in this file needs to run in an unrelocated binary. It should not // access any external symbol, including its own non-hidden globals. -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS extern "C" { INTERFACE_ATTRIBUTE void __hwasan_shadow(); diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index d97974ee9074e9eb16a9dc8ae6abce3e23d12614..1acfe19dc8b6b0c9dc3175b08794041807eab49d 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -18,7 +18,7 @@ #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \ - !SANITIZER_SOLARIS + !SANITIZER_SOLARIS && !SANITIZER_OHOS # error "Interception doesn't work on this operating system." #endif diff --git a/compiler-rt/lib/interception/interception_type_test.cpp b/compiler-rt/lib/interception/interception_type_test.cpp index 2a118fb214fffee8ef568f2034fc83d4ea46b8d7..0146b2b34f0a25c9b2fcdeda50424c9d1e7e0ace 100644 --- a/compiler-rt/lib/interception/interception_type_test.cpp +++ b/compiler-rt/lib/interception/interception_type_test.cpp @@ -31,8 +31,8 @@ COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t)); // The following are the cases when pread (and friends) is used instead of // pread64. In those cases we need OFF_T to match off_t. We don't care about the // rest (they depend on _FILE_OFFSET_BITS setting when building an application). -# if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ - _FILE_OFFSET_BITS != 64 +#if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ + _FILE_OFFSET_BITS != 64 || SANITIZER_OHOS COMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t)); # endif diff --git a/compiler-rt/lib/orc/endianness.h b/compiler-rt/lib/orc/endianness.h index 4ee5505ce6ddf167329d5dfb1f4b2c6ac3232e66..a8e55629a6be32a8d332eac056348adf52b33a25 100644 --- a/compiler-rt/lib/orc/endianness.h +++ b/compiler-rt/lib/orc/endianness.h @@ -22,7 +22,8 @@ #endif #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ - defined(__Fuchsia__) || defined(__EMSCRIPTEN__) + defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || \ + defined(__OHOS_FAMILY__) #include #elif defined(_AIX) #include diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 9af296b1853a9f74ede4e675ff6d8aa31350b74f..e97ceadcfcd9da0f29e14c3382bf4481619ab329 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2276,11 +2276,13 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { #if SANITIZER_GLIBC namespace __sanitizer { extern "C" { +#if !SANITIZER_OHOS int real_clock_gettime(u32 clk_id, void *tp) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_clock_gettime(clk_id, tp); return REAL(clock_gettime)(clk_id, tp); } +#endif } // extern "C" } // namespace __sanitizer #endif @@ -2666,7 +2668,7 @@ INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { } return res; } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage); @@ -3973,7 +3975,7 @@ INTERCEPTOR(char *, strerror, int errnum) { // static storage. #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ SANITIZER_APPLE || SANITIZER_ANDROID || SANITIZER_NETBSD || \ - SANITIZER_FREEBSD + SANITIZER_FREEBSD || SANITIZER_OHOS // POSIX version. Spec is not clear on whether buf is NULL-terminated. // At least on OSX, buf contents are valid even when the call fails. INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index 49ec4097c900bd7fd23efaa7ac3bf32438d67ee8..17ac1af2431cb8a8999678b170835f32c21b1145 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -98,7 +98,7 @@ static void ioctl_table_fill() { _(SIOCSIFNETMASK, READ, struct_ifreq_sz); #endif -#if (SANITIZER_LINUX && !SANITIZER_ANDROID) +# if (SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS) _(SIOCGETSGCNT, WRITE, struct_sioc_sg_req_sz); _(SIOCGETVIFCNT, WRITE, struct_sioc_vif_req_sz); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc index a38b134085aabde4e4d589bc98de222f0fc297e5..7e7628ea0c1cb970b3285a3a2d3538f6f89bd5b1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -2509,7 +2509,7 @@ PRE_SYSCALL(ni_syscall)() {} POST_SYSCALL(ni_syscall)(long res) {} PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { -# if !SANITIZER_ANDROID && \ +# if !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ SANITIZER_RISCV64) @@ -2531,7 +2531,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { } POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { -# if !SANITIZER_ANDROID && \ +# if !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ SANITIZER_RISCV64) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc index 6148ae56067cae03e7094070062f5ec083454565..509bcf6afd1af8dc6f0c5b0376aed036e2749c24 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -62,7 +62,7 @@ COMMON_FLAG( COMMON_FLAG(const char *, log_suffix, nullptr, "String to append to log file name, e.g. \".txt\".") COMMON_FLAG( - bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_APPLE, + bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_OHOS || (bool)SANITIZER_APPLE, "Write all sanitizer output to syslog in addition to other means of " "logging.") COMMON_FLAG( @@ -242,13 +242,13 @@ COMMON_FLAG(bool, intercept_stat, true, COMMON_FLAG(bool, intercept_send, true, "If set, uses custom wrappers for send* functions " "to find more errors.") -COMMON_FLAG(bool, decorate_proc_maps, (bool)SANITIZER_ANDROID, +COMMON_FLAG(bool, decorate_proc_maps, (bool)SANITIZER_ANDROID || (bool)SANITIZER_OHOS, "If set, decorate sanitizer mappings in /proc/self/maps with " "user-readable names") COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool " "found an error") COMMON_FLAG( - bool, abort_on_error, (bool)SANITIZER_ANDROID || (bool)SANITIZER_APPLE, + bool, abort_on_error, (bool)SANITIZER_ANDROID || (bool)SANITIZER_OHOS || (bool)SANITIZER_APPLE, "If set, the tool calls abort() instead of _exit() after printing the " "error report.") COMMON_FLAG(bool, suppress_equal_pcs, true, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index 15738ff1e1bcbda31cf87ec3357bf715fad52d2d..9a5923dd83019005786e77a5660b4699b8c2eef5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -177,7 +177,8 @@ typedef long pid_t; typedef int pid_t; #endif -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE || \ +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE || \ + SANITIZER_OHOS || \ (SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \ (SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID) || \ (SANITIZER_LINUX && (defined(__x86_64__) || defined(__hexagon__))) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index dc2ea933fadc710916d4bdcfd41a03bd6b3dec0f..f03ef2562033f78452f64eae697fa20cbe3a52d8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -34,7 +34,7 @@ // format. Struct kernel_stat is defined as 'struct stat' in asm/stat.h. To // access stat from asm/stat.h, without conflicting with definition in // sys/stat.h, we use this trick. -#if SANITIZER_MIPS64 +#if SANITIZER_MIPS64 || SANITIZER_RISCV64 #include #include #define stat kernel_stat @@ -49,7 +49,6 @@ #include #undef stat #endif - #include #include #include @@ -74,7 +73,7 @@ #include #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS #include #endif @@ -163,7 +162,7 @@ void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *old) { ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) { __sanitizer_sigset_t set; internal_sigfillset(&set); -# if SANITIZER_LINUX && !SANITIZER_ANDROID +# if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked // on any thread, setuid call hangs. // See test/sanitizer_common/TestCases/Linux/setuid.c. @@ -277,7 +276,9 @@ uptr internal_ftruncate(fd_t fd, uptr size) { return res; } -#if (!SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_SPARC) && SANITIZER_LINUX +# if (!SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_SPARC || \ + SANITIZER_OHOS) && \ + SANITIZER_LINUX static void stat64_to_stat(struct stat64 *in, struct stat *out) { internal_memset(out, 0, sizeof(*out)); out->st_dev = in->st_dev; @@ -378,18 +379,19 @@ uptr internal_stat(const char *path, void *buf) { AT_NO_AUTOMOUNT, STATX_BASIC_STATS, (uptr)&bufx); statx_to_stat(&bufx, (struct stat *)buf); return res; -# elif (SANITIZER_WORDSIZE == 64 || SANITIZER_X32 || \ - (defined(__mips__) && _MIPS_SIM == _ABIN32)) && \ - !SANITIZER_SPARC +# elif ( \ + SANITIZER_WORDSIZE == 64 || SANITIZER_X32 || \ + (defined(__mips__) && _MIPS_SIM == _ABIN32 && !SANITIZER_OHOS)) && \ + !SANITIZER_SPARC return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0); -# else +# else struct stat64 buf64; int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, (uptr)&buf64, 0); stat64_to_stat(&buf64, (struct stat *)buf); return res; -# endif +# endif # else struct stat64 buf64; int res = internal_syscall(SYSCALL(stat64), path, &buf64); @@ -410,18 +412,19 @@ uptr internal_lstat(const char *path, void *buf) { STATX_BASIC_STATS, (uptr)&bufx); statx_to_stat(&bufx, (struct stat *)buf); return res; -# elif (defined(_LP64) || SANITIZER_X32 || \ - (defined(__mips__) && _MIPS_SIM == _ABIN32)) && \ - !SANITIZER_SPARC +# elif ( \ + defined(_LP64) || SANITIZER_X32 || \ + (defined(__mips__) && _MIPS_SIM == _ABIN32 && !SANITIZER_OHOS)) && \ + !SANITIZER_SPARC return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, AT_SYMLINK_NOFOLLOW); -# else +# else struct stat64 buf64; int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, (uptr)&buf64, AT_SYMLINK_NOFOLLOW); stat64_to_stat(&buf64, (struct stat *)buf); return res; -# endif +# endif # else struct stat64 buf64; int res = internal_syscall(SYSCALL(lstat64), path, &buf64); @@ -895,7 +898,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { // rt_sigaction, so we need to do the same (we'll need to reimplement the // restorers; for x86_64 the restorer address can be obtained from // oldact->sa_restorer upon a call to sigaction(xxx, NULL, oldact). -#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 +#if (!SANITIZER_ANDROID && !SANITIZER_OHOS) || !SANITIZER_MIPS32 k_act.sa_restorer = u_act->sa_restorer; #endif } @@ -911,7 +914,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { internal_memcpy(&u_oldact->sa_mask, &k_oldact.sa_mask, sizeof(__sanitizer_kernel_sigset_t)); u_oldact->sa_flags = k_oldact.sa_flags; -#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 +#if (!SANITIZER_ANDROID && !SANITIZER_OHOS) || !SANITIZER_MIPS32 u_oldact->sa_restorer = k_oldact.sa_restorer; #endif } @@ -1081,7 +1084,7 @@ static uptr GetKernelAreaSize() { if ((segment.end >= 3 * gbyte) && segment.IsWritable()) return 0; } -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS // Even if nothing is mapped, top Gb may still be accessible // if we are running on 64-bit kernel. // Uname may report misleading results if personality type diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 761c57d1b8eb8802c50da49a1bb3c7e9e7b03bac..1b1b98fe4989d23a3e890ed022b00a11917a7c4b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -134,7 +134,7 @@ inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { ReleaseMemoryPagesToOS(beg, end); } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS #if defined(__aarch64__) # define __get_tls() \ @@ -152,6 +152,9 @@ inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { "rdhwr %0,$29\n" \ ".set pop\n" : "=r"(__v)); \ __v; }) +#elif defined(__riscv) +# define __get_tls() \ + ({ void** __v; __asm__("mv %0, tp" : "=r"(__v)); __v; }) #elif defined(__i386__) # define __get_tls() \ ({ void** __v; __asm__("movl %%gs:0, %0" : "=r"(__v)); __v; }) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index d74851c43e14e2627d596ee59ce5062f0b348b29..9032962b7f9e93e33468c9c1cda41ba55e6be9cc 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -82,7 +82,7 @@ struct __sanitizer::linux_dirent { #endif #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS #include #include #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 32005eef08cd5ed3e12d5199cd5383570862cccc..9469f0587f7f4de8ecc7629f2580b5d5b8a08fe9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -14,7 +14,7 @@ #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ - !(defined(__sun__) && defined(__svr4__)) + !defined(__OHOS_FAMILY__) && !(defined(__sun__) && defined(__svr4__)) # error "This operating system is not supported" #endif @@ -123,6 +123,12 @@ # define SANITIZER_ANDROID 0 #endif +#if defined(__OHOS__) +#define SANITIZER_OHOS 1 +#else +#define SANITIZER_OHOS 0 +#endif + #if defined(__Fuchsia__) # define SANITIZER_FUCHSIA 1 #else @@ -284,7 +290,8 @@ // For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or // change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here. #ifndef SANITIZER_CAN_USE_ALLOCATOR64 -# if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA +# if ((SANITIZER_ANDROID || SANITIZER_OHOS) && defined(__aarch64__)) || \ + SANITIZER_FUCHSIA # define SANITIZER_CAN_USE_ALLOCATOR64 1 # elif defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) @@ -435,7 +442,9 @@ # endif #endif -#if defined(__thumb__) && defined(__linux__) +// HUAWEI: musl seems to not respect static ctor order and we start +// background thread before parsing flags. FIXME +#if (defined(__thumb__) && defined(__linux__)) || SANITIZER_OHOS // Workaround for // https://lab.llvm.org/buildbot/#/builders/clang-thumbv7-full-2stage // or diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index ffa7e272b7e0195eb392fa3de5071b5e13686779..0640991620af95aa28df3cc08fc28846ef4111f3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -58,6 +58,12 @@ #define SI_ANDROID 0 #endif +#if SANITIZER_OHOS +#define SI_OHOS 1 +#else +#define SI_OHOS 0 +#endif + #if SANITIZER_FREEBSD #define SI_FREEBSD 1 #else @@ -270,7 +276,7 @@ #define SANITIZER_INTERCEPT_SYSINFO SI_LINUX #define SANITIZER_INTERCEPT_READDIR SI_POSIX #define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 -#if SI_LINUX_NOT_ANDROID && \ +#if SI_LINUX_NOT_ANDROID && !SI_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ defined(__s390__) || SANITIZER_RISCV64) @@ -340,7 +346,7 @@ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_SHMCTL \ - (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && SANITIZER_WORDSIZE == 64) || \ + (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && !SI_OHOS && SANITIZER_WORDSIZE == 64) || \ SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_RANDOM_R SI_GLIBC #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX @@ -466,7 +472,7 @@ #define SI_STAT_LINUX (SI_LINUX && __GLIBC_PREREQ(2, 33)) #define SANITIZER_INTERCEPT_STAT \ (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || \ - SI_STAT_LINUX) + SI_STAT_LINUX || SI_OHOS) #define SANITIZER_INTERCEPT_STAT64 SI_STAT_LINUX && SANITIZER_HAS_STAT64 #define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX) #define SANITIZER_INTERCEPT___XSTAT \ @@ -497,7 +503,7 @@ #define SANITIZER_INTERCEPT_WCSCAT SI_POSIX #define SANITIZER_INTERCEPT_WCSDUP SI_POSIX #define SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA) -#define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID +#define SANITIZER_INTERCEPT_BSD_SIGNAL (SI_ANDROID || SI_OHOS) #define SANITIZER_INTERCEPT_ACCT (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_USER_FROM_UID SI_NETBSD @@ -509,7 +515,7 @@ #define SANITIZER_INTERCEPT_GETGROUPLIST \ (SI_NETBSD || SI_FREEBSD || SI_LINUX) #define SANITIZER_INTERCEPT_STRLCPY \ - (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID) + (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID || SI_OHOS) #define SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT SI_LINUX_NOT_ANDROID diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp index bf0f355847cb13332fac82fb756fe2afa068991a..6d608cbb63ed6ab9623e39f451f105e5d80f635e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -76,7 +76,7 @@ CHECK_SIZE_AND_OFFSET(io_event, obj); CHECK_SIZE_AND_OFFSET(io_event, res); CHECK_SIZE_AND_OFFSET(io_event, res2); -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_OHOS COMPILER_CHECK(sizeof(struct __sanitizer_perf_event_attr) <= sizeof(struct perf_event_attr)); CHECK_SIZE_AND_OFFSET(perf_event_attr, type); @@ -85,7 +85,7 @@ CHECK_SIZE_AND_OFFSET(perf_event_attr, size); COMPILER_CHECK(iocb_cmd_pread == IOCB_CMD_PREAD); COMPILER_CHECK(iocb_cmd_pwrite == IOCB_CMD_PWRITE); -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_OHOS COMPILER_CHECK(iocb_cmd_preadv == IOCB_CMD_PREADV); COMPILER_CHECK(iocb_cmd_pwritev == IOCB_CMD_PWRITEV); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index c85cf1626a75b1b0d43fc6f3026e3b87fb6bcb15..839d31a8b75ca518fd09124bb8632af7f3eb07f6 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -69,7 +69,9 @@ #include #include #include +#if !SANITIZER_OHOS #include +#endif #include #include #include @@ -93,6 +95,13 @@ #if SANITIZER_LINUX # include # include +# if SANITIZER_OHOS +// Do not include asm/sigcontext.h on behalf of asm/ptrace.h +// to avoid multiple definiton errors. +# define __ASM_SIGCONTEXT_H 1 +# include +# endif + # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ defined(__hexagon__) || SANITIZER_RISCV64 # include @@ -133,6 +142,13 @@ typedef struct user_fpregs elf_fpregset_t; #if SANITIZER_ANDROID #include +#elif SANITIZER_OHOS +#include +#include +#include +#include +#include +#include #else #include #include @@ -303,7 +319,6 @@ namespace __sanitizer { int e_tabsz = (int)E_TABSZ; #endif - #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_shminfo_sz = sizeof(struct shminfo); unsigned struct_shm_info_sz = sizeof(struct shm_info); @@ -521,7 +536,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); #endif // SANITIZER_GLIBC -#if !SANITIZER_ANDROID && !SANITIZER_APPLE +#if !SANITIZER_ANDROID && !SANITIZER_APPLE && !SANITIZER_OHOS unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); #endif @@ -574,7 +589,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_TIOCSPGRP = TIOCSPGRP; unsigned IOCTL_TIOCSTI = TIOCSTI; unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT; #endif @@ -866,7 +881,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_EQL_EMANCIPATE = EQL_EMANCIPATE; unsigned IOCTL_EQL_ENSLAVE = EQL_ENSLAVE; unsigned IOCTL_EQL_GETMASTRCFG = EQL_GETMASTRCFG; @@ -950,7 +965,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_TIOCSSERIAL = TIOCSSERIAL; #endif // SANITIZER_LINUX && !SANITIZER_ANDROID -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_GIO_SCRNMAP = GIO_SCRNMAP; unsigned IOCTL_KDDISABIO = KDDISABIO; unsigned IOCTL_KDENABIO = KDENABIO; @@ -1118,7 +1133,8 @@ CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); // didn't exist. CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags); #endif -#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) +#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && \ + !SANITIZER_OHOS CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer); #endif @@ -1212,7 +1228,7 @@ CHECK_TYPE_SIZE(clock_t); CHECK_TYPE_SIZE(clockid_t); #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS CHECK_TYPE_SIZE(ifaddrs); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index bd5692ed511b2970bdac0efbb4954cdbdad3c164..a13117a330ec668c4965c2bf5504cbd27f152e8b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -98,6 +98,9 @@ const unsigned struct_kernel_stat64_sz = 104; const unsigned struct_kernel_stat_sz = 144; const unsigned struct_kernel_stat64_sz = 104; #elif defined(__mips__) +# if SANITIZER_OHOS +# define _ABIN32 1 +# endif const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID ? FIRST_32_SECOND_64(104, 128) @@ -212,13 +215,15 @@ struct __sanitizer_struct_mallinfo { #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID -struct __sanitizer_struct_mallinfo { - int v[10]; -}; - extern unsigned struct_ustat_sz; extern unsigned struct_rlimit64_sz; extern unsigned struct_statvfs64_sz; +#endif + +#if SANITIZER_LINUX && !SANITIZER_ANDROID +struct __sanitizer_struct_mallinfo { + int v[10]; +}; struct __sanitizer_ipc_perm { int __key; @@ -617,7 +622,7 @@ struct __sanitizer_sigaction { }; __sanitizer_sigset_t sa_mask; }; -#elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32) +# elif (SANITIZER_ANDROID || SANITIZER_OHOS) && (SANITIZER_WORDSIZE == 32) struct __sanitizer_sigaction { union { __sanitizer_sigactionhandler_ptr sigaction; @@ -627,59 +632,59 @@ struct __sanitizer_sigaction { uptr sa_flags; void (*sa_restorer)(); }; -#else // !SANITIZER_ANDROID +# else // !SANITIZER_ANDROID struct __sanitizer_sigaction { -#if defined(__mips__) && !SANITIZER_FREEBSD +# if defined(__mips__) && !SANITIZER_FREEBSD unsigned int sa_flags; -#endif +# endif union { __sanitizer_sigactionhandler_ptr sigaction; __sanitizer_sighandler_ptr handler; }; -#if SANITIZER_FREEBSD +# if SANITIZER_FREEBSD int sa_flags; __sanitizer_sigset_t sa_mask; -#else -#if defined(__s390x__) +# else +# if defined(__s390x__) int sa_resv; -#else +# else __sanitizer_sigset_t sa_mask; -#endif -#ifndef __mips__ -#if defined(__sparc__) -#if __GLIBC_PREREQ (2, 20) +# endif +# ifndef __mips__ +# if defined(__sparc__) +# if __GLIBC_PREREQ(2, 20) // On sparc glibc 2.19 and earlier sa_flags was unsigned long. -#if defined(__arch64__) +# if defined(__arch64__) // To maintain ABI compatibility on sparc64 when switching to an int, // __glibc_reserved0 was added. int __glibc_reserved0; -#endif +# endif int sa_flags; -#else +# else unsigned long sa_flags; -#endif -#else +# endif +# else int sa_flags; -#endif -#endif -#endif -#if SANITIZER_LINUX +# endif +# endif +# endif +# if SANITIZER_LINUX void (*sa_restorer)(); -#endif -#if defined(__mips__) && (SANITIZER_WORDSIZE == 32) +# endif +# if defined(__mips__) && (SANITIZER_WORDSIZE == 32) int sa_resv[1]; -#endif -#if defined(__s390x__) +# endif +# if defined(__s390x__) __sanitizer_sigset_t sa_mask; -#endif +# endif }; -#endif // !SANITIZER_ANDROID +# endif // !SANITIZER_ANDROID -#if defined(__mips__) -#define __SANITIZER_KERNEL_NSIG 128 -#else -#define __SANITIZER_KERNEL_NSIG 64 -#endif +# if defined(__mips__) +# define __SANITIZER_KERNEL_NSIG 128 +# else +# define __SANITIZER_KERNEL_NSIG 64 +# endif struct __sanitizer_kernel_sigset_t { uptr sig[__SANITIZER_KERNEL_NSIG / (sizeof(uptr) * 8)]; @@ -816,7 +821,7 @@ struct __sanitizer_wordexp_t { uptr we_offs; }; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS struct __sanitizer_FILE { int _flags; char *_IO_read_ptr; @@ -840,7 +845,7 @@ typedef void __sanitizer_FILE; # define SANITIZER_HAS_STRUCT_FILE 0 #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ defined(__s390__) || SANITIZER_RISCV64) @@ -1018,7 +1023,7 @@ extern unsigned struct_synth_info_sz; extern unsigned struct_vt_mode_sz; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS extern unsigned struct_ax25_parms_struct_sz; extern unsigned struct_input_keymap_entry_sz; extern unsigned struct_ipx_config_data_sz; @@ -1044,7 +1049,7 @@ extern unsigned struct_audio_buf_info_sz; extern unsigned struct_ppp_stats_sz; #endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID -#if !SANITIZER_ANDROID && !SANITIZER_APPLE +#if !SANITIZER_ANDROID && !SANITIZER_APPLE && !SANITIZER_OHOS extern unsigned struct_sioc_sg_req_sz; extern unsigned struct_sioc_vif_req_sz; #endif @@ -1099,7 +1104,7 @@ extern unsigned IOCTL_TIOCSETD; extern unsigned IOCTL_TIOCSPGRP; extern unsigned IOCTL_TIOCSTI; extern unsigned IOCTL_TIOCSWINSZ; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS extern unsigned IOCTL_SIOCGETSGCNT; extern unsigned IOCTL_SIOCGETVIFCNT; #endif @@ -1371,7 +1376,16 @@ extern unsigned IOCTL_VT_SETMODE; extern unsigned IOCTL_VT_WAITACTIVE; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS +extern unsigned IOCTL_CYGETDEFTHRESH; +extern unsigned IOCTL_CYGETDEFTIMEOUT; +extern unsigned IOCTL_CYGETMON; +extern unsigned IOCTL_CYGETTHRESH; +extern unsigned IOCTL_CYGETTIMEOUT; +extern unsigned IOCTL_CYSETDEFTHRESH; +extern unsigned IOCTL_CYSETDEFTIMEOUT; +extern unsigned IOCTL_CYSETTHRESH; +extern unsigned IOCTL_CYSETTIMEOUT; extern unsigned IOCTL_EQL_EMANCIPATE; extern unsigned IOCTL_EQL_ENSLAVE; extern unsigned IOCTL_EQL_GETMASTRCFG; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp index b0e32b50c0764e53cb2cc9c3bc33aa34992081e7..87d2d717de3ab88b8a5a1aa57fb6d5a134f58ac8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -344,7 +344,7 @@ bool ShouldMockFailureToOpen(const char *path) { internal_strncmp(path, "/proc/", 6) == 0; } -#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO && !SANITIZER_OHOS int GetNamedMappingFd(const char *name, uptr size, int *flags) { if (!common_flags()->decorate_proc_maps || !name) return -1; @@ -376,7 +376,7 @@ int GetNamedMappingFd(const char *name, uptr size, int *flags) { } #endif -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS #define PR_SET_VMA 0x53564d41 #define PR_SET_VMA_ANON_NAME 0 void DecorateMapping(uptr addr, uptr size, const char *name) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index 46e41c669738cd3833cac3605c7efb883a5c9d67..ec874e50adc446e41de36e7622677fdc011ac59f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -171,7 +171,8 @@ void SetAlternateSignalStack() { CHECK_EQ(0, sigaltstack(nullptr, &oldstack)); // If the alternate stack is already in place, do nothing. // Android always sets an alternate stack, but it's too small for us. - if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return; + if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) + return; // TODO(glider): the mapped stack should have the MAP_STACK flag in the // future. It is not required by man 2 sigaltstack now (they're using // malloc()). diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp index a746d4621936c62555caa89efcf533804f4716d7..590348fd67ad2e86a0a1eec636008d47389f75fe 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -27,7 +27,7 @@ struct StackDepotNode { u32 link; StackStore::Id store_id; - static const u32 kTabSizeLog = SANITIZER_ANDROID ? 16 : 20; + static const u32 kTabSizeLog = (SANITIZER_ANDROID || SANITIZER_OHOS) ? 16 : 20; typedef StackTrace args_type; bool eq(hash_type hash, const args_type &args) const { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h index cca6fd53468839c63d40e22e7b49ce182406c341..91b93a1b937ee53bf8171c59d42fe0e547cc8a25 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h @@ -31,7 +31,8 @@ struct StackDepotHandle { void inc_use_count_unsafe(); }; -const int kStackDepotMaxUseCount = 1U << (SANITIZER_ANDROID ? 16 : 20); +const int kStackDepotMaxUseCount = + 1U << ((SANITIZER_ANDROID || SANITIZER_OHOS) ? 16 : 20); StackDepotStats StackDepotGetStats(); u32 StackDepotPut(StackTrace stack); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp index d24fae98213aa4daa15868afe06d432dcda91417..937afb1645d0f8dd2067f46f735443bfdb623afe 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp @@ -149,6 +149,11 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, #endif // !defined(__sparc__) void BufferedStackTrace::PopStackFrames(uptr count) { + // HUAWEI: Don't atempt to pop if stack unwinding failed + // this may happen at the aearly stage of ASAN initialization + // (e.g malloc called from __dl_vseterr) + if (count == 0) + return; CHECK_LT(count, size); size -= count; for (uptr i = 0; i < size; ++i) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp index 403bda1174cc46b7a9998e26be388c2173e93850..556fdfaaa89e9e9c609f8cc0cbf44ea23debceca 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -33,28 +33,33 @@ #include // for NT_PRSTATUS #if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID // GLIBC 2.20+ sys/user does not include asm/ptrace.h +#if SANITIZER_OHOS +// Do not include asm/sigcontext.h on behalf of asm/ptrace.h +// to avoid multiple definiton errors. +#define __ASM_SIGCONTEXT_H 1 +#endif # include #endif #include // for user_regs_struct -#if SANITIZER_ANDROID && SANITIZER_MIPS -# include // for mips SP register in sys/user.h -#endif -#include // for signal-related stuff - -#ifdef sa_handler -# undef sa_handler -#endif - -#ifdef sa_sigaction -# undef sa_sigaction -#endif - -#include "sanitizer_common.h" -#include "sanitizer_flags.h" -#include "sanitizer_libc.h" -#include "sanitizer_linux.h" -#include "sanitizer_mutex.h" -#include "sanitizer_placement_new.h" +# if (SANITIZER_ANDROID || SANITIZER_OHOS) && SANITIZER_MIPS +# include // for mips SP register in sys/user.h +# endif +# include // for signal-related stuff + +# ifdef sa_handler +# undef sa_handler +# endif + +# ifdef sa_sigaction +# undef sa_sigaction +# endif + +# include "sanitizer_common.h" +# include "sanitizer_flags.h" +# include "sanitizer_libc.h" +# include "sanitizer_linux.h" +# include "sanitizer_mutex.h" +# include "sanitizer_placement_new.h" // Sufficiently old kernel headers don't provide this value, but we can still // call prctl with it. If the runtime kernel is new enough, the prctl call will @@ -504,9 +509,14 @@ typedef pt_regs regs_struct; typedef struct user regs_struct; # if SANITIZER_ANDROID # define REG_SP regs[EF_R29] -# else -# define REG_SP regs[EF_REG29] -# endif +// FIXME: For some reason, EF_R29 is not defined in asm/reg.h under +// #if _MIPS_SIM == _MIPS_SIM_ABI32 condition, so use MIPS32_EF_R29 as a +// temporary solution. +# elif SANITIZER_OHOS +# define REG_SP regs[MIPS32_EF_R29] +# else +# define REG_SP regs[EF_REG29] +# endif #elif defined(__aarch64__) typedef struct user_pt_regs regs_struct; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp index d5c028e3640d221bd87f7166a44e81bd6b8388b5..f4e138d5c990b0cb923463d4ad08c37f9896c150 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -89,7 +89,7 @@ void ReportErrorSummary(const char *error_type, const StackTrace *stack, } void ReportMmapWriteExec(int prot, int flags) { -#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID) +#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID) && !SANITIZER_OHOS int pflags = (PROT_WRITE | PROT_EXEC); if ((prot & pflags) != pflags) return; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp index 72f025a7d307adcd30fd000562c61bc923c5faf9..a793432c5276e1a57caca4eb9ce608933bdb1186 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp @@ -16,7 +16,7 @@ #include "sanitizer_common.h" #include "sanitizer_stacktrace.h" -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS #include // for dlopen() #endif diff --git a/compiler-rt/lib/scudo/scudo_flags.inc b/compiler-rt/lib/scudo/scudo_flags.inc index c124738c1f3a712f84f320242cb93a07d90b6f46..ce4d641b811ae481ec1235839a8346421034af0c 100644 --- a/compiler-rt/lib/scudo/scudo_flags.inc +++ b/compiler-rt/lib/scudo/scudo_flags.inc @@ -39,7 +39,7 @@ SCUDO_FLAG(int, QuarantineChunksUpToSize, -1, // Disable the deallocation type check by default on Android, it causes too many // issues with third party libraries. SCUDO_FLAG(bool, DeallocationTypeMismatch, !SANITIZER_ANDROID, - "Report errors on malloc/delete, new/free, new/delete[], etc.") + "Report errors on malloc/delete, new/free, new/delete[], etc.") SCUDO_FLAG(bool, DeleteSizeMismatch, true, "Report errors on mismatch between size of new and delete.") diff --git a/compiler-rt/lib/scudo/scudo_platform.h b/compiler-rt/lib/scudo/scudo_platform.h index 07d4b70fc8e9bc0a86d5f1098ee19db81272672b..c2414ec60237d4c038f3de953145a56cb82c9ceb 100644 --- a/compiler-rt/lib/scudo/scudo_platform.h +++ b/compiler-rt/lib/scudo/scudo_platform.h @@ -24,10 +24,10 @@ #ifndef SCUDO_TSD_EXCLUSIVE // SCUDO_TSD_EXCLUSIVE wasn't defined, use a default TSD model for the platform. -# if SANITIZER_ANDROID || SANITIZER_FUCHSIA +#if SANITIZER_ANDROID || SANITIZER_FUCHSIA // Android and Fuchsia use a pool of TSDs shared between threads. # define SCUDO_TSD_EXCLUSIVE 0 -# elif SANITIZER_LINUX && !SANITIZER_ANDROID +#elif SANITIZER_LINUX && !SANITIZER_ANDROID // Non-Android Linux use an exclusive TSD per thread. # define SCUDO_TSD_EXCLUSIVE 1 # else @@ -42,7 +42,7 @@ // Maximum number of TSDs that can be created for the Shared model. #ifndef SCUDO_SHARED_TSD_POOL_SIZE -# if SANITIZER_ANDROID +#if SANITIZER_ANDROID # define SCUDO_SHARED_TSD_POOL_SIZE 2U # else # define SCUDO_SHARED_TSD_POOL_SIZE 32U @@ -67,7 +67,7 @@ namespace __scudo { #if SANITIZER_CAN_USE_ALLOCATOR64 -# if defined(__aarch64__) && SANITIZER_ANDROID +#if defined(__aarch64__) && SANITIZER_ANDROID const uptr AllocatorSize = 0x4000000000ULL; // 256G. # elif defined(__aarch64__) const uptr AllocatorSize = 0x10000000000ULL; // 1T. diff --git a/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp b/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp index 2c91db8ca3974841a2314b86a97b6d259c9e0d9c..002e87038cfbe5e44cef3896d105bc10ba814dca 100644 --- a/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp +++ b/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp @@ -26,7 +26,7 @@ // debuggerd handler, but before the ART handler. // * Interceptors don't work at all when ubsan runtime is loaded late, ex. when // it is part of an APK that does not use wrap.sh method. -#if SANITIZER_FUCHSIA || SANITIZER_ANDROID +#if SANITIZER_FUCHSIA || SANITIZER_ANDROID || SANITIZER_OHOS namespace __ubsan { void InitializeDeadlySignals() {} diff --git a/compiler-rt/test/asan/CMakeLists.txt b/compiler-rt/test/asan/CMakeLists.txt index d02ee4b5bd68098d74265d77b4153e4d3876d029..91f4bc675d79dcdad82ec53e0355edb80d5c0ba2 100644 --- a/compiler-rt/test/asan/CMakeLists.txt +++ b/compiler-rt/test/asan/CMakeLists.txt @@ -143,7 +143,7 @@ if(COMPILER_RT_INCLUDE_TESTS) ${CMAKE_CURRENT_BINARY_DIR}/Unit/${CONFIG_NAME_DYNAMIC}/lit.site.cfg.py) endif() # FIXME: support unit test in the android test runner - if (NOT ANDROID) + if (NOT ANDROID AND NOT OHOS) list(APPEND ASAN_TEST_DEPS AsanUnitTests) list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/${CONFIG_NAME}) if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME) diff --git a/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py b/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py index 57271b8078a49730b9ae06f901ec3faf907dcef5..c2352c676cc594c3ddab7ddc92b1ab0b7382f885 100644 --- a/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py +++ b/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py @@ -5,5 +5,5 @@ def getRoot(config): root = getRoot(config) -if root.host_os not in ['Linux']: +if root.host_os not in ['Linux', 'OHOS']: config.unsupported = True diff --git a/compiler-rt/test/asan/TestCases/Linux/odr_c_test.c b/compiler-rt/test/asan/TestCases/Linux/odr_c_test.c index 9929b4a67af38fdfd71e44aea17c754691665c3d..f5f2340288675702333a19c6ebf62c852eb69ef8 100644 --- a/compiler-rt/test/asan/TestCases/Linux/odr_c_test.c +++ b/compiler-rt/test/asan/TestCases/Linux/odr_c_test.c @@ -17,7 +17,7 @@ __attribute__((aligned(8))) int x; __attribute__((aligned(1))) char y; // The gold linker puts ZZZ at the start of bss (where it is aligned) // unless we have a large alternative like Displace: -__attribute__((aligned(1))) char Displace[105]; +__attribute__((aligned(8))) char Displace[105]; __attribute__((aligned(1))) char ZZZ[100]; #elif defined(FILE2) int ZZZ = 1; diff --git a/compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp b/compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp index f7bccbfbe8db81476de5a6404399bec2d20ffea4..35530e61b3dd61017625a707a25ec933ea5815e7 100644 --- a/compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp @@ -4,7 +4,9 @@ // RUN: %env_asan_opts=quarantine_size_mb=10:verbosity=1:hard_rss_limit_mb=50 %run %t 2>&1 | FileCheck %s --check-prefix=Q10 // RUN: %env_asan_opts=quarantine_size_mb=10:quarantine_size=20:verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=BOTH // RUN: %env_asan_opts=quarantine_size_mb=1000:hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT -// RUN: %env_asan_opts=hard_rss_limit_mb=20 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT + +// HUAWEI: Sometimes measured RSS on device is 19Mb and test fails with 20Mb limit +// RUN: %env_asan_opts=hard_rss_limit_mb=10 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT // https://github.com/google/sanitizers/issues/981 // UNSUPPORTED: android-26 diff --git a/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp b/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp index e1752bc894c063f3b998d81b90557fd5bd5ba4ed..8fed52092be8377e0f2c12d9414df41312e2ea55 100644 --- a/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp @@ -1,5 +1,5 @@ // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 -// XFAIL: android +// XFAIL: android && !ohos_family // // RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 // Regression test for @@ -22,6 +22,6 @@ int main() { struct shm_info shmInfo; res = shmctl(0, SHM_INFO, (struct shmid_ds *)&shmInfo); assert(res > -1); - + return 0; } diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py index b437a151e16a907178b79635a4973a8bbcda43e1..cbe84170c61e52b1c3440280d8408e5f6789e4f4 100644 --- a/compiler-rt/test/asan/lit.cfg.py +++ b/compiler-rt/test/asan/lit.cfg.py @@ -239,7 +239,7 @@ else: config.substitutions.append(('%pie', '-pie')) # Only run the tests on supported OSs. -if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'SunOS', 'Windows', 'NetBSD']: +if config.host_os not in ['OHOS', 'Linux', 'Darwin', 'FreeBSD', 'SunOS', 'Windows', 'NetBSD']: config.unsupported = True if not config.parallelism_group: diff --git a/compiler-rt/test/builtins/Unit/divtf3_test.c b/compiler-rt/test/builtins/Unit/divtf3_test.c index 927d0b826f8f57cf995c6542a230fdf3f7957c71..f8b1f20e59d266fae6de933de77bf929c803bf57 100644 --- a/compiler-rt/test/builtins/Unit/divtf3_test.c +++ b/compiler-rt/test/builtins/Unit/divtf3_test.c @@ -185,6 +185,11 @@ int main() UINT64_C(0))) return 1; + if (test__divtf3(-1L, + -0.999999999999999999999999999999999904L, + UINT64_C(0x1), + UINT64_C(0x3fff000000000000))) + return 1; #else printf("skipped\n"); diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py index 3dd258283e5ce26cb043b6b73034ea6713f74fca..a49c3c0bbfdea651830b3caa45a39725fbaa292a 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -83,6 +83,9 @@ def find_compiler_libdir(): return None +def is_ohos_family_mobile(): + return config.ohos_family and config.target_arch != 'x86_64' + # Choose between lit's internal shell pipeline runner and a real shell. If # LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") @@ -232,10 +235,10 @@ if config.host_os == 'NetBSD': config.netbsd_nomprotect_prefix = ('sh ' + os.path.join(nb_commands_dir, 'run_nomprotect.sh')) - config.substitutions.append( ('%run_nomprotect', - config.netbsd_nomprotect_prefix) ) + config.substitutions.append(('%run_nomprotect', + config.netbsd_nomprotect_prefix)) else: - config.substitutions.append( ('%run_nomprotect', '%run') ) + config.substitutions.append(('%run_nomprotect', '%run')) # Copied from libcxx's config.py def get_lit_conf(name, default=None): @@ -254,13 +257,26 @@ def get_ios_commands_dir(): # Allow tests to be executed on a simulator or remotely. if emulator: - config.substitutions.append( ('%run', emulator) ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', emulator)) + config.substitutions.append(('%env ', "env ")) # TODO: Implement `%device_rm` to perform removal of files in the emulator. # For now just make it a no-op. lit_config.warning('%device_rm is not implemented') - config.substitutions.append( ('%device_rm', 'echo ') ) + config.substitutions.append(('%device_rm', 'echo ')) config.compile_wrapper = "" +elif is_ohos_family_mobile(): + config.available_features.add('ohos_family') + # FIXME: some tests for hos also need this now, + # probably this shouldn't be added for ohos + config.available_features.add('android') + compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ohos_family_commands", "ohos_compile.py") + " " + config.compile_wrapper = compile_wrapper + config.substitutions.append( ('%run', "") ) + config.substitutions.append( ('%env ', "env ") ) + # TODO: Implement `%device_rm` to perform removal of files on a device. For + # now just make it a no-op. + lit_config.warning('%device_rm is not implemented') + config.substitutions.append( ('%device_rm', 'echo ') ) elif config.host_os == 'Darwin' and config.apple_platform != "osx": # Darwin tests can be targetting macOS, a device or a simulator. All devices # are declared as "ios", even for iOS derivatives (tvOS, watchOS). Similarly, @@ -321,20 +337,20 @@ elif config.android: config.available_features.add('android') compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "android_commands", "android_compile.py") + " " config.compile_wrapper = compile_wrapper - config.substitutions.append( ('%run', "") ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', "")) + config.substitutions.append(('%env ', "env ")) else: - config.substitutions.append( ('%run', "") ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', "")) + config.substitutions.append(('%env ', "env ")) # When running locally %device_rm is a no-op. - config.substitutions.append( ('%device_rm', 'echo ') ) + config.substitutions.append(('%device_rm', 'echo ')) config.compile_wrapper = "" # Define CHECK-%os to check for OS-dependent output. -config.substitutions.append( ('CHECK-%os', ("CHECK-" + config.host_os))) +config.substitutions.append(('CHECK-%os', ("CHECK-" + config.host_os))) # Define %arch to check for architecture-dependent output. -config.substitutions.append( ('%arch', (config.host_arch))) +config.substitutions.append(('%arch', (config.host_arch))) if config.host_os == 'Windows': # FIXME: This isn't quite right. Specifically, it will succeed if the program @@ -345,7 +361,7 @@ if config.host_os == 'Windows': else: config.expect_crash = "not --crash " -config.substitutions.append( ("%expect_crash ", config.expect_crash) ) +config.substitutions.append(("%expect_crash ", config.expect_crash)) target_arch = getattr(config, 'target_arch', None) if target_arch: @@ -475,26 +491,27 @@ if config.android: # These are needed for tests to upload/download temp files, such as # suppression-files, to device. config.substitutions.append( ('%device_rundir/', "/data/local/tmp/Output/") ) - config.substitutions.append( ('%push_to_device', "%s -s '%s' push " % (adb, env['ANDROID_SERIAL']) ) ) - config.substitutions.append( ('%adb_shell ', "%s -s '%s' shell " % (adb, env['ANDROID_SERIAL']) ) ) - config.substitutions.append( ('%device_rm', "%s -s '%s' shell 'rm ' " % (adb, env['ANDROID_SERIAL']) ) ) + if not config.host_os == 'OHOS': + config.substitutions.append( ('%push_to_device', "%s -s '%s' push " % (adb, env['ANDROID_SERIAL']) ) ) + config.substitutions.append( ('%adb_shell ', "%s -s '%s' shell " % (adb, env['ANDROID_SERIAL']) ) ) + config.substitutions.append( ('%device_rm', "%s -s '%s' shell 'rm ' " % (adb, env['ANDROID_SERIAL']) ) ) - try: - android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip() - android_api_codename = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.codename"], env=env).rstrip().decode("utf-8") - except (subprocess.CalledProcessError, OSError): - lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb)" % adb) - try: - android_api_level = int(android_api_level_str) - except ValueError: - lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb): got '%s'" % (adb, android_api_level_str)) - android_api_level = min(android_api_level, int(config.android_api_level)) - for required in [26, 28, 29, 30]: - if android_api_level >= required: - config.available_features.add('android-%s' % required) - # FIXME: Replace with appropriate version when availible. - if android_api_level > 30 or (android_api_level == 30 and android_api_codename == 'S'): - config.available_features.add('android-thread-properties-api') + try: + android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip() + android_api_codename = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.codename"], env=env).rstrip().decode("utf-8") + except (subprocess.CalledProcessError, OSError): + lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb)" % adb) + try: + android_api_level = int(android_api_level_str) + except ValueError: + lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb): got '%s'" % (adb, android_api_level_str)) + android_api_level = min(android_api_level, int(config.android_api_level)) + for required in [26, 28, 29, 30]: + if android_api_level >= required: + config.available_features.add('android-%s' % required) + # FIXME: Replace with appropriate version when availible. + if android_api_level > 30 or (android_api_level == 30 and android_api_codename == 'S'): + config.available_features.add('android-thread-properties-api') # Prepare the device. android_tmpdir = '/data/local/tmp/Output' @@ -636,7 +653,7 @@ for postfix in ["2", "1", ""]: elif config.host_os in ('FreeBSD', 'NetBSD', 'OpenBSD'): config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) ) config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') ) - elif config.host_os == 'Linux': + elif config.host_os in ['Linux', 'OHOS']: config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) ) config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') ) elif config.host_os == 'SunOS': @@ -675,7 +692,7 @@ if config.host_os == 'Darwin': lit_config.warning('log command found but cannot queried') else: lit_config.warning('log command not found. Some tests will be skipped.') -elif config.android: +elif config.android or is_ohos_family_mobile(): config.default_sanitizer_opts += ['abort_on_error=0'] # Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL diff --git a/compiler-rt/test/lit.common.configured.in b/compiler-rt/test/lit.common.configured.in index 5db6ef0121fbe631442c021cde37c2959c25532b..a06ede7e73313af10081e4eb3b53d2c1e6d5ea49 100644 --- a/compiler-rt/test/lit.common.configured.in +++ b/compiler-rt/test/lit.common.configured.in @@ -41,6 +41,7 @@ set_default("use_lld", @COMPILER_RT_TEST_USE_LLD_PYBOOL@) set_default("use_thinlto", False) set_default("use_lto", config.use_thinlto) set_default("android", @ANDROID_PYBOOL@) +set_default("ohos_family", @OHOS_FAMILY_PYBOOL@) set_default("android_api_level", "@ANDROID_API_LEVEL@") set_default("android_serial", "@ANDROID_SERIAL_FOR_TESTING@") set_default("android_files_to_push", []) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py new file mode 100755 index 0000000000000000000000000000000000000000..da6e6b9d2fd43e020e8d3946a0a84f236090d0be --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py @@ -0,0 +1,45 @@ +import os, subprocess, tempfile + +HOS_TMPDIR = '/data/local/tmp/Output' +ADB = os.environ.get('ADB', 'adb') + +verbose = False +if os.environ.get('HOS_RUN_VERBOSE') == '1': + verbose = True + +def host_to_device_path(path): + rel = os.path.relpath(path, "/") + dev = os.path.join(HOS_TMPDIR, rel) + return dev + +def adb(args, attempts = 1): + if verbose: + print args + tmpname = tempfile.mktemp() + out = open(tmpname, 'w') + ret = 255 + while attempts > 0 and ret != 0: + attempts -= 1 + ret = subprocess.call([ADB] + args, stdout=out, stderr=subprocess.STDOUT) + if attempts != 0: + ret = 5 + if ret != 0: + print "adb command failed", args + print tmpname + out.close() + out = open(tmpname, 'r') + print out.read() + out.close() + os.unlink(tmpname) + return ret + +def pull_from_device(path): + tmp = tempfile.mktemp() + adb(['pull', path, tmp], 5) + text = open(tmp, 'r').read() + os.unlink(tmp) + return text + +def push_to_device(path): + dst_path = host_to_device_path(path) + adb(['push', path, dst_path], 5) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py new file mode 100755 index 0000000000000000000000000000000000000000..3a4769a5196b7f61093a8d2f77e34d034b28597f --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +import os, sys, subprocess +from ohos_common import * + + +here = os.path.abspath(os.path.dirname(sys.argv[0])) +hos_run = os.path.join(here, 'ohos_run.py') + +output = None +output_type = 'executable' + +args = sys.argv[1:] +append_args = [] +check_trgt = False +while args: + arg = args.pop(0) + if arg == '-shared': + output_type = 'shared' + elif arg == '-c': + output_type = 'object' + elif arg == '-o': + output = args.pop(0) + elif arg == '-target': + check_trgt = True + elif check_trgt or arg.startswith('--target='): + check_trgt = False + if arg.endswith('-linux-ohos'): + arg = arg.split('=')[-1] + dyld = 'unknown_hos_dyld' + # FIXME: Handle -mfloat-abi=hard for arm + # TODO: Support x86_64 + if arg.startswith('arm'): + dyld = 'ld-musl-arm.so.1' + elif arg.startswith('aarch64'): + dyld = 'ld-musl-aarch64.so.1' + append_args += ['-Wl,--dynamic-linker=' + os.path.join(HOS_TMPDIR, dyld)] + +if output == None: + print "No output file name!" + sys.exit(1) + +ret = subprocess.call(sys.argv[1:] + append_args) +if ret != 0: + sys.exit(ret) + +if output_type in ['executable', 'shared']: + push_to_device(output) + +if output_type == 'executable': + os.rename(output, output + '.real') + os.symlink(hos_run, output) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py new file mode 100755 index 0000000000000000000000000000000000000000..84a8d9fb709cac3831c0fd229db812107b82f173 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py @@ -0,0 +1,38 @@ +#!/usr/bin/python + +import os, signal, sys, subprocess +import re +from ohos_common import * + +device_binary = host_to_device_path(sys.argv[0]) + +def build_env(): + args = [] + # HOS linker ignores RPATH. Set LD_LIBRARY_PATH to Output dir. + args.append('LD_LIBRARY_PATH=%s' % (HOS_TMPDIR,)) + for (key, value) in os.environ.items(): + if key in ['ASAN_ACTIVATION_OPTIONS', 'SCUDO_OPTIONS'] or key.endswith('SAN_OPTIONS'): + args.append('%s="%s"' % (key, value)) + return ' '.join(args) + +device_env = build_env() +device_args = ' '.join(sys.argv[1:]) # FIXME: escape? +device_stdout = device_binary + '.stdout' +device_stderr = device_binary + '.stderr' +device_exitcode = device_binary + '.exitcode' +device_linker = '' + +ret = adb(['shell', 'cd %s && %s %s %s %s >%s 2>%s ; echo $? >%s' % + (HOS_TMPDIR, device_env, device_linker, device_binary, device_args, + device_stdout, device_stderr, device_exitcode)]) +if ret != 0: + sys.exit(ret) + +sys.stdout.write(pull_from_device(device_stdout)) +sys.stderr.write(pull_from_device(device_stderr)) +retcode = int(pull_from_device(device_exitcode)) +# If the device process died with a signal, do abort(). +# Not exactly the same, but good enough to fool "not --crash". +if retcode > 128: + os.kill(os.getpid(), signal.SIGABRT) +sys.exit(retcode) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 74eff2002fc9938511d9c119242b676ed98100a6..945a59509075d457fc88c0e6cc8dada627c6cc70 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -416,13 +416,21 @@ set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH "Path where built libc++ runtime libraries should be installed.") if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) - set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") - set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH - "Path where built libc++ libraries should be installed.") set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE PATH "Path where target-specific libc++ headers should be installed.") + if(OHOS) + set(LIBCXX_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBCXX_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX} CACHE PATH + "Path where built libc++ libraries should be installed.") + else() + set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libc++ libraries should be installed.") + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake index 209e6214a47180a48b44d9efa4326a1f547528c5..9e79b7bbde3ff42d1136594bd3789128e8bba97b 100644 --- a/libcxx/cmake/config-ix.cmake +++ b/libcxx/cmake/config-ix.cmake @@ -114,6 +114,8 @@ elseif(APPLE) set(LIBCXX_HAS_M_LIB NO) set(LIBCXX_HAS_RT_LIB NO) set(LIBCXX_HAS_ATOMIC_LIB NO) +elseif(OHOS) + set(LIBCXX_HAS_ATOMIC_LIB NO) elseif(FUCHSIA) set(LIBCXX_HAS_M_LIB NO) set(LIBCXX_HAS_PTHREAD_LIB NO) diff --git a/libcxx/include/__config b/libcxx/include/__config index 589b5c3b2241e0b5d2a3597053050f59f232e922..42be8ee88c0c909a1deca2726c226de356d9245e 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -912,7 +912,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD defined(__sun__) || \ defined(__MVS__) || \ defined(_AIX) || \ - defined(__EMSCRIPTEN__) + defined(__EMSCRIPTEN__) || \ + defined(__OHOS_FAMILY__) // clang-format on # define _LIBCPP_HAS_THREAD_API_PTHREAD # elif defined(__Fuchsia__) @@ -990,7 +991,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # endif # if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \ - defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) || defined(__OHOS_FAMILY__) # define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE # endif diff --git a/libcxx/include/__locale b/libcxx/include/__locale index 40f9a3ff57c22635254be654227333b2a10eca6a..e1407a07f63229c77e381cff99c04fb2d1d45463 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -40,6 +40,9 @@ #elif defined(__wasi__) // WASI libc uses musl's locales support. # include <__support/musl/xlocale.h> +#elif defined(__LITEOS__) || defined(__OHOS__) +// LiteOS libc uses musl's locales support. +# include <__support/musl/xlocale.h> #elif defined(_LIBCPP_HAS_MUSL_LIBC) # include <__support/musl/xlocale.h> #endif diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt index 9abf548abbb9526c6ba2da307114b9d12d781556..02ee3e023a23efc5584c5236920f627409706c09 100644 --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -194,6 +194,9 @@ endfunction() split_list(LIBCXX_COMPILE_FLAGS) split_list(LIBCXX_LINK_FLAGS) +if (NOT DEFINED LIBCXX_OUTPUT_NAME) + set (LIBCXX_OUTPUT_NAME "c++") +endif() # Build the shared library. if (LIBCXX_ENABLE_SHARED) add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) @@ -204,7 +207,7 @@ if (LIBCXX_ENABLE_SHARED) PROPERTIES COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" LINK_FLAGS "${LIBCXX_LINK_FLAGS}" - OUTPUT_NAME "c++" + OUTPUT_NAME "${LIBCXX_OUTPUT_NAME}" VERSION "${LIBCXX_LIBRARY_VERSION}" SOVERSION "${LIBCXX_ABI_VERSION}" DEFINE_SYMBOL "" @@ -278,6 +281,9 @@ endif() set(CMAKE_STATIC_LIBRARY_PREFIX "lib") +if (NOT DEFINED LIBCXX_OUTPUT_STATIC_NAME) + set (LIBCXX_OUTPUT_STATIC_NAME "c++") +endif() # Build the static library. if (LIBCXX_ENABLE_STATIC) add_library(cxx_static STATIC ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) @@ -289,7 +295,7 @@ if (LIBCXX_ENABLE_STATIC) PROPERTIES COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" LINK_FLAGS "${LIBCXX_LINK_FLAGS}" - OUTPUT_NAME "c++" + OUTPUT_NAME "${LIBCXX_OUTPUT_STATIC_NAME}" ) cxx_add_common_build_flags(cxx_static) cxx_set_common_defines(cxx_static) diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h index bef26ec5019eccab758733eb85a1f8a6fc404968..0e762d276330d618fe77b4e1fb261006b4ade687 100644 --- a/libcxx/src/include/config_elast.h +++ b/libcxx/src/include/config_elast.h @@ -29,6 +29,8 @@ // No _LIBCPP_ELAST needed on Fuchsia #elif defined(__wasi__) // No _LIBCPP_ELAST needed on WASI +#elif defined(__OHOS_FAMILY__) +// No _LIBCPP_ELAST needed on OHOS #elif defined(__EMSCRIPTEN__) // No _LIBCPP_ELAST needed on Emscripten #elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC) diff --git a/libcxx/test/libcxx/modules_include.sh.cpp b/libcxx/test/libcxx/modules_include.sh.cpp index b6d73e8ed446078e241b8f79db547f5d7762e344..ddd9caafcd81dd76bff5f581de5746c38918fee1 100644 --- a/libcxx/test/libcxx/modules_include.sh.cpp +++ b/libcxx/test/libcxx/modules_include.sh.cpp @@ -16,6 +16,9 @@ // GCC doesn't support -fcxx-modules // UNSUPPORTED: gcc +// FIXME: hangs on CI +// UNSUPPORTED: ohos-ci + // The Windows headers don't appear to be compatible with modules // UNSUPPORTED: windows diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py index dea8b38e7cbe9926c57b721afb10b26b7f871378..8ec356c85b9dc4afa54c5438edf1ffc8822f171b 100644 --- a/libcxx/utils/libcxx/test/features.py +++ b/libcxx/utils/libcxx/test/features.py @@ -299,3 +299,7 @@ DEFAULT_FEATURES += [ actions=[AddSubstitution('%{gdb}', lambda cfg: shutil.which('gdb'))] ) ] + +DEFAULT_FEATURES += [ + Feature(name='ohos-ci', when=lambda cfg: os.path.exists('/.dockerenv')) +] diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt index b8326d08d23a8f743870b47b3733f39568e8f800..f6f945a134f867b857f8957c5937809a9be9e7b9 100644 --- a/libcxxabi/CMakeLists.txt +++ b/libcxxabi/CMakeLists.txt @@ -186,9 +186,17 @@ set(LIBCXXABI_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) set(LIBCXXABI_HEADER_DIR ${LLVM_BINARY_DIR}) - set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) - set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH - "Path where built libc++abi libraries should be installed.") + if(OHOS) + set(LIBCXXABI_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBCXXABI_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX} CACHE PATH + "Path where built libc++abi libraries should be installed.") + else() + set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libc++abi libraries should be installed.") + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXXABI_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR}) string(APPEND LIBCXXABI_INSTALL_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR}) diff --git a/libcxxabi/src/abort_message.cpp b/libcxxabi/src/abort_message.cpp index 859a5031b93fecdd24c07ca4246d822b61ead541..2264168e1ef0ab7bb0af8d4f32ca5721e18883d3 100644 --- a/libcxxabi/src/abort_message.cpp +++ b/libcxxabi/src/abort_message.cpp @@ -11,7 +11,7 @@ #include #include "abort_message.h" -#ifdef __BIONIC__ +#if defined(__BIONIC__) && !defined(__OHOS__) # include # if __ANDROID_API__ >= 21 # include @@ -52,7 +52,7 @@ void abort_message(const char* format, ...) va_end(list); CRSetCrashLogMessage(buffer); -#elif defined(__BIONIC__) +#elif defined(__BIONIC__) && !defined(__OHOS__) char* buffer; va_list list; va_start(list, format); diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt index 5a06805f05f182a34f8d5f7223fe00d45deaba62..a895e4787c8550e76a2e61dfa9fccf09d5144917 100644 --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -116,9 +116,17 @@ set(LIBUNWIND_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH "Path where built libunwind runtime libraries should be installed.") if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) - set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) - set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH - "Path where built libunwind libraries should be installed.") + if(OHOS) + set(LIBUNWIND_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBUNWIND_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX} CACHE PATH + "Path where built libunwind libraries should be installed.") + else() + set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libunwind libraries should be installed.") + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBUNWIND_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR}) string(APPEND LIBUNWIND_INSTALL_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR}) @@ -313,7 +321,7 @@ if (C_SUPPORTS_COMMENT_LIB_PRAGMA) if (LIBUNWIND_HAS_DL_LIB) add_definitions(-D_LIBUNWIND_LINK_DL_LIB) endif() - if (LIBUNWIND_HAS_PTHREAD_LIB) + if (LIBUNWIND_HAS_PTHREAD_LIB AND NOT OHOS) add_definitions(-D_LIBUNWIND_LINK_PTHREAD_LIB) endif() endif() diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index af976e39147db43cab849b8a5189bb7920d09ac3..d6babe9f74c256bcf7f16f29389bf7b6712413c2 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -286,6 +286,8 @@ struct Configuration { uint64_t zStackSize; unsigned ltoPartitions; unsigned ltoo; + unsigned ltos; + bool mergeFunctions; unsigned optimize; StringRef thinLTOJobs; unsigned timeTraceGranularity; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 296fb4220012e06f8a6807a954db7424c3809c3c..abcc8a984a65905cc2b62a84903015a86b588c7b 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -63,6 +63,7 @@ #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include +#include #include using namespace llvm; @@ -1018,6 +1019,47 @@ static bool isValidReportString(StringRef arg) { return arg == "none" || arg == "warning" || arg == "error"; } +static std::pair +parseLTOOptArg(opt::InputArgList &args, unsigned key, StringRef defaultValue) { + auto *a = args.getLastArg(key); + llvm::StringRef value = a ? a->getValue() : defaultValue; + + unsigned optLevel = 0; + unsigned sizeLevel = 0; + + if (value.size() != 1) { + error("invalid optimization level for LTO: " + value); + return {optLevel, sizeLevel}; + } + + char c = value[0]; + + switch (c) { + + case '0': + case '1': + case '2': + case '3': + optLevel = c - '0'; + break; + + case 's': + optLevel = 2; + sizeLevel = 1; + break; + + case 'z': + optLevel = 2; + sizeLevel = 2; + break; + + default: + error("invalid optimization level for LTO: " + value); + } + + return {optLevel, sizeLevel}; +} + // Initializes Config members by the command line options. static void readConfigs(opt::InputArgList &args) { errorHandler().verbose = args.hasArg(OPT_verbose); @@ -1104,8 +1146,9 @@ static void readConfigs(opt::InputArgList &args) { config->ltoWholeProgramVisibility = args.hasFlag(OPT_lto_whole_program_visibility, OPT_no_lto_whole_program_visibility, false); - config->ltoo = args::getInteger(args, OPT_lto_O, 2); config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq); + std::tie(config->ltoo, config->ltos) = parseLTOOptArg(args, OPT_lto_O, "2"); + config->mergeFunctions = args.hasArg(OPT_lto_mf); config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile); config->ltoBasicBlockSections = diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index d9266e59588793faaa96ec811eb5b258796d83e4..4e6c20f5c7f6014f4f23ed17b0962212966989c6 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -557,6 +557,10 @@ def lto_newpm_passes: JJ<"lto-newpm-passes=">, HelpText<"Passes to run during LTO">; def lto_O: JJ<"lto-O">, MetaVarName<"">, HelpText<"Optimization level for LTO">; +def lto_S: J<"lto-S">, MetaVarName<"">, + HelpText<"Size Optimization level for LTO, works only with -lto-O2">; +def lto_mf: F<"lto-mf">, + HelpText<"Enable Merge Functions pass for link time optimizations.">; def lto_partitions: JJ<"lto-partitions=">, HelpText<"Number of LTO codegen partitions">; def lto_cs_profile_generate: FF<"lto-cs-profile-generate">, diff --git a/lld/test/ELF/lto/opt-level.ll b/lld/test/ELF/lto/opt-level.ll index 6e0cc9ac98c55c945e418a9154c5533f36c9cfc7..628e4ef7126c0504c86bb352fd73448df225f9df 100644 --- a/lld/test/ELF/lto/opt-level.ll +++ b/lld/test/ELF/lto/opt-level.ll @@ -19,14 +19,14 @@ ; RUN: FileCheck --check-prefix=INVALID1 %s ; RUN: not ld.lld -o /dev/null -e main --plugin-opt=Ofoo %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALID2 %s -; INVALID2: --plugin-opt=Ofoo: number expected, but got 'foo' +; INVALID2: invalid optimization level for LTO: foo ; RUN: not ld.lld -o /dev/null -e main --lto-O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s -; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE1: invalid optimization level for LTO: -1 ; RUN: not ld.lld -o /dev/null -e main --plugin-opt=O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s -; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE2: invalid optimization level for LTO: -1 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lldb/cmake/modules/FindPythonAndSwig.cmake b/lldb/cmake/modules/FindPythonAndSwig.cmake index 3535b548c45f2de5dda4c1e5c9b7d5ead261c936..562d5307e8c8047d23dae32ae6e060951443b343 100644 --- a/lldb/cmake/modules/FindPythonAndSwig.cmake +++ b/lldb/cmake/modules/FindPythonAndSwig.cmake @@ -35,6 +35,17 @@ macro(FindPython3) endif() endmacro() +#OHOS specific: copy LLVM-10 definitions if new Python3_*** are not set +if(NOT Python3_EXECUTABLE AND PYTHON_EXECUTABLE) + set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) +endif() +if(NOT Python3_LIBRARIES AND PYTHON_LIBRARIES) + set(Python3_LIBRARIES ${PYTHON_LIBRARIES}) +endif() +if(NOT Python3_INCLUDE_DIRS AND PYTHON_INCLUDE_DIRS) + set(Python3_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) +endif() + if(Python3_LIBRARIES AND Python3_INCLUDE_DIRS AND Python3_EXECUTABLE AND SWIG_EXECUTABLE) set(PYTHONANDSWIG_FOUND TRUE) else() diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 987353517d0d5947aa94cfaf07cfb85465e5e15a..55d1aa17b46b597240e2acc0a09ac3832a22ccb6 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -313,7 +313,7 @@ endif() # Figure out if lldb could use lldb-server. If so, then we'll # ensure we build lldb-server when an lldb target is being built. -if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|Windows") +if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|Windows|OHOS") set(LLDB_CAN_USE_LLDB_SERVER ON) else() set(LLDB_CAN_USE_LLDB_SERVER OFF) diff --git a/lldb/include/lldb/Host/HostInfo.h b/lldb/include/lldb/Host/HostInfo.h index b7010d69d88e7fc33e079cce514558ff6d49ff51..fbb5bbf1e442c77e73a926fb038441e5eb03aaa0 100644 --- a/lldb/include/lldb/Host/HostInfo.h +++ b/lldb/include/lldb/Host/HostInfo.h @@ -39,6 +39,9 @@ #if defined(__ANDROID__) #include "lldb/Host/android/HostInfoAndroid.h" #define HOST_INFO_TYPE HostInfoAndroid +#elif defined(__OHOS_FAMILY__) +#include "lldb/Host/ohos/HostInfoOHOS.h" +#define HOST_INFO_TYPE HostInfoOHOS #else #include "lldb/Host/linux/HostInfoLinux.h" #define HOST_INFO_TYPE HostInfoLinux diff --git a/lldb/include/lldb/Host/MainLoop.h b/lldb/include/lldb/Host/MainLoop.h index f04ac7359cc1851e91078f25d925c148f9e809a0..c89a28387b6a654af18a9f15a3c255c7cc13ef82 100644 --- a/lldb/include/lldb/Host/MainLoop.h +++ b/lldb/include/lldb/Host/MainLoop.h @@ -16,7 +16,8 @@ #include #include -#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) +#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) && \ + !defined(__OHOS_FAMILY__) #define SIGNAL_POLLING_UNSUPPORTED 1 #endif diff --git a/lldb/include/lldb/Host/ohos/HostInfoOHOS.h b/lldb/include/lldb/Host/ohos/HostInfoOHOS.h new file mode 100644 index 0000000000000000000000000000000000000000..e20582820145a886be2c46b40e81032075eebde1 --- /dev/null +++ b/lldb/include/lldb/Host/ohos/HostInfoOHOS.h @@ -0,0 +1,32 @@ +//===-- HostInfoOHOS.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_ohos_HostInfoOHOS_h_ +#define lldb_Host_ohos_HostInfoOHOS_h_ + +#include "lldb/Host/linux/HostInfoLinux.h" + +namespace lldb_private { + +class HostInfoOHOS : public HostInfoLinux { + friend class HostInfoBase; + +public: + static FileSpec GetDefaultShell(); + static FileSpec ResolveLibraryPath(const std::string &path, + const ArchSpec &arch); + +protected: + static void ComputeHostArchitectureSupport(ArchSpec &arch_32, + ArchSpec &arch_64); + static bool ComputeTempFileBaseDirectory(FileSpec &file_spec); +}; + +} // end of namespace lldb_private + +#endif // #ifndef lldb_Host_ohos_HostInfoOHOS_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepRange.h b/lldb/include/lldb/Target/ThreadPlanStepRange.h index 2fe88527710006b00f395ebf98e713ca025ce28c..36288a0d10aefccae00690f0a2974e3944cb4791 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepRange.h @@ -44,6 +44,7 @@ protected: bool InRange(); lldb::FrameComparison CompareCurrentFrameToStartFrame(); bool InSymbol(); + bool MaybeAArch32Or64FunctionTail(); void DumpRanges(Stream *s); Disassembler *GetDisassembler(); diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py index 191a1e0ad7cccf78bd20f3a1cbd75a6909e62654..dc553938e1cceabfb4b31bb993cc0ae25fc4edc0 100644 --- a/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/lldb/packages/Python/lldbsuite/test/decorators.py @@ -663,6 +663,9 @@ def skipIfPlatform(oslist): return unittest2.skipIf(lldbplatformutil.getPlatform() in oslist, "skip on %s" % (", ".join(oslist))) +def skipOnOpenHarmonyCI(func): + return unittest2.skipIf(lldbplatformutil.isOpenHarmonyCI(), "skip on OpenHarmony CI")(func) + def skipUnlessPlatform(oslist): """Decorate the item to skip tests unless running on one of the listed platforms.""" diff --git a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py index 719131c9248e816c5c4ae9ef88f7a68c7bdd405b..317f19bd712f69042c3fde8e956f3c8e91764a06 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py +++ b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py @@ -149,6 +149,8 @@ def platformIsDarwin(): """Returns true if the OS triple for the selected platform is any valid apple OS""" return getPlatform() in getDarwinOSTriples() +def isOpenHarmonyCI(): + return getPlatform() == 'linux' and os.path.exists('/.dockerenv') def findMainThreadCheckerDylib(): if not platformIsDarwin(): diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index d46e54f30bd5555c88d7484ea21d2a9837ebb7e7..d6c249d644b1e796815dcab8ca24842794d60297 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -739,11 +739,6 @@ class Base(unittest2.TestCase): for setting, value in configuration.settings: commands.append('setting set %s %s'%(setting, value)) - # Make sure that a sanitizer LLDB's environment doesn't get passed on. - if cls.platformContext and cls.platformContext.shlib_environment_var in os.environ: - commands.append('settings set target.env-vars {}='.format( - cls.platformContext.shlib_environment_var)) - # Set environment variables for the inferior. if lldbtest_config.inferior_env: commands.append('settings set target.env-vars {}'.format( diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index a6efeb3f960f7fc20264287b50cbc2f408974b69..2a080fbcfd221baa216f1fb04b8b88199b4e98bb 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -167,6 +167,18 @@ public: const Constant *constant = dyn_cast(value); if (constant) { + if (constant->getValueID() == Value::ConstantFPVal) { + if (auto *cfp = dyn_cast(constant)) { + if (cfp->getType()->isDoubleTy()) + scalar = cfp->getValueAPF().convertToDouble(); + else if (cfp->getType()->isFloatTy()) + scalar = cfp->getValueAPF().convertToFloat(); + else + return false; + return true; + } + return false; + } APInt value_apint; if (!ResolveConstantValue(value_apint, constant)) @@ -189,9 +201,18 @@ public: lldb::offset_t offset = 0; if (value_size <= 8) { - uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); - return AssignToMatchType(scalar, llvm::APInt(64, u64value), - value->getType()); + Type *ty = value->getType(); + if (ty->isDoubleTy()) { + scalar = value_extractor.GetDouble(&offset); + return true; + } else if (ty->isFloatTy()) { + scalar = value_extractor.GetFloat(&offset); + return true; + } else { + uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); + return AssignToMatchType(scalar, llvm::APInt(64, u64value), + value->getType()); + } } return false; @@ -205,11 +226,15 @@ public: return false; lldb_private::Scalar cast_scalar; - - scalar.MakeUnsigned(); - if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()), - value->getType())) - return false; + Type *vty = value->getType(); + if (vty->isFloatTy() || vty->isDoubleTy()) { + cast_scalar = scalar; + } else { + scalar.MakeUnsigned(); + if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()), + value->getType())) + return false; + } size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType()); @@ -543,16 +568,17 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, } break; case Instruction::GetElementPtr: break; + case Instruction::FCmp: case Instruction::ICmp: { - ICmpInst *icmp_inst = dyn_cast(&ii); + CmpInst *cmp_inst = dyn_cast(&ii); - if (!icmp_inst) { + if (!cmp_inst) { error.SetErrorToGenericError(); error.SetErrorString(interpreter_internal_error); return false; } - switch (icmp_inst->getPredicate()) { + switch (cmp_inst->getPredicate()) { default: { LLDB_LOGF(log, "Unsupported ICmp predicate: %s", PrintValue(&ii).c_str()); @@ -561,11 +587,17 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, error.SetErrorString(unsupported_opcode_error); return false; } + case CmpInst::FCMP_OEQ: case CmpInst::ICMP_EQ: + case CmpInst::FCMP_UNE: case CmpInst::ICMP_NE: + case CmpInst::FCMP_OGT: case CmpInst::ICMP_UGT: + case CmpInst::FCMP_OGE: case CmpInst::ICMP_UGE: + case CmpInst::FCMP_OLT: case CmpInst::ICMP_ULT: + case CmpInst::FCMP_OLE: case CmpInst::ICMP_ULE: case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: @@ -595,6 +627,11 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, case Instruction::Xor: case Instruction::ZExt: break; + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: + break; } for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) { @@ -709,7 +746,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, case Instruction::AShr: case Instruction::And: case Instruction::Or: - case Instruction::Xor: { + case Instruction::Xor: + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: { const BinaryOperator *bin_op = dyn_cast(inst); if (!bin_op) { @@ -748,12 +789,15 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, default: break; case Instruction::Add: + case Instruction::FAdd: result = L + R; break; case Instruction::Mul: + case Instruction::FMul: result = L * R; break; case Instruction::Sub: + case Instruction::FSub: result = L - R; break; case Instruction::SDiv: @@ -766,6 +810,9 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, R.MakeUnsigned(); result = L / R; break; + case Instruction::FDiv: + result = L / R; + break; case Instruction::SRem: L.MakeSigned(); R.MakeSigned(); @@ -1028,10 +1075,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, LLDB_LOGF(log, " Poffset : %s", frame.SummarizeValue(inst).c_str()); } } break; + case Instruction::FCmp: case Instruction::ICmp: { - const ICmpInst *icmp_inst = cast(inst); + const CmpInst *cmp_inst = cast(inst); - CmpInst::Predicate predicate = icmp_inst->getPredicate(); + CmpInst::Predicate predicate = cmp_inst->getPredicate(); Value *lhs = inst->getOperand(0); Value *rhs = inst->getOperand(1); @@ -1059,9 +1107,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, default: return false; case CmpInst::ICMP_EQ: + case CmpInst::FCMP_OEQ: result = (L == R); break; case CmpInst::ICMP_NE: + case CmpInst::FCMP_UNE: result = (L != R); break; case CmpInst::ICMP_UGT: @@ -1074,16 +1124,28 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, R.MakeUnsigned(); result = (L >= R); break; + case CmpInst::FCMP_OGE: + result = (L >= R); + break; + case CmpInst::FCMP_OGT: + result = (L > R); + break; case CmpInst::ICMP_ULT: L.MakeUnsigned(); R.MakeUnsigned(); result = (L < R); break; + case CmpInst::FCMP_OLT: + result = (L < R); + break; case CmpInst::ICMP_ULE: L.MakeUnsigned(); R.MakeUnsigned(); result = (L <= R); break; + case CmpInst::FCMP_OLE: + result = (L <= R); + break; case CmpInst::ICMP_SGT: L.MakeSigned(); R.MakeSigned(); diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index 64d9bb00ffab3622e19368f2f29653dea345ec56..ea368a6d4d71c45fe6a2d94e7016fbe27c0f2d02 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -96,7 +96,7 @@ else() endif() - elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") + elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") add_host_subdirectory(linux linux/AbstractSocket.cpp linux/Host.cpp @@ -110,6 +110,11 @@ else() android/LibcGlue.cpp ) endif() + if (CMAKE_SYSTEM_NAME MATCHES "OHOS") + add_host_subdirectory(ohos + ohos/HostInfoOHOS.cpp + ) + endif() elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") add_host_subdirectory(freebsd freebsd/Host.cpp diff --git a/lldb/source/Host/common/MainLoop.cpp b/lldb/source/Host/common/MainLoop.cpp index 8e384c9266b6b12a21500dbcd060aa2f81eea389..bfc1fb16ea0e15ab7b53e80c73faecd6263cf322 100644 --- a/lldb/source/Host/common/MainLoop.cpp +++ b/lldb/source/Host/common/MainLoop.cpp @@ -86,7 +86,7 @@ private: int num_events = -1; #else -#ifdef __ANDROID__ +#if defined(__ANDROID__) fd_set read_fd_set; #else std::vector read_fds; @@ -140,7 +140,7 @@ void MainLoop::RunImpl::ProcessEvents() { } #else MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { -#ifndef __ANDROID__ +#if !defined(__ANDROID__) read_fds.reserve(loop.m_read_fds.size()); #endif } @@ -162,7 +162,7 @@ sigset_t MainLoop::RunImpl::get_sigmask() { return sigmask; } -#ifdef __ANDROID__ +#if defined(__ANDROID__) Status MainLoop::RunImpl::Poll() { // ppoll(2) is not supported on older all android versions. Also, older // versions android (API <= 19) implemented pselect in a non-atomic way, as a @@ -218,7 +218,7 @@ Status MainLoop::RunImpl::Poll() { #endif void MainLoop::RunImpl::ProcessEvents() { -#ifdef __ANDROID__ +#if defined(__ANDROID__) // Collect first all readable file descriptors into a separate vector and // then iterate over it to invoke callbacks. Iterating directly over // loop.m_read_fds is not possible because the callbacks can modify the diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index c2fb5509034e5c20879d3df81e2f177c0ef8895b..db954a6d9efa32ad1fa4f48cc3fc3f489f3f6c8b 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -38,7 +38,7 @@ #include "lldb/Host/linux/AbstractSocket.h" #endif -#ifdef __ANDROID__ +#if defined(__ANDROID__) #include #include #include diff --git a/lldb/source/Host/common/TCPSocket.cpp b/lldb/source/Host/common/TCPSocket.cpp index eabc9fef8a661c867978f7313f1005ef741feb84..c1d7308025eb22defb4dee6dd83f171c211952a6 100644 --- a/lldb/source/Host/common/TCPSocket.cpp +++ b/lldb/source/Host/common/TCPSocket.cpp @@ -160,6 +160,8 @@ Status TCPSocket::Connect(llvm::StringRef name) { std::vector addresses = SocketAddress::GetAddressInfo(host_port->hostname.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); + llvm::partition(addresses, + [](auto &sa) { return sa.GetFamily() == AF_INET; }); for (SocketAddress &address : addresses) { error = CreateSocket(address.GetFamily()); if (error.Fail()) diff --git a/lldb/source/Host/ohos/HostInfoOHOS.cpp b/lldb/source/Host/ohos/HostInfoOHOS.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e47d26e3e93868d2fc1fbe6dbd241ed83264576b --- /dev/null +++ b/lldb/source/Host/ohos/HostInfoOHOS.cpp @@ -0,0 +1,94 @@ +//===-- HostInfoOHOS.cpp -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/ohos/HostInfoOHOS.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/linux/HostInfoLinux.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +using namespace lldb_private; +using namespace llvm; + +void HostInfoOHOS::ComputeHostArchitectureSupport(ArchSpec &arch_32, + ArchSpec &arch_64) { + HostInfoLinux::ComputeHostArchitectureSupport(arch_32, arch_64); + + if (arch_32.IsValid()) { + arch_32.GetTriple().setEnvironment(llvm::Triple::UnknownEnvironment); + } + if (arch_64.IsValid()) { + arch_64.GetTriple().setEnvironment(llvm::Triple::UnknownEnvironment); + } +} + +FileSpec HostInfoOHOS::GetDefaultShell() { + return FileSpec("/system/bin/sh"); +} + +FileSpec HostInfoOHOS::ResolveLibraryPath(const std::string &module_path, + const ArchSpec &arch) { + static const char *const ld_library_path_separator = ":"; + static const char *const default_lib32_path[] = {"/vendor/lib", "/system/lib", + nullptr}; + static const char *const default_lib64_path[] = {"/vendor/lib64", + "/system/lib64", nullptr}; + + if (module_path.empty() || module_path[0] == '/') { + FileSpec file_spec(module_path.c_str()); + FileSystem::Instance().Resolve(file_spec); + return file_spec; + } + + SmallVector ld_paths; + + if (const char *ld_library_path = ::getenv("LD_LIBRARY_PATH")) + StringRef(ld_library_path) + .split(ld_paths, StringRef(ld_library_path_separator), -1, false); + + const char *const *default_lib_path = nullptr; + switch (arch.GetAddressByteSize()) { + case 4: + default_lib_path = default_lib32_path; + break; + case 8: + default_lib_path = default_lib64_path; + break; + default: + assert(false && "Unknown address byte size"); + return FileSpec(); + } + + for (const char *const *it = default_lib_path; *it; ++it) + ld_paths.push_back(StringRef(*it)); + + for (const StringRef &path : ld_paths) { + FileSpec file_candidate(path.str().c_str()); + FileSystem::Instance().Resolve(file_candidate); + file_candidate.AppendPathComponent(module_path.c_str()); + + if (FileSystem::Instance().Exists(file_candidate)) + return file_candidate; + } + + return FileSpec(); +} + +bool HostInfoOHOS::ComputeTempFileBaseDirectory(FileSpec &file_spec) { + bool success = HostInfoLinux::ComputeTempFileBaseDirectory(file_spec); + + // On OHOS, there is no path which is guaranteed to be writable. If the + // user has not provided a path via an environment variable, the generic + // algorithm will deduce /tmp, which is plain wrong. In that case we have an + // invalid directory, we substitute the path with /data/local/tmp, which is + // correct at least in some cases (i.e., when running as shell user). + if (!success || !FileSystem::Instance().Exists(file_spec)) + file_spec = FileSpec("/data/local/tmp"); + + return FileSystem::Instance().Exists(file_spec); +} diff --git a/lldb/source/Host/posix/DomainSocket.cpp b/lldb/source/Host/posix/DomainSocket.cpp index ddbd983abb81dd155d20888caa1093d4b33b8beb..bd2809817de8b5e2f3ec6df001c604974e115001 100644 --- a/lldb/source/Host/posix/DomainSocket.cpp +++ b/lldb/source/Host/posix/DomainSocket.cpp @@ -18,7 +18,7 @@ using namespace lldb; using namespace lldb_private; -#ifdef __ANDROID__ +#if defined(__ANDROID__) // Android does not have SUN_LEN #ifndef SUN_LEN #define SUN_LEN(ptr) \ diff --git a/lldb/source/Host/posix/HostInfoPosix.cpp b/lldb/source/Host/posix/HostInfoPosix.cpp index 63553590dff51119534aefefaad4c8bf8232733f..0c8e05aecdf319e17bee59b71eadf5752e60c029 100644 --- a/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/lldb/source/Host/posix/HostInfoPosix.cpp @@ -95,7 +95,7 @@ llvm::Optional PosixUserIDResolver::DoGetUserName(id_t uid) { } llvm::Optional PosixUserIDResolver::DoGetGroupName(id_t gid) { -#ifndef __ANDROID__ +#if !defined(__ANDROID__) && !defined(__OHOS_FAMILY__) char group_buffer[PATH_MAX]; size_t group_buffer_size = sizeof(group_buffer); struct group group_info; diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt index 6869587f917ebab915a5ecfa9ca290da9e8884cd..8ff59c124f75127370b461a48c9ce27a50b882cb 100644 --- a/lldb/source/Plugins/Platform/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/CMakeLists.txt @@ -8,3 +8,4 @@ add_subdirectory(OpenBSD) add_subdirectory(POSIX) add_subdirectory(QemuUser) add_subdirectory(Windows) +add_subdirectory(OHOS) diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index 9fdfe4c0dc14096e58f000198077cfcd9f347e1a..1fe7f35d0d7541b827f04c723d0bf4bb216b8da8 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -85,7 +85,7 @@ void PlatformLinux::Initialize() { PlatformPOSIX::Initialize(); if (g_initialize_count++ == 0) { -#if defined(__linux__) && !defined(__ANDROID__) +#if defined(__linux__) && !defined(__ANDROID__) && !defined(__OHOS_FAMILY__) PlatformSP default_platform_sp(new PlatformLinux(true)); default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); Platform::SetHostPlatform(default_platform_sp); diff --git a/lldb/source/Plugins/Platform/OHOS/CMakeLists.txt b/lldb/source/Plugins/Platform/OHOS/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..cc71762efe2ea58aafadcf05184ebe6fc3bd4078 --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/CMakeLists.txt @@ -0,0 +1,13 @@ +add_lldb_library(lldbPluginPlatformOHOS PLUGIN + HdcClient.cpp + PlatformOHOS.cpp + PlatformOHOSRemoteGDBServer.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbPluginPlatformLinux + lldbPluginPlatformGDB + LINK_COMPONENTS + Support + ) diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97fa08fb44da2de096b3483e9690465f7bb6da98 --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp @@ -0,0 +1,379 @@ +//===-- HdcClient.cpp -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "HdcClient.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FileUtilities.h" + +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/PosixApi.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataEncoder.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timeout.h" + +#if defined(_WIN32) +#include +#else +#include +#endif + +#include + +#include +#include +#include +#include + +// On Windows, transitive dependencies pull in , which defines a +// macro that clashes with a method name. +#ifdef SendMessage +#undef SendMessage +#endif + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::platform_ohos; +using namespace std::chrono; + +namespace { + +const seconds kReadTimeout(20); +const char *kSocketNamespaceAbstract = "localabstract"; +const char *kSocketNamespaceFileSystem = "localfilesystem"; + +Status ReadAllBytes(Connection &conn, void *buffer, size_t size, + size_t *read_ptr, ConnectionStatus *status_ptr) { + + Status error; + ConnectionStatus status; + char *read_buffer = static_cast(buffer); + + auto now = steady_clock::now(); + const auto deadline = now + kReadTimeout; + size_t total_read_bytes = 0; + while (total_read_bytes < size && now < deadline) { + auto read_bytes = + conn.Read(read_buffer + total_read_bytes, size - total_read_bytes, + duration_cast(deadline - now), status, &error); + if (status_ptr) + *status_ptr = status; + if (error.Fail()) + return error; + total_read_bytes += read_bytes; + if (read_ptr) + *read_ptr = total_read_bytes; + if (status != eConnectionStatusSuccess) + break; + now = steady_clock::now(); + } + if (total_read_bytes < size) + error = Status( + "Unable to read requested number of bytes. Connection status: %d.", + status); + return error; +} + +} // namespace + +Status HdcClient::CreateByDeviceID(const std::string &device_id, + HdcClient &hdc) { + DeviceIDList connect_devices; + auto error = hdc.GetDevices(connect_devices); + if (error.Fail()) + return error; + + std::string hdc_utid; + if (!device_id.empty()) + hdc_utid = device_id; + else if (const char *env_hdc_utid = std::getenv("HDC_UTID")) + hdc_utid = env_hdc_utid; + + if (hdc_utid.empty()) { + if (connect_devices.size() != 1) + return Status("Expected a single connected device, got instead %zu - try " + "setting 'HDC_UTID'", + connect_devices.size()); + hdc.SetDeviceID(connect_devices.front()); + } else { + auto find_it = std::find(connect_devices.begin(), connect_devices.end(), + hdc_utid); + if (find_it == connect_devices.end()) + return Status( + "Device \"%s\" not found, check HDC_UTID environment variable", + hdc_utid.c_str()); + + hdc.SetDeviceID(*find_it); + } + return error; +} + +HdcClient::HdcClient() {} + +HdcClient::HdcClient(const std::string &device_id) : m_device_id(device_id) {} + +HdcClient::~HdcClient() {} + +void HdcClient::SetDeviceID(const std::string &device_id) { + m_device_id = device_id; +} + +const std::string &HdcClient::GetDeviceID() const { return m_device_id; } + +namespace { +typedef unsigned msg_len_t; +struct ChannelHandShake { + msg_len_t size; + char banner[12]; // must first index + union { + uint32_t channelId; + char connectKey[32]; + }; +} __attribute__((packed)); +} // namespace + +Status HdcClient::Connect() { + Status error; + ChannelHandShake handshake = {}; + if (m_device_id.size() > sizeof(handshake.connectKey)) + return Status("Device id is too long: %s", m_device_id.c_str()); + m_conn.reset(new ConnectionFileDescriptor); + std::string port = "8710"; + + const char *env_port = std::getenv("OHOS_HDC_SERVER_PORT"); + if ((env_port != NULL) && (atoi(env_port) > 0)) { + port = env_port; + } + + std::string uri = "connect://localhost:" + port; + m_conn->Connect(uri.c_str(), &error); + ConnectionStatus status = eConnectionStatusError; + if (error.Success()) { + error = ReadAllBytes(&handshake, sizeof(handshake)); + if (error.Success()) { + memset(handshake.connectKey, 0, sizeof(handshake.connectKey)); + memcpy(handshake.connectKey, m_device_id.c_str(), m_device_id.size()); + m_conn->Write(&handshake, sizeof(handshake), status, &error); + } + } + return error; +} + +Status HdcClient::GetDevices(DeviceIDList &device_list) { + device_list.clear(); + + auto error = SendMessage("list targets"); + if (error.Fail()) + return error; + + std::vector in_buffer; + error = ReadMessage(in_buffer); + + llvm::StringRef response(&in_buffer[0], in_buffer.size()); + llvm::SmallVector devices; + response.split(devices, "\n", -1, false); + + for (const auto device : devices) + device_list.push_back(static_cast(device.split('\t').first)); + + // Force disconnect since ADB closes connection after host:devices response + // is sent. + m_conn.reset(); + return error; +} + +Status HdcClient::SetPortForwarding(const uint16_t local_port, + const uint16_t remote_port) { + char message[48]; + snprintf(message, sizeof(message), "fport tcp:%d tcp:%d", local_port, + remote_port); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus("Forwardport result:OK"); +} + +Status +HdcClient::SetPortForwarding(const uint16_t local_port, + llvm::StringRef remote_socket_name, + const UnixSocketNamespace socket_namespace) { + char message[PATH_MAX]; + const char *sock_namespace_str = + (socket_namespace == UnixSocketNamespaceAbstract) + ? kSocketNamespaceAbstract + : kSocketNamespaceFileSystem; + snprintf(message, sizeof(message), "fport tcp:%d %s:%s", local_port, + sock_namespace_str, remote_socket_name.str().c_str()); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus("Forwardport result:OK"); +} + +Status HdcClient::DeletePortForwarding(std::pair fwd) { + char message[32]; + snprintf(message, sizeof(message), "fport rm tcp:%d tcp:%d", fwd.first, + fwd.second); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus(nullptr); +} + +Status HdcClient::TransferFile(const char *direction, const FileSpec &src, + const FileSpec &dst) { + llvm::SmallVector cwd; + std::error_code ec = llvm::sys::fs::current_path(cwd); + if (ec) + return Status(ec); + + std::stringstream cmd; + cmd << "file " << direction << " -cwd "; + cmd.write(cwd.data(), cwd.size()); + cmd << " " << src.GetPath() << " " << dst.GetPath(); + Status error = SendMessage(cmd.str()); + if (error.Fail()) + return error; + + return ReadResponseStatus("FileTransfer finish"); +} + +Status HdcClient::RecvFile(const FileSpec &src, const FileSpec &dst) { + return TransferFile("recv", src, dst); +} + +Status HdcClient::SendFile(const FileSpec &src, const FileSpec &dst) { + return TransferFile("send", src, dst); +} + +Status HdcClient::SendMessage(llvm::StringRef packet, const bool reconnect) { + Status error; + if (!m_conn || reconnect) { + error = Connect(); + if (error.Fail()) + return error; + } + + unsigned msg_len = packet.size() + 1; + llvm::SmallVector message(msg_len + sizeof(msg_len_t), 0); + msg_len_t len = htonl(msg_len); + memcpy(message.data(), &len, sizeof(len)); + memcpy(message.data() + sizeof(len), packet.data(), packet.size()); + + ConnectionStatus status; + m_conn->Write(message.data(), message.size(), status, &error); + if (error.Fail()) + return error; + + return error; +} + +Status HdcClient::ReadMessage(std::vector &message) { + message.clear(); + + msg_len_t packet_len; + auto error = ReadAllBytes(&packet_len, sizeof(packet_len)); + if (error.Fail()) + return error; + + packet_len = htonl(packet_len); + message.resize(packet_len, 0); + error = ReadAllBytes(&message[0], packet_len); + if (error.Fail()) + message.clear(); + + return error; +} + +Status HdcClient::ReadMessageStream(std::vector &message, + milliseconds timeout) { + auto start = steady_clock::now(); + message.clear(); + + Status error; + lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; + char buffer[1024]; + while (error.Success() && status == lldb::eConnectionStatusSuccess) { + auto end = steady_clock::now(); + auto elapsed = end - start; + if (elapsed >= timeout) + return Status("Timed out"); + + size_t n = m_conn->Read(buffer, sizeof(buffer), + duration_cast(timeout - elapsed), + status, &error); + if (n > 0) + message.insert(message.end(), &buffer[0], &buffer[n]); + } + return error; +} + +Status HdcClient::ReadResponseStatus(const char *expected) { + msg_len_t len; + ConnectionStatus conn_status; + size_t read; + + auto error = ::ReadAllBytes(*m_conn, &len, sizeof(len), &read, &conn_status); + // Special case: we expect server to close connection + if (expected == nullptr) { + if (read == 0 && conn_status == eConnectionStatusEndOfFile) + return Status(); + else if (error.Fail()) + return error; + // Something went wrong - response is not empty + // Read it and wrap to error object + } + + len = htonl(len); + llvm::SmallVector message(len + 1); + error = ReadAllBytes(message.data(), len); + if (error.Fail()) + return error; + + message[len] = 0; + if (expected == nullptr || + strncmp(message.data(), expected, strlen(expected))) + return Status("%s", message.data()); + + return error; +} + +Status HdcClient::ReadAllBytes(void *buffer, size_t size) { + return ::ReadAllBytes(*m_conn, buffer, size, nullptr, nullptr); +} + +Status HdcClient::Shell(const char *command, milliseconds timeout, + std::string *output) { + assert(command && command[0]); + std::string cmd = "shell "; + cmd += command; + Status error = SendMessage(cmd); + if (error.Fail()) + return error; + + std::vector message; + error = ReadMessageStream(message, timeout); + if (error.Fail()) + return error; + + (*output) = std::string(message.data(), message.size()); + return error; +} diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.h b/lldb/source/Plugins/Platform/OHOS/HdcClient.h new file mode 100644 index 0000000000000000000000000000000000000000..64a5a324325a34d8996803f14a2f364bb43c00a4 --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.h @@ -0,0 +1,90 @@ +//===-- HdcClient.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_HdcClient_h_ +#define liblldb_HdcClient_h_ + +#include "lldb/Utility/Status.h" +#include +#include +#include +#include +#include +#include + +namespace lldb_private { + +class FileSpec; + +namespace platform_ohos { + +class HdcClient { +public: + enum UnixSocketNamespace { + UnixSocketNamespaceAbstract, + UnixSocketNamespaceFileSystem, + }; + + using DeviceIDList = std::list; + + static Status CreateByDeviceID(const std::string &device_id, HdcClient &hdc); + + HdcClient(); + explicit HdcClient(const std::string &device_id); + + ~HdcClient(); + + const std::string &GetDeviceID() const; + + Status GetDevices(DeviceIDList &device_list); + + Status SetPortForwarding(const uint16_t local_port, + const uint16_t remote_port); + + Status SetPortForwarding(const uint16_t local_port, + llvm::StringRef remote_socket_name, + const UnixSocketNamespace socket_namespace); + + Status DeletePortForwarding(std::pair fwd); + + Status RecvFile(const FileSpec &src, const FileSpec &dst); + + Status SendFile(const FileSpec &src, const FileSpec &dst); + + Status Shell(const char *command, std::chrono::milliseconds timeout, + std::string *output); + +private: + Status Connect(); + + Status TransferFile(const char *direction, const FileSpec &src, + const FileSpec &dst); + + void SetDeviceID(const std::string &device_id); + + Status SendMessage(llvm::StringRef packet, const bool reconnect = true); + + Status SendDeviceMessage(const std::string &packet); + + Status ReadMessage(std::vector &message); + + Status ReadMessageStream(std::vector &message, + std::chrono::milliseconds timeout); + + Status ReadResponseStatus(const char *expected); + + Status ReadAllBytes(void *buffer, size_t size); + + std::string m_device_id; + std::unique_ptr m_conn; +}; + +} // namespace platform_ohos +} // namespace lldb_private + +#endif // liblldb_HdcClient_h_ diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86dda7741ac68c879704ff94ca9f9cc8e1118f49 --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -0,0 +1,256 @@ +//===-- PlatformOHOS.cpp -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/UriParser.h" + +#include "HdcClient.h" +#include "PlatformOHOS.h" +#include "PlatformOHOSRemoteGDBServer.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::platform_ohos; +using namespace std::chrono; + +static uint32_t g_initialize_count = 0; +static const unsigned int g_ohos_default_cache_size = + 2048; // Fits inside 4k adb packet. + +LLDB_PLUGIN_DEFINE(PlatformOHOS) + +void PlatformOHOS::Initialize() { + PlatformLinux::Initialize(); + + if (g_initialize_count++ == 0) { +#if defined(__OHOS_FAMILY__) + PlatformSP default_platform_sp(new PlatformOHOS(true)); + default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); + Platform::SetHostPlatform(default_platform_sp); +#endif + PluginManager::RegisterPlugin( + PlatformOHOS::GetPluginNameStatic(false), + PlatformOHOS::GetPluginDescriptionStatic(false), + PlatformOHOS::CreateInstance); + } +} + +void PlatformOHOS::Terminate() { + if (g_initialize_count > 0) { + if (--g_initialize_count == 0) { + PluginManager::UnregisterPlugin(PlatformOHOS::CreateInstance); + } + } + + PlatformLinux::Terminate(); +} + +PlatformSP PlatformOHOS::CreateInstance(bool force, const ArchSpec *arch) { + Log *log = GetLog(LLDBLog::Platform); + if (log) { + const char *arch_name; + if (arch && arch->GetArchitectureName()) + arch_name = arch->GetArchitectureName(); + else + arch_name = ""; + + const char *triple_cstr = + arch ? arch->GetTriple().getTriple().c_str() : ""; + + log->Printf("PlatformOHOS::%s(force=%s, arch={%s,%s})", __FUNCTION__, + force ? "true" : "false", arch_name, triple_cstr); + } + + bool create = force; + if (!create && arch && arch->IsValid()) { + const llvm::Triple &triple = arch->GetTriple(); + switch (triple.getVendor()) { + case llvm::Triple::PC: + create = true; + break; + default: + break; + } + + if (create) { + switch (triple.getEnvironment()) { + case llvm::Triple::OpenHOS: + break; + default: + create = false; + break; + } + } + } + + if (create) { + if (log) + log->Printf("PlatformOHOS::%s() creating remote-ohos platform", + __FUNCTION__); + + return PlatformSP(new PlatformOHOS(false)); + } + + if (log) + log->Printf( + "PlatformOHOS::%s() aborting creation of remote-ohos platform", + __FUNCTION__); + + return PlatformSP(); +} + +PlatformOHOS::PlatformOHOS(bool is_host) : PlatformLinux(is_host) {} + +PlatformOHOS::~PlatformOHOS() {} + +llvm::StringRef PlatformOHOS::GetPluginNameStatic(bool is_host) { + return is_host ? Platform::GetHostPlatformName() : "remote-ohos"; +} + +const char *PlatformOHOS::GetPluginDescriptionStatic(bool is_host) { + return is_host ? "Local OpenHarmony OS user platform plug-in." : + "Remote OpenHarmony OS user platform plug-in."; +} + +llvm::StringRef PlatformOHOS::GetPluginName() { + return GetPluginNameStatic(IsHost()); +} + +Status PlatformOHOS::ConnectRemote(Args &args) { + m_device_id.clear(); + + if (IsHost()) { + return Status("can't connect to the host platform '%s', always connected", + GetPluginName().str().c_str()); + } + + if (!m_remote_platform_sp) + m_remote_platform_sp = PlatformSP(new PlatformOHOSRemoteGDBServer()); + + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Status("URL is null."); + llvm::Optional uri = URI::Parse(url); + if (!uri) + return Status("Invalid URL: %s", url); + if (uri->hostname != "localhost") + m_device_id = static_cast(uri->hostname); + + auto error = PlatformLinux::ConnectRemote(args); + if (error.Success()) { + HdcClient adb; + error = HdcClient::CreateByDeviceID(m_device_id, adb); + if (error.Fail()) + return error; + + m_device_id = adb.GetDeviceID(); + } + return error; +} + +Status PlatformOHOS::GetFile(const FileSpec &source, + const FileSpec &destination) { + if (IsHost() || !m_remote_platform_sp) + return PlatformLinux::GetFile(source, destination); + + FileSpec source_spec(source.GetPath(false), FileSpec::Style::posix); + if (source_spec.IsRelative()) + source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent( + source_spec.GetCString(false)); + + HdcClient hdc(m_device_id); + Status error = hdc.RecvFile(source, destination); + return error; +} + +Status PlatformOHOS::PutFile(const FileSpec &source, + const FileSpec &destination, uint32_t uid, + uint32_t gid) { + if (IsHost() || !m_remote_platform_sp) + return PlatformLinux::PutFile(source, destination, uid, gid); + + FileSpec destination_spec(destination.GetPath(false), FileSpec::Style::posix); + if (destination_spec.IsRelative()) + destination_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent( + destination_spec.GetCString(false)); + + // TODO: Set correct uid and gid on remote file. + HdcClient hdc(m_device_id); + Status error = hdc.SendFile(source, destination_spec); + return error; +} + +const char *PlatformOHOS::GetCacheHostname() { return m_device_id.c_str(); } + +Status PlatformOHOS::DownloadModuleSlice(const FileSpec &src_file_spec, + const uint64_t src_offset, + const uint64_t src_size, + const FileSpec &dst_file_spec) { + if (src_offset != 0) + return Status("Invalid offset - %" PRIu64, src_offset); + + return GetFile(src_file_spec, dst_file_spec); +} + +Status PlatformOHOS::DisconnectRemote() { + Status error = PlatformLinux::DisconnectRemote(); + if (error.Success()) + m_device_id.clear(); + return error; +} + +uint32_t PlatformOHOS::GetDefaultMemoryCacheLineSize() { + return g_ohos_default_cache_size; +} + +uint32_t PlatformOHOS::GetSdkVersion() { + if (!IsConnected()) + return 0; + + // TBD + return 1; +} + +bool PlatformOHOS::GetRemoteOSVersion() { + m_os_version = llvm::VersionTuple(GetSdkVersion()); + return !m_os_version.empty(); +} + +llvm::StringRef +PlatformOHOS::GetLibdlFunctionDeclarations(lldb_private::Process *process) { + SymbolContextList matching_symbols; + std::vector dl_open_names = { "__dl_dlopen", "dlopen" }; + const char *dl_open_name = nullptr; + Target &target = process->GetTarget(); + for (auto name: dl_open_names) { + target.GetImages().FindFunctionSymbols(ConstString(name), + eFunctionNameTypeFull, + matching_symbols); + if (matching_symbols.GetSize()) { + dl_open_name = name; + break; + } + } + // Older platform versions have the dl function symbols mangled + if (dl_open_name == dl_open_names[0]) + return R"( + extern "C" void* dlopen(const char*, int) asm("__dl_dlopen"); + extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym"); + extern "C" int dlclose(void*) asm("__dl_dlclose"); + extern "C" char* dlerror(void) asm("__dl_dlerror"); + )"; + + return PlatformPOSIX::GetLibdlFunctionDeclarations(process); +} diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h new file mode 100644 index 0000000000000000000000000000000000000000..78e4e187801ff88ee5ad5f6425663a44a2a4e31f --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h @@ -0,0 +1,77 @@ +//===-- PlatformOHOS.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformOHOS_h_ +#define liblldb_PlatformOHOS_h_ + +#include +#include + +#include "Plugins/Platform/Linux/PlatformLinux.h" + +#include "HdcClient.h" + +namespace lldb_private { +namespace platform_ohos { + +class PlatformOHOS : public platform_linux::PlatformLinux { +public: + PlatformOHOS(bool is_host); + + ~PlatformOHOS() override; + + static void Initialize(); + + static void Terminate(); + + // lldb_private::PluginInterface functions + static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); + + static llvm::StringRef GetPluginNameStatic(bool is_host); + + static const char *GetPluginDescriptionStatic(bool is_host); + + llvm::StringRef GetPluginName() override; + + // lldb_private::Platform functions + Status ConnectRemote(Args &args) override; + + Status GetFile(const FileSpec &source, const FileSpec &destination) override; + + Status PutFile(const FileSpec &source, const FileSpec &destination, + uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override; + + uint32_t GetSdkVersion(); + + bool GetRemoteOSVersion() override; + + Status DisconnectRemote() override; + + uint32_t GetDefaultMemoryCacheLineSize() override; + +protected: + const char *GetCacheHostname() override; + + Status DownloadModuleSlice(const FileSpec &src_file_spec, + const uint64_t src_offset, const uint64_t src_size, + const FileSpec &dst_file_spec) override; + + llvm::StringRef + GetLibdlFunctionDeclarations(lldb_private::Process *process) override; + +private: + std::string m_device_id; + + PlatformOHOS(const PlatformOHOS &other) = delete; + PlatformOHOS& operator=(const PlatformOHOS &other) = delete; +}; + +} // namespace platofor_ohos +} // namespace lldb_private + +#endif // liblldb_PlatformOHOS_h_ diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab9c8b8bf30602bd9ff2a377a32a7c9f07e2a346 --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp @@ -0,0 +1,246 @@ +//===-- PlatformOHOSRemoteGDBServer.cpp ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/common/TCPSocket.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/UriParser.h" + +#include "PlatformOHOSRemoteGDBServer.h" + +#include + +using namespace lldb; +using namespace lldb_private; +using namespace platform_ohos; + +static const lldb::pid_t g_remote_platform_pid = + 0; // Alias for the process id of lldb-platform + +static uint16_t g_hdc_forward_port_offset = 0; + +static Status ForwardPortWithHdc( + const uint16_t local_port, const uint16_t remote_port, + llvm::StringRef remote_socket_name, + const llvm::Optional &socket_namespace, + std::string &device_id) { + Log *log = GetLog(LLDBLog::Platform); + + HdcClient hdc; + auto error = HdcClient::CreateByDeviceID(device_id, hdc); + if (error.Fail()) + return error; + + device_id = hdc.GetDeviceID(); + if (log) + log->Printf("Connected to OHOS device \"%s\"", device_id.c_str()); + + if (remote_port != 0) { + if (log) + log->Printf("Forwarding remote TCP port %d to local TCP port %d", + remote_port, local_port); + return hdc.SetPortForwarding(local_port, remote_port); + } + + if (log) + log->Printf("Forwarding remote socket \"%s\" to local TCP port %d", + remote_socket_name.str().c_str(), local_port); + + if (!socket_namespace) + return Status("Invalid socket namespace"); + + return hdc.SetPortForwarding(local_port, remote_socket_name, + *socket_namespace); +} + +static Status DeleteForwardPortWithHdc(std::pair ports, + const std::string &device_id) { + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Delete port forwarding %d -> %d, device=%s", ports.first, + ports.second, device_id.c_str()); + + HdcClient hdc(device_id); + return hdc.DeletePortForwarding(ports); +} + +static Status FindUnusedPort(uint16_t &port) { + Status error; + + if (const char *env_port = std::getenv("HDC_FORWARD_PORT_BASE_FOR_LLDB")) { + port = std::atoi(env_port) + g_hdc_forward_port_offset; + g_hdc_forward_port_offset++; + return error; + } + + std::unique_ptr tcp_socket(new TCPSocket(true, false)); + if (error.Fail()) + return error; + + error = tcp_socket->Listen("127.0.0.1:0", 1); + if (error.Success()) + port = tcp_socket->GetLocalPortNumber(); + + return error; +} + +PlatformOHOSRemoteGDBServer::PlatformOHOSRemoteGDBServer() {} + +PlatformOHOSRemoteGDBServer::~PlatformOHOSRemoteGDBServer() { + for (const auto &it : m_port_forwards) + DeleteForwardPortWithHdc(it.second, m_device_id); +} + +bool PlatformOHOSRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid, + std::string &connect_url) { + uint16_t remote_port = 0; + std::string socket_name; + if (!m_gdb_client_up->LaunchGDBServer("127.0.0.1", pid, remote_port, socket_name)) + return false; + + Log *log = GetLog(LLDBLog::Platform); + + auto error = + MakeConnectURL(pid, remote_port, socket_name.c_str(), connect_url); + if (error.Success() && log) + log->Printf("gdbserver connect URL: %s", connect_url.c_str()); + + return error.Success(); +} + +bool PlatformOHOSRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) { + DeleteForwardPort(pid); + return m_gdb_client_up->KillSpawnedProcess(pid); +} + +Status PlatformOHOSRemoteGDBServer::ConnectRemote(Args &args) { + m_device_id.clear(); + + if (args.GetArgumentCount() != 1) + return Status( + "\"platform connect\" takes a single argument: "); + + llvm::Optional uri; + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Status("URL is null."); + uri = URI::Parse(url); + if (!uri) + return Status("Invalid URL: %s", url); + if (uri->hostname != "localhost") + m_device_id = static_cast(uri->hostname); + + m_socket_namespace.reset(); + if (uri->scheme == "unix-connect") + m_socket_namespace = HdcClient::UnixSocketNamespaceFileSystem; + else if (uri->scheme == "unix-abstract-connect") + m_socket_namespace = HdcClient::UnixSocketNamespaceAbstract; + + std::string connect_url; + auto error = + MakeConnectURL(g_remote_platform_pid, uri->port ? (*uri->port) : 0, + uri->path, connect_url); + + if (error.Fail()) + return error; + + args.ReplaceArgumentAtIndex(0, connect_url); + + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Rewritten platform connect URL: %s", connect_url.c_str()); + + error = PlatformRemoteGDBServer::ConnectRemote(args); + if (error.Fail()) + DeleteForwardPort(g_remote_platform_pid); + + return error; +} + +Status PlatformOHOSRemoteGDBServer::DisconnectRemote() { + DeleteForwardPort(g_remote_platform_pid); + g_hdc_forward_port_offset = 0; + return PlatformRemoteGDBServer::DisconnectRemote(); +} + +void PlatformOHOSRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) { + Log *log = GetLog(LLDBLog::Platform); + + auto it = m_port_forwards.find(pid); + if (it == m_port_forwards.end()) + return; + + const auto port = it->second; + const auto error = DeleteForwardPortWithHdc(port, m_device_id); + if (error.Fail()) { + if (log) + log->Printf("Failed to delete port forwarding (pid=%" PRIu64 + ", fwd=(%d -> %d), device=%s): %s", + pid, port.first, port.second, m_device_id.c_str(), + error.AsCString()); + } + m_port_forwards.erase(it); +} + +Status PlatformOHOSRemoteGDBServer::MakeConnectURL( + const lldb::pid_t pid, const uint16_t remote_port, + llvm::StringRef remote_socket_name, std::string &connect_url) { + static const int kAttempsNum = 5; + + Status error; + // There is a race possibility that somebody will occupy a port while we're + // in between FindUnusedPort and ForwardPortWithHdc - adding the loop to + // mitigate such problem. + for (auto i = 0; i < kAttempsNum; ++i) { + uint16_t local_port = 0; + error = FindUnusedPort(local_port); + if (error.Fail()) + return error; + + error = ForwardPortWithHdc(local_port, remote_port, remote_socket_name, + m_socket_namespace, m_device_id); + if (error.Success()) { + m_port_forwards[pid] = {local_port, remote_port}; + std::ostringstream url_str; + url_str << "connect://localhost:" << local_port; + connect_url = url_str.str(); + break; + } + } + + return error; +} + +lldb::ProcessSP PlatformOHOSRemoteGDBServer::ConnectProcess( + llvm::StringRef connect_url, llvm::StringRef plugin_name, + lldb_private::Debugger &debugger, lldb_private::Target *target, + lldb_private::Status &error) { + // We don't have the pid of the remote gdbserver when it isn't started by us + // but we still want to store the list of port forwards we set up in our port + // forward map. Generate a fake pid for these cases what won't collide with + // any other valid pid on ohos. + static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL; + + llvm::Optional uri = URI::Parse(connect_url); + if (!uri) { + error.SetErrorStringWithFormat("Invalid URL: %s", + connect_url.str().c_str()); + return nullptr; + } + + std::string new_connect_url; + error = MakeConnectURL(s_remote_gdbserver_fake_pid--, + (*uri->port) ? (*uri->port) : 0, uri->path, + new_connect_url); + if (error.Fail()) + return nullptr; + + return PlatformRemoteGDBServer::ConnectProcess(new_connect_url, plugin_name, + debugger, target, error); +} diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h new file mode 100644 index 0000000000000000000000000000000000000000..f9818589275d0bc714eeb50b2967c631e1043a5c --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h @@ -0,0 +1,64 @@ +//===-- PlatformOHOSRemoteGDBServer.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformOHOSRemoteGDBServer_h_ +#define liblldb_PlatformOHOSRemoteGDBServer_h_ + +#include +#include + +#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" + +#include "llvm/ADT/Optional.h" + +#include "HdcClient.h" + +namespace lldb_private { +namespace platform_ohos { + +class PlatformOHOSRemoteGDBServer + : public platform_gdb_server::PlatformRemoteGDBServer { +public: + PlatformOHOSRemoteGDBServer(); + + ~PlatformOHOSRemoteGDBServer() override; + + Status ConnectRemote(Args &args) override; + + Status DisconnectRemote() override; + + lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, + llvm::StringRef plugin_name, + lldb_private::Debugger &debugger, + lldb_private::Target *target, + lldb_private::Status &error) override; + +protected: + std::string m_device_id; + std::map> m_port_forwards; + llvm::Optional m_socket_namespace; + + bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) override; + + bool KillSpawnedProcess(lldb::pid_t pid) override; + + void DeleteForwardPort(lldb::pid_t pid); + + Status MakeConnectURL(const lldb::pid_t pid, const uint16_t remote_port, + llvm::StringRef remote_socket_name, + std::string &connect_url); + +private: + PlatformOHOSRemoteGDBServer(const PlatformOHOSRemoteGDBServer &other) = delete; + PlatformOHOSRemoteGDBServer& operator=(const PlatformOHOSRemoteGDBServer &other) = delete; +}; + +} // namespace platform_ohos +} // namespace lldb_private + +#endif // liblldb_PlatformOHOSRemoteGDBServer_h_ diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt index a51d0f7afd1759121b89a1bb0dfe3a254c15b6b0..d30d90ca4dfd72f977b2f07f767aebab712d79a7 100644 --- a/lldb/source/Plugins/Process/CMakeLists.txt +++ b/lldb/source/Plugins/Process/CMakeLists.txt @@ -1,4 +1,4 @@ -if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") +if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") add_subdirectory(Linux) add_subdirectory(POSIX) elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h index 14f669a3ce98f04ba0d77040dec96c9066c595f1..9fee81e1b65955bec3f83bb7d7d3ac8834c4e60c 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h @@ -16,6 +16,11 @@ #include "Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" +#if __OHOS__ +// Do not include to avoid conflicting definitions for +// aarch64-linux-ohos target +#define __ASM_SIGCONTEXT_H 1 +#endif #include namespace lldb_private { diff --git a/lldb/source/Plugins/Process/Linux/Procfs.h b/lldb/source/Plugins/Process/Linux/Procfs.h index 3a068432074b7d330488fa0a756ba1fc8a657334..79bc35d8105daa4eab4996e495126f6cd578f3ed 100644 --- a/lldb/source/Plugins/Process/Linux/Procfs.h +++ b/lldb/source/Plugins/Process/Linux/Procfs.h @@ -17,7 +17,7 @@ #include -#ifdef __ANDROID__ +#if defined(__ANDROID__) #if defined(__arm64__) || defined(__aarch64__) typedef unsigned long elf_greg_t; typedef elf_greg_t diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 2a58f2028386892fd198674c5081ca62307aeca1..39fb9a8a8fde31169f67df833d270611ffb49465 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -45,12 +45,15 @@ #include "lldb/Host/android/HostInfoAndroid.h" #endif +#if defined(__OHOS_FAMILY__) +#include "lldb/Host/ohos/HostInfoOHOS.h" +#endif using namespace lldb; using namespace lldb_private::process_gdb_remote; using namespace lldb_private; -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(__OHOS_FAMILY__) const static uint32_t g_default_packet_timeout_sec = 20; // seconds #else const static uint32_t g_default_packet_timeout_sec = 0; // not specified @@ -181,7 +184,6 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( StreamString response; // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 - ArchSpec host_arch(HostInfo::GetArchitecture()); const llvm::Triple &host_triple = host_arch.GetTriple(); response.PutCString("triple:"); @@ -1309,6 +1311,8 @@ FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( const std::string &module_path, const ArchSpec &arch) { #ifdef __ANDROID__ return HostInfoAndroid::ResolveLibraryPath(module_path, arch); +#elif defined(__OHOS_FAMILY__) + return HostInfoOHOS::ResolveLibraryPath(module_path, arch); #else FileSpec file_spec(module_path); FileSystem::Instance().Resolve(file_spec); @@ -1320,7 +1324,6 @@ ModuleSpec GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple) { ArchSpec arch(triple); - FileSpec req_module_path_spec(module_path); FileSystem::Instance().Resolve(req_module_path_spec); @@ -1336,7 +1339,6 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, ModuleSpec matched_module_spec; if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) return ModuleSpec(); - return matched_module_spec; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp index 37e28a09f3c45a1ab27a5892ed319c76bbec68e2..c357033aa91d7aa42e2d3341845a069f10f58f41 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp @@ -92,8 +92,8 @@ const DWARFDataExtractor &DWARFContext::getOrLoadLocListsData() { } const DWARFDataExtractor &DWARFContext::getOrLoadMacroData() { - return LoadOrGetSection(eSectionTypeDWARFDebugMacro, llvm::None, - m_data_debug_macro); + return LoadOrGetSection(eSectionTypeDWARFDebugMacro, + eSectionTypeDWARFDebugMacro, m_data_debug_macro); } const DWARFDataExtractor &DWARFContext::getOrLoadRangesData() { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 19c6448c4e74a063dadc2b4d36edec7c6ca1b785..e84a76451727a6a99e8f82db9b4b01a844f39497 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -16,6 +16,13 @@ using namespace lldb_private; using namespace lldb_private::dwarf; +uint64_t DWARFStrOffsetsInfo::GetOffset(uint64_t index) const { + assert(IsValid()); + // LLDB doesn't support DWARF64, so we always have item size of 4. + uint64_t offset = cu_offset + 4 * index; + return data->GetU32(&offset); +} + DWARFDebugMacroHeader DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) { @@ -59,7 +66,8 @@ void DWARFDebugMacroHeader::SkipOperandTable( void DWARFDebugMacroEntry::ReadMacroEntries( const DWARFDataExtractor &debug_macro_data, - const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit, + const DWARFDataExtractor &debug_str_data, + const DWARFStrOffsetsInfo &str_offsets_info, const bool offset_is_64_bit, lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf, DebugMacrosSP &debug_macros_sp) { llvm::dwarf::MacroEntryType type = @@ -97,6 +105,22 @@ void DWARFDebugMacroEntry::ReadMacroEntries( debug_macros_sp->AddMacroEntry( DebugMacroEntry::CreateUndefEntry(line, macro_str)); break; + case DW_MACRO_define_strx: + case DW_MACRO_undef_strx: + line = debug_macro_data.GetULEB128(offset); + str_offset = debug_macro_data.GetULEB128(offset); + if (!str_offsets_info.IsValid()) + // Can't do much in this case, skip all such entries + continue; + str_offset = str_offsets_info.GetOffset(str_offset); + macro_str = debug_str_data.GetCStr(&str_offset); + if (type == DW_MACRO_define_strx) + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateDefineEntry(line, macro_str)); + else + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateUndefEntry(line, macro_str)); + break; case DW_MACRO_start_file: line = debug_macro_data.GetULEB128(offset); debug_line_file_idx = debug_macro_data.GetULEB128(offset); @@ -113,7 +137,7 @@ void DWARFDebugMacroEntry::ReadMacroEntries( else new_offset = debug_macro_data.GetU32(offset); debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry( - sym_file_dwarf->ParseDebugMacros(&new_offset))); + sym_file_dwarf->ParseDebugMacros(&new_offset, str_offsets_info))); break; default: // TODO: Add support for other standard operations. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h index cbf762458331bcd1f127d4372e87469efcdbc7f9..b598d680d5fb74f627f62bd697d34e6e8a73577c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h @@ -24,6 +24,14 @@ class DWARFDataExtractor; class SymbolFileDWARF; +struct DWARFStrOffsetsInfo { + lldb::offset_t cu_offset; + const lldb_private::DWARFDataExtractor *data; + + bool IsValid() const { return cu_offset && cu_offset != DW_INVALID_OFFSET; } + uint64_t GetOffset(uint64_t index) const; +}; + class DWARFDebugMacroHeader { public: enum HeaderFlagMask { @@ -53,6 +61,7 @@ public: static void ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data, const lldb_private::DWARFDataExtractor &debug_str_data, + const DWARFStrOffsetsInfo &str_offsets_info, const bool offset_is_64_bit, lldb::offset_t *sect_offset, SymbolFileDWARF *sym_file_dwarf, lldb_private::DebugMacrosSP &debug_macros_sp); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 8ee709db9cdb59f523f34ecadd689775c0c4673e..1049012cef0d887e68832471ac6e27d0a921220b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1174,7 +1174,8 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { } lldb_private::DebugMacrosSP -SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { +SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset, + const DWARFStrOffsetsInfo &str_offsets_info) { auto iter = m_debug_macros_map.find(*offset); if (iter != m_debug_macros_map.end()) return iter->second; @@ -1190,8 +1191,8 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset); DWARFDebugMacroEntry::ReadMacroEntries( - debug_macro_data, m_context.getOrLoadStrData(), header.OffsetIs64Bit(), - offset, this, debug_macros_sp); + debug_macro_data, m_context.getOrLoadStrData(), str_offsets_info, + header.OffsetIs64Bit(), offset, this, debug_macros_sp); return debug_macros_sp; } @@ -1199,7 +1200,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) { std::lock_guard guard(GetModuleMutex()); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + DWARFUnit *dwarf_cu = &GetDWARFCompileUnit(&comp_unit)->GetNonSkeletonUnit(); if (dwarf_cu == nullptr) return false; @@ -1215,8 +1216,16 @@ bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) { if (sect_offset == DW_INVALID_OFFSET) return false; - comp_unit.SetDebugMacros(ParseDebugMacros(§_offset)); + DWARFStrOffsetsInfo str_offsets_info = {}; + str_offsets_info.cu_offset = dwarf_cu->GetStrOffsetsBase(); + SymbolFileDWARF &symfile = dwarf_cu->GetSymbolFileDWARF(); + + if (str_offsets_info.IsValid()) + str_offsets_info.data = + &symfile.GetDWARFContext().getOrLoadStrOffsetsData(); + comp_unit.SetDebugMacros( + symfile.ParseDebugMacros(§_offset, str_offsets_info)); return true; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index cfd18f02053b40af7dfe29e221be6e2f43580b48..ccf955ee4b90f31b15274de7b1b1f4db0f1ec500 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -55,6 +55,8 @@ class SymbolFileDWARFDebugMap; class SymbolFileDWARFDwo; class SymbolFileDWARFDwp; +struct DWARFStrOffsetsInfo; + #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) class SymbolFileDWARF : public lldb_private::SymbolFileCommon, @@ -244,7 +246,9 @@ public: bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu); - lldb_private::DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset); + lldb_private::DebugMacrosSP + ParseDebugMacros(lldb::offset_t *offset, + const DWARFStrOffsetsInfo &str_offsets_info); static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die); diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp index 4ebb175fcd85ac4c877a2c69b00ac430c50f2aa4..45c166e7e5cf8c49d527e87ff658908d1f40ac80 100644 --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -131,7 +131,7 @@ void PathMappingList::Dump(Stream *s, int pair_index) { } } -void PathMappingList::Clear(bool notify) { +void PathMappingList::Clear (bool notify) { if (!m_pairs.empty()) ++m_mod_id; m_pairs.clear(); @@ -197,7 +197,7 @@ PathMappingList::RemapPath(llvm::StringRef mapping_path, return {}; } -bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const { +bool PathMappingList::ReverseRemapPath (const FileSpec &file, FileSpec &fixed) const { std::string path = file.GetPath(); llvm::StringRef path_ref(path); for (const auto &it : m_pairs) { diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index 0d5144d7a46b5f33f17f89709fc7e0bcefa7291a..d08805460ee1f851eecd6bfb580f11513655f5e3 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -206,6 +206,13 @@ bool ThreadPlanStepRange::InSymbol() { return false; } +// TODO: Limit this function scope to OHOS targets +bool ThreadPlanStepRange::MaybeAArch32Or64FunctionTail() { + const llvm::Triple &triple = GetTarget().GetArchitecture().GetTriple(); + const bool isArm32or64 = triple.isAArch64() || triple.isARM(); + return isArm32or64 && InSymbol() && InRange(); +} + // FIXME: This should also handle inlining if we aren't going to do inlining in // the // main stack. diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp index a99aed82bc886852782ff7f859aab684504bf5bc..79c5cd3f18fc0a4a93a072219e26a1faffb87e49 100644 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -936,7 +936,7 @@ bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const { return IsEqualTo(rhs, false); } -static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, +static bool IsCompatibleEnvironment (llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs) { if (lhs == rhs) return true; @@ -958,6 +958,8 @@ static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, // that they are using the Android ABI. if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) || (rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) || + (lhs == llvm::Triple::OpenHOS && rhs == llvm::Triple::EABI) || + (rhs == llvm::Triple::OpenHOS && lhs == llvm::Triple::EABI) || (lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) || (rhs == llvm::Triple::GNUEABI && lhs == llvm::Triple::EABI) || (lhs == llvm::Triple::GNUEABIHF && rhs == llvm::Triple::EABIHF) || diff --git a/lldb/source/Utility/TildeExpressionResolver.cpp b/lldb/source/Utility/TildeExpressionResolver.cpp index 6311ae062f1f5399102ce180d4c649c68ee0193c..d4c464ddfe01446cf44aa1dea82d99245b982e4f 100644 --- a/lldb/source/Utility/TildeExpressionResolver.cpp +++ b/lldb/source/Utility/TildeExpressionResolver.cpp @@ -47,7 +47,7 @@ bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr, assert(Expr.empty() || Expr[0] == '~'); Output.clear(); -#if defined(_WIN32) || defined(__ANDROID__) +#if defined(_WIN32) || defined(__ANDROID__) || defined(__OHOS_FAMILY__) return false; #else if (Expr.empty()) diff --git a/lldb/test/API/api/command-return-object/Makefile b/lldb/test/API/api/command-return-object/Makefile index 99998b20bcb0502181cbf488a2034823e5f66d22..680e1abfbef58d92108cf5a6b041381abe69af7e 100644 --- a/lldb/test/API/api/command-return-object/Makefile +++ b/lldb/test/API/api/command-return-object/Makefile @@ -1,3 +1,4 @@ CXX_SOURCES := main.cpp +USE_LIBCPP := 1 include Makefile.rules diff --git a/lldb/test/API/functionalities/plugins/command_plugin/Makefile b/lldb/test/API/functionalities/plugins/command_plugin/Makefile index 3119c3707841d4a0565af78008b4e120e2f834aa..b792c8d50d989c9cd8a90a613daed540edbb63c2 100644 --- a/lldb/test/API/functionalities/plugins/command_plugin/Makefile +++ b/lldb/test/API/functionalities/plugins/command_plugin/Makefile @@ -2,5 +2,6 @@ DYLIB_CXX_SOURCES := plugin.cpp DYLIB_NAME := plugin DYLIB_ONLY := YES MAKE_DSYM := NO +USE_LIBCPP := 1 include Makefile.rules diff --git a/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py b/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py index 2ab6820c09203d5b7e3c5fe697810cd834d8a954..53805f5d535fdd34887a59fda9a23335e76f603e 100644 --- a/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py +++ b/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py @@ -72,6 +72,7 @@ class TestGdbRemoteMemoryAllocation(gdbremote_testcase.GdbRemoteTestCaseBase): True) self.expect_gdbremote_sequence() + @skipOnOpenHarmonyCI # investigate CI test failures def test_bad_packet(self): """Make sure we get a proper error for malformed packets.""" diff --git a/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py b/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py index 7acb0188dcff72112de93f0354e8e3181925f726..ca84825af0e68d1e0a701f5ed90726f4316a1e3a 100644 --- a/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py +++ b/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py @@ -59,6 +59,7 @@ class TestGdbRemote_QPassSignals(gdbremote_testcase.GdbRemoteTestCaseBase): self.expect_exit_code(len(signals_to_ignore)) @skipUnlessPlatform(["linux", "android"]) + @skipOnOpenHarmonyCI #investigate CI timeouts def test_change_signals_at_runtime(self): self.build() self.set_inferior_startup_launch() diff --git a/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py b/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py index af563af158ce2a5c1a01580913aad5fc0b7547aa..52d81871c46dfa609e8a4b1a4f22e2f6f558da57 100644 --- a/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py +++ b/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py @@ -25,6 +25,7 @@ class TestGdbRemoteThreadName(gdbremote_testcase.GdbRemoteTestCaseBase): self.assertEqual(expected_name, kv_dict.get("name")) @skipIfWindows # the test is not updated for Windows. + @skipOnOpenHarmonyCI # investigate CI timeouts def test(self): """ Make sure lldb-server can retrieve inferior thread name""" self.build() diff --git a/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py b/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py index cda935ff70c3f29db325f58f0415628255e7f17b..9c956ab5c11c6a9833e9e61e1ac44a428db963ea 100644 --- a/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py +++ b/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py @@ -42,6 +42,7 @@ class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase): self.continue_to_exit() @skipIfWindows + @skipIfLinux @skipIfNetBSD # Hangs on NetBSD as well @skipIfRemote def test_by_pid(self): diff --git a/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py b/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py index 4731d13821a5c70f7f7aaca74a973babcab816e5..61d1dba1f46c4339ed6690f59675e6d1194ce0e0 100644 --- a/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py +++ b/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py @@ -46,6 +46,7 @@ class TestVSCode_runInTerminal(lldbvscode_testcase.VSCodeTestCaseBase): return False @skipIfWindows + @skipIfLinux @skipIfRemote @skipIf(archs=no_match(['x86_64'])) def test_runInTerminal(self): diff --git a/lldb/tools/lldb-server/CMakeLists.txt b/lldb/tools/lldb-server/CMakeLists.txt index 3fb22b0a61098d5dfdf198b9ebb188d233bd9247..b7026ef121654f9d9c5791555e1df8b042777104 100644 --- a/lldb/tools/lldb-server/CMakeLists.txt +++ b/lldb/tools/lldb-server/CMakeLists.txt @@ -5,7 +5,7 @@ set_target_properties(LLGSOptionsTableGen PROPERTIES FOLDER "lldb misc") set(LLDB_PLUGINS) -if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android") +if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") list(APPEND LLDB_PLUGINS lldbPluginProcessLinux) endif() diff --git a/llvm-build/Makefile b/llvm-build/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2e3562419e15fb56ea8718c797611a4bfde944b0 --- /dev/null +++ b/llvm-build/Makefile @@ -0,0 +1,230 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +ARCH = arm +ifneq ($(GCC),) +TARGET = +CROSS_COMPILE = $(GCC:%gcc=%) +CC = $(GCC) $(ARCH_CFLAGS) +MULTILIB = $(patsubst %.,%,$(shell $(CC) -print-multi-directory)) +else +TARGET = $(ARCH)-liteos-ohos +CLANG ?= clang +CROSS_COMPILE = $(CLANG:%clang=%llvm-) +CC = $(CLANG) --target=$(TARGET) $(ARCH_CFLAGS) +BUILD=x86_64-linux-gnu +MULTILIB = $(patsubst $(dir $(shell $(filter-out $(ARCH_CFLAGS),$(CC)) -print-libgcc-file-name))%,/%,$(dir $(shell $(CC) -print-libgcc-file-name))) +endif +MUSLBUILDDIR = build_$(or $(TARGET),$(ARCH))$(subst /,_,$(MULTILIB:%/=%)) +HIDE = @ +BUILD_DEBUG = false +SED_ARGS = -e '/install-libs:/s/if/and/g' + +TOPDIR = $(shell pwd)/../../../.. +MUSLDIR = $(TOPDIR)/third_party/musl +LINUXKERNELDIR = $(TOPDIR)/third_party/Linux_Kernel +OPTRTDIR = $(TOPDIR)/third_party/optimized-routines +NUTTXDIR = $(TOPDIR)/third_party/NuttX +SYSROOTDIR = $(TOPDIR)/prebuilts/lite/sysroot +LITEOSADIR = $(TOPDIR)/kernel/liteos_a +LINUXDIR = $(TOPDIR)/kernel/linux/linux-5.10 + +TARGETS = $(if $(wildcard $(LITEOSADIR)),liteos_a_user,) +TARGETS += $(if $(wildcard $(LINUXDIR)),linux_user,) + +define LINUX_TYPES_H +#ifndef _LINUX_TYPES_H +#define _LINUX_TYPES_H +#include +typedef uint32_t __u32, __le32; +#endif +endef +export LINUX_TYPES_H + +ifeq ($(ARCH),arm) +ARCH_CFLAGS = -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 +else +ifeq ($(ARCH),aarch64) +ARCH_CFLAGS = +else +ifeq ($(ARCH),riscv64) +ARCH_CFLAGS = +else +ifeq ($(ARCH),mips) +ARCH_CFLAGS = +else +ifeq ($(ARCH),x86_64) +ARCH_CFLAGS = +else +$(warning *** warning: ARCH $(ARCH) has not been tested yet, use with cautions!) +ARCH_CFLAGS = +endif +endif +endif +endif +endif + +ifeq ($(ARCH),aarch64) +CFLAGS = -march=armv8 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),riscv64) +CFLAGS = -march=rv64gc -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),mips) +CFLAGS = -march=mips32r2 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),x86_64) +CFLAGS = -march=x86-64 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +CFLAGS = -march=armv7-a -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +endif +endif +endif +endif + +CFLAGS += -Wno-int-conversion + +.PHONY: $(TARGETS:%=musl_copy_for_%) +.PHONY: $(TARGETS:%=musl_patch_for_%) +.PHONY: $(TARGETS:%=musl_install_for_%) +.PHONY: $(TARGETS:%=musl_header_install_for_%) +.PHONY: $(TARGETS:%=linux_header_install_for_%) +.PHONY: $(TARGETS:%=nuttx_header_install_for_%) +.PHONY: $(TARGETS:%=optimized_routines_install_for_%) +.PHONY: all clean distclean + +all: $(TARGETS:%=musl_install_for_%) + +$(TARGETS:%=musl_copy_for_%): + $(HIDE) mkdir -p $@ + $(HIDE) cp -rfu $(MUSLDIR)/[^p]* $@ + +optimized_routines_install_for_liteos_a_user: musl_copy_for_liteos_a_user +ifneq ($(ARCH),) + $(HIDE) cp -rfp $(OPTRTDIR)/string/$(ARCH)/* $> $ $ $/dev/null && \ + make -sj install-headers + +musl_install_for_liteos_a_user: musl_patch_for_liteos_a_user + $(HIDE) cd musl_copy_for_liteos_a_user && mkdir -p $(MUSLBUILDDIR) && cd $(MUSLBUILDDIR) && \ + ../configure --prefix=$(SYSROOTDIR)/$(TARGET)/usr --target=$(TARGET) \ + --includedir=$(SYSROOTDIR)/$(TARGET)/usr/include \ + --libdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --syslibdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --build=$(BUILD) \ + $(if $(LDFLAGS),LDFLAGS="$(LDFLAGS)",) \ + CC="$(CC)" CROSS_COMPILE="$(CROSS_COMPILE)" CFLAGS="$(CFLAGS)" >/dev/null && \ + make -sj install + +musl_patch_for_linux_user: musl_copy_for_linux_user + $(HIDE) cp -rfp $(MUSLDIR)/porting/linux/user/* $/dev/null && \ + make -sj install-headers + +musl_install_for_linux_user: musl_patch_for_linux_user + $(HIDE) cd musl_copy_for_linux_user && mkdir -p $(MUSLBUILDDIR) && cd $(MUSLBUILDDIR) && \ + ../configure --prefix=$(SYSROOTDIR)/$(TARGET)/usr --target=$(TARGET) \ + --includedir=$(SYSROOTDIR)/$(TARGET)/usr/include \ + --libdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --syslibdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --build=$(BUILD) \ + CC="$(CC)" CROSS_COMPILE="$(CROSS_COMPILE)" CFLAGS="$(CFLAGS)" >/dev/null && \ + make -sj install + +clean: + $(HIDE) rm -rf musl_copy_for_* linux_header_install_for_* + +distclean: clean + $(HIDE) rm -rf $(SYSROOTDIR)/lib $(SYSROOTDIR)/usr diff --git a/llvm-build/OHOS.cmake b/llvm-build/OHOS.cmake new file mode 100644 index 0000000000000000000000000000000000000000..df2c08ce41ba84d48fd24b5c2d2b7a7ff7a566ac --- /dev/null +++ b/llvm-build/OHOS.cmake @@ -0,0 +1,22 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(Platform/Linux) + +# OHOS has soname, but binary names must end in ".so" so we cannot append +# a version number. Also we cannot portably represent symlinks on the host. +set(CMAKE_PLATFORM_NO_VERSIONED_SONAME 1) + +# OHOS reportedly ignores RPATH, and we cannot predict the install +# location anyway. +set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") diff --git a/llvm-build/README.md b/llvm-build/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e12de6c793fa98dd4ffffc1737c0acb374bc0913 --- /dev/null +++ b/llvm-build/README.md @@ -0,0 +1,126 @@ +## Overview + +This readme briefly describes the functionality of our LLVM toolchain and how to build it + +1. [Build WIKI](#build_wiki) +2. [Function Introduction](#function_introduction) + + +## Build WIKI +
+ +### System Requirements for Toolchain BUild + +Ubuntu >= 16.04 +MacOS X >= 10.15.4 + +
+ +### Get Code +``` +repo init -u https://gitee.com/OpenHarmony/manifest.git -b add_llvm_toolchain-dev (not ready yet) +repo sync -c +repo forall -c 'git lfs pull' +cp -r toolchain/llvm-project/llvm-build toolchain +``` +
+ +### Toolchain build process + +Here is an example of starting build process on Linux or MacOS: +``` +# update prebuilts, no need to run each time +./toolchain/llvm-project/llvm-build/env_prepare.sh +# build +python3 ./toolchain/llvm-build/build.py +``` + +1. env_prepare (one time only) +![输入图片说明](../data/one_time_setup.png) + +2. build +![输入图片说明](../data/llvm_build.png) + +
+ +### Options + +build.py options: + +``` +--skip-build # skip compile and goto package step +--skip-package # do compile without package step +--enable-assertions # enable assertion when compiling +--build-name # specify release package name +--debug # build debug version llvm toolchain +--no-build-arm # skip triplet arm +--no-build-aarch64 # skip triplet arm64 +--no-build-x86_64 # skip triplet x86_64 +--no-lto # disable LTO optimization when build toolchain +--build-instrumented # enable instrument pgo when build toolchain +--xunit-xml-output # specify LLVM unit test XML report path +--no-build # optional, skip some targets + windows + libs + lldb-mi + lldb-server + linux + check-api +``` +
+ +### Output Layout + +When build successfully completed. following artifacts will be available in `out` directory + +`sysroot` -> sysroots for OHOS targets +`install` -> toolchain build +`*.tar.bz2` -> archived versions of toolchain and sysroots +
+ +### OHOS Archive + +1. llvm +``` +contains: +1. toolchain which provides clang compiler, lldb(-mi), clang-tidy etc. tools +2. libc++/clang_rt/asan/fuzzer libs for target device + +OHOS sync from: https://mirrors.huaweicloud.com/openharmony/compiler/clang/ +Which is the same as: out/clang-dev-${platform}-${arch}.tar.bz2 +OHOS archive to: prebuilts/clang/ohos//${platform}/llvm + +License: Apache License v2.0 with LLVM Exceptions +``` + +2. libcxx-ndk +``` +contains: provide libc++ for ndk in target device + +OHOS fetch prebuilts from: https://mirrors.huaweicloud.com/openharmony/compiler/clang/ and archive it to prebuilts/clang/ohos//${platform}/libcxx-ndk. This tar is + +License: Apache License v2.0 with LLVM Exceptions +``` + + +## Function Introduction +
+ +### Functionality + +The LLVM toolchain is built based on LLVM 12.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 12.0.1, please refer to [LLVM 12.0.1](https://lists.llvm.org/pipermail/llvm-announce/2021-July/000093.html). +
+ +### Specifically Included Triplets + +Despite all the components provided by LLVM community, we included several triplets for different types of ohos devices to our LLVM toochain, listed as below. For specification, liteos is a newly included OS name which indicate the simplified linux kernel. + +| Triplet Name | Architecture | System Kernel | System | +| ---------------------- | ------------ | ------------- | --------------- | +| arm-liteos-ohos | ARM 32bits | LiteOS | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Standard system | +| aarch64-linux-ohos | ARM 64bits | Linux | Standard system | + +For detailed definition of Small System and Standard System, please refer to [System Types](https://gitee.com/openharmony/docs/blob/master/en/device-dev/Readme-EN.md). + diff --git a/llvm-build/build.py b/llvm-build/build.py new file mode 100755 index 0000000000000000000000000000000000000000..e5a74de8ed96eb81c709cb62f17c36b8fa050082 --- /dev/null +++ b/llvm-build/build.py @@ -0,0 +1,1796 @@ +#!/usr/bin/env python +# Copyright (C) 2021 Huawei Device Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# 2021.3.15 build for OHOS LLVM. +# Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + +import os +import platform +import re +import datetime +import logging +import glob +import subprocess +import shutil +import argparse +import mingw +import stat + + +class BuildConfig(): + # Defines public methods and functions and obtains script parameters. + + def __init__(self): + args = self.parse_args() + self.do_build = not args.skip_build + self.do_package = not args.skip_package + self.build_name = args.build_name + self.debug = args.debug + self.no_lto = args.no_lto + self.build_instrumented = args.build_instrumented + self.xunit_xml_output = args.xunit_xml_output + self.enable_assertions = args.enable_assertions + self.need_libs = self.do_build and 'libs' not in args.no_build + self.need_lldb_mi = self.do_build and 'lldb-mi' not in args.no_build + self.need_lldb_server = self.do_build and 'lldb-server' not in args.no_build + + self.no_build_arm = args.skip_build or args.no_build_arm + self.no_build_aarch64 = args.skip_build or args.no_build_aarch64 + self.no_build_riscv64 = args.skip_build or args.no_build_riscv64 + self.no_build_mipsel = args.skip_build or args.no_build_mipsel + self.no_build_x86_64 = args.skip_build or args.no_build_x86_64 + + self.CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) + self.REPOROOT_DIR = os.path.abspath(os.path.join(self.CURRENT_DIR, '../../')) + self.LLVM_PROJECT_DIR = os.path.abspath(os.path.join(self.REPOROOT_DIR, 'toolchain', 'llvm-project')) + self.OUT_PATH = os.path.join(self.REPOROOT_DIR, 'out') + self.TARGETS = 'AArch64;ARM;BPF;Mips;RISCV;X86' + self.ORIG_ENV = dict(os.environ) + self.VERSION = None # autodetected + + self.OPENHOS_SFX = '-linux-ohos' + self.LITEOS_SFX = '-liteos-ohos' + self.LLDB_PY_VERSION = '3.10' + self.CLANG_VERSION = '10.0.1' + self.MINGW_TRIPLE = 'x86_64-windows-gnu' + logging.basicConfig(level=logging.INFO) + + @staticmethod + def parse_add_argument(parser): + + parser.add_argument( + '--enable-assertions', + action='store_true', + default=False, + help='Apply assertions, some parameters are affected.') + + parser.add_argument( + '--build-name', + default='dev', + help='Release name for the package.') + + parser.add_argument( + '--debug', + action='store_true', + default=False, + help='Building Clang and LLVM Tools for Debugging (only affects stage2)') + + parser.add_argument( + '--no-build-arm', + action='store_true', + default=False, + help='Omit build os target: arm.') + + parser.add_argument( + '--no-build-aarch64', + action='store_true', + default=False, + help='Omit build os target: aarch64.') + + parser.add_argument( + '--no-build-riscv64', + action='store_true', + default=False, + help='Omit build os target: 64-bit RISC-V.') + + parser.add_argument( + '--no-build-mipsel', + action='store_true', + default=False, + help='Omit build os target: mipsel.') + + parser.add_argument( + '--no-build-x86_64', + action='store_true', + default=False, + help='Omit build os target: x86_64.') + + parser.add_argument( + '--no-lto', + action='store_true', + default=False, + help='Accelerate builds by disabling LTO (only affects llvm product)') + + parser.add_argument( + '--build-instrumented', + action='store_true', + default=False, + help='Using the PGO instrumentation to build LLVM tool') + + parser.add_argument( + '--xunit-xml-output', + default=None, + help='Output path for LLVM unit tests XML report') + + def parse_args(self): + + parser = argparse.ArgumentParser(description='Process some integers.') + + # Options to skip build or packaging, can't skip two + build_package_group = parser.add_mutually_exclusive_group() + build_package_group.add_argument( + '--skip-build', + '-sb', + action='store_true', + default=False, + help='Omit the build, perform the packaging step directly.') + + build_package_group.add_argument( + '--skip-package', + '-sp', + action='store_true', + default=False, + help='Omit the packaging, perform the packaging step directly.') + + self.parse_add_argument(parser) + + known_platforms = ('windows', 'libs', 'lldb-mi', 'lldb-server', 'linux', 'check-api') + known_platforms_str = ', '.join(known_platforms) + + class SeparatedListByCommaAction(argparse.Action): + def __call__(self, parser, namespace, vals, option_string): + for val in vals.split(','): + if val in known_platforms: + continue + else: + error = '\'{}\' invalid. Choose from {}'.format(val, known_platforms) + raise argparse.ArgumentError(self, error) + setattr(namespace, self.dest, vals.split(',')) + + parser.add_argument( + '--no-build', + action=SeparatedListByCommaAction, + default=list(), + help='Don\'t build toolchain for specified platforms. Choices: ' + known_platforms_str) + + return parser.parse_args() + + +class ClangVersion(object): + """Parse and save clang version from version file.""" + + def __init__(self, version_file): + self._parse_version_file(version_file) + + @staticmethod + def _parse(text, key): + return re.findall(r'%s\s+(\d+)' % key, text)[0] + + def _parse_version_file(self, version_file): + with open(version_file, 'r') as fp: + text = fp.read() + self.major = self._parse(text, 'CLANG_VERSION_MAJOR') + self.minor = self._parse(text, 'CLANG_VERSION_MINOR') + self.patch = self._parse(text, 'CLANG_VERSION_PATCHLEVEL') + + def long_version(self): + return '.'.join([self.major, self.minor, self.patch]) + + def short_version(self): + return '.'.join([self.major, self.minor]) + + def major_version(self): + return self.major + + +class BuildUtils(object): + + def __init__(self, build_config): + self.build_config = build_config + + self.CMAKE_BIN_DIR = os.path.abspath( + os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts/cmake', self.platform_prefix(), 'bin')) + + def open_ohos_triple(self, arch): + return arch + self.build_config.OPENHOS_SFX + + def liteos_triple(self, arch): + return arch + self.build_config.LITEOS_SFX + + def set_clang_version(self, install_dir): + self.build_config.VERSION = self.get_clang_version(install_dir).long_version() + + def invoke_ninja(self, + out_path, + env, + target=None, + install=True, + build_threads=False): + + ninja_bin_path = os.path.join(self.CMAKE_BIN_DIR, 'ninja') + + ninja_list = ['-l{}'.format(build_threads)] if build_threads else [] + + ninja_target = [target] if target else [] + + self.check_call([ninja_bin_path] + ninja_list + ninja_target, cwd=out_path, env=env) + if install: + self.check_call([ninja_bin_path, 'install'], cwd=out_path, env=env) + + def invoke_cmake(self, + cmake_path, + out_path, + invoke_defines, + env): + + cmake_bin_path = os.path.join(self.CMAKE_BIN_DIR, 'cmake') + flags = ['-G', 'Ninja'] + flags += ['-DCMAKE_PREFIX_PATH=%s' % self.CMAKE_BIN_DIR] + + for key in invoke_defines: + newdef = ''.join(['-D', key, '=', invoke_defines[key]]) + flags += [newdef] + + flags += [cmake_path] + self.check_create_dir(out_path) + + self.check_call([cmake_bin_path] + flags, cwd=out_path, env=env) + + @staticmethod + def logger(): + """Returns the module level logger.""" + return logging.getLogger(__name__) + + @staticmethod + def get_clang_version(llvm_install): + version_file = os.path.join(llvm_install, 'include', 'clang', 'Basic', + 'Version.inc') + return ClangVersion(version_file) + + def check_create_dir(self, path): + if not os.path.exists(path): + """Proxy for os.makedirs with logging and dry-run support.""" + self.logger().info('makedirs %s', path) + os.makedirs(path) + + def check_rm_tree(self, tree_dir): + """Removes directory tree.""" + def chmod_and_retry(func, path, _): + if not os.access(path, os.W_OK): + os.chmod(path, stat.S_IWUSR) + return func(path) + raise IOError("rmtree on %s failed" % path) + + if os.path.exists(tree_dir): + self.logger().info('shutil rmtree %s', tree_dir) + shutil.rmtree(tree_dir, onerror=chmod_and_retry) + + def check_copy_tree(self, src_dir, dst_dir): + self.check_rm_tree(dst_dir) + """Proxy for shutil.copytree with logging and dry-run support.""" + self.logger().info('copytree %s %s', src_dir, dst_dir) + shutil.copytree(src_dir, dst_dir, symlinks=True) + + def check_copy_file(self, src_file, dst_file): + if os.path.exists(src_file): + """Proxy for shutil.copy2 with logging and dry-run support.""" + self.logger().info('copy %s %s', src_file, dst_file) + shutil.copy2(src_file, dst_file) + + def check_call(self, cmd, *args, **kwargs): + """subprocess.check_call with logging.""" + self.logger().info('check_call:%s %s', + datetime.datetime.now().strftime("%H:%M:%S"), subprocess.list2cmdline(cmd)) + + subprocess.check_call(cmd, *args, **kwargs) + + def merge_out_path(self, *args): + return os.path.abspath(os.path.join(self.build_config.OUT_PATH, *args)) + + @staticmethod + def use_platform(): + sysstr = platform.system().lower() + arch = platform.machine() + return "%s-%s" % (sysstr, arch) + + def platform_prefix(self): + prefix = self.use_platform() + if (prefix.endswith('x86_64')): + return prefix[:-3] + return prefix + + def host_is_linux(self): + return self.use_platform().startswith('linux-') + + def host_is_darwin(self): + return self.use_platform().startswith('darwin-') + + def rm_cmake_cache(self, cache_dir): + for dirpath, dirs, files in os.walk(cache_dir): + if 'CMakeCache.txt' in files: + self.logger().info('rm CMakeCache.txt on %s', cache_dir) + os.remove(os.path.join(dirpath, 'CMakeCache.txt')) + if 'CMakeFiles' in dirs: + self.logger().info('rm CMakeFiles on %s', cache_dir) + self.check_rm_tree(os.path.join(dirpath, 'CMakeFiles')) + + @staticmethod + def find_program(name): + # FIXME: Do we need Windows support here? + return os.popen('which ' + name).read().strip() + + # Base cmake options such as build type that are common across all invocations + def base_cmake_defines(self): + mac_min_version = '10.9' + defines = {} + + defines['CMAKE_BUILD_TYPE'] = 'Release' + defines['LLVM_ENABLE_ASSERTIONS'] = 'OFF' + defines['LLVM_ENABLE_TERMINFO'] = 'OFF' + defines['LLVM_ENABLE_THREADS'] = 'ON' + defines['LLVM_USE_NEWPM'] = 'ON' + defines['LLVM_ENABLE_BINDINGS'] = 'OFF' + defines['CLANG_REPOSITORY_STRING'] = 'llvm-project' + + if self.host_is_darwin(): + defines['CMAKE_OSX_DEPLOYMENT_TARGET'] = mac_min_version + defines['LLDB_INCLUDE_TESTS'] = 'OFF' + defines['LIBCXX_INCLUDE_TESTS'] = 'OFF' + + defines['COMPILER_RT_BUILD_XRAY'] = 'OFF' + return defines + + +class LlvmCore(BuildUtils): + + def __init__(self, build_config): + super(LlvmCore, self).__init__(build_config) + + def build_llvm(self, + targets, + build_dir, + install_dir, + build_name, + extra_defines=None, + extra_env=None): + + common_defines = self.base_cmake_defines() + common_defines['CMAKE_INSTALL_PREFIX'] = install_dir + common_defines['LLVM_INSTALL_UTILS'] = 'ON' + common_defines['LLVM_TARGETS_TO_BUILD'] = targets + common_defines['LLVM_BUILD_LLVM_DYLIB'] = 'ON' + + build_number = '' + if re.match(r'\d+-.\D*$', build_name): + build_number, build_name = build_name.split('-', 1) + elif re.match(r'^\d+$', build_name): + build_number = build_name + build_name = '' + elif re.match(r'^\D+$', build_name): + build_name = build_name + else: + raise Exception('Warning! Build name is invalid, because it must not contain digits. ' + 'If you want to pass digit version, please, use follow template: {NUMBER}-{SUFFIX} ' + 'or just pass number. Otherwise unit tests will fail with assertions') + + common_defines['CLANG_VENDOR'] = 'OHOS (%s) ' % build_name + common_defines['CLANG_VENDOR_BUILD_VERSION'] = build_number + common_defines.update(extra_defines) + + env = dict(self.build_config.ORIG_ENV) + if extra_env is not None: + env.update(extra_env) + + llvm_project_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'llvm')) + + self.invoke_cmake(llvm_project_path, + build_dir, + common_defines, + env=env) + + self.invoke_ninja(out_path=build_dir, + env=env, + target=None, + install=True) + + + def llvm_compile_darwin_defines(self, llvm_defines): + if self.host_is_darwin(): + llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + llvm_defines['LLDB_NO_DEBUGSERVER'] = 'ON' + llvm_defines['LLDB_ENABLE_PYTHON'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + llvm_defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON' + + def llvm_compile_linux_defines(self, + llvm_defines, + debug_build=False, + no_lto=False, + build_instrumented=False): + if self.host_is_linux(): + llvm_defines['LLVM_ENABLE_LLD'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + llvm_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + llvm_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF' + llvm_defines['LIBCXX_USE_COMPILER_RT'] = 'ON' + llvm_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + llvm_defines['LIBCXXABI_ENABLE_STATIC_UNWINDER'] = 'ON' + llvm_defines['LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY'] = 'YES' + llvm_defines['LIBCXXABI_USE_COMPILER_RT'] = 'ON' + llvm_defines['COMPILER_RT_USE_LLVM_UNWINDER'] = 'ON' + llvm_defines['COMPILER_RT_ENABLE_STATIC_UNWINDER'] = 'ON' + llvm_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_ORC'] = 'OFF' + llvm_defines['LIBUNWIND_USE_COMPILER_RT'] = 'ON' + llvm_defines['LLVM_BINUTILS_INCDIR'] = '/usr/include' + + + if not build_instrumented and not no_lto and not debug_build: + llvm_defines['LLVM_ENABLE_LTO'] = 'Thin' + + @staticmethod + def llvm_compile_llvm_defines(llvm_defines, llvm_cc, llvm_cxx, cflags, ldflags): + llvm_defines['LLVM_ENABLE_PROJECTS'] = 'clang;lld;clang-tools-extra;openmp;lldb' + llvm_defines['LLVM_ENABLE_RUNTIMES'] = 'libunwind;libcxxabi;libcxx;compiler-rt' + llvm_defines['LLVM_ENABLE_BINDINGS'] = 'OFF' + llvm_defines['CMAKE_C_COMPILER'] = llvm_cc + llvm_defines['CMAKE_CXX_COMPILER'] = llvm_cxx + llvm_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + llvm_defines['SANITIZER_ALLOW_CXXABI'] = 'OFF' + llvm_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + llvm_defines['OPENMP_TEST_FLAGS'] = '-Wl,-ldl' + llvm_defines['CLANG_BUILD_EXAMPLES'] = 'OFF' + llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + llvm_defines['LLDB_ENABLE_PYTHON'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + llvm_defines['COMPILER_RT_BUILD_MEMPROF'] = 'OFF' + llvm_defines['CMAKE_ASM_FLAGS'] = cflags + llvm_defines['CMAKE_C_FLAGS'] = cflags + llvm_defines['CMAKE_CXX_FLAGS'] = '%s -stdlib=libc++' % cflags + llvm_defines['CMAKE_EXE_LINKER_FLAGS'] = ldflags + llvm_defines['CMAKE_SHARED_LINKER_FLAGS'] = ldflags + llvm_defines['CMAKE_MODULE_LINKER_FLAGS'] = ldflags + + def llvm_compile(self, + build_name, + out_dir, + debug_build=False, + no_lto=False, + build_instrumented=False, + xunit_xml_output=None): + + llvm_clang_install = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'prebuilts/clang/ohos', self.use_platform(), + 'clang-%s' % self.build_config.CLANG_VERSION)) + llvm_path = self.merge_out_path('llvm_make') + llvm_cc = os.path.join(llvm_clang_install, 'bin', 'clang') + llvm_cxx = os.path.join(llvm_clang_install, 'bin', 'clang++') + llvm_profdata = os.path.join(llvm_clang_install, 'bin', 'llvm-profdata') + + if self.host_is_darwin(): + ldflags = '' + else: + ldflags = '-fuse-ld=lld' + ldflags = '%s -L%s' % (ldflags, os.path.join(llvm_clang_install, 'lib')) + + llvm_extra_env = {} + llvm_extra_env['LD_LIBRARY_PATH'] = os.path.join(llvm_clang_install, 'lib') + + llvm_defines = {} + + self.llvm_compile_darwin_defines(llvm_defines) + self.llvm_compile_linux_defines(llvm_defines, debug_build, no_lto, build_instrumented) + + if self.host_is_linux(): + ldflags += ' -l:libunwind.a -l:libc++abi.a --rtlib=compiler-rt -stdlib=libc++ -static-libstdc++' + + if xunit_xml_output: + llvm_defines['LLVM_LIT_ARGS'] = "--xunit-xml-output={} -sv".format(xunit_xml_output) + + if self.build_config.enable_assertions: + llvm_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + if debug_build: + llvm_defines['CMAKE_BUILD_TYPE'] = 'Debug' + + if build_instrumented: + llvm_defines['LLVM_BUILD_INSTRUMENTED'] = 'ON' + llvm_defines['LLVM_PROFDATA'] = llvm_profdata + + resource_dir = "lib/clang/10.0.1/lib/linux/libclang_rt.profile-x86_64.a" + ldflags += ' %s' % os.path.join(llvm_clang_install, resource_dir) + + cflags = '-fstack-protector-strong -fPIE' + if not self.host_is_darwin(): + ldflags += ' -Wl,-z,relro,-z,now -pie -s' + + self.llvm_compile_llvm_defines(llvm_defines, llvm_cc, llvm_cxx, cflags, ldflags) + + linker_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts', 'clang', + 'ohos', 'linux-x86_64', 'llvm', 'bin', 'ld.lld')) + llvm_defines['CMAKE_LINKER'] = linker_path + + self.build_llvm(targets=self.build_config.TARGETS, + build_dir=llvm_path, + install_dir=out_dir, + build_name=build_name, + extra_defines=llvm_defines, + extra_env=llvm_extra_env) + + def llvm_compile_windows_defines(self, + windows_defines, + cc, + cxx, + windows_sysroot): + + if self.build_config.enable_assertions: + + windows_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' + win_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + windows_defines['LLDB_ENABLE_PYTHON'] = 'ON' + windows_defines['LLDB_PYTHON_HOME'] = 'python' + windows_defines['LLDB_PYTHON_RELATIVE_PATH'] = \ + 'bin/python/lib/python%s' % (self.build_config.LLDB_PY_VERSION) + windows_defines['LLDB_PYTHON_EXE_RELATIVE_PATH'] = 'bin/python' + windows_defines['LLDB_PYTHON_EXT_SUFFIX'] = '.pys' + windows_defines['PYTHON_INCLUDE_DIRS'] = os.path.join(win_sysroot, + 'include', 'python%s' % self.build_config.LLDB_PY_VERSION) + windows_defines['PYTHON_LIBRARIES'] = os.path.join(win_sysroot, 'lib', 'libpython%s.dll.a' + % self.build_config.LLDB_PY_VERSION) + windows_defines['SWIG_EXECUTABLE'] = self.find_program('swig') + windows_defines['PYTHON_EXECUTABLE'] = self.find_program('python3') + + windows_defines['CMAKE_C_COMPILER'] = cc + windows_defines['CMAKE_CXX_COMPILER'] = cxx + windows_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + windows_defines['CMAKE_BUILD_TYPE'] = 'Release' + windows_defines['LLVM_BUILD_RUNTIME'] = 'OFF' + windows_defines['LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD'] = 'ON' + windows_defines['LLVM_TOOL_OPENMP_BUILD'] = 'OFF' + windows_defines['LLVM_INCLUDE_TESTS'] = 'OFF' + windows_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + windows_defines['LLVM_ENABLE_PROJECTS'] = 'clang;clang-tools-extra;lld;lldb' + windows_defines['LLVM_BUILD_LLVM_DYLIB'] = 'OFF' + windows_defines['CLANG_BUILD_EXAMPLES'] = 'OFF' + windows_defines['CMAKE_SYSROOT'] = windows_sysroot + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + windows_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' + + def llvm_compile_windows_flags(self, + windows_defines, + windowstool_path, + windows64_install, + ldflags, + cflags): + + windows_defines['CROSS_TOOLCHAIN_FLAGS_NATIVE'] = ';'.join([ + '-DCMAKE_PREFIX_PATH=%s' % self.CMAKE_BIN_DIR, + '-DCOMPILER_RT_BUILD_LIBFUZZER=OFF', + '-DLLVM_ENABLE_LIBCXX=ON', + '-DCMAKE_BUILD_WITH_INSTALL_RPATH=TRUE', + '-DCMAKE_INSTALL_RPATH=%s' % os.path.join(windowstool_path, 'lib')] + ) + + ldflag = ['-fuse-ld=lld', + '-stdlib=libc++', + '--rtlib=compiler-rt', + '-lunwind', '-Wl,--dynamicbase', + '-Wl,--nxcompat', + '-lucrt', + '-lucrtbase', + '-L', + os.path.join(windows64_install, 'lib'), + '-Wl,--high-entropy-va'] + ldflags.extend(ldflag) + + cflag = ['-stdlib=libc++', + '--target=x86_64-pc-windows-gnu', + '-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-D_WIN32_WINNT=0x0600', + '-DWINVER=0x0600', + '-D__MSVCRT_VERSION__=0x1400', + '-DMS_WIN64'] + cflags.extend(cflag) + + def llvm_compile_windows_cmake(self, + cflags, + cxxflags, + ldflags, + windows_defines): + + + zlib_path = self.merge_out_path('../', 'prebuilts', 'clang', 'host', 'windows-x86', 'toolchain-prebuilts', + 'zlib') + zlib_inc = os.path.join(zlib_path, 'include') + zlib_lib = os.path.join(zlib_path, 'lib') + + cflags.extend(['-I', zlib_inc]) + cxxflags.extend(['-I', zlib_inc]) + ldflags.extend(['-L', zlib_lib]) + + windows_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + windows_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + windows_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + windows_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + windows_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + windows_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + + def llvm_compile_for_windows(self, + targets, + enable_assertions, + build_name): + + self.logger().info('Building llvm for windows.') + + build_dir = self.merge_out_path("windows-x86_64") + windowstool_path = self.merge_out_path('llvm-install') + windows64_install = self.merge_out_path('windows-x86_64-install') + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + + self.check_create_dir(build_dir) + + # Write a NATIVE.cmake in windows_path that contains the compilers used + # to build native tools such as llvm-tblgen and llvm-config. This is + # used below via the CMake variable CROSS_TOOLCHAIN_FLAGS_NATIVE. + cc = os.path.join(windowstool_path, 'bin', 'clang') + cxx = os.path.join(windowstool_path, 'bin', 'clang++') + + # Extra cmake defines to use while building for Windows + windows_defines = {} + self.llvm_compile_windows_defines(windows_defines, cc, cxx, windows_sysroot) + + # Set CMake path, toolchain file for native compilation (to build tablegen + # etc). Also disable libfuzzer build during native compilation. + + ldflags = [] + cflags = [] + + self.llvm_compile_windows_flags(windows_defines, + windowstool_path, windows64_install, ldflags, cflags) + + cxxflags = list(cflags) + + windows_extra_env = dict() + + cxxflags.append('-fuse-cxa-atexit') + cxxflags.extend(('-I', os.path.join(windows64_install, 'include', 'c++', 'v1'))) + + self.llvm_compile_windows_cmake(cflags, cxxflags, ldflags, windows_defines) + + self.build_llvm(self.build_config.TARGETS, + build_dir, + windows64_install, + build_name, + extra_defines=windows_defines, + extra_env=windows_extra_env) + + +class SysrootComposer(BuildUtils): + + def __init__(self, build_config): + super(SysrootComposer, self).__init__(build_config) + + def setup_cmake_platform(self, llvm_install): + + # OHOS.cmake already exsit on cmake prebuilts, + # but it didn't contain these two lines, so we still need OHOS.cmake. + ohos_cmake = 'OHOS.cmake' + dst_dir = self.merge_out_path( + '../prebuilts/cmake/%s/share/cmake-3.16/Modules/Platform' % self.platform_prefix()) + src_file = '%s/%s' % (self.build_config.CURRENT_DIR, ohos_cmake) + if os.path.exists(os.path.join(dst_dir, ohos_cmake)): + os.remove(os.path.join(dst_dir, ohos_cmake)) + shutil.copy2(src_file, dst_dir) + + + def build_musl(self, llvm_install, target, *extra_args): + cur_dir = os.getcwd() + os.chdir(self.build_config.CURRENT_DIR) + self.logger().info('build musl %s', self.merge_out_path('install')) + args = ['./build_musl.sh', '-t', target, '-c', + self.merge_out_path(llvm_install, 'bin'), '-o', self.merge_out_path()] + list(extra_args) + self.check_call(args) + os.chdir(cur_dir) + + def install_linux_headers(self, arch, target): + dir_suffix = arch + if arch == 'x86_64': + dir_suffix = 'x86' + elif arch == 'mipsel': + dir_suffix = 'mips' + linux_kernel_dir = os.path.join('kernel_linux_patches', 'linux-5.10') + linux_kernel_path = os.path.join(self.build_config.OUT_PATH, '..', linux_kernel_dir) + ohosmusl_sysroot_dst = self.merge_out_path('sysroot', target, 'usr') + headers_tmp_dir = os.path.join(linux_kernel_path, 'prebuilts', 'usr', 'include') + self.check_copy_tree(os.path.join(headers_tmp_dir, 'linux'), + os.path.join(ohosmusl_sysroot_dst, 'include/linux')) + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-%s' % dir_suffix,'asm'), + os.path.join(ohosmusl_sysroot_dst, 'include', 'asm')) + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-generic'), + os.path.join(ohosmusl_sysroot_dst, 'include/asm-generic')) + + def copy_libz_to_sysroot(self, libz_path, llvm_triple): + # Install to sysroot + dest_usr = self.merge_out_path('sysroot', llvm_triple, 'usr') + dest_usr_include = os.path.join(dest_usr, 'include') + + # Copy over usr/include. + zlib_h = self.merge_out_path('../third_party/zlib', 'zlib.h') + self.check_copy_file(zlib_h, dest_usr_include) + + zconf_h = os.path.join(libz_path, 'zconf.h') + self.check_copy_file(zconf_h, dest_usr_include) + + # Copy over usr/lib. + dest_usr_lib = os.path.join(dest_usr, 'lib') + static_zlib = os.path.join(libz_path, 'libz.a') + self.check_copy_file(static_zlib, dest_usr_lib) + + +class LlvmLibs(BuildUtils): + + def __init__(self, build_config, sysroot_composer, llvm_package): + super(LlvmLibs, self).__init__(build_config) + self.sysroot_composer = sysroot_composer + self.llvm_package = llvm_package + + def build_crt_libs(self, configs, llvm_install, need_lldb_server): + for (arch, target) in configs: + self.sysroot_composer.build_musl(llvm_install, target) + if target.endswith(self.build_config.OPENHOS_SFX): + self.sysroot_composer.install_linux_headers(arch, target) + self.build_libs(need_lldb_server, + llvm_install, + target, + precompilation=True) + self.sysroot_composer.build_musl(llvm_install, target, '-l') + + def build_libs_defines(self, + llvm_triple, + defines, + cc, + cxx, + ar, + llvm_config, + ldflags, + cflags, + extra_flags): + + sysroot = self.merge_out_path('sysroot') + + defines['CMAKE_C_COMPILER'] = cc + defines['CMAKE_CXX_COMPILER'] = cxx + defines['CMAKE_AR'] = ar + defines['LLVM_CONFIG_PATH'] = llvm_config + defines['CMAKE_SYSROOT'] = sysroot + defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + ldflag = [ + '-fuse-ld=lld', + '-Wl,--gc-sections', + '-Wl,--build-id=sha1', + '--rtlib=compiler-rt', + '-stdlib=libc++', ] + + if not self.host_is_darwin(): + ldflag.append('-Wl,-z,relro,-z,now -s -pie') + + ldflags.extend(ldflag) + + cflag = [ + '-fstack-protector-strong', + '-fPIE', + '--target=%s' % llvm_triple, + '-ffunction-sections', + '-fdata-sections', + extra_flags, ] + + cflags.extend(cflag) + + def build_libs(self, need_lldb_server, llvm_install, llvm_build, precompilation=False): + configs_list = [ + ('arm', self.liteos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.liteos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.liteos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), + ('arm', self.liteos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), + + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.open_ohos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), + ('arm', self.open_ohos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), + ('aarch64', self.open_ohos_triple('aarch64'), '', ''), + ('riscv64', self.open_ohos_triple('riscv64'), '', ''), + ('mipsel', self.open_ohos_triple('mipsel'), '-march=mips32r2', ''), + ('x86_64', self.open_ohos_triple('x86_64'), '', ''),] + + cc = os.path.join(llvm_install, 'bin', 'clang') + cxx = os.path.join(llvm_install, 'bin', 'clang++') + ar = os.path.join(llvm_install, 'bin', 'llvm-ar') + llvm_config = os.path.join(llvm_install, 'bin', 'llvm-config') + seen_arch_list = [self.liteos_triple('arm')] + + self.set_clang_version(llvm_install) + for (arch, llvm_triple, extra_flags, multilib_suffix) in configs_list: + if llvm_build != llvm_triple: + continue + + has_lldb_server = arch not in ['riscv64', 'mipsel'] + + defines = {} + ldflags = [] + cflags = [] + self.logger().info('Build libs for %s', llvm_triple) + self.build_libs_defines(llvm_triple, defines, cc, cxx, ar, llvm_config, ldflags, cflags, extra_flags) + if arch == 'mipsel': + ldflags.append('-Wl,-z,notext') + ldflags.append('-Wl,--no-check-dynamic-relocations') + + llvm_path = self.merge_out_path('llvm_make') + arch_list = [self.liteos_triple('arm'), self.open_ohos_triple('arm'), + self.open_ohos_triple('aarch64'), self.open_ohos_triple('riscv64'), + self.open_ohos_triple('mipsel'), self.open_ohos_triple('x86_64')] + if precompilation: + self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + continue + # libunwind is added to linker command line by OHOS toolchain, so we have to use two step build + self.build_runtimes(llvm_install, "libunwind", ldflags, cflags, llvm_triple, arch, multilib_suffix, defines) + self.build_runtimes(llvm_install, "libunwind;libcxxabi;libcxx", ldflags, cflags, llvm_triple, arch, multilib_suffix, defines) + self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines, + first_time=False) + + if llvm_triple in arch_list: + if need_lldb_server and has_lldb_server and llvm_triple not in seen_arch_list: + self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, + defines) + seen_arch_list.append(llvm_triple) + continue + + self.build_libomp(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + self.build_libz(arch, llvm_triple, cflags, ldflags, defines) + if need_lldb_server and has_lldb_server and llvm_triple not in seen_arch_list: + self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, defines) + seen_arch_list.append(llvm_triple) + + def build_runtimes(self, + llvm_install, + rt_list, + ldflags, + cflags, + llvm_triple, + arch, + multilib_suffix, + defines): + + self.logger().info('Building runtimes(%s) for %s', (rt_list, arch)) + + out_path = self.merge_out_path('lib', rt_list.replace(';', '-') + '-' + str(llvm_triple)) + + rt_cflags = list(cflags) + rt_cflags.append('-fstack-protector-strong') + + rt_defines = defines.copy() + rt_defines['OHOS'] = '1' + rt_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + rt_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + rt_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + rt_defines['LLVM_ENABLE_RUNTIMES'] = rt_list + rt_defines['LIBUNWIND_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBUNWIND_ENABLE_SHARED'] = 'OFF' + rt_defines['LIBCXXABI_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + rt_defines['LIBCXXABI_ENABLE_STATIC_UNWINDER'] = 'ON' + rt_defines['LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL'] = 'OFF' + rt_defines['LIBCXXABI_ENABLE_SHARED'] = 'OFF' + rt_defines['LIBCXXABI_LIBCXX_INCLUDES'] = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxx', 'include')) + rt_defines['LIBCXX_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBCXX_ABI_NAMESPACE'] = '__h' + rt_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF' + rt_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + rt_defines['CMAKE_ASM_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_C_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_CXX_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + rt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + rt_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + rt_defines['CMAKE_CROSSCOMPILING'] = 'True' + rt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + self.check_rm_tree(out_path) + cmake_rt = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'runtimes')) + + self.invoke_cmake(cmake_rt, + out_path, + rt_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=out_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_crts(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines, + first_time=True): + + self.logger().info('Building compiler-rt for %s', arch) + + suffix = '-' + multilib_suffix if multilib_suffix else '' + crt_path = self.merge_out_path('lib', 'clangrt-%s%s' % (llvm_triple, suffix)) + crt_install = os.path.join(llvm_install, 'lib', 'clang', self.build_config.VERSION) + + crt_extra_flags = [] + if not self.build_config.debug: + # Remove absolute paths from compiler-rt debug info emitted with -gline-tables-only + crt_extra_flags = ['-ffile-prefix-map=%s=.' % self.build_config.REPOROOT_DIR] + + crt_defines = defines.copy() + crt_defines.update(self.base_cmake_defines()) + crt_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags) + crt_defines['OHOS'] = '1' + crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = llvm_triple + crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'ON' + crt_defines['CMAKE_INSTALL_PREFIX'] = crt_install + crt_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + if first_time or llvm_triple == self.liteos_triple('arm'): + crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + else: + crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + crt_defines['COMPILER_RT_BUILD_ORC'] = 'OFF' + crt_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + crt_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + crt_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + crt_defines['CMAKE_CROSSCOMPILING'] = 'True' + crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi' + crt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + crt_defines['COMPILER_RT_HWASAN_WITH_INTERCEPTORS'] = 'OFF' + crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = \ + 'OFF' if llvm_triple == self.liteos_triple('arm') or first_time else 'ON' + crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = llvm_triple + crt_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'compiler-rt')) + self.rm_cmake_cache(crt_path) + + self.invoke_cmake(crt_cmake_path, + crt_path, + crt_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=crt_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libomp(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines): + + self.logger().info('Building libomp for %s', arch) + + libomp_path = self.merge_out_path('lib', 'libomp-%s' % llvm_triple) + out_dir = os.path.join(libomp_path, 'lib') + + libomp_cflags = list(cflags) + libomp_cflags.append('-fPIC') + + libomp_defines = defines.copy() + libomp_defines.update(self.base_cmake_defines()) + libomp_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libomp_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libomp_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + libomp_defines['OHOS'] = '1' + libomp_defines['CMAKE_ASM_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['CMAKE_C_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['CMAKE_CXX_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['OPENMP_ENABLE_LIBOMPTARGET'] = 'FALSE' + + libomp_defines['OPENMP_LIBDIR_SUFFIX'] = os.path.join(os.sep, llvm_triple, multilib_suffix) + libomp_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + libomp_defines['CMAKE_POLICY_DEFAULT_CMP0056'] = 'NEW' + libomp_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + libomp_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + libomp_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + libomp_defines['CMAKE_CROSSCOMPILING'] = 'True' + libomp_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + libomp_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + libomp_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'openmp') + self.rm_cmake_cache(libomp_path) + + self.invoke_cmake(libomp_cmake_path, + libomp_path, + libomp_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libomp_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libz(self, + arch, + llvm_triple, + cflags, + ldflags, + defines): + + self.logger().info('Building libz for %s ', arch) + + libz_path = self.merge_out_path('lib', 'libz-%s' % llvm_triple) + if llvm_triple == self.hos_triple('arm'): + ldflags.append('-lunwind') + + libz_cflags = list(cflags) + libz_cflags.append('-fPIC') + + libz_defines = defines.copy() + libz_defines.update(self.base_cmake_defines()) + libz_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['OHOS'] = '1' + libz_defines['CMAKE_ASM_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_C_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_CXX_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + libz_cmake_path = os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib') + self.rm_cmake_cache(libz_path) + + self.invoke_cmake(libz_cmake_path, + libz_path, + libz_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libz_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=False) + + self.sysroot_composer.copy_libz_to_sysroot(libz_path, llvm_triple) + + def build_lldb_server(self, + llvm_install, + llvm_path, + arch, + llvm_triple, + cflags, + ldflags, + defines): + + self.logger().info('Building lldb for %s', arch) + + lldb_path = self.merge_out_path('lib', 'lldb-server-%s' % llvm_triple) + crt_install = os.path.join(llvm_install, 'lib', 'clang', self.build_config.VERSION) + out_dir = os.path.join(lldb_path, 'bin') + + lldb_ldflags = list(ldflags) + lldb_cflags = list(cflags) + + lldb_ldflags.append('-lunwind') + lldb_ldflags.append('-static') + + lldb_defines = defines.copy() + lldb_defines.update(self.base_cmake_defines()) + + lldb_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + lldb_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + lldb_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + + lldb_defines['OHOS'] = '1' + lldb_defines['CMAKE_C_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_ASM_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_CXX_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_INSTALL_PREFIX'] = crt_install + lldb_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + lldb_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + lldb_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + lldb_defines['CMAKE_CROSSCOMPILING'] = 'True' + lldb_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + lldb_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_defines['LLVM_ENABLE_PROJECTS'] = 'clang;lldb' + lldb_defines['LLVM_TABLEGEN'] = os.path.join(llvm_install, 'bin', 'llvm-tblgen') + lldb_defines['CLANG_TABLEGEN'] = os.path.join(llvm_install, '..', llvm_path, 'bin', 'clang-tblgen') + lldb_defines['LLDB_TABLEGEN'] = os.path.join(llvm_install, '..', llvm_path, 'bin', 'lldb-tblgen') + lldb_defines['LLVM_HOST_TRIPLE'] = llvm_triple + lldb_defines['LLVM_TARGET_ARCH'] = arch + lldb_defines['LLVM_TARGETS_TO_BUILD'] = self.build_config.TARGETS + + lldb_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'llvm') + + self.invoke_cmake(lldb_cmake_path, + lldb_path, + lldb_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=lldb_path, + env=dict(self.build_config.ORIG_ENV), + target='lldb-server', + install=False) + + self.llvm_package.copy_lldb_server_to_llvm_install(lldb_path, crt_install, llvm_triple) + + + def build_runtimes_for_windows(self, enable_assertions): + + self.logger().info('Building libs for windows.') + toolchain_dir = self.merge_out_path('llvm-install') + install_dir = self.merge_out_path('windows-x86_64-install') + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + + cflags = ['-stdlib=libc++', '--target=x86_64-pc-windows-gnu', '-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', '-D_WIN32_WINNT=0x0600', '-DWINVER=0x0600', '-D__MSVCRT_VERSION__=0x1400'] + + cmake_defines = {} + cmake_defines['CMAKE_C_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang') + cmake_defines['CMAKE_CXX_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang++') + cmake_defines['CMAKE_CROSSCOMPILING'] = 'True' + cmake_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + cmake_defines['CMAKE_SYSROOT'] = windows_sysroot + cmake_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + cmake_defines['CMAKE_INSTALL_PREFIX'] = install_dir + cmake_defines['LLVM_CONFIG_PATH'] = os.path.join(toolchain_dir, 'bin', 'llvm-config') + cmake_defines['LIBCXX_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + cmake_defines['LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS'] = 'ON' + cmake_defines['LIBCXXABI_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBUNWIND_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + cmake_defines['LLVM_ENABLE_RUNTIMES'] = 'libunwind;libcxxabi;libcxx' + cmake_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' if enable_assertions else 'OFF' + + out_path = self.merge_out_path('lib', 'windows-runtimes') + cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'runtimes')) + + self.invoke_cmake(cmake_path, + out_path, + cmake_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path, + env=dict(self.build_config.ORIG_ENV), + install=True) + + + +class LldbMi(BuildUtils): + + def __init__(self, build_config, llvm_package): + super(LldbMi, self).__init__(build_config) + self.llvm_package = llvm_package + + def build_lldb_mi(self, llvm_install): + self.logger().info('Building lldb-mi for linux.') + + llvm_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'prebuilts/clang/ohos', self.use_platform(), 'clang-%s' % self.build_config.CLANG_VERSION)) + lldb_mi_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi') + lldb_mi_path = self.merge_out_path('lldb_mi_build') + + self.check_rm_tree(lldb_mi_path) + self.rm_cmake_cache(lldb_mi_path) + + if self.host_is_darwin(): + cflags = [] + cxxflags =[] + ldflags = ['-Wl,-rpath,%s' % '@loader_path/../lib'] + else: + cflags = [] + cxxflags =[] + ldflags = ['-fuse-ld=lld', '-Wl,-rpath,%s' % '\$ORIGIN/../lib'] + ldflags.append('-Wl,-z,relro,-z,now -pie -s') + + ldflags.append('-L%s' % os.path.join(llvm_path, 'lib')) + cxxflags.append('-std=c++14') + cxxflags.append('-fstack-protector-strong -fPIE') + cflags.append('-fstack-protector-strong -fPIE') + + lldb_mi_defines = {} + lldb_mi_defines['CMAKE_C_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang') + lldb_mi_defines['CMAKE_CXX_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang++') + lldb_mi_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + lldb_mi_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + lldb_mi_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['LLVM_DIR'] = os.path.join(llvm_install, 'lib/cmake/llvm/') + lldb_mi_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_mi_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + + self.invoke_cmake(lldb_mi_cmake_path, + lldb_mi_path, + lldb_mi_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(lldb_mi_path, + env=dict(self.build_config.ORIG_ENV), + install=False) + + self.llvm_package.copy_lldb_mi_to_llvm_install(lldb_mi_path, llvm_install) + + @staticmethod + def ldflags_lists_define(): + ldflags_lists = ['-Wl,--dynamicbase', + '-Wl,--nxcompat', + '-lucrt', + '-lucrtbase', + '-L', ] + return ldflags_lists + + @staticmethod + def cflags_lists_define(): + cflags_lists = ['-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-D_WIN32_WINNT=0x0600', + '-DWINVER=0x0600', + '-D__MSVCRT_VERSION__=0x1400', + '-DMS_WIN64', ] + return cflags_lists + + # Extra cmake defines to use while building for Windows + def lldb_mi_windefines_dictionary(self, cc, cxx, windows_sysroot, cflags, cxxflags, ldflags): + lldb_mi_windefines = {} + lldb_mi_windefines['CMAKE_C_COMPILER'] = cc + lldb_mi_windefines['CMAKE_CXX_COMPILER'] = cxx + lldb_mi_windefines['CMAKE_C_COMPILER_WORKS'] = '1' + lldb_mi_windefines['CMAKE_CXX_COMPILER_WORKS'] = '1' + lldb_mi_windefines['CMAKE_SYSTEM_NAME'] = 'Windows' + lldb_mi_windefines['CMAKE_SYSTEM_PROCESSOR'] = 'x86_64' + lldb_mi_windefines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_mi_windefines['CMAKE_SYSROOT'] = windows_sysroot + lldb_mi_windefines['LLVM_INSTALL_PREFIX'] = self.merge_out_path('windows-x86_64-install') + lldb_mi_windefines['LLVM_DIR'] = self.merge_out_path('windows-x86_64-install/lib/cmake/llvm/') + lldb_mi_windefines['CMAKE_C_FLAGS'] = ' '.join(cflags) + lldb_mi_windefines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + lldb_mi_windefines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_windefines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_windefines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + if self.build_config.enable_assertions: + lldb_mi_windefines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + return lldb_mi_windefines + + + def build_lldb_mi_for_windows(self): + self.logger().info('Building lldb-mi for windows.') + + build_dir = self.merge_out_path('llvm-install') + lldb_mi_windows64_path = self.merge_out_path('windows-x86_64-lldb-mi') + lldb_mi_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi')) + windows64_install = self.merge_out_path('windows-x86_64-install') + cc = os.path.join(build_dir, 'bin', 'clang') + cxx = os.path.join(build_dir, 'bin', 'clang++') + + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + self.check_create_dir(lldb_mi_windows64_path) + + ldflags = ['-fuse-ld=lld', + '--rtlib=compiler-rt', + '-lunwind', + '-L%s' % os.path.join(windows64_install, 'lib'), + ] + ldflags.extend(self.ldflags_lists_define()) + ldflags.append(os.path.join(windows64_install, 'lib')) + ldflags.append('-Wl,--high-entropy-va') + + + cflags = ['-stdlib=libc++', + '--target=x86_64-pc-windows-gnu', + ] + cflags.extend(self.cflags_lists_define()) + cflags.append('-fno-exceptions') + cflags.append('-fno-rtti') + + cxxflags = list(cflags) + cxxflags.extend(('-I', os.path.join(windows64_install, 'include', 'c++', 'v1'))) + + zlib_path = os.path.abspath( + os.path.join('../../', 'prebuilts', 'clang', 'host', 'windows-x86', 'toolchain-prebuilts', 'zlib')) + zlib_inc = os.path.join(zlib_path, 'include') + zlib_lib = os.path.join(zlib_path, 'lib') + + cflags.extend(['-I', zlib_inc]) + cxxflags.extend(['-I', zlib_inc]) + ldflags.extend(['-L', zlib_lib]) + + + lldb_mi_env = dict(self.build_config.ORIG_ENV) + lldb_mi_env['LD_LIBRARY_PATH'] = os.path.join(build_dir, 'lib') + self.rm_cmake_cache(lldb_mi_windows64_path) + + self.invoke_cmake(lldb_mi_cmake_path, + lldb_mi_windows64_path, + self.lldb_mi_windefines_dictionary(cc, cxx, windows_sysroot, cflags, cxxflags, ldflags), + env=lldb_mi_env) + + self.invoke_ninja(lldb_mi_windows64_path, + env=lldb_mi_env, + install=False) + + self.llvm_package.copy_lldb_mi_to_windows(windows64_install, lldb_mi_windows64_path) + + +class LlvmPackage(BuildUtils): + + def __init__(self, build_config): + super(LlvmPackage, self).__init__(build_config) + + def copy_lldb_server_to_llvm_install(self, lldb_path, crt_install, llvm_triple): + # Copy lldb-server + libname = 'lldb-server' + src_lib = os.path.join(lldb_path, 'bin', libname) + dst_dir = os.path.join(crt_install, 'bin', llvm_triple) + self.check_create_dir(dst_dir) + self.check_copy_file(src_lib, os.path.join(dst_dir, libname)) + + def copy_lldb_mi_to_llvm_install(self, lldb_mi_path, llvm_install): + # Copy lldb-mi + lldb_mi_dst = os.path.join(llvm_install, 'bin', 'lldb-mi') + lldb_mi_src = os.path.join(lldb_mi_path, 'src', 'lldb-mi') + + if os.path.exists(lldb_mi_dst): + os.remove(lldb_mi_dst) + self.check_copy_file(lldb_mi_src, lldb_mi_dst) + + def copy_lldb_mi_to_windows(self, windows64_install, lldb_mi_windows64_path): + # Copy lldb-mi for windows + lldb_mi_dst = os.path.join(windows64_install, 'bin', 'lldb-mi.exe') + lldb_mi_src = os.path.join(lldb_mi_windows64_path, 'src', 'lldb-mi.exe') + if os.path.exists(lldb_mi_dst): + os.remove(lldb_mi_dst) + self.check_copy_file(lldb_mi_src, lldb_mi_dst) + + def package_libcxx(self): + libcxx_ndk_install=self.merge_out_path('libcxx-ndk') + libcxx_ndk_install_include=self.merge_out_path(libcxx_ndk_install, 'include', 'libcxx-ohos', 'include', 'c++', 'v1') + hosts_list=['linux-x86_64', 'darwin-x86_64', 'windows-x86_64', 'darwin-arm64'] + + if os.path.exists(libcxx_ndk_install): + for headerfile in os.listdir(libcxx_ndk_install_include): + if not headerfile =='__config': + if os.path.isdir(os.path.join(libcxx_ndk_install_include, headerfile)): + shutil.rmtree(os.path.join(libcxx_ndk_install_include, headerfile)) + else: + os.remove(os.path.join(libcxx_ndk_install_include, headerfile)) + + #Package libcxx-ndk + for host in hosts_list: + tarball_name = 'libcxx-ndk-%s-%s' % (self.build_config.build_name, host) + package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + args = ['tar', '-chjC', self.build_config.OUT_PATH, '-f', package_path, 'libcxx-ndk'] + self.check_call(args) + self.check_rm_tree(libcxx_ndk_install) + + @staticmethod + def merge_tree(src_dir, dst_dir): + for item in os.listdir(src_dir): + src_path = os.path.join(src_dir, item) + dst_path = os.path.join(dst_dir, item) + if os.path.isfile(src_path): + shutil.copyfile(src_path, dst_path) + else: + shutil.copytree(src_path, dst_path) + + + def install_mingw_python(self, install_dir): + py_root = self.merge_out_path('../third_party', 'mingw-w64', 'mingw-w64-python', + self.build_config.LLDB_PY_VERSION) + bin_root = os.path.join(install_dir, 'bin') + py_dll = 'libpython' + self.build_config.LLDB_PY_VERSION + '.dll' + shutil.copyfile(os.path.join(py_root, py_dll), os.path.join(bin_root, py_dll)) + self.merge_tree(os.path.join(py_root, 'lib'), + os.path.join(bin_root, 'python', 'lib', 'python%s' % self.build_config.LLDB_PY_VERSION)) + + + + + + def windows_lib_files_operation(self, lib_files, lib_dir, install_dir): + + # Remove unnecessary Windows lib files. + windows_necessary_lib_files = ['libc++.a', 'libc++abi.a'] + + for lib_file in lib_files: + if lib_file.endswith('.a') and lib_file not in windows_necessary_lib_files: + static_library = os.path.join(lib_dir, lib_file) + os.remove(static_library) + + for necessary_lib_file in windows_necessary_lib_files: + if not os.path.isfile(os.path.join(lib_dir, necessary_lib_file)): + raise RuntimeError('Did not find %s under %s' % (necessary_lib_file, lib_dir)) + self.install_mingw_python(install_dir) + + + def darwin_stripped_xargs(self, bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin): + for bin_filename in os.listdir(bin_dir): + binary = os.path.join(bin_dir, bin_filename) + if not os.path.isfile(binary): + continue + if bin_filename not in necessary_bin_files: + os.remove(binary) + elif bin_filename not in script_bins: + if bin_filename not in need_x_bins_darwin and self.host_is_darwin(): + self.check_call(['strip', '-x', binary]) + else: + self.check_call(['strip', binary]) + + + def strip_lldb_server(self, host, install_dir): + clang_version_bin_dir = os.path.join(install_dir, 'lib', 'clang', self.build_config.CLANG_VERSION, 'bin') + + if not host.startswith('linux') or not os.path.exists(clang_version_bin_dir): + return + llvm_strip = os.path.join(install_dir, 'bin', 'llvm-strip') + for llvm_triple_dir in os.listdir(clang_version_bin_dir): + llvm_triple_bin_dir = os.path.join(clang_version_bin_dir, llvm_triple_dir) + + if not os.path.isdir(llvm_triple_bin_dir): + continue + + for bin_filename in os.listdir(llvm_triple_bin_dir): + binary = os.path.join(llvm_triple_bin_dir, bin_filename) + if os.path.isfile(binary): + self.check_call([llvm_strip, binary]) + + + def notice_prebuilts_file(self, host, projects, install_dir): + + # Fetch all the LICENSE.* files under our projects and append them into a + # Single NOTICE file for the resulting prebuilts. + notices = [] + for project in projects: + license_pattern = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, project, 'LICENSE.*')) + for license_file in glob.glob(license_pattern): + with open(license_file) as notice_file: + notices.append(notice_file.read()) + + zlib_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib/LICENSE')) + with open(zlib_license_file) as notice_file: + notices.append(notice_file.read()) + + if host.startswith('windows'): + mingw_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'third_party/mingw-w64/COPYING')) + with open(mingw_license_file) as notice_file: + notices.append(notice_file.read()) + + with open(os.path.join(install_dir, 'NOTICE'), 'w') as notice_file: + notice_file.write('\n'.join(notices)) + + + def package_clang_bin_file(self, necessary_bin_files, ext): + necessary_bin_file = [ + 'clang%s' % ext, + 'clang++%s' % ext, + 'clang-cpp%s' % ext, + 'clang-%s%s' % (self.build_config.VERSION.split('.')[0], ext), + 'clang-check%s' % ext, + 'clang-cl%s' % ext, + 'clang-format%s' % ext, + 'clang-tidy%s' % ext, + 'clangd%s' % ext, + 'count%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_lldb_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'dsymutil%s' % ext, + 'FileCheck%s' % ext, + 'git-clang-format', + 'ld.lld%s' % ext, + 'ld64.lld%s' % ext, + 'lld%s' % ext, + 'lld-link%s' % ext, + 'lldb%s' % ext, + 'lldb-argdumper%s' % ext, + 'lldb-server%s' % ext, + 'lldb-vscode%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_llvm_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'llvm-addr2line%s' % ext, + 'llvm-ar%s' % ext, + 'llvm-as%s' % ext, + 'llvm-cfi-verify%s' % ext, + 'llvm-config%s' % ext, + 'llvm-cov%s' % ext, + 'llvm-cxxfilt%s' % ext, + 'llvm-dis%s' % ext, + 'llvm-lib%s' % ext, + 'llvm-link%s' % ext, + 'llvm-modextract%s' % ext, + 'llvm-nm%s' % ext, + 'llvm-objcopy%s' % ext, + 'llvm-objdump%s' % ext, + 'llvm-profdata%s' % ext, + 'llvm-ranlib%s' % ext, + 'llvm-readelf%s' % ext, + 'llvm-readobj%s' % ext, + 'llvm-rc%s' % ext, + 'llvm-size%s' % ext, + 'llvm-strings%s' % ext, + 'llvm-strip%s' % ext, + 'llvm-symbolizer%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_scan_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'not%s' % ext, + 'sancov%s' % ext, + 'sanstats%s' % ext, + 'scan-build%s' % ext, + 'scan-view%s' % ext, + 'yaml2obj%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_license_project_tuple(): + # Install license files as NOTICE in the toolchain install dir. + projects = ( + 'llvm', + 'compiler-rt', + 'libcxx', + 'libcxxabi', + 'openmp', + 'clang', + 'clang-tools-extra', + 'lld', + 'lldb', + 'libunwind', + ) + return projects + + def remove_unnecessary_bin(self, necessary_bin_files, host, lib_dir, install_dir, ext, shlib_ext): + + lib_files = [] + if os.path.isdir(lib_dir): + lib_files = os.listdir(lib_dir) + if host.startswith('windows'): + vers_major = int(self.build_config.VERSION.split('.')[0]) + # Redefining necessary bin files for Windows. + windows_forbidden_list_bin_files = ['clang-%s%s' % (vers_major, ext), 'scan-build%s' % ext, + 'scan-view%s' % ext] + windows_additional_bin_files = ['liblldb%s' % shlib_ext, 'libpython3.10%s' % shlib_ext] + + new_necessary_bin_files = list(set(necessary_bin_files) - set(windows_forbidden_list_bin_files)) + new_necessary_bin_files.extend(windows_additional_bin_files) + del necessary_bin_files[:] + necessary_bin_files.extend(new_necessary_bin_files) + + self.windows_lib_files_operation(lib_files, lib_dir, install_dir) + else: + # Remove unnecessary static libraries. + for lib_file in lib_files: + if lib_file.endswith('.a'): + static_library = os.path.join(lib_dir, lib_file) + os.remove(static_library) + + def package_up_resulting(self, package_name, host, install_host_dir): + # Package up the resulting trimmed install/ directory. + tarball_name = '%s-%s' % (package_name, host) + package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + args = ['tar', '-cjC', install_host_dir, '-f', package_path, package_name] + if host.startswith('windows'): + # windows do not support symlinks, + # replace them with file copies + args.insert(1, '--dereference') + + self.check_call(args) + + # Package ohos NDK + if os.path.exists(self.merge_out_path('sysroot')): + tarball_ndk_name = 'ohos-sysroot-%s' % self.build_config.build_name + package_ndk_path = '%s%s' % (self.merge_out_path(tarball_ndk_name), '.tar.bz2') + self.logger().info('Packaging %s', package_ndk_path) + args = ['tar', '-chjC', self.build_config.OUT_PATH, '-f', package_ndk_path, 'sysroot'] + self.check_call(args) + + # Packing Operation. + + def package_operation(self, build_dir, host): + + self.logger().info('Packaging for other environments.') + package_name = 'clang-%s' % self.build_config.build_name + self.set_clang_version(build_dir) + + if host.startswith('windows'): + ext = '.exe' + shlib_ext = '.dll' + elif host.startswith('linux'): + ext = '' + shlib_ext = '.so' + else: + ext = '' + shlib_ext = '.dylib' + + install_dir = self.merge_out_path('install', host, package_name) + bin_dir = os.path.join(install_dir, 'bin') + lib_dir = os.path.join(install_dir, 'lib') + install_host_dir = os.path.abspath(os.path.join(install_dir, '../')) + self.check_rm_tree(install_host_dir) + self.check_copy_tree(build_dir, install_dir) + # copy readme file to install_dir + shutil.copyfile(os.path.join(self.build_config.CURRENT_DIR, "toolchain_readme.md"), + os.path.join(install_dir, "README.md")) + + # Remove unnecessary binaries. + necessary_bin_files = [] + self.package_clang_bin_file(necessary_bin_files, ext) + self.package_lldb_bin_file(necessary_bin_files, ext) + self.package_llvm_bin_file(necessary_bin_files, ext) + self.package_scan_bin_file(necessary_bin_files, ext) + + if self.build_config.need_lldb_mi: + necessary_bin_files.append('lldb-mi%s' % ext) + self.remove_unnecessary_bin(necessary_bin_files, host, lib_dir, install_dir, ext, shlib_ext) + + # Scripts that should not be stripped + script_bins = ['git-clang-format', 'scan-build', 'scan-view'] + need_x_bins_darwin = ['clang', 'clang++', 'clang-9', 'clang-cl', 'clang-cpp'] + + # Bin file in the list should be stripped with -x args when host=darwin + self.darwin_stripped_xargs(bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin) + + # Strip lldb-server + self.strip_lldb_server(host, install_dir) + + for necessary_bin_file in necessary_bin_files: + if not os.path.isfile(os.path.join(bin_dir, necessary_bin_file)): + print('Did not find %s in %s' % (necessary_bin_file, bin_dir)) + raise RuntimeError('Did not find %s in %s' % (necessary_bin_file, bin_dir)) + + cmake_dir = os.path.join(lib_dir, 'cmake') + self.check_rm_tree(cmake_dir) + + self.notice_prebuilts_file(host, self.package_license_project_tuple(), install_dir) + + create_tar = True + if create_tar: + self.package_up_resulting(package_name, host, install_host_dir) + + return + + + +def main(): + build_config = BuildConfig() + build_utils = BuildUtils(build_config) + sysroot_composer = SysrootComposer(build_config) + llvm_core = LlvmCore(build_config) + llvm_package = LlvmPackage(build_config) + lldb_mi = LldbMi(build_config, llvm_package) + llvm_libs = LlvmLibs(build_config, sysroot_composer, llvm_package) + + args = build_config.parse_args() + need_host = build_utils.host_is_darwin() or ('linux' not in args.no_build) + need_windows = build_utils.host_is_linux() and \ + ('windows' not in args.no_build) + + llvm_install = build_utils.merge_out_path('llvm-install') + windows64_install = build_utils.merge_out_path('windows-x86_64-install') + + configs = [] + if not build_config.no_build_arm: + configs.append(('arm', build_utils.liteos_triple('arm'))) + configs.append(('arm', build_utils.open_ohos_triple('arm'))) + + if not build_config.no_build_aarch64: + configs.append(('arm64', build_utils.open_ohos_triple('aarch64'))) + + if not build_config.no_build_riscv64: + configs.append(('riscv', build_utils.open_ohos_triple('riscv64'))) + + if not build_config.no_build_mipsel: + configs.append(('mipsel', build_utils.open_ohos_triple('mipsel'))) + + if not build_config.no_build_x86_64: + configs.append(('x86_64', build_utils.open_ohos_triple('x86_64'))) + + + if build_config.do_build and need_host: + llvm_core.llvm_compile( + build_config.build_name, + llvm_install, + build_config.debug, + build_config.no_lto, + build_config.build_instrumented, + build_config.xunit_xml_output) + + llvm_core.set_clang_version(llvm_install) + + if build_config.do_build and build_utils.host_is_linux(): + sysroot_composer.setup_cmake_platform(llvm_install) + llvm_libs.build_crt_libs(configs, llvm_install, build_config.need_lldb_server) + + if build_config.need_libs: + for (arch, target) in configs: + llvm_libs.build_libs(build_config.need_lldb_server, llvm_install, target) + + if build_config.do_build and need_windows: + mingw.main(build_config.VERSION) + llvm_libs.build_runtimes_for_windows(build_config.enable_assertions) + llvm_core.llvm_compile_for_windows(build_config.TARGETS, + build_config.enable_assertions, + build_config.build_name) + + if build_config.need_lldb_mi: + lldb_mi.build_lldb_mi_for_windows() + + if build_config.do_build and build_config.need_lldb_mi and need_host: + lldb_mi.build_lldb_mi(llvm_install) + + if build_config.do_package: + if build_utils.host_is_linux(): + llvm_package.package_libcxx() + llvm_package.package_operation(llvm_install, build_utils.use_platform()) + if build_config.do_package and need_windows: + llvm_package.package_operation(windows64_install, 'windows-x86_64') + +if __name__ == '__main__': + main() diff --git a/llvm-build/build_cpython-mingw.sh b/llvm-build/build_cpython-mingw.sh new file mode 100755 index 0000000000000000000000000000000000000000..7419458cc7d956f3362f51213503ca4baca1666b --- /dev/null +++ b/llvm-build/build_cpython-mingw.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +PROJECT_ROOT=$(pwd) +CPYTHON_MINGW_SRC=${PROJECT_ROOT}/third_party/python +MINGW_W64_SRC=${PROJECT_ROOT}/third_party/mingw-w64 + +# prepare SYSROOT for cpython-mingw build +CLANG_MINGW_BUILD=${PROJECT_ROOT}/out/clang_mingw +python3 ${PROJECT_ROOT}/toolchain/llvm-build/mingw.py + +# refreash cpython-mingw config +cd ${CPYTHON_MINGW_SRC} +cat ./patchs/cpython_mingw_v3.10.2.patch | patch -d ./ -p1 -E +rm -rf ${CPYTHON_MINGW_SRC}/configure +autoconf ${CPYTHON_MINGW_SRC}/configure.ac > ${CPYTHON_MINGW_SRC}/configure +chmod 777 ${CPYTHON_MINGW_SRC}/configure +./configure + +# # prepare build config and build libpython for cpython-mingw +CPYTHON_MINGW_BUILD=${PROJECT_ROOT}/out/cpython-mingw-build +mkdir -p ${CPYTHON_MINGW_BUILD} +cd ${CPYTHON_MINGW_BUILD} +MINGW_PREFIX=${CPYTHON_MINGW_BUILD}/mingw64 +MINGW_CHOST=x86_64-w64-mingw32 +MINGW_BUILD=x86_64-unknown-linux-gnu +CLANG_VERSION=clang-10.0.1 +TOOLCHAIN_ROOT=${CLANG_MINGW_BUILD}/${CLANG_VERSION}/bin +SYSROOT=${CLANG_MINGW_BUILD}/${CLANG_VERSION}/x86_64-w64-mingw32 +mkdir $MINGW_BUILD + +export CC=$TOOLCHAIN_ROOT/clang +export CXX=$TOOLCHAIN_ROOT/clang++ +export CFLAGS="-target ${MINGW_CHOST} --sysroot=$SYSROOT" +export LDFLAGS="--sysroot=$SYSROOT -rtlib=compiler-rt -target ${MINGW_CHOST} -lucrt -lucrtbase -fuse-ld=lld" + +${CPYTHON_MINGW_SRC}/configure \ + --prefix=${MINGW_PREFIX} \ + --host=${MINGW_CHOST} \ + --build=${MINGW_BUILD} \ + --enable-shared \ + --enable-static \ + --without-ensurepip \ + --without-c-locale-coercion \ + --enable-loadable-sqlite-extensions + +make -j4 + +# copy build result to mingw-w64 +cp ${CPYTHON_MINGW_BUILD}/libpython3.10.dll.a ${MINGW_W64_SRC}/mingw-w64-crt/lib64 +cp ${CPYTHON_MINGW_BUILD}/libpython3.10.dll ${MINGW_W64_SRC}/mingw-w64-python/3.10 +cd ../.. + +# example steps to install autoconf 2.71 +# wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz +# export PATH=/mnt/disk2/liwentao/workspace/tools/autoconf/autoconf-2.71/bin:$PATH +# sudo cp -r /mnt/disk2/liwentao/workspace/tools/autoconf/autoconf-2.71/lib /usr/local/share/autoconf + +# refreash configure and Makefile for mingw-w64 +# you need autoconf (2.69 for Ubuntu 20.04 LTS apt install, to support mingw-w64 9.x and later version, please install autoconf 2.71 http://ftp.gnu.org/gnu/autoconf/) +# and automake (1.16.1 for Ubuntu 20.04 LTS apt install) +cd ${MINGW_W64_SRC}/mingw-w64-crt +rm -rf configure +autoconf configure.ac > configure +chmod 777 configure + +aclocal +automake + +cd ${MINGW_W64_SRC}/mingw-w64-headers +rm -rf configure +autoconf configure.ac > configure +chmod 777 configure + +aclocal +automake + +# move cpython-mingw build result and python header file to mingw-w64 +cp -r ${CPYTHON_MINGW_SRC}/Include ${MINGW_W64_SRC}/mingw-w64-headers/include/python3.10 +cp ${CPYTHON_MINGW_SRC}/pyconfig.h ${MINGW_W64_SRC}/mingw-w64-headers/include/python3.10 +mkdir -p ${MINGW_W64_SRC}/mingw-w64-python/3.10 +cp -r ${CPYTHON_MINGW_SRC}/Lib ${MINGW_W64_SRC}/mingw-w64-python/3.10/lib \ No newline at end of file diff --git a/llvm-build/build_musl.sh b/llvm-build/build_musl.sh new file mode 100755 index 0000000000000000000000000000000000000000..9fb8737c032a015587d0a42f46add2c31c7ff372 --- /dev/null +++ b/llvm-build/build_musl.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set -e + +# This script is used to create musl's libc.so. + +#default variables +CLANG_BIN_ROOT="${PWD}/../../out/install/linux-x86_64/clang-dev/bin/" +TARGET_TRIPLE="" +OUT="${PWD}/../../out" +make_libs=0 + +#argument parser +while getopts "c:t:o:lh" arg +do + case "${arg}" in + "c") + CLANG_BIN_ROOT=${OPTARG} + ;; + "t") + TARGET_TRIPLE=${OPTARG} + ;; + "o") + OUT=${OPTARG} + ;; + "l") + make_libs=1 + ;; + "h") + echo "Usage: ./build_musl.sh [OPTION]" + echo " Build C/C++ dynamic libs and runtime object" + echo " Options are:" + echo " -c Specify clang bin path" + echo " -t Specify target tripple" + echo " -o Specify the build output directory" + echo " -l Install libs" + exit 0 + ;; + ?) + echo "unkown argument" + exit 1 + ;; + esac +done + +if [ -z "${TARGET_TRIPLE}" ] +then + echo "[ERROR] Empty target triple in build_musl.sh" + exit 1 +fi + +# Canonicalize paths +CLANG_BIN_ROOT=$(readlink -f ${CLANG_BIN_ROOT}) + +CFLAGS_FOR_TARGET=("-mfloat-abi=soft" "-mfloat-abi=soft -mcpu=cortex-a7" +"-mfloat-abi=softfp -mfpu=neon-vfpv4 -mcpu=cortex-a7" "-mfloat-abi=hard -mfpu=neon-vfpv4 -mcpu=cortex-a7") + +if [ $TARGET_TRIPLE == "arm-liteos-ohos" ]; then + TARGET_USER="liteos_a_user" + TARGETS_PREFIX="arm" +elif [ $TARGET_TRIPLE == "arm-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="arm" +elif [ $TARGET_TRIPLE == "mipsel-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="mips" + CFLAGS_FOR_TARGET=("-march=mips32r2") +elif [ $TARGET_TRIPLE == "riscv64-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="riscv64" +elif [ $TARGET_TRIPLE == "x86_64-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="x86_64" +else + TARGET_USER="linux_user" + TARGETS_PREFIX="aarch64" +fi + +echo "CLANG_BIN_ROOT=${CLANG_BIN_ROOT}" +echo "ARCH=${TARGETS_PREFIX}" +echo "TARGET=${TARGET_TRIPLE}" +echo "TOPDIR=${PWD}/../.." +echo "TARGETS=${TARGET_USER}" +echo "OUT=${OUT}" +echo "SYSROOTDIR=${OUT}/sysroot" + +# build musl_headers +make musl_header_install_for_${TARGET_USER} CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../\ + SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER} TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile + +# build musl_libs +if ((make_libs == 1)); then + if [ $TARGET_TRIPLE == "aarch64-linux-ohos" ] || [ $TARGET_TRIPLE == "riscv64-linux-ohos" ] || \ + [ $TARGET_TRIPLE == "mipsel-linux-ohos" ] || [ $TARGET_TRIPLE == "x86_64-linux-ohos" ]; then + make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../ SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ + TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile + else + for ARCH_CFLAG in "${CFLAGS_FOR_TARGET[@]}" + do + make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../ SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ + TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} ARCH_CFLAGS="${ARCH_CFLAG}" -f Makefile + done + fi +fi +make distclean -f Makefile diff --git a/llvm-build/env_prepare.sh b/llvm-build/env_prepare.sh new file mode 100755 index 0000000000000000000000000000000000000000..552fbdba47722853296a9102ac013d6c9d6b0d29 --- /dev/null +++ b/llvm-build/env_prepare.sh @@ -0,0 +1,113 @@ +case $(uname -s) in + Linux) + + host_platform=linux + ;; + Darwin) + host_platform=darwin + ;; + *) + echo "Unsupported host platform: $(uname -s)" + exit 1 +esac + +case $(uname -m) in + arm64) + + host_cpu=arm64 + ;; + *) + host_cpu=x86_64 +esac + +# sync code directory +code_dir=$(pwd) + +# downloaded files will be automatically unzipped under this path +bin_dir=${code_dir}/download_packages + +# download and initialize prebuild files +if [ ! -d "${bin_dir}" ];then + mkdir -p "${bin_dir}" +fi + + +function download_and_archive() { + archive_dir=$1 + download_source_url=$2 + bin_file=$(basename ${download_source_url}) + wget -t3 -T10 -O "${bin_dir}/${bin_file}" "${download_source_url}" + if [ ! -d "${code_dir}/${archive_dir}" ];then + mkdir -p "${code_dir}/${archive_dir}" + fi + if [ "X${bin_file:0-3}" = "Xzip" ];then + unzip -o "${bin_dir}/${bin_file}" -d "${code_dir}/${archive_dir}/" + elif [ "X${bin_file:0-6}" = "Xtar.gz" ];then + tar -xvzf "${bin_dir}/${bin_file}" -C "${code_dir}/${archive_dir}" + else + tar -xvf "${bin_dir}/${bin_file}" -C "${code_dir}/${archive_dir}" + fi +} + + +copy_config=""" +""" + +copy_config_linux_x86_64=""" +prebuilts/cmake,https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/${host_platform}/cmake-${host_platform}-x86-3.16.5.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://mirrors.huaweicloud.com/openharmony/compiler/clang/10.0.1-62608/${host_platform}/llvm.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +""" + + +copy_config_darwin_x86_64=""" +prebuilts/cmake,https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/${host_platform}/cmake-${host_platform}-x86-3.16.5.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/clang+llvm-12.0.0-x86_64-apple-darwin.tar.xz +""" + + +if [[ "${host_platform}" == "linux" ]]; then + if [[ "${host_cpu}" == "x86_64" ]]; then + copy_config+=${copy_config_linux_x86_64} + echo "add ubuntu here" + else + echo "unknwon host_cpu - ${host_cpu} for linux" + fi +elif [[ "${host_platform}" == "darwin" ]]; then + if [[ "${host_cpu}" == "x86_64" ]]; then + copy_config+=${copy_config_darwin_x86_64} + echo "add x86-64 mac here" + elif [[ "${host_cpu}" == "arm64" ]]; then + echo "add m1 config here" + else + echo "unknwon host_cpu - ${host_cpu} for darwin" + fi +else + echo "unknown ${host_platform}" +fi + + +for i in $(echo ${copy_config}) +do + unzip_dir=$(echo $i|awk -F ',' '{print $1}') + remote_url=$(echo $i|awk -F ',' '{print $2}') + download_and_archive "${unzip_dir}" "${remote_url}" +done + + +if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-62608" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" + mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-62608" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" + ln -snf 10.0.1 "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/current" +fi + + +if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" + mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" +fi + +if [ -d "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-12.0.0-x86_64-apple-darwin" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" + mv "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-12.0.0-x86_64-apple-darwin" "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" +fi diff --git a/llvm-build/mingw.py b/llvm-build/mingw.py new file mode 100755 index 0000000000000000000000000000000000000000..78e1f5e5b217de4b0171e6920741d536b44b3f1e --- /dev/null +++ b/llvm-build/mingw.py @@ -0,0 +1,226 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""donwload and build mingw64-7.0.0 sysroot""" + +import logging +import os +import shutil +import subprocess +import sys + + +class BuildConfig(): + + def __init__(self, clang_version): + self.THIS_DIR = os.path.realpath(os.path.dirname(__file__)) + self.OUT_DIR = os.environ.get('OUT_DIR', self.repo_root('out')) + self.CLANG_VERSION = clang_version + self.LLVM_TRIPLE = 'x86_64-windows-gnu' + + def repo_root(self, *args): + return os.path.realpath(os.path.join(self.THIS_DIR, '../../', *args)) + + def out_root(self, *args): + return os.path.realpath(os.path.join(self.OUT_DIR, *args)) + + def mingw64_dir(self): + return self.out_root('mingw', self.LLVM_TRIPLE) + + def llvm_path(self, *args): + return os.path.realpath(os.path.join(self.THIS_DIR, '../llvm-project', *args)) + + +class LlvmMingw(): + + def __init__(self, build_config): + self.build_config = build_config + + self.CMAKE_BIN_PATH = os.path.join(self.cmake_prebuilt_bin_dir(), 'cmake') + self.NINJA_BIN_PATH = os.path.join(self.cmake_prebuilt_bin_dir(), 'ninja') + + self.LLVM_ROOT = self.build_config.out_root('llvm-install') + self.LLVM_CONFIG = os.path.join(self.LLVM_ROOT, 'bin', 'llvm-config') + self.SYSROOT = self.build_config.mingw64_dir() + self.CRT_PATH = self.build_config.out_root('lib', 'mingw-clangrt-%s' % self.build_config.LLVM_TRIPLE) + self.CRT_INSTALL = self.build_config.out_root('llvm-install', 'lib', 'clang', self.build_config.CLANG_VERSION) + # prefix & env + self.prefix = build_config.mingw64_dir() + common_flags = "-target x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libc++ \ + -fuse-ld=lld -Qunused-arguments -g -O2 --sysroot=" + self.build_config.mingw64_dir() + self.env = { + "CC": "%s/bin/clang" % self.LLVM_ROOT, + "CXX": "%s/bin/clang++" % self.LLVM_ROOT, + "AR": "%s/bin/llvm-ar" % self.LLVM_ROOT, + "DLLTOOL": "%s/bin/llvm-dlltool" % self.LLVM_ROOT, + "LD": "%s/bin/ld.lld" % self.LLVM_ROOT, + "RANLIB": "%s/bin/llvm-ranlib" % self.LLVM_ROOT, + "STRIP": "%s/bin/llvm-strip" % self.LLVM_ROOT, + "LDFLAGS": common_flags, + "CFLAGS": common_flags, + "CXXFLAGS": common_flags, + } + + def cmake_prebuilt_bin_dir(self): + return self.build_config.repo_root('prebuilts/cmake', 'linux-x86', 'bin') + + def base_cmake_defines(self): + self.cmake_defines = {} + self.cmake_defines['CMAKE_BUILD_TYPE'] = 'Release' + self.cmake_defines['LLVM_ENABLE_ASSERTIONS'] = 'OFF' + self.cmake_defines['LLVM_ENABLE_TERMINFO'] = 'OFF' + self.cmake_defines['LLVM_ENABLE_THREADS'] = 'ON' + self.cmake_defines['LLVM_USE_NEWPM'] = 'ON' + self.cmake_defines['COMPILER_RT_BUILD_XRAY'] = 'OFF' + return self.cmake_defines + + @staticmethod + def check_create_path(path): + if not os.path.exists(path): + os.makedirs(path) + + @staticmethod + def check_call(cmd, *args, **kwargs): + subprocess.check_call(cmd, *args, **kwargs) + + @staticmethod + def update_cmake_sysroot_flags(defines, sysroot): + defines['CMAKE_SYSROOT'] = sysroot + defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + def compiler_rt_defines(self): + arch = 'x86_64' + cc = os.path.join(self.LLVM_ROOT, 'bin', 'clang') + cxx = os.path.join(self.LLVM_ROOT, 'bin', 'clang++') + self.crt_defines = {} + self.crt_defines['CMAKE_C_COMPILER'] = cc + self.crt_defines['CMAKE_CXX_COMPILER'] = cxx + self.crt_defines['LLVM_CONFIG_PATH'] = self.LLVM_CONFIG + clang_libcxx_lib = self.build_config.out_root('clang_mingw', 'clang-%s' % self.build_config.CLANG_VERSION, 'lib') + ldflags = [ + '-L%s' % clang_libcxx_lib, + '-fuse-ld=lld', + '-Wl,--gc-sections', + '-pie', + '--rtlib=compiler-rt', + '-stdlib=libc++', + '-v', + ] + self.crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + self.update_cmake_sysroot_flags(self.crt_defines, self.SYSROOT) + cflags = [ + '--target=%s' % self.build_config.LLVM_TRIPLE, + '-ffunction-sections', + '-fdata-sections', + ] + cflags.append('-funwind-tables') + cflags.append('-v') + self.crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + self.crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + self.crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + self.crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags) + self.crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = self.build_config.LLVM_TRIPLE + self.crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = self.build_config.LLVM_TRIPLE + self.crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'OFF' + self.crt_defines['CMAKE_INSTALL_PREFIX'] = self.CRT_INSTALL + self.crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + self.crt_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'TRUE' + self.crt_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + self.crt_defines['CMAKE_CROSSCOMPILING'] = 'True' + self.crt_defines['CMAKE_C_COMPILER_WORKS'] = '1' + self.crt_defines['CMAKE_CXX_COMPILER_WORKS'] = '1' + self.crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi' + self.crt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + self.crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + self.crt_defines['COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN'] = 'OFF' + #cmake config + self.crt_defines.update(self.base_cmake_defines()) + return self.crt_defines + + def build_compiler_rt(self): + crt_defines = self.compiler_rt_defines() + #environ + crt_env = dict(dict(os.environ)) + #compiler-rt path + crt_cmake_path = self.build_config.llvm_path('compiler-rt') + #cmake + self.invoke_cmake( + out_path=self.CRT_PATH, + defines=crt_defines, + env=crt_env, + cmake_path=crt_cmake_path) + + def invoke_cmake(self, out_path, defines, env, cmake_path, target=None, install=True): + flags = ['-G', 'Ninja'] + flags += ['-DCMAKE_PREFIX_PATH=%s' % self.cmake_prebuilt_bin_dir()] + + for key in defines: + newdef = ''.join(['-D', key, '=', defines[key]]) + flags += [newdef] + flags += [cmake_path] + + self.check_create_path(out_path) + + if target: + ninja_target = [target] + else: + ninja_target = [] + + self.check_call([self.CMAKE_BIN_PATH] + flags, cwd=out_path, env=env) + self.check_call([self.NINJA_BIN_PATH] + ninja_target, cwd=out_path, env=env) + if install: + self.check_call([self.NINJA_BIN_PATH, 'install'], cwd=out_path, env=env) + + def build_mingw64_headers(self): + headers_dir = self.build_config.repo_root('third_party', 'mingw-w64', 'mingw-w64-headers', 'build') + if os.path.isdir(headers_dir): + shutil.rmtree(headers_dir) + os.makedirs(headers_dir) + os.chdir(headers_dir) + cmd = ['../configure', '--prefix=%s' % self.prefix, + '--enable-idl', '--with-default-win32-winnt=0x600', + '--with-default-msvcrt=ucrt'] + self.env['INSTALL'] = "install -C" + self.check_call(cmd, env=self.env) + self.check_call(['make', 'install'], env=self.env) + + def build_mingw64_crtlibs(self): + crtlibs_dir = self.build_config.repo_root('third_party', 'mingw-w64', 'mingw-w64-crt', 'build') + if os.path.isdir(crtlibs_dir): + shutil.rmtree(crtlibs_dir) + os.makedirs(crtlibs_dir) + os.chdir(crtlibs_dir) + cmd = ['../configure', '--prefix=%s' % self.prefix, + '--host=x86_64-w64-mingw32', '--disable-lib32', + '--enable-lib64', '--with-default-msvcrt=ucrt'] + self.check_call(cmd, env=self.env) + self.check_call(['make', '-j4'], env=self.env) + self.check_call(['make', 'install'], env=self.env) + + +def main(clang_version): + build_config = BuildConfig(clang_version) + llvm_mingw = LlvmMingw(build_config) + + llvm_mingw.build_mingw64_headers() + llvm_mingw.build_mingw64_crtlibs() + llvm_mingw.build_compiler_rt() + return 0 + +if __name__ == '__main__': + main() diff --git a/llvm-build/toolchain_readme.md b/llvm-build/toolchain_readme.md new file mode 100644 index 0000000000000000000000000000000000000000..eb042745aa1111f0037f519bc1f0403d8148a68f --- /dev/null +++ b/llvm-build/toolchain_readme.md @@ -0,0 +1,26 @@ +## Overview + +This readme briefly describes the functionality of our LLVM toolchain and what we have included specially to the LLVM toolchain. + +## Functionality + +The LLVM toolchain is built based on LLVM 12.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 12.0.1, please refer to [LLVM 12.0.1](https://lists.llvm.org/pipermail/llvm-announce/2021-July/000093.html). +
+ + +## Specifically Included Triplets + +Despite all the components provided by LLVM community, we included several triplets for different types of ohos devices to our LLVM toochain, listed as below. For specification, liteos is a newly included OS name which indicate the simplified linux kernel. + +| Triplet Name | Architecture | System Kernel | System | +| ---------------------- | ------------ | ------------- | --------------- | +| arm-liteos-ohos | ARM 32bits | LiteOS | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Standard system | +| aarch64-linux-ohos | ARM 64bits | Linux | Standard system | + +For detailed definition of Small System and Standard System, please refer to [System Types](https://gitee.com/openharmony/docs/blob/master/en/device-dev/Readme-EN.md). + +### Specify the triplet + +To build images for different types of platform, you can configure the triplet in the build scripts by setting "--target=xxx" using cflags, xxx should be replaced with a specific triplet name. diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index ba4584dc60faf1b9a170493bbe3075c08d5ff2a8..b2b79adc1f811e2604e89097103b2e595433c0c4 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -190,7 +190,7 @@ public: IOS, KFreeBSD, Linux, - Lv2, // PS3 + Lv2, // PS3 MacOSX, NetBSD, OpenBSD, @@ -219,6 +219,7 @@ public: WASI, // Experimental WebAssembly OS Emscripten, ShaderModel, // DirectX ShaderModel + LiteOS, LastOSType = ShaderModel }; enum EnvironmentType { @@ -263,8 +264,8 @@ public: Callable, Mesh, Amplification, - - LastEnvironmentType = Amplification + OpenHOS, + LastEnvironmentType = OpenHOS }; enum ObjectFormatType { UnknownObjectFormat, @@ -717,9 +718,19 @@ public: return getEnvironment() == Triple::Musl || getEnvironment() == Triple::MuslEABI || getEnvironment() == Triple::MuslEABIHF || - getEnvironment() == Triple::MuslX32; + getEnvironment() == Triple::MuslX32 || + getEnvironment() == Triple::OpenHOS || + isOSLiteOS(); } + /// Tests whether the target is OHOS + /// LiteOS default enviroment is also OHOS, but omited on triple. + bool isOHOSFamily() const { return isOpenHOS() || isOSLiteOS(); } + + bool isOpenHOS() const { return getEnvironment() == Triple::OpenHOS; } + + bool isOSLiteOS() const { return getOS() == Triple::LiteOS; } + /// Tests whether the target is DXIL. bool isDXIL() const { return getArch() == Triple::dxil; @@ -766,6 +777,7 @@ public: getEnvironment() == Triple::MuslEABI || getEnvironment() == Triple::EABIHF || getEnvironment() == Triple::GNUEABIHF || + getEnvironment() == Triple::OpenHOS || getEnvironment() == Triple::MuslEABIHF || isAndroid()) && isOSBinFormatELF(); } diff --git a/llvm/include/llvm/BinaryFormat/MinidumpConstants.def b/llvm/include/llvm/BinaryFormat/MinidumpConstants.def index 543305feea77383cd7bc0a59fe835a631dc13062..c03a4f8fd9eaf83546e78996d9461d389988d321 100644 --- a/llvm/include/llvm/BinaryFormat/MinidumpConstants.def +++ b/llvm/include/llvm/BinaryFormat/MinidumpConstants.def @@ -115,6 +115,7 @@ HANDLE_MDMP_PLATFORM(0x8202, Solaris) // Solaris HANDLE_MDMP_PLATFORM(0x8203, Android) // Android HANDLE_MDMP_PLATFORM(0x8204, PS3) // PS3 HANDLE_MDMP_PLATFORM(0x8205, NaCl) // Native Client (NaCl) +HANDLE_MDMP_PLATFORM(0x8207, OpenHOS) HANDLE_MDMP_PROTECT(0x01, NoAccess, PAGE_NO_ACCESS) HANDLE_MDMP_PROTECT(0x02, ReadOnly, PAGE_READ_ONLY) diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index b2ed8e60bd779841f9469e5744b94cc9dddc517a..d4a22159104efc6c0691977cd48410b7acaddbbc 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -55,6 +55,7 @@ struct Config { CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; CodeGenFileType CGFileType = CGFT_ObjectFile; unsigned OptLevel = 2; + bool DisableVerify = false; /// Use the standard optimization pipeline. diff --git a/llvm/lib/Support/AArch64TargetParser.cpp b/llvm/lib/Support/AArch64TargetParser.cpp index e2579bf5326075d252def9d16a544588d778bf80..d0e879840e43ffb538dc16e69e6c6eb1102423df 100644 --- a/llvm/lib/Support/AArch64TargetParser.cpp +++ b/llvm/lib/Support/AArch64TargetParser.cpp @@ -171,7 +171,7 @@ void AArch64::fillValidCPUArchList(SmallVectorImpl &Values) { bool AArch64::isX18ReservedByDefault(const Triple &TT) { return TT.isAndroid() || TT.isOSDarwin() || TT.isOSFuchsia() || - TT.isOSWindows(); + TT.isOSWindows() || TT.isOHOSFamily(); } // Allows partial match, ex. "v8a" matches "armv8a". diff --git a/llvm/lib/Support/ARMTargetParser.cpp b/llvm/lib/Support/ARMTargetParser.cpp index d7294b5b107445deb96ee07e3e2e195b3eb96bc6..8e8375e735f06e27976670ff331e7549363aa016 100644 --- a/llvm/lib/Support/ARMTargetParser.cpp +++ b/llvm/lib/Support/ARMTargetParser.cpp @@ -633,7 +633,7 @@ StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) { default: if (TT.isOSNetBSD()) return "apcs-gnu"; - if (TT.isOSOpenBSD()) + if (TT.isOSOpenBSD() || TT.isOHOSFamily()) return "aapcs-linux"; return "aapcs"; } diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp index 6696d158b2c1ae3d31f0819880ec0814f74a3a16..d163bcff0d3fced5e041cc596907fbd68c7748a4 100644 --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -240,6 +240,7 @@ StringRef Triple::getOSTypeName(OSType Kind) { case Win32: return "windows"; case ZOS: return "zos"; case ShaderModel: return "shadermodel"; + case LiteOS: return "liteos"; } llvm_unreachable("Invalid OSType"); @@ -284,6 +285,7 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { case Callable: return "callable"; case Mesh: return "mesh"; case Amplification: return "amplification"; + case OpenHOS: return "ohos"; } llvm_unreachable("Invalid EnvironmentType!"); @@ -587,6 +589,7 @@ static Triple::OSType parseOS(StringRef OSName) { .StartsWith("wasi", Triple::WASI) .StartsWith("emscripten", Triple::Emscripten) .StartsWith("shadermodel", Triple::ShaderModel) + .StartsWith("liteos", Triple::LiteOS) .Default(Triple::UnknownOS); } @@ -628,6 +631,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("callable", Triple::Callable) .StartsWith("mesh", Triple::Mesh) .StartsWith("amplification", Triple::Amplification) + .StartsWith("ohos", Triple::OpenHOS) .Default(Triple::UnknownEnvironment); } diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp index 4ad93f7b0b68201f25db54bbbea58a6539934f71..e0c10cf5db15db4a1cf042c74d982f51cc081c21 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp @@ -552,8 +552,8 @@ static const char *getRegisterName(unsigned RegNum) { {0x2e09, "COMPUTE_NUM_THREAD_Z"}, {0xa2db, "VGT_TF_PARAM"}, {0xa2d6, "VGT_LS_HS_CONFIG"}, - {0xa287, "VGT_HOS_MIN_TESS_LEVEL"}, - {0xa286, "VGT_HOS_MAX_TESS_LEVEL"}, + {0xa287, "VGT_OHOS_MIN_TESS_LEVEL"}, + {0xa286, "VGT_OHOS_MAX_TESS_LEVEL"}, {0xa2f8, "PA_SC_AA_CONFIG"}, {0xa310, "PA_SC_SHADER_CONTROL"}, {0xa313, "PA_SC_CONSERVATIVE_RASTERIZATION_CNTL"}, diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index 460ec62d5a33ee35531ea13bd03967f0163c0346..f046b198afb73eca97b44a4ab6d9e0cb56527cf7 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -393,8 +393,9 @@ public: } bool isTargetMuslAEABI() const { return (TargetTriple.getEnvironment() == Triple::MuslEABI || - TargetTriple.getEnvironment() == Triple::MuslEABIHF) && - !isTargetDarwin() && !isTargetWindows(); + TargetTriple.getEnvironment() == Triple::MuslEABIHF || + TargetTriple.getEnvironment() == Triple::OpenHOS) && + !isTargetDarwin() && !isTargetWindows(); } // ARM Targets that support EHABI exception handling standard diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index d95c21d6504b746baa6a54b984e617679625778e..88b89e560597b87d0204bda8c4674cc6c6d36e9e 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -240,7 +240,8 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT, if ((TargetTriple.getEnvironment() == Triple::GNUEABI || TargetTriple.getEnvironment() == Triple::GNUEABIHF || TargetTriple.getEnvironment() == Triple::MuslEABI || - TargetTriple.getEnvironment() == Triple::MuslEABIHF) && + TargetTriple.getEnvironment() == Triple::MuslEABIHF || + TargetTriple.getEnvironment() == Triple::OpenHOS) && !(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin())) this->Options.EABIVersion = EABI::GNU; else diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index d0ca325e9c140e1d62136ccc6b969a72aba8a61f..80dbe18a526bce986afd6b0da2dd90d7770bc9b4 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3856,6 +3856,8 @@ SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op, SDLoc DL(Op); GlobalAddressSDNode *N = cast(Op); assert(N->getOffset() == 0 && "unexpected offset in global node"); + if (DAG.getTarget().useEmulatedTLS()) + return LowerToTLSEmulatedModel(N, DAG); TLSModel::Model Model = getTargetMachine().getTLSModel(N->getGlobal()); diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 5fd4e45d80fb00908ebd9589419503cac33d4426..cb83d698001edb74db93d08c88edd1557bed79ba 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1911,7 +1911,7 @@ public: "vector.memcheck"); auto DiffChecks = RtPtrChecking.getDiffChecks(); - if (DiffChecks) { + if (L->getParentLoop() == nullptr && DiffChecks) { Value *RuntimeVF = nullptr; MemRuntimeCheckCond = addDiffRuntimeChecks( MemCheckBlock->getTerminator(), L, *DiffChecks, MemCheckExp, diff --git a/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll b/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll index 89fc6457482f08450b6cd70708840a083199f6c7..0ea2e20cfa522f5d3a9af8c4c5f40e57ae835351 100644 --- a/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll +++ b/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll @@ -2,6 +2,7 @@ ; RUN: llc -mtriple=arm64-freebsd-gnu -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=arm64-linux-gnu -o - %s | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-android -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 +; RUN: llc -mtriple=aarch64-linux-ohos -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=aarch64-fuchsia -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=aarch64-windows -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 diff --git a/llvm/test/CodeGen/RISCV/emutls.ll b/llvm/test/CodeGen/RISCV/emutls.ll new file mode 100644 index 0000000000000000000000000000000000000000..441bb9897ce196f7e8aaf3c9898b3166da449637 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/emutls.ll @@ -0,0 +1,307 @@ +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-gnu | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-ohos | FileCheck -check-prefix=RISCV64 %s + +; RUN: llc < %s -mtriple=riscv64-linux-gnu | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=riscv64-linux-ohos | FileCheck -check-prefix=RISCV64 %s + +; Copied from X86/emutls.ll + +; NoEMU-NOT: __emutls + +; Use my_emutls_get_address like __emutls_get_address. +@my_emutls_v_xyz = external global i8*, align 4 +declare i8* @my_emutls_get_address(i8*) + +define dso_local i32 @my_get_xyz() { +; RISCV64-LABEL: my_get_xyz: +; RISCV64: lui a0, %hi(my_emutls_v_xyz) +; RISCV64-NEXT: addi a0, a0, %lo(my_emutls_v_xyz) +; RISCV64-NEXT: call my_emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) + %0 = bitcast i8* %call to i32* + %1 = load i32, i32* %0, align 4 + ret i32 %1 +} + +@i1 = dso_local thread_local global i32 15 +@i2 = external thread_local global i32 +@i3 = internal thread_local global i32 15 +@i4 = hidden thread_local global i32 15 +@i5 = external hidden thread_local global i32 +@s1 = dso_local thread_local global i16 15 +@b1 = dso_local thread_local global i8 0 + +define dso_local i32 @f1() { +; RISCV64-LABEL: f1: +; RISCV64: lui a0, %hi(__emutls_v.i1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i1 + ret i32 %tmp1 +} + +define dso_local i32* @f2() { +; RISCV64-LABEL: f2: +; RISCV64: lui a0, %hi(__emutls_v.i1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i1 +} + +define dso_local i32 @f3() nounwind { +; RISCV64-LABEL: f3: +; RISCV64: lui a0, %hi(__emutls_v.i2) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i2) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i2 + ret i32 %tmp1 +} + +define dso_local i32* @f4() { +; RISCV64-LABEL: f4: +; RISCV64: lui a0, %hi(__emutls_v.i2) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i2) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i2 +} + +define dso_local i32 @f5() nounwind { +; RISCV64-LABEL: f5: +; RISCV64: lui a0, %hi(__emutls_v.i3) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i3) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i3 + ret i32 %tmp1 +} + +define dso_local i32* @f6() { +; RISCV64-LABEL: f6: +; RISCV64: lui a0, %hi(__emutls_v.i3) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i3) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i3 +} + +define dso_local i32 @f7() { +; RISCV64-LABEL: f7: +; RISCV64: lui a0, %hi(__emutls_v.i4) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i4) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i4 + ret i32 %tmp1 +} + +define dso_local i32* @f8() { +; RISCV64-LABEL: f8: +; RISCV64: lui a0, %hi(__emutls_v.i4) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i4) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i4 +} + +define dso_local i32 @f9() { +; RISCV64-LABEL: f9: +; RISCV64: lui a0, %hi(__emutls_v.i5) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i5) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i5 + ret i32 %tmp1 +} + +define dso_local i32* @f10() { +; RISCV64-LABEL: f10: +; RISCV64: lui a0, %hi(__emutls_v.i5) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i5) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i5 +} + +define dso_local i16 @f11() { +; RISCV64-LABEL: f11: +; RISCV64: lui a0, %hi(__emutls_v.s1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.s1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lh a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i16, i16* @s1 + ret i16 %tmp1 +} + +define dso_local i32 @f12sext() { +; RISCV64-LABEL: f12sext: +; RISCV64: lui a0, %hi(__emutls_v.s1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.s1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lh a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i16, i16* @s1 + %tmp2 = sext i16 %tmp1 to i32 + ret i32 %tmp2 +} + +define dso_local i32 @f12zext() { +; RISCV64-LABEL: f12zext: +; RISCV64: lui a0, %hi(__emutls_v.s1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.s1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lhu a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i16, i16* @s1 + %tmp2 = zext i16 %tmp1 to i32 + ret i32 %tmp2 +} + +define dso_local i8 @f13() { +; RISCV64-LABEL: f13: +; RISCV64: lui a0, %hi(__emutls_v.b1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.b1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lb a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i8, i8* @b1 + ret i8 %tmp1 +} + +define dso_local i32 @f14sext() { +; RISCV64-LABEL: f14sext: +; RISCV64: lui a0, %hi(__emutls_v.b1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.b1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lb a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i8, i8* @b1 + %tmp2 = sext i8 %tmp1 to i32 + ret i32 %tmp2 +} + +define dso_local i32 @f14zext() { +; RISCV64-LABEL: f14zext: +; RISCV64: lui a0, %hi(__emutls_v.b1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.b1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lbu a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i8, i8* @b1 + %tmp2 = zext i8 %tmp1 to i32 + ret i32 %tmp2 +} + +;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t. + +; RISCV64-LABEL: __emutls_v.i1: +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.i1 + +; RISCV64-LABEL: __emutls_t.i1: +; RISCV64-NEXT: .word 15 + +; RISCV64-NOT: __emutls_v.i2 + +; RISCV64-LABEL: __emutls_v.i3: +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.i3 + +; RISCV64-LABEL: __emutls_t.i3: +; RISCV64-NEXT: .word 15 + +; RISCV64-LABEL: __emutls_v.i4: +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.i4 + +; RISCV64-LABEL: __emutls_t.i4: +; RISCV64-NEXT: .word 15 + +; RISCV64-NOT: __emutls_v.i5: +; RISCV64: .hidden __emutls_v.i5 +; RISCV64-NOT: __emutls_v.i5: + +; RISCV64-LABEL: __emutls_v.s1: +; RISCV64-NEXT: .quad 2 +; RISCV64-NEXT: .quad 2 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.s1 + +; RISCV64-LABEL: __emutls_t.s1: +; RISCV64-NEXT: .half 15 + +; RISCV64-LABEL: __emutls_v.b1: +; RISCV64-NEXT: .quad 1 +; RISCV64-NEXT: .quad 1 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad 0 + +; RISCV64-NOT: __emutls_t.b1 diff --git a/llvm/test/CodeGen/RISCV/emutls_generic.ll b/llvm/test/CodeGen/RISCV/emutls_generic.ll new file mode 100644 index 0000000000000000000000000000000000000000..9f2345d8e673fb69f7bd11b6f3821f153196db49 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/emutls_generic.ll @@ -0,0 +1,75 @@ +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-gnu -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-ohos -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-ohos -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s + +; RUN: llc < %s -mtriple=riscv64-linux-gnu -O3 \ +; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=riscv64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -mtriple=riscv64-linux-ohos -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -mtriple=riscv64-linux-ohos -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s + +; NoEMU-NOT: __emutls + +; Make sure that TLS symbols are emitted in expected order. + +@external_x = external thread_local global i32, align 8 +@external_y = thread_local global i8 7, align 2 +@internal_y = internal thread_local global i64 9, align 16 + +define i32* @get_external_x() { +entry: + ret i32* @external_x +} + +define i8* @get_external_y() { +entry: + ret i8* @external_y +} + +define i64* @get_internal_y() { +entry: + ret i64* @internal_y +} + +; RISCV64-LABEL: get_external_x: +; RISCV64: __emutls_v.external_x +; RISCV64: __emutls_get_address +; RISCV64-LABEL: get_external_y: +; RISCV64: __emutls_v.external_y +; RISCV64: __emutls_get_address +; RISCV64-LABEL: get_internal_y: +; RISCV64: __emutls_v.internal_y +; RISCV64: __emutls_get_address +; RISCV64-NOT: __emutls_t.external_x +; RISCV64-NOT: __emutls_v.external_x: +; RISCV64: .data{{$}} +; RISCV64: .globl __emutls_v.external_y +; RISCV64: .p2align 3 +; RISCV64-LABEL: __emutls_v.external_y: +; RISCV64-NEXT: .quad 1 +; RISCV64-NEXT: .quad 2 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.external_y +; RISCV64-NOT: __emutls_v.external_x: +; RISCV64: .section .r{{o?}}data, +; RISCV64-LABEL: __emutls_t.external_y: +; RISCV64-NEXT: .byte 7 +; RISCV64: .data{{$}} +; RISCV64-NOT: .globl __emutls_v +; RISCV64: .p2align 3 +; RISCV64-LABEL: __emutls_v.internal_y: +; RISCV64-NEXT: .quad 8 +; RISCV64-NEXT: .quad 16 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.internal_y +; RISCV64: .section .r{{o?}}data, +; RISCV64-LABEL: __emutls_t.internal_y: +; RISCV64-NEXT: .quad 9 diff --git a/llvm/test/Transforms/LoopVectorize/nested-loop.ll b/llvm/test/Transforms/LoopVectorize/nested-loop.ll new file mode 100644 index 0000000000000000000000000000000000000000..d00eef9d2daea66a1d8b2aeae41565d120ba2af7 --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/nested-loop.ll @@ -0,0 +1,74 @@ +; RUN: opt -loop-vectorize -S %s -o - | FileCheck %s +; CHECK: vector.memcheck: +; CHECK-NEXT: %bound0 = icmp ult ptr +; CHECK-NEXT: %bound1 = icmp ult ptr +; CHECK-NEXT: %found.conflict = and i1 %bound0, %bound1 + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +; Function Attrs: nofree nounwind uwtable +define dso_local void @array_magick(ptr nocapture noundef %a, ptr nocapture noundef readonly %b, i32 noundef %len) local_unnamed_addr #0 { +entry: + %cmp24 = icmp sgt i32 %len, 0 + br i1 %cmp24, label %for.cond1.preheader.us.preheader, label %for.end12 + +for.cond1.preheader.us.preheader: ; preds = %entry + %wide.trip.count30 = zext i32 %len to i64 + br label %for.cond1.preheader.us + +for.cond1.preheader.us: ; preds = %for.cond1.preheader.us.preheader, %for.cond1.for.end_crit_edge.us + %indvars.iv27 = phi i64 [ 0, %for.cond1.preheader.us.preheader ], [ %indvars.iv.next28, %for.cond1.for.end_crit_edge.us ] + %arrayidx.us = getelementptr inbounds i32, ptr %a, i64 %indvars.iv27 + %.pre = load i32, ptr %arrayidx.us, align 4, !tbaa !5 + br label %for.body3.us + +for.body3.us: ; preds = %for.cond1.preheader.us, %for.body3.us + %0 = phi i32 [ %.pre, %for.cond1.preheader.us ], [ %sub.us, %for.body3.us ] + %indvars.iv = phi i64 [ 0, %for.cond1.preheader.us ], [ %indvars.iv.next, %for.body3.us ] + %arrayidx5.us = getelementptr inbounds i32, ptr %b, i64 %indvars.iv + %1 = load i32, ptr %arrayidx5.us, align 4, !tbaa !5 + %sub.us = sub i32 %0, %1 + store i32 %sub.us, ptr %arrayidx.us, align 4, !tbaa !5 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count30 + br i1 %exitcond.not, label %for.cond1.for.end_crit_edge.us, label %for.body3.us, !llvm.loop !9 + +for.cond1.for.end_crit_edge.us: ; preds = %for.body3.us + %sub.us.lcssa = phi i32 [ %sub.us, %for.body3.us ] + %call.us = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str, i32 noundef %sub.us.lcssa) + %indvars.iv.next28 = add nuw nsw i64 %indvars.iv27, 1 + %exitcond31.not = icmp eq i64 %indvars.iv.next28, %wide.trip.count30 + br i1 %exitcond31.not, label %for.end12.loopexit, label %for.cond1.preheader.us, !llvm.loop !12 + +for.end12.loopexit: ; preds = %for.cond1.for.end_crit_edge.us + br label %for.end12 + +for.end12: ; preds = %for.end12.loopexit, %entry + ret void +} + +; Function Attrs: nofree nounwind +declare noundef i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1 + +attributes #0 = { nofree nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nounwind "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } + +!llvm.module.flags = !{!0, !1, !2, !3} +!llvm.ident = !{!4} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{!"clang version 16.0.0 (https://github.com/llvm/llvm-project.git 09f608fda51ca9dd2d88c2985bad1cfc1e36251e)"} +!5 = !{!6, !6, i64 0} +!6 = !{!"int", !7, i64 0} +!7 = !{!"omnipotent char", !8, i64 0} +!8 = !{!"Simple C/C++ TBAA"} +!9 = distinct !{!9, !10, !11} +!10 = !{!"llvm.loop.mustprogress"} +!11 = !{!"llvm.loop.unroll.disable"} +!12 = distinct !{!12, !10, !11} diff --git a/llvm/test/Transforms/SafeStack/AArch64/abi.ll b/llvm/test/Transforms/SafeStack/AArch64/abi.ll index bd6710d160c55cd12526134e762bdf3f7f84ba08..45961b767180320ae7754ee0b822db98b3adabf1 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/abi.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/abi.ll @@ -1,8 +1,10 @@ ; RUN: opt -safe-stack -S -mtriple=aarch64-linux-android < %s -o - | FileCheck %s +; RUN: opt -safe-stack -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck %s --check-prefix=OHOS define void @foo() nounwind uwtable safestack { entry: +; OHOS-NOT: call i8* @llvm.thread.pointer() ; CHECK: %[[TP:.*]] = call i8* @llvm.thread.pointer() ; CHECK: %[[SPA0:.*]] = getelementptr i8, i8* %[[TP]], i32 72 ; CHECK: %[[SPA:.*]] = bitcast i8* %[[SPA0]] to i8** diff --git a/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll b/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll index c78b20aaa01abce5a32efcf5da2ae605cb1e6e26..9069ea50a4d58ac50cb04a66f66ec8056940c72f 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll @@ -1,4 +1,5 @@ ; RUN: opt -safe-stack -S -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefixes=TLS,ANDROID %s +; RUN: opt -safe-stack -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck --check-prefix=OHOS %s ; RUN: opt -safe-stack -S -mtriple=aarch64-unknown-fuchsia < %s -o - | FileCheck --check-prefixes=TLS,FUCHSIA %s define void @foo() nounwind uwtable safestack sspreq { @@ -6,6 +7,7 @@ entry: ; The first @llvm.thread.pointer is for the unsafe stack pointer, skip it. ; TLS: call i8* @llvm.thread.pointer() +; OHOS-NOT: call i8* @llvm.thread.pointer() ; TLS: %[[TP2:.*]] = call i8* @llvm.thread.pointer() ; ANDROID: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 40 ; FUCHSIA: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 -16 diff --git a/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll b/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll index 53ed690ebb09b5c69d1eff2b0433910ae750798d..7009fce7a4a43faf1633c2d84412112fe1c516a8 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll @@ -1,7 +1,9 @@ ; RUN: opt -safe-stack -safe-stack-coloring -S -mtriple=aarch64-linux-android < %s -o - | FileCheck %s +; RUN: opt -safe-stack -safe-stack-coloring -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck %s --check-prefix=OHOSMUSL define void @foo() nounwind uwtable safestack { entry: +; OHOSMUSL-NOT: call i8* @llvm.thread.pointer() ; CHECK: %[[TP:.*]] = call i8* @llvm.thread.pointer() ; CHECK: %[[SPA0:.*]] = getelementptr i8, i8* %[[TP]], i32 72 ; CHECK: %[[SPA:.*]] = bitcast i8* %[[SPA0]] to i8** diff --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py index 7dae83733f31e7e6cec76bdd426a605ad5141b09..5ef907a6de29f7892509c21dccbc08fdc092f7f2 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -12,7 +12,7 @@ from lit.llvm.subst import ToolSubst lit_path_displayed = False -class LLVMConfig(object): +class LLVMConfig (object): def __init__(self, lit_config, config): self.lit_config = lit_config @@ -78,6 +78,8 @@ class LLVMConfig(object): features.add('system-windows') elif platform.system() == 'Linux': features.add('system-linux') + if os.path.exists('/.dockerenv'): + features.add('ohos-ci') elif platform.system() in ['FreeBSD']: features.add('system-freebsd') elif platform.system() == 'NetBSD': diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h index 357cffc13c8096f554f349ebdf4580f7cfc55c6d..57b93b074153573d4f6aacb760097101ce256df7 100644 --- a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h @@ -88,6 +88,9 @@ # if defined __ANDROID__ # define GTEST_OS_LINUX_ANDROID 1 # endif +# if defined __OHOS_FAMILY__ +# define GTEST_OS_LINUX_OHOS_FAMILY 1 +# endif #elif defined __MVS__ # define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) diff --git a/llvm/utils/unittest/googletest/src/gtest-death-test.cc b/llvm/utils/unittest/googletest/src/gtest-death-test.cc index 5d1031bea257099d894b2a48a44a998e13500709..bdb4b6585624f7466420a59f1f72c279ff1c5935 100644 --- a/llvm/utils/unittest/googletest/src/gtest-death-test.cc +++ b/llvm/utils/unittest/googletest/src/gtest-death-test.cc @@ -1364,7 +1364,9 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { if (!use_fork) { static const bool stack_grows_down = StackGrowsDown(); - const auto stack_size = static_cast(getpagesize() * 2); + // HUAWEI: increase stack size for child process or we won't see + // error message in case death test fails. + const auto stack_size = static_cast(getpagesize() * 4); // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); diff --git a/llvm/utils/unittest/googletest/src/gtest-port.cc b/llvm/utils/unittest/googletest/src/gtest-port.cc index fc5ba6becc55fd2cd6bb178454a7edc56998b1ab..a79dd856272a2993424edbed244e7a44bdd76637 100644 --- a/llvm/utils/unittest/googletest/src/gtest-port.cc +++ b/llvm/utils/unittest/googletest/src/gtest-port.cc @@ -1093,7 +1093,7 @@ class CapturedStream { // directory, so we create the temporary file in the /tmp directory // instead. We use /tmp on most systems, and /sdcard on Android. // That's because Android doesn't have /tmp. -# if GTEST_OS_LINUX_ANDROID +#if GTEST_OS_LINUX_ANDROID || GTEST_OS_LINUX_OHOS_FAMILY // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h index 6aeb495d44f24a456084b281dc04ef43f09698f2..07b2a9a3ff726f4b114356f0e1106e205afc9959 100644 --- a/openmp/runtime/src/kmp.h +++ b/openmp/runtime/src/kmp.h @@ -54,9 +54,8 @@ #define KMP_CANCEL_THREADS #define KMP_THREAD_ATTR -// Android does not have pthread_cancel. Undefine KMP_CANCEL_THREADS if being // built on Android -#if defined(__ANDROID__) +#if defined(__ANDROID__) || defined(__OHOS__) #undef KMP_CANCEL_THREADS #endif diff --git a/openmp/runtime/src/kmp_i18n.cpp b/openmp/runtime/src/kmp_i18n.cpp index a164aa180dd48b6751d7d9bbd5b7c03cf0d93d02..2474810ce6bf23e74ba418b9fd023c07ad00b0ed 100644 --- a/openmp/runtime/src/kmp_i18n.cpp +++ b/openmp/runtime/src/kmp_i18n.cpp @@ -710,7 +710,8 @@ static char *sys_error(int err) { #if (defined(__GLIBC__) && defined(_GNU_SOURCE)) || \ (defined(__BIONIC__) && defined(_GNU_SOURCE) && \ - __ANDROID_API__ >= __ANDROID_API_M__) + __ANDROID_API__ >= __ANDROID_API_M__) || \ + (defined(__OHOS__) && defined(_GNU_SOURCE)) // GNU version of strerror_r. char buffer[2048]; diff --git a/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp b/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp index 430c2006a451e6831cda803d3f12026e8ce0102e..0a24809c20f3731ad9a10d72b704a9852277e230 100644 --- a/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp +++ b/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp @@ -1,5 +1,6 @@ // RUN: %libomp-cxx-compile-and-run // RUN: %libomp-cxx-compile && env OMP_NUM_THREADS=1 %libomp-run +// UNSUPPORTED: ohos-ci /* * This test aims to check whether hidden helper task can work with regular task diff --git a/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp b/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp index 881e27df723c70147a445facb33c8514bfa82f5c..5b38a913577342bc2e1ee15a7736218543395f3d 100644 --- a/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp +++ b/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp @@ -42,7 +42,9 @@ struct anon { }; } -kmp_int32 __kmp_hidden_helper_threads_num; +// OHOS specific: we use static libomp and get link error on this symbol +// probably push this to mainline +__attribute__((weak)) kmp_int32 __kmp_hidden_helper_threads_num; kmp_int32 omp_task_entry(kmp_int32 gtid, kmp_task_t_with_privates *task) { auto shareds = reinterpret_cast(task->task.shareds);