| 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 | 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 | 356 | .riscv64 => { |
| 323 | 357 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 324 | 358 | // a0, a1, a2, a3, a4, a5, a6 |
lib/std/Target.zig+10-1| ... | ... | @@ -720,7 +720,16 @@ pub const Abi = enum { |
| 720 | 720 | |
| 721 | 721 | pub inline fn isGnu(abi: Abi) bool { |
| 722 | 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 | 733 | else => false, |
| 725 | 734 | }; |
| 726 | 735 | } |
lib/std/Thread.zig+31-18| ... | ... | @@ -1082,11 +1082,11 @@ const LinuxThreadImpl = struct { |
| 1082 | 1082 | fn freeAndExit(self: *ThreadCompletion) noreturn { |
| 1083 | 1083 | switch (target.cpu.arch) { |
| 1084 | 1084 | .x86 => asm volatile ( |
| 1085 | \\ movl $91, %%eax | |
| 1085 | \\ movl $91, %%eax # SYS_munmap | |
| 1086 | 1086 | \\ movl %[ptr], %%ebx |
| 1087 | 1087 | \\ movl %[len], %%ecx |
| 1088 | 1088 | \\ int $128 |
| 1089 | \\ movl $1, %%eax | |
| 1089 | \\ movl $1, %%eax # SYS_exit | |
| 1090 | 1090 | \\ movl $0, %%ebx |
| 1091 | 1091 | \\ int $128 |
| 1092 | 1092 | : |
| ... | ... | @@ -1095,9 +1095,9 @@ const LinuxThreadImpl = struct { |
| 1095 | 1095 | : "memory" |
| 1096 | 1096 | ), |
| 1097 | 1097 | .x86_64 => asm volatile ( |
| 1098 | \\ movq $11, %%rax | |
| 1098 | \\ movq $11, %%rax # SYS_munmap | |
| 1099 | 1099 | \\ syscall |
| 1100 | \\ movq $60, %%rax | |
| 1100 | \\ movq $60, %%rax # SYS_exit | |
| 1101 | 1101 | \\ movq $1, %%rdi |
| 1102 | 1102 | \\ syscall |
| 1103 | 1103 | : |
| ... | ... | @@ -1105,11 +1105,11 @@ const LinuxThreadImpl = struct { |
| 1105 | 1105 | [len] "{rsi}" (self.mapped.len), |
| 1106 | 1106 | ), |
| 1107 | 1107 | .arm, .armeb, .thumb, .thumbeb => asm volatile ( |
| 1108 | \\ mov r7, #91 | |
| 1108 | \\ mov r7, #91 // SYS_munmap | |
| 1109 | 1109 | \\ mov r0, %[ptr] |
| 1110 | 1110 | \\ mov r1, %[len] |
| 1111 | 1111 | \\ svc 0 |
| 1112 | \\ mov r7, #1 | |
| 1112 | \\ mov r7, #1 // SYS_exit | |
| 1113 | 1113 | \\ mov r0, #0 |
| 1114 | 1114 | \\ svc 0 |
| 1115 | 1115 | : |
| ... | ... | @@ -1118,11 +1118,11 @@ const LinuxThreadImpl = struct { |
| 1118 | 1118 | : "memory" |
| 1119 | 1119 | ), |
| 1120 | 1120 | .aarch64, .aarch64_be => asm volatile ( |
| 1121 | \\ mov x8, #215 | |
| 1121 | \\ mov x8, #215 // SYS_munmap | |
| 1122 | 1122 | \\ mov x0, %[ptr] |
| 1123 | 1123 | \\ mov x1, %[len] |
| 1124 | 1124 | \\ svc 0 |
| 1125 | \\ mov x8, #93 | |
| 1125 | \\ mov x8, #93 // SYS_exit | |
| 1126 | 1126 | \\ mov x0, #0 |
| 1127 | 1127 | \\ svc 0 |
| 1128 | 1128 | : |
| ... | ... | @@ -1132,11 +1132,11 @@ const LinuxThreadImpl = struct { |
| 1132 | 1132 | ), |
| 1133 | 1133 | .mips, .mipsel => asm volatile ( |
| 1134 | 1134 | \\ move $sp, $25 |
| 1135 | \\ li $2, 4091 | |
| 1135 | \\ li $2, 4091 # SYS_munmap | |
| 1136 | 1136 | \\ move $4, %[ptr] |
| 1137 | 1137 | \\ move $5, %[len] |
| 1138 | 1138 | \\ syscall |
| 1139 | \\ li $2, 4001 | |
| 1139 | \\ li $2, 4001 # SYS_exit | |
| 1140 | 1140 | \\ li $4, 0 |
| 1141 | 1141 | \\ syscall |
| 1142 | 1142 | : |
| ... | ... | @@ -1145,11 +1145,11 @@ const LinuxThreadImpl = struct { |
| 1145 | 1145 | : "memory" |
| 1146 | 1146 | ), |
| 1147 | 1147 | .mips64, .mips64el => asm volatile ( |
| 1148 | \\ li $2, 4091 | |
| 1148 | \\ li $2, 4091 # SYS_munmap | |
| 1149 | 1149 | \\ move $4, %[ptr] |
| 1150 | 1150 | \\ move $5, %[len] |
| 1151 | 1151 | \\ syscall |
| 1152 | \\ li $2, 4001 | |
| 1152 | \\ li $2, 4001 # SYS_exit | |
| 1153 | 1153 | \\ li $4, 0 |
| 1154 | 1154 | \\ syscall |
| 1155 | 1155 | : |
| ... | ... | @@ -1158,11 +1158,11 @@ const LinuxThreadImpl = struct { |
| 1158 | 1158 | : "memory" |
| 1159 | 1159 | ), |
| 1160 | 1160 | .powerpc, .powerpcle, .powerpc64, .powerpc64le => asm volatile ( |
| 1161 | \\ li 0, 91 | |
| 1161 | \\ li 0, 91 # SYS_munmap | |
| 1162 | 1162 | \\ mr %[ptr], 3 |
| 1163 | 1163 | \\ mr %[len], 4 |
| 1164 | 1164 | \\ sc |
| 1165 | \\ li 0, 1 | |
| 1165 | \\ li 0, 1 # SYS_exit | |
| 1166 | 1166 | \\ li 3, 0 |
| 1167 | 1167 | \\ sc |
| 1168 | 1168 | \\ blr |
| ... | ... | @@ -1171,12 +1171,25 @@ const LinuxThreadImpl = struct { |
| 1171 | 1171 | [len] "r" (self.mapped.len), |
| 1172 | 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 | 1187 | .riscv64 => asm volatile ( |
| 1175 | \\ li a7, 215 | |
| 1188 | \\ li a7, 215 # SYS_munmap | |
| 1176 | 1189 | \\ mv a0, %[ptr] |
| 1177 | 1190 | \\ mv a1, %[len] |
| 1178 | 1191 | \\ ecall |
| 1179 | \\ li a7, 93 | |
| 1192 | \\ li a7, 93 # SYS_exit | |
| 1180 | 1193 | \\ mv a0, zero |
| 1181 | 1194 | \\ ecall |
| 1182 | 1195 | : |
| ... | ... | @@ -1196,14 +1209,14 @@ const LinuxThreadImpl = struct { |
| 1196 | 1209 | \\ ba 1b |
| 1197 | 1210 | \\ restore |
| 1198 | 1211 | \\ 2: |
| 1199 | \\ mov 73, %%g1 | |
| 1212 | \\ mov 73, %%g1 # SYS_munmap | |
| 1200 | 1213 | \\ mov %[ptr], %%o0 |
| 1201 | 1214 | \\ mov %[len], %%o1 |
| 1202 | 1215 | \\ # Flush register window contents to prevent background |
| 1203 | 1216 | \\ # memory access before unmapping the stack. |
| 1204 | 1217 | \\ flushw |
| 1205 | 1218 | \\ t 0x6d |
| 1206 | \\ mov 1, %%g1 | |
| 1219 | \\ mov 1, %%g1 # SYS_exit | |
| 1207 | 1220 | \\ mov 1, %%o0 |
| 1208 | 1221 | \\ t 0x6d |
| 1209 | 1222 | : |
lib/std/debug.zig+2-1| ... | ... | @@ -747,7 +747,8 @@ pub const StackIterator = struct { |
| 747 | 747 | .SUCCESS => return bytes_read == buf.len, |
| 748 | 748 | .FAULT => return false, |
| 749 | 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 | 752 | else => unreachable, // unexpected |
| 752 | 753 | } |
| 753 | 754 | var path_buf: [ |
lib/std/fs/Dir.zig+27-2| ... | ... | @@ -334,7 +334,6 @@ pub const Iterator = switch (native_os) { |
| 334 | 334 | first_iter: bool, |
| 335 | 335 | |
| 336 | 336 | const Self = @This(); |
| 337 | const linux = std.os.linux; | |
| 338 | 337 | |
| 339 | 338 | pub const Error = IteratorError; |
| 340 | 339 | |
| ... | ... | @@ -2690,8 +2689,33 @@ pub fn statFile(self: Dir, sub_path: []const u8) StatFileError!Stat { |
| 2690 | 2689 | const st = try std.os.fstatat_wasi(self.fd, sub_path, .{ .SYMLINK_FOLLOW = true }); |
| 2691 | 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 | 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 | 2721 | pub const ChmodError = File.ChmodError; |
| ... | ... | @@ -2751,6 +2775,7 @@ const path = fs.path; |
| 2751 | 2775 | const fs = std.fs; |
| 2752 | 2776 | const Allocator = std.mem.Allocator; |
| 2753 | 2777 | const assert = std.debug.assert; |
| 2778 | const linux = std.os.linux; | |
| 2754 | 2779 | const windows = std.os.windows; |
| 2755 | 2780 | const native_os = builtin.os.tag; |
| 2756 | 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 | 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 | 347 | /// TODO: integrate with async I/O |
| 348 | 348 | pub fn getPos(self: File) GetSeekPosError!u64 { |
| ... | ... | @@ -357,7 +357,7 @@ pub fn getEndPos(self: File) GetSeekPosError!u64 { |
| 357 | 357 | return (try self.stat()).size; |
| 358 | 358 | } |
| 359 | 359 | |
| 360 | pub const ModeError = posix.FStatError; | |
| 360 | pub const ModeError = StatError; | |
| 361 | 361 | |
| 362 | 362 | /// TODO: integrate with async I/O |
| 363 | 363 | pub fn mode(self: File) ModeError!Mode { |
| ... | ... | @@ -392,7 +392,7 @@ pub const Stat = struct { |
| 392 | 392 | /// Last status/metadata change time in nanoseconds, relative to UTC 1970-01-01. |
| 393 | 393 | ctime: i128, |
| 394 | 394 | |
| 395 | pub fn fromSystem(st: posix.Stat) Stat { | |
| 395 | pub fn fromPosix(st: posix.Stat) Stat { | |
| 396 | 396 | const atime = st.atime(); |
| 397 | 397 | const mtime = st.mtime(); |
| 398 | 398 | const ctime = st.ctime(); |
| ... | ... | @@ -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 | 454 | pub fn fromWasi(st: std.os.wasi.filestat_t) Stat { |
| 430 | 455 | return .{ |
| 431 | 456 | .inode = st.ino, |
| ... | ... | @@ -502,8 +527,34 @@ pub fn stat(self: File) StatError!Stat { |
| 502 | 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 | 556 | const st = try posix.fstat(self.handle); |
| 506 | return Stat.fromSystem(st); | |
| 557 | return Stat.fromPosix(st); | |
| 507 | 558 | } |
| 508 | 559 | |
| 509 | 560 | pub const ChmodError = posix.FChmodError; |
| ... | ... | @@ -731,7 +782,7 @@ pub const Metadata = struct { |
| 731 | 782 | |
| 732 | 783 | /// Returns the time the file was created in nanoseconds since UTC 1970-01-01 |
| 733 | 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 | 786 | /// On Unices, this returns null if the filesystem or OS does not support creation times |
| 736 | 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 | 788 | pub fn created(self: Self) ?i128 { |
| ... | ... | @@ -822,7 +873,6 @@ pub const MetadataUnix = struct { |
| 822 | 873 | }; |
| 823 | 874 | |
| 824 | 875 | /// `MetadataUnix`, but using Linux's `statx` syscall. |
| 825 | /// On Linux versions below 4.11, `statx` will be filled with data from stat. | |
| 826 | 876 | pub const MetadataLinux = struct { |
| 827 | 877 | statx: std.os.linux.Statx, |
| 828 | 878 | |
| ... | ... | @@ -1010,34 +1060,29 @@ pub fn metadata(self: File) MetadataError!Metadata { |
| 1010 | 1060 | }; |
| 1011 | 1061 | }, |
| 1012 | 1062 | .linux => blk: { |
| 1013 | const l = std.os.linux; | |
| 1014 | var stx = std.mem.zeroes(l.Statx); | |
| 1015 | const rcx = l.statx(self.handle, "\x00", l.AT.EMPTY_PATH, l.STATX_TYPE | | |
| 1016 | l.STATX_MODE | l.STATX_ATIME | l.STATX_MTIME | l.STATX_BTIME, &stx); | |
| 1017 | ||
| 1018 | switch (posix.errno(rcx)) { | |
| 1063 | var stx = std.mem.zeroes(linux.Statx); | |
| 1064 | ||
| 1065 | // We are gathering information for Metadata, which is meant to contain all the | |
| 1066 | // native OS information about the file, so use all known flags. | |
| 1067 | const rc = linux.statx( | |
| 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 | 1076 | .SUCCESS => {}, |
| 1020 | // NOSYS happens when `statx` is unsupported, which is the case on kernel versions before 4.11 | |
| 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 | }, | |
| 1077 | .ACCES => unreachable, | |
| 1038 | 1078 | .BADF => unreachable, |
| 1039 | 1079 | .FAULT => unreachable, |
| 1080 | .INVAL => unreachable, | |
| 1081 | .LOOP => unreachable, | |
| 1082 | .NAMETOOLONG => unreachable, | |
| 1083 | .NOENT => unreachable, | |
| 1040 | 1084 | .NOMEM => return error.SystemResources, |
| 1085 | .NOTDIR => unreachable, | |
| 1041 | 1086 | else => |err| return posix.unexpectedErrno(err), |
| 1042 | 1087 | } |
| 1043 | 1088 | |
| ... | ... | @@ -1731,6 +1776,7 @@ const posix = std.posix; |
| 1731 | 1776 | const io = std.io; |
| 1732 | 1777 | const math = std.math; |
| 1733 | 1778 | const assert = std.debug.assert; |
| 1779 | const linux = std.os.linux; | |
| 1734 | 1780 | const windows = std.os.windows; |
| 1735 | 1781 | const Os = std.builtin.Os; |
| 1736 | 1782 | const maxInt = std.math.maxInt; |
lib/std/os/linux.zig+61-37| ... | ... | @@ -39,6 +39,7 @@ const arch_bits = switch (native_arch) { |
| 39 | 39 | .x86_64 => @import("linux/x86_64.zig"), |
| 40 | 40 | .aarch64, .aarch64_be => @import("linux/arm64.zig"), |
| 41 | 41 | .arm, .armeb, .thumb, .thumbeb => @import("linux/arm-eabi.zig"), |
| 42 | .riscv32 => @import("linux/riscv32.zig"), | |
| 42 | 43 | .riscv64 => @import("linux/riscv64.zig"), |
| 43 | 44 | .sparc64 => @import("linux/sparc64.zig"), |
| 44 | 45 | .mips, .mipsel => @import("linux/mips.zig"), |
| ... | ... | @@ -104,6 +105,7 @@ pub const SYS = switch (@import("builtin").cpu.arch) { |
| 104 | 105 | .x86_64 => syscalls.X64, |
| 105 | 106 | .aarch64, .aarch64_be => syscalls.Arm64, |
| 106 | 107 | .arm, .armeb, .thumb, .thumbeb => syscalls.Arm, |
| 108 | .riscv32 => syscalls.RiscV32, | |
| 107 | 109 | .riscv64 => syscalls.RiscV64, |
| 108 | 110 | .sparc64 => syscalls.Sparc64, |
| 109 | 111 | .mips, .mipsel => syscalls.Mips, |
| ... | ... | @@ -163,7 +165,7 @@ pub const MAP = switch (native_arch) { |
| 163 | 165 | UNINITIALIZED: bool = false, |
| 164 | 166 | _: u5 = 0, |
| 165 | 167 | }, |
| 166 | .riscv64 => packed struct(u32) { | |
| 168 | .riscv32, .riscv64 => packed struct(u32) { | |
| 167 | 169 | TYPE: MAP_TYPE, |
| 168 | 170 | FIXED: bool = false, |
| 169 | 171 | ANONYMOUS: bool = false, |
| ... | ... | @@ -268,7 +270,7 @@ pub const O = switch (native_arch) { |
| 268 | 270 | TMPFILE: bool = false, |
| 269 | 271 | _: u9 = 0, |
| 270 | 272 | }, |
| 271 | .x86, .riscv64 => packed struct(u32) { | |
| 273 | .x86, .riscv32, .riscv64 => packed struct(u32) { | |
| 272 | 274 | ACCMODE: ACCMODE = .RDONLY, |
| 273 | 275 | _2: u4 = 0, |
| 274 | 276 | CREAT: bool = false, |
| ... | ... | @@ -474,7 +476,7 @@ pub fn dup2(old: i32, new: i32) usize { |
| 474 | 476 | } else { |
| 475 | 477 | if (old == new) { |
| 476 | 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 | 480 | if (@as(isize, @bitCast(rc)) < 0) return rc; |
| 479 | 481 | } |
| 480 | 482 | return @as(usize, @intCast(old)); |
| ... | ... | @@ -1211,7 +1213,7 @@ pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize { |
| 1211 | 1213 | // NOTE: The offset parameter splitting is independent from the target |
| 1212 | 1214 | // endianness. |
| 1213 | 1215 | return syscall5( |
| 1214 | ._llseek, | |
| 1216 | .llseek, | |
| 1215 | 1217 | @as(usize, @bitCast(@as(isize, fd))), |
| 1216 | 1218 | @as(usize, @truncate(offset >> 32)), |
| 1217 | 1219 | @as(usize, @truncate(offset)), |
| ... | ... | @@ -1370,7 +1372,11 @@ pub fn waitid(id_type: P, id: i32, infop: *siginfo_t, flags: u32) usize { |
| 1370 | 1372 | } |
| 1371 | 1373 | |
| 1372 | 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 | 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 | 1842 | } |
| 1837 | 1843 | |
| 1838 | 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 | 1850 | return syscall2(.fstat64, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(stat_buf)); |
| 1841 | 1851 | } else { |
| 1842 | 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 | 1854 | } |
| 1845 | 1855 | |
| 1846 | 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 | 1862 | return syscall2(.stat64, @intFromPtr(pathname), @intFromPtr(statbuf)); |
| 1849 | 1863 | } else { |
| 1850 | 1864 | return syscall2(.stat, @intFromPtr(pathname), @intFromPtr(statbuf)); |
| ... | ... | @@ -1852,7 +1866,11 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize { |
| 1852 | 1866 | } |
| 1853 | 1867 | |
| 1854 | 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 | 1874 | return syscall2(.lstat64, @intFromPtr(pathname), @intFromPtr(statbuf)); |
| 1857 | 1875 | } else { |
| 1858 | 1876 | return syscall2(.lstat, @intFromPtr(pathname), @intFromPtr(statbuf)); |
| ... | ... | @@ -1860,7 +1878,11 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize { |
| 1860 | 1878 | } |
| 1861 | 1879 | |
| 1862 | 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 | 1886 | return syscall4(.fstatat64, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), flags); |
| 1865 | 1887 | } else { |
| 1866 | 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 | 1890 | } |
| 1869 | 1891 | |
| 1870 | 1892 | pub fn statx(dirfd: i32, path: [*:0]const u8, flags: u32, mask: u32, statx_buf: *Statx) usize { |
| 1871 | if (@hasField(SYS, "statx")) { | |
| 1872 | return syscall5( | |
| 1873 | .statx, | |
| 1874 | @as(usize, @bitCast(@as(isize, dirfd))), | |
| 1875 | @intFromPtr(path), | |
| 1876 | flags, | |
| 1877 | mask, | |
| 1878 | @intFromPtr(statx_buf), | |
| 1879 | ); | |
| 1880 | } | |
| 1881 | return @as(usize, @bitCast(-@as(isize, @intFromEnum(E.NOSYS)))); | |
| 1893 | return syscall5( | |
| 1894 | .statx, | |
| 1895 | @as(usize, @bitCast(@as(isize, dirfd))), | |
| 1896 | @intFromPtr(path), | |
| 1897 | flags, | |
| 1898 | mask, | |
| 1899 | @intFromPtr(statx_buf), | |
| 1900 | ); | |
| 1882 | 1901 | } |
| 1883 | 1902 | |
| 1884 | 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 | 2217 | } |
| 2199 | 2218 | |
| 2200 | 2219 | pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize { |
| 2201 | if (comptime builtin.cpu.arch.isMIPS()) { | |
| 2202 | // MIPS requires a 7 argument syscall | |
| 2220 | if (comptime native_arch.isARM() or native_arch.isPPC()) { | |
| 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 | 2224 | const offset_halves = splitValue64(offset); |
| 2205 | 2225 | const length_halves = splitValue64(len); |
| 2206 | 2226 | |
| 2207 | return syscall7( | |
| 2208 | .fadvise64, | |
| 2227 | return syscall6( | |
| 2228 | .fadvise64_64, | |
| 2209 | 2229 | @as(usize, @bitCast(@as(isize, fd))), |
| 2210 | 0, | |
| 2230 | advice, | |
| 2211 | 2231 | offset_halves[0], |
| 2212 | 2232 | offset_halves[1], |
| 2213 | 2233 | length_halves[0], |
| 2214 | 2234 | length_halves[1], |
| 2215 | advice, | |
| 2216 | 2235 | ); |
| 2217 | } else if (comptime builtin.cpu.arch.isARM()) { | |
| 2218 | // ARM reorders the arguments | |
| 2236 | } else if (comptime native_arch == .mips or native_arch == .mipsel) { | |
| 2237 | // MIPS O32 does not deal with the register alignment issue, so pass a dummy value. | |
| 2219 | 2238 | |
| 2220 | 2239 | const offset_halves = splitValue64(offset); |
| 2221 | 2240 | const length_halves = splitValue64(len); |
| 2222 | 2241 | |
| 2223 | return syscall6( | |
| 2224 | .fadvise64_64, | |
| 2242 | return syscall7( | |
| 2243 | .fadvise64, | |
| 2225 | 2244 | @as(usize, @bitCast(@as(isize, fd))), |
| 2226 | advice, | |
| 2245 | 0, | |
| 2227 | 2246 | offset_halves[0], |
| 2228 | 2247 | offset_halves[1], |
| 2229 | 2248 | length_halves[0], |
| 2230 | 2249 | length_halves[1], |
| 2250 | advice, | |
| 2231 | 2251 | ); |
| 2232 | } else if (@hasField(SYS, "fadvise64_64") and usize_bits != 64) { | |
| 2233 | // The extra usize check is needed to avoid SPARC64 because it provides both | |
| 2234 | // fadvise64 and fadvise64_64 but the latter behaves differently than other platforms. | |
| 2252 | } else if (comptime usize_bits < 64) { | |
| 2253 | // Other 32-bit architectures do not require register alignment. | |
| 2235 | 2254 | |
| 2236 | 2255 | const offset_halves = splitValue64(offset); |
| 2237 | 2256 | const length_halves = splitValue64(len); |
| ... | ... | @@ -2246,8 +2265,11 @@ pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize { |
| 2246 | 2265 | advice, |
| 2247 | 2266 | ); |
| 2248 | 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 | 2271 | return syscall4( |
| 2250 | .fadvise64, | |
| 2272 | if (@hasField(SYS, "fadvise64_64")) .fadvise64_64 else .fadvise64, | |
| 2251 | 2273 | @as(usize, @bitCast(@as(isize, fd))), |
| 2252 | 2274 | @as(usize, @bitCast(offset)), |
| 2253 | 2275 | @as(usize, @bitCast(len)), |
| ... | ... | @@ -6295,12 +6317,13 @@ pub const POSIX_FADV = switch (native_arch) { |
| 6295 | 6317 | }; |
| 6296 | 6318 | |
| 6297 | 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 | 6321 | sec: i64, |
| 6300 | 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 | 6327 | sec: isize, |
| 6305 | 6328 | nsec: isize, |
| 6306 | 6329 | }; |
| ... | ... | @@ -7338,6 +7361,7 @@ pub const AUDIT = struct { |
| 7338 | 7361 | .x86_64 => .X86_64, |
| 7339 | 7362 | .aarch64 => .AARCH64, |
| 7340 | 7363 | .arm, .thumb => .ARM, |
| 7364 | .riscv32 => .RISCV32, | |
| 7341 | 7365 | .riscv64 => .RISCV64, |
| 7342 | 7366 | .sparc64 => .SPARC64, |
| 7343 | 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 | 136 | |
| 137 | 137 | pub const blksize_t = i32; |
| 138 | 138 | pub const nlink_t = u32; |
| 139 | pub const time_t = isize; | |
| 139 | pub const time_t = i64; | |
| 140 | 140 | pub const mode_t = u32; |
| 141 | pub const off_t = isize; | |
| 142 | pub const ino_t = usize; | |
| 143 | pub const dev_t = usize; | |
| 144 | pub const blkcnt_t = isize; | |
| 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 | 145 | |
| 146 | 146 | pub const timeval = extern struct { |
| 147 | 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 | 26 | .hexagon => R_HEXAGON_RELATIVE, |
| 27 | 27 | .loongarch32, .loongarch64 => R_LARCH_RELATIVE, |
| 28 | 28 | .m68k => R_68K_RELATIVE, |
| 29 | .riscv64 => R_RISCV_RELATIVE, | |
| 29 | .riscv32, .riscv64 => R_RISCV_RELATIVE, | |
| 30 | 30 | .s390x => R_390_RELATIVE, |
| 31 | 31 | else => @compileError("Missing R_RELATIVE definition for this target"), |
| 32 | 32 | }; |
| ... | ... | @@ -111,7 +111,7 @@ fn getDynamicSymbol() [*]elf.Dyn { |
| 111 | 111 | \\ lea (%[ret], %%pc), %[ret] |
| 112 | 112 | : [ret] "=r" (-> [*]elf.Dyn), |
| 113 | 113 | ), |
| 114 | .riscv64 => asm volatile ( | |
| 114 | .riscv32, .riscv64 => asm volatile ( | |
| 115 | 115 | \\ .weak _DYNAMIC |
| 116 | 116 | \\ .hidden _DYNAMIC |
| 117 | 117 | \\ lla %[ret], _DYNAMIC |
lib/std/os/linux/syscalls.zig+337-33| ... | ... | @@ -142,16 +142,16 @@ pub const X86 = enum(usize) { |
| 142 | 142 | afs_syscall = 137, |
| 143 | 143 | setfsuid = 138, |
| 144 | 144 | setfsgid = 139, |
| 145 | _llseek = 140, | |
| 145 | llseek = 140, | |
| 146 | 146 | getdents = 141, |
| 147 | _newselect = 142, | |
| 147 | newselect = 142, | |
| 148 | 148 | flock = 143, |
| 149 | 149 | msync = 144, |
| 150 | 150 | readv = 145, |
| 151 | 151 | writev = 146, |
| 152 | 152 | getsid = 147, |
| 153 | 153 | fdatasync = 148, |
| 154 | _sysctl = 149, | |
| 154 | sysctl = 149, | |
| 155 | 155 | mlock = 150, |
| 156 | 156 | munlock = 151, |
| 157 | 157 | mlockall = 152, |
| ... | ... | @@ -607,7 +607,7 @@ pub const X64 = enum(usize) { |
| 607 | 607 | vhangup = 153, |
| 608 | 608 | modify_ldt = 154, |
| 609 | 609 | pivot_root = 155, |
| 610 | _sysctl = 156, | |
| 610 | sysctl = 156, | |
| 611 | 611 | prctl = 157, |
| 612 | 612 | arch_prctl = 158, |
| 613 | 613 | adjtimex = 159, |
| ... | ... | @@ -927,16 +927,16 @@ pub const Arm = enum(usize) { |
| 927 | 927 | personality = 136, |
| 928 | 928 | setfsuid = 138, |
| 929 | 929 | setfsgid = 139, |
| 930 | _llseek = 140, | |
| 930 | llseek = 140, | |
| 931 | 931 | getdents = 141, |
| 932 | _newselect = 142, | |
| 932 | newselect = 142, | |
| 933 | 933 | flock = 143, |
| 934 | 934 | msync = 144, |
| 935 | 935 | readv = 145, |
| 936 | 936 | writev = 146, |
| 937 | 937 | getsid = 147, |
| 938 | 938 | fdatasync = 148, |
| 939 | _sysctl = 149, | |
| 939 | sysctl = 149, | |
| 940 | 940 | mlock = 150, |
| 941 | 941 | munlock = 151, |
| 942 | 942 | mlockall = 152, |
| ... | ... | @@ -1454,12 +1454,12 @@ pub const Sparc64 = enum(usize) { |
| 1454 | 1454 | afs_syscall = 227, |
| 1455 | 1455 | setfsuid = 228, |
| 1456 | 1456 | setfsgid = 229, |
| 1457 | _newselect = 230, | |
| 1457 | newselect = 230, | |
| 1458 | 1458 | splice = 232, |
| 1459 | 1459 | stime = 233, |
| 1460 | 1460 | statfs64 = 234, |
| 1461 | 1461 | fstatfs64 = 235, |
| 1462 | _llseek = 236, | |
| 1462 | llseek = 236, | |
| 1463 | 1463 | mlock = 237, |
| 1464 | 1464 | munlock = 238, |
| 1465 | 1465 | mlockall = 239, |
| ... | ... | @@ -1474,7 +1474,7 @@ pub const Sparc64 = enum(usize) { |
| 1474 | 1474 | sched_rr_get_interval = 248, |
| 1475 | 1475 | nanosleep = 249, |
| 1476 | 1476 | mremap = 250, |
| 1477 | _sysctl = 251, | |
| 1477 | sysctl = 251, | |
| 1478 | 1478 | getsid = 252, |
| 1479 | 1479 | fdatasync = 253, |
| 1480 | 1480 | nfsservctl = 254, |
| ... | ... | @@ -1771,9 +1771,9 @@ pub const Mips = enum(usize) { |
| 1771 | 1771 | afs_syscall = Linux + 137, |
| 1772 | 1772 | setfsuid = Linux + 138, |
| 1773 | 1773 | setfsgid = Linux + 139, |
| 1774 | _llseek = Linux + 140, | |
| 1774 | llseek = Linux + 140, | |
| 1775 | 1775 | getdents = Linux + 141, |
| 1776 | _newselect = Linux + 142, | |
| 1776 | newselect = Linux + 142, | |
| 1777 | 1777 | flock = Linux + 143, |
| 1778 | 1778 | msync = Linux + 144, |
| 1779 | 1779 | readv = Linux + 145, |
| ... | ... | @@ -1783,7 +1783,7 @@ pub const Mips = enum(usize) { |
| 1783 | 1783 | sysmips = Linux + 149, |
| 1784 | 1784 | getsid = Linux + 151, |
| 1785 | 1785 | fdatasync = Linux + 152, |
| 1786 | _sysctl = Linux + 153, | |
| 1786 | sysctl = Linux + 153, | |
| 1787 | 1787 | mlock = Linux + 154, |
| 1788 | 1788 | munlock = Linux + 155, |
| 1789 | 1789 | mlockall = Linux + 156, |
| ... | ... | @@ -2087,7 +2087,7 @@ pub const Mips64 = enum(usize) { |
| 2087 | 2087 | writev = Linux + 19, |
| 2088 | 2088 | access = Linux + 20, |
| 2089 | 2089 | pipe = Linux + 21, |
| 2090 | _newselect = Linux + 22, | |
| 2090 | newselect = Linux + 22, | |
| 2091 | 2091 | sched_yield = Linux + 23, |
| 2092 | 2092 | mremap = Linux + 24, |
| 2093 | 2093 | msync = Linux + 25, |
| ... | ... | @@ -2217,7 +2217,7 @@ pub const Mips64 = enum(usize) { |
| 2217 | 2217 | munlockall = Linux + 149, |
| 2218 | 2218 | vhangup = Linux + 150, |
| 2219 | 2219 | pivot_root = Linux + 151, |
| 2220 | _sysctl = Linux + 152, | |
| 2220 | sysctl = Linux + 152, | |
| 2221 | 2221 | prctl = Linux + 153, |
| 2222 | 2222 | adjtimex = Linux + 154, |
| 2223 | 2223 | setrlimit = Linux + 155, |
| ... | ... | @@ -2568,16 +2568,16 @@ pub const PowerPC = enum(usize) { |
| 2568 | 2568 | afs_syscall = 137, |
| 2569 | 2569 | setfsuid = 138, |
| 2570 | 2570 | setfsgid = 139, |
| 2571 | _llseek = 140, | |
| 2571 | llseek = 140, | |
| 2572 | 2572 | getdents = 141, |
| 2573 | _newselect = 142, | |
| 2573 | newselect = 142, | |
| 2574 | 2574 | flock = 143, |
| 2575 | 2575 | msync = 144, |
| 2576 | 2576 | readv = 145, |
| 2577 | 2577 | writev = 146, |
| 2578 | 2578 | getsid = 147, |
| 2579 | 2579 | fdatasync = 148, |
| 2580 | _sysctl = 149, | |
| 2580 | sysctl = 149, | |
| 2581 | 2581 | mlock = 150, |
| 2582 | 2582 | munlock = 151, |
| 2583 | 2583 | mlockall = 152, |
| ... | ... | @@ -3008,16 +3008,16 @@ pub const PowerPC64 = enum(usize) { |
| 3008 | 3008 | afs_syscall = 137, |
| 3009 | 3009 | setfsuid = 138, |
| 3010 | 3010 | setfsgid = 139, |
| 3011 | _llseek = 140, | |
| 3011 | llseek = 140, | |
| 3012 | 3012 | getdents = 141, |
| 3013 | _newselect = 142, | |
| 3013 | newselect = 142, | |
| 3014 | 3014 | flock = 143, |
| 3015 | 3015 | msync = 144, |
| 3016 | 3016 | readv = 145, |
| 3017 | 3017 | writev = 146, |
| 3018 | 3018 | getsid = 147, |
| 3019 | 3019 | fdatasync = 148, |
| 3020 | _sysctl = 149, | |
| 3020 | sysctl = 149, | |
| 3021 | 3021 | mlock = 150, |
| 3022 | 3022 | munlock = 151, |
| 3023 | 3023 | mlockall = 152, |
| ... | ... | @@ -3351,7 +3351,7 @@ pub const Arm64 = enum(usize) { |
| 3351 | 3351 | pwrite64 = 68, |
| 3352 | 3352 | preadv = 69, |
| 3353 | 3353 | pwritev = 70, |
| 3354 | sendfile = 71, | |
| 3354 | sendfile64 = 71, | |
| 3355 | 3355 | pselect6 = 72, |
| 3356 | 3356 | ppoll = 73, |
| 3357 | 3357 | signalfd4 = 74, |
| ... | ... | @@ -3359,8 +3359,8 @@ pub const Arm64 = enum(usize) { |
| 3359 | 3359 | splice = 76, |
| 3360 | 3360 | tee = 77, |
| 3361 | 3361 | readlinkat = 78, |
| 3362 | fstatat = 79, | |
| 3363 | fstat = 80, | |
| 3362 | fstatat64 = 79, | |
| 3363 | fstat64 = 80, | |
| 3364 | 3364 | sync = 81, |
| 3365 | 3365 | fsync = 82, |
| 3366 | 3366 | fdatasync = 83, |
| ... | ... | @@ -3503,7 +3503,7 @@ pub const Arm64 = enum(usize) { |
| 3503 | 3503 | clone = 220, |
| 3504 | 3504 | execve = 221, |
| 3505 | 3505 | mmap = 222, |
| 3506 | fadvise64 = 223, | |
| 3506 | fadvise64_64 = 223, | |
| 3507 | 3507 | swapon = 224, |
| 3508 | 3508 | swapoff = 225, |
| 3509 | 3509 | mprotect = 226, |
| ... | ... | @@ -3594,9 +3594,313 @@ pub const Arm64 = enum(usize) { |
| 3594 | 3594 | futex_requeue = 456, |
| 3595 | 3595 | }; |
| 3596 | 3596 | |
| 3597 | pub const RiscV64 = enum(usize) { | |
| 3598 | pub const arch_specific_syscall = 244; | |
| 3597 | pub const RiscV32 = enum(usize) { | |
| 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 | 3904 | io_setup = 0, |
| 3601 | 3905 | io_destroy = 1, |
| 3602 | 3906 | io_submit = 2, |
| ... | ... | @@ -3667,7 +3971,7 @@ pub const RiscV64 = enum(usize) { |
| 3667 | 3971 | pwrite64 = 68, |
| 3668 | 3972 | preadv = 69, |
| 3669 | 3973 | pwritev = 70, |
| 3670 | sendfile = 71, | |
| 3974 | sendfile64 = 71, | |
| 3671 | 3975 | pselect6 = 72, |
| 3672 | 3976 | ppoll = 73, |
| 3673 | 3977 | signalfd4 = 74, |
| ... | ... | @@ -3675,8 +3979,8 @@ pub const RiscV64 = enum(usize) { |
| 3675 | 3979 | splice = 76, |
| 3676 | 3980 | tee = 77, |
| 3677 | 3981 | readlinkat = 78, |
| 3678 | fstatat = 79, | |
| 3679 | fstat = 80, | |
| 3982 | fstatat64 = 79, | |
| 3983 | fstat64 = 80, | |
| 3680 | 3984 | sync = 81, |
| 3681 | 3985 | fsync = 82, |
| 3682 | 3986 | fdatasync = 83, |
| ... | ... | @@ -3819,7 +4123,7 @@ pub const RiscV64 = enum(usize) { |
| 3819 | 4123 | clone = 220, |
| 3820 | 4124 | execve = 221, |
| 3821 | 4125 | mmap = 222, |
| 3822 | fadvise64 = 223, | |
| 4126 | fadvise64_64 = 223, | |
| 3823 | 4127 | swapon = 224, |
| 3824 | 4128 | swapoff = 225, |
| 3825 | 4129 | mprotect = 226, |
| ... | ... | @@ -3908,8 +4212,8 @@ pub const RiscV64 = enum(usize) { |
| 3908 | 4212 | futex_wake = 454, |
| 3909 | 4213 | futex_wait = 455, |
| 3910 | 4214 | futex_requeue = 456, |
| 3911 | ||
| 3912 | riscv_flush_icache = arch_specific_syscall + 15, | |
| 4215 | riscv_flush_icache = (244 + 15), | |
| 4216 | riscv_hwprobe = (244 + 14), | |
| 3913 | 4217 | }; |
| 3914 | 4218 | |
| 3915 | 4219 | pub const LoongArch64 = enum(usize) { |
lib/std/os/linux/test.zig+2-2| ... | ... | @@ -79,11 +79,11 @@ test "statx" { |
| 79 | 79 | var statx_buf: linux.Statx = undefined; |
| 80 | 80 | switch (linux.E.init(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) { |
| 81 | 81 | .SUCCESS => {}, |
| 82 | // The statx syscall was only introduced in linux 4.11 | |
| 83 | .NOSYS => return error.SkipZigTest, | |
| 84 | 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 | 87 | var stat_buf: linux.Stat = undefined; |
| 88 | 88 | switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) { |
| 89 | 89 | .SUCCESS => {}, |
lib/std/os/linux/tls.zig+1-1| ... | ... | @@ -170,7 +170,7 @@ pub fn setThreadPointer(addr: usize) void { |
| 170 | 170 | const rc = @call(.always_inline, linux.syscall1, .{ .set_tls, addr }); |
| 171 | 171 | assert(rc == 0); |
| 172 | 172 | }, |
| 173 | .riscv64 => { | |
| 173 | .riscv32, .riscv64 => { | |
| 174 | 174 | asm volatile ( |
| 175 | 175 | \\ mv tp, %[addr] |
| 176 | 176 | : |
lib/std/posix.zig+4-32| ... | ... | @@ -615,7 +615,6 @@ pub fn getrandom(buffer: []u8) GetRandomError!void { |
| 615 | 615 | .INVAL => unreachable, |
| 616 | 616 | .FAULT => unreachable, |
| 617 | 617 | .INTR => continue, |
| 618 | .NOSYS => return getRandomBytesDevURandom(buf), | |
| 619 | 618 | else => return unexpectedErrno(err), |
| 620 | 619 | } |
| 621 | 620 | } |
| ... | ... | @@ -4534,7 +4533,6 @@ pub const FanotifyInitError = error{ |
| 4534 | 4533 | ProcessFdQuotaExceeded, |
| 4535 | 4534 | SystemFdQuotaExceeded, |
| 4536 | 4535 | SystemResources, |
| 4537 | OperationNotSupported, | |
| 4538 | 4536 | PermissionDenied, |
| 4539 | 4537 | } || UnexpectedError; |
| 4540 | 4538 | |
| ... | ... | @@ -4546,7 +4544,6 @@ pub fn fanotify_init(flags: std.os.linux.fanotify.InitFlags, event_f_flags: u32) |
| 4546 | 4544 | .MFILE => return error.ProcessFdQuotaExceeded, |
| 4547 | 4545 | .NFILE => return error.SystemFdQuotaExceeded, |
| 4548 | 4546 | .NOMEM => return error.SystemResources, |
| 4549 | .NOSYS => return error.OperationNotSupported, | |
| 4550 | 4547 | .PERM => return error.PermissionDenied, |
| 4551 | 4548 | else => |err| return unexpectedErrno(err), |
| 4552 | 4549 | } |
| ... | ... | @@ -4559,7 +4556,6 @@ pub const FanotifyMarkError = error{ |
| 4559 | 4556 | FileNotFound, |
| 4560 | 4557 | SystemResources, |
| 4561 | 4558 | UserMarkQuotaExceeded, |
| 4562 | NotImplemented, | |
| 4563 | 4559 | NotDir, |
| 4564 | 4560 | OperationNotSupported, |
| 4565 | 4561 | PermissionDenied, |
| ... | ... | @@ -4600,7 +4596,6 @@ pub fn fanotify_markZ( |
| 4600 | 4596 | .NOENT => return error.FileNotFound, |
| 4601 | 4597 | .NOMEM => return error.SystemResources, |
| 4602 | 4598 | .NOSPC => return error.UserMarkQuotaExceeded, |
| 4603 | .NOSYS => return error.NotImplemented, | |
| 4604 | 4599 | .NOTDIR => return error.NotDir, |
| 4605 | 4600 | .OPNOTSUPP => return error.OperationNotSupported, |
| 4606 | 4601 | .PERM => return error.PermissionDenied, |
| ... | ... | @@ -6183,13 +6178,6 @@ pub fn sendfile( |
| 6183 | 6178 | |
| 6184 | 6179 | switch (native_os) { |
| 6185 | 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 | 6181 | if (headers.len != 0) { |
| 6194 | 6182 | const amt = try writev(out_fd, headers); |
| 6195 | 6183 | total_written += amt; |
| ... | ... | @@ -6223,14 +6211,14 @@ pub fn sendfile( |
| 6223 | 6211 | .OVERFLOW => unreachable, // We avoid passing too large of a `count`. |
| 6224 | 6212 | .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket |
| 6225 | 6213 | |
| 6226 | .INVAL, .NOSYS => { | |
| 6214 | .INVAL => { | |
| 6227 | 6215 | // EINVAL could be any of the following situations: |
| 6228 | 6216 | // * Descriptor is not valid or locked |
| 6229 | 6217 | // * an mmap(2)-like operation is not available for in_fd |
| 6230 | 6218 | // * count is negative |
| 6231 | 6219 | // * out_fd has the APPEND flag set |
| 6232 | 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 | 6222 | break :sf; |
| 6235 | 6223 | }, |
| 6236 | 6224 | .AGAIN => return error.WouldBlock, |
| ... | ... | @@ -6456,21 +6444,15 @@ pub const CopyFileRangeError = error{ |
| 6456 | 6444 | /// `flags` has different meanings per operating system; refer to the respective man pages. |
| 6457 | 6445 | /// |
| 6458 | 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 | 6448 | /// * FreeBSD 13.0 |
| 6461 | 6449 | /// |
| 6462 | 6450 | /// Other systems fall back to calling `pread` / `pwrite`. |
| 6463 | 6451 | /// |
| 6464 | 6452 | /// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`. |
| 6465 | 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 | 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 | |
| 6472 | std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and | |
| 6473 | @atomicLoad(bool, &global.has_copy_file_range, .monotonic))) | |
| 6455 | (comptime builtin.os.tag == .linux and std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }))) | |
| 6474 | 6456 | { |
| 6475 | 6457 | var off_in_copy: i64 = @bitCast(off_in); |
| 6476 | 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 | 6486 | .PERM => return error.PermissionDenied, |
| 6505 | 6487 | .TXTBSY => return error.SwapFile, |
| 6506 | 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 | 6489 | else => |err| return unexpectedErrno(err), |
| 6512 | 6490 | } |
| 6513 | 6491 | } |
| ... | ... | @@ -6775,10 +6753,6 @@ pub const MemFdCreateError = error{ |
| 6775 | 6753 | OutOfMemory, |
| 6776 | 6754 | /// Either the name provided exceeded `NAME_MAX`, or invalid flags were passed. |
| 6777 | 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 | 6756 | } || UnexpectedError; |
| 6783 | 6757 | |
| 6784 | 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 | 6769 | .NFILE => return error.SystemFdQuotaExceeded, |
| 6796 | 6770 | .MFILE => return error.ProcessFdQuotaExceeded, |
| 6797 | 6771 | .NOMEM => return error.OutOfMemory, |
| 6798 | .NOSYS => return error.SystemOutdated, | |
| 6799 | 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 | 6888 | .NOMEM => return error.SystemResources, |
| 6916 | 6889 | .MFILE => return error.ProcessResources, |
| 6917 | 6890 | .NODEV => return error.InodeMountFail, |
| 6918 | .NOSYS => return error.SystemOutdated, | |
| 6919 | 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 | 580 | else => return error.SkipZigTest, |
| 581 | 581 | } |
| 582 | 582 | |
| 583 | const fd = posix.memfd_create("test", 0) catch |err| switch (err) { | |
| 584 | // Related: https://github.com/ziglang/zig/issues/4019 | |
| 585 | error.SystemOutdated => return error.SkipZigTest, | |
| 586 | else => |e| return e, | |
| 587 | }; | |
| 583 | const fd = try posix.memfd_create("test", 0); | |
| 588 | 584 | defer posix.close(fd); |
| 589 | 585 | try expect((try posix.write(fd, "test")) == 4); |
| 590 | 586 | try posix.lseek_SET(fd, 0); |
lib/std/start.zig+1-1| ... | ... | @@ -272,7 +272,7 @@ fn _start() callconv(.Naked) noreturn { |
| 272 | 272 | \\ bstrins.d $sp, $zero, 3, 0 |
| 273 | 273 | \\ b %[posixCallMainAndExit] |
| 274 | 274 | , |
| 275 | .riscv64 => | |
| 275 | .riscv32, .riscv64 => | |
| 276 | 276 | \\ li s0, 0 |
| 277 | 277 | \\ li ra, 0 |
| 278 | 278 | \\ mv a0, sp |
lib/std/zig/target.zig+1-1| ... | ... | @@ -56,7 +56,7 @@ pub const available_libcs = [_]ArchOsAbi{ |
| 56 | 56 | .{ .arch = .powerpc, .os = .linux, .abi = .gnueabi }, |
| 57 | 57 | .{ .arch = .powerpc, .os = .linux, .abi = .gnueabihf }, |
| 58 | 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 | 60 | .{ .arch = .riscv32, .os = .linux, .abi = .musl }, |
| 61 | 61 | .{ .arch = .riscv64, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 27, .patch = 0 } }, |
| 62 | 62 | .{ .arch = .riscv64, .os = .linux, .abi = .musl }, |
src/link/Elf.zig+1-1| ... | ... | @@ -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 | 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 | 301 | pub fn needsCrtiCrtn(target: std.Target) bool { |
| 302 | 302 | // zig fmt: off |
| 303 | 303 | return switch (target.cpu.arch) { |
| 304 | .riscv32, | |
| 304 | 305 | .riscv64, |
| 305 | 306 | .wasm32, .wasm64 => return false, |
| 306 | 307 | else => true, |
tools/gen_stubs.zig+7-2| ... | ... | @@ -2,13 +2,14 @@ |
| 2 | 2 | //! ./gen_stubs /path/to/musl/build-all >libc.S |
| 3 | 3 | //! |
| 4 | 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 | 7 | //! ...each with 'lib/libc.so' inside of them. |
| 8 | 8 | //! |
| 9 | 9 | //! When building the resulting libc.S file, these defines are required: |
| 10 | 10 | //! * `-DPTR64`: when the architecture is 64-bit |
| 11 | 11 | //! * One of the following, corresponding to the CPU architecture: |
| 12 | //! - `-DARCH_riscv32` | |
| 12 | 13 | //! - `-DARCH_riscv64` |
| 13 | 14 | //! - `-DARCH_mips` |
| 14 | 15 | //! - `-DARCH_mips64` |
| ... | ... | @@ -68,7 +69,8 @@ const MultiSym = struct { |
| 68 | 69 | } |
| 69 | 70 | |
| 70 | 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 | 74 | ms.present[archIndex(.mips)] == true and |
| 73 | 75 | ms.present[archIndex(.mips64)] == false and |
| 74 | 76 | ms.present[archIndex(.x86)] == true and |
| ... | ... | @@ -110,6 +112,7 @@ const MultiSym = struct { |
| 110 | 112 | |
| 111 | 113 | fn isPtrSize(ms: MultiSym) bool { |
| 112 | 114 | const map = .{ |
| 115 | .{ .riscv32, 4 }, | |
| 113 | 116 | .{ .riscv64, 8 }, |
| 114 | 117 | .{ .mips, 4 }, |
| 115 | 118 | .{ .mips64, 8 }, |
| ... | ... | @@ -132,6 +135,7 @@ const MultiSym = struct { |
| 132 | 135 | |
| 133 | 136 | fn isPtr2Size(ms: MultiSym) bool { |
| 134 | 137 | const map = .{ |
| 138 | .{ .riscv32, 8 }, | |
| 135 | 139 | .{ .riscv64, 16 }, |
| 136 | 140 | .{ .mips, 8 }, |
| 137 | 141 | .{ .mips64, 16 }, |
| ... | ... | @@ -154,6 +158,7 @@ const MultiSym = struct { |
| 154 | 158 | |
| 155 | 159 | fn isWeak64(ms: MultiSym) bool { |
| 156 | 160 | const map = .{ |
| 161 | .{ .riscv32, 1 }, | |
| 157 | 162 | .{ .riscv64, 2 }, |
| 158 | 163 | .{ .mips, 1 }, |
| 159 | 164 | .{ .mips64, 2 }, |
tools/generate_linux_syscalls.zig+112-48| ... | ... | @@ -10,7 +10,12 @@ const zig = std.zig; |
| 10 | 10 | const fs = std.fs; |
| 11 | 11 | |
| 12 | 12 | const stdlib_renames = std.StaticStringMap([]const u8).initComptime(.{ |
| 13 | // Remove underscore prefix. | |
| 14 | .{ "_llseek", "llseek" }, | |
| 15 | .{ "_newselect", "newselect" }, | |
| 16 | .{ "_sysctl", "sysctl" }, | |
| 13 | 17 | // Most 64-bit archs. |
| 18 | .{ "newfstat", "fstat64" }, | |
| 14 | 19 | .{ "newfstatat", "fstatat64" }, |
| 15 | 20 | // POWER. |
| 16 | 21 | .{ "sync_file_range2", "sync_file_range" }, |
| ... | ... | @@ -19,6 +24,24 @@ const stdlib_renames = std.StaticStringMap([]const u8).initComptime(.{ |
| 19 | 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 | 45 | pub fn main() !void { |
| 23 | 46 | var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); |
| 24 | 47 | defer arena.deinit(); |
| ... | ... | @@ -60,8 +83,9 @@ pub fn main() !void { |
| 60 | 83 | // abi is always i386 |
| 61 | 84 | _ = fields.next() orelse return error.Incomplete; |
| 62 | 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 | 91 | try writer.writeAll("};\n\n"); |
| ... | ... | @@ -80,8 +104,8 @@ pub fn main() !void { |
| 80 | 104 | // The x32 abi syscalls are always at the end. |
| 81 | 105 | if (mem.eql(u8, abi, "x32")) break; |
| 82 | 106 | const name = fields.next() orelse return error.Incomplete; |
| 83 | ||
| 84 | 107 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; |
| 108 | ||
| 85 | 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 | 129 | const abi = fields.next() orelse return error.Incomplete; |
| 106 | 130 | if (mem.eql(u8, abi, "oabi")) continue; |
| 107 | 131 | const name = fields.next() orelse return error.Incomplete; |
| 108 | ||
| 109 | 132 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; |
| 133 | ||
| 110 | 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 | 160 | const abi = fields.next() orelse return error.Incomplete; |
| 137 | 161 | if (mem.eql(u8, abi, "32")) continue; |
| 138 | 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 | 168 | try writer.writeAll("};\n\n"); |
| ... | ... | @@ -161,8 +186,9 @@ pub fn main() !void { |
| 161 | 186 | _ = fields.next() orelse return error.Incomplete; |
| 162 | 187 | const name = fields.next() orelse return error.Incomplete; |
| 163 | 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 | 194 | try writer.writeAll("};\n\n"); |
| ... | ... | @@ -232,11 +258,6 @@ pub fn main() !void { |
| 232 | 258 | // Newer architectures (starting with aarch64 c. 2012) now use the same C |
| 233 | 259 | // header file for their syscall numbers. Arch-specific headers are used to |
| 234 | 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 | 262 | try writer.writeAll("pub const Arm64 = enum(usize) {\n"); |
| 242 | 263 | |
| ... | ... | @@ -254,6 +275,8 @@ pub fn main() !void { |
| 254 | 275 | // Using -I=[dir] includes the zig linux headers, which we don't want. |
| 255 | 276 | "-Iinclude", |
| 256 | 277 | "-Iinclude/uapi", |
| 278 | // Output the syscall in a format we can easily recognize. | |
| 279 | "-D __SYSCALL(nr, nm)=zigsyscall nm nr", | |
| 257 | 280 | "arch/arm64/include/uapi/asm/unistd.h", |
| 258 | 281 | }; |
| 259 | 282 | |
| ... | ... | @@ -277,32 +300,79 @@ pub fn main() !void { |
| 277 | 300 | }; |
| 278 | 301 | |
| 279 | 302 | var lines = mem.tokenizeScalar(u8, defines, '\n'); |
| 280 | loop: while (lines.next()) |line| { | |
| 281 | var fields = mem.tokenizeAny(u8, line, " \t"); | |
| 282 | const cmd = 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; | |
| 303 | while (lines.next()) |line| { | |
| 304 | var fields = mem.tokenizeAny(u8, line, " "); | |
| 305 | const prefix = fields.next() orelse return error.Incomplete; | |
| 286 | 306 | |
| 287 | if (!std.ascii.isDigit(number[0])) 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; | |
| 307 | if (!mem.eql(u8, prefix, "zigsyscall")) continue; | |
| 292 | 308 | |
| 293 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | |
| 294 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); | |
| 309 | const sys_name = fields.next() orelse return error.Incomplete; | |
| 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 | 317 | try writer.writeAll("};\n\n"); |
| 298 | 318 | } |
| 299 | 319 | { |
| 300 | try writer.writeAll( | |
| 301 | \\pub const RiscV64 = enum(usize) { | |
| 302 | \\ pub const arch_specific_syscall = 244; | |
| 303 | \\ | |
| 304 | \\ | |
| 305 | ); | |
| 320 | try writer.writeAll("pub const RiscV32 = enum(usize) {\n"); | |
| 321 | ||
| 322 | const child_args = [_][]const u8{ | |
| 323 | zig_exe, | |
| 324 | "cc", | |
| 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 | 377 | const child_args = [_][]const u8{ |
| 308 | 378 | zig_exe, |
| ... | ... | @@ -315,6 +385,8 @@ pub fn main() !void { |
| 315 | 385 | "-nostdinc", |
| 316 | 386 | "-Iinclude", |
| 317 | 387 | "-Iinclude/uapi", |
| 388 | "-Iarch/riscv/include/uapi", | |
| 389 | "-D __SYSCALL(nr, nm)=zigsyscall nm nr", | |
| 318 | 390 | "arch/riscv/include/uapi/asm/unistd.h", |
| 319 | 391 | }; |
| 320 | 392 | |
| ... | ... | @@ -338,29 +410,21 @@ pub fn main() !void { |
| 338 | 410 | }; |
| 339 | 411 | |
| 340 | 412 | var lines = mem.tokenizeScalar(u8, defines, '\n'); |
| 341 | loop: while (lines.next()) |line| { | |
| 342 | var fields = mem.tokenizeAny(u8, line, " \t"); | |
| 343 | const cmd = 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; | |
| 413 | while (lines.next()) |line| { | |
| 414 | var fields = mem.tokenizeAny(u8, line, " "); | |
| 415 | const prefix = fields.next() orelse return error.Incomplete; | |
| 347 | 416 | |
| 348 | if (!std.ascii.isDigit(number[0])) 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; | |
| 417 | if (!mem.eql(u8, prefix, "zigsyscall")) continue; | |
| 353 | 418 | |
| 354 | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; | |
| 355 | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); | |
| 419 | const sys_name = fields.next() orelse return error.Incomplete; | |
| 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( | |
| 359 | \\ | |
| 360 | \\ riscv_flush_icache = arch_specific_syscall + 15, | |
| 361 | \\}; | |
| 362 | \\ | |
| 363 | ); | |
| 427 | try writer.writeAll("};\n\n"); | |
| 364 | 428 | } |
| 365 | 429 | { |
| 366 | 430 | try writer.writeAll( |