diff --git a/OAT.xml b/OAT.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fe34bbf4d4a419173f6d15376329f3de6b7f4580
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,224 @@
+
+
+
+
+
+ llvm/LICENSE.TXT|clang/LICENSE.TXT|libcxx/LICENSE.TXT|lldb/LICENSE.TXT|clang-tools-extra/LICENSE.TXT|llvm/utils/lit/LICENSE.TXT|llvm/tools/msbuild/license.txt|llvm/tools/msbuild/license.txt|clang-tools-extra/clang-tidy/cert/LICENSE.TXT|clang-tools-extra/clang-tidy/hicpp/LICENSE.TXT|libclc/LICENSE.TXT|llvm/include/llvm/Support/LICENSE.TXT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README.OpenSource b/README.OpenSource
new file mode 100644
index 0000000000000000000000000000000000000000..9993653867759e97cc97946ab5d0981285f92423
--- /dev/null
+++ b/README.OpenSource
@@ -0,0 +1,11 @@
+[
+ {
+ "Name": "LLVM",
+ "License": "Apache License v2.0 with LLVM Exceptions",
+ "License File": "./libunwind/LICENSE.TXT ./lld/LICENSE.TXT ./polly/tools/GPURuntime/LICENSE.TXT ./libcxxabi/LICENSE.TXT ./llvm/include/llvm/Support/LICENSE.TXT ./llvm/utils/unittest/googletest/LICENSE.TXT ./llvm/LICENSE.TXT ./compiler-rt/LICENSE.TXT ./clang-tools-extra/clang-tidy/cert/LICENSE.TXT ./clang-tools-extra/clang-tidy/hicpp/LICENSE.TXT ./clang-tools-extra/LICENSE.TXT ./lldb/LICENSE.TXT ./llgo/LICENSE.TXT ./libcxx/LICENSE.TXT ./clang/LICENSE.TXT ./libclc/LICENSE.TXT ./parallel-libs/acxxel/LICENSE.TXT",
+ "Version Number": "12.0.1",
+ "Owner": "sunqiang13@huawei.com",
+ "Upstream URL": "http://llvm.org/",
+ "Description": "The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Despite its name, LLVM has little to do with traditional virtual machines. The name \"LLVM\" itself is not an acronym; it is the full name of the project."
+ }
+]
diff --git a/README.md b/README.md
index 6e02ee378eb3585788de8ed3e7d404bd1e5a7dad..21370584c1c7939fec8ccd1da90a50e5ee79facd 100644
--- a/README.md
+++ b/README.md
@@ -108,3 +108,5 @@ Consult the
page for detailed information on configuring and compiling LLVM. You can visit
[Directory Layout](https://llvm.org/docs/GettingStarted.html#directory-layout)
to learn about the layout of the source code tree.
+
+For the llvm construction of openharmony, please refer to [llvm-build](https://gitee.com/openharmony-sig/third_party_llvm-project/tree/llvmorg-12.0.1-dev/llvm-build).
\ No newline at end of file
diff --git a/README_zh.md b/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..cbbdef3546a9df6fb0b72b8c4e0533583d861790
--- /dev/null
+++ b/README_zh.md
@@ -0,0 +1,73 @@
+# LLVM编译器基础架构
+
+此目录及其子目录包含LLVM的源代码,LLVM是一个用于构建高度优化的编译器、优化器和运行时环境的工具包。
+
+自述文件简要介绍了如何开始构建LLVM。有关如何为LLVM项目做出贡献的更多信息,请查看 [为LLVM做出贡献](https://llvm.org/docs/Contributing.html) 指南。
+
+## LLVM系统入门
+
+取自 [https://llvm.org/docs/GettingStarted.html](https://gitee.com/link?target=https%3A%2F%2Fllvm.org%2Fdocs%2FGettingStarted.html).
+
+### 概述
+
+欢迎来到LLVM项目!
+
+LLVM项目有多个组件。该项目的核心本身被称为“LLVM”。这包含处理中间表示并将其转换为对象文件所需的所有工具、库和头文件。工具包括汇编器、反汇编器、位码分析器和位码优化器。它还包含基本的回归测试。
+
+类C语言使用 [Clang](https://clang.llvm.org/) 前端。此组件将C、C++、目标-C和目标-C++代码编译为LLVM位码,并使用LLVM将其编译为目标文件。
+
+其他组件包括:[libc++ C++ 标准库](https://libcxx.llvm.org/),[LLD链接器](https://lld.llvm.org/) 等。
+
+### 获取源代码并构建LLVM
+
+LLVM入门文档可能已过期。[Clang入门](https://clang.llvm.org/get_started.html) 页面可能有更准确的信息。
+
+这是获取和构建LLVM源的示例工作流和配置:
+
+1. Checkout LLVM (包括Clang等相关子项目):
+
+ - `git clone https://github.com/llvm/llvm-project.git`
+ - 或 在 Windows上, `git clone --config core.autocrlf=false https://github.com/llvm/llvm-project.git`
+
+2. 配置和构建LLVM和Clang:
+
+ - `cd llvm-project`
+
+ - `mkdir build`
+
+ - `cd build`
+
+ - `cmake -G [options] ../llvm`
+
+ 一些常见的构建系统生成器有:
+
+ - `Ninja`---用于生成 [Ninja](https://ninja-build.org/) 构建文件。大多数llvm开发人员使用Ninja。
+ - `Unix Makefiles` --- 用于生成与make兼容的并行makefile。
+ - `Visual Studio` --- 用于生成Visual Studio项目和解决方案。
+ - `Xcode` --- 用于生成Xcode项目。
+
+ 一些常见选项:
+
+ - `-DLLVM_ENABLE_PROJECTS='...'` --- 要额外构建的LLVM子项目的分号分隔列表。可以包括:clang、clang-tools-extra、libcxx、libcxxabi、libunwind、lldb、编译器-rt、lld、波莉或调试信息测试中的任何一个。
+
+ 例如,要构建LLVM、Clang、libcxx和libcxxabi,请使用 `-DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"`.
+
+ - `-DCMAKE_INSTALL_PREFIX=directory` --- 为*目录* 指定要安装LLVM工具和库的完整路径名 (默认 `/usr/local`).
+
+ - `-DCMAKE_BUILD_TYPE=type` --- *类型* 的有效选项为 调试、发布、带调试信息发布 和最小尺寸发布。默认值为调试。
+
+ - `-DLLVM_ENABLE_ASSERTIONS=On` --- 在启用断言检查的情况下编译(调试编译的默认值为Yes,所有其他编译类型的默认值为No)。
+
+ - `cmake --build . [-- [options] ]` 或直接在上面指定的构建系统。
+
+ - 默认目标(即 `ninja` or `make`)将构建所有LLVM。
+ - `check-all`目标(即`ninja check-all`)将运行回归测试,以确保一切都正常工作。
+ - CMake将为每个工具和库生成目标,大多数LLVM子项目生成自己的`check-`目标。
+ - 运行串行构建将是 **缓慢** 。要提高速度,请尝试运行并行构建。在忍者中,默认情况下,这是在“make”中完成的;对于`make`,请使用选项`-j NNN`,其中`NNN`是并行作业的数量,例如您拥有的CPU数量。
+
+ - 有关详细信息,请参阅 [CMake](https://llvm.org/docs/CMake.html)
+
+请参阅 [LLVM入门](https://llvm.org/docs/GettingStarted.html#getting-started-with-llvm) 页面,了解有关配置和编译LLVM的详细信息。您可以访问 [目录布局](https://llvm.org/docs/GettingStarted.html#directory-layout) 以了解源代码树的布局。
+
+有关Openharmony的llvm构建请参考[llvm-build](https://gitee.com/openharmony-sig/third_party_llvm-project/tree/llvmorg-12.0.1-dev/llvm-build)。
+
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index bfd50f6a6779bf0ef1bad040506a7869c0d8c668..f62b547b72f5f7ebcd484b4a090cf2264df03552 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -840,6 +840,7 @@ def Availability : InheritableAttr {
.Case("tvos_app_extension", "tvOS (App Extension)")
.Case("watchos_app_extension", "watchOS (App Extension)")
.Case("swift", "Swift")
+ .Case("ohos", "OpenHOS")
.Default(llvm::StringRef());
}
static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 817798926650f0b368b14725011bc904f02df77b..9019ea8f72980b5af59f1c27789fd262383347ad 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2415,6 +2415,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 28c37a44e1eb8c86e8c654c2f760c376c700a010..9ead01d68335d38a6e79f014ac44faa2b428f8f4 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -441,7 +441,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 642ee753d22412e3a50df1f731da842d493dd4d4..d727d99914434692bf6d318c2d6d95cf766fc67f 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -68,7 +68,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
// alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See
// https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.
// This alignment guarantee also applies to Windows and Android.
- 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
NewAlign = 0; // Infer from basic type alignment.
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 90a67d03b7b2050fe8400cd4555668f13d089035..b0c3e9ce9c97942480bfa2d521ba83643c675090 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -143,7 +143,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:
@@ -183,7 +188,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:
@@ -546,6 +558,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 a2c96ad12a76d3ce837892b21b070a57766d27f0..cca55956b2f4c2e03c10af643093b809b8bb17bc 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -305,7 +305,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/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index 67fa1a537fea9415df7365fc5244054e56a2d2d6..295e68426752f2b973097988aaced1a5dae22011 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -947,6 +947,69 @@ public:
: WebAssemblyOSTargetInfo(Triple, Opts) {}
};
+// 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");
+
+ unsigned Maj, Min, Rev;
+ Triple.getEnvironmentVersion(Maj, Min, Rev);
+ this->PlatformName = "ohos";
+ this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
+ if (Maj) {
+ Builder.defineMacro("__OHOS_Major__", Twine(Maj));
+ Builder.defineMacro("__OHOS_Minor__", Twine(Min));
+ Builder.defineMacro("__OHOS_Micro__", Twine(Rev));
+ }
+ }
+
+ 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 91a365c7d405014afc4646dc2978eac8c5dfe613..2b8e9bbe16b3f5c3110b66054b320a1db75eb7fc 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -909,6 +909,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 56f0dd4322d2212e830795162c954058a8f8b3b3..035b6e5a293cae6f852406d8fae8a02de392d0a0 100644
--- a/clang/lib/CodeGen/ABIInfo.h
+++ b/clang/lib/CodeGen/ABIInfo.h
@@ -89,6 +89,7 @@ namespace swiftcall {
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/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 38e96c0f4ee678fd8c7f1bf50943d712f744ea83..82cdd95ac7e0991644d15bdbff6be19a3c6d7386 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -66,19 +66,20 @@ public:
// Note that we intentionally hide the CreateLoad APIs that don't
// take an alignment.
llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") {
- return CreateAlignedLoad(Addr.getPointer(),
+ return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
Addr.getAlignment().getAsAlign(), Name);
}
llvm::LoadInst *CreateLoad(Address Addr, const char *Name) {
// This overload is required to prevent string literals from
// ending up in the IsVolatile overload.
- return CreateAlignedLoad(Addr.getPointer(),
+ return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
Addr.getAlignment().getAsAlign(), Name);
}
llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile,
const llvm::Twine &Name = "") {
- return CreateAlignedLoad(
- Addr.getPointer(), Addr.getAlignment().getAsAlign(), IsVolatile, Name);
+ return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
+ Addr.getAlignment().getAsAlign(), IsVolatile,
+ Name);
}
using CGBuilderBaseTy::CreateAlignedLoad;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 10e3820d9657803975576cb3e921d1b72f271628..a62e1b0986e998e08cc51a6bd2e30b26f0cddcc9 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -14473,11 +14473,12 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
break;
}
+ llvm::Type *Ty = FixedVectorType::get(Builder.getInt64Ty(), 2);
Value *InOps[9];
InOps[0] = Ops[2];
for (int i = 0; i != 8; ++i) {
Value *Ptr = Builder.CreateConstGEP1_32(Ops[1], i);
- InOps[i + 1] = Builder.CreateAlignedLoad(Ptr, Align(16));
+ InOps[i + 1] = Builder.CreateAlignedLoad(Ty, Ptr, Align(16));
}
Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), InOps);
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index a4bd2c6d5da0dcae8076d67c808b325dd67ab6d6..641740c37a68a11d5f20546ba96ff6f60d061096 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -252,8 +252,8 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF,
"No kext in Microsoft ABI");
CodeGenModule &CGM = CGF.CGM;
llvm::Value *VTable = CGM.getCXXABI().getAddrOfVTable(RD, CharUnits());
- Ty = Ty->getPointerTo()->getPointerTo();
- VTable = CGF.Builder.CreateBitCast(VTable, Ty);
+ Ty = Ty->getPointerTo();
+ VTable = CGF.Builder.CreateBitCast(VTable, Ty->getPointerTo());
assert(VTable && "BuildVirtualCall = kext vtbl pointer is null");
uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
const VTableLayout &VTLayout = CGM.getItaniumVTableContext().getVTableLayout(RD);
@@ -264,7 +264,7 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF,
llvm::Value *VFuncPtr =
CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");
llvm::Value *VFunc = CGF.Builder.CreateAlignedLoad(
- VFuncPtr, llvm::Align(CGF.PointerAlignInBytes));
+ Ty, VFuncPtr, llvm::Align(CGF.PointerAlignInBytes));
CGCallee Callee(GD, VFunc);
return Callee;
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 95c0b7b4d7c09cca999a127eb245d28fa5735fdb..80b8818fda6011794389f4787226becef9ccdc17 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4775,7 +4775,8 @@ inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF,
// Otherwise, it should be an alloca instruction, as set up in save().
auto alloca = cast(value.getPointer());
- return CGF.Builder.CreateAlignedLoad(alloca, alloca->getAlign());
+ return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca,
+ alloca->getAlign());
}
} // end namespace CodeGen
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index bcd24292ff411db22af9f810b06d0fd5cb0b545f..4b916b729aeb6d873f1edfa5f04fad00daacd877 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -223,6 +223,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;
}
@@ -5607,7 +5611,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);
}
@@ -6158,7 +6162,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 aeffcf0bb43ae00476bebe27c751a20aaa6b9c97..7dca74742803f8f5ba087016223bc5271afd1814 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -63,6 +63,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 418e1d3e8ec993145fc140c76cca4295da06ba53..71e3df95cb1f77e7183c24311daa624bd317a369 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -37,6 +37,7 @@
#include "ToolChains/Myriad.h"
#include "ToolChains/NaCl.h"
#include "ToolChains/NetBSD.h"
+#include "ToolChains/OHOS.h"
#include "ToolChains/OpenBSD.h"
#include "ToolChains/PPCLinux.h"
#include "ToolChains/PS4CPU.h"
@@ -5118,7 +5119,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;
@@ -5176,6 +5178,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/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index b2ddef141a7591b15f1a96b992eb7a7713a696de..5dc8f6720b384b92e27231e7e98a8f04074b9a05 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -823,7 +823,13 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
Triple.setEnvironment(isHardFloat ? Triple::MuslEABIHF
: Triple::MuslEABI);
break;
+ case Triple::OpenHOS:
+ break;
default: {
+ if (Triple.isOSLiteOS()) {
+ Triple.setEnvironment(Triple::OpenHOS);
+ break;
+ }
arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple);
if (DefaultABI != arm::FloatABI::Invalid &&
isHardFloat != (DefaultABI == arm::FloatABI::Hard)) {
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index ef590db1eecd7bfe1a932be4a922892fb2dfe37b..a812bcb588735cc349b975aa36fcf578fb88c2c0 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -211,6 +211,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/BareMetal.h b/clang/lib/Driver/ToolChains/BareMetal.h
index a6d4922a380ff777f7aa7e7404d344a355e8402f..c29fe67a898b8470d60a9292abc33493eaca3310 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.h
+++ b/clang/lib/Driver/ToolChains/BareMetal.h
@@ -34,7 +34,7 @@ protected:
Tool *buildLinker() 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 override { return false; }
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1976b48e0f6a4aaab5c84358a99604d5c2b033ae..32397abf1b54051a2d2d9898f28d2f35cf53980c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1702,7 +1702,7 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
else
CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0");
- } else if (Triple.isAndroid()) {
+ } else if (Triple.isAndroid() || Triple.isOHOSFamily()) {
// Enabled A53 errata (835769) workaround by default on android
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
@@ -5627,6 +5627,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
options::OPT_fno_unroll_loops);
+ 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 bcaea71dca9436b566647d7caf9504e48fd37c0f..ce90569494c154f1bef28759d1cd80ecf432a443 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -753,7 +753,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");
@@ -1132,6 +1132,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()) {
@@ -1391,6 +1403,11 @@ static LibGccType getLibGccType(const Driver &D, const ArgList &Args) {
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() || TC.getTriple().isOSIAMCU() ||
TC.getTriple().isOSBinFormatWasm() ||
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 1d8a3cdce92a8a01596b1ac076429d82f4326c16..4106cd9cfa688d53e7b7b0bf2a35efe7f5a0cd7d 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -393,6 +393,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(Args, Triple);
if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")
CmdArgs.push_back("--fix-cortex-a53-843419");
@@ -456,8 +457,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// Android does not allow shared text relocations. Emit a warning if the
// user's code contains any.
- if (isAndroid)
- CmdArgs.push_back("--warn-shared-textrel");
+ if (isAndroid || isOHOSFamily)
+ CmdArgs.push_back("--warn-shared-textrel");
ToolChain.addExtraOpts(CmdArgs);
@@ -615,7 +616,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
- 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))
@@ -2074,8 +2076,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
// lifetime or initialization issues.
static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
static const char *const AArch64Triples[] = {
- "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux",
- "aarch64-suse-linux", "aarch64-linux-android"};
+ "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux",
+ "aarch64-suse-linux", "aarch64-linux-android", "aarch64-linux-ohos"};
static const char *const AArch64beLibDirs[] = {"/lib"};
static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu",
"aarch64_be-linux-gnu"};
diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0c243a1ef723877f4454bb14891e461eb5667d47
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/OHOS.cpp
@@ -0,0 +1,439 @@
+//===--- 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::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();
+ if (D.CCCIsCXX()) {
+ if (auto CXXStdlibPath = getCXXStdlibPath())
+ getFilePaths().push_back(*CXXStdlibPath);
+ }
+
+ std::string CandidateLibPath = getArchSpecificLibPath();
+ if (getVFS().exists(CandidateLibPath))
+ getFilePaths().push_back(CandidateLibPath);
+
+ getLibraryPaths().clear();
+ if (auto RuntimePath = getRuntimePath())
+ getLibraryPaths().push_back(*RuntimePath);
+
+ // 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
+ unsigned Major;
+ unsigned Minor;
+ unsigned Micro;
+ Triple.getEnvironmentVersion(Major, Minor, Micro);
+ 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);
+}
+
+std::string OHOS::ComputeEffectiveClangTriple(const ArgList &Args,
+ types::ID InputType) const {
+ // Don't modify this, it is impact of the toolchain and target init process.
+ return ComputeLLVMTriple(Args, InputType);
+}
+
+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 Path = makePath({getDriver().Dir, "..", "include",
+ "libcxx-ohos", "include", "c++", "v1"});
+ addSystemInclude(DriverArgs, CC1Args, Path);
+ 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;
+}
+
+Optional OHOS::getRuntimePath() const {
+ SmallString<128> P;
+ 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());
+ if (getVFS().exists(P))
+ return llvm::Optional(static_cast(P.str()));
+
+ // Second try the normalized triple.
+ P.assign(D.ResourceDir);
+ llvm::sys::path::append(P, "lib", Triple.str(), SelectedMultilib.gccSuffix());
+ if (getVFS().exists(P))
+ return llvm::Optional(static_cast(P.str()));
+
+ // Third try the effective triple.
+ P.assign(D.ResourceDir);
+ std::string SysRoot = computeSysRoot();
+ llvm::sys::path::append(P, "lib", getMultiarchTriple(Triple),
+ SelectedMultilib.gccSuffix());
+ if (getVFS().exists(P))
+ return llvm::Optional(static_cast(P.str()));
+
+ return None;
+}
+
+Optional OHOS::getCXXStdlibPath() const {
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ const std::string &MultiarchTriple = getMultiarchTriple(getTriple());
+
+ const std::string &P = makePath({D.Dir, "..", "lib", MultiarchTriple, "c++",
+ SelectedMultilib.gccSuffix()});
+ if (getVFS().exists(P))
+ return llvm::Optional(P);
+
+ return None;
+}
+
+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");
+ 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();
+}
\ No newline at end of file
diff --git a/clang/lib/Driver/ToolChains/OHOS.h b/clang/lib/Driver/ToolChains/OHOS.h
new file mode 100644
index 0000000000000000000000000000000000000000..002ee71f7b900efd3515454d56498e34b5e0b3e7
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/OHOS.h
@@ -0,0 +1,103 @@
+//===--- 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 override { return true; }
+ bool isPICDefaultForced() const override { return false; }
+ bool isNoExecStackDefault() const override { return true; }
+ bool useRelaxRelocations() const override { return false; }
+ UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override;
+ UnwindLibType GetDefaultUnwindLibType() const override { return UNW_CompilerRT; }
+
+ std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
+ types::ID InputType = types::TY_INVALID) const override;
+
+ 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);
+ }
+
+ Optional getRuntimePath() const override;
+ Optional getCXXStdlibPath() const override;
+
+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/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1f7ab49ccdd7ce443d008bc1fec8c47fc531487c..66826a8b3ba72cef48623f92a3c6ff8c5d60afe0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14922,7 +14922,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
// errno in those environments even though it could set errno based on the
// C standard.
const llvm::Triple &Trip = Context.getTargetInfo().getTriple();
- if ((Trip.isGNUEnvironment() || Trip.isAndroid() || Trip.isOSMSVCRT()) &&
+ if ((Trip.isGNUEnvironment() || Trip.isAndroid() || Trip.isOSMSVCRT() ||
+ Trip.isOHOSFamily()) &&
!FD->hasAttr()) {
switch (BuiltinID) {
case Builtin::BI__builtin_fma:
diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..847f6661fa05c5bc8cb295c279367eaccd23620a
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp
@@ -0,0 +1,103 @@
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace
+{
+class MemcpyChecker : public Checker
+{
+ CallDescription MemcpyS;
+
+ std::unique_ptr OverflowBugType;
+
+ public:
+ MemcpyChecker();
+ void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
+};
+
+MemcpyChecker::MemcpyChecker()
+ : MemcpyS("memcpy_s")
+{
+ OverflowBugType.reset(
+ new BugType(this, "MyFistChecker memcpy_s overflow", "MyFistChecker error"));
+}
+
+void MemcpyChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const
+{
+ if (!Call.isCalled(MemcpyS)) {
+ return;
+ }
+
+ SValBuilder &SVB = C.getSValBuilder();
+ ProgramStateRef state = C.getState();
+ SVal dstAddrSVal = Call.getArgSVal(0);
+ SVal srcLengthSVal = Call.getArgSVal(3);
+
+ const MemRegion *dstAddrMR = dstAddrSVal.getAsRegion();
+ if (!dstAddrMR) {
+ return;
+ }
+
+ const ElementRegion *dstAddrER = dyn_cast(dstAddrMR);
+ if (!dstAddrER) {
+ return;
+ }
+
+ DefinedOrUnknownSVal Idx = dstAddrER->getIndex().castAs();
+ Optional IdxSVal = Idx.getAs();
+ if (!IdxSVal) {
+ return;
+ }
+
+ DefinedOrUnknownSVal ElementCount = getDynamicElementCount(
+ state, dstAddrER->getSuperRegion(), C.getSValBuilder(), dstAddrER->getValueType());
+
+ Optional dstAddrLenSVal = ElementCount.getAs();
+ if (!dstAddrLenSVal) {
+ return;
+ }
+
+ Optional srcLengthDSVal = srcLengthSVal.getAs();
+
+ SVal srcLenDSval = SVB.evalBinOp(state, BO_Add, *srcLengthDSVal, *IdxSVal, SVB.getArrayIndexType());
+
+ SVal dstLessThanSrcLength = SVB.evalBinOp(state, BO_LT, *dstAddrLenSVal, srcLenDSval, SVB.getConditionType());
+
+ Optional dstLessThanSrcLengthDVal = dstLessThanSrcLength.getAs();
+ if (!dstLessThanSrcLengthDVal) {
+ return;
+ }
+
+ if (state->assume(*dstLessThanSrcLengthDVal, true)) {
+ // it is possible that dst less than src length
+ ExplodedNode *ErrNode = C.generateNonFatalErrorNode();
+ // If we've already reached this node on another path, return.
+ if (!ErrNode)
+ return;
+
+ // Generate the report.
+ auto R = std::make_unique(
+ *OverflowBugType, "MemcpyChecker BugReport", ErrNode);
+ R->addRange(Call.getSourceRange());
+ C.emitReport(std::move(R));
+ return;
+ }
+}
+} // namespace
+
+void ento::registerMemcpyChecker(CheckerManager &mgr)
+{
+ mgr.registerChecker();
+}
+
+// This checker should be enabled regardless of how language options are set.
+bool ento::shouldRegisterMemcpyChecker(const CheckerManager &mgr)
+{
+ return true;
+}
diff --git a/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c b/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c
index c6a38b20074acf585bb3320250363ea0b6d76d52..74949c91ae6c1d220095af51fba986ae68e843ae 100644
--- a/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c
+++ b/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c
@@ -9,6 +9,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 da4af7a8cc82df914597c85fc55592762e53d284..56a1d18073e25024230c64e677a4a894cbd16348 100644
--- a/clang/test/CodeGen/arm64-abi-vector.c
+++ b/clang/test/CodeGen/arm64-abi-vector.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple aarch64-linux-android -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s
+// RUN: %clang_cc1 -triple aarch64-linux-ohos -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s
#include
diff --git a/clang/test/CodeGen/math-builtins.c b/clang/test/CodeGen/math-builtins.c
index ac2a7595e1c9bd160f3a777b3215247f5969f61f..7f595e3b0b674f72a4917bfb70a68664740a7c61 100644
--- a/clang/test/CodeGen/math-builtins.c
+++ b/clang/test/CodeGen/math-builtins.c
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU
// RUN: %clang_cc1 -triple x86_64-unknown-unknown-android -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_ANDROID
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown-ohos -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_ANDROID
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN
// Test attributes and codegen of math builtins.
diff --git a/clang/test/CodeGen/matrix-type-builtins.c b/clang/test/CodeGen/matrix-type-builtins.c
index 67f5c78196878cabed1fd1f338c75c8cf7dd4989..ec0be85b7151eab28823973e018694fde3459745 100644
--- a/clang/test/CodeGen/matrix-type-builtins.c
+++ b/clang/test/CodeGen/matrix-type-builtins.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+// RUN: %clang_cc1 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck --check-prefixes=COMMON,CHECK64 %s
+// RUN: %clang_cc1 -fenable-matrix -triple i386-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck --check-prefixes=COMMON,CHECK32 %s
// Also check we do not crash when running some middle-end passes. Most
// importantly this includes the IR verifier, to ensure we emit valid IR.
@@ -15,30 +16,33 @@ typedef unsigned ux1x6_t __attribute__((matrix_type(1, 6)));
typedef unsigned ux6x1_t __attribute__((matrix_type(6, 1)));
void transpose_double_5x5(dx5x5_t *a) {
- // CHECK-LABEL: define{{.*}} void @transpose_double_5x5(
- // CHECK: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
- // CHECK-NEXT: [[TRANS:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[A]], i32 5, i32 5)
- // CHECK-NEXT: [[AT_ADDR:%.*]] = bitcast [25 x double]* %a_t to <25 x double>*
- // CHECK-NEXT: store <25 x double> [[TRANS]], <25 x double>* [[AT_ADDR]], align 8
+ // COMMON-LABEL: define{{.*}} void @transpose_double_5x5(
+ // CHECK32: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
+ // CHECK64: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
+ // COMMON-NEXT: [[TRANS:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[A]], i32 5, i32 5)
+ // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [25 x double]* %a_t to <25 x double>*
+ // CHECK32-NEXT: store <25 x double> [[TRANS]], <25 x double>* [[AT_ADDR]], align 4
+ // CHECK64-NEXT: store <25 x double> [[TRANS]], <25 x double>* [[AT_ADDR]], align 8
+
dx5x5_t a_t = __builtin_matrix_transpose(*a);
}
void transpose_float_3x2(fx3x2_t *a) {
- // CHECK-LABEL: define{{.*}} void @transpose_float_3x2(
- // CHECK: [[A:%.*]] = load <6 x float>, <6 x float>* {{.*}}, align 4
- // CHECK-NEXT: [[TRANS:%.*]] = call <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> [[A]], i32 3, i32 2)
- // CHECK-NEXT: [[AT_ADDR:%.*]] = bitcast [6 x float]* %a_t to <6 x float>*
- // CHECK-NEXT: store <6 x float> [[TRANS]], <6 x float>* [[AT_ADDR]], align 4
+ // COMMON-LABEL: define{{.*}} void @transpose_float_3x2(
+ // COMMON: [[A:%.*]] = load <6 x float>, <6 x float>* {{.*}}, align 4
+ // COMMON-NEXT: [[TRANS:%.*]] = call <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> [[A]], i32 3, i32 2)
+ // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [6 x float]* %a_t to <6 x float>*
+ // COMMON-NEXT: store <6 x float> [[TRANS]], <6 x float>* [[AT_ADDR]], align 4
fx2x3_t a_t = __builtin_matrix_transpose(*a);
}
void transpose_int_20x4(ix20x4_t *a) {
- // CHECK-LABEL: define{{.*}} void @transpose_int_20x4(
- // CHECK: [[A:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
- // CHECK-NEXT: [[TRANS:%.*]] = call <80 x i32> @llvm.matrix.transpose.v80i32(<80 x i32> [[A]], i32 20, i32 4)
- // CHECK-NEXT: [[AT_ADDR:%.*]] = bitcast [80 x i32]* %a_t to <80 x i32>*
- // CHECK-NEXT: store <80 x i32> [[TRANS]], <80 x i32>* [[AT_ADDR]], align 4
+ // COMMON-LABEL: define{{.*}} void @transpose_int_20x4(
+ // COMMON: [[A:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
+ // COMMON-NEXT: [[TRANS:%.*]] = call <80 x i32> @llvm.matrix.transpose.v80i32(<80 x i32> [[A]], i32 20, i32 4)
+ // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [80 x i32]* %a_t to <80 x i32>*
+ // COMMON-NEXT: store <80 x i32> [[TRANS]], <80 x i32>* [[AT_ADDR]], align 4
ix4x20_t a_t = __builtin_matrix_transpose(*a);
}
@@ -49,26 +53,28 @@ struct Foo {
};
void transpose_struct_member(struct Foo *F) {
- // CHECK-LABEL: define{{.*}} void @transpose_struct_member(
- // CHECK: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4
- // CHECK-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6)
- // CHECK-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8
- // CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 1
- // CHECK-NEXT: [[OUT_PTR_C:%.*]] = bitcast [6 x i32]* [[OUT_PTR]] to <6 x i32>*
- // CHECK-NEXT: store <6 x i32> [[M_T]], <6 x i32>* [[OUT_PTR_C]], align 4
+ // COMMON-LABEL: define{{.*}} void @transpose_struct_member(
+ // COMMON: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4
+ // COMMON-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6)
+ // CHECK32-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 4
+ // CHECK64-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8
+ // COMMON-NEXT: [[OUT_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 1
+ // COMMON-NEXT: [[OUT_PTR_C:%.*]] = bitcast [6 x i32]* [[OUT_PTR]] to <6 x i32>*
+ // COMMON-NEXT: store <6 x i32> [[M_T]], <6 x i32>* [[OUT_PTR_C]], align 4
F->out = __builtin_matrix_transpose(F->in);
}
void transpose_transpose_struct_member(struct Foo *F) {
- // CHECK-LABEL: define{{.*}} void @transpose_transpose_struct_member(
- // CHECK: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4
- // CHECK-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6)
- // CHECK-NEXT: [[M_T2:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M_T]], i32 6, i32 1)
- // CHECK-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8
- // CHECK-NEXT: [[IN_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 0
- // CHECK-NEXT: [[IN_PTR_C:%.*]] = bitcast [6 x i32]* [[IN_PTR]] to <6 x i32>*
- // CHECK-NEXT: store <6 x i32> [[M_T2]], <6 x i32>* [[IN_PTR_C]], align 4
+ // COMMON-LABEL: define{{.*}} void @transpose_transpose_struct_member(
+ // COMMON: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4
+ // COMMON-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6)
+ // COMMON-NEXT: [[M_T2:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M_T]], i32 6, i32 1)
+ // CHECK32-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 4
+ // CHECK64-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8
+ // COMMON-NEXT: [[IN_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 0
+ // COMMON-NEXT: [[IN_PTR_C:%.*]] = bitcast [6 x i32]* [[IN_PTR]] to <6 x i32>*
+ // COMMON-NEXT: store <6 x i32> [[M_T2]], <6 x i32>* [[IN_PTR_C]], align 4
F->in = __builtin_matrix_transpose(__builtin_matrix_transpose(F->in));
}
@@ -76,13 +82,16 @@ void transpose_transpose_struct_member(struct Foo *F) {
dx5x5_t get_matrix();
void transpose_rvalue() {
- // CHECK-LABEL: define{{.*}} void @transpose_rvalue()
- // CHECK-NEXT: entry:
- // CHECK-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8
- // CHECK-NEXT: [[CALL:%.*]] = call <25 x double> (...) @get_matrix()
- // CHECK-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[CALL]], i32 5, i32 5)
- // CHECK-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>*
- // CHECK-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8
+ // COMMON-LABEL: define{{.*}} void @transpose_rvalue()
+ // COMMON-NEXT: entry:
+ // CHECK32-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 4
+ // CHECK64-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8
+ // CHECK32-NEXT: [[CALL:%.*]] = call <25 x double> bitcast (<25 x double> (...)* @get_matrix to <25 x double> ()*)()
+ // CHECK64-NEXT: [[CALL:%.*]] = call <25 x double> (...) @get_matrix()
+ // COMMON-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[CALL]], i32 5, i32 5)
+ // COMMON-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>*
+ // CHECK32-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 4
+ // CHECK64-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8
dx5x5_t m_t = __builtin_matrix_transpose(get_matrix());
}
@@ -90,162 +99,215 @@ void transpose_rvalue() {
const dx5x5_t global_matrix;
void transpose_global() {
- // CHECK-LABEL: define{{.*}} void @transpose_global()
- // CHECK-NEXT: entry:
- // CHECK-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8
- // CHECK-NEXT: [[GLOBAL_MATRIX:%.*]] = load <25 x double>, <25 x double>* bitcast ([25 x double]* @global_matrix to <25 x double>*), align 8
- // CHECK-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[GLOBAL_MATRIX]], i32 5, i32 5)
- // CHECK-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>*
- // CHECK-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8
+ // COMMON-LABEL: define{{.*}} void @transpose_global()
+ // COMMON-NEXT: entry:
+ // CHECK32-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 4
+ // CHECK32-NEXT: [[GLOBAL_MATRIX:%.*]] = load <25 x double>, <25 x double>* bitcast ([25 x double]* @global_matrix to <25 x double>*), align 4
+ // CHECK64-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8
+ // CHECK64-NEXT: [[GLOBAL_MATRIX:%.*]] = load <25 x double>, <25 x double>* bitcast ([25 x double]* @global_matrix to <25 x double>*), align 8
+ // COMMON-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[GLOBAL_MATRIX]], i32 5, i32 5)
+ // COMMON-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>*
+ // CHECK32-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 4
+ // CHECK64-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8
dx5x5_t m_t = __builtin_matrix_transpose(global_matrix);
}
void column_major_load_with_const_stride_double(double *Ptr) {
- // CHECK-LABEL: define{{.*}} void @column_major_load_with_const_stride_double(double* %Ptr)
- // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_with_const_stride_double(double* %Ptr)
+ // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5)
+ // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
}
void column_major_load_with_const_stride2_double(double *Ptr) {
- // CHECK-LABEL: define{{.*}} void @column_major_load_with_const_stride2_double(double* %Ptr)
- // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_with_const_stride2_double(double* %Ptr)
+ // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 15, i1 false, i32 5, i32 5)
+ // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5)
dx5x5_t m_a2 = __builtin_matrix_column_major_load(Ptr, 5, 5, 2 * 3 + 9);
}
void column_major_load_with_variable_stride_ull_float(float *Ptr, unsigned long long S) {
- // CHECK-LABEL: define{{.*}} void @column_major_load_with_variable_stride_ull_float(float* %Ptr, i64 %S)
- // CHECK: [[S:%.*]] = load i64, i64* %S.addr, align 8
- // CHECK-NEXT: [[PTR:%.*]] = load float*, float** %Ptr.addr, align 8
- // CHECK-NEXT: call <6 x float> @llvm.matrix.column.major.load.v6f32(float* align 4 [[PTR]], i64 [[S]], i1 false, i32 2, i32 3)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_with_variable_stride_ull_float(float* %Ptr, i64 %S)
+ // CHECK32: [[S:%.*]] = load i64, i64* %S.addr, align 8
+ // CHECK32-NEXT: [[STRIDE_TRUNC:%.*]] = trunc i64 [[S]] to i32
+ // CHECK32-NEXT: [[PTR:%.*]] = load float*, float** %Ptr.addr, align 4
+ // CHECK32-NEXT: call <6 x float> @llvm.matrix.column.major.load.v6f32.i32(float* align 4 [[PTR]], i32 [[STRIDE_TRUNC]], i1 false, i32 2, i32 3)
+
+ // CHECK64: [[S:%.*]] = load i64, i64* %S.addr, align 8
+ // CHECK64-NEXT: [[PTR:%.*]] = load float*, float** %Ptr.addr, align 8
+ // CHECK64-NEXT: call <6 x float> @llvm.matrix.column.major.load.v6f32.i64(float* align 4 [[PTR]], i64 [[S]], i1 false, i32 2, i32 3)
fx2x3_t m_b = __builtin_matrix_column_major_load(Ptr, 2, 3, S);
}
void column_major_load_with_stride_math_int(int *Ptr, int S) {
- // CHECK-LABEL: define{{.*}} void @column_major_load_with_stride_math_int(i32* %Ptr, i32 %S)
- // CHECK: [[S:%.*]] = load i32, i32* %S.addr, align 4
- // CHECK-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S]], 32
- // CHECK-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
- // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: call <80 x i32> @llvm.matrix.column.major.load.v80i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_with_stride_math_int(i32* %Ptr, i32 %S)
+ // COMMON: [[S:%.*]] = load i32, i32* %S.addr, align 4
+ // COMMON-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S]], 32
+ // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4
+ // CHECK32-NEXT: call <80 x i32> @llvm.matrix.column.major.load.v80i32.i32(i32* align 4 [[PTR]], i32 [[STRIDE]], i1 false, i32 4, i32 20)
+ //
+ // CHECK64-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
+ // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
+ // CHECK64-NEXT: call <80 x i32> @llvm.matrix.column.major.load.v80i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20)
ix4x20_t m_c = __builtin_matrix_column_major_load(Ptr, 4, 20, S + 32);
}
void column_major_load_with_stride_math_s_int(int *Ptr, short S) {
- // CHECK-LABEL: define{{.*}} void @column_major_load_with_stride_math_s_int(i32* %Ptr, i16 signext %S)
- // CHECK: [[S:%.*]] = load i16, i16* %S.addr, align 2
- // CHECK-NEXT: [[S_EXT:%.*]] = sext i16 [[S]] to i32
- // CHECK-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S_EXT]], 32
- // CHECK-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
- // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: %matrix = call <80 x i32> @llvm.matrix.column.major.load.v80i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_with_stride_math_s_int(i32* %Ptr, i16 signext %S)
+ // COMMON: [[S:%.*]] = load i16, i16* %S.addr, align 2
+ // COMMON-NEXT: [[S_EXT:%.*]] = sext i16 [[S]] to i32
+ // COMMON-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S_EXT]], 32
+ // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4
+ // CHECK32-NEXT: %matrix = call <80 x i32> @llvm.matrix.column.major.load.v80i32.i32(i32* align 4 [[PTR]], i32 [[STRIDE]], i1 false, i32 4, i32 20)
+ //
+ // CHECK64-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
+ // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
+ // CHECK64-NEXT: %matrix = call <80 x i32> @llvm.matrix.column.major.load.v80i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20)
ix4x20_t m_c = __builtin_matrix_column_major_load(Ptr, 4, 20, S + 32);
}
void column_major_load_array1(double Ptr[25]) {
- // CHECK-LABEL: define{{.*}} void @column_major_load_array1(double* %Ptr)
- // CHECK: [[ADDR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[ADDR]], i64 5, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_array1(double* %Ptr)
+ // CHECK32: [[ADDR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[ADDR]], i32 5, i1 false, i32 5, i32 5)
+
+ // CHECK64: [[ADDR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[ADDR]], i64 5, i1 false, i32 5, i32 5)
dx5x5_t m = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
}
void column_major_load_array2() {
- // CHECK-LABEL: define{{.*}} void @column_major_load_array2() #0 {
- // CHECK-NEXT: entry:
- // CHECK-NEXT: [[PTR:%.*]] = alloca [25 x double], align 16
- // CHECK: [[ARRAY_DEC:%.*]] = getelementptr inbounds [25 x double], [25 x double]* [[PTR]], i64 0, i64 0
- // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 16 [[ARRAY_DEC]], i64 5, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_array2() #0 {
+ // COMMON-NEXT: entry:
+ // CHECK32-NEXT: [[PTR:%.*]] = alloca [25 x double], align 8
+ // CHECK32: [[ARRAY_DEC:%.*]] = getelementptr inbounds [25 x double], [25 x double]* [[PTR]], i32 0, i32 0
+ // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 8 [[ARRAY_DEC]], i32 5, i1 false, i32 5, i32 5)
+
+ // CHECK64-NEXT: [[PTR:%.*]] = alloca [25 x double], align 16
+ // CHECK64: [[ARRAY_DEC:%.*]] = getelementptr inbounds [25 x double], [25 x double]* [[PTR]], i64 0, i64 0
+ // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 16 [[ARRAY_DEC]], i64 5, i1 false, i32 5, i32 5)
double Ptr[25];
dx5x5_t m = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
}
void column_major_load_const(const double *Ptr) {
- // CHECK-LABEL: define{{.*}} void @column_major_load_const(double* %Ptr)
- // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_const(double* %Ptr)
+ // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5)
+ //
+ // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
}
void column_major_load_volatile(volatile double *Ptr) {
- // CHECK-LABEL: define{{.*}} void @column_major_load_volatile(double* %Ptr)
- // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_load_volatile(double* %Ptr)
+ // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 true, i32 5, i32 5)
+ //
+ // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5)
dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
}
void column_major_store_with_const_stride_double(double *Ptr) {
- // CHECK-LABEL: define{{.*}} void @column_major_store_with_const_stride_double(double* %Ptr)
- // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
- // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_store_with_const_stride_double(double* %Ptr)
+ // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
+ // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5)
+ //
+ // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
+ // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
dx5x5_t m;
__builtin_matrix_column_major_store(m, Ptr, 5);
}
void column_major_store_with_const_stride2_double(double *Ptr) {
- // CHECK-LABEL: define{{.*}} void @column_major_store_with_const_stride2_double(double* %Ptr)
- // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
- // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_store_with_const_stride2_double(double* %Ptr)
+ // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
+ // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 15, i1 false, i32 5, i32 5)
+ //
+ // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
+ // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5)
//
dx5x5_t m;
__builtin_matrix_column_major_store(m, Ptr, 2 * 3 + 9);
}
void column_major_store_with_stride_math_int(int *Ptr, int S) {
- // CHECK-LABEL: define{{.*}} void @column_major_store_with_stride_math_int(i32* %Ptr, i32 %S)
- // CHECK: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
- // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: [[S:%.*]] = load i32, i32* %S.addr, align 4
- // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[S]], 32
- // CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v80i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20)
+ // COMMON-LABEL: define{{.*}} void @column_major_store_with_stride_math_int(i32* %Ptr, i32 %S)
+ // COMMON: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
+ // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4
+ // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
+ // COMMON-NEXT: [[S:%.*]] = load i32, i32* %S.addr, align 4
+ // COMMON-NEXT: [[ADD:%.*]] = add nsw i32 [[S]], 32
+ // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v80i32.i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i32 [[ADD]], i1 false, i32 4, i32 20)
+ //
+ // CHECK64-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
+ // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v80i32.i64(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20)
ix4x20_t m;
__builtin_matrix_column_major_store(m, Ptr, S + 32);
}
void column_major_store_with_stride_math_s_int(int *Ptr, short S) {
- // CHECK-LABEL: define{{.*}} void @column_major_store_with_stride_math_s_int(i32* %Ptr, i16 signext %S)
- // CHECK: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
- // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: [[S:%.*]] = load i16, i16* %S.addr, align 2
- // CHECK-NEXT: [[EXT:%.*]] = sext i16 [[S]] to i32
- // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[EXT]], 2
- // CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v80i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20)
+ // COMMON-LABEL: define{{.*}} void @column_major_store_with_stride_math_s_int(i32* %Ptr, i16 signext %S)
+ // COMMON: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
+ // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4
+ // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
+ // COMMON-NEXT: [[S:%.*]] = load i16, i16* %S.addr, align 2
+ // COMMON-NEXT: [[EXT:%.*]] = sext i16 [[S]] to i32
+ // COMMON-NEXT: [[ADD:%.*]] = add nsw i32 [[EXT]], 2
+ // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v80i32.i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i32 [[ADD]], i1 false, i32 4, i32 20)
+ //
+ // CHECK64-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
+ // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v80i32.i64(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20)
ix4x20_t m;
__builtin_matrix_column_major_store(m, Ptr, S + 2);
}
void column_major_store_array1(double Ptr[25]) {
- // CHECK-LABEL: define{{.*}} void @column_major_store_array1(double* %Ptr)
- // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
- // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_store_array1(double* %Ptr)
+ // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
+ // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5)
+ //
+ // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
+ // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
dx5x5_t m;
__builtin_matrix_column_major_store(m, Ptr, 5);
}
void column_major_store_array2() {
- // CHECK-LABEL: define{{.*}} void @column_major_store_array2()
- // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
- // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [25 x double], [25 x double]* %Ptr, i64 0, i64 0
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 16 [[PTR]], i64 5, i1 false, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_store_array2()
+ // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
+ // CHECK32-NEXT: [[PTR:%.*]] = getelementptr inbounds [25 x double], [25 x double]* %Ptr, i32 0, i32 0
+ // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 8 [[PTR]], i32 5, i1 false, i32 5, i32 5)
+ //
+ // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
+ // CHECK64-NEXT: [[PTR:%.*]] = getelementptr inbounds [25 x double], [25 x double]* %Ptr, i64 0, i64 0
+ // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 16 [[PTR]], i64 5, i1 false, i32 5, i32 5)
double Ptr[25];
dx5x5_t m;
@@ -253,10 +315,14 @@ void column_major_store_array2() {
}
void column_major_store_volatile(volatile double *Ptr) {
- // CHECK-LABEL: define{{.*}} void @column_major_store_volatile(double* %Ptr) #0 {
- // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
- // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5)
+ // COMMON-LABEL: define{{.*}} void @column_major_store_volatile(double* %Ptr) #0 {
+ // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
+ // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
+ // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 true, i32 5, i32 5)
+ //
+ // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
+ // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
+ // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5)
dx5x5_t m;
__builtin_matrix_column_major_store(m, Ptr, 5);
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/CodeGenCXX/matrix-type-builtins.cpp b/clang/test/CodeGenCXX/matrix-type-builtins.cpp
index 6cae343d2c248f2749325c4628af4676b75bbbae..d95774feb7c7524320911ecde4da45dc78132065 100644
--- a/clang/test/CodeGenCXX/matrix-type-builtins.cpp
+++ b/clang/test/CodeGenCXX/matrix-type-builtins.cpp
@@ -94,7 +94,7 @@ void test_column_major_load_with_stride_template_double(double *Ptr) {
// CHECK-LABEL: define linkonce_odr <40 x double> @_Z29column_major_load_with_strideIdLj10ELj4ELj15EEu11matrix_typeIXT0_EXT1_ET_EPS0_(double* %Ptr)
// CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call <40 x double> @llvm.matrix.column.major.load.v40f64(double* align 8 [[PTR]], i64 15, i1 false, i32 10, i32 4)
+ // CHECK-NEXT: call <40 x double> @llvm.matrix.column.major.load.v40f64.i64(double* align 8 [[PTR]], i64 15, i1 false, i32 10, i32 4)
matrix_t M1 = column_major_load_with_stride(Ptr);
}
@@ -106,7 +106,7 @@ void test_column_major_load_with_stride_template_int(int *Ptr) {
// CHECK-LABEL: define linkonce_odr <6 x i32> @_Z29column_major_load_with_strideIiLj3ELj2ELj12EEu11matrix_typeIXT0_EXT1_ET_EPS0_(i32* %Ptr)
// CHECK: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: call <6 x i32> @llvm.matrix.column.major.load.v6i32(i32* align 4 [[PTR]], i64 12, i1 false, i32 3, i32 2)
+ // CHECK-NEXT: call <6 x i32> @llvm.matrix.column.major.load.v6i32.i64(i32* align 4 [[PTR]], i64 12, i1 false, i32 3, i32 2)
matrix_t M1 = column_major_load_with_stride(Ptr);
}
@@ -124,7 +124,7 @@ void test_column_major_load_stride_wrapper(int *Ptr, UnsignedWrapper &W) {
// CHECK-NEXT: [[STRIDE:%.*]] = call i32 @_ZN15UnsignedWrappercvjEv(%struct.UnsignedWrapper* {{[^,]*}} [[W]])
// CHECK-NEXT: [[STRIDE_EXT:%.*]] = zext i32 [[STRIDE]] to i64
// CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: call <4 x i32> @llvm.matrix.column.major.load.v4i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 2, i32 2)
+ // CHECK-NEXT: call <4 x i32> @llvm.matrix.column.major.load.v4i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 2, i32 2)
matrix_t M1 = __builtin_matrix_column_major_load(Ptr, 2, 2, W);
}
@@ -133,7 +133,7 @@ constexpr int constexpr3() { return 3; }
void test_column_major_load_constexpr_num_rows(int *Ptr) {
// CHECK-LABEL: define{{.*}} void @_Z41test_column_major_load_constexpr_num_rowsPi(i32* %Ptr)
// CHECK: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: call <6 x i32> @llvm.matrix.column.major.load.v6i32(i32* align 4 [[PTR]], i64 3, i1 false, i32 3, i32 2)
+ // CHECK-NEXT: call <6 x i32> @llvm.matrix.column.major.load.v6i32.i64(i32* align 4 [[PTR]], i64 3, i1 false, i32 3, i32 2)
matrix_t M1 = __builtin_matrix_column_major_load(Ptr, constexpr3(), 2, 3);
}
@@ -143,7 +143,7 @@ constexpr int constexpr1() { return 1; }
void test_column_major_load_constexpr_num_columns(int *Ptr) {
// CHECK-LABEL: define{{.*}} void @_Z44test_column_major_load_constexpr_num_columnsPi(i32* %Ptr)
// CHECK: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: call <2 x i32> @llvm.matrix.column.major.load.v2i32(i32* align 4 [[PTR]], i64 3, i1 false, i32 2, i32 1)
+ // CHECK-NEXT: call <2 x i32> @llvm.matrix.column.major.load.v2i32.i64(i32* align 4 [[PTR]], i64 3, i1 false, i32 2, i32 1)
matrix_t M1 = __builtin_matrix_column_major_load(Ptr, 2, constexpr1(), 3);
}
@@ -153,7 +153,7 @@ constexpr int constexpr_plus1() { return N + 1; }
void test_column_major_load_constexpr_num_columns_temp(int *Ptr) {
// CHECK-LABEL: define{{.*}} void @_Z49test_column_major_load_constexpr_num_columns_tempPi(i32* %Ptr)
// CHECK: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: call <10 x i32> @llvm.matrix.column.major.load.v10i32(i32* align 4 [[PTR]], i64 3, i1 false, i32 2, i32 5)
+ // CHECK-NEXT: call <10 x i32> @llvm.matrix.column.major.load.v10i32.i64(i32* align 4 [[PTR]], i64 3, i1 false, i32 2, i32 5)
matrix_t M1 = __builtin_matrix_column_major_load(Ptr, 2, constexpr_plus1<4>(), 3);
}
@@ -162,7 +162,7 @@ void test_column_major_load_constexpr_stride_constexpr(int *Ptr) {
// CHECK: [[STRIDE:%.*]] = call i32 @_Z10constexpr3v()
// CHECK-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
// CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: call <4 x i32> @llvm.matrix.column.major.load.v4i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 2, i32 2)
+ // CHECK-NEXT: call <4 x i32> @llvm.matrix.column.major.load.v4i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 2, i32 2)
matrix_t M1 = __builtin_matrix_column_major_load(Ptr, 2, 2, constexpr3());
}
@@ -200,7 +200,7 @@ void test_column_major_store_with_stride_template_double(double *Ptr) {
// CHECK-LABEL: define linkonce_odr void @_Z30column_major_store_with_strideIdLj10ELj4ELj15EEvRu11matrix_typeIXT0_EXT1_ET_EPS0_([40 x double]* nonnull align 8 dereferenceable(320) %m, double* %Ptr)
// CHECK: [[M:%.*]] = load <40 x double>, <40 x double>* {{.*}}, align 8
// CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v40f64(<40 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 10, i32 4)
+ // CHECK-NEXT: call void @llvm.matrix.column.major.store.v40f64.i64(<40 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 10, i32 4)
matrix_t M1;
column_major_store_with_stride(M1, Ptr);
@@ -214,7 +214,7 @@ void test_column_major_store_with_stride_template_int(int *Ptr) {
// CHECK-LABEL: define linkonce_odr void @_Z30column_major_store_with_strideIiLj3ELj2ELj3EEvRu11matrix_typeIXT0_EXT1_ET_EPS0_([6 x i32]* nonnull align 4 dereferenceable(24) %m, i32* %Ptr)
// CHECK: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4
// CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v6i32(<6 x i32> [[M]], i32* align 4 [[PTR]], i64 3, i1 false, i32 3, i32 2)
+ // CHECK-NEXT: call void @llvm.matrix.column.major.store.v6i32.i64(<6 x i32> [[M]], i32* align 4 [[PTR]], i64 3, i1 false, i32 3, i32 2)
matrix_t M1;
column_major_store_with_stride(M1, Ptr);
@@ -227,7 +227,7 @@ void test_column_major_store_stride_wrapper(int *Ptr, UnsignedWrapper &W) {
// CHECK-NEXT: [[W:%.*]] = load %struct.UnsignedWrapper*, %struct.UnsignedWrapper** %W.addr, align 8
// CHECK-NEXT: [[IDX:%.*]] = call i32 @_ZN15UnsignedWrappercvjEv(%struct.UnsignedWrapper* {{[^,]*}} [[W]])
// CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v4i32(<4 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 2, i32 2)
+ // CHECK-NEXT: call void @llvm.matrix.column.major.store.v4i32.i64(<4 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 2, i32 2)
matrix_t M1;
__builtin_matrix_column_major_store(M1, Ptr, W);
@@ -239,7 +239,7 @@ void test_column_major_store_constexpr_stride_constexpr(int *Ptr) {
// CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
// CHECK-NEXT: [[IDX:%.*]] = call i32 @_Z10constexpr3v()
// CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[IDX]] to i64
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v4i32(<4 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 2, i32 2)
+ // CHECK-NEXT: call void @llvm.matrix.column.major.store.v4i32.i64(<4 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 2, i32 2)
matrix_t M;
__builtin_matrix_column_major_store(M, Ptr, constexpr3());
diff --git a/clang/test/CodeGenObjC/matrix-type-builtins.m b/clang/test/CodeGenObjC/matrix-type-builtins.m
index f0faaace444288e79a4b12777af55a292d966c70..0d517dd4964a87eb87af154546e330d8d76ef507 100644
--- a/clang/test/CodeGenObjC/matrix-type-builtins.m
+++ b/clang/test/CodeGenObjC/matrix-type-builtins.m
@@ -56,7 +56,7 @@ void test_column_major_load(PtrValue *Ptr, IntValue *Stride) {
// CHECK: [[STRIDE:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)
// CHECK-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
// CHECK: [[PTR:%.*]] = call i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32* (i8*, i8*)*)
- // CHECK-NEXT: call <12 x i32> @llvm.matrix.column.major.load.v12i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 3, i32 4)
+ // CHECK-NEXT: call <12 x i32> @llvm.matrix.column.major.load.v12i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 3, i32 4)
u3x4 m = __builtin_matrix_column_major_load(Ptr.value, 3, 4, Stride.value);
}
@@ -67,7 +67,7 @@ void test_column_major_store(UnsignedMatrixValue *M, PtrValue *Ptr, IntValue *St
// CHECK: [[PTR:%.*]] = call i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32* (i8*, i8*)*)
// CHECK: [[IDX:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)
// CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[IDX]] to i64
- // CHECK-NEXT: call void @llvm.matrix.column.major.store.v12i32(<12 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 3, i32 4)
+ // CHECK-NEXT: call void @llvm.matrix.column.major.store.v12i32.i64(<12 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 3, i32 4)
__builtin_matrix_column_major_store(M.value, Ptr.value, Stride.value);
}
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..170c0da0ce068cbaae76f2b4c5cc95fbd0326853
--- /dev/null
+++ b/clang/test/Driver/ohos.c
@@ -0,0 +1,245 @@
+// 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: "-z" "noexecstack"
+// 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: "-Bstatic"
+// 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
+// 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 %s -### -o %t.o 2>&1 \
+// RUN: --target=armv7-linux-ohos \
+// RUN: | FileCheck --check-prefix=CHECK-OHOS-WARN-SHARED-TEXTREL %s
+
+// CHECK-OHOS-WARN-SHARED-TEXTREL: "{{.*}}ld{{(.exe)?}}"
+// CHECK-OHOS-WARN-SHARED-TEXTREL: "--warn-shared-textrel"
+
+// 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..d0fe244c6e78af1fd0985d168f44754cb5482932
--- /dev/null
+++ b/clang/test/Driver/ohos.cpp
@@ -0,0 +1,123 @@
+// 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-isystem" "{{.*[/\\]}}include{{/|\\\\}}c++{{/|\\\\}}v1"
+// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include"
+// CHECK: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]"
+// CHECK: "-pie"
+// CHECK: "-z" "noexecstack"
+// 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/c++/"
+// 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: "-Bstatic"
+// 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: "-Bstatic"
+// 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{{/|\\\\}}c++/"
+// CHECK-MULTILIB-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/"
+
+// CHECK-MULTILIB-ARM-A7-SOFT: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}c++/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{{/|\\\\}}c++{{/|\\\\}}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{{/|\\\\}}c++{{/|\\\\}}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/ohos.c b/clang/test/Preprocessor/ohos.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd1060133c4e3b229e679b52148cc1d665143dd4
--- /dev/null
+++ b/clang/test/Preprocessor/ohos.c
@@ -0,0 +1,11 @@
+// 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 -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -check-prefix=OHOS-DEFS
+
+// ARM-HOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U
+// ARM-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U
+// ARM64-HOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL
+// ARM64-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 bb635dfff991a48ba265a9d24c64edcdaa7fe355..bcb84f1d3d7c3e3365667d6549c47ea9c07329e4 100644
--- a/clang/unittests/CMakeLists.txt
+++ b/clang/unittests/CMakeLists.txt
@@ -39,7 +39,9 @@ add_subdirectory(CodeGen)
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/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
index b44ad2c2118ef18c9873c8c747f8ff4a810f673c..732e8863ed32e5f7b55a62e4f5f675ad199607cd 100644
--- a/compiler-rt/CMakeLists.txt
+++ b/compiler-rt/CMakeLists.txt
@@ -120,7 +120,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})
@@ -131,7 +138,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)
@@ -235,7 +242,7 @@ option(SANITIZER_USE_STATIC_CXX_ABI
"Use static libc++abi." ${DEFAULT_SANITIZER_USE_STATIC_CXX_ABI})
set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY OFF)
-if (FUCHSIA)
+if (FUCHSIA OR OHOS)
set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY ON)
endif()
@@ -441,24 +448,9 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia")
list(APPEND SANITIZER_COMMON_LINK_LIBS zircon)
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()
macro(append_libcxx_libs var)
if (${var}_INTREE)
diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
index 361538a58e47cae7524c490da28437de6c4711d6..3fb062f78f7086f447d7d0f3cb6c874536a6ccf6 100644
--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake
+++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
@@ -239,9 +239,9 @@ function(add_compiler_rt_runtime name type)
NOT name STREQUAL "clang_rt.builtins")
get_compiler_rt_target(${arch} target)
find_compiler_rt_library(builtins ${target} builtins_${libname})
- if(builtins_${libname} STREQUAL "NOTFOUND")
- message(FATAL_ERROR "Cannot find builtins library for the target architecture")
- endif()
+ #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/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
index f61d487e93a033b5b09b7f2c4cb36f804ff224ed..00bec8bdb846dcbd35838ff73ea59c82a5a447f3 100644
--- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
+++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
@@ -378,7 +378,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_PATH}/lib/${target} PARENT_SCOPE)
+ if(OHOS)
+ set(${install_dir} ${COMPILER_RT_INSTALL_PATH}/lib/${target}/${LLVM_TARGET_MULTILIB_SUFFIX} PARENT_SCOPE)
+ else()
+ set(${install_dir} ${COMPILER_RT_INSTALL_PATH}/lib/${target} PARENT_SCOPE)
+ endif()
else()
set(${install_dir} ${COMPILER_RT_LIBRARY_INSTALL_DIR} PARENT_SCOPE)
endif()
@@ -387,7 +391,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_DIR}/lib/${target} PARENT_SCOPE)
+ if(OHOS)
+ set(${output_dir} ${COMPILER_RT_OUTPUT_DIR}/lib/${target}/${LLVM_TARGET_MULTILIB_SUFFIX} PARENT_SCOPE)
+ else()
+ set(${output_dir} ${COMPILER_RT_OUTPUT_DIR}/lib/${target} PARENT_SCOPE)
+ endif()
else()
set(${output_dir} ${COMPILER_RT_LIBRARY_OUTPUT_DIR} PARENT_SCOPE)
endif()
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake
index 1edab43e7c0dd7b1a8ded830c90fd6262b37a219..61e7e0084ba3405504bc0c5c8bc31049d5cf36bf 100644
--- a/compiler-rt/cmake/base-config-ix.cmake
+++ b/compiler-rt/cmake/base-config-ix.cmake
@@ -165,6 +165,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 f81b8384cbd50391d80bd3d8c11a4d0bc28aa31f..347de3a08bb69b3f00b2a53a26fd6a8bdf2776cd 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -50,6 +50,8 @@ if (COMPILER_RT_HAS_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 ()
@@ -128,9 +130,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.
@@ -159,8 +165,11 @@ check_library_exists(stdc++ __cxa_throw "" COMPILER_RT_HAS_LIBSTDCXX)
check_linker_flag("-Wl,-z,text" COMPILER_RT_HAS_Z_TEXT)
check_linker_flag("-fuse-ld=lld" COMPILER_RT_HAS_FUSE_LD_LLD_FLAG)
-set(VERS_COMPAT_OPTION "-Wl,-z,gnu-version-script-compat")
-check_linker_flag("${VERS_COMPAT_OPTION}" COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
+if (NOT OHOS)
+ # lld fails to link when this option is passed
+ set(VERS_COMPAT_OPTION "-Wl,-z,gnu-version-script-compat")
+ check_linker_flag("${VERS_COMPAT_OPTION}" COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
+endif()
set(DUMMY_VERS ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/dummy.vers)
file(WRITE ${DUMMY_VERS} "{};")
@@ -312,9 +321,9 @@ if(OS_NAME MATCHES "Linux")
set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${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" OR OS_NAME MATCHES "OHOS")
set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64})
-else()
+else ()
set(ALL_FUZZER_SUPPORTED_ARCH ${X86_64} ${ARM64})
endif()
@@ -646,7 +655,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)
@@ -666,17 +675,17 @@ 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()
+else ()
set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE)
endif()
# TODO: Add builtins support.
-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()
+else ()
set(COMPILER_RT_HAS_CRT FALSE)
endif()
@@ -702,7 +711,7 @@ else()
endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND
- OS_NAME MATCHES "Linux|Android")
+ OS_NAME MATCHES "Linux|Android|OHOS")
set(COMPILER_RT_HAS_HWASAN TRUE)
else()
set(COMPILER_RT_HAS_HWASAN FALSE)
@@ -716,28 +725,28 @@ 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|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 AND
- OS_NAME MATCHES "Darwin|Linux|FreeBSD|Android|NetBSD")
+ OS_NAME MATCHES "Darwin|Linux|FreeBSD|Android|NetBSD|OHOS")
set(COMPILER_RT_HAS_TSAN TRUE)
else()
set(COMPILER_RT_HAS_TSAN FALSE)
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)
@@ -765,7 +774,7 @@ else()
endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND SCUDO_SUPPORTED_ARCH AND
- OS_NAME MATCHES "Linux|Android|Fuchsia")
+ OS_NAME MATCHES "Linux|Android|Fuchsia|OHOS")
set(COMPILER_RT_HAS_SCUDO TRUE)
else()
set(COMPILER_RT_HAS_SCUDO FALSE)
@@ -779,14 +788,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/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h
index 2963e979b55c0cd1b28622bac8df2830af4f25b5..a56e1ea43c223beabdbdede45e5dbd405e8e4d08 100644
--- a/compiler-rt/lib/asan/asan_allocator.h
+++ b/compiler-rt/lib/asan/asan_allocator.h
@@ -128,7 +128,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_internal.h b/compiler-rt/lib/asan/asan_internal.h
index cfb54927c6cf4fea8dc7e83ab0f054b5357f5574..100754da08e40c7c6393baa50482315aa4dbf30c 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 || SANITIZER_RTEMS
+#if SANITIZER_IOS || SANITIZER_ANDROID || SANITIZER_RTEMS || 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 4bcbe5d02e3344da86ba2ed8c63230691f1cd74a..09dc9a798387b71289848ae08631496f8900c19a 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() {}
@@ -214,7 +215,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/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp
index c0b79bba48ff87a2d9bdbda0f8379d4e4efdfc2d..25f5b5a44416d33e1c48e9362982fa7e19472315 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/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index 73b6bead84245394e61586caa58f840e2763b237..6088cce8f8dda96e9e043d5c70a62b528a140a5d 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -693,6 +693,7 @@ else ()
foreach (arch ${BUILTIN_SUPPORTED_ARCH})
if (CAN_TARGET_${arch})
+ set(BUILTIN_CFLAGS_${arch} ${BUILTIN_CFLAGS})
# For ARM archs, exclude any VFP builtins if VFP is not supported
if (${arch} MATCHES "^(arm|armhf|armv7|armv7s|armv7k|armv7m|armv7em)$")
string(REPLACE ";" " " _TARGET_${arch}_CFLAGS "${TARGET_${arch}_CFLAGS}")
@@ -717,13 +718,13 @@ else ()
# Needed for clear_cache on debug mode, due to r7's usage in inline asm.
# Release mode already sets it via -O2/3, Debug mode doesn't.
if (${arch} STREQUAL "armhf")
- list(APPEND BUILTIN_CFLAGS -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET)
+ list(APPEND BUILTIN_CFLAGS_${arch} -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET)
endif()
# For RISCV32, we must force enable int128 for compiling long
# double routines.
if("${arch}" STREQUAL "riscv32")
- list(APPEND BUILTIN_CFLAGS -fforce-enable-int128)
+ list(APPEND BUILTIN_CFLAGS_${arch} -fforce-enable-int128)
endif()
add_compiler_rt_runtime(clang_rt.builtins
@@ -731,7 +732,7 @@ else ()
ARCHS ${arch}
SOURCES ${${arch}_SOURCES}
DEFS ${BUILTIN_DEFS}
- CFLAGS ${BUILTIN_CFLAGS}
+ CFLAGS ${BUILTIN_CFLAGS_${arch}}
PARENT_TARGET builtins)
endif ()
endforeach ()
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..c95c728598fbc082eb37bc330b59d8d1cdd15be4 100644
--- a/compiler-rt/lib/builtins/int_util.h
+++ b/compiler-rt/lib/builtins/int_util.h
@@ -40,6 +40,10 @@ 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 9a641d33ac48341b77c3a7842f05e8e50cc0eedf..1cc0b3cb6087417915441116a0da0aa3f54c2c00 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/FuzzerInterceptors.cpp b/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
index b87798603fda5bacdbc88c10a4b3b2a956ebc0fc..cb2d1e5843f95fe16d984de4eb7110cb3e9834d1 100644
--- a/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
@@ -25,6 +25,7 @@
}
#include
+#include
#include
#include // for dlsym()
diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp
index c5322110cb662a55092d94d85b66767bf932f538..5d301bb90ae45c1bf76cdc7c9ff995d11307bcd1 100644
--- a/compiler-rt/lib/hwasan/hwasan.cpp
+++ b/compiler-rt/lib/hwasan/hwasan.cpp
@@ -76,7 +76,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 12730b29bae3675a22b08749c2664ca0e59e1da3..d99ff482eed1b555990677115d75e59a92ae321a 100644
--- a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp
@@ -24,7 +24,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 cb0b5284ed268d7e99a7c07352c13e5a3550e697..9536a3d52ce471c81a7f7180c6c850edf018ffb0 100644
--- a/compiler-rt/lib/interception/interception.h
+++ b/compiler-rt/lib/interception/interception.h
@@ -16,8 +16,8 @@
#include "sanitizer_common/sanitizer_internal_defs.h"
-#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \
- !SANITIZER_NETBSD && !SANITIZER_WINDOWS && \
+#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \
+ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_OHOS && \
!SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_SOLARIS
# 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 a611604a700cf7f383b3a5f79f3aebc1bafd041b..37f54a79b16561783fecb7b1890a2605331a21ca 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/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h
index b0ae6f020b63a0b00c3c78e0cf04f8abf524f0a7..3c65d9df225e5347025978c5b54a5f577412a758 100644
--- a/compiler-rt/lib/lsan/lsan_common.h
+++ b/compiler-rt/lib/lsan/lsan_common.h
@@ -31,7 +31,7 @@
// the new architecture inside the sanitizer library.
// Exclude leak-detection on arm32 for Android because `__aeabi_read_tp`
// is missing. This caused a link error.
-#if SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))
+#if (SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__)))
#define CAN_SANITIZE_LEAKS 0
#elif (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \
(defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp
index 3157b35ffaf803595b6ec493e233ffdec6a4774d..b5b14b9218240193c010ccf06e2f21c29d7ac872 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp
@@ -26,7 +26,7 @@ const char *SecondaryAllocatorName = "LargeMmapAllocator";
// ThreadSanitizer for Go uses libc malloc/free.
#if defined(SANITIZER_USE_MALLOC)
-# if SANITIZER_LINUX && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS
extern "C" void *__libc_malloc(uptr size);
# if !SANITIZER_GO
extern "C" void *__libc_memalign(uptr alignment, uptr size);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index d4b9ea5f7f067ca446b3b8948928c34d3acee3e8..37d5dfbc8d89ba0d12b2f8aed3c11591a897993f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2180,11 +2180,13 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
}
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
INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
@@ -2451,7 +2453,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);
@@ -3750,7 +3752,7 @@ INTERCEPTOR(char *, strerror, int errnum) {
// static storage.
#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \
SANITIZER_MAC || 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 b7da659875574ed3ca457780799d5b4c556d2f68..a546a45293a96a948858cf1a51c81b5526110a68 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 1b89d6e176840570667808f8301c9a1c01b68c3b..e5f7af4d107a8eb52b2780a71033e91876905634 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
@@ -2294,7 +2294,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)
@@ -2316,7 +2316,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_errno.h b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h
index 94f16b6e87358499ae64d2deeca3db0827778f6e..efcc9820bd596191ceabb882cca518cc5399d1fb 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h
@@ -23,8 +23,7 @@
#if SANITIZER_FREEBSD || SANITIZER_MAC
# define __errno_location __error
-#elif SANITIZER_ANDROID || SANITIZER_NETBSD || \
- SANITIZER_RTEMS
+#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_RTEMS
# define __errno_location __errno
#elif SANITIZER_SOLARIS
# define __errno_location ___errno
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
index cfb5822645f131416602a16236534d8ce5694a8b..32827da14f1bde04cc47cc47a28451a9cd90df97 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
@@ -60,7 +60,8 @@ COMMON_FLAG(
"Mention name of executable when reporting error and "
"append executable name to logs (as in \"log_path.exe_name.pid\").")
COMMON_FLAG(
- bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC,
+ bool, log_to_syslog,
+ (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC || (bool)SANITIZER_OHOS,
"Write all sanitizer output to syslog in addition to other means of "
"logging.")
COMMON_FLAG(
@@ -230,13 +231,15 @@ 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_MAC,
+ bool, abort_on_error,
+ (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC || (bool)SANITIZER_OHOS,
"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 d8f0540037d2435bc201a6cd7733fe4272f03519..16345fb954fa7573b681fb97445afd87dbd09426 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
@@ -168,8 +168,8 @@ typedef long pid_t;
typedef int pid_t;
#endif
-#if SANITIZER_FREEBSD || SANITIZER_NETBSD || \
- SANITIZER_MAC || \
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \
+ SANITIZER_OHOS || \
(SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \
(SANITIZER_LINUX && defined(__x86_64__))
typedef u64 OFF_T;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 379f6d9e294b7a2dcfeb1fc02542b1041aeaca5f..bef7eb5d7f527bdfc8f00cfc45a2ea76af98ee9a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -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
@@ -489,7 +488,7 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
}
#endif
-#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
+#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_OHOS
u64 NanoTime() {
#if SANITIZER_FREEBSD
timeval tv;
@@ -501,10 +500,19 @@ u64 NanoTime() {
return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;
}
+#elif SANITIZER_OHOS
+u64 NanoTime() {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ return (u64)ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
+}
+#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
+
+#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_OHOS
uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
return internal_syscall(SYSCALL(clock_gettime), clk_id, tp);
}
-#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
+#endif
// Like getenv, but reads env directly from /proc (on Linux) or parses the
// 'environ' array (on some others) and does not use libc. This function
@@ -822,7 +830,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
}
@@ -838,7 +846,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
}
@@ -1004,7 +1012,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
@@ -1765,7 +1773,7 @@ void *internal_start_thread(void *(*func)(void *arg), void *arg) {
// Start the thread with signals blocked, otherwise it can steal user signals.
__sanitizer_sigset_t set, old;
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/tsan/setuid.c).
internal_sigdelset(&set, 33);
@@ -1795,7 +1803,7 @@ struct __sanitizer_esr_context {
static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) {
static const u32 kEsrMagic = 0x45535201;
- u8 *aux = ucontext->uc_mcontext.__reserved;
+ u8 *aux = (u8 *)ucontext->uc_mcontext.__reserved;
while (true) {
_aarch64_ctx *ctx = (_aarch64_ctx *)aux;
if (ctx->size == 0) break;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index 24902d1b6bcefb8dbb0de6dfe32e015078dce6bf..4aefab43b13c3fc4151c6c47a544b6853baeb7e3 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -116,7 +116,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() \
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index f20b9001c2c20b26f2b0f958ab972cbe91847937..fe9d80e0e465fe3f802d51fc60d99a288013ab55 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -75,7 +75,7 @@ struct __sanitizer::linux_dirent {
#endif
#endif
-#if !SANITIZER_ANDROID
+#if !SANITIZER_ANDROID && !SANITIZER_OHOS
#include
#include
#endif
@@ -803,7 +803,7 @@ void LogMessageOnPrintf(const char *str) {
#endif // SANITIZER_LINUX
-#if SANITIZER_LINUX && !SANITIZER_GO
+#if SANITIZER_LINUX && !SANITIZER_GO && !SANITIZER_OHOS
// glibc crashes when using clock_gettime from a preinit_array function as the
// vDSO function pointers haven't been initialized yet. __progname is
// initialized after the vDSO function pointers, so if it exists, is not null
@@ -839,7 +839,11 @@ u64 MonotonicNanoTime() {
// Non-Linux & Go always use the syscall.
u64 MonotonicNanoTime() {
timespec ts;
+#if SANITIZER_OHOS
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+#else
internal_clock_gettime(CLOCK_MONOTONIC, &ts);
+#endif
return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
}
#endif // SANITIZER_LINUX && !SANITIZER_GO
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
index 96c01bad870d1642b5b33870c90b6792d45a79c9..8f5f59b34366b616fecf11c9f5f3148390d163c8 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -13,9 +13,9 @@
#define SANITIZER_PLATFORM_H
#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
- !defined(__APPLE__) && !defined(_WIN32) && \
- !defined(__Fuchsia__) && !defined(__rtems__) && \
- !(defined(__sun__) && defined(__svr4__))
+ !defined(__APPLE__) && !defined(_WIN32) && !defined(__OHOS_FAMILY__) && \
+ !defined(__Fuchsia__) && !defined(__rtems__) && \
+ !(defined(__sun__) && defined(__svr4__))
# error "This operating system is not supported"
#endif
@@ -105,6 +105,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
@@ -238,7 +244,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__)
# define SANITIZER_CAN_USE_ALLOCATOR64 0
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 068fc9829e57db3f6056a04d13d936e49877beb7..70e8a2c197fa58cbab0aecf4d77cb07e61ef17e3 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
@@ -271,7 +277,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)
@@ -341,8 +347,9 @@
#define SANITIZER_INTERCEPT_ETHER_HOST \
(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) || \
+#define SANITIZER_INTERCEPT_SHMCTL \
+ (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && !SI_OHOS && \
+ SANITIZER_WORDSIZE == 64) || \
SI_NETBSD || SI_SOLARIS) // NOLINT
#define SANITIZER_INTERCEPT_RANDOM_R SI_GLIBC
#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX
@@ -464,7 +471,7 @@
#define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX
#define SANITIZER_INTERCEPT_STAT \
- (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS)
+ (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || SI_OHOS)
#define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX)
#define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID
@@ -494,7 +501,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
@@ -505,7 +512,7 @@
#define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_GETGROUPLIST SI_NETBSD
#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 c51327e1269e081cb0e231b75cbce71b62601e88..470f6ebf8d38f24afa32290e2aa4e84aaf2071d9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp
@@ -59,7 +59,7 @@ using namespace __sanitizer;
namespace __sanitizer {
#if !SANITIZER_ANDROID
- unsigned struct_statfs64_sz = sizeof(struct statfs64);
+unsigned struct_statfs64_sz = sizeof(struct statfs64);
#endif
} // namespace __sanitizer
@@ -81,7 +81,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);
@@ -90,7 +90,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 7abaeb880bf347dee2490b1eb8b0295adfa8bb9c..c4a1b2807a84eff72dbedb2e17bd48ec97e06321 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
@@ -91,8 +93,17 @@
#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__) || \
SANITIZER_RISCV64
+
# include
# ifdef __arm__
typedef struct user_fpregs elf_fpregset_t;
@@ -131,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
@@ -251,7 +269,7 @@ namespace __sanitizer {
unsigned struct_rlimit64_sz = sizeof(struct rlimit64);
unsigned struct_statvfs64_sz = sizeof(struct statvfs64);
unsigned struct_crypt_data_sz = sizeof(struct crypt_data);
-#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
+#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned struct_timex_sz = sizeof(struct timex);
@@ -269,7 +287,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);
@@ -483,7 +500,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_MAC
+#if !SANITIZER_ANDROID && !SANITIZER_MAC && !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
@@ -536,7 +553,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
@@ -820,7 +837,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;
@@ -904,7 +921,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;
@@ -1072,7 +1089,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
@@ -1166,7 +1184,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 8a156b7fcb80aed32fdeaf773c4ca3e60d3dc97a..f4294a74f8e24274f5d1d56927b45f7a52efabda 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -188,13 +188,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;
@@ -367,7 +369,7 @@ struct __sanitizer_group {
char **gr_mem;
};
-#if defined(__x86_64__) && !defined(_LP64)
+#if SANITIZER_OHOS || (defined(__x86_64__) && !defined(_LP64))
typedef long long __sanitizer_time_t;
#else
typedef long __sanitizer_time_t;
@@ -475,7 +477,7 @@ struct __sanitizer_dirent {
unsigned short d_reclen;
// more fields that we don't care about
};
-#elif SANITIZER_ANDROID || defined(__x86_64__)
+#elif SANITIZER_ANDROID || defined(__x86_64__) || SANITIZER_OHOS
struct __sanitizer_dirent {
unsigned long long d_ino;
unsigned long long d_off;
@@ -601,7 +603,7 @@ struct __sanitizer_sigaction {
uptr sa_flags;
void (*sa_restorer)();
};
-#else // !SANITIZER_ANDROID
+#else // !SANITIZER_ANDROID
struct __sanitizer_sigaction {
#if defined(__mips__) && !SANITIZER_FREEBSD
unsigned int sa_flags;
@@ -779,7 +781,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;
@@ -803,7 +805,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)
@@ -981,7 +983,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;
@@ -1002,12 +1004,12 @@ extern unsigned struct_unimapinit_sz;
extern const unsigned long __sanitizer_bufsiz;
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS
extern unsigned struct_audio_buf_info_sz;
extern unsigned struct_ppp_stats_sz;
#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
-#if !SANITIZER_ANDROID && !SANITIZER_MAC
+#if !SANITIZER_ANDROID && !SANITIZER_MAC && !SANITIZER_OHOS
extern unsigned struct_sioc_sg_req_sz;
extern unsigned struct_sioc_vif_req_sz;
#endif
@@ -1062,7 +1064,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
@@ -1326,7 +1328,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 2e080098283fde0dc5e525a388d8d65a2f6078e7..01860a9c1704e6467b82f62cd202167d32ee73e0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
@@ -341,7 +341,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;
@@ -373,7 +373,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 12603da1750d155c0b4bc525411b1bcb485da57c..a5e3b4d76e2d58bf0ffd342e75072532705e7620 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -177,7 +177,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 44a95214e38bfeb91dfea21f869cc0bce206b0d5..38af2748c9ba57f3dd14f1908dd705a14b204c1c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp
@@ -26,7 +26,8 @@ struct StackDepotNode {
u32 tag;
uptr stack[1]; // [size]
- static const u32 kTabSizeLog = SANITIZER_ANDROID ? 16 : 20;
+ static const u32 kTabSizeLog =
+ (SANITIZER_ANDROID || SANITIZER_OHOS) ? 16 : 20;
// Lower kTabSizeLog bits are equal for all items in one bucket.
// We use these bits to store the per-stack use counter.
static const u32 kUseCountBits = kTabSizeLog;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h
index 0e26c1fc37c49099aa28487d1af09076e6282a72..3e6c0b9d4691f904831bacd1637df75e7adfc297 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_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
index 53cfddcfbe0bebf00be9b43ebd9d2c5bedf07488..0735b93c9a23a008918a6ad9f627e3f245e6c649 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
@@ -33,6 +33,11 @@
#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
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp
index c99a6ceaa5623f200611b5a3543eac5f0c395efa..ff72a823b960ace8e5fba3533a5c41da5dfb5b52 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) {
-#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID)
+#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID) && !SANITIZER_OHOS
if ((prot & (PROT_WRITE | PROT_EXEC)) != (PROT_WRITE | PROT_EXEC))
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 b2628dcc4dc1f68b1799f3a60021ae33aced9584..18178cd69eb5cfb4600961e41317d82be9cd8589 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 855fac4f039f650c26990bc3a104a6fc2523581c..c8b2152b373cc002d9ad2e8b06b6c7f6caf85e20 100644
--- a/compiler-rt/test/asan/CMakeLists.txt
+++ b/compiler-rt/test/asan/CMakeLists.txt
@@ -132,7 +132,7 @@ if(COMPILER_RT_INCLUDE_TESTS)
${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic/lit.site.cfg.py)
endif()
# FIXME: support unit test in the android test runner
- if (NOT ANDROID)
+ if (NOT ANDROID AND NOT OHOS_FAMILY)
list(APPEND ASAN_TEST_DEPS AsanUnitTests)
list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit)
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/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 4f56c886e92e3cbc5a265062d5131773bc032de4..8be427f7ba1ad4c568776bd073521d27ca745c0e 100644
--- a/compiler-rt/test/asan/lit.cfg.py
+++ b/compiler-rt/test/asan/lit.cfg.py
@@ -247,7 +247,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 30cfdbee13e20b6cd6767b8ba24a46f8ed79e849..c28b2cea07ac2dd59c17696c26aaff5927380ee8 100644
--- a/compiler-rt/test/lit.common.cfg.py
+++ b/compiler-rt/test/lit.common.cfg.py
@@ -12,6 +12,9 @@ import json
import lit.formats
import lit.util
+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")
@@ -117,10 +120,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):
@@ -136,13 +139,26 @@ emulator = get_lit_conf('emulator', None)
# 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,
@@ -203,20 +219,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
@@ -227,7 +243,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:
@@ -329,12 +345,12 @@ if config.host_os == 'Darwin':
for vers in min_macos_deployment_target_substitutions:
flag = config.apple_platform_min_deployment_target_flag
major, minor = get_macos_aligned_version(vers)
- config.substitutions.append( ('%%min_macos_deployment_target=%s.%s' % vers, '{}={}.{}'.format(flag, major, minor)) )
+ config.substitutions.append(('%%min_macos_deployment_target=%s.%s' % vers, '{}={}.{}'.format(flag, major, minor)))
else:
for vers in min_macos_deployment_target_substitutions:
- config.substitutions.append( ('%%min_macos_deployment_target=%s.%s' % vers, '') )
+ config.substitutions.append(('%%min_macos_deployment_target=%s.%s' % vers, ''))
-if config.android:
+if config.android or is_ohos_family_mobile():
env = os.environ.copy()
if config.android_serial:
env['ANDROID_SERIAL'] = config.android_serial
@@ -345,21 +361,25 @@ 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( ('%pull_from_device', "%s -s '%s' pull " % (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( ('%pull_from_device', "%s -s '%s' pull " % (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")
+ 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))
+ if config.android_api_level:
+ android_api_level = min(android_api_level, int(config.android_api_level))
for required in [26, 28, 30]:
if android_api_level >= required:
config.available_features.add('android-%s' % required)
@@ -507,7 +527,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':
@@ -546,7 +566,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 5653bcd90caa620dfc2ee5f8006bab563fd736de..957226a918881d04924065584729b85612c9dc6b 100644
--- a/compiler-rt/test/lit.common.configured.in
+++ b/compiler-rt/test/lit.common.configured.in
@@ -40,6 +40,7 @@ set_default("use_thinlto", False)
set_default("use_lto", config.use_thinlto)
set_default("use_newpm", False)
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 100644
index 0000000000000000000000000000000000000000..e38f7a48518999989e5115b93b71ad3c87068f58
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py
@@ -0,0 +1,45 @@
+import os, subprocess, tempfile
+
+OHOS_TMPDIR = '/data/local/tmp/Output'
+ADB = os.environ.get('ADB', 'adb')
+
+verbose = False
+if os.environ.get('OHOS_RUN_VERBOSE') == '1':
+ verbose = True
+
+def host_to_device_path(path):
+ rel = os.path.relpath(path, "/")
+ dev = os.path.join(OHOS_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 100644
index 0000000000000000000000000000000000000000..bc5cd811ebb2116b87a20e6d3d9e566a49e74b6f
--- /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]))
+ohos_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_ohos_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(OHOS_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(ohos_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 100644
index 0000000000000000000000000000000000000000..b5605e615dc33674327a9c88e229f539c8045723
--- /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' % (OHOS_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' %
+ (OHOS_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/data/llvm_build.png b/data/llvm_build.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7f0bdb0c100cf88771a169dc06772109799650d
Binary files /dev/null and b/data/llvm_build.png differ
diff --git a/data/one_time_setup.png b/data/one_time_setup.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d7573173460eedb09eef86edbf8562c687c40f4
Binary files /dev/null and b/data/one_time_setup.png differ
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index cdd5495e36ab02da2bda36ac317a38f8132f6eb5..25ce254649a9ad15a0be6a14e9a0011be4a44ca3 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -400,9 +400,17 @@ endif ()
#===============================================================================
if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
- set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
- set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR})
- set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ if(OHOS)
+ set(LIBCXX_LIBRARY_DIR
+ ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/${LLVM_TARGET_MULTILIB_SUFFIX})
+ set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR})
+ set(LIBCXX_INSTALL_LIBRARY_DIR
+ lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/${LLVM_TARGET_MULTILIB_SUFFIX})
+ else()
+ set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR})
+ set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ 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 894f637f814ffbdcf3619c7581098fa3159c4caa..991efe0c25d586d907b9be33566ff29678ca2e96 100644
--- a/libcxx/cmake/config-ix.cmake
+++ b/libcxx/cmake/config-ix.cmake
@@ -93,6 +93,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 a3838c89e8e168c605708f7866b198fcc42eb457..384d59700132e8157c362b707b6f1a5c7d3c4466 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1132,6 +1132,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
defined(__CloudABI__) || \
defined(__sun__) || \
defined(__MVS__) || \
+ defined(__OHOS_FAMILY__) || \
(defined(__MINGW32__) && __has_include())
# define _LIBCPP_HAS_THREAD_API_PTHREAD
# elif defined(__Fuchsia__)
@@ -1226,7 +1227,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
# endif
#endif
-#if defined(__BIONIC__) || defined(__CloudABI__) || defined(__NuttX__) || \
+#if defined(__BIONIC__) || defined(__CloudABI__) || defined(__OHOS_FAMILY__) || \
defined(__Fuchsia__) || defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) || \
defined(__MVS__) || defined(__OpenBSD__)
#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index 77e5faab2676ddf2b75f56a9a0f88fa14af23b53..9d6a901898e2f3151f7d5b47dbd8f44088dd3355 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -43,6 +43,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/include/atomic b/libcxx/include/atomic
index 0fc799a243190a56bacc0539f635304e66e3a46b..57d01ad2791a8f4dfff3670bdb05b9a11dab0c84 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -2791,10 +2791,13 @@ typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::typ
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
#else
// No signed/unsigned lock-free types
+#define _LIBCPP_NO_LOCK_FREE_TYPES
#endif
+#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
+#endif
#define ATOMIC_FLAG_INIT {false}
#define ATOMIC_VAR_INIT(__v) {__v}
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 9965104cb5b23a2b472787722d14d544779a1e2e..f80c8e062526720547035c51e1768ca9a15d5f34 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -178,11 +178,14 @@ if (LIBCXX_ENABLE_SHARED)
add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
target_link_libraries(cxx_shared PUBLIC cxx-headers
PRIVATE ${LIBCXX_LIBRARIES})
+ if (NOT DEFINED LIBCXX_OUTPUT_NAME)
+ set (LIBCXX_OUTPUT_NAME "c++")
+ endif()
set_target_properties(cxx_shared
PROPERTIES
COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
LINK_FLAGS "${LIBCXX_LINK_FLAGS}"
- OUTPUT_NAME "c++"
+ OUTPUT_NAME "${LIBCXX_OUTPUT_NAME}"
VERSION "${LIBCXX_ABI_VERSION}.0"
SOVERSION "${LIBCXX_ABI_VERSION}"
DEFINE_SYMBOL ""
@@ -254,11 +257,14 @@ if (LIBCXX_ENABLE_STATIC)
target_link_libraries(cxx_static PUBLIC cxx-headers
PRIVATE ${LIBCXX_LIBRARIES})
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+ if (NOT DEFINED LIBCXX_OUTPUT_STATIC_NAME)
+ set (LIBCXX_OUTPUT_STATIC_NAME "c++")
+ endif()
set_target_properties(cxx_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 3113f9fb5cd17eee67d99d2cd5575393e528a1ee..91b4de27f7680d5da1e85ba1cd616ff3c7139a45 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 LiteOS
#elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC)
#define _LIBCPP_ELAST 4095
#elif defined(__APPLE__)
diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt
index 6de2b5a2ed1039987814282c54bf5e513b49cc44..981d0c583485e402fd935d7be88608dd38c68b57 100644
--- a/libcxxabi/CMakeLists.txt
+++ b/libcxxabi/CMakeLists.txt
@@ -179,8 +179,15 @@ set(CMAKE_MODULE_PATH
)
if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
- set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
- set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ if(OHOS)
+ set(LIBCXXABI_LIBRARY_DIR
+ ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/${LLVM_TARGET_MULTILIB_SUFFIX})
+ set(LIBCXXABI_INSTALL_LIBRARY_DIR
+ lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/${LLVM_TARGET_MULTILIB_SUFFIX})
+ else()
+ set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ endif()
if(LIBCXX_LIBDIR_SUBDIR)
string(APPEND LIBCXXABI_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR})
string(APPEND LIBCXXABI_INSTALL_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR})
@@ -464,7 +471,7 @@ if (LIBCXXABI_BAREMETAL)
add_definitions(-DLIBCXXABI_BAREMETAL)
endif()
-if (LIBCXXABI_HAS_COMMENT_LIB_PRAGMA)
+if (LIBCXXABI_HAS_COMMENT_LIB_PRAGMA AND NOT OHOS)
if (LIBCXXABI_HAS_PTHREAD_LIB)
add_definitions(-D_LIBCXXABI_LINK_PTHREAD_LIB)
endif()
diff --git a/libcxxabi/src/abort_message.cpp b/libcxxabi/src/abort_message.cpp
index ad44063facb71b8f1f83ed99727e1d616e562cd2..e2a53cc708783e2e441bbae88ae8185a93973afa 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 570b8db906532d4ea97bc04fbcf5467929e52146..a9320d96520700dd4d5b735487bd015b68238d22 100644
--- a/libunwind/CMakeLists.txt
+++ b/libunwind/CMakeLists.txt
@@ -114,8 +114,15 @@ set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH})
if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
- set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
- set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ 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})
+ else()
+ set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
+ endif()
if(LIBCXX_LIBDIR_SUBDIR)
string(APPEND LIBUNWIND_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR})
string(APPEND LIBUNWIND_INSTALL_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR})
@@ -327,7 +334,7 @@ if (LIBUNWIND_HAS_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 c84b5f5bdfda1b3465bcb244601c04765191f54d..39b7ec18cc3fad9fe9539f22ced690c03267592f 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -263,6 +263,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 3b2a8ba192933d5451f94062a1d4143daaa7fa30..a41a7d1b8dc42567ad76601213ec73297a944f08 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -62,6 +62,7 @@
#include "llvm/Support/raw_ostream.h"
#include
#include
+#include
using namespace llvm;
using namespace llvm::ELF;
@@ -925,6 +926,48 @@ static void parseClangOption(StringRef opt, const Twine &msg) {
error(msg + ": " + StringRef(err).trim());
}
+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);
@@ -1002,8 +1045,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->ltoPseudoProbeForProfiling =
args.hasArg(OPT_lto_pseudo_probe_for_profiling);
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index b3d4b7dee9f8ee725bac59901305148331f07eb0..9381509542ad8664a918a6f9e25b0509498a5699 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -129,6 +129,8 @@ static lto::Config createConfig() {
c.DisableVerify = config->disableVerify;
c.DiagHandler = diagnosticHandler;
c.OptLevel = config->ltoo;
+ c.SizeLevel = config->ltos;
+ c.MergeFunctions = config->mergeFunctions;
c.CPU = getCPUStr();
c.MAttrs = getMAttrs();
c.CGOptLevel = args::getCGOptLevel(config->ltoo);
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 65ef3e824f50d9d855ac360d23e0ef501d1bdbbf..e6d77f21d027095d1cc63f20f4b1cdc9222262b3 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -538,6 +538,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/CMakeLists.txt b/lldb/CMakeLists.txt
index b5633e21c56a39bd539c3bc4316978fc2988eadb..7448c99de72aa1baa37db4475ab67f7e36dfb5aa 100644
--- a/lldb/CMakeLists.txt
+++ b/lldb/CMakeLists.txt
@@ -31,13 +31,21 @@ if (WIN32)
endif()
if (LLDB_ENABLE_PYTHON)
- execute_process(
- COMMAND ${Python3_EXECUTABLE}
- -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(True, False, ''))"
- OUTPUT_VARIABLE LLDB_PYTHON_DEFAULT_RELATIVE_PATH
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- file(TO_CMAKE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH} LLDB_PYTHON_DEFAULT_RELATIVE_PATH)
+ if (NOT CMAKE_CROSSCOMPILING)
+ execute_process(
+ COMMAND ${Python3_EXECUTABLE}
+ -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(True, False, ''))"
+ OUTPUT_VARIABLE LLDB_PYTHON_DEFAULT_RELATIVE_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ file(TO_CMAKE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH} LLDB_PYTHON_DEFAULT_RELATIVE_PATH)
+ else ()
+ if ("${LLDB_PYTHON_RELATIVE_PATH}" STREQUAL "")
+ message(FATAL_ERROR
+ "Crosscompiling LLDB with Python requires manually setting
+ LLDB_PYTHON_RELATIVE_PATH.")
+ endif ()
+ endif ()
set(LLDB_PYTHON_RELATIVE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH}
CACHE STRING "Path where Python modules are installed, relative to install prefix")
endif ()
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 2fdf1502d0559b0451f50015fd5dc089638e7fbe..a50f6ce7c3157b68210a91c8e53e8097900fa84c 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -295,7 +295,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 9ca5040b60a89b7c88e66ac75e59434b083ec871..e26b8c8cb61b0418b56258c9ae7018b861836700 100644
--- a/lldb/include/lldb/Host/MainLoop.h
+++ b/lldb/include/lldb/Host/MainLoop.h
@@ -14,7 +14,8 @@
#include "llvm/ADT/DenseMap.h"
#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/PathMappingList.h b/lldb/include/lldb/Target/PathMappingList.h
index 9e1e6eb26eb9b534b45e6a2fe6959a27bace65cc..fc7b23bcfad33f76424f69af01cea2ee26b67846 100644
--- a/lldb/include/lldb/Target/PathMappingList.h
+++ b/lldb/include/lldb/Target/PathMappingList.h
@@ -72,13 +72,9 @@ public:
/// \param[in] path
/// The original source file path to try and remap.
///
- /// \param[out] new_path
- /// The newly remapped filespec that is may or may not exist.
- ///
/// \return
- /// /b true if \a path was successfully located and \a new_path
- /// is filled in with a new source path, \b false otherwise.
- bool RemapPath(llvm::StringRef path, std::string &new_path) const;
+ /// The remapped filespec that may or may not exist on disk.
+ llvm::Optional RemapPath(llvm::StringRef path) const;
bool RemapPath(const char *, std::string &) const = delete;
bool ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const;
@@ -94,14 +90,9 @@ public:
/// \param[in] orig_spec
/// The original source file path to try and remap.
///
- /// \param[out] new_spec
- /// The newly remapped filespec that is guaranteed to exist.
- ///
/// \return
- /// /b true if \a orig_spec was successfully located and
- /// \a new_spec is filled in with an existing file spec,
- /// \b false otherwise.
- bool FindFile(const FileSpec &orig_spec, FileSpec &new_spec) const;
+ /// The newly remapped filespec that is guaranteed to exist.
+ llvm::Optional FindFile(const FileSpec &orig_spec) const;
uint32_t FindIndexForPath(ConstString path) const;
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 ff445fa0b926e88890b9e569cf9fedb494cef5be..f66cb7f1d6d0a051f5f48a3251a0a0538ef98a54 100644
--- a/lldb/packages/Python/lldbsuite/test/decorators.py
+++ b/lldb/packages/Python/lldbsuite/test/decorators.py
@@ -641,6 +641,9 @@ def skipIfPlatform(oslist):
return unittest2.skipIf(lldbplatformutil.getPlatform() in oslist,
"skip on %s" % (", ".join(oslist)))
+def skipOnHuaweiCI(func):
+ return unittest2.skipIf(lldbplatformutil.isHuaweiCI(), "skip on Huawei 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 94b133589dcc5aeda9d613dfeb3808d6ac50b0a2..d1dfcde78c445204179c135680cd26ae8b1b9c45 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py
@@ -152,6 +152,8 @@ def getPlatform():
# It still might be an unconnected remote platform.
return ''
+def isHuaweiCI():
+ return getPlatform() == 'linux' and os.path.exists('/.dockerenv')
def platformIsDarwin():
"""Returns true if the OS triple for the selected platform is any valid apple OS"""
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 958cadd3a7c8120020402877c54a55ce41901d5b..964bcfdd1cffead89401400705809d436a803dbe 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -804,11 +804,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/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 1f9987c216588eb0c70753174193e456c1daa082..17cfaa79e6407069550d35750655c7d8ffb1f0d9 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1595,13 +1595,21 @@ bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {
bool Module::FindSourceFile(const FileSpec &orig_spec,
FileSpec &new_spec) const {
std::lock_guard guard(m_mutex);
- return m_source_mappings.FindFile(orig_spec, new_spec);
+ if (auto remapped = m_source_mappings.FindFile(orig_spec)) {
+ new_spec = *remapped;
+ return true;
+ }
+ return false;
}
bool Module::RemapSourceFile(llvm::StringRef path,
std::string &new_path) const {
std::lock_guard guard(m_mutex);
- return m_source_mappings.RemapPath(path, new_path);
+ if (auto remapped = m_source_mappings.RemapPath(path)) {
+ new_path = remapped->GetPath();
+ return true;
+ }
+ return false;
}
void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) {
diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp
index e79fcb48742d8c43d8156491d1fd5fbf04338a99..61cf919635577d1c1452429052139cdffd5c2ca6 100644
--- a/lldb/source/Core/SourceManager.cpp
+++ b/lldb/source/Core/SourceManager.cpp
@@ -441,13 +441,17 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec,
}
// Try remapping if m_file_spec does not correspond to an existing file.
if (!FileSystem::Instance().Exists(m_file_spec)) {
- FileSpec new_file_spec;
- // Check target specific source remappings first, then fall back to
- // modules objects can have individual path remappings that were
- // detected when the debug info for a module was found. then
- if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) ||
- target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) {
- m_file_spec = new_file_spec;
+ // Check target specific source remappings (i.e., the
+ // target.source-map setting), then fall back to the module
+ // specific remapping (i.e., the .dSYM remapping dictionary).
+ auto remapped = target->GetSourcePathMap().FindFile(m_file_spec);
+ if (!remapped) {
+ FileSpec new_spec;
+ if (target->GetImages().FindSourceFile(m_file_spec, new_spec))
+ remapped = new_spec;
+ }
+ if (remapped) {
+ m_file_spec = *remapped;
m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec);
}
}
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp
index b87a759aadc58a00974ad8a02d5bb572437074bb..f892bb3dbd9bf16b4665db62ee9a0f491d1ab6a2 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -166,6 +166,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))
@@ -188,9 +200,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;
@@ -204,11 +225,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());
@@ -534,16 +559,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());
@@ -552,11 +578,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:
@@ -586,6 +618,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) {
@@ -701,7 +738,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) {
@@ -740,12 +781,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:
@@ -758,6 +802,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();
@@ -1020,10 +1067,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);
@@ -1051,9 +1099,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:
@@ -1066,16 +1116,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 7456cb98bfa198af0e4be4a54855b4fe370af5b2..1cf30c20a030edf92cde3312b5edcd93fcc9b675 100644
--- a/lldb/source/Host/CMakeLists.txt
+++ b/lldb/source/Host/CMakeLists.txt
@@ -99,7 +99,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
@@ -113,6 +113,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 02cabbc93550a639bfd99f60eb3b139ef890306e..fc8b94309b09bff659171c1c8d50825d1969fd33 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 4bcf34a6b45673332ab2f72948d47710f8068758..f4037da059e525e90c78d1dba009a4af39c081d4 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 ea7377edbd4546298a376e110cc480b0959e4089..c9f4db5fae49179c718ec935fc6c43e4f1f31f1c 100644
--- a/lldb/source/Host/common/TCPSocket.cpp
+++ b/lldb/source/Host/common/TCPSocket.cpp
@@ -162,6 +162,8 @@ Status TCPSocket::Connect(llvm::StringRef name) {
std::vector addresses = SocketAddress::GetAddressInfo(
host_str.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 5a396906fdf6cfd711c3c3e44fb8d72f3718d5e6..97e8d4859e14caeb89c1b5dab0a26c684dddced2 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 7e110f07d7cfadddc8b7a5884cf254e3f4fd6334..cbfdf60a0a0a4dae16eb659a67b5752340e4411b 100644
--- a/lldb/source/Host/posix/HostInfoPosix.cpp
+++ b/lldb/source/Host/posix/HostInfoPosix.cpp
@@ -86,7 +86,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/Host/posix/ProcessLauncherPosixFork.cpp b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
index 35482341d3e6af4631b1ab5d99408db0344dc139..de622473272ac995c43f864d30848cfb010ed7d1 100644
--- a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
+++ b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
@@ -38,7 +38,7 @@ using namespace lldb;
using namespace lldb_private;
static void FixupEnvironment(Environment &env) {
-#ifdef __ANDROID__
+#if defined(__ANDROID__)
// If there is no PATH variable specified inside the environment then set the
// path to /system/bin. It is required because the default path used by
// execve() is wrong on android.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 9be294750fa03673ac98df899486edbb329b54cd..7e0da5663b37236920f086c3c55531b898e2e034 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -519,7 +519,7 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
// Try to create a configuration from the files. If there is no valid
// configuration possible with the files, this just returns an invalid
// configuration.
- return CppModuleConfiguration(files);
+ return CppModuleConfiguration(files, target->GetArchitecture().GetTriple());
}
bool ClangUserExpression::PrepareForParsing(
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
index ffab16b1682bee2e7bbbff8b838d8cede9de5778..7148a7c236d65f81a19447fe88af85e48f6b190a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -10,6 +10,7 @@
#include "ClangHost.h"
#include "lldb/Host/FileSystem.h"
+#include "llvm/ADT/Triple.h"
using namespace lldb_private;
@@ -30,7 +31,29 @@ bool CppModuleConfiguration::SetOncePath::TrySet(llvm::StringRef path) {
return false;
}
-bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
+static std::string targetSpecificIncludePath(const llvm::Triple &triple) {
+ if (triple.getArchName().empty() || triple.getOSAndEnvironmentName().empty())
+ return "";
+ return ("/usr/include/" + triple.getArchName() + "-" +
+ triple.getOSAndEnvironmentName())
+ .str();
+}
+
+static bool guessIncludePath(llvm::StringRef pathToFile,
+ llvm::StringRef pattern, llvm::StringRef &result) {
+ result = llvm::StringRef();
+ if (pattern.empty())
+ return false;
+ size_t pos = pathToFile.find(pattern);
+ if (pos == llvm::StringRef::npos)
+ return false;
+
+ result = pathToFile.substr(0, pos + pattern.size());
+ return true;
+}
+
+bool CppModuleConfiguration::analyzeFile(const FileSpec &f,
+ const llvm::Triple &triple) {
using namespace llvm::sys::path;
// Convert to slashes to make following operations simpler.
std::string dir_buffer = convert_to_slash(f.GetDirectory().GetStringRef());
@@ -46,12 +69,12 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
return m_std_inc.TrySet(posix_dir);
}
- // Check for /usr/include. On Linux this might be /usr/include/bits, so
- // we should remove that '/bits' suffix to get the actual include directory.
- if (posix_dir.endswith("/usr/include/bits"))
- posix_dir.consume_back("/bits");
- if (posix_dir.endswith("/usr/include"))
- return m_c_inc.TrySet(posix_dir);
+ llvm::StringRef inc_path;
+ // Target specific path contains /usr/include, so we check it first
+ if (guessIncludePath(posix_dir, targetSpecificIncludePath(triple), inc_path))
+ return m_c_target_inc.TrySet(inc_path);
+ if (guessIncludePath(posix_dir, "/usr/include", inc_path))
+ return m_c_inc.TrySet(inc_path);
// File wasn't interesting, continue analyzing.
return true;
@@ -92,11 +115,11 @@ bool CppModuleConfiguration::hasValidConfig() {
}
CppModuleConfiguration::CppModuleConfiguration(
- const FileSpecList &support_files) {
+ const FileSpecList &support_files, const llvm::Triple &triple) {
// Analyze all files we were given to build the configuration.
bool error = !llvm::all_of(support_files,
std::bind(&CppModuleConfiguration::analyzeFile,
- this, std::placeholders::_1));
+ this, std::placeholders::_1, triple));
// If we have a valid configuration at this point, set the
// include directories and module list that should be used.
if (!error && hasValidConfig()) {
@@ -109,6 +132,8 @@ CppModuleConfiguration::CppModuleConfiguration(
// This order matches the way Clang orders these directories.
m_include_dirs = {m_std_inc.Get().str(), m_resource_inc,
m_c_inc.Get().str()};
+ if (m_c_target_inc.Valid())
+ m_include_dirs.push_back(m_c_target_inc.Get().str());
m_imported_modules = {"std"};
}
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
index b984db43fa6d3ff5deca3a513fd6c987c4d1b017..60199005b6bab1c2cbdeebd693d02accc6803174 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -44,6 +44,9 @@ class CppModuleConfiguration {
SetOncePath m_std_inc;
/// If valid, the include path to the C library (e.g. /usr/include).
SetOncePath m_c_inc;
+ /// If valid, the include path to target-specific C library files
+ /// (e.g. /usr/include/x86_64-linux-gnu).
+ SetOncePath m_c_target_inc;
/// The Clang resource include path for this configuration.
std::string m_resource_inc;
@@ -53,11 +56,12 @@ class CppModuleConfiguration {
/// Analyze a given source file to build the current configuration.
/// Returns false iff there was a fatal error that makes analyzing any
/// further files pointless as the configuration is now invalid.
- bool analyzeFile(const FileSpec &f);
+ bool analyzeFile(const FileSpec &f, const llvm::Triple &triple);
public:
/// Creates a configuration by analyzing the given list of used source files.
- explicit CppModuleConfiguration(const FileSpecList &support_files);
+ explicit CppModuleConfiguration(const FileSpecList &support_files,
+ const llvm::Triple &triple);
/// Creates an empty and invalid configuration.
CppModuleConfiguration() {}
diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt
index 5f284e517dcac6d46203ff158fcce3dbf2ea77e2..8c532955a9ddc2272f2232792f2695914b8853f0 100644
--- a/lldb/source/Plugins/Platform/CMakeLists.txt
+++ b/lldb/source/Plugins/Platform/CMakeLists.txt
@@ -15,3 +15,4 @@
add_subdirectory(POSIX)
add_subdirectory(gdb-server)
add_subdirectory(Android)
+add_subdirectory(OHOS)
diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 2cb671fd4dc39a66faf9cfe7abe7279849c4244a..9cdc9d5f434c6f8f7ecfe5c5078d22d6e5b1242b 100644
--- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -97,7 +97,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..6807d24cf317f4dc4a38769f57f1ea648b702110
--- /dev/null
+++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp
@@ -0,0 +1,399 @@
+//===-- 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("Remove forward ruler success");
+}
+
+Status HdcClient::DeletePortForwarding(const uint16_t local_port,
+ const std::string remote_socket_name,
+ const UnixSocketNamespace socket_namespace) {
+ const char *sock_namespace_str =
+ (socket_namespace == UnixSocketNamespaceAbstract)
+ ? kSocketNamespaceAbstract
+ : kSocketNamespaceFileSystem;
+ char message[PATH_MAX] = "";
+
+ snprintf(message, sizeof(message), "fport rm tcp:%d %s:%s", local_port,
+ sock_namespace_str, remote_socket_name.c_str());
+
+ const auto error = SendMessage(message);
+ if (error.Fail()){
+ return error;
+ }
+
+ return ReadResponseStatus("Remove forward ruler success");
+}
+
+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..39b6569b447a38007e48a2fee784855f82ff6603
--- /dev/null
+++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.h
@@ -0,0 +1,93 @@
+//===-- 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 DeletePortForwarding(const uint16_t local_port, const std::string remote_socket_name,
+ const UnixSocketNamespace socket_namespace);
+
+ 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..f76e016bb6aa4eed576eceac0d0f4b3efa726594
--- /dev/null
+++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp
@@ -0,0 +1,266 @@
+//===-- 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/Host/StringConvert.h"
+#include "lldb/Utility/Log.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(GetLogIfAllCategoriesSet(LIBLLDB_LOG_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() {}
+
+ConstString PlatformOHOS::GetPluginNameStatic(bool is_host) {
+ if (is_host) {
+ static ConstString g_host_name(Platform::GetHostPlatformName());
+ return g_host_name;
+ } else {
+ static ConstString g_remote_name("remote-ohos");
+ return g_remote_name;
+ }
+}
+
+const char *PlatformOHOS::GetPluginDescriptionStatic(bool is_host) {
+ if (is_host)
+ return "Local OpenHarmony OS user platform plug-in.";
+ else
+ return "Remote OpenHarmony OS user platform plug-in.";
+}
+
+ConstString 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().GetCString());
+ }
+
+ if (!m_remote_platform_sp)
+ m_remote_platform_sp = PlatformSP(new PlatformOHOSRemoteGDBServer());
+
+ int port;
+ llvm::StringRef scheme, host, path;
+ const char *url = args.GetArgumentAtIndex(0);
+ if (!url)
+ return Status("URL is null.");
+ if (!UriParser::Parse(url, scheme, host, port, path))
+ return Status("Invalid URL: %s", url);
+ if (host != "localhost")
+ m_device_id = static_cast(host);
+
+ 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..643b7ae3f75fdedf9f94c52c5aabcad629b39e3c
--- /dev/null
+++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h
@@ -0,0 +1,80 @@
+//===-- 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 ConstString GetPluginNameStatic(bool is_host);
+
+ static const char *GetPluginDescriptionStatic(bool is_host);
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ // 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..1b54c2cce2253389e29a7fd2f542c5ebcb1bd77a
--- /dev/null
+++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp
@@ -0,0 +1,282 @@
+//===-- 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/Log.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(GetLogIfAllCategoriesSet(LIBLLDB_LOG_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(GetLogIfAllCategoriesSet(LIBLLDB_LOG_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 DeleteForwardPortWithHdc(std::pair remote_socket,
+ const llvm::Optional &socket_namespace,
+ const std::string &device_id) {
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ uint16_t local_port = remote_socket.first;
+ std::string remote_socket_name = remote_socket.second;
+ if (log)
+ log->Printf("Delete port forwarding %d -> %s, device=%s", local_port,
+ remote_socket_name.c_str(), device_id.c_str());
+
+ HdcClient hdc(device_id);
+ return hdc.DeletePortForwarding(local_port, remote_socket_name, *socket_namespace);
+}
+
+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);
+ }
+ for (const auto &it_socket : m_remote_socket_name){
+ DeleteForwardPortWithHdc(it_socket.second, m_socket_namespace, 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.LaunchGDBServer("127.0.0.1", pid, remote_port, socket_name))
+ return false;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_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.KillSpawnedProcess(pid);
+}
+
+Status PlatformOHOSRemoteGDBServer::ConnectRemote(Args &args) {
+ m_device_id.clear();
+
+ if (args.GetArgumentCount() != 1)
+ return Status(
+ "\"platform connect\" takes a single argument: ");
+
+ int remote_port;
+ llvm::StringRef scheme, host, path;
+ const char *url = args.GetArgumentAtIndex(0);
+ if (!url)
+ return Status("URL is null.");
+ if (!UriParser::Parse(url, scheme, host, remote_port, path))
+ return Status("Invalid URL: %s", url);
+ if (host != "localhost")
+ m_device_id = static_cast(host);
+
+ m_socket_namespace.reset();
+ if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME)
+ m_socket_namespace = HdcClient::UnixSocketNamespaceFileSystem;
+ else if (scheme == ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME)
+ m_socket_namespace = HdcClient::UnixSocketNamespaceAbstract;
+
+ std::string connect_url;
+ auto error =
+ MakeConnectURL(g_remote_platform_pid, (remote_port < 0) ? 0 : remote_port,
+ path, connect_url);
+
+ if (error.Fail())
+ return error;
+
+ args.ReplaceArgumentAtIndex(0, connect_url);
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_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(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
+ auto it = m_port_forwards.find(pid);
+ auto it_socket = m_remote_socket_name.find(pid);
+ if (it != m_port_forwards.end() && it->second.second != 0){
+ const auto error = DeleteForwardPortWithHdc(it->second, m_device_id);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to delete port forwarding (pid=%" PRIu64
+ ", fwd=(%d -> %d), device=%s): %s",
+ pid, it->second.first, it->second.second, m_device_id.c_str(),
+ error.AsCString());
+ }
+ m_port_forwards.erase(it);
+ }
+
+ if(it_socket != m_remote_socket_name.end()){
+ const auto error_Socket = DeleteForwardPortWithHdc(it_socket->second, m_socket_namespace, m_device_id);
+ if (error_Socket.Fail()) {
+ if (log)
+ log->Printf("Failed to delete port forwarding (pid=%" PRIu64
+ ", fwd=(%d->%s)device=%s): %s", pid, it_socket->second.first, it_socket->second.second.c_str(), m_device_id.c_str(),error_Socket.AsCString());
+ }
+ m_remote_socket_name.erase(it_socket);
+ }
+
+ return;
+}
+
+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()) {
+ if (remote_port != 0){
+ m_port_forwards[pid] = {local_port, remote_port};
+ }
+ else{
+ m_remote_socket_name[pid] ={local_port, remote_socket_name.str()};
+ }
+ 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;
+
+ int remote_port;
+ llvm::StringRef scheme, host, path;
+ if (!UriParser::Parse(connect_url, scheme, host, remote_port, path)) {
+ error.SetErrorStringWithFormat("Invalid URL: %s",
+ connect_url.str().c_str());
+ return nullptr;
+ }
+
+ std::string new_connect_url;
+ error = MakeConnectURL(s_remote_gdbserver_fake_pid--,
+ (remote_port < 0) ? 0 : remote_port, 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..680ddc1e733c182c1cdbb64e45b802c8e6580103
--- /dev/null
+++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h
@@ -0,0 +1,65 @@
+//===-- 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