Skip to content

Commit a32a27f

Browse files
committed
s390x linux_raw support
1 parent 613940f commit a32a27f

File tree

9 files changed

+316
-10
lines changed

9 files changed

+316
-10
lines changed

.github/workflows/main.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ jobs:
638638
runs-on: ${{ matrix.os }}
639639
strategy:
640640
matrix:
641-
build: [powerpc64le-linux]
641+
build: [powerpc64le-linux, s390x-linux]
642642
include:
643643
- build: powerpc64le-linux
644644
os: ubuntu-latest
@@ -649,11 +649,21 @@ jobs:
649649
qemu: qemu-ppc64le
650650
qemu_args: -L /usr/powerpc64le-linux-gnu
651651
qemu_target: ppc64le-linux-user
652+
- build: s390x-linux
653+
os: ubuntu-latest
654+
rust: nightly
655+
target: s390x-unknown-linux-gnu
656+
gcc_package: gcc-s390x-linux-gnu
657+
gcc: s390x-linux-gnu-gcc
658+
qemu: qemu-s390x
659+
qemu_args: -L /usr/s390x-linux-gnu
660+
qemu_target: s390x-linux-user
652661
env:
653662
# -D warnings is commented out in our install-rust action; re-add it here.
654663
RUSTFLAGS: --cfg rustix_use_experimental_asm -D warnings -D elided-lifetimes-in-paths
655664
RUSTDOCFLAGS: --cfg rustix_use_experimental_asm
656665
CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_experimental_asm
666+
CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_experimental_asm
657667
QEMU_BUILD_VERSION: 8.1.2
658668
steps:
659669
- uses: actions/checkout@v4

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ once_cell = { version = "1.5.2", optional = true }
3535
# addition to the libc backend. The linux_raw backend is used by default. The
3636
# libc backend can be selected via adding `--cfg=rustix_use_libc` to
3737
# `RUSTFLAGS` or enabling the `use-libc` cargo feature.
38-
[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 = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"))))'.dependencies]
38+
[target.'cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", any(target_endian = "little", target_arch = "s390x"), 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 = "s390x"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"))))'.dependencies]
3939
linux-raw-sys = { version = "0.4.14", default-features = false, features = ["general", "errno", "ioctl", "no_std", "elf"] }
4040
libc_errno = { package = "errno", version = "0.3.8", default-features = false, optional = true }
4141
libc = { version = "0.2.156", default-features = false, optional = true }
@@ -44,15 +44,15 @@ libc = { version = "0.2.156", default-features = false, optional = true }
4444
#
4545
# On all other Unix-family platforms, and under Miri, we always use the libc
4646
# backend, so enable its dependencies unconditionally.
47-
[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 = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
47+
[target.'cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = "linux", any(target_endian = "little", target_arch = "s390x"), 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 = "s390x"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
4848
libc_errno = { package = "errno", version = "0.3.8", default-features = false }
4949
libc = { version = "0.2.156", default-features = false }
5050

5151
# Additional dependencies for Linux with the libc backend:
5252
#
5353
# Some syscalls do not have libc wrappers, such as in `io_uring`. For these,
5454
# the libc backend uses the linux-raw-sys ABI and `libc::syscall`.
55-
[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 = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
55+
[target.'cfg(all(any(target_os = "android", target_os = "linux"), any(rustix_use_libc, miri, not(all(target_os = "linux", any(target_endian = "little", target_arch = "s390x"), 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 = "s390x"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
5656
linux-raw-sys = { version = "0.4.14", default-features = false, features = ["general", "ioctl", "no_std"] }
5757

5858
# For the libc backend on Windows, use the Winsock API in windows-sys.

build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ fn main() {
9595
|| !inline_asm_name_present
9696
|| is_unsupported_abi
9797
|| miri
98-
|| ((arch == "powerpc64" || arch.starts_with("mips")) && !rustix_use_experimental_asm);
98+
|| ((arch == "powerpc64" || arch == "s390x" || arch.starts_with("mips"))
99+
&& !rustix_use_experimental_asm);
99100
if libc {
100101
// Use the libc backend.
101102
use_feature("libc");

src/backend/linux_raw/arch/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#[cfg_attr(target_arch = "mips64r6", path = "mips64r6.rs")]
3333
#[cfg_attr(target_arch = "powerpc64", path = "powerpc64.rs")]
3434
#[cfg_attr(target_arch = "riscv64", path = "riscv64.rs")]
35+
#[cfg_attr(target_arch = "s390x", path = "s390x.rs")]
3536
#[cfg_attr(target_arch = "x86", path = "x86.rs")]
3637
#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")]
3738
pub(in crate::backend) mod asm;
@@ -47,6 +48,7 @@ pub(in crate::backend) mod asm;
4748
target_arch = "mips64r6",
4849
target_arch = "powerpc64",
4950
target_arch = "riscv64",
51+
target_arch = "s390x",
5052
target_arch = "x86_64",
5153
))]
5254
pub(in crate::backend) use self::asm as choose;

src/backend/linux_raw/arch/s390x.rs

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
//! s390x Linux system calls.
2+
3+
use crate::backend::reg::{
4+
ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0,
5+
};
6+
use core::arch::asm;
7+
8+
#[inline]
9+
pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> {
10+
let r0;
11+
asm!(
12+
"svc 0",
13+
in("r1") nr.to_asm(),
14+
lateout("r2") r0,
15+
options(nostack, preserves_flags, readonly)
16+
);
17+
FromAsm::from_asm(r0)
18+
}
19+
20+
#[inline]
21+
pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
22+
let r0;
23+
asm!(
24+
"svc 0",
25+
in("r1") nr.to_asm(),
26+
inlateout("r2") a0.to_asm() => r0,
27+
options(nostack, preserves_flags)
28+
);
29+
FromAsm::from_asm(r0)
30+
}
31+
32+
#[inline]
33+
pub(in crate::backend) unsafe fn syscall1_readonly(
34+
nr: SyscallNumber<'_>,
35+
a0: ArgReg<'_, A0>,
36+
) -> RetReg<R0> {
37+
let r0;
38+
asm!(
39+
"svc 0",
40+
in("r1") nr.to_asm(),
41+
inlateout("r2") a0.to_asm() => r0,
42+
options(nostack, preserves_flags, readonly)
43+
);
44+
FromAsm::from_asm(r0)
45+
}
46+
47+
#[inline]
48+
pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! {
49+
asm!(
50+
"svc 0",
51+
in("r1") nr.to_asm(),
52+
in("r2") a0.to_asm(),
53+
options(nostack, preserves_flags, noreturn)
54+
)
55+
}
56+
57+
#[inline]
58+
pub(in crate::backend) unsafe fn syscall2(
59+
nr: SyscallNumber<'_>,
60+
a0: ArgReg<'_, A0>,
61+
a1: ArgReg<'_, A1>,
62+
) -> RetReg<R0> {
63+
let r0;
64+
asm!(
65+
"svc 0",
66+
in("r1") nr.to_asm(),
67+
inlateout("r2") a0.to_asm() => r0,
68+
in("r3") a1.to_asm(),
69+
options(nostack, preserves_flags)
70+
);
71+
FromAsm::from_asm(r0)
72+
}
73+
74+
#[inline]
75+
pub(in crate::backend) unsafe fn syscall2_readonly(
76+
nr: SyscallNumber<'_>,
77+
a0: ArgReg<'_, A0>,
78+
a1: ArgReg<'_, A1>,
79+
) -> RetReg<R0> {
80+
let r0;
81+
asm!(
82+
"svc 0",
83+
in("r1") nr.to_asm(),
84+
inlateout("r2") a0.to_asm() => r0,
85+
in("r3") a1.to_asm(),
86+
options(nostack, preserves_flags, readonly)
87+
);
88+
FromAsm::from_asm(r0)
89+
}
90+
91+
#[inline]
92+
pub(in crate::backend) unsafe fn syscall3(
93+
nr: SyscallNumber<'_>,
94+
a0: ArgReg<'_, A0>,
95+
a1: ArgReg<'_, A1>,
96+
a2: ArgReg<'_, A2>,
97+
) -> RetReg<R0> {
98+
let r0;
99+
asm!(
100+
"svc 0",
101+
in("r1") nr.to_asm(),
102+
inlateout("r2") a0.to_asm() => r0,
103+
in("r3") a1.to_asm(),
104+
in("r4") a2.to_asm(),
105+
options(nostack, preserves_flags)
106+
);
107+
FromAsm::from_asm(r0)
108+
}
109+
110+
#[inline]
111+
pub(in crate::backend) unsafe fn syscall3_readonly(
112+
nr: SyscallNumber<'_>,
113+
a0: ArgReg<'_, A0>,
114+
a1: ArgReg<'_, A1>,
115+
a2: ArgReg<'_, A2>,
116+
) -> RetReg<R0> {
117+
let r0;
118+
asm!(
119+
"svc 0",
120+
in("r1") nr.to_asm(),
121+
inlateout("r2") a0.to_asm() => r0,
122+
in("r3") a1.to_asm(),
123+
in("r4") a2.to_asm(),
124+
options(nostack, preserves_flags, readonly)
125+
);
126+
FromAsm::from_asm(r0)
127+
}
128+
129+
#[inline]
130+
pub(in crate::backend) unsafe fn syscall4(
131+
nr: SyscallNumber<'_>,
132+
a0: ArgReg<'_, A0>,
133+
a1: ArgReg<'_, A1>,
134+
a2: ArgReg<'_, A2>,
135+
a3: ArgReg<'_, A3>,
136+
) -> RetReg<R0> {
137+
let r0;
138+
asm!(
139+
"svc 0",
140+
in("r1") nr.to_asm(),
141+
inlateout("r2") a0.to_asm() => r0,
142+
in("r3") a1.to_asm(),
143+
in("r4") a2.to_asm(),
144+
in("r5") a3.to_asm(),
145+
options(nostack, preserves_flags)
146+
);
147+
FromAsm::from_asm(r0)
148+
}
149+
150+
#[inline]
151+
pub(in crate::backend) unsafe fn syscall4_readonly(
152+
nr: SyscallNumber<'_>,
153+
a0: ArgReg<'_, A0>,
154+
a1: ArgReg<'_, A1>,
155+
a2: ArgReg<'_, A2>,
156+
a3: ArgReg<'_, A3>,
157+
) -> RetReg<R0> {
158+
let r0;
159+
asm!(
160+
"svc 0",
161+
in("r1") nr.to_asm(),
162+
inlateout("r2") a0.to_asm() => r0,
163+
in("r3") a1.to_asm(),
164+
in("r4") a2.to_asm(),
165+
in("r5") a3.to_asm(),
166+
options(nostack, preserves_flags, readonly)
167+
);
168+
FromAsm::from_asm(r0)
169+
}
170+
171+
#[inline]
172+
pub(in crate::backend) unsafe fn syscall5(
173+
nr: SyscallNumber<'_>,
174+
a0: ArgReg<'_, A0>,
175+
a1: ArgReg<'_, A1>,
176+
a2: ArgReg<'_, A2>,
177+
a3: ArgReg<'_, A3>,
178+
a4: ArgReg<'_, A4>,
179+
) -> RetReg<R0> {
180+
let r0;
181+
asm!(
182+
"svc 0",
183+
in("r1") nr.to_asm(),
184+
inlateout("r2") a0.to_asm() => r0,
185+
in("r3") a1.to_asm(),
186+
in("r4") a2.to_asm(),
187+
in("r5") a3.to_asm(),
188+
in("r6") a4.to_asm(),
189+
options(nostack, preserves_flags)
190+
);
191+
FromAsm::from_asm(r0)
192+
}
193+
194+
#[inline]
195+
pub(in crate::backend) unsafe fn syscall5_readonly(
196+
nr: SyscallNumber<'_>,
197+
a0: ArgReg<'_, A0>,
198+
a1: ArgReg<'_, A1>,
199+
a2: ArgReg<'_, A2>,
200+
a3: ArgReg<'_, A3>,
201+
a4: ArgReg<'_, A4>,
202+
) -> RetReg<R0> {
203+
let r0;
204+
asm!(
205+
"svc 0",
206+
in("r1") nr.to_asm(),
207+
inlateout("r2") a0.to_asm() => r0,
208+
in("r3") a1.to_asm(),
209+
in("r4") a2.to_asm(),
210+
in("r5") a3.to_asm(),
211+
in("r6") a4.to_asm(),
212+
options(nostack, preserves_flags, readonly)
213+
);
214+
FromAsm::from_asm(r0)
215+
}
216+
217+
#[inline]
218+
pub(in crate::backend) unsafe fn syscall6(
219+
nr: SyscallNumber<'_>,
220+
a0: ArgReg<'_, A0>,
221+
a1: ArgReg<'_, A1>,
222+
a2: ArgReg<'_, A2>,
223+
a3: ArgReg<'_, A3>,
224+
a4: ArgReg<'_, A4>,
225+
a5: ArgReg<'_, A5>,
226+
) -> RetReg<R0> {
227+
let r0;
228+
asm!(
229+
"svc 0",
230+
in("r1") nr.to_asm(),
231+
inlateout("r2") a0.to_asm() => r0,
232+
in("r3") a1.to_asm(),
233+
in("r4") a2.to_asm(),
234+
in("r5") a3.to_asm(),
235+
in("r6") a4.to_asm(),
236+
in("r7") a5.to_asm(),
237+
options(nostack, preserves_flags)
238+
);
239+
FromAsm::from_asm(r0)
240+
}
241+
242+
#[inline]
243+
pub(in crate::backend) unsafe fn syscall6_readonly(
244+
nr: SyscallNumber<'_>,
245+
a0: ArgReg<'_, A0>,
246+
a1: ArgReg<'_, A1>,
247+
a2: ArgReg<'_, A2>,
248+
a3: ArgReg<'_, A3>,
249+
a4: ArgReg<'_, A4>,
250+
a5: ArgReg<'_, A5>,
251+
) -> RetReg<R0> {
252+
let r0;
253+
asm!(
254+
"svc 0",
255+
in("r1") nr.to_asm(),
256+
inlateout("r2") a0.to_asm() => r0,
257+
in("r3") a1.to_asm(),
258+
in("r4") a2.to_asm(),
259+
in("r5") a3.to_asm(),
260+
in("r6") a4.to_asm(),
261+
in("r7") a5.to_asm(),
262+
options(nostack, preserves_flags, readonly)
263+
);
264+
FromAsm::from_asm(r0)
265+
}

0 commit comments

Comments
 (0)