Files
2026-05-29 09:40:38 +02:00

194 lines
4.5 KiB
Zig

const builtin = @import("builtin");
const std = @import("../../std.zig");
const SYS = std.os.linux.SYS;
pub const syscall_arg_t = u32;
pub fn syscall0(
number: SYS,
) u32 {
return asm volatile ("syscall"
: [ret] "={a2}" (-> u32),
: [number] "{a2}" (@intFromEnum(number)),
: .{ .memory = true });
}
pub fn syscall1(
number: SYS,
arg1: syscall_arg_t,
) u32 {
return asm volatile ("syscall"
: [ret] "={a2}" (-> u32),
: [number] "{a2}" (@intFromEnum(number)),
[arg1] "{a6}" (arg1),
: .{ .memory = true });
}
pub fn syscall2(
number: SYS,
arg1: syscall_arg_t,
arg2: syscall_arg_t,
) u32 {
return asm volatile ("syscall"
: [ret] "={a2}" (-> u32),
: [number] "{a2}" (@intFromEnum(number)),
[arg1] "{a6}" (arg1),
[arg2] "{a3}" (arg2),
: .{ .memory = true });
}
pub fn syscall3(
number: SYS,
arg1: syscall_arg_t,
arg2: syscall_arg_t,
arg3: syscall_arg_t,
) u32 {
return asm volatile ("syscall"
: [ret] "={a2}" (-> u32),
: [number] "{a2}" (@intFromEnum(number)),
[arg1] "{a6}" (arg1),
[arg2] "{a3}" (arg2),
[arg3] "{a4}" (arg3),
: .{ .memory = true });
}
pub fn syscall4(
number: SYS,
arg1: syscall_arg_t,
arg2: syscall_arg_t,
arg3: syscall_arg_t,
arg4: syscall_arg_t,
) u32 {
return asm volatile ("syscall"
: [ret] "={a2}" (-> u32),
: [number] "{a2}" (@intFromEnum(number)),
[arg1] "{a6}" (arg1),
[arg2] "{a3}" (arg2),
[arg3] "{a4}" (arg3),
[arg4] "{a5}" (arg4),
: .{ .memory = true });
}
pub fn syscall5(
number: SYS,
arg1: syscall_arg_t,
arg2: syscall_arg_t,
arg3: syscall_arg_t,
arg4: syscall_arg_t,
arg5: syscall_arg_t,
) u32 {
return asm volatile ("syscall"
: [ret] "={a2}" (-> u32),
: [number] "{a2}" (@intFromEnum(number)),
[arg1] "{a6}" (arg1),
[arg2] "{a3}" (arg2),
[arg3] "{a4}" (arg3),
[arg4] "{a5}" (arg4),
[arg5] "{a8}" (arg5),
: .{ .memory = true });
}
pub fn syscall6(
number: SYS,
arg1: syscall_arg_t,
arg2: syscall_arg_t,
arg3: syscall_arg_t,
arg4: syscall_arg_t,
arg5: syscall_arg_t,
arg6: syscall_arg_t,
) u32 {
return asm volatile ("syscall"
: [ret] "={a2}" (-> u32),
: [number] "{a2}" (@intFromEnum(number)),
[arg1] "{a6}" (arg1),
[arg2] "{a3}" (arg2),
[arg3] "{a4}" (arg3),
[arg4] "{a5}" (arg4),
[arg5] "{a8}" (arg5),
[arg6] "{a9}" (arg6),
: .{ .memory = true });
}
pub fn clone() callconv(.naked) u32 {
// __clone(func, stack, flags, arg, ptid, tls, ctid)
// a2, a3, a4, a5, a6, a7, +16
//
// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
// a2 a6, a3, a4, a5, a8
if (builtin.abi != .call0) asm volatile (
\\ entry sp, 16
);
asm volatile (
\\ movi a8, -16
\\ and a3, a3, a8
\\
\\ mov a9, a2
\\ mov a10, a5
\\
\\ mov a5, a7
\\ mov a8, a6
\\ mov a6, a4
\\ mov a4, a8
);
if (builtin.abi == .call0) asm volatile (
\\ l32i a8, sp, 0
) else asm volatile (
\\ l32i a8, sp, 16
);
asm volatile (
\\ movi a2, 116 // SYS_clone
\\ syscall
);
if (builtin.abi == .call0) asm volatile (
\\ beqz a2, 1f
\\ // parent
\\ ret
\\
\\ // child
\\1:
\\ movi a15, 0
\\ movi a0, 0
\\
\\ mov a2, a10
\\ callx0 a9
) else asm volatile (
\\ beqz a2, 1f
\\ // parent
\\ retw
\\
\\ // child
\\1:
\\ movi a7, 0
\\ movi a0, 0
\\
\\ mov a6, a10
\\ callx4 a9
);
asm volatile (
\\ movi a2, 118 // SYS_exit
\\ syscall
);
}
pub const restore = restore_rt;
pub fn restore_rt() callconv(.naked) noreturn {
switch (builtin.zig_backend) {
.stage2_c => asm volatile (
\\ movi a2, %[number]
\\ syscall
:
: [number] "I" (@intFromEnum(SYS.rt_sigreturn)),
),
else => asm volatile (
\\ syscall
:
: [number] "{a2}" (@intFromEnum(SYS.rt_sigreturn)),
),
}
}
pub const VDSO = void;
pub const time_t = i32;