commit 5f3d9e0b7a67b8a23b659ca7dada8641f55b8503 (tree)
parent f29bdd6746691d0a547140e435056a000419480f
Author: Andrew Kelley <andrew@ziglang.org>
Date: Fri, 6 Sep 2024 17:43:10 -0700
Merge pull request #21261 from alexrp/riscv32
More `riscv32-linux` port work
Diffstat:
6 files changed, 85 insertions(+), 5 deletions(-)
diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig
@@ -215,7 +215,8 @@ pub const ElfDynLib = struct {
const fd = try resolveFromName(path);
defer posix.close(fd);
- const stat = try posix.fstat(fd);
+ const file: std.fs.File = .{ .handle = fd };
+ const stat = try file.stat();
const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig;
// This one is to read the ELF info. We do more mmapping later
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
@@ -1456,6 +1456,16 @@ pub fn clock_settime(clk_id: i32, tp: *const timespec) usize {
return syscall2(.clock_settime, @as(usize, @bitCast(@as(isize, clk_id))), @intFromPtr(tp));
}
+pub fn clock_nanosleep(clockid: clockid_t, flags: TIMER, request: *const timespec, remain: ?*timespec) usize {
+ return syscall4(
+ .clock_nanosleep,
+ @intFromEnum(clockid),
+ @as(u32, @bitCast(flags)),
+ @intFromPtr(request),
+ @intFromPtr(remain),
+ );
+}
+
pub fn gettimeofday(tv: ?*timeval, tz: ?*timezone) usize {
return syscall2(.gettimeofday, @intFromPtr(tv), @intFromPtr(tz));
}
@@ -1465,7 +1475,9 @@ pub fn settimeofday(tv: *const timeval, tz: *const timezone) usize {
}
pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize {
- return syscall2(.nanosleep, @intFromPtr(req), @intFromPtr(rem));
+ if (native_arch == .riscv32) {
+ @compileError("No nanosleep syscall on this architecture.");
+ } else return syscall2(.nanosleep, @intFromPtr(req), @intFromPtr(rem));
}
pub fn pause() usize {
@@ -4525,6 +4537,11 @@ pub const clockid_t = enum(u32) {
_,
};
+pub const TIMER = packed struct(u32) {
+ ABSTIME: bool,
+ _: u31 = 0,
+};
+
pub const CSIGNAL = 0x000000ff;
pub const CLONE = struct {
@@ -7452,7 +7469,7 @@ pub const kernel_timespec = extern struct {
};
// https://github.com/ziglang/zig/issues/4726#issuecomment-2190337877
-pub const timespec = if (!builtin.link_libc and native_arch == .riscv32) kernel_timespec else extern struct {
+pub const timespec = if (native_arch == .riscv32) kernel_timespec else extern struct {
sec: isize,
nsec: isize,
};
diff --git a/lib/std/os/linux/riscv32.zig b/lib/std/os/linux/riscv32.zig
@@ -212,8 +212,37 @@ pub const msghdr_const = extern struct {
flags: i32,
};
-/// No `Stat` structure on this platform, only `Statx`.
-pub const Stat = void;
+// The `stat` definition used by the Linux kernel.
+pub const Stat = extern struct {
+ dev: dev_t,
+ ino: ino_t,
+ mode: mode_t,
+ nlink: nlink_t,
+ uid: uid_t,
+ gid: gid_t,
+ rdev: dev_t,
+ __pad: usize,
+ size: off_t,
+ blksize: blksize_t,
+ __pad2: i32,
+ blocks: blkcnt_t,
+ atim: timespec,
+ mtim: timespec,
+ ctim: timespec,
+ __unused: [2]u32,
+
+ pub fn atime(self: @This()) timespec {
+ return self.atim;
+ }
+
+ pub fn mtime(self: @This()) timespec {
+ return self.mtim;
+ }
+
+ pub fn ctime(self: @This()) timespec {
+ return self.ctim;
+ }
+};
pub const Elf_Symndx = u32;
diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig
@@ -349,6 +349,7 @@ test "linkat with different directories" {
}
test "fstatat" {
+ if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.
// enable when `fstat` and `fstatat` are implemented on Windows
if (native_os == .windows) return error.SkipZigTest;
@@ -1264,6 +1265,9 @@ test "fchmodat smoke test" {
0o644,
);
posix.close(fd);
+
+ if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.
+
try posix.symlinkat("regfile", tmp.dir.fd, "symlink");
const sym_mode = blk: {
const st = try posix.fstatat(tmp.dir.fd, "symlink", posix.AT.SYMLINK_NOFOLLOW);
diff --git a/lib/std/time.zig b/lib/std/time.zig
@@ -50,6 +50,34 @@ pub fn sleep(nanoseconds: u64) void {
const s = nanoseconds / ns_per_s;
const ns = nanoseconds % ns_per_s;
+
+ // Newer kernel ports don't have old `nanosleep()` and `clock_nanosleep()` has been around
+ // since Linux 2.6 and glibc 2.1 anyway.
+ if (builtin.os.tag == .linux) {
+ const linux = std.os.linux;
+
+ var req: linux.timespec = .{
+ .sec = std.math.cast(linux.time_t, s) orelse std.math.maxInt(linux.time_t),
+ .nsec = std.math.cast(linux.time_t, ns) orelse std.math.maxInt(linux.time_t),
+ };
+ var rem: linux.timespec = undefined;
+
+ while (true) {
+ switch (linux.E.init(linux.clock_nanosleep(.MONOTONIC, .{ .ABSTIME = false }, &req, &rem))) {
+ .SUCCESS => return,
+ .INTR => {
+ req = rem;
+ continue;
+ },
+ .FAULT,
+ .INVAL,
+ .OPNOTSUPP,
+ => unreachable,
+ else => return,
+ }
+ }
+ }
+
posix.nanosleep(s, ns);
}
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
@@ -12398,6 +12398,7 @@ fn backendSupportsF16(target: std.Target) bool {
.mipsel,
.mips64,
.mips64el,
+ .riscv32,
.s390x,
=> false,
.aarch64,