Skip to content

Commit

Permalink
Remove support for out-of-line asm.
Browse files Browse the repository at this point in the history
rustix 0.38 removed for most of the out-of-line asm libraries, and #722
removed the out-of-line libraries for 32-bit x86. This PR removes the
libraries for mips and power, which will now default to the libc
backend, though the linux_raw backend can still be enabled using
`RUSTFLAGS=--cfg=rustix_use_experimental_asm`.

Closes #720.
  • Loading branch information
sunfishcode committed Jul 6, 2023
1 parent 6199eb9 commit 6392b8f
Show file tree
Hide file tree
Showing 26 changed files with 22 additions and 826 deletions.
12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ categories = ["os::unix-apis", "date-and-time", "filesystem", "network-programmi
include = ["src", "build.rs", "Cargo.toml", "COPYRIGHT", "LICENSE*", "/*.md", "benches"]
rust-version = "1.63"

[build-dependencies]
cc = { version = "1.0.68", optional = true }

[dependencies]
bitflags = { version = "2.3.3", default-features = false }
itoa = { version = "1.0.1", default-features = false, optional = true }
Expand All @@ -37,7 +34,7 @@ once_cell = { version = "1.5.2", optional = true }
# addition to the libc backend. The linux_raw backend is used by default. The
# libc backend can be selected via adding `--cfg=rustix_use_libc` to
# `RUSTFLAGS` or enabling the `use-libc` cargo feature.
[target.'cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "powerpc64", target_arch = "riscv64", target_arch = "mips", target_arch = "mips64", target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"))))'.dependencies]
[target.'cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "riscv64", all(rustix_use_experimental_asm, target_arch = "powerpc64"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips64"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"))))'.dependencies]
linux-raw-sys = { version = "0.4.3", default-features = false, features = ["general", "errno", "ioctl", "no_std"] }
libc_errno = { package = "errno", version = "0.3.1", default-features = false, optional = true }
libc = { version = "0.2.147", features = ["extra_traits"], optional = true }
Expand All @@ -46,15 +43,15 @@ libc = { version = "0.2.147", features = ["extra_traits"], optional = true }
#
# On all other Unix-family platforms, and under Miri, we always use the libc
# backend, so enable its dependencies unconditionally.
[target.'cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "powerpc64", target_arch = "riscv64", target_arch = "mips", target_arch = "mips64", target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
[target.'cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "riscv64", all(rustix_use_experimental_asm, target_arch = "powerpc64"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips64"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
libc_errno = { package = "errno", version = "0.3.1", default-features = false }
libc = { version = "0.2.147", features = ["extra_traits"] }

# Additional dependencies for Linux with the libc backend:
#
# Some syscalls do not have libc wrappers, such as in `io_uring`. For these,
# the libc backend uses the linux-raw-sys ABI and `libc::syscall`.
[target.'cfg(all(any(target_os = "android", target_os = "linux"), any(rustix_use_libc, miri, not(all(target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "powerpc64", target_arch = "riscv64", target_arch = "mips", target_arch = "mips64", target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
[target.'cfg(all(any(target_os = "android", target_os = "linux"), any(rustix_use_libc, miri, not(all(target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "riscv64", all(rustix_use_experimental_asm, target_arch = "powerpc64"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips64"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
linux-raw-sys = { version = "0.4.3", default-features = false, features = ["general", "ioctl", "no_std"] }

# For the libc backend on Windows, use the Winsock2 API in windows-sys.
Expand Down Expand Up @@ -223,3 +220,6 @@ linux_4_11 = []

# Enable all optimizations for the latest Linux versions.
linux_latest = ["linux_4_11"]

# Obsolete and deprecated.
cc = []
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,10 @@ supported on Redox, such as `*at` functions like `openat`, which are important
features for `rustix`.

`rustix` has its own code for making direct syscalls, similar to the
[`syscall`], [`sc`], and [`scall`] crates, though `rustix` can use either the
Rust `asm!` macro or out-of-line `.s` files so it supports Rust versions from
1.63 through Nightly and architectures where Rust's inline asm is not yet
stable. `rustix` can also use Linux's vDSO mechanism to optimize Linux
`clock_gettime` on all architectures, and all Linux system calls on x86. And
`rustix`'s syscalls report errors using an optimized `Errno` type.
[`syscall`], [`sc`], and [`scall`] crates, using the Rust `asm!` macro.
`rustix` can also use Linux's vDSO mechanism to optimize Linux `clock_gettime`
on all architectures, and all Linux system calls on x86. And `rustix`'s
syscalls report errors using an optimized `Errno` type.

`rustix`'s `*at` functions are similar to the [`openat`] crate, but `rustix`
provides them as free functions rather than associated functions of a `Dir`
Expand Down
83 changes: 6 additions & 77 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
#[cfg(feature = "cc")]
use cc::Build;
use std::env::var;
use std::io::Write;

/// The directory for out-of-line (“outline”) libraries.
const OUTLINE_PATH: &str = "src/backend/linux_raw/arch/outline";

/// The directory for inline asm.
const INLINE_PATH: &str = "src/backend/linux_raw/arch/inline";
const ASM_PATH: &str = "src/backend/linux_raw/arch/asm";

fn main() {
// Don't rerun this on changes other than build.rs, as we only depend on
Expand All @@ -27,8 +22,7 @@ fn main() {

// Gather target information.
let arch = var("CARGO_CFG_TARGET_ARCH").unwrap();
let outline_asm_name = format!("{}/{}.s", OUTLINE_PATH, arch);
let inline_asm_name = format!("{}/{}.rs", INLINE_PATH, arch);
let inline_asm_name = format!("{}/{}.rs", ASM_PATH, arch);
let inline_asm_name_present = std::fs::metadata(inline_asm_name).is_ok();
let target_os = var("CARGO_CFG_TARGET_OS").unwrap();
let pointer_width = var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap();
Expand Down Expand Up @@ -71,27 +65,17 @@ fn main() {
|| !inline_asm_name_present
|| is_unsupported_abi
|| miri
|| ((arch == "powerpc64" || arch == "mips" || arch == "mips64")
&& !rustix_use_experimental_asm)
{
// Use the libc backend.
use_feature("libc");
} else {
// Use the linux_raw backend.
use_feature("linux_raw");
use_feature_or_nothing("core_intrinsics");

// Use inline asm if we have it, or outline asm otherwise. On 32-bit
// x86 our asm support requires naked functions. On PowerPC and MIPS,
// Rust's inline asm is considered experimental, so only use it if
// `--cfg=rustix_use_experimental_asm` is given.
if (arch != "powerpc64" && arch != "mips" && arch != "mips64")
|| rustix_use_experimental_asm
{
use_feature("asm");
if rustix_use_experimental_asm {
use_feature("asm_experimental_arch");
}
} else {
link_in_librustix_outline(&arch, &outline_asm_name);
if rustix_use_experimental_asm {
use_feature("asm_experimental_arch");
}
}

Expand Down Expand Up @@ -152,61 +136,6 @@ fn main() {
println!("cargo:rerun-if-env-changed=CARGO_CFG_MIRI");
}

/// Link in the desired version of librustix_outline_{arch}.a, containing the
/// outline assembly code for making syscalls.
fn link_in_librustix_outline(arch: &str, asm_name: &str) {
let name = format!("rustix_outline_{}", arch);
let profile = var("PROFILE").unwrap();
let to = format!("{}/{}/lib{}.a", OUTLINE_PATH, profile, name);
println!("cargo:rerun-if-changed={}", to);

// If "cc" is not enabled, use a pre-built library.
#[cfg(not(feature = "cc"))]
{
let _ = asm_name;
println!("cargo:rustc-link-search={}/{}", OUTLINE_PATH, profile);
println!("cargo:rustc-link-lib=static={}", name);
}

// If "cc" is enabled, build the library from source, update the pre-built
// version, and assert that the pre-built version is checked in.
#[cfg(feature = "cc")]
{
let out_dir = var("OUT_DIR").unwrap();
// Add `-gdwarf-3` so that we always get the same output, regardless of
// the Rust version we're using. DWARF3 is entirely adequate for our
// simple needs here.
let mut build = Build::new();
if profile == "debug" {
build.flag("-gdwarf-3");
}
build.file(&asm_name);
build.compile(&name);
println!("cargo:rerun-if-changed={}", asm_name);
if std::fs::metadata(".git").is_ok() {
let from = format!("{}/lib{}.a", out_dir, name);
let prev_metadata = std::fs::metadata(&to);
std::fs::copy(&from, &to).unwrap();
assert!(
prev_metadata.is_ok(),
"{} didn't previously exist; please inspect the new file and `git add` it",
to
);
assert!(
std::process::Command::new("git")
.arg("diff")
.arg("--quiet")
.arg(&to)
.status()
.unwrap()
.success(),
"{} changed; please inspect the change and `git commit` it",
to
);
}
}
}

fn use_thumb_mode() -> bool {
// In thumb mode, r7 is reserved.
!can_compile("pub unsafe fn f() { core::arch::asm!(\"udf #16\", in(\"r7\") 0); }")
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 3 additions & 11 deletions src/backend/linux_raw/arch/mod.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
//! Architecture-specific syscall code.
//!
//! `rustix` has inline assembly sequences using `asm!`, but that requires
//! Rust 1.59, so it also has out-of-line ("outline") assembly sequences in .s
//! files. And 32-bit x86 is special (see comments below).
//!
//! This module also has a `choose` submodule which chooses a scheme and is
//! what most of the `rustix` syscalls use.
//!
//! # Safety
//!
//! This contains the inline `asm` statements performing the syscall
//! instructions and FFI declarations declaring the out-of-line ("outline")
//! syscall instructions.
//! instructions.

#![allow(unsafe_code)]
#![cfg_attr(not(feature = "all-apis"), allow(unused_imports))]
// We'll use as many arguments as syscalls need.
#![allow(clippy::too_many_arguments)]

// When inline asm is available, use it. Otherwise, use out-of-line asm. These
// functions always use the machine's syscall instruction, even when it isn't
// the fastest option available.
#[cfg_attr(asm, path = "inline/mod.rs")]
#[cfg_attr(not(asm), path = "outline/mod.rs")]
// These functions always use the machine's syscall instruction, even when it
// isn't the fastest option available.
pub(in crate::backend) mod asm;

// On most architectures, the architecture syscall instruction is fast, so use
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 6392b8f

Please sign in to comment.