| ... | ... | @@ -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,24 @@ 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 RiscV32 = enum(usize) { |
| 302 | | \\ pub const arch_specific_syscall = 244; |
| 303 | | \\ |
| 304 | | \\ |
| 305 | | ); |
| 320 | try writer.writeAll("pub const RiscV32 = enum(usize) {\n"); |
| 306 | 321 | |
| 307 | 322 | const child_args = [_][]const u8{ |
| 308 | 323 | zig_exe, |
| ... | ... | @@ -316,6 +331,7 @@ pub fn main() !void { |
| 316 | 331 | "-Iinclude", |
| 317 | 332 | "-Iinclude/uapi", |
| 318 | 333 | "-Iarch/riscv/include/uapi", |
| 334 | "-D __SYSCALL(nr, nm)=zigsyscall nm nr", |
| 319 | 335 | "arch/riscv/include/uapi/asm/unistd.h", |
| 320 | 336 | }; |
| 321 | 337 | |
| ... | ... | @@ -339,38 +355,24 @@ pub fn main() !void { |
| 339 | 355 | }; |
| 340 | 356 | |
| 341 | 357 | var lines = mem.tokenizeScalar(u8, defines, '\n'); |
| 342 | | loop: while (lines.next()) |line| { |
| 343 | | var fields = mem.tokenizeAny(u8, line, " \t"); |
| 344 | | const cmd = fields.next() orelse return error.Incomplete; |
| 345 | | if (!mem.eql(u8, cmd, "#define")) continue; |
| 346 | | const define = fields.next() orelse return error.Incomplete; |
| 347 | | const number = fields.next() orelse continue; |
| 358 | while (lines.next()) |line| { |
| 359 | var fields = mem.tokenizeAny(u8, line, " "); |
| 360 | const prefix = fields.next() orelse return error.Incomplete; |
| 348 | 361 | |
| 349 | | if (!std.ascii.isDigit(number[0])) continue; |
| 350 | | if (!mem.startsWith(u8, define, "__NR")) continue; |
| 351 | | const name = mem.trimLeft(u8, mem.trimLeft(u8, define, "__NR3264_"), "__NR_"); |
| 352 | | if (mem.eql(u8, name, "arch_specific_syscall")) continue; |
| 353 | | if (mem.eql(u8, name, "syscalls")) break :loop; |
| 362 | if (!mem.eql(u8, prefix, "zigsyscall")) continue; |
| 354 | 363 | |
| 355 | | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; |
| 356 | | try writer.print(" {p} = {s},\n", .{ zig.fmtId(fixed_name), number }); |
| 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 }); |
| 357 | 370 | } |
| 358 | 371 | |
| 359 | | try writer.writeAll( |
| 360 | | \\ |
| 361 | | \\ riscv_flush_icache = arch_specific_syscall + 15, |
| 362 | | \\ riscv_hwprobe = arch_specific_syscall + 14, |
| 363 | | \\}; |
| 364 | | \\ |
| 365 | | ); |
| 372 | try writer.writeAll("};\n\n"); |
| 366 | 373 | } |
| 367 | 374 | { |
| 368 | | try writer.writeAll( |
| 369 | | \\pub const RiscV64 = enum(usize) { |
| 370 | | \\ pub const arch_specific_syscall = 244; |
| 371 | | \\ |
| 372 | | \\ |
| 373 | | ); |
| 375 | try writer.writeAll("pub const RiscV64 = enum(usize) {\n"); |
| 374 | 376 | |
| 375 | 377 | const child_args = [_][]const u8{ |
| 376 | 378 | zig_exe, |
| ... | ... | @@ -384,6 +386,7 @@ pub fn main() !void { |
| 384 | 386 | "-Iinclude", |
| 385 | 387 | "-Iinclude/uapi", |
| 386 | 388 | "-Iarch/riscv/include/uapi", |
| 389 | "-D __SYSCALL(nr, nm)=zigsyscall nm nr", |
| 387 | 390 | "arch/riscv/include/uapi/asm/unistd.h", |
| 388 | 391 | }; |
| 389 | 392 | |
| ... | ... | @@ -407,30 +410,21 @@ pub fn main() !void { |
| 407 | 410 | }; |
| 408 | 411 | |
| 409 | 412 | var lines = mem.tokenizeScalar(u8, defines, '\n'); |
| 410 | | loop: while (lines.next()) |line| { |
| 411 | | var fields = mem.tokenizeAny(u8, line, " \t"); |
| 412 | | const cmd = fields.next() orelse return error.Incomplete; |
| 413 | | if (!mem.eql(u8, cmd, "#define")) continue; |
| 414 | | const define = fields.next() orelse return error.Incomplete; |
| 415 | | 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; |
| 416 | 416 | |
| 417 | | if (!std.ascii.isDigit(number[0])) continue; |
| 418 | | if (!mem.startsWith(u8, define, "__NR")) continue; |
| 419 | | const name = mem.trimLeft(u8, mem.trimLeft(u8, define, "__NR3264_"), "__NR_"); |
| 420 | | if (mem.eql(u8, name, "arch_specific_syscall")) continue; |
| 421 | | if (mem.eql(u8, name, "syscalls")) break :loop; |
| 417 | if (!mem.eql(u8, prefix, "zigsyscall")) continue; |
| 422 | 418 | |
| 423 | | const fixed_name = if (stdlib_renames.get(name)) |fixed| fixed else name; |
| 424 | | 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 }); |
| 425 | 425 | } |
| 426 | 426 | |
| 427 | | try writer.writeAll( |
| 428 | | \\ |
| 429 | | \\ riscv_flush_icache = arch_specific_syscall + 15, |
| 430 | | \\ riscv_hwprobe = arch_specific_syscall + 14, |
| 431 | | \\}; |
| 432 | | \\ |
| 433 | | ); |
| 427 | try writer.writeAll("};\n\n"); |
| 434 | 428 | } |
| 435 | 429 | { |
| 436 | 430 | try writer.writeAll( |