From 6c0df3bf58c26b8c310fa36c4f1336e5c77ffedf Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Wed, 3 Aug 2022 16:50:21 +0300 Subject: [PATCH 01/41] Port OHOS toolchain to LLVM-15 Signed-off-by: Ivan Eliseev --- clang/include/clang/Basic/Attr.td | 1 + clang/include/clang/Driver/Options.td | 2 + clang/include/clang/Driver/ToolChain.h | 3 +- clang/lib/Basic/TargetInfo.cpp | 2 +- clang/lib/Basic/Targets.cpp | 18 +- clang/lib/Basic/Targets/ARM.cpp | 2 +- clang/lib/Basic/Targets/OSTargets.h | 62 +++ clang/lib/Basic/Targets/X86.h | 22 + clang/lib/CodeGen/ABIInfo.h | 1 + clang/lib/CodeGen/TargetInfo.cpp | 8 +- clang/lib/Driver/CMakeLists.txt | 1 + clang/lib/Driver/Driver.cpp | 7 +- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 2 +- clang/lib/Driver/ToolChains/Arch/ARM.cpp | 4 + clang/lib/Driver/ToolChains/BareMetal.h | 2 +- clang/lib/Driver/ToolChains/Clang.cpp | 3 + clang/lib/Driver/ToolChains/CommonArgs.cpp | 19 +- clang/lib/Driver/ToolChains/Gnu.cpp | 6 +- clang/lib/Driver/ToolChains/OHOS.cpp | 422 ++++++++++++++++++ clang/lib/Driver/ToolChains/OHOS.h | 100 +++++ .../CodeGen/aarch64-fix-cortex-a53-835769.c | 2 + clang/test/CodeGen/arm64-abi-vector.c | 1 + clang/test/CodeGen/merge-functions.c | 22 + .../Inputs/ohos_native_tree/llvm/bin/.keep | 0 .../llvm/include/c++/v1/.keep | 0 .../a7_hard_neon-vfpv4/libc++.so | 0 .../lib/arm-liteos-ohos/a7_soft/libc++.so | 0 .../a7_softfp_neon-vfpv4/libc++.so | 0 .../llvm/lib/arm-liteos-ohos/libc++.so | 0 .../lib/clang/x.y.z/lib/arm-liteos-ohos/.keep | 0 .../arm-liteos-ohos/a7_hard_neon-vfpv4/.keep | 0 .../a7_hard_neon-vfpv4/clang_rt.crtbegin.o | 0 .../a7_hard_neon-vfpv4/clang_rt.crtend.o | 0 .../a7_hard_neon-vfpv4/libclang_rt.builtins.a | 0 .../a7_hard_neon-vfpv4/libclang_rt.profile.a | 0 .../x.y.z/lib/arm-liteos-ohos/a7_soft/.keep | 0 .../a7_soft/clang_rt.crtbegin.o | 0 .../arm-liteos-ohos/a7_soft/clang_rt.crtend.o | 0 .../a7_soft/libclang_rt.builtins.a | 0 .../a7_soft/libclang_rt.profile.a | 0 .../a7_softfp_neon-vfpv4/.keep | 0 .../a7_softfp_neon-vfpv4/clang_rt.crtbegin.o | 0 .../a7_softfp_neon-vfpv4/clang_rt.crtend.o | 0 .../libclang_rt.builtins.a | 0 .../libclang_rt.profile.a | 0 .../lib/arm-liteos-ohos/clang_rt.crtbegin.o | 0 .../lib/arm-liteos-ohos/clang_rt.crtend.o | 0 .../arm-liteos-ohos/libclang_rt.builtins.a | 0 .../lib/arm-liteos-ohos/libclang_rt.profile.a | 0 .../sysroot/usr/include/.keep | 0 .../sysroot/usr/include/arm-liteos-ohos/.keep | 0 .../ohos_native_tree/sysroot/usr/lib/.keep | 0 .../sysroot/usr/lib/arm-liteos-ohos/.keep | 0 .../arm-liteos-ohos/a7_hard_neon-vfpv4/.keep | 0 .../usr/lib/arm-liteos-ohos/a7_soft/.keep | 0 .../a7_softfp_neon-vfpv4/.keep | 0 clang/test/Driver/as-fno-integrated-as.c | 3 + clang/test/Driver/fenable-merge-functions.cpp | 28 ++ clang/test/Driver/ohos.c | 237 ++++++++++ clang/test/Driver/ohos.cpp | 121 +++++ clang/test/Preprocessor/ohos.c | 11 + clang/unittests/CMakeLists.txt | 4 +- .../Interpreter/ExceptionTests/CMakeLists.txt | 1 + compiler-rt/CMakeLists.txt | 32 +- compiler-rt/cmake/Modules/AddCompilerRT.cmake | 3 - .../cmake/Modules/AllSupportedArchDefs.cmake | 2 +- .../cmake/Modules/CompilerRTUtils.cmake | 12 +- compiler-rt/cmake/base-config-ix.cmake | 3 + compiler-rt/cmake/config-ix.cmake | 30 +- compiler-rt/cmake/crt-config-ix.cmake | 2 +- compiler-rt/lib/asan/asan_allocator.h | 2 +- compiler-rt/lib/asan/asan_internal.h | 2 +- compiler-rt/lib/asan/asan_linux.cpp | 7 +- compiler-rt/lib/asan/tests/asan_test.cpp | 4 +- compiler-rt/lib/builtins/divtf3.c | 2 +- compiler-rt/lib/builtins/fp_div_impl.inc | 2 +- compiler-rt/lib/builtins/int_util.h | 3 + compiler-rt/lib/cfi/CMakeLists.txt | 2 +- compiler-rt/lib/fuzzer/CMakeLists.txt | 2 +- compiler-rt/lib/hwasan/hwasan.cpp | 2 +- .../lib/hwasan/hwasan_dynamic_shadow.cpp | 2 +- compiler-rt/lib/interception/interception.h | 2 +- .../interception/interception_type_test.cpp | 4 +- compiler-rt/lib/orc/endianness.h | 3 +- .../sanitizer_common_interceptors.inc | 6 +- .../sanitizer_common_interceptors_ioctl.inc | 2 +- .../sanitizer_common_syscalls.inc | 4 +- .../lib/sanitizer_common/sanitizer_errno.h | 2 +- .../lib/sanitizer_common/sanitizer_flags.inc | 6 +- .../sanitizer_internal_defs.h | 3 +- .../lib/sanitizer_common/sanitizer_linux.cpp | 11 +- .../lib/sanitizer_common/sanitizer_linux.h | 2 +- .../sanitizer_linux_libcdep.cpp | 2 +- .../lib/sanitizer_common/sanitizer_platform.h | 11 +- .../sanitizer_platform_interceptors.h | 16 +- .../sanitizer_platform_limits_linux.cpp | 4 +- .../sanitizer_platform_limits_posix.cpp | 30 +- .../sanitizer_platform_limits_posix.h | 33 +- .../lib/sanitizer_common/sanitizer_posix.cpp | 4 +- .../sanitizer_posix_libcdep.cpp | 3 +- .../sanitizer_common/sanitizer_stackdepot.cpp | 2 +- .../sanitizer_common/sanitizer_stackdepot.h | 3 +- .../sanitizer_stoptheworld_linux_libcdep.cpp | 5 + .../sanitizer_symbolizer_report.cpp | 2 +- .../sanitizer_unwind_linux_libcdep.cpp | 2 +- compiler-rt/lib/scudo/scudo_flags.inc | 2 +- compiler-rt/lib/scudo/scudo_platform.h | 8 +- .../lib/ubsan/ubsan_signals_standalone.cpp | 2 +- .../asan/TestCases/Linux/lit.local.cfg.py | 2 +- .../test/asan/TestCases/Linux/odr_c_test.c | 2 +- .../test/asan/TestCases/Linux/shmctl.cpp | 4 +- compiler-rt/test/asan/lit.cfg.py | 2 +- compiler-rt/test/builtins/Unit/divtf3_test.c | 5 + compiler-rt/test/lit.common.cfg.py | 87 ++-- compiler-rt/test/lit.common.configured.in | 1 + .../ohos_family_commands/ohos_common.py | 45 ++ .../ohos_family_commands/ohos_compile.py | 52 +++ .../ohos_family_commands/ohos_run.py | 38 ++ libcxx/CMakeLists.txt | 14 +- libcxx/cmake/config-ix.cmake | 2 + libcxx/include/__config | 5 +- libcxx/include/__locale | 3 + libcxx/src/CMakeLists.txt | 10 +- libcxx/src/include/config_elast.h | 2 + libcxxabi/CMakeLists.txt | 14 +- libcxxabi/src/abort_message.cpp | 4 +- libunwind/CMakeLists.txt | 16 +- lld/ELF/Config.h | 2 + lld/ELF/Driver.cpp | 45 +- lld/ELF/Options.td | 4 + lld/test/ELF/lto/opt-level.ll | 6 +- lldb/cmake/modules/FindPythonAndSwig.cmake | 11 + lldb/cmake/modules/LLDBConfig.cmake | 2 +- lldb/include/lldb/Host/HostInfo.h | 3 + lldb/include/lldb/Host/MainLoop.h | 3 +- lldb/include/lldb/Host/ohos/HostInfoOHOS.h | 32 ++ .../include/lldb/Target/ThreadPlanStepRange.h | 1 + .../Python/lldbsuite/test/decorators.py | 3 + .../Python/lldbsuite/test/lldbplatformutil.py | 2 + .../Python/lldbsuite/test/lldbtest.py | 5 - lldb/source/Expression/IRInterpreter.cpp | 90 +++- lldb/source/Host/CMakeLists.txt | 7 +- lldb/source/Host/common/MainLoop.cpp | 8 +- lldb/source/Host/common/Socket.cpp | 2 +- lldb/source/Host/common/TCPSocket.cpp | 2 + lldb/source/Host/ohos/HostInfoOHOS.cpp | 94 ++++ lldb/source/Host/posix/DomainSocket.cpp | 2 +- lldb/source/Host/posix/HostInfoPosix.cpp | 2 +- lldb/source/Plugins/Platform/CMakeLists.txt | 1 + .../Plugins/Platform/Linux/PlatformLinux.cpp | 2 +- .../Plugins/Platform/OHOS/CMakeLists.txt | 13 + .../Plugins/Platform/OHOS/HdcClient.cpp | 379 ++++++++++++++++ lldb/source/Plugins/Platform/OHOS/HdcClient.h | 90 ++++ .../Plugins/Platform/OHOS/PlatformOHOS.cpp | 256 +++++++++++ .../Plugins/Platform/OHOS/PlatformOHOS.h | 77 ++++ .../OHOS/PlatformOHOSRemoteGDBServer.cpp | 246 ++++++++++ .../OHOS/PlatformOHOSRemoteGDBServer.h | 64 +++ lldb/source/Plugins/Process/CMakeLists.txt | 2 +- .../Linux/NativeRegisterContextLinux_arm64.h | 5 + lldb/source/Plugins/Process/Linux/Procfs.h | 2 +- .../GDBRemoteCommunicationServerCommon.cpp | 10 +- .../Plugins/SymbolFile/DWARF/DWARFContext.cpp | 4 +- .../SymbolFile/DWARF/DWARFDebugMacro.cpp | 28 +- .../SymbolFile/DWARF/DWARFDebugMacro.h | 9 + .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 19 +- .../SymbolFile/DWARF/SymbolFileDWARF.h | 6 +- lldb/source/Target/PathMappingList.cpp | 4 +- lldb/source/Target/ThreadPlanStepRange.cpp | 7 + lldb/source/Utility/ArchSpec.cpp | 4 +- .../Utility/TildeExpressionResolver.cpp | 2 +- .../API/api/command-return-object/Makefile | 1 + .../plugins/command_plugin/Makefile | 1 + .../TestGdbRemoteMemoryAllocation.py | 1 + .../TestGdbRemote_QPassSignals.py | 1 + .../thread-name/TestGdbRemoteThreadName.py | 1 + .../lldb-vscode/attach/TestVSCode_attach.py | 1 + .../runInTerminal/TestVSCode_runInTerminal.py | 1 + lldb/tools/lldb-server/CMakeLists.txt | 2 +- llvm/include/llvm/ADT/Triple.h | 19 +- .../llvm/BinaryFormat/MinidumpConstants.def | 1 + llvm/include/llvm/LTO/Config.h | 1 + llvm/lib/Support/AArch64TargetParser.cpp | 2 +- llvm/lib/Support/ARMTargetParser.cpp | 2 +- llvm/lib/Support/Triple.cpp | 4 + .../Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp | 4 +- llvm/lib/Target/ARM/ARMSubtarget.h | 5 +- llvm/lib/Target/ARM/ARMTargetMachine.cpp | 3 +- .../CodeGen/AArch64/arm64-platform-reg.ll | 1 + llvm/test/Transforms/SafeStack/AArch64/abi.ll | 2 + .../Transforms/SafeStack/AArch64/abi_ssp.ll | 2 + .../SafeStack/AArch64/unreachable.ll | 2 + llvm/utils/lit/lit/llvm/config.py | 4 +- .../include/gtest/internal/gtest-port-arch.h | 3 + .../unittest/googletest/src/gtest-port.cc | 2 +- openmp/runtime/src/kmp.h | 3 +- openmp/runtime/src/kmp_i18n.cpp | 3 +- .../tasking/hidden_helper_task/depend.cpp | 1 + .../test/tasking/hidden_helper_task/gtid.cpp | 4 +- 198 files changed, 3091 insertions(+), 255 deletions(-) create mode 100644 clang/lib/Driver/ToolChains/OHOS.cpp create mode 100644 clang/lib/Driver/ToolChains/OHOS.h create mode 100644 clang/test/CodeGen/merge-functions.c create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/bin/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/include/c++/v1/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libc++.so create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_soft/libc++.so create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libc++.so create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/libc++.so create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtbegin.o create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtend.o create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.profile.a create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtbegin.o create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtend.o create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.profile.a create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtbegin.o create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtend.o create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.profile.a create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtbegin.o create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtend.o create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.builtins.a create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.profile.a create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/arm-liteos-ohos/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_soft/.keep create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep create mode 100644 clang/test/Driver/as-fno-integrated-as.c create mode 100644 clang/test/Driver/fenable-merge-functions.cpp create mode 100644 clang/test/Driver/ohos.c create mode 100644 clang/test/Driver/ohos.cpp create mode 100644 clang/test/Preprocessor/ohos.c create mode 100644 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py create mode 100644 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py create mode 100644 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py create mode 100644 lldb/include/lldb/Host/ohos/HostInfoOHOS.h create mode 100644 lldb/source/Host/ohos/HostInfoOHOS.cpp create mode 100644 lldb/source/Plugins/Platform/OHOS/CMakeLists.txt create mode 100644 lldb/source/Plugins/Platform/OHOS/HdcClient.cpp create mode 100644 lldb/source/Plugins/Platform/OHOS/HdcClient.h create mode 100644 lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp create mode 100644 lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h create mode 100644 lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp create mode 100644 lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index d61f3583281d..68f0841c51bd 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -901,6 +901,7 @@ def Availability : InheritableAttr { .Case("maccatalyst", "macCatalyst") .Case("maccatalyst_app_extension", "macCatalyst (App Extension)") .Case("swift", "Swift") + .Case("ohos", "OpenHOS") .Default(llvm::StringRef()); } static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) { diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3cab37b21aaf..07d89546eb10 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2910,6 +2910,8 @@ def ffinite_loops: Flag<["-"], "ffinite-loops">, Group, def fno_finite_loops: Flag<["-"], "fno-finite-loops">, Group, HelpText<"Do not assume that any loop is finite.">, Flags<[CC1Option]>; +def fenable_merge_functions : Flag<["-"], "fenable-merge-functions">, Group, + HelpText<"Enables Merge Functions optimization">; def ftrigraphs : Flag<["-"], "ftrigraphs">, Group, HelpText<"Process trigraph sequences">, Flags<[CC1Option]>; def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index f20ab164531b..4f9d52ad9be1 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -482,7 +482,8 @@ public: // Returns /lib//. This is used by runtimes (such // as OpenMP) to find arch-specific libraries. - std::string getArchSpecificLibPath() const; + // OHOS specific: make this function virtual to override in OHOS.cpp + virtual std::string getArchSpecificLibPath() const; // Returns part of above. virtual StringRef getOSLibName() const; diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 6685145ea6d2..b4b1af20a64d 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -71,7 +71,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html. // This alignment guarantee also applies to Windows and Android. On Darwin // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems. - if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid()) + if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() || T.isOHOSFamily()) NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; else if (T.isOSDarwin() || T.isOSOpenBSD()) NewAlign = 128; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 2d6ef998485a..1f8fa8b7f1b6 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -146,7 +146,12 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Fuchsia: return new FuchsiaTargetInfo(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } case llvm::Triple::NetBSD: return new NetBSDTargetInfo(Triple, Opts); case llvm::Triple::OpenBSD: @@ -186,7 +191,14 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::CloudABI: return new CloudABITargetInfo(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } + case llvm::Triple::LiteOS: + return new OHOSTargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo(Triple, Opts); case llvm::Triple::NetBSD: @@ -559,6 +571,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 b2f61cff81c9..fd005a6570fb 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -317,7 +317,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, default: if (IsNetBSD) setABI("apcs-gnu"); - else if (IsOpenBSD) + else if (IsOpenBSD || Triple.isOHOSFamily()) setABI("aapcs-linux"); else setABI("aapcs"); diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index a814f681b146..878efbf48317 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -1013,6 +1013,68 @@ public: } }; +// OHOS target +template +class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + // Linux defines; list based off of gcc output + DefineStd(Builder, "unix", Opts); + + Builder.defineMacro("__ELF__"); + + // Generic OHOS target defines + if (Triple.isOHOSFamily()) { + Builder.defineMacro("__OHOS_FAMILY__", "1"); + + auto Version = Triple.getEnvironmentVersion(); + this->PlatformName = "ohos"; + this->PlatformMinVersion = Version; + Builder.defineMacro("__OHOS_Major__", Twine(Version.getMajor())); + if (auto Minor = Version.getMinor()) + Builder.defineMacro("__OHOS_Minor__", Twine(*Minor)); + if (auto Subminor = Version.getSubminor()) + Builder.defineMacro("__OHOS_Micro__", Twine(*Subminor)); + } + + if (Triple.isOpenHOS()) + Builder.defineMacro("__OHOS__"); + + if (Triple.isOSLinux()) { + DefineStd(Builder, "linux", Opts); + } else if (Triple.isOSLiteOS()) { + Builder.defineMacro("__LITEOS__"); + } + + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); + } + +public: + OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo(Triple, Opts) { + this->WIntType = TargetInfo::UnsignedInt; + + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->HasFloat128 = true; + break; + } + } + + const char *getStaticInitSectionSpecifier() const override { + return ".text.startup"; + } +}; + } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index ed0864aec6d2..0d5d068741a5 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -943,6 +943,28 @@ public: LongDoubleFormat = &llvm::APFloat::IEEEquad(); } }; + +// x86_32 OHOS target +class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo + : public OHOSTargetInfo { +public: + OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OHOSTargetInfo(Triple, Opts) { + SuitableAlign = 32; + LongDoubleWidth = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } +}; + +// x86_64 OHOS target +class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo + : public OHOSTargetInfo { +public: + OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OHOSTargetInfo(Triple, Opts) { + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } +}; } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h index c1eb8a975796..250272fb8d23 100644 --- a/clang/lib/CodeGen/ABIInfo.h +++ b/clang/lib/CodeGen/ABIInfo.h @@ -85,6 +85,7 @@ namespace CodeGen { QualType Ty) const = 0; bool isAndroid() const; + bool isOHOSFamily() const; /// Emit the target dependent code to load a value of /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 36e10e4df4c1..3e667abc6f1c 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -231,6 +231,10 @@ const CodeGenOptions &ABIInfo::getCodeGenOpts() const { bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); } +bool ABIInfo::isOHOSFamily() const { + return getTarget().getTriple().isOHOSFamily(); +} + bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { return false; } @@ -5726,7 +5730,7 @@ ABIArgInfo AArch64ABIInfo::coerceIllegalVector(QualType Ty) const { uint64_t Size = getContext().getTypeSize(Ty); // Android promotes <2 x i8> to i16, not i32 - if (isAndroid() && (Size <= 16)) { + if ((isAndroid() || isOHOSFamily()) && (Size <= 16)) { llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext()); return ABIArgInfo::getDirect(ResType); } @@ -6323,7 +6327,7 @@ public: case llvm::Triple::MuslEABIHF: return true; default: - return false; + return getTarget().getTriple().isOHOSFamily(); } } diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 18c9b2d042f6..7be7f959e896 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -71,6 +71,7 @@ add_clang_library(clangDriver ToolChains/Myriad.cpp ToolChains/NaCl.cpp ToolChains/NetBSD.cpp + ToolChains/OHOS.cpp ToolChains/OpenBSD.cpp ToolChains/PS4CPU.cpp ToolChains/RISCVToolchain.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 3f29afd35971..cbd2ff494de9 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -40,6 +40,7 @@ #include "ToolChains/Myriad.h" #include "ToolChains/NaCl.h" #include "ToolChains/NetBSD.h" +#include "ToolChains/OHOS.h" #include "ToolChains/OpenBSD.h" #include "ToolChains/PPCFreeBSD.h" #include "ToolChains/PPCLinux.h" @@ -5999,7 +6000,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, Args); else if (Target.getArch() == llvm::Triple::ve) TC = std::make_unique(*this, Target, Args); - + else if (Target.isOHOSFamily()) + TC = std::make_unique(*this, Target, Args); else TC = std::make_unique(*this, Target, Args); break; @@ -6060,6 +6062,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Hurd: TC = std::make_unique(*this, Target, Args); break; + case llvm::Triple::LiteOS: + TC = std::make_unique(*this, Target, Args); + break; case llvm::Triple::ZOS: TC = std::make_unique(*this, Target, Args); break; diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index cf7e201b4972..b497c14b7902 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -608,7 +608,7 @@ fp16_fml_fallthrough: Features.push_back("+fix-cortex-a53-835769"); else Features.push_back("-fix-cortex-a53-835769"); - } else if (Triple.isAndroid()) { + } else if (Triple.isAndroid() || Triple.isOHOSFamily()) { // Enabled A53 errata (835769) workaround by default on android Features.push_back("+fix-cortex-a53-835769"); } diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index a64909d9a6e7..2d3cabe53bb0 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -295,6 +295,8 @@ void arm::setFloatABIInTriple(const Driver &D, const ArgList &Args, Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF : llvm::Triple::MuslEABI); break; + case llvm::Triple::OpenHOS: + break; default: { arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple); if (DefaultABI != arm::FloatABI::Invalid && @@ -364,6 +366,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 dc718e09ad43..95970f7421ca 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.h +++ b/clang/lib/Driver/ToolChains/BareMetal.h @@ -39,7 +39,7 @@ protected: bool AddArch = true) const override; public: - bool useIntegratedAs() const override { return true; } + bool IsIntegratedAssemblerDefault() const override { return true; } bool isCrossCompiling() const override { return true; } bool isPICDefault() const override { return false; } bool isPIEDefault(const llvm::opt::ArgList &Args) const override { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3704ed858668..3d5ddba6c0fb 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6264,6 +6264,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fstrict_flex_arrays_EQ); + if (Args.hasArg(options::OPT_fenable_merge_functions)) + CmdArgs.push_back(Args.MakeArgString("-fmerge-functions")); + Args.AddLastArg(CmdArgs, options::OPT_pthread); if (Args.hasFlag(options::OPT_mspeculative_load_hardening, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 443725f7d8a8..84946b9e6d25 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -828,7 +828,7 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, CmdArgs.push_back(getAsNeededOption(TC, false)); // There's no libpthread or librt on RTEMS & Android. if (TC.getTriple().getOS() != llvm::Triple::RTEMS && - !TC.getTriple().isAndroid()) { + !TC.getTriple().isAndroid() && !TC.getTriple().isOHOSFamily()) { CmdArgs.push_back("-lpthread"); if (!TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lrt"); @@ -1243,6 +1243,18 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { } } + // OHOS-specific defaults for PIC/PIE + if (Triple.isOHOSFamily()) { + switch (Triple.getArch()) { + case llvm::Triple::aarch64: + PIC = true; // "-fpic" + break; + + default: + break; + } + } + // OpenBSD-specific defaults for PIE if (Triple.isOSOpenBSD()) { switch (ToolChain.getArch()) { @@ -1505,6 +1517,11 @@ static LibGccType getLibGccType(const ToolChain &TC, const Driver &D, static void AddUnwindLibrary(const ToolChain &TC, const Driver &D, ArgStringList &CmdArgs, const ArgList &Args) { ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args); + if (TC.getTriple().isOHOSFamily() && UNW != ToolChain::UNW_None) { + CmdArgs.push_back("-l:libunwind.a"); + return; + } + // Targets that don't use unwind libraries. if ((TC.getTriple().isAndroid() && UNW == ToolChain::UNW_Libgcc) || TC.getTriple().isOSIAMCU() || TC.getTriple().isOSBinFormatWasm() || diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 665cdc3132fb..b0605edf4669 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -398,6 +398,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); const llvm::Triple::ArchType Arch = ToolChain.getArch(); + const bool isOHOSFamily = ToolChain.getTriple().isOHOSFamily(); const bool isAndroid = ToolChain.getTriple().isAndroid(); const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); const bool IsVE = ToolChain.getTriple().isVE(); @@ -448,7 +449,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Most Android ARM64 targets should enable the linker fix for erratum // 843419. Only non-Cortex-A53 devices are allowed to skip this flag. - if (Arch == llvm::Triple::aarch64 && isAndroid) { + if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) { std::string CPU = getCPUName(D, Args, Triple); if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53") CmdArgs.push_back("--fix-cortex-a53-843419"); @@ -641,7 +642,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--pop-state"); } - if (WantPthread && !isAndroid) + // We don't need libpthread neither for bionic nor for musl + if (WantPthread && !isAndroid && !isOHOSFamily) CmdArgs.push_back("-lpthread"); if (Args.hasArg(options::OPT_fsplit_stack)) diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp new file mode 100644 index 000000000000..8909966a99d5 --- /dev/null +++ b/clang/lib/Driver/ToolChains/OHOS.cpp @@ -0,0 +1,422 @@ +//===--- 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(); + std::string CandidateLibPath = getArchSpecificLibPath(); + if (getVFS().exists(CandidateLibPath)) + getFilePaths().push_back(CandidateLibPath); + + getLibraryPaths().clear(); + for (auto &Path : getRuntimePaths()) + if (getVFS().exists(Path)) + getLibraryPaths().push_back(Path); + + // OHOS sysroots contain a library directory for each supported OS + // version as well as some unversioned libraries in the usual multiarch + // directory. Support --target=aarch64-linux-ohosX.Y.Z or + // --target=aarch64-linux-ohosX.Y or --target=aarch64-linux-ohosX + path_list &Paths = getFilePaths(); + std::string SysRootLibPath = makePath({SysRoot, "usr", "lib"}); + std::string MultiarchTriple = getMultiarchTriple(getTriple()); + addPathIfExists(D, makePath({SysRootLibPath, SelectedMultilib.gccSuffix()}), + Paths); + addPathIfExists(D, + makePath({D.Dir, "..", "lib", MultiarchTriple, + SelectedMultilib.gccSuffix()}), + Paths); + + // For compatibility with arm-liteos sysroot + // FIXME: Remove this when we'll use arm-liteos sysroot produced by build.py. + addPathIfExists( + D, + makePath({SysRootLibPath, MultiarchTriple, SelectedMultilib.gccSuffix()}), + Paths); +} + +std::string OHOS::ComputeEffectiveClangTriple(const ArgList &Args, + types::ID InputType) const { + auto TripleStr = Generic_ELF::ComputeEffectiveClangTriple(Args, InputType); + llvm::Triple T(TripleStr); + T.setEnvironment(llvm::Triple::OpenHOS); + return T.str(); +} + +ToolChain::RuntimeLibType OHOS::GetRuntimeLibType( + const ArgList &Args) const { + if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) { + StringRef Value = A->getValue(); + if (Value != "compiler-rt") + getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name) + << A->getAsString(Args); + } + + return ToolChain::RLT_CompilerRT; +} + +ToolChain::CXXStdlibType +OHOS::GetCXXStdlibType(const ArgList &Args) const { + if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { + StringRef Value = A->getValue(); + if (Value != "libc++") + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); + } + + return ToolChain::CST_Libcxx; +} + +void OHOS::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + const llvm::Triple &Triple = getTriple(); + std::string SysRoot = computeSysRoot(); + + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; + addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); + } + return; + } + + addExternCSystemInclude(DriverArgs, CC1Args, + SysRoot + "/usr/include/" + + getMultiarchTriple(Triple)); + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); +} + +void OHOS::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + switch (GetCXXStdlibType(DriverArgs)) { + case ToolChain::CST_Libcxx: { + std::string IncPath = makePath({getDriver().Dir, "..", "include"}); + std::string IncTargetPath = + makePath({IncPath, getMultiarchTriple(getTriple()), "c++", "v1"}); + if (getVFS().exists(IncTargetPath)) { + addSystemInclude(DriverArgs, CC1Args, makePath({IncPath, "c++", "v1"})); + addSystemInclude(DriverArgs, CC1Args, IncTargetPath); + } + break; + } + + default: + llvm_unreachable("invalid stdlib name"); + } +} + +void OHOS::AddCXXStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + switch (GetCXXStdlibType(Args)) { + case ToolChain::CST_Libcxx: + CmdArgs.push_back("-lc++"); + CmdArgs.push_back("-lc++abi"); + CmdArgs.push_back("-lunwind"); + break; + + case ToolChain::CST_Libstdcxx: + llvm_unreachable("invalid stdlib name"); + } +} + +std::string OHOS::computeSysRoot() const { + std::string SysRoot = + !getDriver().SysRoot.empty() + ? getDriver().SysRoot + : makePath({getDriver().getInstalledDir(), "..", "..", "sysroot"}); + if (!llvm::sys::fs::exists(SysRoot)) + return std::string(); + + std::string ArchRoot = makePath({SysRoot, getMultiarchTriple(getTriple())}); + return llvm::sys::fs::exists(ArchRoot) ? ArchRoot : SysRoot; +} + +ToolChain::path_list OHOS::getRuntimePaths() const { + SmallString<128> P; + path_list Paths; + const Driver &D = getDriver(); + const llvm::Triple &Triple = getTriple(); + + // First try the triple passed to driver as --target=. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, "lib", D.getTargetTriple(), SelectedMultilib.gccSuffix()); + Paths.push_back(P.c_str()); + + // Second try the normalized triple. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, "lib", Triple.str(), SelectedMultilib.gccSuffix()); + Paths.push_back(P.c_str()); + + // Third try the effective triple. + P.assign(D.ResourceDir); + std::string SysRoot = computeSysRoot(); + llvm::sys::path::append(P, "lib", getMultiarchTriple(Triple), + SelectedMultilib.gccSuffix()); + Paths.push_back(P.c_str()); + + return Paths; +} + +std::string OHOS::getDynamicLinker(const ArgList &Args) const { + const llvm::Triple &Triple = getTriple(); + const llvm::Triple::ArchType Arch = getArch(); + + assert(Triple.isMusl()); + std::string ArchName; + bool IsArm = false; + + switch (Arch) { + case llvm::Triple::arm: + case llvm::Triple::thumb: + ArchName = "arm"; + IsArm = true; + break; + case llvm::Triple::armeb: + case llvm::Triple::thumbeb: + ArchName = "armeb"; + IsArm = true; + break; + default: + ArchName = Triple.getArchName().str(); + } + if (IsArm && + (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)) + ArchName += "hf"; + + return "/lib/ld-musl-" + ArchName + ".so.1"; +} + +std::string OHOS::getCompilerRT(const ArgList &Args, StringRef Component, + FileType Type) const { + SmallString<128> Path(getDriver().ResourceDir); + llvm::sys::path::append(Path, "lib", getMultiarchTriple(getTriple()), + SelectedMultilib.gccSuffix()); + const char *Prefix = + Type == ToolChain::FT_Object ? "" : "lib"; + const char *Suffix; + switch (Type) { + case ToolChain::FT_Object: + Suffix = ".o"; + break; + case ToolChain::FT_Static: + Suffix = ".a"; + break; + case ToolChain::FT_Shared: + Suffix = ".so"; + break; + } + llvm::sys::path::append( + Path, Prefix + Twine("clang_rt.") + Component + Suffix); + return static_cast(Path.str()); +} + +void OHOS::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + CmdArgs.push_back("-z"); + CmdArgs.push_back("now"); + CmdArgs.push_back("-z"); + CmdArgs.push_back("relro"); + CmdArgs.push_back("-z"); + CmdArgs.push_back("max-page-size=4096"); + CmdArgs.push_back("--hash-style=gnu"); + // FIXME: gnu or both??? + CmdArgs.push_back("--hash-style=both"); +#ifdef ENABLE_LINKER_BUILD_ID + CmdArgs.push_back("--build-id"); +#endif + CmdArgs.push_back("--enable-new-dtags"); +} + +SanitizerMask OHOS::getSupportedSanitizers() const { + SanitizerMask Res = ToolChain::getSupportedSanitizers(); + Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; + Res |= SanitizerKind::Fuzzer; + Res |= SanitizerKind::FuzzerNoLink; + Res |= SanitizerKind::Memory; + Res |= SanitizerKind::Vptr; + Res |= SanitizerKind::SafeStack; + Res |= SanitizerKind::Scudo; + // TODO: kASAN for liteos ?? + // TODO: Support TSAN and HWASAN and update mask. + return Res; +} + +// TODO: Make a base class for Linux and OHOS and move this there. +void OHOS::addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + // Add linker option -u__llvm_profile_runtime to cause runtime + // initialization module to be linked in. + if (needsProfileRT(Args)) + CmdArgs.push_back(Args.MakeArgString( + Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); + ToolChain::addProfileRTLibs(Args, CmdArgs); +} + +std::string OHOS::getArchSpecificLibPath() const { + llvm::Triple Triple = getTriple(); + return makePath({getDriver().ResourceDir, "lib", getMultiarchTriple(Triple)}); +} + +ToolChain::UnwindLibType OHOS::GetUnwindLibType(const llvm::opt::ArgList &Args) const { + if (const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ)) + return Generic_ELF::GetUnwindLibType(Args); + return GetDefaultUnwindLibType(); +} diff --git a/clang/lib/Driver/ToolChains/OHOS.h b/clang/lib/Driver/ToolChains/OHOS.h new file mode 100644 index 000000000000..be1115967b78 --- /dev/null +++ b/clang/lib/Driver/ToolChains/OHOS.h @@ -0,0 +1,100 @@ +//===--- OHOS.h - OHOS ToolChain Implementations ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H + +#include "Linux.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY OHOS : public Generic_ELF { +public: + OHOS(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + + bool HasNativeLLVMSupport() const override { return true; } + bool IsIntegratedAssemblerDefault() const override { return true; } + bool IsMathErrnoDefault() const override { return false; } + RuntimeLibType GetDefaultRuntimeLibType() const override { + return ToolChain::RLT_CompilerRT; + } + CXXStdlibType GetDefaultCXXStdlibType() const override { + return ToolChain::CST_Libcxx; + } + // Not add -funwind-tables by default + bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override { + return false; + } + bool isPICDefault() const override { return false; } + bool isPIEDefault(const llvm::opt::ArgList &Args) const override { return true; } + bool isPICDefaultForced() const override { return false; } + bool useRelaxRelocations() const override { return false; } + UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override; + UnwindLibType GetDefaultUnwindLibType() const override { return UNW_CompilerRT; } + + 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); + } + + path_list getRuntimePaths() const; + +protected: + std::string getMultiarchTriple(const llvm::Triple &T) const; + std::string getMultiarchTriple(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef SysRoot) const override; + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; + SanitizerMask getSupportedSanitizers() const override; + void addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + std::string getArchSpecificLibPath() const override; +private: + Multilib SelectedMultilib; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H diff --git a/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c b/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c index 3ce5b9d12217..3d1a2c7aceb1 100644 --- a/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c +++ b/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c @@ -7,6 +7,8 @@ // RUN: %clang -O3 -target aarch64-android-eabi %s -S -o- \ // RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s +// RUN: %clang -O3 -target aarch64-linux-ohos %s -S -o- \ +// RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s // RUN: %clang -O3 -target aarch64-android-eabi -mfix-cortex-a53-835769 %s -S -o- \ // RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s // RUN: %clang -O3 -target aarch64-android-eabi -mno-fix-cortex-a53-835769 %s -S -o- \ diff --git a/clang/test/CodeGen/arm64-abi-vector.c b/clang/test/CodeGen/arm64-abi-vector.c index 10f721ab1f2f..677639bb3c1d 100644 --- a/clang/test/CodeGen/arm64-abi-vector.c +++ b/clang/test/CodeGen/arm64-abi-vector.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios7 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -no-opaque-pointers -triple aarch64-linux-android -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s +// RUN: %clang_cc1 -no-opaque-pointers -triple aarch64-linux-ohos -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s #include diff --git a/clang/test/CodeGen/merge-functions.c b/clang/test/CodeGen/merge-functions.c new file mode 100644 index 000000000000..7e382853cc7c --- /dev/null +++ b/clang/test/CodeGen/merge-functions.c @@ -0,0 +1,22 @@ +// Check that code gen really activates function merging. In this case +// just check a trivial functions merging case. + +// RUN: %clang_cc1 -emit-llvm %s -fmerge-functions -o - | FileCheck %s + +void foo1() {} +void foo2() {} + +int main() { + + // If merge functions pass is enabled, + // then second and first calls will refer to foo1 + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo1(); + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo2(); + + return 0; +} + diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/bin/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/bin/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/include/c++/v1/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/include/c++/v1/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libc++.so new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_soft/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_soft/libc++.so new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libc++.so new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/libc++.so new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtbegin.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtend.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/clang_rt.crtend.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.profile.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.profile.a new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtbegin.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtend.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/clang_rt.crtend.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.profile.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_soft/libclang_rt.profile.a new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtbegin.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtend.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/clang_rt.crtend.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.profile.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.profile.a new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtbegin.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtend.o b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/clang_rt.crtend.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.builtins.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.builtins.a new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.profile.a b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z/lib/arm-liteos-ohos/libclang_rt.profile.a new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/arm-liteos-ohos/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/include/arm-liteos-ohos/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_soft/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_soft/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep b/clang/test/Driver/Inputs/ohos_native_tree/sysroot/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/.keep new file mode 100644 index 000000000000..e69de29bb2d1 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 000000000000..866cc421e522 --- /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 000000000000..f45cdd3b09e9 --- /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 000000000000..b934b7509e14 --- /dev/null +++ b/clang/test/Driver/ohos.c @@ -0,0 +1,237 @@ +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-liteos \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARM %s +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-liteos \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARM-A7-SOFT %s +// CHECK: {{.*}}clang{{.*}}" "-cc1" +// CHECK-NOT: "--mrelax-relocations" +// CHECK-NOT: "-munwind-tables" +// CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" +// CHECK-NOT: "-fsanitize=safe-stack" +// CHECK-NOT: "-stack-protector" "2" +// CHECK-NOT: "-fno-common" +// CHECK: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-NOT: "--sysroot=[[SYSROOT]]" +// CHECK: "-pie" +// CHECK-NOT: "--build-id" +// CHECK: "--hash-style=gnu" +// CHECK: "--hash-style=both" +// CHECK: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK: Scrt1.o +// CHECK: crti.o +// CHECK: clang_rt.crtbegin.o +// CHECK-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" +// CHECK-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" +// CHECK-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-ARM-A7-SOFT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos/a7_soft{{/|\\\\}}libclang_rt.builtins.a" +// CHECK: "-lc" +// CHECK: clang_rt.crtend.o +// CHECK: crtn.o + +// RUN: %clang %s -### --target=arm-liteos -rtlib=libgcc -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RTLIB +// CHECK-RTLIB: error: invalid runtime library name in argument '-rtlib=libgcc' + +// RUN: %clang %s -### --target=arm-liteos -static -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC +// CHECK-STATIC: "-static" +// CHECK-STATIC-NOT: "-Bdynamic" +// CHECK-STATIC: "-l:libunwind.a" +// CHECK-STATIC: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -shared -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-SHARED +// CHECK-SHARED-NOT: "-pie" +// CHECK-SHARED: "-shared" +// CHECK-SHARED: "-lc" +// CHECK-SHARED: "-l:libunwind.a" + +// RUN: %clang %s -### --target=arm-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// RUN: %clang %s -### --target=aarch64-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// CHECK-RUNTIME: "{{.*}}/libclang_rt.builtins.a" +// CHECK-RUNTIME: "-l:libunwind.a" +// CHECK-LIBM: "-lm" + +// RUN: %clang %s -### --target=arm-liteos -r -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RELOCATABLE +// CHECK-RELOCATABLE-NOT: "-pie" +// CHECK-RELOCATABLE-NOT: "--build-id" +// CHECK-RELOCATABLE: "-r" + +// RUN: %clang %s -### --target=arm-liteos -nodefaultlibs -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NODEFAULTLIBS +// CHECK-NODEFAULTLIBS: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NODEFAULTLIBS-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NODEFAULTLIBS-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -nostdlib -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIB +// CHECK-NOSTDLIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOSTDLIB-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NOSTDLIB-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -nolibc -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOLIBC +// CHECK-NOLIBC: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOLIBC: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NOLIBC-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=safe-stack 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SAFESTACK +// CHECK-SAFESTACK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SAFESTACK: "-fsanitize=safe-stack" +// CHECK-SAFESTACK: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.safestack.a" +// CHECK-SAFESTACK: "__safestack_init" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=address 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-ARM +// CHECK-ASAN-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-ASAN-ARM: "-fsanitize=address" +// CHECK-ASAN-ARM: "-fsanitize-address-use-after-scope" +// CHECK-ASAN-ARM: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-ASAN-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan.a" +// CHECK-ASAN-ARM-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan-preinit.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=address -fPIC -shared 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -shared-libsan \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-SHARED +// CHECK-ASAN-SHARED: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-ASAN-SHARED: "-fsanitize=address" +// CHECK-ASAN-SHARED: "-fsanitize-address-use-after-scope" +// CHECK-ASAN-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan.so" +// CHECK-ASAN-SHARED-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan-preinit.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=fuzzer 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-FUZZER-ARM +// CHECK-FUZZER-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-FUZZER-ARM: "-fsanitize=fuzzer,fuzzer-no-link" +// CHECK-FUZZER-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.fuzzer.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=scudo 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SCUDO-ARM +// CHECK-SCUDO-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SCUDO-ARM: "-fsanitize=scudo" +// CHECK-SCUDO-ARM: "-pie" +// CHECK-SCUDO-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.scudo.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=scudo -fPIC -shared 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -shared-libsan \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SCUDO-SHARED +// CHECK-SCUDO-SHARED: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SCUDO-SHARED: "-fsanitize=scudo" +// CHECK-SCUDO-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.scudo.so" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fxray-instrument -fxray-modes=xray-basic \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-XRAY-ARM +// CHECK-XRAY-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-XRAY-ARM: "-fxray-instrument" +// CHECK-XRAY-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.xray.a" +// CHECK-XRAY-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.xray-basic.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -O3 -flto -mcpu=cortex-a53 2>&1 \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-LTO +// CHECK-LTO: "-plugin-opt=mcpu=cortex-a53" +// CHECK-LTO: "-plugin-opt=O3" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -flto=thin -flto-jobs=8 -mcpu=cortex-a7 2>&1 \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-THINLTO +// CHECK-THINLTO: "-plugin-opt=mcpu=cortex-a7" +// CHECK-THINLTO: "-plugin-opt=thinlto" +// CHECK-THINLTO: "-plugin-opt=jobs=8" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFT +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFTFP +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-HF,CHECK-MULTILIB-ARM-A7-HARD +// CHECK-MULTILIB: {{.*}}clang{{.*}}" "-cc1" +// CHECK-MULTILIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-MULTILIB: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-MULTILIB: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-MULTILIB-SF: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-MULTILIB-HF: "-dynamic-linker" "/lib/ld-musl-armhf.so.1" + +// CHECK-MULTILIB-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" + +// CHECK-MULTILIB-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" + +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4" + +// CHECK-MULTILIB-ARM-A7-HARD: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4" + +// CHECK-MULTILIB-ARM: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFT: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-HARD: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a" + +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-linux-ohos -fprofile-instr-generate -v \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK-PROFILE-RTLIB %s + +// CHECK-PROFILE-RTLIB: -u__llvm_profile_runtime +// CHECK-PROFILE-RTLIB: libclang_rt.profile + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: --target=arm64-linux-ohos -pthread \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -shared \ +// RUN: | FileCheck --check-prefix=CHECK-OHOS-PTHREAD %s + +// CHECK-OHOS-PTHREAD-NOT: -lpthread + diff --git a/clang/test/Driver/ohos.cpp b/clang/test/Driver/ohos.cpp new file mode 100644 index 000000000000..4b822350898c --- /dev/null +++ b/clang/test/Driver/ohos.cpp @@ -0,0 +1,121 @@ +// RUN: %clangxx %s -### -no-canonical-prefixes --target=arm-liteos -march=armv7-a \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld 2>&1 | FileCheck %s +// CHECK: {{.*}}clang{{.*}}" "-cc1" +// CHECK: "-triple" "armv7-unknown-liteos-ohos" +// CHECK-NOT: "-fuse-init-array" +// CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" +// CHECK: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK: "-pie" +// CHECK-NOT: "--build-id" +// CHECK: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK: Scrt1.o +// CHECK: crti.o +// CHECK: clang_rt.crtbegin.o +// CHECK: "-L{{.*[/\\]}}lib/arm-liteos-ohos/" +// CHECK-NOT: "--push-state" +// CHECK-NOT: "--as-needed" +// CHECK: "-lc++" +// CHECK: "-lm" +// CHECK-NOT: "--pop-state" +// CHECK: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK: "-lc" +// CHECK: clang_rt.crtend.o +// CHECK: crtn.o + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -stdlib=libstdc++ \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STDLIB +// CHECK-STDLIB: error: invalid library name in argument '-stdlib=libstdc++' + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -static-libstdc++ \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC +// CHECK-STATIC-NOT: "--push-state" +// CHECK-STATIC-NOT: "--as-needed" +// CHECK-STATIC: "-Bstatic" +// CHECK-STATIC: "-lc++" +// CHECK-STATIC: "-Bdynamic" +// CHECK-STATIC: "-lm" +// CHECK-STATIC-NOT: "--pop-state" +// CHECK-STATIC: "-lc" + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -static \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC1 +// CHECK-STATIC1-NOT: "-fuse-init-array" +// CHECK-STATIC1: "-static" +// CHECK-STATIC1: "-lc++" +// CHECK-STATIC1: "-lc++abi" +// CHECK-STATIC1: "-lunwind" +// CHECK-STATIC1: "-lm" +// CHECK-STATIC1: "-lc" + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -march=armv7-a -mfloat-abi=soft -static -fPIE -fPIC -fpic -pie \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC2 +// CHECK-STATIC2: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-STATIC2: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-STATIC2: "-static" +// CHECK-STATIC2: "-lc++" +// CHECK-STATIC2: "-lc++abi" +// CHECK-STATIC2: "-lunwind" +// CHECK-STATIC2: "-lm" +// CHECK-STATIC2: "-lc" + +// RUN: %clangxx %s -### --target=arm-liteos -nostdlib++ -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIBXX +// CHECK-NOSTDLIBXX-NOT: "-lc++" +// CHECK-NOSTDLIBXX: "-lm" +// CHECK-NOSTDLIBXX: "-lc" + +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFT +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFTFP +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-HF,CHECK-MULTILIB-ARM-A7-HARD +// CHECK-MULTILIB: {{.*}}clang{{.*}}" "-cc1" +// CHECK-MULTILIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-MULTILIB: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-MULTILIB: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-MULTILIB-SF: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-MULTILIB-HF: "-dynamic-linker" "/lib/ld-musl-armhf.so.1" + +// CHECK-MULTILIB-ARM: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}" +// CHECK-MULTILIB-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" + +// CHECK-MULTILIB-ARM-A7-SOFT: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}a7_soft" +// CHECK-MULTILIB-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" + +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}a7_softfp_neon-vfpv4" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4" + +// CHECK-MULTILIB-ARM-A7-HARD: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}a7_hard_neon-vfpv4" +// CHECK-MULTILIB-ARM-A7-HARD: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4" + +// CHECK-MULTILIB-ARM: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFT: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-HARD: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a" diff --git a/clang/test/Preprocessor/ohos.c b/clang/test/Preprocessor/ohos.c new file mode 100644 index 000000000000..bd1060133c4e --- /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 51fe5de9ce64..37a2a167c38d 100644 --- a/clang/unittests/CMakeLists.txt +++ b/clang/unittests/CMakeLists.txt @@ -41,7 +41,9 @@ add_subdirectory(Interpreter) if(NOT WIN32 AND CLANG_TOOL_LIBCLANG_BUILD) add_subdirectory(libclang) endif() -add_subdirectory(DirectoryWatcher) +if (NOT APPLE) + add_subdirectory(DirectoryWatcher) +endif() add_subdirectory(Rename) add_subdirectory(Index) add_subdirectory(Serialization) diff --git a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt index 9f6ed2eb4fe7..b10af074635e 100644 --- a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt +++ b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt @@ -13,6 +13,7 @@ set(LLVM_LINK_COMPONENTS add_clang_unittest(ClangReplInterpreterExceptionTests InterpreterExceptionTest.cpp ) +set_property(TARGET ClangReplInterpreterExceptionTests APPEND_STRING PROPERTY LINK_FLAGS " -static-libstdc++ -l:libc++abi.a") llvm_update_compile_flags(ClangReplInterpreterExceptionTests) target_link_libraries(ClangReplInterpreterExceptionTests PUBLIC diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 62737735695f..fd7e3205abe4 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -116,7 +116,14 @@ if ("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES ".*android.*") string(REGEX MATCH "-target(=| +)[^ ]+android[a-z]*([0-9]+)" ANDROID_API_LEVEL "${CMAKE_C_FLAGS}") set(ANDROID_API_LEVEL ${CMAKE_MATCH_2}) endif() + +# We define OHOS for ohos targets for now +if (OHOS) + set(OHOS_FAMILY 1) +endif() + pythonize_bool(ANDROID) +pythonize_bool(OHOS_FAMILY) set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -127,7 +134,7 @@ pythonize_bool(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR) # and target a UNIX-like system or Windows. # We can run tests on Android even when we are cross-compiling. if(("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}" AND (UNIX OR WIN32)) OR ANDROID - OR COMPILER_RT_EMULATOR) + OR COMPILER_RT_EMULATOR OR OHOS) option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" ON) else() option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" OFF) @@ -258,7 +265,7 @@ cmake_dependent_option(COMPILER_RT_STATIC_CXX_LIBRARY "COMPILER_RT_CXX_LIBRARY" OFF) set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY OFF) -if (FUCHSIA) +if (FUCHSIA OR OHOS) set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY ON) endif() @@ -510,24 +517,9 @@ if (SANITIZER_NO_UNDEFINED_SYMBOLS) list(APPEND SANITIZER_COMMON_LINK_FLAGS -Wl,-z,defs) endif() -# TODO: COMPILER_RT_COMMON_CFLAGS and COMPILER_RT_COMMON_LINK_FLAGS are -# intended for use in non-sanitizer runtimes such as libFuzzer, profile or XRay, -# move these higher to include common flags, then derive SANITIZER_COMMON_CFLAGS -# and SANITIZER_COMMON_LINK_FLAGS from those and append sanitizer-specific flags. -set(COMPILER_RT_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS}) -set(COMPILER_RT_COMMON_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS}) - -# We don't use the C++ standard library, so avoid including it by mistake. -append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ SANITIZER_COMMON_CFLAGS) -append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ SANITIZER_COMMON_LINK_FLAGS) - -# Remove -stdlib= which is unused when passing -nostdinc++... -string(REGEX MATCHALL "-stdlib=[a-zA-Z+]*" stdlib_flag "${CMAKE_CXX_FLAGS}") -string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - -# ...we need it to build some runtimes and tests so readd it where appropriate. -list(APPEND COMPILER_RT_COMMON_CFLAGS ${stdlib_flag}) -list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag}) +if (OHOS) + list(APPEND SANITIZER_COMMON_LINK_LIBS unwind) +endif() # TODO: There's a lot of duplication across lib/*/tests/CMakeLists.txt files, # move some of the common flags to COMPILER_RT_UNITTEST_CFLAGS. diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake index 00bb892be595..c0adcbc0a358 100644 --- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake +++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake @@ -282,9 +282,6 @@ function(add_compiler_rt_runtime name type) NOT name STREQUAL "clang_rt.builtins") get_compiler_rt_target(${arch} target) find_compiler_rt_library(builtins builtins_${libname} TARGET ${target}) - if(builtins_${libname} STREQUAL "NOTFOUND") - message(FATAL_ERROR "Cannot find builtins library for the target architecture") - endif() endif() set(sources_${libname} ${LIB_SOURCES}) format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS}) diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake index a1da35b0ac4b..4612e4d8b9af 100644 --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -41,7 +41,7 @@ if(OS_NAME MATCHES "Linux") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${S390X}) elseif (OS_NAME MATCHES "Windows") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64}) -elseif(OS_NAME MATCHES "Android") +elseif(OS_NAME MATCHES "Android|OHOS") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}) else() set(ALL_FUZZER_SUPPORTED_ARCH ${X86_64} ${ARM64}) diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index e322af89a042..c0c0498f3ef5 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -497,7 +497,11 @@ endfunction() function(get_compiler_rt_install_dir arch install_dir) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) get_compiler_rt_target(${arch} target) - set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR}/${target} PARENT_SCOPE) + if(OHOS) + set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR}/${target}/${LLVM_TARGET_MULTILIB_SUFFIX} PARENT_SCOPE) + else() + set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR}/${target} PARENT_SCOPE) + endif() else() set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR} PARENT_SCOPE) endif() @@ -506,7 +510,11 @@ endfunction() function(get_compiler_rt_output_dir arch output_dir) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) get_compiler_rt_target(${arch} target) - set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/${target} PARENT_SCOPE) + if(OHOS) + set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/${target}/${LLVM_TARGET_MULTILIB_SUFFIX} PARENT_SCOPE) + else() + set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/${target} PARENT_SCOPE) + endif() else() set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR} PARENT_SCOPE) endif() diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index 8a6219568b3f..f61b962bdb24 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -191,6 +191,9 @@ macro(test_targets) # Examine compiler output to determine target architecture. detect_target_arch() set(COMPILER_RT_OS_SUFFIX "-android") + elseif(OHOS) + detect_target_arch() + set(COMPILER_RT_OS_SUFFIX "") elseif(NOT APPLE) # Supported archs for Apple platforms are generated later if(COMPILER_RT_DEFAULT_TARGET_ONLY) add_default_target_arch(${COMPILER_RT_DEFAULT_TARGET_ARCH}) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index cd45176cf2ba..a631ae4e86c3 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -61,6 +61,8 @@ if (C_SUPPORTS_NODEFAULTLIBS_FLAG) shell32 user32 kernel32 mingw32 ${MINGW_RUNTIME} moldname mingwex msvcrt) list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) + elseif (OHOS) + list(APPEND CMAKE_REQUIRED_LIBRARIES unwind) endif() endif () @@ -148,9 +150,13 @@ check_include_files("sys/auxv.h" COMPILER_RT_HAS_AUXV) # Libraries. check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL) -check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) +if (NOT OHOS) + check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) +endif() check_library_exists(m pow "" COMPILER_RT_HAS_LIBM) -check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) +if (NOT OHOS) + check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) +endif() check_library_exists(execinfo backtrace "" COMPILER_RT_HAS_LIBEXECINFO) # Look for terminfo library, used in unittests that depend on LLVMSupport. @@ -692,7 +698,7 @@ set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}") if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS" OR + (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS|OHOS" OR (OS_NAME MATCHES "Windows" AND NOT CYGWIN AND (NOT MINGW OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")))) set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE) @@ -712,7 +718,7 @@ else() set(COMPILER_RT_HAS_ASAN FALSE) endif() -if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS") +if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS|OHOS") set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE) else() set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE) @@ -742,7 +748,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Android|Fuchsia") + OS_NAME MATCHES "Linux|Android|Fuchsia|OHOS") set(COMPILER_RT_HAS_HWASAN TRUE) else() set(COMPILER_RT_HAS_HWASAN FALSE) @@ -756,14 +762,14 @@ else() endif() if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|OHOS") set(COMPILER_RT_HAS_PROFILE TRUE) else() set(COMPILER_RT_HAS_PROFILE FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH) - if (OS_NAME MATCHES "Linux|Darwin|FreeBSD|NetBSD") + if (OS_NAME MATCHES "Linux|Darwin|FreeBSD|NetBSD|OHOS") set(COMPILER_RT_HAS_TSAN TRUE) elseif (OS_NAME MATCHES "Android" AND ANDROID_PLATFORM_LEVEL GREATER 23) set(COMPILER_RT_HAS_TSAN TRUE) @@ -781,14 +787,14 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS|OHOS") set(COMPILER_RT_HAS_UBSAN TRUE) else() set(COMPILER_RT_HAS_UBSAN FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin") + OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin|OHOS") set(COMPILER_RT_HAS_UBSAN_MINIMAL TRUE) else() set(COMPILER_RT_HAS_UBSAN_MINIMAL FALSE) @@ -816,7 +822,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SCUDO_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Fuchsia") + OS_NAME MATCHES "Linux|Fuchsia|OHOS") set(COMPILER_RT_HAS_SCUDO TRUE) else() set(COMPILER_RT_HAS_SCUDO FALSE) @@ -836,14 +842,14 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND FUZZER_SUPPORTED_ARCH AND - OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|Fuchsia|Windows") + OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|Fuchsia|Windows|OHOS") set(COMPILER_RT_HAS_FUZZER TRUE) else() set(COMPILER_RT_HAS_FUZZER FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SHADOWCALLSTACK_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Android") + OS_NAME MATCHES "Linux|Android|OHOS") set(COMPILER_RT_HAS_SHADOWCALLSTACK TRUE) else() set(COMPILER_RT_HAS_SHADOWCALLSTACK FALSE) diff --git a/compiler-rt/cmake/crt-config-ix.cmake b/compiler-rt/cmake/crt-config-ix.cmake index 78d1a0de1c8a..b476d5ab0717 100644 --- a/compiler-rt/cmake/crt-config-ix.cmake +++ b/compiler-rt/cmake/crt-config-ix.cmake @@ -43,7 +43,7 @@ if(NOT APPLE) message(STATUS "Supported architectures for crt: ${CRT_SUPPORTED_ARCH}") endif() -if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER) +if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|OHOS" AND NOT LLVM_USE_SANITIZER) set(COMPILER_RT_HAS_CRT TRUE) else() set(COMPILER_RT_HAS_CRT FALSE) diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h index 27d826fb613a..893aa834bb8c 100644 --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -126,7 +126,7 @@ typedef DefaultSizeClassMap SizeClassMap; const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; -# elif defined(__aarch64__) && SANITIZER_ANDROID +#elif defined(__aarch64__) && (SANITIZER_ANDROID || SANITIZER_OHOS) // Android needs to support 39, 42 and 48 bit VMA. const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x2000000000ULL; // 128G. diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index 9c46f225116e..b5c56251d2d4 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -35,7 +35,7 @@ // If set, values like allocator chunk size, as well as defaults for some flags // will be changed towards less memory overhead. #ifndef ASAN_LOW_MEMORY -# if SANITIZER_IOS || SANITIZER_ANDROID +# if SANITIZER_IOS || SANITIZER_ANDROID || SANITIZER_OHOS # define ASAN_LOW_MEMORY 1 # else # define ASAN_LOW_MEMORY 0 diff --git a/compiler-rt/lib/asan/asan_linux.cpp b/compiler-rt/lib/asan/asan_linux.cpp index 89450fc120a0..35682cdb52fb 100644 --- a/compiler-rt/lib/asan/asan_linux.cpp +++ b/compiler-rt/lib/asan/asan_linux.cpp @@ -45,7 +45,8 @@ #include #endif -#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS +#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS || \ + SANITIZER_OHOS #include extern "C" void* _DYNAMIC; #elif SANITIZER_NETBSD @@ -121,7 +122,7 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) { ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size)); } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS // FIXME: should we do anything for Android? void AsanCheckDynamicRTPrereqs() {} void AsanCheckIncompatibleRT() {} @@ -208,7 +209,7 @@ void AsanCheckIncompatibleRT() { } #endif // SANITIZER_ANDROID -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS void ReadContextStack(void *context, uptr *stack, uptr *ssize) { ucontext_t *ucp = (ucontext_t*)context; *stack = (uptr)ucp->uc_stack.ss_sp; diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp index eb61410d768f..e392ea90dbc2 100644 --- a/compiler-rt/lib/asan/tests/asan_test.cpp +++ b/compiler-rt/lib/asan/tests/asan_test.cpp @@ -1322,7 +1322,9 @@ TEST(AddressSanitizer, LongDoubleNegativeTest) { memcpy(Ident(&c), Ident(&b), sizeof(long double)); } -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(__OHOS__) +// On OHOS/Musl sched_param is not int. +// See __interceptor_pthread_getschedparam TEST(AddressSanitizer, pthread_getschedparam) { int policy; struct sched_param param; diff --git a/compiler-rt/lib/builtins/divtf3.c b/compiler-rt/lib/builtins/divtf3.c index 5bcc9a8e4aa1..809c5a4f4adb 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 29bcd1920edf..b49a6fd2bd73 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 c372c2edc637..32b66732f8f7 100644 --- a/compiler-rt/lib/builtins/int_util.h +++ b/compiler-rt/lib/builtins/int_util.h @@ -40,6 +40,9 @@ NORETURN void __compilerrt_abort_impl(const char *file, int line, #define REPEAT_4_TIMES(code_to_repeat) \ REPEAT_3_TIMES(code_to_repeat) \ code_to_repeat +#define REPEAT_5_TIMES(code_to_repeat) \ + REPEAT_4_TIMES(code_to_repeat) \ + code_to_repeat #define REPEAT_N_TIMES_(N, code_to_repeat) REPEAT_##N##_TIMES(code_to_repeat) #define REPEAT_N_TIMES(N, code_to_repeat) REPEAT_N_TIMES_(N, code_to_repeat) diff --git a/compiler-rt/lib/cfi/CMakeLists.txt b/compiler-rt/lib/cfi/CMakeLists.txt index 2197fa4a5c75..cf8479d39c25 100644 --- a/compiler-rt/lib/cfi/CMakeLists.txt +++ b/compiler-rt/lib/cfi/CMakeLists.txt @@ -1,6 +1,6 @@ add_compiler_rt_component(cfi) -if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetBSD") +if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetBSD" OR OS_NAME MATCHES "OHOS") set(CFI_SOURCES cfi.cpp ) diff --git a/compiler-rt/lib/fuzzer/CMakeLists.txt b/compiler-rt/lib/fuzzer/CMakeLists.txt index a9a10f724d1a..a0532c838c27 100644 --- a/compiler-rt/lib/fuzzer/CMakeLists.txt +++ b/compiler-rt/lib/fuzzer/CMakeLists.txt @@ -147,7 +147,7 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir") file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir}) add_custom_command(TARGET clang_rt.${name}-${arch} POST_BUILD - COMMAND ${CMAKE_CXX_COMPILER} ${target_cflags} -Wl,--whole-archive "$" -Wl,--no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o + COMMAND ${CMAKE_CXX_COMPILER} ${target_cflags} -Wl,--whole-archive "$" -Wl,--no-whole-archive ${dir}/lib/libc++.a -nodefaultlibs -r -o ${name}.o COMMAND ${CMAKE_OBJCOPY} --localize-hidden ${name}.o COMMAND ${CMAKE_COMMAND} -E remove "$" COMMAND ${CMAKE_AR} qcs "$" ${name}.o diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp index b771025cb93d..235aa73740af 100644 --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -83,7 +83,7 @@ static void InitializeFlags() { cf.intercept_tls_get_addr = true; cf.exitcode = 99; // 8 shadow pages ~512kB, small enough to cover common stack sizes. - cf.clear_shadow_mmap_threshold = 4096 * (SANITIZER_ANDROID ? 2 : 8); + cf.clear_shadow_mmap_threshold = 4096 * ((SANITIZER_ANDROID) ? 2 : 8); // Sigtrap is used in error reporting. cf.handle_sigtrap = kHandleSignalExclusive; diff --git a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp index 7642ba6c0bf0..bf69694a5476 100644 --- a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp +++ b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp @@ -26,7 +26,7 @@ // The code in this file needs to run in an unrelocated binary. It should not // access any external symbol, including its own non-hidden globals. -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS extern "C" { INTERFACE_ATTRIBUTE void __hwasan_shadow(); diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index d97974ee9074..1acfe19dc8b6 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -18,7 +18,7 @@ #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \ - !SANITIZER_SOLARIS + !SANITIZER_SOLARIS && !SANITIZER_OHOS # error "Interception doesn't work on this operating system." #endif diff --git a/compiler-rt/lib/interception/interception_type_test.cpp b/compiler-rt/lib/interception/interception_type_test.cpp index 2a118fb214ff..0146b2b34f0a 100644 --- a/compiler-rt/lib/interception/interception_type_test.cpp +++ b/compiler-rt/lib/interception/interception_type_test.cpp @@ -31,8 +31,8 @@ COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t)); // The following are the cases when pread (and friends) is used instead of // pread64. In those cases we need OFF_T to match off_t. We don't care about the // rest (they depend on _FILE_OFFSET_BITS setting when building an application). -# if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ - _FILE_OFFSET_BITS != 64 +#if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ + _FILE_OFFSET_BITS != 64 || SANITIZER_OHOS COMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t)); # endif diff --git a/compiler-rt/lib/orc/endianness.h b/compiler-rt/lib/orc/endianness.h index 4ee5505ce6dd..a8e55629a6be 100644 --- a/compiler-rt/lib/orc/endianness.h +++ b/compiler-rt/lib/orc/endianness.h @@ -22,7 +22,8 @@ #endif #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ - defined(__Fuchsia__) || defined(__EMSCRIPTEN__) + defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || \ + defined(__OHOS_FAMILY__) #include #elif defined(_AIX) #include diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index b29665a63390..507c181f0526 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2276,11 +2276,13 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { #if SANITIZER_GLIBC namespace __sanitizer { extern "C" { +#if !SANITIZER_OHOS int real_clock_gettime(u32 clk_id, void *tp) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_clock_gettime(clk_id, tp); return REAL(clock_gettime)(clk_id, tp); } +#endif } // extern "C" } // namespace __sanitizer #endif @@ -2666,7 +2668,7 @@ INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { } return res; } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage); @@ -3973,7 +3975,7 @@ INTERCEPTOR(char *, strerror, int errnum) { // static storage. #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ SANITIZER_APPLE || SANITIZER_ANDROID || SANITIZER_NETBSD || \ - SANITIZER_FREEBSD + SANITIZER_FREEBSD || SANITIZER_OHOS // POSIX version. Spec is not clear on whether buf is NULL-terminated. // At least on OSX, buf contents are valid even when the call fails. INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index 49ec4097c900..17ac1af2431c 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 a38b134085aa..7e7628ea0c1c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -2509,7 +2509,7 @@ PRE_SYSCALL(ni_syscall)() {} POST_SYSCALL(ni_syscall)(long res) {} PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { -# if !SANITIZER_ANDROID && \ +# if !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ SANITIZER_RISCV64) @@ -2531,7 +2531,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { } POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { -# if !SANITIZER_ANDROID && \ +# if !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ SANITIZER_RISCV64) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h index 46c85364cef5..e85533c0fd8a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h @@ -23,7 +23,7 @@ #if SANITIZER_FREEBSD || SANITIZER_APPLE # define __errno_location __error -#elif SANITIZER_ANDROID || SANITIZER_NETBSD +#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_OHOS # 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 6148ae56067c..509bcf6afd1a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -62,7 +62,7 @@ COMMON_FLAG( COMMON_FLAG(const char *, log_suffix, nullptr, "String to append to log file name, e.g. \".txt\".") COMMON_FLAG( - bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_APPLE, + bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_OHOS || (bool)SANITIZER_APPLE, "Write all sanitizer output to syslog in addition to other means of " "logging.") COMMON_FLAG( @@ -242,13 +242,13 @@ COMMON_FLAG(bool, intercept_stat, true, COMMON_FLAG(bool, intercept_send, true, "If set, uses custom wrappers for send* functions " "to find more errors.") -COMMON_FLAG(bool, decorate_proc_maps, (bool)SANITIZER_ANDROID, +COMMON_FLAG(bool, decorate_proc_maps, (bool)SANITIZER_ANDROID || (bool)SANITIZER_OHOS, "If set, decorate sanitizer mappings in /proc/self/maps with " "user-readable names") COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool " "found an error") COMMON_FLAG( - bool, abort_on_error, (bool)SANITIZER_ANDROID || (bool)SANITIZER_APPLE, + bool, abort_on_error, (bool)SANITIZER_ANDROID || (bool)SANITIZER_OHOS || (bool)SANITIZER_APPLE, "If set, the tool calls abort() instead of _exit() after printing the " "error report.") COMMON_FLAG(bool, suppress_equal_pcs, true, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index 15738ff1e1bc..9a5923dd8301 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -177,7 +177,8 @@ typedef long pid_t; typedef int pid_t; #endif -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE || \ +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE || \ + SANITIZER_OHOS || \ (SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \ (SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID) || \ (SANITIZER_LINUX && (defined(__x86_64__) || defined(__hexagon__))) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index dc2ea933fadc..f5bdf4b575dc 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 @@ -163,7 +162,7 @@ void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *old) { ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) { __sanitizer_sigset_t set; internal_sigfillset(&set); -# if SANITIZER_LINUX && !SANITIZER_ANDROID +# if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked // on any thread, setuid call hangs. // See test/sanitizer_common/TestCases/Linux/setuid.c. @@ -895,7 +894,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { // rt_sigaction, so we need to do the same (we'll need to reimplement the // restorers; for x86_64 the restorer address can be obtained from // oldact->sa_restorer upon a call to sigaction(xxx, NULL, oldact). -#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 +#if (!SANITIZER_ANDROID && !SANITIZER_OHOS) || !SANITIZER_MIPS32 k_act.sa_restorer = u_act->sa_restorer; #endif } @@ -911,7 +910,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { internal_memcpy(&u_oldact->sa_mask, &k_oldact.sa_mask, sizeof(__sanitizer_kernel_sigset_t)); u_oldact->sa_flags = k_oldact.sa_flags; -#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 +#if (!SANITIZER_ANDROID && !SANITIZER_OHOS) || !SANITIZER_MIPS32 u_oldact->sa_restorer = k_oldact.sa_restorer; #endif } @@ -1081,7 +1080,7 @@ static uptr GetKernelAreaSize() { if ((segment.end >= 3 * gbyte) && segment.IsWritable()) return 0; } -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS // Even if nothing is mapped, top Gb may still be accessible // if we are running on 64-bit kernel. // Uname may report misleading results if personality type diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 761c57d1b8eb..6d619b1e7d37 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -134,7 +134,7 @@ inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { ReleaseMemoryPagesToOS(beg, end); } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS #if defined(__aarch64__) # define __get_tls() \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index d74851c43e14..9032962b7f9e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -82,7 +82,7 @@ struct __sanitizer::linux_dirent { #endif #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS #include #include #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 32005eef08cd..088cba6b36eb 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -14,7 +14,7 @@ #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ - !(defined(__sun__) && defined(__svr4__)) + !defined(__OHOS_FAMILY__) && !(defined(__sun__) && defined(__svr4__)) # error "This operating system is not supported" #endif @@ -123,6 +123,12 @@ # define SANITIZER_ANDROID 0 #endif +#if defined(__OHOS__) +#define SANITIZER_OHOS 1 +#else +#define SANITIZER_OHOS 0 +#endif + #if defined(__Fuchsia__) # define SANITIZER_FUCHSIA 1 #else @@ -284,7 +290,8 @@ // For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or // change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here. #ifndef SANITIZER_CAN_USE_ALLOCATOR64 -# if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA +# if ((SANITIZER_ANDROID || SANITIZER_OHOS) && defined(__aarch64__)) || \ + SANITIZER_FUCHSIA # define SANITIZER_CAN_USE_ALLOCATOR64 1 # elif defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index ffa7e272b7e0..0640991620af 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -58,6 +58,12 @@ #define SI_ANDROID 0 #endif +#if SANITIZER_OHOS +#define SI_OHOS 1 +#else +#define SI_OHOS 0 +#endif + #if SANITIZER_FREEBSD #define SI_FREEBSD 1 #else @@ -270,7 +276,7 @@ #define SANITIZER_INTERCEPT_SYSINFO SI_LINUX #define SANITIZER_INTERCEPT_READDIR SI_POSIX #define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 -#if SI_LINUX_NOT_ANDROID && \ +#if SI_LINUX_NOT_ANDROID && !SI_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ defined(__s390__) || SANITIZER_RISCV64) @@ -340,7 +346,7 @@ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_SHMCTL \ - (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && SANITIZER_WORDSIZE == 64) || \ + (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && !SI_OHOS && SANITIZER_WORDSIZE == 64) || \ SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_RANDOM_R SI_GLIBC #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX @@ -466,7 +472,7 @@ #define SI_STAT_LINUX (SI_LINUX && __GLIBC_PREREQ(2, 33)) #define SANITIZER_INTERCEPT_STAT \ (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || \ - SI_STAT_LINUX) + SI_STAT_LINUX || SI_OHOS) #define SANITIZER_INTERCEPT_STAT64 SI_STAT_LINUX && SANITIZER_HAS_STAT64 #define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX) #define SANITIZER_INTERCEPT___XSTAT \ @@ -497,7 +503,7 @@ #define SANITIZER_INTERCEPT_WCSCAT SI_POSIX #define SANITIZER_INTERCEPT_WCSDUP SI_POSIX #define SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA) -#define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID +#define SANITIZER_INTERCEPT_BSD_SIGNAL (SI_ANDROID || SI_OHOS) #define SANITIZER_INTERCEPT_ACCT (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_USER_FROM_UID SI_NETBSD @@ -509,7 +515,7 @@ #define SANITIZER_INTERCEPT_GETGROUPLIST \ (SI_NETBSD || SI_FREEBSD || SI_LINUX) #define SANITIZER_INTERCEPT_STRLCPY \ - (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID) + (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID || SI_OHOS) #define SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT SI_LINUX_NOT_ANDROID diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp index bf0f355847cb..6d608cbb63ed 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -76,7 +76,7 @@ CHECK_SIZE_AND_OFFSET(io_event, obj); CHECK_SIZE_AND_OFFSET(io_event, res); CHECK_SIZE_AND_OFFSET(io_event, res2); -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_OHOS COMPILER_CHECK(sizeof(struct __sanitizer_perf_event_attr) <= sizeof(struct perf_event_attr)); CHECK_SIZE_AND_OFFSET(perf_event_attr, type); @@ -85,7 +85,7 @@ CHECK_SIZE_AND_OFFSET(perf_event_attr, size); COMPILER_CHECK(iocb_cmd_pread == IOCB_CMD_PREAD); COMPILER_CHECK(iocb_cmd_pwrite == IOCB_CMD_PWRITE); -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_OHOS COMPILER_CHECK(iocb_cmd_preadv == IOCB_CMD_PREADV); COMPILER_CHECK(iocb_cmd_pwritev == IOCB_CMD_PWRITEV); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index c85cf1626a75..839d31a8b75c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -69,7 +69,9 @@ #include #include #include +#if !SANITIZER_OHOS #include +#endif #include #include #include @@ -93,6 +95,13 @@ #if SANITIZER_LINUX # include # include +# if SANITIZER_OHOS +// Do not include asm/sigcontext.h on behalf of asm/ptrace.h +// to avoid multiple definiton errors. +# define __ASM_SIGCONTEXT_H 1 +# include +# endif + # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ defined(__hexagon__) || SANITIZER_RISCV64 # include @@ -133,6 +142,13 @@ typedef struct user_fpregs elf_fpregset_t; #if SANITIZER_ANDROID #include +#elif SANITIZER_OHOS +#include +#include +#include +#include +#include +#include #else #include #include @@ -303,7 +319,6 @@ namespace __sanitizer { int e_tabsz = (int)E_TABSZ; #endif - #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_shminfo_sz = sizeof(struct shminfo); unsigned struct_shm_info_sz = sizeof(struct shm_info); @@ -521,7 +536,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); #endif // SANITIZER_GLIBC -#if !SANITIZER_ANDROID && !SANITIZER_APPLE +#if !SANITIZER_ANDROID && !SANITIZER_APPLE && !SANITIZER_OHOS unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); #endif @@ -574,7 +589,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_TIOCSPGRP = TIOCSPGRP; unsigned IOCTL_TIOCSTI = TIOCSTI; unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT; #endif @@ -866,7 +881,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_EQL_EMANCIPATE = EQL_EMANCIPATE; unsigned IOCTL_EQL_ENSLAVE = EQL_ENSLAVE; unsigned IOCTL_EQL_GETMASTRCFG = EQL_GETMASTRCFG; @@ -950,7 +965,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_TIOCSSERIAL = TIOCSSERIAL; #endif // SANITIZER_LINUX && !SANITIZER_ANDROID -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_GIO_SCRNMAP = GIO_SCRNMAP; unsigned IOCTL_KDDISABIO = KDDISABIO; unsigned IOCTL_KDENABIO = KDENABIO; @@ -1118,7 +1133,8 @@ CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); // didn't exist. CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags); #endif -#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) +#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && \ + !SANITIZER_OHOS CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer); #endif @@ -1212,7 +1228,7 @@ CHECK_TYPE_SIZE(clock_t); CHECK_TYPE_SIZE(clockid_t); #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS CHECK_TYPE_SIZE(ifaddrs); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index bd5692ed511b..5718fddd3a18 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -212,13 +212,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; @@ -627,7 +629,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; @@ -816,7 +818,7 @@ struct __sanitizer_wordexp_t { uptr we_offs; }; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS struct __sanitizer_FILE { int _flags; char *_IO_read_ptr; @@ -840,7 +842,7 @@ typedef void __sanitizer_FILE; # define SANITIZER_HAS_STRUCT_FILE 0 #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ defined(__s390__) || SANITIZER_RISCV64) @@ -1018,7 +1020,7 @@ extern unsigned struct_synth_info_sz; extern unsigned struct_vt_mode_sz; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS extern unsigned struct_ax25_parms_struct_sz; extern unsigned struct_input_keymap_entry_sz; extern unsigned struct_ipx_config_data_sz; @@ -1044,7 +1046,7 @@ extern unsigned struct_audio_buf_info_sz; extern unsigned struct_ppp_stats_sz; #endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID -#if !SANITIZER_ANDROID && !SANITIZER_APPLE +#if !SANITIZER_ANDROID && !SANITIZER_APPLE && !SANITIZER_OHOS extern unsigned struct_sioc_sg_req_sz; extern unsigned struct_sioc_vif_req_sz; #endif @@ -1099,7 +1101,7 @@ extern unsigned IOCTL_TIOCSETD; extern unsigned IOCTL_TIOCSPGRP; extern unsigned IOCTL_TIOCSTI; extern unsigned IOCTL_TIOCSWINSZ; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS extern unsigned IOCTL_SIOCGETSGCNT; extern unsigned IOCTL_SIOCGETVIFCNT; #endif @@ -1371,7 +1373,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 b0e32b50c076..87d2d717de3a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -344,7 +344,7 @@ bool ShouldMockFailureToOpen(const char *path) { internal_strncmp(path, "/proc/", 6) == 0; } -#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO && !SANITIZER_OHOS int GetNamedMappingFd(const char *name, uptr size, int *flags) { if (!common_flags()->decorate_proc_maps || !name) return -1; @@ -376,7 +376,7 @@ int GetNamedMappingFd(const char *name, uptr size, int *flags) { } #endif -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS #define PR_SET_VMA 0x53564d41 #define PR_SET_VMA_ANON_NAME 0 void DecorateMapping(uptr addr, uptr size, const char *name) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index 46e41c669738..ec874e50adc4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -171,7 +171,8 @@ void SetAlternateSignalStack() { CHECK_EQ(0, sigaltstack(nullptr, &oldstack)); // If the alternate stack is already in place, do nothing. // Android always sets an alternate stack, but it's too small for us. - if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return; + if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) + return; // TODO(glider): the mapped stack should have the MAP_STACK flag in the // future. It is not required by man 2 sigaltstack now (they're using // malloc()). diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp index a746d4621936..590348fd67ad 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -27,7 +27,7 @@ struct StackDepotNode { u32 link; StackStore::Id store_id; - static const u32 kTabSizeLog = SANITIZER_ANDROID ? 16 : 20; + static const u32 kTabSizeLog = (SANITIZER_ANDROID || SANITIZER_OHOS) ? 16 : 20; typedef StackTrace args_type; bool eq(hash_type hash, const args_type &args) const { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h index cca6fd534688..91b93a1b937e 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 403bda1174cc..9598c41ea676 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 d5c028e3640d..f4e138d5c990 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -89,7 +89,7 @@ void ReportErrorSummary(const char *error_type, const StackTrace *stack, } void ReportMmapWriteExec(int prot, int flags) { -#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID) +#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID) && !SANITIZER_OHOS int pflags = (PROT_WRITE | PROT_EXEC); if ((prot & pflags) != pflags) return; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp index 72f025a7d307..a793432c5276 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 c124738c1f3a..ce4d641b811a 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 07d4b70fc8e9..c2414ec60237 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 2c91db8ca397..002e87038cfb 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/TestCases/Linux/lit.local.cfg.py b/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py index 57271b8078a4..c2352c676cc5 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 9929b4a67af3..f5f234028867 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 e1752bc894c0..8fed52092be8 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 b437a151e16a..cbe84170c61e 100644 --- a/compiler-rt/test/asan/lit.cfg.py +++ b/compiler-rt/test/asan/lit.cfg.py @@ -239,7 +239,7 @@ else: config.substitutions.append(('%pie', '-pie')) # Only run the tests on supported OSs. -if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'SunOS', 'Windows', 'NetBSD']: +if config.host_os not in ['OHOS', 'Linux', 'Darwin', 'FreeBSD', 'SunOS', 'Windows', 'NetBSD']: config.unsupported = True if not config.parallelism_group: diff --git a/compiler-rt/test/builtins/Unit/divtf3_test.c b/compiler-rt/test/builtins/Unit/divtf3_test.c index 927d0b826f8f..f8b1f20e59d2 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 3dd258283e5c..a49c3c0bbfde 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -83,6 +83,9 @@ def find_compiler_libdir(): return None +def is_ohos_family_mobile(): + return config.ohos_family and config.target_arch != 'x86_64' + # Choose between lit's internal shell pipeline runner and a real shell. If # LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") @@ -232,10 +235,10 @@ if config.host_os == 'NetBSD': config.netbsd_nomprotect_prefix = ('sh ' + os.path.join(nb_commands_dir, 'run_nomprotect.sh')) - config.substitutions.append( ('%run_nomprotect', - config.netbsd_nomprotect_prefix) ) + config.substitutions.append(('%run_nomprotect', + config.netbsd_nomprotect_prefix)) else: - config.substitutions.append( ('%run_nomprotect', '%run') ) + config.substitutions.append(('%run_nomprotect', '%run')) # Copied from libcxx's config.py def get_lit_conf(name, default=None): @@ -254,13 +257,26 @@ def get_ios_commands_dir(): # Allow tests to be executed on a simulator or remotely. if emulator: - config.substitutions.append( ('%run', emulator) ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', emulator)) + config.substitutions.append(('%env ', "env ")) # TODO: Implement `%device_rm` to perform removal of files in the emulator. # For now just make it a no-op. lit_config.warning('%device_rm is not implemented') - config.substitutions.append( ('%device_rm', 'echo ') ) + config.substitutions.append(('%device_rm', 'echo ')) config.compile_wrapper = "" +elif is_ohos_family_mobile(): + config.available_features.add('ohos_family') + # FIXME: some tests for hos also need this now, + # probably this shouldn't be added for ohos + config.available_features.add('android') + compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ohos_family_commands", "ohos_compile.py") + " " + config.compile_wrapper = compile_wrapper + config.substitutions.append( ('%run', "") ) + config.substitutions.append( ('%env ', "env ") ) + # TODO: Implement `%device_rm` to perform removal of files on a device. For + # now just make it a no-op. + lit_config.warning('%device_rm is not implemented') + config.substitutions.append( ('%device_rm', 'echo ') ) elif config.host_os == 'Darwin' and config.apple_platform != "osx": # Darwin tests can be targetting macOS, a device or a simulator. All devices # are declared as "ios", even for iOS derivatives (tvOS, watchOS). Similarly, @@ -321,20 +337,20 @@ elif config.android: config.available_features.add('android') compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "android_commands", "android_compile.py") + " " config.compile_wrapper = compile_wrapper - config.substitutions.append( ('%run', "") ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', "")) + config.substitutions.append(('%env ', "env ")) else: - config.substitutions.append( ('%run', "") ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', "")) + config.substitutions.append(('%env ', "env ")) # When running locally %device_rm is a no-op. - config.substitutions.append( ('%device_rm', 'echo ') ) + config.substitutions.append(('%device_rm', 'echo ')) config.compile_wrapper = "" # Define CHECK-%os to check for OS-dependent output. -config.substitutions.append( ('CHECK-%os', ("CHECK-" + config.host_os))) +config.substitutions.append(('CHECK-%os', ("CHECK-" + config.host_os))) # Define %arch to check for architecture-dependent output. -config.substitutions.append( ('%arch', (config.host_arch))) +config.substitutions.append(('%arch', (config.host_arch))) if config.host_os == 'Windows': # FIXME: This isn't quite right. Specifically, it will succeed if the program @@ -345,7 +361,7 @@ if config.host_os == 'Windows': else: config.expect_crash = "not --crash " -config.substitutions.append( ("%expect_crash ", config.expect_crash) ) +config.substitutions.append(("%expect_crash ", config.expect_crash)) target_arch = getattr(config, 'target_arch', None) if target_arch: @@ -475,26 +491,27 @@ if config.android: # These are needed for tests to upload/download temp files, such as # suppression-files, to device. config.substitutions.append( ('%device_rundir/', "/data/local/tmp/Output/") ) - config.substitutions.append( ('%push_to_device', "%s -s '%s' push " % (adb, env['ANDROID_SERIAL']) ) ) - config.substitutions.append( ('%adb_shell ', "%s -s '%s' shell " % (adb, env['ANDROID_SERIAL']) ) ) - config.substitutions.append( ('%device_rm', "%s -s '%s' shell 'rm ' " % (adb, env['ANDROID_SERIAL']) ) ) + if not config.host_os == 'OHOS': + config.substitutions.append( ('%push_to_device', "%s -s '%s' push " % (adb, env['ANDROID_SERIAL']) ) ) + config.substitutions.append( ('%adb_shell ', "%s -s '%s' shell " % (adb, env['ANDROID_SERIAL']) ) ) + config.substitutions.append( ('%device_rm', "%s -s '%s' shell 'rm ' " % (adb, env['ANDROID_SERIAL']) ) ) - try: - android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip() - android_api_codename = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.codename"], env=env).rstrip().decode("utf-8") - except (subprocess.CalledProcessError, OSError): - lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb)" % adb) - try: - android_api_level = int(android_api_level_str) - except ValueError: - lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb): got '%s'" % (adb, android_api_level_str)) - android_api_level = min(android_api_level, int(config.android_api_level)) - for required in [26, 28, 29, 30]: - if android_api_level >= required: - config.available_features.add('android-%s' % required) - # FIXME: Replace with appropriate version when availible. - if android_api_level > 30 or (android_api_level == 30 and android_api_codename == 'S'): - config.available_features.add('android-thread-properties-api') + try: + android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip() + android_api_codename = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.codename"], env=env).rstrip().decode("utf-8") + except (subprocess.CalledProcessError, OSError): + lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb)" % adb) + try: + android_api_level = int(android_api_level_str) + except ValueError: + lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb): got '%s'" % (adb, android_api_level_str)) + android_api_level = min(android_api_level, int(config.android_api_level)) + for required in [26, 28, 29, 30]: + if android_api_level >= required: + config.available_features.add('android-%s' % required) + # FIXME: Replace with appropriate version when availible. + if android_api_level > 30 or (android_api_level == 30 and android_api_codename == 'S'): + config.available_features.add('android-thread-properties-api') # Prepare the device. android_tmpdir = '/data/local/tmp/Output' @@ -636,7 +653,7 @@ for postfix in ["2", "1", ""]: elif config.host_os in ('FreeBSD', 'NetBSD', 'OpenBSD'): config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) ) config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') ) - elif config.host_os == 'Linux': + elif config.host_os in ['Linux', 'OHOS']: config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) ) config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') ) elif config.host_os == 'SunOS': @@ -675,7 +692,7 @@ if config.host_os == 'Darwin': lit_config.warning('log command found but cannot queried') else: lit_config.warning('log command not found. Some tests will be skipped.') -elif config.android: +elif config.android or is_ohos_family_mobile(): config.default_sanitizer_opts += ['abort_on_error=0'] # Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL diff --git a/compiler-rt/test/lit.common.configured.in b/compiler-rt/test/lit.common.configured.in index 5db6ef0121fb..a06ede7e7331 100644 --- a/compiler-rt/test/lit.common.configured.in +++ b/compiler-rt/test/lit.common.configured.in @@ -41,6 +41,7 @@ set_default("use_lld", @COMPILER_RT_TEST_USE_LLD_PYBOOL@) set_default("use_thinlto", False) set_default("use_lto", config.use_thinlto) set_default("android", @ANDROID_PYBOOL@) +set_default("ohos_family", @OHOS_FAMILY_PYBOOL@) set_default("android_api_level", "@ANDROID_API_LEVEL@") set_default("android_serial", "@ANDROID_SERIAL_FOR_TESTING@") set_default("android_files_to_push", []) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py new file mode 100644 index 000000000000..da6e6b9d2fd4 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py @@ -0,0 +1,45 @@ +import os, subprocess, tempfile + +HOS_TMPDIR = '/data/local/tmp/Output' +ADB = os.environ.get('ADB', 'adb') + +verbose = False +if os.environ.get('HOS_RUN_VERBOSE') == '1': + verbose = True + +def host_to_device_path(path): + rel = os.path.relpath(path, "/") + dev = os.path.join(HOS_TMPDIR, rel) + return dev + +def adb(args, attempts = 1): + if verbose: + print args + tmpname = tempfile.mktemp() + out = open(tmpname, 'w') + ret = 255 + while attempts > 0 and ret != 0: + attempts -= 1 + ret = subprocess.call([ADB] + args, stdout=out, stderr=subprocess.STDOUT) + if attempts != 0: + ret = 5 + if ret != 0: + print "adb command failed", args + print tmpname + out.close() + out = open(tmpname, 'r') + print out.read() + out.close() + os.unlink(tmpname) + return ret + +def pull_from_device(path): + tmp = tempfile.mktemp() + adb(['pull', path, tmp], 5) + text = open(tmp, 'r').read() + os.unlink(tmp) + return text + +def push_to_device(path): + dst_path = host_to_device_path(path) + adb(['push', path, dst_path], 5) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py new file mode 100644 index 000000000000..1c8624fbd621 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +import os, sys, subprocess +from ohos_common import * + + +here = os.path.abspath(os.path.dirname(sys.argv[0])) +hos_run = os.path.join(here, 'hos_run.py') + +output = None +output_type = 'executable' + +args = sys.argv[1:] +append_args = [] +check_trgt = False +while args: + arg = args.pop(0) + if arg == '-shared': + output_type = 'shared' + elif arg == '-c': + output_type = 'object' + elif arg == '-o': + output = args.pop(0) + elif arg == '-target': + check_trgt = True + elif check_trgt or arg.startswith('--target='): + check_trgt = False + if arg.endswith('-linux-ohos'): + arg = arg.split('=')[-1] + dyld = 'unknown_hos_dyld' + # FIXME: Handle -mfloat-abi=hard for arm + # TODO: Support x86_64 + if arg.startswith('arm'): + dyld = 'ld-musl-arm.so.1' + elif arg.startswith('aarch64'): + dyld = 'ld-musl-aarch64.so.1' + append_args += ['-Wl,--dynamic-linker=' + os.path.join(HOS_TMPDIR, dyld)] + +if output == None: + print "No output file name!" + sys.exit(1) + +ret = subprocess.call(sys.argv[1:] + append_args) +if ret != 0: + sys.exit(ret) + +if output_type in ['executable', 'shared']: + push_to_device(output) + +if output_type == 'executable': + os.rename(output, output + '.real') + os.symlink(hos_run, output) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py new file mode 100644 index 000000000000..84a8d9fb709c --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py @@ -0,0 +1,38 @@ +#!/usr/bin/python + +import os, signal, sys, subprocess +import re +from ohos_common import * + +device_binary = host_to_device_path(sys.argv[0]) + +def build_env(): + args = [] + # HOS linker ignores RPATH. Set LD_LIBRARY_PATH to Output dir. + args.append('LD_LIBRARY_PATH=%s' % (HOS_TMPDIR,)) + for (key, value) in os.environ.items(): + if key in ['ASAN_ACTIVATION_OPTIONS', 'SCUDO_OPTIONS'] or key.endswith('SAN_OPTIONS'): + args.append('%s="%s"' % (key, value)) + return ' '.join(args) + +device_env = build_env() +device_args = ' '.join(sys.argv[1:]) # FIXME: escape? +device_stdout = device_binary + '.stdout' +device_stderr = device_binary + '.stderr' +device_exitcode = device_binary + '.exitcode' +device_linker = '' + +ret = adb(['shell', 'cd %s && %s %s %s %s >%s 2>%s ; echo $? >%s' % + (HOS_TMPDIR, device_env, device_linker, device_binary, device_args, + device_stdout, device_stderr, device_exitcode)]) +if ret != 0: + sys.exit(ret) + +sys.stdout.write(pull_from_device(device_stdout)) +sys.stderr.write(pull_from_device(device_stderr)) +retcode = int(pull_from_device(device_exitcode)) +# If the device process died with a signal, do abort(). +# Not exactly the same, but good enough to fool "not --crash". +if retcode > 128: + os.kill(os.getpid(), signal.SIGABRT) +sys.exit(retcode) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 74eff2002fc9..945a59509075 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -416,13 +416,21 @@ set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH "Path where built libc++ runtime libraries should be installed.") if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) - set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") - set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH - "Path where built libc++ libraries should be installed.") set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE PATH "Path where target-specific libc++ headers should be installed.") + if(OHOS) + set(LIBCXX_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBCXX_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX} CACHE PATH + "Path where built libc++ libraries should be installed.") + else() + set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libc++ libraries should be installed.") + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake index 209e6214a471..9e79b7bbde3f 100644 --- a/libcxx/cmake/config-ix.cmake +++ b/libcxx/cmake/config-ix.cmake @@ -114,6 +114,8 @@ elseif(APPLE) set(LIBCXX_HAS_M_LIB NO) set(LIBCXX_HAS_RT_LIB NO) set(LIBCXX_HAS_ATOMIC_LIB NO) +elseif(OHOS) + set(LIBCXX_HAS_ATOMIC_LIB NO) elseif(FUCHSIA) set(LIBCXX_HAS_M_LIB NO) set(LIBCXX_HAS_PTHREAD_LIB NO) diff --git a/libcxx/include/__config b/libcxx/include/__config index 810189c94a94..8bc9e49e9b35 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -912,7 +912,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD defined(__sun__) || \ defined(__MVS__) || \ defined(_AIX) || \ - defined(__EMSCRIPTEN__) + defined(__EMSCRIPTEN__) || \ + defined(__OHOS_FAMILY__) // clang-format on # define _LIBCPP_HAS_THREAD_API_PTHREAD # elif defined(__Fuchsia__) @@ -990,7 +991,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # endif # if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \ - defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) || defined(__OHOS_FAMILY__) # define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE # endif diff --git a/libcxx/include/__locale b/libcxx/include/__locale index 40f9a3ff57c2..e1407a07f632 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -40,6 +40,9 @@ #elif defined(__wasi__) // WASI libc uses musl's locales support. # include <__support/musl/xlocale.h> +#elif defined(__LITEOS__) || defined(__OHOS__) +// LiteOS libc uses musl's locales support. +# include <__support/musl/xlocale.h> #elif defined(_LIBCPP_HAS_MUSL_LIBC) # include <__support/musl/xlocale.h> #endif diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt index 9abf548abbb9..02ee3e023a23 100644 --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -194,6 +194,9 @@ endfunction() split_list(LIBCXX_COMPILE_FLAGS) split_list(LIBCXX_LINK_FLAGS) +if (NOT DEFINED LIBCXX_OUTPUT_NAME) + set (LIBCXX_OUTPUT_NAME "c++") +endif() # Build the shared library. if (LIBCXX_ENABLE_SHARED) add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) @@ -204,7 +207,7 @@ if (LIBCXX_ENABLE_SHARED) PROPERTIES COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" LINK_FLAGS "${LIBCXX_LINK_FLAGS}" - OUTPUT_NAME "c++" + OUTPUT_NAME "${LIBCXX_OUTPUT_NAME}" VERSION "${LIBCXX_LIBRARY_VERSION}" SOVERSION "${LIBCXX_ABI_VERSION}" DEFINE_SYMBOL "" @@ -278,6 +281,9 @@ endif() set(CMAKE_STATIC_LIBRARY_PREFIX "lib") +if (NOT DEFINED LIBCXX_OUTPUT_STATIC_NAME) + set (LIBCXX_OUTPUT_STATIC_NAME "c++") +endif() # Build the static library. if (LIBCXX_ENABLE_STATIC) add_library(cxx_static STATIC ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) @@ -289,7 +295,7 @@ if (LIBCXX_ENABLE_STATIC) PROPERTIES COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" LINK_FLAGS "${LIBCXX_LINK_FLAGS}" - OUTPUT_NAME "c++" + OUTPUT_NAME "${LIBCXX_OUTPUT_STATIC_NAME}" ) cxx_add_common_build_flags(cxx_static) cxx_set_common_defines(cxx_static) diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h index bef26ec5019e..0e762d276330 100644 --- a/libcxx/src/include/config_elast.h +++ b/libcxx/src/include/config_elast.h @@ -29,6 +29,8 @@ // No _LIBCPP_ELAST needed on Fuchsia #elif defined(__wasi__) // No _LIBCPP_ELAST needed on WASI +#elif defined(__OHOS_FAMILY__) +// No _LIBCPP_ELAST needed on OHOS #elif defined(__EMSCRIPTEN__) // No _LIBCPP_ELAST needed on Emscripten #elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC) diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt index b8326d08d23a..f6f945a134f8 100644 --- a/libcxxabi/CMakeLists.txt +++ b/libcxxabi/CMakeLists.txt @@ -186,9 +186,17 @@ set(LIBCXXABI_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) set(LIBCXXABI_HEADER_DIR ${LLVM_BINARY_DIR}) - set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) - set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH - "Path where built libc++abi libraries should be installed.") + if(OHOS) + set(LIBCXXABI_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBCXXABI_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX} CACHE PATH + "Path where built libc++abi libraries should be installed.") + else() + set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libc++abi libraries should be installed.") + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXXABI_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR}) string(APPEND LIBCXXABI_INSTALL_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR}) diff --git a/libcxxabi/src/abort_message.cpp b/libcxxabi/src/abort_message.cpp index 859a5031b93f..2264168e1ef0 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 5a06805f05f1..a895e4787c85 100644 --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -116,9 +116,17 @@ set(LIBUNWIND_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH "Path where built libunwind runtime libraries should be installed.") if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) - set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) - set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH - "Path where built libunwind libraries should be installed.") + if(OHOS) + set(LIBUNWIND_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBUNWIND_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX} CACHE PATH + "Path where built libunwind libraries should be installed.") + else() + set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libunwind libraries should be installed.") + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBUNWIND_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR}) string(APPEND LIBUNWIND_INSTALL_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR}) @@ -313,7 +321,7 @@ if (C_SUPPORTS_COMMENT_LIB_PRAGMA) if (LIBUNWIND_HAS_DL_LIB) add_definitions(-D_LIBUNWIND_LINK_DL_LIB) endif() - if (LIBUNWIND_HAS_PTHREAD_LIB) + if (LIBUNWIND_HAS_PTHREAD_LIB AND NOT OHOS) add_definitions(-D_LIBUNWIND_LINK_PTHREAD_LIB) endif() endif() diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index af976e39147d..d6babe9f74c2 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -286,6 +286,8 @@ struct Configuration { uint64_t zStackSize; unsigned ltoPartitions; unsigned ltoo; + unsigned ltos; + bool mergeFunctions; unsigned optimize; StringRef thinLTOJobs; unsigned timeTraceGranularity; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 296fb4220012..abcc8a984a65 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -63,6 +63,7 @@ #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include +#include #include using namespace llvm; @@ -1018,6 +1019,47 @@ static bool isValidReportString(StringRef arg) { return arg == "none" || arg == "warning" || arg == "error"; } +static std::pair +parseLTOOptArg(opt::InputArgList &args, unsigned key, StringRef defaultValue) { + auto *a = args.getLastArg(key); + llvm::StringRef value = a ? a->getValue() : defaultValue; + + unsigned optLevel = 0; + unsigned sizeLevel = 0; + + if (value.size() != 1) { + error("invalid optimization level for LTO: " + value); + return {optLevel, sizeLevel}; + } + + char c = value[0]; + + switch (c) { + + case '0': + case '1': + case '2': + case '3': + optLevel = c - '0'; + break; + + case 's': + optLevel = 2; + sizeLevel = 1; + break; + + case 'z': + optLevel = 2; + sizeLevel = 2; + break; + + default: + error("invalid optimization level for LTO: " + value); + } + + return {optLevel, sizeLevel}; +} + // Initializes Config members by the command line options. static void readConfigs(opt::InputArgList &args) { errorHandler().verbose = args.hasArg(OPT_verbose); @@ -1104,8 +1146,9 @@ static void readConfigs(opt::InputArgList &args) { config->ltoWholeProgramVisibility = args.hasFlag(OPT_lto_whole_program_visibility, OPT_no_lto_whole_program_visibility, false); - config->ltoo = args::getInteger(args, OPT_lto_O, 2); config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq); + std::tie(config->ltoo, config->ltos) = parseLTOOptArg(args, OPT_lto_O, "2"); + config->mergeFunctions = args.hasArg(OPT_lto_mf); config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile); config->ltoBasicBlockSections = diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index d9266e595887..4e6c20f5c7f6 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -557,6 +557,10 @@ def lto_newpm_passes: JJ<"lto-newpm-passes=">, HelpText<"Passes to run during LTO">; def lto_O: JJ<"lto-O">, MetaVarName<"">, HelpText<"Optimization level for LTO">; +def lto_S: J<"lto-S">, MetaVarName<"">, + HelpText<"Size Optimization level for LTO, works only with -lto-O2">; +def lto_mf: F<"lto-mf">, + HelpText<"Enable Merge Functions pass for link time optimizations.">; def lto_partitions: JJ<"lto-partitions=">, HelpText<"Number of LTO codegen partitions">; def lto_cs_profile_generate: FF<"lto-cs-profile-generate">, diff --git a/lld/test/ELF/lto/opt-level.ll b/lld/test/ELF/lto/opt-level.ll index 6e0cc9ac98c5..628e4ef7126c 100644 --- a/lld/test/ELF/lto/opt-level.ll +++ b/lld/test/ELF/lto/opt-level.ll @@ -19,14 +19,14 @@ ; RUN: FileCheck --check-prefix=INVALID1 %s ; RUN: not ld.lld -o /dev/null -e main --plugin-opt=Ofoo %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALID2 %s -; INVALID2: --plugin-opt=Ofoo: number expected, but got 'foo' +; INVALID2: invalid optimization level for LTO: foo ; RUN: not ld.lld -o /dev/null -e main --lto-O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s -; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE1: invalid optimization level for LTO: -1 ; RUN: not ld.lld -o /dev/null -e main --plugin-opt=O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s -; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE2: invalid optimization level for LTO: -1 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lldb/cmake/modules/FindPythonAndSwig.cmake b/lldb/cmake/modules/FindPythonAndSwig.cmake index 3535b548c45f..562d5307e8c8 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 987353517d0d..55d1aa17b46b 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -313,7 +313,7 @@ endif() # Figure out if lldb could use lldb-server. If so, then we'll # ensure we build lldb-server when an lldb target is being built. -if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|Windows") +if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|Windows|OHOS") set(LLDB_CAN_USE_LLDB_SERVER ON) else() set(LLDB_CAN_USE_LLDB_SERVER OFF) diff --git a/lldb/include/lldb/Host/HostInfo.h b/lldb/include/lldb/Host/HostInfo.h index b7010d69d88e..fbb5bbf1e442 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 f04ac7359cc1..c89a28387b6a 100644 --- a/lldb/include/lldb/Host/MainLoop.h +++ b/lldb/include/lldb/Host/MainLoop.h @@ -16,7 +16,8 @@ #include #include -#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) +#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) && \ + !defined(__OHOS_FAMILY__) #define SIGNAL_POLLING_UNSUPPORTED 1 #endif diff --git a/lldb/include/lldb/Host/ohos/HostInfoOHOS.h b/lldb/include/lldb/Host/ohos/HostInfoOHOS.h new file mode 100644 index 000000000000..e20582820145 --- /dev/null +++ b/lldb/include/lldb/Host/ohos/HostInfoOHOS.h @@ -0,0 +1,32 @@ +//===-- HostInfoOHOS.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_ohos_HostInfoOHOS_h_ +#define lldb_Host_ohos_HostInfoOHOS_h_ + +#include "lldb/Host/linux/HostInfoLinux.h" + +namespace lldb_private { + +class HostInfoOHOS : public HostInfoLinux { + friend class HostInfoBase; + +public: + static FileSpec GetDefaultShell(); + static FileSpec ResolveLibraryPath(const std::string &path, + const ArchSpec &arch); + +protected: + static void ComputeHostArchitectureSupport(ArchSpec &arch_32, + ArchSpec &arch_64); + static bool ComputeTempFileBaseDirectory(FileSpec &file_spec); +}; + +} // end of namespace lldb_private + +#endif // #ifndef lldb_Host_ohos_HostInfoOHOS_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepRange.h b/lldb/include/lldb/Target/ThreadPlanStepRange.h index 2fe885277100..36288a0d10ae 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 191a1e0ad7cc..dc553938e1cc 100644 --- a/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/lldb/packages/Python/lldbsuite/test/decorators.py @@ -663,6 +663,9 @@ def skipIfPlatform(oslist): return unittest2.skipIf(lldbplatformutil.getPlatform() in oslist, "skip on %s" % (", ".join(oslist))) +def skipOnOpenHarmonyCI(func): + return unittest2.skipIf(lldbplatformutil.isOpenHarmonyCI(), "skip on OpenHarmony CI")(func) + def skipUnlessPlatform(oslist): """Decorate the item to skip tests unless running on one of the listed platforms.""" diff --git a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py index 719131c9248e..317f19bd712f 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py +++ b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py @@ -149,6 +149,8 @@ def platformIsDarwin(): """Returns true if the OS triple for the selected platform is any valid apple OS""" return getPlatform() in getDarwinOSTriples() +def isOpenHarmonyCI(): + return getPlatform() == 'linux' and os.path.exists('/.dockerenv') def findMainThreadCheckerDylib(): if not platformIsDarwin(): diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index d46e54f30bd5..d6c249d644b1 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -739,11 +739,6 @@ class Base(unittest2.TestCase): for setting, value in configuration.settings: commands.append('setting set %s %s'%(setting, value)) - # Make sure that a sanitizer LLDB's environment doesn't get passed on. - if cls.platformContext and cls.platformContext.shlib_environment_var in os.environ: - commands.append('settings set target.env-vars {}='.format( - cls.platformContext.shlib_environment_var)) - # Set environment variables for the inferior. if lldbtest_config.inferior_env: commands.append('settings set target.env-vars {}'.format( diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index a6efeb3f960f..2a080fbcfd22 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -167,6 +167,18 @@ public: const Constant *constant = dyn_cast(value); if (constant) { + if (constant->getValueID() == Value::ConstantFPVal) { + if (auto *cfp = dyn_cast(constant)) { + if (cfp->getType()->isDoubleTy()) + scalar = cfp->getValueAPF().convertToDouble(); + else if (cfp->getType()->isFloatTy()) + scalar = cfp->getValueAPF().convertToFloat(); + else + return false; + return true; + } + return false; + } APInt value_apint; if (!ResolveConstantValue(value_apint, constant)) @@ -189,9 +201,18 @@ public: lldb::offset_t offset = 0; if (value_size <= 8) { - uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); - return AssignToMatchType(scalar, llvm::APInt(64, u64value), - value->getType()); + Type *ty = value->getType(); + if (ty->isDoubleTy()) { + scalar = value_extractor.GetDouble(&offset); + return true; + } else if (ty->isFloatTy()) { + scalar = value_extractor.GetFloat(&offset); + return true; + } else { + uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); + return AssignToMatchType(scalar, llvm::APInt(64, u64value), + value->getType()); + } } return false; @@ -205,11 +226,15 @@ public: return false; lldb_private::Scalar cast_scalar; - - scalar.MakeUnsigned(); - if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()), - value->getType())) - return false; + Type *vty = value->getType(); + if (vty->isFloatTy() || vty->isDoubleTy()) { + cast_scalar = scalar; + } else { + scalar.MakeUnsigned(); + if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()), + value->getType())) + return false; + } size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType()); @@ -543,16 +568,17 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, } break; case Instruction::GetElementPtr: break; + case Instruction::FCmp: case Instruction::ICmp: { - ICmpInst *icmp_inst = dyn_cast(&ii); + CmpInst *cmp_inst = dyn_cast(&ii); - if (!icmp_inst) { + if (!cmp_inst) { error.SetErrorToGenericError(); error.SetErrorString(interpreter_internal_error); return false; } - switch (icmp_inst->getPredicate()) { + switch (cmp_inst->getPredicate()) { default: { LLDB_LOGF(log, "Unsupported ICmp predicate: %s", PrintValue(&ii).c_str()); @@ -561,11 +587,17 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, error.SetErrorString(unsupported_opcode_error); return false; } + case CmpInst::FCMP_OEQ: case CmpInst::ICMP_EQ: + case CmpInst::FCMP_UNE: case CmpInst::ICMP_NE: + case CmpInst::FCMP_OGT: case CmpInst::ICMP_UGT: + case CmpInst::FCMP_OGE: case CmpInst::ICMP_UGE: + case CmpInst::FCMP_OLT: case CmpInst::ICMP_ULT: + case CmpInst::FCMP_OLE: case CmpInst::ICMP_ULE: case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: @@ -595,6 +627,11 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, case Instruction::Xor: case Instruction::ZExt: break; + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: + break; } for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) { @@ -709,7 +746,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, case Instruction::AShr: case Instruction::And: case Instruction::Or: - case Instruction::Xor: { + case Instruction::Xor: + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: { const BinaryOperator *bin_op = dyn_cast(inst); if (!bin_op) { @@ -748,12 +789,15 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, default: break; case Instruction::Add: + case Instruction::FAdd: result = L + R; break; case Instruction::Mul: + case Instruction::FMul: result = L * R; break; case Instruction::Sub: + case Instruction::FSub: result = L - R; break; case Instruction::SDiv: @@ -766,6 +810,9 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, R.MakeUnsigned(); result = L / R; break; + case Instruction::FDiv: + result = L / R; + break; case Instruction::SRem: L.MakeSigned(); R.MakeSigned(); @@ -1028,10 +1075,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, LLDB_LOGF(log, " Poffset : %s", frame.SummarizeValue(inst).c_str()); } } break; + case Instruction::FCmp: case Instruction::ICmp: { - const ICmpInst *icmp_inst = cast(inst); + const CmpInst *cmp_inst = cast(inst); - CmpInst::Predicate predicate = icmp_inst->getPredicate(); + CmpInst::Predicate predicate = cmp_inst->getPredicate(); Value *lhs = inst->getOperand(0); Value *rhs = inst->getOperand(1); @@ -1059,9 +1107,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, default: return false; case CmpInst::ICMP_EQ: + case CmpInst::FCMP_OEQ: result = (L == R); break; case CmpInst::ICMP_NE: + case CmpInst::FCMP_UNE: result = (L != R); break; case CmpInst::ICMP_UGT: @@ -1074,16 +1124,28 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, R.MakeUnsigned(); result = (L >= R); break; + case CmpInst::FCMP_OGE: + result = (L >= R); + break; + case CmpInst::FCMP_OGT: + result = (L > R); + break; case CmpInst::ICMP_ULT: L.MakeUnsigned(); R.MakeUnsigned(); result = (L < R); break; + case CmpInst::FCMP_OLT: + result = (L < R); + break; case CmpInst::ICMP_ULE: L.MakeUnsigned(); R.MakeUnsigned(); result = (L <= R); break; + case CmpInst::FCMP_OLE: + result = (L <= R); + break; case CmpInst::ICMP_SGT: L.MakeSigned(); R.MakeSigned(); diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index 64d9bb00ffab..ea368a6d4d71 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -96,7 +96,7 @@ else() endif() - elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") + elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") add_host_subdirectory(linux linux/AbstractSocket.cpp linux/Host.cpp @@ -110,6 +110,11 @@ else() android/LibcGlue.cpp ) endif() + if (CMAKE_SYSTEM_NAME MATCHES "OHOS") + add_host_subdirectory(ohos + ohos/HostInfoOHOS.cpp + ) + endif() elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") add_host_subdirectory(freebsd freebsd/Host.cpp diff --git a/lldb/source/Host/common/MainLoop.cpp b/lldb/source/Host/common/MainLoop.cpp index 8e384c9266b6..bfc1fb16ea0e 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 c2fb5509034e..db954a6d9efa 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 eabc9fef8a66..c1d7308025eb 100644 --- a/lldb/source/Host/common/TCPSocket.cpp +++ b/lldb/source/Host/common/TCPSocket.cpp @@ -160,6 +160,8 @@ Status TCPSocket::Connect(llvm::StringRef name) { std::vector addresses = SocketAddress::GetAddressInfo(host_port->hostname.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); + llvm::partition(addresses, + [](auto &sa) { return sa.GetFamily() == AF_INET; }); for (SocketAddress &address : addresses) { error = CreateSocket(address.GetFamily()); if (error.Fail()) diff --git a/lldb/source/Host/ohos/HostInfoOHOS.cpp b/lldb/source/Host/ohos/HostInfoOHOS.cpp new file mode 100644 index 000000000000..e47d26e3e938 --- /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 ddbd983abb81..bd2809817de8 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 63553590dff5..0c8e05aecdf3 100644 --- a/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/lldb/source/Host/posix/HostInfoPosix.cpp @@ -95,7 +95,7 @@ llvm::Optional PosixUserIDResolver::DoGetUserName(id_t uid) { } llvm::Optional PosixUserIDResolver::DoGetGroupName(id_t gid) { -#ifndef __ANDROID__ +#if !defined(__ANDROID__) && !defined(__OHOS_FAMILY__) char group_buffer[PATH_MAX]; size_t group_buffer_size = sizeof(group_buffer); struct group group_info; diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt index 6869587f917e..8ff59c124f75 100644 --- a/lldb/source/Plugins/Platform/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/CMakeLists.txt @@ -8,3 +8,4 @@ add_subdirectory(OpenBSD) add_subdirectory(POSIX) add_subdirectory(QemuUser) add_subdirectory(Windows) +add_subdirectory(OHOS) diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index 9fdfe4c0dc14..1fe7f35d0d75 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -85,7 +85,7 @@ void PlatformLinux::Initialize() { PlatformPOSIX::Initialize(); if (g_initialize_count++ == 0) { -#if defined(__linux__) && !defined(__ANDROID__) +#if defined(__linux__) && !defined(__ANDROID__) && !defined(__OHOS_FAMILY__) PlatformSP default_platform_sp(new PlatformLinux(true)); default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); Platform::SetHostPlatform(default_platform_sp); diff --git a/lldb/source/Plugins/Platform/OHOS/CMakeLists.txt b/lldb/source/Plugins/Platform/OHOS/CMakeLists.txt new file mode 100644 index 000000000000..cc71762efe2e --- /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 000000000000..97fa08fb44da --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp @@ -0,0 +1,379 @@ +//===-- HdcClient.cpp -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "HdcClient.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FileUtilities.h" + +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/PosixApi.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataEncoder.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timeout.h" + +#if defined(_WIN32) +#include +#else +#include +#endif + +#include + +#include +#include +#include +#include + +// On Windows, transitive dependencies pull in , which defines a +// macro that clashes with a method name. +#ifdef SendMessage +#undef SendMessage +#endif + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::platform_ohos; +using namespace std::chrono; + +namespace { + +const seconds kReadTimeout(20); +const char *kSocketNamespaceAbstract = "localabstract"; +const char *kSocketNamespaceFileSystem = "localfilesystem"; + +Status ReadAllBytes(Connection &conn, void *buffer, size_t size, + size_t *read_ptr, ConnectionStatus *status_ptr) { + + Status error; + ConnectionStatus status; + char *read_buffer = static_cast(buffer); + + auto now = steady_clock::now(); + const auto deadline = now + kReadTimeout; + size_t total_read_bytes = 0; + while (total_read_bytes < size && now < deadline) { + auto read_bytes = + conn.Read(read_buffer + total_read_bytes, size - total_read_bytes, + duration_cast(deadline - now), status, &error); + if (status_ptr) + *status_ptr = status; + if (error.Fail()) + return error; + total_read_bytes += read_bytes; + if (read_ptr) + *read_ptr = total_read_bytes; + if (status != eConnectionStatusSuccess) + break; + now = steady_clock::now(); + } + if (total_read_bytes < size) + error = Status( + "Unable to read requested number of bytes. Connection status: %d.", + status); + return error; +} + +} // namespace + +Status HdcClient::CreateByDeviceID(const std::string &device_id, + HdcClient &hdc) { + DeviceIDList connect_devices; + auto error = hdc.GetDevices(connect_devices); + if (error.Fail()) + return error; + + std::string hdc_utid; + if (!device_id.empty()) + hdc_utid = device_id; + else if (const char *env_hdc_utid = std::getenv("HDC_UTID")) + hdc_utid = env_hdc_utid; + + if (hdc_utid.empty()) { + if (connect_devices.size() != 1) + return Status("Expected a single connected device, got instead %zu - try " + "setting 'HDC_UTID'", + connect_devices.size()); + hdc.SetDeviceID(connect_devices.front()); + } else { + auto find_it = std::find(connect_devices.begin(), connect_devices.end(), + hdc_utid); + if (find_it == connect_devices.end()) + return Status( + "Device \"%s\" not found, check HDC_UTID environment variable", + hdc_utid.c_str()); + + hdc.SetDeviceID(*find_it); + } + return error; +} + +HdcClient::HdcClient() {} + +HdcClient::HdcClient(const std::string &device_id) : m_device_id(device_id) {} + +HdcClient::~HdcClient() {} + +void HdcClient::SetDeviceID(const std::string &device_id) { + m_device_id = device_id; +} + +const std::string &HdcClient::GetDeviceID() const { return m_device_id; } + +namespace { +typedef unsigned msg_len_t; +struct ChannelHandShake { + msg_len_t size; + char banner[12]; // must first index + union { + uint32_t channelId; + char connectKey[32]; + }; +} __attribute__((packed)); +} // namespace + +Status HdcClient::Connect() { + Status error; + ChannelHandShake handshake = {}; + if (m_device_id.size() > sizeof(handshake.connectKey)) + return Status("Device id is too long: %s", m_device_id.c_str()); + m_conn.reset(new ConnectionFileDescriptor); + std::string port = "8710"; + + const char *env_port = std::getenv("OHOS_HDC_SERVER_PORT"); + if ((env_port != NULL) && (atoi(env_port) > 0)) { + port = env_port; + } + + std::string uri = "connect://localhost:" + port; + m_conn->Connect(uri.c_str(), &error); + ConnectionStatus status = eConnectionStatusError; + if (error.Success()) { + error = ReadAllBytes(&handshake, sizeof(handshake)); + if (error.Success()) { + memset(handshake.connectKey, 0, sizeof(handshake.connectKey)); + memcpy(handshake.connectKey, m_device_id.c_str(), m_device_id.size()); + m_conn->Write(&handshake, sizeof(handshake), status, &error); + } + } + return error; +} + +Status HdcClient::GetDevices(DeviceIDList &device_list) { + device_list.clear(); + + auto error = SendMessage("list targets"); + if (error.Fail()) + return error; + + std::vector in_buffer; + error = ReadMessage(in_buffer); + + llvm::StringRef response(&in_buffer[0], in_buffer.size()); + llvm::SmallVector devices; + response.split(devices, "\n", -1, false); + + for (const auto device : devices) + device_list.push_back(static_cast(device.split('\t').first)); + + // Force disconnect since ADB closes connection after host:devices response + // is sent. + m_conn.reset(); + return error; +} + +Status HdcClient::SetPortForwarding(const uint16_t local_port, + const uint16_t remote_port) { + char message[48]; + snprintf(message, sizeof(message), "fport tcp:%d tcp:%d", local_port, + remote_port); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus("Forwardport result:OK"); +} + +Status +HdcClient::SetPortForwarding(const uint16_t local_port, + llvm::StringRef remote_socket_name, + const UnixSocketNamespace socket_namespace) { + char message[PATH_MAX]; + const char *sock_namespace_str = + (socket_namespace == UnixSocketNamespaceAbstract) + ? kSocketNamespaceAbstract + : kSocketNamespaceFileSystem; + snprintf(message, sizeof(message), "fport tcp:%d %s:%s", local_port, + sock_namespace_str, remote_socket_name.str().c_str()); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus("Forwardport result:OK"); +} + +Status HdcClient::DeletePortForwarding(std::pair fwd) { + char message[32]; + snprintf(message, sizeof(message), "fport rm tcp:%d tcp:%d", fwd.first, + fwd.second); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus(nullptr); +} + +Status HdcClient::TransferFile(const char *direction, const FileSpec &src, + const FileSpec &dst) { + llvm::SmallVector cwd; + std::error_code ec = llvm::sys::fs::current_path(cwd); + if (ec) + return Status(ec); + + std::stringstream cmd; + cmd << "file " << direction << " -cwd "; + cmd.write(cwd.data(), cwd.size()); + cmd << " " << src.GetPath() << " " << dst.GetPath(); + Status error = SendMessage(cmd.str()); + if (error.Fail()) + return error; + + return ReadResponseStatus("FileTransfer finish"); +} + +Status HdcClient::RecvFile(const FileSpec &src, const FileSpec &dst) { + return TransferFile("recv", src, dst); +} + +Status HdcClient::SendFile(const FileSpec &src, const FileSpec &dst) { + return TransferFile("send", src, dst); +} + +Status HdcClient::SendMessage(llvm::StringRef packet, const bool reconnect) { + Status error; + if (!m_conn || reconnect) { + error = Connect(); + if (error.Fail()) + return error; + } + + unsigned msg_len = packet.size() + 1; + llvm::SmallVector message(msg_len + sizeof(msg_len_t), 0); + msg_len_t len = htonl(msg_len); + memcpy(message.data(), &len, sizeof(len)); + memcpy(message.data() + sizeof(len), packet.data(), packet.size()); + + ConnectionStatus status; + m_conn->Write(message.data(), message.size(), status, &error); + if (error.Fail()) + return error; + + return error; +} + +Status HdcClient::ReadMessage(std::vector &message) { + message.clear(); + + msg_len_t packet_len; + auto error = ReadAllBytes(&packet_len, sizeof(packet_len)); + if (error.Fail()) + return error; + + packet_len = htonl(packet_len); + message.resize(packet_len, 0); + error = ReadAllBytes(&message[0], packet_len); + if (error.Fail()) + message.clear(); + + return error; +} + +Status HdcClient::ReadMessageStream(std::vector &message, + milliseconds timeout) { + auto start = steady_clock::now(); + message.clear(); + + Status error; + lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; + char buffer[1024]; + while (error.Success() && status == lldb::eConnectionStatusSuccess) { + auto end = steady_clock::now(); + auto elapsed = end - start; + if (elapsed >= timeout) + return Status("Timed out"); + + size_t n = m_conn->Read(buffer, sizeof(buffer), + duration_cast(timeout - elapsed), + status, &error); + if (n > 0) + message.insert(message.end(), &buffer[0], &buffer[n]); + } + return error; +} + +Status HdcClient::ReadResponseStatus(const char *expected) { + msg_len_t len; + ConnectionStatus conn_status; + size_t read; + + auto error = ::ReadAllBytes(*m_conn, &len, sizeof(len), &read, &conn_status); + // Special case: we expect server to close connection + if (expected == nullptr) { + if (read == 0 && conn_status == eConnectionStatusEndOfFile) + return Status(); + else if (error.Fail()) + return error; + // Something went wrong - response is not empty + // Read it and wrap to error object + } + + len = htonl(len); + llvm::SmallVector message(len + 1); + error = ReadAllBytes(message.data(), len); + if (error.Fail()) + return error; + + message[len] = 0; + if (expected == nullptr || + strncmp(message.data(), expected, strlen(expected))) + return Status("%s", message.data()); + + return error; +} + +Status HdcClient::ReadAllBytes(void *buffer, size_t size) { + return ::ReadAllBytes(*m_conn, buffer, size, nullptr, nullptr); +} + +Status HdcClient::Shell(const char *command, milliseconds timeout, + std::string *output) { + assert(command && command[0]); + std::string cmd = "shell "; + cmd += command; + Status error = SendMessage(cmd); + if (error.Fail()) + return error; + + std::vector message; + error = ReadMessageStream(message, timeout); + if (error.Fail()) + return error; + + (*output) = std::string(message.data(), message.size()); + return error; +} diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.h b/lldb/source/Plugins/Platform/OHOS/HdcClient.h new file mode 100644 index 000000000000..64a5a324325a --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.h @@ -0,0 +1,90 @@ +//===-- HdcClient.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_HdcClient_h_ +#define liblldb_HdcClient_h_ + +#include "lldb/Utility/Status.h" +#include +#include +#include +#include +#include +#include + +namespace lldb_private { + +class FileSpec; + +namespace platform_ohos { + +class HdcClient { +public: + enum UnixSocketNamespace { + UnixSocketNamespaceAbstract, + UnixSocketNamespaceFileSystem, + }; + + using DeviceIDList = std::list; + + static Status CreateByDeviceID(const std::string &device_id, HdcClient &hdc); + + HdcClient(); + explicit HdcClient(const std::string &device_id); + + ~HdcClient(); + + const std::string &GetDeviceID() const; + + Status GetDevices(DeviceIDList &device_list); + + Status SetPortForwarding(const uint16_t local_port, + const uint16_t remote_port); + + Status SetPortForwarding(const uint16_t local_port, + llvm::StringRef remote_socket_name, + const UnixSocketNamespace socket_namespace); + + Status DeletePortForwarding(std::pair fwd); + + Status RecvFile(const FileSpec &src, const FileSpec &dst); + + Status SendFile(const FileSpec &src, const FileSpec &dst); + + Status Shell(const char *command, std::chrono::milliseconds timeout, + std::string *output); + +private: + Status Connect(); + + Status TransferFile(const char *direction, const FileSpec &src, + const FileSpec &dst); + + void SetDeviceID(const std::string &device_id); + + Status SendMessage(llvm::StringRef packet, const bool reconnect = true); + + Status SendDeviceMessage(const std::string &packet); + + Status ReadMessage(std::vector &message); + + Status ReadMessageStream(std::vector &message, + std::chrono::milliseconds timeout); + + Status ReadResponseStatus(const char *expected); + + Status ReadAllBytes(void *buffer, size_t size); + + std::string m_device_id; + std::unique_ptr m_conn; +}; + +} // namespace platform_ohos +} // namespace lldb_private + +#endif // liblldb_HdcClient_h_ diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp new file mode 100644 index 000000000000..86dda7741ac6 --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -0,0 +1,256 @@ +//===-- PlatformOHOS.cpp -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/UriParser.h" + +#include "HdcClient.h" +#include "PlatformOHOS.h" +#include "PlatformOHOSRemoteGDBServer.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::platform_ohos; +using namespace std::chrono; + +static uint32_t g_initialize_count = 0; +static const unsigned int g_ohos_default_cache_size = + 2048; // Fits inside 4k adb packet. + +LLDB_PLUGIN_DEFINE(PlatformOHOS) + +void PlatformOHOS::Initialize() { + PlatformLinux::Initialize(); + + if (g_initialize_count++ == 0) { +#if defined(__OHOS_FAMILY__) + PlatformSP default_platform_sp(new PlatformOHOS(true)); + default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); + Platform::SetHostPlatform(default_platform_sp); +#endif + PluginManager::RegisterPlugin( + PlatformOHOS::GetPluginNameStatic(false), + PlatformOHOS::GetPluginDescriptionStatic(false), + PlatformOHOS::CreateInstance); + } +} + +void PlatformOHOS::Terminate() { + if (g_initialize_count > 0) { + if (--g_initialize_count == 0) { + PluginManager::UnregisterPlugin(PlatformOHOS::CreateInstance); + } + } + + PlatformLinux::Terminate(); +} + +PlatformSP PlatformOHOS::CreateInstance(bool force, const ArchSpec *arch) { + Log *log = GetLog(LLDBLog::Platform); + if (log) { + const char *arch_name; + if (arch && arch->GetArchitectureName()) + arch_name = arch->GetArchitectureName(); + else + arch_name = ""; + + const char *triple_cstr = + arch ? arch->GetTriple().getTriple().c_str() : ""; + + log->Printf("PlatformOHOS::%s(force=%s, arch={%s,%s})", __FUNCTION__, + force ? "true" : "false", arch_name, triple_cstr); + } + + bool create = force; + if (!create && arch && arch->IsValid()) { + const llvm::Triple &triple = arch->GetTriple(); + switch (triple.getVendor()) { + case llvm::Triple::PC: + create = true; + break; + default: + break; + } + + if (create) { + switch (triple.getEnvironment()) { + case llvm::Triple::OpenHOS: + break; + default: + create = false; + break; + } + } + } + + if (create) { + if (log) + log->Printf("PlatformOHOS::%s() creating remote-ohos platform", + __FUNCTION__); + + return PlatformSP(new PlatformOHOS(false)); + } + + if (log) + log->Printf( + "PlatformOHOS::%s() aborting creation of remote-ohos platform", + __FUNCTION__); + + return PlatformSP(); +} + +PlatformOHOS::PlatformOHOS(bool is_host) : PlatformLinux(is_host) {} + +PlatformOHOS::~PlatformOHOS() {} + +llvm::StringRef PlatformOHOS::GetPluginNameStatic(bool is_host) { + return is_host ? Platform::GetHostPlatformName() : "remote-ohos"; +} + +const char *PlatformOHOS::GetPluginDescriptionStatic(bool is_host) { + return is_host ? "Local OpenHarmony OS user platform plug-in." : + "Remote OpenHarmony OS user platform plug-in."; +} + +llvm::StringRef PlatformOHOS::GetPluginName() { + return GetPluginNameStatic(IsHost()); +} + +Status PlatformOHOS::ConnectRemote(Args &args) { + m_device_id.clear(); + + if (IsHost()) { + return Status("can't connect to the host platform '%s', always connected", + GetPluginName().str().c_str()); + } + + if (!m_remote_platform_sp) + m_remote_platform_sp = PlatformSP(new PlatformOHOSRemoteGDBServer()); + + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Status("URL is null."); + llvm::Optional uri = URI::Parse(url); + if (!uri) + return Status("Invalid URL: %s", url); + if (uri->hostname != "localhost") + m_device_id = static_cast(uri->hostname); + + auto error = PlatformLinux::ConnectRemote(args); + if (error.Success()) { + HdcClient adb; + error = HdcClient::CreateByDeviceID(m_device_id, adb); + if (error.Fail()) + return error; + + m_device_id = adb.GetDeviceID(); + } + return error; +} + +Status PlatformOHOS::GetFile(const FileSpec &source, + const FileSpec &destination) { + if (IsHost() || !m_remote_platform_sp) + return PlatformLinux::GetFile(source, destination); + + FileSpec source_spec(source.GetPath(false), FileSpec::Style::posix); + if (source_spec.IsRelative()) + source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent( + source_spec.GetCString(false)); + + HdcClient hdc(m_device_id); + Status error = hdc.RecvFile(source, destination); + return error; +} + +Status PlatformOHOS::PutFile(const FileSpec &source, + const FileSpec &destination, uint32_t uid, + uint32_t gid) { + if (IsHost() || !m_remote_platform_sp) + return PlatformLinux::PutFile(source, destination, uid, gid); + + FileSpec destination_spec(destination.GetPath(false), FileSpec::Style::posix); + if (destination_spec.IsRelative()) + destination_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent( + destination_spec.GetCString(false)); + + // TODO: Set correct uid and gid on remote file. + HdcClient hdc(m_device_id); + Status error = hdc.SendFile(source, destination_spec); + return error; +} + +const char *PlatformOHOS::GetCacheHostname() { return m_device_id.c_str(); } + +Status PlatformOHOS::DownloadModuleSlice(const FileSpec &src_file_spec, + const uint64_t src_offset, + const uint64_t src_size, + const FileSpec &dst_file_spec) { + if (src_offset != 0) + return Status("Invalid offset - %" PRIu64, src_offset); + + return GetFile(src_file_spec, dst_file_spec); +} + +Status PlatformOHOS::DisconnectRemote() { + Status error = PlatformLinux::DisconnectRemote(); + if (error.Success()) + m_device_id.clear(); + return error; +} + +uint32_t PlatformOHOS::GetDefaultMemoryCacheLineSize() { + return g_ohos_default_cache_size; +} + +uint32_t PlatformOHOS::GetSdkVersion() { + if (!IsConnected()) + return 0; + + // TBD + return 1; +} + +bool PlatformOHOS::GetRemoteOSVersion() { + m_os_version = llvm::VersionTuple(GetSdkVersion()); + return !m_os_version.empty(); +} + +llvm::StringRef +PlatformOHOS::GetLibdlFunctionDeclarations(lldb_private::Process *process) { + SymbolContextList matching_symbols; + std::vector dl_open_names = { "__dl_dlopen", "dlopen" }; + const char *dl_open_name = nullptr; + Target &target = process->GetTarget(); + for (auto name: dl_open_names) { + target.GetImages().FindFunctionSymbols(ConstString(name), + eFunctionNameTypeFull, + matching_symbols); + if (matching_symbols.GetSize()) { + dl_open_name = name; + break; + } + } + // Older platform versions have the dl function symbols mangled + if (dl_open_name == dl_open_names[0]) + return R"( + extern "C" void* dlopen(const char*, int) asm("__dl_dlopen"); + extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym"); + extern "C" int dlclose(void*) asm("__dl_dlclose"); + extern "C" char* dlerror(void) asm("__dl_dlerror"); + )"; + + return PlatformPOSIX::GetLibdlFunctionDeclarations(process); +} diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h new file mode 100644 index 000000000000..78e4e187801f --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h @@ -0,0 +1,77 @@ +//===-- PlatformOHOS.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformOHOS_h_ +#define liblldb_PlatformOHOS_h_ + +#include +#include + +#include "Plugins/Platform/Linux/PlatformLinux.h" + +#include "HdcClient.h" + +namespace lldb_private { +namespace platform_ohos { + +class PlatformOHOS : public platform_linux::PlatformLinux { +public: + PlatformOHOS(bool is_host); + + ~PlatformOHOS() override; + + static void Initialize(); + + static void Terminate(); + + // lldb_private::PluginInterface functions + static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); + + static llvm::StringRef GetPluginNameStatic(bool is_host); + + static const char *GetPluginDescriptionStatic(bool is_host); + + llvm::StringRef GetPluginName() override; + + // lldb_private::Platform functions + Status ConnectRemote(Args &args) override; + + Status GetFile(const FileSpec &source, const FileSpec &destination) override; + + Status PutFile(const FileSpec &source, const FileSpec &destination, + uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override; + + uint32_t GetSdkVersion(); + + bool GetRemoteOSVersion() override; + + Status DisconnectRemote() override; + + uint32_t GetDefaultMemoryCacheLineSize() override; + +protected: + const char *GetCacheHostname() override; + + Status DownloadModuleSlice(const FileSpec &src_file_spec, + const uint64_t src_offset, const uint64_t src_size, + const FileSpec &dst_file_spec) override; + + llvm::StringRef + GetLibdlFunctionDeclarations(lldb_private::Process *process) override; + +private: + std::string m_device_id; + + PlatformOHOS(const PlatformOHOS &other) = delete; + PlatformOHOS& operator=(const PlatformOHOS &other) = delete; +}; + +} // namespace platofor_ohos +} // namespace lldb_private + +#endif // liblldb_PlatformOHOS_h_ diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp new file mode 100644 index 000000000000..ab9c8b8bf306 --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp @@ -0,0 +1,246 @@ +//===-- PlatformOHOSRemoteGDBServer.cpp ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/common/TCPSocket.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/UriParser.h" + +#include "PlatformOHOSRemoteGDBServer.h" + +#include + +using namespace lldb; +using namespace lldb_private; +using namespace platform_ohos; + +static const lldb::pid_t g_remote_platform_pid = + 0; // Alias for the process id of lldb-platform + +static uint16_t g_hdc_forward_port_offset = 0; + +static Status ForwardPortWithHdc( + const uint16_t local_port, const uint16_t remote_port, + llvm::StringRef remote_socket_name, + const llvm::Optional &socket_namespace, + std::string &device_id) { + Log *log = GetLog(LLDBLog::Platform); + + HdcClient hdc; + auto error = HdcClient::CreateByDeviceID(device_id, hdc); + if (error.Fail()) + return error; + + device_id = hdc.GetDeviceID(); + if (log) + log->Printf("Connected to OHOS device \"%s\"", device_id.c_str()); + + if (remote_port != 0) { + if (log) + log->Printf("Forwarding remote TCP port %d to local TCP port %d", + remote_port, local_port); + return hdc.SetPortForwarding(local_port, remote_port); + } + + if (log) + log->Printf("Forwarding remote socket \"%s\" to local TCP port %d", + remote_socket_name.str().c_str(), local_port); + + if (!socket_namespace) + return Status("Invalid socket namespace"); + + return hdc.SetPortForwarding(local_port, remote_socket_name, + *socket_namespace); +} + +static Status DeleteForwardPortWithHdc(std::pair ports, + const std::string &device_id) { + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Delete port forwarding %d -> %d, device=%s", ports.first, + ports.second, device_id.c_str()); + + HdcClient hdc(device_id); + return hdc.DeletePortForwarding(ports); +} + +static Status FindUnusedPort(uint16_t &port) { + Status error; + + if (const char *env_port = std::getenv("HDC_FORWARD_PORT_BASE_FOR_LLDB")) { + port = std::atoi(env_port) + g_hdc_forward_port_offset; + g_hdc_forward_port_offset++; + return error; + } + + std::unique_ptr tcp_socket(new TCPSocket(true, false)); + if (error.Fail()) + return error; + + error = tcp_socket->Listen("127.0.0.1:0", 1); + if (error.Success()) + port = tcp_socket->GetLocalPortNumber(); + + return error; +} + +PlatformOHOSRemoteGDBServer::PlatformOHOSRemoteGDBServer() {} + +PlatformOHOSRemoteGDBServer::~PlatformOHOSRemoteGDBServer() { + for (const auto &it : m_port_forwards) + DeleteForwardPortWithHdc(it.second, m_device_id); +} + +bool PlatformOHOSRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid, + std::string &connect_url) { + uint16_t remote_port = 0; + std::string socket_name; + if (!m_gdb_client_up->LaunchGDBServer("127.0.0.1", pid, remote_port, socket_name)) + return false; + + Log *log = GetLog(LLDBLog::Platform); + + auto error = + MakeConnectURL(pid, remote_port, socket_name.c_str(), connect_url); + if (error.Success() && log) + log->Printf("gdbserver connect URL: %s", connect_url.c_str()); + + return error.Success(); +} + +bool PlatformOHOSRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) { + DeleteForwardPort(pid); + return m_gdb_client_up->KillSpawnedProcess(pid); +} + +Status PlatformOHOSRemoteGDBServer::ConnectRemote(Args &args) { + m_device_id.clear(); + + if (args.GetArgumentCount() != 1) + return Status( + "\"platform connect\" takes a single argument: "); + + llvm::Optional uri; + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Status("URL is null."); + uri = URI::Parse(url); + if (!uri) + return Status("Invalid URL: %s", url); + if (uri->hostname != "localhost") + m_device_id = static_cast(uri->hostname); + + m_socket_namespace.reset(); + if (uri->scheme == "unix-connect") + m_socket_namespace = HdcClient::UnixSocketNamespaceFileSystem; + else if (uri->scheme == "unix-abstract-connect") + m_socket_namespace = HdcClient::UnixSocketNamespaceAbstract; + + std::string connect_url; + auto error = + MakeConnectURL(g_remote_platform_pid, uri->port ? (*uri->port) : 0, + uri->path, connect_url); + + if (error.Fail()) + return error; + + args.ReplaceArgumentAtIndex(0, connect_url); + + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Rewritten platform connect URL: %s", connect_url.c_str()); + + error = PlatformRemoteGDBServer::ConnectRemote(args); + if (error.Fail()) + DeleteForwardPort(g_remote_platform_pid); + + return error; +} + +Status PlatformOHOSRemoteGDBServer::DisconnectRemote() { + DeleteForwardPort(g_remote_platform_pid); + g_hdc_forward_port_offset = 0; + return PlatformRemoteGDBServer::DisconnectRemote(); +} + +void PlatformOHOSRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) { + Log *log = GetLog(LLDBLog::Platform); + + auto it = m_port_forwards.find(pid); + if (it == m_port_forwards.end()) + return; + + const auto port = it->second; + const auto error = DeleteForwardPortWithHdc(port, m_device_id); + if (error.Fail()) { + if (log) + log->Printf("Failed to delete port forwarding (pid=%" PRIu64 + ", fwd=(%d -> %d), device=%s): %s", + pid, port.first, port.second, m_device_id.c_str(), + error.AsCString()); + } + m_port_forwards.erase(it); +} + +Status PlatformOHOSRemoteGDBServer::MakeConnectURL( + const lldb::pid_t pid, const uint16_t remote_port, + llvm::StringRef remote_socket_name, std::string &connect_url) { + static const int kAttempsNum = 5; + + Status error; + // There is a race possibility that somebody will occupy a port while we're + // in between FindUnusedPort and ForwardPortWithHdc - adding the loop to + // mitigate such problem. + for (auto i = 0; i < kAttempsNum; ++i) { + uint16_t local_port = 0; + error = FindUnusedPort(local_port); + if (error.Fail()) + return error; + + error = ForwardPortWithHdc(local_port, remote_port, remote_socket_name, + m_socket_namespace, m_device_id); + if (error.Success()) { + m_port_forwards[pid] = {local_port, remote_port}; + std::ostringstream url_str; + url_str << "connect://localhost:" << local_port; + connect_url = url_str.str(); + break; + } + } + + return error; +} + +lldb::ProcessSP PlatformOHOSRemoteGDBServer::ConnectProcess( + llvm::StringRef connect_url, llvm::StringRef plugin_name, + lldb_private::Debugger &debugger, lldb_private::Target *target, + lldb_private::Status &error) { + // We don't have the pid of the remote gdbserver when it isn't started by us + // but we still want to store the list of port forwards we set up in our port + // forward map. Generate a fake pid for these cases what won't collide with + // any other valid pid on ohos. + static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL; + + llvm::Optional uri = URI::Parse(connect_url); + if (!uri) { + error.SetErrorStringWithFormat("Invalid URL: %s", + connect_url.str().c_str()); + return nullptr; + } + + std::string new_connect_url; + error = MakeConnectURL(s_remote_gdbserver_fake_pid--, + (*uri->port) ? (*uri->port) : 0, uri->path, + new_connect_url); + if (error.Fail()) + return nullptr; + + return PlatformRemoteGDBServer::ConnectProcess(new_connect_url, plugin_name, + debugger, target, error); +} diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h new file mode 100644 index 000000000000..f9818589275d --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h @@ -0,0 +1,64 @@ +//===-- PlatformOHOSRemoteGDBServer.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformOHOSRemoteGDBServer_h_ +#define liblldb_PlatformOHOSRemoteGDBServer_h_ + +#include +#include + +#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" + +#include "llvm/ADT/Optional.h" + +#include "HdcClient.h" + +namespace lldb_private { +namespace platform_ohos { + +class PlatformOHOSRemoteGDBServer + : public platform_gdb_server::PlatformRemoteGDBServer { +public: + PlatformOHOSRemoteGDBServer(); + + ~PlatformOHOSRemoteGDBServer() override; + + Status ConnectRemote(Args &args) override; + + Status DisconnectRemote() override; + + lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, + llvm::StringRef plugin_name, + lldb_private::Debugger &debugger, + lldb_private::Target *target, + lldb_private::Status &error) override; + +protected: + std::string m_device_id; + std::map> m_port_forwards; + llvm::Optional m_socket_namespace; + + bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) override; + + bool KillSpawnedProcess(lldb::pid_t pid) override; + + void DeleteForwardPort(lldb::pid_t pid); + + Status MakeConnectURL(const lldb::pid_t pid, const uint16_t remote_port, + llvm::StringRef remote_socket_name, + std::string &connect_url); + +private: + PlatformOHOSRemoteGDBServer(const PlatformOHOSRemoteGDBServer &other) = delete; + PlatformOHOSRemoteGDBServer& operator=(const PlatformOHOSRemoteGDBServer &other) = delete; +}; + +} // namespace platform_ohos +} // namespace lldb_private + +#endif // liblldb_PlatformOHOSRemoteGDBServer_h_ diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt index a51d0f7afd17..d30d90ca4dfd 100644 --- a/lldb/source/Plugins/Process/CMakeLists.txt +++ b/lldb/source/Plugins/Process/CMakeLists.txt @@ -1,4 +1,4 @@ -if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") +if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") add_subdirectory(Linux) add_subdirectory(POSIX) elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h index 14f669a3ce98..9fee81e1b659 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h @@ -16,6 +16,11 @@ #include "Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" +#if __OHOS__ +// Do not include to avoid conflicting definitions for +// aarch64-linux-ohos target +#define __ASM_SIGCONTEXT_H 1 +#endif #include namespace lldb_private { diff --git a/lldb/source/Plugins/Process/Linux/Procfs.h b/lldb/source/Plugins/Process/Linux/Procfs.h index 3a068432074b..79bc35d8105d 100644 --- a/lldb/source/Plugins/Process/Linux/Procfs.h +++ b/lldb/source/Plugins/Process/Linux/Procfs.h @@ -17,7 +17,7 @@ #include -#ifdef __ANDROID__ +#if defined(__ANDROID__) #if defined(__arm64__) || defined(__aarch64__) typedef unsigned long elf_greg_t; typedef elf_greg_t diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 2a58f2028386..39fb9a8a8fde 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -45,12 +45,15 @@ #include "lldb/Host/android/HostInfoAndroid.h" #endif +#if defined(__OHOS_FAMILY__) +#include "lldb/Host/ohos/HostInfoOHOS.h" +#endif using namespace lldb; using namespace lldb_private::process_gdb_remote; using namespace lldb_private; -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(__OHOS_FAMILY__) const static uint32_t g_default_packet_timeout_sec = 20; // seconds #else const static uint32_t g_default_packet_timeout_sec = 0; // not specified @@ -181,7 +184,6 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( StreamString response; // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 - ArchSpec host_arch(HostInfo::GetArchitecture()); const llvm::Triple &host_triple = host_arch.GetTriple(); response.PutCString("triple:"); @@ -1309,6 +1311,8 @@ FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( const std::string &module_path, const ArchSpec &arch) { #ifdef __ANDROID__ return HostInfoAndroid::ResolveLibraryPath(module_path, arch); +#elif defined(__OHOS_FAMILY__) + return HostInfoOHOS::ResolveLibraryPath(module_path, arch); #else FileSpec file_spec(module_path); FileSystem::Instance().Resolve(file_spec); @@ -1320,7 +1324,6 @@ ModuleSpec GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple) { ArchSpec arch(triple); - FileSpec req_module_path_spec(module_path); FileSystem::Instance().Resolve(req_module_path_spec); @@ -1336,7 +1339,6 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, ModuleSpec matched_module_spec; if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) return ModuleSpec(); - return matched_module_spec; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp index 37e28a09f3c4..c357033aa91d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp @@ -92,8 +92,8 @@ const DWARFDataExtractor &DWARFContext::getOrLoadLocListsData() { } const DWARFDataExtractor &DWARFContext::getOrLoadMacroData() { - return LoadOrGetSection(eSectionTypeDWARFDebugMacro, llvm::None, - m_data_debug_macro); + return LoadOrGetSection(eSectionTypeDWARFDebugMacro, + eSectionTypeDWARFDebugMacro, m_data_debug_macro); } const DWARFDataExtractor &DWARFContext::getOrLoadRangesData() { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 19c6448c4e74..e84a76451727 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -16,6 +16,13 @@ using namespace lldb_private; using namespace lldb_private::dwarf; +uint64_t DWARFStrOffsetsInfo::GetOffset(uint64_t index) const { + assert(IsValid()); + // LLDB doesn't support DWARF64, so we always have item size of 4. + uint64_t offset = cu_offset + 4 * index; + return data->GetU32(&offset); +} + DWARFDebugMacroHeader DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) { @@ -59,7 +66,8 @@ void DWARFDebugMacroHeader::SkipOperandTable( void DWARFDebugMacroEntry::ReadMacroEntries( const DWARFDataExtractor &debug_macro_data, - const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit, + const DWARFDataExtractor &debug_str_data, + const DWARFStrOffsetsInfo &str_offsets_info, const bool offset_is_64_bit, lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf, DebugMacrosSP &debug_macros_sp) { llvm::dwarf::MacroEntryType type = @@ -97,6 +105,22 @@ void DWARFDebugMacroEntry::ReadMacroEntries( debug_macros_sp->AddMacroEntry( DebugMacroEntry::CreateUndefEntry(line, macro_str)); break; + case DW_MACRO_define_strx: + case DW_MACRO_undef_strx: + line = debug_macro_data.GetULEB128(offset); + str_offset = debug_macro_data.GetULEB128(offset); + if (!str_offsets_info.IsValid()) + // Can't do much in this case, skip all such entries + continue; + str_offset = str_offsets_info.GetOffset(str_offset); + macro_str = debug_str_data.GetCStr(&str_offset); + if (type == DW_MACRO_define_strx) + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateDefineEntry(line, macro_str)); + else + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateUndefEntry(line, macro_str)); + break; case DW_MACRO_start_file: line = debug_macro_data.GetULEB128(offset); debug_line_file_idx = debug_macro_data.GetULEB128(offset); @@ -113,7 +137,7 @@ void DWARFDebugMacroEntry::ReadMacroEntries( else new_offset = debug_macro_data.GetU32(offset); debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry( - sym_file_dwarf->ParseDebugMacros(&new_offset))); + sym_file_dwarf->ParseDebugMacros(&new_offset, str_offsets_info))); break; default: // TODO: Add support for other standard operations. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h index cbf762458331..b598d680d5fb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h @@ -24,6 +24,14 @@ class DWARFDataExtractor; class SymbolFileDWARF; +struct DWARFStrOffsetsInfo { + lldb::offset_t cu_offset; + const lldb_private::DWARFDataExtractor *data; + + bool IsValid() const { return cu_offset && cu_offset != DW_INVALID_OFFSET; } + uint64_t GetOffset(uint64_t index) const; +}; + class DWARFDebugMacroHeader { public: enum HeaderFlagMask { @@ -53,6 +61,7 @@ public: static void ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data, const lldb_private::DWARFDataExtractor &debug_str_data, + const DWARFStrOffsetsInfo &str_offsets_info, const bool offset_is_64_bit, lldb::offset_t *sect_offset, SymbolFileDWARF *sym_file_dwarf, lldb_private::DebugMacrosSP &debug_macros_sp); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 8ee709db9cdb..1049012cef0d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1174,7 +1174,8 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { } lldb_private::DebugMacrosSP -SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { +SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset, + const DWARFStrOffsetsInfo &str_offsets_info) { auto iter = m_debug_macros_map.find(*offset); if (iter != m_debug_macros_map.end()) return iter->second; @@ -1190,8 +1191,8 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset); DWARFDebugMacroEntry::ReadMacroEntries( - debug_macro_data, m_context.getOrLoadStrData(), header.OffsetIs64Bit(), - offset, this, debug_macros_sp); + debug_macro_data, m_context.getOrLoadStrData(), str_offsets_info, + header.OffsetIs64Bit(), offset, this, debug_macros_sp); return debug_macros_sp; } @@ -1199,7 +1200,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) { std::lock_guard guard(GetModuleMutex()); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + DWARFUnit *dwarf_cu = &GetDWARFCompileUnit(&comp_unit)->GetNonSkeletonUnit(); if (dwarf_cu == nullptr) return false; @@ -1215,8 +1216,16 @@ bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) { if (sect_offset == DW_INVALID_OFFSET) return false; - comp_unit.SetDebugMacros(ParseDebugMacros(§_offset)); + DWARFStrOffsetsInfo str_offsets_info = {}; + str_offsets_info.cu_offset = dwarf_cu->GetStrOffsetsBase(); + SymbolFileDWARF &symfile = dwarf_cu->GetSymbolFileDWARF(); + + if (str_offsets_info.IsValid()) + str_offsets_info.data = + &symfile.GetDWARFContext().getOrLoadStrOffsetsData(); + comp_unit.SetDebugMacros( + symfile.ParseDebugMacros(§_offset, str_offsets_info)); return true; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index cfd18f02053b..ccf955ee4b90 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -55,6 +55,8 @@ class SymbolFileDWARFDebugMap; class SymbolFileDWARFDwo; class SymbolFileDWARFDwp; +struct DWARFStrOffsetsInfo; + #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) class SymbolFileDWARF : public lldb_private::SymbolFileCommon, @@ -244,7 +246,9 @@ public: bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu); - lldb_private::DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset); + lldb_private::DebugMacrosSP + ParseDebugMacros(lldb::offset_t *offset, + const DWARFStrOffsetsInfo &str_offsets_info); static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die); diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp index 4ebb175fcd85..45c166e7e5cf 100644 --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -131,7 +131,7 @@ void PathMappingList::Dump(Stream *s, int pair_index) { } } -void PathMappingList::Clear(bool notify) { +void PathMappingList::Clear (bool notify) { if (!m_pairs.empty()) ++m_mod_id; m_pairs.clear(); @@ -197,7 +197,7 @@ PathMappingList::RemapPath(llvm::StringRef mapping_path, return {}; } -bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const { +bool PathMappingList::ReverseRemapPath (const FileSpec &file, FileSpec &fixed) const { std::string path = file.GetPath(); llvm::StringRef path_ref(path); for (const auto &it : m_pairs) { diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index 0d5144d7a46b..d08805460ee1 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -206,6 +206,13 @@ bool ThreadPlanStepRange::InSymbol() { return false; } +// TODO: Limit this function scope to OHOS targets +bool ThreadPlanStepRange::MaybeAArch32Or64FunctionTail() { + const llvm::Triple &triple = GetTarget().GetArchitecture().GetTriple(); + const bool isArm32or64 = triple.isAArch64() || triple.isARM(); + return isArm32or64 && InSymbol() && InRange(); +} + // FIXME: This should also handle inlining if we aren't going to do inlining in // the // main stack. diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp index a99aed82bc88..79c5cd3f18fc 100644 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -936,7 +936,7 @@ bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const { return IsEqualTo(rhs, false); } -static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, +static bool IsCompatibleEnvironment (llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs) { if (lhs == rhs) return true; @@ -958,6 +958,8 @@ static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, // that they are using the Android ABI. if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) || (rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) || + (lhs == llvm::Triple::OpenHOS && rhs == llvm::Triple::EABI) || + (rhs == llvm::Triple::OpenHOS && lhs == llvm::Triple::EABI) || (lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) || (rhs == llvm::Triple::GNUEABI && lhs == llvm::Triple::EABI) || (lhs == llvm::Triple::GNUEABIHF && rhs == llvm::Triple::EABIHF) || diff --git a/lldb/source/Utility/TildeExpressionResolver.cpp b/lldb/source/Utility/TildeExpressionResolver.cpp index 6311ae062f1f..d4c464ddfe01 100644 --- a/lldb/source/Utility/TildeExpressionResolver.cpp +++ b/lldb/source/Utility/TildeExpressionResolver.cpp @@ -47,7 +47,7 @@ bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr, assert(Expr.empty() || Expr[0] == '~'); Output.clear(); -#if defined(_WIN32) || defined(__ANDROID__) +#if defined(_WIN32) || defined(__ANDROID__) || defined(__OHOS_FAMILY__) return false; #else if (Expr.empty()) diff --git a/lldb/test/API/api/command-return-object/Makefile b/lldb/test/API/api/command-return-object/Makefile index 99998b20bcb0..680e1abfbef5 100644 --- a/lldb/test/API/api/command-return-object/Makefile +++ b/lldb/test/API/api/command-return-object/Makefile @@ -1,3 +1,4 @@ CXX_SOURCES := main.cpp +USE_LIBCPP := 1 include Makefile.rules diff --git a/lldb/test/API/functionalities/plugins/command_plugin/Makefile b/lldb/test/API/functionalities/plugins/command_plugin/Makefile index 3119c3707841..b792c8d50d98 100644 --- a/lldb/test/API/functionalities/plugins/command_plugin/Makefile +++ b/lldb/test/API/functionalities/plugins/command_plugin/Makefile @@ -2,5 +2,6 @@ DYLIB_CXX_SOURCES := plugin.cpp DYLIB_NAME := plugin DYLIB_ONLY := YES MAKE_DSYM := NO +USE_LIBCPP := 1 include Makefile.rules diff --git a/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py b/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py index 2ab6820c0920..53805f5d535f 100644 --- a/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py +++ b/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py @@ -72,6 +72,7 @@ class TestGdbRemoteMemoryAllocation(gdbremote_testcase.GdbRemoteTestCaseBase): True) self.expect_gdbremote_sequence() + @skipOnOpenHarmonyCI # investigate CI test failures def test_bad_packet(self): """Make sure we get a proper error for malformed packets.""" diff --git a/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py b/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py index 7acb0188dcff..ca84825af0e6 100644 --- a/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py +++ b/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py @@ -59,6 +59,7 @@ class TestGdbRemote_QPassSignals(gdbremote_testcase.GdbRemoteTestCaseBase): self.expect_exit_code(len(signals_to_ignore)) @skipUnlessPlatform(["linux", "android"]) + @skipOnOpenHarmonyCI #investigate CI timeouts def test_change_signals_at_runtime(self): self.build() self.set_inferior_startup_launch() diff --git a/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py b/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py index af563af158ce..52d81871c46d 100644 --- a/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py +++ b/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py @@ -25,6 +25,7 @@ class TestGdbRemoteThreadName(gdbremote_testcase.GdbRemoteTestCaseBase): self.assertEqual(expected_name, kv_dict.get("name")) @skipIfWindows # the test is not updated for Windows. + @skipOnOpenHarmonyCI # investigate CI timeouts def test(self): """ Make sure lldb-server can retrieve inferior thread name""" self.build() diff --git a/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py b/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py index cda935ff70c3..9c956ab5c11c 100644 --- a/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py +++ b/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py @@ -42,6 +42,7 @@ class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase): self.continue_to_exit() @skipIfWindows + @skipIfLinux @skipIfNetBSD # Hangs on NetBSD as well @skipIfRemote def test_by_pid(self): diff --git a/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py b/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py index 4731d13821a5..61d1dba1f46c 100644 --- a/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py +++ b/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py @@ -46,6 +46,7 @@ class TestVSCode_runInTerminal(lldbvscode_testcase.VSCodeTestCaseBase): return False @skipIfWindows + @skipIfLinux @skipIfRemote @skipIf(archs=no_match(['x86_64'])) def test_runInTerminal(self): diff --git a/lldb/tools/lldb-server/CMakeLists.txt b/lldb/tools/lldb-server/CMakeLists.txt index 3fb22b0a6109..b7026ef12165 100644 --- a/lldb/tools/lldb-server/CMakeLists.txt +++ b/lldb/tools/lldb-server/CMakeLists.txt @@ -5,7 +5,7 @@ set_target_properties(LLGSOptionsTableGen PROPERTIES FOLDER "lldb misc") set(LLDB_PLUGINS) -if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android") +if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") list(APPEND LLDB_PLUGINS lldbPluginProcessLinux) endif() diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index ba4584dc60fa..95bf1757cbb0 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -190,7 +190,7 @@ public: IOS, KFreeBSD, Linux, - Lv2, // PS3 + Lv2, // PS3 MacOSX, NetBSD, OpenBSD, @@ -219,6 +219,7 @@ public: WASI, // Experimental WebAssembly OS Emscripten, ShaderModel, // DirectX ShaderModel + LiteOS, LastOSType = ShaderModel }; enum EnvironmentType { @@ -263,8 +264,8 @@ public: Callable, Mesh, Amplification, - - LastEnvironmentType = Amplification + OpenHOS, + LastEnvironmentType = OpenHOS }; enum ObjectFormatType { UnknownObjectFormat, @@ -717,9 +718,19 @@ public: return getEnvironment() == Triple::Musl || getEnvironment() == Triple::MuslEABI || getEnvironment() == Triple::MuslEABIHF || - getEnvironment() == Triple::MuslX32; + getEnvironment() == Triple::MuslX32 || + getEnvironment() == Triple::OpenHOS || + isOSLiteOS(); } + /// Tests whether the target is OHOS + /// LiteOS default enviroment is also OHOS, but omited on triple. + bool isOHOSFamily() const { return isOpenHOS() || isOSLiteOS(); } + + bool isOpenHOS() const { return getEnvironment() == Triple::OpenHOS; } + + bool isOSLiteOS() const { return getOS() == Triple::LiteOS; } + /// Tests whether the target is DXIL. bool isDXIL() const { return getArch() == Triple::dxil; diff --git a/llvm/include/llvm/BinaryFormat/MinidumpConstants.def b/llvm/include/llvm/BinaryFormat/MinidumpConstants.def index 543305feea77..c03a4f8fd9ea 100644 --- a/llvm/include/llvm/BinaryFormat/MinidumpConstants.def +++ b/llvm/include/llvm/BinaryFormat/MinidumpConstants.def @@ -115,6 +115,7 @@ HANDLE_MDMP_PLATFORM(0x8202, Solaris) // Solaris HANDLE_MDMP_PLATFORM(0x8203, Android) // Android HANDLE_MDMP_PLATFORM(0x8204, PS3) // PS3 HANDLE_MDMP_PLATFORM(0x8205, NaCl) // Native Client (NaCl) +HANDLE_MDMP_PLATFORM(0x8207, OpenHOS) HANDLE_MDMP_PROTECT(0x01, NoAccess, PAGE_NO_ACCESS) HANDLE_MDMP_PROTECT(0x02, ReadOnly, PAGE_READ_ONLY) diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index b2ed8e60bd77..d4a22159104e 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -55,6 +55,7 @@ struct Config { CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; CodeGenFileType CGFileType = CGFT_ObjectFile; unsigned OptLevel = 2; + bool DisableVerify = false; /// Use the standard optimization pipeline. diff --git a/llvm/lib/Support/AArch64TargetParser.cpp b/llvm/lib/Support/AArch64TargetParser.cpp index e2579bf53260..d0e879840e43 100644 --- a/llvm/lib/Support/AArch64TargetParser.cpp +++ b/llvm/lib/Support/AArch64TargetParser.cpp @@ -171,7 +171,7 @@ void AArch64::fillValidCPUArchList(SmallVectorImpl &Values) { bool AArch64::isX18ReservedByDefault(const Triple &TT) { return TT.isAndroid() || TT.isOSDarwin() || TT.isOSFuchsia() || - TT.isOSWindows(); + TT.isOSWindows() || TT.isOHOSFamily(); } // Allows partial match, ex. "v8a" matches "armv8a". diff --git a/llvm/lib/Support/ARMTargetParser.cpp b/llvm/lib/Support/ARMTargetParser.cpp index d7294b5b1074..8e8375e735f0 100644 --- a/llvm/lib/Support/ARMTargetParser.cpp +++ b/llvm/lib/Support/ARMTargetParser.cpp @@ -633,7 +633,7 @@ StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) { default: if (TT.isOSNetBSD()) return "apcs-gnu"; - if (TT.isOSOpenBSD()) + if (TT.isOSOpenBSD() || TT.isOHOSFamily()) return "aapcs-linux"; return "aapcs"; } diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp index 6696d158b2c1..d163bcff0d3f 100644 --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -240,6 +240,7 @@ StringRef Triple::getOSTypeName(OSType Kind) { case Win32: return "windows"; case ZOS: return "zos"; case ShaderModel: return "shadermodel"; + case LiteOS: return "liteos"; } llvm_unreachable("Invalid OSType"); @@ -284,6 +285,7 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { case Callable: return "callable"; case Mesh: return "mesh"; case Amplification: return "amplification"; + case OpenHOS: return "ohos"; } llvm_unreachable("Invalid EnvironmentType!"); @@ -587,6 +589,7 @@ static Triple::OSType parseOS(StringRef OSName) { .StartsWith("wasi", Triple::WASI) .StartsWith("emscripten", Triple::Emscripten) .StartsWith("shadermodel", Triple::ShaderModel) + .StartsWith("liteos", Triple::LiteOS) .Default(Triple::UnknownOS); } @@ -628,6 +631,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("callable", Triple::Callable) .StartsWith("mesh", Triple::Mesh) .StartsWith("amplification", Triple::Amplification) + .StartsWith("ohos", Triple::OpenHOS) .Default(Triple::UnknownEnvironment); } diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp index 4ad93f7b0b68..e0c10cf5db15 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp @@ -552,8 +552,8 @@ static const char *getRegisterName(unsigned RegNum) { {0x2e09, "COMPUTE_NUM_THREAD_Z"}, {0xa2db, "VGT_TF_PARAM"}, {0xa2d6, "VGT_LS_HS_CONFIG"}, - {0xa287, "VGT_HOS_MIN_TESS_LEVEL"}, - {0xa286, "VGT_HOS_MAX_TESS_LEVEL"}, + {0xa287, "VGT_OHOS_MIN_TESS_LEVEL"}, + {0xa286, "VGT_OHOS_MAX_TESS_LEVEL"}, {0xa2f8, "PA_SC_AA_CONFIG"}, {0xa310, "PA_SC_SHADER_CONTROL"}, {0xa313, "PA_SC_CONSERVATIVE_RASTERIZATION_CNTL"}, diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index 460ec62d5a33..f046b198afb7 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -393,8 +393,9 @@ public: } bool isTargetMuslAEABI() const { return (TargetTriple.getEnvironment() == Triple::MuslEABI || - TargetTriple.getEnvironment() == Triple::MuslEABIHF) && - !isTargetDarwin() && !isTargetWindows(); + TargetTriple.getEnvironment() == Triple::MuslEABIHF || + TargetTriple.getEnvironment() == Triple::OpenHOS) && + !isTargetDarwin() && !isTargetWindows(); } // ARM Targets that support EHABI exception handling standard diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index d95c21d6504b..88b89e560597 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -240,7 +240,8 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT, if ((TargetTriple.getEnvironment() == Triple::GNUEABI || TargetTriple.getEnvironment() == Triple::GNUEABIHF || TargetTriple.getEnvironment() == Triple::MuslEABI || - TargetTriple.getEnvironment() == Triple::MuslEABIHF) && + TargetTriple.getEnvironment() == Triple::MuslEABIHF || + TargetTriple.getEnvironment() == Triple::OpenHOS) && !(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin())) this->Options.EABIVersion = EABI::GNU; else diff --git a/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll b/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll index 89fc6457482f..0ea2e20cfa52 100644 --- a/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll +++ b/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll @@ -2,6 +2,7 @@ ; RUN: llc -mtriple=arm64-freebsd-gnu -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=arm64-linux-gnu -o - %s | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-android -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 +; RUN: llc -mtriple=aarch64-linux-ohos -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=aarch64-fuchsia -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=aarch64-windows -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 diff --git a/llvm/test/Transforms/SafeStack/AArch64/abi.ll b/llvm/test/Transforms/SafeStack/AArch64/abi.ll index bd6710d160c5..45961b767180 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/abi.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/abi.ll @@ -1,8 +1,10 @@ ; RUN: opt -safe-stack -S -mtriple=aarch64-linux-android < %s -o - | FileCheck %s +; RUN: opt -safe-stack -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck %s --check-prefix=OHOS define void @foo() nounwind uwtable safestack { entry: +; OHOS-NOT: call i8* @llvm.thread.pointer() ; CHECK: %[[TP:.*]] = call i8* @llvm.thread.pointer() ; CHECK: %[[SPA0:.*]] = getelementptr i8, i8* %[[TP]], i32 72 ; CHECK: %[[SPA:.*]] = bitcast i8* %[[SPA0]] to i8** diff --git a/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll b/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll index c78b20aaa01a..9069ea50a4d5 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll @@ -1,4 +1,5 @@ ; RUN: opt -safe-stack -S -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefixes=TLS,ANDROID %s +; RUN: opt -safe-stack -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck --check-prefix=OHOS %s ; RUN: opt -safe-stack -S -mtriple=aarch64-unknown-fuchsia < %s -o - | FileCheck --check-prefixes=TLS,FUCHSIA %s define void @foo() nounwind uwtable safestack sspreq { @@ -6,6 +7,7 @@ entry: ; The first @llvm.thread.pointer is for the unsafe stack pointer, skip it. ; TLS: call i8* @llvm.thread.pointer() +; OHOS-NOT: call i8* @llvm.thread.pointer() ; TLS: %[[TP2:.*]] = call i8* @llvm.thread.pointer() ; ANDROID: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 40 ; FUCHSIA: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 -16 diff --git a/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll b/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll index 53ed690ebb09..7009fce7a4a4 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll @@ -1,7 +1,9 @@ ; RUN: opt -safe-stack -safe-stack-coloring -S -mtriple=aarch64-linux-android < %s -o - | FileCheck %s +; RUN: opt -safe-stack -safe-stack-coloring -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck %s --check-prefix=OHOSMUSL define void @foo() nounwind uwtable safestack { entry: +; OHOSMUSL-NOT: call i8* @llvm.thread.pointer() ; CHECK: %[[TP:.*]] = call i8* @llvm.thread.pointer() ; CHECK: %[[SPA0:.*]] = getelementptr i8, i8* %[[TP]], i32 72 ; CHECK: %[[SPA:.*]] = bitcast i8* %[[SPA0]] to i8** diff --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py index 7dae83733f31..5ef907a6de29 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -12,7 +12,7 @@ from lit.llvm.subst import ToolSubst lit_path_displayed = False -class LLVMConfig(object): +class LLVMConfig (object): def __init__(self, lit_config, config): self.lit_config = lit_config @@ -78,6 +78,8 @@ class LLVMConfig(object): features.add('system-windows') elif platform.system() == 'Linux': features.add('system-linux') + if os.path.exists('/.dockerenv'): + features.add('ohos-ci') elif platform.system() in ['FreeBSD']: features.add('system-freebsd') elif platform.system() == 'NetBSD': diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h index 357cffc13c80..57b93b074153 100644 --- a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h @@ -88,6 +88,9 @@ # if defined __ANDROID__ # define GTEST_OS_LINUX_ANDROID 1 # endif +# if defined __OHOS_FAMILY__ +# define GTEST_OS_LINUX_OHOS_FAMILY 1 +# endif #elif defined __MVS__ # define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) diff --git a/llvm/utils/unittest/googletest/src/gtest-port.cc b/llvm/utils/unittest/googletest/src/gtest-port.cc index fc5ba6becc55..a79dd856272a 100644 --- a/llvm/utils/unittest/googletest/src/gtest-port.cc +++ b/llvm/utils/unittest/googletest/src/gtest-port.cc @@ -1093,7 +1093,7 @@ class CapturedStream { // directory, so we create the temporary file in the /tmp directory // instead. We use /tmp on most systems, and /sdcard on Android. // That's because Android doesn't have /tmp. -# if GTEST_OS_LINUX_ANDROID +#if GTEST_OS_LINUX_ANDROID || GTEST_OS_LINUX_OHOS_FAMILY // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h index 6aeb495d44f2..07b2a9a3ff72 100644 --- a/openmp/runtime/src/kmp.h +++ b/openmp/runtime/src/kmp.h @@ -54,9 +54,8 @@ #define KMP_CANCEL_THREADS #define KMP_THREAD_ATTR -// Android does not have pthread_cancel. Undefine KMP_CANCEL_THREADS if being // built on Android -#if defined(__ANDROID__) +#if defined(__ANDROID__) || defined(__OHOS__) #undef KMP_CANCEL_THREADS #endif diff --git a/openmp/runtime/src/kmp_i18n.cpp b/openmp/runtime/src/kmp_i18n.cpp index a164aa180dd4..2474810ce6bf 100644 --- a/openmp/runtime/src/kmp_i18n.cpp +++ b/openmp/runtime/src/kmp_i18n.cpp @@ -710,7 +710,8 @@ static char *sys_error(int err) { #if (defined(__GLIBC__) && defined(_GNU_SOURCE)) || \ (defined(__BIONIC__) && defined(_GNU_SOURCE) && \ - __ANDROID_API__ >= __ANDROID_API_M__) + __ANDROID_API__ >= __ANDROID_API_M__) || \ + (defined(__OHOS__) && defined(_GNU_SOURCE)) // GNU version of strerror_r. char buffer[2048]; diff --git a/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp b/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp index 430c2006a451..0a24809c20f3 100644 --- a/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp +++ b/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp @@ -1,5 +1,6 @@ // RUN: %libomp-cxx-compile-and-run // RUN: %libomp-cxx-compile && env OMP_NUM_THREADS=1 %libomp-run +// UNSUPPORTED: ohos-ci /* * This test aims to check whether hidden helper task can work with regular task diff --git a/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp b/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp index 881e27df723c..5b38a9135773 100644 --- a/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp +++ b/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp @@ -42,7 +42,9 @@ struct anon { }; } -kmp_int32 __kmp_hidden_helper_threads_num; +// OHOS specific: we use static libomp and get link error on this symbol +// probably push this to mainline +__attribute__((weak)) kmp_int32 __kmp_hidden_helper_threads_num; kmp_int32 omp_task_entry(kmp_int32 gtid, kmp_task_t_with_privates *task) { auto shareds = reinterpret_cast(task->task.shareds); -- Gitee From 03ee2ef59b027aa073f124697114b6d7d74ae212 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Wed, 3 Aug 2022 16:53:54 +0300 Subject: [PATCH 02/41] Add CI config Signed-off-by: Ivan Eliseev --- .gitlab-ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000000..13b217bea8d6 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,8 @@ +variables: + TOOLCHAIN_MANIFEST: 'huawei/dev-open-harmonyos' + TOOLCHAIN_NAME: 'HOS-OS' + +include: + - project: 'rus-os-team/compilers/testing/automation/llvm-ci' + ref: 'master-opensource' + file: '/pipelines/llvm/ohos/main.yml' -- Gitee From e9a0b3636028cdf3a7c433aa13cf763d324b722d Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Fri, 5 Aug 2022 21:40:11 +0300 Subject: [PATCH 03/41] Fix pipeline issues - Use __errno_location instead of __errno in ASAN runtime - Don't emit error when *-ohos environment is omitted. Signed-off-by: Ivan Eliseev --- clang/lib/Driver/ToolChains/Arch/ARM.cpp | 5 +++++ clang/lib/Driver/ToolChains/OHOS.cpp | 8 -------- clang/lib/Driver/ToolChains/OHOS.h | 3 --- compiler-rt/lib/sanitizer_common/sanitizer_errno.h | 2 +- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index 2d3cabe53bb0..1f199fcd8d83 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -276,6 +276,11 @@ void arm::setArchNameInTriple(const Driver &D, const ArgList &Args, void arm::setFloatABIInTriple(const Driver &D, const ArgList &Args, llvm::Triple &Triple) { + if (Triple.isOSLiteOS()) { + Triple.setEnvironment(llvm::Triple::OpenHOS); + return; + } + bool isHardFloat = (arm::getARMFloatABI(D, Triple, Args) == arm::FloatABI::Hard); diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp index 8909966a99d5..83366bef2081 100644 --- a/clang/lib/Driver/ToolChains/OHOS.cpp +++ b/clang/lib/Driver/ToolChains/OHOS.cpp @@ -169,14 +169,6 @@ OHOS::OHOS(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) Paths); } -std::string OHOS::ComputeEffectiveClangTriple(const ArgList &Args, - types::ID InputType) const { - auto TripleStr = Generic_ELF::ComputeEffectiveClangTriple(Args, InputType); - llvm::Triple T(TripleStr); - T.setEnvironment(llvm::Triple::OpenHOS); - return T.str(); -} - ToolChain::RuntimeLibType OHOS::GetRuntimeLibType( const ArgList &Args) const { if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) { diff --git a/clang/lib/Driver/ToolChains/OHOS.h b/clang/lib/Driver/ToolChains/OHOS.h index be1115967b78..1d826122e239 100644 --- a/clang/lib/Driver/ToolChains/OHOS.h +++ b/clang/lib/Driver/ToolChains/OHOS.h @@ -42,9 +42,6 @@ public: 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 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h index e85533c0fd8a..46c85364cef5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h @@ -23,7 +23,7 @@ #if SANITIZER_FREEBSD || SANITIZER_APPLE # define __errno_location __error -#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_OHOS +#elif SANITIZER_ANDROID || SANITIZER_NETBSD # define __errno_location __errno #elif SANITIZER_SOLARIS # define __errno_location ___errno -- Gitee From 8a03a226fef280025e627dc5416dd6e7a2ceabdb Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Mon, 8 Aug 2022 18:58:04 +0300 Subject: [PATCH 04/41] Change llvm-ci branch Signed-off-by: Ivan Eliseev --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 13b217bea8d6..7b91e1e2f440 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,5 +4,5 @@ variables: include: - project: 'rus-os-team/compilers/testing/automation/llvm-ci' - ref: 'master-opensource' + ref: 'master-opensource-llvm-15' file: '/pipelines/llvm/ohos/main.yml' -- Gitee From 16105bd1f13ef7f3517206901e9e5320055afb72 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Wed, 24 Aug 2022 13:55:15 +0300 Subject: [PATCH 05/41] Emit runtime checks correctly for nested loops Differential revision: https://reviews.llvm.org/D132490 TODO: Patch is on review - need to act accordingly to review status. Signed-off-by: Ivan Eliseev --- .../Transforms/Vectorize/LoopVectorize.cpp | 2 +- .../Transforms/LoopVectorize/nested-loop.ll | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/LoopVectorize/nested-loop.ll diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 5fd4e45d80fb..cb83d698001e 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1911,7 +1911,7 @@ public: "vector.memcheck"); auto DiffChecks = RtPtrChecking.getDiffChecks(); - if (DiffChecks) { + if (L->getParentLoop() == nullptr && DiffChecks) { Value *RuntimeVF = nullptr; MemRuntimeCheckCond = addDiffRuntimeChecks( MemCheckBlock->getTerminator(), L, *DiffChecks, MemCheckExp, diff --git a/llvm/test/Transforms/LoopVectorize/nested-loop.ll b/llvm/test/Transforms/LoopVectorize/nested-loop.ll new file mode 100644 index 000000000000..d00eef9d2dae --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/nested-loop.ll @@ -0,0 +1,74 @@ +; RUN: opt -loop-vectorize -S %s -o - | FileCheck %s +; CHECK: vector.memcheck: +; CHECK-NEXT: %bound0 = icmp ult ptr +; CHECK-NEXT: %bound1 = icmp ult ptr +; CHECK-NEXT: %found.conflict = and i1 %bound0, %bound1 + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +; Function Attrs: nofree nounwind uwtable +define dso_local void @array_magick(ptr nocapture noundef %a, ptr nocapture noundef readonly %b, i32 noundef %len) local_unnamed_addr #0 { +entry: + %cmp24 = icmp sgt i32 %len, 0 + br i1 %cmp24, label %for.cond1.preheader.us.preheader, label %for.end12 + +for.cond1.preheader.us.preheader: ; preds = %entry + %wide.trip.count30 = zext i32 %len to i64 + br label %for.cond1.preheader.us + +for.cond1.preheader.us: ; preds = %for.cond1.preheader.us.preheader, %for.cond1.for.end_crit_edge.us + %indvars.iv27 = phi i64 [ 0, %for.cond1.preheader.us.preheader ], [ %indvars.iv.next28, %for.cond1.for.end_crit_edge.us ] + %arrayidx.us = getelementptr inbounds i32, ptr %a, i64 %indvars.iv27 + %.pre = load i32, ptr %arrayidx.us, align 4, !tbaa !5 + br label %for.body3.us + +for.body3.us: ; preds = %for.cond1.preheader.us, %for.body3.us + %0 = phi i32 [ %.pre, %for.cond1.preheader.us ], [ %sub.us, %for.body3.us ] + %indvars.iv = phi i64 [ 0, %for.cond1.preheader.us ], [ %indvars.iv.next, %for.body3.us ] + %arrayidx5.us = getelementptr inbounds i32, ptr %b, i64 %indvars.iv + %1 = load i32, ptr %arrayidx5.us, align 4, !tbaa !5 + %sub.us = sub i32 %0, %1 + store i32 %sub.us, ptr %arrayidx.us, align 4, !tbaa !5 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count30 + br i1 %exitcond.not, label %for.cond1.for.end_crit_edge.us, label %for.body3.us, !llvm.loop !9 + +for.cond1.for.end_crit_edge.us: ; preds = %for.body3.us + %sub.us.lcssa = phi i32 [ %sub.us, %for.body3.us ] + %call.us = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str, i32 noundef %sub.us.lcssa) + %indvars.iv.next28 = add nuw nsw i64 %indvars.iv27, 1 + %exitcond31.not = icmp eq i64 %indvars.iv.next28, %wide.trip.count30 + br i1 %exitcond31.not, label %for.end12.loopexit, label %for.cond1.preheader.us, !llvm.loop !12 + +for.end12.loopexit: ; preds = %for.cond1.for.end_crit_edge.us + br label %for.end12 + +for.end12: ; preds = %for.end12.loopexit, %entry + ret void +} + +; Function Attrs: nofree nounwind +declare noundef i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1 + +attributes #0 = { nofree nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nounwind "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } + +!llvm.module.flags = !{!0, !1, !2, !3} +!llvm.ident = !{!4} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{!"clang version 16.0.0 (https://github.com/llvm/llvm-project.git 09f608fda51ca9dd2d88c2985bad1cfc1e36251e)"} +!5 = !{!6, !6, i64 0} +!6 = !{!"int", !7, i64 0} +!7 = !{!"omnipotent char", !8, i64 0} +!8 = !{!"Simple C/C++ TBAA"} +!9 = distinct !{!9, !10, !11} +!10 = !{!"llvm.loop.mustprogress"} +!11 = !{!"llvm.loop.unroll.disable"} +!12 = distinct !{!12, !10, !11} -- Gitee From ca62447b3f4a44536987a6cb7d4723416afa53ac Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Mon, 29 Aug 2022 18:32:00 +0300 Subject: [PATCH 06/41] Temporary disable libcxx test on OHOS-CI Test case hangs on CI, but passes locally, Need to investigate this. Signed-off-by: Ivan Eliseev --- libcxx/test/libcxx/modules_include.sh.cpp | 3 +++ libcxx/utils/libcxx/test/features.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/libcxx/test/libcxx/modules_include.sh.cpp b/libcxx/test/libcxx/modules_include.sh.cpp index b6d73e8ed446..ddd9caafcd81 100644 --- a/libcxx/test/libcxx/modules_include.sh.cpp +++ b/libcxx/test/libcxx/modules_include.sh.cpp @@ -16,6 +16,9 @@ // GCC doesn't support -fcxx-modules // UNSUPPORTED: gcc +// FIXME: hangs on CI +// UNSUPPORTED: ohos-ci + // The Windows headers don't appear to be compatible with modules // UNSUPPORTED: windows diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py index dea8b38e7cbe..8ec356c85b9d 100644 --- a/libcxx/utils/libcxx/test/features.py +++ b/libcxx/utils/libcxx/test/features.py @@ -299,3 +299,7 @@ DEFAULT_FEATURES += [ actions=[AddSubstitution('%{gdb}', lambda cfg: shutil.which('gdb'))] ) ] + +DEFAULT_FEATURES += [ + Feature(name='ohos-ci', when=lambda cfg: os.path.exists('/.dockerenv')) +] -- Gitee From 82fba4869ee31fabbf20b19af6b3d03eed3ab9d2 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 30 Aug 2022 20:01:22 +0300 Subject: [PATCH 07/41] Fix exception handling on 32-bit ARM Signed-off-by: Ivan Eliseev --- llvm/include/llvm/ADT/Triple.h | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index 95bf1757cbb0..b2b79adc1f81 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -777,6 +777,7 @@ public: getEnvironment() == Triple::MuslEABI || getEnvironment() == Triple::EABIHF || getEnvironment() == Triple::GNUEABIHF || + getEnvironment() == Triple::OpenHOS || getEnvironment() == Triple::MuslEABIHF || isAndroid()) && isOSBinFormatELF(); } -- Gitee From 0295f52188b60b16f3a2ff421ddf7507dca1e207 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 6 Sep 2022 15:41:52 +0300 Subject: [PATCH 08/41] Prevent using system memcpy in case of ODR violation In case of ODR violation ASAN may attempt to copy global which may cause LLVM to emit memcpy call. THe memcpy call goes through interceptor and causes nested error, because memory for global is poisoned TODO: Create mainline patch Signed-off-by: Ivan Eliseev --- compiler-rt/lib/asan/asan_errors.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler-rt/lib/asan/asan_errors.h b/compiler-rt/lib/asan/asan_errors.h index c6ac88f6dc2a..df9868c6a382 100644 --- a/compiler-rt/lib/asan/asan_errors.h +++ b/compiler-rt/lib/asan/asan_errors.h @@ -339,10 +339,13 @@ struct ErrorODRViolation : ErrorBase { ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_, const __asan_global *g2, u32 stack_id2_) : ErrorBase(tid, 10, "odr-violation"), - global1(*g1), - global2(*g2), stack_id1(stack_id1_), - stack_id2(stack_id2_) {} + stack_id2(stack_id2_) { + // HUAWEI: We must avoid memcpy intrinsic, because memory for g2 + // is poisoned. + internal_memcpy(&global1, g1, sizeof(*g1)); + internal_memcpy(&global2, g2, sizeof(*g2)); + } void Print(); }; -- Gitee From 39fd56d3727b72b413d9b6b9275c4ac38326c9f6 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 6 Sep 2022 15:47:21 +0300 Subject: [PATCH 09/41] Increase stack memory for death test Google test harness allocates only two memory pages for child process in case of death test. This causes stack overflow when launch of child process fails and gtest tries to show error message. TODO: Upstream Signed-off-by: Ivan Eliseev --- llvm/utils/unittest/googletest/src/gtest-death-test.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/utils/unittest/googletest/src/gtest-death-test.cc b/llvm/utils/unittest/googletest/src/gtest-death-test.cc index 5d1031bea257..bdb4b6585624 100644 --- a/llvm/utils/unittest/googletest/src/gtest-death-test.cc +++ b/llvm/utils/unittest/googletest/src/gtest-death-test.cc @@ -1364,7 +1364,9 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { if (!use_fork) { static const bool stack_grows_down = StackGrowsDown(); - const auto stack_size = static_cast(getpagesize() * 2); + // HUAWEI: increase stack size for child process or we won't see + // error message in case death test fails. + const auto stack_size = static_cast(getpagesize() * 4); // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); -- Gitee From 4ee5b437ef120ba62e364d23d9cdf00826a5317e Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 6 Sep 2022 15:49:29 +0300 Subject: [PATCH 10/41] Fix ASAN test runner on OHOS Signed-off-by: Ivan Eliseev --- .../test/sanitizer_common/ohos_family_commands/ohos_common.py | 0 .../test/sanitizer_common/ohos_family_commands/ohos_compile.py | 2 +- .../test/sanitizer_common/ohos_family_commands/ohos_run.py | 0 3 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py mode change 100644 => 100755 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py mode change 100644 => 100755 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py 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 old mode 100644 new mode 100755 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 old mode 100644 new mode 100755 index 1c8624fbd621..3a4769a5196b --- a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py @@ -5,7 +5,7 @@ from ohos_common import * here = os.path.abspath(os.path.dirname(sys.argv[0])) -hos_run = os.path.join(here, 'hos_run.py') +hos_run = os.path.join(here, 'ohos_run.py') output = None output_type = 'executable' 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 old mode 100644 new mode 100755 -- Gitee From 4d221b2d4c749a23b45ea2c65afd65299d7c287d Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Wed, 7 Sep 2022 20:44:52 +0300 Subject: [PATCH 11/41] Don't run unit tests with check-asan Signed-off-by: Ivan Eliseev --- compiler-rt/test/asan/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/test/asan/CMakeLists.txt b/compiler-rt/test/asan/CMakeLists.txt index d02ee4b5bd68..91f4bc675d79 100644 --- a/compiler-rt/test/asan/CMakeLists.txt +++ b/compiler-rt/test/asan/CMakeLists.txt @@ -143,7 +143,7 @@ if(COMPILER_RT_INCLUDE_TESTS) ${CMAKE_CURRENT_BINARY_DIR}/Unit/${CONFIG_NAME_DYNAMIC}/lit.site.cfg.py) endif() # FIXME: support unit test in the android test runner - if (NOT ANDROID) + if (NOT ANDROID AND NOT OHOS) list(APPEND ASAN_TEST_DEPS AsanUnitTests) list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/${CONFIG_NAME}) if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME) -- Gitee From f2f75a5733461675225a0d31809a0082a4ec8f89 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Thu, 8 Sep 2022 09:35:17 +0300 Subject: [PATCH 12/41] Lower RSS limit in test Sometimes measured RSS on phone is 19Mb and test fails. Signed-off-by: Ivan Eliseev --- compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp b/compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp index f7bccbfbe8db..35530e61b3dd 100644 --- a/compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/quarantine_size_mb.cpp @@ -4,7 +4,9 @@ // RUN: %env_asan_opts=quarantine_size_mb=10:verbosity=1:hard_rss_limit_mb=50 %run %t 2>&1 | FileCheck %s --check-prefix=Q10 // RUN: %env_asan_opts=quarantine_size_mb=10:quarantine_size=20:verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=BOTH // RUN: %env_asan_opts=quarantine_size_mb=1000:hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT -// RUN: %env_asan_opts=hard_rss_limit_mb=20 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT + +// HUAWEI: Sometimes measured RSS on device is 19Mb and test fails with 20Mb limit +// RUN: %env_asan_opts=hard_rss_limit_mb=10 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT // https://github.com/google/sanitizers/issues/981 // UNSUPPORTED: android-26 -- Gitee From 451d5df884539d3d6e56b5ea93a8974e5e09418a Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Thu, 8 Sep 2022 09:36:33 +0300 Subject: [PATCH 13/41] Allow llvm-ci to find ASAN unit test binaries llvm-ci looks at tests/default for static binaries and at tests/dynamic for dynamic binaries Signed-off-by: Ivan Eliseev --- compiler-rt/lib/asan/tests/CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt index a0c6d2910d6f..7bbe9c2a36e8 100644 --- a/compiler-rt/lib/asan/tests/CMakeLists.txt +++ b/compiler-rt/lib/asan/tests/CMakeLists.txt @@ -168,8 +168,13 @@ function(add_asan_tests arch test_runtime) # selection. Each configuration expects the test binaries in a corresponding # subdirectory. Generate subdirectory names based on the architecture name. string(TOUPPER ${arch} ARCH_UPPER_CASE) - set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) - set(CONFIG_NAME_DYNAMIC ${ARCH_UPPER_CASE}${OS_NAME}DynamicConfig) + if (OHOS) + set(CONFIG_NAME default) + set(CONFIG_NAME_DYNAMIC dynamic) + else() + set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) + set(CONFIG_NAME_DYNAMIC ${ARCH_UPPER_CASE}${OS_NAME}DynamicConfig) + endif() # Closure to keep the values. function(generate_asan_tests test_objects test_suite testname) -- Gitee From 31471157b5bb5567fcab5b763f5cb8338899c1f0 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Thu, 8 Sep 2022 11:17:07 +0300 Subject: [PATCH 14/41] Prevent too early initialization of background thread This fixes quarantine_size_mb test when shared runtime is used. Signed-off-by: Ivan Eliseev --- compiler-rt/lib/sanitizer_common/sanitizer_platform.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 088cba6b36eb..9469f0587f7f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -442,7 +442,9 @@ # endif #endif -#if defined(__thumb__) && defined(__linux__) +// HUAWEI: musl seems to not respect static ctor order and we start +// background thread before parsing flags. FIXME +#if (defined(__thumb__) && defined(__linux__)) || SANITIZER_OHOS // Workaround for // https://lab.llvm.org/buildbot/#/builders/clang-thumbv7-full-2stage // or -- Gitee From a887d885be9e2922cd49ff79191488d86819f8c8 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Thu, 8 Sep 2022 13:44:38 +0300 Subject: [PATCH 15/41] Don't attempt to pop frames if stack unwinding failed Signed-off-by: Ivan Eliseev --- compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp index d24fae98213a..937afb1645d0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp @@ -149,6 +149,11 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, #endif // !defined(__sparc__) void BufferedStackTrace::PopStackFrames(uptr count) { + // HUAWEI: Don't atempt to pop if stack unwinding failed + // this may happen at the aearly stage of ASAN initialization + // (e.g malloc called from __dl_vseterr) + if (count == 0) + return; CHECK_LT(count, size); size -= count; for (uptr i = 0; i < size; ++i) { -- Gitee From 63c1de5e395d9307db22256a1e6f991c572426cc Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Mon, 17 Oct 2022 18:55:47 +0300 Subject: [PATCH 16/41] Add llvm-build Signed-off-by: Ivan Eliseev --- llvm-build/Makefile | 228 ++++ llvm-build/OHOS.cmake | 22 + llvm-build/README.md | 126 ++ llvm-build/build.py | 1805 +++++++++++++++++++++++++++++ llvm-build/build_cpython-mingw.sh | 81 ++ llvm-build/build_musl.sh | 116 ++ llvm-build/env_prepare.sh | 113 ++ llvm-build/mingw.py | 226 ++++ llvm-build/toolchain_readme.md | 26 + 9 files changed, 2743 insertions(+) create mode 100644 llvm-build/Makefile create mode 100644 llvm-build/OHOS.cmake create mode 100644 llvm-build/README.md create mode 100755 llvm-build/build.py create mode 100755 llvm-build/build_cpython-mingw.sh create mode 100755 llvm-build/build_musl.sh create mode 100755 llvm-build/env_prepare.sh create mode 100755 llvm-build/mingw.py create mode 100644 llvm-build/toolchain_readme.md diff --git a/llvm-build/Makefile b/llvm-build/Makefile new file mode 100644 index 000000000000..54a94743676c --- /dev/null +++ b/llvm-build/Makefile @@ -0,0 +1,228 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +ARCH = arm +ifneq ($(GCC),) +TARGET = +CROSS_COMPILE = $(GCC:%gcc=%) +CC = $(GCC) $(ARCH_CFLAGS) +MULTILIB = $(patsubst %.,%,$(shell $(CC) -print-multi-directory)) +else +TARGET = $(ARCH)-liteos-ohos +CLANG ?= clang +CROSS_COMPILE = $(CLANG:%clang=%llvm-) +CC = $(CLANG) --target=$(TARGET) $(ARCH_CFLAGS) +BUILD=x86_64-linux-gnu +MULTILIB = $(patsubst $(dir $(shell $(filter-out $(ARCH_CFLAGS),$(CC)) -print-libgcc-file-name))%,/%,$(dir $(shell $(CC) -print-libgcc-file-name))) +endif +MUSLBUILDDIR = build_$(or $(TARGET),$(ARCH))$(subst /,_,$(MULTILIB:%/=%)) +HIDE = @ +BUILD_DEBUG = false +SED_ARGS = -e '/install-libs:/s/if/and/g' + +TOPDIR = $(shell pwd)/../../../.. +MUSLDIR = $(TOPDIR)/third_party/musl +LINUXKERNELDIR = $(TOPDIR)/third_party/Linux_Kernel +OPTRTDIR = $(TOPDIR)/third_party/optimized-routines +NUTTXDIR = $(TOPDIR)/third_party/NuttX +SYSROOTDIR = $(TOPDIR)/prebuilts/lite/sysroot +LITEOSADIR = $(TOPDIR)/kernel/liteos_a +LINUXDIR = $(TOPDIR)/kernel/linux/linux-5.10 + +TARGETS = $(if $(wildcard $(LITEOSADIR)),liteos_a_user,) +TARGETS += $(if $(wildcard $(LINUXDIR)),linux_user,) + +define LINUX_TYPES_H +#ifndef _LINUX_TYPES_H +#define _LINUX_TYPES_H +#include +typedef uint32_t __u32, __le32; +#endif +endef +export LINUX_TYPES_H + +ifeq ($(ARCH),arm) +ARCH_CFLAGS = -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 +else +ifeq ($(ARCH),aarch64) +ARCH_CFLAGS = +else +ifeq ($(ARCH),riscv64) +ARCH_CFLAGS = +else +ifeq ($(ARCH),mips) +ARCH_CFLAGS = +else +ifeq ($(ARCH),x86_64) +ARCH_CFLAGS = +else +$(warning *** warning: ARCH $(ARCH) has not been tested yet, use with cautions!) +ARCH_CFLAGS = +endif +endif +endif +endif +endif + +ifeq ($(ARCH),aarch64) +CFLAGS = -march=armv8 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),riscv64) +CFLAGS = -march=rv64gc -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),mips) +CFLAGS = -march=mips32r2 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),x86_64) +CFLAGS = -march=x86-64 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +CFLAGS = -march=armv7-a -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +endif +endif +endif +endif + +.PHONY: $(TARGETS:%=musl_copy_for_%) +.PHONY: $(TARGETS:%=musl_patch_for_%) +.PHONY: $(TARGETS:%=musl_install_for_%) +.PHONY: $(TARGETS:%=musl_header_install_for_%) +.PHONY: $(TARGETS:%=linux_header_install_for_%) +.PHONY: $(TARGETS:%=nuttx_header_install_for_%) +.PHONY: $(TARGETS:%=optimized_routines_install_for_%) +.PHONY: all clean distclean + +all: $(TARGETS:%=musl_install_for_%) + +$(TARGETS:%=musl_copy_for_%): + $(HIDE) mkdir -p $@ + $(HIDE) cp -rfu $(MUSLDIR)/[^p]* $@ + +optimized_routines_install_for_liteos_a_user: musl_copy_for_liteos_a_user +ifneq ($(ARCH),) + $(HIDE) cp -rfp $(OPTRTDIR)/string/$(ARCH)/* $> $ $ $/dev/null && \ + make -sj install-headers + +musl_install_for_liteos_a_user: musl_patch_for_liteos_a_user + $(HIDE) cd musl_copy_for_liteos_a_user && mkdir -p $(MUSLBUILDDIR) && cd $(MUSLBUILDDIR) && \ + ../configure --prefix=$(SYSROOTDIR)/$(TARGET)/usr --target=$(TARGET) \ + --includedir=$(SYSROOTDIR)/$(TARGET)/usr/include \ + --libdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --syslibdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --build=$(BUILD) \ + $(if $(LDFLAGS),LDFLAGS="$(LDFLAGS)",) \ + CC="$(CC)" CROSS_COMPILE="$(CROSS_COMPILE)" CFLAGS="$(CFLAGS)" >/dev/null && \ + make -sj install + +musl_patch_for_linux_user: musl_copy_for_linux_user + $(HIDE) cp -rfp $(MUSLDIR)/porting/linux/user/* $/dev/null && \ + make -sj install-headers + +musl_install_for_linux_user: musl_patch_for_linux_user + $(HIDE) cd musl_copy_for_linux_user && mkdir -p $(MUSLBUILDDIR) && cd $(MUSLBUILDDIR) && \ + ../configure --prefix=$(SYSROOTDIR)/$(TARGET)/usr --target=$(TARGET) \ + --includedir=$(SYSROOTDIR)/$(TARGET)/usr/include \ + --libdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --syslibdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --build=$(BUILD) \ + CC="$(CC)" CROSS_COMPILE="$(CROSS_COMPILE)" CFLAGS="$(CFLAGS)" >/dev/null && \ + make -sj install + +clean: + $(HIDE) rm -rf musl_copy_for_* linux_header_install_for_* + +distclean: clean + $(HIDE) rm -rf $(SYSROOTDIR)/lib $(SYSROOTDIR)/usr diff --git a/llvm-build/OHOS.cmake b/llvm-build/OHOS.cmake new file mode 100644 index 000000000000..df2c08ce41ba --- /dev/null +++ b/llvm-build/OHOS.cmake @@ -0,0 +1,22 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(Platform/Linux) + +# OHOS has soname, but binary names must end in ".so" so we cannot append +# a version number. Also we cannot portably represent symlinks on the host. +set(CMAKE_PLATFORM_NO_VERSIONED_SONAME 1) + +# OHOS reportedly ignores RPATH, and we cannot predict the install +# location anyway. +set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") diff --git a/llvm-build/README.md b/llvm-build/README.md new file mode 100644 index 000000000000..e12de6c793fa --- /dev/null +++ b/llvm-build/README.md @@ -0,0 +1,126 @@ +## Overview + +This readme briefly describes the functionality of our LLVM toolchain and how to build it + +1. [Build WIKI](#build_wiki) +2. [Function Introduction](#function_introduction) + + +## Build WIKI +
+ +### System Requirements for Toolchain BUild + +Ubuntu >= 16.04 +MacOS X >= 10.15.4 + +
+ +### Get Code +``` +repo init -u https://gitee.com/OpenHarmony/manifest.git -b add_llvm_toolchain-dev (not ready yet) +repo sync -c +repo forall -c 'git lfs pull' +cp -r toolchain/llvm-project/llvm-build toolchain +``` +
+ +### Toolchain build process + +Here is an example of starting build process on Linux or MacOS: +``` +# update prebuilts, no need to run each time +./toolchain/llvm-project/llvm-build/env_prepare.sh +# build +python3 ./toolchain/llvm-build/build.py +``` + +1. env_prepare (one time only) +![输入图片说明](../data/one_time_setup.png) + +2. build +![输入图片说明](../data/llvm_build.png) + +
+ +### Options + +build.py options: + +``` +--skip-build # skip compile and goto package step +--skip-package # do compile without package step +--enable-assertions # enable assertion when compiling +--build-name # specify release package name +--debug # build debug version llvm toolchain +--no-build-arm # skip triplet arm +--no-build-aarch64 # skip triplet arm64 +--no-build-x86_64 # skip triplet x86_64 +--no-lto # disable LTO optimization when build toolchain +--build-instrumented # enable instrument pgo when build toolchain +--xunit-xml-output # specify LLVM unit test XML report path +--no-build # optional, skip some targets + windows + libs + lldb-mi + lldb-server + linux + check-api +``` +
+ +### Output Layout + +When build successfully completed. following artifacts will be available in `out` directory + +`sysroot` -> sysroots for OHOS targets +`install` -> toolchain build +`*.tar.bz2` -> archived versions of toolchain and sysroots +
+ +### OHOS Archive + +1. llvm +``` +contains: +1. toolchain which provides clang compiler, lldb(-mi), clang-tidy etc. tools +2. libc++/clang_rt/asan/fuzzer libs for target device + +OHOS sync from: https://mirrors.huaweicloud.com/openharmony/compiler/clang/ +Which is the same as: out/clang-dev-${platform}-${arch}.tar.bz2 +OHOS archive to: prebuilts/clang/ohos//${platform}/llvm + +License: Apache License v2.0 with LLVM Exceptions +``` + +2. libcxx-ndk +``` +contains: provide libc++ for ndk in target device + +OHOS fetch prebuilts from: https://mirrors.huaweicloud.com/openharmony/compiler/clang/ and archive it to prebuilts/clang/ohos//${platform}/libcxx-ndk. This tar is + +License: Apache License v2.0 with LLVM Exceptions +``` + + +## Function Introduction +
+ +### Functionality + +The LLVM toolchain is built based on LLVM 12.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 12.0.1, please refer to [LLVM 12.0.1](https://lists.llvm.org/pipermail/llvm-announce/2021-July/000093.html). +
+ +### Specifically Included Triplets + +Despite all the components provided by LLVM community, we included several triplets for different types of ohos devices to our LLVM toochain, listed as below. For specification, liteos is a newly included OS name which indicate the simplified linux kernel. + +| Triplet Name | Architecture | System Kernel | System | +| ---------------------- | ------------ | ------------- | --------------- | +| arm-liteos-ohos | ARM 32bits | LiteOS | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Standard system | +| aarch64-linux-ohos | ARM 64bits | Linux | Standard system | + +For detailed definition of Small System and Standard System, please refer to [System Types](https://gitee.com/openharmony/docs/blob/master/en/device-dev/Readme-EN.md). + diff --git a/llvm-build/build.py b/llvm-build/build.py new file mode 100755 index 000000000000..24a18955ac79 --- /dev/null +++ b/llvm-build/build.py @@ -0,0 +1,1805 @@ +#!/usr/bin/env python +# Copyright (C) 2021 Huawei Device Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# 2021.3.15 build for OHOS LLVM. +# Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + +import os +import platform +import re +import datetime +import logging +import glob +import subprocess +import shutil +import argparse +import mingw +import stat + + +class BuildConfig(): + # Defines public methods and functions and obtains script parameters. + + def __init__(self): + args = self.parse_args() + self.do_build = not args.skip_build + self.do_package = not args.skip_package + self.build_name = args.build_name + self.debug = args.debug + self.no_lto = args.no_lto + self.build_instrumented = args.build_instrumented + self.xunit_xml_output = args.xunit_xml_output + self.enable_assertions = args.enable_assertions + self.need_libs = self.do_build and 'libs' not in args.no_build + self.need_lldb_mi = self.do_build and 'lldb-mi' not in args.no_build + self.need_lldb_server = self.do_build and 'lldb-server' not in args.no_build + + self.no_build_arm = args.skip_build or args.no_build_arm + self.no_build_aarch64 = args.skip_build or args.no_build_aarch64 + self.no_build_riscv64 = args.skip_build or args.no_build_riscv64 + self.no_build_mipsel = args.skip_build or args.no_build_mipsel + self.no_build_x86_64 = args.skip_build or args.no_build_x86_64 + + self.CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) + self.REPOROOT_DIR = os.path.abspath(os.path.join(self.CURRENT_DIR, '../../')) + self.LLVM_PROJECT_DIR = os.path.abspath(os.path.join(self.REPOROOT_DIR, 'toolchain', 'llvm-project')) + self.OUT_PATH = os.path.join(self.REPOROOT_DIR, 'out') + self.TARGETS = 'AArch64;ARM;BPF;Mips;RISCV;X86' + self.ORIG_ENV = dict(os.environ) + self.VERSION = None # autodetected + + self.OPENHOS_SFX = '-linux-ohos' + self.LITEOS_SFX = '-liteos-ohos' + self.LLDB_PY_VERSION = '3.10' + self.CLANG_VERSION = '10.0.1' + logging.basicConfig(level=logging.INFO) + + @staticmethod + def parse_add_argument(parser): + + parser.add_argument( + '--enable-assertions', + action='store_true', + default=False, + help='Apply assertions, some parameters are affected.') + + parser.add_argument( + '--build-name', + default='dev', + help='Release name for the package.') + + parser.add_argument( + '--debug', + action='store_true', + default=False, + help='Building Clang and LLVM Tools for Debugging (only affects stage2)') + + parser.add_argument( + '--no-build-arm', + action='store_true', + default=False, + help='Omit build os target: arm.') + + parser.add_argument( + '--no-build-aarch64', + action='store_true', + default=False, + help='Omit build os target: aarch64.') + + parser.add_argument( + '--no-build-riscv64', + action='store_true', + default=False, + help='Omit build os target: 64-bit RISC-V.') + + parser.add_argument( + '--no-build-mipsel', + action='store_true', + default=False, + help='Omit build os target: mipsel.') + + parser.add_argument( + '--no-build-x86_64', + action='store_true', + default=False, + help='Omit build os target: x86_64.') + + parser.add_argument( + '--no-lto', + action='store_true', + default=False, + help='Accelerate builds by disabling LTO (only affects llvm product)') + + parser.add_argument( + '--build-instrumented', + action='store_true', + default=False, + help='Using the PGO instrumentation to build LLVM tool') + + parser.add_argument( + '--xunit-xml-output', + default=None, + help='Output path for LLVM unit tests XML report') + + def parse_args(self): + + parser = argparse.ArgumentParser(description='Process some integers.') + + # Options to skip build or packaging, can't skip two + build_package_group = parser.add_mutually_exclusive_group() + build_package_group.add_argument( + '--skip-build', + '-sb', + action='store_true', + default=False, + help='Omit the build, perform the packaging step directly.') + + build_package_group.add_argument( + '--skip-package', + '-sp', + action='store_true', + default=False, + help='Omit the packaging, perform the packaging step directly.') + + self.parse_add_argument(parser) + + known_platforms = ('windows', 'libs', 'lldb-mi', 'lldb-server', 'linux', 'check-api') + known_platforms_str = ', '.join(known_platforms) + + class SeparatedListByCommaAction(argparse.Action): + def __call__(self, parser, namespace, vals, option_string): + for val in vals.split(','): + if val in known_platforms: + continue + else: + error = '\'{}\' invalid. Choose from {}'.format(val, known_platforms) + raise argparse.ArgumentError(self, error) + setattr(namespace, self.dest, vals.split(',')) + + parser.add_argument( + '--no-build', + action=SeparatedListByCommaAction, + default=list(), + help='Don\'t build toolchain for specified platforms. Choices: ' + known_platforms_str) + + return parser.parse_args() + + +class ClangVersion(object): + """Parse and save clang version from version file.""" + + def __init__(self, version_file): + self._parse_version_file(version_file) + + @staticmethod + def _parse(text, key): + return re.findall(r'%s\s+(\d+)' % key, text)[0] + + def _parse_version_file(self, version_file): + with open(version_file, 'r') as fp: + text = fp.read() + self.major = self._parse(text, 'CLANG_VERSION_MAJOR') + self.minor = self._parse(text, 'CLANG_VERSION_MINOR') + self.patch = self._parse(text, 'CLANG_VERSION_PATCHLEVEL') + + def long_version(self): + return '.'.join([self.major, self.minor, self.patch]) + + def short_version(self): + return '.'.join([self.major, self.minor]) + + def major_version(self): + return self.major + + +class BuildUtils(object): + + def __init__(self, build_config): + self.build_config = build_config + + self.CMAKE_BIN_DIR = os.path.abspath( + os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts/cmake', self.platform_prefix(), 'bin')) + + def open_ohos_triple(self, arch): + return arch + self.build_config.OPENHOS_SFX + + def liteos_triple(self, arch): + return arch + self.build_config.LITEOS_SFX + + def set_clang_version(self, install_dir): + self.build_config.VERSION = self.get_clang_version(install_dir).long_version() + + def invoke_ninja(self, + out_path, + env, + target=None, + install=True, + build_threads=False): + + ninja_bin_path = os.path.join(self.CMAKE_BIN_DIR, 'ninja') + + ninja_list = ['-l{}'.format(build_threads)] if build_threads else [] + + ninja_target = [target] if target else [] + + self.check_call([ninja_bin_path] + ninja_list + ninja_target, cwd=out_path, env=env) + if install: + self.check_call([ninja_bin_path, 'install'], cwd=out_path, env=env) + + def invoke_cmake(self, + cmake_path, + out_path, + invoke_defines, + env): + + cmake_bin_path = os.path.join(self.CMAKE_BIN_DIR, 'cmake') + flags = ['-G', 'Ninja'] + flags += ['-DCMAKE_PREFIX_PATH=%s' % self.CMAKE_BIN_DIR] + + for key in invoke_defines: + newdef = ''.join(['-D', key, '=', invoke_defines[key]]) + flags += [newdef] + + flags += [cmake_path] + self.check_create_dir(out_path) + + self.check_call([cmake_bin_path] + flags, cwd=out_path, env=env) + + @staticmethod + def logger(): + """Returns the module level logger.""" + return logging.getLogger(__name__) + + @staticmethod + def get_clang_version(llvm_install): + version_file = os.path.join(llvm_install, 'include', 'clang', 'Basic', + 'Version.inc') + return ClangVersion(version_file) + + def check_create_dir(self, path): + if not os.path.exists(path): + """Proxy for os.makedirs with logging and dry-run support.""" + self.logger().info('makedirs %s', path) + os.makedirs(path) + + def check_rm_tree(self, tree_dir): + """Removes directory tree.""" + def chmod_and_retry(func, path, _): + if not os.access(path, os.W_OK): + os.chmod(path, stat.S_IWUSR) + return func(path) + raise IOError("rmtree on %s failed" % path) + + if os.path.exists(tree_dir): + self.logger().info('shutil rmtree %s', tree_dir) + shutil.rmtree(tree_dir, onerror=chmod_and_retry) + + def check_copy_tree(self, src_dir, dst_dir): + self.check_rm_tree(dst_dir) + """Proxy for shutil.copytree with logging and dry-run support.""" + self.logger().info('copytree %s %s', src_dir, dst_dir) + shutil.copytree(src_dir, dst_dir, symlinks=True) + + def check_copy_file(self, src_file, dst_file): + if os.path.exists(src_file): + """Proxy for shutil.copy2 with logging and dry-run support.""" + self.logger().info('copy %s %s', src_file, dst_file) + shutil.copy2(src_file, dst_file) + + def check_call(self, cmd, *args, **kwargs): + """subprocess.check_call with logging.""" + self.logger().info('check_call:%s %s', + datetime.datetime.now().strftime("%H:%M:%S"), subprocess.list2cmdline(cmd)) + + subprocess.check_call(cmd, *args, **kwargs) + + def merge_out_path(self, *args): + return os.path.abspath(os.path.join(self.build_config.OUT_PATH, *args)) + + @staticmethod + def use_platform(): + sysstr = platform.system().lower() + arch = platform.machine() + return "%s-%s" % (sysstr, arch) + + def platform_prefix(self): + prefix = self.use_platform() + if (prefix.endswith('x86_64')): + return prefix[:-3] + return prefix + + def host_is_linux(self): + return self.use_platform().startswith('linux-') + + def host_is_darwin(self): + return self.use_platform().startswith('darwin-') + + def rm_cmake_cache(self, cache_dir): + for dirpath, dirs, files in os.walk(cache_dir): + if 'CMakeCache.txt' in files: + self.logger().info('rm CMakeCache.txt on %s', cache_dir) + os.remove(os.path.join(dirpath, 'CMakeCache.txt')) + if 'CMakeFiles' in dirs: + self.logger().info('rm CMakeFiles on %s', cache_dir) + self.check_rm_tree(os.path.join(dirpath, 'CMakeFiles')) + + @staticmethod + def find_program(name): + # FIXME: Do we need Windows support here? + return os.popen('which ' + name).read().strip() + + # Base cmake options such as build type that are common across all invocations + def base_cmake_defines(self): + mac_min_version = '10.9' + defines = {} + + defines['CMAKE_BUILD_TYPE'] = 'Release' + defines['LLVM_ENABLE_ASSERTIONS'] = 'OFF' + defines['LLVM_ENABLE_TERMINFO'] = 'OFF' + defines['LLVM_ENABLE_THREADS'] = 'ON' + defines['LLVM_USE_NEWPM'] = 'ON' + defines['LLVM_ENABLE_BINDINGS'] = 'OFF' + defines['CLANG_REPOSITORY_STRING'] = 'llvm-project' + + if self.host_is_darwin(): + defines['CMAKE_OSX_DEPLOYMENT_TARGET'] = mac_min_version + defines['LLDB_INCLUDE_TESTS'] = 'OFF' + defines['LIBCXX_INCLUDE_TESTS'] = 'OFF' + + defines['COMPILER_RT_BUILD_XRAY'] = 'OFF' + return defines + + +class LlvmCore(BuildUtils): + + def __init__(self, build_config): + super(LlvmCore, self).__init__(build_config) + + def build_llvm(self, + targets, + build_dir, + install_dir, + build_name, + extra_defines=None, + extra_env=None): + + common_defines = self.base_cmake_defines() + common_defines['CMAKE_INSTALL_PREFIX'] = install_dir + common_defines['LLVM_INSTALL_UTILS'] = 'ON' + common_defines['LLVM_TARGETS_TO_BUILD'] = targets + common_defines['LLVM_BUILD_LLVM_DYLIB'] = 'ON' + + build_number = '' + if re.match(r'\d+-.\D*$', build_name): + build_number, build_name = build_name.split('-', 1) + elif re.match(r'^\d+$', build_name): + build_number = build_name + build_name = '' + elif re.match(r'^\D+$', build_name): + build_name = build_name + else: + raise Exception('Warning! Build name is invalid, because it must not contain digits. ' + 'If you want to pass digit version, please, use follow template: {NUMBER}-{SUFFIX} ' + 'or just pass number. Otherwise unit tests will fail with assertions') + + common_defines['CLANG_VENDOR'] = 'OHOS (%s) ' % build_name + common_defines['CLANG_VENDOR_BUILD_VERSION'] = build_number + common_defines.update(extra_defines) + + env = dict(self.build_config.ORIG_ENV) + if extra_env is not None: + env.update(extra_env) + + llvm_project_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'llvm')) + + self.invoke_cmake(llvm_project_path, + build_dir, + common_defines, + env=env) + + self.invoke_ninja(out_path=build_dir, + env=env, + target=None, + install=True) + + + def llvm_compile_darwin_defines(self, llvm_defines): + if self.host_is_darwin(): + llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + llvm_defines['LLDB_NO_DEBUGSERVER'] = 'ON' + llvm_defines['LLDB_ENABLE_PYTHON'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + llvm_defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON' + + def llvm_compile_linux_defines(self, + llvm_defines, + debug_build=False, + no_lto=False, + build_instrumented=False): + if self.host_is_linux(): + llvm_defines['LLVM_ENABLE_LLD'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + llvm_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + llvm_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF' + llvm_defines['LIBCXX_USE_COMPILER_RT'] = 'ON' + llvm_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + llvm_defines['LIBCXXABI_ENABLE_STATIC_UNWINDER'] = 'ON' + llvm_defines['LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY'] = 'YES' + llvm_defines['LIBCXXABI_USE_COMPILER_RT'] = 'ON' + llvm_defines['COMPILER_RT_USE_LLVM_UNWINDER'] = 'ON' + llvm_defines['COMPILER_RT_ENABLE_STATIC_UNWINDER'] = 'ON' + llvm_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_ORC'] = 'OFF' + llvm_defines['LIBUNWIND_USE_COMPILER_RT'] = 'ON' + llvm_defines['LLVM_BINUTILS_INCDIR'] = '/usr/include' + + + if not build_instrumented and not no_lto and not debug_build: + llvm_defines['LLVM_ENABLE_LTO'] = 'Thin' + + @staticmethod + def llvm_compile_llvm_defines(llvm_defines, llvm_cc, llvm_cxx, cflags, ldflags): + llvm_defines['LLVM_ENABLE_PROJECTS'] = 'clang;lld;clang-tools-extra;openmp;lldb' + llvm_defines['LLVM_ENABLE_RUNTIMES'] = 'libunwind;libcxxabi;libcxx;compiler-rt' + llvm_defines['LLVM_ENABLE_BINDINGS'] = 'OFF' + llvm_defines['CMAKE_C_COMPILER'] = llvm_cc + llvm_defines['CMAKE_CXX_COMPILER'] = llvm_cxx + llvm_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + llvm_defines['SANITIZER_ALLOW_CXXABI'] = 'OFF' + llvm_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + llvm_defines['OPENMP_TEST_FLAGS'] = '-Wl,-ldl' + llvm_defines['CLANG_BUILD_EXAMPLES'] = 'OFF' + llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + llvm_defines['LLDB_ENABLE_PYTHON'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + llvm_defines['COMPILER_RT_BUILD_MEMPROF'] = 'OFF' + llvm_defines['CMAKE_ASM_FLAGS'] = cflags + llvm_defines['CMAKE_C_FLAGS'] = cflags + llvm_defines['CMAKE_CXX_FLAGS'] = '%s -stdlib=libc++' % cflags + llvm_defines['CMAKE_EXE_LINKER_FLAGS'] = ldflags + llvm_defines['CMAKE_SHARED_LINKER_FLAGS'] = ldflags + llvm_defines['CMAKE_MODULE_LINKER_FLAGS'] = ldflags + + def llvm_compile(self, + build_name, + out_dir, + debug_build=False, + no_lto=False, + build_instrumented=False, + xunit_xml_output=None): + + llvm_clang_install = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'prebuilts/clang/ohos', self.use_platform(), + 'clang-%s' % self.build_config.CLANG_VERSION)) + llvm_path = self.merge_out_path('llvm_make') + llvm_cc = os.path.join(llvm_clang_install, 'bin', 'clang') + llvm_cxx = os.path.join(llvm_clang_install, 'bin', 'clang++') + llvm_profdata = os.path.join(llvm_clang_install, 'bin', 'llvm-profdata') + + if self.host_is_darwin(): + ldflags = '' + else: + ldflags = '-fuse-ld=lld' + ldflags = '%s -L%s' % (ldflags, os.path.join(llvm_clang_install, 'lib')) + + llvm_extra_env = {} + llvm_extra_env['LD_LIBRARY_PATH'] = os.path.join(llvm_clang_install, 'lib') + + llvm_defines = {} + + self.llvm_compile_darwin_defines(llvm_defines) + self.llvm_compile_linux_defines(llvm_defines, debug_build, no_lto, build_instrumented) + + if self.host_is_linux(): + ldflags += ' -l:libunwind.a -l:libc++abi.a --rtlib=compiler-rt -stdlib=libc++ -static-libstdc++' + + if xunit_xml_output: + llvm_defines['LLVM_LIT_ARGS'] = "--xunit-xml-output={} -sv".format(xunit_xml_output) + + if self.build_config.enable_assertions: + llvm_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + if debug_build: + llvm_defines['CMAKE_BUILD_TYPE'] = 'Debug' + + if build_instrumented: + llvm_defines['LLVM_BUILD_INSTRUMENTED'] = 'ON' + llvm_defines['LLVM_PROFDATA'] = llvm_profdata + + resource_dir = "lib/clang/10.0.1/lib/linux/libclang_rt.profile-x86_64.a" + ldflags += ' %s' % os.path.join(llvm_clang_install, resource_dir) + + cflags = '-fstack-protector-strong -fPIE' + if not self.host_is_darwin(): + ldflags += ' -Wl,-z,relro,-z,now -pie -s' + + self.llvm_compile_llvm_defines(llvm_defines, llvm_cc, llvm_cxx, cflags, ldflags) + + linker_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts', 'clang', + 'ohos', 'linux-x86_64', 'llvm', 'bin', 'ld.lld')) + llvm_defines['CMAKE_LINKER'] = linker_path + + self.build_llvm(targets=self.build_config.TARGETS, + build_dir=llvm_path, + install_dir=out_dir, + build_name=build_name, + extra_defines=llvm_defines, + extra_env=llvm_extra_env) + + def llvm_compile_windows_defines(self, + windows_defines, + cc, + cxx, + windows_sysroot): + + if self.build_config.enable_assertions: + + windows_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' + win_sysroot = self.merge_out_path('mingw', 'x86_64-w64-mingw32') + windows_defines['LLDB_ENABLE_PYTHON'] = 'ON' + windows_defines['LLDB_PYTHON_HOME'] = 'python' + windows_defines['LLDB_PYTHON_RELATIVE_PATH'] = + 'bin/python/lib/python%s' % (self.build_config.LLDB_PY_VERSION) + windows_defines['LLDB_PYTHON_EXE_RELATIVE_PATH'] = 'bin/python' + windows_defines['LLDB_PYTHON_EXT_SUFFIX'] = '.pys' + windows_defines['PYTHON_INCLUDE_DIRS'] = os.path.join(win_sysroot, + 'include', 'python%s' % self.build_config.LLDB_PY_VERSION) + windows_defines['PYTHON_LIBRARIES'] = os.path.join(win_sysroot, 'lib', 'libpython%s.dll.a' + % self.build_config.LLDB_PY_VERSION) + windows_defines['SWIG_EXECUTABLE'] = self.find_program('swig') + windows_defines['PYTHON_EXECUTABLE'] = self.find_program('python3') + + windows_defines['CMAKE_C_COMPILER'] = cc + windows_defines['CMAKE_CXX_COMPILER'] = cxx + windows_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + windows_defines['CMAKE_BUILD_TYPE'] = 'Release' + windows_defines['LLVM_BUILD_RUNTIME'] = 'OFF' + windows_defines['LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD'] = 'ON' + windows_defines['LLVM_TOOL_OPENMP_BUILD'] = 'OFF' + windows_defines['LLVM_INCLUDE_TESTS'] = 'OFF' + windows_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + windows_defines['LLVM_ENABLE_PROJECTS'] = 'clang;clang-tools-extra;lld;lldb' + windows_defines['LLVM_BUILD_LLVM_DYLIB'] = 'OFF' + windows_defines['CLANG_BUILD_EXAMPLES'] = 'OFF' + windows_defines['CMAKE_SYSROOT'] = windows_sysroot + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + windows_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' + + def llvm_compile_windows_flags(self, + windows_defines, + compiler_rt_path, + windowstool_path, + windows64_install, + ldflags, + cflags): + + windows_defines['CROSS_TOOLCHAIN_FLAGS_NATIVE'] = ';'.join([ + '-DCMAKE_PREFIX_PATH=%s' % self.CMAKE_BIN_DIR, + '-DCOMPILER_RT_BUILD_LIBFUZZER=OFF', + '-DLLVM_ENABLE_LIBCXX=ON', + '-DCMAKE_BUILD_WITH_INSTALL_RPATH=TRUE', + '-DCMAKE_INSTALL_RPATH=%s' % os.path.join(windowstool_path, 'lib')] + ) + + ldflag = ['-fuse-ld=lld', + '-stdlib=libc++', + '--rtlib=compiler-rt', + '-lunwind', '-Wl,--dynamicbase', + '-Wl,--nxcompat', + '-lucrt', + '-lucrtbase', + '-L', + os.path.join(windows64_install, 'lib'), + '-Wl,--high-entropy-va'] + ldflags.extend(ldflag) + + cflag = ['-stdlib=libc++', + '--target=x86_64-pc-windows-gnu', + '-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-D_WIN32_WINNT=0x0600', + '-DWINVER=0x0600', + '-D__MSVCRT_VERSION__=0x1400', + '-DMS_WIN64'] + cflags.extend(cflag) + + def llvm_compile_windows_cmake(self, + cflags, + cxxflags, + ldflags, + windows_defines): + + + zlib_path = self.merge_out_path('../', 'prebuilts', 'clang', 'host', 'windows-x86', 'toolchain-prebuilts', + 'zlib') + zlib_inc = os.path.join(zlib_path, 'include') + zlib_lib = os.path.join(zlib_path, 'lib') + + cflags.extend(['-I', zlib_inc]) + cxxflags.extend(['-I', zlib_inc]) + ldflags.extend(['-L', zlib_lib]) + + windows_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + windows_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + windows_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + windows_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + windows_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + windows_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + + def llvm_compile_for_windows(self, + targets, + enable_assertions, + build_name): + + self.logger().info('Building llvm for windows.') + + build_dir = self.merge_out_path("windows-x86_64") + windowstool_path = self.merge_out_path('llvm-install') + windows64_install = self.merge_out_path('windows-x86_64-install') + windows_sysroot = self.merge_out_path('mingw', 'x86_64-w64-mingw32') + + self.check_create_dir(build_dir) + + # Write a NATIVE.cmake in windows_path that contains the compilers used + # to build native tools such as llvm-tblgen and llvm-config. This is + # used below via the CMake variable CROSS_TOOLCHAIN_FLAGS_NATIVE. + cc = os.path.join(windowstool_path, 'bin', 'clang') + cxx = os.path.join(windowstool_path, 'bin', 'clang++') + + # Extra cmake defines to use while building for Windows + windows_defines = {} + self.llvm_compile_windows_defines(windows_defines, cc, cxx, windows_sysroot) + + # Set CMake path, toolchain file for native compilation (to build tablegen + # etc). Also disable libfuzzer build during native compilation. + + ldflags = [] + cflags = [] + + self.llvm_compile_windows_flags(windows_defines, compiler_rt_path, + windowstool_path, windows64_install, ldflags, cflags) + + cxxflags = list(cflags) + + windows_extra_env = dict() + + cxxflags.append('-fuse-cxa-atexit') + cxxflags.extend(('-I', os.path.join(windows64_install, 'include', 'c++', 'v1'))) + + self.llvm_compile_windows_cmake(cflags, cxxflags, ldflags, windows_defines) + + self.build_llvm(self.build_config.TARGETS, + build_dir, + windows64_install, + build_name, + extra_defines=windows_defines, + extra_env=windows_extra_env) + + +class SysrootComposer(BuildUtils): + + def __init__(self, build_config): + super(SysrootComposer, self).__init__(build_config) + + def setup_cmake_platform(self, llvm_install): + + # OHOS.cmake already exsit on cmake prebuilts, + # but it didn't contain these two lines, so we still need OHOS.cmake. + ohos_cmake = 'OHOS.cmake' + dst_dir = self.merge_out_path( + '../prebuilts/cmake/%s/share/cmake-3.16/Modules/Platform' % self.platform_prefix()) + src_file = '%s/%s' % (self.build_config.CURRENT_DIR, ohos_cmake) + if os.path.exists(os.path.join(dst_dir, ohos_cmake)): + os.remove(os.path.join(dst_dir, ohos_cmake)) + shutil.copy2(src_file, dst_dir) + + + def build_musl(self, llvm_install, target, *extra_args): + cur_dir = os.getcwd() + os.chdir(self.build_config.CURRENT_DIR) + self.logger().info('build musl %s', self.merge_out_path('install')) + args = ['./build_musl.sh', '-t', target, '-c', + self.merge_out_path(llvm_install, 'bin'), '-o', self.merge_out_path()] + list(extra_args) + self.check_call(args) + os.chdir(cur_dir) + + def install_linux_headers(self, arch, target): + dir_suffix = arch + if arch == 'x86_64': + dir_suffix = 'x86' + elif arch == 'mipsel': + dir_suffix = 'mips' + linux_kernel_dir = os.path.join('kernel_linux_patches', 'linux-5.10') + linux_kernel_path = os.path.join(self.build_config.OUT_PATH, '..', linux_kernel_dir) + ohosmusl_sysroot_dst = self.merge_out_path('sysroot', target, 'usr') + headers_tmp_dir = os.path.join(linux_kernel_path, 'prebuilts', 'usr', 'include') + self.check_copy_tree(os.path.join(headers_tmp_dir, 'linux'), + os.path.join(ohosmusl_sysroot_dst, 'include/linux')) + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-%s' % dir_suffix,'asm'), + os.path.join(ohosmusl_sysroot_dst, 'include', 'asm')) + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-generic'), + os.path.join(ohosmusl_sysroot_dst, 'include/asm-generic')) + + def copy_libz_to_sysroot(self, libz_path, llvm_triple): + # Install to sysroot + dest_usr = self.merge_out_path('sysroot', llvm_triple, 'usr') + dest_usr_include = os.path.join(dest_usr, 'include') + + # Copy over usr/include. + zlib_h = self.merge_out_path('../third_party/zlib', 'zlib.h') + self.check_copy_file(zlib_h, dest_usr_include) + + zconf_h = os.path.join(libz_path, 'zconf.h') + self.check_copy_file(zconf_h, dest_usr_include) + + # Copy over usr/lib. + dest_usr_lib = os.path.join(dest_usr, 'lib') + static_zlib = os.path.join(libz_path, 'libz.a') + self.check_copy_file(static_zlib, dest_usr_lib) + + +class LlvmLibs(BuildUtils): + + def __init__(self, build_config, sysroot_composer, llvm_package): + super(LlvmLibs, self).__init__(build_config) + self.sysroot_composer = sysroot_composer + self.llvm_package = llvm_package + + def build_crt_libs(self, configs, llvm_install, need_lldb_server): + for (arch, target) in configs: + self.sysroot_composer.build_musl(llvm_install, target) + if target.endswith(self.build_config.OPENHOS_SFX): + self.sysroot_composer.install_linux_headers(arch, target) + self.build_libs(need_lldb_server, + llvm_install, + target, + precompilation=True) + self.sysroot_composer.build_musl(llvm_install, target, '-l') + + def build_libs_defines(self, + llvm_triple, + defines, + cc, + cxx, + ar, + llvm_config, + ldflags, + cflags, + extra_flags): + + sysroot = self.merge_out_path('sysroot') + + defines['CMAKE_C_COMPILER'] = cc + defines['CMAKE_CXX_COMPILER'] = cxx + defines['CMAKE_AR'] = ar + defines['LLVM_CONFIG_PATH'] = llvm_config + defines['CMAKE_SYSROOT'] = sysroot + defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + ldflag = [ + '-fuse-ld=lld', + '-Wl,--gc-sections', + '-Wl,--build-id=sha1', + '--rtlib=compiler-rt', + '-stdlib=libc++', ] + + if not self.host_is_darwin(): + ldflag.append('-Wl,-z,relro,-z,now -s -pie') + + ldflags.extend(ldflag) + + cflag = [ + '-fstack-protector-strong', + '-fPIE', + '--target=%s' % llvm_triple, + '-ffunction-sections', + '-fdata-sections', + extra_flags, ] + + cflags.extend(cflag) + + def build_libs(self, need_lldb_server, llvm_install, llvm_build, precompilation=False): + configs_list = [ + ('arm', self.liteos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.liteos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.liteos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), + ('arm', self.liteos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), + + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.open_ohos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), + ('arm', self.open_ohos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), + ('aarch64', self.open_ohos_triple('aarch64'), '', ''), + ('riscv64', self.open_ohos_triple('riscv64'), '', ''), + ('mipsel', self.open_ohos_triple('mipsel'), '-march=mips32r2', ''), + ('x86_64', self.open_ohos_triple('x86_64'), '', ''),] + + cc = os.path.join(llvm_install, 'bin', 'clang') + cxx = os.path.join(llvm_install, 'bin', 'clang++') + ar = os.path.join(llvm_install, 'bin', 'llvm-ar') + llvm_config = os.path.join(llvm_install, 'bin', 'llvm-config') + seen_arch_list = [self.liteos_triple('arm')] + + self.set_clang_version(llvm_install) + for (arch, llvm_triple, extra_flags, multilib_suffix) in configs_list: + if llvm_build != llvm_triple: + continue + + has_lldb_server = arch not in ['riscv64'] + + defines = {} + ldflags = [] + cflags = [] + self.logger().info('Build libs for %s', llvm_triple) + self.build_libs_defines(llvm_triple, defines, cc, cxx, ar, llvm_config, ldflags, cflags, extra_flags) + if arch == 'mipsel': + ldflags.append('-Wl,-z,notext') + + llvm_path = self.merge_out_path('llvm_make') + arch_list = [self.liteos_triple('arm'), self.open_ohos_triple('arm'), + self.open_ohos_triple('aarch64'), self.open_ohos_triple('riscv64'), + self.open_ohos_triple('mipsel'), self.open_ohos_triple('x86_64')] + if precompilation: + self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + continue + # libunwind is added to linker command line by OHOS toolchain, so we have to use two step build + self.build_runtimes(llvm_install, "libunwind", ldflags, cflags, llvm_triple, arch, multilib_suffix, defines) + self.build_runtimes(llvm_install, "libunwind;libcxxabi;libcxx", ldflags, cflags, llvm_triple, arch, multilib_suffix, defines) + self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines, + first_time=False) + + if llvm_triple in arch_list: + if need_lldb_server and has_lldb_server and llvm_triple not in seen_arch_list: + self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, + defines) + seen_arch_list.append(llvm_triple) + continue + + self.build_libomp(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + self.build_libz(arch, llvm_triple, cflags, ldflags, defines) + if need_lldb_server and has_lldb_server and llvm_triple not in seen_arch_list: + self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, defines) + seen_arch_list.append(llvm_triple) + + def build_runtimes(self, + llvm_install, + rt_list, + ldflags, + cflags, + llvm_triple, + arch, + multilib_suffix, + defines): + + self.logger().info('Building runtimes(%s) for %s', (rt_list, arch)) + + out_path = self.merge_out_path('lib', rt_list.replace(';', '-') + '-' + str(llvm_triple)) + + rt_cflags = list(cflags) + rt_cflags.append('-fstack-protector-strong') + + rt_defines = defines.copy() + rt_defines['OHOS'] = '1' + rt_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + rt_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + rt_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + rt_defines['LLVM_ENABLE_RUNTIMES'] = rt_list + rt_defines['LIBUNWIND_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBUNWIND_ENABLE_SHARED'] = 'OFF' + rt_defines['LIBCXXABI_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + rt_defines['LIBCXXABI_ENABLE_STATIC_UNWINDER'] = 'ON' + rt_defines['LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL'] = 'OFF' + rt_defines['LIBCXXABI_ENABLE_SHARED'] = 'OFF' + rt_defines['LIBCXXABI_LIBCXX_INCLUDES'] = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxx', 'include')) + rt_defines['LIBCXX_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBCXX_ABI_NAMESPACE'] = '__h' + rt_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF' + rt_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + rt_defines['CMAKE_ASM_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_C_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_CXX_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + rt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + rt_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + rt_defines['CMAKE_CROSSCOMPILING'] = 'True' + rt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + self.check_rm_tree(out_path) + cmake_rt = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'runtimes')) + + self.invoke_cmake(cmake_rt, + out_path, + rt_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=out_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_crts(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines, + first_time=True): + + self.logger().info('Building compiler-rt for %s', arch) + + suffix = '-' + multilib_suffix if multilib_suffix else '' + crt_path = self.merge_out_path('lib', 'clangrt-%s%s' % (llvm_triple, suffix)) + crt_install = os.path.join(llvm_install, 'lib', 'clang', self.build_config.VERSION) + + crt_extra_flags = [] + if not self.build_config.debug: + # Remove absolute paths from compiler-rt debug info emitted with -gline-tables-only + crt_extra_flags = ['-ffile-prefix-map=%s=.' % self.build_config.REPOROOT_DIR] + + crt_defines = defines.copy() + crt_defines.update(self.base_cmake_defines()) + crt_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags) + crt_defines['OHOS'] = '1' + crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = llvm_triple + crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'ON' + crt_defines['CMAKE_INSTALL_PREFIX'] = crt_install + crt_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + if first_time or llvm_triple == self.liteos_triple('arm'): + crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + else: + crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + crt_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + crt_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + crt_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + crt_defines['CMAKE_CROSSCOMPILING'] = 'True' + crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi' + crt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + crt_defines['COMPILER_RT_HWASAN_WITH_INTERCEPTORS'] = 'OFF' + crt_defines['COMPILER_RT_BUILD_ORC'] = 'OFF' + crt_defines['COMPILER_RT_USE_LLVM_UNWINDER'] = 'ON' + + crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = + 'OFF' if llvm_triple == self.liteos_triple('arm') or first_time else 'ON' + crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = llvm_triple + crt_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'compiler-rt')) + self.rm_cmake_cache(crt_path) + + self.invoke_cmake(crt_cmake_path, + crt_path, + crt_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=crt_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libomp(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines): + + self.logger().info('Building libomp for %s', arch) + + libomp_path = self.merge_out_path('lib', 'libomp-%s' % llvm_triple) + out_dir = os.path.join(libomp_path, 'lib') + + libomp_cflags = list(cflags) + libomp_cflags.append('-fPIC') + + libomp_defines = defines.copy() + libomp_defines.update(self.base_cmake_defines()) + libomp_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libomp_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libomp_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + libomp_defines['OHOS'] = '1' + libomp_defines['CMAKE_ASM_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['CMAKE_C_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['CMAKE_CXX_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['OPENMP_ENABLE_LIBOMPTARGET'] = 'FALSE' + + libomp_defines['OPENMP_LIBDIR_SUFFIX'] = os.path.join(os.sep, llvm_triple, multilib_suffix) + libomp_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + libomp_defines['CMAKE_POLICY_DEFAULT_CMP0056'] = 'NEW' + libomp_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + libomp_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + libomp_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + libomp_defines['CMAKE_CROSSCOMPILING'] = 'True' + libomp_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + libomp_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + libomp_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'openmp') + self.rm_cmake_cache(libomp_path) + + self.invoke_cmake(libomp_cmake_path, + libomp_path, + libomp_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libomp_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libz(self, + arch, + llvm_triple, + cflags, + ldflags, + defines): + + self.logger().info('Building libz for %s ', arch) + + libz_path = self.merge_out_path('lib', 'libz-%s' % llvm_triple) + if llvm_triple == self.hos_triple('arm'): + ldflags.append('-lunwind') + + libz_cflags = list(cflags) + libz_cflags.append('-fPIC') + + libz_defines = defines.copy() + libz_defines.update(self.base_cmake_defines()) + libz_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['OHOS'] = '1' + libz_defines['CMAKE_ASM_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_C_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_CXX_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + libz_cmake_path = os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib') + self.rm_cmake_cache(libz_path) + + self.invoke_cmake(libz_cmake_path, + libz_path, + libz_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libz_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=False) + + self.sysroot_composer.copy_libz_to_sysroot(libz_path, llvm_triple) + + def build_lldb_server(self, + llvm_install, + llvm_path, + arch, + llvm_triple, + cflags, + ldflags, + defines): + + self.logger().info('Building lldb for %s', arch) + + lldb_path = self.merge_out_path('lib', 'lldb-server-%s' % llvm_triple) + crt_install = os.path.join(llvm_install, 'lib', 'clang', self.build_config.VERSION) + out_dir = os.path.join(lldb_path, 'bin') + + lldb_ldflags = list(ldflags) + lldb_cflags = list(cflags) + + lldb_ldflags.append('-lunwind') + lldb_ldflags.append('-static') + + lldb_defines = defines.copy() + lldb_defines.update(self.base_cmake_defines()) + + lldb_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + lldb_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + lldb_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + + lldb_defines['OHOS'] = '1' + lldb_defines['CMAKE_C_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_ASM_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_CXX_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_INSTALL_PREFIX'] = crt_install + lldb_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + lldb_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + lldb_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + lldb_defines['CMAKE_CROSSCOMPILING'] = 'True' + lldb_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + lldb_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_defines['LLVM_ENABLE_PROJECTS'] = 'clang;lldb' + lldb_defines['LLVM_TABLEGEN'] = os.path.join(llvm_install, 'bin', 'llvm-tblgen') + lldb_defines['CLANG_TABLEGEN'] = os.path.join(llvm_install, '..', llvm_path, 'bin', 'clang-tblgen') + lldb_defines['LLDB_TABLEGEN'] = os.path.join(llvm_install, '..', llvm_path, 'bin', 'lldb-tblgen') + lldb_defines['LLVM_HOST_TRIPLE'] = llvm_triple + lldb_defines['LLVM_TARGET_ARCH'] = arch + lldb_defines['LLVM_TARGETS_TO_BUILD'] = self.build_config.TARGETS + + lldb_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'llvm') + + self.invoke_cmake(lldb_cmake_path, + lldb_path, + lldb_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=lldb_path, + env=dict(self.build_config.ORIG_ENV), + target='lldb-server', + install=False) + + self.llvm_package.copy_lldb_server_to_llvm_install(lldb_path, crt_install, llvm_triple) + + @staticmethod + def build_libs_windows_cmake_defines(cmake_defines, toolchain_dir, windows_sysroot): + cmake_defines['CMAKE_C_COMPILER_WORKS'] = '1' + cmake_defines['CMAKE_CXX_COMPILER_WORKS'] = '1' + cmake_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + cmake_defines['CMAKE_SYSTEM_PROCESSOR'] = 'x86_64' + cmake_defines['CMAKE_C_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang') + cmake_defines['CMAKE_CXX_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang++') + cmake_defines['LLVM_CONFIG_PATH'] = os.path.join(toolchain_dir, 'bin', 'llvm-config') + cmake_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + cmake_defines['CMAKE_SYSROOT'] = windows_sysroot + cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + + def build_runtimes_for_windows(self, enable_assertions): + + self.logger().info('Building libs for windows.') + toolchain_dir = self.merge_out_path('llvm-install') + install_dir = self.merge_out_path('windows-x86_64-install') + windows_sysroot = self.merge_out_path('mingw', 'x86_64-w64-mingw32') + + cflags = ['-stdlib=libc++', '--target=x86_64-pc-windows-gnu', '-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', '-D_WIN32_WINNT=0x0600', '-DWINVER=0x0600', '-D__MSVCRT_VERSION__=0x1400'] + + cmake_defines = {} + self.build_libs_windows_cmake_defines(cmake_defines, toolchain_dir, windows_sysroot) + + cmake_defines['CMAKE_CROSSCOMPILING'] = 'True' + cmake_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + cmake_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + cmake_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + cmake_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + out_path = self.merge_out_path('lib', 'windows-runtimes') + cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'runtimes')) + + self.invoke_cmake(cmake_path, + out_path, + cmake_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path, + env=dict(self.build_config.ORIG_ENV), + install=True) + + + +class LldbMi(BuildUtils): + + def __init__(self, build_config, llvm_package): + super(LldbMi, self).__init__(build_config) + self.llvm_package = llvm_package + + def build_lldb_mi(self, llvm_install): + self.logger().info('Building lldb-mi for linux.') + + llvm_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'prebuilts/clang/ohos', self.use_platform(), 'clang-%s' % self.build_config.CLANG_VERSION)) + lldb_mi_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi') + lldb_mi_path = self.merge_out_path('lldb_mi_build') + + self.check_rm_tree(lldb_mi_path) + self.rm_cmake_cache(lldb_mi_path) + + if self.host_is_darwin(): + cflags = [] + cxxflags =[] + ldflags = ['-Wl,-rpath,%s' % '@loader_path/../lib'] + else: + cflags = [] + cxxflags =[] + ldflags = ['-fuse-ld=lld', '-Wl,-rpath,%s' % '\$ORIGIN/../lib'] + ldflags.append('-Wl,-z,relro,-z,now -pie -s') + + ldflags.append('-L%s' % os.path.join(llvm_path, 'lib')) + cxxflags.append('-std=c++14') + cxxflags.append('-fstack-protector-strong -fPIE') + cflags.append('-fstack-protector-strong -fPIE') + + lldb_mi_defines = {} + lldb_mi_defines['CMAKE_C_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang') + lldb_mi_defines['CMAKE_CXX_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang++') + lldb_mi_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + lldb_mi_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + lldb_mi_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['LLVM_DIR'] = os.path.join(llvm_install, 'lib/cmake/llvm/') + lldb_mi_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_mi_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + + self.invoke_cmake(lldb_mi_cmake_path, + lldb_mi_path, + lldb_mi_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(lldb_mi_path, + env=dict(self.build_config.ORIG_ENV), + install=False) + + self.llvm_package.copy_lldb_mi_to_llvm_install(lldb_mi_path, llvm_install) + + @staticmethod + def ldflags_lists_define(): + ldflags_lists = ['-Wl,--dynamicbase', + '-Wl,--nxcompat', + '-lucrt', + '-lucrtbase', + '-lpthread', + '-L', ] + return ldflags_lists + + @staticmethod + def cflags_lists_define(): + cflags_lists = ['-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-D_WIN32_WINNT=0x0600', + '-DWINVER=0x0600', + '-D__MSVCRT_VERSION__=0x1400', + '-DMS_WIN64', ] + return cflags_lists + + # Extra cmake defines to use while building for Windows + def lldb_mi_windefines_dictionary(self, cc, cxx, windows_sysroot, cflags, cxxflags, ldflags): + lldb_mi_windefines = {} + lldb_mi_windefines['CMAKE_C_COMPILER'] = cc + lldb_mi_windefines['CMAKE_CXX_COMPILER'] = cxx + lldb_mi_windefines['CMAKE_C_COMPILER_WORKS'] = '1' + lldb_mi_windefines['CMAKE_CXX_COMPILER_WORKS'] = '1' + lldb_mi_windefines['CMAKE_SYSTEM_NAME'] = 'Windows' + lldb_mi_windefines['CMAKE_SYSTEM_PROCESSOR'] = 'x86_64' + lldb_mi_windefines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_mi_windefines['CMAKE_SYSROOT'] = windows_sysroot + lldb_mi_windefines['LLVM_INSTALL_PREFIX'] = self.merge_out_path('windows-x86_64-install') + lldb_mi_windefines['LLVM_DIR'] = self.merge_out_path('windows-x86_64-install/lib/cmake/llvm/') + lldb_mi_windefines['CMAKE_C_FLAGS'] = ' '.join(cflags) + lldb_mi_windefines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + lldb_mi_windefines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_windefines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_windefines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + if self.build_config.enable_assertions: + lldb_mi_windefines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + return lldb_mi_windefines + + + def build_lldb_mi_for_windows(self): + self.logger().info('Building lldb-mi for windows.') + + build_dir = self.merge_out_path('clang_mingw', 'clang-10.0.1') + lldb_mi_windows64_path = self.merge_out_path('windows-x86_64-lldb-mi') + lldb_mi_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi')) + windows64_install = self.merge_out_path('windows-x86_64-install') + cc = os.path.join(build_dir, 'bin', 'clang') + cxx = os.path.join(build_dir, 'bin', 'clang++') + + windows_sysroot = self.merge_out_path('mingw', 'x86_64-w64-mingw32') + self.check_create_dir(lldb_mi_windows64_path) + + ldflags = ['-fuse-ld=lld', + '--rtlib=compiler-rt', + '-lunwind', + '-L%s' % os.path.join(windows64_install, 'lib'), + ] + ldflags.extend(self.ldflags_lists_define()) + ldflags.append(os.path.join(windows64_install, 'lib')) + ldflags.append('-Wl,--high-entropy-va') + + + cflags = ['-stdlib=libc++', + '--target=x86_64-pc-windows-gnu', + ] + cflags.extend(self.cflags_lists_define()) + cflags.append('-fno-exceptions') + cflags.append('-fno-rtti') + + cxxflags = list(cflags) + cxxflags.extend(('-I', os.path.join(windows64_install, 'include', 'c++', 'v1'))) + + zlib_path = os.path.abspath( + os.path.join('../../', 'prebuilts', 'clang', 'host', 'windows-x86', 'toolchain-prebuilts', 'zlib')) + zlib_inc = os.path.join(zlib_path, 'include') + zlib_lib = os.path.join(zlib_path, 'lib') + + cflags.extend(['-I', zlib_inc]) + cxxflags.extend(['-I', zlib_inc]) + ldflags.extend(['-L', zlib_lib]) + + + lldb_mi_env = dict(self.build_config.ORIG_ENV) + lldb_mi_env['LD_LIBRARY_PATH'] = os.path.join(build_dir, 'lib') + self.rm_cmake_cache(lldb_mi_windows64_path) + + self.invoke_cmake(lldb_mi_cmake_path, + lldb_mi_windows64_path, + self.lldb_mi_windefines_dictionary(cc, cxx, windows_sysroot, cflags, cxxflags, ldflags), + env=lldb_mi_env) + + self.invoke_ninja(lldb_mi_windows64_path, + env=lldb_mi_env, + install=False) + + self.llvm_package.copy_lldb_mi_to_windows(windows64_install, lldb_mi_windows64_path) + + +class LlvmPackage(BuildUtils): + + def __init__(self, build_config): + super(LlvmPackage, self).__init__(build_config) + + def copy_lldb_server_to_llvm_install(self, lldb_path, crt_install, llvm_triple): + # Copy lldb-server + libname = 'lldb-server' + src_lib = os.path.join(lldb_path, 'bin', libname) + dst_dir = os.path.join(crt_install, 'bin', llvm_triple) + self.check_create_dir(dst_dir) + self.check_copy_file(src_lib, os.path.join(dst_dir, libname)) + + def copy_lldb_mi_to_llvm_install(self, lldb_mi_path, llvm_install): + # Copy lldb-mi + lldb_mi_dst = os.path.join(llvm_install, 'bin', 'lldb-mi') + lldb_mi_src = os.path.join(lldb_mi_path, 'src', 'lldb-mi') + + if os.path.exists(lldb_mi_dst): + os.remove(lldb_mi_dst) + self.check_copy_file(lldb_mi_src, lldb_mi_dst) + + def copy_lldb_mi_to_windows(self, windows64_install, lldb_mi_windows64_path): + # Copy lldb-mi for windows + lldb_mi_dst = os.path.join(windows64_install, 'bin', 'lldb-mi.exe') + lldb_mi_src = os.path.join(lldb_mi_windows64_path, 'src', 'lldb-mi.exe') + if os.path.exists(lldb_mi_dst): + os.remove(lldb_mi_dst) + self.check_copy_file(lldb_mi_src, lldb_mi_dst) + + def package_libcxx(self): + libcxx_ndk_install=self.merge_out_path('libcxx-ndk') + libcxx_ndk_install_include=self.merge_out_path(libcxx_ndk_install, 'include', 'libcxx-ohos', 'include', 'c++', 'v1') + hosts_list=['linux-x86_64', 'darwin-x86_64', 'windows-x86_64', 'darwin-arm64'] + + if os.path.exists(libcxx_ndk_install): + for headerfile in os.listdir(libcxx_ndk_install_include): + if not headerfile =='__config': + if os.path.isdir(os.path.join(libcxx_ndk_install_include, headerfile)): + shutil.rmtree(os.path.join(libcxx_ndk_install_include, headerfile)) + else: + os.remove(os.path.join(libcxx_ndk_install_include, headerfile)) + + #Package libcxx-ndk + for host in hosts_list: + tarball_name = 'libcxx-ndk-%s-%s' % (self.build_config.build_name, host) + package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + args = ['tar', '-chjC', self.build_config.OUT_PATH, '-f', package_path, 'libcxx-ndk'] + self.check_call(args) + self.check_rm_tree(libcxx_ndk_install) + + @staticmethod + def merge_tree(src_dir, dst_dir): + for item in os.listdir(src_dir): + src_path = os.path.join(src_dir, item) + dst_path = os.path.join(dst_dir, item) + if os.path.isfile(src_path): + shutil.copyfile(src_path, dst_path) + else: + shutil.copytree(src_path, dst_path) + + + def install_mingw_python(self, install_dir): + py_root = self.merge_out_path('../third_party', 'mingw-w64', 'mingw-w64-python', + self.build_config.LLDB_PY_VERSION) + bin_root = os.path.join(install_dir, 'bin') + py_dll = 'libpython' + self.build_config.LLDB_PY_VERSION + '.dll' + shutil.copyfile(os.path.join(py_root, py_dll), os.path.join(bin_root, py_dll)) + self.merge_tree(os.path.join(py_root, 'lib'), + os.path.join(bin_root, 'python', 'lib', 'python%s' % self.build_config.LLDB_PY_VERSION)) + + + + + + def windows_lib_files_operation(self, lib_files, lib_dir, install_dir): + + # Remove unnecessary Windows lib files. + windows_necessary_lib_files = ['libc++.a', 'libc++abi.a'] + + for lib_file in lib_files: + if lib_file.endswith('.a') and lib_file not in windows_necessary_lib_files: + static_library = os.path.join(lib_dir, lib_file) + os.remove(static_library) + + for necessary_lib_file in windows_necessary_lib_files: + if not os.path.isfile(os.path.join(lib_dir, necessary_lib_file)): + raise RuntimeError('Did not find %s under %s' % (necessary_lib_file, lib_dir)) + self.install_mingw_python(install_dir) + + + def darwin_stripped_xargs(self, bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin): + for bin_filename in os.listdir(bin_dir): + binary = os.path.join(bin_dir, bin_filename) + if not os.path.isfile(binary): + continue + if bin_filename not in necessary_bin_files: + os.remove(binary) + elif bin_filename not in script_bins: + if bin_filename not in need_x_bins_darwin and self.host_is_darwin(): + self.check_call(['strip', '-x', binary]) + else: + self.check_call(['strip', binary]) + + + def strip_lldb_server(self, host, install_dir): + clang_version_bin_dir = os.path.join(install_dir, 'lib', 'clang', self.build_config.CLANG_VERSION, 'bin') + + if not host.startswith('linux') or not os.path.exists(clang_version_bin_dir): + return + llvm_strip = os.path.join(install_dir, 'bin', 'llvm-strip') + for llvm_triple_dir in os.listdir(clang_version_bin_dir): + llvm_triple_bin_dir = os.path.join(clang_version_bin_dir, llvm_triple_dir) + + if not os.path.isdir(llvm_triple_bin_dir): + continue + + for bin_filename in os.listdir(llvm_triple_bin_dir): + binary = os.path.join(llvm_triple_bin_dir, bin_filename) + if os.path.isfile(binary): + self.check_call([llvm_strip, binary]) + + + def notice_prebuilts_file(self, host, projects, install_dir): + + # Fetch all the LICENSE.* files under our projects and append them into a + # Single NOTICE file for the resulting prebuilts. + notices = [] + for project in projects: + license_pattern = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, project, 'LICENSE.*')) + for license_file in glob.glob(license_pattern): + with open(license_file) as notice_file: + notices.append(notice_file.read()) + + zlib_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib/LICENSE')) + with open(zlib_license_file) as notice_file: + notices.append(notice_file.read()) + + if host.startswith('windows'): + mingw_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'third_party/mingw-w64/COPYING')) + with open(mingw_license_file) as notice_file: + notices.append(notice_file.read()) + + with open(os.path.join(install_dir, 'NOTICE'), 'w') as notice_file: + notice_file.write('\n'.join(notices)) + + + def package_clang_bin_file(self, necessary_bin_files, ext): + necessary_bin_file = [ + 'clang%s' % ext, + 'clang++%s' % ext, + 'clang-cpp%s' % ext, + 'clang-%s%s' % (self.build_config.VERSION.split('.')[0], ext), + 'clang-check%s' % ext, + 'clang-cl%s' % ext, + 'clang-format%s' % ext, + 'clang-tidy%s' % ext, + 'clangd%s' % ext, + 'count%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_lldb_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'dsymutil%s' % ext, + 'FileCheck%s' % ext, + 'git-clang-format', + 'ld.lld%s' % ext, + 'ld64.lld%s' % ext, + 'lld%s' % ext, + 'lld-link%s' % ext, + 'lldb%s' % ext, + 'lldb-argdumper%s' % ext, + 'lldb-server%s' % ext, + 'lldb-vscode%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_llvm_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'llvm-addr2line%s' % ext, + 'llvm-ar%s' % ext, + 'llvm-as%s' % ext, + 'llvm-cfi-verify%s' % ext, + 'llvm-config%s' % ext, + 'llvm-cov%s' % ext, + 'llvm-cxxfilt%s' % ext, + 'llvm-dis%s' % ext, + 'llvm-lib%s' % ext, + 'llvm-link%s' % ext, + 'llvm-modextract%s' % ext, + 'llvm-nm%s' % ext, + 'llvm-objcopy%s' % ext, + 'llvm-objdump%s' % ext, + 'llvm-profdata%s' % ext, + 'llvm-ranlib%s' % ext, + 'llvm-readelf%s' % ext, + 'llvm-readobj%s' % ext, + 'llvm-rc%s' % ext, + 'llvm-size%s' % ext, + 'llvm-strings%s' % ext, + 'llvm-strip%s' % ext, + 'llvm-symbolizer%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_scan_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'not%s' % ext, + 'sancov%s' % ext, + 'sanstats%s' % ext, + 'scan-build%s' % ext, + 'scan-view%s' % ext, + 'yaml2obj%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_license_project_tuple(): + # Install license files as NOTICE in the toolchain install dir. + projects = ( + 'llvm', + 'compiler-rt', + 'libcxx', + 'libcxxabi', + 'openmp', + 'clang', + 'clang-tools-extra', + 'lld', + 'lldb', + 'libunwind', + ) + return projects + + def remove_unnecessary_bin(self, necessary_bin_files, host, lib_dir, install_dir, ext, shlib_ext): + + lib_files = [] + if os.path.isdir(lib_dir): + lib_files = os.listdir(lib_dir) + if host.startswith('windows'): + vers_major = int(self.build_config.VERSION.split('.')[0]) + # Redefining necessary bin files for Windows. + windows_forbidden_list_bin_files = ['clang-%s%s' % (vers_major, ext), 'scan-build%s' % ext, + 'scan-view%s' % ext] + windows_additional_bin_files = ['liblldb%s' % shlib_ext, 'libpython3.10%s' % shlib_ext] + + new_necessary_bin_files = list(set(necessary_bin_files) - set(windows_forbidden_list_bin_files)) + new_necessary_bin_files.extend(windows_additional_bin_files) + del necessary_bin_files[:] + necessary_bin_files.extend(new_necessary_bin_files) + + self.windows_lib_files_operation(lib_files, lib_dir, install_dir) + else: + # Remove unnecessary static libraries. + for lib_file in lib_files: + if lib_file.endswith('.a'): + static_library = os.path.join(lib_dir, lib_file) + os.remove(static_library) + + def package_up_resulting(self, package_name, host, install_host_dir): + # Package up the resulting trimmed install/ directory. + tarball_name = '%s-%s' % (package_name, host) + package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + args = ['tar', '-cjC', install_host_dir, '-f', package_path, package_name] + if host.startswith('windows'): + # windows do not support symlinks, + # replace them with file copies + args.insert(1, '--dereference') + + self.check_call(args) + + # Package ohos NDK + if os.path.exists(self.merge_out_path('sysroot')): + tarball_ndk_name = 'ohos-sysroot-%s' % self.build_config.build_name + package_ndk_path = '%s%s' % (self.merge_out_path(tarball_ndk_name), '.tar.bz2') + self.logger().info('Packaging %s', package_ndk_path) + args = ['tar', '-chjC', self.build_config.OUT_PATH, '-f', package_ndk_path, 'sysroot'] + self.check_call(args) + + # Packing Operation. + + def package_operation(self, build_dir, host): + + self.logger().info('Packaging for other environments.') + package_name = 'clang-%s' % self.build_config.build_name + self.set_clang_version(build_dir) + + if host.startswith('windows'): + ext = '.exe' + shlib_ext = '.dll' + elif host.startswith('linux'): + ext = '' + shlib_ext = '.so' + else: + ext = '' + shlib_ext = '.dylib' + + install_dir = self.merge_out_path('install', host, package_name) + bin_dir = os.path.join(install_dir, 'bin') + lib_dir = os.path.join(install_dir, 'lib') + install_host_dir = os.path.abspath(os.path.join(install_dir, '../')) + self.check_rm_tree(install_host_dir) + self.check_copy_tree(build_dir, install_dir) + # copy readme file to install_dir + shutil.copyfile(os.path.join(self.build_config.CURRENT_DIR, "toolchain_readme.md"), + os.path.join(install_dir, "README.md")) + + # Remove unnecessary binaries. + necessary_bin_files = [] + self.package_clang_bin_file(necessary_bin_files, ext) + self.package_lldb_bin_file(necessary_bin_files, ext) + self.package_llvm_bin_file(necessary_bin_files, ext) + self.package_scan_bin_file(necessary_bin_files, ext) + + if self.build_config.need_lldb_mi: + necessary_bin_files.append('lldb-mi%s' % ext) + self.remove_unnecessary_bin(necessary_bin_files, host, lib_dir, install_dir, ext, shlib_ext) + + # Scripts that should not be stripped + script_bins = ['git-clang-format', 'scan-build', 'scan-view'] + need_x_bins_darwin = ['clang', 'clang++', 'clang-9', 'clang-cl', 'clang-cpp'] + + # Bin file in the list should be stripped with -x args when host=darwin + self.darwin_stripped_xargs(bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin) + + # Strip lldb-server + self.strip_lldb_server(host, install_dir) + + for necessary_bin_file in necessary_bin_files: + if not os.path.isfile(os.path.join(bin_dir, necessary_bin_file)): + print('Did not find %s in %s' % (necessary_bin_file, bin_dir)) + raise RuntimeError('Did not find %s in %s' % (necessary_bin_file, bin_dir)) + + cmake_dir = os.path.join(lib_dir, 'cmake') + self.check_rm_tree(cmake_dir) + + self.notice_prebuilts_file(host, self.package_license_project_tuple(), install_dir) + + create_tar = True + if create_tar: + self.package_up_resulting(package_name, host, install_host_dir) + + return + + + +def main(): + build_config = BuildConfig() + build_utils = BuildUtils(build_config) + sysroot_composer = SysrootComposer(build_config) + llvm_core = LlvmCore(build_config) + llvm_package = LlvmPackage(build_config) + lldb_mi = LldbMi(build_config, llvm_package) + llvm_libs = LlvmLibs(build_config, sysroot_composer, llvm_package) + + args = build_config.parse_args() + need_host = build_utils.host_is_darwin() or ('linux' not in args.no_build) + need_windows = build_utils.host_is_linux() and \ + ('windows' not in args.no_build) + + llvm_install = build_utils.merge_out_path('llvm-install') + windows64_install = build_utils.merge_out_path('windows-x86_64-install') + + configs = [] + if not build_config.no_build_arm: + configs.append(('arm', build_utils.liteos_triple('arm'))) + configs.append(('arm', build_utils.open_ohos_triple('arm'))) + + if not build_config.no_build_aarch64: + configs.append(('arm64', build_utils.open_ohos_triple('aarch64'))) + + if not build_config.no_build_riscv64: + configs.append(('riscv', build_utils.open_ohos_triple('riscv64'))) + + if not build_config.no_build_mipsel: + configs.append(('mipsel', build_utils.open_ohos_triple('mipsel'))) + + if not build_config.no_build_x86_64: + configs.append(('x86_64', build_utils.open_ohos_triple('x86_64'))) + + + if build_config.do_build and need_host: + llvm_core.llvm_compile( + build_config.build_name, + llvm_install, + build_config.debug, + build_config.no_lto, + build_config.build_instrumented, + build_config.xunit_xml_output) + + llvm_core.set_clang_version(llvm_install) + + if build_config.do_build and build_utils.host_is_linux(): + sysroot_composer.setup_cmake_platform(llvm_install) + llvm_libs.build_crt_libs(configs, llvm_install, build_config.need_lldb_server) + + if build_config.need_libs: + for (arch, target) in configs: + llvm_libs.build_libs(build_config.need_lldb_server, llvm_install, target) + + if build_config.do_build and need_windows: + mingw.main(build_config.VERSION) + llvm_libs.build_runtimes_for_windows(build_config.enable_assertions) + llvm_core.llvm_compile_for_windows(build_config.TARGETS, + build_config.enable_assertions, + build_config.build_name) + + if build_config.need_lldb_mi: + lldb_mi.build_lldb_mi_for_windows() + + if build_config.do_build and build_config.need_lldb_mi and need_host: + lldb_mi.build_lldb_mi(llvm_install) + + if build_config.do_package: + if build_utils.host_is_linux(): + llvm_package.package_libcxx() + llvm_package.package_operation(llvm_install, build_utils.use_platform()) + if build_config.do_package and need_windows: + llvm_package.package_operation(windows64_install, 'windows-x86_64') + +if __name__ == '__main__': + main() diff --git a/llvm-build/build_cpython-mingw.sh b/llvm-build/build_cpython-mingw.sh new file mode 100755 index 000000000000..7419458cc7d9 --- /dev/null +++ b/llvm-build/build_cpython-mingw.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +PROJECT_ROOT=$(pwd) +CPYTHON_MINGW_SRC=${PROJECT_ROOT}/third_party/python +MINGW_W64_SRC=${PROJECT_ROOT}/third_party/mingw-w64 + +# prepare SYSROOT for cpython-mingw build +CLANG_MINGW_BUILD=${PROJECT_ROOT}/out/clang_mingw +python3 ${PROJECT_ROOT}/toolchain/llvm-build/mingw.py + +# refreash cpython-mingw config +cd ${CPYTHON_MINGW_SRC} +cat ./patchs/cpython_mingw_v3.10.2.patch | patch -d ./ -p1 -E +rm -rf ${CPYTHON_MINGW_SRC}/configure +autoconf ${CPYTHON_MINGW_SRC}/configure.ac > ${CPYTHON_MINGW_SRC}/configure +chmod 777 ${CPYTHON_MINGW_SRC}/configure +./configure + +# # prepare build config and build libpython for cpython-mingw +CPYTHON_MINGW_BUILD=${PROJECT_ROOT}/out/cpython-mingw-build +mkdir -p ${CPYTHON_MINGW_BUILD} +cd ${CPYTHON_MINGW_BUILD} +MINGW_PREFIX=${CPYTHON_MINGW_BUILD}/mingw64 +MINGW_CHOST=x86_64-w64-mingw32 +MINGW_BUILD=x86_64-unknown-linux-gnu +CLANG_VERSION=clang-10.0.1 +TOOLCHAIN_ROOT=${CLANG_MINGW_BUILD}/${CLANG_VERSION}/bin +SYSROOT=${CLANG_MINGW_BUILD}/${CLANG_VERSION}/x86_64-w64-mingw32 +mkdir $MINGW_BUILD + +export CC=$TOOLCHAIN_ROOT/clang +export CXX=$TOOLCHAIN_ROOT/clang++ +export CFLAGS="-target ${MINGW_CHOST} --sysroot=$SYSROOT" +export LDFLAGS="--sysroot=$SYSROOT -rtlib=compiler-rt -target ${MINGW_CHOST} -lucrt -lucrtbase -fuse-ld=lld" + +${CPYTHON_MINGW_SRC}/configure \ + --prefix=${MINGW_PREFIX} \ + --host=${MINGW_CHOST} \ + --build=${MINGW_BUILD} \ + --enable-shared \ + --enable-static \ + --without-ensurepip \ + --without-c-locale-coercion \ + --enable-loadable-sqlite-extensions + +make -j4 + +# copy build result to mingw-w64 +cp ${CPYTHON_MINGW_BUILD}/libpython3.10.dll.a ${MINGW_W64_SRC}/mingw-w64-crt/lib64 +cp ${CPYTHON_MINGW_BUILD}/libpython3.10.dll ${MINGW_W64_SRC}/mingw-w64-python/3.10 +cd ../.. + +# example steps to install autoconf 2.71 +# wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz +# export PATH=/mnt/disk2/liwentao/workspace/tools/autoconf/autoconf-2.71/bin:$PATH +# sudo cp -r /mnt/disk2/liwentao/workspace/tools/autoconf/autoconf-2.71/lib /usr/local/share/autoconf + +# refreash configure and Makefile for mingw-w64 +# you need autoconf (2.69 for Ubuntu 20.04 LTS apt install, to support mingw-w64 9.x and later version, please install autoconf 2.71 http://ftp.gnu.org/gnu/autoconf/) +# and automake (1.16.1 for Ubuntu 20.04 LTS apt install) +cd ${MINGW_W64_SRC}/mingw-w64-crt +rm -rf configure +autoconf configure.ac > configure +chmod 777 configure + +aclocal +automake + +cd ${MINGW_W64_SRC}/mingw-w64-headers +rm -rf configure +autoconf configure.ac > configure +chmod 777 configure + +aclocal +automake + +# move cpython-mingw build result and python header file to mingw-w64 +cp -r ${CPYTHON_MINGW_SRC}/Include ${MINGW_W64_SRC}/mingw-w64-headers/include/python3.10 +cp ${CPYTHON_MINGW_SRC}/pyconfig.h ${MINGW_W64_SRC}/mingw-w64-headers/include/python3.10 +mkdir -p ${MINGW_W64_SRC}/mingw-w64-python/3.10 +cp -r ${CPYTHON_MINGW_SRC}/Lib ${MINGW_W64_SRC}/mingw-w64-python/3.10/lib \ No newline at end of file diff --git a/llvm-build/build_musl.sh b/llvm-build/build_musl.sh new file mode 100755 index 000000000000..9fb8737c032a --- /dev/null +++ b/llvm-build/build_musl.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set -e + +# This script is used to create musl's libc.so. + +#default variables +CLANG_BIN_ROOT="${PWD}/../../out/install/linux-x86_64/clang-dev/bin/" +TARGET_TRIPLE="" +OUT="${PWD}/../../out" +make_libs=0 + +#argument parser +while getopts "c:t:o:lh" arg +do + case "${arg}" in + "c") + CLANG_BIN_ROOT=${OPTARG} + ;; + "t") + TARGET_TRIPLE=${OPTARG} + ;; + "o") + OUT=${OPTARG} + ;; + "l") + make_libs=1 + ;; + "h") + echo "Usage: ./build_musl.sh [OPTION]" + echo " Build C/C++ dynamic libs and runtime object" + echo " Options are:" + echo " -c Specify clang bin path" + echo " -t Specify target tripple" + echo " -o Specify the build output directory" + echo " -l Install libs" + exit 0 + ;; + ?) + echo "unkown argument" + exit 1 + ;; + esac +done + +if [ -z "${TARGET_TRIPLE}" ] +then + echo "[ERROR] Empty target triple in build_musl.sh" + exit 1 +fi + +# Canonicalize paths +CLANG_BIN_ROOT=$(readlink -f ${CLANG_BIN_ROOT}) + +CFLAGS_FOR_TARGET=("-mfloat-abi=soft" "-mfloat-abi=soft -mcpu=cortex-a7" +"-mfloat-abi=softfp -mfpu=neon-vfpv4 -mcpu=cortex-a7" "-mfloat-abi=hard -mfpu=neon-vfpv4 -mcpu=cortex-a7") + +if [ $TARGET_TRIPLE == "arm-liteos-ohos" ]; then + TARGET_USER="liteos_a_user" + TARGETS_PREFIX="arm" +elif [ $TARGET_TRIPLE == "arm-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="arm" +elif [ $TARGET_TRIPLE == "mipsel-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="mips" + CFLAGS_FOR_TARGET=("-march=mips32r2") +elif [ $TARGET_TRIPLE == "riscv64-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="riscv64" +elif [ $TARGET_TRIPLE == "x86_64-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="x86_64" +else + TARGET_USER="linux_user" + TARGETS_PREFIX="aarch64" +fi + +echo "CLANG_BIN_ROOT=${CLANG_BIN_ROOT}" +echo "ARCH=${TARGETS_PREFIX}" +echo "TARGET=${TARGET_TRIPLE}" +echo "TOPDIR=${PWD}/../.." +echo "TARGETS=${TARGET_USER}" +echo "OUT=${OUT}" +echo "SYSROOTDIR=${OUT}/sysroot" + +# build musl_headers +make musl_header_install_for_${TARGET_USER} CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../\ + SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER} TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile + +# build musl_libs +if ((make_libs == 1)); then + if [ $TARGET_TRIPLE == "aarch64-linux-ohos" ] || [ $TARGET_TRIPLE == "riscv64-linux-ohos" ] || \ + [ $TARGET_TRIPLE == "mipsel-linux-ohos" ] || [ $TARGET_TRIPLE == "x86_64-linux-ohos" ]; then + make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../ SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ + TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile + else + for ARCH_CFLAG in "${CFLAGS_FOR_TARGET[@]}" + do + make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../ SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ + TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} ARCH_CFLAGS="${ARCH_CFLAG}" -f Makefile + done + fi +fi +make distclean -f Makefile diff --git a/llvm-build/env_prepare.sh b/llvm-build/env_prepare.sh new file mode 100755 index 000000000000..552fbdba4772 --- /dev/null +++ b/llvm-build/env_prepare.sh @@ -0,0 +1,113 @@ +case $(uname -s) in + Linux) + + host_platform=linux + ;; + Darwin) + host_platform=darwin + ;; + *) + echo "Unsupported host platform: $(uname -s)" + exit 1 +esac + +case $(uname -m) in + arm64) + + host_cpu=arm64 + ;; + *) + host_cpu=x86_64 +esac + +# sync code directory +code_dir=$(pwd) + +# downloaded files will be automatically unzipped under this path +bin_dir=${code_dir}/download_packages + +# download and initialize prebuild files +if [ ! -d "${bin_dir}" ];then + mkdir -p "${bin_dir}" +fi + + +function download_and_archive() { + archive_dir=$1 + download_source_url=$2 + bin_file=$(basename ${download_source_url}) + wget -t3 -T10 -O "${bin_dir}/${bin_file}" "${download_source_url}" + if [ ! -d "${code_dir}/${archive_dir}" ];then + mkdir -p "${code_dir}/${archive_dir}" + fi + if [ "X${bin_file:0-3}" = "Xzip" ];then + unzip -o "${bin_dir}/${bin_file}" -d "${code_dir}/${archive_dir}/" + elif [ "X${bin_file:0-6}" = "Xtar.gz" ];then + tar -xvzf "${bin_dir}/${bin_file}" -C "${code_dir}/${archive_dir}" + else + tar -xvf "${bin_dir}/${bin_file}" -C "${code_dir}/${archive_dir}" + fi +} + + +copy_config=""" +""" + +copy_config_linux_x86_64=""" +prebuilts/cmake,https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/${host_platform}/cmake-${host_platform}-x86-3.16.5.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://mirrors.huaweicloud.com/openharmony/compiler/clang/10.0.1-62608/${host_platform}/llvm.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +""" + + +copy_config_darwin_x86_64=""" +prebuilts/cmake,https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/${host_platform}/cmake-${host_platform}-x86-3.16.5.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/clang+llvm-12.0.0-x86_64-apple-darwin.tar.xz +""" + + +if [[ "${host_platform}" == "linux" ]]; then + if [[ "${host_cpu}" == "x86_64" ]]; then + copy_config+=${copy_config_linux_x86_64} + echo "add ubuntu here" + else + echo "unknwon host_cpu - ${host_cpu} for linux" + fi +elif [[ "${host_platform}" == "darwin" ]]; then + if [[ "${host_cpu}" == "x86_64" ]]; then + copy_config+=${copy_config_darwin_x86_64} + echo "add x86-64 mac here" + elif [[ "${host_cpu}" == "arm64" ]]; then + echo "add m1 config here" + else + echo "unknwon host_cpu - ${host_cpu} for darwin" + fi +else + echo "unknown ${host_platform}" +fi + + +for i in $(echo ${copy_config}) +do + unzip_dir=$(echo $i|awk -F ',' '{print $1}') + remote_url=$(echo $i|awk -F ',' '{print $2}') + download_and_archive "${unzip_dir}" "${remote_url}" +done + + +if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-62608" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" + mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-62608" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" + ln -snf 10.0.1 "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/current" +fi + + +if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" + mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" +fi + +if [ -d "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-12.0.0-x86_64-apple-darwin" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" + mv "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-12.0.0-x86_64-apple-darwin" "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" +fi diff --git a/llvm-build/mingw.py b/llvm-build/mingw.py new file mode 100755 index 000000000000..830ad7ebeefa --- /dev/null +++ b/llvm-build/mingw.py @@ -0,0 +1,226 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""donwload and build mingw64-7.0.0 sysroot""" + +import logging +import os +import shutil +import subprocess +import sys + + +class BuildConfig(): + + def __init__(self, clang_version): + self.THIS_DIR = os.path.realpath(os.path.dirname(__file__)) + self.OUT_DIR = os.environ.get('OUT_DIR', self.repo_root('out')) + self.CLANG_VERSION = clang_version + + def repo_root(self, *args): + return os.path.realpath(os.path.join(self.THIS_DIR, '../../', *args)) + + def out_root(self, *args): + return os.path.realpath(os.path.join(self.OUT_DIR, *args)) + + def mingw64_dir(self): + return out_root('mingw', 'x86_64-w64-mingw32') + + def llvm_path(self, *args): + return os.path.realpath(os.path.join(self.THIS_DIR, '../llvm-project', *args)) + + +class LlvmMingw(): + + def __init__(self, build_config): + self.build_config = build_config + + self.CMAKE_BIN_PATH = os.path.join(self.cmake_prebuilt_bin_dir(), 'cmake') + self.NINJA_BIN_PATH = os.path.join(self.cmake_prebuilt_bin_dir(), 'ninja') + + self.LLVM_ROOT = self.build_config.out_root('llvm-install') + self.LLVM_CONFIG = os.path.join(self.LLVM_ROOT, 'bin', 'llvm-config') + self.SYSROOT = self.build_config.mingw64_dir() + self.LLVM_TRIPLE = 'x86_64-windows-gnu' + self.CRT_PATH = self.build_config.out_root('lib', 'mingw-clangrt-%s' % llvm_triple) + self.CRT_INSTALL = self.build_config.out_root('llvm-install', 'lib', 'clang', self.build_config.CLANG_VERSION) + # prefix & env + self.prefix = build_config.mingw64_dir() + common_flags = "-target x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libc++ \ + -fuse-ld=lld -Qunused-arguments -g -O2 --sysroot=" + mingw64_sysroot() + self.env = { + "CC": "%s/bin/clang" % self.LLVM_ROOT, + "CXX": "%s/bin/clang++" % self.LLVM_ROOT, + "AR": "%s/bin/llvm-ar" % self.LLVM_ROOT, + "DLLTOOL": "%s/bin/llvm-dlltool" % self.LLVM_ROOT, + "LD": "%s/bin/ld.lld" % self.LLVM_ROOT, + "RANLIB": "%s/bin/llvm-ranlib" % self.LLVM_ROOT, + "STRIP": "%s/bin/llvm-strip" % self.LLVM_ROOT, + "LDFLAGS": common_flags, + "CFLAGS": common_flags, + "CXXFLAGS": common_flags, + } + + def cmake_prebuilt_bin_dir(self): + return self.build_config.repo_root('prebuilts/cmake', 'linux-x86', 'bin') + + def base_cmake_defines(self): + self.cmake_defines = {} + self.cmake_defines['CMAKE_BUILD_TYPE'] = 'Release' + self.cmake_defines['LLVM_ENABLE_ASSERTIONS'] = 'OFF' + self.cmake_defines['LLVM_ENABLE_TERMINFO'] = 'OFF' + self.cmake_defines['LLVM_ENABLE_THREADS'] = 'ON' + self.cmake_defines['LLVM_USE_NEWPM'] = 'ON' + self.cmake_defines['COMPILER_RT_BUILD_XRAY'] = 'OFF' + return self.cmake_defines + + @staticmethod + def check_create_path(path): + if not os.path.exists(path): + os.makedirs(path) + + @staticmethod + def check_call(cmd, *args, **kwargs): + subprocess.check_call(cmd, *args, **kwargs) + + @staticmethod + def update_cmake_sysroot_flags(defines, sysroot): + defines['CMAKE_SYSROOT'] = sysroot + defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + def compiler_rt_defines(self): + arch = 'x86_64' + cc = os.path.join(self.LLVM_ROOT, 'bin', 'clang') + cxx = os.path.join(self.LLVM_ROOT, 'bin', 'clang++') + self.crt_defines = {} + self.crt_defines['CMAKE_C_COMPILER'] = cc + self.crt_defines['CMAKE_CXX_COMPILER'] = cxx + self.crt_defines['LLVM_CONFIG_PATH'] = self.LLVM_CONFIG + clang_libcxx_lib = self.build_config.out_root('clang_mingw', 'clang-%s' % self.build_config.CLANG_VERSION, 'lib') + ldflags = [ + '-L%s' % clang_libcxx_lib, + '-fuse-ld=lld', + '-Wl,--gc-sections', + '-pie', + '--rtlib=compiler-rt', + '-stdlib=libc++', + '-v', + ] + self.crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + self.update_cmake_sysroot_flags(self.crt_defines, self.SYSROOT) + cflags = [ + '--target=%s' % self.LLVM_TRIPLE, + '-ffunction-sections', + '-fdata-sections', + ] + cflags.append('-funwind-tables') + cflags.append('-v') + self.crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + self.crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + self.crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + self.crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags) + self.crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = self.LLVM_TRIPLE + self.crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = self.LLVM_TRIPLE + self.crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'OFF' + self.crt_defines['CMAKE_INSTALL_PREFIX'] = self.CRT_INSTALL + self.crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + self.crt_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'TRUE' + self.crt_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + self.crt_defines['CMAKE_CROSSCOMPILING'] = 'True' + self.crt_defines['CMAKE_C_COMPILER_WORKS'] = '1' + self.crt_defines['CMAKE_CXX_COMPILER_WORKS'] = '1' + self.crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi' + self.crt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + self.crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + self.crt_defines['COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN'] = 'OFF' + #cmake config + self.crt_defines.update(self.base_cmake_defines()) + return self.crt_defines + + def build_compiler_rt(self): + crt_defines = self.compiler_rt_defines() + #environ + crt_env = dict(dict(os.environ)) + #compiler-rt path + crt_cmake_path = self.build_config.llvm_path('compiler-rt') + #cmake + self.invoke_cmake( + out_path=self.CRT_PATH, + defines=crt_defines, + env=crt_env, + cmake_path=crt_cmake_path) + + def invoke_cmake(self, out_path, defines, env, cmake_path, target=None, install=True): + flags = ['-G', 'Ninja'] + flags += ['-DCMAKE_PREFIX_PATH=%s' % self.cmake_prebuilt_bin_dir()] + + for key in defines: + newdef = ''.join(['-D', key, '=', defines[key]]) + flags += [newdef] + flags += [cmake_path] + + self.check_create_path(out_path) + + if target: + ninja_target = [target] + else: + ninja_target = [] + + self.check_call([self.CMAKE_BIN_PATH] + flags, cwd=out_path, env=env) + self.check_call([self.NINJA_BIN_PATH] + ninja_target, cwd=out_path, env=env) + if install: + self.check_call([self.NINJA_BIN_PATH, 'install'], cwd=out_path, env=env) + + def build_mingw64_headers(self): + headers_dir = self.build_config.repo_root('third_party', 'mingw-w64', 'mingw-w64-headers', 'build') + if os.path.isdir(headers_dir): + shutil.rmtree(headers_dir) + os.makedirs(headers_dir) + os.chdir(headers_dir) + cmd = ['../configure', '--prefix=%s' % self.prefix, + '--enable-idl', '--with-default-win32-winnt=0x600', + '--with-default-msvcrt=ucrt'] + self.env['INSTALL'] = "install -C" + self.check_call(cmd, env=self.env) + self.check_call(['make', 'install'], env=self.env) + + def build_mingw64_crtlibs(self): + crtlibs_dir = self.build_config.repo_root('third_party', 'mingw-w64', 'mingw-w64-crt', 'build') + if os.path.isdir(crtlibs_dir): + shutil.rmtree(crtlibs_dir) + os.makedirs(crtlibs_dir) + os.chdir(crtlibs_dir) + cmd = ['../configure', '--prefix=%s' % self.prefix, + '--host=x86_64-w64-mingw32', '--disable-lib32', + '--enable-lib64', '--with-default-msvcrt=ucrt'] + self.check_call(cmd, env=self.env) + self.check_call(['make', '-j4'], env=self.env) + self.check_call(['make', 'install'], env=self.env) + + +def main(clang_version): + build_config = BuildConfig(clang_version) + llvm_mingw = LlvmMingw(build_config) + + llvm_mingw.build_mingw64_headers() + llvm_mingw.build_mingw64_crtlibs() + llvm_mingw.build_compiler_rt() + return 0 + +if __name__ == '__main__': + main() diff --git a/llvm-build/toolchain_readme.md b/llvm-build/toolchain_readme.md new file mode 100644 index 000000000000..eb042745aa11 --- /dev/null +++ b/llvm-build/toolchain_readme.md @@ -0,0 +1,26 @@ +## Overview + +This readme briefly describes the functionality of our LLVM toolchain and what we have included specially to the LLVM toolchain. + +## Functionality + +The LLVM toolchain is built based on LLVM 12.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 12.0.1, please refer to [LLVM 12.0.1](https://lists.llvm.org/pipermail/llvm-announce/2021-July/000093.html). +
+ + +## Specifically Included Triplets + +Despite all the components provided by LLVM community, we included several triplets for different types of ohos devices to our LLVM toochain, listed as below. For specification, liteos is a newly included OS name which indicate the simplified linux kernel. + +| Triplet Name | Architecture | System Kernel | System | +| ---------------------- | ------------ | ------------- | --------------- | +| arm-liteos-ohos | ARM 32bits | LiteOS | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Standard system | +| aarch64-linux-ohos | ARM 64bits | Linux | Standard system | + +For detailed definition of Small System and Standard System, please refer to [System Types](https://gitee.com/openharmony/docs/blob/master/en/device-dev/Readme-EN.md). + +### Specify the triplet + +To build images for different types of platform, you can configure the triplet in the build scripts by setting "--target=xxx" using cflags, xxx should be replaced with a specific triplet name. -- Gitee From 71944f54b4eb9624b868e412df1e014735fc29f4 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 25 Oct 2022 17:52:00 +0300 Subject: [PATCH 17/41] Add RISCV64 target support Signed-off-by: Ivan Eliseev --- clang/lib/Basic/Targets.cpp | 7 +- clang/lib/Driver/ToolChains/OHOS.cpp | 2 + clang/test/Preprocessor/ohos.c | 6 +- .../lib/sanitizer_common/sanitizer_linux.cpp | 2 +- .../lib/sanitizer_common/sanitizer_linux.h | 3 + llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 + llvm/test/CodeGen/RISCV/emutls.ll | 307 ++++++++++++++++++ llvm/test/CodeGen/RISCV/emutls_generic.ll | 75 +++++ 8 files changed, 400 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/RISCV/emutls.ll create mode 100644 llvm/test/CodeGen/RISCV/emutls_generic.ll diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 1f8fa8b7f1b6..b10a9c6da1d5 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -433,7 +433,12 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Fuchsia: return new FuchsiaTargetInfo(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } default: return new RISCV64TargetInfo(Triple, Opts); } diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp index 83366bef2081..5783a621e51b 100644 --- a/clang/lib/Driver/ToolChains/OHOS.cpp +++ b/clang/lib/Driver/ToolChains/OHOS.cpp @@ -103,6 +103,8 @@ std::string OHOS::getMultiarchTriple(const llvm::Triple &T) const { return T.isOSLiteOS() ? "arm-liteos-ohos" : "arm-linux-ohos"; case llvm::Triple::riscv32: return "riscv32-liteos-ohos"; + case llvm::Triple::riscv64: + return "riscv64-linux-ohos"; case llvm::Triple::x86: return "i686-linux-ohos"; case llvm::Triple::x86_64: diff --git a/clang/test/Preprocessor/ohos.c b/clang/test/Preprocessor/ohos.c index bd1060133c4e..de5d0c48afcf 100644 --- a/clang/test/Preprocessor/ohos.c +++ b/clang/test/Preprocessor/ohos.c @@ -1,11 +1,13 @@ // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM-OHOS-CXX // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=aarch64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM64-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=riscv64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=RISCV64-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=x86_64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=X86_64-OHOS-CXX // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -check-prefix=OHOS-DEFS -// ARM-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 +// RISCV64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// X86_64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL // OHOS-DEFS: __OHOS_FAMILY__ // OHOS-DEFS: __OHOS__ // OHOS-DEFS-NOT: __OHOS__ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index f5bdf4b575dc..fcbf141b2ac7 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -34,7 +34,7 @@ // format. Struct kernel_stat is defined as 'struct stat' in asm/stat.h. To // access stat from asm/stat.h, without conflicting with definition in // sys/stat.h, we use this trick. -#if SANITIZER_MIPS64 +#if SANITIZER_MIPS64 || SANITIZER_RISCV64 #include #include #define stat kernel_stat diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 6d619b1e7d37..1b1b98fe4989 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -152,6 +152,9 @@ inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { "rdhwr %0,$29\n" \ ".set pop\n" : "=r"(__v)); \ __v; }) +#elif defined(__riscv) +# define __get_tls() \ + ({ void** __v; __asm__("mv %0, tp" : "=r"(__v)); __v; }) #elif defined(__i386__) # define __get_tls() \ ({ void** __v; __asm__("movl %%gs:0, %0" : "=r"(__v)); __v; }) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index d0ca325e9c14..80dbe18a526b 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3856,6 +3856,8 @@ SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op, SDLoc DL(Op); GlobalAddressSDNode *N = cast(Op); assert(N->getOffset() == 0 && "unexpected offset in global node"); + if (DAG.getTarget().useEmulatedTLS()) + return LowerToTLSEmulatedModel(N, DAG); TLSModel::Model Model = getTargetMachine().getTLSModel(N->getGlobal()); diff --git a/llvm/test/CodeGen/RISCV/emutls.ll b/llvm/test/CodeGen/RISCV/emutls.ll new file mode 100644 index 000000000000..441bb9897ce1 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/emutls.ll @@ -0,0 +1,307 @@ +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-gnu | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-ohos | FileCheck -check-prefix=RISCV64 %s + +; RUN: llc < %s -mtriple=riscv64-linux-gnu | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=riscv64-linux-ohos | FileCheck -check-prefix=RISCV64 %s + +; Copied from X86/emutls.ll + +; NoEMU-NOT: __emutls + +; Use my_emutls_get_address like __emutls_get_address. +@my_emutls_v_xyz = external global i8*, align 4 +declare i8* @my_emutls_get_address(i8*) + +define dso_local i32 @my_get_xyz() { +; RISCV64-LABEL: my_get_xyz: +; RISCV64: lui a0, %hi(my_emutls_v_xyz) +; RISCV64-NEXT: addi a0, a0, %lo(my_emutls_v_xyz) +; RISCV64-NEXT: call my_emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) + %0 = bitcast i8* %call to i32* + %1 = load i32, i32* %0, align 4 + ret i32 %1 +} + +@i1 = dso_local thread_local global i32 15 +@i2 = external thread_local global i32 +@i3 = internal thread_local global i32 15 +@i4 = hidden thread_local global i32 15 +@i5 = external hidden thread_local global i32 +@s1 = dso_local thread_local global i16 15 +@b1 = dso_local thread_local global i8 0 + +define dso_local i32 @f1() { +; RISCV64-LABEL: f1: +; RISCV64: lui a0, %hi(__emutls_v.i1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i1 + ret i32 %tmp1 +} + +define dso_local i32* @f2() { +; RISCV64-LABEL: f2: +; RISCV64: lui a0, %hi(__emutls_v.i1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i1 +} + +define dso_local i32 @f3() nounwind { +; RISCV64-LABEL: f3: +; RISCV64: lui a0, %hi(__emutls_v.i2) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i2) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i2 + ret i32 %tmp1 +} + +define dso_local i32* @f4() { +; RISCV64-LABEL: f4: +; RISCV64: lui a0, %hi(__emutls_v.i2) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i2) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i2 +} + +define dso_local i32 @f5() nounwind { +; RISCV64-LABEL: f5: +; RISCV64: lui a0, %hi(__emutls_v.i3) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i3) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i3 + ret i32 %tmp1 +} + +define dso_local i32* @f6() { +; RISCV64-LABEL: f6: +; RISCV64: lui a0, %hi(__emutls_v.i3) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i3) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i3 +} + +define dso_local i32 @f7() { +; RISCV64-LABEL: f7: +; RISCV64: lui a0, %hi(__emutls_v.i4) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i4) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i4 + ret i32 %tmp1 +} + +define dso_local i32* @f8() { +; RISCV64-LABEL: f8: +; RISCV64: lui a0, %hi(__emutls_v.i4) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i4) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i4 +} + +define dso_local i32 @f9() { +; RISCV64-LABEL: f9: +; RISCV64: lui a0, %hi(__emutls_v.i5) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i5) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lw a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i32, i32* @i5 + ret i32 %tmp1 +} + +define dso_local i32* @f10() { +; RISCV64-LABEL: f10: +; RISCV64: lui a0, %hi(__emutls_v.i5) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.i5) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + ret i32* @i5 +} + +define dso_local i16 @f11() { +; RISCV64-LABEL: f11: +; RISCV64: lui a0, %hi(__emutls_v.s1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.s1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lh a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i16, i16* @s1 + ret i16 %tmp1 +} + +define dso_local i32 @f12sext() { +; RISCV64-LABEL: f12sext: +; RISCV64: lui a0, %hi(__emutls_v.s1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.s1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lh a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i16, i16* @s1 + %tmp2 = sext i16 %tmp1 to i32 + ret i32 %tmp2 +} + +define dso_local i32 @f12zext() { +; RISCV64-LABEL: f12zext: +; RISCV64: lui a0, %hi(__emutls_v.s1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.s1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lhu a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i16, i16* @s1 + %tmp2 = zext i16 %tmp1 to i32 + ret i32 %tmp2 +} + +define dso_local i8 @f13() { +; RISCV64-LABEL: f13: +; RISCV64: lui a0, %hi(__emutls_v.b1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.b1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lb a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i8, i8* @b1 + ret i8 %tmp1 +} + +define dso_local i32 @f14sext() { +; RISCV64-LABEL: f14sext: +; RISCV64: lui a0, %hi(__emutls_v.b1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.b1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lb a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i8, i8* @b1 + %tmp2 = sext i8 %tmp1 to i32 + ret i32 %tmp2 +} + +define dso_local i32 @f14zext() { +; RISCV64-LABEL: f14zext: +; RISCV64: lui a0, %hi(__emutls_v.b1) +; RISCV64-NEXT: addi a0, a0, %lo(__emutls_v.b1) +; RISCV64-NEXT: call __emutls_get_address@plt +; RISCV64-NEXT: lbu a0, 0(a0) +; RISCV64-NEXT: ld ra, 8(sp) +; RISCV64-NEXT: addi sp, sp, 16 +; RISCV64-NEXT: ret +entry: + %tmp1 = load i8, i8* @b1 + %tmp2 = zext i8 %tmp1 to i32 + ret i32 %tmp2 +} + +;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t. + +; RISCV64-LABEL: __emutls_v.i1: +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.i1 + +; RISCV64-LABEL: __emutls_t.i1: +; RISCV64-NEXT: .word 15 + +; RISCV64-NOT: __emutls_v.i2 + +; RISCV64-LABEL: __emutls_v.i3: +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.i3 + +; RISCV64-LABEL: __emutls_t.i3: +; RISCV64-NEXT: .word 15 + +; RISCV64-LABEL: __emutls_v.i4: +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 4 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.i4 + +; RISCV64-LABEL: __emutls_t.i4: +; RISCV64-NEXT: .word 15 + +; RISCV64-NOT: __emutls_v.i5: +; RISCV64: .hidden __emutls_v.i5 +; RISCV64-NOT: __emutls_v.i5: + +; RISCV64-LABEL: __emutls_v.s1: +; RISCV64-NEXT: .quad 2 +; RISCV64-NEXT: .quad 2 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.s1 + +; RISCV64-LABEL: __emutls_t.s1: +; RISCV64-NEXT: .half 15 + +; RISCV64-LABEL: __emutls_v.b1: +; RISCV64-NEXT: .quad 1 +; RISCV64-NEXT: .quad 1 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad 0 + +; RISCV64-NOT: __emutls_t.b1 diff --git a/llvm/test/CodeGen/RISCV/emutls_generic.ll b/llvm/test/CodeGen/RISCV/emutls_generic.ll new file mode 100644 index 000000000000..9f2345d8e673 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/emutls_generic.ll @@ -0,0 +1,75 @@ +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-gnu -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-ohos -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -emulated-tls -mtriple=riscv64-linux-ohos -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s + +; RUN: llc < %s -mtriple=riscv64-linux-gnu -O3 \ +; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=riscv64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -mtriple=riscv64-linux-ohos -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s +; RUN: llc < %s -mtriple=riscv64-linux-ohos -O3 \ +; RUN: | FileCheck -check-prefix=RISCV64 %s + +; NoEMU-NOT: __emutls + +; Make sure that TLS symbols are emitted in expected order. + +@external_x = external thread_local global i32, align 8 +@external_y = thread_local global i8 7, align 2 +@internal_y = internal thread_local global i64 9, align 16 + +define i32* @get_external_x() { +entry: + ret i32* @external_x +} + +define i8* @get_external_y() { +entry: + ret i8* @external_y +} + +define i64* @get_internal_y() { +entry: + ret i64* @internal_y +} + +; RISCV64-LABEL: get_external_x: +; RISCV64: __emutls_v.external_x +; RISCV64: __emutls_get_address +; RISCV64-LABEL: get_external_y: +; RISCV64: __emutls_v.external_y +; RISCV64: __emutls_get_address +; RISCV64-LABEL: get_internal_y: +; RISCV64: __emutls_v.internal_y +; RISCV64: __emutls_get_address +; RISCV64-NOT: __emutls_t.external_x +; RISCV64-NOT: __emutls_v.external_x: +; RISCV64: .data{{$}} +; RISCV64: .globl __emutls_v.external_y +; RISCV64: .p2align 3 +; RISCV64-LABEL: __emutls_v.external_y: +; RISCV64-NEXT: .quad 1 +; RISCV64-NEXT: .quad 2 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.external_y +; RISCV64-NOT: __emutls_v.external_x: +; RISCV64: .section .r{{o?}}data, +; RISCV64-LABEL: __emutls_t.external_y: +; RISCV64-NEXT: .byte 7 +; RISCV64: .data{{$}} +; RISCV64-NOT: .globl __emutls_v +; RISCV64: .p2align 3 +; RISCV64-LABEL: __emutls_v.internal_y: +; RISCV64-NEXT: .quad 8 +; RISCV64-NEXT: .quad 16 +; RISCV64-NEXT: .quad 0 +; RISCV64-NEXT: .quad __emutls_t.internal_y +; RISCV64: .section .r{{o?}}data, +; RISCV64-LABEL: __emutls_t.internal_y: +; RISCV64-NEXT: .quad 9 -- Gitee From 5b267185b7cc1cc9425a838f1ab2fa10d286293d Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 25 Oct 2022 17:50:28 +0300 Subject: [PATCH 18/41] Add MIPS target support Signed-off-by: Ivan Eliseev --- .../clang/Basic/DiagnosticCommonKinds.td | 1 + clang/lib/Basic/Targets.cpp | 7 +- clang/lib/Basic/Targets/Mips.cpp | 6 ++ clang/lib/Basic/Targets/Mips.h | 5 +- clang/lib/Driver/ToolChains/Arch/Mips.cpp | 7 ++ clang/lib/Driver/ToolChains/Gnu.cpp | 3 +- clang/lib/Driver/ToolChains/OHOS.cpp | 11 +++- clang/test/Driver/ohos.c | 2 + clang/test/Preprocessor/init-mips.c | 8 +++ clang/test/Preprocessor/ohos.c | 2 + compiler-rt/CMakeLists.txt | 4 +- .../cmake/Modules/CompilerRTUtils.cmake | 2 +- compiler-rt/cmake/crt-config-ix.cmake | 2 +- .../sanitizer_platform_limits_posix.h | 64 +++++++++---------- .../sanitizer_stoptheworld_linux_libcdep.cpp | 49 +++++++------- 15 files changed, 110 insertions(+), 63 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 39dee7e683ff..ad5815180c48 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -308,6 +308,7 @@ def err_target_unsupported_abi_for_triple : Error< def err_unsupported_abi_for_opt : Error<"'%0' can only be used with the '%1' ABI">; def err_mips_fp64_req : Error< "'%0' can only be used if the target supports the mfhc1 and mthc1 instructions">; +def err_unsupported_fpxx_ohos : Error<"fpxx is currently unsupported on OHOS">; def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">; def err_target_unsupported_fpmath : Error< "the '%0' unit is not supported with this instruction set">; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index b10a9c6da1d5..d2eac5cae7b6 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -273,7 +273,12 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::mipsel: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } case llvm::Triple::RTEMS: return new RTEMSTargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index 39246f650cce..706e0826f764 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -269,6 +269,12 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { return false; } + // TODO: remove this if entry when fpxx is supported on OHOS + if (getTriple().isOpenHOS() && FPMode == FPXX) { + Diags.Report(diag::err_unsupported_fpxx_ohos); + return false; + } + // -fpxx is valid only for the o32 ABI if (FPMode == FPXX && (ABI == "n32" || ABI == "n64")) { Diags.Report(diag::err_unsupported_abi_for_opt) << "-mfpxx" << "o32"; diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index b54d36e1c95f..966def9632ad 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -86,7 +86,10 @@ public: } bool isFP64Default() const { - return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64"; + // TODO: remove getTriple().isOpenHOS() case + // when fpxx is supported on OHOS + return getTriple().isOpenHOS() || CPU == "mips32r6" || ABI == "n32" || + ABI == "n64" || ABI == "64"; } bool isNan2008() const override { return IsNan2008; } diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp index c374d745da38..68a86974e6f1 100644 --- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp @@ -362,6 +362,9 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, } else if (mips::isFP64ADefault(Triple, CPUName)) { Features.push_back("+fp64"); Features.push_back("+nooddspreg"); + } else if (Triple.isOpenHOS()) { + // TODO: remove this else if entry when fpxx is supported on OHOS + Features.push_back("+fp64"); } AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg, @@ -467,6 +470,10 @@ bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) { bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName, StringRef ABIName, mips::FloatABI FloatABI) { + // TODO: remove this if entry when fpxx is supported on OHOS + if (Triple.isOpenHOS()) + return false; + if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies && Triple.getVendor() != llvm::Triple::MipsTechnologies && !Triple.isAndroid()) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index b0605edf4669..9ea8db1a7255 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -2231,7 +2231,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"}; static const char *const MIPSELLibDirs[] = {"/libo32", "/lib"}; static const char *const MIPSELTriples[] = { - "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu"}; + "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu", + "mipsel-linux-ohos"}; static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"}; static const char *const MIPS64Triples[] = { diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp index 5783a621e51b..64dcec7bb1f2 100644 --- a/clang/lib/Driver/ToolChains/OHOS.cpp +++ b/clang/lib/Driver/ToolChains/OHOS.cpp @@ -105,6 +105,8 @@ std::string OHOS::getMultiarchTriple(const llvm::Triple &T) const { return "riscv32-liteos-ohos"; case llvm::Triple::riscv64: return "riscv64-linux-ohos"; + case llvm::Triple::mipsel: + return "mipsel-linux-ohos"; case llvm::Triple::x86: return "i686-linux-ohos"; case llvm::Triple::x86_64: @@ -368,9 +370,12 @@ void OHOS::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { 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"); + // .gnu.hash section is not compatible with the MIPS target + if (getArch() != llvm::Triple::mipsel) { + CmdArgs.push_back("--hash-style=gnu"); + // FIXME: gnu or both??? + CmdArgs.push_back("--hash-style=both"); + } #ifdef ENABLE_LINKER_BUILD_ID CmdArgs.push_back("--build-id"); #endif diff --git a/clang/test/Driver/ohos.c b/clang/test/Driver/ohos.c index b934b7509e14..7d358346fad9 100644 --- a/clang/test/Driver/ohos.c +++ b/clang/test/Driver/ohos.c @@ -55,6 +55,8 @@ // RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME // RUN: %clang %s -### --target=aarch64-linux-ohos -fuse-ld=lld 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// RUN: %clang %s -### --target=mipsel-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME // CHECK-RUNTIME: "{{.*}}/libclang_rt.builtins.a" // CHECK-RUNTIME: "-l:libunwind.a" // CHECK-LIBM: "-lm" diff --git a/clang/test/Preprocessor/init-mips.c b/clang/test/Preprocessor/init-mips.c index a07cee64e684..40d8d3a80027 100644 --- a/clang/test/Preprocessor/init-mips.c +++ b/clang/test/Preprocessor/init-mips.c @@ -1,4 +1,7 @@ +// RUN: %clang_cc1 -E -dM -triple=mipsel-linux-ohos < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32EL-OHOS %s // +// MIPS32EL-OHOS:#define __mips_fpr 64 + // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=mips-none-none < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32BE -check-prefix MIPS32BE-C %s // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=mips-none-none < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32BE -check-prefix MIPS32BE-CXX %s // @@ -1697,6 +1700,11 @@ // RUN: | FileCheck -match-full-lines -check-prefix MIPS64-NOFP %s // MIPS64-NOFP:#define __mips_fpr 64 +// RUN: not %clang_cc1 -target-feature +fpxx \ +// RUN: -E -dM -triple=mipsel-linux-ohos < /dev/null 2>&1 \ +// RUN: | FileCheck -match-full-lines -check-prefix MIPS32EL-OHOS-MFPXX %s +// MIPS32EL-OHOS-MFPXX:error: fpxx is currently unsupported on OHOS + // RUN: not %clang_cc1 -target-feature -fp64 \ // RUN: -E -dM -triple=mips64-none-none < /dev/null 2>&1 \ // RUN: | FileCheck -match-full-lines -check-prefix MIPS64-MFP32 %s diff --git a/clang/test/Preprocessor/ohos.c b/clang/test/Preprocessor/ohos.c index de5d0c48afcf..0c435c7ed5ab 100644 --- a/clang/test/Preprocessor/ohos.c +++ b/clang/test/Preprocessor/ohos.c @@ -1,12 +1,14 @@ // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM-OHOS-CXX // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=aarch64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM64-OHOS-CXX // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=riscv64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=RISCV64-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=mipsel-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=MIPSEL-OHOS-CXX // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=x86_64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=X86_64-OHOS-CXX // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -check-prefix=OHOS-DEFS // ARM-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U // ARM64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL // RISCV64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// MIPSEL-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U // X86_64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL // OHOS-DEFS: __OHOS_FAMILY__ // OHOS-DEFS: __OHOS__ diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index fd7e3205abe4..c72f90709cb5 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -484,7 +484,9 @@ append_list_if(MINGW -fms-extensions SANITIZER_COMMON_CFLAGS) # TODO: We should consider using the same model as libc++, that is use either # -nostdlib++ and --unwindlib=none if supported, or -nodefaultlibs otherwise. append_list_if(C_SUPPORTS_NODEFAULTLIBS_FLAG -nodefaultlibs SANITIZER_COMMON_LINK_FLAGS) -append_list_if(COMPILER_RT_HAS_Z_TEXT -Wl,-z,text SANITIZER_COMMON_LINK_FLAGS) +if (NOT __MIPS) + append_list_if(COMPILER_RT_HAS_Z_TEXT -Wl,-z,text SANITIZER_COMMON_LINK_FLAGS) +endif() # Only necessary for 32-bit SPARC. Solaris 11.2+ ld uses -z ignore/-z record # natively, but supports --as-needed/--no-as-needed for GNU ld compatibility. diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index c0c0498f3ef5..8675f5689b99 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -182,7 +182,7 @@ macro(detect_target_arch) elseif(__MIPS64) # must be checked before __MIPS add_default_target_arch(mips64) elseif(__MIPS) - add_default_target_arch(mips) + add_default_target_arch(mipsel) elseif(__PPC64) # must be checked before __PPC add_default_target_arch(powerpc64) elseif(__PPC64LE) diff --git a/compiler-rt/cmake/crt-config-ix.cmake b/compiler-rt/cmake/crt-config-ix.cmake index b476d5ab0717..f737e4eba822 100644 --- a/compiler-rt/cmake/crt-config-ix.cmake +++ b/compiler-rt/cmake/crt-config-ix.cmake @@ -30,7 +30,7 @@ set(RISCV64 riscv64) set(VE ve) set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} - ${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON}) + ${PPC64} ${MIPS32} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON}) include(CompilerRTUtils) 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 5718fddd3a18..052a0d0c0870 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -619,7 +619,7 @@ struct __sanitizer_sigaction { }; __sanitizer_sigset_t sa_mask; }; -#elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32) +# elif (SANITIZER_ANDROID || SANITIZER_OHOS) && (SANITIZER_WORDSIZE == 32) struct __sanitizer_sigaction { union { __sanitizer_sigactionhandler_ptr sigaction; @@ -629,59 +629,59 @@ struct __sanitizer_sigaction { uptr sa_flags; void (*sa_restorer)(); }; -#else // !SANITIZER_ANDROID +# else // !SANITIZER_ANDROID struct __sanitizer_sigaction { -#if defined(__mips__) && !SANITIZER_FREEBSD +# if defined(__mips__) && !SANITIZER_FREEBSD unsigned int sa_flags; -#endif +# endif union { __sanitizer_sigactionhandler_ptr sigaction; __sanitizer_sighandler_ptr handler; }; -#if SANITIZER_FREEBSD +# if SANITIZER_FREEBSD int sa_flags; __sanitizer_sigset_t sa_mask; -#else -#if defined(__s390x__) +# else +# if defined(__s390x__) int sa_resv; -#else +# else __sanitizer_sigset_t sa_mask; -#endif -#ifndef __mips__ -#if defined(__sparc__) -#if __GLIBC_PREREQ (2, 20) +# endif +# ifndef __mips__ +# if defined(__sparc__) +# if __GLIBC_PREREQ(2, 20) // On sparc glibc 2.19 and earlier sa_flags was unsigned long. -#if defined(__arch64__) +# if defined(__arch64__) // To maintain ABI compatibility on sparc64 when switching to an int, // __glibc_reserved0 was added. int __glibc_reserved0; -#endif +# endif int sa_flags; -#else +# else unsigned long sa_flags; -#endif -#else +# endif +# else int sa_flags; -#endif -#endif -#endif -#if SANITIZER_LINUX +# endif +# endif +# endif +# if SANITIZER_LINUX void (*sa_restorer)(); -#endif -#if defined(__mips__) && (SANITIZER_WORDSIZE == 32) +# endif +# if defined(__mips__) && (SANITIZER_WORDSIZE == 32) int sa_resv[1]; -#endif -#if defined(__s390x__) +# endif +# if defined(__s390x__) __sanitizer_sigset_t sa_mask; -#endif +# endif }; -#endif // !SANITIZER_ANDROID +# endif // !SANITIZER_ANDROID -#if defined(__mips__) -#define __SANITIZER_KERNEL_NSIG 128 -#else -#define __SANITIZER_KERNEL_NSIG 64 -#endif +# if defined(__mips__) +# define __SANITIZER_KERNEL_NSIG 128 +# else +# define __SANITIZER_KERNEL_NSIG 64 +# endif struct __sanitizer_kernel_sigset_t { uptr sig[__SANITIZER_KERNEL_NSIG / (sizeof(uptr) * 8)]; 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 9598c41ea676..556fdfaaa89e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -41,25 +41,25 @@ # include #endif #include // for user_regs_struct -#if SANITIZER_ANDROID && SANITIZER_MIPS -# include // for mips SP register in sys/user.h -#endif -#include // for signal-related stuff - -#ifdef sa_handler -# undef sa_handler -#endif - -#ifdef sa_sigaction -# undef sa_sigaction -#endif - -#include "sanitizer_common.h" -#include "sanitizer_flags.h" -#include "sanitizer_libc.h" -#include "sanitizer_linux.h" -#include "sanitizer_mutex.h" -#include "sanitizer_placement_new.h" +# if (SANITIZER_ANDROID || SANITIZER_OHOS) && SANITIZER_MIPS +# include // for mips SP register in sys/user.h +# endif +# include // for signal-related stuff + +# ifdef sa_handler +# undef sa_handler +# endif + +# ifdef sa_sigaction +# undef sa_sigaction +# endif + +# include "sanitizer_common.h" +# include "sanitizer_flags.h" +# include "sanitizer_libc.h" +# include "sanitizer_linux.h" +# include "sanitizer_mutex.h" +# include "sanitizer_placement_new.h" // Sufficiently old kernel headers don't provide this value, but we can still // call prctl with it. If the runtime kernel is new enough, the prctl call will @@ -509,9 +509,14 @@ typedef pt_regs regs_struct; typedef struct user regs_struct; # if SANITIZER_ANDROID # define REG_SP regs[EF_R29] -# else -# define REG_SP regs[EF_REG29] -# endif +// FIXME: For some reason, EF_R29 is not defined in asm/reg.h under +// #if _MIPS_SIM == _MIPS_SIM_ABI32 condition, so use MIPS32_EF_R29 as a +// temporary solution. +# elif SANITIZER_OHOS +# define REG_SP regs[MIPS32_EF_R29] +# else +# define REG_SP regs[EF_REG29] +# endif #elif defined(__aarch64__) typedef struct user_pt_regs regs_struct; -- Gitee From 9f44c907f355c0d0e948d1e27a999dede6afd3d2 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 25 Oct 2022 17:50:50 +0300 Subject: [PATCH 19/41] Add few fixes for RISC and MIPS Signed-off-by: Ivan Eliseev --- clang/test/Driver/ohos.c | 2 ++ .../lib/sanitizer_common/sanitizer_linux.cpp | 26 +++++++++++-------- .../sanitizer_platform_limits_posix.h | 3 +++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/clang/test/Driver/ohos.c b/clang/test/Driver/ohos.c index 7d358346fad9..a38b83338ee0 100644 --- a/clang/test/Driver/ohos.c +++ b/clang/test/Driver/ohos.c @@ -57,6 +57,8 @@ // RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME // RUN: %clang %s -### --target=mipsel-linux-ohos -fuse-ld=lld 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// RUN: %clang %s -### --target=x86_64-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-pr // CHECK-RUNTIME: "{{.*}}/libclang_rt.builtins.a" // CHECK-RUNTIME: "-l:libunwind.a" // CHECK-LIBM: "-lm" diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index fcbf141b2ac7..f03ef2562033 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -276,7 +276,9 @@ uptr internal_ftruncate(fd_t fd, uptr size) { return res; } -#if (!SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_SPARC) && SANITIZER_LINUX +# if (!SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_SPARC || \ + SANITIZER_OHOS) && \ + SANITIZER_LINUX static void stat64_to_stat(struct stat64 *in, struct stat *out) { internal_memset(out, 0, sizeof(*out)); out->st_dev = in->st_dev; @@ -377,18 +379,19 @@ uptr internal_stat(const char *path, void *buf) { AT_NO_AUTOMOUNT, STATX_BASIC_STATS, (uptr)&bufx); statx_to_stat(&bufx, (struct stat *)buf); return res; -# elif (SANITIZER_WORDSIZE == 64 || SANITIZER_X32 || \ - (defined(__mips__) && _MIPS_SIM == _ABIN32)) && \ - !SANITIZER_SPARC +# elif ( \ + SANITIZER_WORDSIZE == 64 || SANITIZER_X32 || \ + (defined(__mips__) && _MIPS_SIM == _ABIN32 && !SANITIZER_OHOS)) && \ + !SANITIZER_SPARC return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0); -# else +# else struct stat64 buf64; int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, (uptr)&buf64, 0); stat64_to_stat(&buf64, (struct stat *)buf); return res; -# endif +# endif # else struct stat64 buf64; int res = internal_syscall(SYSCALL(stat64), path, &buf64); @@ -409,18 +412,19 @@ uptr internal_lstat(const char *path, void *buf) { STATX_BASIC_STATS, (uptr)&bufx); statx_to_stat(&bufx, (struct stat *)buf); return res; -# elif (defined(_LP64) || SANITIZER_X32 || \ - (defined(__mips__) && _MIPS_SIM == _ABIN32)) && \ - !SANITIZER_SPARC +# elif ( \ + defined(_LP64) || SANITIZER_X32 || \ + (defined(__mips__) && _MIPS_SIM == _ABIN32 && !SANITIZER_OHOS)) && \ + !SANITIZER_SPARC return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, AT_SYMLINK_NOFOLLOW); -# else +# else struct stat64 buf64; int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, (uptr)&buf64, AT_SYMLINK_NOFOLLOW); stat64_to_stat(&buf64, (struct stat *)buf); return res; -# endif +# endif # else struct stat64 buf64; int res = internal_syscall(SYSCALL(lstat64), path, &buf64); 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 052a0d0c0870..a13117a330ec 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -98,6 +98,9 @@ const unsigned struct_kernel_stat64_sz = 104; const unsigned struct_kernel_stat_sz = 144; const unsigned struct_kernel_stat64_sz = 104; #elif defined(__mips__) +# if SANITIZER_OHOS +# define _ABIN32 1 +# endif const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID ? FIRST_32_SECOND_64(104, 128) -- Gitee From 95faf25ef21e0ac5396167539c7c1c01a944e50d Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 25 Oct 2022 17:51:13 +0300 Subject: [PATCH 20/41] Fix llvm-build scripts Windows and Linux builds now work Signed-off-by: Ivan Eliseev --- llvm-build/Makefile | 2 ++ llvm-build/build.py | 61 +++++++++++++++++++-------------------------- llvm-build/mingw.py | 14 +++++------ 3 files changed, 35 insertions(+), 42 deletions(-) diff --git a/llvm-build/Makefile b/llvm-build/Makefile index 54a94743676c..2e3562419e15 100644 --- a/llvm-build/Makefile +++ b/llvm-build/Makefile @@ -108,6 +108,8 @@ endif endif endif +CFLAGS += -Wno-int-conversion + .PHONY: $(TARGETS:%=musl_copy_for_%) .PHONY: $(TARGETS:%=musl_patch_for_%) .PHONY: $(TARGETS:%=musl_install_for_%) diff --git a/llvm-build/build.py b/llvm-build/build.py index 24a18955ac79..e5a74de8ed96 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -63,6 +63,7 @@ class BuildConfig(): self.LITEOS_SFX = '-liteos-ohos' self.LLDB_PY_VERSION = '3.10' self.CLANG_VERSION = '10.0.1' + self.MINGW_TRIPLE = 'x86_64-windows-gnu' logging.basicConfig(level=logging.INFO) @staticmethod @@ -548,10 +549,10 @@ class LlvmCore(BuildUtils): windows_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' - win_sysroot = self.merge_out_path('mingw', 'x86_64-w64-mingw32') + win_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) windows_defines['LLDB_ENABLE_PYTHON'] = 'ON' windows_defines['LLDB_PYTHON_HOME'] = 'python' - windows_defines['LLDB_PYTHON_RELATIVE_PATH'] = + windows_defines['LLDB_PYTHON_RELATIVE_PATH'] = \ 'bin/python/lib/python%s' % (self.build_config.LLDB_PY_VERSION) windows_defines['LLDB_PYTHON_EXE_RELATIVE_PATH'] = 'bin/python' windows_defines['LLDB_PYTHON_EXT_SUFFIX'] = '.pys' @@ -584,7 +585,6 @@ class LlvmCore(BuildUtils): def llvm_compile_windows_flags(self, windows_defines, - compiler_rt_path, windowstool_path, windows64_install, ldflags, @@ -654,7 +654,7 @@ class LlvmCore(BuildUtils): build_dir = self.merge_out_path("windows-x86_64") windowstool_path = self.merge_out_path('llvm-install') windows64_install = self.merge_out_path('windows-x86_64-install') - windows_sysroot = self.merge_out_path('mingw', 'x86_64-w64-mingw32') + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) self.check_create_dir(build_dir) @@ -674,7 +674,7 @@ class LlvmCore(BuildUtils): ldflags = [] cflags = [] - self.llvm_compile_windows_flags(windows_defines, compiler_rt_path, + self.llvm_compile_windows_flags(windows_defines, windowstool_path, windows64_install, ldflags, cflags) cxxflags = list(cflags) @@ -850,7 +850,7 @@ class LlvmLibs(BuildUtils): if llvm_build != llvm_triple: continue - has_lldb_server = arch not in ['riscv64'] + has_lldb_server = arch not in ['riscv64', 'mipsel'] defines = {} ldflags = [] @@ -859,6 +859,7 @@ class LlvmLibs(BuildUtils): self.build_libs_defines(llvm_triple, defines, cc, cxx, ar, llvm_config, ldflags, cflags, extra_flags) if arch == 'mipsel': ldflags.append('-Wl,-z,notext') + ldflags.append('-Wl,--no-check-dynamic-relocations') llvm_path = self.merge_out_path('llvm_make') arch_list = [self.liteos_triple('arm'), self.open_ohos_triple('arm'), @@ -982,6 +983,7 @@ class LlvmLibs(BuildUtils): crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' else: crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + crt_defines['COMPILER_RT_BUILD_ORC'] = 'OFF' crt_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' crt_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' crt_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' @@ -989,10 +991,7 @@ class LlvmLibs(BuildUtils): crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi' crt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' crt_defines['COMPILER_RT_HWASAN_WITH_INTERCEPTORS'] = 'OFF' - crt_defines['COMPILER_RT_BUILD_ORC'] = 'OFF' - crt_defines['COMPILER_RT_USE_LLVM_UNWINDER'] = 'ON' - - crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = + crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = \ 'OFF' if llvm_triple == self.liteos_triple('arm') or first_time else 'ON' crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = llvm_triple crt_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'compiler-rt')) @@ -1163,44 +1162,37 @@ class LlvmLibs(BuildUtils): self.llvm_package.copy_lldb_server_to_llvm_install(lldb_path, crt_install, llvm_triple) - @staticmethod - def build_libs_windows_cmake_defines(cmake_defines, toolchain_dir, windows_sysroot): - cmake_defines['CMAKE_C_COMPILER_WORKS'] = '1' - cmake_defines['CMAKE_CXX_COMPILER_WORKS'] = '1' - cmake_defines['CMAKE_SYSTEM_NAME'] = 'Windows' - cmake_defines['CMAKE_SYSTEM_PROCESSOR'] = 'x86_64' - cmake_defines['CMAKE_C_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang') - cmake_defines['CMAKE_CXX_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang++') - cmake_defines['LLVM_CONFIG_PATH'] = os.path.join(toolchain_dir, 'bin', 'llvm-config') - cmake_defines['LLVM_ENABLE_LIBCXX'] = 'ON' - cmake_defines['CMAKE_SYSROOT'] = windows_sysroot - cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' - cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' - cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' - cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' - def build_runtimes_for_windows(self, enable_assertions): self.logger().info('Building libs for windows.') toolchain_dir = self.merge_out_path('llvm-install') install_dir = self.merge_out_path('windows-x86_64-install') - windows_sysroot = self.merge_out_path('mingw', 'x86_64-w64-mingw32') + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) cflags = ['-stdlib=libc++', '--target=x86_64-pc-windows-gnu', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_WIN32_WINNT=0x0600', '-DWINVER=0x0600', '-D__MSVCRT_VERSION__=0x1400'] cmake_defines = {} - self.build_libs_windows_cmake_defines(cmake_defines, toolchain_dir, windows_sysroot) - + cmake_defines['CMAKE_C_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang') + cmake_defines['CMAKE_CXX_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang++') cmake_defines['CMAKE_CROSSCOMPILING'] = 'True' cmake_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + cmake_defines['CMAKE_SYSROOT'] = windows_sysroot cmake_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) cmake_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) cmake_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) - cmake_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) - cmake_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) - cmake_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + cmake_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + cmake_defines['CMAKE_INSTALL_PREFIX'] = install_dir + cmake_defines['LLVM_CONFIG_PATH'] = os.path.join(toolchain_dir, 'bin', 'llvm-config') + cmake_defines['LIBCXX_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + cmake_defines['LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS'] = 'ON' + cmake_defines['LIBCXXABI_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBUNWIND_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + cmake_defines['LLVM_ENABLE_RUNTIMES'] = 'libunwind;libcxxabi;libcxx' + cmake_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' if enable_assertions else 'OFF' out_path = self.merge_out_path('lib', 'windows-runtimes') cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'runtimes')) @@ -1277,7 +1269,6 @@ class LldbMi(BuildUtils): '-Wl,--nxcompat', '-lucrt', '-lucrtbase', - '-lpthread', '-L', ] return ldflags_lists @@ -1319,14 +1310,14 @@ class LldbMi(BuildUtils): def build_lldb_mi_for_windows(self): self.logger().info('Building lldb-mi for windows.') - build_dir = self.merge_out_path('clang_mingw', 'clang-10.0.1') + build_dir = self.merge_out_path('llvm-install') lldb_mi_windows64_path = self.merge_out_path('windows-x86_64-lldb-mi') lldb_mi_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi')) windows64_install = self.merge_out_path('windows-x86_64-install') cc = os.path.join(build_dir, 'bin', 'clang') cxx = os.path.join(build_dir, 'bin', 'clang++') - windows_sysroot = self.merge_out_path('mingw', 'x86_64-w64-mingw32') + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) self.check_create_dir(lldb_mi_windows64_path) ldflags = ['-fuse-ld=lld', diff --git a/llvm-build/mingw.py b/llvm-build/mingw.py index 830ad7ebeefa..78e1f5e5b217 100755 --- a/llvm-build/mingw.py +++ b/llvm-build/mingw.py @@ -28,6 +28,7 @@ class BuildConfig(): self.THIS_DIR = os.path.realpath(os.path.dirname(__file__)) self.OUT_DIR = os.environ.get('OUT_DIR', self.repo_root('out')) self.CLANG_VERSION = clang_version + self.LLVM_TRIPLE = 'x86_64-windows-gnu' def repo_root(self, *args): return os.path.realpath(os.path.join(self.THIS_DIR, '../../', *args)) @@ -36,7 +37,7 @@ class BuildConfig(): return os.path.realpath(os.path.join(self.OUT_DIR, *args)) def mingw64_dir(self): - return out_root('mingw', 'x86_64-w64-mingw32') + return self.out_root('mingw', self.LLVM_TRIPLE) def llvm_path(self, *args): return os.path.realpath(os.path.join(self.THIS_DIR, '../llvm-project', *args)) @@ -53,13 +54,12 @@ class LlvmMingw(): self.LLVM_ROOT = self.build_config.out_root('llvm-install') self.LLVM_CONFIG = os.path.join(self.LLVM_ROOT, 'bin', 'llvm-config') self.SYSROOT = self.build_config.mingw64_dir() - self.LLVM_TRIPLE = 'x86_64-windows-gnu' - self.CRT_PATH = self.build_config.out_root('lib', 'mingw-clangrt-%s' % llvm_triple) + self.CRT_PATH = self.build_config.out_root('lib', 'mingw-clangrt-%s' % self.build_config.LLVM_TRIPLE) self.CRT_INSTALL = self.build_config.out_root('llvm-install', 'lib', 'clang', self.build_config.CLANG_VERSION) # prefix & env self.prefix = build_config.mingw64_dir() common_flags = "-target x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libc++ \ - -fuse-ld=lld -Qunused-arguments -g -O2 --sysroot=" + mingw64_sysroot() + -fuse-ld=lld -Qunused-arguments -g -O2 --sysroot=" + self.build_config.mingw64_dir() self.env = { "CC": "%s/bin/clang" % self.LLVM_ROOT, "CXX": "%s/bin/clang++" % self.LLVM_ROOT, @@ -124,7 +124,7 @@ class LlvmMingw(): self.crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) self.update_cmake_sysroot_flags(self.crt_defines, self.SYSROOT) cflags = [ - '--target=%s' % self.LLVM_TRIPLE, + '--target=%s' % self.build_config.LLVM_TRIPLE, '-ffunction-sections', '-fdata-sections', ] @@ -134,8 +134,8 @@ class LlvmMingw(): self.crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) self.crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) self.crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags) - self.crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = self.LLVM_TRIPLE - self.crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = self.LLVM_TRIPLE + self.crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = self.build_config.LLVM_TRIPLE + self.crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = self.build_config.LLVM_TRIPLE self.crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'OFF' self.crt_defines['CMAKE_INSTALL_PREFIX'] = self.CRT_INSTALL self.crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' -- Gitee From ae9aa1e0a3b6042edea62060570647a1a3c04794 Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Tue, 1 Nov 2022 17:45:42 +0300 Subject: [PATCH 21/41] Fix issue in test case Signed-off-by: Ivan Eliseev --- clang/test/Driver/ohos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Driver/ohos.c b/clang/test/Driver/ohos.c index a38b83338ee0..480519c54112 100644 --- a/clang/test/Driver/ohos.c +++ b/clang/test/Driver/ohos.c @@ -58,7 +58,7 @@ // RUN: %clang %s -### --target=mipsel-linux-ohos -fuse-ld=lld 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME // RUN: %clang %s -### --target=x86_64-linux-ohos -fuse-ld=lld 2>&1 \ -// RUN: | FileCheck %s -check-pr +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME // CHECK-RUNTIME: "{{.*}}/libclang_rt.builtins.a" // CHECK-RUNTIME: "-l:libunwind.a" // CHECK-LIBM: "-lm" -- Gitee From 60543fb147d93b43587bfe3e32648ba8cc9a105f Mon Sep 17 00:00:00 2001 From: xwx1135370 Date: Thu, 3 Nov 2022 15:49:34 +0300 Subject: [PATCH 22/41] Fport rm message sent by lldb to hdc does not match Signed-off-by: Ivan Eliseev --- .../Plugins/Platform/OHOS/HdcClient.cpp | 22 ++++++- lldb/source/Plugins/Platform/OHOS/HdcClient.h | 3 + .../OHOS/PlatformOHOSRemoteGDBServer.cpp | 65 +++++++++++++++---- .../OHOS/PlatformOHOSRemoteGDBServer.h | 1 + 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp index 97fa08fb44da..6807d24cf317 100644 --- a/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp @@ -235,7 +235,27 @@ Status HdcClient::DeletePortForwarding(std::pair fwd) { if (error.Fail()) return error; - return ReadResponseStatus(nullptr); + 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, diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.h b/lldb/source/Plugins/Platform/OHOS/HdcClient.h index 64a5a324325a..39b6569b447a 100644 --- a/lldb/source/Plugins/Platform/OHOS/HdcClient.h +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.h @@ -51,6 +51,9 @@ public: 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); diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp index ab9c8b8bf306..40d5fae3f91b 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp @@ -70,6 +70,23 @@ static Status DeleteForwardPortWithHdc(std::pair ports, 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()); + if (!socket_namespace) + return Status("Invalid socket namespace"); + + HdcClient hdc(device_id); + return hdc.DeletePortForwarding(local_port, remote_socket_name, *socket_namespace); +} + static Status FindUnusedPort(uint16_t &port) { Status error; @@ -93,8 +110,12 @@ static Status FindUnusedPort(uint16_t &port) { PlatformOHOSRemoteGDBServer::PlatformOHOSRemoteGDBServer() {} PlatformOHOSRemoteGDBServer::~PlatformOHOSRemoteGDBServer() { - for (const auto &it : m_port_forwards) + 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, @@ -173,19 +194,30 @@ void PlatformOHOSRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) { Log *log = GetLog(LLDBLog::Platform); auto it = m_port_forwards.find(pid); - if (it == m_port_forwards.end()) - return; - - const auto port = it->second; - const auto error = DeleteForwardPortWithHdc(port, m_device_id); - if (error.Fail()) { - if (log) - log->Printf("Failed to delete port forwarding (pid=%" PRIu64 - ", fwd=(%d -> %d), device=%s): %s", - pid, port.first, port.second, m_device_id.c_str(), - error.AsCString()); + 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); } - m_port_forwards.erase(it); + + return; } Status PlatformOHOSRemoteGDBServer::MakeConnectURL( @@ -206,7 +238,12 @@ Status PlatformOHOSRemoteGDBServer::MakeConnectURL( error = ForwardPortWithHdc(local_port, remote_port, remote_socket_name, m_socket_namespace, m_device_id); if (error.Success()) { - m_port_forwards[pid] = {local_port, remote_port}; + 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(); diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h index f9818589275d..680ddc1e733c 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h @@ -41,6 +41,7 @@ public: protected: std::string m_device_id; std::map> m_port_forwards; + std::map> m_remote_socket_name; llvm::Optional m_socket_namespace; bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) override; -- Gitee From e915d14a59ddebcf8dfa86f4b614ec1b69afcc48 Mon Sep 17 00:00:00 2001 From: liwentao Date: Thu, 3 Nov 2022 16:08:16 +0300 Subject: [PATCH 23/41] !22 Add support for x86_64-linux-ohos target and m1 build, add some lldb bugfixs Author: @Anton @Pavel @Leviant @Nikolai Signed-off-by: Ivan Eliseev --- clang/lib/Driver/ToolChains/Gnu.cpp | 2 +- lldb/include/lldb/Target/Platform.h | 2 + .../Plugins/Platform/OHOS/PlatformOHOS.cpp | 43 +++++++++++++++---- .../Plugins/Platform/OHOS/PlatformOHOS.h | 7 ++- .../Process/Utility/InferiorCallPOSIX.cpp | 5 ++- lldb/source/Target/Platform.cpp | 4 ++ 6 files changed, 50 insertions(+), 13 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 9ea8db1a7255..f8dfb189eaf6 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -2210,7 +2210,7 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( "x86_64-redhat-linux", "x86_64-suse-linux", "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", "x86_64-unknown-linux", - "x86_64-amazon-linux"}; + "x86_64-amazon-linux", "x86_64-linux-ohos"}; static const char *const X32Triples[] = {"x86_64-linux-gnux32", "x86_64-pc-linux-gnux32"}; static const char *const X32LibDirs[] = {"/libx32", "/lib"}; diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index aa09b345e4e1..42f926ead21d 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -544,6 +544,8 @@ public: virtual Status Unlink(const FileSpec &file_spec); + virtual ConstString GetMmapSymbolName(const ArchSpec &arch); + virtual MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr, lldb::addr_t length, diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp index 86dda7741ac6..68ae66616b22 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -1,4 +1,4 @@ -//===-- PlatformOHOS.cpp -------------------------------------*- C++ -*-===// +//===-- 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. @@ -14,6 +14,7 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/UriParser.h" +#include "llvm/Config/config.h" #include "HdcClient.h" #include "PlatformOHOS.h" @@ -35,7 +36,7 @@ void PlatformOHOS::Initialize() { PlatformLinux::Initialize(); if (g_initialize_count++ == 0) { -#if defined(__OHOS_FAMILY__) +#if defined(__OHOS__) PlatformSP default_platform_sp(new PlatformOHOS(true)); default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); Platform::SetHostPlatform(default_platform_sp); @@ -111,7 +112,8 @@ PlatformSP PlatformOHOS::CreateInstance(bool force, const ArchSpec *arch) { return PlatformSP(); } -PlatformOHOS::PlatformOHOS(bool is_host) : PlatformLinux(is_host) {} +PlatformOHOS::PlatformOHOS(bool is_host) + : PlatformLinux(is_host), m_sdk_version(0) {} PlatformOHOS::~PlatformOHOS() {} @@ -120,8 +122,8 @@ llvm::StringRef PlatformOHOS::GetPluginNameStatic(bool is_host) { } const char *PlatformOHOS::GetPluginDescriptionStatic(bool is_host) { - return is_host ? "Local OpenHarmony OS user platform plug-in." : - "Remote OpenHarmony OS user platform plug-in."; + return is_host ? "Local Open HarmonyOS user platform plug-in." + : "Remote Open HarmonyOS user platform plug-in."; } llvm::StringRef PlatformOHOS::GetPluginName() { @@ -206,8 +208,10 @@ Status PlatformOHOS::DownloadModuleSlice(const FileSpec &src_file_spec, Status PlatformOHOS::DisconnectRemote() { Status error = PlatformLinux::DisconnectRemote(); - if (error.Success()) + if (error.Success()) { m_device_id.clear(); + m_sdk_version = 0; + } return error; } @@ -219,8 +223,25 @@ uint32_t PlatformOHOS::GetSdkVersion() { if (!IsConnected()) return 0; - // TBD - return 1; + if (m_sdk_version != 0) + return m_sdk_version; + + std::string version_string; + HdcClient hdc(m_device_id); + Status error = + hdc.Shell("getprop ro.build.version.sdk", seconds(5), &version_string); + version_string = llvm::StringRef(version_string).trim().str(); + + if (error.Fail() || version_string.empty()) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM); + if (log) + log->Printf("Get SDK version failed. (error: %s, output: %s)", + error.AsCString(), version_string.c_str()); + return 0; + } + + m_sdk_version = StringConvert::ToUInt32(version_string.c_str()); + return m_sdk_version; } bool PlatformOHOS::GetRemoteOSVersion() { @@ -254,3 +275,9 @@ PlatformOHOS::GetLibdlFunctionDeclarations(lldb_private::Process *process) { return PlatformPOSIX::GetLibdlFunctionDeclarations(process); } + +ConstString PlatformOHOS::GetMmapSymbolName(const ArchSpec &arch) { + return arch.GetTriple().isArch32Bit() + ? ConstString("__lldb_mmap") + : PlatformLinux::GetMmapSymbolName(arch); +} diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h index 78e4e187801f..83645ff209a5 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h @@ -1,4 +1,4 @@ -//===-- PlatformOHOS.h ---------------------------------------*- C++ -*-===// +//===-- 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. @@ -54,6 +54,8 @@ public: uint32_t GetDefaultMemoryCacheLineSize() override; + ConstString GetMmapSymbolName(const ArchSpec &arch) override; + protected: const char *GetCacheHostname() override; @@ -66,12 +68,13 @@ protected: private: std::string m_device_id; + uint32_t m_sdk_version; PlatformOHOS(const PlatformOHOS &other) = delete; PlatformOHOS& operator=(const PlatformOHOS &other) = delete; }; -} // namespace platofor_ohos +} // namespace platform_ohos } // namespace lldb_private #endif // liblldb_PlatformOHOS_h_ diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 5091f68a9acf..fb0ab2523190 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -46,9 +46,11 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, function_options.include_symbols = true; function_options.include_inlines = false; + const ArchSpec arch = process->GetTarget().GetArchitecture(); + auto mmap_name = process->GetTarget().GetPlatform()->GetMmapSymbolName(arch); SymbolContextList sc_list; process->GetTarget().GetImages().FindFunctions( - ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list); + mmap_name, eFunctionNameTypeFull, function_options, sc_list); const uint32_t count = sc_list.GetSize(); if (count > 0) { SymbolContext sc; @@ -91,7 +93,6 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, CompilerType void_ptr_type = type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid) .GetPointerType(); - const ArchSpec arch = process->GetTarget().GetArchitecture(); MmapArgList args = process->GetTarget().GetPlatform()->GetMmapArgumentList( arch, addr, length, prot_arg, flags, fd, offset); diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 559f7664c72e..ee472114de33 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -1262,6 +1262,10 @@ Status Platform::Unlink(const FileSpec &path) { return Status("unimplemented"); } +ConstString Platform::GetMmapSymbolName(const ArchSpec &) { + return ConstString("mmap"); +} + MmapArgList Platform::GetMmapArgumentList(const ArchSpec &arch, addr_t addr, addr_t length, unsigned prot, unsigned flags, addr_t fd, -- Gitee From f75f95e64217925cc1aed3b59228d4c4e42930f0 Mon Sep 17 00:00:00 2001 From: hhj Date: Thu, 3 Nov 2022 16:31:23 +0300 Subject: [PATCH 24/41] Use emulated-tls for ohos build Signed-off-by: Ivan Eliseev --- compiler-rt/lib/asan/asan_fake_stack.cpp | 3 ++- compiler-rt/lib/lsan/lsan_common.h | 3 ++- .../sanitizer_platform_interceptors.h | 2 +- llvm/include/llvm/ADT/Triple.h | 3 ++- llvm/test/CodeGen/AArch64/emutls.ll | 4 ++++ llvm/test/CodeGen/AArch64/emutls_generic.ll | 12 ++++++++++++ llvm/test/CodeGen/ARM/emutls.ll | 4 ++++ llvm/test/CodeGen/ARM/emutls_generic.ll | 4 ++++ llvm/test/CodeGen/X86/emutls-pic.ll | 4 ++++ llvm/test/CodeGen/X86/emutls-pie.ll | 8 ++++++++ llvm/test/CodeGen/X86/emutls.ll | 4 ++++ llvm/test/CodeGen/X86/emutls_generic.ll | 12 ++++++++++++ 12 files changed, 59 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/asan/asan_fake_stack.cpp b/compiler-rt/lib/asan/asan_fake_stack.cpp index 74a039b65798..d924427c508c 100644 --- a/compiler-rt/lib/asan/asan_fake_stack.cpp +++ b/compiler-rt/lib/asan/asan_fake_stack.cpp @@ -169,7 +169,8 @@ void FakeStack::ForEachFakeFrame(RangeIteratorCallback callback, void *arg) { } } -#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_FUCHSIA +#if (SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS) || \ + SANITIZER_FUCHSIA static THREADLOCAL FakeStack *fake_stack_tls; FakeStack *GetTLSFakeStack() { diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h index d7153751faee..2fc038b8fd14 100644 --- a/compiler-rt/lib/lsan/lsan_common.h +++ b/compiler-rt/lib/lsan/lsan_common.h @@ -32,7 +32,8 @@ // 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_OHOS || \ + (SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))) # define CAN_SANITIZE_LEAKS 0 #elif (SANITIZER_LINUX || SANITIZER_APPLE) && (SANITIZER_WORDSIZE == 64) && \ (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 0640991620af..b78534e8fc42 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -411,7 +411,7 @@ (SI_FREEBSD || SI_NETBSD || SI_GLIBC || SI_SOLARIS) #define SANITIZER_INTERCEPT_TLS_GET_ADDR \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || (SI_LINUX_NOT_ANDROID && !SI_OHOS) || SI_SOLARIS) #define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX #define SANITIZER_INTERCEPT_GETXATTR SI_LINUX diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index b2b79adc1f81..72657016efcf 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -931,7 +931,8 @@ public: /// Tests whether the target uses emulated TLS as default. bool hasDefaultEmulatedTLS() const { - return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment(); + return isOpenHOS() || isAndroid() || isOSOpenBSD() || + isWindowsCygwinEnvironment(); } /// Tests whether the target uses -data-sections as default. diff --git a/llvm/test/CodeGen/AArch64/emutls.ll b/llvm/test/CodeGen/AArch64/emutls.ll index 4fdc99d0b7e0..1ffcb03144d7 100644 --- a/llvm/test/CodeGen/AArch64/emutls.ll +++ b/llvm/test/CodeGen/AArch64/emutls.ll @@ -2,6 +2,10 @@ ; RUN: -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s ; RUN: llc -mtriple=aarch64-linux-android \ ; RUN: -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s +; RUN: llc -emulated-tls -mtriple=aarch64-linux-ohos \ +; RUN: -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s +; RUN: llc -mtriple=aarch64-linux-ohos \ +; RUN: -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s ; Copied from X86/emutls.ll diff --git a/llvm/test/CodeGen/AArch64/emutls_generic.ll b/llvm/test/CodeGen/AArch64/emutls_generic.ll index 840833972881..6b5819a7fc4e 100644 --- a/llvm/test/CodeGen/AArch64/emutls_generic.ll +++ b/llvm/test/CodeGen/AArch64/emutls_generic.ll @@ -8,6 +8,12 @@ ; RUN: | FileCheck -check-prefix=ARM_64 %s ; RUN: llc < %s -emulated-tls -mtriple=aarch64-apple-darwin -O3 \ ; RUN: | FileCheck -check-prefix=DARWIN %s +; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-ohos -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-ohos -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s ; RUN: llc < %s -mtriple=aarch64-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=ARM_64 %s @@ -18,6 +24,12 @@ ; aarch64-windows-gnu needs explicit -emulated-tls ; RUN: llc < %s -mtriple=aarch64-apple-darwin -O3 \ ; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=aarch64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -mtriple=aarch64-linux-ohos -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -mtriple=aarch64-linux-ohos -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s ; NoEMU-NOT: __emutls diff --git a/llvm/test/CodeGen/ARM/emutls.ll b/llvm/test/CodeGen/ARM/emutls.ll index 92b656d9ba09..29894a9efa7b 100644 --- a/llvm/test/CodeGen/ARM/emutls.ll +++ b/llvm/test/CodeGen/ARM/emutls.ll @@ -2,6 +2,10 @@ ; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s ; RUN: llc -mtriple=arm-linux-android \ ; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s +; RUN: llc -emulated-tls -mtriple=arm-linux-ohos \ +; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s +; RUN: llc -mtriple=arm-linux-ohos \ +; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s ; Copied from X86/emutls.ll diff --git a/llvm/test/CodeGen/ARM/emutls_generic.ll b/llvm/test/CodeGen/ARM/emutls_generic.ll index 8bf0ab301244..803462740f79 100644 --- a/llvm/test/CodeGen/ARM/emutls_generic.ll +++ b/llvm/test/CodeGen/ARM/emutls_generic.ll @@ -10,6 +10,8 @@ ; RUN: | FileCheck -check-prefix=DARWIN %s ; RUN: llc < %s -emulated-tls -mtriple=thumbv7-windows-gnu -O3 \ ; RUN: | FileCheck -check-prefix=WIN %s +; RUN: llc < %s -emulated-tls -mtriple=arm-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_32 %s ; RUN: llc < %s -mtriple=arm-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=ARM_32 %s @@ -21,6 +23,8 @@ ; RUN: | FileCheck -check-prefix=ARM_32 %s ; arm-apple-darwin must use -emulated-tls ; windows must use -emulated-tls +; RUN: llc < %s -mtriple=arm-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_32 %s ; Make sure that TLS symbols are emitted in expected order. diff --git a/llvm/test/CodeGen/X86/emutls-pic.ll b/llvm/test/CodeGen/X86/emutls-pic.ll index d5daa3b6677e..59c6f7b6debd 100644 --- a/llvm/test/CodeGen/X86/emutls-pic.ll +++ b/llvm/test/CodeGen/X86/emutls-pic.ll @@ -2,11 +2,15 @@ ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -emulated-tls -mtriple=i386-linux-ohos -relocation-model=pic | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-ohos -relocation-model=pic | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -mtriple=i386-linux-gnu -relocation-model=pic | FileCheck -check-prefix=NoEMU %s ; RUN: llc < %s -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=NoEMU %s ; RUN: llc < %s -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mtriple=i386-linux-ohos -relocation-model=pic | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -mtriple=x86_64-linux-ohos -relocation-model=pic | FileCheck -check-prefix=X64 %s ; NoEMU-NOT: __emutls diff --git a/llvm/test/CodeGen/X86/emutls-pie.ll b/llvm/test/CodeGen/X86/emutls-pie.ll index 8563eb3a50db..b205689ddb48 100644 --- a/llvm/test/CodeGen/X86/emutls-pie.ll +++ b/llvm/test/CodeGen/X86/emutls-pie.ll @@ -6,6 +6,10 @@ ; RUN: | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=i386-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=NoEMU %s @@ -15,6 +19,10 @@ ; RUN: | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X64 %s ; NoEMU-NOT: __emutls diff --git a/llvm/test/CodeGen/X86/emutls.ll b/llvm/test/CodeGen/X86/emutls.ll index a7fbc2d8531d..357eda32aa52 100644 --- a/llvm/test/CodeGen/X86/emutls.ll +++ b/llvm/test/CodeGen/X86/emutls.ll @@ -2,11 +2,15 @@ ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-android | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -emulated-tls -mtriple=i386-linux-ohos | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-ohos | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -mtriple=i386-linux-gnu | FileCheck -check-prefix=NoEMU %s ; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=NoEMU %s ; RUN: llc < %s -mtriple=i386-linux-android | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mtriple=i386-linux-ohos | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -mtriple=x86_64-linux-ohos | FileCheck -check-prefix=X64 %s ; Copied from tls.ll; emulated TLS model is not implemented ; for *-pc-win32 and *-pc-windows targets yet. diff --git a/llvm/test/CodeGen/X86/emutls_generic.ll b/llvm/test/CodeGen/X86/emutls_generic.ll index 3c3463c0bc8c..5e6c8deb5017 100644 --- a/llvm/test/CodeGen/X86/emutls_generic.ll +++ b/llvm/test/CodeGen/X86/emutls_generic.ll @@ -6,6 +6,12 @@ ; RUN: | FileCheck -check-prefix=X86_64 %s ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck %s +; RUN: llc < %s -emulated-tls -mtriple=i686-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -emulated-tls -mtriple=i686-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_64 %s ; RUN: llc < %s -mtriple=i686-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X86_32 %s @@ -15,6 +21,12 @@ ; RUN: | FileCheck -check-prefix=X86_64 %s ; RUN: llc < %s -mtriple=i386-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=i686-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -mtriple=i686-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -mtriple=x86_64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_64 %s ; NoEMU-NOT: __emutls -- Gitee From 0f7112f847a59953faeda8a62d135dd9c09fe984 Mon Sep 17 00:00:00 2001 From: xwx1135370 Date: Thu, 3 Nov 2022 16:38:46 +0300 Subject: [PATCH 25/41] Cleanup platform data upon disconnect Signed-off-by: Ivan Eliseev --- lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp index 68ae66616b22..ea4b62b2530f 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -211,6 +211,7 @@ Status PlatformOHOS::DisconnectRemote() { if (error.Success()) { m_device_id.clear(); m_sdk_version = 0; + m_remote_platform_sp.reset(); } return error; } -- Gitee From 74784c9e9535e8090914e23f0853bae359f7ca1f Mon Sep 17 00:00:00 2001 From: xwx1135370 Date: Thu, 3 Nov 2022 16:40:01 +0300 Subject: [PATCH 26/41] Use HDC_SERVER_PORT for adb connections Signed-off-by: Ivan Eliseev --- lldb/source/Plugins/Platform/Android/AdbClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.cpp b/lldb/source/Plugins/Platform/Android/AdbClient.cpp index 9af921f4843c..b7fdeff8a568 100644 --- a/lldb/source/Plugins/Platform/Android/AdbClient.cpp +++ b/lldb/source/Plugins/Platform/Android/AdbClient.cpp @@ -130,7 +130,7 @@ Status AdbClient::Connect() { Status error; m_conn = std::make_unique(); std::string port = "5037"; - if (const char *env_port = std::getenv("ANDROID_ADB_SERVER_PORT")) { + if (const char *env_port = std::getenv("HDC_SERVER_PORT")) { port = env_port; } std::string uri = "connect://127.0.0.1:" + port; -- Gitee From 380a403457df6d8a8d000c9d274f707404dc3f12 Mon Sep 17 00:00:00 2001 From: JinuineLi Date: Thu, 3 Nov 2022 16:42:25 +0300 Subject: [PATCH 27/41] add OpenHarmony Checkers UnixAPIArgsChecker: checks open() system call args MemcpyChecker: checks memcpy_s() system call args Signed-off-by: Ivan Eliseev --- .../clang/StaticAnalyzer/Checkers/Checkers.td | 16 ++ .../StaticAnalyzer/Checkers/CMakeLists.txt | 2 + .../Checkers/OpenHarmony/MemcpyChecker.cpp | 112 ++++++++ .../OpenHarmony/UnixAPIArgsChecker.cpp | 239 ++++++++++++++++++ clang/test/Analysis/memcpy_s.c | 51 ++++ clang/test/Analysis/unix-api.c | 26 ++ 6 files changed, 446 insertions(+) create mode 100644 clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp create mode 100644 clang/lib/StaticAnalyzer/Checkers/OpenHarmony/UnixAPIArgsChecker.cpp create mode 100644 clang/test/Analysis/memcpy_s.c diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index cf8cec3b13c3..3b1326ffc37e 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -120,6 +120,8 @@ def FuchsiaAlpha : Package<"fuchsia">, ParentPackage; def WebKit : Package<"webkit">; def WebKitAlpha : Package<"webkit">, ParentPackage; +def OpenHarmony : Package<"openharmony">; + //===----------------------------------------------------------------------===// // Core Checkers. //===----------------------------------------------------------------------===// @@ -1734,3 +1736,17 @@ def UncountedLocalVarsChecker : Checker<"UncountedLocalVarsChecker">, Documentation; } // end alpha.webkit + +//===----------------------------------------------------------------------===// +// OpenHarmony checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = OpenHarmony in { +def UnixAPIArgsChecker : Checker<"UnixAPIArgs">, + HelpText<"Check for open unix api arguments">, + Documentation; + +def MemcpyChecker : Checker<"Memcpy">, + HelpText<"Check for memcpy_s api arguments">, + Documentation; +} diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 84886b93d2e4..9a0c774b859a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -135,6 +135,8 @@ add_clang_library(clangStaticAnalyzerCheckers WebKit/UncountedCallArgsChecker.cpp WebKit/UncountedLambdaCapturesChecker.cpp WebKit/UncountedLocalVarsChecker.cpp + OpenHarmony/UnixAPIArgsChecker.cpp + OpenHarmony/MemcpyChecker.cpp LINK_LIBS clangAST diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp new file mode 100644 index 000000000000..0f80e0e458e0 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp @@ -0,0 +1,112 @@ +//== MemcpyChecker.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 +// +//===----------------------------------------------------------------------===// +// +// This file defines MemcpyChecker, which is a path-sensitive check +// looking for mismatch src and dest buffer length may cause buffer overflow. +// +//===----------------------------------------------------------------------===// + +#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, "Unsafe buffer operation", categories::UnixAPI)); + } + +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(); + if (!srcLengthDSVal) { + return; + } + + 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, "memcpy_s(): src length may be larger than dst length", ErrNode); + R->addRange(Call.getSourceRange()); + C.emitReport(std::move(R)); + return; + } +} +} + +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/lib/StaticAnalyzer/Checkers/OpenHarmony/UnixAPIArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/UnixAPIArgsChecker.cpp new file mode 100644 index 000000000000..c4747fcdfe33 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/UnixAPIArgsChecker.cpp @@ -0,0 +1,239 @@ +//== UnixAPIArgsChecker.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 +// +//===----------------------------------------------------------------------===// +// +// This defines UnixAPIArgsChecker, which is a path-sensitive checker +// looking for open a file with open() with GROUP and OTHER having +// write or execute permission +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; +using namespace ento; + +enum class OpenVariant { + /// The standard open() call: + /// int open(const char *pathname, int flags, mode_t mode); + Open, + + /// The variant taking a directory file descriptor and a relative path: + /// int openat(int fd, const char *pathname, int flags, mode_t mode); + OpenAt +}; + +namespace { +class UnixAPIArgsChecker : public Checker< check::PreStmt > { + mutable std::unique_ptr BT_open; + // value of O_CREAT flag + const uint64_t Val_O_CREAT = 0100; + // value of mode being checked + const uint64_t Val_MODE = 0133; + +public: + void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; + + void CheckOpen(CheckerContext &C, const CallExpr *CE) const; + void CheckOpenAt(CheckerContext &C, const CallExpr *CE) const; + + void CheckOpenVariant(CheckerContext &C, + const CallExpr *CE, OpenVariant Variant) const; + + void ReportOpenBug(CheckerContext &C, + ProgramStateRef State, + const char *Msg, + SourceRange SR) const; +}; +} //end anonymous namespace + +static void LazyInitialize(const CheckerBase *Checker, + std::unique_ptr &BT, + const char *name) { + if (BT) + return; + BT.reset(new BugType(Checker, name, categories::UnixAPI)); +} + +//===----------------------------------------------------------------------===// +// "open" (man 2 open) +//===----------------------------------------------------------------------===/ + +void UnixAPIArgsChecker::checkPreStmt(const CallExpr *CE, + CheckerContext &C) const { + const FunctionDecl *FD = C.getCalleeDecl(CE); + if (!FD || FD->getKind() != Decl::Function) + return; + + // Don't treat functions in namespaces with the same name a Unix function + // as a call to the Unix function. + const DeclContext *NamespaceCtx = FD->getEnclosingNamespaceContext(); + if (NamespaceCtx && isa(NamespaceCtx)) + return; + + StringRef FName = C.getCalleeName(FD); + if (FName.empty()) + return; + + if (FName == "open") + CheckOpen(C, CE); + + else if (FName == "openat") + CheckOpenAt(C, CE); +} +void UnixAPIArgsChecker::ReportOpenBug(CheckerContext &C, + ProgramStateRef State, + const char *Msg, + SourceRange SR) const { + ExplodedNode *N = C.generateErrorNode(State); + if (!N) + return; + + LazyInitialize(this, BT_open, "Improper use of 'open'"); + + auto Report = std::make_unique(*BT_open, Msg, N); + Report->addRange(SR); + C.emitReport(std::move(Report)); +} + +void UnixAPIArgsChecker::CheckOpen(CheckerContext &C, + const CallExpr *CE) const { + CheckOpenVariant(C, CE, OpenVariant::Open); +} + +void UnixAPIArgsChecker::CheckOpenAt(CheckerContext &C, + const CallExpr *CE) const { + CheckOpenVariant(C, CE, OpenVariant::OpenAt); +} + +void UnixAPIArgsChecker::CheckOpenVariant(CheckerContext &C, + const CallExpr *CE, + OpenVariant Variant) const { + // The index of the argument taking the flags open flags (O_RDONLY, + // O_WRONLY, O_CREAT, etc.), + unsigned int FlagsArgIndex; + switch (Variant) { + case OpenVariant::Open: + FlagsArgIndex = 1; + break; + case OpenVariant::OpenAt: + FlagsArgIndex = 2; + break; + }; + + // All calls should at least provide arguments up to the 'flags' parameter. + unsigned int MinArgCount = FlagsArgIndex + 1; + + // If the flags has O_CREAT set then open/openat() require an additional + // argument specifying the file mode (permission bits) for the created file. + unsigned int CreateModeArgIndex = FlagsArgIndex + 1; + + // The create mode argument should be the last argument. + unsigned int MaxArgCount = CreateModeArgIndex + 1; + + ProgramStateRef state = C.getState(); + + // Checked via UnixAPIChecker + if (CE->getNumArgs() < MinArgCount || CE->getNumArgs() > MaxArgCount) { + return; + } else if (CE->getNumArgs() == MaxArgCount) { + const Expr *Arg = CE->getArg(CreateModeArgIndex); + QualType QT = Arg->getType(); + if (!QT->isIntegerType()) { + return; + } + } + + // Now check if oflags has O_CREAT set. + const Expr *oflagsEx = CE->getArg(FlagsArgIndex); + const SVal V = C.getSVal(oflagsEx); + if (!V.getAs()) { + // The case where 'V' can be a location can only be due to a bad header, + // so in this case bail out. + return; + } + NonLoc oflags = V.castAs(); + NonLoc ocreateFlag = C.getSValBuilder() + .makeIntVal(Val_O_CREAT, oflagsEx->getType()).castAs(); + SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And, + oflags, ocreateFlag, + oflagsEx->getType()); + if (maskedFlagsUC.isUnknownOrUndef()) + return; + DefinedSVal maskedFlags = maskedFlagsUC.castAs(); + + // Check if maskedFlags is non-zero. + ProgramStateRef trueState, falseState; + std::tie(trueState, falseState) = state->assume(maskedFlags); + + // Only emit an error if the value of 'maskedFlags' is properly + // constrained; + if (!(trueState && !falseState)) + return; + + if (CE->getNumArgs() < MaxArgCount) { + return; + } + + // Now check mode when O_CREAT flag is set, GROUP and OTHER should not + // have write or execute permission + const Expr *createModeEx = CE->getArg(CreateModeArgIndex); + const SVal CM = C.getSVal(createModeEx); + if (!CM.getAs()) { + return; + } + NonLoc createMode = CM.castAs(); + NonLoc createModeCheck = C.getSValBuilder(). + makeIntVal(Val_MODE, createModeEx->getType()).castAs(); + + SVal maskedCreateMode = C.getSValBuilder().evalBinOpNN(state, BO_And, + createMode, createModeCheck, + createModeEx->getType()); + if (maskedCreateMode.isUnknownOrUndef()) + return; + DefinedSVal maskedCreateModeSVal = maskedCreateMode.castAs(); + + // Check if maskedFlags is non-zero. + ProgramStateRef t, f; + std::tie(t, f) = state->assume(maskedCreateModeSVal); + + // Only emit an error if the value of 'maskedFlags' is properly + // constrained; + if (t && !f) { + SmallString<256> SBuf; + llvm::raw_svector_ostream OS(SBuf); + OS << "Open() system call, GROUP/OTHER should not have write or execute permission"; + ReportOpenBug(C, t, + SBuf.c_str(), + createModeEx->getSourceRange()); + } +} + +//===----------------------------------------------------------------------===// +// Registration. +//===----------------------------------------------------------------------===// + +#define REGISTER_CHECKER(CHECKERNAME) \ + void ento::register##CHECKERNAME(CheckerManager &mgr) { \ + mgr.registerChecker(); \ + } \ + \ + bool ento::shouldRegister##CHECKERNAME(const CheckerManager &mgr) { \ + return true; \ + } + +REGISTER_CHECKER(UnixAPIArgsChecker) diff --git a/clang/test/Analysis/memcpy_s.c b/clang/test/Analysis/memcpy_s.c new file mode 100644 index 000000000000..e040e181bd90 --- /dev/null +++ b/clang/test/Analysis/memcpy_s.c @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// 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 +//===----------------------------------------------------------------------===// + +#define __STDC_WANT_LIB_EXT1__ 1 +#include +#include +#include +#include +#include + +int memcpy_s(char *dst, int dstLen, char *src, int srcLen) { + return dstLen; +} + +void check1(int dstLen, int srcLen) { + char dstStr[dstLen]; + char srcStr[srcLen]; + memcpy_s(dstStr, sizeof(dstStr), srcStr, srcLen); // expected-warning{{src length may be larger than dst length}} +} + +void check2() { + int dstLen = 20; + int srcLen = 10; + char dstStr[dstLen]; + char srcStr[srcLen]; + memcpy_s(dstStr, sizeof(dstStr), srcStr, srcLen); // no-warning +} + +void check3() { + int dstLen = 10; + int srcLen = 20; + char dstStr[dstLen]; + char srcStr[srcLen]; + memcpy_s(dstStr, sizeof(dstStr), srcStr, srcLen); // expected-warning{{src length may be larger than dst length}} +} + +void check4() { + int dstLen = 20; + int srcLen = 10; + char dstStr[dstLen]; + char srcStr[srcLen]; + int offset = 15; + // srcLen > dstStr[offset]'s length, bug reported + memcpy_s(&dstStr[offset], srcLen, srcStr, srcLen); // expected-warning{{src length may be larger than dst length}} + offset = 5; + // srcLen < dstStr[offset]'s length, no bug reported + memcpy_s(&dstStr[offset], srcLen, srcStr, srcLen); // no-warning +} diff --git a/clang/test/Analysis/unix-api.c b/clang/test/Analysis/unix-api.c index 64ff3c0fccf4..722702fc0c89 100644 --- a/clang/test/Analysis/unix-api.c +++ b/clang/test/Analysis/unix-api.c @@ -1,9 +1,19 @@ +//===----------------------------------------------------------------------===// +// 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 +//===----------------------------------------------------------------------===// + // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API -verify %s #ifndef O_RDONLY #define O_RDONLY 0 #endif +#ifndef O_CREAT +#define O_CREAT 0100 +#endif + #ifndef NULL #define NULL ((void*) 0) #endif @@ -90,3 +100,19 @@ void open_8(const char *path) { if (fd > -1) close(fd); } + +void open_9(const char *path) { + int fd; + int mode = 0631; + fd = open(path, O_CREAT, mode); // expected-warning{{Open() system call, GROUP/OTHER should not have write or execute permission}} + if (fd > -1) + close(fd); +} + +void open_10(const char *path) { + int fd; + int mode = 0644; + fd = open(path, O_CREAT, mode); // no-warning + if (fd > -1) + close(fd); +} \ No newline at end of file -- Gitee From 6a05c4fe9a121a89090a34169bebf13505f54690 Mon Sep 17 00:00:00 2001 From: Sukhikh Alexander Date: Thu, 3 Nov 2022 16:47:18 +0300 Subject: [PATCH 28/41] Fix tests Driver/ohos.cpp Signed-off-by: Ivan Eliseev --- .../llvm/lib/arm-liteos-ohos/c++/a7_hard_neon-vfpv4/libc++.so | 0 .../llvm/lib/arm-liteos-ohos/c++/a7_soft/libc++.so | 0 .../llvm/lib/arm-liteos-ohos/c++/a7_softfp_neon-vfpv4/libc++.so | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_hard_neon-vfpv4/libc++.so create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_soft/libc++.so create mode 100644 clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_softfp_neon-vfpv4/libc++.so diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_hard_neon-vfpv4/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_hard_neon-vfpv4/libc++.so new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_soft/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_soft/libc++.so new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_softfp_neon-vfpv4/libc++.so b/clang/test/Driver/Inputs/ohos_native_tree/llvm/lib/arm-liteos-ohos/c++/a7_softfp_neon-vfpv4/libc++.so new file mode 100644 index 000000000000..e69de29bb2d1 -- Gitee From 2161f13ce70c2bcf38bf77f553df7d49669124e1 Mon Sep 17 00:00:00 2001 From: Sukhikh Alexander Date: Thu, 3 Nov 2022 17:33:06 +0300 Subject: [PATCH 29/41] Fixes to run lldb tests on remote target Signed-off-by: Ivan Eliseev --- .../Python/lldbsuite/test/concurrent_base.py | 2 +- .../Python/lldbsuite/test/lldbtest.py | 100 +++++++++--------- .../tools/lldb-server/gdbremote_testcase.py | 8 +- .../lldb-server/TestGdbRemoteCompletion.py | 6 +- 4 files changed, 61 insertions(+), 55 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/concurrent_base.py b/lldb/packages/Python/lldbsuite/test/concurrent_base.py index 6acd71ce9e46..bb33d05da216 100644 --- a/lldb/packages/Python/lldbsuite/test/concurrent_base.py +++ b/lldb/packages/Python/lldbsuite/test/concurrent_base.py @@ -76,7 +76,7 @@ class ConcurrentEventsBase(TestBase): bp = self.inferior_target.FindBreakpointByID(bpno) descriptions.append( ": file = 'main.cpp', line = %d" % - self.finish_breakpoint_line) + line) return bp def inferior_done(self): diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index d6c249d644b1..2889030cc21f 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -892,6 +892,56 @@ class Base(unittest2.TestCase): self.subprocesses.append(proc) return proc + def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False): + """ + Ask the command interpreter to handle the command and then check its + return status. + """ + # Fail fast if 'cmd' is not meaningful. + if cmd is None: + raise Exception("Bad 'cmd' parameter encountered") + + trace = (True if traceAlways else trace) + + if cmd.startswith("target create "): + cmd = cmd.replace("target create ", "file ") + + running = (cmd.startswith("run") or cmd.startswith("process launch")) + + for i in range(self.maxLaunchCount if running else 1): + self.ci.HandleCommand(cmd, self.res, inHistory) + + with recording(self, trace) as sbuf: + print("runCmd:", cmd, file=sbuf) + if not check: + print("check of return status not required", file=sbuf) + if self.res.Succeeded(): + print("output:", self.res.GetOutput(), file=sbuf) + else: + print("runCmd failed!", file=sbuf) + print(self.res.GetError(), file=sbuf) + + if self.res.Succeeded(): + break + elif running: + # For process launch, wait some time before possible next try. + time.sleep(self.timeWaitNextLaunch) + with recording(self, trace) as sbuf: + print("Command '" + cmd + "' failed!", file=sbuf) + + if check: + output = "" + if self.res.GetOutput(): + output += "\nCommand output:\n" + self.res.GetOutput() + if self.res.GetError(): + output += "\nError output:\n" + self.res.GetError() + if msg: + msg += output + if cmd: + cmd += output + self.assertTrue(self.res.Succeeded(), + msg if (msg) else CMD_MSG(cmd)) + def HideStdout(self): """Hide output to stdout from the user. @@ -1942,56 +1992,6 @@ class TestBase(Base): if matched: self.runCmd('thread select %s' % matched.group(1)) - def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False): - """ - Ask the command interpreter to handle the command and then check its - return status. - """ - # Fail fast if 'cmd' is not meaningful. - if cmd is None: - raise Exception("Bad 'cmd' parameter encountered") - - trace = (True if traceAlways else trace) - - if cmd.startswith("target create "): - cmd = cmd.replace("target create ", "file ") - - running = (cmd.startswith("run") or cmd.startswith("process launch")) - - for i in range(self.maxLaunchCount if running else 1): - self.ci.HandleCommand(cmd, self.res, inHistory) - - with recording(self, trace) as sbuf: - print("runCmd:", cmd, file=sbuf) - if not check: - print("check of return status not required", file=sbuf) - if self.res.Succeeded(): - print("output:", self.res.GetOutput(), file=sbuf) - else: - print("runCmd failed!", file=sbuf) - print(self.res.GetError(), file=sbuf) - - if self.res.Succeeded(): - break - elif running: - # For process launch, wait some time before possible next try. - time.sleep(self.timeWaitNextLaunch) - with recording(self, trace) as sbuf: - print("Command '" + cmd + "' failed!", file=sbuf) - - if check: - output = "" - if self.res.GetOutput(): - output += "\nCommand output:\n" + self.res.GetOutput() - if self.res.GetError(): - output += "\nError output:\n" + self.res.GetError() - if msg: - msg += output - if cmd: - cmd += output - self.assertTrue(self.res.Succeeded(), - msg if (msg) else CMD_MSG(cmd)) - def match( self, str, diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py index df1fd2cb71b6..794f4170832c 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -139,7 +139,9 @@ class GdbRemoteTestCaseBase(Base): if configuration.lldb_platform_url.startswith('unix-'): url_pattern = '(.+)://\[?(.+?)\]?/.*' else: - url_pattern = '(.+)://(.+):\d+' + # use (.*) for host instead of (.+) because + # 'connect://:port' - is a valid way to connect to lldb-server + url_pattern = '(.+)://(.*):\d+' scheme, host = re.match( url_pattern, configuration.lldb_platform_url).groups() if configuration.lldb_platform_name == 'remote-android' and host != 'localhost': @@ -274,8 +276,8 @@ class GdbRemoteTestCaseBase(Base): logger = self.logger - triple = self.dbg.GetSelectedPlatform().GetTriple() - if re.match(".*-.*-.*-android", triple): + # TODO: forward port always when use adb connection + if configuration.lldb_platform_name == 'remote-android': self.forward_adb_port( self.port, self.port, diff --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py index 820bdab6e850..64c2b62c3fef 100644 --- a/lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py +++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py @@ -1,4 +1,5 @@ import tempfile +import os import gdbremote_testcase from lldbsuite.test.lldbtest import * from lldbsuite.test.decorators import * @@ -10,7 +11,10 @@ class GdbRemoteCompletionTestCase(gdbremote_testcase.GdbRemoteTestCaseBase): self.debug_monitor_exe = get_lldb_server_exe() if not self.debug_monitor_exe: self.skipTest("lldb-server exe not found") - port_file = tempfile.NamedTemporaryFile().name + port_file = os.path.join( + lldb.remote_platform.GetWorkingDirectory(), + 'connect.sock' + ) if lldb.remote_platform else tempfile.NamedTemporaryFile().name commandline_args = [ "platform", "--listen", -- Gitee From 0e923bf7dc78719a46897b4eaf599e881d2a4e3b Mon Sep 17 00:00:00 2001 From: yaofeng wang Date: Thu, 3 Nov 2022 17:37:38 +0300 Subject: [PATCH 30/41] fix longtime waiting while attach to remote process Signed-off-by: Ivan Eliseev --- lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp index ea4b62b2530f..73c4321ab650 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -29,6 +29,7 @@ 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. +static constexpr uint32_t INVALID_SDK_VERSION = 0xFFFFFFFF; LLDB_PLUGIN_DEFINE(PlatformOHOS) @@ -230,7 +231,7 @@ uint32_t PlatformOHOS::GetSdkVersion() { std::string version_string; HdcClient hdc(m_device_id); Status error = - hdc.Shell("getprop ro.build.version.sdk", seconds(5), &version_string); + hdc.Shell("param get const.ohos.apiversion", seconds(5), &version_string); version_string = llvm::StringRef(version_string).trim().str(); if (error.Fail() || version_string.empty()) { @@ -238,10 +239,15 @@ uint32_t PlatformOHOS::GetSdkVersion() { if (log) log->Printf("Get SDK version failed. (error: %s, output: %s)", error.AsCString(), version_string.c_str()); + m_sdk_version = INVALID_SDK_VERSION; + return 0; + } + + m_sdk_version = StringConvert::ToUInt32(version_string.c_str(), INVALID_SDK_VERSION); + if (m_sdk_version == INVALID_SDK_VERSION) { return 0; } - m_sdk_version = StringConvert::ToUInt32(version_string.c_str()); return m_sdk_version; } -- Gitee From 080960a658346ee01b19906c29fa23ce3227e80f Mon Sep 17 00:00:00 2001 From: dhy308 Date: Thu, 3 Nov 2022 17:40:04 +0300 Subject: [PATCH 31/41] fix issues after enabling emutls feature Signed-off-by: Ivan Eliseev --- compiler-rt/lib/builtins/emutls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/builtins/emutls.c b/compiler-rt/lib/builtins/emutls.c index 390ffb25f6cf..8ff6c86427f5 100644 --- a/compiler-rt/lib/builtins/emutls.c +++ b/compiler-rt/lib/builtins/emutls.c @@ -12,7 +12,7 @@ #include "int_lib.h" -#ifdef __BIONIC__ +#if defined(__BIONIC__) || defined(__OHOS__) // There are 4 pthread key cleanup rounds on Bionic. Delay emutls deallocation // to round 2. We need to delay deallocation because: // - Android versions older than M lack __cxa_thread_atexit_impl, so apps @@ -397,7 +397,7 @@ void *__emutls_get_address(__emutls_control *control) { return array->data[index]; } -#ifdef __BIONIC__ +#if defined(__BIONIC__) || defined(__OHOS__) // Called by Bionic on dlclose to delete the emutls pthread key. __attribute__((visibility("hidden"))) void __emutls_unregister_key(void) { if (emutls_key_created) { -- Gitee From 7193c6ada01521d4de3dd2abceea14f44efe90db Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Thu, 3 Nov 2022 18:01:37 +0300 Subject: [PATCH 32/41] Don't use -mrelax on RISV Signed-off-by: Ivan Eliseev --- clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index de6e045a9447..8b0f76e66965 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -138,7 +138,10 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back("+reserve-x31"); // -mrelax is default, unless -mno-relax is specified. - if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) { + // lld does not support relocations used by -mrelax on RISC-V + bool DefaultMRelax = !Triple.isOpenHOS(); + if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, DefaultMRelax)) + if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, DefaultMRelax)) { Features.push_back("+relax"); // -gsplit-dwarf -mrelax requires DW_AT_high_pc/DW_AT_ranges/... indexing // into .debug_addr, which is currently not implemented. -- Gitee From fcb05d29b1d8871829fe9c7786af1c64547a5ab8 Mon Sep 17 00:00:00 2001 From: kosovpavel Date: Thu, 3 Nov 2022 18:03:24 +0300 Subject: [PATCH 33/41] [OHOS] Fix tests for code checker Signed-off-by: Ivan Eliseev --- clang/test/Analysis/memcpy_s.c | 39 +++++++++++----------------------- clang/test/Analysis/unix-api.c | 2 +- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/clang/test/Analysis/memcpy_s.c b/clang/test/Analysis/memcpy_s.c index e040e181bd90..d945a4b4a969 100644 --- a/clang/test/Analysis/memcpy_s.c +++ b/clang/test/Analysis/memcpy_s.c @@ -4,12 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception //===----------------------------------------------------------------------===// -#define __STDC_WANT_LIB_EXT1__ 1 -#include -#include -#include -#include -#include +// RUN: %clang_analyze_cc1 -analyzer-checker=openharmony -verify %s int memcpy_s(char *dst, int dstLen, char *src, int srcLen) { return dstLen; @@ -18,34 +13,24 @@ int memcpy_s(char *dst, int dstLen, char *src, int srcLen) { void check1(int dstLen, int srcLen) { char dstStr[dstLen]; char srcStr[srcLen]; - memcpy_s(dstStr, sizeof(dstStr), srcStr, srcLen); // expected-warning{{src length may be larger than dst length}} + memcpy_s(dstStr, sizeof(dstStr), srcStr, srcLen); // expected-warning{{memcpy_s(): src length may be larger than dst length}} } void check2() { - int dstLen = 20; - int srcLen = 10; - char dstStr[dstLen]; - char srcStr[srcLen]; - memcpy_s(dstStr, sizeof(dstStr), srcStr, srcLen); // no-warning + char dstStr[20]; + char srcStr[10]; + memcpy_s(dstStr, sizeof(dstStr), srcStr, 10); // no-warning } void check3() { - int dstLen = 10; - int srcLen = 20; - char dstStr[dstLen]; - char srcStr[srcLen]; - memcpy_s(dstStr, sizeof(dstStr), srcStr, srcLen); // expected-warning{{src length may be larger than dst length}} + char dstStr[10]; + char srcStr[20]; + memcpy_s(dstStr, sizeof(dstStr), srcStr, 20); // expected-warning{{memcpy_s(): src length may be larger than dst length}} } void check4() { - int dstLen = 20; - int srcLen = 10; - char dstStr[dstLen]; - char srcStr[srcLen]; - int offset = 15; - // srcLen > dstStr[offset]'s length, bug reported - memcpy_s(&dstStr[offset], srcLen, srcStr, srcLen); // expected-warning{{src length may be larger than dst length}} - offset = 5; - // srcLen < dstStr[offset]'s length, no bug reported - memcpy_s(&dstStr[offset], srcLen, srcStr, srcLen); // no-warning + char dstStr[20]; + char srcStr[10]; + memcpy_s(&dstStr[15], 10, srcStr, 10); // expected-warning{{memcpy_s(): src length may be larger than dst length}} + memcpy_s(&dstStr[5], 10, srcStr, 10); // no-warning } diff --git a/clang/test/Analysis/unix-api.c b/clang/test/Analysis/unix-api.c index 722702fc0c89..4adca811bfee 100644 --- a/clang/test/Analysis/unix-api.c +++ b/clang/test/Analysis/unix-api.c @@ -4,7 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception //===----------------------------------------------------------------------===// -// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API,openharmony -verify %s #ifndef O_RDONLY #define O_RDONLY 0 -- Gitee From 7fc2504b85a6c8f40983b18bede6156321ea7509 Mon Sep 17 00:00:00 2001 From: xwx1135370 Date: Thu, 3 Nov 2022 18:31:26 +0300 Subject: [PATCH 34/41] Add HOS lldb platform and related codes, add m_container option Signed-off-by: Ivan Eliseev --- .../lldb/Interpreter/OptionGroupPlatform.h | 5 + lldb/include/lldb/Target/Platform.h | 5 + .../Interpreter/OptionGroupPlatform.cpp | 34 +- .../Plugins/Platform/Android/AdbClient.cpp | 2 +- lldb/source/Plugins/Platform/CMakeLists.txt | 1 + .../Plugins/Platform/HOS/CMakeLists.txt | 5 + .../source/Plugins/Platform/HOS/HdcClient.cpp | 808 ++++++++++++++++++ lldb/source/Plugins/Platform/HOS/HdcClient.h | 138 +++ .../Plugins/Platform/HOS/PlatformHOS.cpp | 466 ++++++++++ .../source/Plugins/Platform/HOS/PlatformHOS.h | 82 ++ .../HOS/PlatformHOSRemoteGDBServer.cpp | 244 ++++++ .../Platform/HOS/PlatformHOSRemoteGDBServer.h | 65 ++ lldb/source/Target/Platform.cpp | 7 +- 13 files changed, 1858 insertions(+), 4 deletions(-) create mode 100644 lldb/source/Plugins/Platform/HOS/CMakeLists.txt create mode 100644 lldb/source/Plugins/Platform/HOS/HdcClient.cpp create mode 100644 lldb/source/Plugins/Platform/HOS/HdcClient.h create mode 100644 lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp create mode 100644 lldb/source/Plugins/Platform/HOS/PlatformHOS.h create mode 100644 lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.cpp create mode 100644 lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.h diff --git a/lldb/include/lldb/Interpreter/OptionGroupPlatform.h b/lldb/include/lldb/Interpreter/OptionGroupPlatform.h index fed2791a6130..c67416809314 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupPlatform.h +++ b/lldb/include/lldb/Interpreter/OptionGroupPlatform.h @@ -56,6 +56,10 @@ public: ConstString GetSDKBuild() const { return m_sdk_build; } void SetSDKBuild(ConstString sdk_build) { m_sdk_build = sdk_build; } + + bool GetContainer() const { return m_container; } + + void SetContainer(bool b_container) { m_container = b_container; } bool PlatformMatches(const lldb::PlatformSP &platform_sp) const; @@ -63,6 +67,7 @@ protected: std::string m_platform_name; ConstString m_sdk_sysroot; ConstString m_sdk_build; + bool m_container; llvm::VersionTuple m_os_version; bool m_include_platform_option; }; diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index 42f926ead21d..997472c59126 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -455,6 +455,10 @@ public: void SetSDKBuild(ConstString sdk_build) { m_sdk_build = sdk_build; } + void SetContainer(bool b_container) { m_container = b_container; } + + bool GetContainer() const { return m_container; } + // Override this to return true if your platform supports Clang modules. You // may also need to override AddClangModuleCompilationOptions to pass the // right Clang flags for your platform. @@ -876,6 +880,7 @@ protected: ConstString m_sdk_sysroot; // the root location of where the SDK files are all located ConstString m_sdk_build; + bool m_container; FileSpec m_working_dir; // The working directory which is used when installing // modules that have no install path set std::string m_remote_url; diff --git a/lldb/source/Interpreter/OptionGroupPlatform.cpp b/lldb/source/Interpreter/OptionGroupPlatform.cpp index acdf3f293496..4d8668fdb41e 100644 --- a/lldb/source/Interpreter/OptionGroupPlatform.cpp +++ b/lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -21,7 +21,10 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( PlatformList &platforms = interpreter.GetDebugger().GetPlatformList(); PlatformSP platform_sp; - + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMANDS)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d OptionGroupPlatform::%s call make_selected:%d", __FILE__, __LINE__, __FUNCTION__, make_selected); + } if (!m_platform_name.empty()) { platform_sp = platforms.Create(m_platform_name); if (!platform_sp) { @@ -65,6 +68,7 @@ void OptionGroupPlatform::OptionParsingStarting( m_sdk_sysroot.Clear(); m_sdk_build.Clear(); m_os_version = llvm::VersionTuple(); + m_container = false; } static constexpr OptionDefinition g_option_table[] = { @@ -78,6 +82,9 @@ static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_ALL, false, "build", 'b', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "Specify the initial SDK build number."}, + {LLDB_OPT_SET_ALL, false, "contain", 'c', OptionParser::eRequiredArgument, + nullptr, {}, 0, eArgTypeNone, + "Specifies whether the application is in a container."}, {LLDB_OPT_SET_ALL, false, "sysroot", 'S', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Specify the SDK root directory " "that contains a root of all " @@ -99,7 +106,10 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx, ++option_idx; const int short_option = g_option_table[option_idx].short_option; - + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMANDS)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d OptionGroupPlatform::%s short_option: %d", __FILE__, __LINE__, __FUNCTION__, short_option); + } switch (short_option) { case 'p': m_platform_name.assign(std::string(option_arg)); @@ -114,6 +124,23 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx, case 'b': m_sdk_build.SetString(option_arg); break; + + case 'c': + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d OptionGroupPlatform::%s option_arg:-c %s", __FILE__, __LINE__, __FUNCTION__, option_arg.str().c_str()); + } + + if (std::string(option_arg) == "true") { + m_container = true; + } + else { + m_container = false; + } + + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d OptionGroupPlatform::%s m_container:%d", __FILE__, __LINE__, __FUNCTION__, m_container); + } + break; case 'S': m_sdk_sysroot.SetString(option_arg); @@ -141,6 +168,9 @@ bool OptionGroupPlatform::PlatformMatches( if (!m_os_version.empty() && m_os_version != platform_sp->GetOSVersion()) return false; + + if (m_container != platform_sp->GetContainer()) + return false; return true; } return false; diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.cpp b/lldb/source/Plugins/Platform/Android/AdbClient.cpp index b7fdeff8a568..9af921f4843c 100644 --- a/lldb/source/Plugins/Platform/Android/AdbClient.cpp +++ b/lldb/source/Plugins/Platform/Android/AdbClient.cpp @@ -130,7 +130,7 @@ Status AdbClient::Connect() { Status error; m_conn = std::make_unique(); std::string port = "5037"; - if (const char *env_port = std::getenv("HDC_SERVER_PORT")) { + if (const char *env_port = std::getenv("ANDROID_ADB_SERVER_PORT")) { port = env_port; } std::string uri = "connect://127.0.0.1:" + port; diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt index 8ff59c124f75..c2c5c9f73be5 100644 --- a/lldb/source/Plugins/Platform/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/CMakeLists.txt @@ -8,4 +8,5 @@ add_subdirectory(OpenBSD) add_subdirectory(POSIX) add_subdirectory(QemuUser) add_subdirectory(Windows) +add_subdirectory(HOS) add_subdirectory(OHOS) diff --git a/lldb/source/Plugins/Platform/HOS/CMakeLists.txt b/lldb/source/Plugins/Platform/HOS/CMakeLists.txt new file mode 100644 index 000000000000..5219c0cea666 --- /dev/null +++ b/lldb/source/Plugins/Platform/HOS/CMakeLists.txt @@ -0,0 +1,5 @@ +add_lldb_library(lldbPluginPlatformHOS PLUGIN HdcClient.cpp PlatformHOS + .cpp PlatformHOSRemoteGDBServer.cpp + + LINK_LIBS lldbCore lldbHost lldbPluginPlatformLinux + lldbPluginPlatformGDB LINK_COMPONENTS Support) \ No newline at end of file diff --git a/lldb/source/Plugins/Platform/HOS/HdcClient.cpp b/lldb/source/Plugins/Platform/HOS/HdcClient.cpp new file mode 100644 index 000000000000..609673b19b2c --- /dev/null +++ b/lldb/source/Plugins/Platform/HOS/HdcClient.cpp @@ -0,0 +1,808 @@ +//===-- 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/Log.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timeout.h" + +#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_hos; +using namespace std::chrono; + +namespace { + +const seconds kReadTimeout(20); +const char *kOKAY = "OKAY"; +const char *kFAIL = "FAIL"; +const char *kDATA = "DATA"; +const char *kDONE = "DONE"; + +const char *kSEND = "SEND"; +const char *kRECV = "RECV"; +const char *kSTAT = "STAT"; + +const size_t kSyncPacketLen = 8; +// Maximum size of a filesync DATA packet. +const size_t kMaxPushData = 2 * 1024; +// Default mode for pushed files. +const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG + +const char *kSocketNamespaceAbstract = "localabstract"; +const char *kSocketNamespaceFileSystem = "localfilesystem"; + +Status ReadAllBytes(Connection &conn, void *buffer, size_t size) { + + 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 (error.Fail()) + return error; + total_read_bytes += 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; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s device_id(%s)", __FILE__, + __LINE__, __FUNCTION__, device_id.c_str()); + } + std::string android_serial; + if (!device_id.empty()) + android_serial = device_id; + else if (const char *env_serial = std::getenv("ANDROID_SERIAL")) + android_serial = env_serial; + + if (android_serial.empty()) { + if (connect_devices.size() != 1) + return Status("Expected a single connected device, got instead %zu - try " + "setting 'ANDROID_SERIAL'", + connect_devices.size()); + hdc.SetDeviceID(connect_devices.front()); + } else { + auto find_it = std::find(connect_devices.begin(), connect_devices.end(), + android_serial); + if (find_it == connect_devices.end()) + return Status("Device \"%s\" not found", android_serial.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; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s m_device_id(%s)", __FILE__, + __LINE__, __FUNCTION__, m_device_id.c_str()); + } +} + +const std::string &HdcClient::GetDeviceID() const { return m_device_id; } + +Status HdcClient::Connect() { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s new ConnectionFileDescriptor", + __FILE__, __LINE__, __FUNCTION__); + } + Status error; + m_conn.reset(new ConnectionFileDescriptor); + std::string port = "5037"; + + const char *env_port = std::getenv("HDC_SERVER_PORT"); + if ((env_port != NULL) && (atoi(env_port) > 0)) { + port = env_port; + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s env_port(%s) port(%s)", + __FILE__, __LINE__, __FUNCTION__, env_port, port.c_str()); + } + } + + std::string uri = "connect://127.0.0.1:" + port; + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s uri(%s)", __FILE__, __LINE__, + __FUNCTION__, uri.c_str()); + } + m_conn->Connect(uri.c_str(), &error); + + return error; +} + +Status HdcClient::GetDevices(DeviceIDList &device_list) { + device_list.clear(); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s call", __FILE__, __LINE__, + __FUNCTION__); + } + auto error = SendMessage("host:devices"); + if (error.Fail()) + return error; + + error = ReadResponseStatus(); + 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(device.split('\t').first.str()); + + // Force disconnect since hdc 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) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s local_port(%d) remote_port(%d)", + __FILE__, __LINE__, __FUNCTION__, local_port, remote_port); + } + char message[48]; + snprintf(message, sizeof(message), "forward:tcp:%d;tcp:%d", local_port, + remote_port); + + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s message(%s)", __FILE__, __LINE__, + __FUNCTION__, message); + } + const auto error = SendDeviceMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus(); +} + +Status +HdcClient::SetPortForwarding(const uint16_t local_port, + llvm::StringRef remote_socket_name, + const UnixSocketNamespace socket_namespace) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s local_port(%d)", __FILE__, + __LINE__, __FUNCTION__, local_port); + } + char message[PATH_MAX]; + const char *sock_namespace_str = + (socket_namespace == UnixSocketNamespaceAbstract) + ? kSocketNamespaceAbstract + : kSocketNamespaceFileSystem; + snprintf(message, sizeof(message), "forward:tcp:%d;%s:%s", local_port, + sock_namespace_str, remote_socket_name.str().c_str()); + + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s message(%s)", __FILE__, __LINE__, + __FUNCTION__, message); + } + const auto error = SendDeviceMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus(); +} + +Status HdcClient::DeletePortForwarding(const uint16_t local_port) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s local_port(%d)", __FILE__, + __LINE__, __FUNCTION__, local_port); + } + char message[32]; + snprintf(message, sizeof(message), "killforward:tcp:%d", local_port); + + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s message(%s)", __FILE__, __LINE__, + __FUNCTION__, message); + } + const auto error = SendDeviceMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus(); +} + +Status HdcClient::SendMessage(const std::string &packet, const bool reconnect) { + Status error; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s packet(%s) reconnect(%d)", + __FILE__, __LINE__, __FUNCTION__, packet.c_str(), reconnect); + } + if (!m_conn || reconnect) { + error = Connect(); + if (error.Fail()) + return error; + } + + char length_buffer[5]; + snprintf(length_buffer, sizeof(length_buffer), "%04x", + static_cast(packet.size())); + + ConnectionStatus status; + + m_conn->Write(length_buffer, 4, status, &error); + if (error.Fail()) + return error; + + m_conn->Write(packet.c_str(), packet.size(), status, &error); + return error; +} + +Status HdcClient::SendDeviceMessage(const std::string &packet) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s packet(%s) ", __FILE__, __LINE__, + __FUNCTION__, packet.c_str()); + } + std::ostringstream msg; + msg << "host-serial:" << m_device_id << ":" << packet; + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s msg(%s) ", __FILE__, __LINE__, + __FUNCTION__, msg.str().c_str()); + } + return SendMessage(msg.str()); +} + +Status HdcClient::ReadMessage(std::vector &message) { + message.clear(); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s call ", __FILE__, __LINE__, + __FUNCTION__); + } + char buffer[5]; + buffer[4] = 0; + + auto error = ReadAllBytes(buffer, 4); + if (error.Fail()) + return error; + + unsigned int packet_len = 0; + sscanf(buffer, "%x", &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(); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s call ", __FILE__, __LINE__, + __FUNCTION__); + } + 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() { + char response_id[5]; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + static const size_t packet_len = 4; + response_id[packet_len] = 0; + + auto error = ReadAllBytes(response_id, packet_len); + if (error.Fail()) + return error; + + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s response_id(%s) ", __FILE__, + __LINE__, __FUNCTION__, response_id); + } + if (strncmp(response_id, kOKAY, packet_len) != 0) + return GetResponseError(response_id); + + return error; +} + +Status HdcClient::GetResponseError(const char *response_id) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (strcmp(response_id, kFAIL) != 0) + return Status("Got unexpected response id from hdc: \"%s\"", response_id); + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s response_id(%s) ", __FILE__, + __LINE__, __FUNCTION__, response_id); + } + std::vector error_message; + auto error = ReadMessage(error_message); + if (error.Success()) + error.SetErrorString( + std::string(&error_message[0], error_message.size()).c_str()); + + return error; +} + +Status HdcClient::SwitchDeviceTransport() { + std::ostringstream msg; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + msg << "host:transport:" << m_device_id; + + auto error = SendMessage(msg.str()); + if (error.Fail()) + return error; + if (log) { + log->Printf("Hsu file(%s):%d HdcClient::%s m_device_id(%s) msg(%s)", + __FILE__, __LINE__, __FUNCTION__, m_device_id.c_str(), + msg.str().c_str()); + } + return ReadResponseStatus(); +} + +Status HdcClient::StartSync() { + auto error = SwitchDeviceTransport(); + if (error.Fail()) + return Status("Failed to switch to device transport: %s", + error.AsCString()); + + error = Sync(); + if (error.Fail()) + return Status("Sync failed: %s", error.AsCString()); + + return error; +} + +Status HdcClient::Sync() { + auto error = SendMessage("sync:", false); + if (error.Fail()) + return error; + + return ReadResponseStatus(); +} + +Status HdcClient::ReadAllBytes(void *buffer, size_t size) { + return ::ReadAllBytes(*m_conn, buffer, size); +} + +Status HdcClient::internalShell(const char *command, milliseconds timeout, + std::vector &output_buf) { + output_buf.clear(); + + auto error = SwitchDeviceTransport(); + if (error.Fail()) + return Status("Failed to switch to device transport: %s", + error.AsCString()); + + StreamString hdc_command; + hdc_command.Printf("shell:%s", command); + error = SendMessage(hdc_command.GetString().str(), false); + if (error.Fail()) + return error; + + error = ReadResponseStatus(); + if (error.Fail()) + return error; + + error = ReadMessageStream(output_buf, timeout); + if (error.Fail()) + return error; + + // HDC doesn't propagate return code of shell execution - if + // output starts with /system/bin/sh: most likely command failed. + static const char *kShellPrefix = "/system/bin/sh:"; + if (output_buf.size() > strlen(kShellPrefix)) { + if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix))) + return Status("Shell command %s failed: %s", command, + std::string(output_buf.begin(), output_buf.end()).c_str()); + } + + return Status(); +} + +Status HdcClient::Shell(const char *command, milliseconds timeout, + std::string *output) { + std::vector output_buffer; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s command(%s)", __FILE__, + __LINE__, __FUNCTION__, command); + } + auto error = internalShell(command, timeout, output_buffer); + if (error.Fail()) + return error; + + if (output) + output->assign(output_buffer.begin(), output_buffer.end()); + return error; +} + +Status HdcClient::ShellToFile(const char *command, milliseconds timeout, + const FileSpec &output_file_spec) { + std::vector output_buffer; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s command(%s)", __FILE__, + __LINE__, __FUNCTION__, command); + } + auto error = internalShell(command, timeout, output_buffer); + if (error.Fail()) + return error; + + const auto output_filename = output_file_spec.GetPath(); + std::error_code EC; + llvm::raw_fd_ostream dst(output_filename, EC, llvm::sys::fs::OF_None); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s output_filename(%s)", + __FILE__, __LINE__, __FUNCTION__, output_filename.c_str()); + } + if (EC) + return Status("Unable to open local file %s", output_filename.c_str()); + + dst.write(&output_buffer[0], output_buffer.size()); + dst.close(); + if (dst.has_error()) + return Status("Failed to write file %s", output_filename.c_str()); + return Status(); +} + +std::unique_ptr +HdcClient::GetSyncService(Status &error) { + std::unique_ptr sync_service; + error = StartSync(); + if (error.Success()) + sync_service.reset(new SyncService(std::move(m_conn))); + + return sync_service; +} + +Status HdcClient::SyncService::internalPullFile(const FileSpec &remote_file, + const FileSpec &local_file) { + const auto local_file_path = local_file.GetPath(); + llvm::FileRemover local_file_remover(local_file_path); + + std::error_code EC; + llvm::raw_fd_ostream dst(local_file_path, EC, llvm::sys::fs::OF_None); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s local_file_path(%s)", + __FILE__, __LINE__, __FUNCTION__, local_file_path.c_str()); + } + if (EC) + return Status("Unable to open local file %s", local_file_path.c_str()); + + const auto remote_file_path = remote_file.GetPath(false); + auto error = SendSyncRequest(kRECV, remote_file_path.length(), + remote_file_path.c_str()); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s remote_file_path(%s)", + __FILE__, __LINE__, __FUNCTION__, remote_file_path.c_str()); + } + if (error.Fail()) + return error; + + std::vector chunk; + bool eof = false; + while (!eof) { + error = PullFileChunk(chunk, eof); + if (error.Fail()) + return error; + if (!eof) + dst.write(&chunk[0], chunk.size()); + } + dst.close(); + if (dst.has_error()) + return Status("Failed to write file %s", local_file_path.c_str()); + + local_file_remover.releaseFile(); + return error; +} + +Status HdcClient::SyncService::internalPushFile(const FileSpec &local_file, + const FileSpec &remote_file) { + const auto local_file_path(local_file.GetPath()); + std::ifstream src(local_file_path.c_str(), std::ios::in | std::ios::binary); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s local_file_path(%s)", + __FILE__, __LINE__, __FUNCTION__, local_file_path.c_str()); + } + if (!src.is_open()) + return Status("Unable to open local file %s", local_file_path.c_str()); + + std::stringstream file_description; + file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode; + std::string file_description_str = file_description.str(); + auto error = SendSyncRequest(kSEND, file_description_str.length(), + file_description_str.c_str()); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s file_description_str(%s)", + __FILE__, __LINE__, __FUNCTION__, file_description_str.c_str()); + } + if (error.Fail()) + return error; + + char chunk[kMaxPushData]; + while (!src.eof() && !src.read(chunk, kMaxPushData).bad()) { + size_t chunk_size = src.gcount(); + error = SendSyncRequest(kDATA, chunk_size, chunk); + if (error.Fail()) + return Status("Failed to send file chunk: %s", error.AsCString()); + } + error = SendSyncRequest( + kDONE, + llvm::sys::toTimeT( + FileSystem::Instance().GetModificationTime(local_file)), + nullptr); + if (error.Fail()) + return error; + + std::string response_id; + uint32_t data_len; + error = ReadSyncHeader(response_id, data_len); + if (error.Fail()) + return Status("Failed to read DONE response: %s", error.AsCString()); + if (response_id == kFAIL) { + std::string error_message(data_len, 0); + error = ReadAllBytes(&error_message[0], data_len); + if (error.Fail()) + return Status("Failed to read DONE error message: %s", error.AsCString()); + return Status("Failed to push file: %s", error_message.c_str()); + } else if (response_id != kOKAY) + return Status("Got unexpected DONE response: %s", response_id.c_str()); + + // If there was an error reading the source file, finish the hdc file + // transfer first so that hdc isn't expecting any more data. + if (src.bad()) + return Status("Failed read on %s", local_file_path.c_str()); + return error; +} + +Status HdcClient::SyncService::internalStat(const FileSpec &remote_file, + uint32_t &mode, uint32_t &size, + uint32_t &mtime) { + const std::string remote_file_path(remote_file.GetPath(false)); + auto error = SendSyncRequest(kSTAT, remote_file_path.length(), + remote_file_path.c_str()); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s remote_file_path(%s)", + __FILE__, __LINE__, __FUNCTION__, remote_file_path.c_str()); + } + if (error.Fail()) + return Status("Failed to send request: %s", error.AsCString()); + + static const size_t stat_len = strlen(kSTAT); + static const size_t response_len = stat_len + (sizeof(uint32_t) * 3); + + std::vector buffer(response_len); + error = ReadAllBytes(&buffer[0], buffer.size()); + if (error.Fail()) + return Status("Failed to read response: %s", error.AsCString()); + + DataExtractor extractor(&buffer[0], buffer.size(), eByteOrderLittle, + sizeof(void *)); + offset_t offset = 0; + + const void *command = extractor.GetData(&offset, stat_len); + if (!command) + return Status("Failed to get response command"); + const char *command_str = static_cast(command); + if (strncmp(command_str, kSTAT, stat_len)) + return Status("Got invalid stat command: %s", command_str); + + mode = extractor.GetU32(&offset); + size = extractor.GetU32(&offset); + mtime = extractor.GetU32(&offset); + return Status(); +} + +Status HdcClient::SyncService::PullFile(const FileSpec &remote_file, + const FileSpec &local_file) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, + "Hsu file(%s):%d HdcClient::%s remote_file(%s) local_file(%s)", + __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), + local_file.GetPath().c_str()); + } + return executeCommand([this, &remote_file, &local_file]() { + return internalPullFile(remote_file, local_file); + }); +} + +Status HdcClient::SyncService::PushFile(const FileSpec &local_file, + const FileSpec &remote_file) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, + "Hsu file(%s):%d HdcClient::%s remote_file(%s) local_file(%s)", + __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), + local_file.GetPath().c_str()); + } + return executeCommand([this, &local_file, &remote_file]() { + return internalPushFile(local_file, remote_file); + }); +} + +Status HdcClient::SyncService::Stat(const FileSpec &remote_file, uint32_t &mode, + uint32_t &size, uint32_t &mtime) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s remote_file(%s) mode(%d)", + __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), + mode); + } + return executeCommand([this, &remote_file, &mode, &size, &mtime]() { + return internalStat(remote_file, mode, size, mtime); + }); +} + +bool HdcClient::SyncService::IsConnected() const { + return m_conn && m_conn->IsConnected(); +} + +HdcClient::SyncService::SyncService(std::unique_ptr &&conn) + : m_conn(std::move(conn)) {} + +Status +HdcClient::SyncService::executeCommand(const std::function &cmd) { + if (!m_conn) + return Status("SyncService is disconnected"); + + const auto error = cmd(); + if (error.Fail()) + m_conn.reset(); + + return error; +} + +HdcClient::SyncService::~SyncService() {} + +Status HdcClient::SyncService::SendSyncRequest(const char *request_id, + const uint32_t data_len, + const void *data) { + const DataBufferSP data_sp(new DataBufferHeap(kSyncPacketLen, 0)); + DataEncoder encoder(data_sp, eByteOrderLittle, sizeof(void *)); + auto offset = encoder.PutData(0, request_id, strlen(request_id)); + encoder.PutUnsigned(offset, 4, data_len); + + Status error; + ConnectionStatus status; + m_conn->Write(data_sp->GetBytes(), kSyncPacketLen, status, &error); + if (error.Fail()) + return error; + + if (data) + m_conn->Write(data, data_len, status, &error); + return error; +} + +Status HdcClient::SyncService::ReadSyncHeader(std::string &response_id, + uint32_t &data_len) { + char buffer[kSyncPacketLen]; + + auto error = ReadAllBytes(buffer, kSyncPacketLen); + if (error.Success()) { + response_id.assign(&buffer[0], 4); + DataExtractor extractor(&buffer[4], 4, eByteOrderLittle, sizeof(void *)); + offset_t offset = 0; + data_len = extractor.GetU32(&offset); + } + + return error; +} + +Status HdcClient::SyncService::PullFileChunk(std::vector &buffer, + bool &eof) { + buffer.clear(); + + std::string response_id; + uint32_t data_len; + auto error = ReadSyncHeader(response_id, data_len); + if (error.Fail()) + return error; + + if (response_id == kDATA) { + buffer.resize(data_len, 0); + error = ReadAllBytes(&buffer[0], data_len); + if (error.Fail()) + buffer.clear(); + } else if (response_id == kDONE) { + eof = true; + } else if (response_id == kFAIL) { + std::string error_message(data_len, 0); + error = ReadAllBytes(&error_message[0], data_len); + if (error.Fail()) + return Status("Failed to read pull error message: %s", error.AsCString()); + return Status("Failed to pull file: %s", error_message.c_str()); + } else + return Status("Pull failed with unknown response: %s", response_id.c_str()); + + return Status(); +} + +Status HdcClient::SyncService::ReadAllBytes(void *buffer, size_t size) { + return ::ReadAllBytes(*m_conn, buffer, size); +} diff --git a/lldb/source/Plugins/Platform/HOS/HdcClient.h b/lldb/source/Plugins/Platform/HOS/HdcClient.h new file mode 100644 index 000000000000..33d4370c9d02 --- /dev/null +++ b/lldb/source/Plugins/Platform/HOS/HdcClient.h @@ -0,0 +1,138 @@ +//===-- 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_hos { + +class HdcClient { +public: + enum UnixSocketNamespace { + UnixSocketNamespaceAbstract, + UnixSocketNamespaceFileSystem, + }; + + using DeviceIDList = std::list; + + class SyncService { + friend class HdcClient; + + public: + ~SyncService(); + + Status PullFile(const FileSpec &remote_file, const FileSpec &local_file); + + Status PushFile(const FileSpec &local_file, const FileSpec &remote_file); + + Status Stat(const FileSpec &remote_file, uint32_t &mode, uint32_t &size, + uint32_t &mtime); + + bool IsConnected() const; + + private: + explicit SyncService(std::unique_ptr &&conn); + + Status SendSyncRequest(const char *request_id, const uint32_t data_len, + const void *data); + + Status ReadSyncHeader(std::string &response_id, uint32_t &data_len); + + Status PullFileChunk(std::vector &buffer, bool &eof); + + Status ReadAllBytes(void *buffer, size_t size); + + Status internalPullFile(const FileSpec &remote_file, + const FileSpec &local_file); + + Status internalPushFile(const FileSpec &local_file, + const FileSpec &remote_file); + + Status internalStat(const FileSpec &remote_file, uint32_t &mode, + uint32_t &size, uint32_t &mtime); + + Status executeCommand(const std::function &cmd); + + std::unique_ptr m_conn; + }; + + 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(const uint16_t local_port); + + Status Shell(const char *command, std::chrono::milliseconds timeout, + std::string *output); + + Status ShellToFile(const char *command, std::chrono::milliseconds timeout, + const FileSpec &output_file_spec); + + std::unique_ptr GetSyncService(Status &error); + + Status SwitchDeviceTransport(); + +private: + Status Connect(); + + void SetDeviceID(const std::string &device_id); + + Status SendMessage(const std::string &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 GetResponseError(const char *response_id); + + Status ReadResponseStatus(); + + Status Sync(); + + Status StartSync(); + + Status internalShell(const char *command, std::chrono::milliseconds timeout, + std::vector &output_buf); + + Status ReadAllBytes(void *buffer, size_t size); + + std::string m_device_id; + std::unique_ptr m_conn; +}; + +} // namespace platform_hos +} // namespace lldb_private + +#endif // liblldb_HdcClient_h_ diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp b/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp new file mode 100644 index 000000000000..a939c6dd0be3 --- /dev/null +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp @@ -0,0 +1,466 @@ +//===-- PlatformHOS.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 "llvm/Config/config.h" + +#include "HdcClient.h" +#include "PlatformHOS.h" +#include "PlatformHOSRemoteGDBServer.h" +#if defined __MINGW32__ +// SetEnvironmentVariableA +#include +#endif + +using namespace lldb; +using namespace lldb_private; +// using namespace lldb_private::platform_android; +using namespace lldb_private::platform_hos; +using namespace std::chrono; +static uint32_t g_initialize_count = 0; +static const unsigned int g_hos_default_cache_size = 2048; +LLDB_PLUGIN_DEFINE(PlatformHOS) + +static void platform_setenv(const char *env, const char *val) { +#if HAVE_SETENV || _MSC_VER + setenv(env, val, true); +#elif defined(__MINGW32__) + SetEnvironmentVariableA(env, val); +#else +#error "setenv not found" +#endif +} + +void PlatformHOS::Initialize() { + PlatformLinux::Initialize(); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (g_initialize_count++ == 0) { +#if defined(__HOS__) + PlatformSP default_platform_sp(new PlatformHOS(true)); + default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); + Platform::SetHostPlatform(default_platform_sp); + if (log) { + LLDB_LOGF(log, "Hsu file(%s)%d PlatformHOS::%s new PlatformHOS(true)", + __FILE__, __LINE__, __FUNCTION__); + } +#endif + PluginManager::RegisterPlugin( + PlatformHOS::GetPluginNameStatic(false), + PlatformHOS::GetPluginDescriptionStatic(false), + PlatformHOS::CreateInstance); + } +} + +void PlatformHOS::Terminate() { + if (g_initialize_count > 0) { + if (--g_initialize_count == 0) { + PluginManager::UnregisterPlugin(PlatformHOS::CreateInstance); + } + } + PlatformLinux::Terminate(); +} + +PlatformSP PlatformHOS::CreateInstance(bool force, const ArchSpec *arch) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + const char *triple_cstr = + arch ? arch->GetTriple().getTriple().c_str() : ""; + + LLDB_LOGF(log, "PlatformHOS::%s(force=%s, triple=%s)", __FUNCTION__, + force ? "true" : "false", 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: + create = triple.isOpenHOS(); + break; + } + } + + if (create) { + if (const char *env = std::getenv("HDC_UTID")) + platform_setenv("ANDROID_SERIAL", env); + + LLDB_LOGF(log, "PlatformHOS::%s() creating remote-hos platform", + __FUNCTION__); + return PlatformSP(new PlatformHOS(false)); + } + + LLDB_LOGF(log, "PlatformHOS::%s() aborting creation of remote-hos platform", + __FUNCTION__); + + return PlatformSP(); +} + +PlatformHOS::PlatformHOS(bool is_host) + : PlatformLinux(is_host), m_sdk_version(0) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + m_container = m_remote_platform_sp->GetContainer(); + if (log) { + LLDB_LOGF(log, + "Hsu file(%s):%d PlatformHOS::%s is_host(%d) m_container(%d)", + __FILE__, __LINE__, __FUNCTION__, is_host, m_container); + } +} + +PlatformHOS::~PlatformHOS() {} + +ConstString PlatformHOS::GetPluginNameStatic(bool is_host) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu %s:%d PlatformHOS::GetPluginNameStatic is_host(%d)", + __FILE__, __LINE__, is_host); + } + if (is_host) { + static ConstString g_host_name(Platform::GetHostPlatformName()); + if (log) { + LLDB_LOGF(log, "Hsu %s:%d PlatformHOS::GetPluginNameStatic g_host_name", + __FILE__, __LINE__); + } + return g_host_name; + } else { + static ConstString g_remote_name("remote-hos"); + if (log) { + LLDB_LOGF(log, "Hsu %s:%d PlatformHOS::GetPluginNameStatic g_remote_name", + __FILE__, __LINE__); + } + return g_remote_name; + } +} + +const char *PlatformHOS::GetPluginDescriptionStatic(bool is_host) { + if (is_host) + return "Local HarmonyOS user platform plug-in."; + else + return "Remote HarmonyOS user platform plug-in."; +} +Status PlatformHOS::ConnectRemote(Args &args) { + m_device_id.clear(); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + LLDB_LOGF(log, "Hsu %s:%d PlatformHOS::ConnectRemote call", __FILE__, + __LINE__); + } + + if (IsHost()) { + return Status("can't connect to the host platform '%s', always connected", + GetPluginName().GetCString()); + } + + if (!m_remote_platform_sp) { + if (log) { + LLDB_LOGF(log, + "Hsu %s:%d PlatformHOS::ConnectRemote new " + "PlatformHOSRemoteGDBServer()", + __FILE__, __LINE__); + } + m_remote_platform_sp = PlatformSP(new PlatformHOSRemoteGDBServer()); + } + + 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 hdc; + if (log) { + LLDB_LOGF(log, + "Hsu file(%s):%d PlatformHOS::ConnectRemote m_device_id(%s)", + __FILE__, __LINE__, m_device_id.c_str()); + } + error = HdcClient::CreateByDeviceID(m_device_id, hdc); + if (error.Fail()) + return error; + + m_device_id = hdc.GetDeviceID(); + if (log) { + LLDB_LOGF(log, + "Hsu file(%s):%d PlatformHOS::ConnectRemote m_device_id(%s)", + __FILE__, __LINE__, m_device_id.c_str()); + } + } + return error; +} + +Status PlatformHOS::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)); + + Status error; + auto sync_service = GetSyncService(error); + if (error.Fail()) + return error; + + uint32_t mode = 0, size = 0, mtime = 0; + error = sync_service->Stat(source_spec, mode, size, mtime); + if (error.Fail()) + return error; + + if (mode != 0) + return sync_service->PullFile(source_spec, destination); + + auto source_file = source_spec.GetCString(false); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + LLDB_LOGF(log, "Got mode == 0 on '%s': try to get file via 'shell cat'", + source_file); + + if (strchr(source_file, '\'') != nullptr) + return Status("Doesn't support single-quotes in filenames"); + + // mode == 0 can signify that adbd cannot access the file due security + // constraints - try "cat ..." as a fallback. + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d PlatformHOS::%s source_file(%s)", __FILE__, + __LINE__, __FUNCTION__, source_file); + } + HdcClient hdc(m_device_id); + + char cmd[PATH_MAX]; + int len = strlen(source_file); + std::string tempFile(source_file); + //ÈÝÆ÷ÄÚÆô¶¯µÄÓ¦Óà + if (m_container) { + //ÈÝÆ÷ÄÚ·¾¶Òª×ª»»³ÉÈÝÆ÷ÍâµÄ·¾¶ + /* + ÈÝÆ÷ÄÚ ÈÝÆ÷Íâ + /data /data/ohos_data + /vendor /sytem/ohos/vendor + /system /system/ohos/system + */ + const std::string str_data = "/data"; + const std::string str_vendor = "/vendor"; + const std::string str_system = "/system"; + if (strncmp(source_file, str_data.c_str(), strlen(str_data.c_str()))) { + // ´Ó/dataºóÃæµÄλÖÿªÊ¼½ØÈ¡£¬Ö±µ½×îºó + tempFile.append(tempFile, strlen(str_data.c_str()), len); + tempFile = str_data + tempFile; + snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); + return hdc.ShellToFile(cmd, minutes(1), destination); + } + + if (strncmp(source_file, str_vendor.c_str(), strlen(str_vendor.c_str()))) { + tempFile.append(tempFile, strlen(str_vendor.c_str()), len); + tempFile = str_vendor + tempFile; + snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); + return hdc.ShellToFile(cmd, minutes(1), destination); + } + + if (strncmp(source_file, str_system.c_str(), strlen(str_system.c_str()))) { + tempFile.append(tempFile, strlen(str_system.c_str()), len); + tempFile = str_system + tempFile; + snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); + return hdc.ShellToFile(cmd, minutes(1), destination); + } + // ÈÝÆ÷ÍâÎÞ¶ÔӦ·¾¶ + return error; + } else { + snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); + } + + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d PlatformHOS::%s source_file(%s)", __FILE__, + __LINE__, __FUNCTION__, source_file); + } + return hdc.ShellToFile(cmd, minutes(1), destination); +} + +Status PlatformHOS::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. + Status error; + auto sync_service = GetSyncService(error); + if (error.Fail()) + return error; + return sync_service->PushFile(source, destination_spec); +} + +const char *PlatformHOS::GetCacheHostname() { return m_device_id.c_str(); } + +Status PlatformHOS::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 PlatformHOS::DisconnectRemote() { + Status error = PlatformLinux::DisconnectRemote(); + if (error.Success()) { + m_device_id.clear(); + m_sdk_version = 0; + } + return error; +} + +uint32_t PlatformHOS::GetDefaultMemoryCacheLineSize() { + return g_hos_default_cache_size; +} + +uint32_t PlatformHOS::GetSdkVersion() { + if (!IsConnected()) + return 0; + + if (m_sdk_version != 0) + return m_sdk_version; + + std::string version_string; + HdcClient hdc(m_device_id); + Status error = + hdc.Shell("getprop ro.build.version.sdk", seconds(5), &version_string); + version_string = llvm::StringRef(version_string).trim().str(); + + if (error.Fail() || version_string.empty()) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM); + LLDB_LOGF(log, "Get SDK version failed. (error: %s, output: %s)", + error.AsCString(), version_string.c_str()); + return 0; + } + + m_sdk_version = StringConvert::ToUInt32(version_string.c_str()); + return m_sdk_version; +} + +Status PlatformHOS::DownloadSymbolFile(const lldb::ModuleSP &module_sp, + const FileSpec &dst_file_spec) { + // For oat file we can try to fetch additional debug info from the device + ConstString extension = module_sp->GetFileSpec().GetFileNameExtension(); + if (extension != ".oat" && extension != ".odex") + return Status( + "Symbol file downloading only supported for oat and odex files"); + + // If we have no information about the platform file we can't execute oatdump + if (!module_sp->GetPlatformFileSpec()) + return Status("No platform file specified"); + + // Symbolizer isn't available before SDK version 23 + if (GetSdkVersion() < 23) + return Status("Symbol file generation only supported on SDK 23+"); + + // If we already have symtab then we don't have to try and generate one + if (module_sp->GetSectionList()->FindSectionByName(ConstString(".symtab")) != + nullptr) + return Status("Symtab already available in the module"); + + HdcClient hdc(m_device_id); + std::string tmpdir; + Status error = hdc.Shell("mktemp --directory --tmpdir /data/local/tmp", + seconds(5), &tmpdir); + if (error.Fail() || tmpdir.empty()) + return Status("Failed to generate temporary directory on the device (%s)", + error.AsCString()); + tmpdir = llvm::StringRef(tmpdir).trim().str(); + + // Create file remover for the temporary directory created on the device + std::unique_ptr> + tmpdir_remover(&tmpdir, [&hdc](std::string *s) { + StreamString command; + command.Printf("rm -rf %s", s->c_str()); + Status error = hdc.Shell(command.GetData(), seconds(5), nullptr); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log && error.Fail()) + LLDB_LOGF(log, "Failed to remove temp directory: %s", + error.AsCString()); + }); + + FileSpec symfile_platform_filespec(tmpdir); + symfile_platform_filespec.AppendPathComponent("symbolized.oat"); + + // Execute oatdump on the remote device to generate a file with symtab + StreamString command; + command.Printf("oatdump --symbolize=%s --output=%s", + module_sp->GetPlatformFileSpec().GetCString(false), + symfile_platform_filespec.GetCString(false)); + error = hdc.Shell(command.GetData(), minutes(1), nullptr); + if (error.Fail()) + return Status("Oatdump failed: %s", error.AsCString()); + + // Download the symbolfile from the remote device + return GetFile(symfile_platform_filespec, dst_file_spec); +} + +bool PlatformHOS::GetRemoteOSVersion() { + m_os_version = llvm::VersionTuple(GetSdkVersion()); + return !m_os_version.empty(); +} + +llvm::StringRef +PlatformHOS::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); +} + +HdcClient::SyncService *PlatformHOS::GetSyncService(Status &error) { + if (m_adb_sync_svc && m_adb_sync_svc->IsConnected()) + return m_adb_sync_svc.get(); + + HdcClient hdc(m_device_id); + m_adb_sync_svc = hdc.GetSyncService(error); + return (error.Success()) ? m_adb_sync_svc.get() : nullptr; +} diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOS.h b/lldb/source/Plugins/Platform/HOS/PlatformHOS.h new file mode 100644 index 000000000000..07057ab83e26 --- /dev/null +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOS.h @@ -0,0 +1,82 @@ +//===-- PlatformHOS.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_PlatformHOS_h_ +#define liblldb_PlatformHOS_h_ + +#include +#include + +//#include "Plugins/Platform/Android/PlatformAndroid.h" +#include "HdcClient.h" +#include "Plugins/Platform/Linux/PlatformLinux.h" + +namespace lldb_private { +namespace platform_hos { + +// class PlatformHOS : public platform_android::PlatformAndroid { +class PlatformHOS : public platform_linux::PlatformLinux { +public: + // PlatformHOS(bool is_host) : PlatformAndroid(is_host) {} + PlatformHOS(bool is_host); + // lldb_private::PluginInterface functions + ~PlatformHOS() override; + static void Initialize(); + + static void Terminate(); + + 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 { return GetPluginNameStatic(IsHost()); } + + uint32_t GetPluginVersion() override { return 1; } + + 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; + + Status DownloadSymbolFile(const lldb::ModuleSP &module_sp, + const FileSpec &dst_file_spec) override; + + llvm::StringRef + GetLibdlFunctionDeclarations(lldb_private::Process *process) override; + +private: + HdcClient::SyncService *GetSyncService(Status &error); + + std::unique_ptr m_adb_sync_svc; + std::string m_device_id; + uint32_t m_sdk_version; +}; + +} // namespace platform_hos +} // namespace lldb_private + +#endif // liblldb_PlatformHOS_h_ diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.cpp new file mode 100644 index 000000000000..8c311a938453 --- /dev/null +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.cpp @@ -0,0 +1,244 @@ +//===-- PlatformHOSRemoteGDBServer.cpp --------------------------------===// +// +// 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 "PlatformHOSRemoteGDBServer.h" + +#include + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::platform_hos; + +static const lldb::pid_t g_remote_platform_pid = + 0; // Alias for the process id of lldb-platform + +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(); + LLDB_LOGF(log, + "Hsu file(%s):%d function(ForwardPortWithHdc) Connected to Hos " + "device \"%s\"", + __FILE__, __LINE__, device_id.c_str()); + + if (remote_port != 0) { + LLDB_LOGF(log, + "Hsu file(%s):%d function(ForwardPortWithHdc) Forwarding remote " + "TCP port %d to local TCP port %d", + __FILE__, __LINE__, remote_port, local_port); + return hdc.SetPortForwarding(local_port, remote_port); + } + + LLDB_LOGF(log, "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(uint16_t local_port, + const std::string &device_id) { + HdcClient hdc(device_id); + return hdc.DeletePortForwarding(local_port); +} + +static Status FindUnusedPort(uint16_t &port) { + Status error; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + 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(); + + if (log) { + LLDB_LOGF(log, "Hsu file(%s):%d FindUnusedPort port(%d)", __FILE__, + __LINE__, port); + } + return error; +} + +PlatformHOSRemoteGDBServer::PlatformHOSRemoteGDBServer() {} + +PlatformHOSRemoteGDBServer::~PlatformHOSRemoteGDBServer() { + for (const auto &it : m_port_forwards) + DeleteForwardPortWithHdc(it.second, m_device_id); +} + +bool PlatformHOSRemoteGDBServer::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) + LLDB_LOGF(log, "gdbserver connect URL: %s", connect_url.c_str()); + + return error.Success(); +} + +bool PlatformHOSRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) { + DeleteForwardPort(pid); + return m_gdb_client.KillSpawnedProcess(pid); +} + +Status PlatformHOSRemoteGDBServer::ConnectRemote(Args &args) { + m_device_id.clear(); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + + 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 = std::string(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 (log) { + LLDB_LOGF(log, + "Hsu file(%s):%d g_remote_platform_pid(%lu) remote_port(%d) " + "connect_url(%s)", + __FILE__, __LINE__, g_remote_platform_pid, remote_port, + connect_url.c_str()); + } + if (error.Fail()) + return error; + + args.ReplaceArgumentAtIndex(0, connect_url); + + // Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + LLDB_LOGF(log, "Rewritten platform connect URL: %s", connect_url.c_str()); + + error = PlatformRemoteGDBServer::ConnectRemote(args); + if (error.Fail()) + DeleteForwardPort(g_remote_platform_pid); + + return error; +} + +Status PlatformHOSRemoteGDBServer::DisconnectRemote() { + DeleteForwardPort(g_remote_platform_pid); + return PlatformRemoteGDBServer::DisconnectRemote(); +} + +void PlatformHOSRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + + auto it = m_port_forwards.find(pid); + if (it == m_port_forwards.end()) + return; + + const auto port = it->second; + const auto error = DeleteForwardPortWithHdc(port, m_device_id); + if (error.Fail()) { + LLDB_LOGF(log, + "Failed to delete port forwarding (pid=%" PRIu64 + ", port=%d, device=%s): %s", + pid, port, m_device_id.c_str(), error.AsCString()); + } + m_port_forwards.erase(it); +} + +Status PlatformHOSRemoteGDBServer::MakeConnectURL( + const lldb::pid_t pid, const uint16_t remote_port, + llvm::StringRef remote_socket_name, std::string &connect_url) { + static const int kAttempsNum = 5; + + Status error; + // There is a race possibility that somebody will occupy a port while we're + // in between FindUnusedPort and ForwardPortWithHdc - adding the loop to + // mitigate such problem. + for (auto i = 0; i < kAttempsNum; ++i) { + uint16_t local_port = 0; + error = FindUnusedPort(local_port); + if (error.Fail()) + return error; + + error = ForwardPortWithHdc(local_port, remote_port, remote_socket_name, + m_socket_namespace, m_device_id); + if (error.Success()) { + m_port_forwards[pid] = local_port; + std::ostringstream url_str; + url_str << "connect://127.0.0.1:" << local_port; + connect_url = url_str.str(); + break; + } + } + + return error; +} + +lldb::ProcessSP PlatformHOSRemoteGDBServer::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 android. + 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/HOS/PlatformHOSRemoteGDBServer.h b/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.h new file mode 100644 index 000000000000..c30b15dd9a80 --- /dev/null +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.h @@ -0,0 +1,65 @@ +//===-- PlatformHOSRemoteGDBServer.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_SOURCE_PLUGINS_PLATFORM_HOS_PLATFORMHOSREMOTEGDBSERVER_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_HOS_PLATFORMHOSREMOTEGDBSERVER_H + +#include +#include + +#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" + +#include "llvm/ADT/Optional.h" + +#include "HdcClient.h" + +namespace lldb_private { +namespace platform_hos { + +class PlatformHOSRemoteGDBServer + : public platform_gdb_server::PlatformRemoteGDBServer { +public: + PlatformHOSRemoteGDBServer(); + + ~PlatformHOSRemoteGDBServer() override; + + Status ConnectRemote(Args &args) override; + + Status DisconnectRemote() override; + + lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, + llvm::StringRef plugin_name, + lldb_private::Debugger &debugger, + lldb_private::Target *target, + lldb_private::Status &error) override; + +protected: + std::string m_device_id; + std::map m_port_forwards; + llvm::Optional m_socket_namespace; + + bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) override; + + bool KillSpawnedProcess(lldb::pid_t pid) override; + + void DeleteForwardPort(lldb::pid_t pid); + + Status MakeConnectURL(const lldb::pid_t pid, const uint16_t remote_port, + llvm::StringRef remote_socket_name, + std::string &connect_url); + +private: + PlatformHOSRemoteGDBServer(const PlatformHOSRemoteGDBServer &) = delete; + const PlatformHOSRemoteGDBServer & + operator=(const PlatformHOSRemoteGDBServer &) = delete; +}; + +} // namespace platform_hos +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_HOS_PLATFORMANDROIDREMOTEGDBSERVER_H diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index ee472114de33..181047242503 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -274,7 +274,7 @@ Platform::Platform(bool is_host) m_max_gid_name_len(0), m_supports_rsync(false), m_rsync_opts(), m_rsync_prefix(), m_supports_ssh(false), m_ssh_opts(), m_ignores_remote_hostname(false), m_trap_handlers(), - m_calculated_trap_handlers(false), + m_container(false), m_calculated_trap_handlers(false), m_module_cache(std::make_unique()) { Log *log = GetLog(LLDBLog::Object); LLDB_LOGF(log, "%p Platform::Platform()", static_cast(this)); @@ -308,9 +308,14 @@ void Platform::GetStatus(Stream &strm) { strm.Printf(" Hostname: %s\n", GetHostname()); } else { const bool is_connected = IsConnected(); + const bool is_container = GetContainer(); + if (log) { + LLDB_LOGF(log, "%p Hsu file(%s):%d Platform::GetStatus() is_container(%d) is_connected(%d)", static_cast(this), __FILE__, __LINE__, is_container, is_connected); + } if (is_connected) strm.Printf(" Hostname: %s\n", GetHostname()); strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no"); + strm.Printf(" Container: %s\n", is_container ? "yes" : "no"); } if (GetSDKRootDirectory()) { -- Gitee From 7d6e3d0bf75945cce1630b359b08aee2923d1e90 Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Thu, 3 Nov 2022 18:38:18 +0300 Subject: [PATCH 35/41] modify shellToFile to support container path rebase Signed-off-by: Ivan Eliseev --- .../lldb/Interpreter/OptionGroupPlatform.h | 2 +- .../source/Commands/CommandObjectPlatform.cpp | 7 ++- .../Interpreter/OptionGroupPlatform.cpp | 33 ++++--------- .../Plugins/Platform/HOS/CMakeLists.txt | 9 ++-- .../Plugins/Platform/HOS/PlatformHOS.cpp | 48 +++++++++---------- lldb/source/Target/Platform.cpp | 2 +- 6 files changed, 44 insertions(+), 57 deletions(-) diff --git a/lldb/include/lldb/Interpreter/OptionGroupPlatform.h b/lldb/include/lldb/Interpreter/OptionGroupPlatform.h index c67416809314..3c24d77cdbe5 100644 --- a/lldb/include/lldb/Interpreter/OptionGroupPlatform.h +++ b/lldb/include/lldb/Interpreter/OptionGroupPlatform.h @@ -56,7 +56,7 @@ public: ConstString GetSDKBuild() const { return m_sdk_build; } void SetSDKBuild(ConstString sdk_build) { m_sdk_build = sdk_build; } - + bool GetContainer() const { return m_container; } void SetContainer(bool b_container) { m_container = b_container; } diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp index 98c6a3b2dd30..87f5af22d802 100644 --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -166,11 +166,16 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { - if (args.GetArgumentCount() == 1) { + if (args.GetArgumentCount() >= 1) { const char *platform_name = args.GetArgumentAtIndex(0); if (platform_name && platform_name[0]) { const bool select = true; m_platform_options.SetPlatformName(platform_name); + if (args.GetArgumentCount() == 2) { + std::string inner(args.GetArgumentAtIndex(1)); + if (inner == "inner") + m_platform_options.SetContainer(true); + } Status error; ArchSpec platform_arch; PlatformSP platform_sp(m_platform_options.CreatePlatformWithOptions( diff --git a/lldb/source/Interpreter/OptionGroupPlatform.cpp b/lldb/source/Interpreter/OptionGroupPlatform.cpp index 4d8668fdb41e..b6e3e04c3710 100644 --- a/lldb/source/Interpreter/OptionGroupPlatform.cpp +++ b/lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -33,6 +33,12 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( m_platform_name); } if (platform_sp) { + if (GetContainer()) { + if (log) { + LLDB_LOGF(log, "Platform is created inside container."); + } + platform_sp->SetContainer(true); + } if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture( arch, {}, false, &platform_arch)) { error.SetErrorStringWithFormatv("platform '{0}' doesn't support '{1}'", @@ -82,9 +88,6 @@ static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_ALL, false, "build", 'b', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "Specify the initial SDK build number."}, - {LLDB_OPT_SET_ALL, false, "contain", 'c', OptionParser::eRequiredArgument, - nullptr, {}, 0, eArgTypeNone, - "Specifies whether the application is in a container."}, {LLDB_OPT_SET_ALL, false, "sysroot", 'S', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Specify the SDK root directory " "that contains a root of all " @@ -106,10 +109,6 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx, ++option_idx; const int short_option = g_option_table[option_idx].short_option; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMANDS)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d OptionGroupPlatform::%s short_option: %d", __FILE__, __LINE__, __FUNCTION__, short_option); - } switch (short_option) { case 'p': m_platform_name.assign(std::string(option_arg)); @@ -124,23 +123,6 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx, case 'b': m_sdk_build.SetString(option_arg); break; - - case 'c': - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d OptionGroupPlatform::%s option_arg:-c %s", __FILE__, __LINE__, __FUNCTION__, option_arg.str().c_str()); - } - - if (std::string(option_arg) == "true") { - m_container = true; - } - else { - m_container = false; - } - - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d OptionGroupPlatform::%s m_container:%d", __FILE__, __LINE__, __FUNCTION__, m_container); - } - break; case 'S': m_sdk_sysroot.SetString(option_arg); @@ -168,9 +150,10 @@ bool OptionGroupPlatform::PlatformMatches( if (!m_os_version.empty() && m_os_version != platform_sp->GetOSVersion()) return false; - + if (m_container != platform_sp->GetContainer()) return false; + return true; } return false; diff --git a/lldb/source/Plugins/Platform/HOS/CMakeLists.txt b/lldb/source/Plugins/Platform/HOS/CMakeLists.txt index 5219c0cea666..ec9e85def9f5 100644 --- a/lldb/source/Plugins/Platform/HOS/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/HOS/CMakeLists.txt @@ -1,5 +1,4 @@ -add_lldb_library(lldbPluginPlatformHOS PLUGIN HdcClient.cpp PlatformHOS - .cpp PlatformHOSRemoteGDBServer.cpp - - LINK_LIBS lldbCore lldbHost lldbPluginPlatformLinux - lldbPluginPlatformGDB LINK_COMPONENTS Support) \ No newline at end of file +add_lldb_library(lldbPluginPlatformHOS PLUGIN HdcClient.cpp PlatformHOS.cpp + PlatformHOSRemoteGDBServer.cpp LINK_LIBS lldbCore + lldbHost lldbPluginPlatformLinux lldbPluginPlatformGDB + LINK_COMPONENTS Support) diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp b/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp index a939c6dd0be3..d5be96da944a 100644 --- a/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp @@ -116,11 +116,9 @@ PlatformSP PlatformHOS::CreateInstance(bool force, const ArchSpec *arch) { PlatformHOS::PlatformHOS(bool is_host) : PlatformLinux(is_host), m_sdk_version(0) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - m_container = m_remote_platform_sp->GetContainer(); if (log) { - LLDB_LOGF(log, - "Hsu file(%s):%d PlatformHOS::%s is_host(%d) m_container(%d)", - __FILE__, __LINE__, __FUNCTION__, is_host, m_container); + LLDB_LOGF(log, "Hsu file(%s):%d PlatformHOS::%s is_host(%d)", __FILE__, + __LINE__, __FUNCTION__, is_host); } } @@ -253,11 +251,8 @@ Status PlatformHOS::GetFile(const FileSpec &source, char cmd[PATH_MAX]; int len = strlen(source_file); std::string tempFile(source_file); - //ÈÝÆ÷ÄÚÆô¶¯µÄÓ¦Óà if (m_container) { - //ÈÝÆ÷ÄÚ·¾¶Òª×ª»»³ÉÈÝÆ÷ÍâµÄ·¾¶ /* - ÈÝÆ÷ÄÚ ÈÝÆ÷Íâ /data /data/ohos_data /vendor /sytem/ohos/vendor /system /system/ohos/system @@ -265,28 +260,27 @@ Status PlatformHOS::GetFile(const FileSpec &source, const std::string str_data = "/data"; const std::string str_vendor = "/vendor"; const std::string str_system = "/system"; - if (strncmp(source_file, str_data.c_str(), strlen(str_data.c_str()))) { - // ´Ó/dataºóÃæµÄλÖÿªÊ¼½ØÈ¡£¬Ö±µ½×îºó - tempFile.append(tempFile, strlen(str_data.c_str()), len); - tempFile = str_data + tempFile; - snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); + const std::string str_data_append = "/data/ohos_data"; + const std::string str_vendor_append = "/vendor/ohos/vendor"; + const std::string str_system_append = "/system/ohos/system"; + if (!strncmp(source_file, str_data.c_str(), strlen(str_data.c_str()))) { + tempFile = str_data_append + tempFile.substr(strlen(str_data.c_str())); + snprintf(cmd, sizeof(cmd), "cat '%s'", tempFile.c_str()); return hdc.ShellToFile(cmd, minutes(1), destination); } - - if (strncmp(source_file, str_vendor.c_str(), strlen(str_vendor.c_str()))) { - tempFile.append(tempFile, strlen(str_vendor.c_str()), len); - tempFile = str_vendor + tempFile; - snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); + if (!strncmp(source_file, str_vendor.c_str(), strlen(str_vendor.c_str()))) { + tempFile = + str_vendor_append + tempFile.substr(strlen(str_vendor.c_str())); + snprintf(cmd, sizeof(cmd), "cat '%s'", tempFile.c_str()); return hdc.ShellToFile(cmd, minutes(1), destination); } - if (strncmp(source_file, str_system.c_str(), strlen(str_system.c_str()))) { - tempFile.append(tempFile, strlen(str_system.c_str()), len); - tempFile = str_system + tempFile; - snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); + if (!strncmp(source_file, str_system.c_str(), strlen(str_system.c_str()))) { + tempFile = + str_system_append + tempFile.substr(strlen(str_system.c_str())); + snprintf(cmd, sizeof(cmd), "cat '%s'", tempFile.c_str()); return hdc.ShellToFile(cmd, minutes(1), destination); } - // ÈÝÆ÷ÍâÎÞ¶ÔӦ·¾¶ return error; } else { snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); @@ -389,8 +383,14 @@ Status PlatformHOS::DownloadSymbolFile(const lldb::ModuleSP &module_sp, HdcClient hdc(m_device_id); std::string tmpdir; - Status error = hdc.Shell("mktemp --directory --tmpdir /data/local/tmp", - seconds(5), &tmpdir); + Status error; + if (m_container) { + error = hdc.Shell("mktemp --directory --tmpdir /data/ohos_data/local/tmp", + seconds(5), &tmpdir); + } else { + error = hdc.Shell("mktemp --directory --tmpdir /data/local/tmp", seconds(5), + &tmpdir); + } if (error.Fail() || tmpdir.empty()) return Status("Failed to generate temporary directory on the device (%s)", error.AsCString()); diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 181047242503..182e7a88b6a1 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -310,7 +310,7 @@ void Platform::GetStatus(Stream &strm) { const bool is_connected = IsConnected(); const bool is_container = GetContainer(); if (log) { - LLDB_LOGF(log, "%p Hsu file(%s):%d Platform::GetStatus() is_container(%d) is_connected(%d)", static_cast(this), __FILE__, __LINE__, is_container, is_connected); + LLDB_LOGF(log, "%p file(%s):%d Platform::GetStatus() is_container(%d) is_connected(%d)", static_cast(this), __FILE__, __LINE__, is_container, is_connected); } if (is_connected) strm.Printf(" Hostname: %s\n", GetHostname()); -- Gitee From 00ce7090fdb9c9888fd9cd6e9964cccd9e128162 Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Thu, 3 Nov 2022 18:40:24 +0300 Subject: [PATCH 36/41] Disable Create host sysroot link if uuid is invalid Signed-off-by: Ivan Eliseev --- lldb/source/Target/ModuleCache.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lldb/source/Target/ModuleCache.cpp b/lldb/source/Target/ModuleCache.cpp index 29bd2b2394b5..d2a7575f8a1f 100644 --- a/lldb/source/Target/ModuleCache.cpp +++ b/lldb/source/Target/ModuleCache.cpp @@ -129,9 +129,26 @@ Status CreateHostSysRootModuleLink(const FileSpec &root_dir_spec, const FileSpec &platform_module_spec, const FileSpec &local_module_spec, bool delete_existing) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); const auto sysroot_module_path_spec = JoinPath(JoinPath(root_dir_spec, hostname), platform_module_spec.GetPath().c_str()); + UUID module_uuid; + { + auto module_sp = + std::make_shared(ModuleSpec(sysroot_module_path_spec)); + module_uuid = module_sp->GetUUID(); + } + + if (!module_uuid.IsValid()) { + LLDB_LOGF(log, "Try CreateHostSysRootModuleLink but uuid is invalid %s", + module_uuid.GetAsString().c_str()); + return Status(); + } + + LLDB_LOGF(log, "CreateHostSysRootModuleLink with uuid %s", + module_uuid.GetAsString().c_str()); + if (FileSystem::Instance().Exists(sysroot_module_path_spec)) { if (!delete_existing) return Status(); -- Gitee From 624a9b9fc12b54474d3623913c30883eaae0e238 Mon Sep 17 00:00:00 2001 From: Oleg Kuptsov Date: Thu, 3 Nov 2022 18:53:51 +0300 Subject: [PATCH 37/41] [OHOS][MIPS] Add mips o32 fpxx support in libunwind Signed-off-by: Ivan Eliseev --- .../clang/Basic/DiagnosticCommonKinds.td | 1 - clang/lib/Basic/Targets/Mips.cpp | 6 - clang/lib/Basic/Targets/Mips.h | 5 +- clang/lib/Driver/ToolChains/Arch/Mips.cpp | 7 - clang/test/Preprocessor/init-mips.c | 8 - libunwind/include/libunwind.h | 12 + libunwind/src/AddressSpace.hpp | 8 +- libunwind/src/DwarfInstructions.hpp | 4 +- libunwind/src/Registers.hpp | 238 +++++++++++------- libunwind/src/UnwindRegistersRestore.S | 64 ++++- libunwind/src/UnwindRegistersSave.S | 140 ++++++++--- libunwind/src/libunwind.cpp | 2 +- 12 files changed, 332 insertions(+), 163 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index ad5815180c48..39dee7e683ff 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -308,7 +308,6 @@ def err_target_unsupported_abi_for_triple : Error< def err_unsupported_abi_for_opt : Error<"'%0' can only be used with the '%1' ABI">; def err_mips_fp64_req : Error< "'%0' can only be used if the target supports the mfhc1 and mthc1 instructions">; -def err_unsupported_fpxx_ohos : Error<"fpxx is currently unsupported on OHOS">; def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">; def err_target_unsupported_fpmath : Error< "the '%0' unit is not supported with this instruction set">; diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index 706e0826f764..39246f650cce 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -269,12 +269,6 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { return false; } - // TODO: remove this if entry when fpxx is supported on OHOS - if (getTriple().isOpenHOS() && FPMode == FPXX) { - Diags.Report(diag::err_unsupported_fpxx_ohos); - return false; - } - // -fpxx is valid only for the o32 ABI if (FPMode == FPXX && (ABI == "n32" || ABI == "n64")) { Diags.Report(diag::err_unsupported_abi_for_opt) << "-mfpxx" << "o32"; diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index 966def9632ad..b54d36e1c95f 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -86,10 +86,7 @@ public: } bool isFP64Default() const { - // TODO: remove getTriple().isOpenHOS() case - // when fpxx is supported on OHOS - return getTriple().isOpenHOS() || CPU == "mips32r6" || ABI == "n32" || - ABI == "n64" || ABI == "64"; + return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64"; } bool isNan2008() const override { return IsNan2008; } diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp index 68a86974e6f1..c374d745da38 100644 --- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp @@ -362,9 +362,6 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, } else if (mips::isFP64ADefault(Triple, CPUName)) { Features.push_back("+fp64"); Features.push_back("+nooddspreg"); - } else if (Triple.isOpenHOS()) { - // TODO: remove this else if entry when fpxx is supported on OHOS - Features.push_back("+fp64"); } AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg, @@ -470,10 +467,6 @@ bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) { bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName, StringRef ABIName, mips::FloatABI FloatABI) { - // TODO: remove this if entry when fpxx is supported on OHOS - if (Triple.isOpenHOS()) - return false; - if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies && Triple.getVendor() != llvm::Triple::MipsTechnologies && !Triple.isAndroid()) diff --git a/clang/test/Preprocessor/init-mips.c b/clang/test/Preprocessor/init-mips.c index 40d8d3a80027..a07cee64e684 100644 --- a/clang/test/Preprocessor/init-mips.c +++ b/clang/test/Preprocessor/init-mips.c @@ -1,7 +1,4 @@ -// RUN: %clang_cc1 -E -dM -triple=mipsel-linux-ohos < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32EL-OHOS %s // -// MIPS32EL-OHOS:#define __mips_fpr 64 - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=mips-none-none < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32BE -check-prefix MIPS32BE-C %s // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=mips-none-none < /dev/null | FileCheck -match-full-lines -check-prefix MIPS32BE -check-prefix MIPS32BE-CXX %s // @@ -1700,11 +1697,6 @@ // RUN: | FileCheck -match-full-lines -check-prefix MIPS64-NOFP %s // MIPS64-NOFP:#define __mips_fpr 64 -// RUN: not %clang_cc1 -target-feature +fpxx \ -// RUN: -E -dM -triple=mipsel-linux-ohos < /dev/null 2>&1 \ -// RUN: | FileCheck -match-full-lines -check-prefix MIPS32EL-OHOS-MFPXX %s -// MIPS32EL-OHOS-MFPXX:error: fpxx is currently unsupported on OHOS - // RUN: not %clang_cc1 -target-feature -fp64 \ // RUN: -E -dM -triple=mips64-none-none < /dev/null 2>&1 \ // RUN: | FileCheck -match-full-lines -check-prefix MIPS64-MFP32 %s diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h index f878b46f0348..7e4f266fab37 100644 --- a/libunwind/include/libunwind.h +++ b/libunwind/include/libunwind.h @@ -84,7 +84,19 @@ typedef uintptr_t unw_word_t; #if defined(__arm__) && !defined(__ARM_DWARF_EH__) && !defined(__SEH__) typedef uint64_t unw_fpreg_t; #else +# if defined(_LIBUNWIND_TARGET_MIPS_O32) && defined(__mips_hard_float) +# if __mips_fpr == 0 +typedef uint64_t unw_fpreg_t; +# elif __mips_fpr == 32 +typedef float unw_fpreg_t; +# elif __mips_fpr == 64 +typedef double unw_fpreg_t; +# else +# error "Unknown __mips_fpr value" +# endif +# else typedef double unw_fpreg_t; +# endif #endif struct unw_proc_info_t { diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp index 36c9f5a9e36f..fcfaf34f1a77 100644 --- a/libunwind/src/AddressSpace.hpp +++ b/libunwind/src/AddressSpace.hpp @@ -176,9 +176,13 @@ public: memcpy(&val, (void *)addr, sizeof(val)); return val; } - double getDouble(pint_t addr) { - double val; + unw_fpreg_t getDouble(pint_t addr) { + unw_fpreg_t val; +#if defined(_LIBUNWIND_TARGET_MIPS_O32) + memcpy(&val, (void *)addr, Registers_mips_o32::getFpuRegsSize()); +#else memcpy(&val, (void *)addr, sizeof(val)); +#endif return val; } v128 getVector(pint_t addr) { diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp index cee4ea53dab7..394448dc4467 100644 --- a/libunwind/src/DwarfInstructions.hpp +++ b/libunwind/src/DwarfInstructions.hpp @@ -56,7 +56,7 @@ private: pint_t initialStackValue); static pint_t getSavedRegister(A &addressSpace, const R ®isters, pint_t cfa, const RegisterLocation &savedReg); - static double getSavedFloatRegister(A &addressSpace, const R ®isters, + static unw_fpreg_t getSavedFloatRegister(A &addressSpace, const R ®isters, pint_t cfa, const RegisterLocation &savedReg); static v128 getSavedVectorRegister(A &addressSpace, const R ®isters, pint_t cfa, const RegisterLocation &savedReg); @@ -119,7 +119,7 @@ typename A::pint_t DwarfInstructions::getSavedRegister( } template -double DwarfInstructions::getSavedFloatRegister( +unw_fpreg_t DwarfInstructions::getSavedFloatRegister( A &addressSpace, const R ®isters, pint_t cfa, const RegisterLocation &savedReg) { switch (savedReg.location) { diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp index 98adb78940f2..9c1f4c936102 100644 --- a/libunwind/src/Registers.hpp +++ b/libunwind/src/Registers.hpp @@ -63,8 +63,8 @@ public: uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value); bool validFloatRegister(int) const { return false; } - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int) const { return false; } v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -242,11 +242,11 @@ inline const char *Registers_x86::getRegisterName(int regNum) { } } -inline double Registers_x86::getFloatRegister(int) const { +inline unw_fpreg_t Registers_x86::getFloatRegister(int) const { _LIBUNWIND_ABORT("no x86 float registers"); } -inline void Registers_x86::setFloatRegister(int, double) { +inline void Registers_x86::setFloatRegister(int, unw_fpreg_t) { _LIBUNWIND_ABORT("no x86 float registers"); } @@ -281,8 +281,8 @@ public: uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value); bool validFloatRegister(int) const { return false; } - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -545,11 +545,11 @@ inline const char *Registers_x86_64::getRegisterName(int regNum) { } } -inline double Registers_x86_64::getFloatRegister(int) const { +inline unw_fpreg_t Registers_x86_64::getFloatRegister(int) const { _LIBUNWIND_ABORT("no x86_64 float registers"); } -inline void Registers_x86_64::setFloatRegister(int, double) { +inline void Registers_x86_64::setFloatRegister(int, unw_fpreg_t) { _LIBUNWIND_ABORT("no x86_64 float registers"); } @@ -600,8 +600,8 @@ public: uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -986,12 +986,12 @@ inline bool Registers_ppc::validFloatRegister(int regNum) const { return true; } -inline double Registers_ppc::getFloatRegister(int regNum) const { +inline unw_fpreg_t Registers_ppc::getFloatRegister(int regNum) const { assert(validFloatRegister(regNum)); return _floatRegisters.__fpregs[regNum - UNW_PPC_F0]; } -inline void Registers_ppc::setFloatRegister(int regNum, double value) { +inline void Registers_ppc::setFloatRegister(int regNum, unw_fpreg_t value) { assert(validFloatRegister(regNum)); _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value; } @@ -1170,8 +1170,8 @@ public: uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -1536,12 +1536,12 @@ inline bool Registers_ppc64::validFloatRegister(int regNum) const { return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31; } -inline double Registers_ppc64::getFloatRegister(int regNum) const { +inline unw_fpreg_t Registers_ppc64::getFloatRegister(int regNum) const { assert(validFloatRegister(regNum)); return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f; } -inline void Registers_ppc64::setFloatRegister(int regNum, double value) { +inline void Registers_ppc64::setFloatRegister(int regNum, unw_fpreg_t value) { assert(validFloatRegister(regNum)); _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value; } @@ -1819,8 +1819,8 @@ public: uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -2070,12 +2070,12 @@ inline bool Registers_arm64::validFloatRegister(int regNum) const { return true; } -inline double Registers_arm64::getFloatRegister(int regNum) const { +inline unw_fpreg_t Registers_arm64::getFloatRegister(int regNum) const { assert(validFloatRegister(regNum)); return _vectorHalfRegisters[regNum - UNW_AARCH64_V0]; } -inline void Registers_arm64::setFloatRegister(int regNum, double value) { +inline void Registers_arm64::setFloatRegister(int regNum, unw_fpreg_t value) { assert(validFloatRegister(regNum)); _vectorHalfRegisters[regNum - UNW_AARCH64_V0] = value; } @@ -2613,8 +2613,8 @@ public: uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -2704,12 +2704,12 @@ inline bool Registers_or1k::validFloatRegister(int /* regNum */) const { return false; } -inline double Registers_or1k::getFloatRegister(int /* regNum */) const { +inline unw_fpreg_t Registers_or1k::getFloatRegister(int /* regNum */) const { _LIBUNWIND_ABORT("or1k float support not implemented"); } inline void Registers_or1k::setFloatRegister(int /* regNum */, - double /* value */) { + unw_fpreg_t /* value */) { _LIBUNWIND_ABORT("or1k float support not implemented"); } @@ -2801,19 +2801,32 @@ inline const char *Registers_or1k::getRegisterName(int regNum) { #endif // _LIBUNWIND_TARGET_OR1K #if defined(_LIBUNWIND_TARGET_MIPS_O32) + +// TODO: check the following for FPU with 32-bit registers: +// - fpxx code works properly +// - fp32 code remains working properly + /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS /// process. class _LIBUNWIND_HIDDEN Registers_mips_o32 { public: Registers_mips_o32(); Registers_mips_o32(const void *registers); +#ifdef __mips_hard_float + Registers_mips_o32(const Registers_mips_o32 &) = default; + Registers_mips_o32 &operator=(const Registers_mips_o32 &src) { + memcpy(&_registers, &src._registers, sizeof(_registers)); + memcpy(&_floatsBuffer, &src._floatsBuffer, sizeof(_floatsBuffer)); + return *this; + } +#endif bool validRegister(int num) const; uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -2823,6 +2836,9 @@ public: return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } static int getArch() { return REGISTERS_MIPS_O32; } +#ifdef __mips_hard_float + static uint32_t getFpuRegsSize(); +#endif uint32_t getSP() const { return _registers.__r[29]; } void setSP(uint32_t value) { _registers.__r[29] = value; } @@ -2843,19 +2859,50 @@ private: /// space. However, using the same layout for 32-bit vs 64-bit /// floating point registers results in a single context size for /// O32 with hard float. - uint32_t _padding; - double _floats[32]; + const uint32_t _fpuRegsSize; + char _floatsBuffer[32 * 8] = {0}; + + char *getFpuRegLocation(int regNum); + const char *getFpuRegLocation(int regNum) const; #endif }; -inline Registers_mips_o32::Registers_mips_o32(const void *registers) { +inline Registers_mips_o32::Registers_mips_o32(const void *registers) +#ifdef __mips_hard_float + : _fpuRegsSize(getFpuRegsSize()) +#endif +{ static_assert((check_fit::does_fit), "mips_o32 registers do not fit into unw_context_t"); memcpy(&_registers, static_cast(registers), sizeof(_registers)); } -inline Registers_mips_o32::Registers_mips_o32() { +#ifdef __mips_hard_float +inline uint32_t Registers_mips_o32::getFpuRegsSize() { +#if __mips_fpr == 32 + return 4; +#elif __mips_fpr == 64 + return 8; +#elif __mips_fpr == 0 + unsigned fpuID; + __asm__ __volatile__(" .set push \n" + " cfc1 %0,$0 \n" + " .set pop \n" + : "=r"(fpuID)); + constexpr unsigned MIPS_FPIR_F64 = (1 << 22); + return (fpuID & MIPS_FPIR_F64) ? 8 : 4; +#else +#error "Unknown __mips_fpr value" +#endif +} +#endif + +inline Registers_mips_o32::Registers_mips_o32() +#ifdef __mips_hard_float + : _fpuRegsSize(getFpuRegsSize()) +#endif +{ memset(&_registers, 0, sizeof(_registers)); } @@ -2873,10 +2920,6 @@ inline bool Registers_mips_o32::validRegister(int regNum) const { return true; if (regNum == UNW_MIPS_LO) return true; -#endif -#if defined(__mips_hard_float) && __mips_fpr == 32 - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) - return true; #endif // FIXME: DSP accumulator registers, MSA registers return false; @@ -2885,17 +2928,6 @@ inline bool Registers_mips_o32::validRegister(int regNum) const { inline uint32_t Registers_mips_o32::getRegister(int regNum) const { if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) return _registers.__r[regNum - UNW_MIPS_R0]; -#if defined(__mips_hard_float) && __mips_fpr == 32 - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { - uint32_t *p; - - if (regNum % 2 == 0) - p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; - else - p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; - return *p; - } -#endif switch (regNum) { case UNW_REG_IP: @@ -2915,19 +2947,6 @@ inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) { _registers.__r[regNum - UNW_MIPS_R0] = value; return; } -#if defined(__mips_hard_float) && __mips_fpr == 32 - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { - uint32_t *p; - - if (regNum % 2 == 0) - p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; - else - p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; - *p = value; - return; - } -#endif - switch (regNum) { case UNW_REG_IP: _registers.__pc = value; @@ -2945,20 +2964,51 @@ inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) { _LIBUNWIND_ABORT("unsupported mips_o32 register"); } +#ifdef __mips_hard_float +inline const char *Registers_mips_o32::getFpuRegLocation(int regNum) const { + const char *regLocation = _floatsBuffer; + int fpuRegNum = regNum - UNW_MIPS_F0; + if (_fpuRegsSize == 4 && fpuRegNum % 2 == 1) + regLocation += (fpuRegNum - 1) * 8 + 4; + else + regLocation += fpuRegNum * 8; + return regLocation; +} + +inline char *Registers_mips_o32::getFpuRegLocation(int regNum) { + char *regLocation = _floatsBuffer; + int fpuRegNum = regNum - UNW_MIPS_F0; + if (_fpuRegsSize == 4 && fpuRegNum % 2 == 1) + regLocation += (fpuRegNum - 1) * 8 + 4; + else + regLocation += fpuRegNum * 8; + return regLocation; +} +#endif + inline bool Registers_mips_o32::validFloatRegister(int regNum) const { -#if defined(__mips_hard_float) && __mips_fpr == 64 - if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) - return true; +#if defined(__mips_hard_float) + return (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31); #else (void)regNum; -#endif return false; +#endif } -inline double Registers_mips_o32::getFloatRegister(int regNum) const { -#if defined(__mips_hard_float) && __mips_fpr == 64 +inline unw_fpreg_t Registers_mips_o32::getFloatRegister(int regNum) const { +#if defined(__mips_hard_float) assert(validFloatRegister(regNum)); - return _floats[regNum - UNW_MIPS_F0]; +#if __mips_fpr == 0 + const char *regLocation = getFpuRegLocation(regNum); + unw_fpreg_t regValue = 0; + memcpy(reinterpret_cast(®Value), regLocation, _fpuRegsSize); + return regValue; +#elif __mips_fpr == 32 || __mips_fpr == 64 + const char *regLocation = getFpuRegLocation(regNum); + return *reinterpret_cast(regLocation); +#else +#error "Unknown __mips_fpr value" +#endif #else (void)regNum; _LIBUNWIND_ABORT("mips_o32 float support not implemented"); @@ -2966,10 +3016,18 @@ inline double Registers_mips_o32::getFloatRegister(int regNum) const { } inline void Registers_mips_o32::setFloatRegister(int regNum, - double value) { -#if defined(__mips_hard_float) && __mips_fpr == 64 + unw_fpreg_t value) { +#if defined(__mips_hard_float) assert(validFloatRegister(regNum)); - _floats[regNum - UNW_MIPS_F0] = value; +#if __mips_fpr == 0 + char *regLocation = getFpuRegLocation(regNum); + memcpy(regLocation, reinterpret_cast(&value), _fpuRegsSize); +#elif __mips_fpr == 32 || __mips_fpr == 64 + char *regLocation = getFpuRegLocation(regNum); + *reinterpret_cast(regLocation) = value; +#else +#error "Unknown __mips_fpr value" +#endif #else (void)regNum; (void)value; @@ -3141,8 +3199,8 @@ public: uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -3252,7 +3310,7 @@ inline bool Registers_mips_newabi::validFloatRegister(int regNum) const { return false; } -inline double Registers_mips_newabi::getFloatRegister(int regNum) const { +inline unw_fpreg_t Registers_mips_newabi::getFloatRegister(int regNum) const { #ifdef __mips_hard_float assert(validFloatRegister(regNum)); return _floats[regNum - UNW_MIPS_F0]; @@ -3263,7 +3321,7 @@ inline double Registers_mips_newabi::getFloatRegister(int regNum) const { } inline void Registers_mips_newabi::setFloatRegister(int regNum, - double value) { + unw_fpreg_t value) { #ifdef __mips_hard_float assert(validFloatRegister(regNum)); _floats[regNum - UNW_MIPS_F0] = value; @@ -3438,8 +3496,8 @@ public: uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -3519,11 +3577,11 @@ inline void Registers_sparc::setRegister(int regNum, uint32_t value) { inline bool Registers_sparc::validFloatRegister(int) const { return false; } -inline double Registers_sparc::getFloatRegister(int) const { +inline unw_fpreg_t Registers_sparc::getFloatRegister(int) const { _LIBUNWIND_ABORT("no Sparc float registers"); } -inline void Registers_sparc::setFloatRegister(int, double) { +inline void Registers_sparc::setFloatRegister(int, unw_fpreg_t) { _LIBUNWIND_ABORT("no Sparc float registers"); } @@ -3809,8 +3867,8 @@ public: uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -3885,12 +3943,12 @@ inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const { return false; } -inline double Registers_hexagon::getFloatRegister(int /* regNum */) const { +inline unw_fpreg_t Registers_hexagon::getFloatRegister(int /* regNum */) const { _LIBUNWIND_ABORT("hexagon float support not implemented"); } inline void Registers_hexagon::setFloatRegister(int /* regNum */, - double /* value */) { + unw_fpreg_t /* value */) { _LIBUNWIND_ABORT("hexagon float support not implemented"); } @@ -4267,7 +4325,7 @@ inline bool Registers_riscv::validFloatRegister(int regNum) const { # endif } -inline fp_t Registers_riscv::getFloatRegister(int regNum) const { +inline unw_fpreg_t Registers_riscv::getFloatRegister(int regNum) const { # if defined(__riscv_flen) assert(validFloatRegister(regNum)); return _floats[regNum - UNW_RISCV_F0]; @@ -4277,7 +4335,7 @@ inline fp_t Registers_riscv::getFloatRegister(int regNum) const { # endif } -inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) { +inline void Registers_riscv::setFloatRegister(int regNum, unw_fpreg_t value) { # if defined(__riscv_flen) assert(validFloatRegister(regNum)); _floats[regNum - UNW_RISCV_F0] = value; @@ -4312,8 +4370,8 @@ public: uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -4418,12 +4476,12 @@ inline bool Registers_ve::validFloatRegister(int /* regNum */) const { return false; } -inline double Registers_ve::getFloatRegister(int /* regNum */) const { +inline unw_fpreg_t Registers_ve::getFloatRegister(int /* regNum */) const { _LIBUNWIND_ABORT("VE doesn't have float registers"); } inline void Registers_ve::setFloatRegister(int /* regNum */, - double /* value */) { + unw_fpreg_t /* value */) { _LIBUNWIND_ABORT("VE doesn't have float registers"); } @@ -4755,8 +4813,8 @@ public: uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value); bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); + unw_fpreg_t getFloatRegister(int num) const; + void setFloatRegister(int num, unw_fpreg_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); @@ -4850,7 +4908,7 @@ inline bool Registers_s390x::validFloatRegister(int regNum) const { return regNum >= UNW_S390X_F0 && regNum <= UNW_S390X_F15; } -inline double Registers_s390x::getFloatRegister(int regNum) const { +inline unw_fpreg_t Registers_s390x::getFloatRegister(int regNum) const { // NOTE: FPR DWARF register numbers are not consecutive. switch (regNum) { case UNW_S390X_F0: @@ -4889,7 +4947,7 @@ inline double Registers_s390x::getFloatRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported s390x register"); } -inline void Registers_s390x::setFloatRegister(int regNum, double value) { +inline void Registers_s390x::setFloatRegister(int regNum, unw_fpreg_t value) { // NOTE: FPR DWARF register numbers are not consecutive. switch (regNum) { case UNW_S390X_F0: diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S index eeb64534966d..894b5f60a155 100644 --- a/libunwind/src/UnwindRegistersRestore.S +++ b/libunwind/src/UnwindRegistersRestore.S @@ -917,7 +917,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) .set noreorder .set nomacro #ifdef __mips_hard_float -#if __mips_fpr != 64 +#if __mips_fpr == 32 ldc1 $f0, (4 * 36 + 8 * 0)($4) ldc1 $f2, (4 * 36 + 8 * 2)($4) ldc1 $f4, (4 * 36 + 8 * 4)($4) @@ -934,7 +934,46 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) ldc1 $f26, (4 * 36 + 8 * 26)($4) ldc1 $f28, (4 * 36 + 8 * 28)($4) ldc1 $f30, (4 * 36 + 8 * 30)($4) -#else +#elif __mips_fpr == 64 + ldc1 $f0, (4 * 36 + 8 * 0)($4) + ldc1 $f1, (4 * 36 + 8 * 1)($4) + ldc1 $f2, (4 * 36 + 8 * 2)($4) + ldc1 $f3, (4 * 36 + 8 * 3)($4) + ldc1 $f4, (4 * 36 + 8 * 4)($4) + ldc1 $f5, (4 * 36 + 8 * 5)($4) + ldc1 $f6, (4 * 36 + 8 * 6)($4) + ldc1 $f7, (4 * 36 + 8 * 7)($4) + ldc1 $f8, (4 * 36 + 8 * 8)($4) + ldc1 $f9, (4 * 36 + 8 * 9)($4) + ldc1 $f10, (4 * 36 + 8 * 10)($4) + ldc1 $f11, (4 * 36 + 8 * 11)($4) + ldc1 $f12, (4 * 36 + 8 * 12)($4) + ldc1 $f13, (4 * 36 + 8 * 13)($4) + ldc1 $f14, (4 * 36 + 8 * 14)($4) + ldc1 $f15, (4 * 36 + 8 * 15)($4) + ldc1 $f16, (4 * 36 + 8 * 16)($4) + ldc1 $f17, (4 * 36 + 8 * 17)($4) + ldc1 $f18, (4 * 36 + 8 * 18)($4) + ldc1 $f19, (4 * 36 + 8 * 19)($4) + ldc1 $f20, (4 * 36 + 8 * 20)($4) + ldc1 $f21, (4 * 36 + 8 * 21)($4) + ldc1 $f22, (4 * 36 + 8 * 22)($4) + ldc1 $f23, (4 * 36 + 8 * 23)($4) + ldc1 $f24, (4 * 36 + 8 * 24)($4) + ldc1 $f25, (4 * 36 + 8 * 25)($4) + ldc1 $f26, (4 * 36 + 8 * 26)($4) + ldc1 $f27, (4 * 36 + 8 * 27)($4) + ldc1 $f28, (4 * 36 + 8 * 28)($4) + ldc1 $f29, (4 * 36 + 8 * 29)($4) + ldc1 $f30, (4 * 36 + 8 * 30)($4) + ldc1 $f31, (4 * 36 + 8 * 31)($4) +#elif __mips_fpr == 0 + cfc1 $t0, $0 + li $t1, 1 + sll $t1, $t1, 22 + and $t0, $t0, $t1 + beq $t0, $0, _fp32 +_fp64: ldc1 $f0, (4 * 36 + 8 * 0)($4) ldc1 $f1, (4 * 36 + 8 * 1)($4) ldc1 $f2, (4 * 36 + 8 * 2)($4) @@ -967,8 +1006,29 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) ldc1 $f29, (4 * 36 + 8 * 29)($4) ldc1 $f30, (4 * 36 + 8 * 30)($4) ldc1 $f31, (4 * 36 + 8 * 31)($4) + j _after_float +_fp32: + ldc1 $f0, (4 * 36 + 8 * 0)($4) + ldc1 $f2, (4 * 36 + 8 * 2)($4) + ldc1 $f4, (4 * 36 + 8 * 4)($4) + ldc1 $f6, (4 * 36 + 8 * 6)($4) + ldc1 $f8, (4 * 36 + 8 * 8)($4) + ldc1 $f10, (4 * 36 + 8 * 10)($4) + ldc1 $f12, (4 * 36 + 8 * 12)($4) + ldc1 $f14, (4 * 36 + 8 * 14)($4) + ldc1 $f16, (4 * 36 + 8 * 16)($4) + ldc1 $f18, (4 * 36 + 8 * 18)($4) + ldc1 $f20, (4 * 36 + 8 * 20)($4) + ldc1 $f22, (4 * 36 + 8 * 22)($4) + ldc1 $f24, (4 * 36 + 8 * 24)($4) + ldc1 $f26, (4 * 36 + 8 * 26)($4) + ldc1 $f28, (4 * 36 + 8 * 28)($4) + ldc1 $f30, (4 * 36 + 8 * 30)($4) +#else +#error "Unknown __mips_fpr value" #endif #endif +_after_float: // restore hi and lo lw $8, (4 * 33)($4) mthi $8 diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S index f57dd637dd9d..2b79f448507f 100644 --- a/libunwind/src/UnwindRegistersSave.S +++ b/libunwind/src/UnwindRegistersSave.S @@ -135,46 +135,8 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) .set noat .set noreorder .set nomacro - sw $1, (4 * 1)($4) - sw $2, (4 * 2)($4) - sw $3, (4 * 3)($4) - sw $4, (4 * 4)($4) - sw $5, (4 * 5)($4) - sw $6, (4 * 6)($4) - sw $7, (4 * 7)($4) - sw $8, (4 * 8)($4) - sw $9, (4 * 9)($4) - sw $10, (4 * 10)($4) - sw $11, (4 * 11)($4) - sw $12, (4 * 12)($4) - sw $13, (4 * 13)($4) - sw $14, (4 * 14)($4) - sw $15, (4 * 15)($4) - sw $16, (4 * 16)($4) - sw $17, (4 * 17)($4) - sw $18, (4 * 18)($4) - sw $19, (4 * 19)($4) - sw $20, (4 * 20)($4) - sw $21, (4 * 21)($4) - sw $22, (4 * 22)($4) - sw $23, (4 * 23)($4) - sw $24, (4 * 24)($4) - sw $25, (4 * 25)($4) - sw $26, (4 * 26)($4) - sw $27, (4 * 27)($4) - sw $28, (4 * 28)($4) - sw $29, (4 * 29)($4) - sw $30, (4 * 30)($4) - sw $31, (4 * 31)($4) - # Store return address to pc - sw $31, (4 * 32)($4) - # hi and lo - mfhi $8 - sw $8, (4 * 33)($4) - mflo $8 - sw $8, (4 * 34)($4) #ifdef __mips_hard_float -#if __mips_fpr != 64 +#if __mips_fpr == 32 sdc1 $f0, (4 * 36 + 8 * 0)($4) sdc1 $f2, (4 * 36 + 8 * 2)($4) sdc1 $f4, (4 * 36 + 8 * 4)($4) @@ -191,7 +153,46 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) sdc1 $f26, (4 * 36 + 8 * 26)($4) sdc1 $f28, (4 * 36 + 8 * 28)($4) sdc1 $f30, (4 * 36 + 8 * 30)($4) -#else +#elif __mips_fpr == 64 + sdc1 $f0, (4 * 36 + 8 * 0)($4) + sdc1 $f1, (4 * 36 + 8 * 1)($4) + sdc1 $f2, (4 * 36 + 8 * 2)($4) + sdc1 $f3, (4 * 36 + 8 * 3)($4) + sdc1 $f4, (4 * 36 + 8 * 4)($4) + sdc1 $f5, (4 * 36 + 8 * 5)($4) + sdc1 $f6, (4 * 36 + 8 * 6)($4) + sdc1 $f7, (4 * 36 + 8 * 7)($4) + sdc1 $f8, (4 * 36 + 8 * 8)($4) + sdc1 $f9, (4 * 36 + 8 * 9)($4) + sdc1 $f10, (4 * 36 + 8 * 10)($4) + sdc1 $f11, (4 * 36 + 8 * 11)($4) + sdc1 $f12, (4 * 36 + 8 * 12)($4) + sdc1 $f13, (4 * 36 + 8 * 13)($4) + sdc1 $f14, (4 * 36 + 8 * 14)($4) + sdc1 $f15, (4 * 36 + 8 * 15)($4) + sdc1 $f16, (4 * 36 + 8 * 16)($4) + sdc1 $f17, (4 * 36 + 8 * 17)($4) + sdc1 $f18, (4 * 36 + 8 * 18)($4) + sdc1 $f19, (4 * 36 + 8 * 19)($4) + sdc1 $f20, (4 * 36 + 8 * 20)($4) + sdc1 $f21, (4 * 36 + 8 * 21)($4) + sdc1 $f22, (4 * 36 + 8 * 22)($4) + sdc1 $f23, (4 * 36 + 8 * 23)($4) + sdc1 $f24, (4 * 36 + 8 * 24)($4) + sdc1 $f25, (4 * 36 + 8 * 25)($4) + sdc1 $f26, (4 * 36 + 8 * 26)($4) + sdc1 $f27, (4 * 36 + 8 * 27)($4) + sdc1 $f28, (4 * 36 + 8 * 28)($4) + sdc1 $f29, (4 * 36 + 8 * 29)($4) + sdc1 $f30, (4 * 36 + 8 * 30)($4) + sdc1 $f31, (4 * 36 + 8 * 31)($4) +#elif __mips_fpr == 0 + cfc1 $t0, $0 + li $t1, 1 + sll $t1, $t1, 22 + and $t0, $t0, $t1 + beq $t0, $0, _fp32 +_fp64: sdc1 $f0, (4 * 36 + 8 * 0)($4) sdc1 $f1, (4 * 36 + 8 * 1)($4) sdc1 $f2, (4 * 36 + 8 * 2)($4) @@ -224,8 +225,67 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) sdc1 $f29, (4 * 36 + 8 * 29)($4) sdc1 $f30, (4 * 36 + 8 * 30)($4) sdc1 $f31, (4 * 36 + 8 * 31)($4) + j _after_float +_fp32: + sdc1 $f0, (4 * 36 + 8 * 0)($4) + sdc1 $f2, (4 * 36 + 8 * 2)($4) + sdc1 $f4, (4 * 36 + 8 * 4)($4) + sdc1 $f6, (4 * 36 + 8 * 6)($4) + sdc1 $f8, (4 * 36 + 8 * 8)($4) + sdc1 $f10, (4 * 36 + 8 * 10)($4) + sdc1 $f12, (4 * 36 + 8 * 12)($4) + sdc1 $f14, (4 * 36 + 8 * 14)($4) + sdc1 $f16, (4 * 36 + 8 * 16)($4) + sdc1 $f18, (4 * 36 + 8 * 18)($4) + sdc1 $f20, (4 * 36 + 8 * 20)($4) + sdc1 $f22, (4 * 36 + 8 * 22)($4) + sdc1 $f24, (4 * 36 + 8 * 24)($4) + sdc1 $f26, (4 * 36 + 8 * 26)($4) + sdc1 $f28, (4 * 36 + 8 * 28)($4) + sdc1 $f30, (4 * 36 + 8 * 30)($4) +#else +#error "Unknown __mips_fpr value" #endif #endif +_after_float: + sw $1, (4 * 1)($4) + sw $2, (4 * 2)($4) + sw $3, (4 * 3)($4) + sw $4, (4 * 4)($4) + sw $5, (4 * 5)($4) + sw $6, (4 * 6)($4) + sw $7, (4 * 7)($4) + sw $8, (4 * 8)($4) + sw $9, (4 * 9)($4) + sw $10, (4 * 10)($4) + sw $11, (4 * 11)($4) + sw $12, (4 * 12)($4) + sw $13, (4 * 13)($4) + sw $14, (4 * 14)($4) + sw $15, (4 * 15)($4) + sw $16, (4 * 16)($4) + sw $17, (4 * 17)($4) + sw $18, (4 * 18)($4) + sw $19, (4 * 19)($4) + sw $20, (4 * 20)($4) + sw $21, (4 * 21)($4) + sw $22, (4 * 22)($4) + sw $23, (4 * 23)($4) + sw $24, (4 * 24)($4) + sw $25, (4 * 25)($4) + sw $26, (4 * 26)($4) + sw $27, (4 * 27)($4) + sw $28, (4 * 28)($4) + sw $29, (4 * 29)($4) + sw $30, (4 * 30)($4) + sw $31, (4 * 31)($4) + # Store return address to pc + sw $31, (4 * 32)($4) + # hi and lo + mfhi $8 + sw $8, (4 * 33)($4) + mflo $8 + sw $8, (4 * 34)($4) jr $31 # return UNW_ESUCCESS or $2, $0, $0 diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp index b8b41ff25e54..0f67d15dc935 100644 --- a/libunwind/src/libunwind.cpp +++ b/libunwind/src/libunwind.cpp @@ -157,7 +157,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_get_fpreg, unw_get_fpreg) /// Set value of specified float register at cursor position in stack frame. _LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, unw_fpreg_t value) { -#if defined(_LIBUNWIND_ARM_EHABI) +#if defined(_LIBUNWIND_ARM_EHABI) || (defined(__mips__) && __mips_fpr == 0) _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)", static_cast(cursor), regNum, value); #else -- Gitee From 983eba6279959ca810372932a0a555c02523ed9f Mon Sep 17 00:00:00 2001 From: Kholiavin Nikolai Date: Thu, 3 Nov 2022 20:02:19 +0300 Subject: [PATCH 38/41] [OHOS][ASan] Disable SANITIZER_CAN_USE_PREINIT_ARRAY OHOS Musl libc does not support .preinit_array sections, so disable `SANITIZER_CAN_USE_PREINIT_ARRAY` for OHOS. Signed-off-by: Ivan Eliseev --- compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index 9a5923dd8301..00c0a5b0bbc3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -104,7 +104,7 @@ // // FIXME: do we have anything like this on Mac? #ifndef SANITIZER_CAN_USE_PREINIT_ARRAY -#if (SANITIZER_LINUX || SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC) +#if ((SANITIZER_LINUX && !SANITIZER_OHOS) || SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC) #define SANITIZER_CAN_USE_PREINIT_ARRAY 1 // Before Solaris 11.4, .preinit_array is fully supported only with GNU ld. // FIXME: Check for those conditions. -- Gitee From 632694ff73a09a58854016d01c8e92a261732b1a Mon Sep 17 00:00:00 2001 From: Ivan Eliseev Date: Fri, 4 Nov 2022 13:39:34 +0300 Subject: [PATCH 39/41] [OHOS] Fix compilation issues Signed-off-by: Ivan Eliseev --- clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 1 - .../Checkers/OpenHarmony/MemcpyChecker.cpp | 9 +- .../Interpreter/ExceptionTests/CMakeLists.txt | 1 - .../Interpreter/OptionGroupPlatform.cpp | 13 +- .../source/Plugins/Platform/HOS/HdcClient.cpp | 216 ++++++++---------- .../Plugins/Platform/HOS/PlatformHOS.cpp | 148 ++++++------ .../source/Plugins/Platform/HOS/PlatformHOS.h | 8 +- .../HOS/PlatformHOSRemoteGDBServer.cpp | 103 ++++----- .../Plugins/Platform/OHOS/PlatformOHOS.cpp | 5 +- .../OHOS/PlatformOHOSRemoteGDBServer.cpp | 2 +- lldb/source/Target/ModuleCache.cpp | 2 +- lldb/source/Target/Platform.cpp | 9 +- 12 files changed, 239 insertions(+), 278 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index 8b0f76e66965..610ba635bc58 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -140,7 +140,6 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, // -mrelax is default, unless -mno-relax is specified. // lld does not support relocations used by -mrelax on RISC-V bool DefaultMRelax = !Triple.isOpenHOS(); - if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, DefaultMRelax)) if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, DefaultMRelax)) { Features.push_back("+relax"); // -gsplit-dwarf -mrelax requires DW_AT_high_pc/DW_AT_ranges/... indexing diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp index 0f80e0e458e0..65f3259b6753 100644 --- a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/MemcpyChecker.cpp @@ -14,9 +14,10 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h" using namespace clang; using namespace ento; @@ -38,9 +39,9 @@ MemcpyChecker::MemcpyChecker() } void MemcpyChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { - if (!Call.isCalled(MemcpyS)) { - return; - } + if (!MemcpyS.matches(Call)) { + return; + } SValBuilder &SVB = C.getSValBuilder(); ProgramStateRef state = C.getState(); diff --git a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt index b10af074635e..9f6ed2eb4fe7 100644 --- a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt +++ b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt @@ -13,7 +13,6 @@ set(LLVM_LINK_COMPONENTS add_clang_unittest(ClangReplInterpreterExceptionTests InterpreterExceptionTest.cpp ) -set_property(TARGET ClangReplInterpreterExceptionTests APPEND_STRING PROPERTY LINK_FLAGS " -static-libstdc++ -l:libc++abi.a") llvm_update_compile_flags(ClangReplInterpreterExceptionTests) target_link_libraries(ClangReplInterpreterExceptionTests PUBLIC diff --git a/lldb/source/Interpreter/OptionGroupPlatform.cpp b/lldb/source/Interpreter/OptionGroupPlatform.cpp index b6e3e04c3710..45694fe112df 100644 --- a/lldb/source/Interpreter/OptionGroupPlatform.cpp +++ b/lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -21,10 +21,10 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( PlatformList &platforms = interpreter.GetDebugger().GetPlatformList(); PlatformSP platform_sp; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMANDS)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d OptionGroupPlatform::%s call make_selected:%d", __FILE__, __LINE__, __FUNCTION__, make_selected); - } + Log *log = GetLog(LLDBLog::Commands); + if (log) + log->Printf("Hsu file(%s):%d OptionGroupPlatform::%s call make_selected:%d", + __FILE__, __LINE__, __FUNCTION__, make_selected); if (!m_platform_name.empty()) { platform_sp = platforms.Create(m_platform_name); if (!platform_sp) { @@ -34,9 +34,8 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( } if (platform_sp) { if (GetContainer()) { - if (log) { - LLDB_LOGF(log, "Platform is created inside container."); - } + if (log) + log->Printf("Platform is created inside container."); platform_sp->SetContainer(true); } if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture( diff --git a/lldb/source/Plugins/Platform/HOS/HdcClient.cpp b/lldb/source/Plugins/Platform/HOS/HdcClient.cpp index 609673b19b2c..4ee3d17b73dc 100644 --- a/lldb/source/Plugins/Platform/HOS/HdcClient.cpp +++ b/lldb/source/Plugins/Platform/HOS/HdcClient.cpp @@ -21,7 +21,7 @@ #include "lldb/Utility/DataEncoder.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Log.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timeout.h" @@ -99,11 +99,10 @@ Status HdcClient::CreateByDeviceID(const std::string &device_id, auto error = hdc.GetDevices(connect_devices); if (error.Fail()) return error; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s device_id(%s)", __FILE__, - __LINE__, __FUNCTION__, device_id.c_str()); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s device_id(%s)", __FILE__, + __LINE__, __FUNCTION__, device_id.c_str()); std::string android_serial; if (!device_id.empty()) android_serial = device_id; @@ -135,21 +134,19 @@ HdcClient::~HdcClient() {} void HdcClient::SetDeviceID(const std::string &device_id) { m_device_id = device_id; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s m_device_id(%s)", __FILE__, - __LINE__, __FUNCTION__, m_device_id.c_str()); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s m_device_id(%s)", __FILE__, + __LINE__, __FUNCTION__, m_device_id.c_str()); } const std::string &HdcClient::GetDeviceID() const { return m_device_id; } Status HdcClient::Connect() { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s new ConnectionFileDescriptor", __FILE__, __LINE__, __FUNCTION__); - } Status error; m_conn.reset(new ConnectionFileDescriptor); std::string port = "5037"; @@ -157,17 +154,15 @@ Status HdcClient::Connect() { const char *env_port = std::getenv("HDC_SERVER_PORT"); if ((env_port != NULL) && (atoi(env_port) > 0)) { port = env_port; - if (log) { + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s env_port(%s) port(%s)", __FILE__, __LINE__, __FUNCTION__, env_port, port.c_str()); - } } std::string uri = "connect://127.0.0.1:" + port; - if (log) { + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s uri(%s)", __FILE__, __LINE__, __FUNCTION__, uri.c_str()); - } m_conn->Connect(uri.c_str(), &error); return error; @@ -175,11 +170,10 @@ Status HdcClient::Connect() { Status HdcClient::GetDevices(DeviceIDList &device_list) { device_list.clear(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s call", __FILE__, __LINE__, __FUNCTION__); - } auto error = SendMessage("host:devices"); if (error.Fail()) return error; @@ -206,19 +200,17 @@ Status HdcClient::GetDevices(DeviceIDList &device_list) { Status HdcClient::SetPortForwarding(const uint16_t local_port, const uint16_t remote_port) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s local_port(%d) remote_port(%d)", __FILE__, __LINE__, __FUNCTION__, local_port, remote_port); - } char message[48]; snprintf(message, sizeof(message), "forward:tcp:%d;tcp:%d", local_port, remote_port); - if (log) { + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s message(%s)", __FILE__, __LINE__, __FUNCTION__, message); - } const auto error = SendDeviceMessage(message); if (error.Fail()) return error; @@ -230,11 +222,10 @@ Status HdcClient::SetPortForwarding(const uint16_t local_port, llvm::StringRef remote_socket_name, const UnixSocketNamespace socket_namespace) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s local_port(%d)", __FILE__, __LINE__, __FUNCTION__, local_port); - } char message[PATH_MAX]; const char *sock_namespace_str = (socket_namespace == UnixSocketNamespaceAbstract) @@ -243,10 +234,9 @@ HdcClient::SetPortForwarding(const uint16_t local_port, snprintf(message, sizeof(message), "forward:tcp:%d;%s:%s", local_port, sock_namespace_str, remote_socket_name.str().c_str()); - if (log) { + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s message(%s)", __FILE__, __LINE__, __FUNCTION__, message); - } const auto error = SendDeviceMessage(message); if (error.Fail()) return error; @@ -255,18 +245,16 @@ HdcClient::SetPortForwarding(const uint16_t local_port, } Status HdcClient::DeletePortForwarding(const uint16_t local_port) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s local_port(%d)", __FILE__, __LINE__, __FUNCTION__, local_port); - } char message[32]; snprintf(message, sizeof(message), "killforward:tcp:%d", local_port); - if (log) { + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s message(%s)", __FILE__, __LINE__, __FUNCTION__, message); - } const auto error = SendDeviceMessage(message); if (error.Fail()) return error; @@ -276,11 +264,10 @@ Status HdcClient::DeletePortForwarding(const uint16_t local_port) { Status HdcClient::SendMessage(const std::string &packet, const bool reconnect) { Status error; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s packet(%s) reconnect(%d)", __FILE__, __LINE__, __FUNCTION__, packet.c_str(), reconnect); - } if (!m_conn || reconnect) { error = Connect(); if (error.Fail()) @@ -302,27 +289,26 @@ Status HdcClient::SendMessage(const std::string &packet, const bool reconnect) { } Status HdcClient::SendDeviceMessage(const std::string &packet) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s packet(%s) ", __FILE__, __LINE__, __FUNCTION__, packet.c_str()); - } + std::ostringstream msg; msg << "host-serial:" << m_device_id << ":" << packet; - if (log) { + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s msg(%s) ", __FILE__, __LINE__, __FUNCTION__, msg.str().c_str()); - } + return SendMessage(msg.str()); } Status HdcClient::ReadMessage(std::vector &message) { message.clear(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s call ", __FILE__, __LINE__, __FUNCTION__); - } char buffer[5]; buffer[4] = 0; @@ -345,11 +331,11 @@ Status HdcClient::ReadMessageStream(std::vector &message, milliseconds timeout) { auto start = steady_clock::now(); message.clear(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s call ", __FILE__, __LINE__, __FUNCTION__); - } + Status error; lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; char buffer[1024]; @@ -370,7 +356,6 @@ Status HdcClient::ReadMessageStream(std::vector &message, Status HdcClient::ReadResponseStatus() { char response_id[5]; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); static const size_t packet_len = 4; response_id[packet_len] = 0; @@ -378,10 +363,11 @@ Status HdcClient::ReadResponseStatus() { if (error.Fail()) return error; - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s response_id(%s) ", __FILE__, __LINE__, __FUNCTION__, response_id); - } + if (strncmp(response_id, kOKAY, packet_len) != 0) return GetResponseError(response_id); @@ -389,13 +375,13 @@ Status HdcClient::ReadResponseStatus() { } Status HdcClient::GetResponseError(const char *response_id) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); if (strcmp(response_id, kFAIL) != 0) return Status("Got unexpected response id from hdc: \"%s\"", response_id); - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s response_id(%s) ", __FILE__, __LINE__, __FUNCTION__, response_id); - } + std::vector error_message; auto error = ReadMessage(error_message); if (error.Success()) @@ -407,17 +393,17 @@ Status HdcClient::GetResponseError(const char *response_id) { Status HdcClient::SwitchDeviceTransport() { std::ostringstream msg; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); msg << "host:transport:" << m_device_id; auto error = SendMessage(msg.str()); if (error.Fail()) return error; - if (log) { + Log *log = GetLog(LLDBLog::Platform); + if (log) log->Printf("Hsu file(%s):%d HdcClient::%s m_device_id(%s) msg(%s)", __FILE__, __LINE__, __FUNCTION__, m_device_id.c_str(), msg.str().c_str()); - } + return ReadResponseStatus(); } @@ -484,11 +470,11 @@ Status HdcClient::internalShell(const char *command, milliseconds timeout, Status HdcClient::Shell(const char *command, milliseconds timeout, std::string *output) { std::vector output_buffer; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s command(%s)", __FILE__, - __LINE__, __FUNCTION__, command); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s command(%s)", __FILE__, __LINE__, + __FUNCTION__, command); + auto error = internalShell(command, timeout, output_buffer); if (error.Fail()) return error; @@ -501,11 +487,11 @@ Status HdcClient::Shell(const char *command, milliseconds timeout, Status HdcClient::ShellToFile(const char *command, milliseconds timeout, const FileSpec &output_file_spec) { std::vector output_buffer; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s command(%s)", __FILE__, - __LINE__, __FUNCTION__, command); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s command(%s)", __FILE__, __LINE__, + __FUNCTION__, command); + auto error = internalShell(command, timeout, output_buffer); if (error.Fail()) return error; @@ -513,10 +499,9 @@ Status HdcClient::ShellToFile(const char *command, milliseconds timeout, const auto output_filename = output_file_spec.GetPath(); std::error_code EC; llvm::raw_fd_ostream dst(output_filename, EC, llvm::sys::fs::OF_None); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s output_filename(%s)", - __FILE__, __LINE__, __FUNCTION__, output_filename.c_str()); - } + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s output_filename(%s)", __FILE__, + __LINE__, __FUNCTION__, output_filename.c_str()); if (EC) return Status("Unable to open local file %s", output_filename.c_str()); @@ -544,21 +529,21 @@ Status HdcClient::SyncService::internalPullFile(const FileSpec &remote_file, std::error_code EC; llvm::raw_fd_ostream dst(local_file_path, EC, llvm::sys::fs::OF_None); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s local_file_path(%s)", - __FILE__, __LINE__, __FUNCTION__, local_file_path.c_str()); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s local_file_path(%s)", __FILE__, + __LINE__, __FUNCTION__, local_file_path.c_str()); + if (EC) return Status("Unable to open local file %s", local_file_path.c_str()); const auto remote_file_path = remote_file.GetPath(false); auto error = SendSyncRequest(kRECV, remote_file_path.length(), remote_file_path.c_str()); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s remote_file_path(%s)", - __FILE__, __LINE__, __FUNCTION__, remote_file_path.c_str()); - } + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s remote_file_path(%s)", __FILE__, + __LINE__, __FUNCTION__, remote_file_path.c_str()); + if (error.Fail()) return error; @@ -583,11 +568,11 @@ Status HdcClient::SyncService::internalPushFile(const FileSpec &local_file, const FileSpec &remote_file) { const auto local_file_path(local_file.GetPath()); std::ifstream src(local_file_path.c_str(), std::ios::in | std::ios::binary); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s local_file_path(%s)", - __FILE__, __LINE__, __FUNCTION__, local_file_path.c_str()); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s local_file_path(%s)", __FILE__, + __LINE__, __FUNCTION__, local_file_path.c_str()); + if (!src.is_open()) return Status("Unable to open local file %s", local_file_path.c_str()); @@ -596,10 +581,10 @@ Status HdcClient::SyncService::internalPushFile(const FileSpec &local_file, std::string file_description_str = file_description.str(); auto error = SendSyncRequest(kSEND, file_description_str.length(), file_description_str.c_str()); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s file_description_str(%s)", - __FILE__, __LINE__, __FUNCTION__, file_description_str.c_str()); - } + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s file_description_str(%s)", + __FILE__, __LINE__, __FUNCTION__, file_description_str.c_str()); + if (error.Fail()) return error; @@ -645,11 +630,11 @@ Status HdcClient::SyncService::internalStat(const FileSpec &remote_file, const std::string remote_file_path(remote_file.GetPath(false)); auto error = SendSyncRequest(kSTAT, remote_file_path.length(), remote_file_path.c_str()); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s remote_file_path(%s)", - __FILE__, __LINE__, __FUNCTION__, remote_file_path.c_str()); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s remote_file_path(%s)", __FILE__, + __LINE__, __FUNCTION__, remote_file_path.c_str()); + if (error.Fail()) return Status("Failed to send request: %s", error.AsCString()); @@ -680,13 +665,12 @@ Status HdcClient::SyncService::internalStat(const FileSpec &remote_file, Status HdcClient::SyncService::PullFile(const FileSpec &remote_file, const FileSpec &local_file) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, - "Hsu file(%s):%d HdcClient::%s remote_file(%s) local_file(%s)", - __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), - local_file.GetPath().c_str()); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s remote_file(%s) local_file(%s)", + __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), + local_file.GetPath().c_str()); + return executeCommand([this, &remote_file, &local_file]() { return internalPullFile(remote_file, local_file); }); @@ -694,13 +678,11 @@ Status HdcClient::SyncService::PullFile(const FileSpec &remote_file, Status HdcClient::SyncService::PushFile(const FileSpec &local_file, const FileSpec &remote_file) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, - "Hsu file(%s):%d HdcClient::%s remote_file(%s) local_file(%s)", - __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), - local_file.GetPath().c_str()); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s remote_file(%s) local_file(%s)", + __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), + local_file.GetPath().c_str()); return executeCommand([this, &local_file, &remote_file]() { return internalPushFile(local_file, remote_file); }); @@ -708,12 +690,11 @@ Status HdcClient::SyncService::PushFile(const FileSpec &local_file, Status HdcClient::SyncService::Stat(const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d HdcClient::%s remote_file(%s) mode(%d)", - __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), - mode); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d HdcClient::%s remote_file(%s) mode(%d)", + __FILE__, __LINE__, __FUNCTION__, remote_file.GetPath().c_str(), + mode); return executeCommand([this, &remote_file, &mode, &size, &mtime]() { return internalStat(remote_file, mode, size, mtime); }); @@ -744,7 +725,8 @@ Status HdcClient::SyncService::SendSyncRequest(const char *request_id, const uint32_t data_len, const void *data) { const DataBufferSP data_sp(new DataBufferHeap(kSyncPacketLen, 0)); - DataEncoder encoder(data_sp, eByteOrderLittle, sizeof(void *)); + DataEncoder encoder(data_sp->GetBytes(), data_sp->GetByteSize(), + eByteOrderLittle, sizeof(void *)); auto offset = encoder.PutData(0, request_id, strlen(request_id)); encoder.PutUnsigned(offset, 4, data_len); diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp b/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp index d5be96da944a..808d2af4a0b7 100644 --- a/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp @@ -11,8 +11,7 @@ #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/LLDBLog.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/UriParser.h" #include "llvm/Config/config.h" @@ -46,16 +45,15 @@ static void platform_setenv(const char *env, const char *val) { void PlatformHOS::Initialize() { PlatformLinux::Initialize(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); if (g_initialize_count++ == 0) { #if defined(__HOS__) PlatformSP default_platform_sp(new PlatformHOS(true)); default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); Platform::SetHostPlatform(default_platform_sp); - if (log) { - LLDB_LOGF(log, "Hsu file(%s)%d PlatformHOS::%s new PlatformHOS(true)", - __FILE__, __LINE__, __FUNCTION__); - } + if (log) + log->Printf("Hsu file(%s)%d PlatformHOS::%s new PlatformHOS(true)", + __FILE__, __LINE__, __FUNCTION__); #endif PluginManager::RegisterPlugin( PlatformHOS::GetPluginNameStatic(false), @@ -74,13 +72,13 @@ void PlatformHOS::Terminate() { } PlatformSP PlatformHOS::CreateInstance(bool force, const ArchSpec *arch) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); if (log) { const char *triple_cstr = arch ? arch->GetTriple().getTriple().c_str() : ""; - LLDB_LOGF(log, "PlatformHOS::%s(force=%s, triple=%s)", __FUNCTION__, - force ? "true" : "false", triple_cstr); + log->Printf("PlatformHOS::%s(force=%s, triple=%s)", __FUNCTION__, + force ? "true" : "false", triple_cstr); } bool create = force; @@ -102,48 +100,41 @@ PlatformSP PlatformHOS::CreateInstance(bool force, const ArchSpec *arch) { if (const char *env = std::getenv("HDC_UTID")) platform_setenv("ANDROID_SERIAL", env); - LLDB_LOGF(log, "PlatformHOS::%s() creating remote-hos platform", - __FUNCTION__); + log->Printf("PlatformHOS::%s() creating remote-hos platform", __FUNCTION__); return PlatformSP(new PlatformHOS(false)); } - LLDB_LOGF(log, "PlatformHOS::%s() aborting creation of remote-hos platform", - __FUNCTION__); + log->Printf("PlatformHOS::%s() aborting creation of remote-hos platform", + __FUNCTION__); return PlatformSP(); } PlatformHOS::PlatformHOS(bool is_host) : PlatformLinux(is_host), m_sdk_version(0) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d PlatformHOS::%s is_host(%d)", __FILE__, - __LINE__, __FUNCTION__, is_host); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d PlatformHOS::%s is_host(%d)", __FILE__, + __LINE__, __FUNCTION__, is_host); } PlatformHOS::~PlatformHOS() {} -ConstString PlatformHOS::GetPluginNameStatic(bool is_host) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu %s:%d PlatformHOS::GetPluginNameStatic is_host(%d)", - __FILE__, __LINE__, is_host); - } +llvm::StringRef PlatformHOS::GetPluginNameStatic(bool is_host) { + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu %s:%d PlatformHOS::GetPluginNameStatic is_host(%d)", + __FILE__, __LINE__, is_host); if (is_host) { - static ConstString g_host_name(Platform::GetHostPlatformName()); - if (log) { - LLDB_LOGF(log, "Hsu %s:%d PlatformHOS::GetPluginNameStatic g_host_name", - __FILE__, __LINE__); - } - return g_host_name; + if (log) + log->Printf("Hsu %s:%d PlatformHOS::GetPluginNameStatic g_host_name", + __FILE__, __LINE__); + return Platform::GetHostPlatformName(); } else { - static ConstString g_remote_name("remote-hos"); - if (log) { - LLDB_LOGF(log, "Hsu %s:%d PlatformHOS::GetPluginNameStatic g_remote_name", - __FILE__, __LINE__); - } - return g_remote_name; + if (log) + log->Printf("Hsu %s:%d PlatformHOS::GetPluginNameStatic g_remote_name", + __FILE__, __LINE__); + return "remote-hos"; } } @@ -153,57 +144,50 @@ const char *PlatformHOS::GetPluginDescriptionStatic(bool is_host) { else return "Remote HarmonyOS user platform plug-in."; } + Status PlatformHOS::ConnectRemote(Args &args) { m_device_id.clear(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) { - LLDB_LOGF(log, "Hsu %s:%d PlatformHOS::ConnectRemote call", __FILE__, - __LINE__); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu %s:%d PlatformHOS::ConnectRemote call", __FILE__, + __LINE__); if (IsHost()) { return Status("can't connect to the host platform '%s', always connected", - GetPluginName().GetCString()); + GetPluginName().str().c_str()); } if (!m_remote_platform_sp) { - if (log) { - LLDB_LOGF(log, - "Hsu %s:%d PlatformHOS::ConnectRemote new " - "PlatformHOSRemoteGDBServer()", - __FILE__, __LINE__); - } + if (log) + log->Printf("Hsu %s:%d PlatformHOS::ConnectRemote new " + "PlatformHOSRemoteGDBServer()", + __FILE__, __LINE__); m_remote_platform_sp = PlatformSP(new PlatformHOSRemoteGDBServer()); } - 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)) + llvm::Optional uri = URI::Parse(url); + if (!uri) return Status("Invalid URL: %s", url); - if (host != "localhost") - m_device_id = static_cast(host); + if (uri->hostname != "localhost") + m_device_id = static_cast(uri->hostname); auto error = PlatformLinux::ConnectRemote(args); if (error.Success()) { HdcClient hdc; - if (log) { - LLDB_LOGF(log, - "Hsu file(%s):%d PlatformHOS::ConnectRemote m_device_id(%s)", - __FILE__, __LINE__, m_device_id.c_str()); - } + if (log) + log->Printf("Hsu file(%s):%d PlatformHOS::ConnectRemote m_device_id(%s)", + __FILE__, __LINE__, m_device_id.c_str()); error = HdcClient::CreateByDeviceID(m_device_id, hdc); if (error.Fail()) return error; m_device_id = hdc.GetDeviceID(); - if (log) { - LLDB_LOGF(log, - "Hsu file(%s):%d PlatformHOS::ConnectRemote m_device_id(%s)", - __FILE__, __LINE__, m_device_id.c_str()); - } + if (log) + log->Printf("Hsu file(%s):%d PlatformHOS::ConnectRemote m_device_id(%s)", + __FILE__, __LINE__, m_device_id.c_str()); } return error; } @@ -233,19 +217,19 @@ Status PlatformHOS::GetFile(const FileSpec &source, auto source_file = source_spec.GetCString(false); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - LLDB_LOGF(log, "Got mode == 0 on '%s': try to get file via 'shell cat'", - source_file); + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Got mode == 0 on '%s': try to get file via 'shell cat'", + source_file); if (strchr(source_file, '\'') != nullptr) return Status("Doesn't support single-quotes in filenames"); // mode == 0 can signify that adbd cannot access the file due security // constraints - try "cat ..." as a fallback. - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d PlatformHOS::%s source_file(%s)", __FILE__, - __LINE__, __FUNCTION__, source_file); - } + if (log) + log->Printf("Hsu file(%s):%d PlatformHOS::%s source_file(%s)", __FILE__, + __LINE__, __FUNCTION__, source_file); HdcClient hdc(m_device_id); char cmd[PATH_MAX]; @@ -286,10 +270,10 @@ Status PlatformHOS::GetFile(const FileSpec &source, snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); } - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d PlatformHOS::%s source_file(%s)", __FILE__, - __LINE__, __FUNCTION__, source_file); - } + if (log) + log->Printf("Hsu file(%s):%d PlatformHOS::%s source_file(%s)", __FILE__, + __LINE__, __FUNCTION__, source_file); + return hdc.ShellToFile(cmd, minutes(1), destination); } @@ -350,13 +334,14 @@ uint32_t PlatformHOS::GetSdkVersion() { version_string = llvm::StringRef(version_string).trim().str(); if (error.Fail() || version_string.empty()) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM); - LLDB_LOGF(log, "Get SDK version failed. (error: %s, output: %s)", - error.AsCString(), version_string.c_str()); + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Get SDK version failed. (error: %s, output: %s)", + error.AsCString(), version_string.c_str()); return 0; } - m_sdk_version = StringConvert::ToUInt32(version_string.c_str()); + llvm::to_integer(version_string.c_str(), m_sdk_version); return m_sdk_version; } @@ -403,10 +388,9 @@ Status PlatformHOS::DownloadSymbolFile(const lldb::ModuleSP &module_sp, command.Printf("rm -rf %s", s->c_str()); Status error = hdc.Shell(command.GetData(), seconds(5), nullptr); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); if (log && error.Fail()) - LLDB_LOGF(log, "Failed to remove temp directory: %s", - error.AsCString()); + log->Printf("Failed to remove temp directory: %s", error.AsCString()); }); FileSpec symfile_platform_filespec(tmpdir); diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOS.h b/lldb/source/Plugins/Platform/HOS/PlatformHOS.h index 07057ab83e26..d725972243ca 100644 --- a/lldb/source/Plugins/Platform/HOS/PlatformHOS.h +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOS.h @@ -32,13 +32,13 @@ public: static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); - static ConstString GetPluginNameStatic(bool is_host); + static llvm::StringRef GetPluginNameStatic(bool is_host); static const char *GetPluginDescriptionStatic(bool is_host); - ConstString GetPluginName() override { return GetPluginNameStatic(IsHost()); } - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { + return GetPluginNameStatic(IsHost()); + } Status ConnectRemote(Args &args) override; diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.cpp index 8c311a938453..344300ea0086 100644 --- a/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOSRemoteGDBServer.cpp @@ -8,7 +8,7 @@ #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/common/TCPSocket.h" -#include "lldb/Utility/Log.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/UriParser.h" @@ -28,7 +28,7 @@ static Status ForwardPortWithHdc( llvm::StringRef remote_socket_name, const llvm::Optional &socket_namespace, std::string &device_id) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); HdcClient hdc; auto error = HdcClient::CreateByDeviceID(device_id, hdc); @@ -36,21 +36,20 @@ static Status ForwardPortWithHdc( return error; device_id = hdc.GetDeviceID(); - LLDB_LOGF(log, - "Hsu file(%s):%d function(ForwardPortWithHdc) Connected to Hos " - "device \"%s\"", - __FILE__, __LINE__, device_id.c_str()); + log->Printf("Hsu file(%s):%d function(ForwardPortWithHdc) Connected to Hos " + "device \"%s\"", + __FILE__, __LINE__, device_id.c_str()); if (remote_port != 0) { - LLDB_LOGF(log, - "Hsu file(%s):%d function(ForwardPortWithHdc) Forwarding remote " - "TCP port %d to local TCP port %d", - __FILE__, __LINE__, remote_port, local_port); + log->Printf( + "Hsu file(%s):%d function(ForwardPortWithHdc) Forwarding remote " + "TCP port %d to local TCP port %d", + __FILE__, __LINE__, remote_port, local_port); return hdc.SetPortForwarding(local_port, remote_port); } - LLDB_LOGF(log, "Forwarding remote socket \"%s\" to local TCP port %d", - remote_socket_name.str().c_str(), local_port); + 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"); @@ -67,7 +66,6 @@ static Status DeleteForwardPortWithHdc(uint16_t local_port, static Status FindUnusedPort(uint16_t &port) { Status error; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); std::unique_ptr tcp_socket(new TCPSocket(true, false)); if (error.Fail()) return error; @@ -76,10 +74,10 @@ static Status FindUnusedPort(uint16_t &port) { if (error.Success()) port = tcp_socket->GetLocalPortNumber(); - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d FindUnusedPort port(%d)", __FILE__, - __LINE__, port); - } + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d FindUnusedPort port(%d)", __FILE__, __LINE__, + port); return error; } @@ -94,66 +92,64 @@ bool PlatformHOSRemoteGDBServer::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)) + if (!m_gdb_client_up->LaunchGDBServer("127.0.0.1", pid, remote_port, + socket_name)) return false; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - + Log *log = GetLog(LLDBLog::Platform); auto error = MakeConnectURL(pid, remote_port, socket_name.c_str(), connect_url); if (error.Success() && log) - LLDB_LOGF(log, "gdbserver connect URL: %s", connect_url.c_str()); + log->Printf("gdbserver connect URL: %s", connect_url.c_str()); return error.Success(); } bool PlatformHOSRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) { DeleteForwardPort(pid); - return m_gdb_client.KillSpawnedProcess(pid); + return m_gdb_client_up->KillSpawnedProcess(pid); } Status PlatformHOSRemoteGDBServer::ConnectRemote(Args &args) { m_device_id.clear(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - 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)) + + llvm::Optional uri; + uri = URI::Parse(url); + if (!uri) return Status("Invalid URL: %s", url); - if (host != "localhost") - m_device_id = std::string(host); + + if (uri->hostname != "localhost") + m_device_id = static_cast(uri->hostname); m_socket_namespace.reset(); - if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME) + if (uri->scheme == "unix-connect") m_socket_namespace = HdcClient::UnixSocketNamespaceFileSystem; - else if (scheme == ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME) + else if (uri->scheme == "unix-abstract-connect") 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 (log) { - LLDB_LOGF(log, - "Hsu file(%s):%d g_remote_platform_pid(%lu) remote_port(%d) " - "connect_url(%s)", - __FILE__, __LINE__, g_remote_platform_pid, remote_port, - connect_url.c_str()); - } + unsigned remote_port = uri->port ? (*uri->port) : 0; + auto error = MakeConnectURL(g_remote_platform_pid, remote_port, uri->path, + connect_url); + Log *log = GetLog(LLDBLog::Platform); + if (log) + log->Printf("Hsu file(%s):%d g_remote_platform_pid(%lu) remote_port(%d) " + "connect_url(%s)", + __FILE__, __LINE__, g_remote_platform_pid, remote_port, + connect_url.c_str()); if (error.Fail()) return error; args.ReplaceArgumentAtIndex(0, connect_url); - // Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - LLDB_LOGF(log, "Rewritten platform connect URL: %s", connect_url.c_str()); + log->Printf("Rewritten platform connect URL: %s", connect_url.c_str()); error = PlatformRemoteGDBServer::ConnectRemote(args); if (error.Fail()) @@ -168,20 +164,17 @@ Status PlatformHOSRemoteGDBServer::DisconnectRemote() { } void PlatformHOSRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - + Log *log = GetLog(LLDBLog::Platform); auto it = m_port_forwards.find(pid); if (it == m_port_forwards.end()) return; const auto port = it->second; const auto error = DeleteForwardPortWithHdc(port, m_device_id); - if (error.Fail()) { - LLDB_LOGF(log, - "Failed to delete port forwarding (pid=%" PRIu64 - ", port=%d, device=%s): %s", - pid, port, m_device_id.c_str(), error.AsCString()); - } + if (error.Fail()) + log->Printf("Failed to delete port forwarding (pid=%" PRIu64 + ", port=%d, device=%s): %s", + pid, port, m_device_id.c_str(), error.AsCString()); m_port_forwards.erase(it); } @@ -224,17 +217,15 @@ lldb::ProcessSP PlatformHOSRemoteGDBServer::ConnectProcess( // any other valid pid on android. 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)) { + llvm::Optional uri = URI::Parse(connect_url); + if (!uri) { error.SetErrorStringWithFormat("Invalid URL: %s", connect_url.str().c_str()); return nullptr; } - std::string new_connect_url; error = MakeConnectURL(s_remote_gdbserver_fake_pid--, - (remote_port < 0) ? 0 : remote_port, path, + (*uri->port) ? (*uri->port) : 0, uri->path, new_connect_url); if (error.Fail()) return nullptr; diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp index 73c4321ab650..eb0cfd9c7fff 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -235,7 +235,7 @@ uint32_t PlatformOHOS::GetSdkVersion() { version_string = llvm::StringRef(version_string).trim().str(); if (error.Fail() || version_string.empty()) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM); + Log *log = GetLog(LLDBLog::Platform); if (log) log->Printf("Get SDK version failed. (error: %s, output: %s)", error.AsCString(), version_string.c_str()); @@ -243,7 +243,8 @@ uint32_t PlatformOHOS::GetSdkVersion() { return 0; } - m_sdk_version = StringConvert::ToUInt32(version_string.c_str(), INVALID_SDK_VERSION); + m_sdk_version = INVALID_SDK_VERSION; + llvm::to_integer(version_string, m_sdk_version); if (m_sdk_version == INVALID_SDK_VERSION) { return 0; } diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp index 40d5fae3f91b..348572ec0553 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp @@ -74,7 +74,7 @@ static Status DeleteForwardPortWithHdc(std::pair remote_s const llvm::Optional &socket_namespace, const std::string &device_id) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + Log *log = GetLog(LLDBLog::Platform); uint16_t local_port = remote_socket.first; std::string remote_socket_name = remote_socket.second; if (log) diff --git a/lldb/source/Target/ModuleCache.cpp b/lldb/source/Target/ModuleCache.cpp index d2a7575f8a1f..5d8b30946456 100644 --- a/lldb/source/Target/ModuleCache.cpp +++ b/lldb/source/Target/ModuleCache.cpp @@ -129,7 +129,7 @@ Status CreateHostSysRootModuleLink(const FileSpec &root_dir_spec, const FileSpec &platform_module_spec, const FileSpec &local_module_spec, bool delete_existing) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log = GetLog(LLDBLog::Modules); const auto sysroot_module_path_spec = JoinPath(JoinPath(root_dir_spec, hostname), platform_module_spec.GetPath().c_str()); diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 182e7a88b6a1..088d6f133117 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -309,8 +309,13 @@ void Platform::GetStatus(Stream &strm) { } else { const bool is_connected = IsConnected(); const bool is_container = GetContainer(); - if (log) { - LLDB_LOGF(log, "%p file(%s):%d Platform::GetStatus() is_container(%d) is_connected(%d)", static_cast(this), __FILE__, __LINE__, is_container, is_connected); + + if (Log *log = GetLog(LLDBLog::Platform)) { + LLDB_LOGF(log, + "%p file(%s):%d Platform::GetStatus() is_container(%d) " + "is_connected(%d)", + static_cast(this), __FILE__, __LINE__, is_container, + is_connected); } if (is_connected) strm.Printf(" Hostname: %s\n", GetHostname()); -- Gitee From cc40d20f51745999067747b4915137e32e624cfb Mon Sep 17 00:00:00 2001 From: arvinzzz Date: Fri, 4 Nov 2022 18:45:45 +0300 Subject: [PATCH 40/41] feature: add backward cfi compile options for ohos on aarch64 Signed-off-by: Ivan Eliseev --- clang/docs/ClangCommandLineReference.rst | 4 + clang/include/clang/Basic/LangOptions.def | 2 +- clang/include/clang/Basic/LangOptions.h | 2 +- clang/include/clang/Driver/Options.td | 6 +- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/Driver/ToolChains/Clang.cpp | 3 + clang/lib/Frontend/InitPreprocessor.cpp | 2 + lld/ELF/ScriptParser.cpp | 1 + lld/ELF/Writer.cpp | 6 +- llvm/include/llvm/BinaryFormat/ELF.h | 2 + llvm/include/llvm/Bitcode/LLVMBitCodes.h | 1 + llvm/include/llvm/CodeGen/MachineFrameInfo.h | 15 +++ llvm/include/llvm/CodeGen/StackProtector.h | 2 + .../llvm/CodeGen/StackProtectorRetLowering.h | 57 +++++++++ .../llvm/CodeGen/TargetFrameLowering.h | 5 + llvm/include/llvm/IR/Attributes.td | 3 + llvm/include/llvm/IR/Function.h | 3 +- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 4 + llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2 + llvm/lib/CodeGen/CMakeLists.txt | 1 + llvm/lib/CodeGen/LocalStackSlotAllocation.cpp | 35 +++++- llvm/lib/CodeGen/PrologEpilogInserter.cpp | 72 +++++++++++- llvm/lib/CodeGen/SafeStack.cpp | 3 +- llvm/lib/CodeGen/StackProtector.cpp | 30 +++++ .../lib/CodeGen/StackProtectorRetLowering.cpp | 111 ++++++++++++++++++ llvm/lib/IR/Attributes.cpp | 11 +- llvm/lib/IR/Function.cpp | 3 +- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 11 ++ .../Target/AArch64/AArch64FrameLowering.cpp | 10 ++ .../lib/Target/AArch64/AArch64FrameLowering.h | 10 +- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 8 ++ .../AArch64StackProtectorRetLowering.cpp | 99 ++++++++++++++++ .../AArch64StackProtectorRetLowering.h | 39 ++++++ llvm/lib/Target/AArch64/CMakeLists.txt | 1 + llvm/lib/Transforms/Utils/CodeExtractor.cpp | 1 + .../test/tools/llvm-objdump/ohos-headers.test | 16 +++ .../llvm-readobj/ELF/program-headers.test | 18 +++ llvm/tools/llvm-objdump/ELFDump.cpp | 3 + llvm/tools/llvm-readobj/ELFDumper.cpp | 2 + 39 files changed, 591 insertions(+), 15 deletions(-) create mode 100644 llvm/include/llvm/CodeGen/StackProtectorRetLowering.h create mode 100644 llvm/lib/CodeGen/StackProtectorRetLowering.cpp create mode 100644 llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp create mode 100644 llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.h create mode 100644 llvm/test/tools/llvm-objdump/ohos-headers.test diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 52eb375a7e14..f29396749305 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -2510,6 +2510,10 @@ Enable stack protectors for all functions Enable stack protectors for some functions vulnerable to stack smashing. Compared to -fstack-protector, this uses a stronger heuristic that includes functions containing arrays of any size (and any type), as well as any calls to alloca or the taking of an address from a local variable +.. option:: -fstack-protector-ret + +Enable stack protectors for all functions with return address check + .. option:: -fstack-size-section, -fno-stack-size-section Emit section containing metadata on function stack sizes diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index ad366821f3cb..4faec655636c 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -358,7 +358,7 @@ ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, HiddenVisibil BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition") BENIGN_LANGOPT(HalfNoSemanticInterposition, 1, 0, "Like -fno-semantic-interposition but don't use local aliases") -ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, +ENUM_LANGOPT(StackProtector, StackProtectorMode, 3, SSPOff, "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, "trivial automatic variable initialization") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 3a1c13dd7256..046775964905 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -81,7 +81,7 @@ public: using RoundingMode = llvm::RoundingMode; enum GCMode { NonGC, GCOnly, HybridGC }; - enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; + enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq, SSPRet }; // Automatic variables live on the stack, and when trivial they're usually // uninitialized because it's undefined behavior to use them without diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 07d89546eb10..1b96288ff225 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2738,6 +2738,8 @@ defm split_stack : BoolFOption<"split-stack", PosFlag>; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; +def fstack_protector_ret : Flag<["-"], "fstack-protector-ret">, Group, + HelpText<"Enable stack protectors for all functions with return address check">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", CodeGenOpts<"StackClashProtector">, DefaultFalse, PosFlag, NegFlag, @@ -6050,9 +6052,9 @@ def static_define : Flag<["-"], "static-define">, MarshallingInfoFlag>; def stack_protector : Separate<["-"], "stack-protector">, HelpText<"Enable stack protectors">, - Values<"0,1,2,3">, + Values<"0,1,2,3,4">, NormalizedValuesScope<"LangOptions">, - NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq"]>, + NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq", "SSPRet"]>, MarshallingInfoEnum, "SSPOff">; def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">, HelpText<"Lower bound for a buffer to be considered for stack protection">, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d87692face2a..c67643c43a7d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1951,6 +1951,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::StackProtectStrong); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) B.addAttribute(llvm::Attribute::StackProtectReq); + else if (LangOpts.getStackProtector() == LangOptions::SSPRet) + B.addAttribute(llvm::Attribute::StackProtectRet); } if (!D) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3d5ddba6c0fb..c4355b9d52ec 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3259,6 +3259,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, options::OPT_fstack_protector_all, + options::OPT_fstack_protector_ret, options::OPT_fstack_protector_strong, options::OPT_fstack_protector)) { if (A->getOption().matches(options::OPT_fstack_protector)) @@ -3266,6 +3267,8 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, std::max<>(LangOptions::SSPOn, DefaultStackProtectorLevel); else if (A->getOption().matches(options::OPT_fstack_protector_strong)) StackProtectorLevel = LangOptions::SSPStrong; + else if (A->getOption().matches(options::OPT_fstack_protector_ret)) + StackProtectorLevel = LangOptions::SSPRet; else if (A->getOption().matches(options::OPT_fstack_protector_all)) StackProtectorLevel = LangOptions::SSPReq; } else { diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 20bfbf144a30..34f8c91fb79d 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1185,6 +1185,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__SSP_STRONG__", "2"); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) Builder.defineMacro("__SSP_ALL__", "3"); + else if (LangOpts.getStackProtector() == LangOptions::SSPRet) + Builder.defineMacro("__SSP_RET__", "4"); if (PPOpts.SetUpStaticAnalyzer) Builder.defineMacro("__clang_analyzer__"); diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 7fc50b293b15..0576c6e66f4d 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -1578,6 +1578,7 @@ unsigned ScriptParser::readPhdrType() { .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) + .Case("PT_OHOS_RANDOMDATA", PT_OHOS_RANDOMDATA) .Default(-1); if (ret == (unsigned)-1) { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index ad80d4344e36..bf213b199d4f 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -832,7 +832,8 @@ static bool isRelroSection(const OutputSection *sec) { return s == ".data.rel.ro" || s == ".bss.rel.ro" || s == ".ctors" || s == ".dtors" || s == ".jcr" || s == ".eh_frame" || s == ".fini_array" || s == ".init_array" || - s == ".openbsd.randomdata" || s == ".preinit_array"; + s == ".openbsd.randomdata" || s == ".preinit_array" || + s == ".ohos.randomdata"; } // We compute a rank for each section. The rank indicates where the @@ -2427,6 +2428,9 @@ SmallVector Writer::createPhdrs(Partition &part) { if (OutputSection *cmd = findSection(".note.gnu.property", partNo)) addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd); + if (OutputSection *cmd = findSection(".ohos.randomdata", partNo)) + addHdr(PT_OHOS_RANDOMDATA, cmd->getPhdrFlags())->add(cmd); + // Create one PT_NOTE per a group of contiguous SHT_NOTE sections with the // same alignment. PhdrEntry *note = nullptr; diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 99e7a9868c29..9d4b9e9878de 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1381,6 +1381,8 @@ enum { PT_OPENBSD_WXNEEDED = 0x65a3dbe7, // Program does W^X violations. PT_OPENBSD_BOOTDATA = 0x65a41be6, // Section for boot arguments. + PT_OHOS_RANDOMDATA = 0x6788FC60, // Fill with random data. + // ARM program header types. PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility info // These all contain stack unwind tables. diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index eee4c50cc13b..104068e0c2a0 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -689,6 +689,7 @@ enum AttributeKindCodes { ATTR_KIND_ALLOC_KIND = 82, ATTR_KIND_PRESPLIT_COROUTINE = 83, ATTR_KIND_FNRETTHUNK_EXTERN = 84, + ATTR_KIND_STACK_PROTECT_RET = 85, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h index 7ea731b46655..1c603e2ccdb2 100644 --- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h +++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h @@ -272,6 +272,13 @@ private: /// The frame index for the stack protector. int StackProtectorIdx = -1; + struct StackProtectorRet { + /// The register to use for stack protector & backwrad cfi calculations + unsigned Register = 0; + /// Set to true if this function needs stack-protector-ret + bool Needed = false; + } SPR; + /// The frame index for the function context. Used for SjLj exceptions. int FunctionContextIdx = -1; @@ -358,6 +365,14 @@ public: void setStackProtectorIndex(int I) { StackProtectorIdx = I; } bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; } + /// Get / Set stack protector ret calculation register + unsigned getStackProtectorRetRegister() const { return SPR.Register; } + void setStackProtectorRetRegister(unsigned I) { SPR.Register = I; } + bool hasStackProtectorRetRegister() const { return SPR.Register != 0; } + /// Get / Set if this frame needs backward cfi protect. + void setStackProtectorRetNeeded(bool I) { SPR.Needed = I; } + bool getStackProtectorRetNeeded() const { return SPR.Needed; } + /// Return the index for the function context object. /// This object is used for SjLj exceptions. int getFunctionContextIndex() const { return FunctionContextIdx; } diff --git a/llvm/include/llvm/CodeGen/StackProtector.h b/llvm/include/llvm/CodeGen/StackProtector.h index b96c0c74fabc..aac31eafc65d 100644 --- a/llvm/include/llvm/CodeGen/StackProtector.h +++ b/llvm/include/llvm/CodeGen/StackProtector.h @@ -100,6 +100,8 @@ private: /// stack protector based upon the stack protector level. bool RequiresStackProtector(); + bool CreateSSPRetCookie(); + public: static char ID; // Pass identification, replacement for typeid. diff --git a/llvm/include/llvm/CodeGen/StackProtectorRetLowering.h b/llvm/include/llvm/CodeGen/StackProtectorRetLowering.h new file mode 100644 index 000000000000..667d0f04ceea --- /dev/null +++ b/llvm/include/llvm/CodeGen/StackProtectorRetLowering.h @@ -0,0 +1,57 @@ +//===-- StackProtectorRetLowering.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 LLVM_CODEGEN_STACKPROTECTORRETLOWERING_H +#define LLVM_CODEGEN_STACKPROTECTORRETLOWERING_H + +#include +#include + +namespace llvm { +class CalleeSavedInfo; +class GlobalVariable; +class MachineBasicBlock; +class MachineFunction; +class MachineInstr; + +class StackProtectorRetLowering { +public: + virtual ~StackProtectorRetLowering() {} + + /// insert stack-protector-ret instrumentation in prologue or epilogue. + virtual void insertStackProtectorRetPrologue(MachineFunction &MF, + MachineBasicBlock &MBB, + GlobalVariable *cookie) const {} + virtual void insertStackProtectorRetEpilogue(MachineFunction &MF, + MachineInstr &MI, + GlobalVariable *cookie) const {} + + /// Check if it is a return instruction. + /// Need to overide the implementation for different architectures. + virtual bool instrIsRet(unsigned opcode) const { return false; } + + /// Get a caller saved temporary register for the target architecture. + /// Need to overide the implementation for different architectures. + virtual unsigned getTargetReg(void) const { return 0; } + + /// Check if backward CFI protection is required. + virtual void setupStackProtectorRet(MachineFunction &MF) const; + + /// Set SSPRetReg as a callee saved register to push the computed stack guard value onto the stack. + virtual void saveStackProtectorRetRegister(MachineFunction &MF, std::vector &CSI) const; + + /// Determine an available SSPRet register and feedback the determination result. + virtual bool determineStackProtectorRetRegister(MachineFunction &MF) const; + + /// insertStackProtectorRets - insert stack-protector-ret instrumentation. + virtual void insertStackProtectorRets(MachineFunction &MF) const; +}; + +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/llvm/include/llvm/CodeGen/TargetFrameLowering.h index fbce5d7a9102..9a8bc4bd517a 100644 --- a/llvm/include/llvm/CodeGen/TargetFrameLowering.h +++ b/llvm/include/llvm/CodeGen/TargetFrameLowering.h @@ -14,6 +14,7 @@ #define LLVM_CODEGEN_TARGETFRAMELOWERING_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/StackProtectorRetLowering.h" #include "llvm/Support/TypeSize.h" #include @@ -217,6 +218,10 @@ public: virtual void emitZeroCallUsedRegs(BitVector RegsToZero, MachineBasicBlock &MBB) const {} + virtual const StackProtectorRetLowering *getStackProtectorRet() const { + return nullptr; + } + /// With basic block sections, emit callee saved frame moves for basic blocks /// that are in a different section. virtual void diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index ea4bf80205f8..ce99b289bdbd 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -244,6 +244,9 @@ def Speculatable : EnumAttr<"speculatable", [FnAttr]>; /// Stack protection. def StackProtect : EnumAttr<"ssp", [FnAttr]>; +/// Stack protection for return address. +def StackProtectRet : EnumAttr<"sspret", [FnAttr]>; + /// Stack protection required. def StackProtectReq : EnumAttr<"sspreq", [FnAttr]>; diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index 7945c64c8610..e661a11a7b75 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -418,7 +418,8 @@ public: return AttributeSets.getFnStackAlignment(); } - /// Returns true if the function has ssp, sspstrong, or sspreq fn attrs. + /// Returns true if the function has ssp, sspstrong, sspret or sspreq fn + /// attrs. bool hasStackProtectorFnAttr() const; /// adds the dereferenceable attribute to the list of attributes for diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 1943b5db94c3..106d2b78170f 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1725,6 +1725,8 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { return 1ULL << 62; case Attribute::NoFree: return 1ULL << 63; + case Attribute::StackProtectRet: + return 1ULL << 64; default: // Other attributes are not supported in the raw format, // as we ran out of space. @@ -1949,6 +1951,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::StackAlignment; case bitc::ATTR_KIND_STACK_PROTECT: return Attribute::StackProtect; + case bitc::ATTR_KIND_STACK_PROTECT_RET: + return Attribute::StackProtectRet; case bitc::ATTR_KIND_STACK_PROTECT_REQ: return Attribute::StackProtectReq; case bitc::ATTR_KIND_STACK_PROTECT_STRONG: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index d7e012fb6a9e..4fac16a7491d 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -728,6 +728,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_STACK_ALIGNMENT; case Attribute::StackProtect: return bitc::ATTR_KIND_STACK_PROTECT; + case Attribute::StackProtectRet: + return bitc::ATTR_KIND_STACK_PROTECT_RET; case Attribute::StackProtectReq: return bitc::ATTR_KIND_STACK_PROTECT_REQ; case Attribute::StackProtectStrong: diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index 689fa9651766..5f0a919f97a1 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -206,6 +206,7 @@ add_llvm_component_library(LLVMCodeGen StackMapLivenessAnalysis.cpp StackMaps.cpp StackProtector.cpp + StackProtectorRetLowering.cpp StackSlotColoring.cpp SwiftErrorValueTracking.cpp SwitchLoweringUtils.cpp diff --git a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp index 5f54d7cc8472..cbde664ef459 100644 --- a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp +++ b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp @@ -27,6 +27,7 @@ #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/IR/Function.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Debug.h" @@ -194,7 +195,9 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { // Make sure that the stack protector comes before the local variables on the // stack. + Function &F = Fn.getFunction(); SmallSet ProtectedObjs; + if (MFI.hasStackProtectorIndex()) { int StackProtectorFI = MFI.getStackProtectorIndex(); @@ -239,7 +242,37 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { } llvm_unreachable("Unexpected SSPLayoutKind."); } - + AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, + Offset, MaxAlign); + AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, + Offset, MaxAlign); + AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, + Offset, MaxAlign); + } else if (F.hasFnAttribute(Attribute::StackProtectRet)) { + StackObjSet LargeArrayObjs; + StackObjSet SmallArrayObjs; + StackObjSet AddrOfObjs; + // Assign large stack objects first. + for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { + if (MFI.isDeadObjectIndex(i)) + continue; + if (!TFI.isStackIdSafeForLocalArea(MFI.getStackID(i))) + continue; + switch (MFI.getObjectSSPLayout(i)) { + case MachineFrameInfo::SSPLK_None: + continue; + case MachineFrameInfo::SSPLK_SmallArray: + SmallArrayObjs.insert(i); + continue; + case MachineFrameInfo::SSPLK_AddrOf: + AddrOfObjs.insert(i); + continue; + case MachineFrameInfo::SSPLK_LargeArray: + LargeArrayObjs.insert(i); + continue; + } + llvm_unreachable("Unexpected SSPLayoutKind."); + } AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign); AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 85d051cfdbe7..2d831819791e 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -212,6 +212,10 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) { const Function &F = MF.getFunction(); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); + const StackProtectorRetLowering *SPRL = TFI->getStackProtectorRet(); + + if (SPRL) + SPRL->setupStackProtectorRet(MF); RS = TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr; FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(MF); @@ -250,6 +254,10 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) { if (!F.hasFnAttribute(Attribute::Naked)) insertPrologEpilogCode(MF); + // Add StackProtectorRets if using them + if (SPRL) + SPRL->insertStackProtectorRets(MF); + // Reinsert stashed debug values at the start of the entry blocks. for (auto &I : EntryDbgValues) I.first->insert(I.first->begin(), I.second.begin(), I.second.end()); @@ -359,7 +367,9 @@ void PEI::calculateCallFrameInfo(MachineFunction &MF) { /// Compute the sets of entry and return blocks for saving and restoring /// callee-saved registers, and placing prolog and epilog code. void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) { - const MachineFrameInfo &MFI = MF.getFrameInfo(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); + const StackProtectorRetLowering *SPRL = TFI->getStackProtectorRet(); // Even when we do not change any CSR, we still want to insert the // prologue and epilogue of the function. @@ -375,7 +385,18 @@ void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) { // epilogue. if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock()) RestoreBlocks.push_back(RestoreBlock); - return; + + // If we are adding stack-protector-rets ensure we can find a available + // register for CFI verification. + if (SPRL && !SPRL->determineStackProtectorRetRegister(MF)) { + // Shrinkwrapping will prevent finding a free register + SaveBlocks.clear(); + RestoreBlocks.clear(); + MFI.setSavePoint(nullptr); + MFI.setRestorePoint(nullptr); + } else { + return; + } } // Save refs to entry and return blocks. @@ -386,6 +407,9 @@ void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) { if (MBB.isReturnBlock()) RestoreBlocks.push_back(&MBB); } + + if (SPRL) + SPRL->determineStackProtectorRetRegister(MF); } static void assignCalleeSavedSpillSlots(MachineFunction &F, @@ -422,6 +446,8 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F, } const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering(); + if (TFI->getStackProtectorRet()) + TFI->getStackProtectorRet()->saveStackProtectorRetRegister(F, CSI); MachineFrameInfo &MFI = F.getFrameInfo(); if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI, MinCSFrameIndex, MaxCSFrameIndex)) { @@ -931,6 +957,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { // Make sure that the stack protector comes before the local variables on the // stack. + Function &F = MF.getFunction(); SmallSet ProtectedObjs; if (MFI.hasStackProtectorIndex()) { int StackProtectorFI = MFI.getStackProtectorIndex(); @@ -1000,6 +1027,47 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { llvm_unreachable("Found protected stack objects not pre-allocated by " "LocalStackSlotPass."); + AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, + Offset, MaxAlign, Skew); + AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, + Offset, MaxAlign, Skew); + AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, + Offset, MaxAlign, Skew); + } else if (F.hasFnAttribute(Attribute::StackProtectRet)) { + StackObjSet LargeArrayObjs; + StackObjSet SmallArrayObjs; + StackObjSet AddrOfObjs; + // Assign large stack objects first. + for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { + if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock()) + continue; + if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) + continue; + if (RS && RS->isScavengingFrameIndex((int)i)) + continue; + if (MFI.isDeadObjectIndex(i)) + continue; + if (EHRegNodeFrameIndex == (int)i) + continue; + if (MFI.getStackID(i) != + TargetStackID::Default) // Only allocate objects on the default stack. + continue; + switch (MFI.getObjectSSPLayout(i)) { + case MachineFrameInfo::SSPLK_None: + continue; + case MachineFrameInfo::SSPLK_SmallArray: + SmallArrayObjs.insert(i); + continue; + case MachineFrameInfo::SSPLK_AddrOf: + AddrOfObjs.insert(i); + continue; + case MachineFrameInfo::SSPLK_LargeArray: + LargeArrayObjs.insert(i); + continue; + } + llvm_unreachable("Unexpected SSPLayoutKind."); + } + AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign, Skew); AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index 00a551ade213..4afe09b62181 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -808,7 +808,8 @@ bool SafeStack::run() { // FIXME: implement weaker forms of stack protector. if (F.hasFnAttribute(Attribute::StackProtect) || F.hasFnAttribute(Attribute::StackProtectStrong) || - F.hasFnAttribute(Attribute::StackProtectReq)) { + F.hasFnAttribute(Attribute::StackProtectReq) || + F.hasFnAttribute(Attribute::StackProtectRet)) { Value *StackGuard = getStackGuard(IRB, F); StackGuardSlot = IRB.CreateAlloca(StackPtrTy, nullptr); IRB.CreateStore(StackGuard, StackGuardSlot); diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp index 510a8e3e4ba2..1a9e8f54461e 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -108,9 +108,36 @@ bool StackProtector::runOnFunction(Function &Fn) { } ++NumFunProtected; + + if (Fn.hasFnAttribute(Attribute::StackProtectRet)) { + HasIRCheck = true; + CreateSSPRetCookie(); + // StackProtectRet requires special code generation methods for backward + // cfi. + return false; + } + return InsertStackProtectors(); } +bool StackProtector::CreateSSPRetCookie() { + std::string cookiename = "__sspret_cookie"; + Type *cookietype = Type::getInt8PtrTy(M->getContext()); + GlobalVariable *cookie = dyn_cast_or_null( + M->getOrInsertGlobal(cookiename, cookietype)); + + cookie->setSection(".ohos.randomdata"); + cookie->setExternallyInitialized(true); + cookie->setInitializer(Constant::getNullValue(cookietype)); + cookie->setLinkage(GlobalVariable::LinkOnceAnyLinkage); + cookie->setVisibility(GlobalValue::HiddenVisibility); + cookie->setComdat(M->getOrInsertComdat(cookiename)); + + F->addFnAttr("sspret-randomdata", cookiename); + + return true; +} + /// \param [out] IsLarge is set to true if a protectable array is found and /// it is "large" ( >= ssp-buffer-size). In the case of a structure with /// multiple arrays, this gets set if any of them is large. @@ -296,6 +323,9 @@ bool StackProtector::RequiresStackProtector() { }); NeedsProtector = true; Strong = true; // Use the same heuristic as strong to determine SSPLayout + } else if (F->hasFnAttribute(Attribute::StackProtectRet)) { + NeedsProtector = true; + Strong = true; } else if (F->hasFnAttribute(Attribute::StackProtectStrong)) Strong = true; else if (!F->hasFnAttribute(Attribute::StackProtect)) diff --git a/llvm/lib/CodeGen/StackProtectorRetLowering.cpp b/llvm/lib/CodeGen/StackProtectorRetLowering.cpp new file mode 100644 index 000000000000..4b068995c743 --- /dev/null +++ b/llvm/lib/CodeGen/StackProtectorRetLowering.cpp @@ -0,0 +1,111 @@ +//===-- StackProtectorRetLowering.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 "llvm/CodeGen/StackProtectorRetLowering.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetFrameLowering.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" + +using namespace llvm; + +/// Check if backward CFI protection is required. +void StackProtectorRetLowering::setupStackProtectorRet(MachineFunction &MF) const { + if (MF.getFunction().hasFnAttribute(Attribute::StackProtectRet)) { + for (auto &MBB : MF) { + for (auto &T : MBB.terminators()) { + if (instrIsRet(T.getOpcode())) { + MF.getFrameInfo().setStackProtectorRetNeeded(true); + return; + } + } + } + } +} + +/// Set SSPRetReg as a callee saved register to push the computed stack guard value onto the stack. +void StackProtectorRetLowering::saveStackProtectorRetRegister( + MachineFunction &MF, std::vector &CSI) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + if (!MFI.getStackProtectorRetNeeded()) + return; + + if (!MFI.hasStackProtectorRetRegister()) + llvm_unreachable("Missing available stack-protector-ret register"); + + unsigned Reg = MFI.getStackProtectorRetRegister(); + CSI.push_back(CalleeSavedInfo(Reg)); +} + +/// Determine an available SSPRet register and feedback the determination result. +bool StackProtectorRetLowering::determineStackProtectorRetRegister(MachineFunction &MF) const { + MachineFrameInfo &MFI = MF.getFrameInfo(); + if (!MFI.getStackProtectorRetNeeded()) + return true; + + unsigned Reg = getTargetReg(); + MFI.setStackProtectorRetRegister(Reg); + + return MFI.hasStackProtectorRetRegister(); +} + +/// insertStackProtectorRets - insert stack-protector-ret instrumentation. +void StackProtectorRetLowering::insertStackProtectorRets(MachineFunction &MF) const { + MachineFrameInfo &MFI = MF.getFrameInfo(); + const Function &Fn = MF.getFunction(); + const Module *M = Fn.getParent(); + + if (!MFI.getStackProtectorRetNeeded()) + return; + + if (!MFI.hasStackProtectorRetRegister()) + llvm_unreachable("Invalid stack-protector-ret state."); + + GlobalVariable *cookie = dyn_cast_or_null(M->getGlobalVariable( + Fn.getFnAttribute("sspret-randomdata").getValueAsString(), Type::getInt8PtrTy(M->getContext()))); + + if (!cookie) + llvm_unreachable("Function needs stack-protector-ret but missing cookies available."); + + unsigned Reg = MFI.getStackProtectorRetRegister(); + + std::vector returnInstrs; + for (auto &MBB : MF) { + if (MBB.isReturnBlock()) { + for (auto &MI : MBB.terminators()) { + if (instrIsRet(MI.getOpcode())) { + returnInstrs.push_back(&MI); + if (!MBB.isLiveIn(Reg)) { + MBB.addLiveIn(Reg); + } + } + } + } + } + + if (returnInstrs.empty()) { + return; + } + + for (auto &MI : returnInstrs) { + insertStackProtectorRetEpilogue(MF, *MI, cookie); + } + + insertStackProtectorRetPrologue(MF, MF.front(), cookie); + + if (!MF.front().isLiveIn(Reg)) { + MF.front().addLiveIn(Reg); + } +} diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 6d9f94b5eefd..0143f625903c 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1910,9 +1910,16 @@ static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { AttributeMask OldSSPAttr; OldSSPAttr.addAttribute(Attribute::StackProtect) .addAttribute(Attribute::StackProtectStrong) - .addAttribute(Attribute::StackProtectReq); + .addAttribute(Attribute::StackProtectReq) + .addAttribute(Attribute::StackProtectRet); - if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { + if (Callee.hasFnAttribute(Attribute::StackProtectRet) && + !Caller.hasFnAttribute(Attribute::StackProtect) && + !Caller.hasFnAttribute(Attribute::StackProtectReq) && + !Caller.hasFnAttribute(Attribute::StackProtectStrong)) { + Caller.removeFnAttrs(OldSSPAttr); + Caller.addFnAttr(Attribute::StackProtectRet); + } else if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { Caller.removeFnAttrs(OldSSPAttr); Caller.addFnAttr(Attribute::StackProtectReq); } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index d4138133721e..300592a38b16 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -706,7 +706,8 @@ void Function::clearGC() { bool Function::hasStackProtectorFnAttr() const { return hasFnAttribute(Attribute::StackProtect) || hasFnAttribute(Attribute::StackProtectStrong) || - hasFnAttribute(Attribute::StackProtectReq); + hasFnAttribute(Attribute::StackProtectReq) || + hasFnAttribute(Attribute::StackProtectRet); } /// Copy all additional attributes (those not needed to create a Function) from diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index c568f73471e1..8ed54a6703cf 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1402,6 +1402,17 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { return; } + case AArch64::SSP_RET_TRAP: { + MCSymbol *TempSymbol = OutContext.createTempSymbol(); + /* Compare and branch */ + EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::CBZX) + .addReg(MI->getOperand(0).getReg()) + .addExpr(MCSymbolRefExpr::create( + TempSymbol, OutContext))); + EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BRK).addImm(1)); + OutStreamer->emitLabel(TempSymbol); + return; + } case AArch64::JumpTableDest32: case AArch64::JumpTableDest16: diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 78babdf9f1f0..a7a1c969faf5 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -189,6 +189,7 @@ #include "AArch64InstrInfo.h" #include "AArch64MachineFunctionInfo.h" #include "AArch64RegisterInfo.h" +#include "AArch64StackProtectorRetLowering.h" #include "AArch64Subtarget.h" #include "AArch64TargetMachine.h" #include "MCTargetDesc/AArch64AddressingModes.h" @@ -2968,6 +2969,10 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, ? RegInfo->getBaseRegister() : (unsigned)AArch64::NoRegister; + if (MFI.hasStackProtectorRetRegister()) { + SavedRegs.set(MFI.getStackProtectorRetRegister()); + } + unsigned ExtraCSSpill = 0; // Figure out which callee-saved registers to save/restore. for (unsigned i = 0; CSRegs[i]; ++i) { @@ -3782,6 +3787,11 @@ unsigned AArch64FrameLowering::getWinEHFuncletFrameSize( getStackAlign()); } +const StackProtectorRetLowering * +AArch64FrameLowering::getStackProtectorRet() const { + return &SPRL; +} + namespace { struct FrameObject { bool IsValid = false; diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h index f59860a24d9b..3bfecc6cc768 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h @@ -13,8 +13,9 @@ #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H #define LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H -#include "llvm/Support/TypeSize.h" +#include "AArch64StackProtectorRetLowering.h" #include "llvm/CodeGen/TargetFrameLowering.h" +#include "llvm/Support/TypeSize.h" namespace llvm { @@ -22,9 +23,12 @@ class MCCFIInstruction; class AArch64FrameLowering : public TargetFrameLowering { public: + const AArch64StackProtectorRetLowering SPRL; + explicit AArch64FrameLowering() : TargetFrameLowering(StackGrowsDown, Align(16), 0, Align(16), - true /*StackRealignable*/) {} + true /*StackRealignable*/), + SPRL() {} void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const; @@ -40,6 +44,8 @@ public: void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + const StackProtectorRetLowering *getStackProtectorRet() const override; + bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 926e7305bab9..4976f51b82e1 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -853,6 +853,14 @@ def ADDlowTLS } // isReMaterializable, isCodeGenOnly +//===----------------------------------------------------------------------===// +// Pseudo instruction used by stack protector ret for backward cfi +let isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in { + let Size = 8 in { + def SSP_RET_TRAP: Pseudo<(outs), (ins GPR64:$reg), []>; + } +} + def : Pat<(AArch64LOADgot tglobaltlsaddr:$addr), (LOADgot tglobaltlsaddr:$addr)>; diff --git a/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp new file mode 100644 index 000000000000..c5f67968a212 --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp @@ -0,0 +1,99 @@ +//===-- AArch64StackProtectorRetLowering.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 "AArch64InstrInfo.h" +#include "AArch64MachineFunctionInfo.h" +#include "AArch64RegisterInfo.h" +#include "AArch64StackProtectorRetLowering.h" +#include "AArch64TargetMachine.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/Function.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/Debug.h" +#include "llvm/Target/TargetOptions.h" +#include + +using namespace llvm; + +void AArch64StackProtectorRetLowering::insertStackProtectorRetPrologue( + MachineFunction &MF, MachineBasicBlock &MBB, GlobalVariable *cookie) const { + + MachineBasicBlock::instr_iterator MI = MBB.instr_begin(); + DebugLoc MBBDL = MBB.findDebugLoc(MI); + const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); + unsigned REG = MF.getFrameInfo().getStackProtectorRetRegister(); + + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::ADRP), REG) + .addGlobalAddress(cookie, 0, AArch64II::MO_PAGE); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::LDRXui), REG) + .addReg(REG) + .addGlobalAddress(cookie, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::ANDXrr), REG) + .addReg(REG) + .addReg(AArch64::LR); +} + +void AArch64StackProtectorRetLowering::insertStackProtectorRetEpilogue( + MachineFunction &MF, MachineInstr &MI, GlobalVariable *cookie) const { + + MachineBasicBlock &MBB = *MI.getParent(); + DebugLoc MBBDL = MI.getDebugLoc(); + const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); + unsigned REG = MF.getFrameInfo().getStackProtectorRetRegister(); + + MBB.addLiveIn(AArch64::X9); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::ADRP), AArch64::X9) + .addGlobalAddress(cookie, 0, AArch64II::MO_PAGE); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::LDRXui), AArch64::X9) + .addReg(AArch64::X9) + .addGlobalAddress(cookie, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::ANDXrr), AArch64::X9) + .addReg(AArch64::X9) + .addReg(AArch64::LR); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::SUBSXrr), REG) + .addReg(REG) + .addReg(AArch64::X9); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::SSP_RET_TRAP)) + .addReg(REG); +} + +/// Check if it is a return instruction on the AArch64 architecture. +bool AArch64StackProtectorRetLowering::instrIsRet(unsigned opcode) const { + switch (opcode) { + case AArch64::RET_ReallyLR: + case AArch64::RET: + return true; + default: + return false; + } +} + +/// Returns a caller-saved register for the AArch64 architecture. +unsigned AArch64StackProtectorRetLowering::getTargetReg(void) const { + return AArch64::X15; +} + +/// Set SSPRetReg as a callee saved register to push the computed stack guard value onto the stack. +void AArch64StackProtectorRetLowering::saveStackProtectorRetRegister( + MachineFunction &MF, std::vector &CSI) const { + + const MachineFrameInfo &MFI = MF.getFrameInfo(); + if (!MFI.getStackProtectorRetNeeded()) + return; + + if (!MFI.hasStackProtectorRetRegister()) + llvm_unreachable("Saving unset stack-protector-ret register"); + + unsigned Reg = MFI.getStackProtectorRetRegister(); + + CSI.insert(CSI.begin(), CalleeSavedInfo(Reg)); +} diff --git a/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.h b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.h new file mode 100644 index 000000000000..835b4b90fd2a --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.h @@ -0,0 +1,39 @@ +//===-- AArch64StackProtectorRetLowering.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 LLVM_LIB_TARGET_AARCH64_AARCH64STACKPROTECTORRETLOWERING_H +#define LLVM_LIB_TARGET_AARCH64_AARCH64STACKPROTECTORRETLOWERING_H + +#include "llvm/CodeGen/StackProtectorRetLowering.h" + +namespace llvm { + +class AArch64StackProtectorRetLowering : public StackProtectorRetLowering { +public: + /// insert stack-protector-ret instrumentation in prologue or epilogue. + virtual void + insertStackProtectorRetPrologue(MachineFunction &MF, MachineBasicBlock &MBB, + GlobalVariable *cookie) const override; + virtual void + insertStackProtectorRetEpilogue(MachineFunction &MF, MachineInstr &MI, + GlobalVariable *cookie) const override; + + /// Check if it is a return instruction. + virtual bool instrIsRet(unsigned opcode) const override; + + /// Get a caller saved temporary register for the target architecture. + virtual unsigned getTargetReg(void) const override; + + /// Set SSPRetReg as a callee saved register to push the computed stack guard value onto the stack. + virtual void saveStackProtectorRetRegister(MachineFunction &MF, + std::vector &CSI) const override; +}; + +} // namespace llvm + +#endif diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt index ca7d53dce2bb..e7aba115d6a6 100644 --- a/llvm/lib/Target/AArch64/CMakeLists.txt +++ b/llvm/lib/Target/AArch64/CMakeLists.txt @@ -75,6 +75,7 @@ add_llvm_target(AArch64CodeGen AArch64SLSHardening.cpp AArch64SelectionDAGInfo.cpp AArch64SpeculationHardening.cpp + AArch64StackProtectorRetLowering.cpp AArch64StackTagging.cpp AArch64StackTaggingPreRA.cpp AArch64StorePairSuppress.cpp diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 421f1f329f07..47366f0f2f2f 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -955,6 +955,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, case Attribute::SanitizeMemTag: case Attribute::SpeculativeLoadHardening: case Attribute::StackProtect: + case Attribute::StackProtectRet: case Attribute::StackProtectReq: case Attribute::StackProtectStrong: case Attribute::StrictFP: diff --git a/llvm/test/tools/llvm-objdump/ohos-headers.test b/llvm/test/tools/llvm-objdump/ohos-headers.test new file mode 100644 index 000000000000..045f54fac359 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/ohos-headers.test @@ -0,0 +1,16 @@ +## Check that llvm-objdump dumps OHOS program headers correctly. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-objdump -p %t | FileCheck %s + +# CHECK: OHOS_RANDOMDATA off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**0 +# CHECK-NEXT: filesz 0x0000000000000000 memsz 0x0000000000000000 flags --- + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +ProgramHeaders: + - Type: 0x6788FC60 ## PT_OHOS_RANDOMDATA diff --git a/llvm/test/tools/llvm-readobj/ELF/program-headers.test b/llvm/test/tools/llvm-readobj/ELF/program-headers.test index 2ecf33525068..e1cf4f9fb5f5 100644 --- a/llvm/test/tools/llvm-readobj/ELF/program-headers.test +++ b/llvm/test/tools/llvm-readobj/ELF/program-headers.test @@ -114,6 +114,7 @@ # MAPPING-NEXT: 20 .foo.begin .foo.end {{$}} # MAPPING-NEXT: 21 .foo.begin .foo.end {{$}} # MAPPING-NEXT: 22 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 23 .foo.begin .foo.end {{$}} # MAPPING-NEXT: None .unused .strtab .shstrtab {{$}} # ELF-LLVM: ProgramHeaders [ @@ -401,6 +402,18 @@ # ELF-LLVM-NEXT: ] # ELF-LLVM-NEXT: Alignment: 1 # ELF-LLVM-NEXT: } +# ELF-LLVM-NEXT: ProgramHeader { +# ELF-LLVM-NEXT: Type: PT_OHOS_RANDOMDATA (0x6788FC60) +# ELF32-LLVM-NEXT: Offset: 0x314 +# ELF64-LLVM-NEXT: Offset: 0x548 +# ELF-LLVM-NEXT: VirtualAddress: 0x1000 +# ELF-LLVM-NEXT: PhysicalAddress: 0x1000 +# ELF-LLVM-NEXT: FileSize: 3 +# ELF-LLVM-NEXT: MemSize: 3 +# ELF-LLVM-NEXT: Flags [ (0x0) +# ELF-LLVM-NEXT: ] +# ELF-LLVM-NEXT: Alignment: 1 +# ELF-LLVM-NEXT: } # ELF-LLVM-NEXT: ] --- !ELF @@ -564,6 +577,11 @@ ProgramHeaders: VAddr: 0x1000 FirstSec: .foo.begin LastSec: .foo.end +## Case 23: the PT_OHOS_RANDOMDATA segment. + - Type: 0x6788FC60 ## PT_OHOS_RANDOMDATA + VAddr: 0x1000 + FirstSec: .foo.begin + LastSec: .foo.end ## Check how we dump ARM specific program headers. # RUN: yaml2obj --docnum=1 -DBITS=64 -DMACHINE=EM_ARM %s -o %tarm.elf diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp index 61676b4323d2..dcc851ad1650 100644 --- a/llvm/tools/llvm-objdump/ELFDump.cpp +++ b/llvm/tools/llvm-objdump/ELFDump.cpp @@ -256,6 +256,9 @@ static void printProgramHeaders(const ELFFile &Obj, StringRef FileName) { case ELF::PT_OPENBSD_WXNEEDED: outs() << " OPENBSD_WXNEEDED "; break; + case ELF::PT_OHOS_RANDOMDATA: + outs() << " OHOS_RANDOMDATA "; + break; case ELF::PT_PHDR: outs() << " PHDR "; break; diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index ba7bae96ade3..37810feabc11 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -1414,6 +1414,8 @@ static StringRef segmentTypeToString(unsigned Arch, unsigned Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA); + + LLVM_READOBJ_ENUM_CASE(ELF, PT_OHOS_RANDOMDATA); default: return ""; } -- Gitee From fbdb720c031e08bdfcd9eae19e9c6e256e8c0c44 Mon Sep 17 00:00:00 2001 From: Pavel Kosov Date: Wed, 16 Nov 2022 10:25:27 +0300 Subject: [PATCH 41/41] Add design doc Signed-off-by: Pavel Kosov --- DesignOHOS.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 DesignOHOS.md diff --git a/DesignOHOS.md b/DesignOHOS.md new file mode 100644 index 000000000000..7b1e6aad444b --- /dev/null +++ b/DesignOHOS.md @@ -0,0 +1,38 @@ +Hi all, + +We would like to contribute a new triple for the operational system OpenHarmony [1,2]. + +OpenHarmony is an open-source project incubated and operated by the OpenAtom Foundation. It is an open-source operating system with a framework and platform applicable to smart devices in all scenarios of a fully-connected world. It aims to promote the development of the Internet of Everything (IoE). + +OpenHarmony supports the following types: + +- Mini system + +A mini system runs on the devices whose memory is greater than or equal to 128 KiB and that are equipped with MCU processors such as Arm Cortex-M and 32-bit RISC-V. This system provides multiple lightweight network protocols and graphics frameworks, and a wide range of read/write components for the IoT bus. Typical products include connection modules, sensors, and wearables for smart home. + +- Small system + +A small system runs on the devices whose memory is greater than or equal to 1 MiB and that are equipped with application processors such as Arm Cortex-A. This system provides higher security capabilities, standard graphics frameworks, and video encoding and decoding capabilities. Typical products include smart home IP cameras, electronic cat eyes, routers, and event data recorders (EDRs) for smart travel. + +- Standard system + +A standard system runs on the devices whose memory is greater than or equal to 128 MiB and that are equipped with application processors such as Arm Cortex-A. This system provides a complete application framework supporting the enhanced interaction, 3D GPU, hardware composer, diverse components, and rich animations. This system applies to high-end refrigerator displays. + +For more detail please refer [3] + +The patches implement all the parts required for code generation: + + LLVM triple: http://reviews.llvm.org/D17003 9 + Clang support: http://reviews.llvm.org/D17002 5 + +We are still actively developing the OS support and have many optimizations in mind. + +This OS already used on a real world devices like [4,5] etc + +Please leave code comments on the Phab patches, while discussing high-level comments about the triples and operational system on this thread. + +1. https://github.com/openharmony/docs +2. https://en.wikipedia.org/wiki/OpenHarmony +3. https://github.com/openharmony/docs/blob/master/en/OpenHarmony-Overview.md +4. https://support.hkvstar.com/file/Hi3516D.pdf +5. https://developer.huawei.com/consumer/cn/market/prod-detail?productId=d0df2ab0845547129b0eb8900ca57d65&shopId=ccee05f52ce04acdbe7ce91b9398a527 \ No newline at end of file -- Gitee