Skip to content

Commit 5b60e70

Browse files
committed
Separate L4Re from Linux code, add aarch64 and enable tests
The L4Re code was previously attached to the Linux code which was not correct in many ways. This commit separates the L4Re code and enables the libc-tests and includes the fixes for the failing tests. Aarch64 is added as a second supported architecture (more to come).
1 parent 9d520fb commit 5b60e70

File tree

19 files changed

+6924
-2743
lines changed

19 files changed

+6924
-2743
lines changed

ci/run-docker.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ run() {
4747
--env RUST_LIBC_UNSTABLE_GNU_TIME_BITS \
4848
--env CARGO_HOME=/cargo \
4949
--env CARGO_TARGET_DIR=/checkout/target \
50-
--volume "$CARGO_HOME":/cargo \
51-
--volume "$(rustc --print sysroot)":/rust:ro \
52-
--volume "$PWD":/checkout:ro \
50+
--volume "$CARGO_HOME":/cargo:Z \
51+
--volume "$(rustc --print sysroot)":/rust:ro,Z \
52+
--volume "$PWD":/checkout:ro,Z \
5353
--volume "$PWD"/target:/checkout/target \
5454
$kvm \
5555
--init \
@@ -78,9 +78,9 @@ build_switch() {
7878
--env LIBC_CI \
7979
--env CARGO_HOME=/cargo \
8080
--env CARGO_TARGET_DIR=/checkout/target \
81-
--volume "$CARGO_HOME":/cargo \
82-
--volume "$(rustc --print sysroot)":/rust:ro \
83-
--volume "$(pwd)":/checkout:ro \
81+
--volume "$CARGO_HOME":/cargo:Z \
82+
--volume "$(rustc --print sysroot)":/rust:ro,Z \
83+
--volume "$(pwd)":/checkout:ro,Z \
8484
--volume "$(pwd)"/target:/checkout/target \
8585
--volume ~/.rustup:/.rustup:Z \
8686
$kvm \

ctest/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,8 @@ fn default_cfg(target: &str) -> Vec<(String, Option<String>)> {
11001100
("hurd", "unix", "gnu")
11011101
} else if target.contains("cygwin") {
11021102
("cygwin", "unix", "")
1103+
} else if target.contains("l4re-uclibc") {
1104+
("l4re", "unix", "uclibc")
11031105
} else {
11041106
panic!("unknown os/family: {target}")
11051107
};

libc-test/build.rs

Lines changed: 73 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ fn do_ctest() {
5757
t if t.contains("emscripten") => test_emscripten(t),
5858
t if t.contains("freebsd") => test_freebsd(t),
5959
t if t.contains("haiku") => test_haiku(t),
60+
t if t.contains("l4re") => test_linux(t),
6061
t if t.contains("linux") => test_linux(t),
6162
t if t.contains("netbsd") => test_netbsd(t),
6263
t if t.contains("openbsd") => test_openbsd(t),
@@ -96,9 +97,10 @@ fn do_semver() {
9697
// NOTE: Android doesn't include the unix file (or the Linux file) because
9798
// there are some many definitions missing it's actually easier just to
9899
// maintain a file for Android.
99-
// NOTE: AIX doesn't include the unix file because there are definitions
100-
// missing on AIX. It is easier to maintain a file for AIX.
101-
if family != os && !matches!(os.as_str(), "android" | "aix") {
100+
// NOTE: AIX and L4Re do not include the unix file because there are
101+
// definitions missing on these systems. It is easier to maintain separate
102+
// files for them.
103+
if family != os && !matches!(os.as_str(), "android" | "aix" | "l4re") {
102104
process_semver_file(&mut output, &mut semver_root, &family);
103105
}
104106
// We don't do semver for unknown targets.
@@ -3653,18 +3655,26 @@ fn config_gnu_bits(target: &str, cfg: &mut ctest::TestGenerator) {
36533655
}
36543656

36553657
fn test_linux(target: &str) {
3656-
assert!(target.contains("linux"));
3658+
assert!(target.contains("linux") || target.contains("l4re"));
3659+
3660+
// target_os
3661+
let linux = target.contains("linux");
3662+
let l4re = target.contains("l4re");
36573663

36583664
// target_env
36593665
let gnu = target.contains("gnu");
36603666
let musl = target.contains("musl") || target.contains("ohos");
36613667
let uclibc = target.contains("uclibc");
36623668

3663-
match (gnu, musl, uclibc) {
3664-
(true, false, false) => (),
3665-
(false, true, false) => (),
3666-
(false, false, true) => (),
3667-
(_, _, _) => panic!("linux target lib is gnu: {gnu}, musl: {musl}, uclibc: {uclibc}"),
3669+
match (linux, gnu, musl, uclibc) {
3670+
(true, true, false, false) => (),
3671+
(true, false, true, false) => (),
3672+
(true, false, false, true) => (),
3673+
(false, false, false, true) => (),
3674+
(_, _, _, _) => panic!(
3675+
"{} target lib is gnu: {gnu}, musl: {musl}, uclibc: {uclibc}",
3676+
if linux { "linux" } else { "l4re" }
3677+
),
36683678
}
36693679

36703680
let arm = target.contains("arm");
@@ -3696,8 +3706,10 @@ fn test_linux(target: &str) {
36963706
// deprecated since glibc >= 2.29. This allows Rust binaries to link against
36973707
// glibc versions older than 2.29.
36983708
cfg.define("__GLIBC_USE_DEPRECATED_SCANF", None);
3699-
37003709
config_gnu_bits(target, &mut cfg);
3710+
if l4re {
3711+
cfg.flag("-Wno-unused-function");
3712+
}
37013713

37023714
headers! { cfg:
37033715
"ctype.h",
@@ -3716,11 +3728,12 @@ fn test_linux(target: &str) {
37163728
"libgen.h",
37173729
"limits.h",
37183730
"link.h",
3719-
"linux/sysctl.h",
3731+
[uclibc]: "linux/if_ether.h",
3732+
[linux]: "linux/sysctl.h",
37203733
"locale.h",
37213734
"malloc.h",
37223735
"mntent.h",
3723-
"mqueue.h",
3736+
[linux]: "mqueue.h",
37243737
"net/ethernet.h",
37253738
"net/if.h",
37263739
"net/if_arp.h",
@@ -3730,6 +3743,7 @@ fn test_linux(target: &str) {
37303743
"netinet/ip.h",
37313744
"netinet/tcp.h",
37323745
"netinet/udp.h",
3746+
[l4re]: "netpacket/packet.h",
37333747
"poll.h",
37343748
"pthread.h",
37353749
"pty.h",
@@ -3740,43 +3754,44 @@ fn test_linux(target: &str) {
37403754
"semaphore.h",
37413755
"shadow.h",
37423756
"signal.h",
3743-
"spawn.h",
3744-
"stddef.h",
3757+
[linux]: "spawn.h",
3758+
[linux]: "stddef.h",
37453759
"stdint.h",
37463760
"stdio.h",
37473761
"stdlib.h",
37483762
"string.h",
3749-
"sys/epoll.h",
3750-
"sys/eventfd.h",
3763+
[l4re]: "sys/auxv.h",
3764+
[linux]: "sys/epoll.h",
3765+
[linux]: "sys/eventfd.h",
37513766
"sys/file.h",
3752-
"sys/fsuid.h",
3753-
"sys/klog.h",
3754-
"sys/inotify.h",
3767+
[linux]: "sys/fsuid.h",
3768+
[linux]: "sys/klog.h",
3769+
[linux]: "sys/inotify.h",
37553770
"sys/ioctl.h",
37563771
"sys/ipc.h",
37573772
"sys/mman.h",
37583773
"sys/mount.h",
3759-
"sys/msg.h",
3760-
"sys/personality.h",
3774+
[linux]: "sys/msg.h",
3775+
[linux]: "sys/personality.h",
37613776
"sys/prctl.h",
3762-
"sys/ptrace.h",
3763-
"sys/quota.h",
3764-
"sys/random.h",
3765-
"sys/reboot.h",
3777+
[linux]: "sys/ptrace.h",
3778+
[linux]: "sys/quota.h",
3779+
[linux]: "sys/random.h",
3780+
[linux]: "sys/reboot.h",
37663781
"sys/resource.h",
37673782
"sys/sem.h",
3768-
"sys/sendfile.h",
3783+
[linux]: "sys/sendfile.h",
37693784
"sys/shm.h",
3770-
"sys/signalfd.h",
3785+
[linux]: "sys/signalfd.h",
37713786
"sys/socket.h",
37723787
"sys/stat.h",
37733788
"sys/statvfs.h",
3774-
"sys/swap.h",
3789+
[linux]: "sys/swap.h",
37753790
"sys/syscall.h",
37763791
"sys/time.h",
3777-
"sys/timerfd.h",
3792+
[linux]: "sys/timerfd.h",
37783793
"sys/times.h",
3779-
"sys/timex.h",
3794+
[linux]: "sys/timex.h",
37803795
"sys/types.h",
37813796
"sys/uio.h",
37823797
"sys/un.h",
@@ -3798,12 +3813,12 @@ fn test_linux(target: &str) {
37983813
// ARM: https://bugzilla.redhat.com/show_bug.cgi?id=1116162
37993814
// Also unavailable on gnueabihf with glibc 2.30.
38003815
// https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=6b33f373c7b9199e00ba5fbafd94ac9bfb4337b1
3801-
[(x86_64 || x86_32 || arm) && !gnueabihf]: "sys/io.h",
3816+
[(x86_64 || x86_32 || arm) && !gnueabihf && !l4re]: "sys/io.h",
38023817
// `sys/reg.h` is only available on x86 and x86_64
3803-
[x86_64 || x86_32]: "sys/reg.h",
3818+
[(x86_64 || x86_32) && !l4re]: "sys/reg.h",
38043819
// sysctl system call is deprecated and not available on musl
38053820
// It is also unsupported in x32, deprecated since glibc 2.30:
3806-
[!(x32 || musl || gnu)]: "sys/sysctl.h",
3821+
[!(x32 || musl || gnu || l4re)]: "sys/sysctl.h",
38073822
// <execinfo.h> is not supported by musl:
38083823
// https://www.openwall.com/lists/musl/2015/04/09/3
38093824
// <execinfo.h> is not present on uclibc.
@@ -3813,11 +3828,11 @@ fn test_linux(target: &str) {
38133828
// Include linux headers at the end:
38143829
headers! {
38153830
cfg:
3816-
[loongarch64 || riscv64]: "asm/hwcap.h",
3817-
"asm/mman.h",
3831+
[(loongarch64 || riscv64) && !l4re]: "asm/hwcap.h",
3832+
[linux]: "asm/mman.h",
38183833
}
38193834

3820-
if !wasm32 {
3835+
if !wasm32 && !l4re {
38213836
headers! { cfg:
38223837
[gnu]: "linux/aio_abi.h",
38233838
"linux/can.h",
@@ -3835,7 +3850,6 @@ fn test_linux(target: &str) {
38353850
"linux/if.h",
38363851
"linux/if_addr.h",
38373852
"linux/if_alg.h",
3838-
"linux/if_ether.h",
38393853
"linux/if_packet.h",
38403854
"linux/if_tun.h",
38413855
"linux/if_xdp.h",
@@ -3881,7 +3895,6 @@ fn test_linux(target: &str) {
38813895
"linux/wait.h",
38823896
"linux/wireless.h",
38833897
"sys/fanotify.h",
3884-
// <sys/auxv.h> is not present on uclibc
38853898
[!uclibc]: "sys/auxv.h",
38863899
[gnu || musl]: "linux/close_range.h",
38873900
}
@@ -3890,7 +3903,7 @@ fn test_linux(target: &str) {
38903903
// note: aio.h must be included before sys/mount.h
38913904
headers! {
38923905
cfg:
3893-
"sys/xattr.h",
3906+
[linux]: "sys/xattr.h",
38943907
"sys/sysinfo.h",
38953908
// AIO is not supported by uclibc:
38963909
[!uclibc]: "aio.h",
@@ -3903,12 +3916,14 @@ fn test_linux(target: &str) {
39033916
| "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
39043917
| "Elf32_Chdr" | "Elf64_Chdr" => ty.to_string(),
39053918

3906-
"Ioctl" if gnu => "unsigned long".to_string(),
3919+
"Ioctl" if gnu || uclibc => "unsigned long".to_string(),
39073920
"Ioctl" => "int".to_string(),
39083921

39093922
// LFS64 types have been removed in musl 1.2.4+
39103923
"off64_t" if musl => "off_t".to_string(),
39113924

3925+
"fsword_t" if uclibc => "__SWORD_TYPE".to_string(),
3926+
39123927
// typedefs don't need any keywords
39133928
t if t.ends_with("_t") => t.to_string(),
39143929
// put `struct` in front of all structs:.
@@ -3956,6 +3971,8 @@ fn test_linux(target: &str) {
39563971
return true;
39573972
}
39583973
match ty {
3974+
t if t.starts_with("l4_") => true,
3975+
39593976
// FIXME(sighandler): `sighandler_t` type is incorrect, see:
39603977
// https://github.com/rust-lang/libc/issues/1359
39613978
"sighandler_t" => true,
@@ -3990,6 +4007,10 @@ fn test_linux(target: &str) {
39904007
});
39914008

39924009
cfg.skip_struct(move |ty| {
4010+
if ty.starts_with("l4_") {
4011+
return true;
4012+
}
4013+
39934014
if ty.starts_with("__c_anonymous_") {
39944015
return true;
39954016
}
@@ -4169,6 +4190,12 @@ fn test_linux(target: &str) {
41694190
});
41704191

41714192
cfg.skip_const(move |name| {
4193+
// L4Re requires a min stack size of 64k; that isn't defined in uClibc, but
4194+
// somewhere in the core libraries. uClibc wants 16k, but that's not enough.
4195+
if name == "PTHREAD_STACK_MIN" {
4196+
return true;
4197+
}
4198+
41724199
if !gnu {
41734200
// Skip definitions from the kernel on non-glibc Linux targets.
41744201
// They're libc-independent, so we only need to check them on one
@@ -4343,7 +4370,7 @@ fn test_linux(target: &str) {
43434370

43444371
// FIXME(musl): on musl the pthread types are defined a little differently
43454372
// - these constants are used by the glibc implementation.
4346-
n if musl && n.contains("__SIZEOF_PTHREAD") => true,
4373+
n if (musl || uclibc) && n.contains("__SIZEOF_PTHREAD") => true,
43474374

43484375
// FIXME(linux): It was extended to 4096 since glibc 2.31 (Linux 5.4).
43494376
// We should do so after a while.
@@ -4655,6 +4682,8 @@ fn test_linux(target: &str) {
46554682
cfg.skip_fn(move |name| {
46564683
// skip those that are manually verified
46574684
match name {
4685+
n if n.starts_with("l4_") => true,
4686+
46584687
// There are two versions of the sterror_r function, see
46594688
//
46604689
// https://linux.die.net/man/3/strerror_r
@@ -4920,7 +4949,9 @@ fn test_linux(target: &str) {
49204949

49214950
cfg.generate(src_hotfix_dir().join("lib.rs"), "main.rs");
49224951

4923-
test_linux_like_apis(target);
4952+
if linux {
4953+
test_linux_like_apis(target);
4954+
}
49244955
}
49254956

49264957
// This function tests APIs that are incompatible to test when other APIs

0 commit comments

Comments
 (0)