Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to 64 bit file and time APIs on GNU libc for 32bit systems #3175

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ee04e86
Add cfg option gnu_time64_abi
snogge Sep 7, 2023
6e9fa92
libc-test: Set the gnu time64 preprocessor symbols for all ptr32
snogge Mar 17, 2023
6b82eb2
gnu: Handle basic file and time types for 32bit systems with time64
snogge Mar 17, 2023
107177a
gnu: Use _TIME_BITS and _FILE_OFFSET_BITS=64 versions of glibc symbols
snogge Mar 17, 2023
5a0eb4b
linux: Set SO_TIMESTAMP* and SO_RCVTIMEO and SO_SNDTIMEO
snogge Mar 20, 2023
9c46b6c
linux: Set RLIM_INFINITY for mips GNU libc with _FILE_OFFSET_BITS=64
snogge Mar 27, 2023
ecf680c
gnu: Update F_GETLK and F_GETLK64 for 64-bit time
snogge Mar 20, 2023
8f514a1
gnu: Update F_SETLK and F_SETLKW for 64-bit time
snogge Mar 20, 2023
5213d0b
linux: Update struct input_event for glibc _TIME_BITS=64
snogge Mar 17, 2023
50a931d
gnu: Handle timeval.tv_usec for glibc 64-bit time_t
snogge Mar 17, 2023
c4a27a8
gnu 32 powerpc: Rename powerpc.rs -> powerpc/mod.rs
snogge May 2, 2024
d2af68c
gnu: Update struct shmid_ds for 64-bit time
snogge Mar 20, 2023
bc553de
gnu: Update struct msqid_ds for 64-bit time
snogge Mar 27, 2023
f2ff593
gnu: Update struct semid_ds for 64-bit time
snogge Mar 20, 2023
83c60cd
gnu: Update struct aiocb for _TIME_BITS=64
snogge Mar 20, 2023
49d1137
gnu: Update struct timespec for _TIME_BITS=64
snogge Mar 27, 2023
fefc83c
gnu: Move struct timex to gnu/b64 and gnu/b32/time*.rs
snogge Mar 17, 2023
d9a25a7
gnu: Update the stat* structs for 64-bit time
snogge Apr 29, 2024
1db367e
full_ci: Test with various _TIME_BITS settings where relevant
snogge Apr 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions .github/workflows/full_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@ jobs:
i686-unknown-linux-gnu,
x86_64-unknown-linux-gnu,
]
bits: [
default,
32,
64
]
exclude:
- target: x86_64-unknown-linux-gnu
bits: 32
- target: x86_64-unknown-linux-gnu
bits: 64
steps:
- uses: actions/checkout@v4
- name: Setup Rust toolchain
run: TARGET=${{ matrix.target }} sh ./ci/install-rust.sh
- name: Execute run-docker.sh
run: LIBC_CI=1 sh ./ci/run-docker.sh ${{ matrix.target }}
run: LIBC_CI=1 RUST_LIBC_TIME_BITS=${{ matrix.bits }} sh ./ci/run-docker.sh ${{ matrix.target }}

macos:
permissions:
Expand Down Expand Up @@ -133,12 +143,22 @@ jobs:
# aren't defined on redox actually.
# x86_64-unknown-redox,
]
include:
- bits: default
- bits: 32
target: arm-unknown-linux-gnueabihf
- bits: 64
target: arm-unknown-linux-gnueabihf
- bits: 32
target: powerpc-unknown-linux-gnu
- bits: 64
target: powerpc-unknown-linux-gnu
steps:
- uses: actions/checkout@v4
- name: Setup Rust toolchain
run: TARGET=${{ matrix.target }} sh ./ci/install-rust.sh
- name: Execute run-docker.sh
run: LIBC_CI=1 sh ./ci/run-docker.sh ${{ matrix.target }}
run: LIBC_CI=1 RUST_LIBC_TIME_BITS=${{ matrix.bits }} sh ./ci/run-docker.sh ${{ matrix.target }}

build_channels_linux:
permissions:
Expand Down
67 changes: 67 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const ALLOWED_CFGS: &'static [&'static str] = &[
"freebsd13",
"freebsd14",
"freebsd15",
"gnu_time64_abi",
"libc_const_extern_fn",
"libc_const_extern_fn_unstable",
"libc_deny_warnings",
Expand Down Expand Up @@ -67,6 +68,11 @@ fn main() {
Some(_) | None => (),
}

// Some ABIs need to redirect time related symbols to their time64 equivalents.
if is_gnu_time64_abi() {
set_cfg("gnu_time64_abi");
}

// On CI: deny all warnings
if libc_ci {
set_cfg("libc_deny_warnings");
Expand Down Expand Up @@ -205,3 +211,64 @@ fn set_cfg(cfg: &str) {
}
println!("cargo:rustc-cfg={}", cfg);
}

fn is_gnu_time64_abi() -> bool {
match env::var("CARGO_CFG_TARGET_ENV") {
Ok(target_env) => {
if target_env != "gnu" {
return false;
}
}
Err(_) => panic!("CARGO_CFG_TARGET_ENV not set"),
}
match env::var("CARGO_CFG_TARGET_OS") {
Ok(target_os) => {
if target_os != "linux" {
return false;
}
}
Err(_) => panic!("CARGO_CFG_TARGET_OS not set"),
}
match env::var("CARGO_CFG_TARGET_POINTER_WIDTH") {
Ok(bits) => {
if bits == "64" {
return false;
}
}
Err(_) => panic!("CARGO_CFG_TARGET_POINTER_WIDTH not set"),
}
match env::var("CARGO_CFG_TARGET_ARCH") {
Ok(bits) => {
if bits == "riscv32" {
return false;
}
}
Err(_) => panic!("CARGO_CFG_TARGET_ARCH not set"),
}
match env::var("RUST_LIBC_TIME_BITS") {
Ok(time_bits) => {
if time_bits == "64" {
return true;
}
if time_bits == "32" {
return false;
}
if time_bits != "default" {
panic!("Invalid value for RUST_LIBC_TIME_BITS");
}
}
Err(_) => {}
}
// At this point, we _know_ it is *-*-linux-gnu* with 32 bit
// pointers. Some 64 bit arch still have 32 bit pointers though.
match env::var("TARGET") {
Ok(target) => {
// x86_64-unknown-linux-gnux32 and similar
if target.contains("x86_64") && target.contains("x32") {
return false;
}
}
Err(_) => panic!("TARGET not set"),
}
return true;
}
23 changes: 23 additions & 0 deletions ci/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,29 @@ test_target() {
TARGET="${2}"
NO_STD="${3}"

if [ "$RUST_LIBC_TIME_BITS" = "" ]; then
while true; do
case "$TARGET" in
arm-unknown-linux-gnueabi);;
arm-unknown-linux-gnueabihf);;
armv7-unknown-linux-gnueabihf);;
i586-unknown-linux-gnu);;
i686-unknown-linux-gnu);;
powerpc-unknown-linux-gnu);;
armv5te-unknown-linux-gnueabi);;
mips-unknown-linux-gnu);;
mipsel-unknown-linux-gnu);;
powerpc-unknown-linux-gnuspe);;
riscv32gc-unknown-linux-gnu);;
sparc-unknown-linux-gnu);;
*) break;
esac
RUST_LIBC_TIME_BITS=32 test_target "$BUILD_CMD" "$TARGET" "$NO_STD"
RUST_LIBC_TIME_BITS=64 test_target "$BUILD_CMD" "$TARGET" "$NO_STD"
break # also build without RUST_LIBC_TIME_BITS set
done
fi

# If there is a std component, fetch it:
if [ "${NO_STD}" != "1" ]; then
# FIXME: rustup often fails to download some artifacts due to network
Expand Down
1 change: 1 addition & 0 deletions ci/run-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ run() {
--env LIBC_CI_ZBUILD_STD \
--env CARGO_HOME=/cargo \
--env CARGO_TARGET_DIR=/checkout/target \
--env RUST_LIBC_TIME_BITS \
--volume "$CARGO_HOME":/cargo \
--volume "$(rustc --print sysroot)":/rust:ro \
--volume "$(pwd)":/checkout:ro \
Expand Down
35 changes: 35 additions & 0 deletions libc-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3260,6 +3260,31 @@ fn test_vxworks(target: &str) {
cfg.generate("../src/lib.rs", "main.rs");
}

fn config_gnu_time64(target: &str, cfg: &mut ctest::TestGenerator) {
let gnu = target.contains("gnu");
let x32 = target.contains("x32");
let riscv = target.contains("riscv32");

if gnu && &env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "32" && !riscv && !x32 {
match env::var("RUST_LIBC_TIME_BITS") {
Ok(time_bits) => {
if time_bits == "64" || time_bits == "default" {
cfg.define("_TIME_BITS", Some("64"));
cfg.define("_FILE_OFFSET_BITS", Some("64"));
cfg.cfg("gnu_time64_abi", None);
} else if time_bits != "32" {
panic!("Unsupported RUST_LIBC_TIME_BITS value {}", time_bits)
}
}
Err(_) => {
cfg.define("_TIME_BITS", Some("64"));
cfg.define("_FILE_OFFSET_BITS", Some("64"));
cfg.cfg("gnu_time64_abi", None);
}
}
}
}

fn test_linux(target: &str) {
assert!(target.contains("linux"));

Expand Down Expand Up @@ -3302,6 +3327,8 @@ fn test_linux(target: &str) {
// glibc versions older than 2.29.
cfg.define("__GLIBC_USE_DEPRECATED_SCANF", None);

config_gnu_time64(target, &mut cfg);

headers! { cfg:
"ctype.h",
"dirent.h",
Expand Down Expand Up @@ -3503,6 +3530,8 @@ fn test_linux(target: &str) {

// LFS64 types have been removed in musl 1.2.4+
"off64_t" if musl => "off_t".to_string(),
// In some gnu targets `stat64` is a typedef to `stat`
"stat64" if gnu => format!("struct {}", ty),

// typedefs don't need any keywords
t if t.ends_with("_t") => t.to_string(),
Expand Down Expand Up @@ -4433,6 +4462,7 @@ fn test_linux_like_apis(target: &str) {
if linux || android || emscripten {
// test strerror_r from the `string.h` header
let mut cfg = ctest_cfg();
config_gnu_time64(target, &mut cfg);
cfg.skip_type(|_| true).skip_static(|_| true);

headers! { cfg: "string.h" }
Expand All @@ -4449,6 +4479,7 @@ fn test_linux_like_apis(target: &str) {
// test fcntl - see:
// http://man7.org/linux/man-pages/man2/fcntl.2.html
let mut cfg = ctest_cfg();
config_gnu_time64(target, &mut cfg);

if musl {
cfg.header("fcntl.h");
Expand Down Expand Up @@ -4478,6 +4509,7 @@ fn test_linux_like_apis(target: &str) {
if linux || android {
// test termios
let mut cfg = ctest_cfg();
config_gnu_time64(target, &mut cfg);
cfg.header("asm/termbits.h");
cfg.header("linux/termios.h");
cfg.skip_type(|_| true)
Expand All @@ -4502,6 +4534,7 @@ fn test_linux_like_apis(target: &str) {
if linux || android {
// test IPV6_ constants:
let mut cfg = ctest_cfg();
config_gnu_time64(target, &mut cfg);
headers! {
cfg:
"linux/in6.h"
Expand Down Expand Up @@ -4533,6 +4566,7 @@ fn test_linux_like_apis(target: &str) {
// "resolve.h" defines a `p_type` macro that expands to `__p_type`
// making the tests for these fails when both are included.
let mut cfg = ctest_cfg();
config_gnu_time64(target, &mut cfg);
cfg.header("elf.h");
cfg.skip_fn(|_| true)
.skip_static(|_| true)
Expand All @@ -4552,6 +4586,7 @@ fn test_linux_like_apis(target: &str) {
if linux || android {
// Test `ARPHRD_CAN`.
let mut cfg = ctest_cfg();
config_gnu_time64(target, &mut cfg);
cfg.header("linux/if_arp.h");
cfg.skip_fn(|_| true)
.skip_static(|_| true)
Expand Down
31 changes: 22 additions & 9 deletions src/unix/linux_like/linux/arch/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ pub const SO_PASSCRED: ::c_int = 16;
pub const SO_PEERCRED: ::c_int = 17;
pub const SO_RCVLOWAT: ::c_int = 18;
pub const SO_SNDLOWAT: ::c_int = 19;
pub const SO_RCVTIMEO: ::c_int = 20;
pub const SO_SNDTIMEO: ::c_int = 21;
// pub const SO_RCVTIMEO_OLD: ::c_int = 20;
// pub const SO_SNDTIMEO_OLD: ::c_int = 21;
pub const SO_SECURITY_AUTHENTICATION: ::c_int = 22;
pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 23;
pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 24;
Expand All @@ -49,18 +45,35 @@ pub const SO_ATTACH_FILTER: ::c_int = 26;
pub const SO_DETACH_FILTER: ::c_int = 27;
pub const SO_GET_FILTER: ::c_int = SO_ATTACH_FILTER;
pub const SO_PEERNAME: ::c_int = 28;
pub const SO_TIMESTAMP: ::c_int = 29;

cfg_if! {
if #[cfg(all(gnu_time64_abi,
any(target_arch = "arm", target_arch = "x86")))] {
pub const SO_TIMESTAMP: ::c_int = 63;
pub const SO_TIMESTAMPNS: ::c_int = 64;
pub const SO_TIMESTAMPING: ::c_int = 65;
pub const SO_RCVTIMEO: ::c_int = 66;
pub const SO_SNDTIMEO: ::c_int = 67;
} else {
pub const SO_TIMESTAMP: ::c_int = 29;
pub const SO_TIMESTAMPNS: ::c_int = 35;
pub const SO_TIMESTAMPING: ::c_int = 37;
pub const SO_RCVTIMEO: ::c_int = 20;
pub const SO_SNDTIMEO: ::c_int = 21;
}
}
// pub const SO_TIMESTAMP_OLD: ::c_int = 29;
// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35;
// pub const SO_TIMESTAMPING_OLD: ::c_int = 37;
// pub const SO_RCVTIMEO_OLD: ::c_int = 20;
// pub const SO_SNDTIMEO_OLD: ::c_int = 21;

pub const SO_ACCEPTCONN: ::c_int = 30;
pub const SO_PEERSEC: ::c_int = 31;
pub const SO_SNDBUFFORCE: ::c_int = 32;
pub const SO_RCVBUFFORCE: ::c_int = 33;
pub const SO_PASSSEC: ::c_int = 34;
pub const SO_TIMESTAMPNS: ::c_int = 35;
// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35;
pub const SO_MARK: ::c_int = 36;
pub const SO_TIMESTAMPING: ::c_int = 37;
// pub const SO_TIMESTAMPING_OLD: ::c_int = 37;
pub const SO_PROTOCOL: ::c_int = 38;
pub const SO_DOMAIN: ::c_int = 39;
pub const SO_RXQ_OVFL: ::c_int = 40;
Expand Down
34 changes: 26 additions & 8 deletions src/unix/linux_like/linux/arch/mips/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,15 @@ pub const SO_RCVLOWAT: ::c_int = 0x1004;
// NOTE: These definitions are now being renamed with _OLD postfix,
// but CI haven't support them yet.
// Some related consts could be found in b32.rs and b64.rs
pub const SO_SNDTIMEO: ::c_int = 0x1005;
pub const SO_RCVTIMEO: ::c_int = 0x1006;
cfg_if! {
if #[cfg(gnu_time64_abi)] {
pub const SO_SNDTIMEO: ::c_int = 67;
pub const SO_RCVTIMEO: ::c_int = 66;
} else {
pub const SO_SNDTIMEO: ::c_int = 0x1005;
pub const SO_RCVTIMEO: ::c_int = 0x1006;
}
}
// pub const SO_SNDTIMEO_OLD: ::c_int = 0x1005;
// pub const SO_RCVTIMEO_OLD: ::c_int = 0x1006;
pub const SO_ACCEPTCONN: ::c_int = 0x1009;
Expand Down Expand Up @@ -88,9 +95,17 @@ pub const SO_BINDTOIFINDEX: ::c_int = 62;
// NOTE: These definitions are now being renamed with _OLD postfix,
// but CI haven't support them yet.
// Some related consts could be found in b32.rs and b64.rs
pub const SO_TIMESTAMP: ::c_int = 29;
pub const SO_TIMESTAMPNS: ::c_int = 35;
pub const SO_TIMESTAMPING: ::c_int = 37;
cfg_if! {
if #[cfg(gnu_time64_abi)] {
pub const SO_TIMESTAMP: ::c_int = 63;
pub const SO_TIMESTAMPNS: ::c_int = 64;
pub const SO_TIMESTAMPING: ::c_int = 65;
} else {
pub const SO_TIMESTAMP: ::c_int = 29;
pub const SO_TIMESTAMPNS: ::c_int = 35;
pub const SO_TIMESTAMPING: ::c_int = 37;
}
}
// pub const SO_TIMESTAMP_OLD: ::c_int = 29;
// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35;
// pub const SO_TIMESTAMPING_OLD: ::c_int = 37;
Expand Down Expand Up @@ -315,9 +330,12 @@ cfg_if! {
}

cfg_if! {
if #[cfg(any(target_arch = "mips", target_arch = "mips32r6"),
any(target_env = "gnu",
target_env = "uclibc"))] {
if #[cfg(all(gnu_time64_abi, any(target_arch = "mips", target_arch = "mips32r6")))] {
pub const RLIM_INFINITY: ::rlim_t = !0;
} else if #[cfg(all(
any(target_arch = "mips", target_arch = "mips32r6"),
any(target_env = "uclibc", all(target_env = "gnu", not(gnu_time64_abi)))
))] {
pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff;
}
}
Loading