diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 5d68d2b77d4..13a15009ad2 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -176,6 +176,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value if cx.use_dll_storage_attrs && tcx.is_dllimport_foreign_item(instance_def_id) && tcx.sess.target.env != "gnu" + && tcx.sess.target.env != "uclibc" { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index f13531814d6..86e5419f964 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -3009,7 +3009,7 @@ fn fn_abi_new_uncached( }; let target = &self.tcx.sess.target; - let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl"); + let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc"); let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu"; let linux_s390x_gnu_like = target.os == "linux" && target.arch == "s390x" && target_env_gnu_like; @@ -3107,7 +3107,7 @@ fn fn_abi_new_uncached( if arg.layout.is_zst() { // For some forsaken reason, x86_64-pc-windows-gnu // doesn't ignore zero-sized struct arguments. - // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl}. + // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}. if is_return || rust_abi || (!win_x64_gnu diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs new file mode 100644 index 00000000000..40ec5f4a86f --- /dev/null +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs @@ -0,0 +1,23 @@ +use crate::spec::{Target, TargetOptions}; + +// This target is for uclibc Linux on ARMv7 without NEON or +// thumb-mode. See the thumbv7neon variant for enabling both. + +pub fn target() -> Target { + let base = super::linux_uclibc_base::opts(); + Target { + llvm_target: "armv7-unknown-linux-gnueabihf".to_string(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + + options: TargetOptions { + // Info about features at https://wiki.debian.org/ArmHardFloatPort + features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(), + cpu: "generic".to_string(), + max_atomic_width: Some(64), + mcount: "_mcount".to_string(), + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 5276da1ba5a..ff5dfa3f746 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -952,6 +952,8 @@ fn $module() { ("bpfel-unknown-none", bpfel_unknown_none), ("armv6k-nintendo-3ds", armv6k_nintendo_3ds), + + ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf), } /// Warnings encountered when parsing the target `json`. diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 1c37f4ee498..2ba6c8d830e 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -307,6 +307,9 @@ pub fn abort_internal() -> ! { #[link(name = "zircon")] #[link(name = "fdio")] extern "C" {} + } else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] { + #[link(name = "dl")] + extern "C" {} } } diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 99013efb495..ac852717f1e 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -419,7 +419,7 @@ fn posix_spawn( } // Only glibc 2.24+ posix_spawn() supports returning ENOENT directly. - #[cfg(all(target_os = "linux", target_env = "gnu"))] + #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))] { if let Some(version) = sys::os::glibc_version() { if version < (2, 24) { diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 5631834eca6..01e54b4a8f1 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -594,7 +594,8 @@ pub unsafe fn current() -> Option { Some(stackaddr - guardsize..stackaddr) } else if cfg!(all(target_os = "linux", target_env = "musl")) { Some(stackaddr - guardsize..stackaddr) - } else if cfg!(all(target_os = "linux", target_env = "gnu")) { + } else if cfg!(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc"))) + { // glibc used to include the guard area within the stack, as noted in the BUGS // section of `man pthread_attr_getguardsize`. This has been corrected starting // with glibc 2.27, and in some distro backports, so the guard is now placed at the diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 25be9e7cc6c..e263780bf38 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -63,7 +63,7 @@ // don't want to duplicate it here. #[cfg(all( target_os = "linux", - target_env = "gnu", + any(target_env = "gnu", target_env = "uclibc"), not(feature = "llvm-libunwind"), not(feature = "system-llvm-libunwind") ))] @@ -72,7 +72,7 @@ #[cfg(all( target_os = "linux", - target_env = "gnu", + any(target_env = "gnu", target_env = "uclibc"), not(feature = "llvm-libunwind"), feature = "system-llvm-libunwind" ))] diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 26fef889462..bbeab598f22 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -220,6 +220,7 @@ target | std | host | notes `armv6-unknown-netbsd-eabihf` | ? | | `armv6k-nintendo-3ds` | * | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) `armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8 +`armv7-unknown-linux-uclibceabihf` | ✓ | ? | ARMv7 Linux uClibc `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD `armv7-unknown-netbsd-eabihf` | ✓ | ✓ | `armv7-wrs-vxworks-eabihf` | ? | |