From e3968be331aaf7fa48f2365998ed4d076ddc82c8 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 10 Nov 2022 10:06:34 +0000 Subject: [PATCH] Add OpenHarmony targets - `aarch64-unknown-linux-ohos` - `armv7-unknown-linux-ohos` --- Cargo.lock | 8 +- compiler/rustc_codegen_llvm/src/back/write.rs | 3 + compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 7 +- .../src/spec/aarch64_unknown_linux_ohos.rs | 31 +++++ .../src/spec/armv7_unknown_linux_ohos.rs | 27 ++++ compiler/rustc_target/src/spec/mod.rs | 9 ++ library/std/Cargo.toml | 2 +- library/std/src/sys/unix/os.rs | 5 +- library/unwind/src/lib.rs | 16 +++ src/bootstrap/lib.rs | 2 + src/bootstrap/llvm.rs | 3 + src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 + .../rustc/src/platform-support/openharmony.md | 128 ++++++++++++++++++ 15 files changed, 238 insertions(+), 7 deletions(-) create mode 100644 compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs create mode 100644 compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs create mode 100644 src/doc/rustc/src/platform-support/openharmony.md diff --git a/Cargo.lock b/Cargo.lock index 449f0c73588..014e6ee71c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -868,9 +868,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.87" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f867ce54c09855ccd135ad4a50c777182a0c7af5ff20a8f537617bd648b10d50" +checksum = "9fc9c2080d347a2c316518840ac9194644a9993dfa1e9778ef38979a339f5d8b" dependencies = [ "cc", "rustc-std-workspace-core", @@ -2879,9 +2879,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" dependencies = [ "rustc-std-workspace-core", ] diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a4ae1b01e86..fb563f70ed0 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -214,6 +214,8 @@ pub fn target_machine_factory( let path_mapping = sess.source_map().path_mapping().clone(); + let force_emulated_tls = sess.target.force_emulated_tls; + Arc::new(move |config: TargetMachineFactoryConfig| { let split_dwarf_file = path_mapping.map_prefix(config.split_dwarf_file.unwrap_or_default()).0; @@ -239,6 +241,7 @@ pub fn target_machine_factory( relax_elf_relocations, use_init_array, split_dwarf_file.as_ptr(), + force_emulated_tls, ) }; diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 9e5265188b5..0d63e634ad8 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2257,6 +2257,7 @@ pub fn LLVMRustCreateTargetMachine( RelaxELFRelocations: bool, UseInitArray: bool, SplitDwarfFile: *const c_char, + ForceEmulatedTls: bool, ) -> Option<&'static mut TargetMachine>; pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); pub fn LLVMRustAddLibraryInfo<'a>( diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index e604e44a715..329e7329b11 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -368,7 +368,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, - const char *SplitDwarfFile) { + const char *SplitDwarfFile, + bool ForceEmulatedTls) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -400,6 +401,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( } Options.RelaxELFRelocations = RelaxELFRelocations; Options.UseInitArray = UseInitArray; + if (ForceEmulatedTls) { + Options.ExplicitEmulatedTLS = true; + Options.EmulatedTLS = true; + } if (TrapUnreachable) { // Tell LLVM to codegen `unreachable` into an explicit trap instruction. diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs new file mode 100644 index 00000000000..0a5e654cf0d --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs @@ -0,0 +1,31 @@ +use crate::spec::{Target, TargetOptions}; + +use super::SanitizerSet; + +pub fn target() -> Target { + let mut base = super::linux_musl_base::opts(); + base.env = "ohos".into(); + base.crt_static_default = false; + base.max_atomic_width = Some(128); + + Target { + // LLVM 15 doesn't support OpenHarmony yet, use a linux target instead. + llvm_target: "aarch64-unknown-linux-musl".into(), + pointer_width: 64, + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), + arch: "aarch64".into(), + options: TargetOptions { + features: "+reserve-x18".into(), + mcount: "\u{1}_mcount".into(), + force_emulated_tls: true, + supported_sanitizers: SanitizerSet::ADDRESS + | SanitizerSet::CFI + | SanitizerSet::LEAK + | SanitizerSet::MEMORY + | SanitizerSet::MEMTAG + | SanitizerSet::THREAD + | SanitizerSet::HWADDRESS, + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs new file mode 100644 index 00000000000..a64f3a4f049 --- /dev/null +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs @@ -0,0 +1,27 @@ +use crate::spec::{Target, TargetOptions}; + +// This target is for OpenHarmony on ARMv7 Linux with thumb-mode, but no NEON or +// hardfloat. + +pub fn target() -> Target { + // Most of these settings are copied from the armv7_unknown_linux_musleabi + // target. + Target { + // LLVM 15 doesn't support OpenHarmony yet, use a linux target instead. + llvm_target: "armv7-unknown-linux-gnueabi".into(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: "arm".into(), + + options: TargetOptions { + abi: "eabi".into(), + features: "+v7,+thumb2,+soft-float,-neon".into(), + max_atomic_width: Some(64), + env: "ohos".into(), + crt_static_default: false, + mcount: "\u{1}mcount".into(), + force_emulated_tls: true, + ..super::linux_musl_base::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2553b11d878..c40284cbf44 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1261,6 +1261,9 @@ fn $module() { ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710), ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), + + ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), + ("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos), } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> @@ -1734,6 +1737,9 @@ pub struct TargetOptions { /// Whether the target supports XRay instrumentation. pub supports_xray: bool, + + /// Forces the use of emulated TLS (__emutls_get_address) + pub force_emulated_tls: bool, } /// Add arguments for the given flavor and also for its "twin" flavors @@ -1954,6 +1960,7 @@ fn default() -> TargetOptions { entry_name: "main".into(), entry_abi: Conv::C, supports_xray: false, + force_emulated_tls: false, } } } @@ -2605,6 +2612,7 @@ macro_rules! key { key!(entry_name); key!(entry_abi, Conv)?; key!(supports_xray, bool); + key!(force_emulated_tls, bool); if base.is_builtin { // This can cause unfortunate ICEs later down the line. @@ -2859,6 +2867,7 @@ macro_rules! target_option_val { target_option_val!(entry_name); target_option_val!(entry_abi); target_option_val!(supports_xray); + target_option_val!(force_emulated_tls); if let Some(abi) = self.default_adjusted_cabi { d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json()); diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 598a4bf9282..6345db24054 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -15,7 +15,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } -libc = { version = "0.2.139", default-features = false, features = ['rustc-dep-of-std'] } +libc = { version = "0.2.140", default-features = false, features = ['rustc-dep-of-std'] } compiler_builtins = { version = "0.1.87" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 21b035fb373..1c44058aff7 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -115,7 +115,10 @@ pub fn set_errno(e: i32) { /// Gets a detailed string description for the given error number. pub fn error_string(errno: i32) -> String { extern "C" { - #[cfg_attr(any(target_os = "linux", target_env = "newlib"), link_name = "__xpg_strerror_r")] + #[cfg_attr( + all(any(target_os = "linux", target_env = "newlib"), not(target_env = "ohos")), + link_name = "__xpg_strerror_r" + )] fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int; } diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index edc10aa39af..b655bae9673 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -54,6 +54,22 @@ } } +// This is the same as musl except that we default to using the system libunwind +// instead of libgcc. +#[cfg(target_env = "ohos")] +cfg_if::cfg_if! { + if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] { + compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time"); + } else if #[cfg(feature = "llvm-libunwind")] { + #[link(name = "unwind", kind = "static", modifiers = "-bundle")] + extern "C" {} + } else { + #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] + #[link(name = "unwind", cfg(not(target_feature = "crt-static")))] + extern "C" {} + } +} + #[cfg(target_os = "android")] cfg_if::cfg_if! { if #[cfg(feature = "llvm-libunwind")] { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 20b92b294fe..f981b5d5da8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -149,6 +149,8 @@ pub unsafe fn setup(_build: &mut crate::Build) {} // Needed to avoid the need to copy windows.lib into the sysroot. (Some(Mode::Rustc), "windows_raw_dylib", None), (Some(Mode::ToolRustc), "windows_raw_dylib", None), + // #[cfg(bootstrap)] ohos + (Some(Mode::Std), "target_env", Some(&["ohos"])), ]; /// A structure representing a Rust compiler. diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index de06f8ca8c0..a22f0f04b2e 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -1008,6 +1008,9 @@ fn supported_sanitizers( "aarch64-unknown-linux-gnu" => { common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) } + "aarch64-unknown-linux-ohos" => { + common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) + } "x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), "x86_64-unknown-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]), "x86_64-apple-ios" => darwin_libs("iossim", &["asan", "tsan"]), diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 752f1cc4aba..0452126cc37 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -26,6 +26,7 @@ - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-android and \*-androideabi](platform-support/android.md) + - [\*-linux-ohos](platform-support/openharmony.md) - [\*-unknown-fuchsia](platform-support/fuchsia.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 2d74a224096..5c18a38ddab 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -218,6 +218,7 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | +[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARM64 OpenHarmony | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore @@ -240,6 +241,7 @@ target | std | host | notes [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) `armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8 [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ? | | ARM Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) +[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARMv7 OpenHarmony | [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7 Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD diff --git a/src/doc/rustc/src/platform-support/openharmony.md b/src/doc/rustc/src/platform-support/openharmony.md new file mode 100644 index 00000000000..aa4debfd45a --- /dev/null +++ b/src/doc/rustc/src/platform-support/openharmony.md @@ -0,0 +1,128 @@ +# `*-linux-ohos*` + +**Tier: 3** + +Targets for the [OpenHarmony](https://gitee.com/openharmony/docs/) operating +system. + +## Target maintainers + +- Amanieu d'Antras ([@Amanieu](https://github.com/Amanieu)) + +## Setup + +The OpenHarmony SDK doesn't currently support Rust compilation directly, so +some setup is required. + +First, you must obtain the OpenHarmony SDK from [this page](https://gitee.com/openharmony/docs/tree/master/en/release-notes). +Select the version of OpenHarmony you are developing for and download the "Public SDK package for the standard system". + +Create the following shell scripts that wrap Clang from the OpenHarmony SDK: + +`aarch64-unknown-linux-ohos-clang.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \ + -target aarch64-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + "$@" +``` + +`aarch64-unknown-linux-ohos-clang++.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \ + -target aarch64-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + "$@" +``` + +`armv7-unknown-linux-ohos-clang.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \ + -target arm-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + -march=armv7-a \ + -mfloat-abi=softfp \ + -mtune=generic-armv7-a \ + -mthumb \ + "$@" +``` + +`armv7-unknown-linux-ohos-clang++.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \ + -target arm-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + -march=armv7-a \ + -mfloat-abi=softfp \ + -mtune=generic-armv7-a \ + -mthumb \ + "$@" +``` + +Future versions of the OpenHarmony SDK will avoid the need for this process. + +## Building the target + +To build a rust toolchain, create a `config.toml` with the following contents: + +```toml +profile = "compiler" +changelog-seen = 2 + +[build] +sanitizers = true +profiler = true + +[target.aarch64-unknown-linux-ohos] +cc = "/path/to/aarch64-unknown-linux-ohos-clang.sh" +cxx = "/path/to/aarch64-unknown-linux-ohos-clang++.sh" +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib" +linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh" + +[target.armv7-unknown-linux-ohos] +cc = "/path/to/armv7-unknown-linux-ohos-clang.sh" +cxx = "/path/to/armv7-unknown-linux-ohos-clang++.sh" +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib" +linker = "/path/to/armv7-unknown-linux-ohos-clang.sh" +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +You will need to configure the linker to use in `~/.cargo/config`: +```toml +[target.aarch64-unknown-linux-ohos] +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh" + +[target.armv7-unknown-linux-ohos] +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +linker = "/path/to/armv7-unknown-linux-ohos-clang.sh" +``` + +## Testing + +Running the Rust testsuite is possible, but currently difficult due to the way +the OpenHarmony emulator is set up (no networking). + +## Cross-compilation toolchains and C code + +You can use the shell scripts above to compile C code for the target.