| author | |
| committer | |
| log | 38e0f049c531e83ec2eec80d50b624e6c3b8c486 |
| tree | 76fb3cf957c9963a720e1845667666b0937e4619 |
| parent | 73a444766e4d1406c194935b54e8167e747b165f |
| parent | 13945548fcd4fe3aab0879b670db1fe8131d8b0e |
| signature |
Some `riscv32-linux` porting work21 files changed, 913 insertions(+), 222 deletions(-)
lib/c.zig+34| ... | @@ -319,6 +319,40 @@ fn clone() callconv(.Naked) void { | ... | @@ -319,6 +319,40 @@ fn clone() callconv(.Naked) void { |
| 319 | \\3: bx r5 | 319 | \\3: bx r5 |
| 320 | ); | 320 | ); |
| 321 | }, | 321 | }, |
| 322 | .riscv32 => { | ||
| 323 | // __clone(func, stack, flags, arg, ptid, tls, ctid) | ||
| 324 | // a0, a1, a2, a3, a4, a5, a6 | ||
| 325 | |||
| 326 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) | ||
| 327 | // a7 a0, a1, a2, a3, a4 | ||
| 328 | asm volatile ( | ||
| 329 | \\ # Save func and arg to stack | ||
| 330 | \\ addi a1, a1, -8 | ||
| 331 | \\ sw a0, 0(a1) | ||
| 332 | \\ sw a3, 4(a1) | ||
| 333 | \\ | ||
| 334 | \\ # Call SYS_clone | ||
| 335 | \\ mv a0, a2 | ||
| 336 | \\ mv a2, a4 | ||
| 337 | \\ mv a3, a5 | ||
| 338 | \\ mv a4, a6 | ||
| 339 | \\ li a7, 220 # SYS_clone | ||
| 340 | \\ ecall | ||
| 341 | \\ | ||
| 342 | \\ beqz a0, 1f | ||
| 343 | \\ # Parent | ||
| 344 | \\ ret | ||
| 345 | \\ | ||
| 346 | \\ # Child | ||
| 347 | \\1: lw a1, 0(sp) | ||
| 348 | \\ lw a0, 4(sp) | ||
| 349 | \\ jalr a1 | ||
| 350 | \\ | ||
| 351 | \\ # Exit | ||
| 352 | \\ li a7, 93 # SYS_exit | ||
| 353 | \\ ecall | ||
| 354 | ); | ||
| 355 | }, | ||
| 322 | .riscv64 => { | 356 | .riscv64 => { |
| 323 | // __clone(func, stack, flags, arg, ptid, tls, ctid) | 357 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 324 | // a0, a1, a2, a3, a4, a5, a6 | 358 | // a0, a1, a2, a3, a4, a5, a6 |
lib/std/Target.zig+10-1| ... | @@ -720,7 +720,16 @@ pub const Abi = enum { | ... | @@ -720,7 +720,16 @@ pub const Abi = enum { |
| 720 | 720 | ||
| 721 | pub inline fn isGnu(abi: Abi) bool { | 721 | pub inline fn isGnu(abi: Abi) bool { |
| 722 | return switch (abi) { | 722 | return switch (abi) { |
| 723 | .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true, | 723 | .gnu, |
| 724 | .gnuabin32, | ||
| 725 | .gnuabi64, | ||
| 726 | .gnueabi, | ||
| 727 | .gnueabihf, | ||
| 728 | .gnuf32, | ||
| 729 | .gnusf, | ||
| 730 | .gnux32, | ||
| 731 | .gnuilp32, | ||
| 732 | => true, | ||
| 724 | else => false, | 733 | else => false, |
| 725 | }; | 734 | }; |
| 726 | } | 735 | } |
lib/std/Thread.zig+31-18| ... | @@ -1082,11 +1082,11 @@ const LinuxThreadImpl = struct { | ... | @@ -1082,11 +1082,11 @@ const LinuxThreadImpl = struct { |
| 1082 | fn freeAndExit(self: *ThreadCompletion) noreturn { | 1082 | fn freeAndExit(self: *ThreadCompletion) noreturn { |
| 1083 | switch (target.cpu.arch) { | 1083 | switch (target.cpu.arch) { |
| 1084 | .x86 => asm volatile ( | 1084 | .x86 => asm volatile ( |
| 1085 | \\ movl $91, %%eax | 1085 | \\ movl $91, %%eax # SYS_munmap |
| 1086 | \\ movl %[ptr], %%ebx | 1086 | \\ movl %[ptr], %%ebx |
| 1087 | \\ movl %[len], %%ecx | 1087 | \\ movl %[len], %%ecx |
| 1088 | \\ int $128 | 1088 | \\ int $128 |
| 1089 | \\ movl $1, %%eax | 1089 | \\ movl $1, %%eax # SYS_exit |
| 1090 | \\ movl $0, %%ebx | 1090 | \\ movl $0, %%ebx |
| 1091 | \\ int $128 | 1091 | \\ int $128 |
| 1092 | : | 1092 | : |
| ... | @@ -1095,9 +1095,9 @@ const LinuxThreadImpl = struct { | ... | @@ -1095,9 +1095,9 @@ const LinuxThreadImpl = struct { |
| 1095 | : "memory" | 1095 | : "memory" |
| 1096 | ), | 1096 | ), |
| 1097 | .x86_64 => asm volatile ( | 1097 | .x86_64 => asm volatile ( |
| 1098 | \\ movq $11, %%rax | 1098 | \\ movq $11, %%rax # SYS_munmap |
| 1099 | \\ syscall | 1099 | \\ syscall |
| 1100 | \\ movq $60, %%rax | 1100 | \\ movq $60, %%rax # SYS_exit |
| 1101 | \\ movq $1, %%rdi | 1101 | \\ movq $1, %%rdi |
| 1102 | \\ syscall | 1102 | \\ syscall |
| 1103 | : | 1103 | : |
| ... | @@ -1105,11 +1105,11 @@ const LinuxThreadImpl = struct { | ... | @@ -1105,11 +1105,11 @@ const LinuxThreadImpl = struct { |
| 1105 | [len] "{rsi}" (self.mapped.len), | 1105 | [len] "{rsi}" (self.mapped.len), |
| 1106 | ), | 1106 | ), |
| 1107 | .arm, .armeb, .thumb, .thumbeb => asm volatile ( | 1107 | .arm, .armeb, .thumb, .thumbeb => asm volatile ( |
| 1108 | \\ mov r7, #91 | 1108 | \\ mov r7, #91 // SYS_munmap |
| 1109 | \\ mov r0, %[ptr] | 1109 | \\ mov r0, %[ptr] |
| 1110 | \\ mov r1, %[len] | 1110 | \\ mov r1, %[len] |
| 1111 | \\ svc 0 | 1111 | \\ svc 0 |
| 1112 | \\ mov r7, #1 | 1112 | \\ mov r7, #1 // SYS_exit |
| 1113 | \\ mov r0, #0 | 1113 | \\ mov r0, #0 |
| 1114 | \\ svc 0 | 1114 | \\ svc 0 |
| 1115 | : | 1115 | : |
| ... | @@ -1118,11 +1118,11 @@ const LinuxThreadImpl = struct { | ... | @@ -1118,11 +1118,11 @@ const LinuxThreadImpl = struct { |
| 1118 | : "memory" | 1118 | : "memory" |
| 1119 | ), | 1119 | ), |
| 1120 | .aarch64, .aarch64_be => asm volatile ( | 1120 | .aarch64, .aarch64_be => asm volatile ( |
| 1121 | \\ mov x8, #215 | 1121 | \\ mov x8, #215 // SYS_munmap |
| 1122 | \\ mov x0, %[ptr] | 1122 | \\ mov x0, %[ptr] |
| 1123 | \\ mov x1, %[len] | 1123 | \\ mov x1, %[len] |
| 1124 | \\ svc 0 | 1124 | \\ svc 0 |
| 1125 | \\ mov x8, #93 | 1125 | \\ mov x8, #93 // SYS_exit |
| 1126 | \\ mov x0, #0 | 1126 | \\ mov x0, #0 |
| 1127 | \\ svc 0 | 1127 | \\ svc 0 |
| 1128 | : | 1128 | : |
| ... | @@ -1132,11 +1132,11 @@ const LinuxThreadImpl = struct { | ... | @@ -1132,11 +1132,11 @@ const LinuxThreadImpl = struct { |
| 1132 | ), | 1132 | ), |
| 1133 | .mips, .mipsel => asm volatile ( | 1133 | .mips, .mipsel => asm volatile ( |
| 1134 | \\ move $sp, $25 | 1134 | \\ move $sp, $25 |
| 1135 | \\ li $2, 4091 | 1135 | \\ li $2, 4091 # SYS_munmap |
| 1136 | \\ move $4, %[ptr] | 1136 | \\ move $4, %[ptr] |
| 1137 | \\ move $5, %[len] | 1137 | \\ move $5, %[len] |
| 1138 | \\ syscall | 1138 | \\ syscall |
| 1139 | \\ li $2, 4001 | 1139 | \\ li $2, 4001 # SYS_exit |
| 1140 | \\ li $4, 0 | 1140 | \\ li $4, 0 |
| 1141 | \\ syscall | 1141 | \\ syscall |
| 1142 | : | 1142 | : |
| ... | @@ -1145,11 +1145,11 @@ const LinuxThreadImpl = struct { | ... | @@ -1145,11 +1145,11 @@ const LinuxThreadImpl = struct { |
| 1145 | : "memory" | 1145 | : "memory" |
| 1146 | ), | 1146 | ), |
| 1147 | .mips64, .mips64el => asm volatile ( | 1147 | .mips64, .mips64el => asm volatile ( |
| 1148 | \\ li $2, 4091 | 1148 | \\ li $2, 4091 # SYS_munmap |
| 1149 | \\ move $4, %[ptr] | 1149 | \\ move $4, %[ptr] |
| 1150 | \\ move $5, %[len] | 1150 | \\ move $5, %[len] |
| 1151 | \\ syscall | 1151 | \\ syscall |
| 1152 | \\ li $2, 4001 | 1152 | \\ li $2, 4001 # SYS_exit |
| 1153 | \\ li $4, 0 | 1153 | \\ li $4, 0 |
| 1154 | \\ syscall | 1154 | \\ syscall |
| 1155 | : | 1155 | : |
| ... | @@ -1158,11 +1158,11 @@ const LinuxThreadImpl = struct { | ... | @@ -1158,11 +1158,11 @@ const LinuxThreadImpl = struct { |
| 1158 | : "memory" | 1158 | : "memory" |
| 1159 | ), | 1159 | ), |
| 1160 | .powerpc, .powerpcle, .powerpc64, .powerpc64le => asm volatile ( | 1160 | .powerpc, .powerpcle, .powerpc64, .powerpc64le => asm volatile ( |
| 1161 | \\ li 0, 91 | 1161 | \\ li 0, 91 # SYS_munmap |
| 1162 | \\ mr %[ptr], 3 | 1162 | \\ mr %[ptr], 3 |
| 1163 | \\ mr %[len], 4 | 1163 | \\ mr %[len], 4 |
| 1164 | \\ sc | 1164 | \\ sc |
| 1165 | \\ li 0, 1 | 1165 | \\ li 0, 1 # SYS_exit |
| 1166 | \\ li 3, 0 | 1166 | \\ li 3, 0 |
| 1167 | \\ sc | 1167 | \\ sc |
| 1168 | \\ blr | 1168 | \\ blr |
| ... | @@ -1171,12 +1171,25 @@ const LinuxThreadImpl = struct { | ... | @@ -1171,12 +1171,25 @@ const LinuxThreadImpl = struct { |
| 1171 | [len] "r" (self.mapped.len), | 1171 | [len] "r" (self.mapped.len), |
| 1172 | : "memory" | 1172 | : "memory" |
| 1173 | ), | 1173 | ), |
| 1174 | .riscv32 => asm volatile ( | ||
| 1175 | \\ li a7, 215 # SYS_munmap | ||
| 1176 | \\ mv a0, %[ptr] | ||
| 1177 | \\ mv a1, %[len] | ||
| 1178 | \\ ecall | ||
| 1179 | \\ li a7, 93 # SYS_exit | ||
| 1180 | \\ mv a0, zero | ||
| 1181 | \\ ecall | ||
| 1182 | : | ||
| 1183 | : [ptr] "r" (@intFromPtr(self.mapped.ptr)), | ||
| 1184 | [len] "r" (self.mapped.len), | ||
| 1185 | : "memory" | ||
| 1186 | ), | ||
| 1174 | .riscv64 => asm volatile ( | 1187 | .riscv64 => asm volatile ( |
| 1175 | \\ li a7, 215 | 1188 | \\ li a7, 215 # SYS_munmap |
| 1176 | \\ mv a0, %[ptr] | 1189 | \\ mv a0, %[ptr] |
| 1177 | \\ mv a1, %[len] | 1190 | \\ mv a1, %[len] |
| 1178 | \\ ecall | 1191 | \\ ecall |
| 1179 | \\ li a7, 93 | 1192 | \\ li a7, 93 # SYS_exit |
| 1180 | \\ mv a0, zero | 1193 | \\ mv a0, zero |
| 1181 | \\ ecall | 1194 | \\ ecall |
| 1182 | : | 1195 | : |
| ... | @@ -1196,14 +1209,14 @@ const LinuxThreadImpl = struct { | ... | @@ -1196,14 +1209,14 @@ const LinuxThreadImpl = struct { |
| 1196 | \\ ba 1b | 1209 | \\ ba 1b |
| 1197 | \\ restore | 1210 | \\ restore |
| 1198 | \\ 2: | 1211 | \\ 2: |
| 1199 | \\ mov 73, %%g1 | 1212 | \\ mov 73, %%g1 # SYS_munmap |
| 1200 | \\ mov %[ptr], %%o0 | 1213 | \\ mov %[ptr], %%o0 |
| 1201 | \\ mov %[len], %%o1 | 1214 | \\ mov %[len], %%o1 |
| 1202 | \\ # Flush register window contents to prevent background | 1215 | \\ # Flush register window contents to prevent background |
| 1203 | \\ # memory access before unmapping the stack. | 1216 | \\ # memory access before unmapping the stack. |
| 1204 | \\ flushw | 1217 | \\ flushw |
| 1205 | \\ t 0x6d | 1218 | \\ t 0x6d |
| 1206 | \\ mov 1, %%g1 | 1219 | \\ mov 1, %%g1 # SYS_exit |
| 1207 | \\ mov 1, %%o0 | 1220 | \\ mov 1, %%o0 |
| 1208 | \\ t 0x6d | 1221 | \\ t 0x6d |
| 1209 | : | 1222 | : |
lib/std/debug.zig+2-1| ... | @@ -747,7 +747,8 @@ pub const StackIterator = struct { | ... | @@ -747,7 +747,8 @@ pub const StackIterator = struct { |
| 747 | .SUCCESS => return bytes_read == buf.len, | 747 | .SUCCESS => return bytes_read == buf.len, |
| 748 | .FAULT => return false, | 748 | .FAULT => return false, |
| 749 | .INVAL, .PERM, .SRCH => unreachable, // own pid is always valid | 749 | .INVAL, .PERM, .SRCH => unreachable, // own pid is always valid |
| 750 | .NOMEM, .NOSYS => {}, | 750 | .NOMEM => {}, |
| 751 | .NOSYS => {}, // QEMU is known not to implement this syscall. | ||
| 751 | else => unreachable, // unexpected | 752 | else => unreachable, // unexpected |
| 752 | } | 753 | } |
| 753 | var path_buf: [ | 754 | var path_buf: [ |
lib/std/fs/Dir.zig+27-2| ... | @@ -334,7 +334,6 @@ pub const Iterator = switch (native_os) { | ... | @@ -334,7 +334,6 @@ pub const Iterator = switch (native_os) { |
| 334 | first_iter: bool, | 334 | first_iter: bool, |
| 335 | 335 | ||
| 336 | const Self = @This(); | 336 | const Self = @This(); |
| 337 | const linux = std.os.linux; | ||
| 338 | 337 | ||
| 339 | pub const Error = IteratorError; | 338 | pub const Error = IteratorError; |
| 340 | 339 | ||
| ... | @@ -2690,8 +2689,33 @@ pub fn statFile(self: Dir, sub_path: []const u8) StatFileError!Stat { | ... | @@ -2690,8 +2689,33 @@ pub fn statFile(self: Dir, sub_path: []const u8) StatFileError!Stat { |
| 2690 | const st = try std.os.fstatat_wasi(self.fd, sub_path, .{ .SYMLINK_FOLLOW = true }); | 2689 | const st = try std.os.fstatat_wasi(self.fd, sub_path, .{ .SYMLINK_FOLLOW = true }); |
| 2691 | return Stat.fromWasi(st); | 2690 | return Stat.fromWasi(st); |
| 2692 | } | 2691 | } |
| 2692 | if (native_os == .linux) { | ||
| 2693 | const sub_path_c = try posix.toPosixPath(sub_path); | ||
| 2694 | var stx = std.mem.zeroes(linux.Statx); | ||
| 2695 | |||
| 2696 | const rc = linux.statx( | ||
| 2697 | self.fd, | ||
| 2698 | &sub_path_c, | ||
| 2699 | linux.AT.NO_AUTOMOUNT, | ||
| 2700 | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME, | ||
| 2701 | &stx, | ||
| 2702 | ); | ||
| 2703 | |||
| 2704 | return switch (linux.E.init(rc)) { | ||
| 2705 | .SUCCESS => Stat.fromLinux(stx), | ||
| 2706 | .ACCES => error.AccessDenied, | ||
| 2707 | .BADF => unreachable, | ||
| 2708 | .FAULT => unreachable, | ||
| 2709 | .INVAL => unreachable, | ||
| 2710 | .LOOP => error.SymLinkLoop, | ||
| 2711 | .NAMETOOLONG => unreachable, // Handled by posix.toPosixPath() above. | ||
| 2712 | .NOENT, .NOTDIR => error.FileNotFound, | ||
| 2713 | .NOMEM => error.SystemResources, | ||
| 2714 | else => |err| posix.unexpectedErrno(err), | ||
| 2715 | }; | ||
| 2716 | } | ||
| 2693 | const st = try posix.fstatat(self.fd, sub_path, 0); | 2717 | const st = try posix.fstatat(self.fd, sub_path, 0); |
| 2694 | return Stat.fromSystem(st); | 2718 | return Stat.fromPosix(st); |
| 2695 | } | 2719 | } |
| 2696 | 2720 | ||
| 2697 | pub const ChmodError = File.ChmodError; | 2721 | pub const ChmodError = File.ChmodError; |
| ... | @@ -2751,6 +2775,7 @@ const path = fs.path; | ... | @@ -2751,6 +2775,7 @@ const path = fs.path; |
| 2751 | const fs = std.fs; | 2775 | const fs = std.fs; |
| 2752 | const Allocator = std.mem.Allocator; | 2776 | const Allocator = std.mem.Allocator; |
| 2753 | const assert = std.debug.assert; | 2777 | const assert = std.debug.assert; |
| 2778 | const linux = std.os.linux; | ||
| 2754 | const windows = std.os.windows; | 2779 | const windows = std.os.windows; |
| 2755 | const native_os = builtin.os.tag; | 2780 | const native_os = builtin.os.tag; |
| 2756 | const have_flock = @TypeOf(posix.system.flock) != void; | 2781 | const have_flock = @TypeOf(posix.system.flock) != void; |
lib/std/fs/File.zig+76-30| ... | @@ -342,7 +342,7 @@ pub fn seekTo(self: File, offset: u64) SeekError!void { | ... | @@ -342,7 +342,7 @@ pub fn seekTo(self: File, offset: u64) SeekError!void { |
| 342 | return posix.lseek_SET(self.handle, offset); | 342 | return posix.lseek_SET(self.handle, offset); |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | pub const GetSeekPosError = posix.SeekError || posix.FStatError; | 345 | pub const GetSeekPosError = posix.SeekError || StatError; |
| 346 | 346 | ||
| 347 | /// TODO: integrate with async I/O | 347 | /// TODO: integrate with async I/O |
| 348 | pub fn getPos(self: File) GetSeekPosError!u64 { | 348 | pub fn getPos(self: File) GetSeekPosError!u64 { |
| ... | @@ -357,7 +357,7 @@ pub fn getEndPos(self: File) GetSeekPosError!u64 { | ... | @@ -357,7 +357,7 @@ pub fn getEndPos(self: File) GetSeekPosError!u64 { |
| 357 | return (try self.stat()).size; | 357 | return (try self.stat()).size; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | pub const ModeError = posix.FStatError; | 360 | pub const ModeError = StatError; |
| 361 | 361 | ||
| 362 | /// TODO: integrate with async I/O | 362 | /// TODO: integrate with async I/O |
| 363 | pub fn mode(self: File) ModeError!Mode { | 363 | pub fn mode(self: File) ModeError!Mode { |
| ... | @@ -392,7 +392,7 @@ pub const Stat = struct { | ... | @@ -392,7 +392,7 @@ pub const Stat = struct { |
| 392 | /// Last status/metadata change time in nanoseconds, relative to UTC 1970-01-01. | 392 | /// Last status/metadata change time in nanoseconds, relative to UTC 1970-01-01. |
| 393 | ctime: i128, | 393 | ctime: i128, |
| 394 | 394 | ||
| 395 | pub fn fromSystem(st: posix.Stat) Stat { | 395 | pub fn fromPosix(st: posix.Stat) Stat { |
| 396 | const atime = st.atime(); | 396 | const atime = st.atime(); |
| 397 | const mtime = st.mtime(); | 397 | const mtime = st.mtime(); |
| 398 | const ctime = st.ctime(); | 398 | const ctime = st.ctime(); |
| ... | @@ -426,6 +426,31 @@ pub const Stat = struct { | ... | @@ -426,6 +426,31 @@ pub const Stat = struct { |
| 426 | }; | 426 | }; |
| 427 | } | 427 | } |
| 428 | 428 | ||
| 429 | pub fn fromLinux(stx: linux.Statx) Stat { | ||
| 430 | const atime = stx.atime; | ||
| 431 | const mtime = stx.mtime; | ||
| 432 | const ctime = stx.ctime; | ||
| 433 | |||
| 434 | return .{ | ||
| 435 | .inode = stx.ino, | ||
| 436 | .size = stx.size, | ||
| 437 | .mode = stx.mode, | ||
| 438 | .kind = switch (stx.mode & linux.S.IFMT) { | ||
| 439 | linux.S.IFDIR => .directory, | ||
| 440 | linux.S.IFCHR => .character_device, | ||
| 441 | linux.S.IFBLK => .block_device, | ||
| 442 | linux.S.IFREG => .file, | ||
| 443 | linux.S.IFIFO => .named_pipe, | ||
| 444 | linux.S.IFLNK => .sym_link, | ||
| 445 | linux.S.IFSOCK => .unix_domain_socket, | ||
| 446 | else => .unknown, | ||
| 447 | }, | ||
| 448 | .atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec, | ||
| 449 | .mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec, | ||
| 450 | .ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec, | ||
| 451 | }; | ||
| 452 | } | ||
| 453 | |||
| 429 | pub fn fromWasi(st: std.os.wasi.filestat_t) Stat { | 454 | pub fn fromWasi(st: std.os.wasi.filestat_t) Stat { |
| 430 | return .{ | 455 | return .{ |
| 431 | .inode = st.ino, | 456 | .inode = st.ino, |
| ... | @@ -502,8 +527,34 @@ pub fn stat(self: File) StatError!Stat { | ... | @@ -502,8 +527,34 @@ pub fn stat(self: File) StatError!Stat { |
| 502 | return Stat.fromWasi(st); | 527 | return Stat.fromWasi(st); |
| 503 | } | 528 | } |
| 504 | 529 | ||
| 530 | if (builtin.os.tag == .linux) { | ||
| 531 | var stx = std.mem.zeroes(linux.Statx); | ||
| 532 | |||
| 533 | const rc = linux.statx( | ||
| 534 | self.handle, | ||
| 535 | "", | ||
| 536 | linux.AT.EMPTY_PATH, | ||
| 537 | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME, | ||
| 538 | &stx, | ||
| 539 | ); | ||
| 540 | |||
| 541 | return switch (linux.E.init(rc)) { | ||
| 542 | .SUCCESS => Stat.fromLinux(stx), | ||
| 543 | .ACCES => unreachable, | ||
| 544 | .BADF => unreachable, | ||
| 545 | .FAULT => unreachable, | ||
| 546 | .INVAL => unreachable, | ||
| 547 | .LOOP => unreachable, | ||
| 548 | .NAMETOOLONG => unreachable, | ||
| 549 | .NOENT => unreachable, | ||
| 550 | .NOMEM => error.SystemResources, | ||
| 551 | .NOTDIR => unreachable, | ||
| 552 | else => |err| posix.unexpectedErrno(err), | ||
| 553 | }; | ||
| 554 | } | ||
| 555 | |||
| 505 | const st = try posix.fstat(self.handle); | 556 | const st = try posix.fstat(self.handle); |
| 506 | return Stat.fromSystem(st); | 557 | return Stat.fromPosix(st); |
| 507 | } | 558 | } |
| 508 | 559 | ||
| 509 | pub const ChmodError = posix.FChmodError; | 560 | pub const ChmodError = posix.FChmodError; |
| ... | @@ -731,7 +782,7 @@ pub const Metadata = struct { | ... | @@ -731,7 +782,7 @@ pub const Metadata = struct { |
| 731 | 782 | ||
| 732 | /// Returns the time the file was created in nanoseconds since UTC 1970-01-01 | 783 | /// Returns the time the file was created in nanoseconds since UTC 1970-01-01 |
| 733 | /// On Windows, this cannot return null | 784 | /// On Windows, this cannot return null |
| 734 | /// On Linux, this returns null if the filesystem does not support creation times, or if the kernel is older than 4.11 | 785 | /// On Linux, this returns null if the filesystem does not support creation times |
| 735 | /// On Unices, this returns null if the filesystem or OS does not support creation times | 786 | /// On Unices, this returns null if the filesystem or OS does not support creation times |
| 736 | /// On MacOS, this returns the ctime if the filesystem does not support creation times; this is insanity, and yet another reason to hate on Apple | 787 | /// On MacOS, this returns the ctime if the filesystem does not support creation times; this is insanity, and yet another reason to hate on Apple |
| 737 | pub fn created(self: Self) ?i128 { | 788 | pub fn created(self: Self) ?i128 { |
| ... | @@ -822,7 +873,6 @@ pub const MetadataUnix = struct { | ... | @@ -822,7 +873,6 @@ pub const MetadataUnix = struct { |
| 822 | }; | 873 | }; |
| 823 | 874 | ||
| 824 | /// `MetadataUnix`, but using Linux's `statx` syscall. | 875 | /// `MetadataUnix`, but using Linux's `statx` syscall. |
| 825 | /// On Linux versions below 4.11, `statx` will be filled with data from stat. | ||
| 826 | pub const MetadataLinux = struct { | 876 | pub const MetadataLinux = struct { |
| 827 | statx: std.os.linux.Statx, | 877 | statx: std.os.linux.Statx, |
| 828 | 878 | ||
| ... | @@ -1010,34 +1060,29 @@ pub fn metadata(self: File) MetadataError!Metadata { | ... | @@ -1010,34 +1060,29 @@ pub fn metadata(self: File) MetadataError!Metadata { |
| 1010 | }; | 1060 | }; |
| 1011 | }, | 1061 | }, |
| 1012 | .linux => blk: { | 1062 | .linux => blk: { |
| 1013 | const l = std.os.linux; | 1063 | var stx = std.mem.zeroes(linux.Statx); |
| 1014 | var stx = std.mem.zeroes(l.Statx); | 1064 | |
| 1015 | const rcx = l.statx(self.handle, "\x00", l.AT.EMPTY_PATH, l.STATX_TYPE | | 1065 | // We are gathering information for Metadata, which is meant to contain all the |
| 1016 | l.STATX_MODE | l.STATX_ATIME | l.STATX_MTIME | l.STATX_BTIME, &stx); | 1066 | // native OS information about the file, so use all known flags. |
| 1017 | 1067 | const rc = linux.statx( | |
| 1018 | switch (posix.errno(rcx)) { | 1068 | self.handle, |
| 1069 | "", | ||
| 1070 | linux.AT.EMPTY_PATH, | ||
| 1071 | linux.STATX_BASIC_STATS | linux.STATX_BTIME, | ||
| 1072 | &stx, | ||
| 1073 | ); | ||
| 1074 | |||
| 1075 | switch (posix.errno(rc)) { | ||
| 1019 | .SUCCESS => {}, | 1076 | .SUCCESS => {}, |
| 1020 | // NOSYS happens when `statx` is unsupported, which is the case on kernel versions before 4.11 | 1077 | .ACCES => unreachable, |
| 1021 | // Here, we call `fstat` and fill `stx` with the data we need | ||
| 1022 | .NOSYS => { | ||
| 1023 | const st = try posix.fstat(self.handle); | ||
| 1024 | |||
| 1025 | stx.mode = @as(u16, @intCast(st.mode)); | ||
| 1026 | |||
| 1027 | // Hacky conversion from timespec to statx_timestamp | ||
| 1028 | stx.atime = std.mem.zeroes(l.statx_timestamp); | ||
| 1029 | stx.atime.sec = st.atim.sec; | ||
| 1030 | stx.atime.nsec = @as(u32, @intCast(st.atim.nsec)); // Guaranteed to succeed (nsec is always below 10^9) | ||
| 1031 | |||
| 1032 | stx.mtime = std.mem.zeroes(l.statx_timestamp); | ||
| 1033 | stx.mtime.sec = st.mtim.sec; | ||
| 1034 | stx.mtime.nsec = @as(u32, @intCast(st.mtim.nsec)); | ||
| 1035 | |||
| 1036 | stx.mask = l.STATX_BASIC_STATS | l.STATX_MTIME; | ||
| 1037 | }, | ||
| 1038 | .BADF => unreachable, | 1078 | .BADF => unreachable, |
| 1039 | .FAULT => unreachable, | 1079 | .FAULT => unreachable, |
| 1080 | .INVAL => unreachable, | ||
| 1081 | .LOOP => unreachable, | ||
| 1082 | .NAMETOOLONG => unreachable, | ||
| 1083 | .NOENT => unreachable, | ||
| 1040 | .NOMEM => return error.SystemResources, | 1084 | .NOMEM => return error.SystemResources, |
| 1085 | .NOTDIR => unreachable, | ||
| 1041 | else => |err| return posix.unexpectedErrno(err), | 1086 | else => |err| return posix.unexpectedErrno(err), |
| 1042 | } | 1087 | } |
| 1043 | 1088 | ||
| ... | @@ -1731,6 +1776,7 @@ const posix = std.posix; | ... | @@ -1731,6 +1776,7 @@ const posix = std.posix; |
| 1731 | const io = std.io; | 1776 | const io = std.io; |
| 1732 | const math = std.math; | 1777 | const math = std.math; |
| 1733 | const assert = std.debug.assert; | 1778 | const assert = std.debug.assert; |
| 1779 | const linux = std.os.linux; | ||
| 1734 | const windows = std.os.windows; | 1780 | const windows = std.os.windows; |
| 1735 | const Os = std.builtin.Os; | 1781 | const Os = std.builtin.Os; |
| 1736 | const maxInt = std.math.maxInt; | 1782 | const maxInt = std.math.maxInt; |
lib/std/os/linux.zig+61-37| ... | @@ -39,6 +39,7 @@ const arch_bits = switch (native_arch) { | ... | @@ -39,6 +39,7 @@ const arch_bits = switch (native_arch) { |
| 39 | .x86_64 => @import("linux/x86_64.zig"), | 39 | .x86_64 => @import("linux/x86_64.zig"), |
| 40 | .aarch64, .aarch64_be => @import("linux/arm64.zig"), | 40 | .aarch64, .aarch64_be => @import("linux/arm64.zig"), |
| 41 | .arm, .armeb, .thumb, .thumbeb => @import("linux/arm-eabi.zig"), | 41 | .arm, .armeb, .thumb, .thumbeb => @import("linux/arm-eabi.zig"), |
| 42 | .riscv32 => @import("linux/riscv32.zig"), | ||
| 42 | .riscv64 => @import("linux/riscv64.zig"), | 43 | .riscv64 => @import("linux/riscv64.zig"), |
| 43 | .sparc64 => @import("linux/sparc64.zig"), | 44 | .sparc64 => @import("linux/sparc64.zig"), |
| 44 | .mips, .mipsel => @import("linux/mips.zig"), | 45 | .mips, .mipsel => @import("linux/mips.zig"), |
| ... | @@ -104,6 +105,7 @@ pub const SYS = switch (@import("builtin").cpu.arch) { | ... | @@ -104,6 +105,7 @@ pub const SYS = switch (@import("builtin").cpu.arch) { |
| 104 | .x86_64 => syscalls.X64, | 105 | .x86_64 => syscalls.X64, |
| 105 | .aarch64, .aarch64_be => syscalls.Arm64, | 106 | .aarch64, .aarch64_be => syscalls.Arm64, |
| 106 | .arm, .armeb, .thumb, .thumbeb => syscalls.Arm, | 107 | .arm, .armeb, .thumb, .thumbeb => syscalls.Arm, |
| 108 | .riscv32 => syscalls.RiscV32, | ||
| 107 | .riscv64 => syscalls.RiscV64, | 109 | .riscv64 => syscalls.RiscV64, |
| 108 | .sparc64 => syscalls.Sparc64, | 110 | .sparc64 => syscalls.Sparc64, |
| 109 | .mips, .mipsel => syscalls.Mips, | 111 | .mips, .mipsel => syscalls.Mips, |
| ... | @@ -163,7 +165,7 @@ pub const MAP = switch (native_arch) { | ... | @@ -163,7 +165,7 @@ pub const MAP = switch (native_arch) { |
| 163 | UNINITIALIZED: bool = false, | 165 | UNINITIALIZED: bool = false, |
| 164 | _: u5 = 0, | 166 | _: u5 = 0, |
| 165 | }, | 167 | }, |
| 166 | .riscv64 => packed struct(u32) { | 168 | .riscv32, .riscv64 => packed struct(u32) { |
| 167 | TYPE: MAP_TYPE, | 169 | TYPE: MAP_TYPE, |
| 168 | FIXED: bool = false, | 170 | FIXED: bool = false, |
| 169 | ANONYMOUS: bool = false, | 171 | ANONYMOUS: bool = false, |
| ... | @@ -268,7 +270,7 @@ pub const O = switch (native_arch) { | ... | @@ -268,7 +270,7 @@ pub const O = switch (native_arch) { |
| 268 | TMPFILE: bool = false, | 270 | TMPFILE: bool = false, |
| 269 | _: u9 = 0, | 271 | _: u9 = 0, |
| 270 | }, | 272 | }, |
| 271 | .x86, .riscv64 => packed struct(u32) { | 273 | .x86, .riscv32, .riscv64 => packed struct(u32) { |
| 272 | ACCMODE: ACCMODE = .RDONLY, | 274 | ACCMODE: ACCMODE = .RDONLY, |
| 273 | _2: u4 = 0, | 275 | _2: u4 = 0, |
| 274 | CREAT: bool = false, | 276 | CREAT: bool = false, |
| ... | @@ -474,7 +476,7 @@ pub fn dup2(old: i32, new: i32) usize { | ... | @@ -474,7 +476,7 @@ pub fn dup2(old: i32, new: i32) usize { |
| 474 | } else { | 476 | } else { |
| 475 | if (old == new) { | 477 | if (old == new) { |
| 476 | if (std.debug.runtime_safety) { | 478 | if (std.debug.runtime_safety) { |
| 477 | const rc = syscall2(.fcntl, @as(usize, @bitCast(@as(isize, old))), F.GETFD); | 479 | const rc = fcntl(F.GETFD, @as(fd_t, old), 0); |
| 478 | if (@as(isize, @bitCast(rc)) < 0) return rc; | 480 | if (@as(isize, @bitCast(rc)) < 0) return rc; |
| 479 | } | 481 | } |
| 480 | return @as(usize, @intCast(old)); | 482 | return @as(usize, @intCast(old)); |
| ... | @@ -1211,7 +1213,7 @@ pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize { | ... | @@ -1211,7 +1213,7 @@ pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize { |
| 1211 | // NOTE: The offset parameter splitting is independent from the target | 1213 | // NOTE: The offset parameter splitting is independent from the target |
| 1212 | // endianness. | 1214 | // endianness. |
| 1213 | return syscall5( | 1215 | return syscall5( |
| 1214 | ._llseek, | 1216 | .llseek, |
| 1215 | @as(usize, @bitCast(@as(isize, fd))), | 1217 | @as(usize, @bitCast(@as(isize, fd))), |
| 1216 | @as(usize, @truncate(offset >> 32)), | 1218 | @as(usize, @truncate(offset >> 32)), |
| 1217 | @as(usize, @truncate(offset)), | 1219 | @as(usize, @truncate(offset)), |
| ... | @@ -1370,7 +1372,11 @@ pub fn waitid(id_type: P, id: i32, infop: *siginfo_t, flags: u32) usize { | ... | @@ -1370,7 +1372,11 @@ pub fn waitid(id_type: P, id: i32, infop: *siginfo_t, flags: u32) usize { |
| 1370 | } | 1372 | } |
| 1371 | 1373 | ||
| 1372 | pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) usize { | 1374 | pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) usize { |
| 1373 | return syscall3(.fcntl, @as(usize, @bitCast(@as(isize, fd))), @as(usize, @bitCast(@as(isize, cmd))), arg); | 1375 | if (@hasField(SYS, "fcntl64")) { |
| 1376 | return syscall3(.fcntl64, @as(usize, @bitCast(@as(isize, fd))), @as(usize, @bitCast(@as(isize, cmd))), arg); | ||
| 1377 | } else { | ||
| 1378 | return syscall3(.fcntl, @as(usize, @bitCast(@as(isize, fd))), @as(usize, @bitCast(@as(isize, cmd))), arg); | ||
| 1379 | } | ||
| 1374 | } | 1380 | } |
| 1375 | 1381 | ||
| 1376 | pub fn flock(fd: fd_t, operation: i32) usize { | 1382 | pub fn flock(fd: fd_t, operation: i32) usize { |
| ... | @@ -1836,7 +1842,11 @@ pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flag | ... | @@ -1836,7 +1842,11 @@ pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flag |
| 1836 | } | 1842 | } |
| 1837 | 1843 | ||
| 1838 | pub fn fstat(fd: i32, stat_buf: *Stat) usize { | 1844 | pub fn fstat(fd: i32, stat_buf: *Stat) usize { |
| 1839 | if (@hasField(SYS, "fstat64")) { | 1845 | if (native_arch == .riscv32) { |
| 1846 | // riscv32 has made the interesting decision to not implement some of | ||
| 1847 | // the older stat syscalls, including this one. | ||
| 1848 | @compileError("No fstat syscall on this architecture."); | ||
| 1849 | } else if (@hasField(SYS, "fstat64")) { | ||
| 1840 | return syscall2(.fstat64, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(stat_buf)); | 1850 | return syscall2(.fstat64, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(stat_buf)); |
| 1841 | } else { | 1851 | } else { |
| 1842 | return syscall2(.fstat, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(stat_buf)); | 1852 | return syscall2(.fstat, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(stat_buf)); |
| ... | @@ -1844,7 +1854,11 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize { | ... | @@ -1844,7 +1854,11 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize { |
| 1844 | } | 1854 | } |
| 1845 | 1855 | ||
| 1846 | pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize { | 1856 | pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize { |
| 1847 | if (@hasField(SYS, "stat64")) { | 1857 | if (native_arch == .riscv32) { |
| 1858 | // riscv32 has made the interesting decision to not implement some of | ||
| 1859 | // the older stat syscalls, including this one. | ||
| 1860 | @compileError("No stat syscall on this architecture."); | ||
| 1861 | } else if (@hasField(SYS, "stat64")) { | ||
| 1848 | return syscall2(.stat64, @intFromPtr(pathname), @intFromPtr(statbuf)); | 1862 | return syscall2(.stat64, @intFromPtr(pathname), @intFromPtr(statbuf)); |
| 1849 | } else { | 1863 | } else { |
| 1850 | return syscall2(.stat, @intFromPtr(pathname), @intFromPtr(statbuf)); | 1864 | return syscall2(.stat, @intFromPtr(pathname), @intFromPtr(statbuf)); |
| ... | @@ -1852,7 +1866,11 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize { | ... | @@ -1852,7 +1866,11 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize { |
| 1852 | } | 1866 | } |
| 1853 | 1867 | ||
| 1854 | pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize { | 1868 | pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize { |
| 1855 | if (@hasField(SYS, "lstat64")) { | 1869 | if (native_arch == .riscv32) { |
| 1870 | // riscv32 has made the interesting decision to not implement some of | ||
| 1871 | // the older stat syscalls, including this one. | ||
| 1872 | @compileError("No lstat syscall on this architecture."); | ||
| 1873 | } else if (@hasField(SYS, "lstat64")) { | ||
| 1856 | return syscall2(.lstat64, @intFromPtr(pathname), @intFromPtr(statbuf)); | 1874 | return syscall2(.lstat64, @intFromPtr(pathname), @intFromPtr(statbuf)); |
| 1857 | } else { | 1875 | } else { |
| 1858 | return syscall2(.lstat, @intFromPtr(pathname), @intFromPtr(statbuf)); | 1876 | return syscall2(.lstat, @intFromPtr(pathname), @intFromPtr(statbuf)); |
| ... | @@ -1860,7 +1878,11 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize { | ... | @@ -1860,7 +1878,11 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize { |
| 1860 | } | 1878 | } |
| 1861 | 1879 | ||
| 1862 | pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usize { | 1880 | pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usize { |
| 1863 | if (@hasField(SYS, "fstatat64")) { | 1881 | if (native_arch == .riscv32) { |
| 1882 | // riscv32 has made the interesting decision to not implement some of | ||
| 1883 | // the older stat syscalls, including this one. | ||
| 1884 | @compileError("No fstatat syscall on this architecture."); | ||
| 1885 | } else if (@hasField(SYS, "fstatat64")) { | ||
| 1864 | return syscall4(.fstatat64, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), flags); | 1886 | return syscall4(.fstatat64, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), flags); |
| 1865 | } else { | 1887 | } else { |
| 1866 | return syscall4(.fstatat, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), flags); | 1888 | return syscall4(.fstatat, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), flags); |
| ... | @@ -1868,17 +1890,14 @@ pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usi | ... | @@ -1868,17 +1890,14 @@ pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usi |
| 1868 | } | 1890 | } |
| 1869 | 1891 | ||
| 1870 | pub fn statx(dirfd: i32, path: [*:0]const u8, flags: u32, mask: u32, statx_buf: *Statx) usize { | 1892 | pub fn statx(dirfd: i32, path: [*:0]const u8, flags: u32, mask: u32, statx_buf: *Statx) usize { |
| 1871 | if (@hasField(SYS, "statx")) { | 1893 | return syscall5( |
| 1872 | return syscall5( | 1894 | .statx, |
| 1873 | .statx, | 1895 | @as(usize, @bitCast(@as(isize, dirfd))), |
| 1874 | @as(usize, @bitCast(@as(isize, dirfd))), | 1896 | @intFromPtr(path), |
| 1875 | @intFromPtr(path), | 1897 | flags, |
| 1876 | flags, | 1898 | mask, |
| 1877 | mask, | 1899 | @intFromPtr(statx_buf), |
| 1878 | @intFromPtr(statx_buf), | 1900 | ); |
| 1879 | ); | ||
| 1880 | } | ||
| 1881 | return @as(usize, @bitCast(-@as(isize, @intFromEnum(E.NOSYS)))); | ||
| 1882 | } | 1901 | } |
| 1883 | 1902 | ||
| 1884 | pub fn listxattr(path: [*:0]const u8, list: [*]u8, size: usize) usize { | 1903 | pub fn listxattr(path: [*:0]const u8, list: [*]u8, size: usize) usize { |
| ... | @@ -2198,40 +2217,40 @@ pub fn process_vm_writev(pid: pid_t, local: []const iovec_const, remote: []const | ... | @@ -2198,40 +2217,40 @@ pub fn process_vm_writev(pid: pid_t, local: []const iovec_const, remote: []const |
| 2198 | } | 2217 | } |
| 2199 | 2218 | ||
| 2200 | pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize { | 2219 | pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize { |
| 2201 | if (comptime builtin.cpu.arch.isMIPS()) { | 2220 | if (comptime native_arch.isARM() or native_arch.isPPC()) { |
| 2202 | // MIPS requires a 7 argument syscall | 2221 | // These architectures reorder the arguments so that a register is not skipped to align the |
| 2222 | // register number that `offset` is passed in. | ||
| 2203 | 2223 | ||
| 2204 | const offset_halves = splitValue64(offset); | 2224 | const offset_halves = splitValue64(offset); |
| 2205 | const length_halves = splitValue64(len); | 2225 | const length_halves = splitValue64(len); |
| 2206 | 2226 | ||
| 2207 | return syscall7( | 2227 | return syscall6( |
| 2208 | .fadvise64, | 2228 | .fadvise64_64, |
| 2209 | @as(usize, @bitCast(@as(isize, fd))), | 2229 | @as(usize, @bitCast(@as(isize, fd))), |
| 2210 | 0, | 2230 | advice, |
| 2211 | offset_halves[0], | 2231 | offset_halves[0], |
| 2212 | offset_halves[1], | 2232 | offset_halves[1], |
| 2213 | length_halves[0], | 2233 | length_halves[0], |
| 2214 | length_halves[1], | 2234 | length_halves[1], |
| 2215 | advice, | ||
| 2216 | ); | 2235 | ); |
| 2217 | } else if (comptime builtin.cpu.arch.isARM()) { | 2236 | } else if (comptime native_arch == .mips or native_arch == .mipsel) { |
| 2218 | // ARM reorders the arguments | 2237 | // MIPS O32 does not deal with the register alignment issue, so pass a dummy value. |
| 2219 | 2238 | ||
| 2220 | const offset_halves = splitValue64(offset); | 2239 | const offset_halves = splitValue64(offset); |
| 2221 | const length_halves = splitValue64(len); | 2240 | const length_halves = splitValue64(len); |
| 2222 | 2241 | ||
| 2223 | return syscall6( | 2242 | return syscall7( |
| 2224 | .fadvise64_64, | 2243 | .fadvise64, |
| 2225 | @as(usize, @bitCast(@as(isize, fd))), | 2244 | @as(usize, @bitCast(@as(isize, fd))), |
| 2226 | advice, | 2245 | 0, |
| 2227 | offset_halves[0], | 2246 | offset_halves[0], |
| 2228 | offset_halves[1], | 2247 | offset_halves[1], |
| 2229 | length_halves[0], | 2248 | length_halves[0], |
| 2230 | length_halves[1], | 2249 | length_halves[1], |
| 2250 | advice, | ||
| 2231 | ); | 2251 | ); |
| 2232 | } else if (@hasField(SYS, "fadvise64_64") and usize_bits != 64) { | 2252 | } else if (comptime usize_bits < 64) { |
| 2233 | // The extra usize check is needed to avoid SPARC64 because it provides both | 2253 | // Other 32-bit architectures do not require register alignment. |
| 2234 | // fadvise64 and fadvise64_64 but the latter behaves differently than other platforms. | ||
| 2235 | 2254 | ||
| 2236 | const offset_halves = splitValue64(offset); | 2255 | const offset_halves = splitValue64(offset); |
| 2237 | const length_halves = splitValue64(len); | 2256 | const length_halves = splitValue64(len); |
| ... | @@ -2246,8 +2265,11 @@ pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize { | ... | @@ -2246,8 +2265,11 @@ pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize { |
| 2246 | advice, | 2265 | advice, |
| 2247 | ); | 2266 | ); |
| 2248 | } else { | 2267 | } else { |
| 2268 | // On 64-bit architectures, fadvise64_64 and fadvise64 are the same. Generally, older ports | ||
| 2269 | // call it fadvise64 (x86, PowerPC, etc), while newer ports call it fadvise64_64 (RISC-V, | ||
| 2270 | // LoongArch, etc). SPARC is the odd one out because it has both. | ||
| 2249 | return syscall4( | 2271 | return syscall4( |
| 2250 | .fadvise64, | 2272 | if (@hasField(SYS, "fadvise64_64")) .fadvise64_64 else .fadvise64, |
| 2251 | @as(usize, @bitCast(@as(isize, fd))), | 2273 | @as(usize, @bitCast(@as(isize, fd))), |
| 2252 | @as(usize, @bitCast(offset)), | 2274 | @as(usize, @bitCast(offset)), |
| 2253 | @as(usize, @bitCast(len)), | 2275 | @as(usize, @bitCast(len)), |
| ... | @@ -6295,12 +6317,13 @@ pub const POSIX_FADV = switch (native_arch) { | ... | @@ -6295,12 +6317,13 @@ pub const POSIX_FADV = switch (native_arch) { |
| 6295 | }; | 6317 | }; |
| 6296 | 6318 | ||
| 6297 | /// The timespec struct used by the kernel. | 6319 | /// The timespec struct used by the kernel. |
| 6298 | pub const kernel_timespec = if (@sizeOf(usize) >= 8) timespec else extern struct { | 6320 | pub const kernel_timespec = extern struct { |
| 6299 | sec: i64, | 6321 | sec: i64, |
| 6300 | nsec: i64, | 6322 | nsec: i64, |
| 6301 | }; | 6323 | }; |
| 6302 | 6324 | ||
| 6303 | pub const timespec = extern struct { | 6325 | // https://github.com/ziglang/zig/issues/4726#issuecomment-2190337877 |
| 6326 | pub const timespec = if (!builtin.link_libc and native_arch == .riscv32) kernel_timespec else extern struct { | ||
| 6304 | sec: isize, | 6327 | sec: isize, |
| 6305 | nsec: isize, | 6328 | nsec: isize, |
| 6306 | }; | 6329 | }; |
| ... | @@ -7338,6 +7361,7 @@ pub const AUDIT = struct { | ... | @@ -7338,6 +7361,7 @@ pub const AUDIT = struct { |
| 7338 | .x86_64 => .X86_64, | 7361 | .x86_64 => .X86_64, |
| 7339 | .aarch64 => .AARCH64, | 7362 | .aarch64 => .AARCH64, |
| 7340 | .arm, .thumb => .ARM, | 7363 | .arm, .thumb => .ARM, |
| 7364 | .riscv32 => .RISCV32, | ||
| 7341 | .riscv64 => .RISCV64, | 7365 | .riscv64 => .RISCV64, |
| 7342 | .sparc64 => .SPARC64, | 7366 | .sparc64 => .SPARC64, |
| 7343 | .mips => .MIPS, | 7367 | .mips => .MIPS, |
lib/std/os/linux/riscv32.zig created+197| ... | @@ -0,0 +1,197 @@ | ||
| 1 | const std = @import("../../std.zig"); | ||
| 2 | const iovec = std.posix.iovec; | ||
| 3 | const iovec_const = std.posix.iovec_const; | ||
| 4 | const linux = std.os.linux; | ||
| 5 | const SYS = linux.SYS; | ||
| 6 | const uid_t = std.os.linux.uid_t; | ||
| 7 | const gid_t = std.os.linux.gid_t; | ||
| 8 | const pid_t = std.os.linux.pid_t; | ||
| 9 | const sockaddr = linux.sockaddr; | ||
| 10 | const socklen_t = linux.socklen_t; | ||
| 11 | const timespec = std.os.linux.timespec; | ||
| 12 | |||
| 13 | pub fn syscall0(number: SYS) usize { | ||
| 14 | return asm volatile ("ecall" | ||
| 15 | : [ret] "={x10}" (-> usize), | ||
| 16 | : [number] "{x17}" (@intFromEnum(number)), | ||
| 17 | : "memory" | ||
| 18 | ); | ||
| 19 | } | ||
| 20 | |||
| 21 | pub fn syscall1(number: SYS, arg1: usize) usize { | ||
| 22 | return asm volatile ("ecall" | ||
| 23 | : [ret] "={x10}" (-> usize), | ||
| 24 | : [number] "{x17}" (@intFromEnum(number)), | ||
| 25 | [arg1] "{x10}" (arg1), | ||
| 26 | : "memory" | ||
| 27 | ); | ||
| 28 | } | ||
| 29 | |||
| 30 | pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { | ||
| 31 | return asm volatile ("ecall" | ||
| 32 | : [ret] "={x10}" (-> usize), | ||
| 33 | : [number] "{x17}" (@intFromEnum(number)), | ||
| 34 | [arg1] "{x10}" (arg1), | ||
| 35 | [arg2] "{x11}" (arg2), | ||
| 36 | : "memory" | ||
| 37 | ); | ||
| 38 | } | ||
| 39 | |||
| 40 | pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { | ||
| 41 | return asm volatile ("ecall" | ||
| 42 | : [ret] "={x10}" (-> usize), | ||
| 43 | : [number] "{x17}" (@intFromEnum(number)), | ||
| 44 | [arg1] "{x10}" (arg1), | ||
| 45 | [arg2] "{x11}" (arg2), | ||
| 46 | [arg3] "{x12}" (arg3), | ||
| 47 | : "memory" | ||
| 48 | ); | ||
| 49 | } | ||
| 50 | |||
| 51 | pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { | ||
| 52 | return asm volatile ("ecall" | ||
| 53 | : [ret] "={x10}" (-> usize), | ||
| 54 | : [number] "{x17}" (@intFromEnum(number)), | ||
| 55 | [arg1] "{x10}" (arg1), | ||
| 56 | [arg2] "{x11}" (arg2), | ||
| 57 | [arg3] "{x12}" (arg3), | ||
| 58 | [arg4] "{x13}" (arg4), | ||
| 59 | : "memory" | ||
| 60 | ); | ||
| 61 | } | ||
| 62 | |||
| 63 | pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { | ||
| 64 | return asm volatile ("ecall" | ||
| 65 | : [ret] "={x10}" (-> usize), | ||
| 66 | : [number] "{x17}" (@intFromEnum(number)), | ||
| 67 | [arg1] "{x10}" (arg1), | ||
| 68 | [arg2] "{x11}" (arg2), | ||
| 69 | [arg3] "{x12}" (arg3), | ||
| 70 | [arg4] "{x13}" (arg4), | ||
| 71 | [arg5] "{x14}" (arg5), | ||
| 72 | : "memory" | ||
| 73 | ); | ||
| 74 | } | ||
| 75 | |||
| 76 | pub fn syscall6( | ||
| 77 | number: SYS, | ||
| 78 | arg1: usize, | ||
| 79 | arg2: usize, | ||
| 80 | arg3: usize, | ||
| 81 | arg4: usize, | ||
| 82 | arg5: usize, | ||
| 83 | arg6: usize, | ||
| 84 | ) usize { | ||
| 85 | return asm volatile ("ecall" | ||
| 86 | : [ret] "={x10}" (-> usize), | ||
| 87 | : [number] "{x17}" (@intFromEnum(number)), | ||
| 88 | [arg1] "{x10}" (arg1), | ||
| 89 | [arg2] "{x11}" (arg2), | ||
| 90 | [arg3] "{x12}" (arg3), | ||
| 91 | [arg4] "{x13}" (arg4), | ||
| 92 | [arg5] "{x14}" (arg5), | ||
| 93 | [arg6] "{x15}" (arg6), | ||
| 94 | : "memory" | ||
| 95 | ); | ||
| 96 | } | ||
| 97 | |||
| 98 | const CloneFn = *const fn (arg: usize) callconv(.C) u8; | ||
| 99 | |||
| 100 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | ||
| 101 | |||
| 102 | pub const restore = restore_rt; | ||
| 103 | |||
| 104 | pub fn restore_rt() callconv(.Naked) noreturn { | ||
| 105 | asm volatile ( | ||
| 106 | \\ ecall | ||
| 107 | : | ||
| 108 | : [number] "{x17}" (@intFromEnum(SYS.rt_sigreturn)), | ||
| 109 | : "memory" | ||
| 110 | ); | ||
| 111 | } | ||
| 112 | |||
| 113 | pub const F = struct { | ||
| 114 | pub const DUPFD = 0; | ||
| 115 | pub const GETFD = 1; | ||
| 116 | pub const SETFD = 2; | ||
| 117 | pub const GETFL = 3; | ||
| 118 | pub const SETFL = 4; | ||
| 119 | pub const GETLK = 5; | ||
| 120 | pub const SETLK = 6; | ||
| 121 | pub const SETLKW = 7; | ||
| 122 | pub const SETOWN = 8; | ||
| 123 | pub const GETOWN = 9; | ||
| 124 | pub const SETSIG = 10; | ||
| 125 | pub const GETSIG = 11; | ||
| 126 | |||
| 127 | pub const RDLCK = 0; | ||
| 128 | pub const WRLCK = 1; | ||
| 129 | pub const UNLCK = 2; | ||
| 130 | |||
| 131 | pub const SETOWN_EX = 15; | ||
| 132 | pub const GETOWN_EX = 16; | ||
| 133 | |||
| 134 | pub const GETOWNER_UIDS = 17; | ||
| 135 | }; | ||
| 136 | |||
| 137 | pub const blksize_t = i32; | ||
| 138 | pub const nlink_t = u32; | ||
| 139 | pub const time_t = i64; | ||
| 140 | pub const mode_t = u32; | ||
| 141 | pub const off_t = i64; | ||
| 142 | pub const ino_t = u64; | ||
| 143 | pub const dev_t = u64; | ||
| 144 | pub const blkcnt_t = i64; | ||
| 145 | |||
| 146 | pub const timeval = extern struct { | ||
| 147 | sec: time_t, | ||
| 148 | usec: i64, | ||
| 149 | }; | ||
| 150 | |||
| 151 | pub const Flock = extern struct { | ||
| 152 | type: i16, | ||
| 153 | whence: i16, | ||
| 154 | start: off_t, | ||
| 155 | len: off_t, | ||
| 156 | pid: pid_t, | ||
| 157 | __unused: [4]u8, | ||
| 158 | }; | ||
| 159 | |||
| 160 | pub const msghdr = extern struct { | ||
| 161 | name: ?*sockaddr, | ||
| 162 | namelen: socklen_t, | ||
| 163 | iov: [*]iovec, | ||
| 164 | iovlen: i32, | ||
| 165 | __pad1: i32 = 0, | ||
| 166 | control: ?*anyopaque, | ||
| 167 | controllen: socklen_t, | ||
| 168 | __pad2: socklen_t = 0, | ||
| 169 | flags: i32, | ||
| 170 | }; | ||
| 171 | |||
| 172 | pub const msghdr_const = extern struct { | ||
| 173 | name: ?*const sockaddr, | ||
| 174 | namelen: socklen_t, | ||
| 175 | iov: [*]const iovec_const, | ||
| 176 | iovlen: i32, | ||
| 177 | __pad1: i32 = 0, | ||
| 178 | control: ?*const anyopaque, | ||
| 179 | controllen: socklen_t, | ||
| 180 | __pad2: socklen_t = 0, | ||
| 181 | flags: i32, | ||
| 182 | }; | ||
| 183 | |||
| 184 | /// No `Stat` structure on this platform, only `Statx`. | ||
| 185 | pub const Stat = void; | ||
| 186 | |||
| 187 | pub const Elf_Symndx = u32; | ||
| 188 | |||
| 189 | pub const MMAP2_UNIT = 4096; | ||
| 190 | |||
| 191 | pub const VDSO = struct {}; | ||
| 192 | |||
| 193 | /// TODO | ||
| 194 | pub const ucontext_t = void; | ||
| 195 | |||
| 196 | /// TODO | ||
| 197 | pub const getcontext = {}; | ||
lib/std/os/linux/riscv64.zig+5-5| ... | @@ -136,12 +136,12 @@ pub const F = struct { | ... | @@ -136,12 +136,12 @@ pub const F = struct { |
| 136 | 136 | ||
| 137 | pub const blksize_t = i32; | 137 | pub const blksize_t = i32; |
| 138 | pub const nlink_t = u32; | 138 | pub const nlink_t = u32; |
| 139 | pub const time_t = isize; | 139 | pub const time_t = i64; |
| 140 | pub const mode_t = u32; | 140 | pub const mode_t = u32; |
| 141 | pub const off_t = isize; | 141 | pub const off_t = i64; |
| 142 | pub const ino_t = usize; | 142 | pub const ino_t = u64; |
| 143 | pub const dev_t = usize; | 143 | pub const dev_t = u64; |
| 144 | pub const blkcnt_t = isize; | 144 | pub const blkcnt_t = i64; |
| 145 | 145 | ||
| 146 | pub const timeval = extern struct { | 146 | pub const timeval = extern struct { |
| 147 | sec: time_t, | 147 | sec: time_t, |
lib/std/os/linux/start_pie.zig+2-2| ... | @@ -26,7 +26,7 @@ const R_RELATIVE = switch (builtin.cpu.arch) { | ... | @@ -26,7 +26,7 @@ const R_RELATIVE = switch (builtin.cpu.arch) { |
| 26 | .hexagon => R_HEXAGON_RELATIVE, | 26 | .hexagon => R_HEXAGON_RELATIVE, |
| 27 | .loongarch32, .loongarch64 => R_LARCH_RELATIVE, | 27 | .loongarch32, .loongarch64 => R_LARCH_RELATIVE, |
| 28 | .m68k => R_68K_RELATIVE, | 28 | .m68k => R_68K_RELATIVE, |
| 29 | .riscv64 => R_RISCV_RELATIVE, | 29 | .riscv32, .riscv64 => R_RISCV_RELATIVE, |
| 30 | .s390x => R_390_RELATIVE, | 30 | .s390x => R_390_RELATIVE, |
| 31 | else => @compileError("Missing R_RELATIVE definition for this target"), | 31 | else => @compileError("Missing R_RELATIVE definition for this target"), |
| 32 | }; | 32 | }; |
| ... | @@ -111,7 +111,7 @@ fn getDynamicSymbol() [*]elf.Dyn { | ... | @@ -111,7 +111,7 @@ fn getDynamicSymbol() [*]elf.Dyn { |
| 111 | \\ lea (%[ret], %%pc), %[ret] | 111 | \\ lea (%[ret], %%pc), %[ret] |
| 112 | : [ret] "=r" (-> [*]elf.Dyn), | 112 | : [ret] "=r" (-> [*]elf.Dyn), |
| 113 | ), | 113 | ), |
| 114 | .riscv64 => asm volatile ( | 114 | .riscv32, .riscv64 => asm volatile ( |
| 115 | \\ .weak _DYNAMIC | 115 | \\ .weak _DYNAMIC |
| 116 | \\ .hidden _DYNAMIC | 116 | \\ .hidden _DYNAMIC |
| 117 | \\ lla %[ret], _DYNAMIC | 117 | \\ lla %[ret], _DYNAMIC |
lib/std/os/linux/syscalls.zig+337-33| ... | @@ -142,16 +142,16 @@ pub const X86 = enum(usize) { | ... | @@ -142,16 +142,16 @@ pub const X86 = enum(usize) { |
| 142 | afs_syscall = 137, | 142 | afs_syscall = 137, |
| 143 | setfsuid = 138, | 143 | setfsuid = 138, |
| 144 | setfsgid = 139, | 144 | setfsgid = 139, |
| 145 | _llseek = 140, | 145 | llseek = 140, |
| 146 | getdents = 141, | 146 | getdents = 141, |
| 147 | _newselect = 142, | 147 | newselect = 142, |
| 148 | flock = 143, | 148 | flock = 143, |
| 149 | msync = 144, | 149 | msync = 144, |
| 150 | readv = 145, | 150 | readv = 145, |
| 151 | writev = 146, | 151 | writev = 146, |
| 152 | getsid = 147, | 152 | getsid = 147, |
| 153 | fdatasync = 148, | 153 | fdatasync = 148, |
| 154 | _sysctl = 149, | 154 | sysctl = 149, |
| 155 | mlock = 150, | 155 | mlock = 150, |
| 156 | munlock = 151, | 156 | munlock = 151, |
| 157 | mlockall = 152, | 157 | mlockall = 152, |
| ... | @@ -607,7 +607,7 @@ pub const X64 = enum(usize) { | ... | @@ -607,7 +607,7 @@ pub const X64 = enum(usize) { |
| 607 | vhangup = 153, | 607 | vhangup = 153, |
| 608 | modify_ldt = 154, | 608 | modify_ldt = 154, |
| 609 | pivot_root = 155, | 609 | pivot_root = 155, |
| 610 | _sysctl = 156, | 610 | sysctl = 156, |
| 611 | prctl = 157, | 611 | prctl = 157, |
| 612 | arch_prctl = 158, | 612 | arch_prctl = 158, |
| 613 | adjtimex = 159, | 613 | adjtimex = 159, |
| ... | @@ -927,16 +927,16 @@ pub const Arm = enum(usize) { | ... | @@ -927,16 +927,16 @@ pub const Arm = enum(usize) { |
| 927 | personality = 136, | 927 | personality = 136, |
| 928 | setfsuid = 138, | 928 | setfsuid = 138, |
| 929 | setfsgid = 139, | 929 | setfsgid = 139, |
| 930 | _llseek = 140, | 930 | llseek = 140, |
| 931 | getdents = 141, | 931 | getdents = 141, |
| 932 | _newselect = 142, | 932 | newselect = 142, |
| 933 | flock = 143, | 933 | flock = 143, |
| 934 | msync = 144, | 934 | msync = 144, |
| 935 | readv = 145, | 935 | readv = 145, |
| 936 | writev = 146, | 936 | writev = 146, |
| 937 | getsid = 147, | 937 | getsid = 147, |
| 938 | fdatasync = 148, | 938 | fdatasync = 148, |
| 939 | _sysctl = 149, | 939 | sysctl = 149, |
| 940 | mlock = 150, | 940 | mlock = 150, |
| 941 | munlock = 151, | 941 | munlock = 151, |
| 942 | mlockall = 152, | 942 | mlockall = 152, |
| ... | @@ -1454,12 +1454,12 @@ pub const Sparc64 = enum(usize) { | ... | @@ -1454,12 +1454,12 @@ pub const Sparc64 = enum(usize) { |
| 1454 | afs_syscall = 227, | 1454 | afs_syscall = 227, |
| 1455 | setfsuid = 228, | 1455 | setfsuid = 228, |
| 1456 | setfsgid = 229, | 1456 | setfsgid = 229, |
| 1457 | _newselect = 230, | 1457 | newselect = 230, |
| 1458 | splice = 232, | 1458 | splice = 232, |
| 1459 | stime = 233, | 1459 | stime = 233, |
| 1460 | statfs64 = 234, | 1460 | statfs64 = 234, |
| 1461 | fstatfs64 = 235, | 1461 | fstatfs64 = 235, |
| 1462 | _llseek = 236, | 1462 | llseek = 236, |
| 1463 | mlock = 237, | 1463 | mlock = 237, |
| 1464 | munlock = 238, | 1464 | munlock = 238, |
| 1465 | mlockall = 239, | 1465 | mlockall = 239, |
| ... | @@ -1474,7 +1474,7 @@ pub const Sparc64 = enum(usize) { | ... | @@ -1474,7 +1474,7 @@ pub const Sparc64 = enum(usize) { |
| 1474 | sched_rr_get_interval = 248, | 1474 | sched_rr_get_interval = 248, |
| 1475 | nanosleep = 249, | 1475 | nanosleep = 249, |
| 1476 | mremap = 250, | 1476 | mremap = 250, |
| 1477 | _sysctl = 251, | 1477 | sysctl = 251, |
| 1478 | getsid = 252, | 1478 | getsid = 252, |
| 1479 | fdatasync = 253, | 1479 | fdatasync = 253, |
| 1480 | nfsservctl = 254, | 1480 | nfsservctl = 254, |
| ... | @@ -1771,9 +1771,9 @@ pub const Mips = enum(usize) { | ... | @@ -1771,9 +1771,9 @@ pub const Mips = enum(usize) { |
| 1771 | afs_syscall = Linux + 137, | 1771 | afs_syscall = Linux + 137, |
| 1772 | setfsuid = Linux + 138, | 1772 | setfsuid = Linux + 138, |
| 1773 | setfsgid = Linux + 139, | 1773 | setfsgid = Linux + 139, |
| 1774 | _llseek = Linux + 140, | 1774 | llseek = Linux + 140, |
| 1775 | getdents = Linux + 141, | 1775 | getdents = Linux + 141, |
| 1776 | _newselect = Linux + 142, | 1776 | newselect = Linux + 142, |
| 1777 | flock = Linux + 143, | 1777 | flock = Linux + 143, |
| 1778 | msync = Linux + 144, | 1778 | msync = Linux + 144, |
| 1779 | readv = Linux + 145, | 1779 | readv = Linux + 145, |
| ... | @@ -1783,7 +1783,7 @@ pub const Mips = enum(usize) { | ... | @@ -1783,7 +1783,7 @@ pub const Mips = enum(usize) { |
| 1783 | sysmips = Linux + 149, | 1783 | sysmips = Linux + 149, |
| 1784 | getsid = Linux + 151, | 1784 | getsid = Linux + 151, |
| 1785 | fdatasync = Linux + 152, | 1785 | fdatasync = Linux + 152, |
| 1786 | _sysctl = Linux + 153, | 1786 | sysctl = Linux + 153, |
| 1787 | mlock = Linux + 154, | 1787 | mlock = Linux + 154, |
| 1788 | munlock = Linux + 155, | 1788 | munlock = Linux + 155, |
| 1789 | mlockall = Linux + 156, | 1789 | mlockall = Linux + 156, |
| ... | @@ -2087,7 +2087,7 @@ pub const Mips64 = enum(usize) { | ... | @@ -2087,7 +2087,7 @@ pub const Mips64 = enum(usize) { |
| 2087 | writev = Linux + 19, | 2087 | writev = Linux + 19, |
| 2088 | access = Linux + 20, | 2088 | access = Linux + 20, |
| 2089 | pipe = Linux + 21, | 2089 | pipe = Linux + 21, |
| 2090 | _newselect = Linux + 22, | 2090 | newselect = Linux + 22, |
| 2091 | sched_yield = Linux + 23, | 2091 | sched_yield = Linux + 23, |
| 2092 | mremap = Linux + 24, | 2092 | mremap = Linux + 24, |
| 2093 | msync = Linux + 25, | 2093 | msync = Linux + 25, |
| ... | @@ -2217,7 +2217,7 @@ pub const Mips64 = enum(usize) { | ... | @@ -2217,7 +2217,7 @@ pub const Mips64 = enum(usize) { |
| 2217 | munlockall = Linux + 149, | 2217 | munlockall = Linux + 149, |
| 2218 | vhangup = Linux + 150, | 2218 | vhangup = Linux + 150, |
| 2219 | pivot_root = Linux + 151, | 2219 | pivot_root = Linux + 151, |
| 2220 | _sysctl = Linux + 152, | 2220 | sysctl = Linux + 152, |
| 2221 | prctl = Linux + 153, | 2221 | prctl = Linux + 153, |
| 2222 | adjtimex = Linux + 154, | 2222 | adjtimex = Linux + 154, |
| 2223 | setrlimit = Linux + 155, | 2223 | setrlimit = Linux + 155, |
| ... | @@ -2568,16 +2568,16 @@ pub const PowerPC = enum(usize) { | ... | @@ -2568,16 +2568,16 @@ pub const PowerPC = enum(usize) { |
| 2568 | afs_syscall = 137, | 2568 | afs_syscall = 137, |
| 2569 | setfsuid = 138, | 2569 | setfsuid = 138, |
| 2570 | setfsgid = 139, | 2570 | setfsgid = 139, |
| 2571 | _llseek = 140, | 2571 | llseek = 140, |
| 2572 | getdents = 141, | 2572 | getdents = 141, |
| 2573 | _newselect = 142, | 2573 | newselect = 142, |
| 2574 | flock = 143, | 2574 | flock = 143, |
| 2575 | msync = 144, | 2575 | msync = 144, |
| 2576 | readv = 145, | 2576 | readv = 145, |
| 2577 | writev = 146, | 2577 | writev = 146, |
| 2578 | getsid = 147, | 2578 | getsid = 147, |
| 2579 | fdatasync = 148, | 2579 | fdatasync = 148, |
| 2580 | _sysctl = 149, | 2580 | sysctl = 149, |
| 2581 | mlock = 150, | 2581 | mlock = 150, |
| 2582 | munlock = 151, | 2582 | munlock = 151, |
| 2583 | mlockall = 152, | 2583 | mlockall = 152, |
| ... | @@ -3008,16 +3008,16 @@ pub const PowerPC64 = enum(usize) { | ... | @@ -3008,16 +3008,16 @@ pub const PowerPC64 = enum(usize) { |
| 3008 | afs_syscall = 137, | 3008 | afs_syscall = 137, |
| 3009 | setfsuid = 138, | 3009 | setfsuid = 138, |
| 3010 | setfsgid = 139, | 3010 | setfsgid = 139, |
| 3011 | _llseek = 140, | 3011 | llseek = 140, |
| 3012 | getdents = 141, | 3012 | getdents = 141, |
| 3013 | _newselect = 142, | 3013 | newselect = 142, |
| 3014 | flock = 143, | 3014 | flock = 143, |
| 3015 | msync = 144, | 3015 | msync = 144, |
| 3016 | readv = 145, | 3016 | readv = 145, |
| 3017 | writev = 146, | 3017 | writev = 146, |
| 3018 | getsid = 147, | 3018 | getsid = 147, |
| 3019 | fdatasync = 148, | 3019 | fdatasync = 148, |
| 3020 | _sysctl = 149, | 3020 | sysctl = 149, |
| 3021 | mlock = 150, | 3021 | mlock = 150, |
| 3022 | munlock = 151, | 3022 | munlock = 151, |
| 3023 | mlockall = 152, | 3023 | mlockall = 152, |
| ... | @@ -3351,7 +3351,7 @@ pub const Arm64 = enum(usize) { | ... | @@ -3351,7 +3351,7 @@ pub const Arm64 = enum(usize) { |
| 3351 | pwrite64 = 68, | 3351 | pwrite64 = 68, |
| 3352 | preadv = 69, | 3352 | preadv = 69, |
| 3353 | pwritev = 70, | 3353 | pwritev = 70, |
| 3354 | sendfile = 71, | 3354 | sendfile64 = 71, |
| 3355 | pselect6 = 72, | 3355 | pselect6 = 72, |
| 3356 | ppoll = 73, | 3356 | ppoll = 73, |
| 3357 | signalfd4 = 74, | 3357 | signalfd4 = 74, |
| ... | @@ -3359,8 +3359,8 @@ pub const Arm64 = enum(usize) { | ... | @@ -3359,8 +3359,8 @@ pub const Arm64 = enum(usize) { |
| 3359 | splice = 76, | 3359 | splice = 76, |
| 3360 | tee = 77, | 3360 | tee = 77, |
| 3361 | readlinkat = 78, | 3361 | readlinkat = 78, |
| 3362 | fstatat = 79, | 3362 | fstatat64 = 79, |
| 3363 | fstat = 80, | 3363 | fstat64 = 80, |
| 3364 | sync = 81, | 3364 | sync = 81, |
| 3365 | fsync = 82, | 3365 | fsync = 82, |
| 3366 | fdatasync = 83, | 3366 | fdatasync = 83, |
| ... | @@ -3503,7 +3503,7 @@ pub const Arm64 = enum(usize) { | ... | @@ -3503,7 +3503,7 @@ pub const Arm64 = enum(usize) { |
| 3503 | clone = 220, | 3503 | clone = 220, |
| 3504 | execve = 221, | 3504 | execve = 221, |
| 3505 | mmap = 222, | 3505 | mmap = 222, |
| 3506 | fadvise64 = 223, | 3506 | fadvise64_64 = 223, |
| 3507 | swapon = 224, | 3507 | swapon = 224, |
| 3508 | swapoff = 225, | 3508 | swapoff = 225, |
| 3509 | mprotect = 226, | 3509 | mprotect = 226, |
| ... | @@ -3594,9 +3594,313 @@ pub const Arm64 = enum(usize) { | ... | @@ -3594,9 +3594,313 @@ pub const Arm64 = enum(usize) { |
| 3594 | futex_requeue = 456, | 3594 | futex_requeue = 456, |
| 3595 | }; | 3595 | }; |
| 3596 | 3596 | ||
| 3597 | pub const RiscV64 = enum(usize) { | 3597 | pub const RiscV32 = enum(usize) { |
| 3598 | pub const arch_specific_syscall = 244; | 3598 | io_setup = 0, |
| 3599 | io_destroy = 1, | ||
| 3600 | io_submit = 2, | ||
| 3601 | io_cancel = 3, | ||
| 3602 | setxattr = 5, | ||
| 3603 | lsetxattr = 6, | ||
| 3604 | fsetxattr = 7, | ||
| 3605 | getxattr = 8, | ||
| 3606 | lgetxattr = 9, | ||
| 3607 | fgetxattr = 10, | ||
| 3608 | listxattr = 11, | ||
| 3609 | llistxattr = 12, | ||
| 3610 | flistxattr = 13, | ||
| 3611 | removexattr = 14, | ||
| 3612 | lremovexattr = 15, | ||
| 3613 | fremovexattr = 16, | ||
| 3614 | getcwd = 17, | ||
| 3615 | lookup_dcookie = 18, | ||
| 3616 | eventfd2 = 19, | ||
| 3617 | epoll_create1 = 20, | ||
| 3618 | epoll_ctl = 21, | ||
| 3619 | epoll_pwait = 22, | ||
| 3620 | dup = 23, | ||
| 3621 | dup3 = 24, | ||
| 3622 | fcntl64 = 25, | ||
| 3623 | inotify_init1 = 26, | ||
| 3624 | inotify_add_watch = 27, | ||
| 3625 | inotify_rm_watch = 28, | ||
| 3626 | ioctl = 29, | ||
| 3627 | ioprio_set = 30, | ||
| 3628 | ioprio_get = 31, | ||
| 3629 | flock = 32, | ||
| 3630 | mknodat = 33, | ||
| 3631 | mkdirat = 34, | ||
| 3632 | unlinkat = 35, | ||
| 3633 | symlinkat = 36, | ||
| 3634 | linkat = 37, | ||
| 3635 | umount2 = 39, | ||
| 3636 | mount = 40, | ||
| 3637 | pivot_root = 41, | ||
| 3638 | nfsservctl = 42, | ||
| 3639 | statfs64 = 43, | ||
| 3640 | fstatfs64 = 44, | ||
| 3641 | truncate64 = 45, | ||
| 3642 | ftruncate64 = 46, | ||
| 3643 | fallocate = 47, | ||
| 3644 | faccessat = 48, | ||
| 3645 | chdir = 49, | ||
| 3646 | fchdir = 50, | ||
| 3647 | chroot = 51, | ||
| 3648 | fchmod = 52, | ||
| 3649 | fchmodat = 53, | ||
| 3650 | fchownat = 54, | ||
| 3651 | fchown = 55, | ||
| 3652 | openat = 56, | ||
| 3653 | close = 57, | ||
| 3654 | vhangup = 58, | ||
| 3655 | pipe2 = 59, | ||
| 3656 | quotactl = 60, | ||
| 3657 | getdents64 = 61, | ||
| 3658 | llseek = 62, | ||
| 3659 | read = 63, | ||
| 3660 | write = 64, | ||
| 3661 | readv = 65, | ||
| 3662 | writev = 66, | ||
| 3663 | pread64 = 67, | ||
| 3664 | pwrite64 = 68, | ||
| 3665 | preadv = 69, | ||
| 3666 | pwritev = 70, | ||
| 3667 | sendfile64 = 71, | ||
| 3668 | signalfd4 = 74, | ||
| 3669 | vmsplice = 75, | ||
| 3670 | splice = 76, | ||
| 3671 | tee = 77, | ||
| 3672 | readlinkat = 78, | ||
| 3673 | sync = 81, | ||
| 3674 | fsync = 82, | ||
| 3675 | fdatasync = 83, | ||
| 3676 | sync_file_range = 84, | ||
| 3677 | timerfd_create = 85, | ||
| 3678 | acct = 89, | ||
| 3679 | capget = 90, | ||
| 3680 | capset = 91, | ||
| 3681 | personality = 92, | ||
| 3682 | exit = 93, | ||
| 3683 | exit_group = 94, | ||
| 3684 | waitid = 95, | ||
| 3685 | set_tid_address = 96, | ||
| 3686 | unshare = 97, | ||
| 3687 | set_robust_list = 99, | ||
| 3688 | get_robust_list = 100, | ||
| 3689 | getitimer = 102, | ||
| 3690 | setitimer = 103, | ||
| 3691 | kexec_load = 104, | ||
| 3692 | init_module = 105, | ||
| 3693 | delete_module = 106, | ||
| 3694 | timer_create = 107, | ||
| 3695 | timer_getoverrun = 109, | ||
| 3696 | timer_delete = 111, | ||
| 3697 | syslog = 116, | ||
| 3698 | ptrace = 117, | ||
| 3699 | sched_setparam = 118, | ||
| 3700 | sched_setscheduler = 119, | ||
| 3701 | sched_getscheduler = 120, | ||
| 3702 | sched_getparam = 121, | ||
| 3703 | sched_setaffinity = 122, | ||
| 3704 | sched_getaffinity = 123, | ||
| 3705 | sched_yield = 124, | ||
| 3706 | sched_get_priority_max = 125, | ||
| 3707 | sched_get_priority_min = 126, | ||
| 3708 | restart_syscall = 128, | ||
| 3709 | kill = 129, | ||
| 3710 | tkill = 130, | ||
| 3711 | tgkill = 131, | ||
| 3712 | sigaltstack = 132, | ||
| 3713 | rt_sigsuspend = 133, | ||
| 3714 | rt_sigaction = 134, | ||
| 3715 | rt_sigprocmask = 135, | ||
| 3716 | rt_sigpending = 136, | ||
| 3717 | rt_sigqueueinfo = 138, | ||
| 3718 | rt_sigreturn = 139, | ||
| 3719 | setpriority = 140, | ||
| 3720 | getpriority = 141, | ||
| 3721 | reboot = 142, | ||
| 3722 | setregid = 143, | ||
| 3723 | setgid = 144, | ||
| 3724 | setreuid = 145, | ||
| 3725 | setuid = 146, | ||
| 3726 | setresuid = 147, | ||
| 3727 | getresuid = 148, | ||
| 3728 | setresgid = 149, | ||
| 3729 | getresgid = 150, | ||
| 3730 | setfsuid = 151, | ||
| 3731 | setfsgid = 152, | ||
| 3732 | times = 153, | ||
| 3733 | setpgid = 154, | ||
| 3734 | getpgid = 155, | ||
| 3735 | getsid = 156, | ||
| 3736 | setsid = 157, | ||
| 3737 | getgroups = 158, | ||
| 3738 | setgroups = 159, | ||
| 3739 | uname = 160, | ||
| 3740 | sethostname = 161, | ||
| 3741 | setdomainname = 162, | ||
| 3742 | getrusage = 165, | ||
| 3743 | umask = 166, | ||
| 3744 | prctl = 167, | ||
| 3745 | getcpu = 168, | ||
| 3746 | getpid = 172, | ||
| 3747 | getppid = 173, | ||
| 3748 | getuid = 174, | ||
| 3749 | geteuid = 175, | ||
| 3750 | getgid = 176, | ||
| 3751 | getegid = 177, | ||
| 3752 | gettid = 178, | ||
| 3753 | sysinfo = 179, | ||
| 3754 | mq_open = 180, | ||
| 3755 | mq_unlink = 181, | ||
| 3756 | mq_notify = 184, | ||
| 3757 | mq_getsetattr = 185, | ||
| 3758 | msgget = 186, | ||
| 3759 | msgctl = 187, | ||
| 3760 | msgrcv = 188, | ||
| 3761 | msgsnd = 189, | ||
| 3762 | semget = 190, | ||
| 3763 | semctl = 191, | ||
| 3764 | semop = 193, | ||
| 3765 | shmget = 194, | ||
| 3766 | shmctl = 195, | ||
| 3767 | shmat = 196, | ||
| 3768 | shmdt = 197, | ||
| 3769 | socket = 198, | ||
| 3770 | socketpair = 199, | ||
| 3771 | bind = 200, | ||
| 3772 | listen = 201, | ||
| 3773 | accept = 202, | ||
| 3774 | connect = 203, | ||
| 3775 | getsockname = 204, | ||
| 3776 | getpeername = 205, | ||
| 3777 | sendto = 206, | ||
| 3778 | recvfrom = 207, | ||
| 3779 | setsockopt = 208, | ||
| 3780 | getsockopt = 209, | ||
| 3781 | shutdown = 210, | ||
| 3782 | sendmsg = 211, | ||
| 3783 | recvmsg = 212, | ||
| 3784 | readahead = 213, | ||
| 3785 | brk = 214, | ||
| 3786 | munmap = 215, | ||
| 3787 | mremap = 216, | ||
| 3788 | add_key = 217, | ||
| 3789 | request_key = 218, | ||
| 3790 | keyctl = 219, | ||
| 3791 | clone = 220, | ||
| 3792 | execve = 221, | ||
| 3793 | mmap2 = 222, | ||
| 3794 | fadvise64_64 = 223, | ||
| 3795 | swapon = 224, | ||
| 3796 | swapoff = 225, | ||
| 3797 | mprotect = 226, | ||
| 3798 | msync = 227, | ||
| 3799 | mlock = 228, | ||
| 3800 | munlock = 229, | ||
| 3801 | mlockall = 230, | ||
| 3802 | munlockall = 231, | ||
| 3803 | mincore = 232, | ||
| 3804 | madvise = 233, | ||
| 3805 | remap_file_pages = 234, | ||
| 3806 | mbind = 235, | ||
| 3807 | get_mempolicy = 236, | ||
| 3808 | set_mempolicy = 237, | ||
| 3809 | migrate_pages = 238, | ||
| 3810 | move_pages = 239, | ||
| 3811 | rt_tgsigqueueinfo = 240, | ||
| 3812 | perf_event_open = 241, | ||
| 3813 | accept4 = 242, | ||
| 3814 | prlimit64 = 261, | ||
| 3815 | fanotify_init = 262, | ||
| 3816 | fanotify_mark = 263, | ||
| 3817 | name_to_handle_at = 264, | ||
| 3818 | open_by_handle_at = 265, | ||
| 3819 | syncfs = 267, | ||
| 3820 | setns = 268, | ||
| 3821 | sendmmsg = 269, | ||
| 3822 | process_vm_readv = 270, | ||
| 3823 | process_vm_writev = 271, | ||
| 3824 | kcmp = 272, | ||
| 3825 | finit_module = 273, | ||
| 3826 | sched_setattr = 274, | ||
| 3827 | sched_getattr = 275, | ||
| 3828 | renameat2 = 276, | ||
| 3829 | seccomp = 277, | ||
| 3830 | getrandom = 278, | ||
| 3831 | memfd_create = 279, | ||
| 3832 | bpf = 280, | ||
| 3833 | execveat = 281, | ||
| 3834 | userfaultfd = 282, | ||
| 3835 | membarrier = 283, | ||
| 3836 | mlock2 = 284, | ||
| 3837 | copy_file_range = 285, | ||
| 3838 | preadv2 = 286, | ||
| 3839 | pwritev2 = 287, | ||
| 3840 | pkey_mprotect = 288, | ||
| 3841 | pkey_alloc = 289, | ||
| 3842 | pkey_free = 290, | ||
| 3843 | statx = 291, | ||
| 3844 | rseq = 293, | ||
| 3845 | kexec_file_load = 294, | ||
| 3846 | clock_gettime = 403, | ||
| 3847 | clock_settime = 404, | ||
| 3848 | clock_adjtime = 405, | ||
| 3849 | clock_getres = 406, | ||
| 3850 | clock_nanosleep = 407, | ||
| 3851 | timer_gettime = 408, | ||
| 3852 | timer_settime = 409, | ||
| 3853 | timerfd_gettime = 410, | ||
| 3854 | timerfd_settime = 411, | ||
| 3855 | utimensat = 412, | ||
| 3856 | pselect6 = 413, | ||
| 3857 | ppoll = 414, | ||
| 3858 | io_pgetevents = 416, | ||
| 3859 | recvmmsg = 417, | ||
| 3860 | mq_timedsend = 418, | ||
| 3861 | mq_timedreceive = 419, | ||
| 3862 | semtimedop = 420, | ||
| 3863 | rt_sigtimedwait = 421, | ||
| 3864 | futex = 422, | ||
| 3865 | sched_rr_get_interval = 423, | ||
| 3866 | pidfd_send_signal = 424, | ||
| 3867 | io_uring_setup = 425, | ||
| 3868 | io_uring_enter = 426, | ||
| 3869 | io_uring_register = 427, | ||
| 3870 | open_tree = 428, | ||
| 3871 | move_mount = 429, | ||
| 3872 | fsopen = 430, | ||
| 3873 | fsconfig = 431, | ||
| 3874 | fsmount = 432, | ||
| 3875 | fspick = 433, | ||
| 3876 | pidfd_open = 434, | ||
| 3877 | clone3 = 435, | ||
| 3878 | close_range = 436, | ||
| 3879 | openat2 = 437, | ||
| 3880 | pidfd_getfd = 438, | ||
| 3881 | faccessat2 = 439, | ||
| 3882 | process_madvise = 440, | ||
| 3883 | epoll_pwait2 = 441, | ||
| 3884 | mount_setattr = 442, | ||
| 3885 | quotactl_fd = 443, | ||
| 3886 | landlock_create_ruleset = 444, | ||
| 3887 | landlock_add_rule = 445, | ||
| 3888 | landlock_restrict_self = 446, | ||
| 3889 | memfd_secret = 447, | ||
| 3890 | process_mrelease = 448, | ||
| 3891 | futex_waitv = 449, | ||
| 3892 | set_mempolicy_home_node = 450, | ||
| 3893 | cachestat = 451, | ||
| 3894 | fchmodat2 = 452, | ||
| 3895 | map_shadow_stack = 453, | ||
| 3896 | futex_wake = 454, | ||
| 3897 | futex_wait = 455, | ||
| 3898 | futex_requeue = 456, | ||
| 3899 | riscv_flush_icache = (244 + 15), | ||
| 3900 | riscv_hwprobe = (244 + 14), | ||
| 3901 | }; | ||
| 3599 | 3902 | ||
| 3903 | pub const RiscV64 = enum(usize) { | ||
| 3600 | io_setup = 0, | 3904 | io_setup = 0, |
| 3601 | io_destroy = 1, | 3905 | io_destroy = 1, |
| 3602 | io_submit = 2, | 3906 | io_submit = 2, |
| ... | @@ -3667,7 +3971,7 @@ pub const RiscV64 = enum(usize) { | ... | @@ -3667,7 +3971,7 @@ pub const RiscV64 = enum(usize) { |
| 3667 | pwrite64 = 68, | 3971 | pwrite64 = 68, |
| 3668 | preadv = 69, | 3972 | preadv = 69, |
| 3669 | pwritev = 70, | 3973 | pwritev = 70, |
| 3670 | sendfile = 71, | 3974 | sendfile64 = 71, |
| 3671 | pselect6 = 72, | 3975 | pselect6 = 72, |
| 3672 | ppoll = 73, | 3976 | ppoll = 73, |
| 3673 | signalfd4 = 74, | 3977 | signalfd4 = 74, |
| ... | @@ -3675,8 +3979,8 @@ pub const RiscV64 = enum(usize) { | ... | @@ -3675,8 +3979,8 @@ pub const RiscV64 = enum(usize) { |
| 3675 | splice = 76, | 3979 | splice = 76, |
| 3676 | tee = 77, | 3980 | tee = 77, |
| 3677 | readlinkat = 78, | 3981 | readlinkat = 78, |
| 3678 | fstatat = 79, | 3982 | fstatat64 = 79, |
| 3679 | fstat = 80, | 3983 | fstat64 = 80, |
| 3680 | sync = 81, | 3984 | sync = 81, |
| 3681 | fsync = 82, | 3985 | fsync = 82, |
| 3682 | fdatasync = 83, | 3986 | fdatasync = 83, |
| ... | @@ -3819,7 +4123,7 @@ pub const RiscV64 = enum(usize) { | ... | @@ -3819,7 +4123,7 @@ pub const RiscV64 = enum(usize) { |
| 3819 | clone = 220, | 4123 | clone = 220, |
| 3820 | execve = 221, | 4124 | execve = 221, |
| 3821 | mmap = 222, | 4125 | mmap = 222, |
| 3822 | fadvise64 = 223, | 4126 | fadvise64_64 = 223, |
| 3823 | swapon = 224, | 4127 | swapon = 224, |
| 3824 | swapoff = 225, | 4128 | swapoff = 225, |
| 3825 | mprotect = 226, | 4129 | mprotect = 226, |
| ... | @@ -3908,8 +4212,8 @@ pub const RiscV64 = enum(usize) { | ... | @@ -3908,8 +4212,8 @@ pub const RiscV64 = enum(usize) { |
| 3908 | futex_wake = 454, | 4212 | futex_wake = 454, |
| 3909 | futex_wait = 455, | 4213 | futex_wait = 455, |
| 3910 | futex_requeue = 456, | 4214 | futex_requeue = 456, |
| 3911 | 4215 | riscv_flush_icache = (244 + 15), | |
| 3912 | riscv_flush_icache = arch_specific_syscall + 15, | 4216 | riscv_hwprobe = (244 + 14), |
| 3913 | }; | 4217 | }; |
| 3914 | 4218 | ||
| 3915 | pub const LoongArch64 = enum(usize) { | 4219 | pub const LoongArch64 = enum(usize) { |
lib/std/os/linux/test.zig+2-2| ... | @@ -79,11 +79,11 @@ test "statx" { | ... | @@ -79,11 +79,11 @@ test "statx" { |
| 79 | var statx_buf: linux.Statx = undefined; | 79 | var statx_buf: linux.Statx = undefined; |
| 80 | switch (linux.E.init(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) { | 80 | switch (linux.E.init(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) { |
| 81 | .SUCCESS => {}, | 81 | .SUCCESS => {}, |
| 82 | // The statx syscall was only introduced in linux 4.11 | ||
| 83 | .NOSYS => return error.SkipZigTest, | ||
| 84 | else => unreachable, | 82 | else => unreachable, |
| 85 | } | 83 | } |
| 86 | 84 | ||
| 85 | if (builtin.cpu.arch == .riscv32) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless. | ||
| 86 | |||
| 87 | var stat_buf: linux.Stat = undefined; | 87 | var stat_buf: linux.Stat = undefined; |
| 88 | switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) { | 88 | switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) { |
| 89 | .SUCCESS => {}, | 89 | .SUCCESS => {}, |
lib/std/os/linux/tls.zig+1-1| ... | @@ -170,7 +170,7 @@ pub fn setThreadPointer(addr: usize) void { | ... | @@ -170,7 +170,7 @@ pub fn setThreadPointer(addr: usize) void { |
| 170 | const rc = @call(.always_inline, linux.syscall1, .{ .set_tls, addr }); | 170 | const rc = @call(.always_inline, linux.syscall1, .{ .set_tls, addr }); |
| 171 | assert(rc == 0); | 171 | assert(rc == 0); |
| 172 | }, | 172 | }, |
| 173 | .riscv64 => { | 173 | .riscv32, .riscv64 => { |
| 174 | asm volatile ( | 174 | asm volatile ( |
| 175 | \\ mv tp, %[addr] | 175 | \\ mv tp, %[addr] |
| 176 | : | 176 | : |
lib/std/posix.zig+4-32| ... | @@ -615,7 +615,6 @@ pub fn getrandom(buffer: []u8) GetRandomError!void { | ... | @@ -615,7 +615,6 @@ pub fn getrandom(buffer: []u8) GetRandomError!void { |
| 615 | .INVAL => unreachable, | 615 | .INVAL => unreachable, |
| 616 | .FAULT => unreachable, | 616 | .FAULT => unreachable, |
| 617 | .INTR => continue, | 617 | .INTR => continue, |
| 618 | .NOSYS => return getRandomBytesDevURandom(buf), | ||
| 619 | else => return unexpectedErrno(err), | 618 | else => return unexpectedErrno(err), |
| 620 | } | 619 | } |
| 621 | } | 620 | } |
| ... | @@ -4534,7 +4533,6 @@ pub const FanotifyInitError = error{ | ... | @@ -4534,7 +4533,6 @@ pub const FanotifyInitError = error{ |
| 4534 | ProcessFdQuotaExceeded, | 4533 | ProcessFdQuotaExceeded, |
| 4535 | SystemFdQuotaExceeded, | 4534 | SystemFdQuotaExceeded, |
| 4536 | SystemResources, | 4535 | SystemResources, |
| 4537 | OperationNotSupported, | ||
| 4538 | PermissionDenied, | 4536 | PermissionDenied, |
| 4539 | } || UnexpectedError; | 4537 | } || UnexpectedError; |
| 4540 | 4538 | ||
| ... | @@ -4546,7 +4544,6 @@ pub fn fanotify_init(flags: std.os.linux.fanotify.InitFlags, event_f_flags: u32) | ... | @@ -4546,7 +4544,6 @@ pub fn fanotify_init(flags: std.os.linux.fanotify.InitFlags, event_f_flags: u32) |
| 4546 | .MFILE => return error.ProcessFdQuotaExceeded, | 4544 | .MFILE => return error.ProcessFdQuotaExceeded, |
| 4547 | .NFILE => return error.SystemFdQuotaExceeded, | 4545 | .NFILE => return error.SystemFdQuotaExceeded, |
| 4548 | .NOMEM => return error.SystemResources, | 4546 | .NOMEM => return error.SystemResources, |
| 4549 | .NOSYS => return error.OperationNotSupported, | ||
| 4550 | .PERM => return error.PermissionDenied, | 4547 | .PERM => return error.PermissionDenied, |
| 4551 | else => |err| return unexpectedErrno(err), | 4548 | else => |err| return unexpectedErrno(err), |
| 4552 | } | 4549 | } |
| ... | @@ -4559,7 +4556,6 @@ pub const FanotifyMarkError = error{ | ... | @@ -4559,7 +4556,6 @@ pub const FanotifyMarkError = error{ |
| 4559 | FileNotFound, | 4556 | FileNotFound, |
| 4560 | SystemResources, | 4557 | SystemResources, |
| 4561 | UserMarkQuotaExceeded, | 4558 | UserMarkQuotaExceeded, |
| 4562 | NotImplemented, | ||
| 4563 | NotDir, | 4559 | NotDir, |
| 4564 | OperationNotSupported, | 4560 | OperationNotSupported, |
| 4565 | PermissionDenied, | 4561 | PermissionDenied, |
| ... | @@ -4600,7 +4596,6 @@ pub fn fanotify_markZ( | ... | @@ -4600,7 +4596,6 @@ pub fn fanotify_markZ( |
| 4600 | .NOENT => return error.FileNotFound, | 4596 | .NOENT => return error.FileNotFound, |
| 4601 | .NOMEM => return error.SystemResources, | 4597 | .NOMEM => return error.SystemResources, |
| 4602 | .NOSPC => return error.UserMarkQuotaExceeded, | 4598 | .NOSPC => return error.UserMarkQuotaExceeded, |
| 4603 | .NOSYS => return error.NotImplemented, | ||
| 4604 | .NOTDIR => return error.NotDir, | 4599 | .NOTDIR => return error.NotDir, |
| 4605 | .OPNOTSUPP => return error.OperationNotSupported, | 4600 | .OPNOTSUPP => return error.OperationNotSupported, |
| 4606 | .PERM => return error.PermissionDenied, | 4601 | .PERM => return error.PermissionDenied, |
| ... | @@ -6183,13 +6178,6 @@ pub fn sendfile( | ... | @@ -6183,13 +6178,6 @@ pub fn sendfile( |
| 6183 | 6178 | ||
| 6184 | switch (native_os) { | 6179 | switch (native_os) { |
| 6185 | .linux => sf: { | 6180 | .linux => sf: { |
| 6186 | // sendfile() first appeared in Linux 2.2, glibc 2.1. | ||
| 6187 | const call_sf = comptime if (builtin.link_libc) | ||
| 6188 | std.c.versionCheck(.{ .major = 2, .minor = 1, .patch = 0 }) | ||
| 6189 | else | ||
| 6190 | builtin.os.version_range.linux.range.max.order(.{ .major = 2, .minor = 2, .patch = 0 }) != .lt; | ||
| 6191 | if (!call_sf) break :sf; | ||
| 6192 | |||
| 6193 | if (headers.len != 0) { | 6181 | if (headers.len != 0) { |
| 6194 | const amt = try writev(out_fd, headers); | 6182 | const amt = try writev(out_fd, headers); |
| 6195 | total_written += amt; | 6183 | total_written += amt; |
| ... | @@ -6223,14 +6211,14 @@ pub fn sendfile( | ... | @@ -6223,14 +6211,14 @@ pub fn sendfile( |
| 6223 | .OVERFLOW => unreachable, // We avoid passing too large of a `count`. | 6211 | .OVERFLOW => unreachable, // We avoid passing too large of a `count`. |
| 6224 | .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket | 6212 | .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket |
| 6225 | 6213 | ||
| 6226 | .INVAL, .NOSYS => { | 6214 | .INVAL => { |
| 6227 | // EINVAL could be any of the following situations: | 6215 | // EINVAL could be any of the following situations: |
| 6228 | // * Descriptor is not valid or locked | 6216 | // * Descriptor is not valid or locked |
| 6229 | // * an mmap(2)-like operation is not available for in_fd | 6217 | // * an mmap(2)-like operation is not available for in_fd |
| 6230 | // * count is negative | 6218 | // * count is negative |
| 6231 | // * out_fd has the APPEND flag set | 6219 | // * out_fd has the APPEND flag set |
| 6232 | // Because of the "mmap(2)-like operation" possibility, we fall back to doing read/write | 6220 | // Because of the "mmap(2)-like operation" possibility, we fall back to doing read/write |
| 6233 | // manually, the same as ENOSYS. | 6221 | // manually. |
| 6234 | break :sf; | 6222 | break :sf; |
| 6235 | }, | 6223 | }, |
| 6236 | .AGAIN => return error.WouldBlock, | 6224 | .AGAIN => return error.WouldBlock, |
| ... | @@ -6456,21 +6444,15 @@ pub const CopyFileRangeError = error{ | ... | @@ -6456,21 +6444,15 @@ pub const CopyFileRangeError = error{ |
| 6456 | /// `flags` has different meanings per operating system; refer to the respective man pages. | 6444 | /// `flags` has different meanings per operating system; refer to the respective man pages. |
| 6457 | /// | 6445 | /// |
| 6458 | /// These systems support in-kernel data copying: | 6446 | /// These systems support in-kernel data copying: |
| 6459 | /// * Linux 4.5 (cross-filesystem 5.3) | 6447 | /// * Linux (cross-filesystem from version 5.3) |
| 6460 | /// * FreeBSD 13.0 | 6448 | /// * FreeBSD 13.0 |
| 6461 | /// | 6449 | /// |
| 6462 | /// Other systems fall back to calling `pread` / `pwrite`. | 6450 | /// Other systems fall back to calling `pread` / `pwrite`. |
| 6463 | /// | 6451 | /// |
| 6464 | /// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`. | 6452 | /// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`. |
| 6465 | pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize { | 6453 | pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize { |
| 6466 | const global = struct { | ||
| 6467 | var has_copy_file_range = true; | ||
| 6468 | }; | ||
| 6469 | |||
| 6470 | if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or | 6454 | if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or |
| 6471 | ((comptime builtin.os.isAtLeast(.linux, .{ .major = 4, .minor = 5, .patch = 0 }) orelse false and | 6455 | (comptime builtin.os.tag == .linux and std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }))) |
| 6472 | std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and | ||
| 6473 | @atomicLoad(bool, &global.has_copy_file_range, .monotonic))) | ||
| 6474 | { | 6456 | { |
| 6475 | var off_in_copy: i64 = @bitCast(off_in); | 6457 | var off_in_copy: i64 = @bitCast(off_in); |
| 6476 | var off_out_copy: i64 = @bitCast(off_out); | 6458 | var off_out_copy: i64 = @bitCast(off_out); |
| ... | @@ -6504,10 +6486,6 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len | ... | @@ -6504,10 +6486,6 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len |
| 6504 | .PERM => return error.PermissionDenied, | 6486 | .PERM => return error.PermissionDenied, |
| 6505 | .TXTBSY => return error.SwapFile, | 6487 | .TXTBSY => return error.SwapFile, |
| 6506 | .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback | 6488 | .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback |
| 6507 | .NOSYS => { | ||
| 6508 | @atomicStore(bool, &global.has_copy_file_range, false, .monotonic); | ||
| 6509 | break; | ||
| 6510 | }, | ||
| 6511 | else => |err| return unexpectedErrno(err), | 6489 | else => |err| return unexpectedErrno(err), |
| 6512 | } | 6490 | } |
| 6513 | } | 6491 | } |
| ... | @@ -6775,10 +6753,6 @@ pub const MemFdCreateError = error{ | ... | @@ -6775,10 +6753,6 @@ pub const MemFdCreateError = error{ |
| 6775 | OutOfMemory, | 6753 | OutOfMemory, |
| 6776 | /// Either the name provided exceeded `NAME_MAX`, or invalid flags were passed. | 6754 | /// Either the name provided exceeded `NAME_MAX`, or invalid flags were passed. |
| 6777 | NameTooLong, | 6755 | NameTooLong, |
| 6778 | |||
| 6779 | /// memfd_create is available in Linux 3.17 and later. This error is returned | ||
| 6780 | /// for older kernel versions. | ||
| 6781 | SystemOutdated, | ||
| 6782 | } || UnexpectedError; | 6756 | } || UnexpectedError; |
| 6783 | 6757 | ||
| 6784 | pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t { | 6758 | pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t { |
| ... | @@ -6795,7 +6769,6 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t { | ... | @@ -6795,7 +6769,6 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t { |
| 6795 | .NFILE => return error.SystemFdQuotaExceeded, | 6769 | .NFILE => return error.SystemFdQuotaExceeded, |
| 6796 | .MFILE => return error.ProcessFdQuotaExceeded, | 6770 | .MFILE => return error.ProcessFdQuotaExceeded, |
| 6797 | .NOMEM => return error.OutOfMemory, | 6771 | .NOMEM => return error.OutOfMemory, |
| 6798 | .NOSYS => return error.SystemOutdated, | ||
| 6799 | else => |err| return unexpectedErrno(err), | 6772 | else => |err| return unexpectedErrno(err), |
| 6800 | } | 6773 | } |
| 6801 | }, | 6774 | }, |
| ... | @@ -6915,7 +6888,6 @@ pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t { | ... | @@ -6915,7 +6888,6 @@ pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t { |
| 6915 | .NOMEM => return error.SystemResources, | 6888 | .NOMEM => return error.SystemResources, |
| 6916 | .MFILE => return error.ProcessResources, | 6889 | .MFILE => return error.ProcessResources, |
| 6917 | .NODEV => return error.InodeMountFail, | 6890 | .NODEV => return error.InodeMountFail, |
| 6918 | .NOSYS => return error.SystemOutdated, | ||
| 6919 | else => |err| return unexpectedErrno(err), | 6891 | else => |err| return unexpectedErrno(err), |
| 6920 | } | 6892 | } |
| 6921 | } | 6893 | } |
lib/std/posix/test.zig+1-5| ... | @@ -580,11 +580,7 @@ test "memfd_create" { | ... | @@ -580,11 +580,7 @@ test "memfd_create" { |
| 580 | else => return error.SkipZigTest, | 580 | else => return error.SkipZigTest, |
| 581 | } | 581 | } |
| 582 | 582 | ||
| 583 | const fd = posix.memfd_create("test", 0) catch |err| switch (err) { | 583 | const fd = try posix.memfd_create("test", 0); |
| 584 | // Related: https://github.com/ziglang/zig/issues/4019 | ||
| 585 | error.SystemOutdated => return error.SkipZigTest, | ||
| 586 | else => |e| return e, | ||
| 587 | }; | ||
| 588 | defer posix.close(fd); | 584 | defer posix.close(fd); |
| 589 | try expect((try posix.write(fd, "test")) == 4); | 585 | try expect((try posix.write(fd, "test")) == 4); |
| 590 | try posix.lseek_SET(fd, 0); | 586 | try posix.lseek_SET(fd, 0); |
lib/std/start.zig+1-1| ... | @@ -272,7 +272,7 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -272,7 +272,7 @@ fn _start() callconv(.Naked) noreturn { |
| 272 | \\ bstrins.d $sp, $zero, 3, 0 | 272 | \\ bstrins.d $sp, $zero, 3, 0 |
| 273 | \\ b %[posixCallMainAndExit] | 273 | \\ b %[posixCallMainAndExit] |
| 274 | , | 274 | , |
| 275 | .riscv64 => | 275 | .riscv32, .riscv64 => |
| 276 | \\ li s0, 0 | 276 | \\ li s0, 0 |
| 277 | \\ li ra, 0 | 277 | \\ li ra, 0 |
| 278 | \\ mv a0, sp | 278 | \\ mv a0, sp |
lib/std/zig/target.zig+1-1| ... | @@ -56,7 +56,7 @@ pub const available_libcs = [_]ArchOsAbi{ | ... | @@ -56,7 +56,7 @@ pub const available_libcs = [_]ArchOsAbi{ |
| 56 | .{ .arch = .powerpc, .os = .linux, .abi = .gnueabi }, | 56 | .{ .arch = .powerpc, .os = .linux, .abi = .gnueabi }, |
| 57 | .{ .arch = .powerpc, .os = .linux, .abi = .gnueabihf }, | 57 | .{ .arch = .powerpc, .os = .linux, .abi = .gnueabihf }, |
| 58 | .{ .arch = .powerpc, .os = .linux, .abi = .musl }, | 58 | .{ .arch = .powerpc, .os = .linux, .abi = .musl }, |
| 59 | .{ .arch = .riscv32, .os = .linux, .abi = .gnuilp32, .glibc_min = .{ .major = 2, .minor = 27, .patch = 0 } }, | 59 | .{ .arch = .riscv32, .os = .linux, .abi = .gnuilp32, .glibc_min = .{ .major = 2, .minor = 33, .patch = 0 } }, |
| 60 | .{ .arch = .riscv32, .os = .linux, .abi = .musl }, | 60 | .{ .arch = .riscv32, .os = .linux, .abi = .musl }, |
| 61 | .{ .arch = .riscv64, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 27, .patch = 0 } }, | 61 | .{ .arch = .riscv64, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 27, .patch = 0 } }, |
| 62 | .{ .arch = .riscv64, .os = .linux, .abi = .musl }, | 62 | .{ .arch = .riscv64, .os = .linux, .abi = .musl }, |
src/link/Elf.zig+1-1| ... | @@ -3150,7 +3150,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { | ... | @@ -3150,7 +3150,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 3150 | } | 3150 | } |
| 3151 | } | 3151 | } |
| 3152 | 3152 | ||
| 3153 | if (self.getTarget().cpu.arch == .riscv64 and self.isEffectivelyDynLib()) { | 3153 | if (self.getTarget().cpu.arch.isRISCV() and self.isEffectivelyDynLib()) { |
| 3154 | self.global_pointer_index = try linker_defined.addGlobal("__global_pointer$", self); | 3154 | self.global_pointer_index = try linker_defined.addGlobal("__global_pointer$", self); |
| 3155 | } | 3155 | } |
| 3156 | 3156 |
src/musl.zig+1| ... | @@ -301,6 +301,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progre | ... | @@ -301,6 +301,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progre |
| 301 | pub fn needsCrtiCrtn(target: std.Target) bool { | 301 | pub fn needsCrtiCrtn(target: std.Target) bool { |
| 302 | // zig fmt: off | 302 | // zig fmt: off |
| 303 | return switch (target.cpu.arch) { | 303 | return switch (target.cpu.arch) { |
| 304 | .riscv32, | ||
| 304 | .riscv64, | 305 | .riscv64, |
| 305 | .wasm32, .wasm64 => return false, | 306 | .wasm32, .wasm64 => return false, |
| 306 | else => true, | 307 | else => true, |
tools/gen_stubs.zig+7-2| ... | @@ -2,13 +2,14 @@ | ... | @@ -2,13 +2,14 @@ |
| 2 | //! ./gen_stubs /path/to/musl/build-all >libc.S | 2 | //! ./gen_stubs /path/to/musl/build-all >libc.S |
| 3 | //! | 3 | //! |
| 4 | //! The directory 'build-all' is expected to contain these subdirectories: | 4 | //! The directory 'build-all' is expected to contain these subdirectories: |
| 5 | //! arm x86 mips mips64 powerpc powerpc64 riscv64 x86_64 | 5 | //! arm x86 mips mips64 powerpc powerpc64 riscv32 riscv64 x86_64 |
| 6 | //! | 6 | //! |
| 7 | //! ...each with 'lib/libc.so' inside of them. | 7 | //! ...each with 'lib/libc.so' inside of them. |
| 8 | //! | 8 | //! |
| 9 | //! When building the resulting libc.S file, these defines are required: | 9 | //! When building the resulting libc.S file, these defines are required: |
| 10 | //! * `-DPTR64`: when the architecture is 64-bit | 10 | //! * `-DPTR64`: when the architecture is 64-bit |
| 11 | //! * One of the following, corresponding to the CPU architecture: | 11 | //! * One of the following, corresponding to the CPU architecture: |
| 12 | //! - `-DARCH_riscv32` | ||
| 12 | //! - `-DARCH_riscv64` | 13 | //! - `-DARCH_riscv64` |
| 13 | //! - `-DARCH_mips` | 14 | //! - `-DARCH_mips` |
| 14 | //! - `-DARCH_mips64` | 15 | //! - `-DARCH_mips64` |
| ... | @@ -68,7 +69,8 @@ const MultiSym = struct { | ... | @@ -68,7 +69,8 @@ const MultiSym = struct { |
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | fn is32Only(ms: MultiSym) bool { | 71 | fn is32Only(ms: MultiSym) bool { |
| 71 | return ms.present[archIndex(.riscv64)] == false and | 72 | return ms.present[archIndex(.riscv32)] == true and |
| 73 | ms.present[archIndex(.riscv64)] == false and | ||
| 72 | ms.present[archIndex(.mips)] == true and | 74 | ms.present[archIndex(.mips)] == true and |
| 73 | ms.present[archIndex(.mips64)] == false and | 75 | ms.present[archIndex(.mips64)] == false and |
| 74 | ms.present[archIndex(.x86)] == true and | 76 | ms.present[archIndex(.x86)] == true and |
| ... | @@ -110,6 +112,7 @@ const MultiSym = struct { | ... | @@ -110,6 +112,7 @@ const MultiSym = struct { |
| 110 | 112 | ||
| 111 | fn isPtrSize(ms: MultiSym) bool { | 113 | fn isPtrSize(ms: MultiSym) bool { |
| 112 | const map = .{ | 114 | const map = .{ |
| 115 | .{ .riscv32, 4 }, | ||
| 113 | .{ .riscv64, 8 }, | 116 | .{ .riscv64, 8 }, |
| 114 | .{ .mips, 4 }, | 117 | .{ .mips, 4 }, |
| 115 | .{ .mips64, 8 }, | 118 | .{ .mips64, 8 }, |
| ... | @@ -132,6 +135,7 @@ const MultiSym = struct { | ... | @@ -132,6 +135,7 @@ const MultiSym = struct { |
| 132 | 135 | ||
| 133 | fn isPtr2Size(ms: MultiSym) bool { | 136 | fn isPtr2Size(ms: MultiSym) bool { |
| 134 | const map = .{ | 137 | const map = .{ |
| 138 | .{ .riscv32, 8 }, | ||
| 135 | .{ .riscv64, 16 }, | 139 | .{ .riscv64, 16 }, |
| 136 | .{ .mips, 8 }, | 140 | .{ .mips, 8 }, |
| 137 | .{ .mips64, 16 }, | 141 | .{ .mips64, 16 }, |
| ... | @@ -154,6 +158,7 @@ const MultiSym = struct { | ... | @@ -154,6 +158,7 @@ const MultiSym = struct { |
| 154 | 158 | ||
| 155 | fn isWeak64(ms: MultiSym) bool { | 159 | fn isWeak64(ms: MultiSym) bool { |
| 156 | const map = .{ | 160 | const map = .{ |
| 161 | .{ .riscv32, 1 }, | ||
| 157 | .{ .riscv64, 2 }, | 162 | .{ .riscv64, 2 }, |
| 158 | .{ .mips, 1 }, | 163 | .{ .mips, 1 }, |
| 159 | .{ .mips64, 2 }, | 164 | .{ .mips64, 2 }, |
tools/generate_linux_syscalls.zig+112-48| ... | @@ -10,7 +10,12 @@ const zig = std.zig; | ... | @@ -10,7 +10,12 @@ const zig = std.zig; |
| 10 | const fs = std.fs; | 10 | const fs = std.fs; |
| 11 | 11 | ||
| 12 | const stdlib_renames = std.StaticStringMap([]const u8).initComptime(.{ | 12 | const stdlib_renames = std.StaticStringMap([]const u8).initComptime(.{ |
| 13 | // Remove underscore prefix. | ||
| 14 | .{ "_llseek", "llseek" }, | ||
| 15 | .{ "_newselect", "newselect" }, | ||
| 16 | .{ "_sysctl", "sysctl" }, | ||
| 13 | // Most 64-bit archs. | 17 | // Most 64-bit archs. |
| 18 | .{ "newfstat", "fstat64" }, | ||
| 14 | .{ "newfstatat", "fstatat64" }, | 19 | .{ "newfstatat", "fstatat64" }, |
| 15 | // POWER. | 20 | // POWER. |
| 16 | .{ "sync_file_range2", "sync_file_range" }, | 21 | .{ "sync_file_range2", "sync_file_range" }, |
| ... | @@ -19,6 +24,24 @@ const stdlib_renames = std.StaticStringMap([]const u8).initComptime(.{ | ... | @@ -19,6 +24,24 @@ const stdlib_renames = std.StaticStringMap([]const u8).initComptime(.{ |
| 19 | .{ "arm_fadvise64_64", "fadvise64_64" }, | 24 | .{ "arm_fadvise64_64", "fadvise64_64" }, |
| 20 | }); | 25 | }); |
| 21 | 26 | ||
| 27 | // Only for newer architectures where we use the C preprocessor. | ||
| 28 | const stdlib_renames_new = std.StaticStringMap([]const u8).initComptime(.{ | ||
| 29 | .{ "newuname", "uname" }, | ||
| 30 | .{ "umount", "umount2" }, | ||
| 31 | }); | ||
| 32 | |||
| 33 | // We use this to deal with the fact that multiple syscalls can be mapped to sys_ni_syscall. | ||
| 34 | // Thankfully it's only 2 well-known syscalls in newer kernel ports at the moment. | ||
| 35 | fn getOverridenNameNew(value: []const u8) ?[]const u8 { | ||
| 36 | if (mem.eql(u8, value, "18")) { | ||
| 37 | return "sys_lookup_dcookie"; | ||
| 38 | } else if (mem.eql(u8, value, "42")) { | ||
| 39 | return "sys_nfsservctl"; | ||
| 40 | } else { | ||
| 41 | return null; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 22 | pub fn main() !void { | 45 | pub fn main() !void { |
| 23 | var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); | 46 | var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); |
| 24 | defer arena.deinit(); | 47 | defer arena.deinit(); |
| ... | @@ -60,8 +83,9 @@ pub fn main() !void { | ... | @@ -60,8 +83,9 @@ pub fn main() !void { |
| 60 | // abi is always i386 | 83 | // abi is always i386 |
| 61 | _ = fields.next() orelse return error.Incomplete; | 84 | _ = fields.next() orelse return error.Incomplete; |
| 62 | const name = fields.next() orelse return error.Incomplete; | 85 | const name = fields.next() orelse return error.Incomplete; |
| 86 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | ||
| 63 | 87 | ||
| 64 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(name), number }); | 88 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); |
| 65 | } | 89 | } |
| 66 | 90 | ||
| 67 | try writer.writeAll("};\n\n"); | 91 | try writer.writeAll("};\n\n"); |
| ... | @@ -80,8 +104,8 @@ pub fn main() !void { | ... | @@ -80,8 +104,8 @@ pub fn main() !void { |
| 80 | // The x32 abi syscalls are always at the end. | 104 | // The x32 abi syscalls are always at the end. |
| 81 | if (mem.eql(u8, abi, "x32")) break; | 105 | if (mem.eql(u8, abi, "x32")) break; |
| 82 | const name = fields.next() orelse return error.Incomplete; | 106 | const name = fields.next() orelse return error.Incomplete; |
| 83 | |||
| 84 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | 107 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; |
| 108 | |||
| 85 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); | 109 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); |
| 86 | } | 110 | } |
| 87 | 111 | ||
| ... | @@ -105,8 +129,8 @@ pub fn main() !void { | ... | @@ -105,8 +129,8 @@ pub fn main() !void { |
| 105 | const abi = fields.next() orelse return error.Incomplete; | 129 | const abi = fields.next() orelse return error.Incomplete; |
| 106 | if (mem.eql(u8, abi, "oabi")) continue; | 130 | if (mem.eql(u8, abi, "oabi")) continue; |
| 107 | const name = fields.next() orelse return error.Incomplete; | 131 | const name = fields.next() orelse return error.Incomplete; |
| 108 | |||
| 109 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | 132 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; |
| 133 | |||
| 110 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); | 134 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); |
| 111 | } | 135 | } |
| 112 | 136 | ||
| ... | @@ -136,8 +160,9 @@ pub fn main() !void { | ... | @@ -136,8 +160,9 @@ pub fn main() !void { |
| 136 | const abi = fields.next() orelse return error.Incomplete; | 160 | const abi = fields.next() orelse return error.Incomplete; |
| 137 | if (mem.eql(u8, abi, "32")) continue; | 161 | if (mem.eql(u8, abi, "32")) continue; |
| 138 | const name = fields.next() orelse return error.Incomplete; | 162 | const name = fields.next() orelse return error.Incomplete; |
| 163 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | ||
| 139 | 164 | ||
| 140 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(name), number }); | 165 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); |
| 141 | } | 166 | } |
| 142 | 167 | ||
| 143 | try writer.writeAll("};\n\n"); | 168 | try writer.writeAll("};\n\n"); |
| ... | @@ -161,8 +186,9 @@ pub fn main() !void { | ... | @@ -161,8 +186,9 @@ pub fn main() !void { |
| 161 | _ = fields.next() orelse return error.Incomplete; | 186 | _ = fields.next() orelse return error.Incomplete; |
| 162 | const name = fields.next() orelse return error.Incomplete; | 187 | const name = fields.next() orelse return error.Incomplete; |
| 163 | if (mem.startsWith(u8, name, "unused")) continue; | 188 | if (mem.startsWith(u8, name, "unused")) continue; |
| 189 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | ||
| 164 | 190 | ||
| 165 | try writer.print(" {p} = Linux + {s},\n", .{ zig.fmtId(name), number }); | 191 | try writer.print(" {p} = Linux + {s},\n", .{ zig.fmtId(fixed_name), number }); |
| 166 | } | 192 | } |
| 167 | 193 | ||
| 168 | try writer.writeAll("};\n\n"); | 194 | try writer.writeAll("};\n\n"); |
| ... | @@ -232,11 +258,6 @@ pub fn main() !void { | ... | @@ -232,11 +258,6 @@ pub fn main() !void { |
| 232 | // Newer architectures (starting with aarch64 c. 2012) now use the same C | 258 | // Newer architectures (starting with aarch64 c. 2012) now use the same C |
| 233 | // header file for their syscall numbers. Arch-specific headers are used to | 259 | // header file for their syscall numbers. Arch-specific headers are used to |
| 234 | // define pre-proc. vars that add additional (usually obsolete) syscalls. | 260 | // define pre-proc. vars that add additional (usually obsolete) syscalls. |
| 235 | // | ||
| 236 | // TODO: | ||
| 237 | // - It would be better to use libclang/translate-c directly to extract the definitions. | ||
| 238 | // - The `-dD` option only does minimal pre-processing and doesn't resolve addition, | ||
| 239 | // so arch specific syscalls are dealt with manually. | ||
| 240 | { | 261 | { |
| 241 | try writer.writeAll("pub const Arm64 = enum(usize) {\n"); | 262 | try writer.writeAll("pub const Arm64 = enum(usize) {\n"); |
| 242 | 263 | ||
| ... | @@ -254,6 +275,8 @@ pub fn main() !void { | ... | @@ -254,6 +275,8 @@ pub fn main() !void { |
| 254 | // Using -I=[dir] includes the zig linux headers, which we don't want. | 275 | // Using -I=[dir] includes the zig linux headers, which we don't want. |
| 255 | "-Iinclude", | 276 | "-Iinclude", |
| 256 | "-Iinclude/uapi", | 277 | "-Iinclude/uapi", |
| 278 | // Output the syscall in a format we can easily recognize. | ||
| 279 | "-D __SYSCALL(nr, nm)=zigsyscall nm nr", | ||
| 257 | "arch/arm64/include/uapi/asm/unistd.h", | 280 | "arch/arm64/include/uapi/asm/unistd.h", |
| 258 | }; | 281 | }; |
| 259 | 282 | ||
| ... | @@ -277,32 +300,79 @@ pub fn main() !void { | ... | @@ -277,32 +300,79 @@ pub fn main() !void { |
| 277 | }; | 300 | }; |
| 278 | 301 | ||
| 279 | var lines = mem.tokenizeScalar(u8, defines, '\n'); | 302 | var lines = mem.tokenizeScalar(u8, defines, '\n'); |
| 280 | loop: while (lines.next()) |line| { | 303 | while (lines.next()) |line| { |
| 281 | var fields = mem.tokenizeAny(u8, line, " \t"); | 304 | var fields = mem.tokenizeAny(u8, line, " "); |
| 282 | const cmd = fields.next() orelse return error.Incomplete; | 305 | const prefix = fields.next() orelse return error.Incomplete; |
| 283 | if (!mem.eql(u8, cmd, "#define")) continue; | ||
| 284 | const define = fields.next() orelse return error.Incomplete; | ||
| 285 | const number = fields.next() orelse continue; | ||
| 286 | 306 | ||
| 287 | if (!std.ascii.isDigit(number[0])) continue; | 307 | if (!mem.eql(u8, prefix, "zigsyscall")) continue; |
| 288 | if (!mem.startsWith(u8, define, "__NR")) continue; | ||
| 289 | const name = mem.trimLeft(u8, mem.trimLeft(u8, define, "__NR3264_"), "__NR_"); | ||
| 290 | if (mem.eql(u8, name, "arch_specific_syscall")) continue; | ||
| 291 | if (mem.eql(u8, name, "syscalls")) break :loop; | ||
| 292 | 308 | ||
| 293 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | 309 | const sys_name = fields.next() orelse return error.Incomplete; |
| 294 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); | 310 | const value = fields.rest(); |
| 311 | const name = (getOverridenNameNew(value) orelse sys_name)["sys_".len..]; | ||
| 312 | const fixed_name = if (stdlib_renames_new.get(name)) |f| f else if (stdlib_renames.get(name)) |f| f else name; | ||
| 313 | |||
| 314 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), value }); | ||
| 295 | } | 315 | } |
| 296 | 316 | ||
| 297 | try writer.writeAll("};\n\n"); | 317 | try writer.writeAll("};\n\n"); |
| 298 | } | 318 | } |
| 299 | { | 319 | { |
| 300 | try writer.writeAll( | 320 | try writer.writeAll("pub const RiscV32 = enum(usize) {\n"); |
| 301 | \\pub const RiscV64 = enum(usize) { | 321 | |
| 302 | \\ pub const arch_specific_syscall = 244; | 322 | const child_args = [_][]const u8{ |
| 303 | \\ | 323 | zig_exe, |
| 304 | \\ | 324 | "cc", |
| 305 | ); | 325 | "-target", |
| 326 | "riscv32-linux-gnuilp32", | ||
| 327 | "-E", | ||
| 328 | "-dD", | ||
| 329 | "-P", | ||
| 330 | "-nostdinc", | ||
| 331 | "-Iinclude", | ||
| 332 | "-Iinclude/uapi", | ||
| 333 | "-Iarch/riscv/include/uapi", | ||
| 334 | "-D __SYSCALL(nr, nm)=zigsyscall nm nr", | ||
| 335 | "arch/riscv/include/uapi/asm/unistd.h", | ||
| 336 | }; | ||
| 337 | |||
| 338 | const child_result = try std.process.Child.run(.{ | ||
| 339 | .allocator = allocator, | ||
| 340 | .argv = &child_args, | ||
| 341 | .cwd = linux_path, | ||
| 342 | .cwd_dir = linux_dir, | ||
| 343 | }); | ||
| 344 | if (child_result.stderr.len > 0) std.debug.print("{s}\n", .{child_result.stderr}); | ||
| 345 | |||
| 346 | const defines = switch (child_result.term) { | ||
| 347 | .Exited => |code| if (code == 0) child_result.stdout else { | ||
| 348 | std.debug.print("zig cc exited with code {d}\n", .{code}); | ||
| 349 | std.process.exit(1); | ||
| 350 | }, | ||
| 351 | else => { | ||
| 352 | std.debug.print("zig cc crashed\n", .{}); | ||
| 353 | std.process.exit(1); | ||
| 354 | }, | ||
| 355 | }; | ||
| 356 | |||
| 357 | var lines = mem.tokenizeScalar(u8, defines, '\n'); | ||
| 358 | while (lines.next()) |line| { | ||
| 359 | var fields = mem.tokenizeAny(u8, line, " "); | ||
| 360 | const prefix = fields.next() orelse return error.Incomplete; | ||
| 361 | |||
| 362 | if (!mem.eql(u8, prefix, "zigsyscall")) continue; | ||
| 363 | |||
| 364 | const sys_name = fields.next() orelse return error.Incomplete; | ||
| 365 | const value = fields.rest(); | ||
| 366 | const name = (getOverridenNameNew(value) orelse sys_name)["sys_".len..]; | ||
| 367 | const fixed_name = if (stdlib_renames_new.get(name)) |f| f else if (stdlib_renames.get(name)) |f| f else name; | ||
| 368 | |||
| 369 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), value }); | ||
| 370 | } | ||
| 371 | |||
| 372 | try writer.writeAll("};\n\n"); | ||
| 373 | } | ||
| 374 | { | ||
| 375 | try writer.writeAll("pub const RiscV64 = enum(usize) {\n"); | ||
| 306 | 376 | ||
| 307 | const child_args = [_][]const u8{ | 377 | const child_args = [_][]const u8{ |
| 308 | zig_exe, | 378 | zig_exe, |
| ... | @@ -315,6 +385,8 @@ pub fn main() !void { | ... | @@ -315,6 +385,8 @@ pub fn main() !void { |
| 315 | "-nostdinc", | 385 | "-nostdinc", |
| 316 | "-Iinclude", | 386 | "-Iinclude", |
| 317 | "-Iinclude/uapi", | 387 | "-Iinclude/uapi", |
| 388 | "-Iarch/riscv/include/uapi", | ||
| 389 | "-D __SYSCALL(nr, nm)=zigsyscall nm nr", | ||
| 318 | "arch/riscv/include/uapi/asm/unistd.h", | 390 | "arch/riscv/include/uapi/asm/unistd.h", |
| 319 | }; | 391 | }; |
| 320 | 392 | ||
| ... | @@ -338,29 +410,21 @@ pub fn main() !void { | ... | @@ -338,29 +410,21 @@ pub fn main() !void { |
| 338 | }; | 410 | }; |
| 339 | 411 | ||
| 340 | var lines = mem.tokenizeScalar(u8, defines, '\n'); | 412 | var lines = mem.tokenizeScalar(u8, defines, '\n'); |
| 341 | loop: while (lines.next()) |line| { | 413 | while (lines.next()) |line| { |
| 342 | var fields = mem.tokenizeAny(u8, line, " \t"); | 414 | var fields = mem.tokenizeAny(u8, line, " "); |
| 343 | const cmd = fields.next() orelse return error.Incomplete; | 415 | const prefix = fields.next() orelse return error.Incomplete; |
| 344 | if (!mem.eql(u8, cmd, "#define")) continue; | ||
| 345 | const define = fields.next() orelse return error.Incomplete; | ||
| 346 | const number = fields.next() orelse continue; | ||
| 347 | 416 | ||
| 348 | if (!std.ascii.isDigit(number[0])) continue; | 417 | if (!mem.eql(u8, prefix, "zigsyscall")) continue; |
| 349 | if (!mem.startsWith(u8, define, "__NR")) continue; | ||
| 350 | const name = mem.trimLeft(u8, mem.trimLeft(u8, define, "__NR3264_"), "__NR_"); | ||
| 351 | if (mem.eql(u8, name, "arch_specific_syscall")) continue; | ||
| 352 | if (mem.eql(u8, name, "syscalls")) break :loop; | ||
| 353 | 418 | ||
| 354 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | 419 | const sys_name = fields.next() orelse return error.Incomplete; |
| 355 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); | 420 | const value = fields.rest(); |
| 421 | const name = (getOverridenNameNew(value) orelse sys_name)["sys_".len..]; | ||
| 422 | const fixed_name = if (stdlib_renames_new.get(name)) |f| f else if (stdlib_renames.get(name)) |f| f else name; | ||
| 423 | |||
| 424 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), value }); | ||
| 356 | } | 425 | } |
| 357 | 426 | ||
| 358 | try writer.writeAll( | 427 | try writer.writeAll("};\n\n"); |
| 359 | \\ | ||
| 360 | \\ riscv_flush_icache = arch_specific_syscall + 15, | ||
| 361 | \\}; | ||
| 362 | \\ | ||
| 363 | ); | ||
| 364 | } | 428 | } |
| 365 | { | 429 | { |
| 366 | try writer.writeAll( | 430 | try writer.writeAll( |