diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index b26969a50120f..e90eb08fcd6e4 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -177,6 +177,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 e7bbdc3ccebdf..8277ff46f9f82 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2743,7 +2743,7 @@ where }; let target = &cx.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; @@ -2842,7 +2842,7 @@ where 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 0000000000000..c5be50af2d666 --- /dev/null +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs @@ -0,0 +1,24 @@ +use crate::spec::{Target, TargetOptions}; + +// This target is for glibc 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), + unsupported_abis: super::arm_base::unsupported_abis(), + mcount: "_mcount".to_string(), + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 801cdd3ebe924..7a15f16f9f092 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -897,6 +897,8 @@ supported_targets! { ("aarch64_be-unknown-linux-gnu", aarch64_be_unknown_linux_gnu), ("aarch64-unknown-linux-gnu_ilp32", aarch64_unknown_linux_gnu_ilp32), ("aarch64_be-unknown-linux-gnu_ilp32", aarch64_be_unknown_linux_gnu_ilp32), + + ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf), } /// Everything `rustc` knows about how to compile for a specific target. diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index 6967647249390..f4da202c563cd 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -100,13 +100,16 @@ mod imp { // On Linux-GNU, we rely on `ARGV_INIT_ARRAY` below to initialize // `ARGC` and `ARGV`. But in Miri that does not actually happen so we // still initialize here. - #[cfg(any(miri, not(all(target_os = "linux", target_env = "gnu"))))] + #[cfg(any( + miri, + not(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc"))) + ))] really_init(_argc, _argv); } /// glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension. /// This allows `std::env::args` to work even in a `cdylib`, as it does on macOS and Windows. - #[cfg(all(target_os = "linux", target_env = "gnu"))] + #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))] #[used] #[link_section = ".init_array.00099"] static ARGV_INIT_ARRAY: extern "C" fn( diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 44328ffc22e5b..234c9fac48b81 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -254,5 +254,8 @@ cfg_if::cfg_if! { #[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 ed9044382a898..17567481523a3 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -265,8 +265,7 @@ impl Command { #[cfg(not(any( target_os = "macos", target_os = "freebsd", - all(target_os = "linux", target_env = "gnu"), - all(target_os = "linux", target_env = "musl"), + all(target_os = "linux", any(target_env = "gnu", target_env = "musl")), )))] fn posix_spawn( &mut self, @@ -281,8 +280,7 @@ impl Command { #[cfg(any( target_os = "macos", target_os = "freebsd", - all(target_os = "linux", target_env = "gnu"), - all(target_os = "linux", target_env = "musl"), + all(target_os = "linux", any(target_env = "gnu", target_env = "musl")), ))] fn posix_spawn( &mut self, @@ -302,7 +300,7 @@ impl Command { } // 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 b8f43caec32a3..6998d9cdd9210 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -434,7 +434,8 @@ pub mod guard { 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 be5e56c71e36f..0bf68112b7988 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -46,7 +46,7 @@ extern "C" {} // 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") ))] @@ -55,7 +55,7 @@ extern "C" {} #[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 f352746d3fbe9..d14ccd9435afa 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -169,6 +169,7 @@ target | std | host | notes `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD `armv6-unknown-netbsd-eabihf` | ? | | `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` | ? | |