diff --git a/lib/std/c.zig b/lib/std/c.zig index c1523cd68a54..0ee7f32e5c3d 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -2753,6 +2753,19 @@ pub const Sigaction = switch (native_os) { restorer: ?*const fn () callconv(.C) void = null, __resv: [1]c_int = .{0}, }, + .s390x => if (builtin.abi == .gnu) extern struct { + pub const handler_fn = *align(1) const fn (i32) callconv(.C) void; + pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.C) void; + + handler: extern union { + handler: ?handler_fn, + sigaction: ?sigaction_fn, + }, + __glibc_reserved0: c_int = 0, + flags: c_uint, + restorer: ?*const fn () callconv(.C) void = null, + mask: sigset_t, + } else linux.Sigaction, else => linux.Sigaction, }, .emscripten => emscripten.Sigaction, diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 0cb201373a73..ad43caee5922 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -61,6 +61,7 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) { .mipsel, .mips64, .mips64el, + .s390x, => false, // `@returnAddress()` in LLVM 10 gives diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index aaf08395fa48..40dfcb933b57 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -904,7 +904,19 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: MAP, fd: i32, of @truncate(@as(u64, @bitCast(offset)) / MMAP2_UNIT), ); } else { - return syscall6( + // The s390x mmap() syscall existed before Linux supported syscalls with 5+ parameters, so + // it takes a single pointer to an array of arguments instead. + return if (native_arch == .s390x) syscall1( + .mmap, + @intFromPtr(&[_]usize{ + @intFromPtr(address), + length, + prot, + @as(u32, @bitCast(flags)), + @bitCast(@as(isize, fd)), + @as(u64, @bitCast(offset)), + }), + ) else syscall6( .mmap, @intFromPtr(address), length, diff --git a/lib/std/os/linux/tls.zig b/lib/std/os/linux/tls.zig index 7dab38024ca6..d1292e86dd03 100644 --- a/lib/std/os/linux/tls.zig +++ b/lib/std/os/linux/tls.zig @@ -541,7 +541,19 @@ inline fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: linux.MAP, fd @as(usize, @truncate(@as(u64, @bitCast(offset)) / linux.MMAP2_UNIT)), }); } else { - return @call(.always_inline, linux.syscall6, .{ + // The s390x mmap() syscall existed before Linux supported syscalls with 5+ parameters, so + // it takes a single pointer to an array of arguments instead. + return if (native_arch == .s390x) @call(.always_inline, linux.syscall1, .{ + .mmap, + @intFromPtr(&[_]usize{ + @intFromPtr(address), + length, + prot, + @as(u32, @bitCast(flags)), + @as(usize, @bitCast(@as(isize, fd))), + @as(u64, @bitCast(offset)), + }), + }) else @call(.always_inline, linux.syscall6, .{ .mmap, @intFromPtr(address), length, diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index e62ffa39ca54..dba7dcde6d9c 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -368,6 +368,11 @@ test "fstatat" { // now repeat but using `fstatat` instead const flags = if (native_os == .wasi) 0x0 else posix.AT.SYMLINK_NOFOLLOW; const statat = try posix.fstatat(tmp.dir.fd, "file.txt", flags); + + // s390x-linux does not have nanosecond precision for fstat(), but it does for fstatat(). As a + // result, comparing the two structures is doomed to fail. + if (builtin.cpu.arch == .s390x and builtin.os.tag == .linux) return error.SkipZigTest; + try expectEqual(stat, statat); } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 2cd1af783e23..1f21516e9ea8 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -12241,6 +12241,7 @@ fn ccAbiPromoteInt( .sparc64, .powerpc64, .powerpc64le, + .s390x, => switch (int_info.bits) { 0...63 => int_info.signedness, else => null, diff --git a/test/tests.zig b/test/tests.zig index 1d6c33bd2448..1e98a48489a4 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -636,6 +636,30 @@ const test_targets = blk: { .use_lld = false, }, + .{ + .target = .{ + .cpu_arch = .s390x, + .os_tag = .linux, + .abi = .none, + }, + }, + .{ + .target = .{ + .cpu_arch = .s390x, + .os_tag = .linux, + .abi = .musl, + }, + .link_libc = true, + }, + .{ + .target = .{ + .cpu_arch = .s390x, + .os_tag = .linux, + .abi = .gnu, + }, + .link_libc = true, + }, + .{ .target = .{ .cpu_arch = .x86_64,