authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-15 14:46:31-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-15 14:51:08-07:00
logf3ebfcae3882c03da84821abed40167ea07a8c78
treef1b759c94cba5b020a9ffb141fc62cb686fc5f04
parent111a2dcf3ad53c0c8ad2c9e7c9bd042b81e90c82
parent0395b35cee8d4082cc40b0dcd0298f797f42309d

Merge remote-tracking branch 'origin/master' into llvm13

Conflicts: * cmake/Findclang.cmake * cmake/Findlld.cmake * cmake/Findllvm.cmake In master branch, more search paths were added to these files with "12" in the path. In this commit I updated them to "13". * src/stage1/codegen.cpp * src/zig_llvm.cpp * src/zig_llvm.h In master branch, ZigLLVMBuildCmpXchg is improved to add `is_single_threaded`. However, the LLVM 13 C API has this already, and in the llvm13 branch, ZigLLVMBuildCmpXchg is deleted in favor of the C API. In this commit I updated stage2 to use the LLVM 13 C API rather than depending on an improved ZigLLVMBuildCmpXchg. Additionally, src/target.zig largestAtomicBits needed to be updated to include the new m68k ISA.

287 files changed, 37006 insertions(+), 34923 deletions(-)

CMakeLists.txt+9-12
...@@ -363,7 +363,9 @@ set(ZIG_STAGE2_SOURCES...@@ -363,7 +363,9 @@ set(ZIG_STAGE2_SOURCES
363 "${CMAKE_SOURCE_DIR}/lib/std/crypto/siphash.zig"363 "${CMAKE_SOURCE_DIR}/lib/std/crypto/siphash.zig"
364 "${CMAKE_SOURCE_DIR}/lib/std/debug.zig"364 "${CMAKE_SOURCE_DIR}/lib/std/debug.zig"
365 "${CMAKE_SOURCE_DIR}/lib/std/dwarf.zig"365 "${CMAKE_SOURCE_DIR}/lib/std/dwarf.zig"
366 "${CMAKE_SOURCE_DIR}/lib/std/dwarf_bits.zig"366 "${CMAKE_SOURCE_DIR}/lib/std/dwarf/AT.zig"
367 "${CMAKE_SOURCE_DIR}/lib/std/dwarf/OP.zig"
368 "${CMAKE_SOURCE_DIR}/lib/std/dwarf/TAG.zig"
367 "${CMAKE_SOURCE_DIR}/lib/std/elf.zig"369 "${CMAKE_SOURCE_DIR}/lib/std/elf.zig"
368 "${CMAKE_SOURCE_DIR}/lib/std/event.zig"370 "${CMAKE_SOURCE_DIR}/lib/std/event.zig"
369 "${CMAKE_SOURCE_DIR}/lib/std/event/batch.zig"371 "${CMAKE_SOURCE_DIR}/lib/std/event/batch.zig"
...@@ -424,18 +426,13 @@ set(ZIG_STAGE2_SOURCES...@@ -424,18 +426,13 @@ set(ZIG_STAGE2_SOURCES
424 "${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig"426 "${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig"
425 "${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig"427 "${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig"
426 "${CMAKE_SOURCE_DIR}/lib/std/os.zig"428 "${CMAKE_SOURCE_DIR}/lib/std/os.zig"
427 "${CMAKE_SOURCE_DIR}/lib/std/os/bits.zig"429 "${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
428 "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux.zig"430 "${CMAKE_SOURCE_DIR}/lib/std/os/linux/errno/generic.zig"
429 "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/errno/generic.zig"431 "${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"
430 "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/netlink.zig"
431 "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/prctl.zig"
432 "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/securebits.zig"
433 "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/x86_64.zig"
434 "${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"432 "${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
435 "${CMAKE_SOURCE_DIR}/lib/std/os/linux/io_uring.zig"433 "${CMAKE_SOURCE_DIR}/lib/std/os/linux/io_uring.zig"
436 "${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"434 "${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"
437 "${CMAKE_SOURCE_DIR}/lib/std/os/windows.zig"435 "${CMAKE_SOURCE_DIR}/lib/std/os/windows.zig"
438 "${CMAKE_SOURCE_DIR}/lib/std/os/windows/bits.zig"
439 "${CMAKE_SOURCE_DIR}/lib/std/os/windows/ntstatus.zig"436 "${CMAKE_SOURCE_DIR}/lib/std/os/windows/ntstatus.zig"
440 "${CMAKE_SOURCE_DIR}/lib/std/os/windows/win32error.zig"437 "${CMAKE_SOURCE_DIR}/lib/std/os/windows/win32error.zig"
441 "${CMAKE_SOURCE_DIR}/lib/std/Progress.zig"438 "${CMAKE_SOURCE_DIR}/lib/std/Progress.zig"
...@@ -447,8 +444,8 @@ set(ZIG_STAGE2_SOURCES...@@ -447,8 +444,8 @@ set(ZIG_STAGE2_SOURCES
447 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/addXf3.zig"444 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/addXf3.zig"
448 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/atomics.zig"445 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/atomics.zig"
449 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clear_cache.zig"446 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clear_cache.zig"
450 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clzsi2.zig"
451 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/compareXf2.zig"447 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/compareXf2.zig"
448 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/count0bits.zig"
452 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divdf3.zig"449 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divdf3.zig"
453 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divsf3.zig"450 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divsf3.zig"
454 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divtf3.zig"451 "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divtf3.zig"
...@@ -532,7 +529,7 @@ set(ZIG_STAGE2_SOURCES...@@ -532,7 +529,7 @@ set(ZIG_STAGE2_SOURCES
532 "${CMAKE_SOURCE_DIR}/lib/std/time.zig"529 "${CMAKE_SOURCE_DIR}/lib/std/time.zig"
533 "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"530 "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"
534 "${CMAKE_SOURCE_DIR}/lib/std/zig.zig"531 "${CMAKE_SOURCE_DIR}/lib/std/zig.zig"
535 "${CMAKE_SOURCE_DIR}/lib/std/zig/ast.zig"532 "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig"
536 "${CMAKE_SOURCE_DIR}/lib/std/zig/cross_target.zig"533 "${CMAKE_SOURCE_DIR}/lib/std/zig/cross_target.zig"
537 "${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"534 "${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"
538 "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"535 "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
...@@ -577,11 +574,11 @@ set(ZIG_STAGE2_SOURCES...@@ -577,11 +574,11 @@ set(ZIG_STAGE2_SOURCES
577 "${CMAKE_SOURCE_DIR}/src/link/Plan9/aout.zig"574 "${CMAKE_SOURCE_DIR}/src/link/Plan9/aout.zig"
578 "${CMAKE_SOURCE_DIR}/src/link/MachO.zig"575 "${CMAKE_SOURCE_DIR}/src/link/MachO.zig"
579 "${CMAKE_SOURCE_DIR}/src/link/MachO/Archive.zig"576 "${CMAKE_SOURCE_DIR}/src/link/MachO/Archive.zig"
577 "${CMAKE_SOURCE_DIR}/src/link/MachO/Atom.zig"
580 "${CMAKE_SOURCE_DIR}/src/link/MachO/CodeSignature.zig"578 "${CMAKE_SOURCE_DIR}/src/link/MachO/CodeSignature.zig"
581 "${CMAKE_SOURCE_DIR}/src/link/MachO/DebugSymbols.zig"579 "${CMAKE_SOURCE_DIR}/src/link/MachO/DebugSymbols.zig"
582 "${CMAKE_SOURCE_DIR}/src/link/MachO/Dylib.zig"580 "${CMAKE_SOURCE_DIR}/src/link/MachO/Dylib.zig"
583 "${CMAKE_SOURCE_DIR}/src/link/MachO/Object.zig"581 "${CMAKE_SOURCE_DIR}/src/link/MachO/Object.zig"
584 "${CMAKE_SOURCE_DIR}/src/link/MachO/TextBlock.zig"
585 "${CMAKE_SOURCE_DIR}/src/link/MachO/Trie.zig"582 "${CMAKE_SOURCE_DIR}/src/link/MachO/Trie.zig"
586 "${CMAKE_SOURCE_DIR}/src/link/MachO/bind.zig"583 "${CMAKE_SOURCE_DIR}/src/link/MachO/bind.zig"
587 "${CMAKE_SOURCE_DIR}/src/link/MachO/commands.zig"584 "${CMAKE_SOURCE_DIR}/src/link/MachO/commands.zig"
ci/srht/index.json+66
...@@ -45,6 +45,72 @@...@@ -45,6 +45,72 @@
45 "size": "{{AARCH64_LINUX_BYTESIZE}}"45 "size": "{{AARCH64_LINUX_BYTESIZE}}"
46 }46 }
47 },47 },
48 "0.8.1": {
49 "date": "2021-09-06",
50 "docs": "https://ziglang.org/documentation/0.8.1/",
51 "stdDocs": "https://ziglang.org/documentation/0.8.1/std/",
52 "notes": "https://ziglang.org/download/0.8.1/release-notes.html",
53 "src": {
54 "tarball": "https://ziglang.org/download/0.8.1/zig-0.8.1.tar.xz",
55 "shasum": "8c428e14a0a89cb7a15a6768424a37442292858cdb695e2eb503fa3c7bf47f1a",
56 "size": "12650228"
57 },
58 "bootstrap": {
59 "tarball": "https://ziglang.org/download/0.8.1/zig-bootstrap-0.8.1.tar.xz",
60 "shasum": "fa1239247f830ecd51c42537043f5220e4d1dfefdc54356fa419616a0efb3902",
61 "size": "43613464"
62 },
63 "x86_64-freebsd": {
64 "tarball": "https://ziglang.org/download/0.8.1/zig-freebsd-x86_64-0.8.1.tar.xz",
65 "shasum": "fc4f6478bcf3a9fce1b8ef677a91694f476dd35be6d6c9c4f44a8b76eedbe176",
66 "size": "39150924"
67 },
68 "aarch64-linux": {
69 "tarball": "https://ziglang.org/download/0.8.1/zig-linux-aarch64-0.8.1.tar.xz",
70 "shasum": "2166dc9f2d8df387e8b4122883bb979d739281e1ff3f3d5483fec3a23b957510",
71 "size": "37605932"
72 },
73 "armv7a-linux": {
74 "tarball": "https://ziglang.org/download/0.8.1/zig-linux-armv7a-0.8.1.tar.xz",
75 "shasum": "5ba58141805e2519f38cf8e715933cbf059f4f3dade92c71838cce341045de05",
76 "size": "39185876"
77 },
78 "i386-linux": {
79 "tarball": "https://ziglang.org/download/0.8.1/zig-linux-i386-0.8.1.tar.xz",
80 "shasum": "2f3e84f30492b5f1c5f97cecc0166f07a8a8d50c5f85dbb3a6ef2a4ee6f915e6",
81 "size": "44782932"
82 },
83 "riscv64-linux": {
84 "tarball": "https://ziglang.org/download/0.8.1/zig-linux-riscv64-0.8.1.tar.xz",
85 "shasum": "4adfaf147b025917c03367462fe5018aaa9edbc6439ef9cd0da2b074ae960554",
86 "size": "41234480"
87 },
88 "x86_64-linux": {
89 "tarball": "https://ziglang.org/download/0.8.1/zig-linux-x86_64-0.8.1.tar.xz",
90 "shasum": "6c032fc61b5d77a3f3cf781730fa549f8f059ffdb3b3f6ad1c2994d2b2d87983",
91 "size": "41250060"
92 },
93 "aarch64-macos": {
94 "tarball": "https://ziglang.org/download/0.8.1/zig-macos-aarch64-0.8.1.tar.xz",
95 "shasum": "5351297e3b8408213514b29c0a938002c5cf9f97eee28c2f32920e1227fd8423",
96 "size": "35340712"
97 },
98 "x86_64-macos": {
99 "tarball": "https://ziglang.org/download/0.8.1/zig-macos-x86_64-0.8.1.tar.xz",
100 "shasum": "16b0e1defe4c1807f2e128f72863124bffdd906cefb21043c34b673bf85cd57f",
101 "size": "39946200"
102 },
103 "i386-windows": {
104 "tarball": "https://ziglang.org/download/0.8.1/zig-windows-i386-0.8.1.zip",
105 "shasum": "099605051eb0452a947c8eab8fbbc7e43833c8376d267e94e41131c289a1c535",
106 "size": "64152358"
107 },
108 "x86_64-windows": {
109 "tarball": "https://ziglang.org/download/0.8.1/zig-windows-x86_64-0.8.1.zip",
110 "shasum": "43573db14cd238f7111d6bdf37492d363f11ecd1eba802567a172f277d003926",
111 "size": "61897838"
112 }
113 },
48 "0.8.0": {114 "0.8.0": {
49 "date": "2021-06-04",115 "date": "2021-06-04",
50 "docs": "https://ziglang.org/documentation/0.8.0/",116 "docs": "https://ziglang.org/documentation/0.8.0/",
cmake/Findclang.cmake+6
...@@ -14,6 +14,8 @@ find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h...@@ -14,6 +14,8 @@ find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h
14 /usr/lib/llvm-13.0/include14 /usr/lib/llvm-13.0/include
15 /usr/local/llvm130/include15 /usr/local/llvm130/include
16 /usr/local/llvm13/include16 /usr/local/llvm13/include
17 /usr/local/opt/llvm@13/include
18 /opt/homebrew/opt/llvm@13/include
17 /mingw64/include19 /mingw64/include
18)20)
1921
...@@ -30,6 +32,8 @@ if(ZIG_PREFER_CLANG_CPP_DYLIB)...@@ -30,6 +32,8 @@ if(ZIG_PREFER_CLANG_CPP_DYLIB)
30 /usr/lib/llvm-13/lib32 /usr/lib/llvm-13/lib
31 /usr/local/llvm130/lib33 /usr/local/llvm130/lib
32 /usr/local/llvm13/lib34 /usr/local/llvm13/lib
35 /usr/local/opt/llvm@13/lib
36 /opt/homebrew/opt/llvm@13/lib
33 )37 )
34endif()38endif()
3539
...@@ -44,6 +48,8 @@ if(NOT CLANG_LIBRARIES)...@@ -44,6 +48,8 @@ if(NOT CLANG_LIBRARIES)
44 /usr/lib/llvm-13.0/lib48 /usr/lib/llvm-13.0/lib
45 /usr/local/llvm130/lib49 /usr/local/llvm130/lib
46 /usr/local/llvm13/lib50 /usr/local/llvm13/lib
51 /usr/local/opt/llvm@13/lib
52 /opt/homebrew/opt/llvm@13/lib
47 /mingw64/lib53 /mingw64/lib
48 /c/msys64/mingw64/lib54 /c/msys64/mingw64/lib
49 c:\\msys64\\mingw64\\lib55 c:\\msys64\\mingw64\\lib
cmake/Findlld.cmake+6
...@@ -11,6 +11,8 @@ find_path(LLD_INCLUDE_DIRS NAMES lld/Common/Driver.h...@@ -11,6 +11,8 @@ find_path(LLD_INCLUDE_DIRS NAMES lld/Common/Driver.h
11 /usr/lib/llvm-13/include11 /usr/lib/llvm-13/include
12 /usr/local/llvm130/include12 /usr/local/llvm130/include
13 /usr/local/llvm13/include13 /usr/local/llvm13/include
14 /usr/local/opt/llvm@13/include
15 /opt/homebrew/opt/llvm@13/include
14 /mingw64/include)16 /mingw64/include)
1517
16find_library(LLD_LIBRARY NAMES lld-13.0 lld130 lld18find_library(LLD_LIBRARY NAMES lld-13.0 lld130 lld
...@@ -18,6 +20,8 @@ find_library(LLD_LIBRARY NAMES lld-13.0 lld130 lld...@@ -18,6 +20,8 @@ find_library(LLD_LIBRARY NAMES lld-13.0 lld130 lld
18 /usr/lib/llvm-13/lib20 /usr/lib/llvm-13/lib
19 /usr/local/llvm130/lib21 /usr/local/llvm130/lib
20 /usr/local/llvm13/lib22 /usr/local/llvm13/lib
23 /usr/local/opt/llvm@13/lib
24 /opt/homebrew/opt/llvm@13/lib
21)25)
22if(EXISTS ${LLD_LIBRARY})26if(EXISTS ${LLD_LIBRARY})
23 set(LLD_LIBRARIES ${LLD_LIBRARY})27 set(LLD_LIBRARIES ${LLD_LIBRARY})
...@@ -30,6 +34,8 @@ else()...@@ -30,6 +34,8 @@ else()
30 /usr/lib/llvm-13/lib34 /usr/lib/llvm-13/lib
31 /usr/local/llvm130/lib35 /usr/local/llvm130/lib
32 /usr/local/llvm13/lib36 /usr/local/llvm13/lib
37 /usr/local/opt/llvm@13/lib
38 /opt/homebrew/opt/llvm@13/lib
33 /mingw64/lib39 /mingw64/lib
34 /c/msys64/mingw64/lib40 /c/msys64/mingw64/lib
35 c:/msys64/mingw64/lib)41 c:/msys64/mingw64/lib)
cmake/Findllvm.cmake+6
...@@ -14,6 +14,8 @@ find_path(LLVM_INCLUDE_DIRS NAMES llvm/IR/IRBuilder.h...@@ -14,6 +14,8 @@ find_path(LLVM_INCLUDE_DIRS NAMES llvm/IR/IRBuilder.h
14 /usr/lib/llvm-13.0/include14 /usr/lib/llvm-13.0/include
15 /usr/local/llvm13/include15 /usr/local/llvm13/include
16 /usr/local/llvm130/include16 /usr/local/llvm130/include
17 /usr/local/opt/llvm@13/include
18 /opt/homebrew/opt/llvm@13/include
17 /mingw64/include19 /mingw64/include
18)20)
1921
...@@ -31,6 +33,8 @@ if(ZIG_PREFER_CLANG_CPP_DYLIB)...@@ -31,6 +33,8 @@ if(ZIG_PREFER_CLANG_CPP_DYLIB)
31 /usr/lib/llvm-13/lib33 /usr/lib/llvm-13/lib
32 /usr/local/llvm13/lib34 /usr/local/llvm13/lib
33 /usr/local/llvm130/lib35 /usr/local/llvm130/lib
36 /usr/local/opt/llvm@13/lib
37 /opt/homebrew/opt/llvm@13/lib
34 )38 )
3539
36 find_program(LLVM_CONFIG_EXE40 find_program(LLVM_CONFIG_EXE
...@@ -185,6 +189,8 @@ else()...@@ -185,6 +189,8 @@ else()
185 /usr/lib/llvm-13.0/lib189 /usr/lib/llvm-13.0/lib
186 /usr/local/llvm130/lib190 /usr/local/llvm130/lib
187 /usr/local/llvm13/lib191 /usr/local/llvm13/lib
192 /usr/local/opt/llvm@13/lib
193 /opt/homebrew/opt/llvm@13/lib
188 /mingw64/lib194 /mingw64/lib
189 /c/msys64/mingw64/lib195 /c/msys64/mingw64/lib
190 c:\\msys64\\mingw64\\lib)196 c:\\msys64\\mingw64\\lib)
doc/docgen.zig+391-65
...@@ -280,7 +280,7 @@ const Code = struct {...@@ -280,7 +280,7 @@ const Code = struct {
280 id: Id,280 id: Id,
281 name: []const u8,281 name: []const u8,
282 source_token: Token,282 source_token: Token,
283 is_inline: bool,283 just_check_syntax: bool,
284 mode: std.builtin.Mode,284 mode: std.builtin.Mode,
285 link_objects: []const []const u8,285 link_objects: []const []const u8,
286 target_str: ?[]const u8,286 target_str: ?[]const u8,
...@@ -305,6 +305,18 @@ const Link = struct {...@@ -305,6 +305,18 @@ const Link = struct {
305 token: Token,305 token: Token,
306};306};
307307
308const SyntaxBlock = struct {
309 source_type: SourceType,
310 name: []const u8,
311 source_token: Token,
312
313 const SourceType = enum {
314 zig,
315 c,
316 javascript,
317 };
318};
319
308const Node = union(enum) {320const Node = union(enum) {
309 Content: []const u8,321 Content: []const u8,
310 Nav,322 Nav,
...@@ -313,7 +325,9 @@ const Node = union(enum) {...@@ -313,7 +325,9 @@ const Node = union(enum) {
313 SeeAlso: []const SeeAlsoItem,325 SeeAlso: []const SeeAlsoItem,
314 Code: Code,326 Code: Code,
315 Link: Link,327 Link: Link,
316 Syntax: Token,328 InlineSyntax: Token,
329 Shell: Token,
330 SyntaxBlock: SyntaxBlock,
317};331};
318332
319const Toc = struct {333const Toc = struct {
...@@ -403,7 +417,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -403,7 +417,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
403 .HeaderOpen = HeaderOpen{417 .HeaderOpen = HeaderOpen{
404 .name = content,418 .name = content,
405 .url = urlized,419 .url = urlized,
406 .n = header_stack_size,420 .n = header_stack_size + 1, // highest-level section headers start at h2
407 },421 },
408 });422 });
409 if (try urls.fetchPut(urlized, tag_token)) |kv| {423 if (try urls.fetchPut(urlized, tag_token)) |kv| {
...@@ -502,7 +516,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -502,7 +516,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
502 }516 }
503 const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];517 const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];
504 var code_kind_id: Code.Id = undefined;518 var code_kind_id: Code.Id = undefined;
505 var is_inline = false;519 var just_check_syntax = false;
506 if (mem.eql(u8, code_kind_str, "exe")) {520 if (mem.eql(u8, code_kind_str, "exe")) {
507 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Succeed };521 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Succeed };
508 } else if (mem.eql(u8, code_kind_str, "exe_err")) {522 } else if (mem.eql(u8, code_kind_str, "exe_err")) {
...@@ -526,7 +540,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -526,7 +540,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
526 code_kind_id = Code.Id.Lib;540 code_kind_id = Code.Id.Lib;
527 } else if (mem.eql(u8, code_kind_str, "syntax")) {541 } else if (mem.eql(u8, code_kind_str, "syntax")) {
528 code_kind_id = Code.Id{ .Obj = null };542 code_kind_id = Code.Id{ .Obj = null };
529 is_inline = true;543 just_check_syntax = true;
530 } else {544 } else {
531 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {s}", .{code_kind_str});545 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {s}", .{code_kind_str});
532 }546 }
...@@ -589,7 +603,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -589,7 +603,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
589 .id = code_kind_id,603 .id = code_kind_id,
590 .name = name,604 .name = name,
591 .source_token = source_token,605 .source_token = source_token,
592 .is_inline = is_inline,606 .just_check_syntax = just_check_syntax,
593 .mode = mode,607 .mode = mode,
594 .link_objects = link_objects.toOwnedSlice(),608 .link_objects = link_objects.toOwnedSlice(),
595 .target_str = target_str,609 .target_str = target_str,
...@@ -615,7 +629,67 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -615,7 +629,67 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
615 );629 );
616 }630 }
617 _ = try eatToken(tokenizer, Token.Id.BracketClose);631 _ = try eatToken(tokenizer, Token.Id.BracketClose);
618 try nodes.append(Node{ .Syntax = content_tok });632 try nodes.append(Node{ .InlineSyntax = content_tok });
633 } else if (mem.eql(u8, tag_name, "shell_samp")) {
634 _ = try eatToken(tokenizer, Token.Id.BracketClose);
635 const content_tok = try eatToken(tokenizer, Token.Id.Content);
636 _ = try eatToken(tokenizer, Token.Id.BracketOpen);
637 const end_syntax_tag = try eatToken(tokenizer, Token.Id.TagContent);
638 const end_tag_name = tokenizer.buffer[end_syntax_tag.start..end_syntax_tag.end];
639 if (!mem.eql(u8, end_tag_name, "end_shell_samp")) {
640 return parseError(
641 tokenizer,
642 end_syntax_tag,
643 "invalid token inside syntax: {s}",
644 .{end_tag_name},
645 );
646 }
647 _ = try eatToken(tokenizer, Token.Id.BracketClose);
648 try nodes.append(Node{ .Shell = content_tok });
649 } else if (mem.eql(u8, tag_name, "syntax_block")) {
650 _ = try eatToken(tokenizer, Token.Id.Separator);
651 const source_type_tok = try eatToken(tokenizer, Token.Id.TagContent);
652 var name: []const u8 = "sample_code";
653 const maybe_sep = tokenizer.next();
654 switch (maybe_sep.id) {
655 Token.Id.Separator => {
656 const name_tok = try eatToken(tokenizer, Token.Id.TagContent);
657 name = tokenizer.buffer[name_tok.start..name_tok.end];
658 _ = try eatToken(tokenizer, Token.Id.BracketClose);
659 },
660 Token.Id.BracketClose => {},
661 else => return parseError(tokenizer, token, "invalid token", .{}),
662 }
663 const source_type_str = tokenizer.buffer[source_type_tok.start..source_type_tok.end];
664 var source_type: SyntaxBlock.SourceType = undefined;
665 if (mem.eql(u8, source_type_str, "zig")) {
666 source_type = SyntaxBlock.SourceType.zig;
667 } else if (mem.eql(u8, source_type_str, "c")) {
668 source_type = SyntaxBlock.SourceType.c;
669 } else if (mem.eql(u8, source_type_str, "javascript")) {
670 source_type = SyntaxBlock.SourceType.javascript;
671 } else {
672 return parseError(tokenizer, source_type_tok, "unrecognized code kind: {s}", .{source_type_str});
673 }
674 const source_token = while (true) {
675 const content_tok = try eatToken(tokenizer, Token.Id.Content);
676 _ = try eatToken(tokenizer, Token.Id.BracketOpen);
677 const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent);
678 const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end];
679 if (mem.eql(u8, end_tag_name, "end_syntax_block")) {
680 _ = try eatToken(tokenizer, Token.Id.BracketClose);
681 break content_tok;
682 } else {
683 return parseError(
684 tokenizer,
685 end_code_tag,
686 "invalid token inside code_begin: {s}",
687 .{end_tag_name},
688 );
689 }
690 _ = try eatToken(tokenizer, Token.Id.BracketClose);
691 } else unreachable; // TODO issue #707
692 try nodes.append(Node{ .SyntaxBlock = SyntaxBlock{ .source_type = source_type, .name = name, .source_token = source_token } });
619 } else {693 } else {
620 return parseError(tokenizer, tag_token, "unrecognized tag name: {s}", .{tag_name});694 return parseError(tokenizer, tag_token, "unrecognized tag name: {s}", .{tag_name});
621 }695 }
...@@ -693,7 +767,7 @@ test "term color" {...@@ -693,7 +767,7 @@ test "term color" {
693 const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";767 const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
694 const result = try termColor(std.testing.allocator, input_bytes);768 const result = try termColor(std.testing.allocator, input_bytes);
695 defer std.testing.allocator.free(result);769 defer std.testing.allocator.free(result);
696 testing.expectEqualSlices(u8, "A<span class=\"t32\">green</span>B", result);770 try testing.expectEqualSlices(u8, "A<span class=\"t32_1\">green</span>B", result);
697}771}
698772
699fn termColor(allocator: *Allocator, input: []const u8) ![]u8 {773fn termColor(allocator: *Allocator, input: []const u8) ![]u8 {
...@@ -799,7 +873,7 @@ fn tokenizeAndPrintRaw(...@@ -799,7 +873,7 @@ fn tokenizeAndPrintRaw(
799) !void {873) !void {
800 const src_non_terminated = mem.trim(u8, raw_src, " \n");874 const src_non_terminated = mem.trim(u8, raw_src, " \n");
801 const src = try allocator.dupeZ(u8, src_non_terminated);875 const src = try allocator.dupeZ(u8, src_non_terminated);
802 try out.writeAll("<code class=\"zig\">");876 try out.writeAll("<code>");
803 var tokenizer = std.zig.Tokenizer.init(src);877 var tokenizer = std.zig.Tokenizer.init(src);
804 var index: usize = 0;878 var index: usize = 0;
805 var next_tok_is_fn = false;879 var next_tok_is_fn = false;
...@@ -1033,6 +1107,47 @@ fn tokenizeAndPrint(...@@ -1033,6 +1107,47 @@ fn tokenizeAndPrint(
1033 return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src);1107 return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src);
1034}1108}
10351109
1110fn printSourceBlock(allocator: *Allocator, docgen_tokenizer: *Tokenizer, out: anytype, syntax_block: SyntaxBlock) !void {
1111 const source_type = @tagName(syntax_block.source_type);
1112
1113 try out.print("<figure><figcaption class=\"{s}-cap\"><cite class=\"file\">{s}</cite></figcaption><pre>", .{ source_type, syntax_block.name });
1114 switch (syntax_block.source_type) {
1115 .zig => try tokenizeAndPrint(allocator, docgen_tokenizer, out, syntax_block.source_token),
1116 else => {
1117 const raw_source = docgen_tokenizer.buffer[syntax_block.source_token.start..syntax_block.source_token.end];
1118 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
1119
1120 try out.writeAll("<code>");
1121 try writeEscaped(out, trimmed_raw_source);
1122 try out.writeAll("</code>");
1123 },
1124 }
1125 try out.writeAll("</pre></figure>");
1126}
1127
1128fn printShell(out: anytype, shell_content: []const u8) !void {
1129 const trimmed_shell_content = mem.trim(u8, shell_content, " \n");
1130 try out.writeAll("<figure><figcaption class=\"shell-cap\">Shell</figcaption><pre><samp>");
1131 var cmd_cont: bool = false;
1132 var iter = std.mem.split(u8, trimmed_shell_content, "\n");
1133 while (iter.next()) |orig_line| {
1134 const line = mem.trimRight(u8, orig_line, " ");
1135 if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] != '\\') {
1136 try out.print("$ <kbd>{s}</kbd>\n", .{std.mem.trimLeft(u8, line[1..], " ")});
1137 } else if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] == '\\') {
1138 try out.print("$ <kbd>{s}\n", .{std.mem.trimLeft(u8, line[1..], " ")});
1139 cmd_cont = true;
1140 } else if (line.len > 0 and line[line.len - 1] != '\\' and cmd_cont) {
1141 try out.print("{s}</kbd>\n", .{line});
1142 cmd_cont = false;
1143 } else {
1144 try out.print("{s}\n", .{line});
1145 }
1146 }
1147
1148 try out.writeAll("</samp></pre></figure>");
1149}
1150
1036fn genHtml(1151fn genHtml(
1037 allocator: *Allocator,1152 allocator: *Allocator,
1038 tokenizer: *Tokenizer,1153 tokenizer: *Tokenizer,
...@@ -1066,9 +1181,9 @@ fn genHtml(...@@ -1066,9 +1181,9 @@ fn genHtml(
1066 try out.writeAll(toc.toc);1181 try out.writeAll(toc.toc);
1067 },1182 },
1068 .Builtin => |tok| {1183 .Builtin => |tok| {
1069 try out.writeAll("<pre>");1184 try out.writeAll("<figure><figcaption class=\"zig-cap\"><cite>@import(\"builtin\")</cite></figcaption><pre>");
1070 try tokenizeAndPrintRaw(allocator, tokenizer, out, tok, builtin_code);1185 try tokenizeAndPrintRaw(allocator, tokenizer, out, tok, builtin_code);
1071 try out.writeAll("</pre>");1186 try out.writeAll("</pre></figure>");
1072 },1187 },
1073 .HeaderOpen => |info| {1188 .HeaderOpen => |info| {
1074 try out.print(1189 try out.print(
...@@ -1087,30 +1202,44 @@ fn genHtml(...@@ -1087,30 +1202,44 @@ fn genHtml(
1087 }1202 }
1088 try out.writeAll("</ul>\n");1203 try out.writeAll("</ul>\n");
1089 },1204 },
1090 .Syntax => |content_tok| {1205 .InlineSyntax => |content_tok| {
1091 try tokenizeAndPrint(allocator, tokenizer, out, content_tok);1206 try tokenizeAndPrint(allocator, tokenizer, out, content_tok);
1092 },1207 },
1208 .Shell => |content_tok| {
1209 const raw_shell_content = tokenizer.buffer[content_tok.start..content_tok.end];
1210 try printShell(out, raw_shell_content);
1211 },
1212 .SyntaxBlock => |syntax_block| {
1213 try printSourceBlock(allocator, tokenizer, out, syntax_block);
1214 },
1093 .Code => |code| {1215 .Code => |code| {
1094 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];1216 const name_plus_ext = try std.fmt.allocPrint(allocator, "{s}.zig", .{code.name});
1095 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");1217 const syntax_block = SyntaxBlock{
1096 if (!code.is_inline) {1218 .source_type = .zig,
1097 try out.print("<p class=\"file\">{s}.zig</p>", .{code.name});1219 .name = name_plus_ext,
1098 }1220 .source_token = code.source_token,
1099 try out.writeAll("<pre>");1221 };
1100 try tokenizeAndPrint(allocator, tokenizer, out, code.source_token);1222
1101 try out.writeAll("</pre>");1223 try printSourceBlock(allocator, tokenizer, out, syntax_block);
11021224
1103 if (!do_code_tests) {1225 // TODO: remove code.just_check_syntax after updating code samples
1226 // that have stopped working due to a change in the compiler.
1227 if (!do_code_tests or code.just_check_syntax) {
1104 continue;1228 continue;
1105 }1229 }
11061230
1107 const name_plus_ext = try std.fmt.allocPrint(allocator, "{s}.zig", .{code.name});1231 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
1232 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
1108 const tmp_source_file_name = try fs.path.join(1233 const tmp_source_file_name = try fs.path.join(
1109 allocator,1234 allocator,
1110 &[_][]const u8{ tmp_dir_name, name_plus_ext },1235 &[_][]const u8{ tmp_dir_name, name_plus_ext },
1111 );1236 );
1112 try fs.cwd().writeFile(tmp_source_file_name, trimmed_raw_source);1237 try fs.cwd().writeFile(tmp_source_file_name, trimmed_raw_source);
11131238
1239 var shell_buffer = std.ArrayList(u8).init(allocator);
1240 defer shell_buffer.deinit();
1241 var shell_out = shell_buffer.writer();
1242
1114 switch (code.id) {1243 switch (code.id) {
1115 Code.Id.Exe => |expected_outcome| code_block: {1244 Code.Id.Exe => |expected_outcome| code_block: {
1116 var build_args = std.ArrayList([]const u8).init(allocator);1245 var build_args = std.ArrayList([]const u8).init(allocator);
...@@ -1121,12 +1250,14 @@ fn genHtml(...@@ -1121,12 +1250,14 @@ fn genHtml(
1121 "--color", "on",1250 "--color", "on",
1122 "--enable-cache", tmp_source_file_name,1251 "--enable-cache", tmp_source_file_name,
1123 });1252 });
1124 try out.print("<pre><code class=\"shell\">$ zig build-exe {s}.zig", .{code.name});1253
1254 try shell_out.print("$ zig build-exe {s} ", .{name_plus_ext});
1255
1125 switch (code.mode) {1256 switch (code.mode) {
1126 .Debug => {},1257 .Debug => {},
1127 else => {1258 else => {
1128 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1259 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1129 try out.print(" -O {s}", .{@tagName(code.mode)});1260 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1130 },1261 },
1131 }1262 }
1132 for (code.link_objects) |link_object| {1263 for (code.link_objects) |link_object| {
...@@ -1136,25 +1267,26 @@ fn genHtml(...@@ -1136,25 +1267,26 @@ fn genHtml(
1136 &[_][]const u8{ tmp_dir_name, name_with_ext },1267 &[_][]const u8{ tmp_dir_name, name_with_ext },
1137 );1268 );
1138 try build_args.append(full_path_object);1269 try build_args.append(full_path_object);
1139 try out.print(" {s}", .{name_with_ext});1270 try shell_out.print("{s} ", .{name_with_ext});
1140 }1271 }
1141 if (code.link_libc) {1272 if (code.link_libc) {
1142 try build_args.append("-lc");1273 try build_args.append("-lc");
1143 try out.print(" -lc", .{});1274 try shell_out.print("-lc ", .{});
1144 }1275 }
1145 const target = try std.zig.CrossTarget.parse(.{1276 const target = try std.zig.CrossTarget.parse(.{
1146 .arch_os_abi = code.target_str orelse "native",1277 .arch_os_abi = code.target_str orelse "native",
1147 });1278 });
1148 if (code.target_str) |triple| {1279 if (code.target_str) |triple| {
1149 try build_args.appendSlice(&[_][]const u8{ "-target", triple });1280 try build_args.appendSlice(&[_][]const u8{ "-target", triple });
1150 if (!code.is_inline) {1281 try shell_out.print("-target {s} ", .{triple});
1151 try out.print(" -target {s}", .{triple});
1152 }
1153 }1282 }
1154 if (code.verbose_cimport) {1283 if (code.verbose_cimport) {
1155 try build_args.append("--verbose-cimport");1284 try build_args.append("--verbose-cimport");
1156 try out.print(" --verbose-cimport", .{});1285 try shell_out.print("--verbose-cimport ", .{});
1157 }1286 }
1287
1288 try shell_out.print("\n", .{});
1289
1158 if (expected_outcome == .BuildFail) {1290 if (expected_outcome == .BuildFail) {
1159 const result = try ChildProcess.exec(.{1291 const result = try ChildProcess.exec(.{
1160 .allocator = allocator,1292 .allocator = allocator,
...@@ -1180,12 +1312,17 @@ fn genHtml(...@@ -1180,12 +1312,17 @@ fn genHtml(
1180 }1312 }
1181 const escaped_stderr = try escapeHtml(allocator, result.stderr);1313 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1182 const colored_stderr = try termColor(allocator, escaped_stderr);1314 const colored_stderr = try termColor(allocator, escaped_stderr);
1183 try out.print("\n{s}</code></pre>\n", .{colored_stderr});1315 try shell_out.writeAll(colored_stderr);
1184 break :code_block;1316 break :code_block;
1185 }1317 }
1186 const exec_result = exec(allocator, &env_map, build_args.items) catch1318 const exec_result = exec(allocator, &env_map, build_args.items) catch
1187 return parseError(tokenizer, code.source_token, "example failed to compile", .{});1319 return parseError(tokenizer, code.source_token, "example failed to compile", .{});
11881320
1321 if (code.verbose_cimport) {
1322 const escaped_build_stderr = try escapeHtml(allocator, exec_result.stderr);
1323 try shell_out.writeAll(escaped_build_stderr);
1324 }
1325
1189 if (code.target_str) |triple| {1326 if (code.target_str) |triple| {
1190 if (mem.startsWith(u8, triple, "wasm32") or1327 if (mem.startsWith(u8, triple, "wasm32") or
1191 mem.startsWith(u8, triple, "riscv64-linux") or1328 mem.startsWith(u8, triple, "riscv64-linux") or
...@@ -1193,7 +1330,6 @@ fn genHtml(...@@ -1193,7 +1330,6 @@ fn genHtml(
1193 std.Target.current.os.tag != .linux or std.Target.current.cpu.arch != .x86_64))1330 std.Target.current.os.tag != .linux or std.Target.current.cpu.arch != .x86_64))
1194 {1331 {
1195 // skip execution1332 // skip execution
1196 try out.print("</code></pre>\n", .{});
1197 break :code_block;1333 break :code_block;
1198 }1334 }
1199 }1335 }
...@@ -1241,41 +1377,38 @@ fn genHtml(...@@ -1241,41 +1377,38 @@ fn genHtml(
1241 const colored_stderr = try termColor(allocator, escaped_stderr);1377 const colored_stderr = try termColor(allocator, escaped_stderr);
1242 const colored_stdout = try termColor(allocator, escaped_stdout);1378 const colored_stdout = try termColor(allocator, escaped_stdout);
12431379
1244 if (code.verbose_cimport) {1380 try shell_out.print("\n$ ./{s}\n{s}{s}", .{ code.name, colored_stdout, colored_stderr });
1245 const escaped_build_stderr = try escapeHtml(allocator, exec_result.stderr);
1246 try out.print("\n{s}", .{escaped_build_stderr});
1247 }
1248 try out.print("\n$ ./{s}\n{s}{s}", .{ code.name, colored_stdout, colored_stderr });
1249 if (exited_with_signal) {1381 if (exited_with_signal) {
1250 try out.print("(process terminated by signal)", .{});1382 try shell_out.print("(process terminated by signal)", .{});
1251 }1383 }
1252 try out.print("</code></pre>\n", .{});1384 try shell_out.writeAll("\n");
1253 },1385 },
1254 Code.Id.Test => {1386 Code.Id.Test => {
1255 var test_args = std.ArrayList([]const u8).init(allocator);1387 var test_args = std.ArrayList([]const u8).init(allocator);
1256 defer test_args.deinit();1388 defer test_args.deinit();
12571389
1258 try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", tmp_source_file_name });1390 try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", tmp_source_file_name });
1259 try out.print("<pre><code class=\"shell\">$ zig test {s}.zig", .{code.name});1391 try shell_out.print("$ zig test {s}.zig ", .{code.name});
1392
1260 switch (code.mode) {1393 switch (code.mode) {
1261 .Debug => {},1394 .Debug => {},
1262 else => {1395 else => {
1263 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1396 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1264 try out.print(" -O {s}", .{@tagName(code.mode)});1397 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1265 },1398 },
1266 }1399 }
1267 if (code.link_libc) {1400 if (code.link_libc) {
1268 try test_args.append("-lc");1401 try test_args.append("-lc");
1269 try out.print(" -lc", .{});1402 try shell_out.print("-lc ", .{});
1270 }1403 }
1271 if (code.target_str) |triple| {1404 if (code.target_str) |triple| {
1272 try test_args.appendSlice(&[_][]const u8{ "-target", triple });1405 try test_args.appendSlice(&[_][]const u8{ "-target", triple });
1273 try out.print(" -target {s}", .{triple});1406 try shell_out.print("-target {s} ", .{triple});
1274 }1407 }
1275 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});1408 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});
1276 const escaped_stderr = try escapeHtml(allocator, result.stderr);1409 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1277 const escaped_stdout = try escapeHtml(allocator, result.stdout);1410 const escaped_stdout = try escapeHtml(allocator, result.stdout);
1278 try out.print("\n{s}{s}</code></pre>\n", .{ escaped_stderr, escaped_stdout });1411 try shell_out.print("\n{s}{s}\n", .{ escaped_stderr, escaped_stdout });
1279 },1412 },
1280 Code.Id.TestError => |error_match| {1413 Code.Id.TestError => |error_match| {
1281 var test_args = std.ArrayList([]const u8).init(allocator);1414 var test_args = std.ArrayList([]const u8).init(allocator);
...@@ -1288,12 +1421,13 @@ fn genHtml(...@@ -1288,12 +1421,13 @@ fn genHtml(
1288 "on",1421 "on",
1289 tmp_source_file_name,1422 tmp_source_file_name,
1290 });1423 });
1291 try out.print("<pre><code class=\"shell\">$ zig test {s}.zig", .{code.name});1424 try shell_out.print("$ zig test {s}.zig ", .{code.name});
1425
1292 switch (code.mode) {1426 switch (code.mode) {
1293 .Debug => {},1427 .Debug => {},
1294 else => {1428 else => {
1295 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1429 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1296 try out.print(" -O {s}", .{@tagName(code.mode)});1430 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1297 },1431 },
1298 }1432 }
1299 const result = try ChildProcess.exec(.{1433 const result = try ChildProcess.exec(.{
...@@ -1325,7 +1459,7 @@ fn genHtml(...@@ -1325,7 +1459,7 @@ fn genHtml(
1325 }1459 }
1326 const escaped_stderr = try escapeHtml(allocator, result.stderr);1460 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1327 const colored_stderr = try termColor(allocator, escaped_stderr);1461 const colored_stderr = try termColor(allocator, escaped_stderr);
1328 try out.print("\n{s}</code></pre>\n", .{colored_stderr});1462 try shell_out.print("\n{s}\n", .{colored_stderr});
1329 },1463 },
13301464
1331 Code.Id.TestSafety => |error_match| {1465 Code.Id.TestSafety => |error_match| {
...@@ -1383,7 +1517,7 @@ fn genHtml(...@@ -1383,7 +1517,7 @@ fn genHtml(
1383 }1517 }
1384 const escaped_stderr = try escapeHtml(allocator, result.stderr);1518 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1385 const colored_stderr = try termColor(allocator, escaped_stderr);1519 const colored_stderr = try termColor(allocator, escaped_stderr);
1386 try out.print("<pre><code class=\"shell\">$ zig test {s}.zig {s}\n{s}</code></pre>\n", .{1520 try shell_out.print("$ zig test {s}.zig {s}\n{s}\n", .{
1387 code.name,1521 code.name,
1388 mode_arg,1522 mode_arg,
1389 colored_stderr,1523 colored_stderr,
...@@ -1406,23 +1540,20 @@ fn genHtml(...@@ -1406,23 +1540,20 @@ fn genHtml(
1406 tmp_dir_name, fs.path.sep, name_plus_obj_ext,1540 tmp_dir_name, fs.path.sep, name_plus_obj_ext,
1407 }),1541 }),
1408 });1542 });
1409 if (!code.is_inline) {1543
1410 try out.print("<pre><code class=\"shell\">$ zig build-obj {s}.zig", .{code.name});1544 try shell_out.print("$ zig build-obj {s}.zig ", .{code.name});
1411 }
14121545
1413 switch (code.mode) {1546 switch (code.mode) {
1414 .Debug => {},1547 .Debug => {},
1415 else => {1548 else => {
1416 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1549 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1417 if (!code.is_inline) {1550 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1418 try out.print(" -O {s}", .{@tagName(code.mode)});
1419 }
1420 },1551 },
1421 }1552 }
14221553
1423 if (code.target_str) |triple| {1554 if (code.target_str) |triple| {
1424 try build_args.appendSlice(&[_][]const u8{ "-target", triple });1555 try build_args.appendSlice(&[_][]const u8{ "-target", triple });
1425 try out.print(" -target {s}", .{triple});1556 try shell_out.print("-target {s} ", .{triple});
1426 }1557 }
14271558
1428 if (maybe_error_match) |error_match| {1559 if (maybe_error_match) |error_match| {
...@@ -1455,13 +1586,11 @@ fn genHtml(...@@ -1455,13 +1586,11 @@ fn genHtml(
1455 }1586 }
1456 const escaped_stderr = try escapeHtml(allocator, result.stderr);1587 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1457 const colored_stderr = try termColor(allocator, escaped_stderr);1588 const colored_stderr = try termColor(allocator, escaped_stderr);
1458 try out.print("\n{s}", .{colored_stderr});1589 try shell_out.print("\n{s} ", .{colored_stderr});
1459 } else {1590 } else {
1460 _ = exec(allocator, &env_map, build_args.items) catch return parseError(tokenizer, code.source_token, "example failed to compile", .{});1591 _ = exec(allocator, &env_map, build_args.items) catch return parseError(tokenizer, code.source_token, "example failed to compile", .{});
1461 }1592 }
1462 if (!code.is_inline) {1593 try shell_out.writeAll("\n");
1463 try out.print("</code></pre>\n", .{});
1464 }
1465 },1594 },
1466 Code.Id.Lib => {1595 Code.Id.Lib => {
1467 const bin_basename = try std.zig.binNameAlloc(allocator, .{1596 const bin_basename = try std.zig.binNameAlloc(allocator, .{
...@@ -1481,36 +1610,41 @@ fn genHtml(...@@ -1481,36 +1610,41 @@ fn genHtml(
1481 tmp_dir_name, fs.path.sep_str, bin_basename,1610 tmp_dir_name, fs.path.sep_str, bin_basename,
1482 }),1611 }),
1483 });1612 });
1484 try out.print("<pre><code class=\"shell\">$ zig build-lib {s}.zig", .{code.name});1613 try shell_out.print("$ zig build-lib {s}.zig ", .{code.name});
1614
1485 switch (code.mode) {1615 switch (code.mode) {
1486 .Debug => {},1616 .Debug => {},
1487 else => {1617 else => {
1488 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1618 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1489 try out.print(" -O {s}", .{@tagName(code.mode)});1619 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1490 },1620 },
1491 }1621 }
1492 if (code.target_str) |triple| {1622 if (code.target_str) |triple| {
1493 try test_args.appendSlice(&[_][]const u8{ "-target", triple });1623 try test_args.appendSlice(&[_][]const u8{ "-target", triple });
1494 try out.print(" -target {s}", .{triple});1624 try shell_out.print("-target {s} ", .{triple});
1495 }1625 }
1496 if (code.link_mode) |link_mode| {1626 if (code.link_mode) |link_mode| {
1497 switch (link_mode) {1627 switch (link_mode) {
1498 .Static => {1628 .Static => {
1499 try test_args.append("-static");1629 try test_args.append("-static");
1500 try out.print(" -static", .{});1630 try shell_out.print("-static ", .{});
1501 },1631 },
1502 .Dynamic => {1632 .Dynamic => {
1503 try test_args.append("-dynamic");1633 try test_args.append("-dynamic");
1504 try out.print(" -dynamic", .{});1634 try shell_out.print("-dynamic ", .{});
1505 },1635 },
1506 }1636 }
1507 }1637 }
1508 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});1638 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});
1509 const escaped_stderr = try escapeHtml(allocator, result.stderr);1639 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1510 const escaped_stdout = try escapeHtml(allocator, result.stdout);1640 const escaped_stdout = try escapeHtml(allocator, result.stdout);
1511 try out.print("\n{s}{s}</code></pre>\n", .{ escaped_stderr, escaped_stdout });1641 try shell_out.print("\n{s}{s}\n", .{ escaped_stderr, escaped_stdout });
1512 },1642 },
1513 }1643 }
1644
1645 if (!code.just_check_syntax) {
1646 try printShell(out, shell_buffer.items);
1647 }
1514 },1648 },
1515 }1649 }
1516 }1650 }
...@@ -1551,3 +1685,195 @@ fn dumpArgs(args: []const []const u8) void {...@@ -1551,3 +1685,195 @@ fn dumpArgs(args: []const []const u8) void {
1551 else1685 else
1552 print("\n", .{});1686 print("\n", .{});
1553}1687}
1688
1689test "shell parsed" {
1690 const test_allocator = std.testing.allocator;
1691
1692 {
1693 const shell_out =
1694 \\$ zig build test.zig
1695 ;
1696 const expected =
1697 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1698 \\</samp></pre></figure>
1699 ;
1700
1701 var buffer = std.ArrayList(u8).init(test_allocator);
1702 defer buffer.deinit();
1703
1704 try printShell(buffer.writer(), shell_out);
1705 try testing.expectEqualSlices(u8, expected, buffer.items);
1706 }
1707 {
1708 const shell_out =
1709 \\$ zig build test.zig
1710 \\build output
1711 ;
1712 const expected =
1713 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1714 \\build output
1715 \\</samp></pre></figure>
1716 ;
1717
1718 var buffer = std.ArrayList(u8).init(test_allocator);
1719 defer buffer.deinit();
1720
1721 try printShell(buffer.writer(), shell_out);
1722 try testing.expectEqualSlices(u8, expected, buffer.items);
1723 }
1724 {
1725 const shell_out =
1726 \\$ zig build test.zig
1727 \\build output
1728 \\$ ./test
1729 ;
1730 const expected =
1731 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1732 \\build output
1733 \\$ <kbd>./test</kbd>
1734 \\</samp></pre></figure>
1735 ;
1736
1737 var buffer = std.ArrayList(u8).init(test_allocator);
1738 defer buffer.deinit();
1739
1740 try printShell(buffer.writer(), shell_out);
1741 try testing.expectEqualSlices(u8, expected, buffer.items);
1742 }
1743 {
1744 const shell_out =
1745 \\$ zig build test.zig
1746 \\
1747 \\$ ./test
1748 \\output
1749 ;
1750 const expected =
1751 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1752 \\
1753 \\$ <kbd>./test</kbd>
1754 \\output
1755 \\</samp></pre></figure>
1756 ;
1757
1758 var buffer = std.ArrayList(u8).init(test_allocator);
1759 defer buffer.deinit();
1760
1761 try printShell(buffer.writer(), shell_out);
1762 try testing.expectEqualSlices(u8, expected, buffer.items);
1763 }
1764 {
1765 const shell_out =
1766 \\$ zig build test.zig
1767 \\$ ./test
1768 \\output
1769 ;
1770 const expected =
1771 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1772 \\$ <kbd>./test</kbd>
1773 \\output
1774 \\</samp></pre></figure>
1775 ;
1776
1777 var buffer = std.ArrayList(u8).init(test_allocator);
1778 defer buffer.deinit();
1779
1780 try printShell(buffer.writer(), shell_out);
1781 try testing.expectEqualSlices(u8, expected, buffer.items);
1782 }
1783 {
1784 const shell_out =
1785 \\$ zig build test.zig \
1786 \\ --build-option
1787 \\build output
1788 \\$ ./test
1789 \\output
1790 ;
1791 const expected =
1792 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
1793 \\ --build-option</kbd>
1794 \\build output
1795 \\$ <kbd>./test</kbd>
1796 \\output
1797 \\</samp></pre></figure>
1798 ;
1799
1800 var buffer = std.ArrayList(u8).init(test_allocator);
1801 defer buffer.deinit();
1802
1803 try printShell(buffer.writer(), shell_out);
1804 try testing.expectEqualSlices(u8, expected, buffer.items);
1805 }
1806 {
1807 // intentional space after "--build-option1 \"
1808 const shell_out =
1809 \\$ zig build test.zig \
1810 \\ --build-option1 \
1811 \\ --build-option2
1812 \\$ ./test
1813 ;
1814 const expected =
1815 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
1816 \\ --build-option1 \
1817 \\ --build-option2</kbd>
1818 \\$ <kbd>./test</kbd>
1819 \\</samp></pre></figure>
1820 ;
1821
1822 var buffer = std.ArrayList(u8).init(test_allocator);
1823 defer buffer.deinit();
1824
1825 try printShell(buffer.writer(), shell_out);
1826 try testing.expectEqualSlices(u8, expected, buffer.items);
1827 }
1828 {
1829 const shell_out =
1830 \\$ zig build test.zig \
1831 \\$ ./test
1832 ;
1833 const expected =
1834 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
1835 \\$ ./test</kbd>
1836 \\</samp></pre></figure>
1837 ;
1838
1839 var buffer = std.ArrayList(u8).init(test_allocator);
1840 defer buffer.deinit();
1841
1842 try printShell(buffer.writer(), shell_out);
1843 try testing.expectEqualSlices(u8, expected, buffer.items);
1844 }
1845 {
1846 const shell_out =
1847 \\$ zig build test.zig
1848 \\$ ./test
1849 \\$1
1850 ;
1851 const expected =
1852 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1853 \\$ <kbd>./test</kbd>
1854 \\$1
1855 \\</samp></pre></figure>
1856 ;
1857
1858 var buffer = std.ArrayList(u8).init(test_allocator);
1859 defer buffer.deinit();
1860
1861 try printShell(buffer.writer(), shell_out);
1862 try testing.expectEqualSlices(u8, expected, buffer.items);
1863 }
1864 {
1865 const shell_out =
1866 \\$zig build test.zig
1867 ;
1868 const expected =
1869 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$zig build test.zig
1870 \\</samp></pre></figure>
1871 ;
1872
1873 var buffer = std.ArrayList(u8).init(test_allocator);
1874 defer buffer.deinit();
1875
1876 try printShell(buffer.writer(), shell_out);
1877 try testing.expectEqualSlices(u8, expected, buffer.items);
1878 }
1879}
doc/langref.html.in+814-683
...@@ -6,225 +6,312 @@...@@ -6,225 +6,312 @@
6 <title>Documentation - The Zig Programming Language</title>6 <title>Documentation - The Zig Programming Language</title>
7 <link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg=="/>7 <link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg=="/>
8 <style>8 <style>
9 :root{
10 --nav-width: 24em;
11 --nav-margin-l: 1em;
12 }
9 body{13 body{
10 font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;14 font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
11 margin: 0;15 margin: 0;
16 line-height: 1.5;
12 }17 }
13 a:not(:hover) {18 header {
14 text-decoration: none;19 padding: 0 1em;
15 }20 }
16 table, th, td {21 #contents {
17 border-collapse: collapse;22 max-width: 60em;
18 border: 1px solid grey;23 margin: auto;
24 padding: 0 1em;
19 }25 }
20 th, td {26 #navigation {
21 padding: 0.1em;27 padding: 0 1em;
22 }28 }
23 .t0_1, .t37, .t37_1 {29
30 @media screen and (min-width: 1025px) {
31 header {
32 margin-left: calc(var(--nav-width) + var(--nav-margin-l));
33 }
34 header h1 {
35 margin: auto;
36 max-width: 30em;
37 }
38 #navigation {
39 overflow: auto;
40 width: var(--nav-width);
41 height: 100vh;
42 position: fixed;
43 top:0;
44 left:0;
45 bottom:0;
46 padding: unset;
47 margin-left: var(--nav-margin-l);
48 }
49 #navigation nav ul {
50 padding-left: 1em;
51 }
52 #contents-wrapper {
53 margin-left: calc(var(--nav-width) + var(--nav-margin-l));
54 }
55 }
56
57 a:hover,a:focus {
58 background: #fff2a8;
59 }
60 dt {
61 font-weight: bold;
62 }
63 table, th, td {
64 border-collapse: collapse;
65 border: 1px solid grey;
66 }
67 th, td {
68 padding: 0.1em;
69 }
70 th[scope=row] {
71 text-align: left;
72 font-weight: normal;
73 }
74 .t0_1, .t37, .t37_1 {
75 font-weight: bold;
76 }
77 .t2_0 {
78 color: #575757;
79 }
80 .t31_1 {
81 color: #b40000;
82 }
83 .t32_1 {
84 color: green;
85 }
86 .t36_1 {
87 color: #005C7A;
88 }
89 .file {
90 font-weight: bold;
91 border: unset;
92 }
93 code {
94 background: #f8f8f8;
95 border: 1px dotted silver;
96 padding-left: 0.3em;
97 padding-right: 0.3em;
98 }
99 pre > code {
100 display: block;
101 overflow: auto;
102 padding: 0.5em;
103 border: 1px solid #eee;
104 line-height: normal;
105 }
106 samp {
107 background: #fafafa;
108 }
109 pre > samp {
110 display: block;
111 overflow: auto;
112 padding: 0.5em;
113 border: 1px solid #eee;
114 line-height: normal;
115 }
116 kbd {
117 font-weight: bold;
118 }
119 .table-wrapper {
120 width: 100%;
121 overflow-x: auto;
122 }
123
124 .tok-kw {
125 color: #333;
24 font-weight: bold;126 font-weight: bold;
127 }
128 .tok-str {
129 color: #d14;
130 }
131 .tok-builtin {
132 color: #005C7A;
133 }
134 .tok-comment {
135 color: #545454;
136 font-style: italic;
137 }
138 .tok-fn {
139 color: #900;
140 font-weight: bold;
141 }
142 .tok-null {
143 color: #005C5C;
144 }
145 .tok-number {
146 color: #005C5C;
147 }
148 .tok-type {
149 color: #458;
150 font-weight: bold;
151 }
152
153 figure {
154 margin: auto 0;
155 }
156 figure pre {
157 margin-top: 0;
158 }
159
160 figcaption {
161 padding-left: 0.5em;
162 font-size: small;
163 border-top-left-radius: 5px;
164 border-top-right-radius: 5px;
165 }
166 figcaption.zig-cap {
167 background: #fcdba5;
168 }
169 figcaption.c-cap {
170 background: #a8b9cc;
171 color: #000;
172 }
173 figcaption.javascript-cap {
174 background: #365d95;
175 color: #fff;
176 }
177 figcaption.shell-cap {
178 background: #ccc;
179 color: #000;
180 }
181
182 aside {
183 border-left: 0.25em solid #f7a41d;
184 padding: 0 1em 0 1em;
185 }
186
187 h1 a, h2 a, h3 a, h4 a, h5 a {
188 text-decoration: none;
189 color: #333;
190 }
191
192 a.hdr {
193 visibility: hidden;
194 }
195 h1:hover > a.hdr, h2:hover > a.hdr, h3:hover > a.hdr, h4:hover > a.hdr, h5:hover > a.hdr {
196 visibility: visible;
197 }
198
199 @media (prefers-color-scheme: dark) {
200 body{
201 background:#121212;
202 color: #ccc;
203 }
204 a {
205 color: #88f;
206 }
207 a:hover,a:focus {
208 color: #000;
209 }
210 table, th, td {
211 border-color: grey;
25 }212 }
26 .t2_0 {213 .t2_0 {
27 color: grey;214 color: grey;
28 }215 }
29 .t31_1 {216 .t31_1 {
30 color: red;217 color: red;
31 }218 }
32 .t32_1 {219 .t32_1 {
33 color: green;220 color: #00B800;
34 }221 }
35 .t36_1 {222 .t36_1 {
36 color: #0086b3;223 color: #0086b3;
37 }224 }
38 .file {225 code {
39 text-decoration: underline;226 background: #222;
227 border-color: #444;
40 }228 }
41 pre > code {229 pre > code {
42 display: block;230 color: #ccc;
43 overflow: auto;231 background: #222;
44 padding: 0.5em;232 border: unset;
45 color: #333;
46 background: #f8f8f8;
47 border: 1px dotted silver;
48 line-height: normal;
49 }233 }
50 code {234 samp {
51 background-color: #f8f8f8;235 background: #000;
52 border: 1px dotted silver;236 color: #ccc;
53 padding-left: 0.3em;
54 padding-right: 0.3em;
55 }237 }
56 .table-wrapper {238 pre > samp {
57 width: 100%;239 border: unset;
58 overflow-y: auto;
59 }240 }
60
61 .tok-kw {241 .tok-kw {
62 color: #333;242 color: #eee;
63 font-weight: bold;
64 }243 }
65 .tok-str {244 .tok-str {
66 color: #d14;245 color: #2e5;
67 }246 }
68 .tok-builtin {247 .tok-builtin {
69 color: #0086b3;248 color: #ff894c;
70 }249 }
71 .tok-comment {250 .tok-comment {
72 color: #777;251 color: #aa7;
73 font-style: italic;
74 }252 }
75 .tok-fn {253 .tok-fn {
76 color: #900;254 color: #B1A0F8;
77 font-weight: bold;
78 }255 }
79 .tok-null {256 .tok-null {
80 color: #008080;257 color: #ff8080;
81 }258 }
82 .tok-number {259 .tok-number {
83 color: #008080;260 color: #ff8080;
84 }261 }
85 .tok-type {262 .tok-type {
86 color: #458;263 color: #68f;
87 font-weight: bold;
88 }
89
90 #main-wrapper {
91 display: flex;
92 flex-direction: column;
93 }
94
95 #contents-wrapper {
96 flex-grow: 1;
97 padding: 0 2em;
98 }264 }
99
100 #contents {
101 max-width: 60em;
102 margin: auto;
103 line-height: 1.5;
104 }
105
106 #toc {
107 padding: 0 1em;
108 }
109
110 @media screen and (min-width: 1025px) {
111 #main-wrapper {
112 flex-direction: row;
113 }
114 #toc {
115 height: 100vh;
116 position: sticky;
117 top: 0;
118 }
119 #contents-wrapper, #toc {
120 overflow: auto;
121 }
122 }
123
124 h1 a, h2 a, h3 a, h4 a, h5 a {265 h1 a, h2 a, h3 a, h4 a, h5 a {
125 text-decoration: none;266 color: #aaa;
126 color: #333;
127 }
128
129 a.hdr {
130 visibility: hidden;
131 }267 }
132 h1:hover > a.hdr, h2:hover > a.hdr, h3:hover > a.hdr, h4:hover > a.hdr, h5:hover > a.hdr {268 figcaption.zig-cap {
133 visibility: visible;269 background-color: #b27306;
270 color: #000;
134 }271 }
135272 figcaption.shell-cap {
136 @media (prefers-color-scheme: dark) {273 background: #2a2a2a;
137 body{274 color: #fff;
138 background-color:#111;
139 color: #bbb;
140 }
141 a {
142 color: #f7a31d;
143 }
144 table, th, td {
145 border-color: grey;
146 }
147 .t2_0 {
148 color: grey;
149 }
150 .t31_1 {
151 color: red;
152 }
153 .t32_1 {
154 color: green;
155 }
156 .t36_1 {
157 color: #0086b3;
158 }
159 pre > code {
160 color: #ccc;
161 background: #222;
162 border-color: #444;
163 }
164 code {
165 background-color: #222;
166 border-color: #444;
167 }
168 .tok-kw {
169 color: #eee;
170 }
171 .tok-str {
172 color: #2e5;
173 }
174 .tok-builtin {
175 color: #ff894c;
176 }
177 .tok-comment {
178 color: #aa7;
179 }
180 .tok-fn {
181 color: #e33;
182 }
183 .tok-null {
184 color: #ff8080;
185 }
186 .tok-number {
187 color: #ff8080;
188 }
189 .tok-type {
190 color: #68f;
191 }
192 h1 a, h2 a, h3 a, h4 a, h5 a {
193 color: #aaa;
194 }
195 }275 }
196 </style>276 }
197 </head>277 </style>
198 <body>278</head>
199 <div id="main-wrapper">279<body>
200 <div id="toc">280 <header><h1>Zig Language Reference</h1></header>
201 <a href="https://ziglang.org/documentation/0.1.1/">0.1.1</a> |281 <div id="main-wrapper">
202 <a href="https://ziglang.org/documentation/0.2.0/">0.2.0</a> |282 <div id="navigation">
203 <a href="https://ziglang.org/documentation/0.3.0/">0.3.0</a> |283 <nav aria-labelledby="zig-version">
204 <a href="https://ziglang.org/documentation/0.4.0/">0.4.0</a> |284 <h2 id="zig-version">Zig Version</h2>
205 <a href="https://ziglang.org/documentation/0.5.0/">0.5.0</a> |285 <a href="https://ziglang.org/documentation/0.1.1/">0.1.1</a> |
206 <a href="https://ziglang.org/documentation/0.6.0/">0.6.0</a> |286 <a href="https://ziglang.org/documentation/0.2.0/">0.2.0</a> |
207 <a href="https://ziglang.org/documentation/0.7.1/">0.7.1</a> |287 <a href="https://ziglang.org/documentation/0.3.0/">0.3.0</a> |
208 <a href="https://ziglang.org/documentation/0.8.0/">0.8.0</a> |288 <a href="https://ziglang.org/documentation/0.4.0/">0.4.0</a> |
209 master289 <a href="https://ziglang.org/documentation/0.5.0/">0.5.0</a> |
210 <h1>Contents</h1>290 <a href="https://ziglang.org/documentation/0.6.0/">0.6.0</a> |
211 {#nav#}291 <a href="https://ziglang.org/documentation/0.7.1/">0.7.1</a> |
292 <a href="https://ziglang.org/documentation/0.8.1/">0.8.1</a> |
293 master
294 </nav>
295 <nav aria-labelledby="table-of-contents">
296 <h2 id="table-of-contents">Table of Contents</h2>
297 {#nav#}
298 </nav>
212 </div>299 </div>
213 <div id="contents-wrapper"><div id="contents">300 <div id="contents-wrapper"><main id="contents">
214 {#header_open|Introduction#}301 {#header_open|Introduction#}
215 <p>302 <p>
216 Zig is a general-purpose programming language and toolchain for maintaining303 <a href="https://ziglang.org">Zig</a> is a general-purpose programming language and toolchain for maintaining
217 <strong>robust</strong>, <strong>optimal</strong>, and <strong>reusable</strong> software.304 <strong>robust</strong>, <strong>optimal</strong>, and <strong>reusable</strong> software.
218 </p>305 </p>
219 <ul>306 <dl>
220 <li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li>307 <dt>Robust</dt><dd>Behavior is correct even for edge cases such as out of memory.</dd>
221 <li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li>308 <dt>Optimal</dt><dd>Write programs the best way they can behave and perform.</dd>
222 <li><strong>Reusable</strong> - the same code works in many environments which have different309 <dt>Reusable</dt><dd>The same code works in many environments which have different
223 constraints.</li>310 constraints.</dd>
224 <li><strong>Maintainable</strong> - precisely communicate intent to the compiler and311 <dt>Maintainable</dt><dd>Precisely communicate intent to the compiler and
225 other programmers. The language imposes a low overhead to reading code and is312 other programmers. The language imposes a low overhead to reading code and is
226 resilient to changing requirements and environments.</li>313 resilient to changing requirements and environments.</dd>
227 </ul>314 </dl>
228 <p>315 <p>
229 Often the most efficient way to learn something new is to see examples, so316 Often the most efficient way to learn something new is to see examples, so
230 this documentation shows how to use each of Zig's features. It is317 this documentation shows how to use each of Zig's features. It is
...@@ -236,8 +323,16 @@...@@ -236,8 +323,16 @@
236 <p>323 <p>
237 This HTML document depends on no external files, so you can use it offline.324 This HTML document depends on no external files, so you can use it offline.
238 </p>325 </p>
326 {#header_close#}
327
328 {#header_open|Zig Standard Library#}
329 <p>
330 The <a href="https://ziglang.org/documentation/master/std/">Zig Standard Library</a> has its own documentation.
331 </p>
239 <p>332 <p>
240 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Where is the documentation for the Zig standard library?</a>333 Zig's Standard Library contains commonly used algorithms, data structures, and definitions to help you build programs or libraries.
334 You will see many examples of Zig's Standard Library used in this documentation. To learn more about the Zig Standard Library,
335 visit the link above.
241 </p>336 </p>
242 {#header_close#}337 {#header_close#}
243338
...@@ -252,96 +347,102 @@ pub fn main() !void {...@@ -252,96 +347,102 @@ pub fn main() !void {
252}347}
253 {#code_end#}348 {#code_end#}
254 <p>349 <p>
255 The Zig code sample above demonstrates one way to create a program that will output <code>Hello, world!</code>.350 The Zig code sample above demonstrates one way to create a program that will output: <samp>Hello, world!</samp>.
256 </p>351 </p>
257 <p>352 <p>
258 The code sample shows the contents of a file named <code>hello.zig</code>. Files storing Zig353 The code sample shows the contents of a file named <code class="file">hello.zig</code>. Files storing Zig
259 source code are {#link|UTF-8 encoded|Source Encoding#} text files. The files storing354 source code are {#link|UTF-8 encoded|Source Encoding#} text files. The files storing
260 Zig source code are usually named with the <code>.zig</code> extension.355 Zig source code are usually named with the <code class="file"><em>.zig</em></code> extension.
261 </p>356 </p>
262 <p>357 <p>
263 Following the <code>hello.zig</code> Zig code sample, the {#link|Zig Build System#} is used358 Following the <code class="file">hello.zig</code> Zig code sample, the {#link|Zig Build System#} is used
264 to build an executable program from the <code>hello.zig</code> source code. Then, the359 to build an executable program from the <code class="file">hello.zig</code> source code. Then, the
265 <code>hello</code> program is executed showing its output <code>Hello, world!</code>. The360 <code class="file">hello</code> program is executed showing its output <samp>Hello, world!</samp>. The
266 lines beginning with <code>$</code> represent command line prompts and a command.361 lines beginning with <samp>$</samp> represent command line prompts and a command.
267 Everything else is program output.362 Everything else is program output.
268 </p>363 </p>
269 <p>364 <p>
270 The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function.365 The code sample begins by adding the {#link|Zig Standard Library#} to the build using the {#link|@import#} builtin function.
271 The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library.366 The {#syntax#}@import("std"){#endsyntax#} function call creates a structure that represents the Zig Standard Library.
272 The code then {#link|declares|Container Level Variables#} a367 The code then {#link|declares|Container Level Variables#} a
273 {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to368 {#link|constant identifier|Assignment#}, named {#syntax#}std{#endsyntax#}, that gives access the features of the Zig Standard Library.
274 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>.
275 </p>369 </p>
276 <p>370 <p>
277 Next, a {#link|public function|Functions#}, {#syntax#}pub fn{#endsyntax#}, named <code>main</code>371 Next, a {#link|public function|Functions#}, {#syntax#}pub fn{#endsyntax#}, named {#syntax#}main{#endsyntax#}
278 is declared. The <code>main</code> function is necessary because it tells the Zig compiler where the start of372 is declared. The {#syntax#}main{#endsyntax#} function is necessary because it tells the Zig compiler where the start of
279 the program exists. Programs designed to be executed will need a {#syntax#}pub fn main{#endsyntax#} function.373 the program exists. Programs designed to be executed will need a {#syntax#}pub fn main{#endsyntax#} function.
280 For more advanced use cases, Zig offers other features to inform the compiler where the start of
281 the program exists. Libraries, on the other hand, do not need a <code>main</code> function because
282 library code is usually called by other programs.
283 </p>374 </p>
375 <aside role="note" aria-label="Note about main function">
376 <p>
377 For more advanced use cases, Zig offers other features to inform the compiler where the start of
378 the program exists. Also, libraries do not need a {#syntax#}pub fn main{#endsyntax#} function because
379 library code is called by other programs or libraries.
380 </p>
381 </aside>
284 <p>382 <p>
285 A function is a block of any number of statements and expressions that, as a whole, perform a task.383 A function is a block of any number of statements and expressions that, as a whole, perform a task.
286 Functions may or may not return data after they are done performing their task. If a function384 Functions may or may not return data after they are done performing their task. If a function
287 cannot perform its task, it might return an error. Zig makes all of this explicit.385 cannot perform its task, it might return an error. Zig makes all of this explicit.
288 </p>386 </p>
289 <p>387 <p>
290 In the <code>hello.zig</code> code sample, the <code>main</code> function is declared388 In the <code class="file">hello.zig</code> code sample, the <code>main</code> function is declared
291 with the {#syntax#}!void{#endsyntax#} return type. This return type is known as an {#link|Error Union Type#}.389 with the {#syntax#}!void{#endsyntax#} return type. This return type is known as an {#link|Error Union Type#}.
292 This syntax tells the Zig compiler that the function will either return an390 This syntax tells the Zig compiler that the function will either return an
293 error or a value. An error union type combines an {#link|Error Set Type#} and a {#link|Primitive Type|Primitive Types#}.391 error or a value. An error union type combines an {#link|Error Set Type#} and any other data type
392 (e.g. a {#link|Primitive Type|Primitive Types#} or a user-defined type such as a {#link|struct#}, {#link|enum#}, or {#link|union#}).
294 The full form of an error union type is393 The full form of an error union type is
295 <code>&lt;error set type&gt;</code>{#syntax#}!{#endsyntax#}<code>&lt;primitive type&gt;</code>. In the code394 <code>&lt;error set type&gt;</code>{#syntax#}!{#endsyntax#}<code>&lt;any data type&gt;</code>. In the code
296 sample, the error set type is not explicitly written on the left side of the {#syntax#}!{#endsyntax#} operator.395 sample, the error set type is not explicitly written on the left side of the {#syntax#}!{#endsyntax#} operator.
297 When written this way, the error set type is a special kind of error union type that has an396 When written this way, the error set type is an {#link|inferred error set type|Inferred Error Sets#}. The
298 {#link|inferred error set type|Inferred Error Sets#}. The {#syntax#}void{#endsyntax#} after the {#syntax#}!{#endsyntax#} operator397 {#syntax#}void{#endsyntax#} after the {#syntax#}!{#endsyntax#} operator
299 tells the compiler that the function will not return a value under normal circumstances (i.e. no errors occur).398 tells the compiler that the function will not return a value under normal circumstances (i.e. when no errors occur).
300 </p>
301 <p>
302 Note to experienced programmers: Zig also has the boolean {#link|operator|Operators#} {#syntax#}!a{#endsyntax#}
303 where {#syntax#}a{#endsyntax#} is a value of type {#syntax#}bool{#endsyntax#}. Error union types contain the
304 name of the type in the syntax: {#syntax#}!{#endsyntax#}<code>&lt;primitive type&gt;</code>.
305 </p>399 </p>
400 <aside role="note" aria-label="Note to disambiguate exclamation mark operator">
401 <p>
402 Note to experienced programmers: Zig also has the boolean {#link|operator|Operators#} {#syntax#}!a{#endsyntax#}
403 where {#syntax#}a{#endsyntax#} is a value of type {#syntax#}bool{#endsyntax#}. Error union types contain the
404 name of the type in the syntax: {#syntax#}!{#endsyntax#}<code>&lt;any data type&gt;</code>.
405 </p>
406 </aside>
306 <p>407 <p>
307 In Zig, a function's block of statements and expressions are surrounded by <code>{</code> and408 In Zig, a function's block of statements and expressions are surrounded by an open curly-brace <code>{</code> and
308 <code>}</code> curly-braces. Inside of the <code>main</code> function are expressions that perform409 close curly-brace <code>}</code>. Inside of the {#syntax#}main{#endsyntax#} function are expressions that perform
309 the task of outputting <code>Hello, world!</code> to standard output.410 the task of outputting <samp>Hello, world!</samp> to standard output.
310 </p>411 </p>
311 <p>412 <p>
312 First, a constant identifier, <code>stdout</code>, is initialized to represent standard output's413 First, a constant identifier, {#syntax#}stdout{#endsyntax#}, is initialized to represent standard output's
313 writer. Then, the program tries to print the <code>Hello, world!</code>414 writer. Then, the program tries to print the <samp>Hello, world!</samp>
314 message to standard output.415 message to standard output.
315 </p>416 </p>
316 <p>417 <p>
317 Functions sometimes need information to perform their task. In Zig, information is passed418 Functions sometimes need information to perform their task. In Zig, information is passed
318 to functions between open <code>(</code> and close <code>)</code> parenthesis placed after419 to functions between an open parenthesis {#syntax#}({#endsyntax#} and a close parenthesis {#syntax#}){#endsyntax#} placed after
319 the function's name. This information is also known as arguments. When there are420 the function's name. This information is also known as arguments. When there are
320 multiple arguments passed to a function, they are separated by commas <code>,</code>.421 multiple arguments passed to a function, they are separated by commas {#syntax#},{#endsyntax#}.
321 </p>422 </p>
322 <p>423 <p>
323 The two arguments passed to the <code>stdout.print()</code> function, <code>"Hello, {s}!\n"</code>424 The two arguments passed to the {#syntax#}stdout.print(){#endsyntax#} function, {#syntax#}"Hello, {s}!\n"{#endsyntax#}
324 and <code>.{"world"}</code>, are evaluated at {#link|compile-time|comptime#}. The code sample is425 and {#syntax#}.{"world"}{#endsyntax#}, are evaluated at {#link|compile-time|comptime#}. The code sample is
325 purposely written to show how to perform {#link|string|String Literals and Unicode Code Point Literals#}426 purposely written to show how to perform {#link|string|String Literals and Unicode Code Point Literals#}
326 substitution in the <code>print</code> function. The curly-braces inside of the first argument427 substitution in the {#syntax#}print{#endsyntax#} function. The curly-braces inside of the first argument
327 are substituted with the compile-time known value inside of the second argument428 are substituted with the compile-time known value inside of the second argument
328 (known as an {#link|anonymous struct literal|Anonymous Struct Literals#}). The <code>\n</code>429 (known as an {#link|anonymous struct literal|Anonymous Struct Literals#}). The <code>\n</code>
329 inside of the double-quotes of the first argument is the {#link|escape sequence|Escape Sequences#} for the430 inside of the double-quotes of the first argument is the {#link|escape sequence|Escape Sequences#} for the
330 newline character. The {#link|try#} expression evaluates the result of <code>stdout.print</code>.431 newline character. The {#link|try#} expression evaluates the result of {#syntax#}stdout.print{#endsyntax#}.
331 If the result is an error, then the {#syntax#}try{#endsyntax#} expression will return from432 If the result is an error, then the {#syntax#}try{#endsyntax#} expression will return from
332 <code>main</code> with the error. Otherwise, the program will continue. In this case, there are no433 {#syntax#}main{#endsyntax#} with the error. Otherwise, the program will continue. In this case, there are no
333 more statements or expressions left to execute in the <code>main</code> function, so the program exits.434 more statements or expressions left to execute in the {#syntax#}main{#endsyntax#} function, so the program exits.
334 </p>435 </p>
335 <p>436 <p>
336 In Zig, the standard output writer's <code>print</code> function is allowed to fail because437 In Zig, the standard output writer's {#syntax#}print{#endsyntax#} function is allowed to fail because
337 it is actually a function defined as part of a generic Writer. Consider a generic Writer that438 it is actually a function defined as part of a generic Writer. Consider a generic Writer that
338 represents writing data to a file. When the disk is full, a write to the file will fail.439 represents writing data to a file. When the disk is full, a write to the file will fail.
339 However, we typically do not expect writing text to the standard output to fail. To avoid having440 However, we typically do not expect writing text to the standard output to fail. To avoid having
340 to handle the failure case of printing to standard output, you can use alternate functions: the441 to handle the failure case of printing to standard output, you can use alternate functions: the
341 functions in <code>std.log</code> for proper logging or the <code>std.debug.print</code> function.442 functions in {#syntax#}std.log{#endsyntax#} for proper logging or the {#syntax#}std.debug.print{#endsyntax#} function.
342 This documentation will use the latter option to print to standard error (stderr) and silently return443 This documentation will use the latter option to print to standard error (stderr) and silently return
343 on failure. The next code sample, <code>hello_again.zig</code> demonstrates the use of444 on failure. The next code sample, <code class="file">hello_again.zig</code> demonstrates the use of
344 <code>std.debug.print</code>.445 {#syntax#}std.debug.print{#endsyntax#}.
345 </p>446 </p>
346 {#code_begin|exe|hello_again#}447 {#code_begin|exe|hello_again#}
347const print = @import("std").debug.print;448const print = @import("std").debug.print;
...@@ -351,13 +452,13 @@ pub fn main() void {...@@ -351,13 +452,13 @@ pub fn main() void {
351}452}
352 {#code_end#}453 {#code_end#}
353 <p>454 <p>
354 Note that you can leave off the {#syntax#}!{#endsyntax#} from the return type because <code>std.debug.print</code> cannot fail.455 Note that you can leave off the {#syntax#}!{#endsyntax#} from the return type because {#syntax#}std.debug.print{#endsyntax#} cannot fail.
355 </p>456 </p>
356 {#see_also|Values|@import|Errors|Root Source File|Source Encoding#}457 {#see_also|Values|@import|Errors|Root Source File|Source Encoding#}
357 {#header_close#}458 {#header_close#}
358 {#header_open|Zig Test#}459 {#header_open|Zig Test#}
359 <p>460 <p>
360 <code>zig test</code> is a tool that can be used to quickly build and run Zig code461 <kbd>zig test</kbd> is a tool that can be used to quickly build and run Zig code
361 to make sure behavior meets expectations. {#syntax#}@import("builtin").is_test{#endsyntax#}462 to make sure behavior meets expectations. {#syntax#}@import("builtin").is_test{#endsyntax#}
362 is available for code to detect whether the current build is a test build.463 is available for code to detect whether the current build is a test build.
363 </p>464 </p>
...@@ -387,7 +488,7 @@ test "unused function" { }...@@ -387,7 +488,7 @@ test "unused function" { }
387 undefined behavior. The implementation of {#syntax#}std.debug.assert{#endsyntax#} is as488 undefined behavior. The implementation of {#syntax#}std.debug.assert{#endsyntax#} is as
388 simple as:489 simple as:
389 </p>490 </p>
390 {#code_begin|syntax#}491 {#code_begin|syntax|assert#}
391pub fn assert(ok: bool) void {492pub fn assert(ok: bool) void {
392 if (!ok) unreachable;493 if (!ok) unreachable;
393}494}
...@@ -396,7 +497,7 @@ pub fn assert(ok: bool) void {...@@ -396,7 +497,7 @@ pub fn assert(ok: bool) void {
396 This means that when testing in ReleaseFast or ReleaseSmall mode, {#syntax#}assert{#endsyntax#}497 This means that when testing in ReleaseFast or ReleaseSmall mode, {#syntax#}assert{#endsyntax#}
397 is not sufficient to check the result of a computation:498 is not sufficient to check the result of a computation:
398 </p>499 </p>
399 {#code_begin|syntax#}500 {#code_begin|syntax|assert_release_fast_mode#}
400const std = @import("std");501const std = @import("std");
401const assert = std.debug.assert;502const assert = std.debug.assert;
402503
...@@ -423,14 +524,13 @@ test "expect in release fast mode" {...@@ -423,14 +524,13 @@ test "expect in release fast mode" {
423 {#code_end#}524 {#code_end#}
424 <p>See the rest of the {#syntax#}std.testing{#endsyntax#} namespace for more available functions.</p>525 <p>See the rest of the {#syntax#}std.testing{#endsyntax#} namespace for more available functions.</p>
425 <p>526 <p>
426 <code>zig test</code> has a few command line parameters which affect the compilation. See527 <kbd>zig test</kbd> has a few command line parameters which affect the compilation. See
427 <code>zig --help</code> for a full list. The most interesting one is <code>--test-filter [text]</code>.528 <kbd>zig --help</kbd> for a full list. The most interesting one is <kbd>--test-filter [text]</kbd>.
428 This makes the test build only include tests whose name contains the supplied filter text.529 This makes the test build only include tests whose name contains the supplied filter text.
429 Again, thanks to lazy analysis, this can allow you to narrow a build to only a few functions in530 Again, thanks to lazy analysis, this can allow you to narrow a build to only a few functions in
430 isolation.531 isolation.
431 </p>532 </p>
432 {#header_close#}533 {#header_close#}
433
434 {#header_open|Comments#}534 {#header_open|Comments#}
435 {#code_begin|test|comments#}535 {#code_begin|test|comments#}
436const expect = @import("std").testing.expect;536const expect = @import("std").testing.expect;
...@@ -555,184 +655,183 @@ pub fn main() void {...@@ -555,184 +655,183 @@ pub fn main() void {
555 {#header_open|Primitive Types#}655 {#header_open|Primitive Types#}
556 <div class="table-wrapper">656 <div class="table-wrapper">
557 <table>657 <table>
558 <tr>658 <caption>Primitive Types</caption>
559 <th>659 <thead>
560 Name660 <tr>
561 </th>661 <th scope="col">Type</th>
562 <th>662 <th scope="col">C Equivalent</th>
563 C Equivalent663 <th scope="col">Description</th>
564 </th>
565 <th>
566 Description
567 </th>
568 </tr>664 </tr>
665 </thead>
666 <tbody>
569 <tr>667 <tr>
570 <td>{#syntax#}i8{#endsyntax#}</td>668 <th scope="row">{#syntax#}i8{#endsyntax#}</th>
571 <td><code class="c">int8_t</code></td>669 <td><code class="c">int8_t</code></td>
572 <td>signed 8-bit integer</td>670 <td>signed 8-bit integer</td>
573 </tr>671 </tr>
574 <tr>672 <tr>
575 <td>{#syntax#}u8{#endsyntax#}</td>673 <th scope="row">{#syntax#}u8{#endsyntax#}</th>
576 <td><code class="c">uint8_t</code></td>674 <td><code class="c">uint8_t</code></td>
577 <td>unsigned 8-bit integer</td>675 <td>unsigned 8-bit integer</td>
578 </tr>676 </tr>
579 <tr>677 <tr>
580 <td>{#syntax#}i16{#endsyntax#}</td>678 <th scope="row">{#syntax#}i16{#endsyntax#}</th>
581 <td><code class="c">int16_t</code></td>679 <td><code class="c">int16_t</code></td>
582 <td>signed 16-bit integer</td>680 <td>signed 16-bit integer</td>
583 </tr>681 </tr>
584 <tr>682 <tr>
585 <td>{#syntax#}u16{#endsyntax#}</td>683 <th scope="row">{#syntax#}u16{#endsyntax#}</th>
586 <td><code class="c">uint16_t</code></td>684 <td><code class="c">uint16_t</code></td>
587 <td>unsigned 16-bit integer</td>685 <td>unsigned 16-bit integer</td>
588 </tr>686 </tr>
589 <tr>687 <tr>
590 <td>{#syntax#}i32{#endsyntax#}</td>688 <th scope="row">{#syntax#}i32{#endsyntax#}</th>
591 <td><code class="c">int32_t</code></td>689 <td><code class="c">int32_t</code></td>
592 <td>signed 32-bit integer</td>690 <td>signed 32-bit integer</td>
593 </tr>691 </tr>
594 <tr>692 <tr>
595 <td>{#syntax#}u32{#endsyntax#}</td>693 <th scope="row">{#syntax#}u32{#endsyntax#}</th>
596 <td><code class="c">uint32_t</code></td>694 <td><code class="c">uint32_t</code></td>
597 <td>unsigned 32-bit integer</td>695 <td>unsigned 32-bit integer</td>
598 </tr>696 </tr>
599 <tr>697 <tr>
600 <td>{#syntax#}i64{#endsyntax#}</td>698 <th scope="row">{#syntax#}i64{#endsyntax#}</th>
601 <td><code class="c">int64_t</code></td>699 <td><code class="c">int64_t</code></td>
602 <td>signed 64-bit integer</td>700 <td>signed 64-bit integer</td>
603 </tr>701 </tr>
604 <tr>702 <tr>
605 <td>{#syntax#}u64{#endsyntax#}</td>703 <th scope="row">{#syntax#}u64{#endsyntax#}</th>
606 <td><code class="c">uint64_t</code></td>704 <td><code class="c">uint64_t</code></td>
607 <td>unsigned 64-bit integer</td>705 <td>unsigned 64-bit integer</td>
608 </tr>706 </tr>
609 <tr>707 <tr>
610 <td>{#syntax#}i128{#endsyntax#}</td>708 <th scope="row">{#syntax#}i128{#endsyntax#}</th>
611 <td><code class="c">__int128</code></td>709 <td><code class="c">__int128</code></td>
612 <td>signed 128-bit integer</td>710 <td>signed 128-bit integer</td>
613 </tr>711 </tr>
614 <tr>712 <tr>
615 <td>{#syntax#}u128{#endsyntax#}</td>713 <th scope="row">{#syntax#}u128{#endsyntax#}</th>
616 <td><code class="c">unsigned __int128</code></td>714 <td><code class="c">unsigned __int128</code></td>
617 <td>unsigned 128-bit integer</td>715 <td>unsigned 128-bit integer</td>
618 </tr>716 </tr>
619 <tr>717 <tr>
620 <td>{#syntax#}isize{#endsyntax#}</td>718 <th scope="row">{#syntax#}isize{#endsyntax#}</th>
621 <td><code class="c">intptr_t</code></td>719 <td><code class="c">intptr_t</code></td>
622 <td>signed pointer sized integer</td>720 <td>signed pointer sized integer</td>
623 </tr>721 </tr>
624 <tr>722 <tr>
625 <td>{#syntax#}usize{#endsyntax#}</td>723 <th scope="row">{#syntax#}usize{#endsyntax#}</th>
626 <td><code class="c">uintptr_t</code></td>724 <td><code class="c">uintptr_t</code></td>
627 <td>unsigned pointer sized integer</td>725 <td>unsigned pointer sized integer</td>
628 </tr>726 </tr>
629727
630 <tr>728 <tr>
631 <td>{#syntax#}c_short{#endsyntax#}</td>729 <th scope="row">{#syntax#}c_short{#endsyntax#}</th>
632 <td><code class="c">short</code></td>730 <td><code class="c">short</code></td>
633 <td>for ABI compatibility with C</td>731 <td>for ABI compatibility with C</td>
634 </tr>732 </tr>
635 <tr>733 <tr>
636 <td>{#syntax#}c_ushort{#endsyntax#}</td>734 <th scope="row">{#syntax#}c_ushort{#endsyntax#}</th>
637 <td><code class="c">unsigned short</code></td>735 <td><code class="c">unsigned short</code></td>
638 <td>for ABI compatibility with C</td>736 <td>for ABI compatibility with C</td>
639 </tr>737 </tr>
640 <tr>738 <tr>
641 <td>{#syntax#}c_int{#endsyntax#}</td>739 <th scope="row">{#syntax#}c_int{#endsyntax#}</th>
642 <td><code class="c">int</code></td>740 <td><code class="c">int</code></td>
643 <td>for ABI compatibility with C</td>741 <td>for ABI compatibility with C</td>
644 </tr>742 </tr>
645 <tr>743 <tr>
646 <td>{#syntax#}c_uint{#endsyntax#}</td>744 <th scope="row">{#syntax#}c_uint{#endsyntax#}</th>
647 <td><code class="c">unsigned int</code></td>745 <td><code class="c">unsigned int</code></td>
648 <td>for ABI compatibility with C</td>746 <td>for ABI compatibility with C</td>
649 </tr>747 </tr>
650 <tr>748 <tr>
651 <td>{#syntax#}c_long{#endsyntax#}</td>749 <th scope="row">{#syntax#}c_long{#endsyntax#}</th>
652 <td><code class="c">long</code></td>750 <td><code class="c">long</code></td>
653 <td>for ABI compatibility with C</td>751 <td>for ABI compatibility with C</td>
654 </tr>752 </tr>
655 <tr>753 <tr>
656 <td>{#syntax#}c_ulong{#endsyntax#}</td>754 <th scope="row">{#syntax#}c_ulong{#endsyntax#}</th>
657 <td><code class="c">unsigned long</code></td>755 <td><code class="c">unsigned long</code></td>
658 <td>for ABI compatibility with C</td>756 <td>for ABI compatibility with C</td>
659 </tr>757 </tr>
660 <tr>758 <tr>
661 <td>{#syntax#}c_longlong{#endsyntax#}</td>759 <th scope="row">{#syntax#}c_longlong{#endsyntax#}</th>
662 <td><code class="c">long long</code></td>760 <td><code class="c">long long</code></td>
663 <td>for ABI compatibility with C</td>761 <td>for ABI compatibility with C</td>
664 </tr>762 </tr>
665 <tr>763 <tr>
666 <td>{#syntax#}c_ulonglong{#endsyntax#}</td>764 <th scope="row">{#syntax#}c_ulonglong{#endsyntax#}</th>
667 <td><code class="c">unsigned long long</code></td>765 <td><code class="c">unsigned long long</code></td>
668 <td>for ABI compatibility with C</td>766 <td>for ABI compatibility with C</td>
669 </tr>767 </tr>
670 <tr>768 <tr>
671 <td>{#syntax#}c_longdouble{#endsyntax#}</td>769 <th scope="row">{#syntax#}c_longdouble{#endsyntax#}</th>
672 <td><code class="c">long double</code></td>770 <td><code class="c">long double</code></td>
673 <td>for ABI compatibility with C</td>771 <td>for ABI compatibility with C</td>
674 </tr>772 </tr>
675 <tr>773 <tr>
676 <td>{#syntax#}c_void{#endsyntax#}</td>774 <th scope="row">{#syntax#}c_void{#endsyntax#}</th>
677 <td><code class="c">void</code></td>775 <td><code class="c">void</code></td>
678 <td>for ABI compatibility with C</td>776 <td>for ABI compatibility with C</td>
679 </tr>777 </tr>
680778
681 <tr>779 <tr>
682 <td>{#syntax#}f16{#endsyntax#}</td>780 <th scope="row">{#syntax#}f16{#endsyntax#}</th>
683 <td><code class="c">_Float16</code></td>781 <td><code class="c">_Float16</code></td>
684 <td>16-bit floating point (10-bit mantissa) IEEE-754-2008 binary16</td>782 <td>16-bit floating point (10-bit mantissa) IEEE-754-2008 binary16</td>
685 </tr>783 </tr>
686 <tr>784 <tr>
687 <td>{#syntax#}f32{#endsyntax#}</td>785 <th scope="row">{#syntax#}f32{#endsyntax#}</th>
688 <td><code class="c">float</code></td>786 <td><code class="c">float</code></td>
689 <td>32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32</td>787 <td>32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32</td>
690 </tr>788 </tr>
691 <tr>789 <tr>
692 <td>{#syntax#}f64{#endsyntax#}</td>790 <th scope="row">{#syntax#}f64{#endsyntax#}</th>
693 <td><code class="c">double</code></td>791 <td><code class="c">double</code></td>
694 <td>64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64</td>792 <td>64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64</td>
695 </tr>793 </tr>
696 <tr>794 <tr>
697 <td>{#syntax#}f128{#endsyntax#}</td>795 <th scope="row">{#syntax#}f128{#endsyntax#}</th>
698 <td><code class="c">_Float128</code></td>796 <td><code class="c">_Float128</code></td>
699 <td>128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128</td>797 <td>128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128</td>
700 </tr>798 </tr>
701 <tr>799 <tr>
702 <td>{#syntax#}bool{#endsyntax#}</td>800 <th scope="row">{#syntax#}bool{#endsyntax#}</th>
703 <td><code class="c">bool</code></td>801 <td><code class="c">bool</code></td>
704 <td>{#syntax#}true{#endsyntax#} or {#syntax#}false{#endsyntax#}</td>802 <td>{#syntax#}true{#endsyntax#} or {#syntax#}false{#endsyntax#}</td>
705 </tr>803 </tr>
706 <tr>804 <tr>
707 <td>{#syntax#}void{#endsyntax#}</td>805 <th scope="row">{#syntax#}void{#endsyntax#}</th>
708 <td>(none)</td>806 <td>(none)</td>
709 <td>0 bit type</td>807 <td>0 bit type</td>
710 </tr>808 </tr>
711 <tr>809 <tr>
712 <td>{#syntax#}noreturn{#endsyntax#}</td>810 <th scope="row">{#syntax#}noreturn{#endsyntax#}</th>
713 <td>(none)</td>811 <td>(none)</td>
714 <td>the type of {#syntax#}break{#endsyntax#}, {#syntax#}continue{#endsyntax#}, {#syntax#}return{#endsyntax#}, {#syntax#}unreachable{#endsyntax#}, and {#syntax#}while (true) {}{#endsyntax#}</td>812 <td>the type of {#syntax#}break{#endsyntax#}, {#syntax#}continue{#endsyntax#}, {#syntax#}return{#endsyntax#}, {#syntax#}unreachable{#endsyntax#}, and {#syntax#}while (true) {}{#endsyntax#}</td>
715 </tr>813 </tr>
716 <tr>814 <tr>
717 <td>{#syntax#}type{#endsyntax#}</td>815 <th scope="row">{#syntax#}type{#endsyntax#}</th>
718 <td>(none)</td>816 <td>(none)</td>
719 <td>the type of types</td>817 <td>the type of types</td>
720 </tr>818 </tr>
721 <tr>819 <tr>
722 <td>{#syntax#}anyerror{#endsyntax#}</td>820 <th scope="row">{#syntax#}anyerror{#endsyntax#}</th>
723 <td>(none)</td>821 <td>(none)</td>
724 <td>an error code</td>822 <td>an error code</td>
725 </tr>823 </tr>
726 <tr>824 <tr>
727 <td>{#syntax#}comptime_int{#endsyntax#}</td>825 <th scope="row">{#syntax#}comptime_int{#endsyntax#}</th>
728 <td>(none)</td>826 <td>(none)</td>
729 <td>Only allowed for {#link|comptime#}-known values. The type of integer literals.</td>827 <td>Only allowed for {#link|comptime#}-known values. The type of integer literals.</td>
730 </tr>828 </tr>
731 <tr>829 <tr>
732 <td>{#syntax#}comptime_float{#endsyntax#}</td>830 <th scope="row">{#syntax#}comptime_float{#endsyntax#}</th>
733 <td>(none)</td>831 <td>(none)</td>
734 <td>Only allowed for {#link|comptime#}-known values. The type of float literals.</td>832 <td>Only allowed for {#link|comptime#}-known values. The type of float literals.</td>
735 </tr>833 </tr>
834 </tbody>
736 </table>835 </table>
737 </div>836 </div>
738 <p>837 <p>
...@@ -746,26 +845,27 @@ pub fn main() void {...@@ -746,26 +845,27 @@ pub fn main() void {
746 {#header_open|Primitive Values#}845 {#header_open|Primitive Values#}
747 <div class="table-wrapper">846 <div class="table-wrapper">
748 <table>847 <table>
848 <caption>Primitive Values</caption>
849 <thead>
749 <tr>850 <tr>
750 <th>851 <th scope="col">Name</th>
751 Name852 <th scope="col">Description</th>
752 </th>
753 <th>
754 Description
755 </th>
756 </tr>853 </tr>
854 </thead>
855 <tbody>
757 <tr>856 <tr>
758 <td>{#syntax#}true{#endsyntax#} and {#syntax#}false{#endsyntax#}</td>857 <th scope="row">{#syntax#}true{#endsyntax#} and {#syntax#}false{#endsyntax#}</th>
759 <td>{#syntax#}bool{#endsyntax#} values</td>858 <td>{#syntax#}bool{#endsyntax#} values</td>
760 </tr>859 </tr>
761 <tr>860 <tr>
762 <td>{#syntax#}null{#endsyntax#}</td>861 <th scope="row">{#syntax#}null{#endsyntax#}</th>
763 <td>used to set an optional type to {#syntax#}null{#endsyntax#}</td>862 <td>used to set an optional type to {#syntax#}null{#endsyntax#}</td>
764 </tr>863 </tr>
765 <tr>864 <tr>
766 <td>{#syntax#}undefined{#endsyntax#}</td>865 <th scope="row">{#syntax#}undefined{#endsyntax#}</th>
767 <td>used to leave a value unspecified</td>866 <td>used to leave a value unspecified</td>
768 </tr>867 </tr>
868 </tbody>
769 </table>869 </table>
770 </div>870 </div>
771 {#see_also|Optionals|undefined#}871 {#see_also|Optionals|undefined#}
...@@ -796,7 +896,7 @@ pub fn main() void {...@@ -796,7 +896,7 @@ pub fn main() void {
796 in recent versions of the Unicode specification (as of Unicode 13.0).896 in recent versions of the Unicode specification (as of Unicode 13.0).
797 In Zig, a Unicode code point literal corresponds to the Unicode definition of a code point.897 In Zig, a Unicode code point literal corresponds to the Unicode definition of a code point.
798 </p>898 </p>
799 {#code_begin|test#}899 {#code_begin|test|string_literals_test#}
800const expect = @import("std").testing.expect;900const expect = @import("std").testing.expect;
801const mem = @import("std").mem;901const mem = @import("std").mem;
802902
...@@ -817,46 +917,47 @@ test "string literals" {...@@ -817,46 +917,47 @@ test "string literals" {
817 {#header_open|Escape Sequences#}917 {#header_open|Escape Sequences#}
818 <div class="table-wrapper">918 <div class="table-wrapper">
819 <table>919 <table>
920 <caption>Escape Sequences</caption>
921 <thead>
820 <tr>922 <tr>
821 <th>923 <th scope="col">Escape Sequence</th>
822 Escape Sequence924 <th scope="col">Name</th>
823 </th>
824 <th>
825 Name
826 </th>
827 </tr>925 </tr>
926 </thead>
927 <tbody>
828 <tr>928 <tr>
829 <td><code>\n</code></td>929 <th scope="row"><code>\n</code></th>
830 <td>Newline</td>930 <td>Newline</td>
831 </tr>931 </tr>
832 <tr>932 <tr>
833 <td><code>\r</code></td>933 <th scope="row"><code>\r</code></th>
834 <td>Carriage Return</td>934 <td>Carriage Return</td>
835 </tr>935 </tr>
836 <tr>936 <tr>
837 <td><code>\t</code></td>937 <th scope="row"><code>\t</code></th>
838 <td>Tab</td>938 <td>Tab</td>
839 </tr>939 </tr>
840 <tr>940 <tr>
841 <td><code>\\</code></td>941 <th scope="row"><code>\\</code></th>
842 <td>Backslash</td>942 <td>Backslash</td>
843 </tr>943 </tr>
844 <tr>944 <tr>
845 <td><code>\'</code></td>945 <th scope="row"><code>\'</code></th>
846 <td>Single Quote</td>946 <td>Single Quote</td>
847 </tr>947 </tr>
848 <tr>948 <tr>
849 <td><code>\"</code></td>949 <th scope="row"><code>\"</code></th>
850 <td>Double Quote</td>950 <td>Double Quote</td>
851 </tr>951 </tr>
852 <tr>952 <tr>
853 <td><code>\xNN</code></td>953 <th scope="row"><code>\xNN</code></th>
854 <td>hexadecimal 8-bit byte value (2 digits)</td>954 <td>hexadecimal 8-bit byte value (2 digits)</td>
855 </tr>955 </tr>
856 <tr>956 <tr>
857 <td><code>\u{NNNNNN}</code></td>957 <th scope="row"><code>\u{NNNNNN}</code></th>
858 <td>hexadecimal Unicode code point UTF-8 encoded (1 or more digits)</td>958 <td>hexadecimal Unicode code point UTF-8 encoded (1 or more digits)</td>
859 </tr>959 </tr>
960 </tbody>
860 </table>961 </table>
861 </div>962 </div>
862 <p>Note that the maximum valid Unicode point is {#syntax#}0x10ffff{#endsyntax#}.</p>963 <p>Note that the maximum valid Unicode point is {#syntax#}0x10ffff{#endsyntax#}.</p>
...@@ -870,7 +971,7 @@ test "string literals" {...@@ -870,7 +971,7 @@ test "string literals" {
870 However, if the next line begins with {#syntax#}\\{#endsyntax#} then a newline is appended and971 However, if the next line begins with {#syntax#}\\{#endsyntax#} then a newline is appended and
871 the string literal continues.972 the string literal continues.
872 </p>973 </p>
873 {#code_begin|syntax#}974 {#code_begin|syntax|multiline_string_literals#}
874const hello_world_in_c =975const hello_world_in_c =
875 \\#include <stdio.h>976 \\#include <stdio.h>
876 \\977 \\
...@@ -902,7 +1003,7 @@ test "assignment" {...@@ -902,7 +1003,7 @@ test "assignment" {
902 {#code_end#}1003 {#code_end#}
903 <p>{#syntax#}const{#endsyntax#} applies to all of the bytes that the identifier immediately addresses. {#link|Pointers#} have their own const-ness.</p>1004 <p>{#syntax#}const{#endsyntax#} applies to all of the bytes that the identifier immediately addresses. {#link|Pointers#} have their own const-ness.</p>
904 <p>If you need a variable that you can modify, use the {#syntax#}var{#endsyntax#} keyword:</p>1005 <p>If you need a variable that you can modify, use the {#syntax#}var{#endsyntax#} keyword:</p>
905 {#code_begin|test#}1006 {#code_begin|test|var_test#}
906const expect = @import("std").testing.expect;1007const expect = @import("std").testing.expect;
9071008
908test "var" {1009test "var" {
...@@ -923,7 +1024,7 @@ test "initialization" {...@@ -923,7 +1024,7 @@ test "initialization" {
923 {#code_end#}1024 {#code_end#}
924 {#header_open|undefined#}1025 {#header_open|undefined#}
925 <p>Use {#syntax#}undefined{#endsyntax#} to leave variables uninitialized:</p>1026 <p>Use {#syntax#}undefined{#endsyntax#} to leave variables uninitialized:</p>
926 {#code_begin|test#}1027 {#code_begin|test|undefined_test#}
927const expect = @import("std").testing.expect;1028const expect = @import("std").testing.expect;
9281029
929test "init with undefined" {1030test "init with undefined" {
...@@ -1108,7 +1209,7 @@ test "comptime vars" {...@@ -1108,7 +1209,7 @@ test "comptime vars" {
11081209
1109 {#header_open|Integers#}1210 {#header_open|Integers#}
1110 {#header_open|Integer Literals#}1211 {#header_open|Integer Literals#}
1111 {#code_begin|syntax#}1212 {#code_begin|syntax|integer_literals#}
1112const decimal_int = 98222;1213const decimal_int = 98222;
1113const hex_int = 0xff;1214const hex_int = 0xff;
1114const another_hex_int = 0xFF;1215const another_hex_int = 0xFF;
...@@ -1131,7 +1232,7 @@ const big_address = 0xFF80_0000_0000_0000;...@@ -1131,7 +1232,7 @@ const big_address = 0xFF80_0000_0000_0000;
1131 However, once an integer value is no longer known at compile-time, it must have a1232 However, once an integer value is no longer known at compile-time, it must have a
1132 known size, and is vulnerable to undefined behavior.1233 known size, and is vulnerable to undefined behavior.
1133 </p>1234 </p>
1134 {#code_begin|syntax#}1235 {#code_begin|syntax|runtime_vs_comptime#}
1135fn divide(a: i32, b: i32) i32 {1236fn divide(a: i32, b: i32) i32 {
1136 return a / b;1237 return a / b;
1137}1238}
...@@ -1174,7 +1275,7 @@ fn divide(a: i32, b: i32) i32 {...@@ -1174,7 +1275,7 @@ fn divide(a: i32, b: i32) i32 {
1174 Float literals {#link|coerce|Type Coercion#} to any floating point type,1275 Float literals {#link|coerce|Type Coercion#} to any floating point type,
1175 and to any {#link|integer|Integers#} type when there is no fractional component.1276 and to any {#link|integer|Integers#} type when there is no fractional component.
1176 </p>1277 </p>
1177 {#code_begin|syntax#}1278 {#code_begin|syntax|float_literals#}
1178const floating_point = 123.0E+77;1279const floating_point = 123.0E+77;
1179const another_float = 123.0;1280const another_float = 123.0;
1180const yet_another = 123.0e+77;1281const yet_another = 123.0e+77;
...@@ -1192,7 +1293,7 @@ const more_hex = 0x1234_5678.9ABC_CDEFp-10;...@@ -1192,7 +1293,7 @@ const more_hex = 0x1234_5678.9ABC_CDEFp-10;
1192 There is no syntax for NaN, infinity, or negative infinity. For these special values,1293 There is no syntax for NaN, infinity, or negative infinity. For these special values,
1193 one must use the standard library:1294 one must use the standard library:
1194 </p>1295 </p>
1195 {#code_begin|syntax#}1296 {#code_begin|syntax|float_special_values#}
1196const std = @import("std");1297const std = @import("std");
11971298
1198const inf = std.math.inf(f32);1299const inf = std.math.inf(f32);
...@@ -1245,23 +1346,19 @@ pub fn main() void {...@@ -1245,23 +1346,19 @@ pub fn main() void {
1245 {#header_open|Table of Operators#}1346 {#header_open|Table of Operators#}
1246 <div class="table-wrapper">1347 <div class="table-wrapper">
1247 <table>1348 <table>
1349 <caption>Table of Operators</caption>
1350 <thead>
1248 <tr>1351 <tr>
1249 <th>1352 <th scope="col">Syntax</th>
1250 Syntax1353 <th scope="col">Relevant Types</th>
1251 </th>1354 <th scope="col">Description</th>
1252 <th>1355 <th scope="col">Example</th>
1253 Relevant Types
1254 </th>
1255 <th>
1256 Description
1257 </th>
1258 <th>
1259 Example
1260 </th>
1261 </tr>1356 </tr>
1357 </thead>
1358 <tbody>
1262 <tr>1359 <tr>
1263 <td><pre>{#syntax#}a + b1360 <th scope="row"><pre>{#syntax#}a + b
1264a += b{#endsyntax#}</pre></td>1361a += b{#endsyntax#}</pre></th>
1265 <td>1362 <td>
1266 <ul>1363 <ul>
1267 <li>{#link|Integers#}</li>1364 <li>{#link|Integers#}</li>
...@@ -1280,8 +1377,8 @@ a += b{#endsyntax#}</pre></td>...@@ -1280,8 +1377,8 @@ a += b{#endsyntax#}</pre></td>
1280 </td>1377 </td>
1281 </tr>1378 </tr>
1282 <tr>1379 <tr>
1283 <td><pre>{#syntax#}a +% b1380 <th scope="row"><pre>{#syntax#}a +% b
1284a +%= b{#endsyntax#}</pre></td>1381a +%= b{#endsyntax#}</pre></th>
1285 <td>1382 <td>
1286 <ul>1383 <ul>
1287 <li>{#link|Integers#}</li>1384 <li>{#link|Integers#}</li>
...@@ -1299,8 +1396,8 @@ a +%= b{#endsyntax#}</pre></td>...@@ -1299,8 +1396,8 @@ a +%= b{#endsyntax#}</pre></td>
1299 </td>1396 </td>
1300 </tr>1397 </tr>
1301 <tr>1398 <tr>
1302 <td><pre>{#syntax#}a - b1399 <th scope="row"><pre>{#syntax#}a - b
1303a -= b{#endsyntax#}</pre></td>1400a -= b{#endsyntax#}</pre></th>
1304 <td>1401 <td>
1305 <ul>1402 <ul>
1306 <li>{#link|Integers#}</li>1403 <li>{#link|Integers#}</li>
...@@ -1319,8 +1416,8 @@ a -= b{#endsyntax#}</pre></td>...@@ -1319,8 +1416,8 @@ a -= b{#endsyntax#}</pre></td>
1319 </td>1416 </td>
1320 </tr>1417 </tr>
1321 <tr>1418 <tr>
1322 <td><pre>{#syntax#}a -% b1419 <th scope="row"><pre>{#syntax#}a -% b
1323a -%= b{#endsyntax#}</pre></td>1420a -%= b{#endsyntax#}</pre></th>
1324 <td>1421 <td>
1325 <ul>1422 <ul>
1326 <li>{#link|Integers#}</li>1423 <li>{#link|Integers#}</li>
...@@ -1338,7 +1435,7 @@ a -%= b{#endsyntax#}</pre></td>...@@ -1338,7 +1435,7 @@ a -%= b{#endsyntax#}</pre></td>
1338 </td>1435 </td>
1339 </tr>1436 </tr>
1340 <tr>1437 <tr>
1341 <td><pre>{#syntax#}-a{#endsyntax#}</pre></td>1438 <th scope="row"><pre>{#syntax#}-a{#endsyntax#}</pre></th>
1342 <td>1439 <td>
1343 <ul>1440 <ul>
1344 <li>{#link|Integers#}</li>1441 <li>{#link|Integers#}</li>
...@@ -1356,7 +1453,7 @@ a -%= b{#endsyntax#}</pre></td>...@@ -1356,7 +1453,7 @@ a -%= b{#endsyntax#}</pre></td>
1356 </td>1453 </td>
1357 </tr>1454 </tr>
1358 <tr>1455 <tr>
1359 <td><pre>{#syntax#}-%a{#endsyntax#}</pre></td>1456 <th scope="row"><pre>{#syntax#}-%a{#endsyntax#}</pre></th>
1360 <td>1457 <td>
1361 <ul>1458 <ul>
1362 <li>{#link|Integers#}</li>1459 <li>{#link|Integers#}</li>
...@@ -1373,8 +1470,8 @@ a -%= b{#endsyntax#}</pre></td>...@@ -1373,8 +1470,8 @@ a -%= b{#endsyntax#}</pre></td>
1373 </td>1470 </td>
1374 </tr>1471 </tr>
1375 <tr>1472 <tr>
1376 <td><pre>{#syntax#}a * b1473 <th scope="row"><pre>{#syntax#}a * b
1377a *= b{#endsyntax#}</pre></td>1474a *= b{#endsyntax#}</pre></th>
1378 <td>1475 <td>
1379 <ul>1476 <ul>
1380 <li>{#link|Integers#}</li>1477 <li>{#link|Integers#}</li>
...@@ -1393,8 +1490,8 @@ a *= b{#endsyntax#}</pre></td>...@@ -1393,8 +1490,8 @@ a *= b{#endsyntax#}</pre></td>
1393 </td>1490 </td>
1394 </tr>1491 </tr>
1395 <tr>1492 <tr>
1396 <td><pre>{#syntax#}a *% b1493 <th scope="row"><pre>{#syntax#}a *% b
1397a *%= b{#endsyntax#}</pre></td>1494a *%= b{#endsyntax#}</pre></th>
1398 <td>1495 <td>
1399 <ul>1496 <ul>
1400 <li>{#link|Integers#}</li>1497 <li>{#link|Integers#}</li>
...@@ -1412,8 +1509,8 @@ a *%= b{#endsyntax#}</pre></td>...@@ -1412,8 +1509,8 @@ a *%= b{#endsyntax#}</pre></td>
1412 </td>1509 </td>
1413 </tr>1510 </tr>
1414 <tr>1511 <tr>
1415 <td><pre>{#syntax#}a / b1512 <th scope="row"><pre>{#syntax#}a / b
1416a /= b{#endsyntax#}</pre></td>1513a /= b{#endsyntax#}</pre></th>
1417 <td>1514 <td>
1418 <ul>1515 <ul>
1419 <li>{#link|Integers#}</li>1516 <li>{#link|Integers#}</li>
...@@ -1438,8 +1535,8 @@ a /= b{#endsyntax#}</pre></td>...@@ -1438,8 +1535,8 @@ a /= b{#endsyntax#}</pre></td>
1438 </td>1535 </td>
1439 </tr>1536 </tr>
1440 <tr>1537 <tr>
1441 <td><pre>{#syntax#}a % b1538 <th scope="row"><pre>{#syntax#}a % b
1442a %= b{#endsyntax#}</pre></td>1539a %= b{#endsyntax#}</pre></th>
1443 <td>1540 <td>
1444 <ul>1541 <ul>
1445 <li>{#link|Integers#}</li>1542 <li>{#link|Integers#}</li>
...@@ -1462,8 +1559,8 @@ a %= b{#endsyntax#}</pre></td>...@@ -1462,8 +1559,8 @@ a %= b{#endsyntax#}</pre></td>
1462 </td>1559 </td>
1463 </tr>1560 </tr>
1464 <tr>1561 <tr>
1465 <td><pre>{#syntax#}a << b1562 <th scope="row"><pre>{#syntax#}a << b
1466a <<= b{#endsyntax#}</pre></td>1563a <<= b{#endsyntax#}</pre></th>
1467 <td>1564 <td>
1468 <ul>1565 <ul>
1469 <li>{#link|Integers#}</li>1566 <li>{#link|Integers#}</li>
...@@ -1481,8 +1578,8 @@ a <<= b{#endsyntax#}</pre></td>...@@ -1481,8 +1578,8 @@ a <<= b{#endsyntax#}</pre></td>
1481 </td>1578 </td>
1482 </tr>1579 </tr>
1483 <tr>1580 <tr>
1484 <td><pre>{#syntax#}a >> b1581 <th scope="row"><pre>{#syntax#}a >> b
1485a >>= b{#endsyntax#}</pre></td>1582a >>= b{#endsyntax#}</pre></th>
1486 <td>1583 <td>
1487 <ul>1584 <ul>
1488 <li>{#link|Integers#}</li>1585 <li>{#link|Integers#}</li>
...@@ -1499,8 +1596,8 @@ a >>= b{#endsyntax#}</pre></td>...@@ -1499,8 +1596,8 @@ a >>= b{#endsyntax#}</pre></td>
1499 </td>1596 </td>
1500 </tr>1597 </tr>
1501 <tr>1598 <tr>
1502 <td><pre>{#syntax#}a & b1599 <th scope="row"><pre>{#syntax#}a & b
1503a &= b{#endsyntax#}</pre></td>1600a &= b{#endsyntax#}</pre></th>
1504 <td>1601 <td>
1505 <ul>1602 <ul>
1506 <li>{#link|Integers#}</li>1603 <li>{#link|Integers#}</li>
...@@ -1516,8 +1613,8 @@ a &= b{#endsyntax#}</pre></td>...@@ -1516,8 +1613,8 @@ a &= b{#endsyntax#}</pre></td>
1516 </td>1613 </td>
1517 </tr>1614 </tr>
1518 <tr>1615 <tr>
1519 <td><pre>{#syntax#}a | b1616 <th scope="row"><pre>{#syntax#}a | b
1520a |= b{#endsyntax#}</pre></td>1617a |= b{#endsyntax#}</pre></th>
1521 <td>1618 <td>
1522 <ul>1619 <ul>
1523 <li>{#link|Integers#}</li>1620 <li>{#link|Integers#}</li>
...@@ -1533,8 +1630,8 @@ a |= b{#endsyntax#}</pre></td>...@@ -1533,8 +1630,8 @@ a |= b{#endsyntax#}</pre></td>
1533 </td>1630 </td>
1534 </tr>1631 </tr>
1535 <tr>1632 <tr>
1536 <td><pre>{#syntax#}a ^ b1633 <th scope="row"><pre>{#syntax#}a ^ b
1537a ^= b{#endsyntax#}</pre></td>1634a ^= b{#endsyntax#}</pre></th>
1538 <td>1635 <td>
1539 <ul>1636 <ul>
1540 <li>{#link|Integers#}</li>1637 <li>{#link|Integers#}</li>
...@@ -1550,7 +1647,7 @@ a ^= b{#endsyntax#}</pre></td>...@@ -1550,7 +1647,7 @@ a ^= b{#endsyntax#}</pre></td>
1550 </td>1647 </td>
1551 </tr>1648 </tr>
1552 <tr>1649 <tr>
1553 <td><pre>{#syntax#}~a{#endsyntax#}</pre></td>1650 <th scope="row"><pre>{#syntax#}~a{#endsyntax#}</pre></th>
1554 <td>1651 <td>
1555 <ul>1652 <ul>
1556 <li>{#link|Integers#}</li>1653 <li>{#link|Integers#}</li>
...@@ -1564,7 +1661,7 @@ a ^= b{#endsyntax#}</pre></td>...@@ -1564,7 +1661,7 @@ a ^= b{#endsyntax#}</pre></td>
1564 </td>1661 </td>
1565 </tr>1662 </tr>
1566 <tr>1663 <tr>
1567 <td><pre>{#syntax#}a orelse b{#endsyntax#}</pre></td>1664 <th scope="row"><pre>{#syntax#}a orelse b{#endsyntax#}</pre></th>
1568 <td>1665 <td>
1569 <ul>1666 <ul>
1570 <li>{#link|Optionals#}</li>1667 <li>{#link|Optionals#}</li>
...@@ -1582,7 +1679,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1582,7 +1679,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1582 </td>1679 </td>
1583 </tr>1680 </tr>
1584 <tr>1681 <tr>
1585 <td><pre>{#syntax#}a.?{#endsyntax#}</pre></td>1682 <th scope="row"><pre>{#syntax#}a.?{#endsyntax#}</pre></th>
1586 <td>1683 <td>
1587 <ul>1684 <ul>
1588 <li>{#link|Optionals#}</li>1685 <li>{#link|Optionals#}</li>
...@@ -1598,8 +1695,8 @@ value.? == 5678{#endsyntax#}</pre>...@@ -1598,8 +1695,8 @@ value.? == 5678{#endsyntax#}</pre>
1598 </td>1695 </td>
1599 </tr>1696 </tr>
1600 <tr>1697 <tr>
1601 <td><pre>{#syntax#}a catch b1698 <th scope="row"><pre>{#syntax#}a catch b
1602a catch |err| b{#endsyntax#}</pre></td>1699a catch |err| b{#endsyntax#}</pre></th>
1603 <td>1700 <td>
1604 <ul>1701 <ul>
1605 <li>{#link|Error Unions|Errors#}</li>1702 <li>{#link|Error Unions|Errors#}</li>
...@@ -1618,7 +1715,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1618,7 +1715,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1618 </td>1715 </td>
1619 </tr>1716 </tr>
1620 <tr>1717 <tr>
1621 <td><pre>{#syntax#}a and b{#endsyntax#}</pre></td>1718 <th scope="row"><pre>{#syntax#}a and b{#endsyntax#}</pre></th>
1622 <td>1719 <td>
1623 <ul>1720 <ul>
1624 <li>{#link|bool|Primitive Types#}</li>1721 <li>{#link|bool|Primitive Types#}</li>
...@@ -1633,7 +1730,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1633,7 +1730,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1633 </td>1730 </td>
1634 </tr>1731 </tr>
1635 <tr>1732 <tr>
1636 <td><pre>{#syntax#}a or b{#endsyntax#}</pre></td>1733 <th scope="row"><pre>{#syntax#}a or b{#endsyntax#}</pre></th>
1637 <td>1734 <td>
1638 <ul>1735 <ul>
1639 <li>{#link|bool|Primitive Types#}</li>1736 <li>{#link|bool|Primitive Types#}</li>
...@@ -1648,7 +1745,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1648,7 +1745,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1648 </td>1745 </td>
1649 </tr>1746 </tr>
1650 <tr>1747 <tr>
1651 <td><pre>{#syntax#}!a{#endsyntax#}</pre></td>1748 <th scope="row"><pre>{#syntax#}!a{#endsyntax#}</pre></th>
1652 <td>1749 <td>
1653 <ul>1750 <ul>
1654 <li>{#link|bool|Primitive Types#}</li>1751 <li>{#link|bool|Primitive Types#}</li>
...@@ -1662,7 +1759,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1662,7 +1759,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1662 </td>1759 </td>
1663 </tr>1760 </tr>
1664 <tr>1761 <tr>
1665 <td><pre>{#syntax#}a == b{#endsyntax#}</pre></td>1762 <th scope="row"><pre>{#syntax#}a == b{#endsyntax#}</pre></th>
1666 <td>1763 <td>
1667 <ul>1764 <ul>
1668 <li>{#link|Integers#}</li>1765 <li>{#link|Integers#}</li>
...@@ -1680,7 +1777,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1680,7 +1777,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1680 </td>1777 </td>
1681 </tr>1778 </tr>
1682 <tr>1779 <tr>
1683 <td><pre>{#syntax#}a == null{#endsyntax#}</pre></td>1780 <th scope="row"><pre>{#syntax#}a == null{#endsyntax#}</pre></th>
1684 <td>1781 <td>
1685 <ul>1782 <ul>
1686 <li>{#link|Optionals#}</li>1783 <li>{#link|Optionals#}</li>
...@@ -1695,7 +1792,7 @@ value == null{#endsyntax#}</pre>...@@ -1695,7 +1792,7 @@ value == null{#endsyntax#}</pre>
1695 </td>1792 </td>
1696 </tr>1793 </tr>
1697 <tr>1794 <tr>
1698 <td><pre>{#syntax#}a != b{#endsyntax#}</pre></td>1795 <th scope="row"><pre>{#syntax#}a != b{#endsyntax#}</pre></th>
1699 <td>1796 <td>
1700 <ul>1797 <ul>
1701 <li>{#link|Integers#}</li>1798 <li>{#link|Integers#}</li>
...@@ -1713,7 +1810,7 @@ value == null{#endsyntax#}</pre>...@@ -1713,7 +1810,7 @@ value == null{#endsyntax#}</pre>
1713 </td>1810 </td>
1714 </tr>1811 </tr>
1715 <tr>1812 <tr>
1716 <td><pre>{#syntax#}a > b{#endsyntax#}</pre></td>1813 <th scope="row"><pre>{#syntax#}a > b{#endsyntax#}</pre></th>
1717 <td>1814 <td>
1718 <ul>1815 <ul>
1719 <li>{#link|Integers#}</li>1816 <li>{#link|Integers#}</li>
...@@ -1729,7 +1826,7 @@ value == null{#endsyntax#}</pre>...@@ -1729,7 +1826,7 @@ value == null{#endsyntax#}</pre>
1729 </td>1826 </td>
1730 </tr>1827 </tr>
1731 <tr>1828 <tr>
1732 <td><pre>{#syntax#}a >= b{#endsyntax#}</pre></td>1829 <th scope="row"><pre>{#syntax#}a >= b{#endsyntax#}</pre></th>
1733 <td>1830 <td>
1734 <ul>1831 <ul>
1735 <li>{#link|Integers#}</li>1832 <li>{#link|Integers#}</li>
...@@ -1745,7 +1842,7 @@ value == null{#endsyntax#}</pre>...@@ -1745,7 +1842,7 @@ value == null{#endsyntax#}</pre>
1745 </td>1842 </td>
1746 </tr>1843 </tr>
1747 <tr>1844 <tr>
1748 <td><pre>{#syntax#}a < b{#endsyntax#}</pre></td>1845 <th scope="row"><pre>{#syntax#}a < b{#endsyntax#}</pre></th>
1749 <td>1846 <td>
1750 <ul>1847 <ul>
1751 <li>{#link|Integers#}</li>1848 <li>{#link|Integers#}</li>
...@@ -1761,7 +1858,7 @@ value == null{#endsyntax#}</pre>...@@ -1761,7 +1858,7 @@ value == null{#endsyntax#}</pre>
1761 </td>1858 </td>
1762 </tr>1859 </tr>
1763 <tr>1860 <tr>
1764 <td><pre>{#syntax#}a <= b{#endsyntax#}</pre></td>1861 <th scope="row"><pre>{#syntax#}a <= b{#endsyntax#}</pre></th>
1765 <td>1862 <td>
1766 <ul>1863 <ul>
1767 <li>{#link|Integers#}</li>1864 <li>{#link|Integers#}</li>
...@@ -1777,7 +1874,7 @@ value == null{#endsyntax#}</pre>...@@ -1777,7 +1874,7 @@ value == null{#endsyntax#}</pre>
1777 </td>1874 </td>
1778 </tr>1875 </tr>
1779 <tr>1876 <tr>
1780 <td><pre>{#syntax#}a ++ b{#endsyntax#}</pre></td>1877 <th scope="row"><pre>{#syntax#}a ++ b{#endsyntax#}</pre></th>
1781 <td>1878 <td>
1782 <ul>1879 <ul>
1783 <li>{#link|Arrays#}</li>1880 <li>{#link|Arrays#}</li>
...@@ -1786,7 +1883,7 @@ value == null{#endsyntax#}</pre>...@@ -1786,7 +1883,7 @@ value == null{#endsyntax#}</pre>
1786 <td>1883 <td>
1787 Array concatenation.1884 Array concatenation.
1788 <ul>1885 <ul>
1789 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}.1886 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}.</li>
1790 </ul>1887 </ul>
1791 </td>1888 </td>
1792 <td>1889 <td>
...@@ -1798,7 +1895,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>...@@ -1798,7 +1895,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>
1798 </td>1895 </td>
1799 </tr>1896 </tr>
1800 <tr>1897 <tr>
1801 <td><pre>{#syntax#}a ** b{#endsyntax#}</pre></td>1898 <th scope="row"><pre>{#syntax#}a ** b{#endsyntax#}</pre></th>
1802 <td>1899 <td>
1803 <ul>1900 <ul>
1804 <li>{#link|Arrays#}</li>1901 <li>{#link|Arrays#}</li>
...@@ -1807,7 +1904,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>...@@ -1807,7 +1904,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>
1807 <td>1904 <td>
1808 Array multiplication.1905 Array multiplication.
1809 <ul>1906 <ul>
1810 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}.1907 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}.</li>
1811 </ul>1908 </ul>
1812 </td>1909 </td>
1813 <td>1910 <td>
...@@ -1817,7 +1914,7 @@ mem.eql(u8, pattern, "ababab"){#endsyntax#}</pre>...@@ -1817,7 +1914,7 @@ mem.eql(u8, pattern, "ababab"){#endsyntax#}</pre>
1817 </td>1914 </td>
1818 </tr>1915 </tr>
1819 <tr>1916 <tr>
1820 <td><pre>{#syntax#}a.*{#endsyntax#}</pre></td>1917 <th scope="row"><pre>{#syntax#}a.*{#endsyntax#}</pre></th>
1821 <td>1918 <td>
1822 <ul>1919 <ul>
1823 <li>{#link|Pointers#}</li>1920 <li>{#link|Pointers#}</li>
...@@ -1833,7 +1930,7 @@ ptr.* == 1234{#endsyntax#}</pre>...@@ -1833,7 +1930,7 @@ ptr.* == 1234{#endsyntax#}</pre>
1833 </td>1930 </td>
1834 </tr>1931 </tr>
1835 <tr>1932 <tr>
1836 <td><pre>{#syntax#}&a{#endsyntax#}</pre></td>1933 <th scope="row"><pre>{#syntax#}&a{#endsyntax#}</pre></th>
1837 <td>1934 <td>
1838 All types1935 All types
1839 </td>1936 </td>
...@@ -1847,7 +1944,7 @@ ptr.* == 1234{#endsyntax#}</pre>...@@ -1847,7 +1944,7 @@ ptr.* == 1234{#endsyntax#}</pre>
1847 </td>1944 </td>
1848 </tr>1945 </tr>
1849 <tr>1946 <tr>
1850 <td><pre>{#syntax#}a || b{#endsyntax#}</pre></td>1947 <th scope="row"><pre>{#syntax#}a || b{#endsyntax#}</pre></th>
1851 <td>1948 <td>
1852 <ul>1949 <ul>
1853 <li>{#link|Error Set Type#}</li>1950 <li>{#link|Error Set Type#}</li>
...@@ -1862,6 +1959,7 @@ const B = error{Two};...@@ -1862,6 +1959,7 @@ const B = error{Two};
1862(A || B) == error{One, Two}{#endsyntax#}</pre>1959(A || B) == error{One, Two}{#endsyntax#}</pre>
1863 </td>1960 </td>
1864 </tr>1961 </tr>
1962 </tbody>
1865 </table>1963 </table>
1866 </div>1964 </div>
1867 {#header_close#}1965 {#header_close#}
...@@ -2138,7 +2236,7 @@ test "null terminated array" {...@@ -2138,7 +2236,7 @@ test "null terminated array" {
2138 </li>2236 </li>
2139 </ul>2237 </ul>
2140 <p>Use {#syntax#}&x{#endsyntax#} to obtain a single-item pointer:</p>2238 <p>Use {#syntax#}&x{#endsyntax#} to obtain a single-item pointer:</p>
2141 {#code_begin|test#}2239 {#code_begin|test|single_item_pointer_test#}
2142const expect = @import("std").testing.expect;2240const expect = @import("std").testing.expect;
21432241
2144test "address of syntax" {2242test "address of syntax" {
...@@ -2182,7 +2280,7 @@ test "pointer array access" {...@@ -2182,7 +2280,7 @@ test "pointer array access" {
2182 against this kind of undefined behavior. This is one reason2280 against this kind of undefined behavior. This is one reason
2183 we prefer slices to pointers.2281 we prefer slices to pointers.
2184 </p>2282 </p>
2185 {#code_begin|test#}2283 {#code_begin|test|slice_bounds#}
2186const expect = @import("std").testing.expect;2284const expect = @import("std").testing.expect;
21872285
2188test "pointer slicing" {2286test "pointer slicing" {
...@@ -2197,7 +2295,7 @@ test "pointer slicing" {...@@ -2197,7 +2295,7 @@ test "pointer slicing" {
2197 {#code_end#}2295 {#code_end#}
2198 <p>Pointers work at compile-time too, as long as the code does not depend on2296 <p>Pointers work at compile-time too, as long as the code does not depend on
2199 an undefined memory layout:</p>2297 an undefined memory layout:</p>
2200 {#code_begin|test#}2298 {#code_begin|test|comptime_pointers#}
2201const expect = @import("std").testing.expect;2299const expect = @import("std").testing.expect;
22022300
2203test "comptime pointers" {2301test "comptime pointers" {
...@@ -2212,7 +2310,7 @@ test "comptime pointers" {...@@ -2212,7 +2310,7 @@ test "comptime pointers" {
2212 {#code_end#}2310 {#code_end#}
2213 <p>To convert an integer address into a pointer, use {#syntax#}@intToPtr{#endsyntax#}.2311 <p>To convert an integer address into a pointer, use {#syntax#}@intToPtr{#endsyntax#}.
2214 To convert a pointer to an integer, use {#syntax#}@ptrToInt{#endsyntax#}:</p>2312 To convert a pointer to an integer, use {#syntax#}@ptrToInt{#endsyntax#}:</p>
2215 {#code_begin|test#}2313 {#code_begin|test|integer_pointer_conversion#}
2216const expect = @import("std").testing.expect;2314const expect = @import("std").testing.expect;
22172315
2218test "@ptrToInt and @intToPtr" {2316test "@ptrToInt and @intToPtr" {
...@@ -2224,7 +2322,7 @@ test "@ptrToInt and @intToPtr" {...@@ -2224,7 +2322,7 @@ test "@ptrToInt and @intToPtr" {
2224 {#code_end#}2322 {#code_end#}
2225 <p>Zig is able to preserve memory addresses in comptime code, as long as2323 <p>Zig is able to preserve memory addresses in comptime code, as long as
2226 the pointer is never dereferenced:</p>2324 the pointer is never dereferenced:</p>
2227 {#code_begin|test#}2325 {#code_begin|test|comptime_pointer_conversion#}
2228const expect = @import("std").testing.expect;2326const expect = @import("std").testing.expect;
22292327
2230test "comptime @intToPtr" {2328test "comptime @intToPtr" {
...@@ -2244,7 +2342,7 @@ test "comptime @intToPtr" {...@@ -2244,7 +2342,7 @@ test "comptime @intToPtr" {
2244 should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}.2342 should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}.
2245 In the following code, loads and stores with {#syntax#}mmio_ptr{#endsyntax#} are guaranteed to all happen2343 In the following code, loads and stores with {#syntax#}mmio_ptr{#endsyntax#} are guaranteed to all happen
2246 and in the same order as in source code:</p>2344 and in the same order as in source code:</p>
2247 {#code_begin|test#}2345 {#code_begin|test|volatile#}
2248const expect = @import("std").testing.expect;2346const expect = @import("std").testing.expect;
22492347
2250test "volatile" {2348test "volatile" {
...@@ -2263,7 +2361,7 @@ test "volatile" {...@@ -2263,7 +2361,7 @@ test "volatile" {
2263 operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other2361 operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other
2264 conversions are not possible.2362 conversions are not possible.
2265 </p>2363 </p>
2266 {#code_begin|test#}2364 {#code_begin|test|pointer_casting#}
2267const std = @import("std");2365const std = @import("std");
2268const expect = std.testing.expect;2366const expect = std.testing.expect;
22692367
...@@ -2301,7 +2399,7 @@ test "pointer child type" {...@@ -2301,7 +2399,7 @@ test "pointer child type" {
2301 In Zig, a pointer type has an alignment value. If the value is equal to the2399 In Zig, a pointer type has an alignment value. If the value is equal to the
2302 alignment of the underlying type, it can be omitted from the type:2400 alignment of the underlying type, it can be omitted from the type:
2303 </p>2401 </p>
2304 {#code_begin|test#}2402 {#code_begin|test|variable_alignment#}
2305const std = @import("std");2403const std = @import("std");
2306const expect = std.testing.expect;2404const expect = std.testing.expect;
23072405
...@@ -2323,7 +2421,7 @@ test "variable alignment" {...@@ -2323,7 +2421,7 @@ test "variable alignment" {
2323 You can specify alignment on variables and functions. If you do this, then2421 You can specify alignment on variables and functions. If you do this, then
2324 pointers to them get the specified alignment:2422 pointers to them get the specified alignment:
2325 </p>2423 </p>
2326 {#code_begin|test#}2424 {#code_begin|test|variable_func_alignment#}
2327const expect = @import("std").testing.expect;2425const expect = @import("std").testing.expect;
23282426
2329var foo: u8 align(4) = 100;2427var foo: u8 align(4) = 100;
...@@ -2660,7 +2758,7 @@ test "linked list" {...@@ -2660,7 +2758,7 @@ test "linked list" {
2660 Each struct field may have an expression indicating the default field value. Such expressions2758 Each struct field may have an expression indicating the default field value. Such expressions
2661 are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression:2759 are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression:
2662 </p>2760 </p>
2663 {#code_begin|test#}2761 {#code_begin|test|default_field_values#}
2664const Foo = struct {2762const Foo = struct {
2665 a: i32 = 1234,2763 a: i32 = 1234,
2666 b: i32,2764 b: i32,
...@@ -2709,7 +2807,7 @@ test "default struct initialization fields" {...@@ -2709,7 +2807,7 @@ test "default struct initialization fields" {
2709 in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory.2807 in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory.
2710 This even works at {#link|comptime#}:2808 This even works at {#link|comptime#}:
2711 </p>2809 </p>
2712 {#code_begin|test#}2810 {#code_begin|test|packed_structs#}
2713const std = @import("std");2811const std = @import("std");
2714const native_endian = @import("builtin").target.cpu.arch.endian();2812const native_endian = @import("builtin").target.cpu.arch.endian();
2715const expect = std.testing.expect;2813const expect = std.testing.expect;
...@@ -2750,7 +2848,7 @@ fn doTheTest() !void {...@@ -2750,7 +2848,7 @@ fn doTheTest() !void {
2750 <p>2848 <p>
2751 Zig allows the address to be taken of a non-byte-aligned field:2849 Zig allows the address to be taken of a non-byte-aligned field:
2752 </p>2850 </p>
2753 {#code_begin|test#}2851 {#code_begin|test|pointer_to_non-byte_aligned_field#}
2754const std = @import("std");2852const std = @import("std");
2755const expect = std.testing.expect;2853const expect = std.testing.expect;
27562854
...@@ -2806,7 +2904,7 @@ fn bar(x: *const u3) u3 {...@@ -2806,7 +2904,7 @@ fn bar(x: *const u3) u3 {
2806 <p>2904 <p>
2807 Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:2905 Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:
2808 </p>2906 </p>
2809 {#code_begin|test#}2907 {#code_begin|test|pointer_to_non-bit_aligned_field#}
2810const std = @import("std");2908const std = @import("std");
2811const expect = std.testing.expect;2909const expect = std.testing.expect;
28122910
...@@ -2830,7 +2928,7 @@ test "pointer to non-bit-aligned field" {...@@ -2830,7 +2928,7 @@ test "pointer to non-bit-aligned field" {
2830 <p>2928 <p>
2831 This can be observed with {#link|@bitOffsetOf#} and {#link|offsetOf#}:2929 This can be observed with {#link|@bitOffsetOf#} and {#link|offsetOf#}:
2832 </p>2930 </p>
2833 {#code_begin|test#}2931 {#code_begin|test|test_bitOffsetOf_offsetOf#}
2834const std = @import("std");2932const std = @import("std");
2835const expect = std.testing.expect;2933const expect = std.testing.expect;
28362934
...@@ -2875,7 +2973,7 @@ test "overaligned pointer to packed struct" {...@@ -2875,7 +2973,7 @@ test "overaligned pointer to packed struct" {
2875 <p>2973 <p>
2876 It's also possible to set alignment of struct fields:2974 It's also possible to set alignment of struct fields:
2877 </p>2975 </p>
2878 {#code_begin|test#}2976 {#code_begin|test|test_aligned_struct_fields#}
2879const std = @import("std");2977const std = @import("std");
2880const expectEqual = std.testing.expectEqual;2978const expectEqual = std.testing.expectEqual;
28812979
...@@ -3129,7 +3227,7 @@ export fn entry(foo: Foo) void { _ = foo; }...@@ -3129,7 +3227,7 @@ export fn entry(foo: Foo) void { _ = foo; }
3129 <p>3227 <p>
3130 Enum literals allow specifying the name of an enum field without specifying the enum type:3228 Enum literals allow specifying the name of an enum field without specifying the enum type:
3131 </p>3229 </p>
3132 {#code_begin|test#}3230 {#code_begin|test|test_enum_literals#}
3133const std = @import("std");3231const std = @import("std");
3134const expect = std.testing.expect;3232const expect = std.testing.expect;
31353233
...@@ -3171,7 +3269,7 @@ test "switch using enum literals" {...@@ -3171,7 +3269,7 @@ test "switch using enum literals" {
3171 A switch on a non-exhaustive enum can include a '_' prong as an alternative to an {#syntax#}else{#endsyntax#} prong3269 A switch on a non-exhaustive enum can include a '_' prong as an alternative to an {#syntax#}else{#endsyntax#} prong
3172 with the difference being that it makes it a compile error if all the known tag names are not handled by the switch.3270 with the difference being that it makes it a compile error if all the known tag names are not handled by the switch.
3173 </p>3271 </p>
3174 {#code_begin|test#}3272 {#code_begin|test|test_switch_non-exhaustive#}
3175const std = @import("std");3273const std = @import("std");
3176const expect = std.testing.expect;3274const expect = std.testing.expect;
31773275
...@@ -3224,7 +3322,7 @@ test "simple union" {...@@ -3224,7 +3322,7 @@ test "simple union" {
3224}3322}
3225 {#code_end#}3323 {#code_end#}
3226 <p>You can activate another field by assigning the entire union:</p>3324 <p>You can activate another field by assigning the entire union:</p>
3227 {#code_begin|test#}3325 {#code_begin|test|test_simple_union#}
3228const std = @import("std");3326const std = @import("std");
3229const expect = std.testing.expect;3327const expect = std.testing.expect;
32303328
...@@ -3253,7 +3351,7 @@ test "simple union" {...@@ -3253,7 +3351,7 @@ test "simple union" {
3253 to use with {#link|switch#} expressions.3351 to use with {#link|switch#} expressions.
3254 Tagged unions coerce to their tag type: {#link|Type Coercion: unions and enums#}.3352 Tagged unions coerce to their tag type: {#link|Type Coercion: unions and enums#}.
3255 </p>3353 </p>
3256 {#code_begin|test#}3354 {#code_begin|test|test_switch_tagged_union#}
3257const std = @import("std");3355const std = @import("std");
3258const expect = std.testing.expect;3356const expect = std.testing.expect;
32593357
...@@ -3291,7 +3389,7 @@ test "coerce to enum" {...@@ -3291,7 +3389,7 @@ test "coerce to enum" {
3291 <p>In order to modify the payload of a tagged union in a switch expression,3389 <p>In order to modify the payload of a tagged union in a switch expression,
3292 place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer:3390 place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer:
3293 </p>3391 </p>
3294 {#code_begin|test#}3392 {#code_begin|test|test_switch_modify_tagged_union#}
3295const std = @import("std");3393const std = @import("std");
3296const expect = std.testing.expect;3394const expect = std.testing.expect;
32973395
...@@ -3320,7 +3418,7 @@ test "modify tagged union in switch" {...@@ -3320,7 +3418,7 @@ test "modify tagged union in switch" {
3320 Unions can be made to infer the enum tag type.3418 Unions can be made to infer the enum tag type.
3321 Further, unions can have methods just like structs and enums.3419 Further, unions can have methods just like structs and enums.
3322 </p>3420 </p>
3323 {#code_begin|test#}3421 {#code_begin|test|test_union_method#}
3324const std = @import("std");3422const std = @import("std");
3325const expect = std.testing.expect;3423const expect = std.testing.expect;
33263424
...@@ -3352,7 +3450,7 @@ test "union method" {...@@ -3352,7 +3450,7 @@ test "union method" {
3352 {#link|@tagName#} can be used to return a {#link|comptime#}3450 {#link|@tagName#} can be used to return a {#link|comptime#}
3353 {#syntax#}[:0]const u8{#endsyntax#} value representing the field name:3451 {#syntax#}[:0]const u8{#endsyntax#} value representing the field name:
3354 </p>3452 </p>
3355 {#code_begin|test#}3453 {#code_begin|test|test_tagName#}
3356const std = @import("std");3454const std = @import("std");
3357const expect = std.testing.expect;3455const expect = std.testing.expect;
33583456
...@@ -3377,7 +3475,7 @@ test "@tagName" {...@@ -3377,7 +3475,7 @@ test "@tagName" {
33773475
3378 {#header_open|packed union#}3476 {#header_open|packed union#}
3379 <p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible3477 <p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible
3380 to be in a {#link|packed struct#}.3478 to be in a {#link|packed struct#}.</p>
3381 {#header_close#}3479 {#header_close#}
33823480
3383 {#header_open|Anonymous Union Literals#}3481 {#header_open|Anonymous Union Literals#}
...@@ -3448,7 +3546,7 @@ test "access variable after block scope" {...@@ -3448,7 +3546,7 @@ test "access variable after block scope" {
3448 <p>Blocks are expressions. When labeled, {#syntax#}break{#endsyntax#} can be used3546 <p>Blocks are expressions. When labeled, {#syntax#}break{#endsyntax#} can be used
3449 to return a value from the block:3547 to return a value from the block:
3450 </p>3548 </p>
3451 {#code_begin|test#}3549 {#code_begin|test|test_labeled_break#}
3452const std = @import("std");3550const std = @import("std");
3453const expect = std.testing.expect;3551const expect = std.testing.expect;
34543552
...@@ -3482,7 +3580,7 @@ test "inside test block" {...@@ -3482,7 +3580,7 @@ test "inside test block" {
3482 Because of this, when you read Zig code you can rely on an identifier always meaning the same thing,3580 Because of this, when you read Zig code you can rely on an identifier always meaning the same thing,
3483 within the scope it is defined. Note that you can, however use the same name if the scopes are separate:3581 within the scope it is defined. Note that you can, however use the same name if the scopes are separate:
3484 </p>3582 </p>
3485 {#code_begin|test#}3583 {#code_begin|test|test_scopes#}
3486test "separate scopes" {3584test "separate scopes" {
3487 {3585 {
3488 const pi = 3.14;3586 const pi = 3.14;
...@@ -3569,7 +3667,7 @@ test "switch inside function" {...@@ -3569,7 +3667,7 @@ test "switch inside function" {
3569 done by placing a {#syntax#}*{#endsyntax#} before the capture variable name,3667 done by placing a {#syntax#}*{#endsyntax#} before the capture variable name,
3570 turning it into a pointer.3668 turning it into a pointer.
3571 </p>3669 </p>
3572 {#code_begin|test#}3670 {#code_begin|test|test_switch_tagged_union#}
3573const expect = @import("std").testing.expect;3671const expect = @import("std").testing.expect;
35743672
3575test "switch on tagged union" {3673test "switch on tagged union" {
...@@ -3636,7 +3734,7 @@ test "exhaustive switching" {...@@ -3636,7 +3734,7 @@ test "exhaustive switching" {
3636 {#link|Enum Literals#} can be useful to use with {#syntax#}switch{#endsyntax#} to avoid3734 {#link|Enum Literals#} can be useful to use with {#syntax#}switch{#endsyntax#} to avoid
3637 repetitively specifying {#link|enum#} or {#link|union#} types:3735 repetitively specifying {#link|enum#} or {#link|union#} types:
3638 </p>3736 </p>
3639 {#code_begin|test#}3737 {#code_begin|test|test_exhaustive_switch#}
3640const std = @import("std");3738const std = @import("std");
3641const expect = std.testing.expect;3739const expect = std.testing.expect;
36423740
...@@ -3761,7 +3859,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {...@@ -3761,7 +3859,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
3761 {#header_open|Labeled while#}3859 {#header_open|Labeled while#}
3762 <p>When a {#syntax#}while{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}3860 <p>When a {#syntax#}while{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}
3763 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>3861 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>
3764 {#code_begin|test#}3862 {#code_begin|test|test_nested_break#}
3765test "nested break" {3863test "nested break" {
3766 outer: while (true) {3864 outer: while (true) {
3767 while (true) {3865 while (true) {
...@@ -3866,7 +3964,7 @@ fn eventuallyErrorSequence() anyerror!u32 {...@@ -3866,7 +3964,7 @@ fn eventuallyErrorSequence() anyerror!u32 {
3866 allows the code to do some things which only work at compile time,3964 allows the code to do some things which only work at compile time,
3867 such as use types as first class values.3965 such as use types as first class values.
3868 </p>3966 </p>
3869 {#code_begin|test#}3967 {#code_begin|test|test_inline_while#}
3870const expect = @import("std").testing.expect;3968const expect = @import("std").testing.expect;
38713969
3872test "inline while loop" {3970test "inline while loop" {
...@@ -3969,7 +4067,7 @@ test "for else" {...@@ -3969,7 +4067,7 @@ test "for else" {
3969 {#header_open|Labeled for#}4067 {#header_open|Labeled for#}
3970 <p>When a {#syntax#}for{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}4068 <p>When a {#syntax#}for{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}
3971 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>4069 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>
3972 {#code_begin|test#}4070 {#code_begin|test|test_nested_break#}
3973const std = @import("std");4071const std = @import("std");
3974const expect = std.testing.expect;4072const expect = std.testing.expect;
39754073
...@@ -4005,7 +4103,7 @@ test "nested continue" {...@@ -4005,7 +4103,7 @@ test "nested continue" {
4005 The capture value and iterator value of inlined for loops are4103 The capture value and iterator value of inlined for loops are
4006 compile-time known.4104 compile-time known.
4007 </p>4105 </p>
4008 {#code_begin|test#}4106 {#code_begin|test|test_inline_loop#}
4009const expect = @import("std").testing.expect;4107const expect = @import("std").testing.expect;
40104108
4011test "inline for loop" {4109test "inline for loop" {
...@@ -4278,16 +4376,16 @@ test "errdefer unwinding" {...@@ -4278,16 +4376,16 @@ test "errdefer unwinding" {
4278 {#header_close#}4376 {#header_close#}
4279 {#header_open|unreachable#}4377 {#header_open|unreachable#}
4280 <p>4378 <p>
4281 In {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, and when using <code>zig test</code>,4379 In {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, and when using <kbd>zig test</kbd>,
4282 {#syntax#}unreachable{#endsyntax#} emits a call to {#syntax#}panic{#endsyntax#} with the message <code>reached unreachable code</code>.4380 {#syntax#}unreachable{#endsyntax#} emits a call to {#syntax#}panic{#endsyntax#} with the message <code>reached unreachable code</code>.
4283 </p>4381 </p>
4284 <p>4382 <p>
4285 In {#syntax#}ReleaseFast{#endsyntax#} mode, the optimizer uses the assumption that {#syntax#}unreachable{#endsyntax#} code4383 In {#syntax#}ReleaseFast{#endsyntax#} mode, the optimizer uses the assumption that {#syntax#}unreachable{#endsyntax#} code
4286 will never be hit to perform optimizations. However, <code>zig test</code> even in {#syntax#}ReleaseFast{#endsyntax#} mode4384 will never be hit to perform optimizations. However, <kbd>zig test</kbd> even in {#syntax#}ReleaseFast{#endsyntax#} mode
4287 still emits {#syntax#}unreachable{#endsyntax#} as calls to {#syntax#}panic{#endsyntax#}.4385 still emits {#syntax#}unreachable{#endsyntax#} as calls to {#syntax#}panic{#endsyntax#}.
4288 </p>4386 </p>
4289 {#header_open|Basics#}4387 {#header_open|Basics#}
4290 {#code_begin|test#}4388 {#code_begin|test|test_unreachable#}
4291// unreachable is used to assert that control flow will never happen upon a4389// unreachable is used to assert that control flow will never happen upon a
4292// particular location:4390// particular location:
4293test "basic math" {4391test "basic math" {
...@@ -4343,7 +4441,7 @@ test "type of unreachable" {...@@ -4343,7 +4441,7 @@ test "type of unreachable" {
4343 <p>When resolving types together, such as {#syntax#}if{#endsyntax#} clauses or {#syntax#}switch{#endsyntax#} prongs,4441 <p>When resolving types together, such as {#syntax#}if{#endsyntax#} clauses or {#syntax#}switch{#endsyntax#} prongs,
4344 the {#syntax#}noreturn{#endsyntax#} type is compatible with every other type. Consider:4442 the {#syntax#}noreturn{#endsyntax#} type is compatible with every other type. Consider:
4345 </p>4443 </p>
4346 {#code_begin|test#}4444 {#code_begin|test|test_noreturn#}
4347fn foo(condition: bool, b: u32) void {4445fn foo(condition: bool, b: u32) void {
4348 const a = if (condition) b else return;4446 const a = if (condition) b else return;
4349 _ = a;4447 _ = a;
...@@ -4354,7 +4452,7 @@ test "noreturn" {...@@ -4354,7 +4452,7 @@ test "noreturn" {
4354}4452}
4355 {#code_end#}4453 {#code_end#}
4356 <p>Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:</p>4454 <p>Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:</p>
4357 {#code_begin|test#}4455 {#code_begin|test|noreturn_from_exit#}
4358 {#target_windows#}4456 {#target_windows#}
4359pub extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(if (@import("builtin").target.cpu.arch == .i386) .Stdcall else .C) noreturn;4457pub extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(if (@import("builtin").target.cpu.arch == .i386) .Stdcall else .C) noreturn;
43604458
...@@ -4451,7 +4549,7 @@ fn foo() void { }...@@ -4451,7 +4549,7 @@ fn foo() void { }
4451 as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way4549 as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way
4452 Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable.4550 Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable.
4453 </p>4551 </p>
4454 {#code_begin|test#}4552 {#code_begin|test|pass_by_reference_or_value#}
4455const Point = struct {4553const Point = struct {
4456 x: i32,4554 x: i32,
4457 y: i32,4555 y: i32,
...@@ -4481,7 +4579,7 @@ test "pass struct to function" {...@@ -4481,7 +4579,7 @@ test "pass struct to function" {
4481 In this case the parameter types will be inferred when the function is called.4579 In this case the parameter types will be inferred when the function is called.
4482 Use {#link|@TypeOf#} and {#link|@typeInfo#} to get information about the inferred type.4580 Use {#link|@TypeOf#} and {#link|@typeInfo#} to get information about the inferred type.
4483 </p>4581 </p>
4484 {#code_begin|test#}4582 {#code_begin|test|test_fn_type_inference#}
4485const expect = @import("std").testing.expect;4583const expect = @import("std").testing.expect;
44864584
4487fn addFortyTwo(x: anytype) @TypeOf(x) {4585fn addFortyTwo(x: anytype) @TypeOf(x) {
...@@ -4499,7 +4597,7 @@ test "fn type inference" {...@@ -4499,7 +4597,7 @@ test "fn type inference" {
44994597
4500 {#header_close#}4598 {#header_close#}
4501 {#header_open|Function Reflection#}4599 {#header_open|Function Reflection#}
4502 {#code_begin|test#}4600 {#code_begin|test|test_fn_reflection#}
4503const expect = @import("std").testing.expect;4601const expect = @import("std").testing.expect;
45044602
4505test "fn reflection" {4603test "fn reflection" {
...@@ -4524,7 +4622,7 @@ test "fn reflection" {...@@ -4524,7 +4622,7 @@ test "fn reflection" {
4524 <p>4622 <p>
4525 You can {#link|coerce|Type Coercion#} an error from a subset to a superset:4623 You can {#link|coerce|Type Coercion#} an error from a subset to a superset:
4526 </p>4624 </p>
4527 {#code_begin|test#}4625 {#code_begin|test|coercing_subset_to_superset#}
4528const std = @import("std");4626const std = @import("std");
45294627
4530const FileOpenError = error {4628const FileOpenError = error {
...@@ -4608,7 +4706,7 @@ const err = (error {FileNotFound}).FileNotFound;...@@ -4608,7 +4706,7 @@ const err = (error {FileNotFound}).FileNotFound;
4608 <p>4706 <p>
4609 Here is a function to parse a string into a 64-bit integer:4707 Here is a function to parse a string into a 64-bit integer:
4610 </p>4708 </p>
4611 {#code_begin|test#}4709 {#code_begin|test|error_union_parsing_u64#}
4612const std = @import("std");4710const std = @import("std");
4613const maxInt = std.math.maxInt;4711const maxInt = std.math.maxInt;
46144712
...@@ -4791,7 +4889,7 @@ fn createFoo(param: i32) !Foo {...@@ -4791,7 +4889,7 @@ fn createFoo(param: i32) !Foo {
47914889
4792 <p>An error union is created with the {#syntax#}!{#endsyntax#} binary operator.4890 <p>An error union is created with the {#syntax#}!{#endsyntax#} binary operator.
4793 You can use compile-time reflection to access the child type of an error union:</p>4891 You can use compile-time reflection to access the child type of an error union:</p>
4794 {#code_begin|test#}4892 {#code_begin|test|test_error_union#}
4795const expect = @import("std").testing.expect;4893const expect = @import("std").testing.expect;
47964894
4797test "error union" {4895test "error union" {
...@@ -4823,7 +4921,7 @@ test "error union" {...@@ -4823,7 +4921,7 @@ test "error union" {
4823 {#syntax#}LinuxFileOpenError || WindowsFileOpenError{#endsyntax#} for the error set of opening4921 {#syntax#}LinuxFileOpenError || WindowsFileOpenError{#endsyntax#} for the error set of opening
4824 files.4922 files.
4825 </p>4923 </p>
4826 {#code_begin|test#}4924 {#code_begin|test|test_merging_error_sets#}
4827const A = error{4925const A = error{
4828 NotDir,4926 NotDir,
48294927
...@@ -4859,7 +4957,7 @@ test "merge error sets" {...@@ -4859,7 +4957,7 @@ test "merge error sets" {
4859 Because many functions in Zig return a possible error, Zig supports inferring the error set.4957 Because many functions in Zig return a possible error, Zig supports inferring the error set.
4860 To infer the error set for a function, use this syntax:4958 To infer the error set for a function, use this syntax:
4861 </p>4959 </p>
4862{#code_begin|test#}4960{#code_begin|test|inferred_error_sets#}
4863// With an inferred error set4961// With an inferred error set
4864pub fn add_inferred(comptime T: type, a: T, b: T) !T {4962pub fn add_inferred(comptime T: type, a: T, b: T) !T {
4865 var answer: T = undefined;4963 var answer: T = undefined;
...@@ -5173,7 +5271,7 @@ fn doAThing(optional_foo: ?*Foo) void {...@@ -5173,7 +5271,7 @@ fn doAThing(optional_foo: ?*Foo) void {
5173 {#header_open|Optional Type#}5271 {#header_open|Optional Type#}
5174 <p>An optional is created by putting {#syntax#}?{#endsyntax#} in front of a type. You can use compile-time5272 <p>An optional is created by putting {#syntax#}?{#endsyntax#} in front of a type. You can use compile-time
5175 reflection to access the child type of an optional:</p>5273 reflection to access the child type of an optional:</p>
5176 {#code_begin|test#}5274 {#code_begin|test|test_optional_type#}
5177const expect = @import("std").testing.expect;5275const expect = @import("std").testing.expect;
51785276
5179test "optional type" {5277test "optional type" {
...@@ -5200,7 +5298,7 @@ const optional_value: ?i32 = null;...@@ -5200,7 +5298,7 @@ const optional_value: ?i32 = null;
5200 {#header_open|Optional Pointers#}5298 {#header_open|Optional Pointers#}
5201 <p>An optional pointer is guaranteed to be the same size as a pointer. The {#syntax#}null{#endsyntax#} of5299 <p>An optional pointer is guaranteed to be the same size as a pointer. The {#syntax#}null{#endsyntax#} of
5202 the optional is guaranteed to be address 0.</p>5300 the optional is guaranteed to be address 0.</p>
5203 {#code_begin|test#}5301 {#code_begin|test|test_optional_pointer#}
5204const expect = @import("std").testing.expect;5302const expect = @import("std").testing.expect;
52055303
5206test "optional pointers" {5304test "optional pointers" {
...@@ -5232,7 +5330,7 @@ test "optional pointers" {...@@ -5232,7 +5330,7 @@ test "optional pointers" {
5232 <p>5330 <p>
5233 Type coercion occurs when one type is expected, but different type is provided:5331 Type coercion occurs when one type is expected, but different type is provided:
5234 </p>5332 </p>
5235 {#code_begin|test#}5333 {#code_begin|test|type_coercion#}
5236test "type coercion - variable declaration" {5334test "type coercion - variable declaration" {
5237 var a: u8 = 1;5335 var a: u8 = 1;
5238 var b: u16 = a;5336 var b: u16 = a;
...@@ -5272,7 +5370,7 @@ test "type coercion - @as builtin" {...@@ -5272,7 +5370,7 @@ test "type coercion - @as builtin" {
5272 <p>5370 <p>
5273 These casts are no-ops at runtime since the value representation does not change.5371 These casts are no-ops at runtime since the value representation does not change.
5274 </p>5372 </p>
5275 {#code_begin|test#}5373 {#code_begin|test|no_op_casts#}
5276test "type coercion - const qualification" {5374test "type coercion - const qualification" {
5277 var a: i32 = 1;5375 var a: i32 = 1;
5278 var b: *i32 = &a;5376 var b: *i32 = &a;
...@@ -5284,7 +5382,7 @@ fn foo(_: *const i32) void {}...@@ -5284,7 +5382,7 @@ fn foo(_: *const i32) void {}
5284 <p>5382 <p>
5285 In addition, pointers coerce to const optional pointers:5383 In addition, pointers coerce to const optional pointers:
5286 </p>5384 </p>
5287 {#code_begin|test#}5385 {#code_begin|test|pointer_coerce_const_optional#}
5288const std = @import("std");5386const std = @import("std");
5289const expect = std.testing.expect;5387const expect = std.testing.expect;
5290const mem = std.mem;5388const mem = std.mem;
...@@ -5301,7 +5399,7 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {...@@ -5301,7 +5399,7 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
5301 {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise5399 {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise
5302 {#link|Floats#} coerce to float types which can represent every value of the old type.5400 {#link|Floats#} coerce to float types which can represent every value of the old type.
5303 </p>5401 </p>
5304 {#code_begin|test#}5402 {#code_begin|test|test_integer_widening#}
5305const std = @import("std");5403const std = @import("std");
5306const expect = std.testing.expect;5404const expect = std.testing.expect;
5307const mem = std.mem;5405const mem = std.mem;
...@@ -5429,7 +5527,7 @@ test "*T to *[1]T" {...@@ -5429,7 +5527,7 @@ test "*T to *[1]T" {
5429 <p>5527 <p>
5430 The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.5528 The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.
5431 </p>5529 </p>
5432 {#code_begin|test#}5530 {#code_begin|test|test_coerce_optionals#}
5433const std = @import("std");5531const std = @import("std");
5434const expect = std.testing.expect;5532const expect = std.testing.expect;
54355533
...@@ -5442,7 +5540,7 @@ test "coerce to optionals" {...@@ -5442,7 +5540,7 @@ test "coerce to optionals" {
5442}5540}
5443 {#code_end#}5541 {#code_end#}
5444 <p>It works nested inside the {#link|Error Union Type#}, too:</p>5542 <p>It works nested inside the {#link|Error Union Type#}, too:</p>
5445 {#code_begin|test#}5543 {#code_begin|test|test_corerce_optional_wrapped_error_union#}
5446const std = @import("std");5544const std = @import("std");
5447const expect = std.testing.expect;5545const expect = std.testing.expect;
54485546
...@@ -5459,7 +5557,7 @@ test "coerce to optionals wrapped in error union" {...@@ -5459,7 +5557,7 @@ test "coerce to optionals wrapped in error union" {
5459 <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}5557 <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}
5460 coerce to the error union type:5558 coerce to the error union type:
5461 </p>5559 </p>
5462 {#code_begin|test#}5560 {#code_begin|test|test_coerce_to_error_union#}
5463const std = @import("std");5561const std = @import("std");
5464const expect = std.testing.expect;5562const expect = std.testing.expect;
54655563
...@@ -5476,7 +5574,7 @@ test "coercion to error unions" {...@@ -5476,7 +5574,7 @@ test "coercion to error unions" {
5476 <p>When a number is {#link|comptime#}-known to be representable in the destination type,5574 <p>When a number is {#link|comptime#}-known to be representable in the destination type,
5477 it may be coerced:5575 it may be coerced:
5478 </p>5576 </p>
5479 {#code_begin|test#}5577 {#code_begin|test|test_coerce_large_to_small#}
5480const std = @import("std");5578const std = @import("std");
5481const expect = std.testing.expect;5579const expect = std.testing.expect;
54825580
...@@ -5492,7 +5590,7 @@ test "coercing large integer type to smaller one when value is comptime known to...@@ -5492,7 +5590,7 @@ test "coercing large integer type to smaller one when value is comptime known to
5492 when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as5590 when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as
5493 {#link|void#}:5591 {#link|void#}:
5494 </p>5592 </p>
5495 {#code_begin|test#}5593 {#code_begin|test|test_coerce_unions_enums#}
5496const std = @import("std");5594const std = @import("std");
5497const expect = std.testing.expect;5595const expect = std.testing.expect;
54985596
...@@ -5525,7 +5623,7 @@ test "coercion between unions and enums" {...@@ -5525,7 +5623,7 @@ test "coercion between unions and enums" {
5525 regardless of const.</p>5623 regardless of const.</p>
5526 <p>TODO document the reasoning for this</p>5624 <p>TODO document the reasoning for this</p>
5527 <p>TODO document whether vice versa should work and why</p>5625 <p>TODO document whether vice versa should work and why</p>
5528 {#code_begin|test#}5626 {#code_begin|test|coerce_zero_bit_types#}
5529test "coercion of zero bit types" {5627test "coercion of zero bit types" {
5530 var x: void = {};5628 var x: void = {};
5531 var y: *void = x;5629 var y: *void = x;
...@@ -5715,7 +5813,7 @@ export fn entry() void {...@@ -5715,7 +5813,7 @@ export fn entry() void {
5715 {#syntax#}Map(Key, Value){#endsyntax#}, one can pass {#syntax#}void{#endsyntax#} for the {#syntax#}Value{#endsyntax#}5813 {#syntax#}Map(Key, Value){#endsyntax#}, one can pass {#syntax#}void{#endsyntax#} for the {#syntax#}Value{#endsyntax#}
5716 type to make it into a {#syntax#}Set{#endsyntax#}:5814 type to make it into a {#syntax#}Set{#endsyntax#}:
5717 </p>5815 </p>
5718 {#code_begin|test#}5816 {#code_begin|test|void_in_hashmap#}
5719const std = @import("std");5817const std = @import("std");
5720const expect = std.testing.expect;5818const expect = std.testing.expect;
57215819
...@@ -5755,7 +5853,7 @@ fn foo() i32 {...@@ -5755,7 +5853,7 @@ fn foo() i32 {
5755}5853}
5756 {#code_end#}5854 {#code_end#}
5757 <p>However, if the expression has type {#syntax#}void{#endsyntax#}, there will be no error. Function return values can also be explicitly ignored by assigning them to {#syntax#}_{#endsyntax#}. </p>5855 <p>However, if the expression has type {#syntax#}void{#endsyntax#}, there will be no error. Function return values can also be explicitly ignored by assigning them to {#syntax#}_{#endsyntax#}. </p>
5758 {#code_begin|test#}5856 {#code_begin|test|void_ignored#}
5759test "void is ignored" {5857test "void is ignored" {
5760 returnsVoid();5858 returnsVoid();
5761}5859}
...@@ -5774,7 +5872,7 @@ fn foo() i32 {...@@ -5774,7 +5872,7 @@ fn foo() i32 {
57745872
5775 {#header_open|Pointers to Zero Bit Types#}5873 {#header_open|Pointers to Zero Bit Types#}
5776 <p>Pointers to zero bit types also have zero bits. They always compare equal to each other:</p>5874 <p>Pointers to zero bit types also have zero bits. They always compare equal to each other:</p>
5777 {#code_begin|test#}5875 {#code_begin|test|pointers_to_zero_bits#}
5778const std = @import("std");5876const std = @import("std");
5779const expect = std.testing.expect;5877const expect = std.testing.expect;
57805878
...@@ -5812,36 +5910,24 @@ test "@intToPtr for pointer to zero bit type" {...@@ -5812,36 +5910,24 @@ test "@intToPtr for pointer to zero bit type" {
58125910
5813 {#header_open|usingnamespace#}5911 {#header_open|usingnamespace#}
5814 <p>5912 <p>
5815 {#syntax#}usingnamespace{#endsyntax#} is a declaration that imports all the public declarations of5913 {#syntax#}usingnamespace{#endsyntax#} is a declaration that mixes all the public
5816 the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope:5914 declarations of the operand, which must be a {#link|struct#}, {#link|union#}, {#link|enum#},
5915 or {#link|opaque#}, into the namespace:
5817 </p>5916 </p>
5818 {#code_begin|test|usingnamespace#}5917 {#code_begin|test|usingnamespace#}
5819usingnamespace @import("std");
5820
5821test "using std namespace" {5918test "using std namespace" {
5822 try testing.expect(true);5919 const S = struct {
5823}5920 usingnamespace @import("std");
5824 {#code_end#}
5825 <p>
5826 {#syntax#}usingnamespace{#endsyntax#} can also be used in containers:
5827 </p>
5828 {#code_begin|test|usingnamespace_inside_struct#}
5829test "using namespace inside struct" {
5830 const L = struct {
5831 usingnamespace struct {
5832 pub fn f() void {}
5833 };
5834 };5921 };
5835 L.f();5922 try S.testing.expect(true);
5836}5923}
5837 {#code_end#}5924 {#code_end#}
5838 <p>5925 <p>
5839 Instead of the above pattern, it is generally recommended to explicitly alias individual declarations.5926 {#syntax#}usingnamespace{#endsyntax#} has an important use case when organizing the public
5840 However, {#syntax#}usingnamespace{#endsyntax#} has an important use case when organizing the public5927 API of a file or package. For example, one might have <code class="file">c.zig</code> with all of the
5841 API of a file or package. For example, one might have <code>c.zig</code> with all of the
5842 {#link|C imports|Import from C Header File#}:5928 {#link|C imports|Import from C Header File#}:
5843 </p>5929 </p>
5844 <pre>{#syntax#}5930 {#syntax_block|zig|c.zig#}
5845pub usingnamespace @cImport({5931pub usingnamespace @cImport({
5846 @cInclude("epoxy/gl.h");5932 @cInclude("epoxy/gl.h");
5847 @cInclude("GLFW/glfw3.h");5933 @cInclude("GLFW/glfw3.h");
...@@ -5849,7 +5935,7 @@ pub usingnamespace @cImport({...@@ -5849,7 +5935,7 @@ pub usingnamespace @cImport({
5849 @cDefine("STBI_NO_STDIO", "");5935 @cDefine("STBI_NO_STDIO", "");
5850 @cInclude("stb_image.h");5936 @cInclude("stb_image.h");
5851});5937});
5852 {#endsyntax#}</pre>5938 {#end_syntax_block#}
5853 <p>5939 <p>
5854 The above example demonstrates using {#syntax#}pub{#endsyntax#} to qualify the5940 The above example demonstrates using {#syntax#}pub{#endsyntax#} to qualify the
5855 {#syntax#}usingnamespace{#endsyntax#} additionally makes the imported declarations5941 {#syntax#}usingnamespace{#endsyntax#} additionally makes the imported declarations
...@@ -5858,6 +5944,7 @@ pub usingnamespace @cImport({...@@ -5858,6 +5944,7 @@ pub usingnamespace @cImport({
5858 </p>5944 </p>
5859 {#header_close#}5945 {#header_close#}
58605946
5947
5861 {#header_open|comptime#}5948 {#header_open|comptime#}
5862 <p>5949 <p>
5863 Zig places importance on the concept of whether an expression is known at compile-time.5950 Zig places importance on the concept of whether an expression is known at compile-time.
...@@ -5934,7 +6021,7 @@ test "try to compare bools" {...@@ -5934,7 +6021,7 @@ test "try to compare bools" {
5934 value is known at compile-time. This means that we actually could make this work for the bool type6021 value is known at compile-time. This means that we actually could make this work for the bool type
5935 if we wanted to:6022 if we wanted to:
5936 </p>6023 </p>
5937 {#code_begin|test#}6024 {#code_begin|test|comptime_max_with_bool#}
5938fn max(comptime T: type, a: T, b: T) T {6025fn max(comptime T: type, a: T, b: T) T {
5939 if (T == bool) {6026 if (T == bool) {
5940 return a or b;6027 return a or b;
...@@ -6097,7 +6184,7 @@ test "foo" {...@@ -6097,7 +6184,7 @@ test "foo" {
6097 <p>6184 <p>
6098 Let's look at an example:6185 Let's look at an example:
6099 </p>6186 </p>
6100 {#code_begin|test#}6187 {#code_begin|test|fibonacci_recursion#}
6101const expect = @import("std").testing.expect;6188const expect = @import("std").testing.expect;
61026189
6103fn fibonacci(index: u32) u32 {6190fn fibonacci(index: u32) u32 {
...@@ -6190,7 +6277,7 @@ test "fibonacci" {...@@ -6190,7 +6277,7 @@ test "fibonacci" {
6190 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to6277 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to
6191 initialize complex static data. For example:6278 initialize complex static data. For example:
6192 </p>6279 </p>
6193 {#code_begin|test#}6280 {#code_begin|test|N_primes#}
6194const first_25_primes = firstNPrimes(25);6281const first_25_primes = firstNPrimes(25);
6195const sum_of_first_25_primes = sum(&first_25_primes);6282const sum_of_first_25_primes = sum(&first_25_primes);
61966283
...@@ -6491,7 +6578,7 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {...@@ -6491,7 +6578,7 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
6491 <p>6578 <p>
6492 Dissecting the syntax:6579 Dissecting the syntax:
6493 </p>6580 </p>
6494 <pre>{#syntax#}// Inline assembly is an expression which returns a value.6581 {#syntax_block|zig|Assembly Syntax Explained#}// Inline assembly is an expression which returns a value.
6495// the `asm` keyword begins the expression.6582// the `asm` keyword begins the expression.
6496_ = asm6583_ = asm
6497// `volatile` is an optional modifier that tells Zig this6584// `volatile` is an optional modifier that tells Zig this
...@@ -6546,7 +6633,7 @@ volatile (...@@ -6546,7 +6633,7 @@ volatile (
6546// output. In this example we list $rcx and $r11 because it is known the6633// output. In this example we list $rcx and $r11 because it is known the
6547// kernel syscall does not preserve these registers.6634// kernel syscall does not preserve these registers.
6548 : "rcx", "r11"6635 : "rcx", "r11"
6549);{#endsyntax#}</pre>6636);{#end_syntax_block#}
6550 <p>6637 <p>
6551 For i386 and x86_64 targets, the syntax is AT&amp;T syntax, rather than the more6638 For i386 and x86_64 targets, the syntax is AT&amp;T syntax, rather than the more
6552 popular Intel syntax. This is due to technical constraints; assembly parsing is6639 popular Intel syntax. This is due to technical constraints; assembly parsing is
...@@ -6672,7 +6759,7 @@ test "global assembly" {...@@ -6672,7 +6759,7 @@ test "global assembly" {
6672 return to the callsite (in the case of the first suspension),6759 return to the callsite (in the case of the first suspension),
6673 or resumer (in the case of subsequent suspensions).6760 or resumer (in the case of subsequent suspensions).
6674 </p>6761 </p>
6675 {#code_begin|test#}6762 {#code_begin|test|suspend_no_resume#}
6676const std = @import("std");6763const std = @import("std");
6677const expect = std.testing.expect;6764const expect = std.testing.expect;
66786765
...@@ -6699,7 +6786,7 @@ fn func() void {...@@ -6699,7 +6786,7 @@ fn func() void {
6699 {#syntax#}resume{#endsyntax#} operation on a different thread.6786 {#syntax#}resume{#endsyntax#} operation on a different thread.
6700 {#link|@frame#} provides access to the async function frame pointer.6787 {#link|@frame#} provides access to the async function frame pointer.
6701 </p>6788 </p>
6702 {#code_begin|test#}6789 {#code_begin|test|async_suspend_block#}
6703const std = @import("std");6790const std = @import("std");
6704const expect = std.testing.expect;6791const expect = std.testing.expect;
67056792
...@@ -6737,7 +6824,7 @@ fn testSuspendBlock() void {...@@ -6737,7 +6824,7 @@ fn testSuspendBlock() void {
6737 However, the async function can be directly resumed from the suspend block, in which case it6824 However, the async function can be directly resumed from the suspend block, in which case it
6738 never returns to its resumer and continues executing.6825 never returns to its resumer and continues executing.
6739 </p>6826 </p>
6740 {#code_begin|test#}6827 {#code_begin|test|resume_from_suspend#}
6741const std = @import("std");6828const std = @import("std");
6742const expect = std.testing.expect;6829const expect = std.testing.expect;
67436830
...@@ -6773,7 +6860,7 @@ fn testResumeFromSuspend(my_result: *i32) void {...@@ -6773,7 +6860,7 @@ fn testResumeFromSuspend(my_result: *i32) void {
6773 execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite,6860 execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite,
6774 and the return value of the async function would be lost.6861 and the return value of the async function would be lost.
6775 </p>6862 </p>
6776 {#code_begin|test#}6863 {#code_begin|test|async_await#}
6777const std = @import("std");6864const std = @import("std");
6778const expect = std.testing.expect;6865const expect = std.testing.expect;
67796866
...@@ -6817,7 +6904,7 @@ fn func() void {...@@ -6817,7 +6904,7 @@ fn func() void {
6817 does not suspend; instead it copies the6904 does not suspend; instead it copies the
6818 return value directly from the target function's frame.6905 return value directly from the target function's frame.
6819 </p>6906 </p>
6820 {#code_begin|test#}6907 {#code_begin|test|async_await_sequence#}
6821const std = @import("std");6908const std = @import("std");
6822const expect = std.testing.expect;6909const expect = std.testing.expect;
68236910
...@@ -7031,6 +7118,16 @@ fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {...@@ -7031,6 +7118,16 @@ fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
7031 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.7118 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
7032 </p>7119 </p>
7033 {#header_close#}7120 {#header_close#}
7121 {#header_open|@addWithSaturation#}
7122 <pre>{#syntax#}@addWithSaturation(a: T, b: T) T{#endsyntax#}</pre>
7123 <p>
7124 Returns {#syntax#}a + b{#endsyntax#}. The result will be clamped between the type maximum and minimum.
7125 </p>
7126 <p>
7127 Once <a href="https://github.com/ziglang/zig/issues/1284">Saturating arithmetic</a>.
7128 is completed, the syntax {#syntax#}a +| b{#endsyntax#} will be equivalent to calling {#syntax#}@addWithSaturation(a, b){#endsyntax#}.
7129 </p>
7130 {#header_close#}
7034 {#header_open|@alignCast#}7131 {#header_open|@alignCast#}
7035 <pre>{#syntax#}@alignCast(comptime alignment: u29, ptr: anytype) anytype{#endsyntax#}</pre>7132 <pre>{#syntax#}@alignCast(comptime alignment: u29, ptr: anytype) anytype{#endsyntax#}</pre>
7036 <p>7133 <p>
...@@ -7085,7 +7182,7 @@ comptime {...@@ -7085,7 +7182,7 @@ comptime {
7085 read after {#link|await|Async and Await#} completes. Any result location provided to7182 read after {#link|await|Async and Await#} completes. Any result location provided to
7086 {#syntax#}await{#endsyntax#} will copy the result from {#syntax#}result_ptr{#endsyntax#}.7183 {#syntax#}await{#endsyntax#} will copy the result from {#syntax#}result_ptr{#endsyntax#}.
7087 </p>7184 </p>
7088 {#code_begin|test#}7185 {#code_begin|test|async_struct_field_fn_pointer#}
7089const std = @import("std");7186const std = @import("std");
7090const expect = std.testing.expect;7187const expect = std.testing.expect;
70917188
...@@ -7527,7 +7624,7 @@ test "main" {...@@ -7527,7 +7624,7 @@ test "main" {
7527 not encountered by analysis, the7624 not encountered by analysis, the
7528 program compiles successfully and the generated executable prints:7625 program compiles successfully and the generated executable prints:
7529 </p>7626 </p>
7530 {#code_begin|test#}7627 {#code_begin|test|without_compileLog#}
7531const print = @import("std").debug.print;7628const print = @import("std").debug.print;
75327629
7533const num1 = blk: {7630const num1 = blk: {
...@@ -7759,7 +7856,7 @@ export fn @"A function name that is a complete sentence."() void {}...@@ -7759,7 +7856,7 @@ export fn @"A function name that is a complete sentence."() void {}
7759 <pre>{#syntax#}@field(lhs: anytype, comptime field_name: []const u8) (field){#endsyntax#}</pre>7856 <pre>{#syntax#}@field(lhs: anytype, comptime field_name: []const u8) (field){#endsyntax#}</pre>
7760 <p>Performs field access by a compile-time string. Works on both fields and declarations.7857 <p>Performs field access by a compile-time string. Works on both fields and declarations.
7761 </p>7858 </p>
7762 {#code_begin|test#}7859 {#code_begin|test|field_decl_access_by_string#}
7763const std = @import("std");7860const std = @import("std");
77647861
7765const Point = struct {7862const Point = struct {
...@@ -7844,7 +7941,7 @@ test "decl access by string" {...@@ -7844,7 +7941,7 @@ test "decl access by string" {
7844 This type is suitable to be used as the return type of {#link|async|Async and Await#} which7941 This type is suitable to be used as the return type of {#link|async|Async and Await#} which
7845 allows one to, for example, heap-allocate an async function frame:7942 allows one to, for example, heap-allocate an async function frame:
7846 </p>7943 </p>
7847 {#code_begin|test#}7944 {#code_begin|test|heap_allocated_frame#}
7848const std = @import("std");7945const std = @import("std");
78497946
7850test "heap allocated frame" {7947test "heap allocated frame" {
...@@ -7890,7 +7987,7 @@ fn func() void {...@@ -7890,7 +7987,7 @@ fn func() void {
7890 Returns whether or not a {#link|struct#}, {#link|enum#}, or {#link|union#} has a declaration7987 Returns whether or not a {#link|struct#}, {#link|enum#}, or {#link|union#} has a declaration
7891 matching {#syntax#}name{#endsyntax#}.7988 matching {#syntax#}name{#endsyntax#}.
7892 </p>7989 </p>
7893 {#code_begin|test#}7990 {#code_begin|test|hasDecl#}
7894const std = @import("std");7991const std = @import("std");
7895const expect = std.testing.expect;7992const expect = std.testing.expect;
78967993
...@@ -8105,7 +8202,7 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>...@@ -8105,7 +8202,7 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
8105 designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use8202 designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use
8106 something like {#syntax#}@import("std").heap.WasmPageAllocator{#endsyntax#}.8203 something like {#syntax#}@import("std").heap.WasmPageAllocator{#endsyntax#}.
8107 </p>8204 </p>
8108 {#code_begin|test#}8205 {#code_begin|test|wasmMemoryGrow#}
8109const std = @import("std");8206const std = @import("std");
8110const native_arch = @import("builtin").target.cpu.arch;8207const native_arch = @import("builtin").target.cpu.arch;
8111const expect = std.testing.expect;8208const expect = std.testing.expect;
...@@ -8143,6 +8240,22 @@ test "@wasmMemoryGrow" {...@@ -8143,6 +8240,22 @@ test "@wasmMemoryGrow" {
8143 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.8240 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
8144 </p>8241 </p>
8145 {#header_close#}8242 {#header_close#}
8243
8244 {#header_open|@mulWithSaturation#}
8245 <pre>{#syntax#}@mulWithSaturation(a: T, b: T) T{#endsyntax#}</pre>
8246 <p>
8247 Returns {#syntax#}a * b{#endsyntax#}. The result will be clamped between the type maximum and minimum.
8248 </p>
8249 <p>
8250 Once <a href="https://github.com/ziglang/zig/issues/1284">Saturating arithmetic</a>.
8251 is completed, the syntax {#syntax#}a *| b{#endsyntax#} will be equivalent to calling {#syntax#}@mulWithSaturation(a, b){#endsyntax#}.
8252 </p>
8253 <p>
8254 NOTE: Currently there is a bug in the llvm.smul.fix.sat intrinsic which affects {#syntax#}@mulWithSaturation{#endsyntax#} of signed integers.
8255 This may result in an incorrect sign bit when there is overflow. This will be fixed in zig's 0.9.0 release.
8256 Check <a href="https://github.com/ziglang/zig/issues/9643">this issue</a> for more information.
8257 </p>
8258 {#header_close#}
81468259
8147 {#header_open|@panic#}8260 {#header_open|@panic#}
8148 <pre>{#syntax#}@panic(message: []const u8) noreturn{#endsyntax#}</pre>8261 <pre>{#syntax#}@panic(message: []const u8) noreturn{#endsyntax#}</pre>
...@@ -8276,7 +8389,7 @@ test "foo" {...@@ -8276,7 +8389,7 @@ test "foo" {
8276}8389}
8277 {#code_end#}8390 {#code_end#}
8278 <p>Now we use {#syntax#}@setEvalBranchQuota{#endsyntax#}:</p>8391 <p>Now we use {#syntax#}@setEvalBranchQuota{#endsyntax#}:</p>
8279 {#code_begin|test#}8392 {#code_begin|test|setEvalBranchQuota#}
8280test "foo" {8393test "foo" {
8281 comptime {8394 comptime {
8282 @setEvalBranchQuota(1001);8395 @setEvalBranchQuota(1001);
...@@ -8368,7 +8481,7 @@ test "@setRuntimeSafety" {...@@ -8368,7 +8481,7 @@ test "@setRuntimeSafety" {
8368 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits.8481 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits.
8369 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior.8482 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior.
8370 </p>8483 </p>
8371 {#see_also|@shrExact|@shlWithOverflow#}8484 {#see_also|@shrExact|@shlWithOverflow|@shlWithSaturation#}
8372 {#header_close#}8485 {#header_close#}
83738486
8374 {#header_open|@shlWithOverflow#}8487 {#header_open|@shlWithOverflow#}
...@@ -8382,7 +8495,22 @@ test "@setRuntimeSafety" {...@@ -8382,7 +8495,22 @@ test "@setRuntimeSafety" {
8382 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits.8495 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits.
8383 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior.8496 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior.
8384 </p>8497 </p>
8385 {#see_also|@shlExact|@shrExact#}8498 {#see_also|@shlExact|@shrExact|@shlWithSaturation#}
8499 {#header_close#}
8500
8501 {#header_open|@shlWithSaturation#}
8502 <pre>{#syntax#}@shlWithSaturation(a: T, shift_amt: T) T{#endsyntax#}</pre>
8503 <p>
8504 Returns {#syntax#}a << b{#endsyntax#}. The result will be clamped between type minimum and maximum.
8505 </p>
8506 <p>
8507 Once <a href="https://github.com/ziglang/zig/issues/1284">Saturating arithmetic</a>.
8508 is completed, the syntax {#syntax#}a <<| b{#endsyntax#} will be equivalent to calling {#syntax#}@shlWithSaturation(a, b){#endsyntax#}.
8509 </p>
8510 <p>
8511 Unlike other @shl builtins, shift_amt doesn't need to be a Log2T as saturated overshifting is well defined.
8512 </p>
8513 {#see_also|@shlExact|@shrExact|@shlWithOverflow#}
8386 {#header_close#}8514 {#header_close#}
83878515
8388 {#header_open|@shrExact#}8516 {#header_open|@shrExact#}
...@@ -8395,7 +8523,7 @@ test "@setRuntimeSafety" {...@@ -8395,7 +8523,7 @@ test "@setRuntimeSafety" {
8395 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits.8523 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits.
8396 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior.8524 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior.
8397 </p>8525 </p>
8398 {#see_also|@shlExact|@shlWithOverflow#}8526 {#see_also|@shlExact|@shlWithOverflow|@shlWithSaturation#}
8399 {#header_close#}8527 {#header_close#}
84008528
8401 {#header_open|@shuffle#}8529 {#header_open|@shuffle#}
...@@ -8460,7 +8588,7 @@ test "@setRuntimeSafety" {...@@ -8460,7 +8588,7 @@ test "@setRuntimeSafety" {
8460 Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value8588 Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value
8461 {#syntax#}scalar{#endsyntax#}:8589 {#syntax#}scalar{#endsyntax#}:
8462 </p>8590 </p>
8463 {#code_begin|test#}8591 {#code_begin|test|vector_splat#}
8464const std = @import("std");8592const std = @import("std");
8465const expect = std.testing.expect;8593const expect = std.testing.expect;
84668594
...@@ -8494,7 +8622,7 @@ test "vector @splat" {...@@ -8494,7 +8622,7 @@ test "vector @splat" {
8494 <li>{#syntax#}.Min{#endsyntax#}, {#syntax#}.Max{#endsyntax#},8622 <li>{#syntax#}.Min{#endsyntax#}, {#syntax#}.Max{#endsyntax#},
8495 {#syntax#}.Add{#endsyntax#}, {#syntax#}.Mul{#endsyntax#} are8623 {#syntax#}.Add{#endsyntax#}, {#syntax#}.Mul{#endsyntax#} are
8496 available for {#link|floating point|Floats#} vectors,</li>8624 available for {#link|floating point|Floats#} vectors,</li>
8497 <li>Every operator is available for {#link|integer|Integers#} vectors.8625 <li>Every operator is available for {#link|integer|Integers#} vectors.</li>
8498 </ul>8626 </ul>
8499 <p>8627 <p>
8500 Note that {#syntax#}.Add{#endsyntax#} and {#syntax#}.Mul{#endsyntax#}8628 Note that {#syntax#}.Add{#endsyntax#} and {#syntax#}.Mul{#endsyntax#}
...@@ -8502,7 +8630,7 @@ test "vector @splat" {...@@ -8502,7 +8630,7 @@ test "vector @splat" {
8502 types the operation associativity is preserved, unless the float mode is8630 types the operation associativity is preserved, unless the float mode is
8503 set to {#syntax#}Optimized{#endsyntax#}.8631 set to {#syntax#}Optimized{#endsyntax#}.
8504 </p>8632 </p>
8505 {#code_begin|test#}8633 {#code_begin|test|vector_reduce#}
8506const std = @import("std");8634const std = @import("std");
8507const expect = std.testing.expect;8635const expect = std.testing.expect;
85088636
...@@ -8524,7 +8652,7 @@ test "vector @reduce" {...@@ -8524,7 +8652,7 @@ test "vector @reduce" {
8524 <p>8652 <p>
8525 Returns a {#syntax#}SourceLocation{#endsyntax#} struct representing the function's name and location in the source code. This must be called in a function.8653 Returns a {#syntax#}SourceLocation{#endsyntax#} struct representing the function's name and location in the source code. This must be called in a function.
8526 </p>8654 </p>
8527 {#code_begin|test#}8655 {#code_begin|test|source_location#}
8528const std = @import("std");8656const std = @import("std");
8529const expect = std.testing.expect;8657const expect = std.testing.expect;
85308658
...@@ -8538,7 +8666,7 @@ fn doTheTest() !void {...@@ -8538,7 +8666,7 @@ fn doTheTest() !void {
8538 try expect(src.line == 9);8666 try expect(src.line == 9);
8539 try expect(src.column == 17);8667 try expect(src.column == 17);
8540 try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));8668 try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));
8541 try expect(std.mem.endsWith(u8, src.file, "test.zig"));8669 try expect(std.mem.endsWith(u8, src.file, "source_location.zig"));
8542}8670}
8543 {#code_end#}8671 {#code_end#}
8544 {#header_close#}8672 {#header_close#}
...@@ -8694,6 +8822,17 @@ fn doTheTest() !void {...@@ -8694,6 +8822,17 @@ fn doTheTest() !void {
8694 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.8822 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
8695 </p>8823 </p>
8696 {#header_close#}8824 {#header_close#}
8825
8826 {#header_open|@subWithSaturation#}
8827 <pre>{#syntax#}@subWithSaturation(a: T, b: T) T{#endsyntax#}</pre>
8828 <p>
8829 Returns {#syntax#}a - b{#endsyntax#}. The result will be clamped between the type maximum and minimum.
8830 </p>
8831 <p>
8832 Once <a href="https://github.com/ziglang/zig/issues/1284">Saturating arithmetic</a>.
8833 is completed, the syntax {#syntax#}a -| b{#endsyntax#} will be equivalent to calling {#syntax#}@subWithSaturation(a, b){#endsyntax#}.
8834 </p>
8835 {#header_close#}
86978836
8698 {#header_open|@tagName#}8837 {#header_open|@tagName#}
8699 <pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>8838 <pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>
...@@ -8708,7 +8847,7 @@ fn doTheTest() !void {...@@ -8708,7 +8847,7 @@ fn doTheTest() !void {
8708 Returns the innermost struct, enum, or union that this function call is inside.8847 Returns the innermost struct, enum, or union that this function call is inside.
8709 This can be useful for an anonymous struct that needs to refer to itself:8848 This can be useful for an anonymous struct that needs to refer to itself:
8710 </p>8849 </p>
8711 {#code_begin|test#}8850 {#code_begin|test|this_innermost#}
8712const std = @import("std");8851const std = @import("std");
8713const expect = std.testing.expect;8852const expect = std.testing.expect;
87148853
...@@ -8843,7 +8982,7 @@ test "integer truncation" {...@@ -8843,7 +8982,7 @@ test "integer truncation" {
8843 <p>8982 <p>
8844 The expressions are evaluated, however they are guaranteed to have no <em>runtime</em> side-effects:8983 The expressions are evaluated, however they are guaranteed to have no <em>runtime</em> side-effects:
8845 </p>8984 </p>
8846 {#code_begin|test#}8985 {#code_begin|test|no_runtime_side_effects#}
8847const std = @import("std");8986const std = @import("std");
8848const expect = std.testing.expect;8987const expect = std.testing.expect;
88498988
...@@ -8884,9 +9023,9 @@ fn foo(comptime T: type, ptr: *T) T {...@@ -8884,9 +9023,9 @@ fn foo(comptime T: type, ptr: *T) T {
8884 <li>{#link|ReleaseSmall#}</li>9023 <li>{#link|ReleaseSmall#}</li>
8885 </ul>9024 </ul>
8886 <p>9025 <p>
8887 To add standard build options to a <code>build.zig</code> file:9026 To add standard build options to a <code class="file">build.zig</code> file:
8888 </p>9027 </p>
8889 {#code_begin|syntax#}9028 {#code_begin|syntax|build#}
8890const Builder = @import("std").build.Builder;9029const Builder = @import("std").build.Builder;
88919030
8892pub fn build(b: *Builder) void {9031pub fn build(b: *Builder) void {
...@@ -8898,11 +9037,13 @@ pub fn build(b: *Builder) void {...@@ -8898,11 +9037,13 @@ pub fn build(b: *Builder) void {
8898 <p>9037 <p>
8899 This causes these options to be available:9038 This causes these options to be available:
8900 </p>9039 </p>
8901 <pre><code class="shell"> -Drelease-safe=[bool] optimizations on and safety on9040 <dl>
8902 -Drelease-fast=[bool] optimizations on and safety off9041 <dt><kbd>-Drelease-safe=[bool]</kbd></dt><dd>Optimizations on and safety on</dd>
8903 -Drelease-small=[bool] size optimizations on and safety off</code></pre>9042 <dt><kbd>-Drelease-fast=[bool]</kbd></dt><dd>Optimizations on and safety off</dd>
9043 <dt><kbd>-Drelease-small=[bool]</kbd></dt><dd>Size optimizations on and safety off</dd>
9044 </dl>
8904 {#header_open|Debug#}9045 {#header_open|Debug#}
8905 <pre><code class="shell">$ zig build-exe example.zig</code></pre>9046 {#shell_samp#}$ zig build-exe example.zig{#end_shell_samp#}
8906 <ul>9047 <ul>
8907 <li>Fast compilation speed</li>9048 <li>Fast compilation speed</li>
8908 <li>Safety checks enabled</li>9049 <li>Safety checks enabled</li>
...@@ -8912,7 +9053,7 @@ pub fn build(b: *Builder) void {...@@ -8912,7 +9053,7 @@ pub fn build(b: *Builder) void {
8912 </ul>9053 </ul>
8913 {#header_close#}9054 {#header_close#}
8914 {#header_open|ReleaseFast#}9055 {#header_open|ReleaseFast#}
8915 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseFast</code></pre>9056 {#shell_samp#}$ zig build-exe example.zig -O ReleaseFast{#end_shell_samp#}
8916 <ul>9057 <ul>
8917 <li>Fast runtime performance</li>9058 <li>Fast runtime performance</li>
8918 <li>Safety checks disabled</li>9059 <li>Safety checks disabled</li>
...@@ -8922,7 +9063,7 @@ pub fn build(b: *Builder) void {...@@ -8922,7 +9063,7 @@ pub fn build(b: *Builder) void {
8922 </ul>9063 </ul>
8923 {#header_close#}9064 {#header_close#}
8924 {#header_open|ReleaseSafe#}9065 {#header_open|ReleaseSafe#}
8925 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseSafe</code></pre>9066 {#shell_samp#}$ zig build-exe example.zig -O ReleaseSafe{#end_shell_samp#}
8926 <ul>9067 <ul>
8927 <li>Medium runtime performance</li>9068 <li>Medium runtime performance</li>
8928 <li>Safety checks enabled</li>9069 <li>Safety checks enabled</li>
...@@ -8932,7 +9073,7 @@ pub fn build(b: *Builder) void {...@@ -8932,7 +9073,7 @@ pub fn build(b: *Builder) void {
8932 </ul>9073 </ul>
8933 {#header_close#}9074 {#header_close#}
8934 {#header_open|ReleaseSmall#}9075 {#header_open|ReleaseSmall#}
8935 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseSmall</code></pre>9076 {#shell_samp#}$ zig build-exe example.zig -O ReleaseSmall{#end_shell_samp#}
8936 <ul>9077 <ul>
8937 <li>Medium runtime performance</li>9078 <li>Medium runtime performance</li>
8938 <li>Safety checks disabled</li>9079 <li>Safety checks disabled</li>
...@@ -8945,7 +9086,7 @@ pub fn build(b: *Builder) void {...@@ -8945,7 +9086,7 @@ pub fn build(b: *Builder) void {
8945 {#header_close#}9086 {#header_close#}
89469087
8947 {#header_open|Single Threaded Builds#}9088 {#header_open|Single Threaded Builds#}
8948 <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p>9089 <p>Zig has a compile option <kbd>--single-threaded</kbd> which has the following effects:</p>
8949 <ul>9090 <ul>
8950 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>9091 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>
8951 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>9092 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>
...@@ -9156,7 +9297,7 @@ pub fn main() void {...@@ -9156,7 +9297,7 @@ pub fn main() void {
9156 <li>{#syntax#}-%{#endsyntax#} (wraparound negation)</li>9297 <li>{#syntax#}-%{#endsyntax#} (wraparound negation)</li>
9157 <li>{#syntax#}*%{#endsyntax#} (wraparound multiplication)</li>9298 <li>{#syntax#}*%{#endsyntax#} (wraparound multiplication)</li>
9158 </ul>9299 </ul>
9159 {#code_begin|test#}9300 {#code_begin|test|wraparound_semantics#}
9160const std = @import("std");9301const std = @import("std");
9161const expect = std.testing.expect;9302const expect = std.testing.expect;
9162const minInt = std.math.minInt;9303const minInt = std.math.minInt;
...@@ -9894,14 +10035,14 @@ const separator = if (builtin.os.tag == builtin.Os.windows) '\\' else '/';...@@ -9894,14 +10035,14 @@ const separator = if (builtin.os.tag == builtin.Os.windows) '\\' else '/';
9894 <li>Custom tasks.</li>10035 <li>Custom tasks.</li>
9895 </ul>10036 </ul>
9896 <p>10037 <p>
9897 To use the build system, run <code class="shell">zig build --help</code>10038 To use the build system, run <kbd>zig build --help</kbd>
9898 to see a command-line usage help menu. This will include project-specific10039 to see a command-line usage help menu. This will include project-specific
9899 options that were declared in the build.zig script.10040 options that were declared in the build.zig script.
9900 </p>10041 </p>
990110042
9902 {#header_open|Building an Executable#}10043 {#header_open|Building an Executable#}
9903 <p>This <code>build.zig</code> file is automatically generated10044 <p>This <code class="file">build.zig</code> file is automatically generated
9904 by <code>zig init-exe</code>.</p>10045 by <kbd>zig init-exe</kbd>.</p>
9905 {#code_begin|syntax|build#}10046 {#code_begin|syntax|build#}
9906const Builder = @import("std").build.Builder;10047const Builder = @import("std").build.Builder;
990710048
...@@ -9934,8 +10075,8 @@ pub fn build(b: *Builder) void {...@@ -9934,8 +10075,8 @@ pub fn build(b: *Builder) void {
9934 {#header_close#}10075 {#header_close#}
993510076
9936 {#header_open|Building a Library#}10077 {#header_open|Building a Library#}
9937 <p>This <code>build.zig</code> file is automatically generated10078 <p>This <code class="file">build.zig</code> file is automatically generated
9938 by <code>zig init-lib</code>.</p>10079 by <kbd>zig init-lib</kbd>.</p>
9939 {#code_begin|syntax|build#}10080 {#code_begin|syntax|build#}
9940const Builder = @import("std").build.Builder;10081const Builder = @import("std").build.Builder;
994110082
...@@ -9994,7 +10135,7 @@ lib.addCSourceFile("src/lib.c", &[_][]const u8{...@@ -9994,7 +10135,7 @@ lib.addCSourceFile("src/lib.c", &[_][]const u8{
9994 {#header_open|Import from C Header File#}10135 {#header_open|Import from C Header File#}
9995 <p>10136 <p>
9996 The {#syntax#}@cImport{#endsyntax#} builtin function can be used10137 The {#syntax#}@cImport{#endsyntax#} builtin function can be used
9997 to directly import symbols from .h files:10138 to directly import symbols from <code class="file">.h</code> files:
9998 </p>10139 </p>
9999 {#code_begin|exe#}10140 {#code_begin|exe#}
10000 {#link_libc#}10141 {#link_libc#}
...@@ -10010,7 +10151,7 @@ pub fn main() void {...@@ -10010,7 +10151,7 @@ pub fn main() void {
10010 <p>10151 <p>
10011 The {#syntax#}@cImport{#endsyntax#} function takes an expression as a parameter.10152 The {#syntax#}@cImport{#endsyntax#} function takes an expression as a parameter.
10012 This expression is evaluated at compile-time and is used to control10153 This expression is evaluated at compile-time and is used to control
10013 preprocessor directives and include multiple .h files:10154 preprocessor directives and include multiple <code class="file">.h</code> files:
10014 </p>10155 </p>
10015 {#code_begin|syntax#}10156 {#code_begin|syntax#}
10016const builtin = @import("builtin");10157const builtin = @import("builtin");
...@@ -10031,66 +10172,65 @@ const c = @cImport({...@@ -10031,66 +10172,65 @@ const c = @cImport({
10031 {#header_close#}10172 {#header_close#}
1003210173
10033 {#header_open|C Translation CLI#}10174 {#header_open|C Translation CLI#}
10034 Zig's C translation capability is available as a CLI tool via <code class="shell">zig translate-c</code>.10175 Zig's C translation capability is available as a CLI tool via <kbd>zig translate-c</kbd>.
10035 It requires a single filename as an argument. It may also take a set of optional flags that are10176 It requires a single filename as an argument. It may also take a set of optional flags that are
10036 forwarded to clang. It writes the translated file to stdout.10177 forwarded to clang. It writes the translated file to stdout.
10037 {#header_open|Command line flags#}10178 {#header_open|Command line flags#}
10038 <ul>10179 <ul>
10039 <li>10180 <li>
10040 <code class="shell">-I</code>:10181 <kbd>-I</kbd>:
10041 Specify a search directory for include files. May be used multiple times. Equivalent to10182 Specify a search directory for include files. May be used multiple times. Equivalent to
10042 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-i-dir">10183 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-i-dir">
10043 clang's <code>-I</code> flag</a>. The current directory is <em>not</em> included by default;10184 clang's <kbd>-I</kbd> flag</a>. The current directory is <em>not</em> included by default;
10044 use <code>-I.</code> to include it.10185 use <kbd>-I.</kbd> to include it.
10045 </li>10186 </li>
10046 <li>10187 <li>
10047 <code class="shell">-D</code>: Define a preprocessor macro. Equivalent to10188 <kbd>-D</kbd>: Define a preprocessor macro. Equivalent to
10048 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-d-macro">10189 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-d-macro">
10049 clang's <code>-D</code> flag</a>.10190 clang's <kbd>-D</kbd> flag</a>.
10050 </li>10191 </li>
10051 <li>10192 <li>
10052 <code class="shell">-cflags [flags] --</code>: Pass arbitrary additional10193 <kbd>-cflags [flags] --</kbd>: Pass arbitrary additional
10053 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html">command line10194 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html">command line
10054 flags</a> to clang. Note: the list of flags must end with <code>--</code>10195 flags</a> to clang. Note: the list of flags must end with <kbd>--</kbd>
10055 </li>10196 </li>
10056 <li>10197 <li>
10057 <code class="shell">-target</code>: The {#link|target triple|Targets#} for the translated Zig code.10198 <kbd>-target</kbd>: The {#link|target triple|Targets#} for the translated Zig code.
10058 If no target is specified, the current host target will be used.10199 If no target is specified, the current host target will be used.
10059 </li>10200 </li>
10060 </ul>10201 </ul>
10061 {#header_close#}10202 {#header_close#}
10062 {#header_open|Using -target and -cflags#}10203 {#header_open|Using -target and -cflags#}
10063 <p>10204 <p>
10064 <strong>Important!</strong> When translating C code with <code class="shell">zig translate-c</code>,10205 <strong>Important!</strong> When translating C code with <kbd>zig translate-c</kbd>,
10065 you <strong>must</strong> use the same <code>-target</code> triple that you will use when compiling10206 you <strong>must</strong> use the same <kbd>-target</kbd> triple that you will use when compiling
10066 the translated code. In addition, you <strong>must</strong> ensure that the <code>-cflags</code> used,10207 the translated code. In addition, you <strong>must</strong> ensure that the <kbd>-cflags</kbd> used,
10067 if any, match the cflags used by code on the target system. Using the incorrect <code>-target</code>10208 if any, match the cflags used by code on the target system. Using the incorrect <kbd>-target</kbd>
10068 or <code>-cflags</code> could result in clang or Zig parse failures, or subtle ABI incompatibilities10209 or <kbd>-cflags</kbd> could result in clang or Zig parse failures, or subtle ABI incompatibilities
10069 when linking with C code.10210 when linking with C code.
10070 </p>10211 </p>
10071 <p class="file">varytarget.h</p>10212 {#syntax_block|c|varytarget.h#}long FOO = __LONG_MAX__;{#end_syntax_block#}
10072 <pre><code class="c">long FOO = __LONG_MAX__;</code></pre>10213 {#shell_samp#}$ zig translate-c -target <em>thumb-freestanding-gnueabihf</em> varytarget.h|grep FOO
10073 <pre><code class="shell">$ zig translate-c -target <strong>thumb-freestanding-gnueabihf</strong> varytarget.h|grep FOO10214pub export var FOO: c_long = <em>2147483647</em>;
10074pub export var FOO: c_long = <strong>2147483647</strong>;</code></pre>10215$ zig translate-c -target <em>x86_64-macos-gnu</em> varytarget.h|grep FOO
10075 <pre><code class="shell">$ zig translate-c -target <strong>x86_64-macos-gnu</strong> varytarget.h|grep FOO10216pub export var FOO: c_long = <em>9223372036854775807</em>;{#end_shell_samp#}
10076pub export var FOO: c_long = <strong>9223372036854775807</strong>;</code></pre>10217 {#syntax_block|c|varycflags.h#}enum FOO { BAR };
10077 <p class="file">varycflags.h</p>10218int do_something(enum FOO foo);
10078 <pre><code class="c">enum FOO { BAR };10219 {#end_syntax_block#}
10079int do_something(enum FOO foo);</code></pre>10220 {#shell_samp#}$ zig translate-c varycflags.h|grep -B1 do_something
10080 <pre><code class="shell">$ zig translate-c varycflags.h|grep -B1 do_something10221pub const enum_FOO = <em>c_uint</em>;
10081pub const enum_FOO = <strong>c_uint</strong>;10222pub extern fn do_something(foo: enum_FOO) c_int;
10082pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>10223$ zig translate-c <em>-cflags -fshort-enums --</em> varycflags.h|grep -B1 do_something
10083 <pre><code class="shell">$ zig translate-c <strong>-cflags -fshort-enums --</strong> varycflags.h|grep -B1 do_something10224pub const enum_FOO = <em>u8</em>;
10084pub const enum_FOO = <strong>u8</strong>;10225pub extern fn do_something(foo: enum_FOO) c_int;{#end_shell_samp#}
10085pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>
10086 {#header_close#}10226 {#header_close#}
10087 {#header_open|@cImport vs translate-c#}10227 {#header_open|@cImport vs translate-c#}
10088 <p>{#syntax#}@cImport{#endsyntax#} and <code class="shell">zig translate-c</code> use the same underlying10228 <p>{#syntax#}@cImport{#endsyntax#} and <kbd>zig translate-c</kbd> use the same underlying
10089 C translation functionality, so on a technical level they are equivalent. In practice,10229 C translation functionality, so on a technical level they are equivalent. In practice,
10090 {#syntax#}@cImport{#endsyntax#} is useful as a way to quickly and easily access numeric constants, typedefs,10230 {#syntax#}@cImport{#endsyntax#} is useful as a way to quickly and easily access numeric constants, typedefs,
10091 and record types without needing any extra setup. If you need to pass {#link|cflags|Using -target and -cflags#}10231 and record types without needing any extra setup. If you need to pass {#link|cflags|Using -target and -cflags#}
10092 to clang, or if you would like to edit the translated code, it is recommended to use10232 to clang, or if you would like to edit the translated code, it is recommended to use
10093 <code class="shell">zig translate-c</code> and save the results to a file. Common reasons for editing10233 <kbd>zig translate-c</kbd> and save the results to a file. Common reasons for editing
10094 the generated code include: changing {#syntax#}anytype{#endsyntax#} parameters in function-like macros to more10234 the generated code include: changing {#syntax#}anytype{#endsyntax#} parameters in function-like macros to more
10095 specific types; changing {#syntax#}[*c]T{#endsyntax#} pointers to {#syntax#}[*]T{#endsyntax#} or10235 specific types; changing {#syntax#}[*c]T{#endsyntax#} pointers to {#syntax#}[*]T{#endsyntax#} or
10096 {#syntax#}*T{#endsyntax#} pointers for improved type safety; and10236 {#syntax#}*T{#endsyntax#} pointers for improved type safety; and
...@@ -10101,14 +10241,14 @@ pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>...@@ -10101,14 +10241,14 @@ pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>
10101 {#header_close#}10241 {#header_close#}
10102 {#header_open|C Translation Caching#}10242 {#header_open|C Translation Caching#}
10103 <p>10243 <p>
10104 The C translation feature (whether used via <code class="shell">zig translate-c</code> or10244 The C translation feature (whether used via <kbd>zig translate-c</kbd> or
10105 {#syntax#}@cImport{#endsyntax#}) integrates with the Zig caching system. Subsequent runs with10245 {#syntax#}@cImport{#endsyntax#}) integrates with the Zig caching system. Subsequent runs with
10106 the same source file, target, and cflags will use the cache instead of repeatedly translating10246 the same source file, target, and cflags will use the cache instead of repeatedly translating
10107 the same code.10247 the same code.
10108 </p>10248 </p>
10109 <p>10249 <p>
10110 To see where the cached files are stored when compiling code that uses {#syntax#}@cImport{#endsyntax#},10250 To see where the cached files are stored when compiling code that uses {#syntax#}@cImport{#endsyntax#},
10111 use the <code class="shell">--verbose-cimport</code> flag:10251 use the <kbd>--verbose-cimport</kbd> flag:
10112 </p>10252 </p>
10113 {#code_begin|exe|verbose#}10253 {#code_begin|exe|verbose#}
10114 {#link_libc#}10254 {#link_libc#}
...@@ -10122,10 +10262,10 @@ pub fn main() void {...@@ -10122,10 +10262,10 @@ pub fn main() void {
10122}10262}
10123 {#code_end#}10263 {#code_end#}
10124 <p>10264 <p>
10125 <code class="shell">cimport.h</code> contains the file to translate (constructed from calls to10265 <code class="file">cimport.h</code> contains the file to translate (constructed from calls to
10126 {#syntax#}@cInclude{#endsyntax#}, {#syntax#}@cDefine{#endsyntax#}, and {#syntax#}@cUndef{#endsyntax#}),10266 {#syntax#}@cInclude{#endsyntax#}, {#syntax#}@cDefine{#endsyntax#}, and {#syntax#}@cUndef{#endsyntax#}),
10127 <code class="shell">cimport.h.d</code> is the list of file dependencies, and10267 <code class="file">cimport.h.d</code> is the list of file dependencies, and
10128 <code class="shell">cimport.zig</code> contains the translated output.10268 <code class="file">cimport.zig</code> contains the translated output.
10129 </p>10269 </p>
10130 {#see_also|Import from C Header File|C Translation CLI|@cInclude|@cImport#}10270 {#see_also|Import from C Header File|C Translation CLI|@cInclude|@cImport#}
10131 {#header_close#}10271 {#header_close#}
...@@ -10165,22 +10305,22 @@ pub fn main() void {...@@ -10165,22 +10305,22 @@ pub fn main() void {
10165 Zig.10305 Zig.
10166 </p>10306 </p>
10167 <p>Consider the following example:</p>10307 <p>Consider the following example:</p>
10168 <p class="file">macro.c</p>10308 {#syntax_block|c|macro.c#}#define MAKELOCAL(NAME, INIT) int NAME = INIT
10169 <pre><code class="c">#define MAKELOCAL(NAME, INIT) int NAME = INIT
10170int foo(void) {10309int foo(void) {
10171 MAKELOCAL(a, 1);10310 MAKELOCAL(a, 1);
10172 MAKELOCAL(b, 2);10311 MAKELOCAL(b, 2);
10173 return a + b;10312 return a + b;
10174}</code></pre>10313}
10175<pre><code class="shell">$ zig translate-c macro.c > macro.zig10314 {#end_syntax_block#}
10176</code></pre>10315 {#shell_samp#}$ zig translate-c macro.c > macro.zig{#end_shell_samp#}
10177 <p class="file">macro.zig</p>10316 {#code_begin|syntax|macro#}
10178 <pre>{#syntax#}pub export fn foo() c_int {10317pub export fn foo() c_int {
10179 var a: c_int = 1;10318 var a: c_int = 1;
10180 var b: c_int = 2;10319 var b: c_int = 2;
10181 return a + b;10320 return a + b;
10182}10321}
10183pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected token .Equal"); // macro.c:1:9{#endsyntax#}</pre>10322pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected token .Equal"); // macro.c:1:9
10323 {#code_end#}
10184 <p>Note that {#syntax#}foo{#endsyntax#} was translated correctly despite using a non-translateable10324 <p>Note that {#syntax#}foo{#endsyntax#} was translated correctly despite using a non-translateable
10185 macro. {#syntax#}MAKELOCAL{#endsyntax#} was demoted to {#syntax#}@compileError{#endsyntax#} since10325 macro. {#syntax#}MAKELOCAL{#endsyntax#} was demoted to {#syntax#}@compileError{#endsyntax#} since
10186 it cannot be expressed as a Zig function; this simply means that you cannot directly use10326 it cannot be expressed as a Zig function; this simply means that you cannot directly use
...@@ -10231,31 +10371,27 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke...@@ -10231,31 +10371,27 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke
10231 to call into. The {#syntax#}export{#endsyntax#} keyword in front of functions, variables, and types causes them to10371 to call into. The {#syntax#}export{#endsyntax#} keyword in front of functions, variables, and types causes them to
10232 be part of the library API:10372 be part of the library API:
10233 </p>10373 </p>
10234 <p class="file">mathtest.zig</p>10374 {#code_begin|syntax|mathtest#}
10235 {#code_begin|syntax#}
10236export fn add(a: i32, b: i32) i32 {10375export fn add(a: i32, b: i32) i32 {
10237 return a + b;10376 return a + b;
10238}10377}
10239 {#code_end#}10378 {#code_end#}
10240 <p>To make a static library:</p>10379 <p>To make a static library:</p>
10241 <pre><code class="shell">$ zig build-lib mathtest.zig10380 {#shell_samp#}$ zig build-lib mathtest.zig{#end_shell_samp#}
10242</code></pre>
10243 <p>To make a shared library:</p>10381 <p>To make a shared library:</p>
10244 <pre><code class="shell">$ zig build-lib mathtest.zig -dynamic10382 {#shell_samp#}$ zig build-lib mathtest.zig -dynamic{#end_shell_samp#}
10245</code></pre>
10246 <p>Here is an example with the {#link|Zig Build System#}:</p>10383 <p>Here is an example with the {#link|Zig Build System#}:</p>
10247 <p class="file">test.c</p>10384 {#syntax_block|c|test.c#}// This header is generated by zig from mathtest.zig
10248 <pre><code class="cpp">// This header is generated by zig from mathtest.zig
10249#include "mathtest.h"10385#include "mathtest.h"
10250#include &lt;stdio.h&gt;10386#include <stdio.h>
1025110387
10252int main(int argc, char **argv) {10388int main(int argc, char **argv) {
10253 int32_t result = add(42, 1337);10389 int32_t result = add(42, 1337);
10254 printf("%d\n", result);10390 printf("%d\n", result);
10255 return 0;10391 return 0;
10256}</code></pre>10392}
10257 <p class="file">build.zig</p>10393 {#end_syntax_block#}
10258 {#code_begin|syntax#}10394 {#code_begin|syntax|build#}
10259const Builder = @import("std").build.Builder;10395const Builder = @import("std").build.Builder;
1026010396
10261pub fn build(b: *Builder) void {10397pub fn build(b: *Builder) void {
...@@ -10274,18 +10410,15 @@ pub fn build(b: *Builder) void {...@@ -10274,18 +10410,15 @@ pub fn build(b: *Builder) void {
10274 test_step.dependOn(&run_cmd.step);10410 test_step.dependOn(&run_cmd.step);
10275}10411}
10276 {#code_end#}10412 {#code_end#}
10277 <p class="file">terminal</p>10413 {#shell_samp#}$ zig build test
10278 <pre><code class="shell">$ zig build test104141379{#end_shell_samp#}
102791379
10280</code></pre>
10281 {#see_also|export#}10415 {#see_also|export#}
10282 {#header_close#}10416 {#header_close#}
10283 {#header_open|Mixing Object Files#}10417 {#header_open|Mixing Object Files#}
10284 <p>10418 <p>
10285 You can mix Zig object files with any other object files that respect the C ABI. Example:10419 You can mix Zig object files with any other object files that respect the C ABI. Example:
10286 </p>10420 </p>
10287 <p class="file">base64.zig</p>10421 {#code_begin|syntax|base64#}
10288 {#code_begin|syntax#}
10289const base64 = @import("std").base64;10422const base64 = @import("std").base64;
1029010423
10291export fn decode_base_64(10424export fn decode_base_64(
...@@ -10302,12 +10435,11 @@ export fn decode_base_64(...@@ -10302,12 +10435,11 @@ export fn decode_base_64(
10302 return decoded_size;10435 return decoded_size;
10303}10436}
10304 {#code_end#}10437 {#code_end#}
10305 <p class="file">test.c</p>10438 {#syntax_block|c|test.c#}// This header is generated by zig from base64.zig
10306 <pre><code class="cpp">// This header is generated by zig from base64.zig
10307#include "base64.h"10439#include "base64.h"
1030810440
10309#include &lt;string.h&gt;10441#include <string.h>
10310#include &lt;stdio.h&gt;10442#include <stdio.h>
1031110443
10312int main(int argc, char **argv) {10444int main(int argc, char **argv) {
10313 const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz";10445 const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz";
...@@ -10318,9 +10450,9 @@ int main(int argc, char **argv) {...@@ -10318,9 +10450,9 @@ int main(int argc, char **argv) {
10318 puts(buf);10450 puts(buf);
1031910451
10320 return 0;10452 return 0;
10321}</code></pre>10453}
10322 <p class="file">build.zig</p>10454 {#end_syntax_block#}
10323 {#code_begin|syntax#}10455 {#code_begin|syntax|build#}
10324const Builder = @import("std").build.Builder;10456const Builder = @import("std").build.Builder;
1032510457
10326pub fn build(b: *Builder) void {10458pub fn build(b: *Builder) void {
...@@ -10333,10 +10465,9 @@ pub fn build(b: *Builder) void {...@@ -10333,10 +10465,9 @@ pub fn build(b: *Builder) void {
10333 exe.install();10465 exe.install();
10334}10466}
10335 {#code_end#}10467 {#code_end#}
10336 <p class="file">terminal</p>10468 {#shell_samp#}$ zig build
10337 <pre><code class="shell">$ zig build
10338$ ./zig-out/bin/test10469$ ./zig-out/bin/test
10339all your base are belong to us</code></pre>10470all your base are belong to us{#end_shell_samp#}
10340 {#see_also|Targets|Zig Build System#}10471 {#see_also|Targets|Zig Build System#}
10341 {#header_close#}10472 {#header_close#}
10342 {#header_close#}10473 {#header_close#}
...@@ -10354,9 +10485,7 @@ export fn add(a: i32, b: i32) void {...@@ -10354,9 +10485,7 @@ export fn add(a: i32, b: i32) void {
10354 print(a + b);10485 print(a + b);
10355}10486}
10356 {#code_end#}10487 {#code_end#}
10357 {#header_close#}10488 {#syntax_block|javascript|test.js#}const fs = require('fs');
10358 <p class="file">test.js</p>
10359 <pre><code>const fs = require('fs');
10360const source = fs.readFileSync("./math.wasm");10489const source = fs.readFileSync("./math.wasm");
10361const typedArray = new Uint8Array(source);10490const typedArray = new Uint8Array(source);
1036210491
...@@ -10366,9 +10495,10 @@ WebAssembly.instantiate(typedArray, {...@@ -10366,9 +10495,10 @@ WebAssembly.instantiate(typedArray, {
10366 }}).then(result =&gt; {10495 }}).then(result =&gt; {
10367 const add = result.instance.exports.add;10496 const add = result.instance.exports.add;
10368 add(1, 2);10497 add(1, 2);
10369});</code></pre>10498});{#end_syntax_block#}
10370 <pre><code>$ node test.js10499 {#shell_samp#}$ node test.js
10371The result is 3</code></pre>10500The result is 3{#end_shell_samp#}
10501 {#header_close#}
10372 {#header_open|WASI#}10502 {#header_open|WASI#}
10373 <p>Zig's support for WebAssembly System Interface (WASI) is under active development.10503 <p>Zig's support for WebAssembly System Interface (WASI) is under active development.
10374 Example of using the standard library and reading command line arguments:</p>10504 Example of using the standard library and reading command line arguments:</p>
...@@ -10387,10 +10517,10 @@ pub fn main() !void {...@@ -10387,10 +10517,10 @@ pub fn main() !void {
10387 }10517 }
10388}10518}
10389 {#code_end#}10519 {#code_end#}
10390 <pre><code>$ wasmtime args.wasm 123 hello10520 {#shell_samp#}$ wasmtime args.wasm 123 hello
103910: args.wasm105210: args.wasm
103921: 123105221: 123
103932: hello</code></pre>105232: hello{#end_shell_samp#}
10394 <p>A more interesting example would be extracting the list of preopens from the runtime.10524 <p>A more interesting example would be extracting the list of preopens from the runtime.
10395 This is now supported in the standard library via {#syntax#}std.fs.wasi.PreopenList{#endsyntax#}:</p>10525 This is now supported in the standard library via {#syntax#}std.fs.wasi.PreopenList{#endsyntax#}:</p>
10396 {#code_begin|exe|preopens#}10526 {#code_begin|exe|preopens#}
...@@ -10412,9 +10542,9 @@ pub fn main() !void {...@@ -10412,9 +10542,9 @@ pub fn main() !void {
10412 }10542 }
10413}10543}
10414 {#code_end#}10544 {#code_end#}
10415 <pre><code>$ wasmtime --dir=. preopens.wasm10545 {#shell_samp#}$ wasmtime --dir=. preopens.wasm
104160: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } }105460: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } }
10417</code></pre>10547 {#end_shell_samp#}
10418 {#header_close#}10548 {#header_close#}
10419 {#header_close#}10549 {#header_close#}
10420 {#header_open|Targets#}10550 {#header_open|Targets#}
...@@ -10423,7 +10553,7 @@ pub fn main() !void {...@@ -10423,7 +10553,7 @@ pub fn main() !void {
10423 what it looks like to execute <code>zig targets</code> on a Linux x86_6410553 what it looks like to execute <code>zig targets</code> on a Linux x86_64
10424 computer:10554 computer:
10425 </p>10555 </p>
10426 <pre><code class="shell">$ zig targets10556 {#shell_samp#}$ zig targets
10427Architectures:10557Architectures:
10428 arm10558 arm
10429 v8_4a10559 v8_4a
...@@ -10660,7 +10790,7 @@ Available libcs:...@@ -10660,7 +10790,7 @@ Available libcs:
10660 wasm32-wasi-musl10790 wasm32-wasi-musl
10661 x86_64-linux-gnu10791 x86_64-linux-gnu
10662 x86_64-linux-gnux3210792 x86_64-linux-gnux32
10663 x86_64-linux-musl</code></pre>10793 x86_64-linux-musl{#end_shell_samp#}
10664 <p>10794 <p>
10665 The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating system10795 The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating system
10666 abstractions, and thus takes additional work to support more platforms.10796 abstractions, and thus takes additional work to support more platforms.
...@@ -10730,9 +10860,9 @@ coding style....@@ -10730,9 +10860,9 @@ coding style.
10730 <p>10860 <p>
10731 File names fall into two categories: types and namespaces. If the file10861 File names fall into two categories: types and namespaces. If the file
10732 (implicitly a struct) has top level fields, it should be named like any10862 (implicitly a struct) has top level fields, it should be named like any
10733 other struct with fields using {#syntax#}TitleCase{#endsyntax#}. Otherwise,10863 other struct with fields using <code class="file">TitleCase</code>. Otherwise,
10734 it should use {#syntax#}snake_case{#endsyntax#}. Directory names should be10864 it should use <code class="file">snake_case</code>. Directory names should be
10735 {#syntax#}snake_case{#endsyntax#}.10865 <code class="file">snake_case</code>.
10736 </p>10866 </p>
10737 <p>10867 <p>
10738 These are general rules of thumb; if it makes sense to do something different,10868 These are general rules of thumb; if it makes sense to do something different,
...@@ -10741,7 +10871,7 @@ coding style....@@ -10741,7 +10871,7 @@ coding style.
10741 </p>10871 </p>
10742 {#header_close#}10872 {#header_close#}
10743 {#header_open|Examples#}10873 {#header_open|Examples#}
10744 <pre>{#syntax#}10874 {#syntax_block|zig|style_example.zig#}
10745const namespace_name = @import("dir_name/file_name.zig");10875const namespace_name = @import("dir_name/file_name.zig");
10746const TypeName = @import("dir_name/TypeName.zig");10876const TypeName = @import("dir_name/TypeName.zig");
10747var global_var: i32 = undefined;10877var global_var: i32 = undefined;
...@@ -10785,9 +10915,9 @@ const XmlParser = struct {...@@ -10785,9 +10915,9 @@ const XmlParser = struct {
1078510915
10786// The initials BE (Big Endian) are just another word in Zig identifier names.10916// The initials BE (Big Endian) are just another word in Zig identifier names.
10787fn readU32Be() u32 {}10917fn readU32Be() u32 {}
10788 {#endsyntax#}</pre>10918 {#end_syntax_block#}
10789 <p>10919 <p>
10790 See the Zig Standard Library for more examples.10920 See the {#link|Zig Standard Library#} for more examples.
10791 </p>10921 </p>
10792 {#header_close#}10922 {#header_close#}
10793 {#header_open|Doc Comment Guidance#}10923 {#header_open|Doc Comment Guidance#}
...@@ -10822,7 +10952,7 @@ fn readU32Be() u32 {}...@@ -10822,7 +10952,7 @@ fn readU32Be() u32 {}
10822 but use of hard tabs is discouraged. See {#link|Grammar#}.10952 but use of hard tabs is discouraged. See {#link|Grammar#}.
10823 </p>10953 </p>
10824 <p>10954 <p>
10825 Note that running <code>zig fmt</code> on a source file will implement all recommendations mentioned here.10955 Note that running <kbd>zig fmt</kbd> on a source file will implement all recommendations mentioned here.
10826 Note also that the stage1 compiler does <a href="https://github.com/ziglang/zig/wiki/FAQ#why-does-zig-force-me-to-use-spaces-instead-of-tabs">not yet support CR or HT</a> control characters.10956 Note also that the stage1 compiler does <a href="https://github.com/ziglang/zig/wiki/FAQ#why-does-zig-force-me-to-use-spaces-instead-of-tabs">not yet support CR or HT</a> control characters.
10827 </p>10957 </p>
10828 <p>10958 <p>
...@@ -10840,18 +10970,18 @@ fn readU32Be() u32 {}...@@ -10840,18 +10970,18 @@ fn readU32Be() u32 {}
10840 {#header_open|Keyword Reference#}10970 {#header_open|Keyword Reference#}
10841 <div class="table-wrapper">10971 <div class="table-wrapper">
10842 <table>10972 <table>
10973 <caption>Keywords</caption>
10974 <thead>
10843 <tr>10975 <tr>
10844 <th>10976 <th scope="col">Keyword</th>
10845 Keyword10977 <th scope="col">Description</th>
10846 </th>
10847 <th>
10848 Description
10849 </th>
10850 </tr>10978 </tr>
10979 </thead>
10980 <tbody>
10851 <tr>10981 <tr>
10852 <td>10982 <th scope="row">
10853 <pre>{#syntax#}align{#endsyntax#}</pre>10983 <pre>{#syntax#}align{#endsyntax#}</pre>
10854 </td>10984 </th>
10855 <td>10985 <td>
10856 {#syntax#}align{#endsyntax#} can be used to specify the alignment of a pointer.10986 {#syntax#}align{#endsyntax#} can be used to specify the alignment of a pointer.
10857 It can also be used after a variable or function declaration to specify the alignment of pointers to that variable or function.10987 It can also be used after a variable or function declaration to specify the alignment of pointers to that variable or function.
...@@ -10861,9 +10991,9 @@ fn readU32Be() u32 {}...@@ -10861,9 +10991,9 @@ fn readU32Be() u32 {}
10861 </td>10991 </td>
10862 </tr>10992 </tr>
10863 <tr>10993 <tr>
10864 <td>10994 <th scope="row">
10865 <pre>{#syntax#}allowzero{#endsyntax#}</pre>10995 <pre>{#syntax#}allowzero{#endsyntax#}</pre>
10866 </td>10996 </th>
10867 <td>10997 <td>
10868 The pointer attribute {#syntax#}allowzero{#endsyntax#} allows a pointer to have address zero.10998 The pointer attribute {#syntax#}allowzero{#endsyntax#} allows a pointer to have address zero.
10869 <ul>10999 <ul>
...@@ -10872,9 +11002,9 @@ fn readU32Be() u32 {}...@@ -10872,9 +11002,9 @@ fn readU32Be() u32 {}
10872 </td>11002 </td>
10873 </tr>11003 </tr>
10874 <tr>11004 <tr>
10875 <td>11005 <th scope="row">
10876 <pre>{#syntax#}and{#endsyntax#}</pre>11006 <pre>{#syntax#}and{#endsyntax#}</pre>
10877 </td>11007 </th>
10878 <td>11008 <td>
10879 The boolean operator {#syntax#}and{#endsyntax#}.11009 The boolean operator {#syntax#}and{#endsyntax#}.
10880 <ul>11010 <ul>
...@@ -10883,9 +11013,9 @@ fn readU32Be() u32 {}...@@ -10883,9 +11013,9 @@ fn readU32Be() u32 {}
10883 </td>11013 </td>
10884 </tr>11014 </tr>
10885 <tr>11015 <tr>
10886 <td>11016 <th scope="row">
10887 <pre>{#syntax#}anyframe{#endsyntax#}</pre>11017 <pre>{#syntax#}anyframe{#endsyntax#}</pre>
10888 </td>11018 </th>
10889 <td>11019 <td>
10890 {#syntax#}anyframe{#endsyntax#} can be used as a type for variables which hold pointers to function frames.11020 {#syntax#}anyframe{#endsyntax#} can be used as a type for variables which hold pointers to function frames.
10891 <ul>11021 <ul>
...@@ -10894,9 +11024,9 @@ fn readU32Be() u32 {}...@@ -10894,9 +11024,9 @@ fn readU32Be() u32 {}
10894 </td>11024 </td>
10895 </tr>11025 </tr>
10896 <tr>11026 <tr>
10897 <td>11027 <th scope="row">
10898 <pre>{#syntax#}anytype{#endsyntax#}</pre>11028 <pre>{#syntax#}anytype{#endsyntax#}</pre>
10899 </td>11029 </th>
10900 <td>11030 <td>
10901 Function parameters and struct fields can be declared with {#syntax#}anytype{#endsyntax#} in place of the type.11031 Function parameters and struct fields can be declared with {#syntax#}anytype{#endsyntax#} in place of the type.
10902 The type will be inferred where the function is called or the struct is instantiated.11032 The type will be inferred where the function is called or the struct is instantiated.
...@@ -10906,9 +11036,9 @@ fn readU32Be() u32 {}...@@ -10906,9 +11036,9 @@ fn readU32Be() u32 {}
10906 </td>11036 </td>
10907 </tr>11037 </tr>
10908 <tr>11038 <tr>
10909 <td>11039 <th scope="row">
10910 <pre>{#syntax#}asm{#endsyntax#}</pre>11040 <pre>{#syntax#}asm{#endsyntax#}</pre>
10911 </td>11041 </th>
10912 <td>11042 <td>
10913 {#syntax#}asm{#endsyntax#} begins an inline assembly expression. This allows for directly controlling the machine code generated on compilation.11043 {#syntax#}asm{#endsyntax#} begins an inline assembly expression. This allows for directly controlling the machine code generated on compilation.
10914 <ul>11044 <ul>
...@@ -10917,9 +11047,9 @@ fn readU32Be() u32 {}...@@ -10917,9 +11047,9 @@ fn readU32Be() u32 {}
10917 </td>11047 </td>
10918 </tr>11048 </tr>
10919 <tr>11049 <tr>
10920 <td>11050 <th scope="row">
10921 <pre>{#syntax#}async{#endsyntax#}</pre>11051 <pre>{#syntax#}async{#endsyntax#}</pre>
10922 </td>11052 </th>
10923 <td>11053 <td>
10924 {#syntax#}async{#endsyntax#} can be used before a function call to get a pointer to the function's frame when it suspends.11054 {#syntax#}async{#endsyntax#} can be used before a function call to get a pointer to the function's frame when it suspends.
10925 <ul>11055 <ul>
...@@ -10928,9 +11058,9 @@ fn readU32Be() u32 {}...@@ -10928,9 +11058,9 @@ fn readU32Be() u32 {}
10928 </td>11058 </td>
10929 </tr>11059 </tr>
10930 <tr>11060 <tr>
10931 <td>11061 <th scope="row">
10932 <pre>{#syntax#}await{#endsyntax#}</pre>11062 <pre>{#syntax#}await{#endsyntax#}</pre>
10933 </td>11063 </th>
10934 <td>11064 <td>
10935 {#syntax#}await{#endsyntax#} can be used to suspend the current function until the frame provided after the {#syntax#}await{#endsyntax#} completes.11065 {#syntax#}await{#endsyntax#} can be used to suspend the current function until the frame provided after the {#syntax#}await{#endsyntax#} completes.
10936 {#syntax#}await{#endsyntax#} copies the value returned from the target function's frame to the caller.11066 {#syntax#}await{#endsyntax#} copies the value returned from the target function's frame to the caller.
...@@ -10940,9 +11070,9 @@ fn readU32Be() u32 {}...@@ -10940,9 +11070,9 @@ fn readU32Be() u32 {}
10940 </td>11070 </td>
10941 </tr>11071 </tr>
10942 <tr>11072 <tr>
10943 <td>11073 <th scope="row">
10944 <pre>{#syntax#}break{#endsyntax#}</pre>11074 <pre>{#syntax#}break{#endsyntax#}</pre>
10945 </td>11075 </th>
10946 <td>11076 <td>
10947 {#syntax#}break{#endsyntax#} can be used with a block label to return a value from the block.11077 {#syntax#}break{#endsyntax#} can be used with a block label to return a value from the block.
10948 It can also be used to exit a loop before iteration completes naturally.11078 It can also be used to exit a loop before iteration completes naturally.
...@@ -10952,9 +11082,9 @@ fn readU32Be() u32 {}...@@ -10952,9 +11082,9 @@ fn readU32Be() u32 {}
10952 </td>11082 </td>
10953 </tr>11083 </tr>
10954 <tr>11084 <tr>
10955 <td>11085 <th scope="row">
10956 <pre>{#syntax#}catch{#endsyntax#}</pre>11086 <pre>{#syntax#}catch{#endsyntax#}</pre>
10957 </td>11087 </th>
10958 <td>11088 <td>
10959 {#syntax#}catch{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to an error.11089 {#syntax#}catch{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to an error.
10960 The expression after the {#syntax#}catch{#endsyntax#} can optionally capture the error value.11090 The expression after the {#syntax#}catch{#endsyntax#} can optionally capture the error value.
...@@ -10964,9 +11094,9 @@ fn readU32Be() u32 {}...@@ -10964,9 +11094,9 @@ fn readU32Be() u32 {}
10964 </td>11094 </td>
10965 </tr>11095 </tr>
10966 <tr>11096 <tr>
10967 <td>11097 <th scope="row">
10968 <pre>{#syntax#}comptime{#endsyntax#}</pre>11098 <pre>{#syntax#}comptime{#endsyntax#}</pre>
10969 </td>11099 </th>
10970 <td>11100 <td>
10971 {#syntax#}comptime{#endsyntax#} before a declaration can be used to label variables or function parameters as known at compile time.11101 {#syntax#}comptime{#endsyntax#} before a declaration can be used to label variables or function parameters as known at compile time.
10972 It can also be used to guarantee an expression is run at compile time.11102 It can also be used to guarantee an expression is run at compile time.
...@@ -10976,9 +11106,9 @@ fn readU32Be() u32 {}...@@ -10976,9 +11106,9 @@ fn readU32Be() u32 {}
10976 </td>11106 </td>
10977 </tr>11107 </tr>
10978 <tr>11108 <tr>
10979 <td>11109 <th scope="row">
10980 <pre>{#syntax#}const{#endsyntax#}</pre>11110 <pre>{#syntax#}const{#endsyntax#}</pre>
10981 </td>11111 </th>
10982 <td>11112 <td>
10983 {#syntax#}const{#endsyntax#} declares a variable that can not be modified.11113 {#syntax#}const{#endsyntax#} declares a variable that can not be modified.
10984 Used as a pointer attribute, it denotes the value referenced by the pointer cannot be modified.11114 Used as a pointer attribute, it denotes the value referenced by the pointer cannot be modified.
...@@ -10988,9 +11118,9 @@ fn readU32Be() u32 {}...@@ -10988,9 +11118,9 @@ fn readU32Be() u32 {}
10988 </td>11118 </td>
10989 </tr>11119 </tr>
10990 <tr>11120 <tr>
10991 <td>11121 <th scope="row">
10992 <pre>{#syntax#}continue{#endsyntax#}</pre>11122 <pre>{#syntax#}continue{#endsyntax#}</pre>
10993 </td>11123 </th>
10994 <td>11124 <td>
10995 {#syntax#}continue{#endsyntax#} can be used in a loop to jump back to the beginning of the loop.11125 {#syntax#}continue{#endsyntax#} can be used in a loop to jump back to the beginning of the loop.
10996 <ul>11126 <ul>
...@@ -10999,9 +11129,9 @@ fn readU32Be() u32 {}...@@ -10999,9 +11129,9 @@ fn readU32Be() u32 {}
10999 </td>11129 </td>
11000 </tr>11130 </tr>
11001 <tr>11131 <tr>
11002 <td>11132 <th scope="row">
11003 <pre>{#syntax#}defer{#endsyntax#}</pre>11133 <pre>{#syntax#}defer{#endsyntax#}</pre>
11004 </td>11134 </th>
11005 <td>11135 <td>
11006 {#syntax#}defer{#endsyntax#} will execute an expression when control flow leaves the current block.11136 {#syntax#}defer{#endsyntax#} will execute an expression when control flow leaves the current block.
11007 <ul>11137 <ul>
...@@ -11010,9 +11140,9 @@ fn readU32Be() u32 {}...@@ -11010,9 +11140,9 @@ fn readU32Be() u32 {}
11010 </td>11140 </td>
11011 </tr>11141 </tr>
11012 <tr>11142 <tr>
11013 <td>11143 <th scope="row">
11014 <pre>{#syntax#}else{#endsyntax#}</pre>11144 <pre>{#syntax#}else{#endsyntax#}</pre>
11015 </td>11145 </th>
11016 <td>11146 <td>
11017 {#syntax#}else{#endsyntax#} can be used to provide an alternate branch for {#syntax#}if{#endsyntax#}, {#syntax#}switch{#endsyntax#},11147 {#syntax#}else{#endsyntax#} can be used to provide an alternate branch for {#syntax#}if{#endsyntax#}, {#syntax#}switch{#endsyntax#},
11018 {#syntax#}while{#endsyntax#}, and {#syntax#}for{#endsyntax#} expressions.11148 {#syntax#}while{#endsyntax#}, and {#syntax#}for{#endsyntax#} expressions.
...@@ -11025,9 +11155,9 @@ fn readU32Be() u32 {}...@@ -11025,9 +11155,9 @@ fn readU32Be() u32 {}
11025 </td>11155 </td>
11026 </tr>11156 </tr>
11027 <tr>11157 <tr>
11028 <td>11158 <th scope="row">
11029 <pre>{#syntax#}enum{#endsyntax#}</pre>11159 <pre>{#syntax#}enum{#endsyntax#}</pre>
11030 </td>11160 </th>
11031 <td>11161 <td>
11032 {#syntax#}enum{#endsyntax#} defines an enum type.11162 {#syntax#}enum{#endsyntax#} defines an enum type.
11033 <ul>11163 <ul>
...@@ -11036,9 +11166,9 @@ fn readU32Be() u32 {}...@@ -11036,9 +11166,9 @@ fn readU32Be() u32 {}
11036 </td>11166 </td>
11037 </tr>11167 </tr>
11038 <tr>11168 <tr>
11039 <td>11169 <th scope="row">
11040 <pre>{#syntax#}errdefer{#endsyntax#}</pre>11170 <pre>{#syntax#}errdefer{#endsyntax#}</pre>
11041 </td>11171 </th>
11042 <td>11172 <td>
11043 {#syntax#}errdefer{#endsyntax#} will execute an expression when control flow leaves the current block if the function returns an error.11173 {#syntax#}errdefer{#endsyntax#} will execute an expression when control flow leaves the current block if the function returns an error.
11044 <ul>11174 <ul>
...@@ -11047,9 +11177,9 @@ fn readU32Be() u32 {}...@@ -11047,9 +11177,9 @@ fn readU32Be() u32 {}
11047 </td>11177 </td>
11048 </tr>11178 </tr>
11049 <tr>11179 <tr>
11050 <td>11180 <th scope="row">
11051 <pre>{#syntax#}error{#endsyntax#}</pre>11181 <pre>{#syntax#}error{#endsyntax#}</pre>
11052 </td>11182 </th>
11053 <td>11183 <td>
11054 {#syntax#}error{#endsyntax#} defines an error type.11184 {#syntax#}error{#endsyntax#} defines an error type.
11055 <ul>11185 <ul>
...@@ -11058,9 +11188,9 @@ fn readU32Be() u32 {}...@@ -11058,9 +11188,9 @@ fn readU32Be() u32 {}
11058 </td>11188 </td>
11059 </tr>11189 </tr>
11060 <tr>11190 <tr>
11061 <td>11191 <th scope="row">
11062 <pre>{#syntax#}export{#endsyntax#}</pre>11192 <pre>{#syntax#}export{#endsyntax#}</pre>
11063 </td>11193 </th>
11064 <td>11194 <td>
11065 {#syntax#}export{#endsyntax#} makes a function or variable externally visible in the generated object file.11195 {#syntax#}export{#endsyntax#} makes a function or variable externally visible in the generated object file.
11066 Exported functions default to the C calling convention.11196 Exported functions default to the C calling convention.
...@@ -11070,9 +11200,9 @@ fn readU32Be() u32 {}...@@ -11070,9 +11200,9 @@ fn readU32Be() u32 {}
11070 </td>11200 </td>
11071 </tr>11201 </tr>
11072 <tr>11202 <tr>
11073 <td>11203 <th scope="row">
11074 <pre>{#syntax#}extern{#endsyntax#}</pre>11204 <pre>{#syntax#}extern{#endsyntax#}</pre>
11075 </td>11205 </th>
11076 <td>11206 <td>
11077 {#syntax#}extern{#endsyntax#} can be used to declare a function or variable that will be resolved at link time, when linking statically11207 {#syntax#}extern{#endsyntax#} can be used to declare a function or variable that will be resolved at link time, when linking statically
11078 or at runtime, when linking dynamically.11208 or at runtime, when linking dynamically.
...@@ -11082,9 +11212,9 @@ fn readU32Be() u32 {}...@@ -11082,9 +11212,9 @@ fn readU32Be() u32 {}
11082 </td>11212 </td>
11083 </tr>11213 </tr>
11084 <tr>11214 <tr>
11085 <td>11215 <th scope="row">
11086 <pre>{#syntax#}false{#endsyntax#}</pre>11216 <pre>{#syntax#}false{#endsyntax#}</pre>
11087 </td>11217 </th>
11088 <td>11218 <td>
11089 The boolean value {#syntax#}false{#endsyntax#}.11219 The boolean value {#syntax#}false{#endsyntax#}.
11090 <ul>11220 <ul>
...@@ -11093,9 +11223,9 @@ fn readU32Be() u32 {}...@@ -11093,9 +11223,9 @@ fn readU32Be() u32 {}
11093 </td>11223 </td>
11094 </tr>11224 </tr>
11095 <tr>11225 <tr>
11096 <td>11226 <th scope="row">
11097 <pre>{#syntax#}fn{#endsyntax#}</pre>11227 <pre>{#syntax#}fn{#endsyntax#}</pre>
11098 </td>11228 </th>
11099 <td>11229 <td>
11100 {#syntax#}fn{#endsyntax#} declares a function.11230 {#syntax#}fn{#endsyntax#} declares a function.
11101 <ul>11231 <ul>
...@@ -11104,9 +11234,9 @@ fn readU32Be() u32 {}...@@ -11104,9 +11234,9 @@ fn readU32Be() u32 {}
11104 </td>11234 </td>
11105 </tr>11235 </tr>
11106 <tr>11236 <tr>
11107 <td>11237 <th scope="row">
11108 <pre>{#syntax#}for{#endsyntax#}</pre>11238 <pre>{#syntax#}for{#endsyntax#}</pre>
11109 </td>11239 </th>
11110 <td>11240 <td>
11111 A {#syntax#}for{#endsyntax#} expression can be used to iterate over the elements of a slice, array, or tuple.11241 A {#syntax#}for{#endsyntax#} expression can be used to iterate over the elements of a slice, array, or tuple.
11112 <ul>11242 <ul>
...@@ -11115,9 +11245,9 @@ fn readU32Be() u32 {}...@@ -11115,9 +11245,9 @@ fn readU32Be() u32 {}
11115 </td>11245 </td>
11116 </tr>11246 </tr>
11117 <tr>11247 <tr>
11118 <td>11248 <th scope="row">
11119 <pre>{#syntax#}if{#endsyntax#}</pre>11249 <pre>{#syntax#}if{#endsyntax#}</pre>
11120 </td>11250 </th>
11121 <td>11251 <td>
11122 An {#syntax#}if{#endsyntax#} expression can test boolean expressions, optional values, or error unions.11252 An {#syntax#}if{#endsyntax#} expression can test boolean expressions, optional values, or error unions.
11123 For optional values or error unions, the if expression can capture the unwrapped value.11253 For optional values or error unions, the if expression can capture the unwrapped value.
...@@ -11127,9 +11257,9 @@ fn readU32Be() u32 {}...@@ -11127,9 +11257,9 @@ fn readU32Be() u32 {}
11127 </td>11257 </td>
11128 </tr>11258 </tr>
11129 <tr>11259 <tr>
11130 <td>11260 <th scope="row">
11131 <pre>{#syntax#}inline{#endsyntax#}</pre>11261 <pre>{#syntax#}inline{#endsyntax#}</pre>
11132 </td>11262 </th>
11133 <td>11263 <td>
11134 {#syntax#}inline{#endsyntax#} can be used to label a loop expression such that it will be unrolled at compile time.11264 {#syntax#}inline{#endsyntax#} can be used to label a loop expression such that it will be unrolled at compile time.
11135 It can also be used to force a function to be inlined at all call sites.11265 It can also be used to force a function to be inlined at all call sites.
...@@ -11139,9 +11269,9 @@ fn readU32Be() u32 {}...@@ -11139,9 +11269,9 @@ fn readU32Be() u32 {}
11139 </td>11269 </td>
11140 </tr>11270 </tr>
11141 <tr>11271 <tr>
11142 <td>11272 <th scope="row">
11143 <pre>{#syntax#}noalias{#endsyntax#}</pre>11273 <pre>{#syntax#}noalias{#endsyntax#}</pre>
11144 </td>11274 </th>
11145 <td>11275 <td>
11146 The {#syntax#}noalias{#endsyntax#} keyword.11276 The {#syntax#}noalias{#endsyntax#} keyword.
11147 <ul>11277 <ul>
...@@ -11150,9 +11280,9 @@ fn readU32Be() u32 {}...@@ -11150,9 +11280,9 @@ fn readU32Be() u32 {}
11150 </td>11280 </td>
11151 </tr>11281 </tr>
11152 <tr>11282 <tr>
11153 <td>11283 <th scope="row">
11154 <pre>{#syntax#}nosuspend{#endsyntax#}</pre>11284 <pre>{#syntax#}nosuspend{#endsyntax#}</pre>
11155 </td>11285 </th>
11156 <td>11286 <td>
11157 The {#syntax#}nosuspend{#endsyntax#} keyword can be used in front of a block, statement or expression, to mark a scope where no suspension points are reached.11287 The {#syntax#}nosuspend{#endsyntax#} keyword can be used in front of a block, statement or expression, to mark a scope where no suspension points are reached.
11158 In particular, inside a {#syntax#}nosuspend{#endsyntax#} scope:11288 In particular, inside a {#syntax#}nosuspend{#endsyntax#} scope:
...@@ -11168,9 +11298,9 @@ fn readU32Be() u32 {}...@@ -11168,9 +11298,9 @@ fn readU32Be() u32 {}
11168 </td>11298 </td>
11169 </tr>11299 </tr>
11170 <tr>11300 <tr>
11171 <td>11301 <th scope="row">
11172 <pre>{#syntax#}null{#endsyntax#}</pre>11302 <pre>{#syntax#}null{#endsyntax#}</pre>
11173 </td>11303 </th>
11174 <td>11304 <td>
11175 The optional value {#syntax#}null{#endsyntax#}.11305 The optional value {#syntax#}null{#endsyntax#}.
11176 <ul>11306 <ul>
...@@ -11179,9 +11309,9 @@ fn readU32Be() u32 {}...@@ -11179,9 +11309,9 @@ fn readU32Be() u32 {}
11179 </td>11309 </td>
11180 </tr>11310 </tr>
11181 <tr>11311 <tr>
11182 <td>11312 <th scope="row">
11183 <pre>{#syntax#}or{#endsyntax#}</pre>11313 <pre>{#syntax#}or{#endsyntax#}</pre>
11184 </td>11314 </th>
11185 <td>11315 <td>
11186 The boolean operator {#syntax#}or{#endsyntax#}.11316 The boolean operator {#syntax#}or{#endsyntax#}.
11187 <ul>11317 <ul>
...@@ -11190,9 +11320,9 @@ fn readU32Be() u32 {}...@@ -11190,9 +11320,9 @@ fn readU32Be() u32 {}
11190 </td>11320 </td>
11191 </tr>11321 </tr>
11192 <tr>11322 <tr>
11193 <td>11323 <th scope="row">
11194 <pre>{#syntax#}orelse{#endsyntax#}</pre>11324 <pre>{#syntax#}orelse{#endsyntax#}</pre>
11195 </td>11325 </th>
11196 <td>11326 <td>
11197 {#syntax#}orelse{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to null.11327 {#syntax#}orelse{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to null.
11198 <ul>11328 <ul>
...@@ -11201,9 +11331,9 @@ fn readU32Be() u32 {}...@@ -11201,9 +11331,9 @@ fn readU32Be() u32 {}
11201 </td>11331 </td>
11202 </tr>11332 </tr>
11203 <tr>11333 <tr>
11204 <td>11334 <th scope="row">
11205 <pre>{#syntax#}packed{#endsyntax#}</pre>11335 <pre>{#syntax#}packed{#endsyntax#}</pre>
11206 </td>11336 </th>
11207 <td>11337 <td>
11208 The {#syntax#}packed{#endsyntax#} keyword before a struct definition changes the struct's in-memory layout11338 The {#syntax#}packed{#endsyntax#} keyword before a struct definition changes the struct's in-memory layout
11209 to the guaranteed {#syntax#}packed{#endsyntax#} layout.11339 to the guaranteed {#syntax#}packed{#endsyntax#} layout.
...@@ -11213,9 +11343,9 @@ fn readU32Be() u32 {}...@@ -11213,9 +11343,9 @@ fn readU32Be() u32 {}
11213 </td>11343 </td>
11214 </tr>11344 </tr>
11215 <tr>11345 <tr>
11216 <td>11346 <th scope="row">
11217 <pre>{#syntax#}pub{#endsyntax#}</pre>11347 <pre>{#syntax#}pub{#endsyntax#}</pre>
11218 </td>11348 </th>
11219 <td>11349 <td>
11220 The {#syntax#}pub{#endsyntax#} in front of a top level declaration makes the declaration available11350 The {#syntax#}pub{#endsyntax#} in front of a top level declaration makes the declaration available
11221 to reference from a different file than the one it is declared in.11351 to reference from a different file than the one it is declared in.
...@@ -11225,9 +11355,9 @@ fn readU32Be() u32 {}...@@ -11225,9 +11355,9 @@ fn readU32Be() u32 {}
11225 </td>11355 </td>
11226 </tr>11356 </tr>
11227 <tr>11357 <tr>
11228 <td>11358 <th scope="row">
11229 <pre>{#syntax#}resume{#endsyntax#}</pre>11359 <pre>{#syntax#}resume{#endsyntax#}</pre>
11230 </td>11360 </th>
11231 <td>11361 <td>
11232 {#syntax#}resume{#endsyntax#} will continue execution of a function frame after the point the function was suspended.11362 {#syntax#}resume{#endsyntax#} will continue execution of a function frame after the point the function was suspended.
11233 <ul>11363 <ul>
...@@ -11236,9 +11366,9 @@ fn readU32Be() u32 {}...@@ -11236,9 +11366,9 @@ fn readU32Be() u32 {}
11236 </td>11366 </td>
11237 </tr>11367 </tr>
11238 <tr>11368 <tr>
11239 <td>11369 <th scope="row">
11240 <pre>{#syntax#}return{#endsyntax#}</pre>11370 <pre>{#syntax#}return{#endsyntax#}</pre>
11241 </td>11371 </th>
11242 <td>11372 <td>
11243 {#syntax#}return{#endsyntax#} exits a function with a value.11373 {#syntax#}return{#endsyntax#} exits a function with a value.
11244 <ul>11374 <ul>
...@@ -11247,9 +11377,9 @@ fn readU32Be() u32 {}...@@ -11247,9 +11377,9 @@ fn readU32Be() u32 {}
11247 </td>11377 </td>
11248 </tr>11378 </tr>
11249 <tr>11379 <tr>
11250 <td>11380 <th scope="row">
11251 <pre>{#syntax#}linksection{#endsyntax#}</pre>11381 <pre>{#syntax#}linksection{#endsyntax#}</pre>
11252 </td>11382 </th>
11253 <td>11383 <td>
11254 The {#syntax#}linksection{#endsyntax#} keyword.11384 The {#syntax#}linksection{#endsyntax#} keyword.
11255 <ul>11385 <ul>
...@@ -11258,9 +11388,9 @@ fn readU32Be() u32 {}...@@ -11258,9 +11388,9 @@ fn readU32Be() u32 {}
11258 </td>11388 </td>
11259 </tr>11389 </tr>
11260 <tr>11390 <tr>
11261 <td>11391 <th scope="row">
11262 <pre>{#syntax#}struct{#endsyntax#}</pre>11392 <pre>{#syntax#}struct{#endsyntax#}</pre>
11263 </td>11393 </th>
11264 <td>11394 <td>
11265 {#syntax#}struct{#endsyntax#} defines a struct.11395 {#syntax#}struct{#endsyntax#} defines a struct.
11266 <ul>11396 <ul>
...@@ -11269,9 +11399,9 @@ fn readU32Be() u32 {}...@@ -11269,9 +11399,9 @@ fn readU32Be() u32 {}
11269 </td>11399 </td>
11270 </tr>11400 </tr>
11271 <tr>11401 <tr>
11272 <td>11402 <th scope="row">
11273 <pre>{#syntax#}suspend{#endsyntax#}</pre>11403 <pre>{#syntax#}suspend{#endsyntax#}</pre>
11274 </td>11404 </th>
11275 <td>11405 <td>
11276 {#syntax#}suspend{#endsyntax#} will cause control flow to return to the call site or resumer of the function.11406 {#syntax#}suspend{#endsyntax#} will cause control flow to return to the call site or resumer of the function.
11277 {#syntax#}suspend{#endsyntax#} can also be used before a block within a function,11407 {#syntax#}suspend{#endsyntax#} can also be used before a block within a function,
...@@ -11282,9 +11412,9 @@ fn readU32Be() u32 {}...@@ -11282,9 +11412,9 @@ fn readU32Be() u32 {}
11282 </td>11412 </td>
11283 </tr>11413 </tr>
11284 <tr>11414 <tr>
11285 <td>11415 <th scope="row">
11286 <pre>{#syntax#}switch{#endsyntax#}</pre>11416 <pre>{#syntax#}switch{#endsyntax#}</pre>
11287 </td>11417 </th>
11288 <td>11418 <td>
11289 A {#syntax#}switch{#endsyntax#} expression can be used to test values of a common type.11419 A {#syntax#}switch{#endsyntax#} expression can be used to test values of a common type.
11290 {#syntax#}switch{#endsyntax#} cases can capture field values of a {#link|Tagged union#}.11420 {#syntax#}switch{#endsyntax#} cases can capture field values of a {#link|Tagged union#}.
...@@ -11294,9 +11424,9 @@ fn readU32Be() u32 {}...@@ -11294,9 +11424,9 @@ fn readU32Be() u32 {}
11294 </td>11424 </td>
11295 </tr>11425 </tr>
11296 <tr>11426 <tr>
11297 <td>11427 <th scope="row">
11298 <pre>{#syntax#}test{#endsyntax#}</pre>11428 <pre>{#syntax#}test{#endsyntax#}</pre>
11299 </td>11429 </th>
11300 <td>11430 <td>
11301 The {#syntax#}test{#endsyntax#} keyword can be used to denote a top-level block of code11431 The {#syntax#}test{#endsyntax#} keyword can be used to denote a top-level block of code
11302 used to make sure behavior meets expectations.11432 used to make sure behavior meets expectations.
...@@ -11306,9 +11436,9 @@ fn readU32Be() u32 {}...@@ -11306,9 +11436,9 @@ fn readU32Be() u32 {}
11306 </td>11436 </td>
11307 </tr>11437 </tr>
11308 <tr>11438 <tr>
11309 <td>11439 <th scope="row">
11310 <pre>{#syntax#}threadlocal{#endsyntax#}</pre>11440 <pre>{#syntax#}threadlocal{#endsyntax#}</pre>
11311 </td>11441 </th>
11312 <td>11442 <td>
11313 {#syntax#}threadlocal{#endsyntax#} can be used to specify a variable as thread-local.11443 {#syntax#}threadlocal{#endsyntax#} can be used to specify a variable as thread-local.
11314 <ul>11444 <ul>
...@@ -11317,9 +11447,9 @@ fn readU32Be() u32 {}...@@ -11317,9 +11447,9 @@ fn readU32Be() u32 {}
11317 </td>11447 </td>
11318 </tr>11448 </tr>
11319 <tr>11449 <tr>
11320 <td>11450 <th scope="row">
11321 <pre>{#syntax#}true{#endsyntax#}</pre>11451 <pre>{#syntax#}true{#endsyntax#}</pre>
11322 </td>11452 </th>
11323 <td>11453 <td>
11324 The boolean value {#syntax#}true{#endsyntax#}.11454 The boolean value {#syntax#}true{#endsyntax#}.
11325 <ul>11455 <ul>
...@@ -11328,9 +11458,9 @@ fn readU32Be() u32 {}...@@ -11328,9 +11458,9 @@ fn readU32Be() u32 {}
11328 </td>11458 </td>
11329 </tr>11459 </tr>
11330 <tr>11460 <tr>
11331 <td>11461 <th scope="row">
11332 <pre>{#syntax#}try{#endsyntax#}</pre>11462 <pre>{#syntax#}try{#endsyntax#}</pre>
11333 </td>11463 </th>
11334 <td>11464 <td>
11335 {#syntax#}try{#endsyntax#} evaluates an error union expression.11465 {#syntax#}try{#endsyntax#} evaluates an error union expression.
11336 If it is an error, it returns from the current function with the same error.11466 If it is an error, it returns from the current function with the same error.
...@@ -11341,9 +11471,9 @@ fn readU32Be() u32 {}...@@ -11341,9 +11471,9 @@ fn readU32Be() u32 {}
11341 </td>11471 </td>
11342 </tr>11472 </tr>
11343 <tr>11473 <tr>
11344 <td>11474 <th scope="row">
11345 <pre>{#syntax#}undefined{#endsyntax#}</pre>11475 <pre>{#syntax#}undefined{#endsyntax#}</pre>
11346 </td>11476 </th>
11347 <td>11477 <td>
11348 {#syntax#}undefined{#endsyntax#} can be used to leave a value uninitialized.11478 {#syntax#}undefined{#endsyntax#} can be used to leave a value uninitialized.
11349 <ul>11479 <ul>
...@@ -11352,9 +11482,9 @@ fn readU32Be() u32 {}...@@ -11352,9 +11482,9 @@ fn readU32Be() u32 {}
11352 </td>11482 </td>
11353 </tr>11483 </tr>
11354 <tr>11484 <tr>
11355 <td>11485 <th scope="row">
11356 <pre>{#syntax#}union{#endsyntax#}</pre>11486 <pre>{#syntax#}union{#endsyntax#}</pre>
11357 </td>11487 </th>
11358 <td>11488 <td>
11359 {#syntax#}union{#endsyntax#} defines a union.11489 {#syntax#}union{#endsyntax#} defines a union.
11360 <ul>11490 <ul>
...@@ -11363,23 +11493,23 @@ fn readU32Be() u32 {}...@@ -11363,23 +11493,23 @@ fn readU32Be() u32 {}
11363 </td>11493 </td>
11364 </tr>11494 </tr>
11365 <tr>11495 <tr>
11366 <td>11496 <th scope="row">
11367 <pre>{#syntax#}unreachable{#endsyntax#}</pre>11497 <pre>{#syntax#}unreachable{#endsyntax#}</pre>
11368 </td>11498 </th>
11369 <td>11499 <td>
11370 {#syntax#}unreachable{#endsyntax#} can be used to assert that control flow will never happen upon a particular location.11500 {#syntax#}unreachable{#endsyntax#} can be used to assert that control flow will never happen upon a particular location.
11371 Depending on the build mode, {#syntax#}unreachable{#endsyntax#} may emit a panic.11501 Depending on the build mode, {#syntax#}unreachable{#endsyntax#} may emit a panic.
11372 <ul>11502 <ul>
11373 <li>Emits a panic in {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, or when using <code>zig test</code>.</li>11503 <li>Emits a panic in {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, or when using <kbd>zig test</kbd>.</li>
11374 <li>Does not emit a panic in {#syntax#}ReleaseFast{#endsyntax#} mode, unless <code>zig test</code> is being used.</li>11504 <li>Does not emit a panic in {#syntax#}ReleaseFast{#endsyntax#} mode, unless <kbd>zig test</kbd> is being used.</li>
11375 <li>See also {#link|unreachable#}</li>11505 <li>See also {#link|unreachable#}</li>
11376 </ul>11506 </ul>
11377 </td>11507 </td>
11378 </tr>11508 </tr>
11379 <tr>11509 <tr>
11380 <td>11510 <th scope="row">
11381 <pre>{#syntax#}usingnamespace{#endsyntax#}</pre>11511 <pre>{#syntax#}usingnamespace{#endsyntax#}</pre>
11382 </td>11512 </th>
11383 <td>11513 <td>
11384 {#syntax#}usingnamespace{#endsyntax#} is a top-level declaration that imports all the public declarations of the operand,11514 {#syntax#}usingnamespace{#endsyntax#} is a top-level declaration that imports all the public declarations of the operand,
11385 which must be a struct, union, or enum, into the current scope.11515 which must be a struct, union, or enum, into the current scope.
...@@ -11389,9 +11519,9 @@ fn readU32Be() u32 {}...@@ -11389,9 +11519,9 @@ fn readU32Be() u32 {}
11389 </td>11519 </td>
11390 </tr>11520 </tr>
11391 <tr>11521 <tr>
11392 <td>11522 <th scope="row">
11393 <pre>{#syntax#}var{#endsyntax#}</pre>11523 <pre>{#syntax#}var{#endsyntax#}</pre>
11394 </td>11524 </th>
11395 <td>11525 <td>
11396 {#syntax#}var{#endsyntax#} declares a variable that may be modified.11526 {#syntax#}var{#endsyntax#} declares a variable that may be modified.
11397 <ul>11527 <ul>
...@@ -11400,9 +11530,9 @@ fn readU32Be() u32 {}...@@ -11400,9 +11530,9 @@ fn readU32Be() u32 {}
11400 </td>11530 </td>
11401 </tr>11531 </tr>
11402 <tr>11532 <tr>
11403 <td>11533 <th scope="row">
11404 <pre>{#syntax#}volatile{#endsyntax#}</pre>11534 <pre>{#syntax#}volatile{#endsyntax#}</pre>
11405 </td>11535 </th>
11406 <td>11536 <td>
11407 {#syntax#}volatile{#endsyntax#} can be used to denote loads or stores of a pointer have side effects.11537 {#syntax#}volatile{#endsyntax#} can be used to denote loads or stores of a pointer have side effects.
11408 It can also modify an inline assembly expression to denote it has side effects.11538 It can also modify an inline assembly expression to denote it has side effects.
...@@ -11412,9 +11542,9 @@ fn readU32Be() u32 {}...@@ -11412,9 +11542,9 @@ fn readU32Be() u32 {}
11412 </td>11542 </td>
11413 </tr>11543 </tr>
11414 <tr>11544 <tr>
11415 <td>11545 <th scope="row">
11416 <pre>{#syntax#}while{#endsyntax#}</pre>11546 <pre>{#syntax#}while{#endsyntax#}</pre>
11417 </td>11547 </th>
11418 <td>11548 <td>
11419 A {#syntax#}while{#endsyntax#} expression can be used to repeatedly test a boolean, optional, or error union expression,11549 A {#syntax#}while{#endsyntax#} expression can be used to repeatedly test a boolean, optional, or error union expression,
11420 and cease looping when that expression evaluates to false, null, or an error, respectively.11550 and cease looping when that expression evaluates to false, null, or an error, respectively.
...@@ -11423,6 +11553,7 @@ fn readU32Be() u32 {}...@@ -11423,6 +11553,7 @@ fn readU32Be() u32 {}
11423 </ul>11553 </ul>
11424 </td>11554 </td>
11425 </tr>11555 </tr>
11556 </tbody>
11426 </table>11557 </table>
11427 </div>11558 </div>
11428 {#header_close#}11559 {#header_close#}
...@@ -11993,7 +12124,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe...@@ -11993,7 +12124,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe
11993 <li>Together we serve the users.</li>12124 <li>Together we serve the users.</li>
11994 </ul>12125 </ul>
11995 {#header_close#}12126 {#header_close#}
11996 </div></div>12127 </main></div>
11997 </div>12128 </div>
11998 </body>12129 </body>
11999</html>12130</html>
lib/libc/mingw/math/arm-common/log2.c created+55
...@@ -0,0 +1,55 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <math.h>
8#include <stdint.h>
9
10typedef union ieee754_double_ {
11 struct __attribute__((__packed__)) {
12 uint64_t f52 : 52;
13 uint64_t exp : 11;
14 uint64_t sgn : 1;
15 };
16 double f;
17} ieee754_double;
18
19typedef union ieee754_float_ {
20 struct __attribute__((__packed__)) {
21 uint32_t f23 : 23;
22 uint32_t exp : 8;
23 uint32_t sgn : 1;
24 };
25 float f;
26} ieee754_float;
27
28double log2(double x)
29{
30 ieee754_double u = { .f = x };
31 if (u.sgn == 0 && u.f52 == 0 && u.exp > 0 && u.exp < 0x7ff) {
32 // Handle exact powers of two exactly
33 return (int)u.exp - 1023;
34 }
35 return log(x) / 0.69314718246459960938;
36}
37
38float log2f(float x)
39{
40 ieee754_float u = { .f = x };
41 if (u.sgn == 0 && u.f23 == 0 && u.exp > 0 && u.exp < 0xff) {
42 // Handle exact powers of two exactly
43 return (int)u.exp - 127;
44 }
45 return logf(x) / 0.69314718246459960938f;
46}
47
48long double log2l(long double x)
49{
50#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_)
51 return log2(x);
52#else
53#error Not supported on your platform yet
54#endif
55}
lib/libc/mingw/math/arm-common/pow.c created+21
...@@ -0,0 +1,21 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <math.h>
8#include <limits.h>
9
10extern double (* __MINGW_IMP_SYMBOL(pow))(double, double);
11
12double pow(double x, double y)
13{
14 if (x == 1.0)
15 return 1.0;
16 if (y == 0.0)
17 return 1.0;
18 if (x == -1.0 && isinf(y))
19 return 1.0;
20 return __MINGW_IMP_SYMBOL(pow)(x, y);
21}
lib/libc/mingw/math/arm-common/scalbn.c created+45
...@@ -0,0 +1,45 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <math.h>
8
9double scalbn(double x, int exp)
10{
11 return x * exp2(exp);
12}
13
14float scalbnf(float x, int exp)
15{
16 return x * exp2f(exp);
17}
18
19long double scalbnl(long double x, int exp)
20{
21#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_)
22 return scalbn(x, exp);
23#else
24#error Not supported on your platform yet
25#endif
26}
27
28double scalbln(double x, long exp)
29{
30 return x * exp2(exp);
31}
32
33float scalblnf(float x, long exp)
34{
35 return x * exp2f(exp);
36}
37
38long double scalblnl(long double x, long exp)
39{
40#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_)
41 return scalbln(x, exp);
42#else
43#error Not supported on your platform yet
44#endif
45}
lib/libc/mingw/math/bsd_private_base.h created+148
...@@ -0,0 +1,148 @@
1/*
2* ====================================================
3* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4*
5* Developed at SunPro, a Sun Microsystems, Inc. business.
6* Permission to use, copy, modify, and distribute this
7* software is freely granted, provided that this notice
8* is preserved.
9* ====================================================
10*/
11
12#include <inttypes.h>
13#include <float.h>
14
15typedef unsigned int u_int32_t;
16
17typedef union
18{
19 double value;
20 struct
21 {
22 u_int32_t lsw;
23 u_int32_t msw;
24 } parts;
25} ieee_double_shape_type;
26
27typedef union {
28 float value;
29 u_int32_t word;
30} ieee_float_shape_type;
31
32/* Get two 32 bit ints from a double. */
33
34#define EXTRACT_WORDS(ix0,ix1,d) \
35do { \
36 ieee_double_shape_type ew_u; \
37 ew_u.value = (d); \
38 (ix0) = ew_u.parts.msw; \
39 (ix1) = ew_u.parts.lsw; \
40} while (0)
41
42/* Get the most significant 32 bit int from a double. */
43
44#define GET_HIGH_WORD(i,d) \
45do { \
46 ieee_double_shape_type gh_u; \
47 gh_u.value = (d); \
48 (i) = gh_u.parts.msw; \
49} while (0)
50
51/* Get the less significant 32 bit int from a double. */
52
53#define GET_LOW_WORD(i,d) \
54do { \
55 ieee_double_shape_type gl_u; \
56 gl_u.value = (d); \
57 (i) = gl_u.parts.lsw; \
58} while (0)
59
60/* Set a double from two 32 bit ints. */
61
62#define INSERT_WORDS(d,ix0,ix1) \
63do { \
64 ieee_double_shape_type iw_u; \
65 iw_u.parts.msw = (ix0); \
66 iw_u.parts.lsw = (ix1); \
67 (d) = iw_u.value; \
68} while (0)
69
70/* Set the more significant 32 bits of a double from an int. */
71
72#define SET_HIGH_WORD(d,v) \
73do { \
74 ieee_double_shape_type sh_u; \
75 sh_u.value = (d); \
76 sh_u.parts.msw = (v); \
77 (d) = sh_u.value; \
78} while (0)
79
80/* Set the less significant 32 bits of a double from an int. */
81
82#define SET_LOW_WORD(d,v) \
83do { \
84 ieee_double_shape_type sl_u; \
85 sl_u.value = (d); \
86 sl_u.parts.lsw = (v); \
87 (d) = sl_u.value; \
88} while (0)
89
90#define GET_FLOAT_WORD(i,d) do \
91{ \
92 ieee_float_shape_type gf_u; \
93 gf_u.value = (d); \
94 (i) = gf_u.word; \
95} while(0)
96
97#define SET_FLOAT_WORD(d,i) do \
98{ \
99 ieee_float_shape_type gf_u; \
100 gf_u.word = (i); \
101 (d) = gf_u.value; \
102} while(0)
103
104
105#ifdef FLT_EVAL_METHOD
106/*
107 * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
108 */
109#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
110#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
111#else
112#define STRICT_ASSIGN(type, lval, rval) do { \
113 volatile type __lval; \
114 \
115 if (sizeof(type) >= sizeof(long double)) \
116 (lval) = (rval); \
117 else { \
118 __lval = (rval); \
119 (lval) = __lval; \
120 } \
121} while (0)
122#endif
123#endif /* FLT_EVAL_METHOD */
124
125/*
126 * Mix 0, 1 or 2 NaNs. First add 0 to each arg. This normally just turns
127 * signaling NaNs into quiet NaNs by setting a quiet bit. We do this
128 * because we want to never return a signaling NaN, and also because we
129 * don't want the quiet bit to affect the result. Then mix the converted
130 * args using the specified operation.
131 *
132 * When one arg is NaN, the result is typically that arg quieted. When both
133 * args are NaNs, the result is typically the quietening of the arg whose
134 * mantissa is largest after quietening. When neither arg is NaN, the
135 * result may be NaN because it is indeterminate, or finite for subsequent
136 * construction of a NaN as the indeterminate 0.0L/0.0L.
137 *
138 * Technical complications: the result in bits after rounding to the final
139 * precision might depend on the runtime precision and/or on compiler
140 * optimizations, especially when different register sets are used for
141 * different precisions. Try to make the result not depend on at least the
142 * runtime precision by always doing the main mixing step in long double
143 * precision. Try to reduce dependencies on optimizations by adding the
144 * the 0's in different precisions (unless everything is in long double
145 * precision).
146 */
147#define nan_mix(x, y) (nan_mix_op((x), (y), +))
148#define nan_mix_op(x, y, op) (((x) + 0.0L) op ((y) + 0))
lib/libc/mingw/misc/initenv.c created+12
...@@ -0,0 +1,12 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <wchar.h>
8
9static char ** local__initenv;
10static wchar_t ** local__winitenv;
11char *** __MINGW_IMP_SYMBOL(__initenv) = &local__initenv;
12wchar_t *** __MINGW_IMP_SYMBOL(__winitenv) = &local__winitenv;
lib/std/Thread.zig+9-9
...@@ -558,7 +558,7 @@ const PosixThreadImpl = struct {...@@ -558,7 +558,7 @@ const PosixThreadImpl = struct {
558 .openbsd => {558 .openbsd => {
559 var count: c_int = undefined;559 var count: c_int = undefined;
560 var count_size: usize = @sizeOf(c_int);560 var count_size: usize = @sizeOf(c_int);
561 const mib = [_]c_int{ os.CTL_HW, os.HW_NCPUONLINE };561 const mib = [_]c_int{ os.CTL.HW, os.system.HW_NCPUONLINE };
562 os.sysctl(&mib, &count, &count_size, null, 0) catch |err| switch (err) {562 os.sysctl(&mib, &count, &count_size, null, 0) catch |err| switch (err) {
563 error.NameTooLong, error.UnknownName => unreachable,563 error.NameTooLong, error.UnknownName => unreachable,
564 else => |e| return e,564 else => |e| return e,
...@@ -877,8 +877,8 @@ const LinuxThreadImpl = struct {...@@ -877,8 +877,8 @@ const LinuxThreadImpl = struct {
877 const mapped = os.mmap(877 const mapped = os.mmap(
878 null,878 null,
879 map_bytes,879 map_bytes,
880 os.PROT_NONE,880 os.PROT.NONE,
881 os.MAP_PRIVATE | os.MAP_ANONYMOUS,881 os.MAP.PRIVATE | os.MAP.ANONYMOUS,
882 -1,882 -1,
883 0,883 0,
884 ) catch |err| switch (err) {884 ) catch |err| switch (err) {
...@@ -893,7 +893,7 @@ const LinuxThreadImpl = struct {...@@ -893,7 +893,7 @@ const LinuxThreadImpl = struct {
893 // map everything but the guard page as read/write893 // map everything but the guard page as read/write
894 os.mprotect(894 os.mprotect(
895 mapped[guard_offset..],895 mapped[guard_offset..],
896 os.PROT_READ | os.PROT_WRITE,896 os.PROT.READ | os.PROT.WRITE,
897 ) catch |err| switch (err) {897 ) catch |err| switch (err) {
898 error.AccessDenied => unreachable,898 error.AccessDenied => unreachable,
899 else => |e| return e,899 else => |e| return e,
...@@ -923,10 +923,10 @@ const LinuxThreadImpl = struct {...@@ -923,10 +923,10 @@ const LinuxThreadImpl = struct {
923 .thread = .{ .mapped = mapped },923 .thread = .{ .mapped = mapped },
924 };924 };
925925
926 const flags: u32 = os.CLONE_THREAD | os.CLONE_DETACHED |926 const flags: u32 = linux.CLONE.THREAD | linux.CLONE.DETACHED |
927 os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES |927 linux.CLONE.VM | linux.CLONE.FS | linux.CLONE.FILES |
928 os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |928 linux.CLONE.PARENT_SETTID | linux.CLONE.CHILD_CLEARTID |
929 os.CLONE_SIGHAND | os.CLONE_SYSVSEM | os.CLONE_SETTLS;929 linux.CLONE.SIGHAND | linux.CLONE.SYSVSEM | linux.CLONE.SETTLS;
930930
931 switch (linux.getErrno(linux.clone(931 switch (linux.getErrno(linux.clone(
932 Instance.entryFn,932 Instance.entryFn,
...@@ -978,7 +978,7 @@ const LinuxThreadImpl = struct {...@@ -978,7 +978,7 @@ const LinuxThreadImpl = struct {
978978
979 switch (linux.getErrno(linux.futex_wait(979 switch (linux.getErrno(linux.futex_wait(
980 &self.thread.child_tid.value,980 &self.thread.child_tid.value,
981 linux.FUTEX_WAIT,981 linux.FUTEX.WAIT,
982 tid,982 tid,
983 null,983 null,
984 ))) {984 ))) {
lib/std/Thread/Futex.zig+3-3
...@@ -142,7 +142,7 @@ const LinuxFutex = struct {...@@ -142,7 +142,7 @@ const LinuxFutex = struct {
142142
143 switch (linux.getErrno(linux.futex_wait(143 switch (linux.getErrno(linux.futex_wait(
144 @ptrCast(*const i32, ptr),144 @ptrCast(*const i32, ptr),
145 linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAIT,145 linux.FUTEX.PRIVATE_FLAG | linux.FUTEX.WAIT,
146 @bitCast(i32, expect),146 @bitCast(i32, expect),
147 ts_ptr,147 ts_ptr,
148 ))) {148 ))) {
...@@ -159,7 +159,7 @@ const LinuxFutex = struct {...@@ -159,7 +159,7 @@ const LinuxFutex = struct {
159 fn wake(ptr: *const Atomic(u32), num_waiters: u32) void {159 fn wake(ptr: *const Atomic(u32), num_waiters: u32) void {
160 switch (linux.getErrno(linux.futex_wake(160 switch (linux.getErrno(linux.futex_wake(
161 @ptrCast(*const i32, ptr),161 @ptrCast(*const i32, ptr),
162 linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAKE,162 linux.FUTEX.PRIVATE_FLAG | linux.FUTEX.WAKE,
163 std.math.cast(i32, num_waiters) catch std.math.maxInt(i32),163 std.math.cast(i32, num_waiters) catch std.math.maxInt(i32),
164 ))) {164 ))) {
165 .SUCCESS => {}, // successful wake up165 .SUCCESS => {}, // successful wake up
...@@ -352,7 +352,7 @@ const PosixFutex = struct {...@@ -352,7 +352,7 @@ const PosixFutex = struct {
352 var ts_ptr: ?*const std.os.timespec = null;352 var ts_ptr: ?*const std.os.timespec = null;
353 if (timeout) |timeout_ns| {353 if (timeout) |timeout_ns| {
354 ts_ptr = &ts;354 ts_ptr = &ts;
355 std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts) catch unreachable;355 std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts) catch unreachable;
356 ts.tv_sec += @intCast(@TypeOf(ts.tv_sec), timeout_ns / std.time.ns_per_s);356 ts.tv_sec += @intCast(@TypeOf(ts.tv_sec), timeout_ns / std.time.ns_per_s);
357 ts.tv_nsec += @intCast(@TypeOf(ts.tv_nsec), timeout_ns % std.time.ns_per_s);357 ts.tv_nsec += @intCast(@TypeOf(ts.tv_nsec), timeout_ns % std.time.ns_per_s);
358 if (ts.tv_nsec >= std.time.ns_per_s) {358 if (ts.tv_nsec >= std.time.ns_per_s) {
lib/std/Thread/Mutex.zig+2-2
...@@ -133,7 +133,7 @@ pub const AtomicMutex = struct {...@@ -133,7 +133,7 @@ pub const AtomicMutex = struct {
133 .linux => {133 .linux => {
134 switch (linux.getErrno(linux.futex_wait(134 switch (linux.getErrno(linux.futex_wait(
135 @ptrCast(*const i32, &m.state),135 @ptrCast(*const i32, &m.state),
136 linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAIT,136 linux.FUTEX.PRIVATE_FLAG | linux.FUTEX.WAIT,
137 @enumToInt(new_state),137 @enumToInt(new_state),
138 null,138 null,
139 ))) {139 ))) {
...@@ -155,7 +155,7 @@ pub const AtomicMutex = struct {...@@ -155,7 +155,7 @@ pub const AtomicMutex = struct {
155 .linux => {155 .linux => {
156 switch (linux.getErrno(linux.futex_wake(156 switch (linux.getErrno(linux.futex_wake(
157 @ptrCast(*const i32, &m.state),157 @ptrCast(*const i32, &m.state),
158 linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAKE,158 linux.FUTEX.PRIVATE_FLAG | linux.FUTEX.WAKE,
159 1,159 1,
160 ))) {160 ))) {
161 .SUCCESS => {},161 .SUCCESS => {},
lib/std/Thread/ResetEvent.zig+1-1
...@@ -152,7 +152,7 @@ pub const PosixEvent = struct {...@@ -152,7 +152,7 @@ pub const PosixEvent = struct {
152 pub fn timedWait(ev: *PosixEvent, timeout_ns: u64) TimedWaitResult {152 pub fn timedWait(ev: *PosixEvent, timeout_ns: u64) TimedWaitResult {
153 var ts: os.timespec = undefined;153 var ts: os.timespec = undefined;
154 var timeout_abs = timeout_ns;154 var timeout_abs = timeout_ns;
155 os.clock_gettime(os.CLOCK_REALTIME, &ts) catch return .timed_out;155 os.clock_gettime(os.CLOCK.REALTIME, &ts) catch return .timed_out;
156 timeout_abs += @intCast(u64, ts.tv_sec) * time.ns_per_s;156 timeout_abs += @intCast(u64, ts.tv_sec) * time.ns_per_s;
157 timeout_abs += @intCast(u64, ts.tv_nsec);157 timeout_abs += @intCast(u64, ts.tv_nsec);
158 ts.tv_sec = @intCast(@TypeOf(ts.tv_sec), @divFloor(timeout_abs, time.ns_per_s));158 ts.tv_sec = @intCast(@TypeOf(ts.tv_sec), @divFloor(timeout_abs, time.ns_per_s));
lib/std/Thread/StaticResetEvent.zig+2-2
...@@ -194,7 +194,7 @@ pub const AtomicEvent = struct {...@@ -194,7 +194,7 @@ pub const AtomicEvent = struct {
194 _ = wake_count;194 _ = wake_count;
195 const waiting = std.math.maxInt(i32); // wake_count195 const waiting = std.math.maxInt(i32); // wake_count
196 const ptr = @ptrCast(*const i32, waiters);196 const ptr = @ptrCast(*const i32, waiters);
197 const rc = linux.futex_wake(ptr, linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG, waiting);197 const rc = linux.futex_wake(ptr, linux.FUTEX.WAKE | linux.FUTEX.PRIVATE_FLAG, waiting);
198 assert(linux.getErrno(rc) == .SUCCESS);198 assert(linux.getErrno(rc) == .SUCCESS);
199 }199 }
200200
...@@ -213,7 +213,7 @@ pub const AtomicEvent = struct {...@@ -213,7 +213,7 @@ pub const AtomicEvent = struct {
213 return;213 return;
214 const expected = @intCast(i32, waiting);214 const expected = @intCast(i32, waiting);
215 const ptr = @ptrCast(*const i32, waiters);215 const ptr = @ptrCast(*const i32, waiters);
216 const rc = linux.futex_wait(ptr, linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG, expected, ts_ptr);216 const rc = linux.futex_wait(ptr, linux.FUTEX.WAIT | linux.FUTEX.PRIVATE_FLAG, expected, ts_ptr);
217 switch (linux.getErrno(rc)) {217 switch (linux.getErrno(rc)) {
218 .SUCCESS => continue,218 .SUCCESS => continue,
219 .TIMEDOUT => return error.TimedOut,219 .TIMEDOUT => return error.TimedOut,
lib/std/array_list.zig+16-14
...@@ -236,21 +236,23 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -236,21 +236,23 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
236 mem.copy(T, self.items[old_len..], items);236 mem.copy(T, self.items[old_len..], items);
237 }237 }
238238
239 pub usingnamespace if (T != u8) struct {} else struct {239 pub const Writer = if (T != u8)
240 pub const Writer = std.io.Writer(*Self, error{OutOfMemory}, appendWrite);240 @compileError("The Writer interface is only defined for ArrayList(u8) " ++
241 "but the given type is ArrayList(" ++ @typeName(T) ++ ")")
242 else
243 std.io.Writer(*Self, error{OutOfMemory}, appendWrite);
241244
242 /// Initializes a Writer which will append to the list.245 /// Initializes a Writer which will append to the list.
243 pub fn writer(self: *Self) Writer {246 pub fn writer(self: *Self) Writer {
244 return .{ .context = self };247 return .{ .context = self };
245 }248 }
246249
247 /// Same as `append` except it returns the number of bytes written, which is always the same250 /// Same as `append` except it returns the number of bytes written, which is always the same
248 /// as `m.len`. The purpose of this function existing is to match `std.io.Writer` API.251 /// as `m.len`. The purpose of this function existing is to match `std.io.Writer` API.
249 fn appendWrite(self: *Self, m: []const u8) !usize {252 fn appendWrite(self: *Self, m: []const u8) !usize {
250 try self.appendSlice(m);253 try self.appendSlice(m);
251 return m.len;254 return m.len;
252 }255 }
253 };
254256
255 /// Append a value to the list `n` times.257 /// Append a value to the list `n` times.
256 /// Allocates more memory as necessary.258 /// Allocates more memory as necessary.
...@@ -741,7 +743,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -741,7 +743,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
741743
742 /// For a nicer API, `items.len` is the length, not the capacity.744 /// For a nicer API, `items.len` is the length, not the capacity.
743 /// This requires "unsafe" slicing.745 /// This requires "unsafe" slicing.
744 fn allocatedSlice(self: Self) Slice {746 pub fn allocatedSlice(self: Self) Slice {
745 return self.items.ptr[0..self.capacity];747 return self.items.ptr[0..self.capacity];
746 }748 }
747 };749 };
lib/std/build.zig+30-2
...@@ -989,10 +989,15 @@ pub const Builder = struct {...@@ -989,10 +989,15 @@ pub const Builder = struct {
989 self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .lib, dest_rel_path).step);989 self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .lib, dest_rel_path).step);
990 }990 }
991991
992 /// Output format (BIN vs Intel HEX) determined by filename
992 pub fn installRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) void {993 pub fn installRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) void {
993 self.getInstallStep().dependOn(&self.addInstallRaw(artifact, dest_filename).step);994 self.getInstallStep().dependOn(&self.addInstallRaw(artifact, dest_filename).step);
994 }995 }
995996
997 pub fn installRawWithFormat(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8, format: InstallRawStep.RawFormat) void {
998 self.getInstallStep().dependOn(&self.addInstallRawWithFormat(artifact, dest_filename, format).step);
999 }
1000
996 ///`dest_rel_path` is relative to install prefix path1001 ///`dest_rel_path` is relative to install prefix path
997 pub fn addInstallFile(self: *Builder, source: FileSource, dest_rel_path: []const u8) *InstallFileStep {1002 pub fn addInstallFile(self: *Builder, source: FileSource, dest_rel_path: []const u8) *InstallFileStep {
998 return self.addInstallFileWithDir(source.dupe(self), .prefix, dest_rel_path);1003 return self.addInstallFileWithDir(source.dupe(self), .prefix, dest_rel_path);
...@@ -1009,7 +1014,11 @@ pub const Builder = struct {...@@ -1009,7 +1014,11 @@ pub const Builder = struct {
1009 }1014 }
10101015
1011 pub fn addInstallRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) *InstallRawStep {1016 pub fn addInstallRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) *InstallRawStep {
1012 return InstallRawStep.create(self, artifact, dest_filename);1017 return InstallRawStep.create(self, artifact, dest_filename, null);
1018 }
1019
1020 pub fn addInstallRawWithFormat(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8, format: InstallRawStep.RawFormat) *InstallRawStep {
1021 return InstallRawStep.create(self, artifact, dest_filename, format);
1013 }1022 }
10141023
1015 pub fn addInstallFileWithDir(1024 pub fn addInstallFileWithDir(
...@@ -1709,6 +1718,10 @@ pub const LibExeObjStep = struct {...@@ -1709,6 +1718,10 @@ pub const LibExeObjStep = struct {
1709 self.builder.installRaw(self, dest_filename);1718 self.builder.installRaw(self, dest_filename);
1710 }1719 }
17111720
1721 pub fn installRawWithFormat(self: *LibExeObjStep, dest_filename: []const u8, format: InstallRawStep.RawFormat) void {
1722 self.builder.installRawWithFormat(self, dest_filename, format);
1723 }
1724
1712 /// Creates a `RunStep` with an executable built with `addExecutable`.1725 /// Creates a `RunStep` with an executable built with `addExecutable`.
1713 /// Add command line arguments with `addArg`.1726 /// Add command line arguments with `addArg`.
1714 pub fn run(exe: *LibExeObjStep) *RunStep {1727 pub fn run(exe: *LibExeObjStep) *RunStep {
...@@ -2536,7 +2549,22 @@ pub const LibExeObjStep = struct {...@@ -2536,7 +2549,22 @@ pub const LibExeObjStep = struct {
2536 } else {2549 } else {
2537 try zig_args.append("-isystem");2550 try zig_args.append("-isystem");
2538 }2551 }
2539 try zig_args.append(self.builder.pathFromRoot(include_path));2552
2553 const resolved_include_path = self.builder.pathFromRoot(include_path);
2554
2555 const common_include_path = if (std.Target.current.os.tag == .windows and builder.sysroot != null and fs.path.isAbsolute(resolved_include_path)) blk: {
2556 // We need to check for disk designator and strip it out from dir path so
2557 // that zig/clang can concat resolved_include_path with sysroot.
2558 const disk_designator = fs.path.diskDesignatorWindows(resolved_include_path);
2559
2560 if (mem.indexOf(u8, resolved_include_path, disk_designator)) |where| {
2561 break :blk resolved_include_path[where + disk_designator.len ..];
2562 }
2563
2564 break :blk resolved_include_path;
2565 } else resolved_include_path;
2566
2567 try zig_args.append(common_include_path);
2540 },2568 },
2541 .other_step => |other| if (other.emit_h) {2569 .other_step => |other| if (other.emit_h) {
2542 const h_path = other.getOutputHSource().getPath(self.builder);2570 const h_path = other.getOutputHSource().getPath(self.builder);
lib/std/build/InstallRawStep.zig+223-5
...@@ -159,7 +159,147 @@ fn writeBinaryElfSection(elf_file: File, out_file: File, section: *BinaryElfSect...@@ -159,7 +159,147 @@ fn writeBinaryElfSection(elf_file: File, out_file: File, section: *BinaryElfSect
159 });159 });
160}160}
161161
162fn emitRaw(allocator: *Allocator, elf_path: []const u8, raw_path: []const u8) !void {162const HexWriter = struct {
163 prev_addr: ?u32 = null,
164 out_file: File,
165
166 /// Max data bytes per line of output
167 const MAX_PAYLOAD_LEN: u8 = 16;
168
169 fn addressParts(address: u16) [2]u8 {
170 const msb = @truncate(u8, address >> 8);
171 const lsb = @truncate(u8, address);
172 return [2]u8{ msb, lsb };
173 }
174
175 const Record = struct {
176 const Type = enum(u8) {
177 Data = 0,
178 EOF = 1,
179 ExtendedSegmentAddress = 2,
180 ExtendedLinearAddress = 4,
181 };
182
183 address: u16,
184 payload: union(Type) {
185 Data: []const u8,
186 EOF: void,
187 ExtendedSegmentAddress: [2]u8,
188 ExtendedLinearAddress: [2]u8,
189 },
190
191 fn EOF() Record {
192 return Record{
193 .address = 0,
194 .payload = .EOF,
195 };
196 }
197
198 fn Data(address: u32, data: []const u8) Record {
199 return Record{
200 .address = @intCast(u16, address % 0x10000),
201 .payload = .{ .Data = data },
202 };
203 }
204
205 fn Address(address: u32) Record {
206 std.debug.assert(address > 0xFFFF);
207 const segment = @intCast(u16, address / 0x10000);
208 if (address > 0xFFFFF) {
209 return Record{
210 .address = 0,
211 .payload = .{ .ExtendedLinearAddress = addressParts(segment) },
212 };
213 } else {
214 return Record{
215 .address = 0,
216 .payload = .{ .ExtendedSegmentAddress = addressParts(segment << 12) },
217 };
218 }
219 }
220
221 fn getPayloadBytes(self: Record) []const u8 {
222 return switch (self.payload) {
223 .Data => |d| d,
224 .EOF => @as([]const u8, &.{}),
225 .ExtendedSegmentAddress, .ExtendedLinearAddress => |*seg| seg,
226 };
227 }
228
229 fn checksum(self: Record) u8 {
230 const payload_bytes = self.getPayloadBytes();
231
232 var sum: u8 = @intCast(u8, payload_bytes.len);
233 const parts = addressParts(self.address);
234 sum +%= parts[0];
235 sum +%= parts[1];
236 sum +%= @enumToInt(self.payload);
237 for (payload_bytes) |byte| {
238 sum +%= byte;
239 }
240 return (sum ^ 0xFF) +% 1;
241 }
242
243 fn write(self: Record, file: File) File.WriteError!void {
244 const linesep = "\r\n";
245 // colon, (length, address, type, payload, checksum) as hex, CRLF
246 const BUFSIZE = 1 + (1 + 2 + 1 + MAX_PAYLOAD_LEN + 1) * 2 + linesep.len;
247 var outbuf: [BUFSIZE]u8 = undefined;
248 const payload_bytes = self.getPayloadBytes();
249 std.debug.assert(payload_bytes.len <= MAX_PAYLOAD_LEN);
250
251 const line = try std.fmt.bufPrint(&outbuf, ":{0X:0>2}{1X:0>4}{2X:0>2}{3s}{4X:0>2}" ++ linesep, .{
252 @intCast(u8, payload_bytes.len),
253 self.address,
254 @enumToInt(self.payload),
255 std.fmt.fmtSliceHexUpper(payload_bytes),
256 self.checksum(),
257 });
258 try file.writeAll(line);
259 }
260 };
261
262 pub fn writeSegment(self: *HexWriter, segment: *const BinaryElfSegment, elf_file: File) !void {
263 var buf: [MAX_PAYLOAD_LEN]u8 = undefined;
264 var bytes_read: usize = 0;
265 while (bytes_read < segment.fileSize) {
266 const row_address = @intCast(u32, segment.physicalAddress + bytes_read);
267
268 const remaining = segment.fileSize - bytes_read;
269 const to_read = @minimum(remaining, MAX_PAYLOAD_LEN);
270 const did_read = try elf_file.preadAll(buf[0..to_read], segment.elfOffset + bytes_read);
271 if (did_read < to_read) return error.UnexpectedEOF;
272
273 try self.writeDataRow(row_address, buf[0..did_read]);
274
275 bytes_read += did_read;
276 }
277 }
278
279 fn writeDataRow(self: *HexWriter, address: u32, data: []const u8) File.WriteError!void {
280 const record = Record.Data(address, data);
281 if (address > 0xFFFF and (self.prev_addr == null or record.address != self.prev_addr.?)) {
282 try Record.Address(address).write(self.out_file);
283 }
284 try record.write(self.out_file);
285 self.prev_addr = @intCast(u32, record.address + data.len);
286 }
287
288 fn writeEOF(self: HexWriter) File.WriteError!void {
289 try Record.EOF().write(self.out_file);
290 }
291};
292
293fn containsValidAddressRange(segments: []*BinaryElfSegment) bool {
294 const max_address = std.math.maxInt(u32);
295 for (segments) |segment| {
296 if (segment.fileSize > max_address or
297 segment.physicalAddress > max_address - segment.fileSize) return false;
298 }
299 return true;
300}
301
302fn emitRaw(allocator: *Allocator, elf_path: []const u8, raw_path: []const u8, format: RawFormat) !void {
163 var elf_file = try fs.cwd().openFile(elf_path, .{});303 var elf_file = try fs.cwd().openFile(elf_path, .{});
164 defer elf_file.close();304 defer elf_file.close();
165305
...@@ -169,8 +309,26 @@ fn emitRaw(allocator: *Allocator, elf_path: []const u8, raw_path: []const u8) !v...@@ -169,8 +309,26 @@ fn emitRaw(allocator: *Allocator, elf_path: []const u8, raw_path: []const u8) !v
169 var binary_elf_output = try BinaryElfOutput.parse(allocator, elf_file);309 var binary_elf_output = try BinaryElfOutput.parse(allocator, elf_file);
170 defer binary_elf_output.deinit();310 defer binary_elf_output.deinit();
171311
172 for (binary_elf_output.sections.items) |section| {312 switch (format) {
173 try writeBinaryElfSection(elf_file, out_file, section);313 .bin => {
314 for (binary_elf_output.sections.items) |section| {
315 try writeBinaryElfSection(elf_file, out_file, section);
316 }
317 },
318 .hex => {
319 if (binary_elf_output.segments.items.len == 0) return;
320 if (!containsValidAddressRange(binary_elf_output.segments.items)) {
321 return error.InvalidHexfileAddressRange;
322 }
323
324 var hex_writer = HexWriter{ .out_file = out_file };
325 for (binary_elf_output.sections.items) |section| {
326 if (section.segment) |segment| {
327 try hex_writer.writeSegment(segment, elf_file);
328 }
329 }
330 try hex_writer.writeEOF();
331 },
174 }332 }
175}333}
176334
...@@ -178,13 +336,27 @@ const InstallRawStep = @This();...@@ -178,13 +336,27 @@ const InstallRawStep = @This();
178336
179pub const base_id = .install_raw;337pub const base_id = .install_raw;
180338
339pub const RawFormat = enum {
340 bin,
341 hex,
342};
343
181step: Step,344step: Step,
182builder: *Builder,345builder: *Builder,
183artifact: *LibExeObjStep,346artifact: *LibExeObjStep,
184dest_dir: InstallDir,347dest_dir: InstallDir,
185dest_filename: []const u8,348dest_filename: []const u8,
349format: RawFormat,
350output_file: std.build.GeneratedFile,
351
352fn detectFormat(filename: []const u8) RawFormat {
353 if (std.mem.endsWith(u8, filename, ".hex") or std.mem.endsWith(u8, filename, ".ihex")) {
354 return .hex;
355 }
356 return .bin;
357}
186358
187pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) *InstallRawStep {359pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8, format: ?RawFormat) *InstallRawStep {
188 const self = builder.allocator.create(InstallRawStep) catch unreachable;360 const self = builder.allocator.create(InstallRawStep) catch unreachable;
189 self.* = InstallRawStep{361 self.* = InstallRawStep{
190 .step = Step.init(.install_raw, builder.fmt("install raw binary {s}", .{artifact.step.name}), builder.allocator, make),362 .step = Step.init(.install_raw, builder.fmt("install raw binary {s}", .{artifact.step.name}), builder.allocator, make),
...@@ -197,6 +369,8 @@ pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []cons...@@ -197,6 +369,8 @@ pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []cons
197 .lib => unreachable,369 .lib => unreachable,
198 },370 },
199 .dest_filename = dest_filename,371 .dest_filename = dest_filename,
372 .format = format orelse detectFormat(dest_filename),
373 .output_file = std.build.GeneratedFile{ .step = &self.step },
200 };374 };
201 self.step.dependOn(&artifact.step);375 self.step.dependOn(&artifact.step);
202376
...@@ -204,6 +378,10 @@ pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []cons...@@ -204,6 +378,10 @@ pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []cons
204 return self;378 return self;
205}379}
206380
381pub fn getOutputSource(self: *const InstallRawStep) std.build.FileSource {
382 return std.build.FileSource{ .generated = &self.output_file };
383}
384
207fn make(step: *Step) !void {385fn make(step: *Step) !void {
208 const self = @fieldParentPtr(InstallRawStep, "step", step);386 const self = @fieldParentPtr(InstallRawStep, "step", step);
209 const builder = self.builder;387 const builder = self.builder;
...@@ -217,9 +395,49 @@ fn make(step: *Step) !void {...@@ -217,9 +395,49 @@ fn make(step: *Step) !void {
217 const full_dest_path = builder.getInstallPath(self.dest_dir, self.dest_filename);395 const full_dest_path = builder.getInstallPath(self.dest_dir, self.dest_filename);
218396
219 fs.cwd().makePath(builder.getInstallPath(self.dest_dir, "")) catch unreachable;397 fs.cwd().makePath(builder.getInstallPath(self.dest_dir, "")) catch unreachable;
220 try emitRaw(builder.allocator, full_src_path, full_dest_path);398 try emitRaw(builder.allocator, full_src_path, full_dest_path, self.format);
399 self.output_file.path = full_dest_path;
221}400}
222401
223test {402test {
224 std.testing.refAllDecls(InstallRawStep);403 std.testing.refAllDecls(InstallRawStep);
225}404}
405
406test "Detect format from filename" {
407 try std.testing.expectEqual(RawFormat.hex, detectFormat("foo.hex"));
408 try std.testing.expectEqual(RawFormat.hex, detectFormat("foo.ihex"));
409 try std.testing.expectEqual(RawFormat.bin, detectFormat("foo.bin"));
410 try std.testing.expectEqual(RawFormat.bin, detectFormat("foo.bar"));
411 try std.testing.expectEqual(RawFormat.bin, detectFormat("a"));
412}
413
414test "containsValidAddressRange" {
415 var segment = BinaryElfSegment{
416 .physicalAddress = 0,
417 .virtualAddress = 0,
418 .elfOffset = 0,
419 .binaryOffset = 0,
420 .fileSize = 0,
421 .firstSection = null,
422 };
423 var buf: [1]*BinaryElfSegment = .{&segment};
424
425 // segment too big
426 segment.fileSize = std.math.maxInt(u32) + 1;
427 try std.testing.expect(!containsValidAddressRange(&buf));
428
429 // start address too big
430 segment.physicalAddress = std.math.maxInt(u32) + 1;
431 segment.fileSize = 2;
432 try std.testing.expect(!containsValidAddressRange(&buf));
433
434 // max address too big
435 segment.physicalAddress = std.math.maxInt(u32) - 1;
436 segment.fileSize = 2;
437 try std.testing.expect(!containsValidAddressRange(&buf));
438
439 // is ok
440 segment.physicalAddress = std.math.maxInt(u32) - 1;
441 segment.fileSize = 1;
442 try std.testing.expect(containsValidAddressRange(&buf));
443}
lib/std/builtin.zig+1-1
...@@ -27,7 +27,7 @@ pub const code_model = builtin.code_model;...@@ -27,7 +27,7 @@ pub const code_model = builtin.code_model;
27/// used rather than `explicit_subsystem`.27/// used rather than `explicit_subsystem`.
28/// On non-Windows targets, this is `null`.28/// On non-Windows targets, this is `null`.
29pub const subsystem: ?std.Target.SubSystem = blk: {29pub const subsystem: ?std.Target.SubSystem = blk: {
30 if (@hasDecl(builtin, "explicit_subsystem")) break :blk explicit_subsystem;30 if (@hasDecl(builtin, "explicit_subsystem")) break :blk builtin.explicit_subsystem;
31 switch (os.tag) {31 switch (os.tag) {
32 .windows => {32 .windows => {
33 if (is_test) {33 if (is_test) {
lib/std/c.zig+185-234
...@@ -1,18 +1,45 @@...@@ -1,18 +1,45 @@
1const std = @import("std");1const std = @import("std");
2const builtin = std.builtin;2const builtin = std.builtin;
3const c = @This();
3const page_size = std.mem.page_size;4const page_size = std.mem.page_size;
5const iovec = std.os.iovec;
6const iovec_const = std.os.iovec_const;
7
8test {
9 _ = tokenizer;
10}
411
5pub const tokenizer = @import("c/tokenizer.zig");12pub const tokenizer = @import("c/tokenizer.zig");
6pub const Token = tokenizer.Token;13pub const Token = tokenizer.Token;
7pub const Tokenizer = tokenizer.Tokenizer;14pub const Tokenizer = tokenizer.Tokenizer;
815
9test {16/// The return type is `type` to force comptime function call execution.
10 _ = tokenizer;17/// TODO: https://github.com/ziglang/zig/issues/425
18/// If not linking libc, returns struct{pub const ok = false;}
19/// If linking musl libc, returns struct{pub const ok = true;}
20/// If linking gnu libc (glibc), the `ok` value will be true if the target
21/// version is greater than or equal to `glibc_version`.
22/// If linking a libc other than these, returns `false`.
23pub fn versionCheck(glibc_version: builtin.Version) type {
24 return struct {
25 pub const ok = blk: {
26 if (!builtin.link_libc) break :blk false;
27 if (builtin.abi.isMusl()) break :blk true;
28 if (builtin.target.isGnuLibC()) {
29 const ver = builtin.os.version_range.linux.glibc;
30 const order = ver.order(glibc_version);
31 break :blk switch (order) {
32 .gt, .eq => true,
33 .lt => false,
34 };
35 } else {
36 break :blk false;
37 }
38 };
39 };
11}40}
1241
13pub usingnamespace @import("os/bits.zig");42pub usingnamespace switch (builtin.os.tag) {
14
15pub usingnamespace switch (std.Target.current.os.tag) {
16 .linux => @import("c/linux.zig"),43 .linux => @import("c/linux.zig"),
17 .windows => @import("c/windows.zig"),44 .windows => @import("c/windows.zig"),
18 .macos, .ios, .tvos, .watchos => @import("c/darwin.zig"),45 .macos, .ios, .tvos, .watchos => @import("c/darwin.zig"),
...@@ -30,40 +57,44 @@ pub usingnamespace switch (std.Target.current.os.tag) {...@@ -30,40 +57,44 @@ pub usingnamespace switch (std.Target.current.os.tag) {
30 else => struct {},57 else => struct {},
31};58};
3259
33pub fn getErrno(rc: anytype) E {60pub const whence_t = if (builtin.os.tag == .wasi) std.os.wasi.whence_t else c_int;
61
62pub usingnamespace switch (builtin.os.tag) {
63 .netbsd, .macos, .ios, .watchos, .tvos, .windows => struct {},
64 else => struct {
65 pub extern "c" fn clock_getres(clk_id: c_int, tp: *c.timespec) c_int;
66 pub extern "c" fn clock_gettime(clk_id: c_int, tp: *c.timespec) c_int;
67 pub extern "c" fn fstat(fd: c.fd_t, buf: *c.Stat) c_int;
68 pub extern "c" fn getrusage(who: c_int, usage: *c.rusage) c_int;
69 pub extern "c" fn gettimeofday(noalias tv: ?*c.timeval, noalias tz: ?*c.timezone) c_int;
70 pub extern "c" fn nanosleep(rqtp: *const c.timespec, rmtp: ?*c.timespec) c_int;
71 pub extern "c" fn sched_yield() c_int;
72 pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const c.Sigaction, noalias oact: ?*c.Sigaction) c_int;
73 pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const c.sigset_t, noalias oset: ?*c.sigset_t) c_int;
74 pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
75 pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *c.Stat) c_int;
76 pub extern "c" fn sigfillset(set: ?*c.sigset_t) void;
77 pub extern "c" fn alarm(seconds: c_uint) c_uint;
78 pub extern "c" fn sigwait(set: ?*c.sigset_t, sig: ?*c_int) c_int;
79 },
80};
81
82pub usingnamespace switch (builtin.os.tag) {
83 .macos, .ios, .watchos, .tvos => struct {},
84 else => struct {
85 pub extern "c" fn realpath(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;
86 pub extern "c" fn fstatat(dirfd: c.fd_t, path: [*:0]const u8, stat_buf: *c.Stat, flags: u32) c_int;
87 },
88};
89
90pub fn getErrno(rc: anytype) c.E {
34 if (rc == -1) {91 if (rc == -1) {
35 return @intToEnum(E, _errno().*);92 return @intToEnum(c.E, c._errno().*);
36 } else {93 } else {
37 return .SUCCESS;94 return .SUCCESS;
38 }95 }
39}96}
4097
41/// The return type is `type` to force comptime function call execution.
42/// TODO: https://github.com/ziglang/zig/issues/425
43/// If not linking libc, returns struct{pub const ok = false;}
44/// If linking musl libc, returns struct{pub const ok = true;}
45/// If linking gnu libc (glibc), the `ok` value will be true if the target
46/// version is greater than or equal to `glibc_version`.
47/// If linking a libc other than these, returns `false`.
48pub fn versionCheck(glibc_version: builtin.Version) type {
49 return struct {
50 pub const ok = blk: {
51 if (!builtin.link_libc) break :blk false;
52 if (std.Target.current.abi.isMusl()) break :blk true;
53 if (std.Target.current.isGnuLibC()) {
54 const ver = std.Target.current.os.version_range.linux.glibc;
55 const order = ver.order(glibc_version);
56 break :blk switch (order) {
57 .gt, .eq => true,
58 .lt => false,
59 };
60 } else {
61 break :blk false;
62 }
63 };
64 };
65}
66
67pub extern "c" var environ: [*:null]?[*:0]u8;98pub extern "c" var environ: [*:null]?[*:0]u8;
6899
69pub extern "c" fn fopen(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE;100pub extern "c" fn fopen(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE;
...@@ -75,255 +106,175 @@ pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;...@@ -75,255 +106,175 @@ pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
75pub extern "c" fn abort() noreturn;106pub extern "c" fn abort() noreturn;
76pub extern "c" fn exit(code: c_int) noreturn;107pub extern "c" fn exit(code: c_int) noreturn;
77pub extern "c" fn _exit(code: c_int) noreturn;108pub extern "c" fn _exit(code: c_int) noreturn;
78pub extern "c" fn isatty(fd: fd_t) c_int;109pub extern "c" fn isatty(fd: c.fd_t) c_int;
79pub extern "c" fn close(fd: fd_t) c_int;110pub extern "c" fn close(fd: c.fd_t) c_int;
80pub extern "c" fn lseek(fd: fd_t, offset: off_t, whence: c_int) off_t;111pub extern "c" fn lseek(fd: c.fd_t, offset: c.off_t, whence: whence_t) c.off_t;
81pub extern "c" fn open(path: [*:0]const u8, oflag: c_uint, ...) c_int;112pub extern "c" fn open(path: [*:0]const u8, oflag: c_uint, ...) c_int;
82pub extern "c" fn openat(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int;113pub extern "c" fn openat(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int;
83pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int;114pub extern "c" fn ftruncate(fd: c_int, length: c.off_t) c_int;
84pub extern "c" fn raise(sig: c_int) c_int;115pub extern "c" fn raise(sig: c_int) c_int;
85pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;116pub extern "c" fn read(fd: c.fd_t, buf: [*]u8, nbyte: usize) isize;
86pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;117pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;
87pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: off_t) isize;118pub extern "c" fn pread(fd: c.fd_t, buf: [*]u8, nbyte: usize, offset: c.off_t) isize;
88pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: off_t) isize;119pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: c.off_t) isize;
89pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize;120pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize;
90pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize;121pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: c.off_t) isize;
91pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;122pub extern "c" fn write(fd: c.fd_t, buf: [*]const u8, nbyte: usize) isize;
92pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize;123pub extern "c" fn pwrite(fd: c.fd_t, buf: [*]const u8, nbyte: usize, offset: c.off_t) isize;
93pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: off_t) *c_void;124pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: c.fd_t, offset: c.off_t) *c_void;
94pub extern "c" fn munmap(addr: *align(page_size) const c_void, len: usize) c_int;125pub extern "c" fn munmap(addr: *align(page_size) const c_void, len: usize) c_int;
95pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;126pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
96pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;127pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;
97pub extern "c" fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: c_int) c_int;128pub extern "c" fn linkat(oldfd: c.fd_t, oldpath: [*:0]const u8, newfd: c.fd_t, newpath: [*:0]const u8, flags: c_int) c_int;
98pub extern "c" fn unlink(path: [*:0]const u8) c_int;129pub extern "c" fn unlink(path: [*:0]const u8) c_int;
99pub extern "c" fn unlinkat(dirfd: fd_t, path: [*:0]const u8, flags: c_uint) c_int;130pub extern "c" fn unlinkat(dirfd: c.fd_t, path: [*:0]const u8, flags: c_uint) c_int;
100pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;131pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
101pub extern "c" fn waitpid(pid: pid_t, stat_loc: ?*c_int, options: c_int) pid_t;132pub extern "c" fn waitpid(pid: c.pid_t, stat_loc: ?*c_int, options: c_int) c.pid_t;
102pub extern "c" fn fork() c_int;133pub extern "c" fn fork() c_int;
103pub extern "c" fn access(path: [*:0]const u8, mode: c_uint) c_int;134pub extern "c" fn access(path: [*:0]const u8, mode: c_uint) c_int;
104pub extern "c" fn faccessat(dirfd: fd_t, path: [*:0]const u8, mode: c_uint, flags: c_uint) c_int;135pub extern "c" fn faccessat(dirfd: c.fd_t, path: [*:0]const u8, mode: c_uint, flags: c_uint) c_int;
105pub extern "c" fn pipe(fds: *[2]fd_t) c_int;136pub extern "c" fn pipe(fds: *[2]c.fd_t) c_int;
106pub extern "c" fn mkdir(path: [*:0]const u8, mode: c_uint) c_int;137pub extern "c" fn mkdir(path: [*:0]const u8, mode: c_uint) c_int;
107pub extern "c" fn mkdirat(dirfd: fd_t, path: [*:0]const u8, mode: u32) c_int;138pub extern "c" fn mkdirat(dirfd: c.fd_t, path: [*:0]const u8, mode: u32) c_int;
108pub extern "c" fn symlink(existing: [*:0]const u8, new: [*:0]const u8) c_int;139pub extern "c" fn symlink(existing: [*:0]const u8, new: [*:0]const u8) c_int;
109pub extern "c" fn symlinkat(oldpath: [*:0]const u8, newdirfd: fd_t, newpath: [*:0]const u8) c_int;140pub extern "c" fn symlinkat(oldpath: [*:0]const u8, newdirfd: c.fd_t, newpath: [*:0]const u8) c_int;
110pub extern "c" fn rename(old: [*:0]const u8, new: [*:0]const u8) c_int;141pub extern "c" fn rename(old: [*:0]const u8, new: [*:0]const u8) c_int;
111pub extern "c" fn renameat(olddirfd: fd_t, old: [*:0]const u8, newdirfd: fd_t, new: [*:0]const u8) c_int;142pub extern "c" fn renameat(olddirfd: c.fd_t, old: [*:0]const u8, newdirfd: c.fd_t, new: [*:0]const u8) c_int;
112pub extern "c" fn chdir(path: [*:0]const u8) c_int;143pub extern "c" fn chdir(path: [*:0]const u8) c_int;
113pub extern "c" fn fchdir(fd: fd_t) c_int;144pub extern "c" fn fchdir(fd: c.fd_t) c_int;
114pub extern "c" fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) c_int;145pub extern "c" fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) c_int;
115pub extern "c" fn dup(fd: fd_t) c_int;146pub extern "c" fn dup(fd: c.fd_t) c_int;
116pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int;147pub extern "c" fn dup2(old_fd: c.fd_t, new_fd: c.fd_t) c_int;
117pub extern "c" fn readlink(noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize;148pub extern "c" fn readlink(noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize;
118pub extern "c" fn readlinkat(dirfd: fd_t, noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize;149pub extern "c" fn readlinkat(dirfd: c.fd_t, noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize;
119
120pub usingnamespace switch (builtin.os.tag) {
121 .macos, .ios, .watchos, .tvos => struct {
122 pub const realpath = @"realpath$DARWIN_EXTSN";
123 pub const fstatat = _fstatat;
124 },
125 else => struct {
126 pub extern "c" fn realpath(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;
127 pub extern "c" fn fstatat(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int;
128 },
129};
130150
131pub extern "c" fn rmdir(path: [*:0]const u8) c_int;151pub extern "c" fn rmdir(path: [*:0]const u8) c_int;
132pub extern "c" fn getenv(name: [*:0]const u8) ?[*:0]u8;152pub extern "c" fn getenv(name: [*:0]const u8) ?[*:0]u8;
133pub extern "c" fn sysctl(name: [*]const c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;153pub extern "c" fn sysctl(name: [*]const c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
134pub extern "c" fn sysctlbyname(name: [*:0]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;154pub extern "c" fn sysctlbyname(name: [*:0]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
135pub extern "c" fn sysctlnametomib(name: [*:0]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;155pub extern "c" fn sysctlnametomib(name: [*:0]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;
136pub extern "c" fn tcgetattr(fd: fd_t, termios_p: *termios) c_int;156pub extern "c" fn tcgetattr(fd: c.fd_t, termios_p: *c.termios) c_int;
137pub extern "c" fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) c_int;157pub extern "c" fn tcsetattr(fd: c.fd_t, optional_action: c.TCSA, termios_p: *const c.termios) c_int;
138pub extern "c" fn fcntl(fd: fd_t, cmd: c_int, ...) c_int;158pub extern "c" fn fcntl(fd: c.fd_t, cmd: c_int, ...) c_int;
139pub extern "c" fn flock(fd: fd_t, operation: c_int) c_int;159pub extern "c" fn flock(fd: c.fd_t, operation: c_int) c_int;
140pub extern "c" fn ioctl(fd: fd_t, request: c_int, ...) c_int;160pub extern "c" fn ioctl(fd: c.fd_t, request: c_int, ...) c_int;
141pub extern "c" fn uname(buf: *utsname) c_int;161pub extern "c" fn uname(buf: *c.utsname) c_int;
142162
143pub extern "c" fn gethostname(name: [*]u8, len: usize) c_int;163pub extern "c" fn gethostname(name: [*]u8, len: usize) c_int;
144pub extern "c" fn shutdown(socket: fd_t, how: c_int) c_int;164pub extern "c" fn shutdown(socket: c.fd_t, how: c_int) c_int;
145pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int;165pub extern "c" fn bind(socket: c.fd_t, address: ?*const c.sockaddr, address_len: c.socklen_t) c_int;
146pub extern "c" fn socketpair(domain: c_uint, sock_type: c_uint, protocol: c_uint, sv: *[2]fd_t) c_int;166pub extern "c" fn socketpair(domain: c_uint, sock_type: c_uint, protocol: c_uint, sv: *[2]c.fd_t) c_int;
147pub extern "c" fn listen(sockfd: fd_t, backlog: c_uint) c_int;167pub extern "c" fn listen(sockfd: c.fd_t, backlog: c_uint) c_int;
148pub extern "c" fn getsockname(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;168pub extern "c" fn getsockname(sockfd: c.fd_t, noalias addr: *c.sockaddr, noalias addrlen: *c.socklen_t) c_int;
149pub extern "c" fn getpeername(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;169pub extern "c" fn getpeername(sockfd: c.fd_t, noalias addr: *c.sockaddr, noalias addrlen: *c.socklen_t) c_int;
150pub extern "c" fn connect(sockfd: fd_t, sock_addr: *const sockaddr, addrlen: socklen_t) c_int;170pub extern "c" fn connect(sockfd: c.fd_t, sock_addr: *const c.sockaddr, addrlen: c.socklen_t) c_int;
151pub extern "c" fn accept(sockfd: fd_t, noalias addr: ?*sockaddr, noalias addrlen: ?*socklen_t) c_int;171pub extern "c" fn accept(sockfd: c.fd_t, noalias addr: ?*c.sockaddr, noalias addrlen: ?*c.socklen_t) c_int;
152pub extern "c" fn accept4(sockfd: fd_t, noalias addr: ?*sockaddr, noalias addrlen: ?*socklen_t, flags: c_uint) c_int;172pub extern "c" fn accept4(sockfd: c.fd_t, noalias addr: ?*c.sockaddr, noalias addrlen: ?*c.socklen_t, flags: c_uint) c_int;
153pub extern "c" fn getsockopt(sockfd: fd_t, level: u32, optname: u32, noalias optval: ?*c_void, noalias optlen: *socklen_t) c_int;173pub extern "c" fn getsockopt(sockfd: c.fd_t, level: u32, optname: u32, noalias optval: ?*c_void, noalias optlen: *c.socklen_t) c_int;
154pub extern "c" fn setsockopt(sockfd: fd_t, level: u32, optname: u32, optval: ?*const c_void, optlen: socklen_t) c_int;174pub extern "c" fn setsockopt(sockfd: c.fd_t, level: u32, optname: u32, optval: ?*const c_void, optlen: c.socklen_t) c_int;
155pub extern "c" fn send(sockfd: fd_t, buf: *const c_void, len: usize, flags: u32) isize;175pub extern "c" fn send(sockfd: c.fd_t, buf: *const c_void, len: usize, flags: u32) isize;
156pub extern "c" fn sendto(176pub extern "c" fn sendto(
157 sockfd: fd_t,177 sockfd: c.fd_t,
158 buf: *const c_void,178 buf: *const c_void,
159 len: usize,179 len: usize,
160 flags: u32,180 flags: u32,
161 dest_addr: ?*const sockaddr,181 dest_addr: ?*const c.sockaddr,
162 addrlen: socklen_t,182 addrlen: c.socklen_t,
163) isize;183) isize;
164pub extern "c" fn sendmsg(sockfd: fd_t, msg: *const std.x.os.Socket.Message, flags: c_int) isize;184pub extern "c" fn sendmsg(sockfd: c.fd_t, msg: *const std.x.os.Socket.Message, flags: c_int) isize;
165185
166pub extern "c" fn recv(sockfd: fd_t, arg1: ?*c_void, arg2: usize, arg3: c_int) isize;186pub extern "c" fn recv(sockfd: c.fd_t, arg1: ?*c_void, arg2: usize, arg3: c_int) isize;
167pub extern "c" fn recvfrom(187pub extern "c" fn recvfrom(
168 sockfd: fd_t,188 sockfd: c.fd_t,
169 noalias buf: *c_void,189 noalias buf: *c_void,
170 len: usize,190 len: usize,
171 flags: u32,191 flags: u32,
172 noalias src_addr: ?*sockaddr,192 noalias src_addr: ?*c.sockaddr,
173 noalias addrlen: ?*socklen_t,193 noalias addrlen: ?*c.socklen_t,
174) isize;194) isize;
175pub extern "c" fn recvmsg(sockfd: fd_t, msg: *std.x.os.Socket.Message, flags: c_int) isize;195pub extern "c" fn recvmsg(sockfd: c.fd_t, msg: *std.x.os.Socket.Message, flags: c_int) isize;
176
177pub usingnamespace switch (builtin.os.tag) {
178 .netbsd => struct {
179 pub const clock_getres = __clock_getres50;
180 pub const clock_gettime = __clock_gettime50;
181 pub const fstat = __fstat50;
182 pub const getdents = __getdents30;
183 pub const getrusage = __getrusage50;
184 pub const gettimeofday = __gettimeofday50;
185 pub const nanosleep = __nanosleep50;
186 pub const sched_yield = __libc_thr_yield;
187 pub const sigaction = __sigaction14;
188 pub const sigaltstack = __sigaltstack14;
189 pub const sigprocmask = __sigprocmask14;
190 pub const socket = __socket30;
191 pub const stat = __stat50;
192 },
193 .macos, .ios, .watchos, .tvos => struct {
194 // XXX: close -> close$NOCANCEL
195 // XXX: getdirentries -> _getdirentries64
196 pub extern "c" fn clock_getres(clk_id: c_int, tp: *timespec) c_int;
197 pub extern "c" fn clock_gettime(clk_id: c_int, tp: *timespec) c_int;
198 pub const fstat = _fstat;
199 pub extern "c" fn getrusage(who: c_int, usage: *rusage) c_int;
200 pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
201 pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;
202 pub extern "c" fn sched_yield() c_int;
203 pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
204 pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
205 pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
206 pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int;
207 pub extern "c" fn sigfillset(set: ?*sigset_t) void;
208 pub extern "c" fn alarm(seconds: c_uint) c_uint;
209 pub extern "c" fn sigwait(set: ?*sigset_t, sig: ?*c_int) c_int;
210 },
211 .windows => struct {
212 // TODO: copied the else case and removed the socket function (because its in ws2_32)
213 // need to verify which of these is actually supported on windows
214 pub extern "c" fn clock_getres(clk_id: c_int, tp: *timespec) c_int;
215 pub extern "c" fn clock_gettime(clk_id: c_int, tp: *timespec) c_int;
216 pub extern "c" fn fstat(fd: fd_t, buf: *libc_stat) c_int;
217 pub extern "c" fn getrusage(who: c_int, usage: *rusage) c_int;
218 pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
219 pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;
220 pub extern "c" fn sched_yield() c_int;
221 pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
222 pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
223 pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int;
224 pub extern "c" fn sigfillset(set: ?*sigset_t) void;
225 pub extern "c" fn alarm(seconds: c_uint) c_uint;
226 pub extern "c" fn sigwait(set: ?*sigset_t, sig: ?*c_int) c_int;
227 },
228 else => struct {
229 pub extern "c" fn clock_getres(clk_id: c_int, tp: *timespec) c_int;
230 pub extern "c" fn clock_gettime(clk_id: c_int, tp: *timespec) c_int;
231 pub extern "c" fn fstat(fd: fd_t, buf: *libc_stat) c_int;
232 pub extern "c" fn getrusage(who: c_int, usage: *rusage) c_int;
233 pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
234 pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;
235 pub extern "c" fn sched_yield() c_int;
236 pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
237 pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
238 pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
239 pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int;
240 pub extern "c" fn sigfillset(set: ?*sigset_t) void;
241 pub extern "c" fn alarm(seconds: c_uint) c_uint;
242 pub extern "c" fn sigwait(set: ?*sigset_t, sig: ?*c_int) c_int;
243 },
244};
245196
246pub extern "c" fn kill(pid: pid_t, sig: c_int) c_int;197pub extern "c" fn kill(pid: c.pid_t, sig: c_int) c_int;
247pub extern "c" fn getdirentries(fd: fd_t, buf_ptr: [*]u8, nbytes: usize, basep: *i64) isize;198pub extern "c" fn getdirentries(fd: c.fd_t, buf_ptr: [*]u8, nbytes: usize, basep: *i64) isize;
248199
249pub extern "c" fn setuid(uid: uid_t) c_int;200pub extern "c" fn setuid(uid: c.uid_t) c_int;
250pub extern "c" fn setgid(gid: gid_t) c_int;201pub extern "c" fn setgid(gid: c.gid_t) c_int;
251pub extern "c" fn seteuid(euid: uid_t) c_int;202pub extern "c" fn seteuid(euid: c.uid_t) c_int;
252pub extern "c" fn setegid(egid: gid_t) c_int;203pub extern "c" fn setegid(egid: c.gid_t) c_int;
253pub extern "c" fn setreuid(ruid: uid_t, euid: uid_t) c_int;204pub extern "c" fn setreuid(ruid: c.uid_t, euid: c.uid_t) c_int;
254pub extern "c" fn setregid(rgid: gid_t, egid: gid_t) c_int;205pub extern "c" fn setregid(rgid: c.gid_t, egid: c.gid_t) c_int;
255pub extern "c" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) c_int;206pub extern "c" fn setresuid(ruid: c.uid_t, euid: c.uid_t, suid: c.uid_t) c_int;
256pub extern "c" fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) c_int;207pub extern "c" fn setresgid(rgid: c.gid_t, egid: c.gid_t, sgid: c.gid_t) c_int;
257208
258pub extern "c" fn malloc(usize) ?*c_void;209pub extern "c" fn malloc(usize) ?*c_void;
259pub extern "c" fn realloc(?*c_void, usize) ?*c_void;210pub extern "c" fn realloc(?*c_void, usize) ?*c_void;
260pub extern "c" fn free(?*c_void) void;211pub extern "c" fn free(?*c_void) void;
261212
262pub extern "c" fn futimes(fd: fd_t, times: *[2]timeval) c_int;213pub extern "c" fn futimes(fd: c.fd_t, times: *[2]c.timeval) c_int;
263pub extern "c" fn utimes(path: [*:0]const u8, times: *[2]timeval) c_int;214pub extern "c" fn utimes(path: [*:0]const u8, times: *[2]c.timeval) c_int;
264215
265pub extern "c" fn utimensat(dirfd: fd_t, pathname: [*:0]const u8, times: *[2]timespec, flags: u32) c_int;216pub extern "c" fn utimensat(dirfd: c.fd_t, pathname: [*:0]const u8, times: *[2]c.timespec, flags: u32) c_int;
266pub extern "c" fn futimens(fd: fd_t, times: *const [2]timespec) c_int;217pub extern "c" fn futimens(fd: c.fd_t, times: *const [2]c.timespec) c_int;
267218
268pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: fn (?*c_void) callconv(.C) ?*c_void, noalias arg: ?*c_void) E;219pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const c.pthread_attr_t, start_routine: fn (?*c_void) callconv(.C) ?*c_void, noalias arg: ?*c_void) c.E;
269pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) E;220pub extern "c" fn pthread_attr_init(attr: *c.pthread_attr_t) c.E;
270pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) E;221pub extern "c" fn pthread_attr_setstack(attr: *c.pthread_attr_t, stackaddr: *c_void, stacksize: usize) c.E;
271pub extern "c" fn pthread_attr_setstacksize(attr: *pthread_attr_t, stacksize: usize) E;222pub extern "c" fn pthread_attr_setstacksize(attr: *c.pthread_attr_t, stacksize: usize) c.E;
272pub extern "c" fn pthread_attr_setguardsize(attr: *pthread_attr_t, guardsize: usize) E;223pub extern "c" fn pthread_attr_setguardsize(attr: *c.pthread_attr_t, guardsize: usize) c.E;
273pub extern "c" fn pthread_attr_destroy(attr: *pthread_attr_t) E;224pub extern "c" fn pthread_attr_destroy(attr: *c.pthread_attr_t) c.E;
274pub extern "c" fn pthread_self() pthread_t;225pub extern "c" fn pthread_self() pthread_t;
275pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) E;226pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c.E;
276pub extern "c" fn pthread_detach(thread: pthread_t) E;227pub extern "c" fn pthread_detach(thread: pthread_t) c.E;
277pub extern "c" fn pthread_atfork(228pub extern "c" fn pthread_atfork(
278 prepare: ?fn () callconv(.C) void,229 prepare: ?fn () callconv(.C) void,
279 parent: ?fn () callconv(.C) void,230 parent: ?fn () callconv(.C) void,
280 child: ?fn () callconv(.C) void,231 child: ?fn () callconv(.C) void,
281) c_int;232) c_int;
282pub extern "c" fn pthread_key_create(key: *pthread_key_t, destructor: ?fn (value: *c_void) callconv(.C) void) E;233pub extern "c" fn pthread_key_create(key: *c.pthread_key_t, destructor: ?fn (value: *c_void) callconv(.C) void) c.E;
283pub extern "c" fn pthread_key_delete(key: pthread_key_t) E;234pub extern "c" fn pthread_key_delete(key: c.pthread_key_t) c.E;
284pub extern "c" fn pthread_getspecific(key: pthread_key_t) ?*c_void;235pub extern "c" fn pthread_getspecific(key: c.pthread_key_t) ?*c_void;
285pub extern "c" fn pthread_setspecific(key: pthread_key_t, value: ?*c_void) c_int;236pub extern "c" fn pthread_setspecific(key: c.pthread_key_t, value: ?*c_void) c_int;
286pub extern "c" fn sem_init(sem: *sem_t, pshared: c_int, value: c_uint) c_int;237pub extern "c" fn sem_init(sem: *c.sem_t, pshared: c_int, value: c_uint) c_int;
287pub extern "c" fn sem_destroy(sem: *sem_t) c_int;238pub extern "c" fn sem_destroy(sem: *c.sem_t) c_int;
288pub extern "c" fn sem_post(sem: *sem_t) c_int;239pub extern "c" fn sem_post(sem: *c.sem_t) c_int;
289pub extern "c" fn sem_wait(sem: *sem_t) c_int;240pub extern "c" fn sem_wait(sem: *c.sem_t) c_int;
290pub extern "c" fn sem_trywait(sem: *sem_t) c_int;241pub extern "c" fn sem_trywait(sem: *c.sem_t) c_int;
291pub extern "c" fn sem_timedwait(sem: *sem_t, abs_timeout: *const timespec) c_int;242pub extern "c" fn sem_timedwait(sem: *c.sem_t, abs_timeout: *const c.timespec) c_int;
292pub extern "c" fn sem_getvalue(sem: *sem_t, sval: *c_int) c_int;243pub extern "c" fn sem_getvalue(sem: *c.sem_t, sval: *c_int) c_int;
293244
294pub extern "c" fn kqueue() c_int;245pub extern "c" fn kqueue() c_int;
295pub extern "c" fn kevent(246pub extern "c" fn kevent(
296 kq: c_int,247 kq: c_int,
297 changelist: [*]const Kevent,248 changelist: [*]const c.Kevent,
298 nchanges: c_int,249 nchanges: c_int,
299 eventlist: [*]Kevent,250 eventlist: [*]c.Kevent,
300 nevents: c_int,251 nevents: c_int,
301 timeout: ?*const timespec,252 timeout: ?*const c.timespec,
302) c_int;253) c_int;
303254
304pub extern "c" fn getaddrinfo(255pub extern "c" fn getaddrinfo(
305 noalias node: ?[*:0]const u8,256 noalias node: ?[*:0]const u8,
306 noalias service: ?[*:0]const u8,257 noalias service: ?[*:0]const u8,
307 noalias hints: ?*const addrinfo,258 noalias hints: ?*const c.addrinfo,
308 noalias res: **addrinfo,259 noalias res: **c.addrinfo,
309) EAI;260) c.EAI;
310261
311pub extern "c" fn freeaddrinfo(res: *addrinfo) void;262pub extern "c" fn freeaddrinfo(res: *c.addrinfo) void;
312263
313pub extern "c" fn getnameinfo(264pub extern "c" fn getnameinfo(
314 noalias addr: *const sockaddr,265 noalias addr: *const c.sockaddr,
315 addrlen: socklen_t,266 addrlen: c.socklen_t,
316 noalias host: [*]u8,267 noalias host: [*]u8,
317 hostlen: socklen_t,268 hostlen: c.socklen_t,
318 noalias serv: [*]u8,269 noalias serv: [*]u8,
319 servlen: socklen_t,270 servlen: c.socklen_t,
320 flags: u32,271 flags: u32,
321) EAI;272) c.EAI;
322273
323pub extern "c" fn gai_strerror(errcode: EAI) [*:0]const u8;274pub extern "c" fn gai_strerror(errcode: c.EAI) [*:0]const u8;
324275
325pub extern "c" fn poll(fds: [*]pollfd, nfds: nfds_t, timeout: c_int) c_int;276pub extern "c" fn poll(fds: [*]c.pollfd, nfds: c.nfds_t, timeout: c_int) c_int;
326pub extern "c" fn ppoll(fds: [*]pollfd, nfds: nfds_t, timeout: ?*const timespec, sigmask: ?*const sigset_t) c_int;277pub extern "c" fn ppoll(fds: [*]c.pollfd, nfds: c.nfds_t, timeout: ?*const c.timespec, sigmask: ?*const c.sigset_t) c_int;
327278
328pub extern "c" fn dn_expand(279pub extern "c" fn dn_expand(
329 msg: [*:0]const u8,280 msg: [*:0]const u8,
...@@ -333,25 +284,25 @@ pub extern "c" fn dn_expand(...@@ -333,25 +284,25 @@ pub extern "c" fn dn_expand(
333 length: c_int,284 length: c_int,
334) c_int;285) c_int;
335286
336pub const PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{};287pub const PTHREAD_MUTEX_INITIALIZER = c.pthread_mutex_t{};
337pub extern "c" fn pthread_mutex_lock(mutex: *pthread_mutex_t) E;288pub extern "c" fn pthread_mutex_lock(mutex: *c.pthread_mutex_t) c.E;
338pub extern "c" fn pthread_mutex_unlock(mutex: *pthread_mutex_t) E;289pub extern "c" fn pthread_mutex_unlock(mutex: *c.pthread_mutex_t) c.E;
339pub extern "c" fn pthread_mutex_trylock(mutex: *pthread_mutex_t) E;290pub extern "c" fn pthread_mutex_trylock(mutex: *c.pthread_mutex_t) c.E;
340pub extern "c" fn pthread_mutex_destroy(mutex: *pthread_mutex_t) E;291pub extern "c" fn pthread_mutex_destroy(mutex: *c.pthread_mutex_t) c.E;
341292
342pub const PTHREAD_COND_INITIALIZER = pthread_cond_t{};293pub const PTHREAD_COND_INITIALIZER = c.pthread_cond_t{};
343pub extern "c" fn pthread_cond_wait(noalias cond: *pthread_cond_t, noalias mutex: *pthread_mutex_t) E;294pub extern "c" fn pthread_cond_wait(noalias cond: *c.pthread_cond_t, noalias mutex: *c.pthread_mutex_t) c.E;
344pub extern "c" fn pthread_cond_timedwait(noalias cond: *pthread_cond_t, noalias mutex: *pthread_mutex_t, noalias abstime: *const timespec) E;295pub extern "c" fn pthread_cond_timedwait(noalias cond: *c.pthread_cond_t, noalias mutex: *c.pthread_mutex_t, noalias abstime: *const c.timespec) c.E;
345pub extern "c" fn pthread_cond_signal(cond: *pthread_cond_t) E;296pub extern "c" fn pthread_cond_signal(cond: *c.pthread_cond_t) c.E;
346pub extern "c" fn pthread_cond_broadcast(cond: *pthread_cond_t) E;297pub extern "c" fn pthread_cond_broadcast(cond: *c.pthread_cond_t) c.E;
347pub extern "c" fn pthread_cond_destroy(cond: *pthread_cond_t) E;298pub extern "c" fn pthread_cond_destroy(cond: *c.pthread_cond_t) c.E;
348299
349pub extern "c" fn pthread_rwlock_destroy(rwl: *pthread_rwlock_t) callconv(.C) E;300pub extern "c" fn pthread_rwlock_destroy(rwl: *c.pthread_rwlock_t) callconv(.C) c.E;
350pub extern "c" fn pthread_rwlock_rdlock(rwl: *pthread_rwlock_t) callconv(.C) E;301pub extern "c" fn pthread_rwlock_rdlock(rwl: *c.pthread_rwlock_t) callconv(.C) c.E;
351pub extern "c" fn pthread_rwlock_wrlock(rwl: *pthread_rwlock_t) callconv(.C) E;302pub extern "c" fn pthread_rwlock_wrlock(rwl: *c.pthread_rwlock_t) callconv(.C) c.E;
352pub extern "c" fn pthread_rwlock_tryrdlock(rwl: *pthread_rwlock_t) callconv(.C) E;303pub extern "c" fn pthread_rwlock_tryrdlock(rwl: *c.pthread_rwlock_t) callconv(.C) c.E;
353pub extern "c" fn pthread_rwlock_trywrlock(rwl: *pthread_rwlock_t) callconv(.C) E;304pub extern "c" fn pthread_rwlock_trywrlock(rwl: *c.pthread_rwlock_t) callconv(.C) c.E;
354pub extern "c" fn pthread_rwlock_unlock(rwl: *pthread_rwlock_t) callconv(.C) E;305pub extern "c" fn pthread_rwlock_unlock(rwl: *c.pthread_rwlock_t) callconv(.C) c.E;
355306
356pub const pthread_t = *opaque {};307pub const pthread_t = *opaque {};
357pub const FILE = opaque {};308pub const FILE = opaque {};
...@@ -367,8 +318,8 @@ pub extern "c" fn fdatasync(fd: c_int) c_int;...@@ -367,8 +318,8 @@ pub extern "c" fn fdatasync(fd: c_int) c_int;
367318
368pub extern "c" fn prctl(option: c_int, ...) c_int;319pub extern "c" fn prctl(option: c_int, ...) c_int;
369320
370pub extern "c" fn getrlimit(resource: rlimit_resource, rlim: *rlimit) c_int;321pub extern "c" fn getrlimit(resource: c.rlimit_resource, rlim: *c.rlimit) c_int;
371pub extern "c" fn setrlimit(resource: rlimit_resource, rlim: *const rlimit) c_int;322pub extern "c" fn setrlimit(resource: c.rlimit_resource, rlim: *const c.rlimit) c_int;
372323
373pub extern "c" fn fmemopen(noalias buf: ?*c_void, size: usize, noalias mode: [*:0]const u8) ?*FILE;324pub extern "c" fn fmemopen(noalias buf: ?*c_void, size: usize, noalias mode: [*:0]const u8) ?*FILE;
374325
...@@ -377,9 +328,9 @@ pub extern "c" fn openlog(ident: [*:0]const u8, logopt: c_int, facility: c_int)...@@ -377,9 +328,9 @@ pub extern "c" fn openlog(ident: [*:0]const u8, logopt: c_int, facility: c_int)
377pub extern "c" fn closelog() void;328pub extern "c" fn closelog() void;
378pub extern "c" fn setlogmask(maskpri: c_int) c_int;329pub extern "c" fn setlogmask(maskpri: c_int) c_int;
379330
380pub const max_align_t = if (std.Target.current.abi == .msvc)331pub const max_align_t = if (builtin.abi == .msvc)
381 f64332 f64
382else if (std.Target.current.isDarwin())333else if (builtin.target.isDarwin())
383 c_longdouble334 c_longdouble
384else335else
385 extern struct {336 extern struct {
lib/std/c/darwin.zig+1750-25
...@@ -3,8 +3,8 @@ const assert = std.debug.assert;...@@ -3,8 +3,8 @@ const assert = std.debug.assert;
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const macho = std.macho;4const macho = std.macho;
5const native_arch = builtin.target.cpu.arch;5const native_arch = builtin.target.cpu.arch;
66const maxInt = std.math.maxInt;
7usingnamespace @import("../os/bits.zig");7const iovec_const = std.os.iovec_const;
88
9extern "c" fn __error() *c_int;9extern "c" fn __error() *c_int;
10pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;10pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;
...@@ -23,20 +23,25 @@ pub const copyfile_state_t = *opaque {};...@@ -23,20 +23,25 @@ pub const copyfile_state_t = *opaque {};
23pub extern "c" fn fcopyfile(from: fd_t, to: fd_t, state: ?copyfile_state_t, flags: u32) c_int;23pub extern "c" fn fcopyfile(from: fd_t, to: fd_t, state: ?copyfile_state_t, flags: u32) c_int;
2424
25pub extern "c" fn @"realpath$DARWIN_EXTSN"(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;25pub extern "c" fn @"realpath$DARWIN_EXTSN"(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;
26pub const realpath = @"realpath$DARWIN_EXTSN";
2627
27pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize;28pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize;
2829
29extern "c" fn fstat(fd: fd_t, buf: *libc_stat) c_int;30const private = struct {
30/// On x86_64 Darwin, fstat has to be manully linked with $INODE64 suffix to force 64bit version.31 extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int;
31/// Note that this is fixed on aarch64 and no longer necessary.32 /// On x86_64 Darwin, fstat has to be manully linked with $INODE64 suffix to
32extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *libc_stat) c_int;33 /// force 64bit version.
33pub const _fstat = if (native_arch == .aarch64) fstat else @"fstat$INODE64";34 /// Note that this is fixed on aarch64 and no longer necessary.
35 extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int;
3436
35extern "c" fn fstatat(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int;37 extern "c" fn fstatat(dirfd: fd_t, path: [*:0]const u8, stat_buf: *Stat, flags: u32) c_int;
36/// On x86_64 Darwin, fstatat has to be manully linked with $INODE64 suffix to force 64bit version.38 /// On x86_64 Darwin, fstatat has to be manully linked with $INODE64 suffix to
37/// Note that this is fixed on aarch64 and no longer necessary.39 /// force 64bit version.
38extern "c" fn @"fstatat$INODE64"(dirfd: fd_t, path_name: [*:0]const u8, buf: *libc_stat, flags: u32) c_int;40 /// Note that this is fixed on aarch64 and no longer necessary.
39pub const _fstatat = if (native_arch == .aarch64) fstatat else @"fstatat$INODE64";41 extern "c" fn @"fstatat$INODE64"(dirfd: fd_t, path_name: [*:0]const u8, buf: *Stat, flags: u32) c_int;
42};
43pub const fstat = if (native_arch == .aarch64) private.fstat else private.@"fstat$INODE64";
44pub const fstatat = if (native_arch == .aarch64) private.fstatat else private.@"fstatat$INODE64";
4045
41pub extern "c" fn mach_absolute_time() u64;46pub extern "c" fn mach_absolute_time() u64;
42pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) void;47pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) void;
...@@ -80,8 +85,6 @@ pub const _errno = __error;...@@ -80,8 +85,6 @@ pub const _errno = __error;
80pub extern "c" fn @"close$NOCANCEL"(fd: fd_t) c_int;85pub extern "c" fn @"close$NOCANCEL"(fd: fd_t) c_int;
81pub extern "c" fn mach_host_self() mach_port_t;86pub extern "c" fn mach_host_self() mach_port_t;
82pub extern "c" fn clock_get_time(clock_serv: clock_serv_t, cur_time: *mach_timespec_t) kern_return_t;87pub extern "c" fn clock_get_time(clock_serv: clock_serv_t, cur_time: *mach_timespec_t) kern_return_t;
83pub extern "c" fn host_get_clock_service(host: host_t, clock_id: clock_id_t, clock_serv: ?[*]clock_serv_t) kern_return_t;
84pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t) kern_return_t;
8588
86pub const sf_hdtr = extern struct {89pub const sf_hdtr = extern struct {
87 headers: [*]const iovec_const,90 headers: [*]const iovec_const,
...@@ -105,17 +108,16 @@ pub fn sigaddset(set: *sigset_t, signo: u5) void {...@@ -105,17 +108,16 @@ pub fn sigaddset(set: *sigset_t, signo: u5) void {
105108
106pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;109pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
107110
108/// get address to use bind()111pub const AI = struct {
109pub const AI_PASSIVE = 0x00000001;112 /// get address to use bind()
110113 pub const PASSIVE = 0x00000001;
111/// fill ai_canonname114 /// fill ai_canonname
112pub const AI_CANONNAME = 0x00000002;115 pub const CANONNAME = 0x00000002;
113116 /// prevent host name resolution
114/// prevent host name resolution117 pub const NUMERICHOST = 0x00000004;
115pub const AI_NUMERICHOST = 0x00000004;118 /// prevent service name resolution
116119 pub const NUMERICSERV = 0x00001000;
117/// prevent service name resolution120};
118pub const AI_NUMERICSERV = 0x00001000;
119121
120pub const EAI = enum(c_int) {122pub const EAI = enum(c_int) {
121 /// address family for hostname not supported123 /// address family for hostname not supported
...@@ -256,3 +258,1726 @@ pub extern "c" fn os_unfair_lock_unlock(o: os_unfair_lock_t) void;...@@ -256,3 +258,1726 @@ pub extern "c" fn os_unfair_lock_unlock(o: os_unfair_lock_t) void;
256pub extern "c" fn os_unfair_lock_trylock(o: os_unfair_lock_t) bool;258pub extern "c" fn os_unfair_lock_trylock(o: os_unfair_lock_t) bool;
257pub extern "c" fn os_unfair_lock_assert_owner(o: os_unfair_lock_t) void;259pub extern "c" fn os_unfair_lock_assert_owner(o: os_unfair_lock_t) void;
258pub extern "c" fn os_unfair_lock_assert_not_owner(o: os_unfair_lock_t) void;260pub extern "c" fn os_unfair_lock_assert_not_owner(o: os_unfair_lock_t) void;
261
262// XXX: close -> close$NOCANCEL
263// XXX: getdirentries -> _getdirentries64
264pub extern "c" fn clock_getres(clk_id: c_int, tp: *timespec) c_int;
265pub extern "c" fn clock_gettime(clk_id: c_int, tp: *timespec) c_int;
266pub extern "c" fn getrusage(who: c_int, usage: *rusage) c_int;
267pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
268pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;
269pub extern "c" fn sched_yield() c_int;
270pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
271pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
272pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
273pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *Stat) c_int;
274pub extern "c" fn sigfillset(set: ?*sigset_t) void;
275pub extern "c" fn alarm(seconds: c_uint) c_uint;
276pub extern "c" fn sigwait(set: ?*sigset_t, sig: ?*c_int) c_int;
277
278// See: https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/sys/_types.h.auto.html
279// TODO: audit mode_t/pid_t, should likely be u16/i32
280pub const fd_t = c_int;
281pub const pid_t = c_int;
282pub const mode_t = c_uint;
283pub const uid_t = u32;
284pub const gid_t = u32;
285
286pub const in_port_t = u16;
287pub const sa_family_t = u8;
288pub const socklen_t = u32;
289pub const sockaddr = extern struct {
290 len: u8,
291 family: sa_family_t,
292 data: [14]u8,
293
294 pub const storage = std.x.os.Socket.Address.Native.Storage;
295 pub const in = extern struct {
296 len: u8 = @sizeOf(in),
297 family: sa_family_t = AF.INET,
298 port: in_port_t,
299 addr: u32,
300 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
301 };
302 pub const in6 = extern struct {
303 len: u8 = @sizeOf(in6),
304 family: sa_family_t = AF.INET6,
305 port: in_port_t,
306 flowinfo: u32,
307 addr: [16]u8,
308 scope_id: u32,
309 };
310
311 /// UNIX domain socket
312 pub const un = extern struct {
313 len: u8 = @sizeOf(un),
314 family: sa_family_t = AF.UNIX,
315 path: [104]u8,
316 };
317};
318pub const timeval = extern struct {
319 tv_sec: c_long,
320 tv_usec: i32,
321};
322
323pub const timezone = extern struct {
324 tz_minuteswest: i32,
325 tz_dsttime: i32,
326};
327
328pub const mach_timebase_info_data = extern struct {
329 numer: u32,
330 denom: u32,
331};
332
333pub const off_t = i64;
334pub const ino_t = u64;
335
336pub const Flock = extern struct {
337 l_start: off_t,
338 l_len: off_t,
339 l_pid: pid_t,
340 l_type: i16,
341 l_whence: i16,
342};
343
344pub const Stat = extern struct {
345 dev: i32,
346 mode: u16,
347 nlink: u16,
348 ino: ino_t,
349 uid: uid_t,
350 gid: gid_t,
351 rdev: i32,
352 atimesec: isize,
353 atimensec: isize,
354 mtimesec: isize,
355 mtimensec: isize,
356 ctimesec: isize,
357 ctimensec: isize,
358 birthtimesec: isize,
359 birthtimensec: isize,
360 size: off_t,
361 blocks: i64,
362 blksize: i32,
363 flags: u32,
364 gen: u32,
365 lspare: i32,
366 qspare: [2]i64,
367
368 pub fn atime(self: @This()) timespec {
369 return timespec{
370 .tv_sec = self.atimesec,
371 .tv_nsec = self.atimensec,
372 };
373 }
374
375 pub fn mtime(self: @This()) timespec {
376 return timespec{
377 .tv_sec = self.mtimesec,
378 .tv_nsec = self.mtimensec,
379 };
380 }
381
382 pub fn ctime(self: @This()) timespec {
383 return timespec{
384 .tv_sec = self.ctimesec,
385 .tv_nsec = self.ctimensec,
386 };
387 }
388};
389
390pub const timespec = extern struct {
391 tv_sec: isize,
392 tv_nsec: isize,
393};
394
395pub const sigset_t = u32;
396pub const empty_sigset: sigset_t = 0;
397
398pub const SIG = struct {
399 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
400 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
401 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
402 pub const HOLD = @intToPtr(?Sigaction.sigaction_fn, 5);
403
404 /// block specified signal set
405 pub const _BLOCK = 1;
406 /// unblock specified signal set
407 pub const _UNBLOCK = 2;
408 /// set specified signal set
409 pub const _SETMASK = 3;
410 /// hangup
411 pub const HUP = 1;
412 /// interrupt
413 pub const INT = 2;
414 /// quit
415 pub const QUIT = 3;
416 /// illegal instruction (not reset when caught)
417 pub const ILL = 4;
418 /// trace trap (not reset when caught)
419 pub const TRAP = 5;
420 /// abort()
421 pub const ABRT = 6;
422 /// pollable event ([XSR] generated, not supported)
423 pub const POLL = 7;
424 /// compatibility
425 pub const IOT = ABRT;
426 /// EMT instruction
427 pub const EMT = 7;
428 /// floating point exception
429 pub const FPE = 8;
430 /// kill (cannot be caught or ignored)
431 pub const KILL = 9;
432 /// bus error
433 pub const BUS = 10;
434 /// segmentation violation
435 pub const SEGV = 11;
436 /// bad argument to system call
437 pub const SYS = 12;
438 /// write on a pipe with no one to read it
439 pub const PIPE = 13;
440 /// alarm clock
441 pub const ALRM = 14;
442 /// software termination signal from kill
443 pub const TERM = 15;
444 /// urgent condition on IO channel
445 pub const URG = 16;
446 /// sendable stop signal not from tty
447 pub const STOP = 17;
448 /// stop signal from tty
449 pub const TSTP = 18;
450 /// continue a stopped process
451 pub const CONT = 19;
452 /// to parent on child stop or exit
453 pub const CHLD = 20;
454 /// to readers pgrp upon background tty read
455 pub const TTIN = 21;
456 /// like TTIN for output if (tp->t_local&LTOSTOP)
457 pub const TTOU = 22;
458 /// input/output possible signal
459 pub const IO = 23;
460 /// exceeded CPU time limit
461 pub const XCPU = 24;
462 /// exceeded file size limit
463 pub const XFSZ = 25;
464 /// virtual time alarm
465 pub const VTALRM = 26;
466 /// profiling time alarm
467 pub const PROF = 27;
468 /// window size changes
469 pub const WINCH = 28;
470 /// information request
471 pub const INFO = 29;
472 /// user defined signal 1
473 pub const USR1 = 30;
474 /// user defined signal 2
475 pub const USR2 = 31;
476};
477
478pub const siginfo_t = extern struct {
479 signo: c_int,
480 errno: c_int,
481 code: c_int,
482 pid: pid_t,
483 uid: uid_t,
484 status: c_int,
485 addr: *c_void,
486 value: extern union {
487 int: c_int,
488 ptr: *c_void,
489 },
490 si_band: c_long,
491 _pad: [7]c_ulong,
492};
493
494/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
495pub const Sigaction = extern struct {
496 pub const handler_fn = fn (c_int) callconv(.C) void;
497 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
498
499 handler: extern union {
500 handler: ?handler_fn,
501 sigaction: ?sigaction_fn,
502 },
503 mask: sigset_t,
504 flags: c_uint,
505};
506
507pub const dirent = extern struct {
508 d_ino: usize,
509 d_seekoff: usize,
510 d_reclen: u16,
511 d_namlen: u16,
512 d_type: u8,
513 d_name: u8, // field address is address of first byte of name
514
515 pub fn reclen(self: dirent) u16 {
516 return self.d_reclen;
517 }
518};
519
520/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
521pub const Kevent = extern struct {
522 ident: usize,
523 filter: i16,
524 flags: u16,
525 fflags: u32,
526 data: isize,
527 udata: usize,
528};
529
530// sys/types.h on macos uses #pragma pack(4) so these checks are
531// to make sure the struct is laid out the same. These values were
532// produced from C code using the offsetof macro.
533comptime {
534 assert(@offsetOf(Kevent, "ident") == 0);
535 assert(@offsetOf(Kevent, "filter") == 8);
536 assert(@offsetOf(Kevent, "flags") == 10);
537 assert(@offsetOf(Kevent, "fflags") == 12);
538 assert(@offsetOf(Kevent, "data") == 16);
539 assert(@offsetOf(Kevent, "udata") == 24);
540}
541
542pub const kevent64_s = extern struct {
543 ident: u64,
544 filter: i16,
545 flags: u16,
546 fflags: u32,
547 data: i64,
548 udata: u64,
549 ext: [2]u64,
550};
551
552// sys/types.h on macos uses #pragma pack() so these checks are
553// to make sure the struct is laid out the same. These values were
554// produced from C code using the offsetof macro.
555comptime {
556 assert(@offsetOf(kevent64_s, "ident") == 0);
557 assert(@offsetOf(kevent64_s, "filter") == 8);
558 assert(@offsetOf(kevent64_s, "flags") == 10);
559 assert(@offsetOf(kevent64_s, "fflags") == 12);
560 assert(@offsetOf(kevent64_s, "data") == 16);
561 assert(@offsetOf(kevent64_s, "udata") == 24);
562 assert(@offsetOf(kevent64_s, "ext") == 32);
563}
564
565pub const mach_port_t = c_uint;
566pub const clock_serv_t = mach_port_t;
567pub const clock_res_t = c_int;
568pub const mach_port_name_t = natural_t;
569pub const natural_t = c_uint;
570pub const mach_timespec_t = extern struct {
571 tv_sec: c_uint,
572 tv_nsec: clock_res_t,
573};
574pub const kern_return_t = c_int;
575pub const host_t = mach_port_t;
576pub const CALENDAR_CLOCK = 1;
577
578pub const PATH_MAX = 1024;
579pub const IOV_MAX = 16;
580
581pub const STDIN_FILENO = 0;
582pub const STDOUT_FILENO = 1;
583pub const STDERR_FILENO = 2;
584
585pub const PROT = struct {
586 /// [MC2] no permissions
587 pub const NONE = 0x00;
588 /// [MC2] pages can be read
589 pub const READ = 0x01;
590 /// [MC2] pages can be written
591 pub const WRITE = 0x02;
592 /// [MC2] pages can be executed
593 pub const EXEC = 0x04;
594};
595
596pub const MAP = struct {
597 /// allocated from memory, swap space
598 pub const ANONYMOUS = 0x1000;
599 /// map from file (default)
600 pub const FILE = 0x0000;
601 /// interpret addr exactly
602 pub const FIXED = 0x0010;
603 /// region may contain semaphores
604 pub const HASSEMAPHORE = 0x0200;
605 /// changes are private
606 pub const PRIVATE = 0x0002;
607 /// share changes
608 pub const SHARED = 0x0001;
609 /// don't cache pages for this mapping
610 pub const NOCACHE = 0x0400;
611 /// don't reserve needed swap area
612 pub const NORESERVE = 0x0040;
613 pub const FAILED = @intToPtr(*c_void, maxInt(usize));
614};
615
616pub const SA = struct {
617 /// take signal on signal stack
618 pub const ONSTACK = 0x0001;
619 /// restart system on signal return
620 pub const RESTART = 0x0002;
621 /// reset to SIG.DFL when taking signal
622 pub const RESETHAND = 0x0004;
623 /// do not generate SIG.CHLD on child stop
624 pub const NOCLDSTOP = 0x0008;
625 /// don't mask the signal we're delivering
626 pub const NODEFER = 0x0010;
627 /// don't keep zombies around
628 pub const NOCLDWAIT = 0x0020;
629 /// signal handler with SIGINFO args
630 pub const SIGINFO = 0x0040;
631 /// do not bounce off kernel's sigtramp
632 pub const USERTRAMP = 0x0100;
633 /// signal handler with SIGINFO args with 64bit regs information
634 pub const @"64REGSET" = 0x0200;
635};
636
637pub const F_OK = 0;
638pub const X_OK = 1;
639pub const W_OK = 2;
640pub const R_OK = 4;
641
642pub const O = struct {
643 pub const PATH = 0x0000;
644 /// open for reading only
645 pub const RDONLY = 0x0000;
646 /// open for writing only
647 pub const WRONLY = 0x0001;
648 /// open for reading and writing
649 pub const RDWR = 0x0002;
650 /// do not block on open or for data to become available
651 pub const NONBLOCK = 0x0004;
652 /// append on each write
653 pub const APPEND = 0x0008;
654 /// create file if it does not exist
655 pub const CREAT = 0x0200;
656 /// truncate size to 0
657 pub const TRUNC = 0x0400;
658 /// error if CREAT and the file exists
659 pub const EXCL = 0x0800;
660 /// atomically obtain a shared lock
661 pub const SHLOCK = 0x0010;
662 /// atomically obtain an exclusive lock
663 pub const EXLOCK = 0x0020;
664 /// do not follow symlinks
665 pub const NOFOLLOW = 0x0100;
666 /// allow open of symlinks
667 pub const SYMLINK = 0x200000;
668 /// descriptor requested for event notifications only
669 pub const EVTONLY = 0x8000;
670 /// mark as close-on-exec
671 pub const CLOEXEC = 0x1000000;
672 pub const ACCMODE = 3;
673 pub const ALERT = 536870912;
674 pub const ASYNC = 64;
675 pub const DIRECTORY = 1048576;
676 pub const DP_GETRAWENCRYPTED = 1;
677 pub const DP_GETRAWUNENCRYPTED = 2;
678 pub const DSYNC = 4194304;
679 pub const FSYNC = SYNC;
680 pub const NOCTTY = 131072;
681 pub const POPUP = 2147483648;
682 pub const SYNC = 128;
683};
684
685pub const SEEK = struct {
686 pub const SET = 0x0;
687 pub const CUR = 0x1;
688 pub const END = 0x2;
689};
690
691pub const DT = struct {
692 pub const UNKNOWN = 0;
693 pub const FIFO = 1;
694 pub const CHR = 2;
695 pub const DIR = 4;
696 pub const BLK = 6;
697 pub const REG = 8;
698 pub const LNK = 10;
699 pub const SOCK = 12;
700 pub const WHT = 14;
701};
702
703/// no flag value
704pub const KEVENT_FLAG_NONE = 0x000;
705
706/// immediate timeout
707pub const KEVENT_FLAG_IMMEDIATE = 0x001;
708
709/// output events only include change
710pub const KEVENT_FLAG_ERROR_EVENTS = 0x002;
711
712/// add event to kq (implies enable)
713pub const EV_ADD = 0x0001;
714
715/// delete event from kq
716pub const EV_DELETE = 0x0002;
717
718/// enable event
719pub const EV_ENABLE = 0x0004;
720
721/// disable event (not reported)
722pub const EV_DISABLE = 0x0008;
723
724/// only report one occurrence
725pub const EV_ONESHOT = 0x0010;
726
727/// clear event state after reporting
728pub const EV_CLEAR = 0x0020;
729
730/// force immediate event output
731/// ... with or without EV_ERROR
732/// ... use KEVENT_FLAG_ERROR_EVENTS
733/// on syscalls supporting flags
734pub const EV_RECEIPT = 0x0040;
735
736/// disable event after reporting
737pub const EV_DISPATCH = 0x0080;
738
739/// unique kevent per udata value
740pub const EV_UDATA_SPECIFIC = 0x0100;
741
742/// ... in combination with EV_DELETE
743/// will defer delete until udata-specific
744/// event enabled. EINPROGRESS will be
745/// returned to indicate the deferral
746pub const EV_DISPATCH2 = EV_DISPATCH | EV_UDATA_SPECIFIC;
747
748/// report that source has vanished
749/// ... only valid with EV_DISPATCH2
750pub const EV_VANISHED = 0x0200;
751
752/// reserved by system
753pub const EV_SYSFLAGS = 0xF000;
754
755/// filter-specific flag
756pub const EV_FLAG0 = 0x1000;
757
758/// filter-specific flag
759pub const EV_FLAG1 = 0x2000;
760
761/// EOF detected
762pub const EV_EOF = 0x8000;
763
764/// error, data contains errno
765pub const EV_ERROR = 0x4000;
766
767pub const EV_POLL = EV_FLAG0;
768pub const EV_OOBAND = EV_FLAG1;
769
770pub const EVFILT_READ = -1;
771pub const EVFILT_WRITE = -2;
772
773/// attached to aio requests
774pub const EVFILT_AIO = -3;
775
776/// attached to vnodes
777pub const EVFILT_VNODE = -4;
778
779/// attached to struct proc
780pub const EVFILT_PROC = -5;
781
782/// attached to struct proc
783pub const EVFILT_SIGNAL = -6;
784
785/// timers
786pub const EVFILT_TIMER = -7;
787
788/// Mach portsets
789pub const EVFILT_MACHPORT = -8;
790
791/// Filesystem events
792pub const EVFILT_FS = -9;
793
794/// User events
795pub const EVFILT_USER = -10;
796
797/// Virtual memory events
798pub const EVFILT_VM = -12;
799
800/// Exception events
801pub const EVFILT_EXCEPT = -15;
802
803pub const EVFILT_SYSCOUNT = 17;
804
805/// On input, NOTE_TRIGGER causes the event to be triggered for output.
806pub const NOTE_TRIGGER = 0x01000000;
807
808/// ignore input fflags
809pub const NOTE_FFNOP = 0x00000000;
810
811/// and fflags
812pub const NOTE_FFAND = 0x40000000;
813
814/// or fflags
815pub const NOTE_FFOR = 0x80000000;
816
817/// copy fflags
818pub const NOTE_FFCOPY = 0xc0000000;
819
820/// mask for operations
821pub const NOTE_FFCTRLMASK = 0xc0000000;
822pub const NOTE_FFLAGSMASK = 0x00ffffff;
823
824/// low water mark
825pub const NOTE_LOWAT = 0x00000001;
826
827/// OOB data
828pub const NOTE_OOB = 0x00000002;
829
830/// vnode was removed
831pub const NOTE_DELETE = 0x00000001;
832
833/// data contents changed
834pub const NOTE_WRITE = 0x00000002;
835
836/// size increased
837pub const NOTE_EXTEND = 0x00000004;
838
839/// attributes changed
840pub const NOTE_ATTRIB = 0x00000008;
841
842/// link count changed
843pub const NOTE_LINK = 0x00000010;
844
845/// vnode was renamed
846pub const NOTE_RENAME = 0x00000020;
847
848/// vnode access was revoked
849pub const NOTE_REVOKE = 0x00000040;
850
851/// No specific vnode event: to test for EVFILT_READ activation
852pub const NOTE_NONE = 0x00000080;
853
854/// vnode was unlocked by flock(2)
855pub const NOTE_FUNLOCK = 0x00000100;
856
857/// process exited
858pub const NOTE_EXIT = 0x80000000;
859
860/// process forked
861pub const NOTE_FORK = 0x40000000;
862
863/// process exec'd
864pub const NOTE_EXEC = 0x20000000;
865
866/// shared with EVFILT_SIGNAL
867pub const NOTE_SIGNAL = 0x08000000;
868
869/// exit status to be returned, valid for child process only
870pub const NOTE_EXITSTATUS = 0x04000000;
871
872/// provide details on reasons for exit
873pub const NOTE_EXIT_DETAIL = 0x02000000;
874
875/// mask for signal & exit status
876pub const NOTE_PDATAMASK = 0x000fffff;
877pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK);
878
879pub const NOTE_EXIT_DETAIL_MASK = 0x00070000;
880pub const NOTE_EXIT_DECRYPTFAIL = 0x00010000;
881pub const NOTE_EXIT_MEMORY = 0x00020000;
882pub const NOTE_EXIT_CSERROR = 0x00040000;
883
884/// will react on memory pressure
885pub const NOTE_VM_PRESSURE = 0x80000000;
886
887/// will quit on memory pressure, possibly after cleaning up dirty state
888pub const NOTE_VM_PRESSURE_TERMINATE = 0x40000000;
889
890/// will quit immediately on memory pressure
891pub const NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000;
892
893/// there was an error
894pub const NOTE_VM_ERROR = 0x10000000;
895
896/// data is seconds
897pub const NOTE_SECONDS = 0x00000001;
898
899/// data is microseconds
900pub const NOTE_USECONDS = 0x00000002;
901
902/// data is nanoseconds
903pub const NOTE_NSECONDS = 0x00000004;
904
905/// absolute timeout
906pub const NOTE_ABSOLUTE = 0x00000008;
907
908/// ext[1] holds leeway for power aware timers
909pub const NOTE_LEEWAY = 0x00000010;
910
911/// system does minimal timer coalescing
912pub const NOTE_CRITICAL = 0x00000020;
913
914/// system does maximum timer coalescing
915pub const NOTE_BACKGROUND = 0x00000040;
916pub const NOTE_MACH_CONTINUOUS_TIME = 0x00000080;
917
918/// data is mach absolute time units
919pub const NOTE_MACHTIME = 0x00000100;
920
921pub const AF = struct {
922 pub const UNSPEC = 0;
923 pub const LOCAL = 1;
924 pub const UNIX = LOCAL;
925 pub const INET = 2;
926 pub const SYS_CONTROL = 2;
927 pub const IMPLINK = 3;
928 pub const PUP = 4;
929 pub const CHAOS = 5;
930 pub const NS = 6;
931 pub const ISO = 7;
932 pub const OSI = ISO;
933 pub const ECMA = 8;
934 pub const DATAKIT = 9;
935 pub const CCITT = 10;
936 pub const SNA = 11;
937 pub const DECnet = 12;
938 pub const DLI = 13;
939 pub const LAT = 14;
940 pub const HYLINK = 15;
941 pub const APPLETALK = 16;
942 pub const ROUTE = 17;
943 pub const LINK = 18;
944 pub const XTP = 19;
945 pub const COIP = 20;
946 pub const CNT = 21;
947 pub const RTIP = 22;
948 pub const IPX = 23;
949 pub const SIP = 24;
950 pub const PIP = 25;
951 pub const ISDN = 28;
952 pub const E164 = ISDN;
953 pub const KEY = 29;
954 pub const INET6 = 30;
955 pub const NATM = 31;
956 pub const SYSTEM = 32;
957 pub const NETBIOS = 33;
958 pub const PPP = 34;
959 pub const MAX = 40;
960};
961
962pub const PF = struct {
963 pub const UNSPEC = AF.UNSPEC;
964 pub const LOCAL = AF.LOCAL;
965 pub const UNIX = PF.LOCAL;
966 pub const INET = AF.INET;
967 pub const IMPLINK = AF.IMPLINK;
968 pub const PUP = AF.PUP;
969 pub const CHAOS = AF.CHAOS;
970 pub const NS = AF.NS;
971 pub const ISO = AF.ISO;
972 pub const OSI = AF.ISO;
973 pub const ECMA = AF.ECMA;
974 pub const DATAKIT = AF.DATAKIT;
975 pub const CCITT = AF.CCITT;
976 pub const SNA = AF.SNA;
977 pub const DECnet = AF.DECnet;
978 pub const DLI = AF.DLI;
979 pub const LAT = AF.LAT;
980 pub const HYLINK = AF.HYLINK;
981 pub const APPLETALK = AF.APPLETALK;
982 pub const ROUTE = AF.ROUTE;
983 pub const LINK = AF.LINK;
984 pub const XTP = AF.XTP;
985 pub const COIP = AF.COIP;
986 pub const CNT = AF.CNT;
987 pub const SIP = AF.SIP;
988 pub const IPX = AF.IPX;
989 pub const RTIP = AF.RTIP;
990 pub const PIP = AF.PIP;
991 pub const ISDN = AF.ISDN;
992 pub const KEY = AF.KEY;
993 pub const INET6 = AF.INET6;
994 pub const NATM = AF.NATM;
995 pub const SYSTEM = AF.SYSTEM;
996 pub const NETBIOS = AF.NETBIOS;
997 pub const PPP = AF.PPP;
998 pub const MAX = AF.MAX;
999};
1000
1001pub const SYSPROTO_EVENT = 1;
1002pub const SYSPROTO_CONTROL = 2;
1003
1004pub const SOCK = struct {
1005 pub const STREAM = 1;
1006 pub const DGRAM = 2;
1007 pub const RAW = 3;
1008 pub const RDM = 4;
1009 pub const SEQPACKET = 5;
1010 pub const MAXADDRLEN = 255;
1011
1012 /// Not actually supported by Darwin, but Zig supplies a shim.
1013 /// This numerical value is not ABI-stable. It need only not conflict
1014 /// with any other `SOCK` bits.
1015 pub const CLOEXEC = 1 << 15;
1016 /// Not actually supported by Darwin, but Zig supplies a shim.
1017 /// This numerical value is not ABI-stable. It need only not conflict
1018 /// with any other `SOCK` bits.
1019 pub const NONBLOCK = 1 << 16;
1020};
1021
1022pub const IPPROTO = struct {
1023 pub const ICMP = 1;
1024 pub const ICMPV6 = 58;
1025 pub const TCP = 6;
1026 pub const UDP = 17;
1027 pub const IP = 0;
1028 pub const IPV6 = 41;
1029};
1030
1031pub const SOL = struct {
1032 pub const SOCKET = 0xffff;
1033};
1034
1035pub const SO = struct {
1036 pub const DEBUG = 0x0001;
1037 pub const ACCEPTCONN = 0x0002;
1038 pub const REUSEADDR = 0x0004;
1039 pub const KEEPALIVE = 0x0008;
1040 pub const DONTROUTE = 0x0010;
1041 pub const BROADCAST = 0x0020;
1042 pub const USELOOPBACK = 0x0040;
1043 pub const LINGER = 0x1080;
1044 pub const OOBINLINE = 0x0100;
1045 pub const REUSEPORT = 0x0200;
1046 pub const ACCEPTFILTER = 0x1000;
1047 pub const SNDBUF = 0x1001;
1048 pub const RCVBUF = 0x1002;
1049 pub const SNDLOWAT = 0x1003;
1050 pub const RCVLOWAT = 0x1004;
1051 pub const SNDTIMEO = 0x1005;
1052 pub const RCVTIMEO = 0x1006;
1053 pub const ERROR = 0x1007;
1054 pub const TYPE = 0x1008;
1055
1056 pub const NREAD = 0x1020;
1057 pub const NKE = 0x1021;
1058 pub const NOSIGPIPE = 0x1022;
1059 pub const NOADDRERR = 0x1023;
1060 pub const NWRITE = 0x1024;
1061 pub const REUSESHAREUID = 0x1025;
1062};
1063
1064pub const W = struct {
1065 /// [XSI] no hang in wait/no child to reap
1066 pub const NOHANG = 0x00000001;
1067 /// [XSI] notify on stop, untraced child
1068 pub const UNTRACED = 0x00000002;
1069
1070 pub fn EXITSTATUS(x: u32) u8 {
1071 return @intCast(u8, x >> 8);
1072 }
1073 pub fn TERMSIG(x: u32) u32 {
1074 return status(x);
1075 }
1076 pub fn STOPSIG(x: u32) u32 {
1077 return x >> 8;
1078 }
1079 pub fn IFEXITED(x: u32) bool {
1080 return status(x) == 0;
1081 }
1082 pub fn IFSTOPPED(x: u32) bool {
1083 return status(x) == stopped and STOPSIG(x) != 0x13;
1084 }
1085 pub fn IFSIGNALED(x: u32) bool {
1086 return status(x) != stopped and status(x) != 0;
1087 }
1088
1089 fn status(x: u32) u32 {
1090 return x & 0o177;
1091 }
1092 const stopped = 0o177;
1093};
1094
1095pub const E = enum(u16) {
1096 /// No error occurred.
1097 SUCCESS = 0,
1098
1099 /// Operation not permitted
1100 PERM = 1,
1101
1102 /// No such file or directory
1103 NOENT = 2,
1104
1105 /// No such process
1106 SRCH = 3,
1107
1108 /// Interrupted system call
1109 INTR = 4,
1110
1111 /// Input/output error
1112 IO = 5,
1113
1114 /// Device not configured
1115 NXIO = 6,
1116
1117 /// Argument list too long
1118 @"2BIG" = 7,
1119
1120 /// Exec format error
1121 NOEXEC = 8,
1122
1123 /// Bad file descriptor
1124 BADF = 9,
1125
1126 /// No child processes
1127 CHILD = 10,
1128
1129 /// Resource deadlock avoided
1130 DEADLK = 11,
1131
1132 /// Cannot allocate memory
1133 NOMEM = 12,
1134
1135 /// Permission denied
1136 ACCES = 13,
1137
1138 /// Bad address
1139 FAULT = 14,
1140
1141 /// Block device required
1142 NOTBLK = 15,
1143
1144 /// Device / Resource busy
1145 BUSY = 16,
1146
1147 /// File exists
1148 EXIST = 17,
1149
1150 /// Cross-device link
1151 XDEV = 18,
1152
1153 /// Operation not supported by device
1154 NODEV = 19,
1155
1156 /// Not a directory
1157 NOTDIR = 20,
1158
1159 /// Is a directory
1160 ISDIR = 21,
1161
1162 /// Invalid argument
1163 INVAL = 22,
1164
1165 /// Too many open files in system
1166 NFILE = 23,
1167
1168 /// Too many open files
1169 MFILE = 24,
1170
1171 /// Inappropriate ioctl for device
1172 NOTTY = 25,
1173
1174 /// Text file busy
1175 TXTBSY = 26,
1176
1177 /// File too large
1178 FBIG = 27,
1179
1180 /// No space left on device
1181 NOSPC = 28,
1182
1183 /// Illegal seek
1184 SPIPE = 29,
1185
1186 /// Read-only file system
1187 ROFS = 30,
1188
1189 /// Too many links
1190 MLINK = 31,
1191
1192 /// Broken pipe
1193 PIPE = 32,
1194
1195 // math software
1196
1197 /// Numerical argument out of domain
1198 DOM = 33,
1199
1200 /// Result too large
1201 RANGE = 34,
1202
1203 // non-blocking and interrupt i/o
1204
1205 /// Resource temporarily unavailable
1206 /// This is the same code used for `WOULDBLOCK`.
1207 AGAIN = 35,
1208
1209 /// Operation now in progress
1210 INPROGRESS = 36,
1211
1212 /// Operation already in progress
1213 ALREADY = 37,
1214
1215 // ipc/network software -- argument errors
1216
1217 /// Socket operation on non-socket
1218 NOTSOCK = 38,
1219
1220 /// Destination address required
1221 DESTADDRREQ = 39,
1222
1223 /// Message too long
1224 MSGSIZE = 40,
1225
1226 /// Protocol wrong type for socket
1227 PROTOTYPE = 41,
1228
1229 /// Protocol not available
1230 NOPROTOOPT = 42,
1231
1232 /// Protocol not supported
1233 PROTONOSUPPORT = 43,
1234
1235 /// Socket type not supported
1236 SOCKTNOSUPPORT = 44,
1237
1238 /// Operation not supported
1239 /// The same code is used for `NOTSUP`.
1240 OPNOTSUPP = 45,
1241
1242 /// Protocol family not supported
1243 PFNOSUPPORT = 46,
1244
1245 /// Address family not supported by protocol family
1246 AFNOSUPPORT = 47,
1247
1248 /// Address already in use
1249 ADDRINUSE = 48,
1250 /// Can't assign requested address
1251
1252 // ipc/network software -- operational errors
1253 ADDRNOTAVAIL = 49,
1254
1255 /// Network is down
1256 NETDOWN = 50,
1257
1258 /// Network is unreachable
1259 NETUNREACH = 51,
1260
1261 /// Network dropped connection on reset
1262 NETRESET = 52,
1263
1264 /// Software caused connection abort
1265 CONNABORTED = 53,
1266
1267 /// Connection reset by peer
1268 CONNRESET = 54,
1269
1270 /// No buffer space available
1271 NOBUFS = 55,
1272
1273 /// Socket is already connected
1274 ISCONN = 56,
1275
1276 /// Socket is not connected
1277 NOTCONN = 57,
1278
1279 /// Can't send after socket shutdown
1280 SHUTDOWN = 58,
1281
1282 /// Too many references: can't splice
1283 TOOMANYREFS = 59,
1284
1285 /// Operation timed out
1286 TIMEDOUT = 60,
1287
1288 /// Connection refused
1289 CONNREFUSED = 61,
1290
1291 /// Too many levels of symbolic links
1292 LOOP = 62,
1293
1294 /// File name too long
1295 NAMETOOLONG = 63,
1296
1297 /// Host is down
1298 HOSTDOWN = 64,
1299
1300 /// No route to host
1301 HOSTUNREACH = 65,
1302 /// Directory not empty
1303
1304 // quotas & mush
1305 NOTEMPTY = 66,
1306
1307 /// Too many processes
1308 PROCLIM = 67,
1309
1310 /// Too many users
1311 USERS = 68,
1312 /// Disc quota exceeded
1313
1314 // Network File System
1315 DQUOT = 69,
1316
1317 /// Stale NFS file handle
1318 STALE = 70,
1319
1320 /// Too many levels of remote in path
1321 REMOTE = 71,
1322
1323 /// RPC struct is bad
1324 BADRPC = 72,
1325
1326 /// RPC version wrong
1327 RPCMISMATCH = 73,
1328
1329 /// RPC prog. not avail
1330 PROGUNAVAIL = 74,
1331
1332 /// Program version wrong
1333 PROGMISMATCH = 75,
1334
1335 /// Bad procedure for program
1336 PROCUNAVAIL = 76,
1337
1338 /// No locks available
1339 NOLCK = 77,
1340
1341 /// Function not implemented
1342 NOSYS = 78,
1343
1344 /// Inappropriate file type or format
1345 FTYPE = 79,
1346
1347 /// Authentication error
1348 AUTH = 80,
1349
1350 /// Need authenticator
1351 NEEDAUTH = 81,
1352
1353 // Intelligent device errors
1354
1355 /// Device power is off
1356 PWROFF = 82,
1357
1358 /// Device error, e.g. paper out
1359 DEVERR = 83,
1360
1361 /// Value too large to be stored in data type
1362 OVERFLOW = 84,
1363
1364 // Program loading errors
1365
1366 /// Bad executable
1367 BADEXEC = 85,
1368
1369 /// Bad CPU type in executable
1370 BADARCH = 86,
1371
1372 /// Shared library version mismatch
1373 SHLIBVERS = 87,
1374
1375 /// Malformed Macho file
1376 BADMACHO = 88,
1377
1378 /// Operation canceled
1379 CANCELED = 89,
1380
1381 /// Identifier removed
1382 IDRM = 90,
1383
1384 /// No message of desired type
1385 NOMSG = 91,
1386
1387 /// Illegal byte sequence
1388 ILSEQ = 92,
1389
1390 /// Attribute not found
1391 NOATTR = 93,
1392
1393 /// Bad message
1394 BADMSG = 94,
1395
1396 /// Reserved
1397 MULTIHOP = 95,
1398
1399 /// No message available on STREAM
1400 NODATA = 96,
1401
1402 /// Reserved
1403 NOLINK = 97,
1404
1405 /// No STREAM resources
1406 NOSR = 98,
1407
1408 /// Not a STREAM
1409 NOSTR = 99,
1410
1411 /// Protocol error
1412 PROTO = 100,
1413
1414 /// STREAM ioctl timeout
1415 TIME = 101,
1416
1417 /// No such policy registered
1418 NOPOLICY = 103,
1419
1420 /// State not recoverable
1421 NOTRECOVERABLE = 104,
1422
1423 /// Previous owner died
1424 OWNERDEAD = 105,
1425
1426 /// Interface output queue is full
1427 QFULL = 106,
1428
1429 _,
1430};
1431
1432pub const SIGSTKSZ = 131072;
1433pub const MINSIGSTKSZ = 32768;
1434
1435pub const SS_ONSTACK = 1;
1436pub const SS_DISABLE = 4;
1437
1438pub const stack_t = extern struct {
1439 sp: [*]u8,
1440 size: isize,
1441 flags: i32,
1442};
1443
1444pub const S = struct {
1445 pub const IFMT = 0o170000;
1446
1447 pub const IFIFO = 0o010000;
1448 pub const IFCHR = 0o020000;
1449 pub const IFDIR = 0o040000;
1450 pub const IFBLK = 0o060000;
1451 pub const IFREG = 0o100000;
1452 pub const IFLNK = 0o120000;
1453 pub const IFSOCK = 0o140000;
1454 pub const IFWHT = 0o160000;
1455
1456 pub const ISUID = 0o4000;
1457 pub const ISGID = 0o2000;
1458 pub const ISVTX = 0o1000;
1459 pub const IRWXU = 0o700;
1460 pub const IRUSR = 0o400;
1461 pub const IWUSR = 0o200;
1462 pub const IXUSR = 0o100;
1463 pub const IRWXG = 0o070;
1464 pub const IRGRP = 0o040;
1465 pub const IWGRP = 0o020;
1466 pub const IXGRP = 0o010;
1467 pub const IRWXO = 0o007;
1468 pub const IROTH = 0o004;
1469 pub const IWOTH = 0o002;
1470 pub const IXOTH = 0o001;
1471
1472 pub fn ISFIFO(m: u32) bool {
1473 return m & IFMT == IFIFO;
1474 }
1475
1476 pub fn ISCHR(m: u32) bool {
1477 return m & IFMT == IFCHR;
1478 }
1479
1480 pub fn ISDIR(m: u32) bool {
1481 return m & IFMT == IFDIR;
1482 }
1483
1484 pub fn ISBLK(m: u32) bool {
1485 return m & IFMT == IFBLK;
1486 }
1487
1488 pub fn ISREG(m: u32) bool {
1489 return m & IFMT == IFREG;
1490 }
1491
1492 pub fn ISLNK(m: u32) bool {
1493 return m & IFMT == IFLNK;
1494 }
1495
1496 pub fn ISSOCK(m: u32) bool {
1497 return m & IFMT == IFSOCK;
1498 }
1499
1500 pub fn IWHT(m: u32) bool {
1501 return m & IFMT == IFWHT;
1502 }
1503};
1504
1505pub const HOST_NAME_MAX = 72;
1506
1507pub const AT = struct {
1508 pub const FDCWD = -2;
1509 /// Use effective ids in access check
1510 pub const EACCESS = 0x0010;
1511 /// Act on the symlink itself not the target
1512 pub const SYMLINK_NOFOLLOW = 0x0020;
1513 /// Act on target of symlink
1514 pub const SYMLINK_FOLLOW = 0x0040;
1515 /// Path refers to directory
1516 pub const REMOVEDIR = 0x0080;
1517};
1518
1519pub const addrinfo = extern struct {
1520 flags: i32,
1521 family: i32,
1522 socktype: i32,
1523 protocol: i32,
1524 addrlen: socklen_t,
1525 canonname: ?[*:0]u8,
1526 addr: ?*sockaddr,
1527 next: ?*addrinfo,
1528};
1529
1530pub const RTLD = struct {
1531 pub const LAZY = 0x1;
1532 pub const NOW = 0x2;
1533 pub const LOCAL = 0x4;
1534 pub const GLOBAL = 0x8;
1535 pub const NOLOAD = 0x10;
1536 pub const NODELETE = 0x80;
1537 pub const FIRST = 0x100;
1538
1539 pub const NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
1540 pub const DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
1541 pub const SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
1542 pub const MAIN_ONLY = @intToPtr(*c_void, @bitCast(usize, @as(isize, -5)));
1543};
1544
1545pub const F = struct {
1546 /// duplicate file descriptor
1547 pub const DUPFD = 0;
1548 /// get file descriptor flags
1549 pub const GETFD = 1;
1550 /// set file descriptor flags
1551 pub const SETFD = 2;
1552 /// get file status flags
1553 pub const GETFL = 3;
1554 /// set file status flags
1555 pub const SETFL = 4;
1556 /// get SIGIO/SIGURG proc/pgrp
1557 pub const GETOWN = 5;
1558 /// set SIGIO/SIGURG proc/pgrp
1559 pub const SETOWN = 6;
1560 /// get record locking information
1561 pub const GETLK = 7;
1562 /// set record locking information
1563 pub const SETLK = 8;
1564 /// F.SETLK; wait if blocked
1565 pub const SETLKW = 9;
1566 /// F.SETLK; wait if blocked, return on timeout
1567 pub const SETLKWTIMEOUT = 10;
1568 pub const FLUSH_DATA = 40;
1569 /// Used for regression test
1570 pub const CHKCLEAN = 41;
1571 /// Preallocate storage
1572 pub const PREALLOCATE = 42;
1573 /// Truncate a file without zeroing space
1574 pub const SETSIZE = 43;
1575 /// Issue an advisory read async with no copy to user
1576 pub const RDADVISE = 44;
1577 /// turn read ahead off/on for this fd
1578 pub const RDAHEAD = 45;
1579 /// turn data caching off/on for this fd
1580 pub const NOCACHE = 48;
1581 /// file offset to device offset
1582 pub const LOG2PHYS = 49;
1583 /// return the full path of the fd
1584 pub const GETPATH = 50;
1585 /// fsync + ask the drive to flush to the media
1586 pub const FULLFSYNC = 51;
1587 /// find which component (if any) is a package
1588 pub const PATHPKG_CHECK = 52;
1589 /// "freeze" all fs operations
1590 pub const FREEZE_FS = 53;
1591 /// "thaw" all fs operations
1592 pub const THAW_FS = 54;
1593 /// turn data caching off/on (globally) for this file
1594 pub const GLOBAL_NOCACHE = 55;
1595 /// add detached signatures
1596 pub const ADDSIGS = 59;
1597 /// add signature from same file (used by dyld for shared libs)
1598 pub const ADDFILESIGS = 61;
1599 /// used in conjunction with F.NOCACHE to indicate that DIRECT, synchonous writes
1600 /// should not be used (i.e. its ok to temporaily create cached pages)
1601 pub const NODIRECT = 62;
1602 ///Get the protection class of a file from the EA, returns int
1603 pub const GETPROTECTIONCLASS = 63;
1604 ///Set the protection class of a file for the EA, requires int
1605 pub const SETPROTECTIONCLASS = 64;
1606 ///file offset to device offset, extended
1607 pub const LOG2PHYS_EXT = 65;
1608 ///get record locking information, per-process
1609 pub const GETLKPID = 66;
1610 ///Mark the file as being the backing store for another filesystem
1611 pub const SETBACKINGSTORE = 70;
1612 ///return the full path of the FD, but error in specific mtmd circumstances
1613 pub const GETPATH_MTMINFO = 71;
1614 ///Returns the code directory, with associated hashes, to the caller
1615 pub const GETCODEDIR = 72;
1616 ///No SIGPIPE generated on EPIPE
1617 pub const SETNOSIGPIPE = 73;
1618 ///Status of SIGPIPE for this fd
1619 pub const GETNOSIGPIPE = 74;
1620 ///For some cases, we need to rewrap the key for AKS/MKB
1621 pub const TRANSCODEKEY = 75;
1622 ///file being written to a by single writer... if throttling enabled, writes
1623 ///may be broken into smaller chunks with throttling in between
1624 pub const SINGLE_WRITER = 76;
1625 ///Get the protection version number for this filesystem
1626 pub const GETPROTECTIONLEVEL = 77;
1627 ///Add detached code signatures (used by dyld for shared libs)
1628 pub const FINDSIGS = 78;
1629 ///Add signature from same file, only if it is signed by Apple (used by dyld for simulator)
1630 pub const ADDFILESIGS_FOR_DYLD_SIM = 83;
1631 ///fsync + issue barrier to drive
1632 pub const BARRIERFSYNC = 85;
1633 ///Add signature from same file, return end offset in structure on success
1634 pub const ADDFILESIGS_RETURN = 97;
1635 ///Check if Library Validation allows this Mach-O file to be mapped into the calling process
1636 pub const CHECK_LV = 98;
1637 ///Deallocate a range of the file
1638 pub const PUNCHHOLE = 99;
1639 ///Trim an active file
1640 pub const TRIM_ACTIVE_FILE = 100;
1641 ///mark the dup with FD_CLOEXEC
1642 pub const DUPFD_CLOEXEC = 67;
1643 /// shared or read lock
1644 pub const RDLCK = 1;
1645 /// unlock
1646 pub const UNLCK = 2;
1647 /// exclusive or write lock
1648 pub const WRLCK = 3;
1649};
1650
1651pub const FCNTL_FS_SPECIFIC_BASE = 0x00010000;
1652
1653///close-on-exec flag
1654pub const FD_CLOEXEC = 1;
1655
1656pub const LOCK = struct {
1657 pub const SH = 1;
1658 pub const EX = 2;
1659 pub const UN = 8;
1660 pub const NB = 4;
1661};
1662
1663pub const nfds_t = u32;
1664pub const pollfd = extern struct {
1665 fd: fd_t,
1666 events: i16,
1667 revents: i16,
1668};
1669
1670pub const POLL = struct {
1671 pub const IN = 0x001;
1672 pub const PRI = 0x002;
1673 pub const OUT = 0x004;
1674 pub const RDNORM = 0x040;
1675 pub const WRNORM = OUT;
1676 pub const RDBAND = 0x080;
1677 pub const WRBAND = 0x100;
1678
1679 pub const EXTEND = 0x0200;
1680 pub const ATTRIB = 0x0400;
1681 pub const NLINK = 0x0800;
1682 pub const WRITE = 0x1000;
1683
1684 pub const ERR = 0x008;
1685 pub const HUP = 0x010;
1686 pub const NVAL = 0x020;
1687
1688 pub const STANDARD = IN | PRI | OUT | RDNORM | RDBAND | WRBAND | ERR | HUP | NVAL;
1689};
1690
1691pub const CLOCK = struct {
1692 pub const REALTIME = 0;
1693 pub const MONOTONIC = 6;
1694 pub const MONOTONIC_RAW = 4;
1695 pub const MONOTONIC_RAW_APPROX = 5;
1696 pub const UPTIME_RAW = 8;
1697 pub const UPTIME_RAW_APPROX = 9;
1698 pub const PROCESS_CPUTIME_ID = 12;
1699 pub const THREAD_CPUTIME_ID = 16;
1700};
1701
1702/// Max open files per process
1703/// https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/sys/syslimits.h.auto.html
1704pub const OPEN_MAX = 10240;
1705pub const RUSAGE_SELF = 0;
1706pub const RUSAGE_CHILDREN = -1;
1707
1708pub const rusage = extern struct {
1709 utime: timeval,
1710 stime: timeval,
1711 maxrss: isize,
1712 ixrss: isize,
1713 idrss: isize,
1714 isrss: isize,
1715 minflt: isize,
1716 majflt: isize,
1717 nswap: isize,
1718 inblock: isize,
1719 oublock: isize,
1720 msgsnd: isize,
1721 msgrcv: isize,
1722 nsignals: isize,
1723 nvcsw: isize,
1724 nivcsw: isize,
1725};
1726
1727pub const rlimit_resource = enum(c_int) {
1728 CPU = 0,
1729 FSIZE = 1,
1730 DATA = 2,
1731 STACK = 3,
1732 CORE = 4,
1733 RSS = 5,
1734 MEMLOCK = 6,
1735 NPROC = 7,
1736 NOFILE = 8,
1737 _,
1738
1739 pub const AS: rlimit_resource = .RSS;
1740};
1741
1742pub const rlim_t = u64;
1743
1744pub const RLIM = struct {
1745 /// No limit
1746 pub const INFINITY: rlim_t = (1 << 63) - 1;
1747
1748 pub const SAVED_MAX = INFINITY;
1749 pub const SAVED_CUR = INFINITY;
1750};
1751
1752pub const rlimit = extern struct {
1753 /// Soft limit
1754 cur: rlim_t,
1755 /// Hard limit
1756 max: rlim_t,
1757};
1758
1759pub const SHUT = struct {
1760 pub const RD = 0;
1761 pub const WR = 1;
1762 pub const RDWR = 2;
1763};
1764
1765// Term
1766pub const VEOF = 0;
1767pub const VEOL = 1;
1768pub const VEOL2 = 2;
1769pub const VERASE = 3;
1770pub const VWERASE = 4;
1771pub const VKILL = 5;
1772pub const VREPRINT = 6;
1773pub const VINTR = 8;
1774pub const VQUIT = 9;
1775pub const VSUSP = 10;
1776pub const VDSUSP = 11;
1777pub const VSTART = 12;
1778pub const VSTOP = 13;
1779pub const VLNEXT = 14;
1780pub const VDISCARD = 15;
1781pub const VMIN = 16;
1782pub const VTIME = 17;
1783pub const VSTATUS = 18;
1784pub const NCCS = 20; // 2 spares (7, 19)
1785
1786pub const IGNBRK = 0x00000001; // ignore BREAK condition
1787pub const BRKINT = 0x00000002; // map BREAK to SIGINTR
1788pub const IGNPAR = 0x00000004; // ignore (discard) parity errors
1789pub const PARMRK = 0x00000008; // mark parity and framing errors
1790pub const INPCK = 0x00000010; // enable checking of parity errors
1791pub const ISTRIP = 0x00000020; // strip 8th bit off chars
1792pub const INLCR = 0x00000040; // map NL into CR
1793pub const IGNCR = 0x00000080; // ignore CR
1794pub const ICRNL = 0x00000100; // map CR to NL (ala CRMOD)
1795pub const IXON = 0x00000200; // enable output flow control
1796pub const IXOFF = 0x00000400; // enable input flow control
1797pub const IXANY = 0x00000800; // any char will restart after stop
1798pub const IMAXBEL = 0x00002000; // ring bell on input queue full
1799pub const IUTF8 = 0x00004000; // maintain state for UTF-8 VERASE
1800
1801pub const OPOST = 0x00000001; //enable following output processing
1802pub const ONLCR = 0x00000002; // map NL to CR-NL (ala CRMOD)
1803pub const OXTABS = 0x00000004; // expand tabs to spaces
1804pub const ONOEOT = 0x00000008; // discard EOT's (^D) on output)
1805
1806pub const OCRNL = 0x00000010; // map CR to NL on output
1807pub const ONOCR = 0x00000020; // no CR output at column 0
1808pub const ONLRET = 0x00000040; // NL performs CR function
1809pub const OFILL = 0x00000080; // use fill characters for delay
1810pub const NLDLY = 0x00000300; // \n delay
1811pub const TABDLY = 0x00000c04; // horizontal tab delay
1812pub const CRDLY = 0x00003000; // \r delay
1813pub const FFDLY = 0x00004000; // form feed delay
1814pub const BSDLY = 0x00008000; // \b delay
1815pub const VTDLY = 0x00010000; // vertical tab delay
1816pub const OFDEL = 0x00020000; // fill is DEL, else NUL
1817
1818pub const NL0 = 0x00000000;
1819pub const NL1 = 0x00000100;
1820pub const NL2 = 0x00000200;
1821pub const NL3 = 0x00000300;
1822pub const TAB0 = 0x00000000;
1823pub const TAB1 = 0x00000400;
1824pub const TAB2 = 0x00000800;
1825pub const TAB3 = 0x00000004;
1826pub const CR0 = 0x00000000;
1827pub const CR1 = 0x00001000;
1828pub const CR2 = 0x00002000;
1829pub const CR3 = 0x00003000;
1830pub const FF0 = 0x00000000;
1831pub const FF1 = 0x00004000;
1832pub const BS0 = 0x00000000;
1833pub const BS1 = 0x00008000;
1834pub const VT0 = 0x00000000;
1835pub const VT1 = 0x00010000;
1836
1837pub const CIGNORE = 0x00000001; // ignore control flags
1838pub const CSIZE = 0x00000300; // character size mask
1839pub const CS5 = 0x00000000; // 5 bits (pseudo)
1840pub const CS6 = 0x00000100; // 6 bits
1841pub const CS7 = 0x00000200; // 7 bits
1842pub const CS8 = 0x00000300; // 8 bits
1843pub const CSTOPB = 0x0000040; // send 2 stop bits
1844pub const CREAD = 0x00000800; // enable receiver
1845pub const PARENB = 0x00001000; // parity enable
1846pub const PARODD = 0x00002000; // odd parity, else even
1847pub const HUPCL = 0x00004000; // hang up on last close
1848pub const CLOCAL = 0x00008000; // ignore modem status lines
1849pub const CCTS_OFLOW = 0x00010000; // CTS flow control of output
1850pub const CRTSCTS = (CCTS_OFLOW | CRTS_IFLOW);
1851pub const CRTS_IFLOW = 0x00020000; // RTS flow control of input
1852pub const CDTR_IFLOW = 0x00040000; // DTR flow control of input
1853pub const CDSR_OFLOW = 0x00080000; // DSR flow control of output
1854pub const CCAR_OFLOW = 0x00100000; // DCD flow control of output
1855pub const MDMBUF = 0x00100000; // old name for CCAR_OFLOW
1856
1857pub const ECHOKE = 0x00000001; // visual erase for line kill
1858pub const ECHOE = 0x00000002; // visually erase chars
1859pub const ECHOK = 0x00000004; // echo NL after line kill
1860pub const ECHO = 0x00000008; // enable echoing
1861pub const ECHONL = 0x00000010; // echo NL even if ECHO is off
1862pub const ECHOPRT = 0x00000020; // visual erase mode for hardcopy
1863pub const ECHOCTL = 0x00000040; // echo control chars as ^(Char)
1864pub const ISIG = 0x00000080; // enable signals INTR, QUIT, [D]SUSP
1865pub const ICANON = 0x00000100; // canonicalize input lines
1866pub const ALTWERASE = 0x00000200; // use alternate WERASE algorithm
1867pub const IEXTEN = 0x00000400; // enable DISCARD and LNEXT
1868pub const EXTPROC = 0x00000800; // external processing
1869pub const TOSTOP = 0x00400000; // stop background jobs from output
1870pub const FLUSHO = 0x00800000; // output being flushed (state)
1871pub const NOKERNINFO = 0x02000000; // no kernel output from VSTATUS
1872pub const PENDIN = 0x20000000; // XXX retype pending input (state)
1873pub const NOFLSH = 0x80000000; // don't flush after interrupt
1874
1875pub const TCSANOW = 0; // make change immediate
1876pub const TCSADRAIN = 1; // drain output, then change
1877pub const TCSAFLUSH = 2; // drain output, flush input
1878pub const TCSASOFT = 0x10; // flag - don't alter h.w. state
1879pub const TCSA = enum(c_uint) {
1880 NOW,
1881 DRAIN,
1882 FLUSH,
1883 _,
1884};
1885
1886pub const B0 = 0;
1887pub const B50 = 50;
1888pub const B75 = 75;
1889pub const B110 = 110;
1890pub const B134 = 134;
1891pub const B150 = 150;
1892pub const B200 = 200;
1893pub const B300 = 300;
1894pub const B600 = 600;
1895pub const B1200 = 1200;
1896pub const B1800 = 1800;
1897pub const B2400 = 2400;
1898pub const B4800 = 4800;
1899pub const B9600 = 9600;
1900pub const B19200 = 19200;
1901pub const B38400 = 38400;
1902pub const B7200 = 7200;
1903pub const B14400 = 14400;
1904pub const B28800 = 28800;
1905pub const B57600 = 57600;
1906pub const B76800 = 76800;
1907pub const B115200 = 115200;
1908pub const B230400 = 230400;
1909pub const EXTA = 19200;
1910pub const EXTB = 38400;
1911
1912pub const TCIFLUSH = 1;
1913pub const TCOFLUSH = 2;
1914pub const TCIOFLUSH = 3;
1915pub const TCOOFF = 1;
1916pub const TCOON = 2;
1917pub const TCIOFF = 3;
1918pub const TCION = 4;
1919
1920pub const cc_t = u8;
1921pub const speed_t = u64;
1922pub const tcflag_t = u64;
1923
1924pub const termios = extern struct {
1925 iflag: tcflag_t, // input flags
1926 oflag: tcflag_t, // output flags
1927 cflag: tcflag_t, // control flags
1928 lflag: tcflag_t, // local flags
1929 cc: [NCCS]cc_t, // control chars
1930 ispeed: speed_t align(8), // input speed
1931 ospeed: speed_t, // output speed
1932};
1933
1934pub const winsize = extern struct {
1935 ws_row: u16,
1936 ws_col: u16,
1937 ws_xpixel: u16,
1938 ws_ypixel: u16,
1939};
1940
1941pub const T = struct {
1942 pub const IOCGWINSZ = ior(0x40000000, 't', 104, @sizeOf(winsize));
1943};
1944pub const IOCPARM_MASK = 0x1fff;
1945
1946fn ior(inout: u32, group: usize, num: usize, len: usize) usize {
1947 return (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num));
1948}
1949
1950// CPU families mapping
1951pub const CPUFAMILY = enum(u32) {
1952 UNKNOWN = 0,
1953 POWERPC_G3 = 0xcee41549,
1954 POWERPC_G4 = 0x77c184ae,
1955 POWERPC_G5 = 0xed76d8aa,
1956 INTEL_6_13 = 0xaa33392b,
1957 INTEL_PENRYN = 0x78ea4fbc,
1958 INTEL_NEHALEM = 0x6b5a4cd2,
1959 INTEL_WESTMERE = 0x573b5eec,
1960 INTEL_SANDYBRIDGE = 0x5490b78c,
1961 INTEL_IVYBRIDGE = 0x1f65e835,
1962 INTEL_HASWELL = 0x10b282dc,
1963 INTEL_BROADWELL = 0x582ed09c,
1964 INTEL_SKYLAKE = 0x37fc219f,
1965 INTEL_KABYLAKE = 0x0f817246,
1966 ARM_9 = 0xe73283ae,
1967 ARM_11 = 0x8ff620d8,
1968 ARM_XSCALE = 0x53b005f5,
1969 ARM_12 = 0xbd1b0ae9,
1970 ARM_13 = 0x0cc90e64,
1971 ARM_14 = 0x96077ef1,
1972 ARM_15 = 0xa8511bca,
1973 ARM_SWIFT = 0x1e2d6381,
1974 ARM_CYCLONE = 0x37a09642,
1975 ARM_TYPHOON = 0x2c91a47e,
1976 ARM_TWISTER = 0x92fb37c8,
1977 ARM_HURRICANE = 0x67ceee93,
1978 ARM_MONSOON_MISTRAL = 0xe81e7ef6,
1979 ARM_VORTEX_TEMPEST = 0x07d34b9f,
1980 ARM_LIGHTNING_THUNDER = 0x462504d2,
1981 ARM_FIRESTORM_ICESTORM = 0x1b588bb3,
1982 _,
1983};
lib/std/c/dragonfly.zig+1087-1
...@@ -1,5 +1,7 @@...@@ -1,5 +1,7 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2usingnamespace std.c;2const maxInt = std.math.maxInt;
3const iovec = std.os.iovec;
4
3extern "c" threadlocal var errno: c_int;5extern "c" threadlocal var errno: c_int;
4pub fn _errno() *c_int {6pub fn _errno() *c_int {
5 return &errno;7 return &errno;
...@@ -30,3 +32,1087 @@ pub const pthread_attr_t = extern struct { // copied from freebsd...@@ -30,3 +32,1087 @@ pub const pthread_attr_t = extern struct { // copied from freebsd
30};32};
3133
32pub const sem_t = ?*opaque {};34pub const sem_t = ?*opaque {};
35
36// See:
37// - https://gitweb.dragonflybsd.org/dragonfly.git/blob/HEAD:/include/unistd.h
38// - https://gitweb.dragonflybsd.org/dragonfly.git/blob/HEAD:/sys/sys/types.h
39// TODO: mode_t should probably be changed to a u16, audit pid_t/off_t as well
40pub const fd_t = c_int;
41pub const pid_t = c_int;
42pub const off_t = c_long;
43pub const mode_t = c_uint;
44pub const uid_t = u32;
45pub const gid_t = u32;
46pub const time_t = isize;
47pub const suseconds_t = c_long;
48
49pub const E = enum(u16) {
50 /// No error occurred.
51 SUCCESS = 0,
52
53 PERM = 1,
54 NOENT = 2,
55 SRCH = 3,
56 INTR = 4,
57 IO = 5,
58 NXIO = 6,
59 @"2BIG" = 7,
60 NOEXEC = 8,
61 BADF = 9,
62 CHILD = 10,
63 DEADLK = 11,
64 NOMEM = 12,
65 ACCES = 13,
66 FAULT = 14,
67 NOTBLK = 15,
68 BUSY = 16,
69 EXIST = 17,
70 XDEV = 18,
71 NODEV = 19,
72 NOTDIR = 20,
73 ISDIR = 21,
74 INVAL = 22,
75 NFILE = 23,
76 MFILE = 24,
77 NOTTY = 25,
78 TXTBSY = 26,
79 FBIG = 27,
80 NOSPC = 28,
81 SPIPE = 29,
82 ROFS = 30,
83 MLINK = 31,
84 PIPE = 32,
85 DOM = 33,
86 RANGE = 34,
87 /// This code is also used for `WOULDBLOCK`.
88 AGAIN = 35,
89 INPROGRESS = 36,
90 ALREADY = 37,
91 NOTSOCK = 38,
92 DESTADDRREQ = 39,
93 MSGSIZE = 40,
94 PROTOTYPE = 41,
95 NOPROTOOPT = 42,
96 PROTONOSUPPORT = 43,
97 SOCKTNOSUPPORT = 44,
98 /// This code is also used for `NOTSUP`.
99 OPNOTSUPP = 45,
100 PFNOSUPPORT = 46,
101 AFNOSUPPORT = 47,
102 ADDRINUSE = 48,
103 ADDRNOTAVAIL = 49,
104 NETDOWN = 50,
105 NETUNREACH = 51,
106 NETRESET = 52,
107 CONNABORTED = 53,
108 CONNRESET = 54,
109 NOBUFS = 55,
110 ISCONN = 56,
111 NOTCONN = 57,
112 SHUTDOWN = 58,
113 TOOMANYREFS = 59,
114 TIMEDOUT = 60,
115 CONNREFUSED = 61,
116 LOOP = 62,
117 NAMETOOLONG = 63,
118 HOSTDOWN = 64,
119 HOSTUNREACH = 65,
120 NOTEMPTY = 66,
121 PROCLIM = 67,
122 USERS = 68,
123 DQUOT = 69,
124 STALE = 70,
125 REMOTE = 71,
126 BADRPC = 72,
127 RPCMISMATCH = 73,
128 PROGUNAVAIL = 74,
129 PROGMISMATCH = 75,
130 PROCUNAVAIL = 76,
131 NOLCK = 77,
132 NOSYS = 78,
133 FTYPE = 79,
134 AUTH = 80,
135 NEEDAUTH = 81,
136 IDRM = 82,
137 NOMSG = 83,
138 OVERFLOW = 84,
139 CANCELED = 85,
140 ILSEQ = 86,
141 NOATTR = 87,
142 DOOFUS = 88,
143 BADMSG = 89,
144 MULTIHOP = 90,
145 NOLINK = 91,
146 PROTO = 92,
147 NOMEDIUM = 93,
148 ASYNC = 99,
149 _,
150};
151
152pub const STDIN_FILENO = 0;
153pub const STDOUT_FILENO = 1;
154pub const STDERR_FILENO = 2;
155
156pub const PROT = struct {
157 pub const NONE = 0;
158 pub const READ = 1;
159 pub const WRITE = 2;
160 pub const EXEC = 4;
161};
162
163pub const MAP = struct {
164 pub const FILE = 0;
165 pub const FAILED = @intToPtr(*c_void, maxInt(usize));
166 pub const ANONYMOUS = ANON;
167 pub const COPY = PRIVATE;
168 pub const SHARED = 1;
169 pub const PRIVATE = 2;
170 pub const FIXED = 16;
171 pub const RENAME = 32;
172 pub const NORESERVE = 64;
173 pub const INHERIT = 128;
174 pub const NOEXTEND = 256;
175 pub const HASSEMAPHORE = 512;
176 pub const STACK = 1024;
177 pub const NOSYNC = 2048;
178 pub const ANON = 4096;
179 pub const VPAGETABLE = 8192;
180 pub const TRYFIXED = 65536;
181 pub const NOCORE = 131072;
182 pub const SIZEALIGN = 262144;
183};
184
185pub const W = struct {
186 pub const NOHANG = 0x0001;
187 pub const UNTRACED = 0x0002;
188 pub const CONTINUED = 0x0004;
189 pub const STOPPED = UNTRACED;
190 pub const NOWAIT = 0x0008;
191 pub const EXITED = 0x0010;
192 pub const TRAPPED = 0x0020;
193
194 pub fn EXITSTATUS(s: u32) u8 {
195 return @intCast(u8, (s & 0xff00) >> 8);
196 }
197 pub fn TERMSIG(s: u32) u32 {
198 return s & 0x7f;
199 }
200 pub fn STOPSIG(s: u32) u32 {
201 return EXITSTATUS(s);
202 }
203 pub fn IFEXITED(s: u32) bool {
204 return TERMSIG(s) == 0;
205 }
206 pub fn IFSTOPPED(s: u32) bool {
207 return @truncate(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
208 }
209 pub fn IFSIGNALED(s: u32) bool {
210 return (s & 0xffff) -% 1 < 0xff;
211 }
212};
213
214pub const SA = struct {
215 pub const ONSTACK = 0x0001;
216 pub const RESTART = 0x0002;
217 pub const RESETHAND = 0x0004;
218 pub const NODEFER = 0x0010;
219 pub const NOCLDWAIT = 0x0020;
220 pub const SIGINFO = 0x0040;
221};
222
223pub const PATH_MAX = 1024;
224pub const IOV_MAX = KERN.IOV_MAX;
225
226pub const ino_t = c_ulong;
227
228pub const Stat = extern struct {
229 ino: ino_t,
230 nlink: c_uint,
231 dev: c_uint,
232 mode: c_ushort,
233 padding1: u16,
234 uid: uid_t,
235 gid: gid_t,
236 rdev: c_uint,
237 atim: timespec,
238 mtim: timespec,
239 ctim: timespec,
240 size: c_ulong,
241 blocks: i64,
242 blksize: u32,
243 flags: u32,
244 gen: u32,
245 lspare: i32,
246 qspare1: i64,
247 qspare2: i64,
248 pub fn atime(self: @This()) timespec {
249 return self.atim;
250 }
251
252 pub fn mtime(self: @This()) timespec {
253 return self.mtim;
254 }
255
256 pub fn ctime(self: @This()) timespec {
257 return self.ctim;
258 }
259};
260
261pub const timespec = extern struct {
262 tv_sec: c_long,
263 tv_nsec: c_long,
264};
265
266pub const timeval = extern struct {
267 /// seconds
268 tv_sec: time_t,
269 /// microseconds
270 tv_usec: suseconds_t,
271};
272
273pub const CTL = struct {
274 pub const UNSPEC = 0;
275 pub const KERN = 1;
276 pub const VM = 2;
277 pub const VFS = 3;
278 pub const NET = 4;
279 pub const DEBUG = 5;
280 pub const HW = 6;
281 pub const MACHDEP = 7;
282 pub const USER = 8;
283 pub const LWKT = 10;
284 pub const MAXID = 11;
285 pub const MAXNAME = 12;
286};
287
288pub const KERN = struct {
289 pub const PROC_ALL = 0;
290 pub const OSTYPE = 1;
291 pub const PROC_PID = 1;
292 pub const OSRELEASE = 2;
293 pub const PROC_PGRP = 2;
294 pub const OSREV = 3;
295 pub const PROC_SESSION = 3;
296 pub const VERSION = 4;
297 pub const PROC_TTY = 4;
298 pub const MAXVNODES = 5;
299 pub const PROC_UID = 5;
300 pub const MAXPROC = 6;
301 pub const PROC_RUID = 6;
302 pub const MAXFILES = 7;
303 pub const PROC_ARGS = 7;
304 pub const ARGMAX = 8;
305 pub const PROC_CWD = 8;
306 pub const PROC_PATHNAME = 9;
307 pub const SECURELVL = 9;
308 pub const PROC_SIGTRAMP = 10;
309 pub const HOSTNAME = 10;
310 pub const HOSTID = 11;
311 pub const CLOCKRATE = 12;
312 pub const VNODE = 13;
313 pub const PROC = 14;
314 pub const FILE = 15;
315 pub const PROC_FLAGMASK = 16;
316 pub const PROF = 16;
317 pub const PROC_FLAG_LWP = 16;
318 pub const POSIX1 = 17;
319 pub const NGROUPS = 18;
320 pub const JOB_CONTROL = 19;
321 pub const SAVED_IDS = 20;
322 pub const BOOTTIME = 21;
323 pub const NISDOMAINNAME = 22;
324 pub const UPDATEINTERVAL = 23;
325 pub const OSRELDATE = 24;
326 pub const NTP_PLL = 25;
327 pub const BOOTFILE = 26;
328 pub const MAXFILESPERPROC = 27;
329 pub const MAXPROCPERUID = 28;
330 pub const DUMPDEV = 29;
331 pub const IPC = 30;
332 pub const DUMMY = 31;
333 pub const PS_STRINGS = 32;
334 pub const USRSTACK = 33;
335 pub const LOGSIGEXIT = 34;
336 pub const IOV_MAX = 35;
337 pub const MAXPOSIXLOCKSPERUID = 36;
338 pub const MAXID = 37;
339};
340
341pub const HOST_NAME_MAX = 255;
342
343// access function
344pub const F_OK = 0; // test for existence of file
345pub const X_OK = 1; // test for execute or search permission
346pub const W_OK = 2; // test for write permission
347pub const R_OK = 4; // test for read permission
348
349pub const O = struct {
350 pub const RDONLY = 0;
351 pub const NDELAY = NONBLOCK;
352 pub const WRONLY = 1;
353 pub const RDWR = 2;
354 pub const ACCMODE = 3;
355 pub const NONBLOCK = 4;
356 pub const APPEND = 8;
357 pub const SHLOCK = 16;
358 pub const EXLOCK = 32;
359 pub const ASYNC = 64;
360 pub const FSYNC = 128;
361 pub const SYNC = 128;
362 pub const NOFOLLOW = 256;
363 pub const CREAT = 512;
364 pub const TRUNC = 1024;
365 pub const EXCL = 2048;
366 pub const NOCTTY = 32768;
367 pub const DIRECT = 65536;
368 pub const CLOEXEC = 131072;
369 pub const FBLOCKING = 262144;
370 pub const FNONBLOCKING = 524288;
371 pub const FAPPEND = 1048576;
372 pub const FOFFSET = 2097152;
373 pub const FSYNCWRITE = 4194304;
374 pub const FASYNCWRITE = 8388608;
375 pub const DIRECTORY = 134217728;
376};
377
378pub const SEEK = struct {
379 pub const SET = 0;
380 pub const CUR = 1;
381 pub const END = 2;
382 pub const DATA = 3;
383 pub const HOLE = 4;
384};
385
386pub const F = struct {
387 pub const ULOCK = 0;
388 pub const LOCK = 1;
389 pub const TLOCK = 2;
390 pub const TEST = 3;
391
392 pub const DUPFD = 0;
393 pub const GETFD = 1;
394 pub const RDLCK = 1;
395 pub const SETFD = 2;
396 pub const UNLCK = 2;
397 pub const WRLCK = 3;
398 pub const GETFL = 3;
399 pub const SETFL = 4;
400 pub const GETOWN = 5;
401 pub const SETOWN = 6;
402 pub const GETLK = 7;
403 pub const SETLK = 8;
404 pub const SETLKW = 9;
405 pub const DUP2FD = 10;
406 pub const DUPFD_CLOEXEC = 17;
407 pub const DUP2FD_CLOEXEC = 18;
408};
409
410pub const FD_CLOEXEC = 1;
411
412pub const AT = struct {
413 pub const FDCWD = -328243;
414 pub const SYMLINK_NOFOLLOW = 1;
415 pub const REMOVEDIR = 2;
416 pub const EACCESS = 4;
417 pub const SYMLINK_FOLLOW = 8;
418};
419
420pub const dirent = extern struct {
421 d_fileno: c_ulong,
422 d_namlen: u16,
423 d_type: u8,
424 d_unused1: u8,
425 d_unused2: u32,
426 d_name: [256]u8,
427
428 pub fn reclen(self: dirent) u16 {
429 return (@offsetOf(dirent, "d_name") + self.d_namlen + 1 + 7) & ~@as(u16, 7);
430 }
431};
432
433pub const DT = struct {
434 pub const UNKNOWN = 0;
435 pub const FIFO = 1;
436 pub const CHR = 2;
437 pub const DIR = 4;
438 pub const BLK = 6;
439 pub const REG = 8;
440 pub const LNK = 10;
441 pub const SOCK = 12;
442 pub const WHT = 14;
443 pub const DBF = 15;
444};
445
446pub const CLOCK = struct {
447 pub const REALTIME = 0;
448 pub const VIRTUAL = 1;
449 pub const PROF = 2;
450 pub const MONOTONIC = 4;
451 pub const UPTIME = 5;
452 pub const UPTIME_PRECISE = 7;
453 pub const UPTIME_FAST = 8;
454 pub const REALTIME_PRECISE = 9;
455 pub const REALTIME_FAST = 10;
456 pub const MONOTONIC_PRECISE = 11;
457 pub const MONOTONIC_FAST = 12;
458 pub const SECOND = 13;
459 pub const THREAD_CPUTIME_ID = 14;
460 pub const PROCESS_CPUTIME_ID = 15;
461};
462
463pub const sockaddr = extern struct {
464 len: u8,
465 family: u8,
466 data: [14]u8,
467
468 pub const storage = std.x.os.Socket.Address.Native.Storage;
469
470 pub const in = extern struct {
471 len: u8 = @sizeOf(in),
472 family: sa_family_t = AF.INET,
473 port: in_port_t,
474 addr: u32,
475 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
476 };
477
478 pub const in6 = extern struct {
479 len: u8 = @sizeOf(in6),
480 family: sa_family_t = AF.INET6,
481 port: in_port_t,
482 flowinfo: u32,
483 addr: [16]u8,
484 scope_id: u32,
485 };
486};
487
488pub const Kevent = extern struct {
489 ident: usize,
490 filter: c_short,
491 flags: c_ushort,
492 fflags: c_uint,
493 data: isize,
494 udata: usize,
495};
496
497pub const EVFILT_FS = -10;
498pub const EVFILT_USER = -9;
499pub const EVFILT_EXCEPT = -8;
500pub const EVFILT_TIMER = -7;
501pub const EVFILT_SIGNAL = -6;
502pub const EVFILT_PROC = -5;
503pub const EVFILT_VNODE = -4;
504pub const EVFILT_AIO = -3;
505pub const EVFILT_WRITE = -2;
506pub const EVFILT_READ = -1;
507pub const EVFILT_SYSCOUNT = 10;
508pub const EVFILT_MARKER = 15;
509
510pub const EV_ADD = 1;
511pub const EV_DELETE = 2;
512pub const EV_ENABLE = 4;
513pub const EV_DISABLE = 8;
514pub const EV_ONESHOT = 16;
515pub const EV_CLEAR = 32;
516pub const EV_RECEIPT = 64;
517pub const EV_DISPATCH = 128;
518pub const EV_NODATA = 4096;
519pub const EV_FLAG1 = 8192;
520pub const EV_ERROR = 16384;
521pub const EV_EOF = 32768;
522pub const EV_SYSFLAGS = 61440;
523
524pub const NOTE_FFNOP = 0;
525pub const NOTE_TRACK = 1;
526pub const NOTE_DELETE = 1;
527pub const NOTE_LOWAT = 1;
528pub const NOTE_TRACKERR = 2;
529pub const NOTE_OOB = 2;
530pub const NOTE_WRITE = 2;
531pub const NOTE_EXTEND = 4;
532pub const NOTE_CHILD = 4;
533pub const NOTE_ATTRIB = 8;
534pub const NOTE_LINK = 16;
535pub const NOTE_RENAME = 32;
536pub const NOTE_REVOKE = 64;
537pub const NOTE_PDATAMASK = 1048575;
538pub const NOTE_FFLAGSMASK = 16777215;
539pub const NOTE_TRIGGER = 16777216;
540pub const NOTE_EXEC = 536870912;
541pub const NOTE_FFAND = 1073741824;
542pub const NOTE_FORK = 1073741824;
543pub const NOTE_EXIT = 2147483648;
544pub const NOTE_FFOR = 2147483648;
545pub const NOTE_FFCTRLMASK = 3221225472;
546pub const NOTE_FFCOPY = 3221225472;
547pub const NOTE_PCTRLMASK = 4026531840;
548
549pub const stack_t = extern struct {
550 sp: [*]u8,
551 size: isize,
552 flags: i32,
553};
554
555pub const S = struct {
556 pub const IREAD = IRUSR;
557 pub const IEXEC = IXUSR;
558 pub const IWRITE = IWUSR;
559 pub const IXOTH = 1;
560 pub const IWOTH = 2;
561 pub const IROTH = 4;
562 pub const IRWXO = 7;
563 pub const IXGRP = 8;
564 pub const IWGRP = 16;
565 pub const IRGRP = 32;
566 pub const IRWXG = 56;
567 pub const IXUSR = 64;
568 pub const IWUSR = 128;
569 pub const IRUSR = 256;
570 pub const IRWXU = 448;
571 pub const ISTXT = 512;
572 pub const BLKSIZE = 512;
573 pub const ISVTX = 512;
574 pub const ISGID = 1024;
575 pub const ISUID = 2048;
576 pub const IFIFO = 4096;
577 pub const IFCHR = 8192;
578 pub const IFDIR = 16384;
579 pub const IFBLK = 24576;
580 pub const IFREG = 32768;
581 pub const IFDB = 36864;
582 pub const IFLNK = 40960;
583 pub const IFSOCK = 49152;
584 pub const IFWHT = 57344;
585 pub const IFMT = 61440;
586
587 pub fn ISCHR(m: u32) bool {
588 return m & IFMT == IFCHR;
589 }
590};
591
592pub const BADSIG = SIG.ERR;
593
594pub const SIG = struct {
595 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
596 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
597 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
598
599 pub const BLOCK = 1;
600 pub const UNBLOCK = 2;
601 pub const SETMASK = 3;
602
603 pub const IOT = ABRT;
604 pub const HUP = 1;
605 pub const INT = 2;
606 pub const QUIT = 3;
607 pub const ILL = 4;
608 pub const TRAP = 5;
609 pub const ABRT = 6;
610 pub const EMT = 7;
611 pub const FPE = 8;
612 pub const KILL = 9;
613 pub const BUS = 10;
614 pub const SEGV = 11;
615 pub const SYS = 12;
616 pub const PIPE = 13;
617 pub const ALRM = 14;
618 pub const TERM = 15;
619 pub const URG = 16;
620 pub const STOP = 17;
621 pub const TSTP = 18;
622 pub const CONT = 19;
623 pub const CHLD = 20;
624 pub const TTIN = 21;
625 pub const TTOU = 22;
626 pub const IO = 23;
627 pub const XCPU = 24;
628 pub const XFSZ = 25;
629 pub const VTALRM = 26;
630 pub const PROF = 27;
631 pub const WINCH = 28;
632 pub const INFO = 29;
633 pub const USR1 = 30;
634 pub const USR2 = 31;
635 pub const THR = 32;
636 pub const CKPT = 33;
637 pub const CKPTEXIT = 34;
638};
639
640pub const siginfo_t = extern struct {
641 signo: c_int,
642 errno: c_int,
643 code: c_int,
644 pid: c_int,
645 uid: uid_t,
646 status: c_int,
647 addr: ?*c_void,
648 value: sigval,
649 band: c_long,
650 __spare__: [7]c_int,
651};
652
653pub const sigval = extern union {
654 sival_int: c_int,
655 sival_ptr: ?*c_void,
656};
657
658pub const _SIG_WORDS = 4;
659
660pub const sigset_t = extern struct {
661 __bits: [_SIG_WORDS]c_uint,
662};
663
664pub const empty_sigset = sigset_t{ .__bits = [_]c_uint{0} ** _SIG_WORDS };
665
666pub const sig_atomic_t = c_int;
667
668pub const Sigaction = extern struct {
669 pub const handler_fn = fn (c_int) callconv(.C) void;
670 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
671
672 /// signal handler
673 handler: extern union {
674 handler: ?handler_fn,
675 sigaction: ?sigaction_fn,
676 },
677 flags: c_uint,
678 mask: sigset_t,
679};
680
681pub const sig_t = [*c]fn (c_int) callconv(.C) void;
682
683pub const SOCK = struct {
684 pub const STREAM = 1;
685 pub const DGRAM = 2;
686 pub const RAW = 3;
687 pub const RDM = 4;
688 pub const SEQPACKET = 5;
689 pub const MAXADDRLEN = 255;
690 pub const CLOEXEC = 0x10000000;
691 pub const NONBLOCK = 0x20000000;
692};
693
694pub const SO = struct {
695 pub const DEBUG = 0x0001;
696 pub const ACCEPTCONN = 0x0002;
697 pub const REUSEADDR = 0x0004;
698 pub const KEEPALIVE = 0x0008;
699 pub const DONTROUTE = 0x0010;
700 pub const BROADCAST = 0x0020;
701 pub const USELOOPBACK = 0x0040;
702 pub const LINGER = 0x0080;
703 pub const OOBINLINE = 0x0100;
704 pub const REUSEPORT = 0x0200;
705 pub const TIMESTAMP = 0x0400;
706 pub const NOSIGPIPE = 0x0800;
707 pub const ACCEPTFILTER = 0x1000;
708 pub const RERROR = 0x2000;
709 pub const PASSCRED = 0x4000;
710
711 pub const SNDBUF = 0x1001;
712 pub const RCVBUF = 0x1002;
713 pub const SNDLOWAT = 0x1003;
714 pub const RCVLOWAT = 0x1004;
715 pub const SNDTIMEO = 0x1005;
716 pub const RCVTIMEO = 0x1006;
717 pub const ERROR = 0x1007;
718 pub const TYPE = 0x1008;
719 pub const SNDSPACE = 0x100a;
720 pub const CPUHINT = 0x1030;
721};
722
723pub const SOL = struct {
724 pub const SOCKET = 0xffff;
725};
726
727pub const PF = struct {
728 pub const INET6 = AF.INET6;
729 pub const IMPLINK = AF.IMPLINK;
730 pub const ROUTE = AF.ROUTE;
731 pub const ISO = AF.ISO;
732 pub const PIP = AF.pseudo_PIP;
733 pub const CHAOS = AF.CHAOS;
734 pub const DATAKIT = AF.DATAKIT;
735 pub const INET = AF.INET;
736 pub const APPLETALK = AF.APPLETALK;
737 pub const SIP = AF.SIP;
738 pub const OSI = AF.ISO;
739 pub const CNT = AF.CNT;
740 pub const LINK = AF.LINK;
741 pub const HYLINK = AF.HYLINK;
742 pub const MAX = AF.MAX;
743 pub const KEY = AF.pseudo_KEY;
744 pub const PUP = AF.PUP;
745 pub const COIP = AF.COIP;
746 pub const SNA = AF.SNA;
747 pub const LOCAL = AF.LOCAL;
748 pub const NETBIOS = AF.NETBIOS;
749 pub const NATM = AF.NATM;
750 pub const BLUETOOTH = AF.BLUETOOTH;
751 pub const UNSPEC = AF.UNSPEC;
752 pub const NETGRAPH = AF.NETGRAPH;
753 pub const ECMA = AF.ECMA;
754 pub const IPX = AF.IPX;
755 pub const DLI = AF.DLI;
756 pub const ATM = AF.ATM;
757 pub const CCITT = AF.CCITT;
758 pub const ISDN = AF.ISDN;
759 pub const RTIP = AF.pseudo_RTIP;
760 pub const LAT = AF.LAT;
761 pub const UNIX = PF.LOCAL;
762 pub const XTP = AF.pseudo_XTP;
763 pub const DECnet = AF.DECnet;
764};
765
766pub const AF = struct {
767 pub const UNSPEC = 0;
768 pub const OSI = ISO;
769 pub const UNIX = LOCAL;
770 pub const LOCAL = 1;
771 pub const INET = 2;
772 pub const IMPLINK = 3;
773 pub const PUP = 4;
774 pub const CHAOS = 5;
775 pub const NETBIOS = 6;
776 pub const ISO = 7;
777 pub const ECMA = 8;
778 pub const DATAKIT = 9;
779 pub const CCITT = 10;
780 pub const SNA = 11;
781 pub const DLI = 13;
782 pub const LAT = 14;
783 pub const HYLINK = 15;
784 pub const APPLETALK = 16;
785 pub const ROUTE = 17;
786 pub const LINK = 18;
787 pub const COIP = 20;
788 pub const CNT = 21;
789 pub const IPX = 23;
790 pub const SIP = 24;
791 pub const ISDN = 26;
792 pub const INET6 = 28;
793 pub const NATM = 29;
794 pub const ATM = 30;
795 pub const NETGRAPH = 32;
796 pub const BLUETOOTH = 33;
797 pub const MPLS = 34;
798 pub const MAX = 36;
799};
800
801pub const in_port_t = u16;
802pub const sa_family_t = u8;
803pub const socklen_t = u32;
804
805pub const EAI = enum(c_int) {
806 ADDRFAMILY = 1,
807 AGAIN = 2,
808 BADFLAGS = 3,
809 FAIL = 4,
810 FAMILY = 5,
811 MEMORY = 6,
812 NODATA = 7,
813 NONAME = 8,
814 SERVICE = 9,
815 SOCKTYPE = 10,
816 SYSTEM = 11,
817 BADHINTS = 12,
818 PROTOCOL = 13,
819 OVERFLOW = 14,
820 _,
821};
822
823pub const AI = struct {
824 pub const PASSIVE = 0x00000001;
825 pub const CANONNAME = 0x00000002;
826 pub const NUMERICHOST = 0x00000004;
827 pub const NUMERICSERV = 0x00000008;
828 pub const MASK = PASSIVE | CANONNAME | NUMERICHOST | NUMERICSERV | ADDRCONFIG;
829 pub const ALL = 0x00000100;
830 pub const V4MAPPED_CFG = 0x00000200;
831 pub const ADDRCONFIG = 0x00000400;
832 pub const V4MAPPED = 0x00000800;
833 pub const DEFAULT = V4MAPPED_CFG | ADDRCONFIG;
834};
835
836pub const RTLD = struct {
837 pub const LAZY = 1;
838 pub const NOW = 2;
839 pub const MODEMASK = 0x3;
840 pub const GLOBAL = 0x100;
841 pub const LOCAL = 0;
842 pub const TRACE = 0x200;
843 pub const NODELETE = 0x01000;
844 pub const NOLOAD = 0x02000;
845
846 pub const NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
847 pub const DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
848 pub const SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
849 pub const ALL = @intToPtr(*c_void, @bitCast(usize, @as(isize, -4)));
850};
851
852pub const dl_phdr_info = extern struct {
853 dlpi_addr: usize,
854 dlpi_name: ?[*:0]const u8,
855 dlpi_phdr: [*]std.elf.Phdr,
856 dlpi_phnum: u16,
857};
858pub const cmsghdr = extern struct {
859 cmsg_len: socklen_t,
860 cmsg_level: c_int,
861 cmsg_type: c_int,
862};
863pub const msghdr = extern struct {
864 msg_name: ?*c_void,
865 msg_namelen: socklen_t,
866 msg_iov: [*c]iovec,
867 msg_iovlen: c_int,
868 msg_control: ?*c_void,
869 msg_controllen: socklen_t,
870 msg_flags: c_int,
871};
872pub const cmsgcred = extern struct {
873 cmcred_pid: pid_t,
874 cmcred_uid: uid_t,
875 cmcred_euid: uid_t,
876 cmcred_gid: gid_t,
877 cmcred_ngroups: c_short,
878 cmcred_groups: [16]gid_t,
879};
880pub const sf_hdtr = extern struct {
881 headers: [*c]iovec,
882 hdr_cnt: c_int,
883 trailers: [*c]iovec,
884 trl_cnt: c_int,
885};
886
887pub const MS_SYNC = 0;
888pub const MS_ASYNC = 1;
889pub const MS_INVALIDATE = 2;
890
891pub const POSIX_MADV_SEQUENTIAL = 2;
892pub const POSIX_MADV_RANDOM = 1;
893pub const POSIX_MADV_DONTNEED = 4;
894pub const POSIX_MADV_NORMAL = 0;
895pub const POSIX_MADV_WILLNEED = 3;
896
897pub const MADV = struct {
898 pub const SEQUENTIAL = 2;
899 pub const CONTROL_END = SETMAP;
900 pub const DONTNEED = 4;
901 pub const RANDOM = 1;
902 pub const WILLNEED = 3;
903 pub const NORMAL = 0;
904 pub const CONTROL_START = INVAL;
905 pub const FREE = 5;
906 pub const NOSYNC = 6;
907 pub const AUTOSYNC = 7;
908 pub const NOCORE = 8;
909 pub const CORE = 9;
910 pub const INVAL = 10;
911 pub const SETMAP = 11;
912};
913
914pub const LOCK = struct {
915 pub const SH = 1;
916 pub const EX = 2;
917 pub const UN = 8;
918 pub const NB = 4;
919};
920
921pub const Flock = extern struct {
922 l_start: off_t,
923 l_len: off_t,
924 l_pid: pid_t,
925 l_type: c_short,
926 l_whence: c_short,
927};
928
929pub const addrinfo = extern struct {
930 flags: i32,
931 family: i32,
932 socktype: i32,
933 protocol: i32,
934 addrlen: socklen_t,
935 canonname: ?[*:0]u8,
936 addr: ?*sockaddr,
937 next: ?*addrinfo,
938};
939
940pub const IPPROTO = struct {
941 pub const IP = 0;
942 pub const ICMP = 1;
943 pub const TCP = 6;
944 pub const UDP = 17;
945 pub const IPV6 = 41;
946 pub const RAW = 255;
947 pub const HOPOPTS = 0;
948 pub const IGMP = 2;
949 pub const GGP = 3;
950 pub const IPV4 = 4;
951 pub const IPIP = IPV4;
952 pub const ST = 7;
953 pub const EGP = 8;
954 pub const PIGP = 9;
955 pub const RCCMON = 10;
956 pub const NVPII = 11;
957 pub const PUP = 12;
958 pub const ARGUS = 13;
959 pub const EMCON = 14;
960 pub const XNET = 15;
961 pub const CHAOS = 16;
962 pub const MUX = 18;
963 pub const MEAS = 19;
964 pub const HMP = 20;
965 pub const PRM = 21;
966 pub const IDP = 22;
967 pub const TRUNK1 = 23;
968 pub const TRUNK2 = 24;
969 pub const LEAF1 = 25;
970 pub const LEAF2 = 26;
971 pub const RDP = 27;
972 pub const IRTP = 28;
973 pub const TP = 29;
974 pub const BLT = 30;
975 pub const NSP = 31;
976 pub const INP = 32;
977 pub const SEP = 33;
978 pub const @"3PC" = 34;
979 pub const IDPR = 35;
980 pub const XTP = 36;
981 pub const DDP = 37;
982 pub const CMTP = 38;
983 pub const TPXX = 39;
984 pub const IL = 40;
985 pub const SDRP = 42;
986 pub const ROUTING = 43;
987 pub const FRAGMENT = 44;
988 pub const IDRP = 45;
989 pub const RSVP = 46;
990 pub const GRE = 47;
991 pub const MHRP = 48;
992 pub const BHA = 49;
993 pub const ESP = 50;
994 pub const AH = 51;
995 pub const INLSP = 52;
996 pub const SWIPE = 53;
997 pub const NHRP = 54;
998 pub const MOBILE = 55;
999 pub const TLSP = 56;
1000 pub const SKIP = 57;
1001 pub const ICMPV6 = 58;
1002 pub const NONE = 59;
1003 pub const DSTOPTS = 60;
1004 pub const AHIP = 61;
1005 pub const CFTP = 62;
1006 pub const HELLO = 63;
1007 pub const SATEXPAK = 64;
1008 pub const KRYPTOLAN = 65;
1009 pub const RVD = 66;
1010 pub const IPPC = 67;
1011 pub const ADFS = 68;
1012 pub const SATMON = 69;
1013 pub const VISA = 70;
1014 pub const IPCV = 71;
1015 pub const CPNX = 72;
1016 pub const CPHB = 73;
1017 pub const WSN = 74;
1018 pub const PVP = 75;
1019 pub const BRSATMON = 76;
1020 pub const ND = 77;
1021 pub const WBMON = 78;
1022 pub const WBEXPAK = 79;
1023 pub const EON = 80;
1024 pub const VMTP = 81;
1025 pub const SVMTP = 82;
1026 pub const VINES = 83;
1027 pub const TTP = 84;
1028 pub const IGP = 85;
1029 pub const DGP = 86;
1030 pub const TCF = 87;
1031 pub const IGRP = 88;
1032 pub const OSPFIGP = 89;
1033 pub const SRPC = 90;
1034 pub const LARP = 91;
1035 pub const MTP = 92;
1036 pub const AX25 = 93;
1037 pub const IPEIP = 94;
1038 pub const MICP = 95;
1039 pub const SCCSP = 96;
1040 pub const ETHERIP = 97;
1041 pub const ENCAP = 98;
1042 pub const APES = 99;
1043 pub const GMTP = 100;
1044 pub const IPCOMP = 108;
1045 pub const PIM = 103;
1046 pub const CARP = 112;
1047 pub const PGM = 113;
1048 pub const PFSYNC = 240;
1049 pub const DIVERT = 254;
1050 pub const MAX = 256;
1051 pub const DONE = 257;
1052 pub const UNKNOWN = 258;
1053};
1054
1055pub const rlimit_resource = enum(c_int) {
1056 CPU = 0,
1057 FSIZE = 1,
1058 DATA = 2,
1059 STACK = 3,
1060 CORE = 4,
1061 RSS = 5,
1062 MEMLOCK = 6,
1063 NPROC = 7,
1064 NOFILE = 8,
1065 SBSIZE = 9,
1066 VMEM = 10,
1067 POSIXLOCKS = 11,
1068 _,
1069
1070 pub const AS: rlimit_resource = .VMEM;
1071};
1072
1073pub const rlim_t = i64;
1074
1075pub const RLIM = struct {
1076 /// No limit
1077 pub const INFINITY: rlim_t = (1 << 63) - 1;
1078
1079 pub const SAVED_MAX = INFINITY;
1080 pub const SAVED_CUR = INFINITY;
1081};
1082
1083pub const rlimit = extern struct {
1084 /// Soft limit
1085 cur: rlim_t,
1086 /// Hard limit
1087 max: rlim_t,
1088};
1089
1090pub const SHUT = struct {
1091 pub const RD = 0;
1092 pub const WR = 1;
1093 pub const RDWR = 2;
1094};
1095
1096pub const nfds_t = u32;
1097
1098pub const pollfd = extern struct {
1099 fd: fd_t,
1100 events: i16,
1101 revents: i16,
1102};
1103
1104pub const POLL = struct {
1105 /// Requestable events.
1106 pub const IN = 0x0001;
1107 pub const PRI = 0x0002;
1108 pub const OUT = 0x0004;
1109 pub const RDNORM = 0x0040;
1110 pub const WRNORM = OUT;
1111 pub const RDBAND = 0x0080;
1112 pub const WRBAND = 0x0100;
1113
1114 /// These events are set if they occur regardless of whether they were requested.
1115 pub const ERR = 0x0008;
1116 pub const HUP = 0x0010;
1117 pub const NVAL = 0x0020;
1118};
lib/std/c/freebsd.zig+1474-21
...@@ -1,5 +1,8 @@...@@ -1,5 +1,8 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2usingnamespace std.c;2const builtin = @import("builtin");
3const maxInt = std.math.maxInt;
4const iovec = std.os.iovec;
5const iovec_const = std.os.iovec_const;
36
4extern "c" fn __error() *c_int;7extern "c" fn __error() *c_int;
5pub const _errno = __error;8pub const _errno = __error;
...@@ -107,32 +110,1482 @@ pub const EAI = enum(c_int) {...@@ -107,32 +110,1482 @@ pub const EAI = enum(c_int) {
107110
108pub const EAI_MAX = 15;111pub const EAI_MAX = 15;
109112
110/// get address to use bind()113pub const AI = struct {
111pub const AI_PASSIVE = 0x00000001;114 /// get address to use bind()
115 pub const PASSIVE = 0x00000001;
116 /// fill ai_canonname
117 pub const CANONNAME = 0x00000002;
118 /// prevent host name resolution
119 pub const NUMERICHOST = 0x00000004;
120 /// prevent service name resolution
121 pub const NUMERICSERV = 0x00000008;
122 /// valid flags for addrinfo (not a standard def, apps should not use it)
123 pub const MASK = (PASSIVE | CANONNAME | NUMERICHOST | NUMERICSERV | ADDRCONFIG | ALL | V4MAPPED);
124 /// IPv6 and IPv4-mapped (with V4MAPPED)
125 pub const ALL = 0x00000100;
126 /// accept IPv4-mapped if kernel supports
127 pub const V4MAPPED_CFG = 0x00000200;
128 /// only if any address is assigned
129 pub const ADDRCONFIG = 0x00000400;
130 /// accept IPv4-mapped IPv6 address
131 pub const V4MAPPED = 0x00000800;
132 /// special recommended flags for getipnodebyname
133 pub const DEFAULT = (V4MAPPED_CFG | ADDRCONFIG);
134};
135
136pub const blksize_t = i32;
137pub const blkcnt_t = i64;
138pub const clockid_t = i32;
139pub const fsblkcnt_t = u64;
140pub const fsfilcnt_t = u64;
141pub const nlink_t = u64;
142pub const fd_t = i32;
143pub const pid_t = i32;
144pub const uid_t = u32;
145pub const gid_t = u32;
146pub const mode_t = u16;
147pub const off_t = i64;
148pub const ino_t = u64;
149pub const dev_t = u64;
150pub const time_t = i64;
151// The signedness is not constant across different architectures.
152pub const clock_t = isize;
153
154pub const socklen_t = u32;
155pub const suseconds_t = c_long;
156
157/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
158pub const Kevent = extern struct {
159 ident: usize,
160 filter: i16,
161 flags: u16,
162 fflags: u32,
163 data: i64,
164 udata: usize,
165 // TODO ext
166};
167
168// Modes and flags for dlopen()
169// include/dlfcn.h
170
171pub const RTLD = struct {
172 /// Bind function calls lazily.
173 pub const LAZY = 1;
174 /// Bind function calls immediately.
175 pub const NOW = 2;
176 pub const MODEMASK = 0x3;
177 /// Make symbols globally available.
178 pub const GLOBAL = 0x100;
179 /// Opposite of GLOBAL, and the default.
180 pub const LOCAL = 0;
181 /// Trace loaded objects and exit.
182 pub const TRACE = 0x200;
183 /// Do not remove members.
184 pub const NODELETE = 0x01000;
185 /// Do not load if not already loaded.
186 pub const NOLOAD = 0x02000;
187};
188pub const dl_phdr_info = extern struct {
189 dlpi_addr: usize,
190 dlpi_name: ?[*:0]const u8,
191 dlpi_phdr: [*]std.elf.Phdr,
192 dlpi_phnum: u16,
193};
194
195pub const Flock = extern struct {
196 l_start: off_t,
197 l_len: off_t,
198 l_pid: pid_t,
199 l_type: i16,
200 l_whence: i16,
201 l_sysid: i32,
202 __unused: [4]u8,
203};
204
205pub const msghdr = extern struct {
206 /// optional address
207 msg_name: ?*sockaddr,
208
209 /// size of address
210 msg_namelen: socklen_t,
211
212 /// scatter/gather array
213 msg_iov: [*]iovec,
214
215 /// # elements in msg_iov
216 msg_iovlen: i32,
217
218 /// ancillary data
219 msg_control: ?*c_void,
220
221 /// ancillary data buffer len
222 msg_controllen: socklen_t,
223
224 /// flags on received message
225 msg_flags: i32,
226};
227
228pub const msghdr_const = extern struct {
229 /// optional address
230 msg_name: ?*const sockaddr,
231
232 /// size of address
233 msg_namelen: socklen_t,
234
235 /// scatter/gather array
236 msg_iov: [*]iovec_const,
237
238 /// # elements in msg_iov
239 msg_iovlen: i32,
240
241 /// ancillary data
242 msg_control: ?*c_void,
243
244 /// ancillary data buffer len
245 msg_controllen: socklen_t,
246
247 /// flags on received message
248 msg_flags: i32,
249};
250
251pub const Stat = extern struct {
252 dev: dev_t,
253 ino: ino_t,
254 nlink: nlink_t,
255
256 mode: mode_t,
257 __pad0: u16,
258 uid: uid_t,
259 gid: gid_t,
260 __pad1: u32,
261 rdev: dev_t,
262
263 atim: timespec,
264 mtim: timespec,
265 ctim: timespec,
266 birthtim: timespec,
267
268 size: off_t,
269 blocks: i64,
270 blksize: isize,
271 flags: u32,
272 gen: u64,
273 __spare: [10]u64,
274
275 pub fn atime(self: @This()) timespec {
276 return self.atim;
277 }
278
279 pub fn mtime(self: @This()) timespec {
280 return self.mtim;
281 }
282
283 pub fn ctime(self: @This()) timespec {
284 return self.ctim;
285 }
286};
287
288pub const timespec = extern struct {
289 tv_sec: isize,
290 tv_nsec: isize,
291};
292
293pub const timeval = extern struct {
294 /// seconds
295 tv_sec: time_t,
296 /// microseconds
297 tv_usec: suseconds_t,
298};
299
300pub const dirent = extern struct {
301 d_fileno: usize,
302 d_off: i64,
303 d_reclen: u16,
304 d_type: u8,
305 d_pad0: u8,
306 d_namlen: u16,
307 d_pad1: u16,
308 d_name: [256]u8,
309
310 pub fn reclen(self: dirent) u16 {
311 return self.d_reclen;
312 }
313};
314
315pub const in_port_t = u16;
316pub const sa_family_t = u8;
317
318pub const sockaddr = extern struct {
319 /// total length
320 len: u8,
321 /// address family
322 family: sa_family_t,
323 /// actually longer; address value
324 data: [14]u8,
325
326 pub const storage = std.x.os.Socket.Address.Native.Storage;
327
328 pub const in = extern struct {
329 len: u8 = @sizeOf(in),
330 family: sa_family_t = AF.INET,
331 port: in_port_t,
332 addr: u32,
333 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
334 };
335
336 pub const in6 = extern struct {
337 len: u8 = @sizeOf(in6),
338 family: sa_family_t = AF.INET6,
339 port: in_port_t,
340 flowinfo: u32,
341 addr: [16]u8,
342 scope_id: u32,
343 };
344
345 pub const un = extern struct {
346 len: u8 = @sizeOf(un),
347 family: sa_family_t = AF.UNIX,
348 path: [104]u8,
349 };
350};
351
352pub const CTL = struct {
353 pub const KERN = 1;
354 pub const DEBUG = 5;
355};
356
357pub const KERN = struct {
358 pub const PROC = 14; // struct: process entries
359 pub const PROC_PATHNAME = 12; // path to executable
360 pub const IOV_MAX = 35;
361};
362
363pub const PATH_MAX = 1024;
364pub const IOV_MAX = KERN.IOV_MAX;
365
366pub const STDIN_FILENO = 0;
367pub const STDOUT_FILENO = 1;
368pub const STDERR_FILENO = 2;
369
370pub const PROT = struct {
371 pub const NONE = 0;
372 pub const READ = 1;
373 pub const WRITE = 2;
374 pub const EXEC = 4;
375};
376
377pub const CLOCK = struct {
378 pub const REALTIME = 0;
379 pub const VIRTUAL = 1;
380 pub const PROF = 2;
381 pub const MONOTONIC = 4;
382 pub const UPTIME = 5;
383 pub const UPTIME_PRECISE = 7;
384 pub const UPTIME_FAST = 8;
385 pub const REALTIME_PRECISE = 9;
386 pub const REALTIME_FAST = 10;
387 pub const MONOTONIC_PRECISE = 11;
388 pub const MONOTONIC_FAST = 12;
389 pub const SECOND = 13;
390 pub const THREAD_CPUTIME_ID = 14;
391 pub const PROCESS_CPUTIME_ID = 15;
392};
393
394pub const MAP = struct {
395 pub const FAILED = @intToPtr(*c_void, maxInt(usize));
396 pub const SHARED = 0x0001;
397 pub const PRIVATE = 0x0002;
398 pub const FIXED = 0x0010;
399 pub const STACK = 0x0400;
400 pub const NOSYNC = 0x0800;
401 pub const ANON = 0x1000;
402 pub const ANONYMOUS = ANON;
403 pub const FILE = 0;
404
405 pub const GUARD = 0x00002000;
406 pub const EXCL = 0x00004000;
407 pub const NOCORE = 0x00020000;
408 pub const PREFAULT_READ = 0x00040000;
409 pub const @"32BIT" = 0x00080000;
410};
411
412pub const W = struct {
413 pub const NOHANG = 1;
414 pub const UNTRACED = 2;
415 pub const STOPPED = UNTRACED;
416 pub const CONTINUED = 4;
417 pub const NOWAIT = 8;
418 pub const EXITED = 16;
419 pub const TRAPPED = 32;
420
421 pub fn EXITSTATUS(s: u32) u8 {
422 return @intCast(u8, (s & 0xff00) >> 8);
423 }
424 pub fn TERMSIG(s: u32) u32 {
425 return s & 0x7f;
426 }
427 pub fn STOPSIG(s: u32) u32 {
428 return EXITSTATUS(s);
429 }
430 pub fn IFEXITED(s: u32) bool {
431 return TERMSIG(s) == 0;
432 }
433 pub fn IFSTOPPED(s: u32) bool {
434 return @truncate(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
435 }
436 pub fn IFSIGNALED(s: u32) bool {
437 return (s & 0xffff) -% 1 < 0xff;
438 }
439};
440
441pub const SA = struct {
442 pub const ONSTACK = 0x0001;
443 pub const RESTART = 0x0002;
444 pub const RESETHAND = 0x0004;
445 pub const NOCLDSTOP = 0x0008;
446 pub const NODEFER = 0x0010;
447 pub const NOCLDWAIT = 0x0020;
448 pub const SIGINFO = 0x0040;
449};
450
451pub const SIG = struct {
452 pub const HUP = 1;
453 pub const INT = 2;
454 pub const QUIT = 3;
455 pub const ILL = 4;
456 pub const TRAP = 5;
457 pub const ABRT = 6;
458 pub const IOT = ABRT;
459 pub const EMT = 7;
460 pub const FPE = 8;
461 pub const KILL = 9;
462 pub const BUS = 10;
463 pub const SEGV = 11;
464 pub const SYS = 12;
465 pub const PIPE = 13;
466 pub const ALRM = 14;
467 pub const TERM = 15;
468 pub const URG = 16;
469 pub const STOP = 17;
470 pub const TSTP = 18;
471 pub const CONT = 19;
472 pub const CHLD = 20;
473 pub const TTIN = 21;
474 pub const TTOU = 22;
475 pub const IO = 23;
476 pub const XCPU = 24;
477 pub const XFSZ = 25;
478 pub const VTALRM = 26;
479 pub const PROF = 27;
480 pub const WINCH = 28;
481 pub const INFO = 29;
482 pub const USR1 = 30;
483 pub const USR2 = 31;
484 pub const THR = 32;
485 pub const LWP = THR;
486 pub const LIBRT = 33;
487
488 pub const RTMIN = 65;
489 pub const RTMAX = 126;
490
491 pub const BLOCK = 1;
492 pub const UNBLOCK = 2;
493 pub const SETMASK = 3;
494
495 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
496 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
497 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
498
499 pub const WORDS = 4;
500 pub const MAXSIG = 128;
501
502 pub inline fn IDX(sig: usize) usize {
503 return sig - 1;
504 }
505 pub inline fn WORD(sig: usize) usize {
506 return IDX(sig) >> 5;
507 }
508 pub inline fn BIT(sig: usize) usize {
509 return 1 << (IDX(sig) & 31);
510 }
511 pub inline fn VALID(sig: usize) usize {
512 return sig <= MAXSIG and sig > 0;
513 }
514};
515pub const sigval = extern union {
516 int: c_int,
517 ptr: ?*c_void,
518};
519
520pub const sigset_t = extern struct {
521 __bits: [SIG.WORDS]u32,
522};
523
524pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** SIG.WORDS };
525
526// access function
527pub const F_OK = 0; // test for existence of file
528pub const X_OK = 1; // test for execute or search permission
529pub const W_OK = 2; // test for write permission
530pub const R_OK = 4; // test for read permission
531
532pub const O = struct {
533 pub const RDONLY = 0x0000;
534 pub const WRONLY = 0x0001;
535 pub const RDWR = 0x0002;
536 pub const ACCMODE = 0x0003;
537
538 pub const SHLOCK = 0x0010;
539 pub const EXLOCK = 0x0020;
540
541 pub const CREAT = 0x0200;
542 pub const EXCL = 0x0800;
543 pub const NOCTTY = 0x8000;
544 pub const TRUNC = 0x0400;
545 pub const APPEND = 0x0008;
546 pub const NONBLOCK = 0x0004;
547 pub const DSYNC = 0o10000;
548 pub const SYNC = 0x0080;
549 pub const RSYNC = 0o4010000;
550 pub const DIRECTORY = 0x20000;
551 pub const NOFOLLOW = 0x0100;
552 pub const CLOEXEC = 0x00100000;
553
554 pub const ASYNC = 0x0040;
555 pub const DIRECT = 0x00010000;
556 pub const NOATIME = 0o1000000;
557 pub const PATH = 0o10000000;
558 pub const TMPFILE = 0o20200000;
559 pub const NDELAY = NONBLOCK;
560};
561
562pub const F = struct {
563 pub const DUPFD = 0;
564 pub const GETFD = 1;
565 pub const SETFD = 2;
566 pub const GETFL = 3;
567 pub const SETFL = 4;
568
569 pub const GETOWN = 5;
570 pub const SETOWN = 6;
571
572 pub const GETLK = 11;
573 pub const SETLK = 12;
574 pub const SETLKW = 13;
575
576 pub const RDLCK = 1;
577 pub const WRLCK = 3;
578 pub const UNLCK = 2;
579
580 pub const SETOWN_EX = 15;
581 pub const GETOWN_EX = 16;
582
583 pub const GETOWNER_UIDS = 17;
584};
585
586pub const LOCK = struct {
587 pub const SH = 1;
588 pub const EX = 2;
589 pub const UN = 8;
590 pub const NB = 4;
591};
592
593pub const FD_CLOEXEC = 1;
594
595pub const SEEK = struct {
596 pub const SET = 0;
597 pub const CUR = 1;
598 pub const END = 2;
599};
600
601pub const SOCK = struct {
602 pub const STREAM = 1;
603 pub const DGRAM = 2;
604 pub const RAW = 3;
605 pub const RDM = 4;
606 pub const SEQPACKET = 5;
607
608 pub const CLOEXEC = 0x10000000;
609 pub const NONBLOCK = 0x20000000;
610};
611
612pub const SO = struct {
613 pub const DEBUG = 0x00000001;
614 pub const ACCEPTCONN = 0x00000002;
615 pub const REUSEADDR = 0x00000004;
616 pub const KEEPALIVE = 0x00000008;
617 pub const DONTROUTE = 0x00000010;
618 pub const BROADCAST = 0x00000020;
619 pub const USELOOPBACK = 0x00000040;
620 pub const LINGER = 0x00000080;
621 pub const OOBINLINE = 0x00000100;
622 pub const REUSEPORT = 0x00000200;
623 pub const TIMESTAMP = 0x00000400;
624 pub const NOSIGPIPE = 0x00000800;
625 pub const ACCEPTFILTER = 0x00001000;
626 pub const BINTIME = 0x00002000;
627 pub const NO_OFFLOAD = 0x00004000;
628 pub const NO_DDP = 0x00008000;
629 pub const REUSEPORT_LB = 0x00010000;
630
631 pub const SNDBUF = 0x1001;
632 pub const RCVBUF = 0x1002;
633 pub const SNDLOWAT = 0x1003;
634 pub const RCVLOWAT = 0x1004;
635 pub const SNDTIMEO = 0x1005;
636 pub const RCVTIMEO = 0x1006;
637 pub const ERROR = 0x1007;
638 pub const TYPE = 0x1008;
639 pub const LABEL = 0x1009;
640 pub const PEERLABEL = 0x1010;
641 pub const LISTENQLIMIT = 0x1011;
642 pub const LISTENQLEN = 0x1012;
643 pub const LISTENINCQLEN = 0x1013;
644 pub const SETFIB = 0x1014;
645 pub const USER_COOKIE = 0x1015;
646 pub const PROTOCOL = 0x1016;
647 pub const PROTOTYPE = PROTOCOL;
648 pub const TS_CLOCK = 0x1017;
649 pub const MAX_PACING_RATE = 0x1018;
650 pub const DOMAIN = 0x1019;
651};
652
653pub const SOL = struct {
654 pub const SOCKET = 0xffff;
655};
656
657pub const PF = struct {
658 pub const UNSPEC = AF.UNSPEC;
659 pub const LOCAL = AF.LOCAL;
660 pub const UNIX = PF.LOCAL;
661 pub const INET = AF.INET;
662 pub const IMPLINK = AF.IMPLINK;
663 pub const PUP = AF.PUP;
664 pub const CHAOS = AF.CHAOS;
665 pub const NETBIOS = AF.NETBIOS;
666 pub const ISO = AF.ISO;
667 pub const OSI = AF.ISO;
668 pub const ECMA = AF.ECMA;
669 pub const DATAKIT = AF.DATAKIT;
670 pub const CCITT = AF.CCITT;
671 pub const DECnet = AF.DECnet;
672 pub const DLI = AF.DLI;
673 pub const LAT = AF.LAT;
674 pub const HYLINK = AF.HYLINK;
675 pub const APPLETALK = AF.APPLETALK;
676 pub const ROUTE = AF.ROUTE;
677 pub const LINK = AF.LINK;
678 pub const XTP = AF.pseudo_XTP;
679 pub const COIP = AF.COIP;
680 pub const CNT = AF.CNT;
681 pub const SIP = AF.SIP;
682 pub const IPX = AF.IPX;
683 pub const RTIP = AF.pseudo_RTIP;
684 pub const PIP = AF.pseudo_PIP;
685 pub const ISDN = AF.ISDN;
686 pub const KEY = AF.pseudo_KEY;
687 pub const INET6 = AF.pseudo_INET6;
688 pub const NATM = AF.NATM;
689 pub const ATM = AF.ATM;
690 pub const NETGRAPH = AF.NETGRAPH;
691 pub const SLOW = AF.SLOW;
692 pub const SCLUSTER = AF.SCLUSTER;
693 pub const ARP = AF.ARP;
694 pub const BLUETOOTH = AF.BLUETOOTH;
695 pub const IEEE80211 = AF.IEEE80211;
696 pub const INET_SDP = AF.INET_SDP;
697 pub const INET6_SDP = AF.INET6_SDP;
698 pub const MAX = AF.MAX;
699};
700
701pub const AF = struct {
702 pub const UNSPEC = 0;
703 pub const UNIX = 1;
704 pub const LOCAL = UNIX;
705 pub const FILE = LOCAL;
706 pub const INET = 2;
707 pub const IMPLINK = 3;
708 pub const PUP = 4;
709 pub const CHAOS = 5;
710 pub const NETBIOS = 6;
711 pub const ISO = 7;
712 pub const OSI = ISO;
713 pub const ECMA = 8;
714 pub const DATAKIT = 9;
715 pub const CCITT = 10;
716 pub const SNA = 11;
717 pub const DECnet = 12;
718 pub const DLI = 13;
719 pub const LAT = 14;
720 pub const HYLINK = 15;
721 pub const APPLETALK = 16;
722 pub const ROUTE = 17;
723 pub const LINK = 18;
724 pub const pseudo_XTP = 19;
725 pub const COIP = 20;
726 pub const CNT = 21;
727 pub const pseudo_RTIP = 22;
728 pub const IPX = 23;
729 pub const SIP = 24;
730 pub const pseudo_PIP = 25;
731 pub const ISDN = 26;
732 pub const E164 = ISDN;
733 pub const pseudo_KEY = 27;
734 pub const INET6 = 28;
735 pub const NATM = 29;
736 pub const ATM = 30;
737 pub const pseudo_HDRCMPLT = 31;
738 pub const NETGRAPH = 32;
739 pub const SLOW = 33;
740 pub const SCLUSTER = 34;
741 pub const ARP = 35;
742 pub const BLUETOOTH = 36;
743 pub const IEEE80211 = 37;
744 pub const INET_SDP = 40;
745 pub const INET6_SDP = 42;
746 pub const MAX = 42;
747};
748
749pub const DT = struct {
750 pub const UNKNOWN = 0;
751 pub const FIFO = 1;
752 pub const CHR = 2;
753 pub const DIR = 4;
754 pub const BLK = 6;
755 pub const REG = 8;
756 pub const LNK = 10;
757 pub const SOCK = 12;
758 pub const WHT = 14;
759};
760
761/// add event to kq (implies enable)
762pub const EV_ADD = 0x0001;
763
764/// delete event from kq
765pub const EV_DELETE = 0x0002;
766
767/// enable event
768pub const EV_ENABLE = 0x0004;
769
770/// disable event (not reported)
771pub const EV_DISABLE = 0x0008;
112772
113/// fill ai_canonname773/// only report one occurrence
114pub const AI_CANONNAME = 0x00000002;774pub const EV_ONESHOT = 0x0010;
115775
116/// prevent host name resolution776/// clear event state after reporting
117pub const AI_NUMERICHOST = 0x00000004;777pub const EV_CLEAR = 0x0020;
118778
119/// prevent service name resolution779/// error, event data contains errno
120pub const AI_NUMERICSERV = 0x00000008;780pub const EV_ERROR = 0x4000;
121781
122/// valid flags for addrinfo (not a standard def, apps should not use it)782/// force immediate event output
123pub const AI_MASK = (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED);783/// ... with or without EV_ERROR
784/// ... use KEVENT_FLAG_ERROR_EVENTS
785/// on syscalls supporting flags
786pub const EV_RECEIPT = 0x0040;
124787
125/// IPv6 and IPv4-mapped (with AI_V4MAPPED)788/// disable event after reporting
126pub const AI_ALL = 0x00000100;789pub const EV_DISPATCH = 0x0080;
127790
128/// accept IPv4-mapped if kernel supports791pub const EVFILT_READ = -1;
129pub const AI_V4MAPPED_CFG = 0x00000200;792pub const EVFILT_WRITE = -2;
130793
131/// only if any address is assigned794/// attached to aio requests
132pub const AI_ADDRCONFIG = 0x00000400;795pub const EVFILT_AIO = -3;
133796
134/// accept IPv4-mapped IPv6 address797/// attached to vnodes
135pub const AI_V4MAPPED = 0x00000800;798pub const EVFILT_VNODE = -4;
136799
137/// special recommended flags for getipnodebyname800/// attached to struct proc
138pub const AI_DEFAULT = (AI_V4MAPPED_CFG | AI_ADDRCONFIG);801pub const EVFILT_PROC = -5;
802
803/// attached to struct proc
804pub const EVFILT_SIGNAL = -6;
805
806/// timers
807pub const EVFILT_TIMER = -7;
808
809/// Process descriptors
810pub const EVFILT_PROCDESC = -8;
811
812/// Filesystem events
813pub const EVFILT_FS = -9;
814
815pub const EVFILT_LIO = -10;
816
817/// User events
818pub const EVFILT_USER = -11;
819
820/// Sendfile events
821pub const EVFILT_SENDFILE = -12;
822
823pub const EVFILT_EMPTY = -13;
824
825/// On input, NOTE_TRIGGER causes the event to be triggered for output.
826pub const NOTE_TRIGGER = 0x01000000;
827
828/// ignore input fflags
829pub const NOTE_FFNOP = 0x00000000;
830
831/// and fflags
832pub const NOTE_FFAND = 0x40000000;
833
834/// or fflags
835pub const NOTE_FFOR = 0x80000000;
836
837/// copy fflags
838pub const NOTE_FFCOPY = 0xc0000000;
839
840/// mask for operations
841pub const NOTE_FFCTRLMASK = 0xc0000000;
842pub const NOTE_FFLAGSMASK = 0x00ffffff;
843
844/// low water mark
845pub const NOTE_LOWAT = 0x00000001;
846
847/// behave like poll()
848pub const NOTE_FILE_POLL = 0x00000002;
849
850/// vnode was removed
851pub const NOTE_DELETE = 0x00000001;
852
853/// data contents changed
854pub const NOTE_WRITE = 0x00000002;
855
856/// size increased
857pub const NOTE_EXTEND = 0x00000004;
858
859/// attributes changed
860pub const NOTE_ATTRIB = 0x00000008;
861
862/// link count changed
863pub const NOTE_LINK = 0x00000010;
864
865/// vnode was renamed
866pub const NOTE_RENAME = 0x00000020;
867
868/// vnode access was revoked
869pub const NOTE_REVOKE = 0x00000040;
870
871/// vnode was opened
872pub const NOTE_OPEN = 0x00000080;
873
874/// file closed, fd did not allow write
875pub const NOTE_CLOSE = 0x00000100;
876
877/// file closed, fd did allow write
878pub const NOTE_CLOSE_WRITE = 0x00000200;
879
880/// file was read
881pub const NOTE_READ = 0x00000400;
882
883/// process exited
884pub const NOTE_EXIT = 0x80000000;
885
886/// process forked
887pub const NOTE_FORK = 0x40000000;
888
889/// process exec'd
890pub const NOTE_EXEC = 0x20000000;
891
892/// mask for signal & exit status
893pub const NOTE_PDATAMASK = 0x000fffff;
894pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK);
895
896/// data is seconds
897pub const NOTE_SECONDS = 0x00000001;
898
899/// data is milliseconds
900pub const NOTE_MSECONDS = 0x00000002;
901
902/// data is microseconds
903pub const NOTE_USECONDS = 0x00000004;
904
905/// data is nanoseconds
906pub const NOTE_NSECONDS = 0x00000008;
907
908/// timeout is absolute
909pub const NOTE_ABSTIME = 0x00000010;
910
911pub const T = struct {
912 pub const IOCEXCL = 0x2000740d;
913 pub const IOCNXCL = 0x2000740e;
914 pub const IOCSCTTY = 0x20007461;
915 pub const IOCGPGRP = 0x40047477;
916 pub const IOCSPGRP = 0x80047476;
917 pub const IOCOUTQ = 0x40047473;
918 pub const IOCSTI = 0x80017472;
919 pub const IOCGWINSZ = 0x40087468;
920 pub const IOCSWINSZ = 0x80087467;
921 pub const IOCMGET = 0x4004746a;
922 pub const IOCMBIS = 0x8004746c;
923 pub const IOCMBIC = 0x8004746b;
924 pub const IOCMSET = 0x8004746d;
925 pub const FIONREAD = 0x4004667f;
926 pub const IOCCONS = 0x80047462;
927 pub const IOCPKT = 0x80047470;
928 pub const FIONBIO = 0x8004667e;
929 pub const IOCNOTTY = 0x20007471;
930 pub const IOCSETD = 0x8004741b;
931 pub const IOCGETD = 0x4004741a;
932 pub const IOCSBRK = 0x2000747b;
933 pub const IOCCBRK = 0x2000747a;
934 pub const IOCGSID = 0x40047463;
935 pub const IOCGPTN = 0x4004740f;
936 pub const IOCSIG = 0x2004745f;
937};
938
939pub const winsize = extern struct {
940 ws_row: u16,
941 ws_col: u16,
942 ws_xpixel: u16,
943 ws_ypixel: u16,
944};
945
946const NSIG = 32;
947
948/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
949pub const Sigaction = extern struct {
950 pub const handler_fn = fn (c_int) callconv(.C) void;
951 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
952
953 /// signal handler
954 handler: extern union {
955 handler: ?handler_fn,
956 sigaction: ?sigaction_fn,
957 },
958
959 /// see signal options
960 flags: c_uint,
961
962 /// signal mask to apply
963 mask: sigset_t,
964};
965
966pub const siginfo_t = extern struct {
967 signo: c_int,
968 errno: c_int,
969 code: c_int,
970 pid: pid_t,
971 uid: uid_t,
972 status: c_int,
973 addr: ?*c_void,
974 value: sigval,
975 reason: extern union {
976 fault: extern struct {
977 trapno: c_int,
978 },
979 timer: extern struct {
980 timerid: c_int,
981 overrun: c_int,
982 },
983 mesgq: extern struct {
984 mqd: c_int,
985 },
986 poll: extern struct {
987 band: c_long,
988 },
989 spare: extern struct {
990 spare1: c_long,
991 spare2: [7]c_int,
992 },
993 },
994};
995
996pub usingnamespace switch (builtin.cpu.arch) {
997 .x86_64 => struct {
998 pub const ucontext_t = extern struct {
999 sigmask: sigset_t,
1000 mcontext: mcontext_t,
1001 link: ?*ucontext_t,
1002 stack: stack_t,
1003 flags: c_int,
1004 __spare__: [4]c_int,
1005 };
1006
1007 /// XXX x86_64 specific
1008 pub const mcontext_t = extern struct {
1009 onstack: u64,
1010 rdi: u64,
1011 rsi: u64,
1012 rdx: u64,
1013 rcx: u64,
1014 r8: u64,
1015 r9: u64,
1016 rax: u64,
1017 rbx: u64,
1018 rbp: u64,
1019 r10: u64,
1020 r11: u64,
1021 r12: u64,
1022 r13: u64,
1023 r14: u64,
1024 r15: u64,
1025 trapno: u32,
1026 fs: u16,
1027 gs: u16,
1028 addr: u64,
1029 flags: u32,
1030 es: u16,
1031 ds: u16,
1032 err: u64,
1033 rip: u64,
1034 cs: u64,
1035 rflags: u64,
1036 rsp: u64,
1037 ss: u64,
1038 };
1039 },
1040 else => struct {},
1041};
1042
1043pub const E = enum(u16) {
1044 /// No error occurred.
1045 SUCCESS = 0,
1046
1047 PERM = 1, // Operation not permitted
1048 NOENT = 2, // No such file or directory
1049 SRCH = 3, // No such process
1050 INTR = 4, // Interrupted system call
1051 IO = 5, // Input/output error
1052 NXIO = 6, // Device not configured
1053 @"2BIG" = 7, // Argument list too long
1054 NOEXEC = 8, // Exec format error
1055 BADF = 9, // Bad file descriptor
1056 CHILD = 10, // No child processes
1057 DEADLK = 11, // Resource deadlock avoided
1058 // 11 was AGAIN
1059 NOMEM = 12, // Cannot allocate memory
1060 ACCES = 13, // Permission denied
1061 FAULT = 14, // Bad address
1062 NOTBLK = 15, // Block device required
1063 BUSY = 16, // Device busy
1064 EXIST = 17, // File exists
1065 XDEV = 18, // Cross-device link
1066 NODEV = 19, // Operation not supported by device
1067 NOTDIR = 20, // Not a directory
1068 ISDIR = 21, // Is a directory
1069 INVAL = 22, // Invalid argument
1070 NFILE = 23, // Too many open files in system
1071 MFILE = 24, // Too many open files
1072 NOTTY = 25, // Inappropriate ioctl for device
1073 TXTBSY = 26, // Text file busy
1074 FBIG = 27, // File too large
1075 NOSPC = 28, // No space left on device
1076 SPIPE = 29, // Illegal seek
1077 ROFS = 30, // Read-only filesystem
1078 MLINK = 31, // Too many links
1079 PIPE = 32, // Broken pipe
1080
1081 // math software
1082 DOM = 33, // Numerical argument out of domain
1083 RANGE = 34, // Result too large
1084
1085 // non-blocking and interrupt i/o
1086
1087 /// Resource temporarily unavailable
1088 /// This code is also used for `WOULDBLOCK`: operation would block.
1089 AGAIN = 35,
1090 INPROGRESS = 36, // Operation now in progress
1091 ALREADY = 37, // Operation already in progress
1092
1093 // ipc/network software -- argument errors
1094 NOTSOCK = 38, // Socket operation on non-socket
1095 DESTADDRREQ = 39, // Destination address required
1096 MSGSIZE = 40, // Message too long
1097 PROTOTYPE = 41, // Protocol wrong type for socket
1098 NOPROTOOPT = 42, // Protocol not available
1099 PROTONOSUPPORT = 43, // Protocol not supported
1100 SOCKTNOSUPPORT = 44, // Socket type not supported
1101 /// Operation not supported
1102 /// This code is also used for `NOTSUP`.
1103 OPNOTSUPP = 45,
1104 PFNOSUPPORT = 46, // Protocol family not supported
1105 AFNOSUPPORT = 47, // Address family not supported by protocol family
1106 ADDRINUSE = 48, // Address already in use
1107 ADDRNOTAVAIL = 49, // Can't assign requested address
1108
1109 // ipc/network software -- operational errors
1110 NETDOWN = 50, // Network is down
1111 NETUNREACH = 51, // Network is unreachable
1112 NETRESET = 52, // Network dropped connection on reset
1113 CONNABORTED = 53, // Software caused connection abort
1114 CONNRESET = 54, // Connection reset by peer
1115 NOBUFS = 55, // No buffer space available
1116 ISCONN = 56, // Socket is already connected
1117 NOTCONN = 57, // Socket is not connected
1118 SHUTDOWN = 58, // Can't send after socket shutdown
1119 TOOMANYREFS = 59, // Too many references: can't splice
1120 TIMEDOUT = 60, // Operation timed out
1121 CONNREFUSED = 61, // Connection refused
1122
1123 LOOP = 62, // Too many levels of symbolic links
1124 NAMETOOLONG = 63, // File name too long
1125
1126 // should be rearranged
1127 HOSTDOWN = 64, // Host is down
1128 HOSTUNREACH = 65, // No route to host
1129 NOTEMPTY = 66, // Directory not empty
1130
1131 // quotas & mush
1132 PROCLIM = 67, // Too many processes
1133 USERS = 68, // Too many users
1134 DQUOT = 69, // Disc quota exceeded
1135
1136 // Network File System
1137 STALE = 70, // Stale NFS file handle
1138 REMOTE = 71, // Too many levels of remote in path
1139 BADRPC = 72, // RPC struct is bad
1140 RPCMISMATCH = 73, // RPC version wrong
1141 PROGUNAVAIL = 74, // RPC prog. not avail
1142 PROGMISMATCH = 75, // Program version wrong
1143 PROCUNAVAIL = 76, // Bad procedure for program
1144
1145 NOLCK = 77, // No locks available
1146 NOSYS = 78, // Function not implemented
1147
1148 FTYPE = 79, // Inappropriate file type or format
1149 AUTH = 80, // Authentication error
1150 NEEDAUTH = 81, // Need authenticator
1151 IDRM = 82, // Identifier removed
1152 NOMSG = 83, // No message of desired type
1153 OVERFLOW = 84, // Value too large to be stored in data type
1154 CANCELED = 85, // Operation canceled
1155 ILSEQ = 86, // Illegal byte sequence
1156 NOATTR = 87, // Attribute not found
1157
1158 DOOFUS = 88, // Programming error
1159
1160 BADMSG = 89, // Bad message
1161 MULTIHOP = 90, // Multihop attempted
1162 NOLINK = 91, // Link has been severed
1163 PROTO = 92, // Protocol error
1164
1165 NOTCAPABLE = 93, // Capabilities insufficient
1166 CAPMODE = 94, // Not permitted in capability mode
1167 NOTRECOVERABLE = 95, // State not recoverable
1168 OWNERDEAD = 96, // Previous owner died
1169 _,
1170};
1171
1172pub const MINSIGSTKSZ = switch (builtin.cpu.arch) {
1173 .i386, .x86_64 => 2048,
1174 .arm, .aarch64 => 4096,
1175 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
1176};
1177pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
1178
1179pub const SS_ONSTACK = 1;
1180pub const SS_DISABLE = 4;
1181
1182pub const stack_t = extern struct {
1183 sp: [*]u8,
1184 size: isize,
1185 flags: i32,
1186};
1187
1188pub const S = struct {
1189 pub const IFMT = 0o170000;
1190
1191 pub const IFIFO = 0o010000;
1192 pub const IFCHR = 0o020000;
1193 pub const IFDIR = 0o040000;
1194 pub const IFBLK = 0o060000;
1195 pub const IFREG = 0o100000;
1196 pub const IFLNK = 0o120000;
1197 pub const IFSOCK = 0o140000;
1198 pub const IFWHT = 0o160000;
1199
1200 pub const ISUID = 0o4000;
1201 pub const ISGID = 0o2000;
1202 pub const ISVTX = 0o1000;
1203 pub const IRWXU = 0o700;
1204 pub const IRUSR = 0o400;
1205 pub const IWUSR = 0o200;
1206 pub const IXUSR = 0o100;
1207 pub const IRWXG = 0o070;
1208 pub const IRGRP = 0o040;
1209 pub const IWGRP = 0o020;
1210 pub const IXGRP = 0o010;
1211 pub const IRWXO = 0o007;
1212 pub const IROTH = 0o004;
1213 pub const IWOTH = 0o002;
1214 pub const IXOTH = 0o001;
1215
1216 pub fn ISFIFO(m: u32) bool {
1217 return m & IFMT == IFIFO;
1218 }
1219
1220 pub fn ISCHR(m: u32) bool {
1221 return m & IFMT == IFCHR;
1222 }
1223
1224 pub fn ISDIR(m: u32) bool {
1225 return m & IFMT == IFDIR;
1226 }
1227
1228 pub fn ISBLK(m: u32) bool {
1229 return m & IFMT == IFBLK;
1230 }
1231
1232 pub fn ISREG(m: u32) bool {
1233 return m & IFMT == IFREG;
1234 }
1235
1236 pub fn ISLNK(m: u32) bool {
1237 return m & IFMT == IFLNK;
1238 }
1239
1240 pub fn ISSOCK(m: u32) bool {
1241 return m & IFMT == IFSOCK;
1242 }
1243
1244 pub fn IWHT(m: u32) bool {
1245 return m & IFMT == IFWHT;
1246 }
1247};
1248
1249pub const HOST_NAME_MAX = 255;
1250
1251pub const AT = struct {
1252 /// Magic value that specify the use of the current working directory
1253 /// to determine the target of relative file paths in the openat() and
1254 /// similar syscalls.
1255 pub const FDCWD = -100;
1256 /// Check access using effective user and group ID
1257 pub const EACCESS = 0x0100;
1258 /// Do not follow symbolic links
1259 pub const SYMLINK_NOFOLLOW = 0x0200;
1260 /// Follow symbolic link
1261 pub const SYMLINK_FOLLOW = 0x0400;
1262 /// Remove directory instead of file
1263 pub const REMOVEDIR = 0x0800;
1264 /// Fail if not under dirfd
1265 pub const BENEATH = 0x1000;
1266};
1267
1268pub const addrinfo = extern struct {
1269 flags: i32,
1270 family: i32,
1271 socktype: i32,
1272 protocol: i32,
1273 addrlen: socklen_t,
1274 canonname: ?[*:0]u8,
1275 addr: ?*sockaddr,
1276 next: ?*addrinfo,
1277};
1278
1279pub const IPPROTO = struct {
1280 /// dummy for IP
1281 pub const IP = 0;
1282 /// control message protocol
1283 pub const ICMP = 1;
1284 /// tcp
1285 pub const TCP = 6;
1286 /// user datagram protocol
1287 pub const UDP = 17;
1288 /// IP6 header
1289 pub const IPV6 = 41;
1290 /// raw IP packet
1291 pub const RAW = 255;
1292 /// IP6 hop-by-hop options
1293 pub const HOPOPTS = 0;
1294 /// group mgmt protocol
1295 pub const IGMP = 2;
1296 /// gateway^2 (deprecated)
1297 pub const GGP = 3;
1298 /// IPv4 encapsulation
1299 pub const IPV4 = 4;
1300 /// for compatibility
1301 pub const IPIP = IPV4;
1302 /// Stream protocol II
1303 pub const ST = 7;
1304 /// exterior gateway protocol
1305 pub const EGP = 8;
1306 /// private interior gateway
1307 pub const PIGP = 9;
1308 /// BBN RCC Monitoring
1309 pub const RCCMON = 10;
1310 /// network voice protocol
1311 pub const NVPII = 11;
1312 /// pup
1313 pub const PUP = 12;
1314 /// Argus
1315 pub const ARGUS = 13;
1316 /// EMCON
1317 pub const EMCON = 14;
1318 /// Cross Net Debugger
1319 pub const XNET = 15;
1320 /// Chaos
1321 pub const CHAOS = 16;
1322 /// Multiplexing
1323 pub const MUX = 18;
1324 /// DCN Measurement Subsystems
1325 pub const MEAS = 19;
1326 /// Host Monitoring
1327 pub const HMP = 20;
1328 /// Packet Radio Measurement
1329 pub const PRM = 21;
1330 /// xns idp
1331 pub const IDP = 22;
1332 /// Trunk-1
1333 pub const TRUNK1 = 23;
1334 /// Trunk-2
1335 pub const TRUNK2 = 24;
1336 /// Leaf-1
1337 pub const LEAF1 = 25;
1338 /// Leaf-2
1339 pub const LEAF2 = 26;
1340 /// Reliable Data
1341 pub const RDP = 27;
1342 /// Reliable Transaction
1343 pub const IRTP = 28;
1344 /// tp-4 w/ class negotiation
1345 pub const TP = 29;
1346 /// Bulk Data Transfer
1347 pub const BLT = 30;
1348 /// Network Services
1349 pub const NSP = 31;
1350 /// Merit Internodal
1351 pub const INP = 32;
1352 /// Datagram Congestion Control Protocol
1353 pub const DCCP = 33;
1354 /// Third Party Connect
1355 pub const @"3PC" = 34;
1356 /// InterDomain Policy Routing
1357 pub const IDPR = 35;
1358 /// XTP
1359 pub const XTP = 36;
1360 /// Datagram Delivery
1361 pub const DDP = 37;
1362 /// Control Message Transport
1363 pub const CMTP = 38;
1364 /// TP++ Transport
1365 pub const TPXX = 39;
1366 /// IL transport protocol
1367 pub const IL = 40;
1368 /// Source Demand Routing
1369 pub const SDRP = 42;
1370 /// IP6 routing header
1371 pub const ROUTING = 43;
1372 /// IP6 fragmentation header
1373 pub const FRAGMENT = 44;
1374 /// InterDomain Routing
1375 pub const IDRP = 45;
1376 /// resource reservation
1377 pub const RSVP = 46;
1378 /// General Routing Encap.
1379 pub const GRE = 47;
1380 /// Mobile Host Routing
1381 pub const MHRP = 48;
1382 /// BHA
1383 pub const BHA = 49;
1384 /// IP6 Encap Sec. Payload
1385 pub const ESP = 50;
1386 /// IP6 Auth Header
1387 pub const AH = 51;
1388 /// Integ. Net Layer Security
1389 pub const INLSP = 52;
1390 /// IP with encryption
1391 pub const SWIPE = 53;
1392 /// Next Hop Resolution
1393 pub const NHRP = 54;
1394 /// IP Mobility
1395 pub const MOBILE = 55;
1396 /// Transport Layer Security
1397 pub const TLSP = 56;
1398 /// SKIP
1399 pub const SKIP = 57;
1400 /// ICMP6
1401 pub const ICMPV6 = 58;
1402 /// IP6 no next header
1403 pub const NONE = 59;
1404 /// IP6 destination option
1405 pub const DSTOPTS = 60;
1406 /// any host internal protocol
1407 pub const AHIP = 61;
1408 /// CFTP
1409 pub const CFTP = 62;
1410 /// "hello" routing protocol
1411 pub const HELLO = 63;
1412 /// SATNET/Backroom EXPAK
1413 pub const SATEXPAK = 64;
1414 /// Kryptolan
1415 pub const KRYPTOLAN = 65;
1416 /// Remote Virtual Disk
1417 pub const RVD = 66;
1418 /// Pluribus Packet Core
1419 pub const IPPC = 67;
1420 /// Any distributed FS
1421 pub const ADFS = 68;
1422 /// Satnet Monitoring
1423 pub const SATMON = 69;
1424 /// VISA Protocol
1425 pub const VISA = 70;
1426 /// Packet Core Utility
1427 pub const IPCV = 71;
1428 /// Comp. Prot. Net. Executive
1429 pub const CPNX = 72;
1430 /// Comp. Prot. HeartBeat
1431 pub const CPHB = 73;
1432 /// Wang Span Network
1433 pub const WSN = 74;
1434 /// Packet Video Protocol
1435 pub const PVP = 75;
1436 /// BackRoom SATNET Monitoring
1437 pub const BRSATMON = 76;
1438 /// Sun net disk proto (temp.)
1439 pub const ND = 77;
1440 /// WIDEBAND Monitoring
1441 pub const WBMON = 78;
1442 /// WIDEBAND EXPAK
1443 pub const WBEXPAK = 79;
1444 /// ISO cnlp
1445 pub const EON = 80;
1446 /// VMTP
1447 pub const VMTP = 81;
1448 /// Secure VMTP
1449 pub const SVMTP = 82;
1450 /// Banyon VINES
1451 pub const VINES = 83;
1452 /// TTP
1453 pub const TTP = 84;
1454 /// NSFNET-IGP
1455 pub const IGP = 85;
1456 /// dissimilar gateway prot.
1457 pub const DGP = 86;
1458 /// TCF
1459 pub const TCF = 87;
1460 /// Cisco/GXS IGRP
1461 pub const IGRP = 88;
1462 /// OSPFIGP
1463 pub const OSPFIGP = 89;
1464 /// Strite RPC protocol
1465 pub const SRPC = 90;
1466 /// Locus Address Resoloution
1467 pub const LARP = 91;
1468 /// Multicast Transport
1469 pub const MTP = 92;
1470 /// AX.25 Frames
1471 pub const AX25 = 93;
1472 /// IP encapsulated in IP
1473 pub const IPEIP = 94;
1474 /// Mobile Int.ing control
1475 pub const MICP = 95;
1476 /// Semaphore Comm. security
1477 pub const SCCSP = 96;
1478 /// Ethernet IP encapsulation
1479 pub const ETHERIP = 97;
1480 /// encapsulation header
1481 pub const ENCAP = 98;
1482 /// any private encr. scheme
1483 pub const APES = 99;
1484 /// GMTP
1485 pub const GMTP = 100;
1486 /// payload compression (IPComp)
1487 pub const IPCOMP = 108;
1488 /// SCTP
1489 pub const SCTP = 132;
1490 /// IPv6 Mobility Header
1491 pub const MH = 135;
1492 /// UDP-Lite
1493 pub const UDPLITE = 136;
1494 /// IP6 Host Identity Protocol
1495 pub const HIP = 139;
1496 /// IP6 Shim6 Protocol
1497 pub const SHIM6 = 140;
1498 /// Protocol Independent Mcast
1499 pub const PIM = 103;
1500 /// CARP
1501 pub const CARP = 112;
1502 /// PGM
1503 pub const PGM = 113;
1504 /// MPLS-in-IP
1505 pub const MPLS = 137;
1506 /// PFSYNC
1507 pub const PFSYNC = 240;
1508 /// Reserved
1509 pub const RESERVED_253 = 253;
1510 /// Reserved
1511 pub const RESERVED_254 = 254;
1512};
1513
1514pub const rlimit_resource = enum(c_int) {
1515 CPU = 0,
1516 FSIZE = 1,
1517 DATA = 2,
1518 STACK = 3,
1519 CORE = 4,
1520 RSS = 5,
1521 MEMLOCK = 6,
1522 NPROC = 7,
1523 NOFILE = 8,
1524 SBSIZE = 9,
1525 VMEM = 10,
1526 NPTS = 11,
1527 SWAP = 12,
1528 KQUEUES = 13,
1529 UMTXP = 14,
1530 _,
1531
1532 pub const AS: rlimit_resource = .VMEM;
1533};
1534
1535pub const rlim_t = i64;
1536
1537pub const RLIM = struct {
1538 /// No limit
1539 pub const INFINITY: rlim_t = (1 << 63) - 1;
1540
1541 pub const SAVED_MAX = INFINITY;
1542 pub const SAVED_CUR = INFINITY;
1543};
1544
1545pub const rlimit = extern struct {
1546 /// Soft limit
1547 cur: rlim_t,
1548 /// Hard limit
1549 max: rlim_t,
1550};
1551
1552pub const SHUT = struct {
1553 pub const RD = 0;
1554 pub const WR = 1;
1555 pub const RDWR = 2;
1556};
1557
1558pub const nfds_t = u32;
1559
1560pub const pollfd = extern struct {
1561 fd: fd_t,
1562 events: i16,
1563 revents: i16,
1564};
1565
1566pub const POLL = struct {
1567 /// any readable data available.
1568 pub const IN = 0x0001;
1569 /// OOB/Urgent readable data.
1570 pub const PRI = 0x0002;
1571 /// file descriptor is writeable.
1572 pub const OUT = 0x0004;
1573 /// non-OOB/URG data available.
1574 pub const RDNORM = 0x0040;
1575 /// no write type differentiation.
1576 pub const WRNORM = OUT;
1577 /// OOB/Urgent readable data.
1578 pub const RDBAND = 0x0080;
1579 /// OOB/Urgent data can be written.
1580 pub const WRBAND = 0x0100;
1581 /// like IN, except ignore EOF.
1582 pub const INIGNEOF = 0x2000;
1583 /// some poll error occurred.
1584 pub const ERR = 0x0008;
1585 /// file descriptor was "hung up".
1586 pub const HUP = 0x0010;
1587 /// requested events "invalid".
1588 pub const NVAL = 0x0020;
1589
1590 pub const STANDARD = IN | PRI | OUT | RDNORM | RDBAND | WRBAND | ERR | HUP | NVAL;
1591};
lib/std/c/haiku.zig+1298-5
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1//
2const std = @import("../std.zig");1const std = @import("../std.zig");
3const builtin = std.builtin;2const builtin = @import("builtin");
43const maxInt = std.math.maxInt;
5usingnamespace std.c;4const iovec = std.os.iovec;
5const iovec_const = std.os.iovec_const;
66
7extern "c" fn _errnop() *c_int;7extern "c" fn _errnop() *c_int;
88
...@@ -19,7 +19,7 @@ pub extern "c" fn _get_next_image_info(team: c_int, cookie: *i32, image_info: *i...@@ -19,7 +19,7 @@ pub extern "c" fn _get_next_image_info(team: c_int, cookie: *i32, image_info: *i
1919
20pub extern "c" fn _kern_read_dir(fd: c_int, buf_ptr: [*]u8, nbytes: usize, maxcount: u32) usize;20pub extern "c" fn _kern_read_dir(fd: c_int, buf_ptr: [*]u8, nbytes: usize, maxcount: u32) usize;
2121
22pub extern "c" fn _kern_read_stat(fd: c_int, path_ptr: [*]u8, traverse_link: bool, libc_stat: *libc_stat, stat_size: i32) usize;22pub extern "c" fn _kern_read_stat(fd: c_int, path_ptr: [*]u8, traverse_link: bool, st: *Stat, stat_size: i32) usize;
2323
24pub extern "c" fn _kern_get_current_team() i32;24pub extern "c" fn _kern_get_current_team() i32;
2525
...@@ -111,3 +111,1296 @@ pub const EAI = enum(c_int) {...@@ -111,3 +111,1296 @@ pub const EAI = enum(c_int) {
111};111};
112112
113pub const EAI_MAX = 15;113pub const EAI_MAX = 15;
114
115pub const fd_t = c_int;
116pub const pid_t = c_int;
117pub const uid_t = u32;
118pub const gid_t = u32;
119pub const mode_t = c_uint;
120
121pub const socklen_t = u32;
122
123/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
124pub const Kevent = extern struct {
125 ident: usize,
126 filter: i16,
127 flags: u16,
128 fflags: u32,
129 data: i64,
130 udata: usize,
131 // TODO ext
132};
133
134// Modes and flags for dlopen()
135// include/dlfcn.h
136
137pub const POLL = struct {
138 pub const IN = 0x0001;
139 pub const ERR = 0x0004;
140 pub const NVAL = 0x1000;
141 pub const HUP = 0x0080;
142};
143
144pub const RTLD = struct {
145 /// Bind function calls lazily.
146 pub const LAZY = 1;
147 /// Bind function calls immediately.
148 pub const NOW = 2;
149 pub const MODEMASK = 0x3;
150 /// Make symbols globally available.
151 pub const GLOBAL = 0x100;
152 /// Opposite of GLOBAL, and the default.
153 pub const LOCAL = 0;
154 /// Trace loaded objects and exit.
155 pub const TRACE = 0x200;
156 /// Do not remove members.
157 pub const NODELETE = 0x01000;
158 /// Do not load if not already loaded.
159 pub const NOLOAD = 0x02000;
160};
161
162pub const dl_phdr_info = extern struct {
163 dlpi_addr: usize,
164 dlpi_name: ?[*:0]const u8,
165 dlpi_phdr: [*]std.elf.Phdr,
166 dlpi_phnum: u16,
167};
168
169pub const Flock = extern struct {
170 l_start: off_t,
171 l_len: off_t,
172 l_pid: pid_t,
173 l_type: i16,
174 l_whence: i16,
175 l_sysid: i32,
176 __unused: [4]u8,
177};
178
179pub const msghdr = extern struct {
180 /// optional address
181 msg_name: ?*sockaddr,
182
183 /// size of address
184 msg_namelen: socklen_t,
185
186 /// scatter/gather array
187 msg_iov: [*]iovec,
188
189 /// # elements in msg_iov
190 msg_iovlen: i32,
191
192 /// ancillary data
193 msg_control: ?*c_void,
194
195 /// ancillary data buffer len
196 msg_controllen: socklen_t,
197
198 /// flags on received message
199 msg_flags: i32,
200};
201
202pub const msghdr_const = extern struct {
203 /// optional address
204 msg_name: ?*const sockaddr,
205
206 /// size of address
207 msg_namelen: socklen_t,
208
209 /// scatter/gather array
210 msg_iov: [*]iovec_const,
211
212 /// # elements in msg_iov
213 msg_iovlen: i32,
214
215 /// ancillary data
216 msg_control: ?*c_void,
217
218 /// ancillary data buffer len
219 msg_controllen: socklen_t,
220
221 /// flags on received message
222 msg_flags: i32,
223};
224
225pub const off_t = i64;
226pub const ino_t = u64;
227
228pub const nfds_t = u32;
229
230pub const pollfd = extern struct {
231 fd: i32,
232 events: i16,
233 revents: i16,
234};
235
236pub const Stat = extern struct {
237 dev: i32,
238 ino: u64,
239 mode: u32,
240 nlink: i32,
241 uid: i32,
242 gid: i32,
243 size: i64,
244 rdev: i32,
245 blksize: i32,
246 atim: timespec,
247 mtim: timespec,
248 ctim: timespec,
249 crtim: timespec,
250 st_type: u32,
251 blocks: i64,
252
253 pub fn atime(self: @This()) timespec {
254 return self.atim;
255 }
256 pub fn mtime(self: @This()) timespec {
257 return self.mtim;
258 }
259 pub fn ctime(self: @This()) timespec {
260 return self.ctim;
261 }
262 pub fn crtime(self: @This()) timespec {
263 return self.crtim;
264 }
265};
266
267pub const timespec = extern struct {
268 tv_sec: isize,
269 tv_nsec: isize,
270};
271
272pub const dirent = extern struct {
273 d_dev: i32,
274 d_pdev: i32,
275 d_ino: i64,
276 d_pino: i64,
277 d_reclen: u16,
278 d_name: [256]u8,
279
280 pub fn reclen(self: dirent) u16 {
281 return self.d_reclen;
282 }
283};
284
285pub const image_info = extern struct {
286 id: u32,
287 type: u32,
288 sequence: i32,
289 init_order: i32,
290 init_routine: *c_void,
291 term_routine: *c_void,
292 device: i32,
293 node: i32,
294 name: [1024]u8,
295 text: *c_void,
296 data: *c_void,
297 text_size: i32,
298 data_size: i32,
299 api_version: i32,
300 abi: i32,
301};
302
303pub const system_info = extern struct {
304 boot_time: i64,
305 cpu_count: u32,
306 max_pages: u64,
307 used_pages: u64,
308 cached_pages: u64,
309 block_cache_pages: u64,
310 ignored_pages: u64,
311 needed_memory: u64,
312 free_memory: u64,
313 max_swap_pages: u64,
314 free_swap_pages: u64,
315 page_faults: u32,
316 max_sems: u32,
317 used_sems: u32,
318 max_ports: u32,
319 used_ports: u32,
320 max_threads: u32,
321 used_threads: u32,
322 max_teams: u32,
323 used_teams: u32,
324 kernel_name: [256]u8,
325 kernel_build_date: [32]u8,
326 kernel_build_time: [32]u8,
327 kernel_version: i64,
328 abi: u32,
329};
330
331pub const in_port_t = u16;
332pub const sa_family_t = u8;
333
334pub const sockaddr = extern struct {
335 /// total length
336 len: u8,
337 /// address family
338 family: sa_family_t,
339 /// actually longer; address value
340 data: [14]u8,
341
342 pub const storage = std.x.os.Socket.Address.Native.Storage;
343
344 pub const in = extern struct {
345 len: u8 = @sizeOf(in),
346 family: sa_family_t = AF.INET,
347 port: in_port_t,
348 addr: u32,
349 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
350 };
351
352 pub const in6 = extern struct {
353 len: u8 = @sizeOf(in6),
354 family: sa_family_t = AF.INET6,
355 port: in_port_t,
356 flowinfo: u32,
357 addr: [16]u8,
358 scope_id: u32,
359 };
360
361 pub const un = extern struct {
362 len: u8 = @sizeOf(un),
363 family: sa_family_t = AF.UNIX,
364 path: [104]u8,
365 };
366};
367
368pub const CTL = struct {
369 pub const KERN = 1;
370 pub const DEBUG = 5;
371};
372
373pub const KERN = struct {
374 pub const PROC = 14; // struct: process entries
375 pub const PROC_PATHNAME = 12; // path to executable
376};
377
378pub const PATH_MAX = 1024;
379
380pub const STDIN_FILENO = 0;
381pub const STDOUT_FILENO = 1;
382pub const STDERR_FILENO = 2;
383
384pub const PROT = struct {
385 pub const NONE = 0;
386 pub const READ = 1;
387 pub const WRITE = 2;
388 pub const EXEC = 4;
389};
390
391pub const CLOCK = struct {
392 pub const MONOTONIC = 0;
393 pub const REALTIME = -1;
394 pub const PROCESS_CPUTIME_ID = -2;
395 pub const THREAD_CPUTIME_ID = -3;
396};
397
398pub const MAP = struct {
399 pub const FAILED = @intToPtr(*c_void, maxInt(usize));
400 pub const SHARED = 0x0001;
401 pub const PRIVATE = 0x0002;
402 pub const FIXED = 0x0010;
403 pub const STACK = 0x0400;
404 pub const NOSYNC = 0x0800;
405 pub const ANON = 0x1000;
406 pub const ANONYMOUS = ANON;
407 pub const FILE = 0;
408
409 pub const GUARD = 0x00002000;
410 pub const EXCL = 0x00004000;
411 pub const NOCORE = 0x00020000;
412 pub const PREFAULT_READ = 0x00040000;
413 pub const @"32BIT" = 0x00080000;
414};
415
416pub const W = struct {
417 pub const NOHANG = 0x1;
418 pub const UNTRACED = 0x2;
419 pub const STOPPED = 0x10;
420 pub const CONTINUED = 0x4;
421 pub const NOWAIT = 0x20;
422 pub const EXITED = 0x08;
423
424 pub fn EXITSTATUS(s: u32) u8 {
425 return @intCast(u8, s & 0xff);
426 }
427
428 pub fn TERMSIG(s: u32) u32 {
429 return (s >> 8) & 0xff;
430 }
431
432 pub fn STOPSIG(s: u32) u32 {
433 return EXITSTATUS(s);
434 }
435
436 pub fn IFEXITED(s: u32) bool {
437 return TERMSIG(s) == 0;
438 }
439
440 pub fn IFSTOPPED(s: u32) bool {
441 return ((s >> 16) & 0xff) != 0;
442 }
443
444 pub fn IFSIGNALED(s: u32) bool {
445 return ((s >> 8) & 0xff) != 0;
446 }
447};
448
449pub const SA = struct {
450 pub const ONSTACK = 0x20;
451 pub const RESTART = 0x10;
452 pub const RESETHAND = 0x04;
453 pub const NOCLDSTOP = 0x01;
454 pub const NODEFER = 0x08;
455 pub const NOCLDWAIT = 0x02;
456 pub const SIGINFO = 0x40;
457 pub const NOMASK = NODEFER;
458 pub const STACK = ONSTACK;
459 pub const ONESHOT = RESETHAND;
460};
461
462pub const SIG = struct {
463 pub const ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
464 pub const DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
465 pub const IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
466
467 pub const HUP = 1;
468 pub const INT = 2;
469 pub const QUIT = 3;
470 pub const ILL = 4;
471 pub const CHLD = 5;
472 pub const ABRT = 6;
473 pub const IOT = ABRT;
474 pub const PIPE = 7;
475 pub const FPE = 8;
476 pub const KILL = 9;
477 pub const STOP = 10;
478 pub const SEGV = 11;
479 pub const CONT = 12;
480 pub const TSTP = 13;
481 pub const ALRM = 14;
482 pub const TERM = 15;
483 pub const TTIN = 16;
484 pub const TTOU = 17;
485 pub const USR1 = 18;
486 pub const USR2 = 19;
487 pub const WINCH = 20;
488 pub const KILLTHR = 21;
489 pub const TRAP = 22;
490 pub const POLL = 23;
491 pub const PROF = 24;
492 pub const SYS = 25;
493 pub const URG = 26;
494 pub const VTALRM = 27;
495 pub const XCPU = 28;
496 pub const XFSZ = 29;
497 pub const BUS = 30;
498 pub const RESERVED1 = 31;
499 pub const RESERVED2 = 32;
500
501 // TODO: check
502 pub const RTMIN = 65;
503 pub const RTMAX = 126;
504
505 pub const BLOCK = 1;
506 pub const UNBLOCK = 2;
507 pub const SETMASK = 3;
508
509 pub const WORDS = 4;
510 pub const MAXSIG = 128;
511 pub inline fn IDX(sig: usize) usize {
512 return sig - 1;
513 }
514 pub inline fn WORD(sig: usize) usize {
515 return IDX(sig) >> 5;
516 }
517 pub inline fn BIT(sig: usize) usize {
518 return 1 << (IDX(sig) & 31);
519 }
520 pub inline fn VALID(sig: usize) usize {
521 return sig <= MAXSIG and sig > 0;
522 }
523};
524
525// access function
526pub const F_OK = 0; // test for existence of file
527pub const X_OK = 1; // test for execute or search permission
528pub const W_OK = 2; // test for write permission
529pub const R_OK = 4; // test for read permission
530
531pub const O = struct {
532 pub const RDONLY = 0x0000;
533 pub const WRONLY = 0x0001;
534 pub const RDWR = 0x0002;
535 pub const ACCMODE = 0x0003;
536
537 pub const SHLOCK = 0x0010;
538 pub const EXLOCK = 0x0020;
539
540 pub const CREAT = 0x0200;
541 pub const EXCL = 0x0800;
542 pub const NOCTTY = 0x8000;
543 pub const TRUNC = 0x0400;
544 pub const APPEND = 0x0008;
545 pub const NONBLOCK = 0x0004;
546 pub const DSYNC = 0o10000;
547 pub const SYNC = 0x0080;
548 pub const RSYNC = 0o4010000;
549 pub const DIRECTORY = 0x20000;
550 pub const NOFOLLOW = 0x0100;
551 pub const CLOEXEC = 0x00100000;
552
553 pub const ASYNC = 0x0040;
554 pub const DIRECT = 0x00010000;
555 pub const NOATIME = 0o1000000;
556 pub const PATH = 0o10000000;
557 pub const TMPFILE = 0o20200000;
558 pub const NDELAY = NONBLOCK;
559};
560
561pub const F = struct {
562 pub const DUPFD = 0;
563 pub const GETFD = 1;
564 pub const SETFD = 2;
565 pub const GETFL = 3;
566 pub const SETFL = 4;
567
568 pub const GETOWN = 5;
569 pub const SETOWN = 6;
570
571 pub const GETLK = 11;
572 pub const SETLK = 12;
573 pub const SETLKW = 13;
574
575 pub const RDLCK = 1;
576 pub const WRLCK = 3;
577 pub const UNLCK = 2;
578
579 pub const SETOWN_EX = 15;
580 pub const GETOWN_EX = 16;
581
582 pub const GETOWNER_UIDS = 17;
583};
584
585pub const LOCK = struct {
586 pub const SH = 1;
587 pub const EX = 2;
588 pub const UN = 8;
589 pub const NB = 4;
590};
591
592pub const FD_CLOEXEC = 1;
593
594pub const SEEK = struct {
595 pub const SET = 0;
596 pub const CUR = 1;
597 pub const END = 2;
598};
599
600pub const SOCK = struct {
601 pub const STREAM = 1;
602 pub const DGRAM = 2;
603 pub const RAW = 3;
604 pub const RDM = 4;
605 pub const SEQPACKET = 5;
606
607 pub const CLOEXEC = 0x10000000;
608 pub const NONBLOCK = 0x20000000;
609};
610
611pub const SO = struct {
612 pub const DEBUG = 0x00000001;
613 pub const ACCEPTCONN = 0x00000002;
614 pub const REUSEADDR = 0x00000004;
615 pub const KEEPALIVE = 0x00000008;
616 pub const DONTROUTE = 0x00000010;
617 pub const BROADCAST = 0x00000020;
618 pub const USELOOPBACK = 0x00000040;
619 pub const LINGER = 0x00000080;
620 pub const OOBINLINE = 0x00000100;
621 pub const REUSEPORT = 0x00000200;
622 pub const TIMESTAMP = 0x00000400;
623 pub const NOSIGPIPE = 0x00000800;
624 pub const ACCEPTFILTER = 0x00001000;
625 pub const BINTIME = 0x00002000;
626 pub const NO_OFFLOAD = 0x00004000;
627 pub const NO_DDP = 0x00008000;
628 pub const REUSEPORT_LB = 0x00010000;
629
630 pub const SNDBUF = 0x1001;
631 pub const RCVBUF = 0x1002;
632 pub const SNDLOWAT = 0x1003;
633 pub const RCVLOWAT = 0x1004;
634 pub const SNDTIMEO = 0x1005;
635 pub const RCVTIMEO = 0x1006;
636 pub const ERROR = 0x1007;
637 pub const TYPE = 0x1008;
638 pub const LABEL = 0x1009;
639 pub const PEERLABEL = 0x1010;
640 pub const LISTENQLIMIT = 0x1011;
641 pub const LISTENQLEN = 0x1012;
642 pub const LISTENINCQLEN = 0x1013;
643 pub const SETFIB = 0x1014;
644 pub const USER_COOKIE = 0x1015;
645 pub const PROTOCOL = 0x1016;
646 pub const PROTOTYPE = PROTOCOL;
647 pub const TS_CLOCK = 0x1017;
648 pub const MAX_PACING_RATE = 0x1018;
649 pub const DOMAIN = 0x1019;
650};
651
652pub const SOL = struct {
653 pub const SOCKET = 0xffff;
654};
655
656pub const PF = struct {
657 pub const UNSPEC = AF.UNSPEC;
658 pub const LOCAL = AF.LOCAL;
659 pub const UNIX = PF.LOCAL;
660 pub const INET = AF.INET;
661 pub const IMPLINK = AF.IMPLINK;
662 pub const PUP = AF.PUP;
663 pub const CHAOS = AF.CHAOS;
664 pub const NETBIOS = AF.NETBIOS;
665 pub const ISO = AF.ISO;
666 pub const OSI = AF.ISO;
667 pub const ECMA = AF.ECMA;
668 pub const DATAKIT = AF.DATAKIT;
669 pub const CCITT = AF.CCITT;
670 pub const DECnet = AF.DECnet;
671 pub const DLI = AF.DLI;
672 pub const LAT = AF.LAT;
673 pub const HYLINK = AF.HYLINK;
674 pub const APPLETALK = AF.APPLETALK;
675 pub const ROUTE = AF.ROUTE;
676 pub const LINK = AF.LINK;
677 pub const XTP = AF.pseudo_XTP;
678 pub const COIP = AF.COIP;
679 pub const CNT = AF.CNT;
680 pub const SIP = AF.SIP;
681 pub const IPX = AF.IPX;
682 pub const RTIP = AF.pseudo_RTIP;
683 pub const PIP = AF.pseudo_PIP;
684 pub const ISDN = AF.ISDN;
685 pub const KEY = AF.pseudo_KEY;
686 pub const INET6 = AF.pseudo_INET6;
687 pub const NATM = AF.NATM;
688 pub const ATM = AF.ATM;
689 pub const NETGRAPH = AF.NETGRAPH;
690 pub const SLOW = AF.SLOW;
691 pub const SCLUSTER = AF.SCLUSTER;
692 pub const ARP = AF.ARP;
693 pub const BLUETOOTH = AF.BLUETOOTH;
694 pub const IEEE80211 = AF.IEEE80211;
695 pub const INET_SDP = AF.INET_SDP;
696 pub const INET6_SDP = AF.INET6_SDP;
697 pub const MAX = AF.MAX;
698};
699
700pub const AF = struct {
701 pub const UNSPEC = 0;
702 pub const UNIX = 1;
703 pub const LOCAL = UNIX;
704 pub const FILE = LOCAL;
705 pub const INET = 2;
706 pub const IMPLINK = 3;
707 pub const PUP = 4;
708 pub const CHAOS = 5;
709 pub const NETBIOS = 6;
710 pub const ISO = 7;
711 pub const OSI = ISO;
712 pub const ECMA = 8;
713 pub const DATAKIT = 9;
714 pub const CCITT = 10;
715 pub const SNA = 11;
716 pub const DECnet = 12;
717 pub const DLI = 13;
718 pub const LAT = 14;
719 pub const HYLINK = 15;
720 pub const APPLETALK = 16;
721 pub const ROUTE = 17;
722 pub const LINK = 18;
723 pub const pseudo_XTP = 19;
724 pub const COIP = 20;
725 pub const CNT = 21;
726 pub const pseudo_RTIP = 22;
727 pub const IPX = 23;
728 pub const SIP = 24;
729 pub const pseudo_PIP = 25;
730 pub const ISDN = 26;
731 pub const E164 = ISDN;
732 pub const pseudo_KEY = 27;
733 pub const INET6 = 28;
734 pub const NATM = 29;
735 pub const ATM = 30;
736 pub const pseudo_HDRCMPLT = 31;
737 pub const NETGRAPH = 32;
738 pub const SLOW = 33;
739 pub const SCLUSTER = 34;
740 pub const ARP = 35;
741 pub const BLUETOOTH = 36;
742 pub const IEEE80211 = 37;
743 pub const INET_SDP = 40;
744 pub const INET6_SDP = 42;
745 pub const MAX = 42;
746};
747
748pub const DT = struct {
749 pub const UNKNOWN = 0;
750 pub const FIFO = 1;
751 pub const CHR = 2;
752 pub const DIR = 4;
753 pub const BLK = 6;
754 pub const REG = 8;
755 pub const LNK = 10;
756 pub const SOCK = 12;
757 pub const WHT = 14;
758};
759
760/// add event to kq (implies enable)
761pub const EV_ADD = 0x0001;
762
763/// delete event from kq
764pub const EV_DELETE = 0x0002;
765
766/// enable event
767pub const EV_ENABLE = 0x0004;
768
769/// disable event (not reported)
770pub const EV_DISABLE = 0x0008;
771
772/// only report one occurrence
773pub const EV_ONESHOT = 0x0010;
774
775/// clear event state after reporting
776pub const EV_CLEAR = 0x0020;
777
778/// force immediate event output
779/// ... with or without EV_ERROR
780/// ... use KEVENT_FLAG_ERROR_EVENTS
781/// on syscalls supporting flags
782pub const EV_RECEIPT = 0x0040;
783
784/// disable event after reporting
785pub const EV_DISPATCH = 0x0080;
786
787pub const EVFILT_READ = -1;
788pub const EVFILT_WRITE = -2;
789
790/// attached to aio requests
791pub const EVFILT_AIO = -3;
792
793/// attached to vnodes
794pub const EVFILT_VNODE = -4;
795
796/// attached to struct proc
797pub const EVFILT_PROC = -5;
798
799/// attached to struct proc
800pub const EVFILT_SIGNAL = -6;
801
802/// timers
803pub const EVFILT_TIMER = -7;
804
805/// Process descriptors
806pub const EVFILT_PROCDESC = -8;
807
808/// Filesystem events
809pub const EVFILT_FS = -9;
810
811pub const EVFILT_LIO = -10;
812
813/// User events
814pub const EVFILT_USER = -11;
815
816/// Sendfile events
817pub const EVFILT_SENDFILE = -12;
818
819pub const EVFILT_EMPTY = -13;
820
821pub const T = struct {
822 pub const CGETA = 0x8000;
823 pub const CSETA = 0x8001;
824 pub const CSETAW = 0x8004;
825 pub const CSETAF = 0x8003;
826 pub const CSBRK = 08005;
827 pub const CXONC = 0x8007;
828 pub const CFLSH = 0x8006;
829
830 pub const IOCSCTTY = 0x8017;
831 pub const IOCGPGRP = 0x8015;
832 pub const IOCSPGRP = 0x8016;
833 pub const IOCGWINSZ = 0x8012;
834 pub const IOCSWINSZ = 0x8013;
835 pub const IOCMGET = 0x8018;
836 pub const IOCMBIS = 0x8022;
837 pub const IOCMBIC = 0x8023;
838 pub const IOCMSET = 0x8019;
839 pub const FIONREAD = 0xbe000001;
840 pub const FIONBIO = 0xbe000000;
841 pub const IOCSBRK = 0x8020;
842 pub const IOCCBRK = 0x8021;
843 pub const IOCGSID = 0x8024;
844};
845
846pub const winsize = extern struct {
847 ws_row: u16,
848 ws_col: u16,
849 ws_xpixel: u16,
850 ws_ypixel: u16,
851};
852
853const NSIG = 32;
854
855/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
856pub const Sigaction = extern struct {
857 /// signal handler
858 __sigaction_u: extern union {
859 __sa_handler: fn (i32) callconv(.C) void,
860 },
861
862 /// see signal options
863 sa_flags: u32,
864
865 /// signal mask to apply
866 sa_mask: sigset_t,
867};
868
869pub const sigset_t = extern struct {
870 __bits: [SIG.WORDS]u32,
871};
872
873pub const E = enum(i32) {
874 /// No error occurred.
875 SUCCESS = 0,
876 PERM = -0x7ffffff1, // Operation not permitted
877 NOENT = -0x7fff9ffd, // No such file or directory
878 SRCH = -0x7fff8ff3, // No such process
879 INTR = -0x7ffffff6, // Interrupted system call
880 IO = -0x7fffffff, // Input/output error
881 NXIO = -0x7fff8ff5, // Device not configured
882 @"2BIG" = -0x7fff8fff, // Argument list too long
883 NOEXEC = -0x7fffecfe, // Exec format error
884 CHILD = -0x7fff8ffe, // No child processes
885 DEADLK = -0x7fff8ffd, // Resource deadlock avoided
886 NOMEM = -0x80000000, // Cannot allocate memory
887 ACCES = -0x7ffffffe, // Permission denied
888 FAULT = -0x7fffecff, // Bad address
889 BUSY = -0x7ffffff2, // Device busy
890 EXIST = -0x7fff9ffe, // File exists
891 XDEV = -0x7fff9ff5, // Cross-device link
892 NODEV = -0x7fff8ff9, // Operation not supported by device
893 NOTDIR = -0x7fff9ffb, // Not a directory
894 ISDIR = -0x7fff9ff7, // Is a directory
895 INVAL = -0x7ffffffb, // Invalid argument
896 NFILE = -0x7fff8ffa, // Too many open files in system
897 MFILE = -0x7fff9ff6, // Too many open files
898 NOTTY = -0x7fff8ff6, // Inappropriate ioctl for device
899 TXTBSY = -0x7fff8fc5, // Text file busy
900 FBIG = -0x7fff8ffc, // File too large
901 NOSPC = -0x7fff9ff9, // No space left on device
902 SPIPE = -0x7fff8ff4, // Illegal seek
903 ROFS = -0x7fff9ff8, // Read-only filesystem
904 MLINK = -0x7fff8ffb, // Too many links
905 PIPE = -0x7fff9ff3, // Broken pipe
906 BADF = -0x7fffa000, // Bad file descriptor
907
908 // math software
909 DOM = 33, // Numerical argument out of domain
910 RANGE = 34, // Result too large
911
912 // non-blocking and interrupt i/o
913
914 /// Also used for `WOULDBLOCK`.
915 AGAIN = -0x7ffffff5,
916 INPROGRESS = -0x7fff8fdc,
917 ALREADY = -0x7fff8fdb,
918
919 // ipc/network software -- argument errors
920 NOTSOCK = 38, // Socket operation on non-socket
921 DESTADDRREQ = 39, // Destination address required
922 MSGSIZE = 40, // Message too long
923 PROTOTYPE = 41, // Protocol wrong type for socket
924 NOPROTOOPT = 42, // Protocol not available
925 PROTONOSUPPORT = 43, // Protocol not supported
926 SOCKTNOSUPPORT = 44, // Socket type not supported
927 /// Also used for `NOTSUP`.
928 OPNOTSUPP = 45, // Operation not supported
929 PFNOSUPPORT = 46, // Protocol family not supported
930 AFNOSUPPORT = 47, // Address family not supported by protocol family
931 ADDRINUSE = 48, // Address already in use
932 ADDRNOTAVAIL = 49, // Can't assign requested address
933
934 // ipc/network software -- operational errors
935 NETDOWN = 50, // Network is down
936 NETUNREACH = 51, // Network is unreachable
937 NETRESET = 52, // Network dropped connection on reset
938 CONNABORTED = 53, // Software caused connection abort
939 CONNRESET = 54, // Connection reset by peer
940 NOBUFS = 55, // No buffer space available
941 ISCONN = 56, // Socket is already connected
942 NOTCONN = 57, // Socket is not connected
943 SHUTDOWN = 58, // Can't send after socket shutdown
944 TOOMANYREFS = 59, // Too many references: can't splice
945 TIMEDOUT = 60, // Operation timed out
946 CONNREFUSED = 61, // Connection refused
947
948 LOOP = 62, // Too many levels of symbolic links
949 NAMETOOLONG = 63, // File name too long
950
951 // should be rearranged
952 HOSTDOWN = 64, // Host is down
953 HOSTUNREACH = 65, // No route to host
954 NOTEMPTY = 66, // Directory not empty
955
956 // quotas & mush
957 PROCLIM = 67, // Too many processes
958 USERS = 68, // Too many users
959 DQUOT = 69, // Disc quota exceeded
960
961 // Network File System
962 STALE = 70, // Stale NFS file handle
963 REMOTE = 71, // Too many levels of remote in path
964 BADRPC = 72, // RPC struct is bad
965 RPCMISMATCH = 73, // RPC version wrong
966 PROGUNAVAIL = 74, // RPC prog. not avail
967 PROGMISMATCH = 75, // Program version wrong
968 PROCUNAVAIL = 76, // Bad procedure for program
969
970 NOLCK = 77, // No locks available
971 NOSYS = 78, // Function not implemented
972
973 FTYPE = 79, // Inappropriate file type or format
974 AUTH = 80, // Authentication error
975 NEEDAUTH = 81, // Need authenticator
976 IDRM = 82, // Identifier removed
977 NOMSG = 83, // No message of desired type
978 OVERFLOW = 84, // Value too large to be stored in data type
979 CANCELED = 85, // Operation canceled
980 ILSEQ = 86, // Illegal byte sequence
981 NOATTR = 87, // Attribute not found
982
983 DOOFUS = 88, // Programming error
984
985 BADMSG = 89, // Bad message
986 MULTIHOP = 90, // Multihop attempted
987 NOLINK = 91, // Link has been severed
988 PROTO = 92, // Protocol error
989
990 NOTCAPABLE = 93, // Capabilities insufficient
991 CAPMODE = 94, // Not permitted in capability mode
992 NOTRECOVERABLE = 95, // State not recoverable
993 OWNERDEAD = 96, // Previous owner died
994
995 _,
996};
997
998pub const MINSIGSTKSZ = switch (builtin.cpu.arch) {
999 .i386, .x86_64 => 2048,
1000 .arm, .aarch64 => 4096,
1001 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
1002};
1003pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
1004
1005pub const SS_ONSTACK = 1;
1006pub const SS_DISABLE = 4;
1007
1008pub const stack_t = extern struct {
1009 sp: [*]u8,
1010 size: isize,
1011 flags: i32,
1012};
1013
1014pub const S = struct {
1015 pub const IFMT = 0o170000;
1016
1017 pub const IFIFO = 0o010000;
1018 pub const IFCHR = 0o020000;
1019 pub const IFDIR = 0o040000;
1020 pub const IFBLK = 0o060000;
1021 pub const IFREG = 0o100000;
1022 pub const IFLNK = 0o120000;
1023 pub const IFSOCK = 0o140000;
1024 pub const IFWHT = 0o160000;
1025
1026 pub const ISUID = 0o4000;
1027 pub const ISGID = 0o2000;
1028 pub const ISVTX = 0o1000;
1029 pub const IRWXU = 0o700;
1030 pub const IRUSR = 0o400;
1031 pub const IWUSR = 0o200;
1032 pub const IXUSR = 0o100;
1033 pub const IRWXG = 0o070;
1034 pub const IRGRP = 0o040;
1035 pub const IWGRP = 0o020;
1036 pub const IXGRP = 0o010;
1037 pub const IRWXO = 0o007;
1038 pub const IROTH = 0o004;
1039 pub const IWOTH = 0o002;
1040 pub const IXOTH = 0o001;
1041
1042 pub fn ISFIFO(m: u32) bool {
1043 return m & IFMT == IFIFO;
1044 }
1045
1046 pub fn ISCHR(m: u32) bool {
1047 return m & IFMT == IFCHR;
1048 }
1049
1050 pub fn ISDIR(m: u32) bool {
1051 return m & IFMT == IFDIR;
1052 }
1053
1054 pub fn ISBLK(m: u32) bool {
1055 return m & IFMT == IFBLK;
1056 }
1057
1058 pub fn ISREG(m: u32) bool {
1059 return m & IFMT == IFREG;
1060 }
1061
1062 pub fn ISLNK(m: u32) bool {
1063 return m & IFMT == IFLNK;
1064 }
1065
1066 pub fn ISSOCK(m: u32) bool {
1067 return m & IFMT == IFSOCK;
1068 }
1069
1070 pub fn IWHT(m: u32) bool {
1071 return m & IFMT == IFWHT;
1072 }
1073};
1074
1075pub const HOST_NAME_MAX = 255;
1076
1077pub const AT = struct {
1078 /// Magic value that specify the use of the current working directory
1079 /// to determine the target of relative file paths in the openat() and
1080 /// similar syscalls.
1081 pub const FDCWD = -100;
1082 /// Check access using effective user and group ID
1083 pub const EACCESS = 0x0100;
1084 /// Do not follow symbolic links
1085 pub const SYMLINK_NOFOLLOW = 0x0200;
1086 /// Follow symbolic link
1087 pub const SYMLINK_FOLLOW = 0x0400;
1088 /// Remove directory instead of file
1089 pub const REMOVEDIR = 0x0800;
1090 /// Fail if not under dirfd
1091 pub const BENEATH = 0x1000;
1092};
1093
1094pub const addrinfo = extern struct {
1095 flags: i32,
1096 family: i32,
1097 socktype: i32,
1098 protocol: i32,
1099 addrlen: socklen_t,
1100 canonname: ?[*:0]u8,
1101 addr: ?*sockaddr,
1102 next: ?*addrinfo,
1103};
1104
1105pub const IPPROTO = struct {
1106 /// dummy for IP
1107 pub const IP = 0;
1108 /// control message protocol
1109 pub const ICMP = 1;
1110 /// tcp
1111 pub const TCP = 6;
1112 /// user datagram protocol
1113 pub const UDP = 17;
1114 /// IP6 header
1115 pub const IPV6 = 41;
1116 /// raw IP packet
1117 pub const RAW = 255;
1118 /// IP6 hop-by-hop options
1119 pub const HOPOPTS = 0;
1120 /// group mgmt protocol
1121 pub const IGMP = 2;
1122 /// gateway^2 (deprecated)
1123 pub const GGP = 3;
1124 /// IPv4 encapsulation
1125 pub const IPV4 = 4;
1126 /// for compatibility
1127 pub const IPIP = IPV4;
1128 /// Stream protocol II
1129 pub const ST = 7;
1130 /// exterior gateway protocol
1131 pub const EGP = 8;
1132 /// private interior gateway
1133 pub const PIGP = 9;
1134 /// BBN RCC Monitoring
1135 pub const RCCMON = 10;
1136 /// network voice protocol
1137 pub const NVPII = 11;
1138 /// pup
1139 pub const PUP = 12;
1140 /// Argus
1141 pub const ARGUS = 13;
1142 /// EMCON
1143 pub const EMCON = 14;
1144 /// Cross Net Debugger
1145 pub const XNET = 15;
1146 /// Chaos
1147 pub const CHAOS = 16;
1148 /// Multiplexing
1149 pub const MUX = 18;
1150 /// DCN Measurement Subsystems
1151 pub const MEAS = 19;
1152 /// Host Monitoring
1153 pub const HMP = 20;
1154 /// Packet Radio Measurement
1155 pub const PRM = 21;
1156 /// xns idp
1157 pub const IDP = 22;
1158 /// Trunk-1
1159 pub const TRUNK1 = 23;
1160 /// Trunk-2
1161 pub const TRUNK2 = 24;
1162 /// Leaf-1
1163 pub const LEAF1 = 25;
1164 /// Leaf-2
1165 pub const LEAF2 = 26;
1166 /// Reliable Data
1167 pub const RDP = 27;
1168 /// Reliable Transaction
1169 pub const IRTP = 28;
1170 /// tp-4 w/ class negotiation
1171 pub const TP = 29;
1172 /// Bulk Data Transfer
1173 pub const BLT = 30;
1174 /// Network Services
1175 pub const NSP = 31;
1176 /// Merit Internodal
1177 pub const INP = 32;
1178 /// Datagram Congestion Control Protocol
1179 pub const DCCP = 33;
1180 /// Third Party Connect
1181 pub const @"3PC" = 34;
1182 /// InterDomain Policy Routing
1183 pub const IDPR = 35;
1184 /// XTP
1185 pub const XTP = 36;
1186 /// Datagram Delivery
1187 pub const DDP = 37;
1188 /// Control Message Transport
1189 pub const CMTP = 38;
1190 /// TP++ Transport
1191 pub const TPXX = 39;
1192 /// IL transport protocol
1193 pub const IL = 40;
1194 /// Source Demand Routing
1195 pub const SDRP = 42;
1196 /// IP6 routing header
1197 pub const ROUTING = 43;
1198 /// IP6 fragmentation header
1199 pub const FRAGMENT = 44;
1200 /// InterDomain Routing
1201 pub const IDRP = 45;
1202 /// resource reservation
1203 pub const RSVP = 46;
1204 /// General Routing Encap.
1205 pub const GRE = 47;
1206 /// Mobile Host Routing
1207 pub const MHRP = 48;
1208 /// BHA
1209 pub const BHA = 49;
1210 /// IP6 Encap Sec. Payload
1211 pub const ESP = 50;
1212 /// IP6 Auth Header
1213 pub const AH = 51;
1214 /// Integ. Net Layer Security
1215 pub const INLSP = 52;
1216 /// IP with encryption
1217 pub const SWIPE = 53;
1218 /// Next Hop Resolution
1219 pub const NHRP = 54;
1220 /// IP Mobility
1221 pub const MOBILE = 55;
1222 /// Transport Layer Security
1223 pub const TLSP = 56;
1224 /// SKIP
1225 pub const SKIP = 57;
1226 /// ICMP6
1227 pub const ICMPV6 = 58;
1228 /// IP6 no next header
1229 pub const NONE = 59;
1230 /// IP6 destination option
1231 pub const DSTOPTS = 60;
1232 /// any host internal protocol
1233 pub const AHIP = 61;
1234 /// CFTP
1235 pub const CFTP = 62;
1236 /// "hello" routing protocol
1237 pub const HELLO = 63;
1238 /// SATNET/Backroom EXPAK
1239 pub const SATEXPAK = 64;
1240 /// Kryptolan
1241 pub const KRYPTOLAN = 65;
1242 /// Remote Virtual Disk
1243 pub const RVD = 66;
1244 /// Pluribus Packet Core
1245 pub const IPPC = 67;
1246 /// Any distributed FS
1247 pub const ADFS = 68;
1248 /// Satnet Monitoring
1249 pub const SATMON = 69;
1250 /// VISA Protocol
1251 pub const VISA = 70;
1252 /// Packet Core Utility
1253 pub const IPCV = 71;
1254 /// Comp. Prot. Net. Executive
1255 pub const CPNX = 72;
1256 /// Comp. Prot. HeartBeat
1257 pub const CPHB = 73;
1258 /// Wang Span Network
1259 pub const WSN = 74;
1260 /// Packet Video Protocol
1261 pub const PVP = 75;
1262 /// BackRoom SATNET Monitoring
1263 pub const BRSATMON = 76;
1264 /// Sun net disk proto (temp.)
1265 pub const ND = 77;
1266 /// WIDEBAND Monitoring
1267 pub const WBMON = 78;
1268 /// WIDEBAND EXPAK
1269 pub const WBEXPAK = 79;
1270 /// ISO cnlp
1271 pub const EON = 80;
1272 /// VMTP
1273 pub const VMTP = 81;
1274 /// Secure VMTP
1275 pub const SVMTP = 82;
1276 /// Banyon VINES
1277 pub const VINES = 83;
1278 /// TTP
1279 pub const TTP = 84;
1280 /// NSFNET-IGP
1281 pub const IGP = 85;
1282 /// dissimilar gateway prot.
1283 pub const DGP = 86;
1284 /// TCF
1285 pub const TCF = 87;
1286 /// Cisco/GXS IGRP
1287 pub const IGRP = 88;
1288 /// OSPFIGP
1289 pub const OSPFIGP = 89;
1290 /// Strite RPC protocol
1291 pub const SRPC = 90;
1292 /// Locus Address Resoloution
1293 pub const LARP = 91;
1294 /// Multicast Transport
1295 pub const MTP = 92;
1296 /// AX.25 Frames
1297 pub const AX25 = 93;
1298 /// IP encapsulated in IP
1299 pub const IPEIP = 94;
1300 /// Mobile Int.ing control
1301 pub const MICP = 95;
1302 /// Semaphore Comm. security
1303 pub const SCCSP = 96;
1304 /// Ethernet IP encapsulation
1305 pub const ETHERIP = 97;
1306 /// encapsulation header
1307 pub const ENCAP = 98;
1308 /// any private encr. scheme
1309 pub const APES = 99;
1310 /// GMTP
1311 pub const GMTP = 100;
1312 /// payload compression (IPComp)
1313 pub const IPCOMP = 108;
1314 /// SCTP
1315 pub const SCTP = 132;
1316 /// IPv6 Mobility Header
1317 pub const MH = 135;
1318 /// UDP-Lite
1319 pub const UDPLITE = 136;
1320 /// IP6 Host Identity Protocol
1321 pub const HIP = 139;
1322 /// IP6 Shim6 Protocol
1323 pub const SHIM6 = 140;
1324 /// Protocol Independent Mcast
1325 pub const PIM = 103;
1326 /// CARP
1327 pub const CARP = 112;
1328 /// PGM
1329 pub const PGM = 113;
1330 /// MPLS-in-IP
1331 pub const MPLS = 137;
1332 /// PFSYNC
1333 pub const PFSYNC = 240;
1334 /// Reserved
1335 pub const RESERVED_253 = 253;
1336 /// Reserved
1337 pub const RESERVED_254 = 254;
1338};
1339
1340pub const rlimit_resource = enum(c_int) {
1341 CPU = 0,
1342 FSIZE = 1,
1343 DATA = 2,
1344 STACK = 3,
1345 CORE = 4,
1346 RSS = 5,
1347 MEMLOCK = 6,
1348 NPROC = 7,
1349 NOFILE = 8,
1350 SBSIZE = 9,
1351 VMEM = 10,
1352 NPTS = 11,
1353 SWAP = 12,
1354 KQUEUES = 13,
1355 UMTXP = 14,
1356 _,
1357
1358 pub const AS: rlimit_resource = .VMEM;
1359};
1360
1361pub const rlim_t = i64;
1362
1363pub const RLIM = struct {
1364 /// No limit
1365 pub const INFINITY: rlim_t = (1 << 63) - 1;
1366
1367 pub const SAVED_MAX = INFINITY;
1368 pub const SAVED_CUR = INFINITY;
1369};
1370
1371pub const rlimit = extern struct {
1372 /// Soft limit
1373 cur: rlim_t,
1374 /// Hard limit
1375 max: rlim_t,
1376};
1377
1378pub const SHUT = struct {
1379 pub const RD = 0;
1380 pub const WR = 1;
1381 pub const RDWR = 2;
1382};
1383
1384// TODO fill out if needed
1385pub const directory_which = enum(c_int) {
1386 B_USER_SETTINGS_DIRECTORY = 0xbbe,
1387
1388 _,
1389};
1390
1391pub const cc_t = u8;
1392pub const speed_t = u8;
1393pub const tcflag_t = u32;
1394
1395pub const NCCS = 32;
1396
1397pub const termios = extern struct {
1398 c_iflag: tcflag_t,
1399 c_oflag: tcflag_t,
1400 c_cflag: tcflag_t,
1401 c_lflag: tcflag_t,
1402 c_line: cc_t,
1403 c_ispeed: speed_t,
1404 c_ospeed: speed_t,
1405 cc_t: [NCCS]cc_t,
1406};
lib/std/c/hermit.zig+4-1
...@@ -1,3 +1,6 @@...@@ -1,3 +1,6 @@
1const std = @import("std");
2const maxInt = std.math.maxInt;
3
1pub const pthread_mutex_t = extern struct {4pub const pthread_mutex_t = extern struct {
2 inner: usize = ~@as(usize, 0),5 inner: usize = ~@as(usize, 0),
3};6};
...@@ -5,5 +8,5 @@ pub const pthread_cond_t = extern struct {...@@ -5,5 +8,5 @@ pub const pthread_cond_t = extern struct {
5 inner: usize = ~@as(usize, 0),8 inner: usize = ~@as(usize, 0),
6};9};
7pub const pthread_rwlock_t = extern struct {10pub const pthread_rwlock_t = extern struct {
8 ptr: usize = std.math.maxInt(usize),11 ptr: usize = maxInt(usize),
9};12};
lib/std/c/linux.zig+198-31
...@@ -1,11 +1,106 @@...@@ -1,11 +1,106 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = @import("builtin");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const abi = std.Target.current.abi;4const native_abi = builtin.abi;
4const arch = std.Target.current.cpu.arch;5const native_arch = builtin.cpu.arch;
5const os_tag = std.Target.current.os.tag;6const linux = std.os.linux;
6usingnamespace std.c;7const iovec = std.os.iovec;
8const iovec_const = std.os.iovec_const;
9const FILE = std.c.FILE;
710
8pub const _errno = switch (abi) {11pub const AF = linux.AF;
12pub const ARCH = linux.ARCH;
13pub const AT = linux.AT;
14pub const CLOCK = linux.CLOCK;
15pub const CPU_COUNT = linux.CPU_COUNT;
16pub const E = linux.E;
17pub const Elf_Symndx = linux.Elf_Symndx;
18pub const F = linux.F;
19pub const FD_CLOEXEC = linux.FD_CLOEXEC;
20pub const F_OK = linux.F_OK;
21pub const Flock = linux.Flock;
22pub const HOST_NAME_MAX = linux.HOST_NAME_MAX;
23pub const IFNAMESIZE = linux.IFNAMESIZE;
24pub const IOV_MAX = linux.IOV_MAX;
25pub const IPPROTO = linux.IPPROTO;
26pub const LOCK = linux.LOCK;
27pub const MADV = linux.MADV;
28pub const MAP = struct {
29 pub usingnamespace linux.MAP;
30 /// Only used by libc to communicate failure.
31 pub const FAILED = @intToPtr(*c_void, maxInt(usize));
32};
33pub const MMAP2_UNIT = linux.MMAP2_UNIT;
34pub const MSG = linux.MSG;
35pub const NAME_MAX = linux.NAME_MAX;
36pub const O = linux.O;
37pub const PATH_MAX = linux.PATH_MAX;
38pub const POLL = linux.POLL;
39pub const PROT = linux.PROT;
40pub const REG = linux.REG;
41pub const RLIM = linux.RLIM;
42pub const R_OK = linux.R_OK;
43pub const S = linux.S;
44pub const SA = linux.SA;
45pub const SC = linux.SC;
46pub const SEEK = linux.SEEK;
47pub const SHUT = linux.SHUT;
48pub const SIG = linux.SIG;
49pub const SIOCGIFINDEX = linux.SIOCGIFINDEX;
50pub const SO = linux.SO;
51pub const SOCK = linux.SOCK;
52pub const SOL = linux.SOL;
53pub const STDERR_FILENO = linux.STDERR_FILENO;
54pub const STDIN_FILENO = linux.STDIN_FILENO;
55pub const STDOUT_FILENO = linux.STDOUT_FILENO;
56pub const SYS = linux.SYS;
57pub const Sigaction = linux.Sigaction;
58pub const TCP = linux.TCP;
59pub const VDSO = linux.VDSO;
60pub const W = linux.W;
61pub const W_OK = linux.W_OK;
62pub const X_OK = linux.X_OK;
63pub const addrinfo = linux.addrinfo;
64pub const blkcnt_t = linux.blkcnt_t;
65pub const blksize_t = linux.blksize_t;
66pub const clock_t = linux.clock_t;
67pub const cpu_set_t = linux.cpu_set_t;
68pub const dev_t = linux.dev_t;
69pub const dl_phdr_info = linux.dl_phdr_info;
70pub const empty_sigset = linux.empty_sigset;
71pub const epoll_event = linux.epoll_event;
72pub const fd_t = linux.fd_t;
73pub const gid_t = linux.gid_t;
74pub const ifreq = linux.ifreq;
75pub const ino_t = linux.ino_t;
76pub const mcontext_t = linux.mcontext_t;
77pub const mode_t = linux.mode_t;
78pub const msghdr = linux.msghdr;
79pub const msghdr_const = linux.msghdr_const;
80pub const nfds_t = linux.nfds_t;
81pub const nlink_t = linux.nlink_t;
82pub const off_t = linux.off_t;
83pub const pid_t = linux.pid_t;
84pub const pollfd = linux.pollfd;
85pub const rlim_t = linux.rlim_t;
86pub const rlimit = linux.rlimit;
87pub const rlimit_resource = linux.rlimit_resource;
88pub const siginfo_t = linux.siginfo_t;
89pub const sigset_t = linux.sigset_t;
90pub const sockaddr = linux.sockaddr;
91pub const socklen_t = linux.socklen_t;
92pub const stack_t = linux.stack_t;
93pub const time_t = linux.time_t;
94pub const timespec = linux.timespec;
95pub const timeval = linux.timeval;
96pub const timezone = linux.timezone;
97pub const ucontext_t = linux.ucontext_t;
98pub const uid_t = linux.uid_t;
99pub const user_desc = linux.user_desc;
100pub const utsname = linux.utsname;
101pub const PR = linux.PR;
102
103pub const _errno = switch (native_abi) {
9 .android => struct {104 .android => struct {
10 extern "c" var __errno: c_int;105 extern "c" var __errno: c_int;
11 fn getErrno() *c_int {106 fn getErrno() *c_int {
...@@ -17,22 +112,92 @@ pub const _errno = switch (abi) {...@@ -17,22 +112,92 @@ pub const _errno = switch (abi) {
17 }.__errno_location,112 }.__errno_location,
18};113};
19114
20pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));115pub const Stat = switch (native_arch) {
116 .sparcv9 => extern struct {
117 dev: u64,
118 ino: ino_t,
119 mode: u32,
120 nlink: usize,
121
122 uid: u32,
123 gid: u32,
124 rdev: u64,
125 __pad0: u32,
126
127 size: off_t,
128 blksize: isize,
129 blocks: i64,
130
131 atim: timespec,
132 mtim: timespec,
133 ctim: timespec,
134 __unused: [2]isize,
135
136 pub fn atime(self: @This()) timespec {
137 return self.atim;
138 }
139
140 pub fn mtime(self: @This()) timespec {
141 return self.mtim;
142 }
143
144 pub fn ctime(self: @This()) timespec {
145 return self.ctim;
146 }
147 },
148 .mips, .mipsel => extern struct {
149 dev: dev_t,
150 __pad0: [2]u32,
151 ino: ino_t,
152 mode: mode_t,
153 nlink: nlink_t,
154 uid: uid_t,
155 gid: gid_t,
156 rdev: dev_t,
157 __pad1: [2]u32,
158 size: off_t,
159 atim: timespec,
160 mtim: timespec,
161 ctim: timespec,
162 blksize: blksize_t,
163 __pad3: u32,
164 blocks: blkcnt_t,
165 __pad4: [14]u32,
166
167 pub fn atime(self: @This()) timespec {
168 return self.atim;
169 }
170
171 pub fn mtime(self: @This()) timespec {
172 return self.mtim;
173 }
174
175 pub fn ctime(self: @This()) timespec {
176 return self.ctim;
177 }
178 },
179
180 else => std.os.linux.Stat, // libc stat is the same as kernel stat.
181};
21182
22pub const AI_PASSIVE = 0x01;183pub const AI = struct {
23pub const AI_CANONNAME = 0x02;184 pub const PASSIVE = 0x01;
24pub const AI_NUMERICHOST = 0x04;185 pub const CANONNAME = 0x02;
25pub const AI_V4MAPPED = 0x08;186 pub const NUMERICHOST = 0x04;
26pub const AI_ALL = 0x10;187 pub const V4MAPPED = 0x08;
27pub const AI_ADDRCONFIG = 0x20;188 pub const ALL = 0x10;
28pub const AI_NUMERICSERV = 0x400;189 pub const ADDRCONFIG = 0x20;
190 pub const NUMERICSERV = 0x400;
191};
29192
30pub const NI_NUMERICHOST = 0x01;193pub const NI = struct {
31pub const NI_NUMERICSERV = 0x02;194 pub const NUMERICHOST = 0x01;
32pub const NI_NOFQDN = 0x04;195 pub const NUMERICSERV = 0x02;
33pub const NI_NAMEREQD = 0x08;196 pub const NOFQDN = 0x04;
34pub const NI_DGRAM = 0x10;197 pub const NAMEREQD = 0x08;
35pub const NI_NUMERICSCOPE = 0x100;198 pub const DGRAM = 0x10;
199 pub const NUMERICSCOPE = 0x100;
200};
36201
37pub const EAI = enum(c_int) {202pub const EAI = enum(c_int) {
38 BADFLAGS = -1,203 BADFLAGS = -1,
...@@ -60,8 +225,8 @@ pub const EAI = enum(c_int) {...@@ -60,8 +225,8 @@ pub const EAI = enum(c_int) {
60225
61pub extern "c" fn fallocate64(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int;226pub extern "c" fn fallocate64(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int;
62pub extern "c" fn fopen64(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE;227pub extern "c" fn fopen64(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE;
63pub extern "c" fn fstat64(fd: fd_t, buf: *libc_stat) c_int;228pub extern "c" fn fstat64(fd: fd_t, buf: *Stat) c_int;
64pub extern "c" fn fstatat64(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int;229pub extern "c" fn fstatat64(dirfd: fd_t, path: [*:0]const u8, stat_buf: *Stat, flags: u32) c_int;
65pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;230pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;
66pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int;231pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int;
67pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64;232pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64;
...@@ -137,7 +302,7 @@ pub const pthread_mutex_t = extern struct {...@@ -137,7 +302,7 @@ pub const pthread_mutex_t = extern struct {
137pub const pthread_cond_t = extern struct {302pub const pthread_cond_t = extern struct {
138 size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,303 size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
139};304};
140pub const pthread_rwlock_t = switch (abi) {305pub const pthread_rwlock_t = switch (native_abi) {
141 .android => switch (@sizeOf(usize)) {306 .android => switch (@sizeOf(usize)) {
142 4 => extern struct {307 4 => extern struct {
143 lock: std.c.pthread_mutex_t = std.c.PTHREAD_MUTEX_INITIALIZER,308 lock: std.c.pthread_mutex_t = std.c.PTHREAD_MUTEX_INITIALIZER,
...@@ -168,11 +333,11 @@ pub const sem_t = extern struct {...@@ -168,11 +333,11 @@ pub const sem_t = extern struct {
168};333};
169334
170const __SIZEOF_PTHREAD_COND_T = 48;335const __SIZEOF_PTHREAD_COND_T = 48;
171const __SIZEOF_PTHREAD_MUTEX_T = if (os_tag == .fuchsia) 40 else switch (abi) {336const __SIZEOF_PTHREAD_MUTEX_T = switch (native_abi) {
172 .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24,337 .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24,
173 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (arch) {338 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (native_arch) {
174 .aarch64 => 48,339 .aarch64 => 48,
175 .x86_64 => if (abi == .gnux32) 40 else 32,340 .x86_64 => if (native_abi == .gnux32) 40 else 32,
176 .mips64, .powerpc64, .powerpc64le, .sparcv9 => 40,341 .mips64, .powerpc64, .powerpc64le, .sparcv9 => 40,
177 else => if (@sizeOf(usize) == 8) 40 else 24,342 else => if (@sizeOf(usize) == 8) 40 else 24,
178 },343 },
...@@ -184,9 +349,11 @@ const __SIZEOF_SEM_T = 4 * @sizeOf(usize);...@@ -184,9 +349,11 @@ const __SIZEOF_SEM_T = 4 * @sizeOf(usize);
184pub extern "c" fn pthread_setname_np(thread: std.c.pthread_t, name: [*:0]const u8) E;349pub extern "c" fn pthread_setname_np(thread: std.c.pthread_t, name: [*:0]const u8) E;
185pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E;350pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E;
186351
187pub const RTLD_LAZY = 1;352pub const RTLD = struct {
188pub const RTLD_NOW = 2;353 pub const LAZY = 1;
189pub const RTLD_NOLOAD = 4;354 pub const NOW = 2;
190pub const RTLD_NODELETE = 4096;355 pub const NOLOAD = 4;
191pub const RTLD_GLOBAL = 256;356 pub const NODELETE = 4096;
192pub const RTLD_LOCAL = 0;357 pub const GLOBAL = 256;
358 pub const LOCAL = 0;
359};
lib/std/c/netbsd.zig+1371-28
...@@ -1,7 +1,10 @@...@@ -1,7 +1,10 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = std.builtin;2const builtin = @import("builtin");
33const maxInt = std.math.maxInt;
4usingnamespace std.c;4const iovec = std.os.iovec;
5const iovec_const = std.os.iovec_const;
6const timezone = std.c.timezone;
7const rusage = std.c.rusage;
58
6extern "c" fn __errno() *c_int;9extern "c" fn __errno() *c_int;
7pub const _errno = __errno;10pub const _errno = __errno;
...@@ -13,56 +16,81 @@ pub extern "c" fn _lwp_self() lwpid_t;...@@ -13,56 +16,81 @@ pub extern "c" fn _lwp_self() lwpid_t;
1316
14pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;17pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
15pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;18pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
16pub extern "c" fn __fstat50(fd: fd_t, buf: *libc_stat) c_int;19
17pub extern "c" fn __stat50(path: [*:0]const u8, buf: *libc_stat) c_int;20pub extern "c" fn __fstat50(fd: fd_t, buf: *Stat) c_int;
21pub const fstat = __fstat50;
22
23pub extern "c" fn __stat50(path: [*:0]const u8, buf: *Stat) c_int;
24pub const stat = __stat50;
25
18pub extern "c" fn __clock_gettime50(clk_id: c_int, tp: *timespec) c_int;26pub extern "c" fn __clock_gettime50(clk_id: c_int, tp: *timespec) c_int;
27pub const clock_gettime = __clock_gettime50;
28
19pub extern "c" fn __clock_getres50(clk_id: c_int, tp: *timespec) c_int;29pub extern "c" fn __clock_getres50(clk_id: c_int, tp: *timespec) c_int;
30pub const clock_getres = __clock_getres50;
31
20pub extern "c" fn __getdents30(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int;32pub extern "c" fn __getdents30(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int;
33pub const getdents = __getdents30;
34
21pub extern "c" fn __sigaltstack14(ss: ?*stack_t, old_ss: ?*stack_t) c_int;35pub extern "c" fn __sigaltstack14(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
36pub const sigaltstack = __sigaltstack14;
37
22pub extern "c" fn __nanosleep50(rqtp: *const timespec, rmtp: ?*timespec) c_int;38pub extern "c" fn __nanosleep50(rqtp: *const timespec, rmtp: ?*timespec) c_int;
39pub const nanosleep = __nanosleep50;
40
23pub extern "c" fn __sigaction14(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;41pub extern "c" fn __sigaction14(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
42pub const sigaction = __sigaction14;
43
24pub extern "c" fn __sigprocmask14(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;44pub extern "c" fn __sigprocmask14(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
45pub const sigprocmask = __sigaction14;
46
25pub extern "c" fn __socket30(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;47pub extern "c" fn __socket30(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
48pub const socket = __socket30;
49
26pub extern "c" fn __gettimeofday50(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;50pub extern "c" fn __gettimeofday50(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
51pub const gettimeofday = __gettimeofday50;
52
27pub extern "c" fn __getrusage50(who: c_int, usage: *rusage) c_int;53pub extern "c" fn __getrusage50(who: c_int, usage: *rusage) c_int;
28// libc aliases this as sched_yield54pub const getrusage = __getrusage50;
55
29pub extern "c" fn __libc_thr_yield() c_int;56pub extern "c" fn __libc_thr_yield() c_int;
57pub const sched_yield = __libc_thr_yield;
3058
31pub extern "c" fn posix_memalign(memptr: *?*c_void, alignment: usize, size: usize) c_int;59pub extern "c" fn posix_memalign(memptr: *?*c_void, alignment: usize, size: usize) c_int;
3260
33pub const pthread_mutex_t = extern struct {61pub const pthread_mutex_t = extern struct {
34 ptm_magic: u32 = 0x33330003,62 magic: u32 = 0x33330003,
35 ptm_errorcheck: padded_pthread_spin_t = 0,63 errorcheck: padded_pthread_spin_t = 0,
36 ptm_ceiling: padded_pthread_spin_t = 0,64 ceiling: padded_pthread_spin_t = 0,
37 ptm_owner: usize = 0,65 owner: usize = 0,
38 ptm_waiters: ?*u8 = null,66 waiters: ?*u8 = null,
39 ptm_recursed: u32 = 0,67 recursed: u32 = 0,
40 ptm_spare2: ?*c_void = null,68 spare2: ?*c_void = null,
41};69};
4270
43pub const pthread_cond_t = extern struct {71pub const pthread_cond_t = extern struct {
44 ptc_magic: u32 = 0x55550005,72 magic: u32 = 0x55550005,
45 ptc_lock: pthread_spin_t = 0,73 lock: pthread_spin_t = 0,
46 ptc_waiters_first: ?*u8 = null,74 waiters_first: ?*u8 = null,
47 ptc_waiters_last: ?*u8 = null,75 waiters_last: ?*u8 = null,
48 ptc_mutex: ?*pthread_mutex_t = null,76 mutex: ?*pthread_mutex_t = null,
49 ptc_private: ?*c_void = null,77 private: ?*c_void = null,
50};78};
5179
52pub const pthread_rwlock_t = extern struct {80pub const pthread_rwlock_t = extern struct {
53 ptr_magic: c_uint = 0x99990009,81 magic: c_uint = 0x99990009,
54 ptr_interlock: switch (std.builtin.cpu.arch) {82 interlock: switch (builtin.cpu.arch) {
55 .aarch64, .sparc, .x86_64, .i386 => u8,83 .aarch64, .sparc, .x86_64, .i386 => u8,
56 .arm, .powerpc => c_int,84 .arm, .powerpc => c_int,
57 else => unreachable,85 else => unreachable,
58 } = 0,86 } = 0,
59 ptr_rblocked_first: ?*u8 = null,87 rblocked_first: ?*u8 = null,
60 ptr_rblocked_last: ?*u8 = null,88 rblocked_last: ?*u8 = null,
61 ptr_wblocked_first: ?*u8 = null,89 wblocked_first: ?*u8 = null,
62 ptr_wblocked_last: ?*u8 = null,90 wblocked_last: ?*u8 = null,
63 ptr_nreaders: c_uint = 0,91 nreaders: c_uint = 0,
64 ptr_owner: std.c.pthread_t = null,92 owner: std.c.pthread_t = null,
65 ptr_private: ?*c_void = null,93 private: ?*c_void = null,
66};94};
6795
68const pthread_spin_t = switch (builtin.cpu.arch) {96const pthread_spin_t = switch (builtin.cpu.arch) {
...@@ -92,3 +120,1318 @@ pub const sem_t = ?*opaque {};...@@ -92,3 +120,1318 @@ pub const sem_t = ?*opaque {};
92120
93pub extern "c" fn pthread_setname_np(thread: std.c.pthread_t, name: [*:0]const u8, arg: ?*c_void) E;121pub extern "c" fn pthread_setname_np(thread: std.c.pthread_t, name: [*:0]const u8, arg: ?*c_void) E;
94pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E;122pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E;
123
124pub const blkcnt_t = i64;
125pub const blksize_t = i32;
126pub const clock_t = u32;
127pub const dev_t = u64;
128pub const fd_t = i32;
129pub const gid_t = u32;
130pub const ino_t = u64;
131pub const mode_t = u32;
132pub const nlink_t = u32;
133pub const off_t = i64;
134pub const pid_t = i32;
135pub const socklen_t = u32;
136pub const time_t = i64;
137pub const uid_t = u32;
138pub const lwpid_t = i32;
139pub const suseconds_t = c_int;
140
141/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
142pub const Kevent = extern struct {
143 ident: usize,
144 filter: i32,
145 flags: u32,
146 fflags: u32,
147 data: i64,
148 udata: usize,
149};
150
151pub const RTLD = struct {
152 pub const LAZY = 1;
153 pub const NOW = 2;
154 pub const GLOBAL = 0x100;
155 pub const LOCAL = 0x200;
156 pub const NODELETE = 0x01000;
157 pub const NOLOAD = 0x02000;
158
159 pub const NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
160 pub const DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
161 pub const SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
162};
163
164pub const dl_phdr_info = extern struct {
165 dlpi_addr: usize,
166 dlpi_name: ?[*:0]const u8,
167 dlpi_phdr: [*]std.elf.Phdr,
168 dlpi_phnum: u16,
169};
170
171pub const Flock = extern struct {
172 l_start: off_t,
173 l_len: off_t,
174 l_pid: pid_t,
175 l_type: i16,
176 l_whence: i16,
177};
178
179pub const addrinfo = extern struct {
180 flags: i32,
181 family: i32,
182 socktype: i32,
183 protocol: i32,
184 addrlen: socklen_t,
185 canonname: ?[*:0]u8,
186 addr: ?*sockaddr,
187 next: ?*addrinfo,
188};
189
190pub const EAI = enum(c_int) {
191 /// address family for hostname not supported
192 ADDRFAMILY = 1,
193
194 /// name could not be resolved at this time
195 AGAIN = 2,
196
197 /// flags parameter had an invalid value
198 BADFLAGS = 3,
199
200 /// non-recoverable failure in name resolution
201 FAIL = 4,
202
203 /// address family not recognized
204 FAMILY = 5,
205
206 /// memory allocation failure
207 MEMORY = 6,
208
209 /// no address associated with hostname
210 NODATA = 7,
211
212 /// name does not resolve
213 NONAME = 8,
214
215 /// service not recognized for socket type
216 SERVICE = 9,
217
218 /// intended socket type was not recognized
219 SOCKTYPE = 10,
220
221 /// system error returned in errno
222 SYSTEM = 11,
223
224 /// invalid value for hints
225 BADHINTS = 12,
226
227 /// resolved protocol is unknown
228 PROTOCOL = 13,
229
230 /// argument buffer overflow
231 OVERFLOW = 14,
232
233 _,
234};
235
236pub const EAI_MAX = 15;
237
238pub const msghdr = extern struct {
239 /// optional address
240 msg_name: ?*sockaddr,
241
242 /// size of address
243 msg_namelen: socklen_t,
244
245 /// scatter/gather array
246 msg_iov: [*]iovec,
247
248 /// # elements in msg_iov
249 msg_iovlen: i32,
250
251 /// ancillary data
252 msg_control: ?*c_void,
253
254 /// ancillary data buffer len
255 msg_controllen: socklen_t,
256
257 /// flags on received message
258 msg_flags: i32,
259};
260
261pub const msghdr_const = extern struct {
262 /// optional address
263 msg_name: ?*const sockaddr,
264
265 /// size of address
266 msg_namelen: socklen_t,
267
268 /// scatter/gather array
269 msg_iov: [*]iovec_const,
270
271 /// # elements in msg_iov
272 msg_iovlen: i32,
273
274 /// ancillary data
275 msg_control: ?*c_void,
276
277 /// ancillary data buffer len
278 msg_controllen: socklen_t,
279
280 /// flags on received message
281 msg_flags: i32,
282};
283
284/// The stat structure used by libc.
285pub const Stat = extern struct {
286 dev: dev_t,
287 mode: mode_t,
288 ino: ino_t,
289 nlink: nlink_t,
290 uid: uid_t,
291 gid: gid_t,
292 rdev: dev_t,
293 atim: timespec,
294 mtim: timespec,
295 ctim: timespec,
296 birthtim: timespec,
297 size: off_t,
298 blocks: blkcnt_t,
299 blksize: blksize_t,
300 flags: u32,
301 gen: u32,
302 __spare: [2]u32,
303
304 pub fn atime(self: @This()) timespec {
305 return self.atim;
306 }
307
308 pub fn mtime(self: @This()) timespec {
309 return self.mtim;
310 }
311
312 pub fn ctime(self: @This()) timespec {
313 return self.ctim;
314 }
315};
316
317pub const timespec = extern struct {
318 tv_sec: i64,
319 tv_nsec: isize,
320};
321
322pub const timeval = extern struct {
323 /// seconds
324 tv_sec: time_t,
325 /// microseconds
326 tv_usec: suseconds_t,
327};
328
329pub const MAXNAMLEN = 511;
330
331pub const dirent = extern struct {
332 d_fileno: ino_t,
333 d_reclen: u16,
334 d_namlen: u16,
335 d_type: u8,
336 d_name: [MAXNAMLEN:0]u8,
337
338 pub fn reclen(self: dirent) u16 {
339 return self.d_reclen;
340 }
341};
342
343pub const SOCK = struct {
344 pub const STREAM = 1;
345 pub const DGRAM = 2;
346 pub const RAW = 3;
347 pub const RDM = 4;
348 pub const SEQPACKET = 5;
349 pub const CONN_DGRAM = 6;
350 pub const DCCP = CONN_DGRAM;
351
352 pub const CLOEXEC = 0x10000000;
353 pub const NONBLOCK = 0x20000000;
354 pub const NOSIGPIPE = 0x40000000;
355 pub const FLAGS_MASK = 0xf0000000;
356};
357
358pub const SO = struct {
359 pub const DEBUG = 0x0001;
360 pub const ACCEPTCONN = 0x0002;
361 pub const REUSEADDR = 0x0004;
362 pub const KEEPALIVE = 0x0008;
363 pub const DONTROUTE = 0x0010;
364 pub const BROADCAST = 0x0020;
365 pub const USELOOPBACK = 0x0040;
366 pub const LINGER = 0x0080;
367 pub const OOBINLINE = 0x0100;
368 pub const REUSEPORT = 0x0200;
369 pub const NOSIGPIPE = 0x0800;
370 pub const ACCEPTFILTER = 0x1000;
371 pub const TIMESTAMP = 0x2000;
372 pub const RERROR = 0x4000;
373
374 pub const SNDBUF = 0x1001;
375 pub const RCVBUF = 0x1002;
376 pub const SNDLOWAT = 0x1003;
377 pub const RCVLOWAT = 0x1004;
378 pub const ERROR = 0x1007;
379 pub const TYPE = 0x1008;
380 pub const OVERFLOWED = 0x1009;
381
382 pub const NOHEADER = 0x100a;
383 pub const SNDTIMEO = 0x100b;
384 pub const RCVTIMEO = 0x100c;
385};
386
387pub const SOL = struct {
388 pub const SOCKET = 0xffff;
389};
390
391pub const PF = struct {
392 pub const UNSPEC = AF.UNSPEC;
393 pub const LOCAL = AF.LOCAL;
394 pub const UNIX = PF.LOCAL;
395 pub const INET = AF.INET;
396 pub const IMPLINK = AF.IMPLINK;
397 pub const PUP = AF.PUP;
398 pub const CHAOS = AF.CHAOS;
399 pub const NS = AF.NS;
400 pub const ISO = AF.ISO;
401 pub const OSI = AF.ISO;
402 pub const ECMA = AF.ECMA;
403 pub const DATAKIT = AF.DATAKIT;
404 pub const CCITT = AF.CCITT;
405 pub const SNA = AF.SNA;
406 pub const DECnet = AF.DECnet;
407 pub const DLI = AF.DLI;
408 pub const LAT = AF.LAT;
409 pub const HYLINK = AF.HYLINK;
410 pub const APPLETALK = AF.APPLETALK;
411 pub const OROUTE = AF.OROUTE;
412 pub const LINK = AF.LINK;
413 pub const COIP = AF.COIP;
414 pub const CNT = AF.CNT;
415 pub const INET6 = AF.INET6;
416 pub const IPX = AF.IPX;
417 pub const ISDN = AF.ISDN;
418 pub const E164 = AF.E164;
419 pub const NATM = AF.NATM;
420 pub const ARP = AF.ARP;
421 pub const BLUETOOTH = AF.BLUETOOTH;
422 pub const MPLS = AF.MPLS;
423 pub const ROUTE = AF.ROUTE;
424 pub const CAN = AF.CAN;
425 pub const ETHER = AF.ETHER;
426 pub const MAX = AF.MAX;
427};
428
429pub const AF = struct {
430 pub const UNSPEC = 0;
431 pub const LOCAL = 1;
432 pub const UNIX = LOCAL;
433 pub const INET = 2;
434 pub const IMPLINK = 3;
435 pub const PUP = 4;
436 pub const CHAOS = 5;
437 pub const NS = 6;
438 pub const ISO = 7;
439 pub const OSI = ISO;
440 pub const ECMA = 8;
441 pub const DATAKIT = 9;
442 pub const CCITT = 10;
443 pub const SNA = 11;
444 pub const DECnet = 12;
445 pub const DLI = 13;
446 pub const LAT = 14;
447 pub const HYLINK = 15;
448 pub const APPLETALK = 16;
449 pub const OROUTE = 17;
450 pub const LINK = 18;
451 pub const COIP = 20;
452 pub const CNT = 21;
453 pub const IPX = 23;
454 pub const INET6 = 24;
455 pub const ISDN = 26;
456 pub const E164 = ISDN;
457 pub const NATM = 27;
458 pub const ARP = 28;
459 pub const BLUETOOTH = 31;
460 pub const IEEE80211 = 32;
461 pub const MPLS = 33;
462 pub const ROUTE = 34;
463 pub const CAN = 35;
464 pub const ETHER = 36;
465 pub const MAX = 37;
466};
467
468pub const in_port_t = u16;
469pub const sa_family_t = u8;
470
471pub const sockaddr = extern struct {
472 /// total length
473 len: u8,
474 /// address family
475 family: sa_family_t,
476 /// actually longer; address value
477 data: [14]u8,
478
479 pub const storage = std.x.os.Socket.Address.Native.Storage;
480
481 pub const in = extern struct {
482 len: u8 = @sizeOf(in),
483 family: sa_family_t = AF.INET,
484 port: in_port_t,
485 addr: u32,
486 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
487 };
488
489 pub const in6 = extern struct {
490 len: u8 = @sizeOf(in6),
491 family: sa_family_t = AF.INET6,
492 port: in_port_t,
493 flowinfo: u32,
494 addr: [16]u8,
495 scope_id: u32,
496 };
497
498 /// Definitions for UNIX IPC domain.
499 pub const un = extern struct {
500 /// total sockaddr length
501 len: u8 = @sizeOf(un),
502
503 family: sa_family_t = AF.LOCAL,
504
505 /// path name
506 path: [104]u8,
507 };
508};
509
510pub const AI = struct {
511 /// get address to use bind()
512 pub const PASSIVE = 0x00000001;
513 /// fill ai_canonname
514 pub const CANONNAME = 0x00000002;
515 /// prevent host name resolution
516 pub const NUMERICHOST = 0x00000004;
517 /// prevent service name resolution
518 pub const NUMERICSERV = 0x00000008;
519 /// only if any address is assigned
520 pub const ADDRCONFIG = 0x00000400;
521};
522
523pub const CTL = struct {
524 pub const KERN = 1;
525 pub const DEBUG = 5;
526};
527
528pub const KERN = struct {
529 pub const PROC_ARGS = 48; // struct: process argv/env
530 pub const PROC_PATHNAME = 5; // path to executable
531 pub const IOV_MAX = 38;
532};
533
534pub const PATH_MAX = 1024;
535pub const IOV_MAX = KERN.IOV_MAX;
536
537pub const STDIN_FILENO = 0;
538pub const STDOUT_FILENO = 1;
539pub const STDERR_FILENO = 2;
540
541pub const PROT = struct {
542 pub const NONE = 0;
543 pub const READ = 1;
544 pub const WRITE = 2;
545 pub const EXEC = 4;
546};
547
548pub const CLOCK = struct {
549 pub const REALTIME = 0;
550 pub const VIRTUAL = 1;
551 pub const PROF = 2;
552 pub const MONOTONIC = 3;
553 pub const THREAD_CPUTIME_ID = 0x20000000;
554 pub const PROCESS_CPUTIME_ID = 0x40000000;
555};
556
557pub const MAP = struct {
558 pub const FAILED = @intToPtr(*c_void, maxInt(usize));
559 pub const SHARED = 0x0001;
560 pub const PRIVATE = 0x0002;
561 pub const REMAPDUP = 0x0004;
562 pub const FIXED = 0x0010;
563 pub const RENAME = 0x0020;
564 pub const NORESERVE = 0x0040;
565 pub const INHERIT = 0x0080;
566 pub const HASSEMAPHORE = 0x0200;
567 pub const TRYFIXED = 0x0400;
568 pub const WIRED = 0x0800;
569
570 pub const FILE = 0x0000;
571 pub const NOSYNC = 0x0800;
572 pub const ANON = 0x1000;
573 pub const ANONYMOUS = ANON;
574 pub const STACK = 0x2000;
575};
576
577pub const W = struct {
578 pub const NOHANG = 0x00000001;
579 pub const UNTRACED = 0x00000002;
580 pub const STOPPED = UNTRACED;
581 pub const CONTINUED = 0x00000010;
582 pub const NOWAIT = 0x00010000;
583 pub const EXITED = 0x00000020;
584 pub const TRAPPED = 0x00000040;
585
586 pub fn EXITSTATUS(s: u32) u8 {
587 return @intCast(u8, (s >> 8) & 0xff);
588 }
589 pub fn TERMSIG(s: u32) u32 {
590 return s & 0x7f;
591 }
592 pub fn STOPSIG(s: u32) u32 {
593 return EXITSTATUS(s);
594 }
595 pub fn IFEXITED(s: u32) bool {
596 return TERMSIG(s) == 0;
597 }
598
599 pub fn IFCONTINUED(s: u32) bool {
600 return ((s & 0x7f) == 0xffff);
601 }
602
603 pub fn IFSTOPPED(s: u32) bool {
604 return ((s & 0x7f != 0x7f) and !IFCONTINUED(s));
605 }
606
607 pub fn IFSIGNALED(s: u32) bool {
608 return !IFSTOPPED(s) and !IFCONTINUED(s) and !IFEXITED(s);
609 }
610};
611
612pub const SA = struct {
613 pub const ONSTACK = 0x0001;
614 pub const RESTART = 0x0002;
615 pub const RESETHAND = 0x0004;
616 pub const NOCLDSTOP = 0x0008;
617 pub const NODEFER = 0x0010;
618 pub const NOCLDWAIT = 0x0020;
619 pub const SIGINFO = 0x0040;
620};
621
622// access function
623pub const F_OK = 0; // test for existence of file
624pub const X_OK = 1; // test for execute or search permission
625pub const W_OK = 2; // test for write permission
626pub const R_OK = 4; // test for read permission
627
628pub const O = struct {
629 /// open for reading only
630 pub const RDONLY = 0x00000000;
631 /// open for writing only
632 pub const WRONLY = 0x00000001;
633 /// open for reading and writing
634 pub const RDWR = 0x00000002;
635 /// mask for above modes
636 pub const ACCMODE = 0x00000003;
637 /// no delay
638 pub const NONBLOCK = 0x00000004;
639 /// set append mode
640 pub const APPEND = 0x00000008;
641 /// open with shared file lock
642 pub const SHLOCK = 0x00000010;
643 /// open with exclusive file lock
644 pub const EXLOCK = 0x00000020;
645 /// signal pgrp when data ready
646 pub const ASYNC = 0x00000040;
647 /// synchronous writes
648 pub const SYNC = 0x00000080;
649 /// don't follow symlinks on the last
650 pub const NOFOLLOW = 0x00000100;
651 /// create if nonexistent
652 pub const CREAT = 0x00000200;
653 /// truncate to zero length
654 pub const TRUNC = 0x00000400;
655 /// error if already exists
656 pub const EXCL = 0x00000800;
657 /// don't assign controlling terminal
658 pub const NOCTTY = 0x00008000;
659 /// write: I/O data completion
660 pub const DSYNC = 0x00010000;
661 /// read: I/O completion as for write
662 pub const RSYNC = 0x00020000;
663 /// use alternate i/o semantics
664 pub const ALT_IO = 0x00040000;
665 /// direct I/O hint
666 pub const DIRECT = 0x00080000;
667 /// fail if not a directory
668 pub const DIRECTORY = 0x00200000;
669 /// set close on exec
670 pub const CLOEXEC = 0x00400000;
671 /// skip search permission checks
672 pub const SEARCH = 0x00800000;
673};
674
675pub const F = struct {
676 pub const DUPFD = 0;
677 pub const GETFD = 1;
678 pub const SETFD = 2;
679 pub const GETFL = 3;
680 pub const SETFL = 4;
681
682 pub const GETOWN = 5;
683 pub const SETOWN = 6;
684
685 pub const GETLK = 7;
686 pub const SETLK = 8;
687 pub const SETLKW = 9;
688
689 pub const RDLCK = 1;
690 pub const WRLCK = 3;
691 pub const UNLCK = 2;
692};
693
694pub const LOCK = struct {
695 pub const SH = 1;
696 pub const EX = 2;
697 pub const UN = 8;
698 pub const NB = 4;
699};
700
701pub const FD_CLOEXEC = 1;
702
703pub const SEEK = struct {
704 pub const SET = 0;
705 pub const CUR = 1;
706 pub const END = 2;
707};
708
709pub const DT = struct {
710 pub const UNKNOWN = 0;
711 pub const FIFO = 1;
712 pub const CHR = 2;
713 pub const DIR = 4;
714 pub const BLK = 6;
715 pub const REG = 8;
716 pub const LNK = 10;
717 pub const SOCK = 12;
718 pub const WHT = 14;
719};
720
721/// add event to kq (implies enable)
722pub const EV_ADD = 0x0001;
723
724/// delete event from kq
725pub const EV_DELETE = 0x0002;
726
727/// enable event
728pub const EV_ENABLE = 0x0004;
729
730/// disable event (not reported)
731pub const EV_DISABLE = 0x0008;
732
733/// only report one occurrence
734pub const EV_ONESHOT = 0x0010;
735
736/// clear event state after reporting
737pub const EV_CLEAR = 0x0020;
738
739/// force immediate event output
740/// ... with or without EV_ERROR
741/// ... use KEVENT_FLAG_ERROR_EVENTS
742/// on syscalls supporting flags
743pub const EV_RECEIPT = 0x0040;
744
745/// disable event after reporting
746pub const EV_DISPATCH = 0x0080;
747
748pub const EVFILT_READ = 0;
749pub const EVFILT_WRITE = 1;
750
751/// attached to aio requests
752pub const EVFILT_AIO = 2;
753
754/// attached to vnodes
755pub const EVFILT_VNODE = 3;
756
757/// attached to struct proc
758pub const EVFILT_PROC = 4;
759
760/// attached to struct proc
761pub const EVFILT_SIGNAL = 5;
762
763/// timers
764pub const EVFILT_TIMER = 6;
765
766/// Filesystem events
767pub const EVFILT_FS = 7;
768
769/// User events
770pub const EVFILT_USER = 1;
771
772/// On input, NOTE_TRIGGER causes the event to be triggered for output.
773pub const NOTE_TRIGGER = 0x08000000;
774
775/// low water mark
776pub const NOTE_LOWAT = 0x00000001;
777
778/// vnode was removed
779pub const NOTE_DELETE = 0x00000001;
780
781/// data contents changed
782pub const NOTE_WRITE = 0x00000002;
783
784/// size increased
785pub const NOTE_EXTEND = 0x00000004;
786
787/// attributes changed
788pub const NOTE_ATTRIB = 0x00000008;
789
790/// link count changed
791pub const NOTE_LINK = 0x00000010;
792
793/// vnode was renamed
794pub const NOTE_RENAME = 0x00000020;
795
796/// vnode access was revoked
797pub const NOTE_REVOKE = 0x00000040;
798
799/// process exited
800pub const NOTE_EXIT = 0x80000000;
801
802/// process forked
803pub const NOTE_FORK = 0x40000000;
804
805/// process exec'd
806pub const NOTE_EXEC = 0x20000000;
807
808/// mask for signal & exit status
809pub const NOTE_PDATAMASK = 0x000fffff;
810pub const NOTE_PCTRLMASK = 0xf0000000;
811
812pub const T = struct {
813 pub const IOCCBRK = 0x2000747a;
814 pub const IOCCDTR = 0x20007478;
815 pub const IOCCONS = 0x80047462;
816 pub const IOCDCDTIMESTAMP = 0x40107458;
817 pub const IOCDRAIN = 0x2000745e;
818 pub const IOCEXCL = 0x2000740d;
819 pub const IOCEXT = 0x80047460;
820 pub const IOCFLAG_CDTRCTS = 0x10;
821 pub const IOCFLAG_CLOCAL = 0x2;
822 pub const IOCFLAG_CRTSCTS = 0x4;
823 pub const IOCFLAG_MDMBUF = 0x8;
824 pub const IOCFLAG_SOFTCAR = 0x1;
825 pub const IOCFLUSH = 0x80047410;
826 pub const IOCGETA = 0x402c7413;
827 pub const IOCGETD = 0x4004741a;
828 pub const IOCGFLAGS = 0x4004745d;
829 pub const IOCGLINED = 0x40207442;
830 pub const IOCGPGRP = 0x40047477;
831 pub const IOCGQSIZE = 0x40047481;
832 pub const IOCGRANTPT = 0x20007447;
833 pub const IOCGSID = 0x40047463;
834 pub const IOCGSIZE = 0x40087468;
835 pub const IOCGWINSZ = 0x40087468;
836 pub const IOCMBIC = 0x8004746b;
837 pub const IOCMBIS = 0x8004746c;
838 pub const IOCMGET = 0x4004746a;
839 pub const IOCMSET = 0x8004746d;
840 pub const IOCM_CAR = 0x40;
841 pub const IOCM_CD = 0x40;
842 pub const IOCM_CTS = 0x20;
843 pub const IOCM_DSR = 0x100;
844 pub const IOCM_DTR = 0x2;
845 pub const IOCM_LE = 0x1;
846 pub const IOCM_RI = 0x80;
847 pub const IOCM_RNG = 0x80;
848 pub const IOCM_RTS = 0x4;
849 pub const IOCM_SR = 0x10;
850 pub const IOCM_ST = 0x8;
851 pub const IOCNOTTY = 0x20007471;
852 pub const IOCNXCL = 0x2000740e;
853 pub const IOCOUTQ = 0x40047473;
854 pub const IOCPKT = 0x80047470;
855 pub const IOCPKT_DATA = 0x0;
856 pub const IOCPKT_DOSTOP = 0x20;
857 pub const IOCPKT_FLUSHREAD = 0x1;
858 pub const IOCPKT_FLUSHWRITE = 0x2;
859 pub const IOCPKT_IOCTL = 0x40;
860 pub const IOCPKT_NOSTOP = 0x10;
861 pub const IOCPKT_START = 0x8;
862 pub const IOCPKT_STOP = 0x4;
863 pub const IOCPTMGET = 0x40287446;
864 pub const IOCPTSNAME = 0x40287448;
865 pub const IOCRCVFRAME = 0x80087445;
866 pub const IOCREMOTE = 0x80047469;
867 pub const IOCSBRK = 0x2000747b;
868 pub const IOCSCTTY = 0x20007461;
869 pub const IOCSDTR = 0x20007479;
870 pub const IOCSETA = 0x802c7414;
871 pub const IOCSETAF = 0x802c7416;
872 pub const IOCSETAW = 0x802c7415;
873 pub const IOCSETD = 0x8004741b;
874 pub const IOCSFLAGS = 0x8004745c;
875 pub const IOCSIG = 0x2000745f;
876 pub const IOCSLINED = 0x80207443;
877 pub const IOCSPGRP = 0x80047476;
878 pub const IOCSQSIZE = 0x80047480;
879 pub const IOCSSIZE = 0x80087467;
880 pub const IOCSTART = 0x2000746e;
881 pub const IOCSTAT = 0x80047465;
882 pub const IOCSTI = 0x80017472;
883 pub const IOCSTOP = 0x2000746f;
884 pub const IOCSWINSZ = 0x80087467;
885 pub const IOCUCNTL = 0x80047466;
886 pub const IOCXMTFRAME = 0x80087444;
887};
888
889pub const winsize = extern struct {
890 ws_row: u16,
891 ws_col: u16,
892 ws_xpixel: u16,
893 ws_ypixel: u16,
894};
895
896const NSIG = 32;
897
898pub const SIG = struct {
899 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
900 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
901 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
902
903 pub const WORDS = 4;
904 pub const MAXSIG = 128;
905
906 pub const BLOCK = 1;
907 pub const UNBLOCK = 2;
908 pub const SETMASK = 3;
909
910 pub const HUP = 1;
911 pub const INT = 2;
912 pub const QUIT = 3;
913 pub const ILL = 4;
914 pub const TRAP = 5;
915 pub const ABRT = 6;
916 pub const IOT = ABRT;
917 pub const EMT = 7;
918 pub const FPE = 8;
919 pub const KILL = 9;
920 pub const BUS = 10;
921 pub const SEGV = 11;
922 pub const SYS = 12;
923 pub const PIPE = 13;
924 pub const ALRM = 14;
925 pub const TERM = 15;
926 pub const URG = 16;
927 pub const STOP = 17;
928 pub const TSTP = 18;
929 pub const CONT = 19;
930 pub const CHLD = 20;
931 pub const TTIN = 21;
932 pub const TTOU = 22;
933 pub const IO = 23;
934 pub const XCPU = 24;
935 pub const XFSZ = 25;
936 pub const VTALRM = 26;
937 pub const PROF = 27;
938 pub const WINCH = 28;
939 pub const INFO = 29;
940 pub const USR1 = 30;
941 pub const USR2 = 31;
942 pub const PWR = 32;
943
944 pub const RTMIN = 33;
945 pub const RTMAX = 63;
946
947 pub inline fn IDX(sig: usize) usize {
948 return sig - 1;
949 }
950 pub inline fn WORD(sig: usize) usize {
951 return IDX(sig) >> 5;
952 }
953 pub inline fn BIT(sig: usize) usize {
954 return 1 << (IDX(sig) & 31);
955 }
956 pub inline fn VALID(sig: usize) usize {
957 return sig <= MAXSIG and sig > 0;
958 }
959};
960
961/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
962pub const Sigaction = extern struct {
963 pub const handler_fn = fn (c_int) callconv(.C) void;
964 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
965
966 /// signal handler
967 handler: extern union {
968 handler: ?handler_fn,
969 sigaction: ?sigaction_fn,
970 },
971 /// signal mask to apply
972 mask: sigset_t,
973 /// signal options
974 flags: c_uint,
975};
976
977pub const sigval_t = extern union {
978 int: i32,
979 ptr: ?*c_void,
980};
981
982pub const siginfo_t = extern union {
983 pad: [128]u8,
984 info: _ksiginfo,
985};
986
987pub const _ksiginfo = extern struct {
988 signo: i32,
989 code: i32,
990 errno: i32,
991 // 64bit architectures insert 4bytes of padding here, this is done by
992 // correctly aligning the reason field
993 reason: extern union {
994 rt: extern struct {
995 pid: pid_t,
996 uid: uid_t,
997 value: sigval_t,
998 },
999 child: extern struct {
1000 pid: pid_t,
1001 uid: uid_t,
1002 status: i32,
1003 utime: clock_t,
1004 stime: clock_t,
1005 },
1006 fault: extern struct {
1007 addr: ?*c_void,
1008 trap: i32,
1009 trap2: i32,
1010 trap3: i32,
1011 },
1012 poll: extern struct {
1013 band: i32,
1014 fd: i32,
1015 },
1016 syscall: extern struct {
1017 sysnum: i32,
1018 retval: [2]i32,
1019 @"error": i32,
1020 args: [8]u64,
1021 },
1022 ptrace_state: extern struct {
1023 pe_report_event: i32,
1024 option: extern union {
1025 pe_other_pid: pid_t,
1026 pe_lwp: lwpid_t,
1027 },
1028 },
1029 } align(@sizeOf(usize)),
1030};
1031
1032pub const sigset_t = extern struct {
1033 __bits: [SIG.WORDS]u32,
1034};
1035
1036pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** SIG.WORDS };
1037
1038// XXX x86_64 specific
1039pub const mcontext_t = extern struct {
1040 gregs: [26]u64,
1041 mc_tlsbase: u64,
1042 fpregs: [512]u8 align(8),
1043};
1044
1045pub const REG = struct {
1046 pub const RBP = 12;
1047 pub const RIP = 21;
1048 pub const RSP = 24;
1049};
1050
1051pub const ucontext_t = extern struct {
1052 flags: u32,
1053 link: ?*ucontext_t,
1054 sigmask: sigset_t,
1055 stack: stack_t,
1056 mcontext: mcontext_t,
1057 __pad: [
1058 switch (builtin.cpu.arch) {
1059 .i386 => 4,
1060 .mips, .mipsel, .mips64, .mips64el => 14,
1061 .arm, .armeb, .thumb, .thumbeb => 1,
1062 .sparc, .sparcel, .sparcv9 => if (@sizeOf(usize) == 4) 43 else 8,
1063 else => 0,
1064 }
1065 ]u32,
1066};
1067
1068pub const E = enum(u16) {
1069 /// No error occurred.
1070 SUCCESS = 0,
1071 PERM = 1, // Operation not permitted
1072 NOENT = 2, // No such file or directory
1073 SRCH = 3, // No such process
1074 INTR = 4, // Interrupted system call
1075 IO = 5, // Input/output error
1076 NXIO = 6, // Device not configured
1077 @"2BIG" = 7, // Argument list too long
1078 NOEXEC = 8, // Exec format error
1079 BADF = 9, // Bad file descriptor
1080 CHILD = 10, // No child processes
1081 DEADLK = 11, // Resource deadlock avoided
1082 // 11 was AGAIN
1083 NOMEM = 12, // Cannot allocate memory
1084 ACCES = 13, // Permission denied
1085 FAULT = 14, // Bad address
1086 NOTBLK = 15, // Block device required
1087 BUSY = 16, // Device busy
1088 EXIST = 17, // File exists
1089 XDEV = 18, // Cross-device link
1090 NODEV = 19, // Operation not supported by device
1091 NOTDIR = 20, // Not a directory
1092 ISDIR = 21, // Is a directory
1093 INVAL = 22, // Invalid argument
1094 NFILE = 23, // Too many open files in system
1095 MFILE = 24, // Too many open files
1096 NOTTY = 25, // Inappropriate ioctl for device
1097 TXTBSY = 26, // Text file busy
1098 FBIG = 27, // File too large
1099 NOSPC = 28, // No space left on device
1100 SPIPE = 29, // Illegal seek
1101 ROFS = 30, // Read-only file system
1102 MLINK = 31, // Too many links
1103 PIPE = 32, // Broken pipe
1104
1105 // math software
1106 DOM = 33, // Numerical argument out of domain
1107 RANGE = 34, // Result too large or too small
1108
1109 // non-blocking and interrupt i/o
1110 // also: WOULDBLOCK: operation would block
1111 AGAIN = 35, // Resource temporarily unavailable
1112 INPROGRESS = 36, // Operation now in progress
1113 ALREADY = 37, // Operation already in progress
1114
1115 // ipc/network software -- argument errors
1116 NOTSOCK = 38, // Socket operation on non-socket
1117 DESTADDRREQ = 39, // Destination address required
1118 MSGSIZE = 40, // Message too long
1119 PROTOTYPE = 41, // Protocol wrong type for socket
1120 NOPROTOOPT = 42, // Protocol option not available
1121 PROTONOSUPPORT = 43, // Protocol not supported
1122 SOCKTNOSUPPORT = 44, // Socket type not supported
1123 OPNOTSUPP = 45, // Operation not supported
1124 PFNOSUPPORT = 46, // Protocol family not supported
1125 AFNOSUPPORT = 47, // Address family not supported by protocol family
1126 ADDRINUSE = 48, // Address already in use
1127 ADDRNOTAVAIL = 49, // Can't assign requested address
1128
1129 // ipc/network software -- operational errors
1130 NETDOWN = 50, // Network is down
1131 NETUNREACH = 51, // Network is unreachable
1132 NETRESET = 52, // Network dropped connection on reset
1133 CONNABORTED = 53, // Software caused connection abort
1134 CONNRESET = 54, // Connection reset by peer
1135 NOBUFS = 55, // No buffer space available
1136 ISCONN = 56, // Socket is already connected
1137 NOTCONN = 57, // Socket is not connected
1138 SHUTDOWN = 58, // Can't send after socket shutdown
1139 TOOMANYREFS = 59, // Too many references: can't splice
1140 TIMEDOUT = 60, // Operation timed out
1141 CONNREFUSED = 61, // Connection refused
1142
1143 LOOP = 62, // Too many levels of symbolic links
1144 NAMETOOLONG = 63, // File name too long
1145
1146 // should be rearranged
1147 HOSTDOWN = 64, // Host is down
1148 HOSTUNREACH = 65, // No route to host
1149 NOTEMPTY = 66, // Directory not empty
1150
1151 // quotas & mush
1152 PROCLIM = 67, // Too many processes
1153 USERS = 68, // Too many users
1154 DQUOT = 69, // Disc quota exceeded
1155
1156 // Network File System
1157 STALE = 70, // Stale NFS file handle
1158 REMOTE = 71, // Too many levels of remote in path
1159 BADRPC = 72, // RPC struct is bad
1160 RPCMISMATCH = 73, // RPC version wrong
1161 PROGUNAVAIL = 74, // RPC prog. not avail
1162 PROGMISMATCH = 75, // Program version wrong
1163 PROCUNAVAIL = 76, // Bad procedure for program
1164
1165 NOLCK = 77, // No locks available
1166 NOSYS = 78, // Function not implemented
1167
1168 FTYPE = 79, // Inappropriate file type or format
1169 AUTH = 80, // Authentication error
1170 NEEDAUTH = 81, // Need authenticator
1171
1172 // SystemV IPC
1173 IDRM = 82, // Identifier removed
1174 NOMSG = 83, // No message of desired type
1175 OVERFLOW = 84, // Value too large to be stored in data type
1176
1177 // Wide/multibyte-character handling, ISO/IEC 9899/AMD1:1995
1178 ILSEQ = 85, // Illegal byte sequence
1179
1180 // From IEEE Std 1003.1-2001
1181 // Base, Realtime, Threads or Thread Priority Scheduling option errors
1182 NOTSUP = 86, // Not supported
1183
1184 // Realtime option errors
1185 CANCELED = 87, // Operation canceled
1186
1187 // Realtime, XSI STREAMS option errors
1188 BADMSG = 88, // Bad or Corrupt message
1189
1190 // XSI STREAMS option errors
1191 NODATA = 89, // No message available
1192 NOSR = 90, // No STREAM resources
1193 NOSTR = 91, // Not a STREAM
1194 TIME = 92, // STREAM ioctl timeout
1195
1196 // File system extended attribute errors
1197 NOATTR = 93, // Attribute not found
1198
1199 // Realtime, XSI STREAMS option errors
1200 MULTIHOP = 94, // Multihop attempted
1201 NOLINK = 95, // Link has been severed
1202 PROTO = 96, // Protocol error
1203
1204 _,
1205};
1206
1207pub const MINSIGSTKSZ = 8192;
1208pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
1209
1210pub const SS_ONSTACK = 1;
1211pub const SS_DISABLE = 4;
1212
1213pub const stack_t = extern struct {
1214 sp: [*]u8,
1215 size: isize,
1216 flags: i32,
1217};
1218
1219pub const S = struct {
1220 pub const IFMT = 0o170000;
1221
1222 pub const IFIFO = 0o010000;
1223 pub const IFCHR = 0o020000;
1224 pub const IFDIR = 0o040000;
1225 pub const IFBLK = 0o060000;
1226 pub const IFREG = 0o100000;
1227 pub const IFLNK = 0o120000;
1228 pub const IFSOCK = 0o140000;
1229 pub const IFWHT = 0o160000;
1230
1231 pub const ISUID = 0o4000;
1232 pub const ISGID = 0o2000;
1233 pub const ISVTX = 0o1000;
1234 pub const IRWXU = 0o700;
1235 pub const IRUSR = 0o400;
1236 pub const IWUSR = 0o200;
1237 pub const IXUSR = 0o100;
1238 pub const IRWXG = 0o070;
1239 pub const IRGRP = 0o040;
1240 pub const IWGRP = 0o020;
1241 pub const IXGRP = 0o010;
1242 pub const IRWXO = 0o007;
1243 pub const IROTH = 0o004;
1244 pub const IWOTH = 0o002;
1245 pub const IXOTH = 0o001;
1246
1247 pub fn ISFIFO(m: u32) bool {
1248 return m & IFMT == IFIFO;
1249 }
1250
1251 pub fn ISCHR(m: u32) bool {
1252 return m & IFMT == IFCHR;
1253 }
1254
1255 pub fn ISDIR(m: u32) bool {
1256 return m & IFMT == IFDIR;
1257 }
1258
1259 pub fn ISBLK(m: u32) bool {
1260 return m & IFMT == IFBLK;
1261 }
1262
1263 pub fn ISREG(m: u32) bool {
1264 return m & IFMT == IFREG;
1265 }
1266
1267 pub fn ISLNK(m: u32) bool {
1268 return m & IFMT == IFLNK;
1269 }
1270
1271 pub fn ISSOCK(m: u32) bool {
1272 return m & IFMT == IFSOCK;
1273 }
1274
1275 pub fn IWHT(m: u32) bool {
1276 return m & IFMT == IFWHT;
1277 }
1278};
1279
1280pub const AT = struct {
1281 /// Magic value that specify the use of the current working directory
1282 /// to determine the target of relative file paths in the openat() and
1283 /// similar syscalls.
1284 pub const FDCWD = -100;
1285 /// Check access using effective user and group ID
1286 pub const EACCESS = 0x0100;
1287 /// Do not follow symbolic links
1288 pub const SYMLINK_NOFOLLOW = 0x0200;
1289 /// Follow symbolic link
1290 pub const SYMLINK_FOLLOW = 0x0400;
1291 /// Remove directory instead of file
1292 pub const REMOVEDIR = 0x0800;
1293};
1294
1295pub const HOST_NAME_MAX = 255;
1296
1297pub const IPPROTO = struct {
1298 /// dummy for IP
1299 pub const IP = 0;
1300 /// IP6 hop-by-hop options
1301 pub const HOPOPTS = 0;
1302 /// control message protocol
1303 pub const ICMP = 1;
1304 /// group mgmt protocol
1305 pub const IGMP = 2;
1306 /// gateway^2 (deprecated)
1307 pub const GGP = 3;
1308 /// IP header
1309 pub const IPV4 = 4;
1310 /// IP inside IP
1311 pub const IPIP = 4;
1312 /// tcp
1313 pub const TCP = 6;
1314 /// exterior gateway protocol
1315 pub const EGP = 8;
1316 /// pup
1317 pub const PUP = 12;
1318 /// user datagram protocol
1319 pub const UDP = 17;
1320 /// xns idp
1321 pub const IDP = 22;
1322 /// tp-4 w/ class negotiation
1323 pub const TP = 29;
1324 /// DCCP
1325 pub const DCCP = 33;
1326 /// IP6 header
1327 pub const IPV6 = 41;
1328 /// IP6 routing header
1329 pub const ROUTING = 43;
1330 /// IP6 fragmentation header
1331 pub const FRAGMENT = 44;
1332 /// resource reservation
1333 pub const RSVP = 46;
1334 /// GRE encaps RFC 1701
1335 pub const GRE = 47;
1336 /// encap. security payload
1337 pub const ESP = 50;
1338 /// authentication header
1339 pub const AH = 51;
1340 /// IP Mobility RFC 2004
1341 pub const MOBILE = 55;
1342 /// IPv6 ICMP
1343 pub const IPV6_ICMP = 58;
1344 /// ICMP6
1345 pub const ICMPV6 = 58;
1346 /// IP6 no next header
1347 pub const NONE = 59;
1348 /// IP6 destination option
1349 pub const DSTOPTS = 60;
1350 /// ISO cnlp
1351 pub const EON = 80;
1352 /// Ethernet-in-IP
1353 pub const ETHERIP = 97;
1354 /// encapsulation header
1355 pub const ENCAP = 98;
1356 /// Protocol indep. multicast
1357 pub const PIM = 103;
1358 /// IP Payload Comp. Protocol
1359 pub const IPCOMP = 108;
1360 /// VRRP RFC 2338
1361 pub const VRRP = 112;
1362 /// Common Address Resolution Protocol
1363 pub const CARP = 112;
1364 /// L2TPv3
1365 pub const L2TP = 115;
1366 /// SCTP
1367 pub const SCTP = 132;
1368 /// PFSYNC
1369 pub const PFSYNC = 240;
1370 /// raw IP packet
1371 pub const RAW = 255;
1372};
1373
1374pub const rlimit_resource = enum(c_int) {
1375 CPU = 0,
1376 FSIZE = 1,
1377 DATA = 2,
1378 STACK = 3,
1379 CORE = 4,
1380 RSS = 5,
1381 MEMLOCK = 6,
1382 NPROC = 7,
1383 NOFILE = 8,
1384 SBSIZE = 9,
1385 VMEM = 10,
1386 NTHR = 11,
1387 _,
1388
1389 pub const AS: rlimit_resource = .VMEM;
1390};
1391
1392pub const rlim_t = u64;
1393
1394pub const RLIM = struct {
1395 /// No limit
1396 pub const INFINITY: rlim_t = (1 << 63) - 1;
1397
1398 pub const SAVED_MAX = INFINITY;
1399 pub const SAVED_CUR = INFINITY;
1400};
1401
1402pub const rlimit = extern struct {
1403 /// Soft limit
1404 cur: rlim_t,
1405 /// Hard limit
1406 max: rlim_t,
1407};
1408
1409pub const SHUT = struct {
1410 pub const RD = 0;
1411 pub const WR = 1;
1412 pub const RDWR = 2;
1413};
1414
1415pub const nfds_t = u32;
1416
1417pub const pollfd = extern struct {
1418 fd: fd_t,
1419 events: i16,
1420 revents: i16,
1421};
1422
1423pub const POLL = struct {
1424 /// Testable events (may be specified in events field).
1425 pub const IN = 0x0001;
1426 pub const PRI = 0x0002;
1427 pub const OUT = 0x0004;
1428 pub const RDNORM = 0x0040;
1429 pub const WRNORM = OUT;
1430 pub const RDBAND = 0x0080;
1431 pub const WRBAND = 0x0100;
1432
1433 /// Non-testable events (may not be specified in events field).
1434 pub const ERR = 0x0008;
1435 pub const HUP = 0x0010;
1436 pub const NVAL = 0x0020;
1437};
lib/std/c/openbsd.zig+1318-3
...@@ -1,7 +1,8 @@...@@ -1,7 +1,8 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = std.builtin;2const maxInt = std.math.maxInt;
33const builtin = @import("builtin");
4usingnamespace std.c;4const iovec = std.os.iovec;
5const iovec_const = std.os.iovec_const;
56
6extern "c" fn __errno() *c_int;7extern "c" fn __errno() *c_int;
7pub const _errno = __errno;8pub const _errno = __errno;
...@@ -43,3 +44,1317 @@ pub extern "c" fn unveil(path: ?[*:0]const u8, permissions: ?[*:0]const u8) c_in...@@ -43,3 +44,1317 @@ pub extern "c" fn unveil(path: ?[*:0]const u8, permissions: ?[*:0]const u8) c_in
4344
44pub extern "c" fn pthread_set_name_np(thread: std.c.pthread_t, name: [*:0]const u8) void;45pub extern "c" fn pthread_set_name_np(thread: std.c.pthread_t, name: [*:0]const u8) void;
45pub extern "c" fn pthread_get_name_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) void;46pub extern "c" fn pthread_get_name_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) void;
47
48pub const blkcnt_t = i64;
49pub const blksize_t = i32;
50pub const clock_t = i64;
51pub const dev_t = i32;
52pub const fd_t = c_int;
53pub const gid_t = u32;
54pub const ino_t = u64;
55pub const mode_t = u32;
56pub const nlink_t = u32;
57pub const off_t = i64;
58pub const pid_t = i32;
59pub const socklen_t = u32;
60pub const time_t = i64;
61pub const uid_t = u32;
62
63/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
64pub const Kevent = extern struct {
65 ident: usize,
66 filter: c_short,
67 flags: u16,
68 fflags: c_uint,
69 data: i64,
70 udata: usize,
71};
72
73// Modes and flags for dlopen()
74// include/dlfcn.h
75
76pub const RTLD = struct {
77 /// Bind function calls lazily.
78 pub const LAZY = 1;
79 /// Bind function calls immediately.
80 pub const NOW = 2;
81 /// Make symbols globally available.
82 pub const GLOBAL = 0x100;
83 /// Opposite of GLOBAL, and the default.
84 pub const LOCAL = 0x000;
85 /// Trace loaded objects and exit.
86 pub const TRACE = 0x200;
87};
88
89pub const dl_phdr_info = extern struct {
90 dlpi_addr: std.elf.Addr,
91 dlpi_name: ?[*:0]const u8,
92 dlpi_phdr: [*]std.elf.Phdr,
93 dlpi_phnum: std.elf.Half,
94};
95
96pub const Flock = extern struct {
97 l_start: off_t,
98 l_len: off_t,
99 l_pid: pid_t,
100 l_type: c_short,
101 l_whence: c_short,
102};
103
104pub const addrinfo = extern struct {
105 flags: c_int,
106 family: c_int,
107 socktype: c_int,
108 protocol: c_int,
109 addrlen: socklen_t,
110 addr: ?*sockaddr,
111 canonname: ?[*:0]u8,
112 next: ?*addrinfo,
113};
114
115pub const EAI = enum(c_int) {
116 /// address family for hostname not supported
117 ADDRFAMILY = -9,
118
119 /// name could not be resolved at this time
120 AGAIN = -3,
121
122 /// flags parameter had an invalid value
123 BADFLAGS = -1,
124
125 /// non-recoverable failure in name resolution
126 FAIL = -4,
127
128 /// address family not recognized
129 FAMILY = -6,
130
131 /// memory allocation failure
132 MEMORY = -10,
133
134 /// no address associated with hostname
135 NODATA = -5,
136
137 /// name does not resolve
138 NONAME = -2,
139
140 /// service not recognized for socket type
141 SERVICE = -8,
142
143 /// intended socket type was not recognized
144 SOCKTYPE = -7,
145
146 /// system error returned in errno
147 SYSTEM = -11,
148
149 /// invalid value for hints
150 BADHINTS = -12,
151
152 /// resolved protocol is unknown
153 PROTOCOL = -13,
154
155 /// argument buffer overflow
156 OVERFLOW = -14,
157
158 _,
159};
160
161pub const EAI_MAX = 15;
162
163pub const msghdr = extern struct {
164 /// optional address
165 msg_name: ?*sockaddr,
166
167 /// size of address
168 msg_namelen: socklen_t,
169
170 /// scatter/gather array
171 msg_iov: [*]iovec,
172
173 /// # elements in msg_iov
174 msg_iovlen: c_uint,
175
176 /// ancillary data
177 msg_control: ?*c_void,
178
179 /// ancillary data buffer len
180 msg_controllen: socklen_t,
181
182 /// flags on received message
183 msg_flags: c_int,
184};
185
186pub const msghdr_const = extern struct {
187 /// optional address
188 msg_name: ?*const sockaddr,
189
190 /// size of address
191 msg_namelen: socklen_t,
192
193 /// scatter/gather array
194 msg_iov: [*]iovec_const,
195
196 /// # elements in msg_iov
197 msg_iovlen: c_uint,
198
199 /// ancillary data
200 msg_control: ?*c_void,
201
202 /// ancillary data buffer len
203 msg_controllen: socklen_t,
204
205 /// flags on received message
206 msg_flags: c_int,
207};
208
209pub const Stat = extern struct {
210 mode: mode_t,
211 dev: dev_t,
212 ino: ino_t,
213 nlink: nlink_t,
214 uid: uid_t,
215 gid: gid_t,
216 rdev: dev_t,
217 atim: timespec,
218 mtim: timespec,
219 ctim: timespec,
220 size: off_t,
221 blocks: blkcnt_t,
222 blksize: blksize_t,
223 flags: u32,
224 gen: u32,
225 birthtim: timespec,
226
227 pub fn atime(self: @This()) timespec {
228 return self.atim;
229 }
230
231 pub fn mtime(self: @This()) timespec {
232 return self.mtim;
233 }
234
235 pub fn ctime(self: @This()) timespec {
236 return self.ctim;
237 }
238};
239
240pub const timespec = extern struct {
241 tv_sec: time_t,
242 tv_nsec: c_long,
243};
244
245pub const timeval = extern struct {
246 tv_sec: time_t,
247 tv_usec: c_long,
248};
249
250pub const timezone = extern struct {
251 tz_minuteswest: c_int,
252 tz_dsttime: c_int,
253};
254
255pub const MAXNAMLEN = 255;
256
257pub const dirent = extern struct {
258 d_fileno: ino_t,
259 d_off: off_t,
260 d_reclen: u16,
261 d_type: u8,
262 d_namlen: u8,
263 __d_padding: [4]u8,
264 d_name: [MAXNAMLEN + 1]u8,
265
266 pub fn reclen(self: dirent) u16 {
267 return self.d_reclen;
268 }
269};
270
271pub const in_port_t = u16;
272pub const sa_family_t = u8;
273
274pub const sockaddr = extern struct {
275 /// total length
276 len: u8,
277 /// address family
278 family: sa_family_t,
279 /// actually longer; address value
280 data: [14]u8,
281
282 pub const storage = std.x.os.Socket.Address.Native.Storage;
283
284 pub const in = extern struct {
285 len: u8 = @sizeOf(in),
286 family: sa_family_t = AF.INET,
287 port: in_port_t,
288 addr: u32,
289 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
290 };
291
292 pub const in6 = extern struct {
293 len: u8 = @sizeOf(in6),
294 family: sa_family_t = AF.INET6,
295 port: in_port_t,
296 flowinfo: u32,
297 addr: [16]u8,
298 scope_id: u32,
299 };
300
301 /// Definitions for UNIX IPC domain.
302 pub const un = extern struct {
303 /// total sockaddr length
304 len: u8 = @sizeOf(un),
305
306 family: sa_family_t = AF.LOCAL,
307
308 /// path name
309 path: [104]u8,
310 };
311};
312
313pub const AI = struct {
314 /// get address to use bind()
315 pub const PASSIVE = 1;
316 /// fill ai_canonname
317 pub const CANONNAME = 2;
318 /// prevent host name resolution
319 pub const NUMERICHOST = 4;
320 /// prevent service name resolution
321 pub const NUMERICSERV = 16;
322 /// only if any address is assigned
323 pub const ADDRCONFIG = 64;
324};
325
326pub const PATH_MAX = 1024;
327pub const IOV_MAX = 1024;
328
329pub const STDIN_FILENO = 0;
330pub const STDOUT_FILENO = 1;
331pub const STDERR_FILENO = 2;
332
333pub const PROT = struct {
334 pub const NONE = 0;
335 pub const READ = 1;
336 pub const WRITE = 2;
337 pub const EXEC = 4;
338};
339
340pub const CLOCK = struct {
341 pub const REALTIME = 0;
342 pub const PROCESS_CPUTIME_ID = 2;
343 pub const MONOTONIC = 3;
344 pub const THREAD_CPUTIME_ID = 4;
345};
346
347pub const MAP = struct {
348 pub const FAILED = @intToPtr(*c_void, maxInt(usize));
349 pub const SHARED = 0x0001;
350 pub const PRIVATE = 0x0002;
351 pub const FIXED = 0x0010;
352 pub const RENAME = 0;
353 pub const NORESERVE = 0;
354 pub const INHERIT = 0;
355 pub const HASSEMAPHORE = 0;
356 pub const TRYFIXED = 0;
357
358 pub const FILE = 0;
359 pub const ANON = 0x1000;
360 pub const ANONYMOUS = ANON;
361 pub const STACK = 0x4000;
362 pub const CONCEAL = 0x8000;
363};
364
365pub const W = struct {
366 pub const NOHANG = 1;
367 pub const UNTRACED = 2;
368 pub const CONTINUED = 8;
369
370 pub fn EXITSTATUS(s: u32) u8 {
371 return @intCast(u8, (s >> 8) & 0xff);
372 }
373 pub fn TERMSIG(s: u32) u32 {
374 return (s & 0x7f);
375 }
376 pub fn STOPSIG(s: u32) u32 {
377 return EXITSTATUS(s);
378 }
379 pub fn IFEXITED(s: u32) bool {
380 return TERMSIG(s) == 0;
381 }
382
383 pub fn IFCONTINUED(s: u32) bool {
384 return ((s & 0o177777) == 0o177777);
385 }
386
387 pub fn IFSTOPPED(s: u32) bool {
388 return (s & 0xff == 0o177);
389 }
390
391 pub fn IFSIGNALED(s: u32) bool {
392 return (((s) & 0o177) != 0o177) and (((s) & 0o177) != 0);
393 }
394};
395
396pub const SA = struct {
397 pub const ONSTACK = 0x0001;
398 pub const RESTART = 0x0002;
399 pub const RESETHAND = 0x0004;
400 pub const NOCLDSTOP = 0x0008;
401 pub const NODEFER = 0x0010;
402 pub const NOCLDWAIT = 0x0020;
403 pub const SIGINFO = 0x0040;
404};
405
406// access function
407pub const F_OK = 0; // test for existence of file
408pub const X_OK = 1; // test for execute or search permission
409pub const W_OK = 2; // test for write permission
410pub const R_OK = 4; // test for read permission
411
412pub const O = struct {
413 /// open for reading only
414 pub const RDONLY = 0x00000000;
415 /// open for writing only
416 pub const WRONLY = 0x00000001;
417 /// open for reading and writing
418 pub const RDWR = 0x00000002;
419 /// mask for above modes
420 pub const ACCMODE = 0x00000003;
421 /// no delay
422 pub const NONBLOCK = 0x00000004;
423 /// set append mode
424 pub const APPEND = 0x00000008;
425 /// open with shared file lock
426 pub const SHLOCK = 0x00000010;
427 /// open with exclusive file lock
428 pub const EXLOCK = 0x00000020;
429 /// signal pgrp when data ready
430 pub const ASYNC = 0x00000040;
431 /// synchronous writes
432 pub const SYNC = 0x00000080;
433 /// don't follow symlinks on the last
434 pub const NOFOLLOW = 0x00000100;
435 /// create if nonexistent
436 pub const CREAT = 0x00000200;
437 /// truncate to zero length
438 pub const TRUNC = 0x00000400;
439 /// error if already exists
440 pub const EXCL = 0x00000800;
441 /// don't assign controlling terminal
442 pub const NOCTTY = 0x00008000;
443 /// write: I/O data completion
444 pub const DSYNC = SYNC;
445 /// read: I/O completion as for write
446 pub const RSYNC = SYNC;
447 /// fail if not a directory
448 pub const DIRECTORY = 0x20000;
449 /// set close on exec
450 pub const CLOEXEC = 0x10000;
451};
452
453pub const F = struct {
454 pub const DUPFD = 0;
455 pub const GETFD = 1;
456 pub const SETFD = 2;
457 pub const GETFL = 3;
458 pub const SETFL = 4;
459
460 pub const GETOWN = 5;
461 pub const SETOWN = 6;
462
463 pub const GETLK = 7;
464 pub const SETLK = 8;
465 pub const SETLKW = 9;
466
467 pub const RDLCK = 1;
468 pub const UNLCK = 2;
469 pub const WRLCK = 3;
470};
471
472pub const LOCK = struct {
473 pub const SH = 0x01;
474 pub const EX = 0x02;
475 pub const NB = 0x04;
476 pub const UN = 0x08;
477};
478
479pub const FD_CLOEXEC = 1;
480
481pub const SEEK = struct {
482 pub const SET = 0;
483 pub const CUR = 1;
484 pub const END = 2;
485};
486
487pub const SOCK = struct {
488 pub const STREAM = 1;
489 pub const DGRAM = 2;
490 pub const RAW = 3;
491 pub const RDM = 4;
492 pub const SEQPACKET = 5;
493
494 pub const CLOEXEC = 0x8000;
495 pub const NONBLOCK = 0x4000;
496};
497
498pub const SO = struct {
499 pub const DEBUG = 0x0001;
500 pub const ACCEPTCONN = 0x0002;
501 pub const REUSEADDR = 0x0004;
502 pub const KEEPALIVE = 0x0008;
503 pub const DONTROUTE = 0x0010;
504 pub const BROADCAST = 0x0020;
505 pub const USELOOPBACK = 0x0040;
506 pub const LINGER = 0x0080;
507 pub const OOBINLINE = 0x0100;
508 pub const REUSEPORT = 0x0200;
509 pub const TIMESTAMP = 0x0800;
510 pub const BINDANY = 0x1000;
511 pub const ZEROIZE = 0x2000;
512 pub const SNDBUF = 0x1001;
513 pub const RCVBUF = 0x1002;
514 pub const SNDLOWAT = 0x1003;
515 pub const RCVLOWAT = 0x1004;
516 pub const SNDTIMEO = 0x1005;
517 pub const RCVTIMEO = 0x1006;
518 pub const ERROR = 0x1007;
519 pub const TYPE = 0x1008;
520 pub const NETPROC = 0x1020;
521 pub const RTABLE = 0x1021;
522 pub const PEERCRED = 0x1022;
523 pub const SPLICE = 0x1023;
524 pub const DOMAIN = 0x1024;
525 pub const PROTOCOL = 0x1025;
526};
527
528pub const SOL = struct {
529 pub const SOCKET = 0xffff;
530};
531
532pub const PF = struct {
533 pub const UNSPEC = AF.UNSPEC;
534 pub const LOCAL = AF.LOCAL;
535 pub const UNIX = AF.UNIX;
536 pub const INET = AF.INET;
537 pub const APPLETALK = AF.APPLETALK;
538 pub const INET6 = AF.INET6;
539 pub const DECnet = AF.DECnet;
540 pub const KEY = AF.KEY;
541 pub const ROUTE = AF.ROUTE;
542 pub const SNA = AF.SNA;
543 pub const MPLS = AF.MPLS;
544 pub const BLUETOOTH = AF.BLUETOOTH;
545 pub const ISDN = AF.ISDN;
546 pub const MAX = AF.MAX;
547};
548
549pub const AF = struct {
550 pub const UNSPEC = 0;
551 pub const UNIX = 1;
552 pub const LOCAL = UNIX;
553 pub const INET = 2;
554 pub const APPLETALK = 16;
555 pub const INET6 = 24;
556 pub const KEY = 30;
557 pub const ROUTE = 17;
558 pub const SNA = 11;
559 pub const MPLS = 33;
560 pub const BLUETOOTH = 32;
561 pub const ISDN = 26;
562 pub const MAX = 36;
563};
564
565pub const DT = struct {
566 pub const UNKNOWN = 0;
567 pub const FIFO = 1;
568 pub const CHR = 2;
569 pub const DIR = 4;
570 pub const BLK = 6;
571 pub const REG = 8;
572 pub const LNK = 10;
573 pub const SOCK = 12;
574 pub const WHT = 14; // XXX
575};
576
577pub const EV_ADD = 0x0001;
578pub const EV_DELETE = 0x0002;
579pub const EV_ENABLE = 0x0004;
580pub const EV_DISABLE = 0x0008;
581pub const EV_ONESHOT = 0x0010;
582pub const EV_CLEAR = 0x0020;
583pub const EV_RECEIPT = 0x0040;
584pub const EV_DISPATCH = 0x0080;
585pub const EV_FLAG1 = 0x2000;
586pub const EV_ERROR = 0x4000;
587pub const EV_EOF = 0x8000;
588
589pub const EVFILT_READ = -1;
590pub const EVFILT_WRITE = -2;
591pub const EVFILT_AIO = -3;
592pub const EVFILT_VNODE = -4;
593pub const EVFILT_PROC = -5;
594pub const EVFILT_SIGNAL = -6;
595pub const EVFILT_TIMER = -7;
596pub const EVFILT_EXCEPT = -9;
597
598// data/hint flags for EVFILT_{READ|WRITE}
599pub const NOTE_LOWAT = 0x0001;
600pub const NOTE_EOF = 0x0002;
601
602// data/hint flags for EVFILT_EXCEPT and EVFILT_{READ|WRITE}
603pub const NOTE_OOB = 0x0004;
604
605// data/hint flags for EVFILT_VNODE
606pub const NOTE_DELETE = 0x0001;
607pub const NOTE_WRITE = 0x0002;
608pub const NOTE_EXTEND = 0x0004;
609pub const NOTE_ATTRIB = 0x0008;
610pub const NOTE_LINK = 0x0010;
611pub const NOTE_RENAME = 0x0020;
612pub const NOTE_REVOKE = 0x0040;
613pub const NOTE_TRUNCATE = 0x0080;
614
615// data/hint flags for EVFILT_PROC
616pub const NOTE_EXIT = 0x80000000;
617pub const NOTE_FORK = 0x40000000;
618pub const NOTE_EXEC = 0x20000000;
619pub const NOTE_PDATAMASK = 0x000fffff;
620pub const NOTE_PCTRLMASK = 0xf0000000;
621pub const NOTE_TRACK = 0x00000001;
622pub const NOTE_TRACKERR = 0x00000002;
623pub const NOTE_CHILD = 0x00000004;
624
625// data/hint flags for EVFILT_DEVICE
626pub const NOTE_CHANGE = 0x00000001;
627
628pub const T = struct {
629 pub const IOCCBRK = 0x2000747a;
630 pub const IOCCDTR = 0x20007478;
631 pub const IOCCONS = 0x80047462;
632 pub const IOCDCDTIMESTAMP = 0x40107458;
633 pub const IOCDRAIN = 0x2000745e;
634 pub const IOCEXCL = 0x2000740d;
635 pub const IOCEXT = 0x80047460;
636 pub const IOCFLAG_CDTRCTS = 0x10;
637 pub const IOCFLAG_CLOCAL = 0x2;
638 pub const IOCFLAG_CRTSCTS = 0x4;
639 pub const IOCFLAG_MDMBUF = 0x8;
640 pub const IOCFLAG_SOFTCAR = 0x1;
641 pub const IOCFLUSH = 0x80047410;
642 pub const IOCGETA = 0x402c7413;
643 pub const IOCGETD = 0x4004741a;
644 pub const IOCGFLAGS = 0x4004745d;
645 pub const IOCGLINED = 0x40207442;
646 pub const IOCGPGRP = 0x40047477;
647 pub const IOCGQSIZE = 0x40047481;
648 pub const IOCGRANTPT = 0x20007447;
649 pub const IOCGSID = 0x40047463;
650 pub const IOCGSIZE = 0x40087468;
651 pub const IOCGWINSZ = 0x40087468;
652 pub const IOCMBIC = 0x8004746b;
653 pub const IOCMBIS = 0x8004746c;
654 pub const IOCMGET = 0x4004746a;
655 pub const IOCMSET = 0x8004746d;
656 pub const IOCM_CAR = 0x40;
657 pub const IOCM_CD = 0x40;
658 pub const IOCM_CTS = 0x20;
659 pub const IOCM_DSR = 0x100;
660 pub const IOCM_DTR = 0x2;
661 pub const IOCM_LE = 0x1;
662 pub const IOCM_RI = 0x80;
663 pub const IOCM_RNG = 0x80;
664 pub const IOCM_RTS = 0x4;
665 pub const IOCM_SR = 0x10;
666 pub const IOCM_ST = 0x8;
667 pub const IOCNOTTY = 0x20007471;
668 pub const IOCNXCL = 0x2000740e;
669 pub const IOCOUTQ = 0x40047473;
670 pub const IOCPKT = 0x80047470;
671 pub const IOCPKT_DATA = 0x0;
672 pub const IOCPKT_DOSTOP = 0x20;
673 pub const IOCPKT_FLUSHREAD = 0x1;
674 pub const IOCPKT_FLUSHWRITE = 0x2;
675 pub const IOCPKT_IOCTL = 0x40;
676 pub const IOCPKT_NOSTOP = 0x10;
677 pub const IOCPKT_START = 0x8;
678 pub const IOCPKT_STOP = 0x4;
679 pub const IOCPTMGET = 0x40287446;
680 pub const IOCPTSNAME = 0x40287448;
681 pub const IOCRCVFRAME = 0x80087445;
682 pub const IOCREMOTE = 0x80047469;
683 pub const IOCSBRK = 0x2000747b;
684 pub const IOCSCTTY = 0x20007461;
685 pub const IOCSDTR = 0x20007479;
686 pub const IOCSETA = 0x802c7414;
687 pub const IOCSETAF = 0x802c7416;
688 pub const IOCSETAW = 0x802c7415;
689 pub const IOCSETD = 0x8004741b;
690 pub const IOCSFLAGS = 0x8004745c;
691 pub const IOCSIG = 0x2000745f;
692 pub const IOCSLINED = 0x80207443;
693 pub const IOCSPGRP = 0x80047476;
694 pub const IOCSQSIZE = 0x80047480;
695 pub const IOCSSIZE = 0x80087467;
696 pub const IOCSTART = 0x2000746e;
697 pub const IOCSTAT = 0x80047465;
698 pub const IOCSTI = 0x80017472;
699 pub const IOCSTOP = 0x2000746f;
700 pub const IOCSWINSZ = 0x80087467;
701 pub const IOCUCNTL = 0x80047466;
702 pub const IOCXMTFRAME = 0x80087444;
703};
704
705pub const winsize = extern struct {
706 ws_row: c_ushort,
707 ws_col: c_ushort,
708 ws_xpixel: c_ushort,
709 ws_ypixel: c_ushort,
710};
711
712const NSIG = 33;
713
714pub const SIG = struct {
715 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
716 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
717 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
718 pub const CATCH = @intToPtr(?Sigaction.sigaction_fn, 2);
719 pub const HOLD = @intToPtr(?Sigaction.sigaction_fn, 3);
720
721 pub const HUP = 1;
722 pub const INT = 2;
723 pub const QUIT = 3;
724 pub const ILL = 4;
725 pub const TRAP = 5;
726 pub const ABRT = 6;
727 pub const IOT = ABRT;
728 pub const EMT = 7;
729 pub const FPE = 8;
730 pub const KILL = 9;
731 pub const BUS = 10;
732 pub const SEGV = 11;
733 pub const SYS = 12;
734 pub const PIPE = 13;
735 pub const ALRM = 14;
736 pub const TERM = 15;
737 pub const URG = 16;
738 pub const STOP = 17;
739 pub const TSTP = 18;
740 pub const CONT = 19;
741 pub const CHLD = 20;
742 pub const TTIN = 21;
743 pub const TTOU = 22;
744 pub const IO = 23;
745 pub const XCPU = 24;
746 pub const XFSZ = 25;
747 pub const VTALRM = 26;
748 pub const PROF = 27;
749 pub const WINCH = 28;
750 pub const INFO = 29;
751 pub const USR1 = 30;
752 pub const USR2 = 31;
753 pub const PWR = 32;
754
755 pub const BLOCK = 1;
756 pub const UNBLOCK = 2;
757 pub const SETMASK = 3;
758};
759
760/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
761pub const Sigaction = extern struct {
762 pub const handler_fn = fn (c_int) callconv(.C) void;
763 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
764
765 /// signal handler
766 handler: extern union {
767 handler: ?handler_fn,
768 sigaction: ?sigaction_fn,
769 },
770 /// signal mask to apply
771 mask: sigset_t,
772 /// signal options
773 flags: c_uint,
774};
775
776pub const sigval = extern union {
777 int: c_int,
778 ptr: ?*c_void,
779};
780
781pub const siginfo_t = extern struct {
782 signo: c_int,
783 code: c_int,
784 errno: c_int,
785 data: extern union {
786 proc: extern struct {
787 pid: pid_t,
788 pdata: extern union {
789 kill: extern struct {
790 uid: uid_t,
791 value: sigval,
792 },
793 cld: extern struct {
794 utime: clock_t,
795 stime: clock_t,
796 status: c_int,
797 },
798 },
799 },
800 fault: extern struct {
801 addr: ?*c_void,
802 trapno: c_int,
803 },
804 __pad: [128 - 3 * @sizeOf(c_int)]u8,
805 },
806};
807
808comptime {
809 if (@sizeOf(usize) == 4)
810 std.debug.assert(@sizeOf(siginfo_t) == 128)
811 else
812 // Take into account the padding between errno and data fields.
813 std.debug.assert(@sizeOf(siginfo_t) == 136);
814}
815
816const arch_bits = switch (builtin.cpu.arch) {
817 .x86_64 => struct {
818 pub const ucontext_t = extern struct {
819 sc_rdi: c_long,
820 sc_rsi: c_long,
821 sc_rdx: c_long,
822 sc_rcx: c_long,
823 sc_r8: c_long,
824 sc_r9: c_long,
825 sc_r10: c_long,
826 sc_r11: c_long,
827 sc_r12: c_long,
828 sc_r13: c_long,
829 sc_r14: c_long,
830 sc_r15: c_long,
831 sc_rbp: c_long,
832 sc_rbx: c_long,
833 sc_rax: c_long,
834 sc_gs: c_long,
835 sc_fs: c_long,
836 sc_es: c_long,
837 sc_ds: c_long,
838 sc_trapno: c_long,
839 sc_err: c_long,
840 sc_rip: c_long,
841 sc_cs: c_long,
842 sc_rflags: c_long,
843 sc_rsp: c_long,
844 sc_ss: c_long,
845
846 sc_fpstate: arch_bits.fxsave64,
847 __sc_unused: c_int,
848 sc_mask: c_int,
849 sc_cookie: c_long,
850 };
851
852 pub const fxsave64 = packed struct {
853 fx_fcw: u16,
854 fx_fsw: u16,
855 fx_ftw: u8,
856 fx_unused1: u8,
857 fx_fop: u16,
858 fx_rip: u64,
859 fx_rdp: u64,
860 fx_mxcsr: u32,
861 fx_mxcsr_mask: u32,
862 fx_st: [8][2]u64,
863 fx_xmm: [16][2]u64,
864 fx_unused3: [96]u8,
865 };
866 },
867 else => struct {},
868};
869pub const ucontext_t = arch_bits.ucontext_t;
870pub const fxsave64 = arch_bits.fxsave64;
871
872pub const sigset_t = c_uint;
873pub const empty_sigset: sigset_t = 0;
874
875pub const E = enum(u16) {
876 /// No error occurred.
877 SUCCESS = 0,
878 PERM = 1, // Operation not permitted
879 NOENT = 2, // No such file or directory
880 SRCH = 3, // No such process
881 INTR = 4, // Interrupted system call
882 IO = 5, // Input/output error
883 NXIO = 6, // Device not configured
884 @"2BIG" = 7, // Argument list too long
885 NOEXEC = 8, // Exec format error
886 BADF = 9, // Bad file descriptor
887 CHILD = 10, // No child processes
888 DEADLK = 11, // Resource deadlock avoided
889 // 11 was AGAIN
890 NOMEM = 12, // Cannot allocate memory
891 ACCES = 13, // Permission denied
892 FAULT = 14, // Bad address
893 NOTBLK = 15, // Block device required
894 BUSY = 16, // Device busy
895 EXIST = 17, // File exists
896 XDEV = 18, // Cross-device link
897 NODEV = 19, // Operation not supported by device
898 NOTDIR = 20, // Not a directory
899 ISDIR = 21, // Is a directory
900 INVAL = 22, // Invalid argument
901 NFILE = 23, // Too many open files in system
902 MFILE = 24, // Too many open files
903 NOTTY = 25, // Inappropriate ioctl for device
904 TXTBSY = 26, // Text file busy
905 FBIG = 27, // File too large
906 NOSPC = 28, // No space left on device
907 SPIPE = 29, // Illegal seek
908 ROFS = 30, // Read-only file system
909 MLINK = 31, // Too many links
910 PIPE = 32, // Broken pipe
911
912 // math software
913 DOM = 33, // Numerical argument out of domain
914 RANGE = 34, // Result too large or too small
915
916 // non-blocking and interrupt i/o
917 // also: WOULDBLOCK: operation would block
918 AGAIN = 35, // Resource temporarily unavailable
919 INPROGRESS = 36, // Operation now in progress
920 ALREADY = 37, // Operation already in progress
921
922 // ipc/network software -- argument errors
923 NOTSOCK = 38, // Socket operation on non-socket
924 DESTADDRREQ = 39, // Destination address required
925 MSGSIZE = 40, // Message too long
926 PROTOTYPE = 41, // Protocol wrong type for socket
927 NOPROTOOPT = 42, // Protocol option not available
928 PROTONOSUPPORT = 43, // Protocol not supported
929 SOCKTNOSUPPORT = 44, // Socket type not supported
930 OPNOTSUPP = 45, // Operation not supported
931 PFNOSUPPORT = 46, // Protocol family not supported
932 AFNOSUPPORT = 47, // Address family not supported by protocol family
933 ADDRINUSE = 48, // Address already in use
934 ADDRNOTAVAIL = 49, // Can't assign requested address
935
936 // ipc/network software -- operational errors
937 NETDOWN = 50, // Network is down
938 NETUNREACH = 51, // Network is unreachable
939 NETRESET = 52, // Network dropped connection on reset
940 CONNABORTED = 53, // Software caused connection abort
941 CONNRESET = 54, // Connection reset by peer
942 NOBUFS = 55, // No buffer space available
943 ISCONN = 56, // Socket is already connected
944 NOTCONN = 57, // Socket is not connected
945 SHUTDOWN = 58, // Can't send after socket shutdown
946 TOOMANYREFS = 59, // Too many references: can't splice
947 TIMEDOUT = 60, // Operation timed out
948 CONNREFUSED = 61, // Connection refused
949
950 LOOP = 62, // Too many levels of symbolic links
951 NAMETOOLONG = 63, // File name too long
952
953 // should be rearranged
954 HOSTDOWN = 64, // Host is down
955 HOSTUNREACH = 65, // No route to host
956 NOTEMPTY = 66, // Directory not empty
957
958 // quotas & mush
959 PROCLIM = 67, // Too many processes
960 USERS = 68, // Too many users
961 DQUOT = 69, // Disc quota exceeded
962
963 // Network File System
964 STALE = 70, // Stale NFS file handle
965 REMOTE = 71, // Too many levels of remote in path
966 BADRPC = 72, // RPC struct is bad
967 RPCMISMATCH = 73, // RPC version wrong
968 PROGUNAVAIL = 74, // RPC prog. not avail
969 PROGMISMATCH = 75, // Program version wrong
970 PROCUNAVAIL = 76, // Bad procedure for program
971
972 NOLCK = 77, // No locks available
973 NOSYS = 78, // Function not implemented
974
975 FTYPE = 79, // Inappropriate file type or format
976 AUTH = 80, // Authentication error
977 NEEDAUTH = 81, // Need authenticator
978 IPSEC = 82, // IPsec processing failure
979 NOATTR = 83, // Attribute not found
980
981 // Wide/multibyte-character handling, ISO/IEC 9899/AMD1:1995
982 ILSEQ = 84, // Illegal byte sequence
983
984 NOMEDIUM = 85, // No medium found
985 MEDIUMTYPE = 86, // Wrong medium type
986 OVERFLOW = 87, // Value too large to be stored in data type
987 CANCELED = 88, // Operation canceled
988 IDRM = 89, // Identifier removed
989 NOMSG = 90, // No message of desired type
990 NOTSUP = 91, // Not supported
991 BADMSG = 92, // Bad or Corrupt message
992 NOTRECOVERABLE = 93, // State not recoverable
993 OWNERDEAD = 94, // Previous owner died
994 PROTO = 95, // Protocol error
995
996 _,
997};
998
999const _MAX_PAGE_SHIFT = switch (builtin.cpu.arch) {
1000 .i386 => 12,
1001 .sparcv9 => 13,
1002};
1003pub const MINSIGSTKSZ = 1 << _MAX_PAGE_SHIFT;
1004pub const SIGSTKSZ = MINSIGSTKSZ + (1 << _MAX_PAGE_SHIFT) * 4;
1005
1006pub const SS_ONSTACK = 0x0001;
1007pub const SS_DISABLE = 0x0004;
1008
1009pub const stack_t = extern struct {
1010 sp: [*]u8,
1011 size: usize,
1012 flags: c_int,
1013};
1014
1015pub const S = struct {
1016 pub const IFMT = 0o170000;
1017
1018 pub const IFIFO = 0o010000;
1019 pub const IFCHR = 0o020000;
1020 pub const IFDIR = 0o040000;
1021 pub const IFBLK = 0o060000;
1022 pub const IFREG = 0o100000;
1023 pub const IFLNK = 0o120000;
1024 pub const IFSOCK = 0o140000;
1025
1026 pub const ISUID = 0o4000;
1027 pub const ISGID = 0o2000;
1028 pub const ISVTX = 0o1000;
1029 pub const IRWXU = 0o700;
1030 pub const IRUSR = 0o400;
1031 pub const IWUSR = 0o200;
1032 pub const IXUSR = 0o100;
1033 pub const IRWXG = 0o070;
1034 pub const IRGRP = 0o040;
1035 pub const IWGRP = 0o020;
1036 pub const IXGRP = 0o010;
1037 pub const IRWXO = 0o007;
1038 pub const IROTH = 0o004;
1039 pub const IWOTH = 0o002;
1040 pub const IXOTH = 0o001;
1041
1042 pub fn ISFIFO(m: u32) bool {
1043 return m & IFMT == IFIFO;
1044 }
1045
1046 pub fn ISCHR(m: u32) bool {
1047 return m & IFMT == IFCHR;
1048 }
1049
1050 pub fn ISDIR(m: u32) bool {
1051 return m & IFMT == IFDIR;
1052 }
1053
1054 pub fn ISBLK(m: u32) bool {
1055 return m & IFMT == IFBLK;
1056 }
1057
1058 pub fn ISREG(m: u32) bool {
1059 return m & IFMT == IFREG;
1060 }
1061
1062 pub fn ISLNK(m: u32) bool {
1063 return m & IFMT == IFLNK;
1064 }
1065
1066 pub fn ISSOCK(m: u32) bool {
1067 return m & IFMT == IFSOCK;
1068 }
1069};
1070
1071pub const AT = struct {
1072 /// Magic value that specify the use of the current working directory
1073 /// to determine the target of relative file paths in the openat() and
1074 /// similar syscalls.
1075 pub const FDCWD = -100;
1076 /// Check access using effective user and group ID
1077 pub const EACCESS = 0x01;
1078 /// Do not follow symbolic links
1079 pub const SYMLINK_NOFOLLOW = 0x02;
1080 /// Follow symbolic link
1081 pub const SYMLINK_FOLLOW = 0x04;
1082 /// Remove directory instead of file
1083 pub const REMOVEDIR = 0x08;
1084};
1085
1086pub const HOST_NAME_MAX = 255;
1087
1088pub const IPPROTO = struct {
1089 /// dummy for IP
1090 pub const IP = 0;
1091 /// IP6 hop-by-hop options
1092 pub const HOPOPTS = IP;
1093 /// control message protocol
1094 pub const ICMP = 1;
1095 /// group mgmt protocol
1096 pub const IGMP = 2;
1097 /// gateway^2 (deprecated)
1098 pub const GGP = 3;
1099 /// IP header
1100 pub const IPV4 = IPIP;
1101 /// IP inside IP
1102 pub const IPIP = 4;
1103 /// tcp
1104 pub const TCP = 6;
1105 /// exterior gateway protocol
1106 pub const EGP = 8;
1107 /// pup
1108 pub const PUP = 12;
1109 /// user datagram protocol
1110 pub const UDP = 17;
1111 /// xns idp
1112 pub const IDP = 22;
1113 /// tp-4 w/ class negotiation
1114 pub const TP = 29;
1115 /// IP6 header
1116 pub const IPV6 = 41;
1117 /// IP6 routing header
1118 pub const ROUTING = 43;
1119 /// IP6 fragmentation header
1120 pub const FRAGMENT = 44;
1121 /// resource reservation
1122 pub const RSVP = 46;
1123 /// GRE encaps RFC 1701
1124 pub const GRE = 47;
1125 /// encap. security payload
1126 pub const ESP = 50;
1127 /// authentication header
1128 pub const AH = 51;
1129 /// IP Mobility RFC 2004
1130 pub const MOBILE = 55;
1131 /// IPv6 ICMP
1132 pub const IPV6_ICMP = 58;
1133 /// ICMP6
1134 pub const ICMPV6 = 58;
1135 /// IP6 no next header
1136 pub const NONE = 59;
1137 /// IP6 destination option
1138 pub const DSTOPTS = 60;
1139 /// ISO cnlp
1140 pub const EON = 80;
1141 /// Ethernet-in-IP
1142 pub const ETHERIP = 97;
1143 /// encapsulation header
1144 pub const ENCAP = 98;
1145 /// Protocol indep. multicast
1146 pub const PIM = 103;
1147 /// IP Payload Comp. Protocol
1148 pub const IPCOMP = 108;
1149 /// VRRP RFC 2338
1150 pub const VRRP = 112;
1151 /// Common Address Resolution Protocol
1152 pub const CARP = 112;
1153 /// PFSYNC
1154 pub const PFSYNC = 240;
1155 /// raw IP packet
1156 pub const RAW = 255;
1157};
1158
1159pub const rlimit_resource = enum(c_int) {
1160 CPU,
1161 FSIZE,
1162 DATA,
1163 STACK,
1164 CORE,
1165 RSS,
1166 MEMLOCK,
1167 NPROC,
1168 NOFILE,
1169
1170 _,
1171};
1172
1173pub const rlim_t = u64;
1174
1175pub const RLIM = struct {
1176 /// No limit
1177 pub const INFINITY: rlim_t = (1 << 63) - 1;
1178
1179 pub const SAVED_MAX = INFINITY;
1180 pub const SAVED_CUR = INFINITY;
1181};
1182
1183pub const rlimit = extern struct {
1184 /// Soft limit
1185 cur: rlim_t,
1186 /// Hard limit
1187 max: rlim_t,
1188};
1189
1190pub const SHUT = struct {
1191 pub const RD = 0;
1192 pub const WR = 1;
1193 pub const RDWR = 2;
1194};
1195
1196pub const nfds_t = c_uint;
1197
1198pub const pollfd = extern struct {
1199 fd: fd_t,
1200 events: c_short,
1201 revents: c_short,
1202};
1203
1204pub const POLL = struct {
1205 pub const IN = 0x0001;
1206 pub const PRI = 0x0002;
1207 pub const OUT = 0x0004;
1208 pub const ERR = 0x0008;
1209 pub const HUP = 0x0010;
1210 pub const NVAL = 0x0020;
1211 pub const RDNORM = 0x0040;
1212 pub const NORM = RDNORM;
1213 pub const WRNORM = OUT;
1214 pub const RDBAND = 0x0080;
1215 pub const WRBAND = 0x0100;
1216};
1217
1218pub const CTL = struct {
1219 pub const UNSPEC = 0;
1220 pub const KERN = 1;
1221 pub const VM = 2;
1222 pub const FS = 3;
1223 pub const NET = 4;
1224 pub const DEBUG = 5;
1225 pub const HW = 6;
1226 pub const MACHDEP = 7;
1227
1228 pub const DDB = 9;
1229 pub const VFS = 10;
1230};
1231
1232pub const KERN = struct {
1233 pub const OSTYPE = 1;
1234 pub const OSRELEASE = 2;
1235 pub const OSREV = 3;
1236 pub const VERSION = 4;
1237 pub const MAXVNODES = 5;
1238 pub const MAXPROC = 6;
1239 pub const MAXFILES = 7;
1240 pub const ARGMAX = 8;
1241 pub const SECURELVL = 9;
1242 pub const HOSTNAME = 10;
1243 pub const HOSTID = 11;
1244 pub const CLOCKRATE = 12;
1245
1246 pub const PROF = 16;
1247 pub const POSIX1 = 17;
1248 pub const NGROUPS = 18;
1249 pub const JOB_CONTROL = 19;
1250 pub const SAVED_IDS = 20;
1251 pub const BOOTTIME = 21;
1252 pub const DOMAINNAME = 22;
1253 pub const MAXPARTITIONS = 23;
1254 pub const RAWPARTITION = 24;
1255 pub const MAXTHREAD = 25;
1256 pub const NTHREADS = 26;
1257 pub const OSVERSION = 27;
1258 pub const SOMAXCONN = 28;
1259 pub const SOMINCONN = 29;
1260
1261 pub const NOSUIDCOREDUMP = 32;
1262 pub const FSYNC = 33;
1263 pub const SYSVMSG = 34;
1264 pub const SYSVSEM = 35;
1265 pub const SYSVSHM = 36;
1266
1267 pub const MSGBUFSIZE = 38;
1268 pub const MALLOCSTATS = 39;
1269 pub const CPTIME = 40;
1270 pub const NCHSTATS = 41;
1271 pub const FORKSTAT = 42;
1272 pub const NSELCOLL = 43;
1273 pub const TTY = 44;
1274 pub const CCPU = 45;
1275 pub const FSCALE = 46;
1276 pub const NPROCS = 47;
1277 pub const MSGBUF = 48;
1278 pub const POOL = 49;
1279 pub const STACKGAPRANDOM = 50;
1280 pub const SYSVIPC_INFO = 51;
1281 pub const ALLOWKMEM = 52;
1282 pub const WITNESSWATCH = 53;
1283 pub const SPLASSERT = 54;
1284 pub const PROC_ARGS = 55;
1285 pub const NFILES = 56;
1286 pub const TTYCOUNT = 57;
1287 pub const NUMVNODES = 58;
1288 pub const MBSTAT = 59;
1289 pub const WITNESS = 60;
1290 pub const SEMINFO = 61;
1291 pub const SHMINFO = 62;
1292 pub const INTRCNT = 63;
1293 pub const WATCHDOG = 64;
1294 pub const ALLOWDT = 65;
1295 pub const PROC = 66;
1296 pub const MAXCLUSTERS = 67;
1297 pub const EVCOUNT = 68;
1298 pub const TIMECOUNTER = 69;
1299 pub const MAXLOCKSPERUID = 70;
1300 pub const CPTIME2 = 71;
1301 pub const CACHEPCT = 72;
1302 pub const FILE = 73;
1303 pub const WXABORT = 74;
1304 pub const CONSDEV = 75;
1305 pub const NETLIVELOCKS = 76;
1306 pub const POOL_DEBUG = 77;
1307 pub const PROC_CWD = 78;
1308 pub const PROC_NOBROADCASTKILL = 79;
1309 pub const PROC_VMMAP = 80;
1310 pub const GLOBAL_PTRACE = 81;
1311 pub const CONSBUFSIZE = 82;
1312 pub const CONSBUF = 83;
1313 pub const AUDIO = 84;
1314 pub const CPUSTATS = 85;
1315 pub const PFSTATUS = 86;
1316 pub const TIMEOUT_STATS = 87;
1317 pub const UTC_OFFSET = 88;
1318 pub const VIDEO = 89;
1319
1320 pub const PROC_ALL = 0;
1321 pub const PROC_PID = 1;
1322 pub const PROC_PGRP = 2;
1323 pub const PROC_SESSION = 3;
1324 pub const PROC_TTY = 4;
1325 pub const PROC_UID = 5;
1326 pub const PROC_RUID = 6;
1327 pub const PROC_KTHREAD = 7;
1328 pub const PROC_SHOW_THREADS = 0x40000000;
1329
1330 pub const PROC_ARGV = 1;
1331 pub const PROC_NARGV = 2;
1332 pub const PROC_ENV = 3;
1333 pub const PROC_NENV = 4;
1334};
1335
1336pub const HW_MACHINE = 1;
1337pub const HW_MODEL = 2;
1338pub const HW_NCPU = 3;
1339pub const HW_BYTEORDER = 4;
1340pub const HW_PHYSMEM = 5;
1341pub const HW_USERMEM = 6;
1342pub const HW_PAGESIZE = 7;
1343pub const HW_DISKNAMES = 8;
1344pub const HW_DISKSTATS = 9;
1345pub const HW_DISKCOUNT = 10;
1346pub const HW_SENSORS = 11;
1347pub const HW_CPUSPEED = 12;
1348pub const HW_SETPERF = 13;
1349pub const HW_VENDOR = 14;
1350pub const HW_PRODUCT = 15;
1351pub const HW_VERSION = 16;
1352pub const HW_SERIALNO = 17;
1353pub const HW_UUID = 18;
1354pub const HW_PHYSMEM64 = 19;
1355pub const HW_USERMEM64 = 20;
1356pub const HW_NCPUFOUND = 21;
1357pub const HW_ALLOWPOWERDOWN = 22;
1358pub const HW_PERFPOLICY = 23;
1359pub const HW_SMT = 24;
1360pub const HW_NCPUONLINE = 25;
lib/std/c/wasi.zig+47-2
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1usingnamespace @import("../os/bits.zig");1const std = @import("../std.zig");
2const wasi = std.os.wasi;
3const FDFLAG = wasi.FDFLAG;
24
3extern threadlocal var errno: c_int;5extern threadlocal var errno: c_int;
46
...@@ -6,12 +8,25 @@ pub fn _errno() *c_int {...@@ -6,12 +8,25 @@ pub fn _errno() *c_int {
6 return &errno;8 return &errno;
7}9}
810
11pub const fd_t = wasi.fd_t;
9pub const pid_t = c_int;12pub const pid_t = c_int;
10pub const uid_t = u32;13pub const uid_t = u32;
11pub const gid_t = u32;14pub const gid_t = u32;
12pub const off_t = i64;15pub const off_t = i64;
16pub const ino_t = wasi.ino_t;
17pub const mode_t = wasi.mode_t;
18pub const time_t = wasi.time_t;
19pub const timespec = wasi.timespec;
20pub const STDERR_FILENO = wasi.STDERR_FILENO;
21pub const STDIN_FILENO = wasi.STDIN_FILENO;
22pub const STDOUT_FILENO = wasi.STDOUT_FILENO;
23pub const E = wasi.E;
24pub const CLOCK = wasi.CLOCK;
25pub const S = wasi.S;
26pub const IOV_MAX = wasi.IOV_MAX;
27pub const AT = wasi.AT;
1328
14pub const libc_stat = extern struct {29pub const Stat = extern struct {
15 dev: i32,30 dev: i32,
16 ino: ino_t,31 ino: ino_t,
17 nlink: u64,32 nlink: u64,
...@@ -53,3 +68,33 @@ pub const libc_stat = extern struct {...@@ -53,3 +68,33 @@ pub const libc_stat = extern struct {
53 };68 };
54 }69 }
55};70};
71
72/// Derived from
73/// https://github.com/WebAssembly/wasi-libc/blob/main/expected/wasm32-wasi/predefined-macros.txt
74pub const O = struct {
75 pub const ACCMODE = (EXEC | RDWR | SEARCH);
76 pub const APPEND = FDFLAG.APPEND;
77 pub const CLOEXEC = (0);
78 pub const CREAT = ((1 << 0) << 12); // = __WASI_OFLAGS_CREAT << 12
79 pub const DIRECTORY = ((1 << 1) << 12); // = __WASI_OFLAGS_DIRECTORY << 12
80 pub const DSYNC = FDFLAG.DSYNC;
81 pub const EXCL = ((1 << 2) << 12); // = __WASI_OFLAGS_EXCL << 12
82 pub const EXEC = (0x02000000);
83 pub const NOCTTY = (0);
84 pub const NOFOLLOW = (0x01000000);
85 pub const NONBLOCK = (1 << FDFLAG.NONBLOCK);
86 pub const RDONLY = (0x04000000);
87 pub const RDWR = (RDONLY | WRONLY);
88 pub const RSYNC = (1 << FDFLAG.RSYNC);
89 pub const SEARCH = (0x08000000);
90 pub const SYNC = (1 << FDFLAG.SYNC);
91 pub const TRUNC = ((1 << 3) << 12); // = __WASI_OFLAGS_TRUNC << 12
92 pub const TTY_INIT = (0);
93 pub const WRONLY = (0x10000000);
94};
95
96pub const SEEK = struct {
97 pub const SET: wasi.whence_t = .SET;
98 pub const CUR: wasi.whence_t = .CUR;
99 pub const END: wasi.whence_t = .END;
100};
lib/std/c/windows.zig+244
...@@ -1,3 +1,247 @@...@@ -1,3 +1,247 @@
1//! The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime).
2const std = @import("../std.zig");
3const ws2_32 = std.os.windows.ws2_32;
4const windows = std.os.windows;
5
1pub extern "c" fn _errno() *c_int;6pub extern "c" fn _errno() *c_int;
27
3pub extern "c" fn _msize(memblock: ?*c_void) usize;8pub extern "c" fn _msize(memblock: ?*c_void) usize;
9
10// TODO: copied the else case and removed the socket function (because its in ws2_32)
11// need to verify which of these is actually supported on windows
12pub extern "c" fn clock_getres(clk_id: c_int, tp: *timespec) c_int;
13pub extern "c" fn clock_gettime(clk_id: c_int, tp: *timespec) c_int;
14pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int;
15pub extern "c" fn getrusage(who: c_int, usage: *rusage) c_int;
16pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
17pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;
18pub extern "c" fn sched_yield() c_int;
19pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
20pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
21pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *Stat) c_int;
22pub extern "c" fn sigfillset(set: ?*sigset_t) void;
23pub extern "c" fn alarm(seconds: c_uint) c_uint;
24pub extern "c" fn sigwait(set: ?*sigset_t, sig: ?*c_int) c_int;
25
26pub const fd_t = windows.HANDLE;
27pub const ino_t = windows.LARGE_INTEGER;
28pub const pid_t = windows.HANDLE;
29pub const mode_t = u0;
30
31pub const PATH_MAX = 260;
32
33pub const time_t = c_longlong;
34
35pub const timespec = extern struct {
36 tv_sec: time_t,
37 tv_nsec: c_long,
38};
39
40pub const timeval = extern struct {
41 tv_sec: c_long,
42 tv_usec: c_long,
43};
44
45pub const Stat = @compileError("TODO windows Stat definition");
46
47pub const sig_atomic_t = c_int;
48
49pub const sigset_t = @compileError("TODO windows sigset_t definition");
50pub const Sigaction = @compileError("TODO windows Sigaction definition");
51pub const timezone = @compileError("TODO windows timezone definition");
52pub const rusage = @compileError("TODO windows rusage definition");
53
54/// maximum signal number + 1
55pub const NSIG = 23;
56
57/// Signal types
58pub const SIG = struct {
59 /// interrupt
60 pub const INT = 2;
61 /// illegal instruction - invalid function image
62 pub const ILL = 4;
63 /// floating point exception
64 pub const FPE = 8;
65 /// segment violation
66 pub const SEGV = 11;
67 /// Software termination signal from kill
68 pub const TERM = 15;
69 /// Ctrl-Break sequence
70 pub const BREAK = 21;
71 /// abnormal termination triggered by abort call
72 pub const ABRT = 22;
73 /// SIGABRT compatible with other platforms, same as SIGABRT
74 pub const ABRT_COMPAT = 6;
75
76 // Signal action codes
77 /// default signal action
78 pub const DFL = 0;
79 /// ignore signal
80 pub const IGN = 1;
81 /// return current value
82 pub const GET = 2;
83 /// signal gets error
84 pub const SGE = 3;
85 /// acknowledge
86 pub const ACK = 4;
87 /// Signal error value (returned by signal call on error)
88 pub const ERR = -1;
89};
90
91pub const SEEK = struct {
92 pub const SET = 0;
93 pub const CUR = 1;
94 pub const END = 2;
95};
96
97pub const E = enum(u16) {
98 /// No error occurred.
99 SUCCESS = 0,
100 PERM = 1,
101 NOENT = 2,
102 SRCH = 3,
103 INTR = 4,
104 IO = 5,
105 NXIO = 6,
106 @"2BIG" = 7,
107 NOEXEC = 8,
108 BADF = 9,
109 CHILD = 10,
110 AGAIN = 11,
111 NOMEM = 12,
112 ACCES = 13,
113 FAULT = 14,
114 BUSY = 16,
115 EXIST = 17,
116 XDEV = 18,
117 NODEV = 19,
118 NOTDIR = 20,
119 ISDIR = 21,
120 NFILE = 23,
121 MFILE = 24,
122 NOTTY = 25,
123 FBIG = 27,
124 NOSPC = 28,
125 SPIPE = 29,
126 ROFS = 30,
127 MLINK = 31,
128 PIPE = 32,
129 DOM = 33,
130 /// Also means `DEADLOCK`.
131 DEADLK = 36,
132 NAMETOOLONG = 38,
133 NOLCK = 39,
134 NOSYS = 40,
135 NOTEMPTY = 41,
136
137 INVAL = 22,
138 RANGE = 34,
139 ILSEQ = 42,
140
141 // POSIX Supplement
142 ADDRINUSE = 100,
143 ADDRNOTAVAIL = 101,
144 AFNOSUPPORT = 102,
145 ALREADY = 103,
146 BADMSG = 104,
147 CANCELED = 105,
148 CONNABORTED = 106,
149 CONNREFUSED = 107,
150 CONNRESET = 108,
151 DESTADDRREQ = 109,
152 HOSTUNREACH = 110,
153 IDRM = 111,
154 INPROGRESS = 112,
155 ISCONN = 113,
156 LOOP = 114,
157 MSGSIZE = 115,
158 NETDOWN = 116,
159 NETRESET = 117,
160 NETUNREACH = 118,
161 NOBUFS = 119,
162 NODATA = 120,
163 NOLINK = 121,
164 NOMSG = 122,
165 NOPROTOOPT = 123,
166 NOSR = 124,
167 NOSTR = 125,
168 NOTCONN = 126,
169 NOTRECOVERABLE = 127,
170 NOTSOCK = 128,
171 NOTSUP = 129,
172 OPNOTSUPP = 130,
173 OTHER = 131,
174 OVERFLOW = 132,
175 OWNERDEAD = 133,
176 PROTO = 134,
177 PROTONOSUPPORT = 135,
178 PROTOTYPE = 136,
179 TIME = 137,
180 TIMEDOUT = 138,
181 TXTBSY = 139,
182 WOULDBLOCK = 140,
183 DQUOT = 10069,
184 _,
185};
186
187pub const STRUNCATE = 80;
188
189pub const F_OK = 0;
190
191/// Remove directory instead of unlinking file
192pub const AT = struct {
193 pub const REMOVEDIR = 0x200;
194};
195
196pub const in_port_t = u16;
197pub const sa_family_t = ws2_32.ADDRESS_FAMILY;
198pub const socklen_t = ws2_32.socklen_t;
199
200pub const sockaddr = ws2_32.sockaddr;
201
202pub const in6_addr = [16]u8;
203pub const in_addr = u32;
204
205pub const addrinfo = ws2_32.addrinfo;
206pub const AF = ws2_32.AF;
207pub const MSG = ws2_32.MSG;
208pub const SOCK = ws2_32.SOCK;
209pub const TCP = ws2_32.TCP;
210pub const IPPROTO = ws2_32.IPPROTO;
211pub const BTHPROTO_RFCOMM = ws2_32.BTHPROTO_RFCOMM;
212
213pub const nfds_t = c_ulong;
214pub const pollfd = ws2_32.pollfd;
215pub const POLL = ws2_32.POLL;
216pub const SOL = ws2_32.SOL;
217pub const SO = ws2_32.SO;
218pub const PVD_CONFIG = ws2_32.PVD_CONFIG;
219
220pub const O = struct {
221 pub const RDONLY = 0o0;
222 pub const WRONLY = 0o1;
223 pub const RDWR = 0o2;
224
225 pub const CREAT = 0o100;
226 pub const EXCL = 0o200;
227 pub const NOCTTY = 0o400;
228 pub const TRUNC = 0o1000;
229 pub const APPEND = 0o2000;
230 pub const NONBLOCK = 0o4000;
231 pub const DSYNC = 0o10000;
232 pub const SYNC = 0o4010000;
233 pub const RSYNC = 0o4010000;
234 pub const DIRECTORY = 0o200000;
235 pub const NOFOLLOW = 0o400000;
236 pub const CLOEXEC = 0o2000000;
237
238 pub const ASYNC = 0o20000;
239 pub const DIRECT = 0o40000;
240 pub const LARGEFILE = 0;
241 pub const NOATIME = 0o1000000;
242 pub const PATH = 0o10000000;
243 pub const TMPFILE = 0o20200000;
244 pub const NDELAY = NONBLOCK;
245};
246
247pub const IFNAMESIZE = 30;
lib/std/child_process.zig+20-19
...@@ -7,6 +7,7 @@ const os = std.os;...@@ -7,6 +7,7 @@ const os = std.os;
7const process = std.process;7const process = std.process;
8const File = std.fs.File;8const File = std.fs.File;
9const windows = os.windows;9const windows = os.windows;
10const linux = os.linux;
10const mem = std.mem;11const mem = std.mem;
11const math = std.math;12const math = std.math;
12const debug = std.debug;13const debug = std.debug;
...@@ -160,7 +161,7 @@ pub const ChildProcess = struct {...@@ -160,7 +161,7 @@ pub const ChildProcess = struct {
160 self.cleanupStreams();161 self.cleanupStreams();
161 return term;162 return term;
162 }163 }
163 try os.kill(self.pid, os.SIGTERM);164 try os.kill(self.pid, os.SIG.TERM);
164 self.waitUnwrapped();165 self.waitUnwrapped();
165 return self.term.?;166 return self.term.?;
166 }167 }
...@@ -189,8 +190,8 @@ pub const ChildProcess = struct {...@@ -189,8 +190,8 @@ pub const ChildProcess = struct {
189 max_output_bytes: usize,190 max_output_bytes: usize,
190 ) !void {191 ) !void {
191 var poll_fds = [_]os.pollfd{192 var poll_fds = [_]os.pollfd{
192 .{ .fd = child.stdout.?.handle, .events = os.POLLIN, .revents = undefined },193 .{ .fd = child.stdout.?.handle, .events = os.POLL.IN, .revents = undefined },
193 .{ .fd = child.stderr.?.handle, .events = os.POLLIN, .revents = undefined },194 .{ .fd = child.stderr.?.handle, .events = os.POLL.IN, .revents = undefined },
194 };195 };
195196
196 var dead_fds: usize = 0;197 var dead_fds: usize = 0;
...@@ -199,7 +200,7 @@ pub const ChildProcess = struct {...@@ -199,7 +200,7 @@ pub const ChildProcess = struct {
199 // of space an ArrayList will allocate grows exponentially.200 // of space an ArrayList will allocate grows exponentially.
200 const bump_amt = 512;201 const bump_amt = 512;
201202
202 const err_mask = os.POLLERR | os.POLLNVAL | os.POLLHUP;203 const err_mask = os.POLL.ERR | os.POLL.NVAL | os.POLL.HUP;
203204
204 while (dead_fds < poll_fds.len) {205 while (dead_fds < poll_fds.len) {
205 const events = try os.poll(&poll_fds, std.math.maxInt(i32));206 const events = try os.poll(&poll_fds, std.math.maxInt(i32));
...@@ -209,9 +210,9 @@ pub const ChildProcess = struct {...@@ -209,9 +210,9 @@ pub const ChildProcess = struct {
209 var remove_stderr = false;210 var remove_stderr = false;
210 // Try reading whatever is available before checking the error211 // Try reading whatever is available before checking the error
211 // conditions.212 // conditions.
212 // It's still possible to read after a POLLHUP is received, always213 // It's still possible to read after a POLL.HUP is received, always
213 // check if there's some data waiting to be read first.214 // check if there's some data waiting to be read first.
214 if (poll_fds[0].revents & os.POLLIN != 0) {215 if (poll_fds[0].revents & os.POLL.IN != 0) {
215 // stdout is ready.216 // stdout is ready.
216 const new_capacity = std.math.min(stdout.items.len + bump_amt, max_output_bytes);217 const new_capacity = std.math.min(stdout.items.len + bump_amt, max_output_bytes);
217 try stdout.ensureCapacity(new_capacity);218 try stdout.ensureCapacity(new_capacity);
...@@ -226,7 +227,7 @@ pub const ChildProcess = struct {...@@ -226,7 +227,7 @@ pub const ChildProcess = struct {
226 remove_stdout = poll_fds[0].revents & err_mask != 0;227 remove_stdout = poll_fds[0].revents & err_mask != 0;
227 }228 }
228229
229 if (poll_fds[1].revents & os.POLLIN != 0) {230 if (poll_fds[1].revents & os.POLL.IN != 0) {
230 // stderr is ready.231 // stderr is ready.
231 const new_capacity = std.math.min(stderr.items.len + bump_amt, max_output_bytes);232 const new_capacity = std.math.min(stderr.items.len + bump_amt, max_output_bytes);
232 try stderr.ensureCapacity(new_capacity);233 try stderr.ensureCapacity(new_capacity);
...@@ -461,7 +462,7 @@ pub const ChildProcess = struct {...@@ -461,7 +462,7 @@ pub const ChildProcess = struct {
461 if (builtin.os.tag == .linux) {462 if (builtin.os.tag == .linux) {
462 var fd = [1]std.os.pollfd{std.os.pollfd{463 var fd = [1]std.os.pollfd{std.os.pollfd{
463 .fd = self.err_pipe[0],464 .fd = self.err_pipe[0],
464 .events = std.os.POLLIN,465 .events = std.os.POLL.IN,
465 .revents = undefined,466 .revents = undefined,
466 }};467 }};
467468
...@@ -471,7 +472,7 @@ pub const ChildProcess = struct {...@@ -471,7 +472,7 @@ pub const ChildProcess = struct {
471472
472 // According to eventfd(2) the descriptro is readable if the counter473 // According to eventfd(2) the descriptro is readable if the counter
473 // has a value greater than 0474 // has a value greater than 0
474 if ((fd[0].revents & std.os.POLLIN) != 0) {475 if ((fd[0].revents & std.os.POLL.IN) != 0) {
475 const err_int = try readIntFd(self.err_pipe[0]);476 const err_int = try readIntFd(self.err_pipe[0]);
476 return @errSetCast(SpawnError, @intToError(err_int));477 return @errSetCast(SpawnError, @intToError(err_int));
477 }478 }
...@@ -494,18 +495,18 @@ pub const ChildProcess = struct {...@@ -494,18 +495,18 @@ pub const ChildProcess = struct {
494 }495 }
495496
496 fn statusToTerm(status: u32) Term {497 fn statusToTerm(status: u32) Term {
497 return if (os.WIFEXITED(status))498 return if (os.W.IFEXITED(status))
498 Term{ .Exited = os.WEXITSTATUS(status) }499 Term{ .Exited = os.W.EXITSTATUS(status) }
499 else if (os.WIFSIGNALED(status))500 else if (os.W.IFSIGNALED(status))
500 Term{ .Signal = os.WTERMSIG(status) }501 Term{ .Signal = os.W.TERMSIG(status) }
501 else if (os.WIFSTOPPED(status))502 else if (os.W.IFSTOPPED(status))
502 Term{ .Stopped = os.WSTOPSIG(status) }503 Term{ .Stopped = os.W.STOPSIG(status) }
503 else504 else
504 Term{ .Unknown = status };505 Term{ .Unknown = status };
505 }506 }
506507
507 fn spawnPosix(self: *ChildProcess) SpawnError!void {508 fn spawnPosix(self: *ChildProcess) SpawnError!void {
508 const pipe_flags = if (io.is_async) os.O_NONBLOCK else 0;509 const pipe_flags = if (io.is_async) os.O.NONBLOCK else 0;
509 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;510 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
510 errdefer if (self.stdin_behavior == StdIo.Pipe) {511 errdefer if (self.stdin_behavior == StdIo.Pipe) {
511 destroyPipe(stdin_pipe);512 destroyPipe(stdin_pipe);
...@@ -523,7 +524,7 @@ pub const ChildProcess = struct {...@@ -523,7 +524,7 @@ pub const ChildProcess = struct {
523524
524 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);525 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
525 const dev_null_fd = if (any_ignore)526 const dev_null_fd = if (any_ignore)
526 os.openZ("/dev/null", os.O_RDWR, 0) catch |err| switch (err) {527 os.openZ("/dev/null", os.O.RDWR, 0) catch |err| switch (err) {
527 error.PathAlreadyExists => unreachable,528 error.PathAlreadyExists => unreachable,
528 error.NoSpaceLeft => unreachable,529 error.NoSpaceLeft => unreachable,
529 error.FileTooBig => unreachable,530 error.FileTooBig => unreachable,
...@@ -575,12 +576,12 @@ pub const ChildProcess = struct {...@@ -575,12 +576,12 @@ pub const ChildProcess = struct {
575 // and execve from the child process to the parent process.576 // and execve from the child process to the parent process.
576 const err_pipe = blk: {577 const err_pipe = blk: {
577 if (builtin.os.tag == .linux) {578 if (builtin.os.tag == .linux) {
578 const fd = try os.eventfd(0, os.EFD_CLOEXEC);579 const fd = try os.eventfd(0, linux.EFD.CLOEXEC);
579 // There's no distinction between the readable and the writeable580 // There's no distinction between the readable and the writeable
580 // end with eventfd581 // end with eventfd
581 break :blk [2]os.fd_t{ fd, fd };582 break :blk [2]os.fd_t{ fd, fd };
582 } else {583 } else {
583 break :blk try os.pipe2(os.O_CLOEXEC);584 break :blk try os.pipe2(os.O.CLOEXEC);
584 }585 }
585 };586 };
586 errdefer destroyPipe(err_pipe);587 errdefer destroyPipe(err_pipe);
lib/std/crypto.zig+3-1
...@@ -109,9 +109,11 @@ pub const pwhash = struct {...@@ -109,9 +109,11 @@ pub const pwhash = struct {
109 crypt,109 crypt,
110 };110 };
111 pub const KdfError = errors.Error || std.mem.Allocator.Error;111 pub const KdfError = errors.Error || std.mem.Allocator.Error;
112 pub const HasherError = KdfError || @import("crypto/phc_encoding.zig").Error;112 pub const HasherError = KdfError || phc_format.Error;
113 pub const Error = HasherError || error{AllocatorRequired};113 pub const Error = HasherError || error{AllocatorRequired};
114114
115 pub const phc_format = @import("crypto/phc_encoding.zig");
116
115 pub const bcrypt = @import("crypto/bcrypt.zig");117 pub const bcrypt = @import("crypto/bcrypt.zig");
116 pub const scrypt = @import("crypto/scrypt.zig");118 pub const scrypt = @import("crypto/scrypt.zig");
117 pub const pbkdf2 = @import("crypto/pbkdf2.zig").pbkdf2;119 pub const pbkdf2 = @import("crypto/pbkdf2.zig").pbkdf2;
lib/std/crypto/25519/curve25519.zig+1-3
...@@ -40,9 +40,7 @@ pub const Curve25519 = struct {...@@ -40,9 +40,7 @@ pub const Curve25519 = struct {
40 }40 }
4141
42 /// Multiply a point by the cofactor42 /// Multiply a point by the cofactor
43 pub fn clearCofactor(p: Edwards25519) Edwards25519 {43 pub const clearCofactor = @compileError("TODO what was this function supposed to do? it didn't compile successfully");
44 return p.dbl().dbl().dbl();
45 }
4644
47 fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) IdentityElementError!Curve25519 {45 fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) IdentityElementError!Curve25519 {
48 var x1 = p.x;46 var x1 = p.x;
lib/std/crypto/benchmark.zig+7-3
...@@ -300,10 +300,14 @@ const CryptoPwhash = struct {...@@ -300,10 +300,14 @@ const CryptoPwhash = struct {
300 params: anytype,300 params: anytype,
301 name: []const u8,301 name: []const u8,
302};302};
303const bcrypt_params = bcrypt.Params{ .rounds_log = 5 };303const bcrypt_params = crypto.pwhash.bcrypt.Params{ .rounds_log = 12 };
304const pwhashes = [_]CryptoPwhash{304const pwhashes = [_]CryptoPwhash{
305 CryptoPwhash{ .hashFn = bcrypt.strHash, .params = bcrypt_params, .name = "bcrypt" },305 .{ .hashFn = crypto.pwhash.bcrypt.strHash, .params = bcrypt_params, .name = "bcrypt" },
306 CryptoPwhash{ .hashFn = scrypt.strHash, .params = scrypt.Params.interactive, .name = "scrypt" },306 .{
307 .hashFn = crypto.pwhash.scrypt.strHash,
308 .params = crypto.pwhash.scrypt.Params.interactive,
309 .name = "scrypt",
310 },
307};311};
308312
309fn benchmarkPwhash(313fn benchmarkPwhash(
lib/std/crypto/pcurves/p256/p256_scalar_64.zig+2-2
...@@ -1766,7 +1766,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[...@@ -1766,7 +1766,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[
1766 var x1: u64 = undefined;1766 var x1: u64 = undefined;
1767 var x2: u1 = undefined;1767 var x2: u1 = undefined;
1768 addcarryxU64(&x1, &x2, 0x0, (~arg1), @as(u64, 0x1));1768 addcarryxU64(&x1, &x2, 0x0, (~arg1), @as(u64, 0x1));
1769 const x3 = (@as(u1, (x1 >> 63)) & @as(u1, ((arg3[0]) & @as(u64, 0x1))));1769 const x3 = @truncate(u1, (x1 >> 63)) & @truncate(u1, ((arg3[0]) & @as(u64, 0x1)));
1770 var x4: u64 = undefined;1770 var x4: u64 = undefined;
1771 var x5: u1 = undefined;1771 var x5: u1 = undefined;
1772 addcarryxU64(&x4, &x5, 0x0, (~arg1), @as(u64, 0x1));1772 addcarryxU64(&x4, &x5, 0x0, (~arg1), @as(u64, 0x1));
...@@ -1880,7 +1880,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[...@@ -1880,7 +1880,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[
1880 cmovznzU64(&x72, x3, (arg5[2]), x66);1880 cmovznzU64(&x72, x3, (arg5[2]), x66);
1881 var x73: u64 = undefined;1881 var x73: u64 = undefined;
1882 cmovznzU64(&x73, x3, (arg5[3]), x68);1882 cmovznzU64(&x73, x3, (arg5[3]), x68);
1883 const x74 = @as(u1, (x22 & @as(u64, 0x1)));1883 const x74 = @truncate(u1, (x22 & @as(u64, 0x1)));
1884 var x75: u64 = undefined;1884 var x75: u64 = undefined;
1885 cmovznzU64(&x75, x74, @as(u64, 0x0), x7);1885 cmovznzU64(&x75, x74, @as(u64, 0x0), x7);
1886 var x76: u64 = undefined;1886 var x76: u64 = undefined;
lib/std/crypto/pcurves/tests.zig+13
...@@ -111,3 +111,16 @@ test "p256 double base multiplication" {...@@ -111,3 +111,16 @@ test "p256 double base multiplication" {
111 const pr2 = (try p1.mul(s1, .Little)).add(try p2.mul(s2, .Little));111 const pr2 = (try p1.mul(s1, .Little)).add(try p2.mul(s2, .Little));
112 try testing.expect(pr1.equivalent(pr2));112 try testing.expect(pr1.equivalent(pr2));
113}113}
114
115test "p256 scalar inverse" {
116 const expected = "3b549196a13c898a6f6e84dfb3a22c40a8b9b17fb88e408ea674e451cd01d0a6";
117 var out: [32]u8 = undefined;
118 _ = try std.fmt.hexToBytes(&out, expected);
119
120 const scalar = try P256.scalar.Scalar.fromBytes(.{
121 0x94, 0xa1, 0xbb, 0xb1, 0x4b, 0x90, 0x6a, 0x61, 0xa2, 0x80, 0xf2, 0x45, 0xf9, 0xe9, 0x3c, 0x7f,
122 0x3b, 0x4a, 0x62, 0x47, 0x82, 0x4f, 0x5d, 0x33, 0xb9, 0x67, 0x07, 0x87, 0x64, 0x2a, 0x68, 0xde,
123 }, .Big);
124 const inverse = scalar.invert();
125 try std.testing.expectEqualSlices(u8, &out, &inverse.toBytes(.Big));
126}
lib/std/crypto/scrypt.zig+27-13
...@@ -523,7 +523,12 @@ pub fn strVerify(...@@ -523,7 +523,12 @@ pub fn strVerify(
523 }523 }
524}524}
525525
526test "scrypt kdf" {526// These tests take way too long to run, so I have disabled them.
527const run_long_tests = false;
528
529test "kdf" {
530 if (!run_long_tests) return error.SkipZigTest;
531
527 const password = "testpass";532 const password = "testpass";
528 const salt = "saltsalt";533 const salt = "saltsalt";
529534
...@@ -537,7 +542,9 @@ test "scrypt kdf" {...@@ -537,7 +542,9 @@ test "scrypt kdf" {
537 try std.testing.expectEqualSlices(u8, &bytes, &dk);542 try std.testing.expectEqualSlices(u8, &bytes, &dk);
538}543}
539544
540test "scrypt kdf rfc 1" {545test "kdf rfc 1" {
546 if (!run_long_tests) return error.SkipZigTest;
547
541 const password = "";548 const password = "";
542 const salt = "";549 const salt = "";
543550
...@@ -551,7 +558,9 @@ test "scrypt kdf rfc 1" {...@@ -551,7 +558,9 @@ test "scrypt kdf rfc 1" {
551 try std.testing.expectEqualSlices(u8, &bytes, &dk);558 try std.testing.expectEqualSlices(u8, &bytes, &dk);
552}559}
553560
554test "scrypt kdf rfc 2" {561test "kdf rfc 2" {
562 if (!run_long_tests) return error.SkipZigTest;
563
555 const password = "password";564 const password = "password";
556 const salt = "NaCl";565 const salt = "NaCl";
557566
...@@ -565,7 +574,9 @@ test "scrypt kdf rfc 2" {...@@ -565,7 +574,9 @@ test "scrypt kdf rfc 2" {
565 try std.testing.expectEqualSlices(u8, &bytes, &dk);574 try std.testing.expectEqualSlices(u8, &bytes, &dk);
566}575}
567576
568test "scrypt kdf rfc 3" {577test "kdf rfc 3" {
578 if (!run_long_tests) return error.SkipZigTest;
579
569 const password = "pleaseletmein";580 const password = "pleaseletmein";
570 const salt = "SodiumChloride";581 const salt = "SodiumChloride";
571582
...@@ -579,11 +590,8 @@ test "scrypt kdf rfc 3" {...@@ -579,11 +590,8 @@ test "scrypt kdf rfc 3" {
579 try std.testing.expectEqualSlices(u8, &bytes, &dk);590 try std.testing.expectEqualSlices(u8, &bytes, &dk);
580}591}
581592
582test "scrypt kdf rfc 4" {593test "kdf rfc 4" {
583 // skip slow test594 if (!run_long_tests) return error.SkipZigTest;
584 if (true) {
585 return error.SkipZigTest;
586 }
587595
588 const password = "pleaseletmein";596 const password = "pleaseletmein";
589 const salt = "SodiumChloride";597 const salt = "SodiumChloride";
...@@ -598,7 +606,9 @@ test "scrypt kdf rfc 4" {...@@ -598,7 +606,9 @@ test "scrypt kdf rfc 4" {
598 try std.testing.expectEqualSlices(u8, &bytes, &dk);606 try std.testing.expectEqualSlices(u8, &bytes, &dk);
599}607}
600608
601test "scrypt password hashing (crypt format)" {609test "password hashing (crypt format)" {
610 if (!run_long_tests) return error.SkipZigTest;
611
602 const str = "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5";612 const str = "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5";
603 const password = "Y0!?iQa9M%5ekffW(`";613 const password = "Y0!?iQa9M%5ekffW(`";
604 try CryptFormatHasher.verify(std.testing.allocator, str, password);614 try CryptFormatHasher.verify(std.testing.allocator, str, password);
...@@ -609,7 +619,9 @@ test "scrypt password hashing (crypt format)" {...@@ -609,7 +619,9 @@ test "scrypt password hashing (crypt format)" {
609 try CryptFormatHasher.verify(std.testing.allocator, str2, password);619 try CryptFormatHasher.verify(std.testing.allocator, str2, password);
610}620}
611621
612test "scrypt strHash and strVerify" {622test "strHash and strVerify" {
623 if (!run_long_tests) return error.SkipZigTest;
624
613 const alloc = std.testing.allocator;625 const alloc = std.testing.allocator;
614626
615 const password = "testpass";627 const password = "testpass";
...@@ -631,7 +643,9 @@ test "scrypt strHash and strVerify" {...@@ -631,7 +643,9 @@ test "scrypt strHash and strVerify" {
631 try strVerify(s1, password, verify_options);643 try strVerify(s1, password, verify_options);
632}644}
633645
634test "scrypt unix-scrypt" {646test "unix-scrypt" {
647 if (!run_long_tests) return error.SkipZigTest;
648
635 const alloc = std.testing.allocator;649 const alloc = std.testing.allocator;
636650
637 // https://gitlab.com/jas/scrypt-unix-crypt/blob/master/unix-scrypt.txt651 // https://gitlab.com/jas/scrypt-unix-crypt/blob/master/unix-scrypt.txt
...@@ -648,7 +662,7 @@ test "scrypt unix-scrypt" {...@@ -648,7 +662,7 @@ test "scrypt unix-scrypt" {
648 }662 }
649}663}
650664
651test "scrypt crypt format" {665test "crypt format" {
652 const str = "$7$C6..../....SodiumChloride$kBGj9fHznVYFQMEn/qDCfrDevf9YDtcDdKvEqHJLV8D";666 const str = "$7$C6..../....SodiumChloride$kBGj9fHznVYFQMEn/qDCfrDevf9YDtcDdKvEqHJLV8D";
653 const params = try crypt_format.deserialize(crypt_format.HashResult(32), str);667 const params = try crypt_format.deserialize(crypt_format.HashResult(32), str);
654 var buf: [str.len]u8 = undefined;668 var buf: [str.len]u8 = undefined;
lib/std/crypto/tlcsprng.zig+3-3
...@@ -74,8 +74,8 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {...@@ -74,8 +74,8 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {
74 wipe_mem = os.mmap(74 wipe_mem = os.mmap(
75 null,75 null,
76 @sizeOf(Context),76 @sizeOf(Context),
77 os.PROT_READ | os.PROT_WRITE,77 os.PROT.READ | os.PROT.WRITE,
78 os.MAP_PRIVATE | os.MAP_ANONYMOUS,78 os.MAP.PRIVATE | os.MAP.ANONYMOUS,
79 -1,79 -1,
80 0,80 0,
81 ) catch {81 ) catch {
...@@ -111,7 +111,7 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {...@@ -111,7 +111,7 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {
111 break :wof;111 break :wof;
112 } else |_| {}112 } else |_| {}
113113
114 if (os.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV_WIPEONFORK)) |_| {114 if (os.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV.WIPEONFORK)) |_| {
115 return initAndFill(buffer);115 return initAndFill(buffer);
116 } else |_| {}116 } else |_| {}
117 }117 }
lib/std/debug.zig+20-20
...@@ -948,8 +948,8 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {...@@ -948,8 +948,8 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
948 const mapped_mem = try os.mmap(948 const mapped_mem = try os.mmap(
949 null,949 null,
950 file_len,950 file_len,
951 os.PROT_READ,951 os.PROT.READ,
952 os.MAP_SHARED,952 os.MAP.SHARED,
953 file.handle,953 file.handle,
954 0,954 0,
955 );955 );
...@@ -1341,7 +1341,7 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1341,7 +1341,7 @@ pub const ModuleDebugInfo = switch (native_os) {
1341 if (o_file_di.findCompileUnit(relocated_address_o)) |compile_unit| {1341 if (o_file_di.findCompileUnit(relocated_address_o)) |compile_unit| {
1342 return SymbolInfo{1342 return SymbolInfo{
1343 .symbol_name = o_file_di.getSymbolName(relocated_address_o) orelse "???",1343 .symbol_name = o_file_di.getSymbolName(relocated_address_o) orelse "???",
1344 .compile_unit_name = compile_unit.die.getAttrString(&o_file_di, DW.AT_name) catch |err| switch (err) {1344 .compile_unit_name = compile_unit.die.getAttrString(&o_file_di, DW.AT.name) catch |err| switch (err) {
1345 error.MissingDebugInfo, error.InvalidDebugInfo => "???",1345 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
1346 else => return err,1346 else => return err,
1347 },1347 },
...@@ -1438,7 +1438,7 @@ fn getSymbolFromDwarf(address: u64, di: *DW.DwarfInfo) !SymbolInfo {...@@ -1438,7 +1438,7 @@ fn getSymbolFromDwarf(address: u64, di: *DW.DwarfInfo) !SymbolInfo {
1438 if (nosuspend di.findCompileUnit(address)) |compile_unit| {1438 if (nosuspend di.findCompileUnit(address)) |compile_unit| {
1439 return SymbolInfo{1439 return SymbolInfo{
1440 .symbol_name = nosuspend di.getSymbolName(address) orelse "???",1440 .symbol_name = nosuspend di.getSymbolName(address) orelse "???",
1441 .compile_unit_name = compile_unit.die.getAttrString(di, DW.AT_name) catch |err| switch (err) {1441 .compile_unit_name = compile_unit.die.getAttrString(di, DW.AT.name) catch |err| switch (err) {
1442 error.MissingDebugInfo, error.InvalidDebugInfo => "???",1442 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
1443 else => return err,1443 else => return err,
1444 },1444 },
...@@ -1470,7 +1470,7 @@ fn getDebugInfoAllocator() *mem.Allocator {...@@ -1470,7 +1470,7 @@ fn getDebugInfoAllocator() *mem.Allocator {
1470pub const have_segfault_handling_support = switch (native_os) {1470pub const have_segfault_handling_support = switch (native_os) {
1471 .linux, .netbsd => true,1471 .linux, .netbsd => true,
1472 .windows => true,1472 .windows => true,
1473 .freebsd, .openbsd => @hasDecl(os, "ucontext_t"),1473 .freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
1474 else => false,1474 else => false,
1475};1475};
1476pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))1476pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))
...@@ -1498,12 +1498,12 @@ pub fn attachSegfaultHandler() void {...@@ -1498,12 +1498,12 @@ pub fn attachSegfaultHandler() void {
1498 var act = os.Sigaction{1498 var act = os.Sigaction{
1499 .handler = .{ .sigaction = handleSegfaultLinux },1499 .handler = .{ .sigaction = handleSegfaultLinux },
1500 .mask = os.empty_sigset,1500 .mask = os.empty_sigset,
1501 .flags = (os.SA_SIGINFO | os.SA_RESTART | os.SA_RESETHAND),1501 .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
1502 };1502 };
15031503
1504 os.sigaction(os.SIGSEGV, &act, null);1504 os.sigaction(os.SIG.SEGV, &act, null);
1505 os.sigaction(os.SIGILL, &act, null);1505 os.sigaction(os.SIG.ILL, &act, null);
1506 os.sigaction(os.SIGBUS, &act, null);1506 os.sigaction(os.SIG.BUS, &act, null);
1507}1507}
15081508
1509fn resetSegfaultHandler() void {1509fn resetSegfaultHandler() void {
...@@ -1515,13 +1515,13 @@ fn resetSegfaultHandler() void {...@@ -1515,13 +1515,13 @@ fn resetSegfaultHandler() void {
1515 return;1515 return;
1516 }1516 }
1517 var act = os.Sigaction{1517 var act = os.Sigaction{
1518 .handler = .{ .sigaction = os.SIG_DFL },1518 .handler = .{ .sigaction = os.SIG.DFL },
1519 .mask = os.empty_sigset,1519 .mask = os.empty_sigset,
1520 .flags = 0,1520 .flags = 0,
1521 };1521 };
1522 os.sigaction(os.SIGSEGV, &act, null);1522 os.sigaction(os.SIG.SEGV, &act, null);
1523 os.sigaction(os.SIGILL, &act, null);1523 os.sigaction(os.SIG.ILL, &act, null);
1524 os.sigaction(os.SIGBUS, &act, null);1524 os.sigaction(os.SIG.BUS, &act, null);
1525}1525}
15261526
1527fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_void) callconv(.C) noreturn {1527fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_void) callconv(.C) noreturn {
...@@ -1542,9 +1542,9 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v...@@ -1542,9 +1542,9 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
1542 nosuspend {1542 nosuspend {
1543 const stderr = io.getStdErr().writer();1543 const stderr = io.getStdErr().writer();
1544 _ = switch (sig) {1544 _ = switch (sig) {
1545 os.SIGSEGV => stderr.print("Segmentation fault at address 0x{x}\n", .{addr}),1545 os.SIG.SEGV => stderr.print("Segmentation fault at address 0x{x}\n", .{addr}),
1546 os.SIGILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),1546 os.SIG.ILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),
1547 os.SIGBUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),1547 os.SIG.BUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),
1548 else => unreachable,1548 else => unreachable,
1549 } catch os.abort();1549 } catch os.abort();
1550 }1550 }
...@@ -1552,20 +1552,20 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v...@@ -1552,20 +1552,20 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
1552 switch (native_arch) {1552 switch (native_arch) {
1553 .i386 => {1553 .i386 => {
1554 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));1554 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
1555 const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_EIP]);1555 const ip = @intCast(usize, ctx.mcontext.gregs[os.REG.EIP]);
1556 const bp = @intCast(usize, ctx.mcontext.gregs[os.REG_EBP]);1556 const bp = @intCast(usize, ctx.mcontext.gregs[os.REG.EBP]);
1557 dumpStackTraceFromBase(bp, ip);1557 dumpStackTraceFromBase(bp, ip);
1558 },1558 },
1559 .x86_64 => {1559 .x86_64 => {
1560 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));1560 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
1561 const ip = switch (native_os) {1561 const ip = switch (native_os) {
1562 .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]),1562 .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG.RIP]),
1563 .freebsd => @intCast(usize, ctx.mcontext.rip),1563 .freebsd => @intCast(usize, ctx.mcontext.rip),
1564 .openbsd => @intCast(usize, ctx.sc_rip),1564 .openbsd => @intCast(usize, ctx.sc_rip),
1565 else => unreachable,1565 else => unreachable,
1566 };1566 };
1567 const bp = switch (native_os) {1567 const bp = switch (native_os) {
1568 .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG_RBP]),1568 .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG.RBP]),
1569 .openbsd => @intCast(usize, ctx.sc_rbp),1569 .openbsd => @intCast(usize, ctx.sc_rbp),
1570 .freebsd => @intCast(usize, ctx.mcontext.rbp),1570 .freebsd => @intCast(usize, ctx.mcontext.rbp),
1571 else => unreachable,1571 else => unreachable,
lib/std/dwarf.zig+277-61
...@@ -9,7 +9,223 @@ const leb = @import("leb128.zig");...@@ -9,7 +9,223 @@ const leb = @import("leb128.zig");
99
10const ArrayList = std.ArrayList;10const ArrayList = std.ArrayList;
1111
12pub usingnamespace @import("dwarf_bits.zig");12pub const TAG = @import("dwarf/TAG.zig");
13pub const AT = @import("dwarf/AT.zig");
14pub const OP = @import("dwarf/OP.zig");
15
16pub const FORM = struct {
17 pub const addr = 0x01;
18 pub const block2 = 0x03;
19 pub const block4 = 0x04;
20 pub const data2 = 0x05;
21 pub const data4 = 0x06;
22 pub const data8 = 0x07;
23 pub const string = 0x08;
24 pub const block = 0x09;
25 pub const block1 = 0x0a;
26 pub const data1 = 0x0b;
27 pub const flag = 0x0c;
28 pub const sdata = 0x0d;
29 pub const strp = 0x0e;
30 pub const udata = 0x0f;
31 pub const ref_addr = 0x10;
32 pub const ref1 = 0x11;
33 pub const ref2 = 0x12;
34 pub const ref4 = 0x13;
35 pub const ref8 = 0x14;
36 pub const ref_udata = 0x15;
37 pub const indirect = 0x16;
38 pub const sec_offset = 0x17;
39 pub const exprloc = 0x18;
40 pub const flag_present = 0x19;
41 pub const ref_sig8 = 0x20;
42
43 // Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
44 pub const GNU_addr_index = 0x1f01;
45 pub const GNU_str_index = 0x1f02;
46
47 // Extensions for DWZ multifile.
48 // See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open .
49 pub const GNU_ref_alt = 0x1f20;
50 pub const GNU_strp_alt = 0x1f21;
51};
52
53pub const ATE = struct {
54 pub const @"void" = 0x0;
55 pub const address = 0x1;
56 pub const boolean = 0x2;
57 pub const complex_float = 0x3;
58 pub const float = 0x4;
59 pub const signed = 0x5;
60 pub const signed_char = 0x6;
61 pub const unsigned = 0x7;
62 pub const unsigned_char = 0x8;
63
64 // DWARF 3.
65 pub const imaginary_float = 0x9;
66 pub const packed_decimal = 0xa;
67 pub const numeric_string = 0xb;
68 pub const edited = 0xc;
69 pub const signed_fixed = 0xd;
70 pub const unsigned_fixed = 0xe;
71 pub const decimal_float = 0xf;
72
73 // DWARF 4.
74 pub const UTF = 0x10;
75
76 pub const lo_user = 0x80;
77 pub const hi_user = 0xff;
78
79 // HP extensions.
80 pub const HP_float80 = 0x80; // Floating-point (80 bit).
81 pub const HP_complex_float80 = 0x81; // Complex floating-point (80 bit).
82 pub const HP_float128 = 0x82; // Floating-point (128 bit).
83 pub const HP_complex_float128 = 0x83; // Complex fp (128 bit).
84 pub const HP_floathpintel = 0x84; // Floating-point (82 bit IA64).
85 pub const HP_imaginary_float80 = 0x85;
86 pub const HP_imaginary_float128 = 0x86;
87 pub const HP_VAX_float = 0x88; // F or G floating.
88 pub const HP_VAX_float_d = 0x89; // D floating.
89 pub const HP_packed_decimal = 0x8a; // Cobol.
90 pub const HP_zoned_decimal = 0x8b; // Cobol.
91 pub const HP_edited = 0x8c; // Cobol.
92 pub const HP_signed_fixed = 0x8d; // Cobol.
93 pub const HP_unsigned_fixed = 0x8e; // Cobol.
94 pub const HP_VAX_complex_float = 0x8f; // F or G floating complex.
95 pub const HP_VAX_complex_float_d = 0x90; // D floating complex.
96};
97
98pub const CFA = struct {
99 pub const advance_loc = 0x40;
100 pub const offset = 0x80;
101 pub const restore = 0xc0;
102 pub const nop = 0x00;
103 pub const set_loc = 0x01;
104 pub const advance_loc1 = 0x02;
105 pub const advance_loc2 = 0x03;
106 pub const advance_loc4 = 0x04;
107 pub const offset_extended = 0x05;
108 pub const restore_extended = 0x06;
109 pub const @"undefined" = 0x07;
110 pub const same_value = 0x08;
111 pub const register = 0x09;
112 pub const remember_state = 0x0a;
113 pub const restore_state = 0x0b;
114 pub const def_cfa = 0x0c;
115 pub const def_cfa_register = 0x0d;
116 pub const def_cfa_offset = 0x0e;
117
118 // DWARF 3.
119 pub const def_cfa_expression = 0x0f;
120 pub const expression = 0x10;
121 pub const offset_extended_sf = 0x11;
122 pub const def_cfa_sf = 0x12;
123 pub const def_cfa_offset_sf = 0x13;
124 pub const val_offset = 0x14;
125 pub const val_offset_sf = 0x15;
126 pub const val_expression = 0x16;
127
128 pub const lo_user = 0x1c;
129 pub const hi_user = 0x3f;
130
131 // SGI/MIPS specific.
132 pub const MIPS_advance_loc8 = 0x1d;
133
134 // GNU extensions.
135 pub const GNU_window_save = 0x2d;
136 pub const GNU_args_size = 0x2e;
137 pub const GNU_negative_offset_extended = 0x2f;
138};
139
140pub const CHILDREN = struct {
141 pub const no = 0x00;
142 pub const yes = 0x01;
143};
144
145pub const LNS = struct {
146 pub const extended_op = 0x00;
147 pub const copy = 0x01;
148 pub const advance_pc = 0x02;
149 pub const advance_line = 0x03;
150 pub const set_file = 0x04;
151 pub const set_column = 0x05;
152 pub const negate_stmt = 0x06;
153 pub const set_basic_block = 0x07;
154 pub const const_add_pc = 0x08;
155 pub const fixed_advance_pc = 0x09;
156 pub const set_prologue_end = 0x0a;
157 pub const set_epilogue_begin = 0x0b;
158 pub const set_isa = 0x0c;
159};
160
161pub const LNE = struct {
162 pub const end_sequence = 0x01;
163 pub const set_address = 0x02;
164 pub const define_file = 0x03;
165 pub const set_discriminator = 0x04;
166 pub const lo_user = 0x80;
167 pub const hi_user = 0xff;
168};
169
170pub const LANG = struct {
171 pub const C89 = 0x0001;
172 pub const C = 0x0002;
173 pub const Ada83 = 0x0003;
174 pub const C_plus_plus = 0x0004;
175 pub const Cobol74 = 0x0005;
176 pub const Cobol85 = 0x0006;
177 pub const Fortran77 = 0x0007;
178 pub const Fortran90 = 0x0008;
179 pub const Pascal83 = 0x0009;
180 pub const Modula2 = 0x000a;
181 pub const Java = 0x000b;
182 pub const C99 = 0x000c;
183 pub const Ada95 = 0x000d;
184 pub const Fortran95 = 0x000e;
185 pub const PLI = 0x000f;
186 pub const ObjC = 0x0010;
187 pub const ObjC_plus_plus = 0x0011;
188 pub const UPC = 0x0012;
189 pub const D = 0x0013;
190 pub const Python = 0x0014;
191 pub const Go = 0x0016;
192 pub const C_plus_plus_11 = 0x001a;
193 pub const Rust = 0x001c;
194 pub const C11 = 0x001d;
195 pub const C_plus_plus_14 = 0x0021;
196 pub const Fortran03 = 0x0022;
197 pub const Fortran08 = 0x0023;
198 pub const lo_user = 0x8000;
199 pub const hi_user = 0xffff;
200 pub const Mips_Assembler = 0x8001;
201 pub const Upc = 0x8765;
202 pub const HP_Bliss = 0x8003;
203 pub const HP_Basic91 = 0x8004;
204 pub const HP_Pascal91 = 0x8005;
205 pub const HP_IMacro = 0x8006;
206 pub const HP_Assembler = 0x8007;
207};
208
209pub const UT = struct {
210 pub const compile = 0x01;
211 pub const @"type" = 0x02;
212 pub const partial = 0x03;
213 pub const skeleton = 0x04;
214 pub const split_compile = 0x05;
215 pub const split_type = 0x06;
216 pub const lo_user = 0x80;
217 pub const hi_user = 0xff;
218};
219
220pub const LNCT = struct {
221 pub const path = 0x1;
222 pub const directory_index = 0x2;
223 pub const timestamp = 0x3;
224 pub const size = 0x4;
225 pub const MD5 = 0x5;
226 pub const lo_user = 0x2000;
227 pub const hi_user = 0x3fff;
228};
13229
14const PcRange = struct {230const PcRange = struct {
15 start: u64,231 start: u64,
...@@ -322,43 +538,43 @@ fn parseFormValueRef(allocator: *mem.Allocator, in_stream: anytype, endian: buil...@@ -322,43 +538,43 @@ fn parseFormValueRef(allocator: *mem.Allocator, in_stream: anytype, endian: buil
322// TODO the nosuspends here are workarounds538// TODO the nosuspends here are workarounds
323fn parseFormValue(allocator: *mem.Allocator, in_stream: anytype, form_id: u64, endian: builtin.Endian, is_64: bool) anyerror!FormValue {539fn parseFormValue(allocator: *mem.Allocator, in_stream: anytype, form_id: u64, endian: builtin.Endian, is_64: bool) anyerror!FormValue {
324 return switch (form_id) {540 return switch (form_id) {
325 FORM_addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) },541 FORM.addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) },
326 FORM_block1 => parseFormValueBlock(allocator, in_stream, endian, 1),542 FORM.block1 => parseFormValueBlock(allocator, in_stream, endian, 1),
327 FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),543 FORM.block2 => parseFormValueBlock(allocator, in_stream, endian, 2),
328 FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),544 FORM.block4 => parseFormValueBlock(allocator, in_stream, endian, 4),
329 FORM_block => {545 FORM.block => {
330 const block_len = try nosuspend leb.readULEB128(usize, in_stream);546 const block_len = try nosuspend leb.readULEB128(usize, in_stream);
331 return parseFormValueBlockLen(allocator, in_stream, block_len);547 return parseFormValueBlockLen(allocator, in_stream, block_len);
332 },548 },
333 FORM_data1 => parseFormValueConstant(allocator, in_stream, false, endian, 1),549 FORM.data1 => parseFormValueConstant(allocator, in_stream, false, endian, 1),
334 FORM_data2 => parseFormValueConstant(allocator, in_stream, false, endian, 2),550 FORM.data2 => parseFormValueConstant(allocator, in_stream, false, endian, 2),
335 FORM_data4 => parseFormValueConstant(allocator, in_stream, false, endian, 4),551 FORM.data4 => parseFormValueConstant(allocator, in_stream, false, endian, 4),
336 FORM_data8 => parseFormValueConstant(allocator, in_stream, false, endian, 8),552 FORM.data8 => parseFormValueConstant(allocator, in_stream, false, endian, 8),
337 FORM_udata, FORM_sdata => {553 FORM.udata, FORM.sdata => {
338 const signed = form_id == FORM_sdata;554 const signed = form_id == FORM.sdata;
339 return parseFormValueConstant(allocator, in_stream, signed, endian, -1);555 return parseFormValueConstant(allocator, in_stream, signed, endian, -1);
340 },556 },
341 FORM_exprloc => {557 FORM.exprloc => {
342 const size = try nosuspend leb.readULEB128(usize, in_stream);558 const size = try nosuspend leb.readULEB128(usize, in_stream);
343 const buf = try readAllocBytes(allocator, in_stream, size);559 const buf = try readAllocBytes(allocator, in_stream, size);
344 return FormValue{ .ExprLoc = buf };560 return FormValue{ .ExprLoc = buf };
345 },561 },
346 FORM_flag => FormValue{ .Flag = (try nosuspend in_stream.readByte()) != 0 },562 FORM.flag => FormValue{ .Flag = (try nosuspend in_stream.readByte()) != 0 },
347 FORM_flag_present => FormValue{ .Flag = true },563 FORM.flag_present => FormValue{ .Flag = true },
348 FORM_sec_offset => FormValue{ .SecOffset = try readAddress(in_stream, endian, is_64) },564 FORM.sec_offset => FormValue{ .SecOffset = try readAddress(in_stream, endian, is_64) },
349565
350 FORM_ref1 => parseFormValueRef(allocator, in_stream, endian, 1),566 FORM.ref1 => parseFormValueRef(allocator, in_stream, endian, 1),
351 FORM_ref2 => parseFormValueRef(allocator, in_stream, endian, 2),567 FORM.ref2 => parseFormValueRef(allocator, in_stream, endian, 2),
352 FORM_ref4 => parseFormValueRef(allocator, in_stream, endian, 4),568 FORM.ref4 => parseFormValueRef(allocator, in_stream, endian, 4),
353 FORM_ref8 => parseFormValueRef(allocator, in_stream, endian, 8),569 FORM.ref8 => parseFormValueRef(allocator, in_stream, endian, 8),
354 FORM_ref_udata => parseFormValueRef(allocator, in_stream, endian, -1),570 FORM.ref_udata => parseFormValueRef(allocator, in_stream, endian, -1),
355571
356 FORM_ref_addr => FormValue{ .RefAddr = try readAddress(in_stream, endian, is_64) },572 FORM.ref_addr => FormValue{ .RefAddr = try readAddress(in_stream, endian, is_64) },
357 FORM_ref_sig8 => FormValue{ .Ref = try nosuspend in_stream.readInt(u64, endian) },573 FORM.ref_sig8 => FormValue{ .Ref = try nosuspend in_stream.readInt(u64, endian) },
358574
359 FORM_string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },575 FORM.string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },
360 FORM_strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },576 FORM.strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },
361 FORM_indirect => {577 FORM.indirect => {
362 const child_form_id = try nosuspend leb.readULEB128(u64, in_stream);578 const child_form_id = try nosuspend leb.readULEB128(u64, in_stream);
363 const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64));579 const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64));
364 var frame = try allocator.create(F);580 var frame = try allocator.create(F);
...@@ -441,24 +657,24 @@ pub const DwarfInfo = struct {...@@ -441,24 +657,24 @@ pub const DwarfInfo = struct {
441 const after_die_offset = try seekable.getPos();657 const after_die_offset = try seekable.getPos();
442658
443 switch (die_obj.tag_id) {659 switch (die_obj.tag_id) {
444 TAG_subprogram, TAG_inlined_subroutine, TAG_subroutine, TAG_entry_point => {660 TAG.subprogram, TAG.inlined_subroutine, TAG.subroutine, TAG.entry_point => {
445 const fn_name = x: {661 const fn_name = x: {
446 var depth: i32 = 3;662 var depth: i32 = 3;
447 var this_die_obj = die_obj;663 var this_die_obj = die_obj;
448 // Prenvent endless loops664 // Prenvent endless loops
449 while (depth > 0) : (depth -= 1) {665 while (depth > 0) : (depth -= 1) {
450 if (this_die_obj.getAttr(AT_name)) |_| {666 if (this_die_obj.getAttr(AT.name)) |_| {
451 const name = try this_die_obj.getAttrString(di, AT_name);667 const name = try this_die_obj.getAttrString(di, AT.name);
452 break :x name;668 break :x name;
453 } else if (this_die_obj.getAttr(AT_abstract_origin)) |_| {669 } else if (this_die_obj.getAttr(AT.abstract_origin)) |_| {
454 // Follow the DIE it points to and repeat670 // Follow the DIE it points to and repeat
455 const ref_offset = try this_die_obj.getAttrRef(AT_abstract_origin);671 const ref_offset = try this_die_obj.getAttrRef(AT.abstract_origin);
456 if (ref_offset > next_offset) return error.InvalidDebugInfo;672 if (ref_offset > next_offset) return error.InvalidDebugInfo;
457 try seekable.seekTo(this_unit_offset + ref_offset);673 try seekable.seekTo(this_unit_offset + ref_offset);
458 this_die_obj = (try di.parseDie(in, abbrev_table, is_64)) orelse return error.InvalidDebugInfo;674 this_die_obj = (try di.parseDie(in, abbrev_table, is_64)) orelse return error.InvalidDebugInfo;
459 } else if (this_die_obj.getAttr(AT_specification)) |_| {675 } else if (this_die_obj.getAttr(AT.specification)) |_| {
460 // Follow the DIE it points to and repeat676 // Follow the DIE it points to and repeat
461 const ref_offset = try this_die_obj.getAttrRef(AT_specification);677 const ref_offset = try this_die_obj.getAttrRef(AT.specification);
462 if (ref_offset > next_offset) return error.InvalidDebugInfo;678 if (ref_offset > next_offset) return error.InvalidDebugInfo;
463 try seekable.seekTo(this_unit_offset + ref_offset);679 try seekable.seekTo(this_unit_offset + ref_offset);
464 this_die_obj = (try di.parseDie(in, abbrev_table, is_64)) orelse return error.InvalidDebugInfo;680 this_die_obj = (try di.parseDie(in, abbrev_table, is_64)) orelse return error.InvalidDebugInfo;
...@@ -471,8 +687,8 @@ pub const DwarfInfo = struct {...@@ -471,8 +687,8 @@ pub const DwarfInfo = struct {
471 };687 };
472688
473 const pc_range = x: {689 const pc_range = x: {
474 if (die_obj.getAttrAddr(AT_low_pc)) |low_pc| {690 if (die_obj.getAttrAddr(AT.low_pc)) |low_pc| {
475 if (die_obj.getAttr(AT_high_pc)) |high_pc_value| {691 if (die_obj.getAttr(AT.high_pc)) |high_pc_value| {
476 const pc_end = switch (high_pc_value.*) {692 const pc_end = switch (high_pc_value.*) {
477 FormValue.Address => |value| value,693 FormValue.Address => |value| value,
478 FormValue.Const => |value| b: {694 FormValue.Const => |value| b: {
...@@ -539,11 +755,11 @@ pub const DwarfInfo = struct {...@@ -539,11 +755,11 @@ pub const DwarfInfo = struct {
539 const compile_unit_die = try di.allocator().create(Die);755 const compile_unit_die = try di.allocator().create(Die);
540 compile_unit_die.* = (try di.parseDie(in, abbrev_table, is_64)) orelse return error.InvalidDebugInfo;756 compile_unit_die.* = (try di.parseDie(in, abbrev_table, is_64)) orelse return error.InvalidDebugInfo;
541757
542 if (compile_unit_die.tag_id != TAG_compile_unit) return error.InvalidDebugInfo;758 if (compile_unit_die.tag_id != TAG.compile_unit) return error.InvalidDebugInfo;
543759
544 const pc_range = x: {760 const pc_range = x: {
545 if (compile_unit_die.getAttrAddr(AT_low_pc)) |low_pc| {761 if (compile_unit_die.getAttrAddr(AT.low_pc)) |low_pc| {
546 if (compile_unit_die.getAttr(AT_high_pc)) |high_pc_value| {762 if (compile_unit_die.getAttr(AT.high_pc)) |high_pc_value| {
547 const pc_end = switch (high_pc_value.*) {763 const pc_end = switch (high_pc_value.*) {
548 FormValue.Address => |value| value,764 FormValue.Address => |value| value,
549 FormValue.Const => |value| b: {765 FormValue.Const => |value| b: {
...@@ -582,16 +798,16 @@ pub const DwarfInfo = struct {...@@ -582,16 +798,16 @@ pub const DwarfInfo = struct {
582 if (target_address >= range.start and target_address < range.end) return compile_unit;798 if (target_address >= range.start and target_address < range.end) return compile_unit;
583 }799 }
584 if (di.debug_ranges) |debug_ranges| {800 if (di.debug_ranges) |debug_ranges| {
585 if (compile_unit.die.getAttrSecOffset(AT_ranges)) |ranges_offset| {801 if (compile_unit.die.getAttrSecOffset(AT.ranges)) |ranges_offset| {
586 var stream = io.fixedBufferStream(debug_ranges);802 var stream = io.fixedBufferStream(debug_ranges);
587 const in = &stream.reader();803 const in = &stream.reader();
588 const seekable = &stream.seekableStream();804 const seekable = &stream.seekableStream();
589805
590 // All the addresses in the list are relative to the value806 // All the addresses in the list are relative to the value
591 // specified by DW_AT_low_pc or to some other value encoded807 // specified by DW_AT.low_pc or to some other value encoded
592 // in the list itself.808 // in the list itself.
593 // If no starting value is specified use zero.809 // If no starting value is specified use zero.
594 var base_address = compile_unit.die.getAttrAddr(AT_low_pc) catch |err| switch (err) {810 var base_address = compile_unit.die.getAttrAddr(AT.low_pc) catch |err| switch (err) {
595 error.MissingDebugInfo => 0,811 error.MissingDebugInfo => 0,
596 else => return err,812 else => return err,
597 };813 };
...@@ -651,7 +867,7 @@ pub const DwarfInfo = struct {...@@ -651,7 +867,7 @@ pub const DwarfInfo = struct {
651 try result.append(AbbrevTableEntry{867 try result.append(AbbrevTableEntry{
652 .abbrev_code = abbrev_code,868 .abbrev_code = abbrev_code,
653 .tag_id = try leb.readULEB128(u64, in),869 .tag_id = try leb.readULEB128(u64, in),
654 .has_children = (try in.readByte()) == CHILDREN_yes,870 .has_children = (try in.readByte()) == CHILDREN.yes,
655 .attrs = ArrayList(AbbrevAttr).init(di.allocator()),871 .attrs = ArrayList(AbbrevAttr).init(di.allocator()),
656 });872 });
657 const attrs = &result.items[result.items.len - 1].attrs;873 const attrs = &result.items[result.items.len - 1].attrs;
...@@ -693,8 +909,8 @@ pub const DwarfInfo = struct {...@@ -693,8 +909,8 @@ pub const DwarfInfo = struct {
693 const in = &stream.reader();909 const in = &stream.reader();
694 const seekable = &stream.seekableStream();910 const seekable = &stream.seekableStream();
695911
696 const compile_unit_cwd = try compile_unit.die.getAttrString(di, AT_comp_dir);912 const compile_unit_cwd = try compile_unit.die.getAttrString(di, AT.comp_dir);
697 const line_info_offset = try compile_unit.die.getAttrSecOffset(AT_stmt_list);913 const line_info_offset = try compile_unit.die.getAttrSecOffset(AT.stmt_list);
698914
699 try seekable.seekTo(line_info_offset);915 try seekable.seekTo(line_info_offset);
700916
...@@ -769,21 +985,21 @@ pub const DwarfInfo = struct {...@@ -769,21 +985,21 @@ pub const DwarfInfo = struct {
769 while ((try seekable.getPos()) < next_unit_pos) {985 while ((try seekable.getPos()) < next_unit_pos) {
770 const opcode = try in.readByte();986 const opcode = try in.readByte();
771987
772 if (opcode == LNS_extended_op) {988 if (opcode == LNS.extended_op) {
773 const op_size = try leb.readULEB128(u64, in);989 const op_size = try leb.readULEB128(u64, in);
774 if (op_size < 1) return error.InvalidDebugInfo;990 if (op_size < 1) return error.InvalidDebugInfo;
775 var sub_op = try in.readByte();991 var sub_op = try in.readByte();
776 switch (sub_op) {992 switch (sub_op) {
777 LNE_end_sequence => {993 LNE.end_sequence => {
778 prog.end_sequence = true;994 prog.end_sequence = true;
779 if (try prog.checkLineMatch()) |info| return info;995 if (try prog.checkLineMatch()) |info| return info;
780 prog.reset();996 prog.reset();
781 },997 },
782 LNE_set_address => {998 LNE.set_address => {
783 const addr = try in.readInt(usize, di.endian);999 const addr = try in.readInt(usize, di.endian);
784 prog.address = addr;1000 prog.address = addr;
785 },1001 },
786 LNE_define_file => {1002 LNE.define_file => {
787 const file_name = try in.readUntilDelimiterAlloc(di.allocator(), 0, math.maxInt(usize));1003 const file_name = try in.readUntilDelimiterAlloc(di.allocator(), 0, math.maxInt(usize));
788 const dir_index = try leb.readULEB128(usize, in);1004 const dir_index = try leb.readULEB128(usize, in);
789 const mtime = try leb.readULEB128(usize, in);1005 const mtime = try leb.readULEB128(usize, in);
...@@ -811,41 +1027,41 @@ pub const DwarfInfo = struct {...@@ -811,41 +1027,41 @@ pub const DwarfInfo = struct {
811 prog.basic_block = false;1027 prog.basic_block = false;
812 } else {1028 } else {
813 switch (opcode) {1029 switch (opcode) {
814 LNS_copy => {1030 LNS.copy => {
815 if (try prog.checkLineMatch()) |info| return info;1031 if (try prog.checkLineMatch()) |info| return info;
816 prog.basic_block = false;1032 prog.basic_block = false;
817 },1033 },
818 LNS_advance_pc => {1034 LNS.advance_pc => {
819 const arg = try leb.readULEB128(usize, in);1035 const arg = try leb.readULEB128(usize, in);
820 prog.address += arg * minimum_instruction_length;1036 prog.address += arg * minimum_instruction_length;
821 },1037 },
822 LNS_advance_line => {1038 LNS.advance_line => {
823 const arg = try leb.readILEB128(i64, in);1039 const arg = try leb.readILEB128(i64, in);
824 prog.line += arg;1040 prog.line += arg;
825 },1041 },
826 LNS_set_file => {1042 LNS.set_file => {
827 const arg = try leb.readULEB128(usize, in);1043 const arg = try leb.readULEB128(usize, in);
828 prog.file = arg;1044 prog.file = arg;
829 },1045 },
830 LNS_set_column => {1046 LNS.set_column => {
831 const arg = try leb.readULEB128(u64, in);1047 const arg = try leb.readULEB128(u64, in);
832 prog.column = arg;1048 prog.column = arg;
833 },1049 },
834 LNS_negate_stmt => {1050 LNS.negate_stmt => {
835 prog.is_stmt = !prog.is_stmt;1051 prog.is_stmt = !prog.is_stmt;
836 },1052 },
837 LNS_set_basic_block => {1053 LNS.set_basic_block => {
838 prog.basic_block = true;1054 prog.basic_block = true;
839 },1055 },
840 LNS_const_add_pc => {1056 LNS.const_add_pc => {
841 const inc_addr = minimum_instruction_length * ((255 - opcode_base) / line_range);1057 const inc_addr = minimum_instruction_length * ((255 - opcode_base) / line_range);
842 prog.address += inc_addr;1058 prog.address += inc_addr;
843 },1059 },
844 LNS_fixed_advance_pc => {1060 LNS.fixed_advance_pc => {
845 const arg = try in.readInt(u16, di.endian);1061 const arg = try in.readInt(u16, di.endian);
846 prog.address += arg;1062 prog.address += arg;
847 },1063 },
848 LNS_set_prologue_end => {},1064 LNS.set_prologue_end => {},
849 else => {1065 else => {
850 if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo;1066 if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo;
851 const len_bytes = standard_opcode_lengths[opcode - 1];1067 const len_bytes = standard_opcode_lengths[opcode - 1];
lib/std/dwarf/AT.zig created+198
...@@ -0,0 +1,198 @@
1pub const sibling = 0x01;
2pub const location = 0x02;
3pub const name = 0x03;
4pub const ordering = 0x09;
5pub const subscr_data = 0x0a;
6pub const byte_size = 0x0b;
7pub const bit_offset = 0x0c;
8pub const bit_size = 0x0d;
9pub const element_list = 0x0f;
10pub const stmt_list = 0x10;
11pub const low_pc = 0x11;
12pub const high_pc = 0x12;
13pub const language = 0x13;
14pub const member = 0x14;
15pub const discr = 0x15;
16pub const discr_value = 0x16;
17pub const visibility = 0x17;
18pub const import = 0x18;
19pub const string_length = 0x19;
20pub const common_reference = 0x1a;
21pub const comp_dir = 0x1b;
22pub const const_value = 0x1c;
23pub const containing_type = 0x1d;
24pub const default_value = 0x1e;
25pub const @"inline" = 0x20;
26pub const is_optional = 0x21;
27pub const lower_bound = 0x22;
28pub const producer = 0x25;
29pub const prototyped = 0x27;
30pub const return_addr = 0x2a;
31pub const start_scope = 0x2c;
32pub const bit_stride = 0x2e;
33pub const upper_bound = 0x2f;
34pub const abstract_origin = 0x31;
35pub const accessibility = 0x32;
36pub const address_class = 0x33;
37pub const artificial = 0x34;
38pub const base_types = 0x35;
39pub const calling_convention = 0x36;
40pub const count = 0x37;
41pub const data_member_location = 0x38;
42pub const decl_column = 0x39;
43pub const decl_file = 0x3a;
44pub const decl_line = 0x3b;
45pub const declaration = 0x3c;
46pub const discr_list = 0x3d;
47pub const encoding = 0x3e;
48pub const external = 0x3f;
49pub const frame_base = 0x40;
50pub const friend = 0x41;
51pub const identifier_case = 0x42;
52pub const macro_info = 0x43;
53pub const namelist_items = 0x44;
54pub const priority = 0x45;
55pub const segment = 0x46;
56pub const specification = 0x47;
57pub const static_link = 0x48;
58pub const @"type" = 0x49;
59pub const use_location = 0x4a;
60pub const variable_parameter = 0x4b;
61pub const virtuality = 0x4c;
62pub const vtable_elem_location = 0x4d;
63
64// DWARF 3 values.
65pub const allocated = 0x4e;
66pub const associated = 0x4f;
67pub const data_location = 0x50;
68pub const byte_stride = 0x51;
69pub const entry_pc = 0x52;
70pub const use_UTF8 = 0x53;
71pub const extension = 0x54;
72pub const ranges = 0x55;
73pub const trampoline = 0x56;
74pub const call_column = 0x57;
75pub const call_file = 0x58;
76pub const call_line = 0x59;
77pub const description = 0x5a;
78pub const binary_scale = 0x5b;
79pub const decimal_scale = 0x5c;
80pub const small = 0x5d;
81pub const decimal_sign = 0x5e;
82pub const digit_count = 0x5f;
83pub const picture_string = 0x60;
84pub const mutable = 0x61;
85pub const threads_scaled = 0x62;
86pub const explicit = 0x63;
87pub const object_pointer = 0x64;
88pub const endianity = 0x65;
89pub const elemental = 0x66;
90pub const pure = 0x67;
91pub const recursive = 0x68;
92
93// DWARF 4.
94pub const signature = 0x69;
95pub const main_subprogram = 0x6a;
96pub const data_bit_offset = 0x6b;
97pub const const_expr = 0x6c;
98pub const enum_class = 0x6d;
99pub const linkage_name = 0x6e;
100
101// DWARF 5
102pub const alignment = 0x88;
103
104pub const lo_user = 0x2000; // Implementation-defined range start.
105pub const hi_user = 0x3fff; // Implementation-defined range end.
106
107// SGI/MIPS extensions.
108pub const MIPS_fde = 0x2001;
109pub const MIPS_loop_begin = 0x2002;
110pub const MIPS_tail_loop_begin = 0x2003;
111pub const MIPS_epilog_begin = 0x2004;
112pub const MIPS_loop_unroll_factor = 0x2005;
113pub const MIPS_software_pipeline_depth = 0x2006;
114pub const MIPS_linkage_name = 0x2007;
115pub const MIPS_stride = 0x2008;
116pub const MIPS_abstract_name = 0x2009;
117pub const MIPS_clone_origin = 0x200a;
118pub const MIPS_has_inlines = 0x200b;
119
120// HP extensions.
121pub const HP_block_index = 0x2000;
122pub const HP_unmodifiable = 0x2001; // Same as AT.MIPS_fde.
123pub const HP_prologue = 0x2005; // Same as AT.MIPS_loop_unroll.
124pub const HP_epilogue = 0x2008; // Same as AT.MIPS_stride.
125pub const HP_actuals_stmt_list = 0x2010;
126pub const HP_proc_per_section = 0x2011;
127pub const HP_raw_data_ptr = 0x2012;
128pub const HP_pass_by_reference = 0x2013;
129pub const HP_opt_level = 0x2014;
130pub const HP_prof_version_id = 0x2015;
131pub const HP_opt_flags = 0x2016;
132pub const HP_cold_region_low_pc = 0x2017;
133pub const HP_cold_region_high_pc = 0x2018;
134pub const HP_all_variables_modifiable = 0x2019;
135pub const HP_linkage_name = 0x201a;
136pub const HP_prof_flags = 0x201b; // In comp unit of procs_info for -g.
137pub const HP_unit_name = 0x201f;
138pub const HP_unit_size = 0x2020;
139pub const HP_widened_byte_size = 0x2021;
140pub const HP_definition_points = 0x2022;
141pub const HP_default_location = 0x2023;
142pub const HP_is_result_param = 0x2029;
143
144// GNU extensions.
145pub const sf_names = 0x2101;
146pub const src_info = 0x2102;
147pub const mac_info = 0x2103;
148pub const src_coords = 0x2104;
149pub const body_begin = 0x2105;
150pub const body_end = 0x2106;
151pub const GNU_vector = 0x2107;
152// Thread-safety annotations.
153// See http://gcc.gnu.org/wiki/ThreadSafetyAnnotation .
154pub const GNU_guarded_by = 0x2108;
155pub const GNU_pt_guarded_by = 0x2109;
156pub const GNU_guarded = 0x210a;
157pub const GNU_pt_guarded = 0x210b;
158pub const GNU_locks_excluded = 0x210c;
159pub const GNU_exclusive_locks_required = 0x210d;
160pub const GNU_shared_locks_required = 0x210e;
161// One-definition rule violation detection.
162// See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo .
163pub const GNU_odr_signature = 0x210f;
164// Template template argument name.
165// See http://gcc.gnu.org/wiki/TemplateParmsDwarf .
166pub const GNU_template_name = 0x2110;
167// The GNU call site extension.
168// See http://www.dwarfstd.org/ShowIssue.php?issue=100909.2&type=open .
169pub const GNU_call_site_value = 0x2111;
170pub const GNU_call_site_data_value = 0x2112;
171pub const GNU_call_site_target = 0x2113;
172pub const GNU_call_site_target_clobbered = 0x2114;
173pub const GNU_tail_call = 0x2115;
174pub const GNU_all_tail_call_sites = 0x2116;
175pub const GNU_all_call_sites = 0x2117;
176pub const GNU_all_source_call_sites = 0x2118;
177// Section offset into .debug_macro section.
178pub const GNU_macros = 0x2119;
179// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
180pub const GNU_dwo_name = 0x2130;
181pub const GNU_dwo_id = 0x2131;
182pub const GNU_ranges_base = 0x2132;
183pub const GNU_addr_base = 0x2133;
184pub const GNU_pubnames = 0x2134;
185pub const GNU_pubtypes = 0x2135;
186// VMS extensions.
187pub const VMS_rtnbeg_pd_address = 0x2201;
188// GNAT extensions.
189// GNAT descriptive type.
190// See http://gcc.gnu.org/wiki/DW_AT_GNAT_descriptive_type .
191pub const use_GNAT_descriptive_type = 0x2301;
192pub const GNAT_descriptive_type = 0x2302;
193// UPC extension.
194pub const upc_threads_scaled = 0x3210;
195// PGI (STMicroelectronics) extensions.
196pub const PGI_lbase = 0x3a00;
197pub const PGI_soffset = 0x3a01;
198pub const PGI_lstride = 0x3a02;
lib/std/dwarf/OP.zig created+195
...@@ -0,0 +1,195 @@
1pub const addr = 0x03;
2pub const deref = 0x06;
3pub const const1u = 0x08;
4pub const const1s = 0x09;
5pub const const2u = 0x0a;
6pub const const2s = 0x0b;
7pub const const4u = 0x0c;
8pub const const4s = 0x0d;
9pub const const8u = 0x0e;
10pub const const8s = 0x0f;
11pub const constu = 0x10;
12pub const consts = 0x11;
13pub const dup = 0x12;
14pub const drop = 0x13;
15pub const over = 0x14;
16pub const pick = 0x15;
17pub const swap = 0x16;
18pub const rot = 0x17;
19pub const xderef = 0x18;
20pub const abs = 0x19;
21pub const @"and" = 0x1a;
22pub const div = 0x1b;
23pub const minus = 0x1c;
24pub const mod = 0x1d;
25pub const mul = 0x1e;
26pub const neg = 0x1f;
27pub const not = 0x20;
28pub const @"or" = 0x21;
29pub const plus = 0x22;
30pub const plus_uconst = 0x23;
31pub const shl = 0x24;
32pub const shr = 0x25;
33pub const shra = 0x26;
34pub const xor = 0x27;
35pub const bra = 0x28;
36pub const eq = 0x29;
37pub const ge = 0x2a;
38pub const gt = 0x2b;
39pub const le = 0x2c;
40pub const lt = 0x2d;
41pub const ne = 0x2e;
42pub const skip = 0x2f;
43pub const lit0 = 0x30;
44pub const lit1 = 0x31;
45pub const lit2 = 0x32;
46pub const lit3 = 0x33;
47pub const lit4 = 0x34;
48pub const lit5 = 0x35;
49pub const lit6 = 0x36;
50pub const lit7 = 0x37;
51pub const lit8 = 0x38;
52pub const lit9 = 0x39;
53pub const lit10 = 0x3a;
54pub const lit11 = 0x3b;
55pub const lit12 = 0x3c;
56pub const lit13 = 0x3d;
57pub const lit14 = 0x3e;
58pub const lit15 = 0x3f;
59pub const lit16 = 0x40;
60pub const lit17 = 0x41;
61pub const lit18 = 0x42;
62pub const lit19 = 0x43;
63pub const lit20 = 0x44;
64pub const lit21 = 0x45;
65pub const lit22 = 0x46;
66pub const lit23 = 0x47;
67pub const lit24 = 0x48;
68pub const lit25 = 0x49;
69pub const lit26 = 0x4a;
70pub const lit27 = 0x4b;
71pub const lit28 = 0x4c;
72pub const lit29 = 0x4d;
73pub const lit30 = 0x4e;
74pub const lit31 = 0x4f;
75pub const reg0 = 0x50;
76pub const reg1 = 0x51;
77pub const reg2 = 0x52;
78pub const reg3 = 0x53;
79pub const reg4 = 0x54;
80pub const reg5 = 0x55;
81pub const reg6 = 0x56;
82pub const reg7 = 0x57;
83pub const reg8 = 0x58;
84pub const reg9 = 0x59;
85pub const reg10 = 0x5a;
86pub const reg11 = 0x5b;
87pub const reg12 = 0x5c;
88pub const reg13 = 0x5d;
89pub const reg14 = 0x5e;
90pub const reg15 = 0x5f;
91pub const reg16 = 0x60;
92pub const reg17 = 0x61;
93pub const reg18 = 0x62;
94pub const reg19 = 0x63;
95pub const reg20 = 0x64;
96pub const reg21 = 0x65;
97pub const reg22 = 0x66;
98pub const reg23 = 0x67;
99pub const reg24 = 0x68;
100pub const reg25 = 0x69;
101pub const reg26 = 0x6a;
102pub const reg27 = 0x6b;
103pub const reg28 = 0x6c;
104pub const reg29 = 0x6d;
105pub const reg30 = 0x6e;
106pub const reg31 = 0x6f;
107pub const breg0 = 0x70;
108pub const breg1 = 0x71;
109pub const breg2 = 0x72;
110pub const breg3 = 0x73;
111pub const breg4 = 0x74;
112pub const breg5 = 0x75;
113pub const breg6 = 0x76;
114pub const breg7 = 0x77;
115pub const breg8 = 0x78;
116pub const breg9 = 0x79;
117pub const breg10 = 0x7a;
118pub const breg11 = 0x7b;
119pub const breg12 = 0x7c;
120pub const breg13 = 0x7d;
121pub const breg14 = 0x7e;
122pub const breg15 = 0x7f;
123pub const breg16 = 0x80;
124pub const breg17 = 0x81;
125pub const breg18 = 0x82;
126pub const breg19 = 0x83;
127pub const breg20 = 0x84;
128pub const breg21 = 0x85;
129pub const breg22 = 0x86;
130pub const breg23 = 0x87;
131pub const breg24 = 0x88;
132pub const breg25 = 0x89;
133pub const breg26 = 0x8a;
134pub const breg27 = 0x8b;
135pub const breg28 = 0x8c;
136pub const breg29 = 0x8d;
137pub const breg30 = 0x8e;
138pub const breg31 = 0x8f;
139pub const regx = 0x90;
140pub const fbreg = 0x91;
141pub const bregx = 0x92;
142pub const piece = 0x93;
143pub const deref_size = 0x94;
144pub const xderef_size = 0x95;
145pub const nop = 0x96;
146
147// DWARF 3 extensions.
148pub const push_object_address = 0x97;
149pub const call2 = 0x98;
150pub const call4 = 0x99;
151pub const call_ref = 0x9a;
152pub const form_tls_address = 0x9b;
153pub const call_frame_cfa = 0x9c;
154pub const bit_piece = 0x9d;
155
156// DWARF 4 extensions.
157pub const implicit_value = 0x9e;
158pub const stack_value = 0x9f;
159
160pub const lo_user = 0xe0; // Implementation-defined range start.
161pub const hi_user = 0xff; // Implementation-defined range end.
162
163// GNU extensions.
164pub const GNU_push_tls_address = 0xe0;
165// The following is for marking variables that are uninitialized.
166pub const GNU_uninit = 0xf0;
167pub const GNU_encoded_addr = 0xf1;
168// The GNU implicit pointer extension.
169// See http://www.dwarfstd.org/ShowIssue.php?issue=100831.1&type=open .
170pub const GNU_implicit_pointer = 0xf2;
171// The GNU entry value extension.
172// See http://www.dwarfstd.org/ShowIssue.php?issue=100909.1&type=open .
173pub const GNU_entry_value = 0xf3;
174// The GNU typed stack extension.
175// See http://www.dwarfstd.org/doc/040408.1.html .
176pub const GNU_const_type = 0xf4;
177pub const GNU_regval_type = 0xf5;
178pub const GNU_deref_type = 0xf6;
179pub const GNU_convert = 0xf7;
180pub const GNU_reinterpret = 0xf9;
181// The GNU parameter ref extension.
182pub const GNU_parameter_ref = 0xfa;
183// Extension for Fission. See http://gcc.gnu.org/wiki/DebugFission.
184pub const GNU_addr_index = 0xfb;
185pub const GNU_const_index = 0xfc;
186// HP extensions.
187pub const HP_unknown = 0xe0; // Ouch, the same as GNU_push_tls_address.
188pub const HP_is_value = 0xe1;
189pub const HP_fltconst4 = 0xe2;
190pub const HP_fltconst8 = 0xe3;
191pub const HP_mod_range = 0xe4;
192pub const HP_unmod_range = 0xe5;
193pub const HP_tls = 0xe6;
194// PGI (STMicroelectronics) extensions.
195pub const PGI_omp_thread_num = 0xf8;
lib/std/dwarf/TAG.zig created+108
...@@ -0,0 +1,108 @@
1pub const padding = 0x00;
2pub const array_type = 0x01;
3pub const class_type = 0x02;
4pub const entry_point = 0x03;
5pub const enumeration_type = 0x04;
6pub const formal_parameter = 0x05;
7pub const imported_declaration = 0x08;
8pub const label = 0x0a;
9pub const lexical_block = 0x0b;
10pub const member = 0x0d;
11pub const pointer_type = 0x0f;
12pub const reference_type = 0x10;
13pub const compile_unit = 0x11;
14pub const string_type = 0x12;
15pub const structure_type = 0x13;
16pub const subroutine = 0x14;
17pub const subroutine_type = 0x15;
18pub const typedef = 0x16;
19pub const union_type = 0x17;
20pub const unspecified_parameters = 0x18;
21pub const variant = 0x19;
22pub const common_block = 0x1a;
23pub const common_inclusion = 0x1b;
24pub const inheritance = 0x1c;
25pub const inlined_subroutine = 0x1d;
26pub const module = 0x1e;
27pub const ptr_to_member_type = 0x1f;
28pub const set_type = 0x20;
29pub const subrange_type = 0x21;
30pub const with_stmt = 0x22;
31pub const access_declaration = 0x23;
32pub const base_type = 0x24;
33pub const catch_block = 0x25;
34pub const const_type = 0x26;
35pub const constant = 0x27;
36pub const enumerator = 0x28;
37pub const file_type = 0x29;
38pub const friend = 0x2a;
39pub const namelist = 0x2b;
40pub const namelist_item = 0x2c;
41pub const packed_type = 0x2d;
42pub const subprogram = 0x2e;
43pub const template_type_param = 0x2f;
44pub const template_value_param = 0x30;
45pub const thrown_type = 0x31;
46pub const try_block = 0x32;
47pub const variant_part = 0x33;
48pub const variable = 0x34;
49pub const volatile_type = 0x35;
50
51// DWARF 3
52pub const dwarf_procedure = 0x36;
53pub const restrict_type = 0x37;
54pub const interface_type = 0x38;
55pub const namespace = 0x39;
56pub const imported_module = 0x3a;
57pub const unspecified_type = 0x3b;
58pub const partial_unit = 0x3c;
59pub const imported_unit = 0x3d;
60pub const condition = 0x3f;
61pub const shared_type = 0x40;
62
63// DWARF 4
64pub const type_unit = 0x41;
65pub const rvalue_reference_type = 0x42;
66pub const template_alias = 0x43;
67
68pub const lo_user = 0x4080;
69pub const hi_user = 0xffff;
70
71// SGI/MIPS Extensions.
72pub const MIPS_loop = 0x4081;
73
74// HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .
75pub const HP_array_descriptor = 0x4090;
76pub const HP_Bliss_field = 0x4091;
77pub const HP_Bliss_field_set = 0x4092;
78
79// GNU extensions.
80pub const format_label = 0x4101; // For FORTRAN 77 and Fortran 90.
81pub const function_template = 0x4102; // For C++.
82pub const class_template = 0x4103; //For C++.
83pub const GNU_BINCL = 0x4104;
84pub const GNU_EINCL = 0x4105;
85
86// Template template parameter.
87// See http://gcc.gnu.org/wiki/TemplateParmsDwarf .
88pub const GNU_template_template_param = 0x4106;
89
90// Template parameter pack extension = specified at
91// http://wiki.dwarfstd.org/index.php?title=C%2B%2B0x:_Variadic_templates
92// The values of these two TAGS are in the DW_TAG_GNU_* space until the tags
93// are properly part of DWARF 5.
94pub const GNU_template_parameter_pack = 0x4107;
95pub const GNU_formal_parameter_pack = 0x4108;
96// The GNU call site extension = specified at
97// http://www.dwarfstd.org/ShowIssue.php?issue=100909.2&type=open .
98// The values of these two TAGS are in the DW_TAG_GNU_* space until the tags
99// are properly part of DWARF 5.
100pub const GNU_call_site = 0x4109;
101pub const GNU_call_site_parameter = 0x410a;
102// Extensions for UPC. See: http://dwarfstd.org/doc/DWARF4.pdf.
103pub const upc_shared_type = 0x8765;
104pub const upc_strict_type = 0x8766;
105pub const upc_relaxed_type = 0x8767;
106// PGI (STMicroelectronics; extensions. No documentation available.
107pub const PGI_kanji_type = 0xA000;
108pub const PGI_interface_block = 0xA020;
lib/std/dwarf_bits.zig deleted-699
...@@ -1,699 +0,0 @@
1pub const TAG_padding = 0x00;
2pub const TAG_array_type = 0x01;
3pub const TAG_class_type = 0x02;
4pub const TAG_entry_point = 0x03;
5pub const TAG_enumeration_type = 0x04;
6pub const TAG_formal_parameter = 0x05;
7pub const TAG_imported_declaration = 0x08;
8pub const TAG_label = 0x0a;
9pub const TAG_lexical_block = 0x0b;
10pub const TAG_member = 0x0d;
11pub const TAG_pointer_type = 0x0f;
12pub const TAG_reference_type = 0x10;
13pub const TAG_compile_unit = 0x11;
14pub const TAG_string_type = 0x12;
15pub const TAG_structure_type = 0x13;
16pub const TAG_subroutine = 0x14;
17pub const TAG_subroutine_type = 0x15;
18pub const TAG_typedef = 0x16;
19pub const TAG_union_type = 0x17;
20pub const TAG_unspecified_parameters = 0x18;
21pub const TAG_variant = 0x19;
22pub const TAG_common_block = 0x1a;
23pub const TAG_common_inclusion = 0x1b;
24pub const TAG_inheritance = 0x1c;
25pub const TAG_inlined_subroutine = 0x1d;
26pub const TAG_module = 0x1e;
27pub const TAG_ptr_to_member_type = 0x1f;
28pub const TAG_set_type = 0x20;
29pub const TAG_subrange_type = 0x21;
30pub const TAG_with_stmt = 0x22;
31pub const TAG_access_declaration = 0x23;
32pub const TAG_base_type = 0x24;
33pub const TAG_catch_block = 0x25;
34pub const TAG_const_type = 0x26;
35pub const TAG_constant = 0x27;
36pub const TAG_enumerator = 0x28;
37pub const TAG_file_type = 0x29;
38pub const TAG_friend = 0x2a;
39pub const TAG_namelist = 0x2b;
40pub const TAG_namelist_item = 0x2c;
41pub const TAG_packed_type = 0x2d;
42pub const TAG_subprogram = 0x2e;
43pub const TAG_template_type_param = 0x2f;
44pub const TAG_template_value_param = 0x30;
45pub const TAG_thrown_type = 0x31;
46pub const TAG_try_block = 0x32;
47pub const TAG_variant_part = 0x33;
48pub const TAG_variable = 0x34;
49pub const TAG_volatile_type = 0x35;
50
51// DWARF 3
52pub const TAG_dwarf_procedure = 0x36;
53pub const TAG_restrict_type = 0x37;
54pub const TAG_interface_type = 0x38;
55pub const TAG_namespace = 0x39;
56pub const TAG_imported_module = 0x3a;
57pub const TAG_unspecified_type = 0x3b;
58pub const TAG_partial_unit = 0x3c;
59pub const TAG_imported_unit = 0x3d;
60pub const TAG_condition = 0x3f;
61pub const TAG_shared_type = 0x40;
62
63// DWARF 4
64pub const TAG_type_unit = 0x41;
65pub const TAG_rvalue_reference_type = 0x42;
66pub const TAG_template_alias = 0x43;
67
68pub const TAG_lo_user = 0x4080;
69pub const TAG_hi_user = 0xffff;
70
71// SGI/MIPS Extensions.
72pub const TAG_MIPS_loop = 0x4081;
73
74// HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .
75pub const TAG_HP_array_descriptor = 0x4090;
76pub const TAG_HP_Bliss_field = 0x4091;
77pub const TAG_HP_Bliss_field_set = 0x4092;
78
79// GNU extensions.
80pub const TAG_format_label = 0x4101; // For FORTRAN 77 and Fortran 90.
81pub const TAG_function_template = 0x4102; // For C++.
82pub const TAG_class_template = 0x4103; //For C++.
83pub const TAG_GNU_BINCL = 0x4104;
84pub const TAG_GNU_EINCL = 0x4105;
85
86// Template template parameter.
87// See http://gcc.gnu.org/wiki/TemplateParmsDwarf .
88pub const TAG_GNU_template_template_param = 0x4106;
89
90// Template parameter pack extension = specified at
91// http://wiki.dwarfstd.org/index.php?title=C%2B%2B0x:_Variadic_templates
92// The values of these two TAGS are in the DW_TAG_GNU_* space until the tags
93// are properly part of DWARF 5.
94pub const TAG_GNU_template_parameter_pack = 0x4107;
95pub const TAG_GNU_formal_parameter_pack = 0x4108;
96// The GNU call site extension = specified at
97// http://www.dwarfstd.org/ShowIssue.php?issue=100909.2&type=open .
98// The values of these two TAGS are in the DW_TAG_GNU_* space until the tags
99// are properly part of DWARF 5.
100pub const TAG_GNU_call_site = 0x4109;
101pub const TAG_GNU_call_site_parameter = 0x410a;
102// Extensions for UPC. See: http://dwarfstd.org/doc/DWARF4.pdf.
103pub const TAG_upc_shared_type = 0x8765;
104pub const TAG_upc_strict_type = 0x8766;
105pub const TAG_upc_relaxed_type = 0x8767;
106// PGI (STMicroelectronics; extensions. No documentation available.
107pub const TAG_PGI_kanji_type = 0xA000;
108pub const TAG_PGI_interface_block = 0xA020;
109
110pub const FORM_addr = 0x01;
111pub const FORM_block2 = 0x03;
112pub const FORM_block4 = 0x04;
113pub const FORM_data2 = 0x05;
114pub const FORM_data4 = 0x06;
115pub const FORM_data8 = 0x07;
116pub const FORM_string = 0x08;
117pub const FORM_block = 0x09;
118pub const FORM_block1 = 0x0a;
119pub const FORM_data1 = 0x0b;
120pub const FORM_flag = 0x0c;
121pub const FORM_sdata = 0x0d;
122pub const FORM_strp = 0x0e;
123pub const FORM_udata = 0x0f;
124pub const FORM_ref_addr = 0x10;
125pub const FORM_ref1 = 0x11;
126pub const FORM_ref2 = 0x12;
127pub const FORM_ref4 = 0x13;
128pub const FORM_ref8 = 0x14;
129pub const FORM_ref_udata = 0x15;
130pub const FORM_indirect = 0x16;
131pub const FORM_sec_offset = 0x17;
132pub const FORM_exprloc = 0x18;
133pub const FORM_flag_present = 0x19;
134pub const FORM_ref_sig8 = 0x20;
135
136// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
137pub const FORM_GNU_addr_index = 0x1f01;
138pub const FORM_GNU_str_index = 0x1f02;
139
140// Extensions for DWZ multifile.
141// See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open .
142pub const FORM_GNU_ref_alt = 0x1f20;
143pub const FORM_GNU_strp_alt = 0x1f21;
144
145pub const AT_sibling = 0x01;
146pub const AT_location = 0x02;
147pub const AT_name = 0x03;
148pub const AT_ordering = 0x09;
149pub const AT_subscr_data = 0x0a;
150pub const AT_byte_size = 0x0b;
151pub const AT_bit_offset = 0x0c;
152pub const AT_bit_size = 0x0d;
153pub const AT_element_list = 0x0f;
154pub const AT_stmt_list = 0x10;
155pub const AT_low_pc = 0x11;
156pub const AT_high_pc = 0x12;
157pub const AT_language = 0x13;
158pub const AT_member = 0x14;
159pub const AT_discr = 0x15;
160pub const AT_discr_value = 0x16;
161pub const AT_visibility = 0x17;
162pub const AT_import = 0x18;
163pub const AT_string_length = 0x19;
164pub const AT_common_reference = 0x1a;
165pub const AT_comp_dir = 0x1b;
166pub const AT_const_value = 0x1c;
167pub const AT_containing_type = 0x1d;
168pub const AT_default_value = 0x1e;
169pub const AT_inline = 0x20;
170pub const AT_is_optional = 0x21;
171pub const AT_lower_bound = 0x22;
172pub const AT_producer = 0x25;
173pub const AT_prototyped = 0x27;
174pub const AT_return_addr = 0x2a;
175pub const AT_start_scope = 0x2c;
176pub const AT_bit_stride = 0x2e;
177pub const AT_upper_bound = 0x2f;
178pub const AT_abstract_origin = 0x31;
179pub const AT_accessibility = 0x32;
180pub const AT_address_class = 0x33;
181pub const AT_artificial = 0x34;
182pub const AT_base_types = 0x35;
183pub const AT_calling_convention = 0x36;
184pub const AT_count = 0x37;
185pub const AT_data_member_location = 0x38;
186pub const AT_decl_column = 0x39;
187pub const AT_decl_file = 0x3a;
188pub const AT_decl_line = 0x3b;
189pub const AT_declaration = 0x3c;
190pub const AT_discr_list = 0x3d;
191pub const AT_encoding = 0x3e;
192pub const AT_external = 0x3f;
193pub const AT_frame_base = 0x40;
194pub const AT_friend = 0x41;
195pub const AT_identifier_case = 0x42;
196pub const AT_macro_info = 0x43;
197pub const AT_namelist_items = 0x44;
198pub const AT_priority = 0x45;
199pub const AT_segment = 0x46;
200pub const AT_specification = 0x47;
201pub const AT_static_link = 0x48;
202pub const AT_type = 0x49;
203pub const AT_use_location = 0x4a;
204pub const AT_variable_parameter = 0x4b;
205pub const AT_virtuality = 0x4c;
206pub const AT_vtable_elem_location = 0x4d;
207
208// DWARF 3 values.
209pub const AT_allocated = 0x4e;
210pub const AT_associated = 0x4f;
211pub const AT_data_location = 0x50;
212pub const AT_byte_stride = 0x51;
213pub const AT_entry_pc = 0x52;
214pub const AT_use_UTF8 = 0x53;
215pub const AT_extension = 0x54;
216pub const AT_ranges = 0x55;
217pub const AT_trampoline = 0x56;
218pub const AT_call_column = 0x57;
219pub const AT_call_file = 0x58;
220pub const AT_call_line = 0x59;
221pub const AT_description = 0x5a;
222pub const AT_binary_scale = 0x5b;
223pub const AT_decimal_scale = 0x5c;
224pub const AT_small = 0x5d;
225pub const AT_decimal_sign = 0x5e;
226pub const AT_digit_count = 0x5f;
227pub const AT_picture_string = 0x60;
228pub const AT_mutable = 0x61;
229pub const AT_threads_scaled = 0x62;
230pub const AT_explicit = 0x63;
231pub const AT_object_pointer = 0x64;
232pub const AT_endianity = 0x65;
233pub const AT_elemental = 0x66;
234pub const AT_pure = 0x67;
235pub const AT_recursive = 0x68;
236
237// DWARF 4.
238pub const AT_signature = 0x69;
239pub const AT_main_subprogram = 0x6a;
240pub const AT_data_bit_offset = 0x6b;
241pub const AT_const_expr = 0x6c;
242pub const AT_enum_class = 0x6d;
243pub const AT_linkage_name = 0x6e;
244
245// DWARF 5
246pub const AT_alignment = 0x88;
247
248pub const AT_lo_user = 0x2000; // Implementation-defined range start.
249pub const AT_hi_user = 0x3fff; // Implementation-defined range end.
250
251// SGI/MIPS extensions.
252pub const AT_MIPS_fde = 0x2001;
253pub const AT_MIPS_loop_begin = 0x2002;
254pub const AT_MIPS_tail_loop_begin = 0x2003;
255pub const AT_MIPS_epilog_begin = 0x2004;
256pub const AT_MIPS_loop_unroll_factor = 0x2005;
257pub const AT_MIPS_software_pipeline_depth = 0x2006;
258pub const AT_MIPS_linkage_name = 0x2007;
259pub const AT_MIPS_stride = 0x2008;
260pub const AT_MIPS_abstract_name = 0x2009;
261pub const AT_MIPS_clone_origin = 0x200a;
262pub const AT_MIPS_has_inlines = 0x200b;
263
264// HP extensions.
265pub const AT_HP_block_index = 0x2000;
266pub const AT_HP_unmodifiable = 0x2001; // Same as AT_MIPS_fde.
267pub const AT_HP_prologue = 0x2005; // Same as AT_MIPS_loop_unroll.
268pub const AT_HP_epilogue = 0x2008; // Same as AT_MIPS_stride.
269pub const AT_HP_actuals_stmt_list = 0x2010;
270pub const AT_HP_proc_per_section = 0x2011;
271pub const AT_HP_raw_data_ptr = 0x2012;
272pub const AT_HP_pass_by_reference = 0x2013;
273pub const AT_HP_opt_level = 0x2014;
274pub const AT_HP_prof_version_id = 0x2015;
275pub const AT_HP_opt_flags = 0x2016;
276pub const AT_HP_cold_region_low_pc = 0x2017;
277pub const AT_HP_cold_region_high_pc = 0x2018;
278pub const AT_HP_all_variables_modifiable = 0x2019;
279pub const AT_HP_linkage_name = 0x201a;
280pub const AT_HP_prof_flags = 0x201b; // In comp unit of procs_info for -g.
281pub const AT_HP_unit_name = 0x201f;
282pub const AT_HP_unit_size = 0x2020;
283pub const AT_HP_widened_byte_size = 0x2021;
284pub const AT_HP_definition_points = 0x2022;
285pub const AT_HP_default_location = 0x2023;
286pub const AT_HP_is_result_param = 0x2029;
287
288// GNU extensions.
289pub const AT_sf_names = 0x2101;
290pub const AT_src_info = 0x2102;
291pub const AT_mac_info = 0x2103;
292pub const AT_src_coords = 0x2104;
293pub const AT_body_begin = 0x2105;
294pub const AT_body_end = 0x2106;
295pub const AT_GNU_vector = 0x2107;
296// Thread-safety annotations.
297// See http://gcc.gnu.org/wiki/ThreadSafetyAnnotation .
298pub const AT_GNU_guarded_by = 0x2108;
299pub const AT_GNU_pt_guarded_by = 0x2109;
300pub const AT_GNU_guarded = 0x210a;
301pub const AT_GNU_pt_guarded = 0x210b;
302pub const AT_GNU_locks_excluded = 0x210c;
303pub const AT_GNU_exclusive_locks_required = 0x210d;
304pub const AT_GNU_shared_locks_required = 0x210e;
305// One-definition rule violation detection.
306// See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo .
307pub const AT_GNU_odr_signature = 0x210f;
308// Template template argument name.
309// See http://gcc.gnu.org/wiki/TemplateParmsDwarf .
310pub const AT_GNU_template_name = 0x2110;
311// The GNU call site extension.
312// See http://www.dwarfstd.org/ShowIssue.php?issue=100909.2&type=open .
313pub const AT_GNU_call_site_value = 0x2111;
314pub const AT_GNU_call_site_data_value = 0x2112;
315pub const AT_GNU_call_site_target = 0x2113;
316pub const AT_GNU_call_site_target_clobbered = 0x2114;
317pub const AT_GNU_tail_call = 0x2115;
318pub const AT_GNU_all_tail_call_sites = 0x2116;
319pub const AT_GNU_all_call_sites = 0x2117;
320pub const AT_GNU_all_source_call_sites = 0x2118;
321// Section offset into .debug_macro section.
322pub const AT_GNU_macros = 0x2119;
323// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
324pub const AT_GNU_dwo_name = 0x2130;
325pub const AT_GNU_dwo_id = 0x2131;
326pub const AT_GNU_ranges_base = 0x2132;
327pub const AT_GNU_addr_base = 0x2133;
328pub const AT_GNU_pubnames = 0x2134;
329pub const AT_GNU_pubtypes = 0x2135;
330// VMS extensions.
331pub const AT_VMS_rtnbeg_pd_address = 0x2201;
332// GNAT extensions.
333// GNAT descriptive type.
334// See http://gcc.gnu.org/wiki/DW_AT_GNAT_descriptive_type .
335pub const AT_use_GNAT_descriptive_type = 0x2301;
336pub const AT_GNAT_descriptive_type = 0x2302;
337// UPC extension.
338pub const AT_upc_threads_scaled = 0x3210;
339// PGI (STMicroelectronics) extensions.
340pub const AT_PGI_lbase = 0x3a00;
341pub const AT_PGI_soffset = 0x3a01;
342pub const AT_PGI_lstride = 0x3a02;
343
344pub const OP_addr = 0x03;
345pub const OP_deref = 0x06;
346pub const OP_const1u = 0x08;
347pub const OP_const1s = 0x09;
348pub const OP_const2u = 0x0a;
349pub const OP_const2s = 0x0b;
350pub const OP_const4u = 0x0c;
351pub const OP_const4s = 0x0d;
352pub const OP_const8u = 0x0e;
353pub const OP_const8s = 0x0f;
354pub const OP_constu = 0x10;
355pub const OP_consts = 0x11;
356pub const OP_dup = 0x12;
357pub const OP_drop = 0x13;
358pub const OP_over = 0x14;
359pub const OP_pick = 0x15;
360pub const OP_swap = 0x16;
361pub const OP_rot = 0x17;
362pub const OP_xderef = 0x18;
363pub const OP_abs = 0x19;
364pub const OP_and = 0x1a;
365pub const OP_div = 0x1b;
366pub const OP_minus = 0x1c;
367pub const OP_mod = 0x1d;
368pub const OP_mul = 0x1e;
369pub const OP_neg = 0x1f;
370pub const OP_not = 0x20;
371pub const OP_or = 0x21;
372pub const OP_plus = 0x22;
373pub const OP_plus_uconst = 0x23;
374pub const OP_shl = 0x24;
375pub const OP_shr = 0x25;
376pub const OP_shra = 0x26;
377pub const OP_xor = 0x27;
378pub const OP_bra = 0x28;
379pub const OP_eq = 0x29;
380pub const OP_ge = 0x2a;
381pub const OP_gt = 0x2b;
382pub const OP_le = 0x2c;
383pub const OP_lt = 0x2d;
384pub const OP_ne = 0x2e;
385pub const OP_skip = 0x2f;
386pub const OP_lit0 = 0x30;
387pub const OP_lit1 = 0x31;
388pub const OP_lit2 = 0x32;
389pub const OP_lit3 = 0x33;
390pub const OP_lit4 = 0x34;
391pub const OP_lit5 = 0x35;
392pub const OP_lit6 = 0x36;
393pub const OP_lit7 = 0x37;
394pub const OP_lit8 = 0x38;
395pub const OP_lit9 = 0x39;
396pub const OP_lit10 = 0x3a;
397pub const OP_lit11 = 0x3b;
398pub const OP_lit12 = 0x3c;
399pub const OP_lit13 = 0x3d;
400pub const OP_lit14 = 0x3e;
401pub const OP_lit15 = 0x3f;
402pub const OP_lit16 = 0x40;
403pub const OP_lit17 = 0x41;
404pub const OP_lit18 = 0x42;
405pub const OP_lit19 = 0x43;
406pub const OP_lit20 = 0x44;
407pub const OP_lit21 = 0x45;
408pub const OP_lit22 = 0x46;
409pub const OP_lit23 = 0x47;
410pub const OP_lit24 = 0x48;
411pub const OP_lit25 = 0x49;
412pub const OP_lit26 = 0x4a;
413pub const OP_lit27 = 0x4b;
414pub const OP_lit28 = 0x4c;
415pub const OP_lit29 = 0x4d;
416pub const OP_lit30 = 0x4e;
417pub const OP_lit31 = 0x4f;
418pub const OP_reg0 = 0x50;
419pub const OP_reg1 = 0x51;
420pub const OP_reg2 = 0x52;
421pub const OP_reg3 = 0x53;
422pub const OP_reg4 = 0x54;
423pub const OP_reg5 = 0x55;
424pub const OP_reg6 = 0x56;
425pub const OP_reg7 = 0x57;
426pub const OP_reg8 = 0x58;
427pub const OP_reg9 = 0x59;
428pub const OP_reg10 = 0x5a;
429pub const OP_reg11 = 0x5b;
430pub const OP_reg12 = 0x5c;
431pub const OP_reg13 = 0x5d;
432pub const OP_reg14 = 0x5e;
433pub const OP_reg15 = 0x5f;
434pub const OP_reg16 = 0x60;
435pub const OP_reg17 = 0x61;
436pub const OP_reg18 = 0x62;
437pub const OP_reg19 = 0x63;
438pub const OP_reg20 = 0x64;
439pub const OP_reg21 = 0x65;
440pub const OP_reg22 = 0x66;
441pub const OP_reg23 = 0x67;
442pub const OP_reg24 = 0x68;
443pub const OP_reg25 = 0x69;
444pub const OP_reg26 = 0x6a;
445pub const OP_reg27 = 0x6b;
446pub const OP_reg28 = 0x6c;
447pub const OP_reg29 = 0x6d;
448pub const OP_reg30 = 0x6e;
449pub const OP_reg31 = 0x6f;
450pub const OP_breg0 = 0x70;
451pub const OP_breg1 = 0x71;
452pub const OP_breg2 = 0x72;
453pub const OP_breg3 = 0x73;
454pub const OP_breg4 = 0x74;
455pub const OP_breg5 = 0x75;
456pub const OP_breg6 = 0x76;
457pub const OP_breg7 = 0x77;
458pub const OP_breg8 = 0x78;
459pub const OP_breg9 = 0x79;
460pub const OP_breg10 = 0x7a;
461pub const OP_breg11 = 0x7b;
462pub const OP_breg12 = 0x7c;
463pub const OP_breg13 = 0x7d;
464pub const OP_breg14 = 0x7e;
465pub const OP_breg15 = 0x7f;
466pub const OP_breg16 = 0x80;
467pub const OP_breg17 = 0x81;
468pub const OP_breg18 = 0x82;
469pub const OP_breg19 = 0x83;
470pub const OP_breg20 = 0x84;
471pub const OP_breg21 = 0x85;
472pub const OP_breg22 = 0x86;
473pub const OP_breg23 = 0x87;
474pub const OP_breg24 = 0x88;
475pub const OP_breg25 = 0x89;
476pub const OP_breg26 = 0x8a;
477pub const OP_breg27 = 0x8b;
478pub const OP_breg28 = 0x8c;
479pub const OP_breg29 = 0x8d;
480pub const OP_breg30 = 0x8e;
481pub const OP_breg31 = 0x8f;
482pub const OP_regx = 0x90;
483pub const OP_fbreg = 0x91;
484pub const OP_bregx = 0x92;
485pub const OP_piece = 0x93;
486pub const OP_deref_size = 0x94;
487pub const OP_xderef_size = 0x95;
488pub const OP_nop = 0x96;
489
490// DWARF 3 extensions.
491pub const OP_push_object_address = 0x97;
492pub const OP_call2 = 0x98;
493pub const OP_call4 = 0x99;
494pub const OP_call_ref = 0x9a;
495pub const OP_form_tls_address = 0x9b;
496pub const OP_call_frame_cfa = 0x9c;
497pub const OP_bit_piece = 0x9d;
498
499// DWARF 4 extensions.
500pub const OP_implicit_value = 0x9e;
501pub const OP_stack_value = 0x9f;
502
503pub const OP_lo_user = 0xe0; // Implementation-defined range start.
504pub const OP_hi_user = 0xff; // Implementation-defined range end.
505
506// GNU extensions.
507pub const OP_GNU_push_tls_address = 0xe0;
508// The following is for marking variables that are uninitialized.
509pub const OP_GNU_uninit = 0xf0;
510pub const OP_GNU_encoded_addr = 0xf1;
511// The GNU implicit pointer extension.
512// See http://www.dwarfstd.org/ShowIssue.php?issue=100831.1&type=open .
513pub const OP_GNU_implicit_pointer = 0xf2;
514// The GNU entry value extension.
515// See http://www.dwarfstd.org/ShowIssue.php?issue=100909.1&type=open .
516pub const OP_GNU_entry_value = 0xf3;
517// The GNU typed stack extension.
518// See http://www.dwarfstd.org/doc/040408.1.html .
519pub const OP_GNU_const_type = 0xf4;
520pub const OP_GNU_regval_type = 0xf5;
521pub const OP_GNU_deref_type = 0xf6;
522pub const OP_GNU_convert = 0xf7;
523pub const OP_GNU_reinterpret = 0xf9;
524// The GNU parameter ref extension.
525pub const OP_GNU_parameter_ref = 0xfa;
526// Extension for Fission. See http://gcc.gnu.org/wiki/DebugFission.
527pub const OP_GNU_addr_index = 0xfb;
528pub const OP_GNU_const_index = 0xfc;
529// HP extensions.
530pub const OP_HP_unknown = 0xe0; // Ouch, the same as GNU_push_tls_address.
531pub const OP_HP_is_value = 0xe1;
532pub const OP_HP_fltconst4 = 0xe2;
533pub const OP_HP_fltconst8 = 0xe3;
534pub const OP_HP_mod_range = 0xe4;
535pub const OP_HP_unmod_range = 0xe5;
536pub const OP_HP_tls = 0xe6;
537// PGI (STMicroelectronics) extensions.
538pub const OP_PGI_omp_thread_num = 0xf8;
539
540pub const ATE_void = 0x0;
541pub const ATE_address = 0x1;
542pub const ATE_boolean = 0x2;
543pub const ATE_complex_float = 0x3;
544pub const ATE_float = 0x4;
545pub const ATE_signed = 0x5;
546pub const ATE_signed_char = 0x6;
547pub const ATE_unsigned = 0x7;
548pub const ATE_unsigned_char = 0x8;
549
550// DWARF 3.
551pub const ATE_imaginary_float = 0x9;
552pub const ATE_packed_decimal = 0xa;
553pub const ATE_numeric_string = 0xb;
554pub const ATE_edited = 0xc;
555pub const ATE_signed_fixed = 0xd;
556pub const ATE_unsigned_fixed = 0xe;
557pub const ATE_decimal_float = 0xf;
558
559// DWARF 4.
560pub const ATE_UTF = 0x10;
561
562pub const ATE_lo_user = 0x80;
563pub const ATE_hi_user = 0xff;
564
565// HP extensions.
566pub const ATE_HP_float80 = 0x80; // Floating-point (80 bit).
567pub const ATE_HP_complex_float80 = 0x81; // Complex floating-point (80 bit).
568pub const ATE_HP_float128 = 0x82; // Floating-point (128 bit).
569pub const ATE_HP_complex_float128 = 0x83; // Complex fp (128 bit).
570pub const ATE_HP_floathpintel = 0x84; // Floating-point (82 bit IA64).
571pub const ATE_HP_imaginary_float80 = 0x85;
572pub const ATE_HP_imaginary_float128 = 0x86;
573pub const ATE_HP_VAX_float = 0x88; // F or G floating.
574pub const ATE_HP_VAX_float_d = 0x89; // D floating.
575pub const ATE_HP_packed_decimal = 0x8a; // Cobol.
576pub const ATE_HP_zoned_decimal = 0x8b; // Cobol.
577pub const ATE_HP_edited = 0x8c; // Cobol.
578pub const ATE_HP_signed_fixed = 0x8d; // Cobol.
579pub const ATE_HP_unsigned_fixed = 0x8e; // Cobol.
580pub const ATE_HP_VAX_complex_float = 0x8f; // F or G floating complex.
581pub const ATE_HP_VAX_complex_float_d = 0x90; // D floating complex.
582
583pub const CFA_advance_loc = 0x40;
584pub const CFA_offset = 0x80;
585pub const CFA_restore = 0xc0;
586pub const CFA_nop = 0x00;
587pub const CFA_set_loc = 0x01;
588pub const CFA_advance_loc1 = 0x02;
589pub const CFA_advance_loc2 = 0x03;
590pub const CFA_advance_loc4 = 0x04;
591pub const CFA_offset_extended = 0x05;
592pub const CFA_restore_extended = 0x06;
593pub const CFA_undefined = 0x07;
594pub const CFA_same_value = 0x08;
595pub const CFA_register = 0x09;
596pub const CFA_remember_state = 0x0a;
597pub const CFA_restore_state = 0x0b;
598pub const CFA_def_cfa = 0x0c;
599pub const CFA_def_cfa_register = 0x0d;
600pub const CFA_def_cfa_offset = 0x0e;
601
602// DWARF 3.
603pub const CFA_def_cfa_expression = 0x0f;
604pub const CFA_expression = 0x10;
605pub const CFA_offset_extended_sf = 0x11;
606pub const CFA_def_cfa_sf = 0x12;
607pub const CFA_def_cfa_offset_sf = 0x13;
608pub const CFA_val_offset = 0x14;
609pub const CFA_val_offset_sf = 0x15;
610pub const CFA_val_expression = 0x16;
611
612pub const CFA_lo_user = 0x1c;
613pub const CFA_hi_user = 0x3f;
614
615// SGI/MIPS specific.
616pub const CFA_MIPS_advance_loc8 = 0x1d;
617
618// GNU extensions.
619pub const CFA_GNU_window_save = 0x2d;
620pub const CFA_GNU_args_size = 0x2e;
621pub const CFA_GNU_negative_offset_extended = 0x2f;
622
623pub const CHILDREN_no = 0x00;
624pub const CHILDREN_yes = 0x01;
625
626pub const LNS_extended_op = 0x00;
627pub const LNS_copy = 0x01;
628pub const LNS_advance_pc = 0x02;
629pub const LNS_advance_line = 0x03;
630pub const LNS_set_file = 0x04;
631pub const LNS_set_column = 0x05;
632pub const LNS_negate_stmt = 0x06;
633pub const LNS_set_basic_block = 0x07;
634pub const LNS_const_add_pc = 0x08;
635pub const LNS_fixed_advance_pc = 0x09;
636pub const LNS_set_prologue_end = 0x0a;
637pub const LNS_set_epilogue_begin = 0x0b;
638pub const LNS_set_isa = 0x0c;
639
640pub const LNE_end_sequence = 0x01;
641pub const LNE_set_address = 0x02;
642pub const LNE_define_file = 0x03;
643pub const LNE_set_discriminator = 0x04;
644pub const LNE_lo_user = 0x80;
645pub const LNE_hi_user = 0xff;
646
647pub const LANG_C89 = 0x0001;
648pub const LANG_C = 0x0002;
649pub const LANG_Ada83 = 0x0003;
650pub const LANG_C_plus_plus = 0x0004;
651pub const LANG_Cobol74 = 0x0005;
652pub const LANG_Cobol85 = 0x0006;
653pub const LANG_Fortran77 = 0x0007;
654pub const LANG_Fortran90 = 0x0008;
655pub const LANG_Pascal83 = 0x0009;
656pub const LANG_Modula2 = 0x000a;
657pub const LANG_Java = 0x000b;
658pub const LANG_C99 = 0x000c;
659pub const LANG_Ada95 = 0x000d;
660pub const LANG_Fortran95 = 0x000e;
661pub const LANG_PLI = 0x000f;
662pub const LANG_ObjC = 0x0010;
663pub const LANG_ObjC_plus_plus = 0x0011;
664pub const LANG_UPC = 0x0012;
665pub const LANG_D = 0x0013;
666pub const LANG_Python = 0x0014;
667pub const LANG_Go = 0x0016;
668pub const LANG_C_plus_plus_11 = 0x001a;
669pub const LANG_Rust = 0x001c;
670pub const LANG_C11 = 0x001d;
671pub const LANG_C_plus_plus_14 = 0x0021;
672pub const LANG_Fortran03 = 0x0022;
673pub const LANG_Fortran08 = 0x0023;
674pub const LANG_lo_user = 0x8000;
675pub const LANG_hi_user = 0xffff;
676pub const LANG_Mips_Assembler = 0x8001;
677pub const LANG_Upc = 0x8765;
678pub const LANG_HP_Bliss = 0x8003;
679pub const LANG_HP_Basic91 = 0x8004;
680pub const LANG_HP_Pascal91 = 0x8005;
681pub const LANG_HP_IMacro = 0x8006;
682pub const LANG_HP_Assembler = 0x8007;
683
684pub const UT_compile = 0x01;
685pub const UT_type = 0x02;
686pub const UT_partial = 0x03;
687pub const UT_skeleton = 0x04;
688pub const UT_split_compile = 0x05;
689pub const UT_split_type = 0x06;
690pub const UT_lo_user = 0x80;
691pub const UT_hi_user = 0xff;
692
693pub const LNCT_path = 0x1;
694pub const LNCT_directory_index = 0x2;
695pub const LNCT_timestamp = 0x3;
696pub const LNCT_size = 0x4;
697pub const LNCT_MD5 = 0x5;
698pub const LNCT_lo_user = 0x2000;
699pub const LNCT_hi_user = 0x3fff;
lib/std/dynamic_library.zig+13-13
...@@ -115,7 +115,7 @@ pub const ElfDynLib = struct {...@@ -115,7 +115,7 @@ pub const ElfDynLib = struct {
115115
116 /// Trusts the file. Malicious file will be able to execute arbitrary code.116 /// Trusts the file. Malicious file will be able to execute arbitrary code.
117 pub fn open(path: []const u8) !ElfDynLib {117 pub fn open(path: []const u8) !ElfDynLib {
118 const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC);118 const fd = try os.open(path, 0, os.O.RDONLY | os.O.CLOEXEC);
119 defer os.close(fd);119 defer os.close(fd);
120120
121 const stat = try os.fstat(fd);121 const stat = try os.fstat(fd);
...@@ -126,8 +126,8 @@ pub const ElfDynLib = struct {...@@ -126,8 +126,8 @@ pub const ElfDynLib = struct {
126 const file_bytes = try os.mmap(126 const file_bytes = try os.mmap(
127 null,127 null,
128 mem.alignForward(size, mem.page_size),128 mem.alignForward(size, mem.page_size),
129 os.PROT_READ,129 os.PROT.READ,
130 os.MAP_PRIVATE,130 os.MAP.PRIVATE,
131 fd,131 fd,
132 0,132 0,
133 );133 );
...@@ -160,12 +160,12 @@ pub const ElfDynLib = struct {...@@ -160,12 +160,12 @@ pub const ElfDynLib = struct {
160 }160 }
161 const dynv = maybe_dynv orelse return error.MissingDynamicLinkingInformation;161 const dynv = maybe_dynv orelse return error.MissingDynamicLinkingInformation;
162162
163 // Reserve the entire range (with no permissions) so that we can do MAP_FIXED below.163 // Reserve the entire range (with no permissions) so that we can do MAP.FIXED below.
164 const all_loaded_mem = try os.mmap(164 const all_loaded_mem = try os.mmap(
165 null,165 null,
166 virt_addr_end,166 virt_addr_end,
167 os.PROT_NONE,167 os.PROT.NONE,
168 os.MAP_PRIVATE | os.MAP_ANONYMOUS,168 os.MAP.PRIVATE | os.MAP.ANONYMOUS,
169 -1,169 -1,
170 0,170 0,
171 );171 );
...@@ -197,7 +197,7 @@ pub const ElfDynLib = struct {...@@ -197,7 +197,7 @@ pub const ElfDynLib = struct {
197 ptr,197 ptr,
198 extended_memsz,198 extended_memsz,
199 prot,199 prot,
200 os.MAP_PRIVATE | os.MAP_FIXED,200 os.MAP.PRIVATE | os.MAP.FIXED,
201 fd,201 fd,
202 ph.p_offset - extra_bytes,202 ph.p_offset - extra_bytes,
203 );203 );
...@@ -206,7 +206,7 @@ pub const ElfDynLib = struct {...@@ -206,7 +206,7 @@ pub const ElfDynLib = struct {
206 ptr,206 ptr,
207 extended_memsz,207 extended_memsz,
208 prot,208 prot,
209 os.MAP_PRIVATE | os.MAP_FIXED | os.MAP_ANONYMOUS,209 os.MAP.PRIVATE | os.MAP.FIXED | os.MAP.ANONYMOUS,
210 -1,210 -1,
211 0,211 0,
212 );212 );
...@@ -294,10 +294,10 @@ pub const ElfDynLib = struct {...@@ -294,10 +294,10 @@ pub const ElfDynLib = struct {
294 }294 }
295295
296 fn elfToMmapProt(elf_prot: u64) u32 {296 fn elfToMmapProt(elf_prot: u64) u32 {
297 var result: u32 = os.PROT_NONE;297 var result: u32 = os.PROT.NONE;
298 if ((elf_prot & elf.PF_R) != 0) result |= os.PROT_READ;298 if ((elf_prot & elf.PF_R) != 0) result |= os.PROT.READ;
299 if ((elf_prot & elf.PF_W) != 0) result |= os.PROT_WRITE;299 if ((elf_prot & elf.PF_W) != 0) result |= os.PROT.WRITE;
300 if ((elf_prot & elf.PF_X) != 0) result |= os.PROT_EXEC;300 if ((elf_prot & elf.PF_X) != 0) result |= os.PROT.EXEC;
301 return result;301 return result;
302 }302 }
303};303};
...@@ -373,7 +373,7 @@ pub const DlDynlib = struct {...@@ -373,7 +373,7 @@ pub const DlDynlib = struct {
373373
374 pub fn openZ(path_c: [*:0]const u8) !DlDynlib {374 pub fn openZ(path_c: [*:0]const u8) !DlDynlib {
375 return DlDynlib{375 return DlDynlib{
376 .handle = system.dlopen(path_c, system.RTLD_LAZY) orelse {376 .handle = system.dlopen(path_c, system.RTLD.LAZY) orelse {
377 return error.FileNotFound;377 return error.FileNotFound;
378 },378 },
379 };379 };
lib/std/event.zig+1-1
...@@ -9,7 +9,7 @@ pub const RwLocked = @import("event/rwlocked.zig").RwLocked;...@@ -9,7 +9,7 @@ pub const RwLocked = @import("event/rwlocked.zig").RwLocked;
9pub const Loop = @import("event/loop.zig").Loop;9pub const Loop = @import("event/loop.zig").Loop;
10pub const WaitGroup = @import("event/wait_group.zig").WaitGroup;10pub const WaitGroup = @import("event/wait_group.zig").WaitGroup;
1111
12test "import event tests" {12test {
13 _ = @import("event/channel.zig");13 _ = @import("event/channel.zig");
14 _ = @import("event/future.zig");14 _ = @import("event/future.zig");
15 _ = @import("event/group.zig");15 _ = @import("event/group.zig");
lib/std/event/loop.zig+104-41
...@@ -222,27 +222,27 @@ pub const Loop = struct {...@@ -222,27 +222,27 @@ pub const Loop = struct {
222 .handle = undefined,222 .handle = undefined,
223 .overlapped = ResumeNode.overlapped_init,223 .overlapped = ResumeNode.overlapped_init,
224 },224 },
225 .eventfd = try os.eventfd(1, os.EFD_CLOEXEC | os.EFD_NONBLOCK),225 .eventfd = try os.eventfd(1, os.linux.EFD.CLOEXEC | os.linux.EFD.NONBLOCK),
226 .epoll_op = os.EPOLL_CTL_ADD,226 .epoll_op = os.linux.EPOLL.CTL_ADD,
227 },227 },
228 .next = undefined,228 .next = undefined,
229 };229 };
230 self.available_eventfd_resume_nodes.push(eventfd_node);230 self.available_eventfd_resume_nodes.push(eventfd_node);
231 }231 }
232232
233 self.os_data.epollfd = try os.epoll_create1(os.EPOLL_CLOEXEC);233 self.os_data.epollfd = try os.epoll_create1(os.linux.EPOLL.CLOEXEC);
234 errdefer os.close(self.os_data.epollfd);234 errdefer os.close(self.os_data.epollfd);
235235
236 self.os_data.final_eventfd = try os.eventfd(0, os.EFD_CLOEXEC | os.EFD_NONBLOCK);236 self.os_data.final_eventfd = try os.eventfd(0, os.linux.EFD.CLOEXEC | os.linux.EFD.NONBLOCK);
237 errdefer os.close(self.os_data.final_eventfd);237 errdefer os.close(self.os_data.final_eventfd);
238238
239 self.os_data.final_eventfd_event = os.epoll_event{239 self.os_data.final_eventfd_event = os.linux.epoll_event{
240 .events = os.EPOLLIN,240 .events = os.linux.EPOLL.IN,
241 .data = os.epoll_data{ .ptr = @ptrToInt(&self.final_resume_node) },241 .data = os.linux.epoll_data{ .ptr = @ptrToInt(&self.final_resume_node) },
242 };242 };
243 try os.epoll_ctl(243 try os.epoll_ctl(
244 self.os_data.epollfd,244 self.os_data.epollfd,
245 os.EPOLL_CTL_ADD,245 os.linux.EPOLL.CTL_ADD,
246 self.os_data.final_eventfd,246 self.os_data.final_eventfd,
247 &self.os_data.final_eventfd_event,247 &self.os_data.final_eventfd_event,
248 );248 );
...@@ -266,7 +266,72 @@ pub const Loop = struct {...@@ -266,7 +266,72 @@ pub const Loop = struct {
266 self.extra_threads[extra_thread_index] = try Thread.spawn(.{}, workerRun, .{self});266 self.extra_threads[extra_thread_index] = try Thread.spawn(.{}, workerRun, .{self});
267 }267 }
268 },268 },
269 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {269 .macos, .freebsd, .netbsd, .dragonfly => {
270 self.os_data.kqfd = try os.kqueue();
271 errdefer os.close(self.os_data.kqfd);
272
273 const empty_kevs = &[0]os.Kevent{};
274
275 for (self.eventfd_resume_nodes) |*eventfd_node, i| {
276 eventfd_node.* = std.atomic.Stack(ResumeNode.EventFd).Node{
277 .data = ResumeNode.EventFd{
278 .base = ResumeNode{
279 .id = ResumeNode.Id.EventFd,
280 .handle = undefined,
281 .overlapped = ResumeNode.overlapped_init,
282 },
283 // this one is for sending events
284 .kevent = os.Kevent{
285 .ident = i,
286 .filter = os.system.EVFILT_USER,
287 .flags = os.system.EV_CLEAR | os.system.EV_ADD | os.system.EV_DISABLE,
288 .fflags = 0,
289 .data = 0,
290 .udata = @ptrToInt(&eventfd_node.data.base),
291 },
292 },
293 .next = undefined,
294 };
295 self.available_eventfd_resume_nodes.push(eventfd_node);
296 const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.data.kevent);
297 _ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null);
298 eventfd_node.data.kevent.flags = os.system.EV_CLEAR | os.system.EV_ENABLE;
299 eventfd_node.data.kevent.fflags = os.system.NOTE_TRIGGER;
300 }
301
302 // Pre-add so that we cannot get error.SystemResources
303 // later when we try to activate it.
304 self.os_data.final_kevent = os.Kevent{
305 .ident = extra_thread_count,
306 .filter = os.system.EVFILT_USER,
307 .flags = os.system.EV_ADD | os.system.EV_DISABLE,
308 .fflags = 0,
309 .data = 0,
310 .udata = @ptrToInt(&self.final_resume_node),
311 };
312 const final_kev_arr = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
313 _ = try os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null);
314 self.os_data.final_kevent.flags = os.system.EV_ENABLE;
315 self.os_data.final_kevent.fflags = os.system.NOTE_TRIGGER;
316
317 if (builtin.single_threaded) {
318 assert(extra_thread_count == 0);
319 return;
320 }
321
322 var extra_thread_index: usize = 0;
323 errdefer {
324 _ = os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null) catch unreachable;
325 while (extra_thread_index != 0) {
326 extra_thread_index -= 1;
327 self.extra_threads[extra_thread_index].join();
328 }
329 }
330 while (extra_thread_index < extra_thread_count) : (extra_thread_index += 1) {
331 self.extra_threads[extra_thread_index] = try Thread.spawn(.{}, workerRun, .{self});
332 }
333 },
334 .openbsd => {
270 self.os_data.kqfd = try os.kqueue();335 self.os_data.kqfd = try os.kqueue();
271 errdefer os.close(self.os_data.kqfd);336 errdefer os.close(self.os_data.kqfd);
272337
...@@ -283,8 +348,8 @@ pub const Loop = struct {...@@ -283,8 +348,8 @@ pub const Loop = struct {
283 // this one is for sending events348 // this one is for sending events
284 .kevent = os.Kevent{349 .kevent = os.Kevent{
285 .ident = i,350 .ident = i,
286 .filter = os.EVFILT_USER,351 .filter = os.system.EVFILT_TIMER,
287 .flags = os.EV_CLEAR | os.EV_ADD | os.EV_DISABLE,352 .flags = os.system.EV_CLEAR | os.system.EV_ADD | os.system.EV_DISABLE | os.system.EV_ONESHOT,
288 .fflags = 0,353 .fflags = 0,
289 .data = 0,354 .data = 0,
290 .udata = @ptrToInt(&eventfd_node.data.base),355 .udata = @ptrToInt(&eventfd_node.data.base),
...@@ -295,24 +360,22 @@ pub const Loop = struct {...@@ -295,24 +360,22 @@ pub const Loop = struct {
295 self.available_eventfd_resume_nodes.push(eventfd_node);360 self.available_eventfd_resume_nodes.push(eventfd_node);
296 const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.data.kevent);361 const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.data.kevent);
297 _ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null);362 _ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null);
298 eventfd_node.data.kevent.flags = os.EV_CLEAR | os.EV_ENABLE;363 eventfd_node.data.kevent.flags = os.system.EV_CLEAR | os.system.EV_ENABLE;
299 eventfd_node.data.kevent.fflags = os.NOTE_TRIGGER;
300 }364 }
301365
302 // Pre-add so that we cannot get error.SystemResources366 // Pre-add so that we cannot get error.SystemResources
303 // later when we try to activate it.367 // later when we try to activate it.
304 self.os_data.final_kevent = os.Kevent{368 self.os_data.final_kevent = os.Kevent{
305 .ident = extra_thread_count,369 .ident = extra_thread_count,
306 .filter = os.EVFILT_USER,370 .filter = os.system.EVFILT_TIMER,
307 .flags = os.EV_ADD | os.EV_DISABLE,371 .flags = os.system.EV_ADD | os.system.EV_ONESHOT | os.system.EV_DISABLE,
308 .fflags = 0,372 .fflags = 0,
309 .data = 0,373 .data = 0,
310 .udata = @ptrToInt(&self.final_resume_node),374 .udata = @ptrToInt(&self.final_resume_node),
311 };375 };
312 const final_kev_arr = @as(*const [1]os.Kevent, &self.os_data.final_kevent);376 const final_kev_arr = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
313 _ = try os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null);377 _ = try os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null);
314 self.os_data.final_kevent.flags = os.EV_ENABLE;378 self.os_data.final_kevent.flags = os.system.EV_ENABLE;
315 self.os_data.final_kevent.fflags = os.NOTE_TRIGGER;
316379
317 if (builtin.single_threaded) {380 if (builtin.single_threaded) {
318 assert(extra_thread_count == 0);381 assert(extra_thread_count == 0);
...@@ -404,19 +467,19 @@ pub const Loop = struct {...@@ -404,19 +467,19 @@ pub const Loop = struct {
404 /// resume_node must live longer than the anyframe that it holds a reference to.467 /// resume_node must live longer than the anyframe that it holds a reference to.
405 /// flags must contain EPOLLET468 /// flags must contain EPOLLET
406 pub fn linuxAddFd(self: *Loop, fd: i32, resume_node: *ResumeNode, flags: u32) !void {469 pub fn linuxAddFd(self: *Loop, fd: i32, resume_node: *ResumeNode, flags: u32) !void {
407 assert(flags & os.EPOLLET == os.EPOLLET);470 assert(flags & os.linux.EPOLL.ET == os.linux.EPOLL.ET);
408 self.beginOneEvent();471 self.beginOneEvent();
409 errdefer self.finishOneEvent();472 errdefer self.finishOneEvent();
410 try self.linuxModFd(473 try self.linuxModFd(
411 fd,474 fd,
412 os.EPOLL_CTL_ADD,475 os.linux.EPOLL.CTL_ADD,
413 flags,476 flags,
414 resume_node,477 resume_node,
415 );478 );
416 }479 }
417480
418 pub fn linuxModFd(self: *Loop, fd: i32, op: u32, flags: u32, resume_node: *ResumeNode) !void {481 pub fn linuxModFd(self: *Loop, fd: i32, op: u32, flags: u32, resume_node: *ResumeNode) !void {
419 assert(flags & os.EPOLLET == os.EPOLLET);482 assert(flags & os.linux.EPOLL.ET == os.linux.EPOLL.ET);
420 var ev = os.linux.epoll_event{483 var ev = os.linux.epoll_event{
421 .events = flags,484 .events = flags,
422 .data = os.linux.epoll_data{ .ptr = @ptrToInt(resume_node) },485 .data = os.linux.epoll_data{ .ptr = @ptrToInt(resume_node) },
...@@ -425,13 +488,13 @@ pub const Loop = struct {...@@ -425,13 +488,13 @@ pub const Loop = struct {
425 }488 }
426489
427 pub fn linuxRemoveFd(self: *Loop, fd: i32) void {490 pub fn linuxRemoveFd(self: *Loop, fd: i32) void {
428 os.epoll_ctl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, null) catch {};491 os.epoll_ctl(self.os_data.epollfd, os.linux.EPOLL.CTL_DEL, fd, null) catch {};
429 self.finishOneEvent();492 self.finishOneEvent();
430 }493 }
431494
432 pub fn linuxWaitFd(self: *Loop, fd: i32, flags: u32) void {495 pub fn linuxWaitFd(self: *Loop, fd: i32, flags: u32) void {
433 assert(flags & os.EPOLLET == os.EPOLLET);496 assert(flags & os.linux.EPOLL.ET == os.linux.EPOLL.ET);
434 assert(flags & os.EPOLLONESHOT == os.EPOLLONESHOT);497 assert(flags & os.linux.EPOLL.ONESHOT == os.linux.EPOLL.ONESHOT);
435 var resume_node = ResumeNode.Basic{498 var resume_node = ResumeNode.Basic{
436 .base = ResumeNode{499 .base = ResumeNode{
437 .id = .Basic,500 .id = .Basic,
...@@ -457,8 +520,8 @@ pub const Loop = struct {...@@ -457,8 +520,8 @@ pub const Loop = struct {
457 // Fall back to a blocking poll(). Ideally this codepath is never hit, since520 // Fall back to a blocking poll(). Ideally this codepath is never hit, since
458 // epoll should be just fine. But this is better than incorrect behavior.521 // epoll should be just fine. But this is better than incorrect behavior.
459 var poll_flags: i16 = 0;522 var poll_flags: i16 = 0;
460 if ((flags & os.EPOLLIN) != 0) poll_flags |= os.POLLIN;523 if ((flags & os.linux.EPOLL.IN) != 0) poll_flags |= os.POLL.IN;
461 if ((flags & os.EPOLLOUT) != 0) poll_flags |= os.POLLOUT;524 if ((flags & os.linux.EPOLL.OUT) != 0) poll_flags |= os.POLL.OUT;
462 var pfd = [1]os.pollfd{os.pollfd{525 var pfd = [1]os.pollfd{os.pollfd{
463 .fd = fd,526 .fd = fd,
464 .events = poll_flags,527 .events = poll_flags,
...@@ -484,10 +547,10 @@ pub const Loop = struct {...@@ -484,10 +547,10 @@ pub const Loop = struct {
484 pub fn waitUntilFdReadable(self: *Loop, fd: os.fd_t) void {547 pub fn waitUntilFdReadable(self: *Loop, fd: os.fd_t) void {
485 switch (builtin.os.tag) {548 switch (builtin.os.tag) {
486 .linux => {549 .linux => {
487 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLIN);550 self.linuxWaitFd(fd, os.linux.EPOLL.ET | os.linux.EPOLL.ONESHOT | os.linux.EPOLL.IN);
488 },551 },
489 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {552 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
490 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);553 self.bsdWaitKev(@intCast(usize, fd), os.system.EVFILT_READ, os.system.EV_ONESHOT);
491 },554 },
492 else => @compileError("Unsupported OS"),555 else => @compileError("Unsupported OS"),
493 }556 }
...@@ -496,10 +559,10 @@ pub const Loop = struct {...@@ -496,10 +559,10 @@ pub const Loop = struct {
496 pub fn waitUntilFdWritable(self: *Loop, fd: os.fd_t) void {559 pub fn waitUntilFdWritable(self: *Loop, fd: os.fd_t) void {
497 switch (builtin.os.tag) {560 switch (builtin.os.tag) {
498 .linux => {561 .linux => {
499 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT);562 self.linuxWaitFd(fd, os.linux.EPOLL.ET | os.linux.EPOLL.ONESHOT | os.linux.EPOLL.OUT);
500 },563 },
501 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {564 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
502 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);565 self.bsdWaitKev(@intCast(usize, fd), os.system.EVFILT_WRITE, os.system.EV_ONESHOT);
503 },566 },
504 else => @compileError("Unsupported OS"),567 else => @compileError("Unsupported OS"),
505 }568 }
...@@ -508,11 +571,11 @@ pub const Loop = struct {...@@ -508,11 +571,11 @@ pub const Loop = struct {
508 pub fn waitUntilFdWritableOrReadable(self: *Loop, fd: os.fd_t) void {571 pub fn waitUntilFdWritableOrReadable(self: *Loop, fd: os.fd_t) void {
509 switch (builtin.os.tag) {572 switch (builtin.os.tag) {
510 .linux => {573 .linux => {
511 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);574 self.linuxWaitFd(fd, os.linux.EPOLL.ET | os.linux.EPOLL.ONESHOT | os.linux.EPOLL.OUT | os.linux.EPOLL.IN);
512 },575 },
513 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {576 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
514 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);577 self.bsdWaitKev(@intCast(usize, fd), os.system.EVFILT_READ, os.system.EV_ONESHOT);
515 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);578 self.bsdWaitKev(@intCast(usize, fd), os.system.EVFILT_WRITE, os.system.EV_ONESHOT);
516 },579 },
517 else => @compileError("Unsupported OS"),580 else => @compileError("Unsupported OS"),
518 }581 }
...@@ -530,7 +593,7 @@ pub const Loop = struct {...@@ -530,7 +593,7 @@ pub const Loop = struct {
530593
531 defer {594 defer {
532 // If the kevent was set to be ONESHOT, it doesn't need to be deleted manually.595 // If the kevent was set to be ONESHOT, it doesn't need to be deleted manually.
533 if (flags & os.EV_ONESHOT != 0) {596 if (flags & os.system.EV_ONESHOT != 0) {
534 self.bsdRemoveKev(ident, filter);597 self.bsdRemoveKev(ident, filter);
535 }598 }
536 }599 }
...@@ -547,7 +610,7 @@ pub const Loop = struct {...@@ -547,7 +610,7 @@ pub const Loop = struct {
547 var kev = [1]os.Kevent{os.Kevent{610 var kev = [1]os.Kevent{os.Kevent{
548 .ident = ident,611 .ident = ident,
549 .filter = filter,612 .filter = filter,
550 .flags = os.EV_ADD | os.EV_ENABLE | os.EV_CLEAR | flags,613 .flags = os.system.EV_ADD | os.system.EV_ENABLE | os.system.EV_CLEAR | flags,
551 .fflags = 0,614 .fflags = 0,
552 .data = 0,615 .data = 0,
553 .udata = @ptrToInt(&resume_node.base),616 .udata = @ptrToInt(&resume_node.base),
...@@ -560,7 +623,7 @@ pub const Loop = struct {...@@ -560,7 +623,7 @@ pub const Loop = struct {
560 var kev = [1]os.Kevent{os.Kevent{623 var kev = [1]os.Kevent{os.Kevent{
561 .ident = ident,624 .ident = ident,
562 .filter = filter,625 .filter = filter,
563 .flags = os.EV_DELETE,626 .flags = os.system.EV_DELETE,
564 .fflags = 0,627 .fflags = 0,
565 .data = 0,628 .data = 0,
566 .udata = 0,629 .udata = 0,
...@@ -590,8 +653,8 @@ pub const Loop = struct {...@@ -590,8 +653,8 @@ pub const Loop = struct {
590 },653 },
591 .linux => {654 .linux => {
592 // the pending count is already accounted for655 // the pending count is already accounted for
593 const epoll_events = os.EPOLLONESHOT | os.linux.EPOLLIN | os.linux.EPOLLOUT |656 const epoll_events = os.linux.EPOLL.ONESHOT | os.linux.EPOLL.IN | os.linux.EPOLL.OUT |
594 os.linux.EPOLLET;657 os.linux.EPOLL.ET;
595 self.linuxModFd(658 self.linuxModFd(
596 eventfd_node.eventfd,659 eventfd_node.eventfd,
597 eventfd_node.epoll_op,660 eventfd_node.epoll_op,
...@@ -903,12 +966,12 @@ pub const Loop = struct {...@@ -903,12 +966,12 @@ pub const Loop = struct {
903 /// will return a value greater than was supplied to the call.966 /// will return a value greater than was supplied to the call.
904 addr_size: *os.socklen_t,967 addr_size: *os.socklen_t,
905 /// The following values can be bitwise ORed in flags to obtain different behavior:968 /// The following values can be bitwise ORed in flags to obtain different behavior:
906 /// * `SOCK_CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the969 /// * `SOCK.CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the
907 /// description of the `O_CLOEXEC` flag in `open` for reasons why this may be useful.970 /// description of the `O.CLOEXEC` flag in `open` for reasons why this may be useful.
908 flags: u32,971 flags: u32,
909 ) os.AcceptError!os.socket_t {972 ) os.AcceptError!os.socket_t {
910 while (true) {973 while (true) {
911 return os.accept(sockfd, addr, addr_size, flags | os.SOCK_NONBLOCK) catch |err| switch (err) {974 return os.accept(sockfd, addr, addr_size, flags | os.SOCK.NONBLOCK) catch |err| switch (err) {
912 error.WouldBlock => {975 error.WouldBlock => {
913 self.waitUntilFdReadable(sockfd);976 self.waitUntilFdReadable(sockfd);
914 continue;977 continue;
...@@ -1344,7 +1407,7 @@ pub const Loop = struct {...@@ -1344,7 +1407,7 @@ pub const Loop = struct {
1344 .Stop => return,1407 .Stop => return,
1345 .EventFd => {1408 .EventFd => {
1346 const event_fd_node = @fieldParentPtr(ResumeNode.EventFd, "base", resume_node);1409 const event_fd_node = @fieldParentPtr(ResumeNode.EventFd, "base", resume_node);
1347 event_fd_node.epoll_op = os.EPOLL_CTL_MOD;1410 event_fd_node.epoll_op = os.linux.EPOLL.CTL_MOD;
1348 const stack_node = @fieldParentPtr(std.atomic.Stack(ResumeNode.EventFd).Node, "data", event_fd_node);1411 const stack_node = @fieldParentPtr(std.atomic.Stack(ResumeNode.EventFd).Node, "data", event_fd_node);
1349 self.available_eventfd_resume_nodes.push(stack_node);1412 self.available_eventfd_resume_nodes.push(stack_node);
1350 },1413 },
lib/std/event/rwlock.zig+1
...@@ -4,6 +4,7 @@ const assert = std.debug.assert;...@@ -4,6 +4,7 @@ const assert = std.debug.assert;
4const testing = std.testing;4const testing = std.testing;
5const mem = std.mem;5const mem = std.mem;
6const Loop = std.event.Loop;6const Loop = std.event.Loop;
7const Allocator = std.mem.Allocator;
78
8/// Thread-safe async/await lock.9/// Thread-safe async/await lock.
9/// Functions which are waiting for the lock are suspended, and10/// Functions which are waiting for the lock are suspended, and
lib/std/fmt.zig+1-1
...@@ -902,7 +902,7 @@ pub fn formatText(...@@ -902,7 +902,7 @@ pub fn formatText(
902 } else if (comptime std.mem.eql(u8, fmt, "Z")) {902 } else if (comptime std.mem.eql(u8, fmt, "Z")) {
903 @compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead");903 @compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead");
904 } else {904 } else {
905 @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");905 @compileError("Unsupported format string '" ++ fmt ++ "' when formatting text");
906 }906 }
907}907}
908908
lib/std/fs.zig+154-153
...@@ -304,7 +304,7 @@ pub const Dir = struct {...@@ -304,7 +304,7 @@ pub const Dir = struct {
304 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {304 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {
305 dir: Dir,305 dir: Dir,
306 seek: i64,306 seek: i64,
307 buf: [8192]u8, // TODO align(@alignOf(os.dirent)),307 buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)),
308 index: usize,308 index: usize,
309 end_index: usize,309 end_index: usize,
310310
...@@ -344,7 +344,7 @@ pub const Dir = struct {...@@ -344,7 +344,7 @@ pub const Dir = struct {
344 self.index = 0;344 self.index = 0;
345 self.end_index = @intCast(usize, rc);345 self.end_index = @intCast(usize, rc);
346 }346 }
347 const darwin_entry = @ptrCast(*align(1) os.dirent, &self.buf[self.index]);347 const darwin_entry = @ptrCast(*align(1) os.system.dirent, &self.buf[self.index]);
348 const next_index = self.index + darwin_entry.reclen();348 const next_index = self.index + darwin_entry.reclen();
349 self.index = next_index;349 self.index = next_index;
350350
...@@ -355,14 +355,14 @@ pub const Dir = struct {...@@ -355,14 +355,14 @@ pub const Dir = struct {
355 }355 }
356356
357 const entry_kind = switch (darwin_entry.d_type) {357 const entry_kind = switch (darwin_entry.d_type) {
358 os.DT_BLK => Entry.Kind.BlockDevice,358 os.DT.BLK => Entry.Kind.BlockDevice,
359 os.DT_CHR => Entry.Kind.CharacterDevice,359 os.DT.CHR => Entry.Kind.CharacterDevice,
360 os.DT_DIR => Entry.Kind.Directory,360 os.DT.DIR => Entry.Kind.Directory,
361 os.DT_FIFO => Entry.Kind.NamedPipe,361 os.DT.FIFO => Entry.Kind.NamedPipe,
362 os.DT_LNK => Entry.Kind.SymLink,362 os.DT.LNK => Entry.Kind.SymLink,
363 os.DT_REG => Entry.Kind.File,363 os.DT.REG => Entry.Kind.File,
364 os.DT_SOCK => Entry.Kind.UnixDomainSocket,364 os.DT.SOCK => Entry.Kind.UnixDomainSocket,
365 os.DT_WHT => Entry.Kind.Whiteout,365 os.DT.WHT => Entry.Kind.Whiteout,
366 else => Entry.Kind.Unknown,366 else => Entry.Kind.Unknown,
367 };367 };
368 return Entry{368 return Entry{
...@@ -391,7 +391,7 @@ pub const Dir = struct {...@@ -391,7 +391,7 @@ pub const Dir = struct {
391 self.index = 0;391 self.index = 0;
392 self.end_index = @intCast(usize, rc);392 self.end_index = @intCast(usize, rc);
393 }393 }
394 const bsd_entry = @ptrCast(*align(1) os.dirent, &self.buf[self.index]);394 const bsd_entry = @ptrCast(*align(1) os.system.dirent, &self.buf[self.index]);
395 const next_index = self.index + bsd_entry.reclen();395 const next_index = self.index + bsd_entry.reclen();
396 self.index = next_index;396 self.index = next_index;
397397
...@@ -409,14 +409,14 @@ pub const Dir = struct {...@@ -409,14 +409,14 @@ pub const Dir = struct {
409 }409 }
410410
411 const entry_kind = switch (bsd_entry.d_type) {411 const entry_kind = switch (bsd_entry.d_type) {
412 os.DT_BLK => Entry.Kind.BlockDevice,412 os.DT.BLK => Entry.Kind.BlockDevice,
413 os.DT_CHR => Entry.Kind.CharacterDevice,413 os.DT.CHR => Entry.Kind.CharacterDevice,
414 os.DT_DIR => Entry.Kind.Directory,414 os.DT.DIR => Entry.Kind.Directory,
415 os.DT_FIFO => Entry.Kind.NamedPipe,415 os.DT.FIFO => Entry.Kind.NamedPipe,
416 os.DT_LNK => Entry.Kind.SymLink,416 os.DT.LNK => Entry.Kind.SymLink,
417 os.DT_REG => Entry.Kind.File,417 os.DT.REG => Entry.Kind.File,
418 os.DT_SOCK => Entry.Kind.UnixDomainSocket,418 os.DT.SOCK => Entry.Kind.UnixDomainSocket,
419 os.DT_WHT => Entry.Kind.Whiteout,419 os.DT.WHT => Entry.Kind.Whiteout,
420 else => Entry.Kind.Unknown,420 else => Entry.Kind.Unknown,
421 };421 };
422 return Entry{422 return Entry{
...@@ -462,7 +462,7 @@ pub const Dir = struct {...@@ -462,7 +462,7 @@ pub const Dir = struct {
462 self.index = 0;462 self.index = 0;
463 self.end_index = @intCast(usize, rc);463 self.end_index = @intCast(usize, rc);
464 }464 }
465 const haiku_entry = @ptrCast(*align(1) os.dirent, &self.buf[self.index]);465 const haiku_entry = @ptrCast(*align(1) os.system.dirent, &self.buf[self.index]);
466 const next_index = self.index + haiku_entry.reclen();466 const next_index = self.index + haiku_entry.reclen();
467 self.index = next_index;467 self.index = next_index;
468 const name = mem.spanZ(@ptrCast([*:0]u8, &haiku_entry.d_name));468 const name = mem.spanZ(@ptrCast([*:0]u8, &haiku_entry.d_name));
...@@ -471,7 +471,7 @@ pub const Dir = struct {...@@ -471,7 +471,7 @@ pub const Dir = struct {
471 continue :start_over;471 continue :start_over;
472 }472 }
473473
474 var stat_info: os.libc_stat = undefined;474 var stat_info: os.Stat = undefined;
475 _ = os.system._kern_read_stat(475 _ = os.system._kern_read_stat(
476 self.dir.fd,476 self.dir.fd,
477 &haiku_entry.d_name,477 &haiku_entry.d_name,
...@@ -479,15 +479,15 @@ pub const Dir = struct {...@@ -479,15 +479,15 @@ pub const Dir = struct {
479 &stat_info,479 &stat_info,
480 0,480 0,
481 );481 );
482 const statmode = stat_info.mode & os.S_IFMT;482 const statmode = stat_info.mode & os.S.IFMT;
483483
484 const entry_kind = switch (statmode) {484 const entry_kind = switch (statmode) {
485 os.S_IFDIR => Entry.Kind.Directory,485 os.S.IFDIR => Entry.Kind.Directory,
486 os.S_IFBLK => Entry.Kind.BlockDevice,486 os.S.IFBLK => Entry.Kind.BlockDevice,
487 os.S_IFCHR => Entry.Kind.CharacterDevice,487 os.S.IFCHR => Entry.Kind.CharacterDevice,
488 os.S_IFLNK => Entry.Kind.SymLink,488 os.S.IFLNK => Entry.Kind.SymLink,
489 os.S_IFREG => Entry.Kind.File,489 os.S.IFREG => Entry.Kind.File,
490 os.S_IFIFO => Entry.Kind.NamedPipe,490 os.S.IFIFO => Entry.Kind.NamedPipe,
491 else => Entry.Kind.Unknown,491 else => Entry.Kind.Unknown,
492 };492 };
493493
...@@ -500,13 +500,14 @@ pub const Dir = struct {...@@ -500,13 +500,14 @@ pub const Dir = struct {
500 },500 },
501 .linux => struct {501 .linux => struct {
502 dir: Dir,502 dir: Dir,
503 // The if guard is solely there to prevent compile errors from missing `os.linux.dirent64`503 // The if guard is solely there to prevent compile errors from missing `linux.dirent64`
504 // definition when compiling for other OSes. It doesn't do anything when compiling for Linux.504 // definition when compiling for other OSes. It doesn't do anything when compiling for Linux.
505 buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(os.linux.dirent64)),505 buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(linux.dirent64)),
506 index: usize,506 index: usize,
507 end_index: usize,507 end_index: usize,
508508
509 const Self = @This();509 const Self = @This();
510 const linux = os.linux;
510511
511 pub const Error = IteratorError;512 pub const Error = IteratorError;
512513
...@@ -515,8 +516,8 @@ pub const Dir = struct {...@@ -515,8 +516,8 @@ pub const Dir = struct {
515 pub fn next(self: *Self) Error!?Entry {516 pub fn next(self: *Self) Error!?Entry {
516 start_over: while (true) {517 start_over: while (true) {
517 if (self.index >= self.end_index) {518 if (self.index >= self.end_index) {
518 const rc = os.linux.getdents64(self.dir.fd, &self.buf, self.buf.len);519 const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len);
519 switch (os.linux.getErrno(rc)) {520 switch (linux.getErrno(rc)) {
520 .SUCCESS => {},521 .SUCCESS => {},
521 .BADF => unreachable, // Dir is invalid or was opened without iteration ability522 .BADF => unreachable, // Dir is invalid or was opened without iteration ability
522 .FAULT => unreachable,523 .FAULT => unreachable,
...@@ -528,7 +529,7 @@ pub const Dir = struct {...@@ -528,7 +529,7 @@ pub const Dir = struct {
528 self.index = 0;529 self.index = 0;
529 self.end_index = rc;530 self.end_index = rc;
530 }531 }
531 const linux_entry = @ptrCast(*align(1) os.dirent64, &self.buf[self.index]);532 const linux_entry = @ptrCast(*align(1) linux.dirent64, &self.buf[self.index]);
532 const next_index = self.index + linux_entry.reclen();533 const next_index = self.index + linux_entry.reclen();
533 self.index = next_index;534 self.index = next_index;
534535
...@@ -540,13 +541,13 @@ pub const Dir = struct {...@@ -540,13 +541,13 @@ pub const Dir = struct {
540 }541 }
541542
542 const entry_kind = switch (linux_entry.d_type) {543 const entry_kind = switch (linux_entry.d_type) {
543 os.DT_BLK => Entry.Kind.BlockDevice,544 linux.DT.BLK => Entry.Kind.BlockDevice,
544 os.DT_CHR => Entry.Kind.CharacterDevice,545 linux.DT.CHR => Entry.Kind.CharacterDevice,
545 os.DT_DIR => Entry.Kind.Directory,546 linux.DT.DIR => Entry.Kind.Directory,
546 os.DT_FIFO => Entry.Kind.NamedPipe,547 linux.DT.FIFO => Entry.Kind.NamedPipe,
547 os.DT_LNK => Entry.Kind.SymLink,548 linux.DT.LNK => Entry.Kind.SymLink,
548 os.DT_REG => Entry.Kind.File,549 linux.DT.REG => Entry.Kind.File,
549 os.DT_SOCK => Entry.Kind.UnixDomainSocket,550 linux.DT.SOCK => Entry.Kind.UnixDomainSocket,
550 else => Entry.Kind.Unknown,551 else => Entry.Kind.Unknown,
551 };552 };
552 return Entry{553 return Entry{
...@@ -677,12 +678,12 @@ pub const Dir = struct {...@@ -677,12 +678,12 @@ pub const Dir = struct {
677 }678 }
678679
679 const entry_kind = switch (entry.d_type) {680 const entry_kind = switch (entry.d_type) {
680 w.FILETYPE_BLOCK_DEVICE => Entry.Kind.BlockDevice,681 .BLOCK_DEVICE => Entry.Kind.BlockDevice,
681 w.FILETYPE_CHARACTER_DEVICE => Entry.Kind.CharacterDevice,682 .CHARACTER_DEVICE => Entry.Kind.CharacterDevice,
682 w.FILETYPE_DIRECTORY => Entry.Kind.Directory,683 .DIRECTORY => Entry.Kind.Directory,
683 w.FILETYPE_SYMBOLIC_LINK => Entry.Kind.SymLink,684 .SYMBOLIC_LINK => Entry.Kind.SymLink,
684 w.FILETYPE_REGULAR_FILE => Entry.Kind.File,685 .REGULAR_FILE => Entry.Kind.File,
685 w.FILETYPE_SOCKET_STREAM, wasi.FILETYPE_SOCKET_DGRAM => Entry.Kind.UnixDomainSocket,686 .SOCKET_STREAM, .SOCKET_DGRAM => Entry.Kind.UnixDomainSocket,
686 else => Entry.Kind.Unknown,687 else => Entry.Kind.Unknown,
687 };688 };
688 return Entry{689 return Entry{
...@@ -879,20 +880,20 @@ pub const Dir = struct {...@@ -879,20 +880,20 @@ pub const Dir = struct {
879 var fdflags: w.fdflags_t = 0x0;880 var fdflags: w.fdflags_t = 0x0;
880 var base: w.rights_t = 0x0;881 var base: w.rights_t = 0x0;
881 if (flags.read) {882 if (flags.read) {
882 base |= w.RIGHT_FD_READ | w.RIGHT_FD_TELL | w.RIGHT_FD_SEEK | w.RIGHT_FD_FILESTAT_GET;883 base |= w.RIGHT.FD_READ | w.RIGHT.FD_TELL | w.RIGHT.FD_SEEK | w.RIGHT.FD_FILESTAT_GET;
883 }884 }
884 if (flags.write) {885 if (flags.write) {
885 fdflags |= w.FDFLAG_APPEND;886 fdflags |= w.FDFLAG.APPEND;
886 base |= w.RIGHT_FD_WRITE |887 base |= w.RIGHT.FD_WRITE |
887 w.RIGHT_FD_TELL |888 w.RIGHT.FD_TELL |
888 w.RIGHT_FD_SEEK |889 w.RIGHT.FD_SEEK |
889 w.RIGHT_FD_DATASYNC |890 w.RIGHT.FD_DATASYNC |
890 w.RIGHT_FD_FDSTAT_SET_FLAGS |891 w.RIGHT.FD_FDSTAT_SET_FLAGS |
891 w.RIGHT_FD_SYNC |892 w.RIGHT.FD_SYNC |
892 w.RIGHT_FD_ALLOCATE |893 w.RIGHT.FD_ALLOCATE |
893 w.RIGHT_FD_ADVISE |894 w.RIGHT.FD_ADVISE |
894 w.RIGHT_FD_FILESTAT_SET_TIMES |895 w.RIGHT.FD_FILESTAT_SET_TIMES |
895 w.RIGHT_FD_FILESTAT_SET_SIZE;896 w.RIGHT.FD_FILESTAT_SET_SIZE;
896 }897 }
897 const fd = try os.openatWasi(self.fd, sub_path, 0x0, 0x0, fdflags, base, 0x0);898 const fd = try os.openatWasi(self.fd, sub_path, 0x0, 0x0, fdflags, base, 0x0);
898 return File{ .handle = fd };899 return File{ .handle = fd };
...@@ -907,35 +908,35 @@ pub const Dir = struct {...@@ -907,35 +908,35 @@ pub const Dir = struct {
907 return self.openFileW(path_w.span(), flags);908 return self.openFileW(path_w.span(), flags);
908 }909 }
909910
910 var os_flags: u32 = os.O_CLOEXEC;911 var os_flags: u32 = os.O.CLOEXEC;
911 // Use the O_ locking flags if the os supports them to acquire the lock912 // Use the O locking flags if the os supports them to acquire the lock
912 // atomically.913 // atomically.
913 const has_flock_open_flags = @hasDecl(os, "O_EXLOCK");914 const has_flock_open_flags = @hasDecl(os.O, "EXLOCK");
914 if (has_flock_open_flags) {915 if (has_flock_open_flags) {
915 // Note that the O_NONBLOCK flag is removed after the openat() call916 // Note that the O.NONBLOCK flag is removed after the openat() call
916 // is successful.917 // is successful.
917 const nonblocking_lock_flag: u32 = if (flags.lock_nonblocking)918 const nonblocking_lock_flag: u32 = if (flags.lock_nonblocking)
918 os.O_NONBLOCK919 os.O.NONBLOCK
919 else920 else
920 0;921 0;
921 os_flags |= switch (flags.lock) {922 os_flags |= switch (flags.lock) {
922 .None => @as(u32, 0),923 .None => @as(u32, 0),
923 .Shared => os.O_SHLOCK | nonblocking_lock_flag,924 .Shared => os.O.SHLOCK | nonblocking_lock_flag,
924 .Exclusive => os.O_EXLOCK | nonblocking_lock_flag,925 .Exclusive => os.O.EXLOCK | nonblocking_lock_flag,
925 };926 };
926 }927 }
927 if (@hasDecl(os, "O_LARGEFILE")) {928 if (@hasDecl(os.O, "LARGEFILE")) {
928 os_flags |= os.O_LARGEFILE;929 os_flags |= os.O.LARGEFILE;
929 }930 }
930 if (!flags.allow_ctty) {931 if (!flags.allow_ctty) {
931 os_flags |= os.O_NOCTTY;932 os_flags |= os.O.NOCTTY;
932 }933 }
933 os_flags |= if (flags.write and flags.read)934 os_flags |= if (flags.write and flags.read)
934 @as(u32, os.O_RDWR)935 @as(u32, os.O.RDWR)
935 else if (flags.write)936 else if (flags.write)
936 @as(u32, os.O_WRONLY)937 @as(u32, os.O.WRONLY)
937 else938 else
938 @as(u32, os.O_RDONLY);939 @as(u32, os.O.RDONLY);
939 const fd = if (flags.intended_io_mode != .blocking)940 const fd = if (flags.intended_io_mode != .blocking)
940 try std.event.Loop.instance.?.openatZ(self.fd, sub_path, os_flags, 0)941 try std.event.Loop.instance.?.openatZ(self.fd, sub_path, os_flags, 0)
941 else942 else
...@@ -947,24 +948,24 @@ pub const Dir = struct {...@@ -947,24 +948,24 @@ pub const Dir = struct {
947 if (builtin.target.os.tag != .wasi) {948 if (builtin.target.os.tag != .wasi) {
948 if (!has_flock_open_flags and flags.lock != .None) {949 if (!has_flock_open_flags and flags.lock != .None) {
949 // TODO: integrate async I/O950 // TODO: integrate async I/O
950 const lock_nonblocking = if (flags.lock_nonblocking) os.LOCK_NB else @as(i32, 0);951 const lock_nonblocking = if (flags.lock_nonblocking) os.LOCK.NB else @as(i32, 0);
951 try os.flock(fd, switch (flags.lock) {952 try os.flock(fd, switch (flags.lock) {
952 .None => unreachable,953 .None => unreachable,
953 .Shared => os.LOCK_SH | lock_nonblocking,954 .Shared => os.LOCK.SH | lock_nonblocking,
954 .Exclusive => os.LOCK_EX | lock_nonblocking,955 .Exclusive => os.LOCK.EX | lock_nonblocking,
955 });956 });
956 }957 }
957 }958 }
958959
959 if (has_flock_open_flags and flags.lock_nonblocking) {960 if (has_flock_open_flags and flags.lock_nonblocking) {
960 var fl_flags = os.fcntl(fd, os.F_GETFL, 0) catch |err| switch (err) {961 var fl_flags = os.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
961 error.FileBusy => unreachable,962 error.FileBusy => unreachable,
962 error.Locked => unreachable,963 error.Locked => unreachable,
963 error.PermissionDenied => unreachable,964 error.PermissionDenied => unreachable,
964 else => |e| return e,965 else => |e| return e,
965 };966 };
966 fl_flags &= ~@as(usize, os.O_NONBLOCK);967 fl_flags &= ~@as(usize, os.O.NONBLOCK);
967 _ = os.fcntl(fd, os.F_SETFL, fl_flags) catch |err| switch (err) {968 _ = os.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
968 error.FileBusy => unreachable,969 error.FileBusy => unreachable,
969 error.Locked => unreachable,970 error.Locked => unreachable,
970 error.PermissionDenied => unreachable,971 error.PermissionDenied => unreachable,
...@@ -1038,26 +1039,26 @@ pub const Dir = struct {...@@ -1038,26 +1039,26 @@ pub const Dir = struct {
1038 /// Same as `createFile` but WASI only.1039 /// Same as `createFile` but WASI only.
1039 pub fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {1040 pub fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
1040 const w = os.wasi;1041 const w = os.wasi;
1041 var oflags = w.O_CREAT;1042 var oflags = w.O.CREAT;
1042 var base: w.rights_t = w.RIGHT_FD_WRITE |1043 var base: w.rights_t = w.RIGHT.FD_WRITE |
1043 w.RIGHT_FD_DATASYNC |1044 w.RIGHT.FD_DATASYNC |
1044 w.RIGHT_FD_SEEK |1045 w.RIGHT.FD_SEEK |
1045 w.RIGHT_FD_TELL |1046 w.RIGHT.FD_TELL |
1046 w.RIGHT_FD_FDSTAT_SET_FLAGS |1047 w.RIGHT.FD_FDSTAT_SET_FLAGS |
1047 w.RIGHT_FD_SYNC |1048 w.RIGHT.FD_SYNC |
1048 w.RIGHT_FD_ALLOCATE |1049 w.RIGHT.FD_ALLOCATE |
1049 w.RIGHT_FD_ADVISE |1050 w.RIGHT.FD_ADVISE |
1050 w.RIGHT_FD_FILESTAT_SET_TIMES |1051 w.RIGHT.FD_FILESTAT_SET_TIMES |
1051 w.RIGHT_FD_FILESTAT_SET_SIZE |1052 w.RIGHT.FD_FILESTAT_SET_SIZE |
1052 w.RIGHT_FD_FILESTAT_GET;1053 w.RIGHT.FD_FILESTAT_GET;
1053 if (flags.read) {1054 if (flags.read) {
1054 base |= w.RIGHT_FD_READ;1055 base |= w.RIGHT.FD_READ;
1055 }1056 }
1056 if (flags.truncate) {1057 if (flags.truncate) {
1057 oflags |= w.O_TRUNC;1058 oflags |= w.O.TRUNC;
1058 }1059 }
1059 if (flags.exclusive) {1060 if (flags.exclusive) {
1060 oflags |= w.O_EXCL;1061 oflags |= w.O.EXCL;
1061 }1062 }
1062 const fd = try os.openatWasi(self.fd, sub_path, 0x0, oflags, 0x0, base, 0x0);1063 const fd = try os.openatWasi(self.fd, sub_path, 0x0, oflags, 0x0, base, 0x0);
1063 return File{ .handle = fd };1064 return File{ .handle = fd };
...@@ -1070,26 +1071,26 @@ pub const Dir = struct {...@@ -1070,26 +1071,26 @@ pub const Dir = struct {
1070 return self.createFileW(path_w.span(), flags);1071 return self.createFileW(path_w.span(), flags);
1071 }1072 }
10721073
1073 // Use the O_ locking flags if the os supports them to acquire the lock1074 // Use the O locking flags if the os supports them to acquire the lock
1074 // atomically.1075 // atomically.
1075 const has_flock_open_flags = @hasDecl(os, "O_EXLOCK");1076 const has_flock_open_flags = @hasDecl(os.O, "EXLOCK");
1076 // Note that the O_NONBLOCK flag is removed after the openat() call1077 // Note that the O.NONBLOCK flag is removed after the openat() call
1077 // is successful.1078 // is successful.
1078 const nonblocking_lock_flag: u32 = if (has_flock_open_flags and flags.lock_nonblocking)1079 const nonblocking_lock_flag: u32 = if (has_flock_open_flags and flags.lock_nonblocking)
1079 os.O_NONBLOCK1080 os.O.NONBLOCK
1080 else1081 else
1081 0;1082 0;
1082 const lock_flag: u32 = if (has_flock_open_flags) switch (flags.lock) {1083 const lock_flag: u32 = if (has_flock_open_flags) switch (flags.lock) {
1083 .None => @as(u32, 0),1084 .None => @as(u32, 0),
1084 .Shared => os.O_SHLOCK | nonblocking_lock_flag,1085 .Shared => os.O.SHLOCK | nonblocking_lock_flag,
1085 .Exclusive => os.O_EXLOCK | nonblocking_lock_flag,1086 .Exclusive => os.O.EXLOCK | nonblocking_lock_flag,
1086 } else 0;1087 } else 0;
10871088
1088 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;1089 const O_LARGEFILE = if (@hasDecl(os.O, "LARGEFILE")) os.O.LARGEFILE else 0;
1089 const os_flags = lock_flag | O_LARGEFILE | os.O_CREAT | os.O_CLOEXEC |1090 const os_flags = lock_flag | O_LARGEFILE | os.O.CREAT | os.O.CLOEXEC |
1090 (if (flags.truncate) @as(u32, os.O_TRUNC) else 0) |1091 (if (flags.truncate) @as(u32, os.O.TRUNC) else 0) |
1091 (if (flags.read) @as(u32, os.O_RDWR) else os.O_WRONLY) |1092 (if (flags.read) @as(u32, os.O.RDWR) else os.O.WRONLY) |
1092 (if (flags.exclusive) @as(u32, os.O_EXCL) else 0);1093 (if (flags.exclusive) @as(u32, os.O.EXCL) else 0);
1093 const fd = if (flags.intended_io_mode != .blocking)1094 const fd = if (flags.intended_io_mode != .blocking)
1094 try std.event.Loop.instance.?.openatZ(self.fd, sub_path_c, os_flags, flags.mode)1095 try std.event.Loop.instance.?.openatZ(self.fd, sub_path_c, os_flags, flags.mode)
1095 else1096 else
...@@ -1101,24 +1102,24 @@ pub const Dir = struct {...@@ -1101,24 +1102,24 @@ pub const Dir = struct {
1101 if (builtin.target.os.tag != .wasi) {1102 if (builtin.target.os.tag != .wasi) {
1102 if (!has_flock_open_flags and flags.lock != .None) {1103 if (!has_flock_open_flags and flags.lock != .None) {
1103 // TODO: integrate async I/O1104 // TODO: integrate async I/O
1104 const lock_nonblocking = if (flags.lock_nonblocking) os.LOCK_NB else @as(i32, 0);1105 const lock_nonblocking = if (flags.lock_nonblocking) os.LOCK.NB else @as(i32, 0);
1105 try os.flock(fd, switch (flags.lock) {1106 try os.flock(fd, switch (flags.lock) {
1106 .None => unreachable,1107 .None => unreachable,
1107 .Shared => os.LOCK_SH | lock_nonblocking,1108 .Shared => os.LOCK.SH | lock_nonblocking,
1108 .Exclusive => os.LOCK_EX | lock_nonblocking,1109 .Exclusive => os.LOCK.EX | lock_nonblocking,
1109 });1110 });
1110 }1111 }
1111 }1112 }
11121113
1113 if (has_flock_open_flags and flags.lock_nonblocking) {1114 if (has_flock_open_flags and flags.lock_nonblocking) {
1114 var fl_flags = os.fcntl(fd, os.F_GETFL, 0) catch |err| switch (err) {1115 var fl_flags = os.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
1115 error.FileBusy => unreachable,1116 error.FileBusy => unreachable,
1116 error.Locked => unreachable,1117 error.Locked => unreachable,
1117 error.PermissionDenied => unreachable,1118 error.PermissionDenied => unreachable,
1118 else => |e| return e,1119 else => |e| return e,
1119 };1120 };
1120 fl_flags &= ~@as(usize, os.O_NONBLOCK);1121 fl_flags &= ~@as(usize, os.O.NONBLOCK);
1121 _ = os.fcntl(fd, os.F_SETFL, fl_flags) catch |err| switch (err) {1122 _ = os.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
1122 error.FileBusy => unreachable,1123 error.FileBusy => unreachable,
1123 error.Locked => unreachable,1124 error.Locked => unreachable,
1124 error.PermissionDenied => unreachable,1125 error.PermissionDenied => unreachable,
...@@ -1262,7 +1263,7 @@ pub const Dir = struct {...@@ -1262,7 +1263,7 @@ pub const Dir = struct {
1262 return self.realpathW(pathname_w.span(), out_buffer);1263 return self.realpathW(pathname_w.span(), out_buffer);
1263 }1264 }
12641265
1265 const flags = if (builtin.os.tag == .linux) os.O_PATH | os.O_NONBLOCK | os.O_CLOEXEC else os.O_NONBLOCK | os.O_CLOEXEC;1266 const flags = if (builtin.os.tag == .linux) os.O.PATH | os.O.NONBLOCK | os.O.CLOEXEC else os.O.NONBLOCK | os.O.CLOEXEC;
1266 const fd = os.openatZ(self.fd, pathname, flags, 0) catch |err| switch (err) {1267 const fd = os.openatZ(self.fd, pathname, flags, 0) catch |err| switch (err) {
1267 error.FileLocksNotSupported => unreachable,1268 error.FileLocksNotSupported => unreachable,
1268 else => |e| return e,1269 else => |e| return e,
...@@ -1401,34 +1402,34 @@ pub const Dir = struct {...@@ -1401,34 +1402,34 @@ pub const Dir = struct {
1401 /// Same as `openDir` except only WASI.1402 /// Same as `openDir` except only WASI.
1402 pub fn openDirWasi(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!Dir {1403 pub fn openDirWasi(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!Dir {
1403 const w = os.wasi;1404 const w = os.wasi;
1404 var base: w.rights_t = w.RIGHT_FD_FILESTAT_GET | w.RIGHT_FD_FDSTAT_SET_FLAGS | w.RIGHT_FD_FILESTAT_SET_TIMES;1405 var base: w.rights_t = w.RIGHT.FD_FILESTAT_GET | w.RIGHT.FD_FDSTAT_SET_FLAGS | w.RIGHT.FD_FILESTAT_SET_TIMES;
1405 if (args.access_sub_paths) {1406 if (args.access_sub_paths) {
1406 base |= w.RIGHT_FD_READDIR |1407 base |= w.RIGHT.FD_READDIR |
1407 w.RIGHT_PATH_CREATE_DIRECTORY |1408 w.RIGHT.PATH_CREATE_DIRECTORY |
1408 w.RIGHT_PATH_CREATE_FILE |1409 w.RIGHT.PATH_CREATE_FILE |
1409 w.RIGHT_PATH_LINK_SOURCE |1410 w.RIGHT.PATH_LINK_SOURCE |
1410 w.RIGHT_PATH_LINK_TARGET |1411 w.RIGHT.PATH_LINK_TARGET |
1411 w.RIGHT_PATH_OPEN |1412 w.RIGHT.PATH_OPEN |
1412 w.RIGHT_PATH_READLINK |1413 w.RIGHT.PATH_READLINK |
1413 w.RIGHT_PATH_RENAME_SOURCE |1414 w.RIGHT.PATH_RENAME_SOURCE |
1414 w.RIGHT_PATH_RENAME_TARGET |1415 w.RIGHT.PATH_RENAME_TARGET |
1415 w.RIGHT_PATH_FILESTAT_GET |1416 w.RIGHT.PATH_FILESTAT_GET |
1416 w.RIGHT_PATH_FILESTAT_SET_SIZE |1417 w.RIGHT.PATH_FILESTAT_SET_SIZE |
1417 w.RIGHT_PATH_FILESTAT_SET_TIMES |1418 w.RIGHT.PATH_FILESTAT_SET_TIMES |
1418 w.RIGHT_PATH_SYMLINK |1419 w.RIGHT.PATH_SYMLINK |
1419 w.RIGHT_PATH_REMOVE_DIRECTORY |1420 w.RIGHT.PATH_REMOVE_DIRECTORY |
1420 w.RIGHT_PATH_UNLINK_FILE;1421 w.RIGHT.PATH_UNLINK_FILE;
1421 }1422 }
1422 const symlink_flags: w.lookupflags_t = if (args.no_follow) 0x0 else w.LOOKUP_SYMLINK_FOLLOW;1423 const symlink_flags: w.lookupflags_t = if (args.no_follow) 0x0 else w.LOOKUP_SYMLINK_FOLLOW;
1423 // TODO do we really need all the rights here?1424 // TODO do we really need all the rights here?
1424 const inheriting: w.rights_t = w.RIGHT_ALL ^ w.RIGHT_SOCK_SHUTDOWN;1425 const inheriting: w.rights_t = w.RIGHT.ALL ^ w.RIGHT.SOCK_SHUTDOWN;
14251426
1426 const result = os.openatWasi(self.fd, sub_path, symlink_flags, w.O_DIRECTORY, 0x0, base, inheriting);1427 const result = os.openatWasi(self.fd, sub_path, symlink_flags, w.O.DIRECTORY, 0x0, base, inheriting);
1427 const fd = result catch |err| switch (err) {1428 const fd = result catch |err| switch (err) {
1428 error.FileTooBig => unreachable, // can't happen for directories1429 error.FileTooBig => unreachable, // can't happen for directories
1429 error.IsDir => unreachable, // we're providing O_DIRECTORY1430 error.IsDir => unreachable, // we're providing O.DIRECTORY
1430 error.NoSpaceLeft => unreachable, // not providing O_CREAT1431 error.NoSpaceLeft => unreachable, // not providing O.CREAT
1431 error.PathAlreadyExists => unreachable, // not providing O_CREAT1432 error.PathAlreadyExists => unreachable, // not providing O.CREAT
1432 error.FileLocksNotSupported => unreachable, // locking folders is not supported1433 error.FileLocksNotSupported => unreachable, // locking folders is not supported
1433 error.WouldBlock => unreachable, // can't happen for directories1434 error.WouldBlock => unreachable, // can't happen for directories
1434 else => |e| return e,1435 else => |e| return e,
...@@ -1442,12 +1443,12 @@ pub const Dir = struct {...@@ -1442,12 +1443,12 @@ pub const Dir = struct {
1442 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);1443 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
1443 return self.openDirW(sub_path_w.span().ptr, args);1444 return self.openDirW(sub_path_w.span().ptr, args);
1444 }1445 }
1445 const symlink_flags: u32 = if (args.no_follow) os.O_NOFOLLOW else 0x0;1446 const symlink_flags: u32 = if (args.no_follow) os.O.NOFOLLOW else 0x0;
1446 if (!args.iterate) {1447 if (!args.iterate) {
1447 const O_PATH = if (@hasDecl(os, "O_PATH")) os.O_PATH else 0;1448 const O_PATH = if (@hasDecl(os.O, "PATH")) os.O.PATH else 0;
1448 return self.openDirFlagsZ(sub_path_c, os.O_DIRECTORY | os.O_RDONLY | os.O_CLOEXEC | O_PATH | symlink_flags);1449 return self.openDirFlagsZ(sub_path_c, os.O.DIRECTORY | os.O.RDONLY | os.O.CLOEXEC | O_PATH | symlink_flags);
1449 } else {1450 } else {
1450 return self.openDirFlagsZ(sub_path_c, os.O_DIRECTORY | os.O_RDONLY | os.O_CLOEXEC | symlink_flags);1451 return self.openDirFlagsZ(sub_path_c, os.O.DIRECTORY | os.O.RDONLY | os.O.CLOEXEC | symlink_flags);
1451 }1452 }
1452 }1453 }
14531454
...@@ -1462,7 +1463,7 @@ pub const Dir = struct {...@@ -1462,7 +1463,7 @@ pub const Dir = struct {
1462 return self.openDirAccessMaskW(sub_path_w, flags, args.no_follow);1463 return self.openDirAccessMaskW(sub_path_w, flags, args.no_follow);
1463 }1464 }
14641465
1465 /// `flags` must contain `os.O_DIRECTORY`.1466 /// `flags` must contain `os.O.DIRECTORY`.
1466 fn openDirFlagsZ(self: Dir, sub_path_c: [*:0]const u8, flags: u32) OpenError!Dir {1467 fn openDirFlagsZ(self: Dir, sub_path_c: [*:0]const u8, flags: u32) OpenError!Dir {
1467 const result = if (need_async_thread)1468 const result = if (need_async_thread)
1468 std.event.Loop.instance.?.openatZ(self.fd, sub_path_c, flags, 0)1469 std.event.Loop.instance.?.openatZ(self.fd, sub_path_c, flags, 0)
...@@ -1470,9 +1471,9 @@ pub const Dir = struct {...@@ -1470,9 +1471,9 @@ pub const Dir = struct {
1470 os.openatZ(self.fd, sub_path_c, flags, 0);1471 os.openatZ(self.fd, sub_path_c, flags, 0);
1471 const fd = result catch |err| switch (err) {1472 const fd = result catch |err| switch (err) {
1472 error.FileTooBig => unreachable, // can't happen for directories1473 error.FileTooBig => unreachable, // can't happen for directories
1473 error.IsDir => unreachable, // we're providing O_DIRECTORY1474 error.IsDir => unreachable, // we're providing O.DIRECTORY
1474 error.NoSpaceLeft => unreachable, // not providing O_CREAT1475 error.NoSpaceLeft => unreachable, // not providing O.CREAT
1475 error.PathAlreadyExists => unreachable, // not providing O_CREAT1476 error.PathAlreadyExists => unreachable, // not providing O.CREAT
1476 error.FileLocksNotSupported => unreachable, // locking folders is not supported1477 error.FileLocksNotSupported => unreachable, // locking folders is not supported
1477 error.WouldBlock => unreachable, // can't happen for directories1478 error.WouldBlock => unreachable, // can't happen for directories
1478 else => |e| return e,1479 else => |e| return e,
...@@ -1537,7 +1538,7 @@ pub const Dir = struct {...@@ -1537,7 +1538,7 @@ pub const Dir = struct {
1537 return self.deleteFileW(sub_path_w.span());1538 return self.deleteFileW(sub_path_w.span());
1538 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {1539 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
1539 os.unlinkatWasi(self.fd, sub_path, 0) catch |err| switch (err) {1540 os.unlinkatWasi(self.fd, sub_path, 0) catch |err| switch (err) {
1540 error.DirNotEmpty => unreachable, // not passing AT_REMOVEDIR1541 error.DirNotEmpty => unreachable, // not passing AT.REMOVEDIR
1541 else => |e| return e,1542 else => |e| return e,
1542 };1543 };
1543 } else {1544 } else {
...@@ -1551,14 +1552,14 @@ pub const Dir = struct {...@@ -1551,14 +1552,14 @@ pub const Dir = struct {
1551 /// Same as `deleteFile` except the parameter is null-terminated.1552 /// Same as `deleteFile` except the parameter is null-terminated.
1552 pub fn deleteFileZ(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void {1553 pub fn deleteFileZ(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void {
1553 os.unlinkatZ(self.fd, sub_path_c, 0) catch |err| switch (err) {1554 os.unlinkatZ(self.fd, sub_path_c, 0) catch |err| switch (err) {
1554 error.DirNotEmpty => unreachable, // not passing AT_REMOVEDIR1555 error.DirNotEmpty => unreachable, // not passing AT.REMOVEDIR
1555 error.AccessDenied => |e| switch (builtin.os.tag) {1556 error.AccessDenied => |e| switch (builtin.os.tag) {
1556 // non-Linux POSIX systems return EPERM when trying to delete a directory, so1557 // non-Linux POSIX systems return EPERM when trying to delete a directory, so
1557 // we need to handle that case specifically and translate the error1558 // we need to handle that case specifically and translate the error
1558 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => {1559 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => {
1559 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)1560 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
1560 const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT_SYMLINK_NOFOLLOW) catch return e;1561 const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT.SYMLINK_NOFOLLOW) catch return e;
1561 const is_dir = fstat.mode & os.S_IFMT == os.S_IFDIR;1562 const is_dir = fstat.mode & os.S.IFMT == os.S.IFDIR;
1562 return if (is_dir) error.IsDir else e;1563 return if (is_dir) error.IsDir else e;
1563 },1564 },
1564 else => return e,1565 else => return e,
...@@ -1570,7 +1571,7 @@ pub const Dir = struct {...@@ -1570,7 +1571,7 @@ pub const Dir = struct {
1570 /// Same as `deleteFile` except the parameter is WTF-16 encoded.1571 /// Same as `deleteFile` except the parameter is WTF-16 encoded.
1571 pub fn deleteFileW(self: Dir, sub_path_w: []const u16) DeleteFileError!void {1572 pub fn deleteFileW(self: Dir, sub_path_w: []const u16) DeleteFileError!void {
1572 os.unlinkatW(self.fd, sub_path_w, 0) catch |err| switch (err) {1573 os.unlinkatW(self.fd, sub_path_w, 0) catch |err| switch (err) {
1573 error.DirNotEmpty => unreachable, // not passing AT_REMOVEDIR1574 error.DirNotEmpty => unreachable, // not passing AT.REMOVEDIR
1574 else => |e| return e,1575 else => |e| return e,
1575 };1576 };
1576 }1577 }
...@@ -1599,8 +1600,8 @@ pub const Dir = struct {...@@ -1599,8 +1600,8 @@ pub const Dir = struct {
1599 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);1600 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
1600 return self.deleteDirW(sub_path_w.span());1601 return self.deleteDirW(sub_path_w.span());
1601 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {1602 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
1602 os.unlinkat(self.fd, sub_path, os.AT_REMOVEDIR) catch |err| switch (err) {1603 os.unlinkat(self.fd, sub_path, os.AT.REMOVEDIR) catch |err| switch (err) {
1603 error.IsDir => unreachable, // not possible since we pass AT_REMOVEDIR1604 error.IsDir => unreachable, // not possible since we pass AT.REMOVEDIR
1604 else => |e| return e,1605 else => |e| return e,
1605 };1606 };
1606 } else {1607 } else {
...@@ -1611,8 +1612,8 @@ pub const Dir = struct {...@@ -1611,8 +1612,8 @@ pub const Dir = struct {
16111612
1612 /// Same as `deleteDir` except the parameter is null-terminated.1613 /// Same as `deleteDir` except the parameter is null-terminated.
1613 pub fn deleteDirZ(self: Dir, sub_path_c: [*:0]const u8) DeleteDirError!void {1614 pub fn deleteDirZ(self: Dir, sub_path_c: [*:0]const u8) DeleteDirError!void {
1614 os.unlinkatZ(self.fd, sub_path_c, os.AT_REMOVEDIR) catch |err| switch (err) {1615 os.unlinkatZ(self.fd, sub_path_c, os.AT.REMOVEDIR) catch |err| switch (err) {
1615 error.IsDir => unreachable, // not possible since we pass AT_REMOVEDIR1616 error.IsDir => unreachable, // not possible since we pass AT.REMOVEDIR
1616 else => |e| return e,1617 else => |e| return e,
1617 };1618 };
1618 }1619 }
...@@ -1620,8 +1621,8 @@ pub const Dir = struct {...@@ -1620,8 +1621,8 @@ pub const Dir = struct {
1620 /// Same as `deleteDir` except the parameter is UTF16LE, NT prefixed.1621 /// Same as `deleteDir` except the parameter is UTF16LE, NT prefixed.
1621 /// This function is Windows-only.1622 /// This function is Windows-only.
1622 pub fn deleteDirW(self: Dir, sub_path_w: []const u16) DeleteDirError!void {1623 pub fn deleteDirW(self: Dir, sub_path_w: []const u16) DeleteDirError!void {
1623 os.unlinkatW(self.fd, sub_path_w, os.AT_REMOVEDIR) catch |err| switch (err) {1624 os.unlinkatW(self.fd, sub_path_w, os.AT.REMOVEDIR) catch |err| switch (err) {
1624 error.IsDir => unreachable, // not possible since we pass AT_REMOVEDIR1625 error.IsDir => unreachable, // not possible since we pass AT.REMOVEDIR
1625 else => |e| return e,1626 else => |e| return e,
1626 };1627 };
1627 }1628 }
...@@ -2132,7 +2133,7 @@ pub fn cwd() Dir {...@@ -2132,7 +2133,7 @@ pub fn cwd() Dir {
2132 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {2133 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
2133 @compileError("WASI doesn't have a concept of cwd(); use std.fs.wasi.PreopenList to get available Dir handles instead");2134 @compileError("WASI doesn't have a concept of cwd(); use std.fs.wasi.PreopenList to get available Dir handles instead");
2134 } else {2135 } else {
2135 return Dir{ .fd = os.AT_FDCWD };2136 return Dir{ .fd = os.AT.FDCWD };
2136 }2137 }
2137}2138}
21382139
...@@ -2441,14 +2442,14 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {...@@ -2441,14 +2442,14 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
2441 switch (builtin.os.tag) {2442 switch (builtin.os.tag) {
2442 .linux => return os.readlinkZ("/proc/self/exe", out_buffer),2443 .linux => return os.readlinkZ("/proc/self/exe", out_buffer),
2443 .freebsd, .dragonfly => {2444 .freebsd, .dragonfly => {
2444 var mib = [4]c_int{ os.CTL_KERN, os.KERN_PROC, os.KERN_PROC_PATHNAME, -1 };2445 var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC, os.KERN.PROC_PATHNAME, -1 };
2445 var out_len: usize = out_buffer.len;2446 var out_len: usize = out_buffer.len;
2446 try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);2447 try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);
2447 // TODO could this slice from 0 to out_len instead?2448 // TODO could this slice from 0 to out_len instead?
2448 return mem.spanZ(std.meta.assumeSentinel(out_buffer.ptr, 0));2449 return mem.spanZ(std.meta.assumeSentinel(out_buffer.ptr, 0));
2449 },2450 },
2450 .netbsd => {2451 .netbsd => {
2451 var mib = [4]c_int{ os.CTL_KERN, os.KERN_PROC_ARGS, -1, os.KERN_PROC_PATHNAME };2452 var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC_ARGS, -1, os.KERN.PROC_PATHNAME };
2452 var out_len: usize = out_buffer.len;2453 var out_len: usize = out_buffer.len;
2453 try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);2454 try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);
2454 // TODO could this slice from 0 to out_len instead?2455 // TODO could this slice from 0 to out_len instead?
lib/std/fs/file.zig+36-33
...@@ -12,20 +12,23 @@ const is_windows = std.Target.current.os.tag == .windows;...@@ -12,20 +12,23 @@ const is_windows = std.Target.current.os.tag == .windows;
1212
13pub const File = struct {13pub const File = struct {
14 /// The OS-specific file descriptor or file handle.14 /// The OS-specific file descriptor or file handle.
15 handle: os.fd_t,15 handle: Handle,
1616
17 /// On some systems, such as Linux, file system file descriptors are incapable of non-blocking I/O.17 /// On some systems, such as Linux, file system file descriptors are incapable
18 /// This forces us to perform asynchronous I/O on a dedicated thread, to achieve non-blocking18 /// of non-blocking I/O. This forces us to perform asynchronous I/O on a dedicated thread,
19 /// file-system I/O. To do this, `File` must be aware of whether it is a file system file descriptor,19 /// to achieve non-blocking file-system I/O. To do this, `File` must be aware of whether
20 /// or, more specifically, whether the I/O is always blocking.20 /// it is a file system file descriptor, or, more specifically, whether the I/O is always
21 /// blocking.
21 capable_io_mode: io.ModeOverride = io.default_mode,22 capable_io_mode: io.ModeOverride = io.default_mode,
2223
23 /// Furthermore, even when `std.io.mode` is async, it is still sometimes desirable to perform blocking I/O,24 /// Furthermore, even when `std.io.mode` is async, it is still sometimes desirable
24 /// although not by default. For example, when printing a stack trace to stderr.25 /// to perform blocking I/O, although not by default. For example, when printing a
25 /// This field tracks both by acting as an overriding I/O mode. When not building in async I/O mode,26 /// stack trace to stderr. This field tracks both by acting as an overriding I/O mode.
26 /// the type only has the `.blocking` tag, making it a zero-bit type.27 /// When not building in async I/O mode, the type only has the `.blocking` tag, making
28 /// it a zero-bit type.
27 intended_io_mode: io.ModeOverride = io.default_mode,29 intended_io_mode: io.ModeOverride = io.default_mode,
2830
31 pub const Handle = os.fd_t;
29 pub const Mode = os.mode_t;32 pub const Mode = os.mode_t;
30 pub const INode = os.ino_t;33 pub const INode = os.ino_t;
3134
...@@ -103,7 +106,7 @@ pub const File = struct {...@@ -103,7 +106,7 @@ pub const File = struct {
103 /// and `false` means `error.WouldBlock` is handled by the event loop.106 /// and `false` means `error.WouldBlock` is handled by the event loop.
104 lock_nonblocking: bool = false,107 lock_nonblocking: bool = false,
105108
106 /// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even109 /// Setting this to `.blocking` prevents `O.NONBLOCK` from being passed even
107 /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions110 /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions
108 /// related to opening the file, reading, writing, and locking.111 /// related to opening the file, reading, writing, and locking.
109 intended_io_mode: io.ModeOverride = io.default_mode,112 intended_io_mode: io.ModeOverride = io.default_mode,
...@@ -164,7 +167,7 @@ pub const File = struct {...@@ -164,7 +167,7 @@ pub const File = struct {
164 /// be created with.167 /// be created with.
165 mode: Mode = default_mode,168 mode: Mode = default_mode,
166169
167 /// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even170 /// Setting this to `.blocking` prevents `O.NONBLOCK` from being passed even
168 /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions171 /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions
169 /// related to opening the file, reading, writing, and locking.172 /// related to opening the file, reading, writing, and locking.
170 intended_io_mode: io.ModeOverride = io.default_mode,173 intended_io_mode: io.ModeOverride = io.default_mode,
...@@ -322,21 +325,21 @@ pub const File = struct {...@@ -322,21 +325,21 @@ pub const File = struct {
322 .size = @bitCast(u64, st.size),325 .size = @bitCast(u64, st.size),
323 .mode = st.mode,326 .mode = st.mode,
324 .kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) {327 .kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) {
325 os.FILETYPE_BLOCK_DEVICE => Kind.BlockDevice,328 .BLOCK_DEVICE => Kind.BlockDevice,
326 os.FILETYPE_CHARACTER_DEVICE => Kind.CharacterDevice,329 .CHARACTER_DEVICE => Kind.CharacterDevice,
327 os.FILETYPE_DIRECTORY => Kind.Directory,330 .DIRECTORY => Kind.Directory,
328 os.FILETYPE_SYMBOLIC_LINK => Kind.SymLink,331 .SYMBOLIC_LINK => Kind.SymLink,
329 os.FILETYPE_REGULAR_FILE => Kind.File,332 .REGULAR_FILE => Kind.File,
330 os.FILETYPE_SOCKET_STREAM, os.FILETYPE_SOCKET_DGRAM => Kind.UnixDomainSocket,333 .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket,
331 else => Kind.Unknown,334 else => Kind.Unknown,
332 } else switch (st.mode & os.S_IFMT) {335 } else switch (st.mode & os.S.IFMT) {
333 os.S_IFBLK => Kind.BlockDevice,336 os.S.IFBLK => Kind.BlockDevice,
334 os.S_IFCHR => Kind.CharacterDevice,337 os.S.IFCHR => Kind.CharacterDevice,
335 os.S_IFDIR => Kind.Directory,338 os.S.IFDIR => Kind.Directory,
336 os.S_IFIFO => Kind.NamedPipe,339 os.S.IFIFO => Kind.NamedPipe,
337 os.S_IFLNK => Kind.SymLink,340 os.S.IFLNK => Kind.SymLink,
338 os.S_IFREG => Kind.File,341 os.S.IFREG => Kind.File,
339 os.S_IFSOCK => Kind.UnixDomainSocket,342 os.S.IFSOCK => Kind.UnixDomainSocket,
340 else => Kind.Unknown,343 else => Kind.Unknown,
341 },344 },
342 .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,345 .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
...@@ -883,9 +886,9 @@ pub const File = struct {...@@ -883,9 +886,9 @@ pub const File = struct {
883 };886 };
884 } else {887 } else {
885 return os.flock(file.handle, switch (l) {888 return os.flock(file.handle, switch (l) {
886 .None => os.LOCK_UN,889 .None => os.LOCK.UN,
887 .Shared => os.LOCK_SH,890 .Shared => os.LOCK.SH,
888 .Exclusive => os.LOCK_EX,891 .Exclusive => os.LOCK.EX,
889 }) catch |err| switch (err) {892 }) catch |err| switch (err) {
890 error.WouldBlock => unreachable, // non-blocking=false893 error.WouldBlock => unreachable, // non-blocking=false
891 else => |e| return e,894 else => |e| return e,
...@@ -908,7 +911,7 @@ pub const File = struct {...@@ -908,7 +911,7 @@ pub const File = struct {
908 error.Unexpected => unreachable, // Resource deallocation must succeed.911 error.Unexpected => unreachable, // Resource deallocation must succeed.
909 };912 };
910 } else {913 } else {
911 return os.flock(file.handle, os.LOCK_UN) catch |err| switch (err) {914 return os.flock(file.handle, os.LOCK.UN) catch |err| switch (err) {
912 error.WouldBlock => unreachable, // unlocking can't block915 error.WouldBlock => unreachable, // unlocking can't block
913 error.SystemResources => unreachable, // We are deallocating resources.916 error.SystemResources => unreachable, // We are deallocating resources.
914 error.Unexpected => unreachable, // Resource deallocation must succeed.917 error.Unexpected => unreachable, // Resource deallocation must succeed.
...@@ -949,9 +952,9 @@ pub const File = struct {...@@ -949,9 +952,9 @@ pub const File = struct {
949 };952 };
950 } else {953 } else {
951 os.flock(file.handle, switch (l) {954 os.flock(file.handle, switch (l) {
952 .None => os.LOCK_UN,955 .None => os.LOCK.UN,
953 .Shared => os.LOCK_SH | os.LOCK_NB,956 .Shared => os.LOCK.SH | os.LOCK.NB,
954 .Exclusive => os.LOCK_EX | os.LOCK_NB,957 .Exclusive => os.LOCK.EX | os.LOCK.NB,
955 }) catch |err| switch (err) {958 }) catch |err| switch (err) {
956 error.WouldBlock => return false,959 error.WouldBlock => return false,
957 else => |e| return e,960 else => |e| return e,
...@@ -998,7 +1001,7 @@ pub const File = struct {...@@ -998,7 +1001,7 @@ pub const File = struct {
998 error.Unexpected => unreachable, // Resource deallocation must succeed.1001 error.Unexpected => unreachable, // Resource deallocation must succeed.
999 };1002 };
1000 } else {1003 } else {
1001 return os.flock(file.handle, os.LOCK_SH | os.LOCK_NB) catch |err| switch (err) {1004 return os.flock(file.handle, os.LOCK.SH | os.LOCK.NB) catch |err| switch (err) {
1002 error.WouldBlock => unreachable, // File was not locked in exclusive mode.1005 error.WouldBlock => unreachable, // File was not locked in exclusive mode.
1003 else => |e| return e,1006 else => |e| return e,
1004 };1007 };
lib/std/fs/wasi.zig+6-5
...@@ -3,8 +3,9 @@ const os = std.os;...@@ -3,8 +3,9 @@ const os = std.os;
3const mem = std.mem;3const mem = std.mem;
4const math = std.math;4const math = std.math;
5const Allocator = mem.Allocator;5const Allocator = mem.Allocator;
66const wasi = std.os.wasi;
7usingnamespace std.os.wasi;7const fd_t = wasi.fd_t;
8const prestat_t = wasi.prestat_t;
89
9/// Type-tag of WASI preopen.10/// Type-tag of WASI preopen.
10///11///
...@@ -115,7 +116,7 @@ pub const PreopenList = struct {...@@ -115,7 +116,7 @@ pub const PreopenList = struct {
115116
116 while (true) {117 while (true) {
117 var buf: prestat_t = undefined;118 var buf: prestat_t = undefined;
118 switch (fd_prestat_get(fd, &buf)) {119 switch (wasi.fd_prestat_get(fd, &buf)) {
119 .SUCCESS => {},120 .SUCCESS => {},
120 .OPNOTSUPP => {121 .OPNOTSUPP => {
121 // not a preopen, so keep going122 // not a preopen, so keep going
...@@ -131,7 +132,7 @@ pub const PreopenList = struct {...@@ -131,7 +132,7 @@ pub const PreopenList = struct {
131 const preopen_len = buf.u.dir.pr_name_len;132 const preopen_len = buf.u.dir.pr_name_len;
132 const path_buf = try self.buffer.allocator.alloc(u8, preopen_len);133 const path_buf = try self.buffer.allocator.alloc(u8, preopen_len);
133 mem.set(u8, path_buf, 0);134 mem.set(u8, path_buf, 0);
134 switch (fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {135 switch (wasi.fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {
135 .SUCCESS => {},136 .SUCCESS => {},
136 else => |err| return os.unexpectedErrno(err),137 else => |err| return os.unexpectedErrno(err),
137 }138 }
...@@ -174,5 +175,5 @@ test "extracting WASI preopens" {...@@ -174,5 +175,5 @@ test "extracting WASI preopens" {
174 try std.testing.expectEqual(@as(usize, 1), preopens.asSlice().len);175 try std.testing.expectEqual(@as(usize, 1), preopens.asSlice().len);
175 const preopen = preopens.find(PreopenType{ .Dir = "." }) orelse unreachable;176 const preopen = preopens.find(PreopenType{ .Dir = "." }) orelse unreachable;
176 try std.testing.expect(preopen.@"type".eql(PreopenType{ .Dir = "." }));177 try std.testing.expect(preopen.@"type".eql(PreopenType{ .Dir = "." }));
177 try std.testing.expectEqual(@as(usize, 3), preopen.fd);178 try std.testing.expectEqual(@as(i32, 3), preopen.fd);
178}179}
lib/std/fs/watch.zig+1-1
...@@ -250,7 +250,7 @@ pub fn Watch(comptime V: type) type {...@@ -250,7 +250,7 @@ pub fn Watch(comptime V: type) type {
250 };250 };
251251
252 // @TODO Can I close this fd and get an error from bsdWaitKev?252 // @TODO Can I close this fd and get an error from bsdWaitKev?
253 const flags = if (comptime std.Target.current.isDarwin()) os.O_SYMLINK | os.O_EVTONLY else 0;253 const flags = if (comptime std.Target.current.isDarwin()) os.O.SYMLINK | os.O.EVTONLY else 0;
254 const fd = try os.open(realpath, flags, 0);254 const fd = try os.open(realpath, flags, 0);
255 gop.value_ptr.putter_frame = async self.kqPutEvents(fd, gop.key_ptr.*, gop.value_ptr.*);255 gop.value_ptr.putter_frame = async self.kqPutEvents(fd, gop.key_ptr.*, gop.value_ptr.*);
256 return null;256 return null;
lib/std/hash_map.zig+34-2
...@@ -92,6 +92,34 @@ pub fn hashString(s: []const u8) u64 {...@@ -92,6 +92,34 @@ pub fn hashString(s: []const u8) u64 {
92 return std.hash.Wyhash.hash(0, s);92 return std.hash.Wyhash.hash(0, s);
93}93}
9494
95pub const StringIndexContext = struct {
96 bytes: *std.ArrayListUnmanaged(u8),
97
98 pub fn eql(self: @This(), a: u32, b: u32) bool {
99 _ = self;
100 return a == b;
101 }
102
103 pub fn hash(self: @This(), x: u32) u64 {
104 const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + x);
105 return hashString(x_slice);
106 }
107};
108
109pub const StringIndexAdapter = struct {
110 bytes: *std.ArrayListUnmanaged(u8),
111
112 pub fn eql(self: @This(), a_slice: []const u8, b: u32) bool {
113 const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + b);
114 return mem.eql(u8, a_slice, b_slice);
115 }
116
117 pub fn hash(self: @This(), adapted_key: []const u8) u64 {
118 _ = self;
119 return hashString(adapted_key);
120 }
121};
122
95/// Deprecated use `default_max_load_percentage`123/// Deprecated use `default_max_load_percentage`
96pub const DefaultMaxLoadPercentage = default_max_load_percentage;124pub const DefaultMaxLoadPercentage = default_max_load_percentage;
97125
...@@ -622,8 +650,12 @@ pub fn HashMap(...@@ -622,8 +650,12 @@ pub fn HashMap(
622 return other.promoteContext(self.allocator, new_ctx);650 return other.promoteContext(self.allocator, new_ctx);
623 }651 }
624652
625 /// Creates a copy of this map, using a specified allocator and context653 /// Creates a copy of this map, using a specified allocator and context.
626 pub fn cloneWithAllocatorAndContext(new_allocator: *Allocator, new_ctx: anytype) !HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {654 pub fn cloneWithAllocatorAndContext(
655 self: Self,
656 new_allocator: *Allocator,
657 new_ctx: anytype,
658 ) !HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {
627 var other = try self.unmanaged.cloneContext(new_allocator, new_ctx);659 var other = try self.unmanaged.cloneContext(new_allocator, new_ctx);
628 return other.promoteContext(new_allocator, new_ctx);660 return other.promoteContext(new_allocator, new_ctx);
629 }661 }
lib/std/heap.zig+6-6
...@@ -88,12 +88,12 @@ const CAllocator = struct {...@@ -88,12 +88,12 @@ const CAllocator = struct {
8888
89 fn alignedAllocSize(ptr: [*]u8) usize {89 fn alignedAllocSize(ptr: [*]u8) usize {
90 if (supports_posix_memalign) {90 if (supports_posix_memalign) {
91 return malloc_size(ptr);91 return CAllocator.malloc_size(ptr);
92 }92 }
9393
94 const unaligned_ptr = getHeader(ptr).*;94 const unaligned_ptr = getHeader(ptr).*;
95 const delta = @ptrToInt(ptr) - @ptrToInt(unaligned_ptr);95 const delta = @ptrToInt(ptr) - @ptrToInt(unaligned_ptr);
96 return malloc_size(unaligned_ptr) - delta;96 return CAllocator.malloc_size(unaligned_ptr) - delta;
97 }97 }
9898
99 fn alloc(99 fn alloc(
...@@ -113,7 +113,7 @@ const CAllocator = struct {...@@ -113,7 +113,7 @@ const CAllocator = struct {
113 return ptr[0..len];113 return ptr[0..len];
114 }114 }
115 const full_len = init: {115 const full_len = init: {
116 if (supports_malloc_size) {116 if (CAllocator.supports_malloc_size) {
117 const s = alignedAllocSize(ptr);117 const s = alignedAllocSize(ptr);
118 assert(s >= len);118 assert(s >= len);
119 break :init s;119 break :init s;
...@@ -141,7 +141,7 @@ const CAllocator = struct {...@@ -141,7 +141,7 @@ const CAllocator = struct {
141 if (new_len <= buf.len) {141 if (new_len <= buf.len) {
142 return mem.alignAllocLen(buf.len, new_len, len_align);142 return mem.alignAllocLen(buf.len, new_len, len_align);
143 }143 }
144 if (supports_malloc_size) {144 if (CAllocator.supports_malloc_size) {
145 const full_len = alignedAllocSize(buf.ptr);145 const full_len = alignedAllocSize(buf.ptr);
146 if (new_len <= full_len) {146 if (new_len <= full_len) {
147 return mem.alignAllocLen(full_len, new_len, len_align);147 return mem.alignAllocLen(full_len, new_len, len_align);
...@@ -304,8 +304,8 @@ const PageAllocator = struct {...@@ -304,8 +304,8 @@ const PageAllocator = struct {
304 const slice = os.mmap(304 const slice = os.mmap(
305 hint,305 hint,
306 alloc_len,306 alloc_len,
307 os.PROT_READ | os.PROT_WRITE,307 os.PROT.READ | os.PROT.WRITE,
308 os.MAP_PRIVATE | os.MAP_ANONYMOUS,308 os.MAP.PRIVATE | os.MAP.ANONYMOUS,
309 -1,309 -1,
310 0,310 0,
311 ) catch return error.OutOfMemory;311 ) catch return error.OutOfMemory;
lib/std/io/c_writer.zig+1
...@@ -2,6 +2,7 @@ const std = @import("../std.zig");...@@ -2,6 +2,7 @@ const std = @import("../std.zig");
2const builtin = std.builtin;2const builtin = std.builtin;
3const io = std.io;3const io = std.io;
4const testing = std.testing;4const testing = std.testing;
5const os = std.os;
56
6pub const CWriter = io.Writer(*std.c.FILE, std.fs.File.WriteError, cWriterWrite);7pub const CWriter = io.Writer(*std.c.FILE, std.fs.File.WriteError, cWriterWrite);
78
lib/std/json.zig+2-2
...@@ -1405,7 +1405,7 @@ fn parsedEqual(a: anytype, b: @TypeOf(a)) bool {...@@ -1405,7 +1405,7 @@ fn parsedEqual(a: anytype, b: @TypeOf(a)) bool {
1405 if (a == null or b == null) return false;1405 if (a == null or b == null) return false;
1406 return parsedEqual(a.?, b.?);1406 return parsedEqual(a.?, b.?);
1407 },1407 },
1408 .Union => {1408 .Union => |info| {
1409 if (info.tag_type) |UnionTag| {1409 if (info.tag_type) |UnionTag| {
1410 const tag_a = std.meta.activeTag(a);1410 const tag_a = std.meta.activeTag(a);
1411 const tag_b = std.meta.activeTag(b);1411 const tag_b = std.meta.activeTag(b);
...@@ -2657,7 +2657,7 @@ test "json.parser.dynamic" {...@@ -2657,7 +2657,7 @@ test "json.parser.dynamic" {
2657 try testing.expect(mem.eql(u8, large_int.NumberString, "18446744073709551615"));2657 try testing.expect(mem.eql(u8, large_int.NumberString, "18446744073709551615"));
2658}2658}
26592659
2660test "import more json tests" {2660test {
2661 _ = @import("json/test.zig");2661 _ = @import("json/test.zig");
2662 _ = @import("json/write_stream.zig");2662 _ = @import("json/write_stream.zig");
2663}2663}
lib/std/macho.zig+20-20
...@@ -601,35 +601,35 @@ pub const segment_command = extern struct {...@@ -601,35 +601,35 @@ pub const segment_command = extern struct {
601/// command and their size is reflected in cmdsize.601/// command and their size is reflected in cmdsize.
602pub const segment_command_64 = extern struct {602pub const segment_command_64 = extern struct {
603 /// LC_SEGMENT_64603 /// LC_SEGMENT_64
604 cmd: u32,604 cmd: u32 = LC_SEGMENT_64,
605605
606 /// includes sizeof section_64 structs606 /// includes sizeof section_64 structs
607 cmdsize: u32,607 cmdsize: u32 = @sizeOf(segment_command_64),
608608
609 /// segment name609 /// segment name
610 segname: [16]u8,610 segname: [16]u8,
611611
612 /// memory address of this segment612 /// memory address of this segment
613 vmaddr: u64,613 vmaddr: u64 = 0,
614614
615 /// memory size of this segment615 /// memory size of this segment
616 vmsize: u64,616 vmsize: u64 = 0,
617617
618 /// file offset of this segment618 /// file offset of this segment
619 fileoff: u64,619 fileoff: u64 = 0,
620620
621 /// amount to map from the file621 /// amount to map from the file
622 filesize: u64,622 filesize: u64 = 0,
623623
624 /// maximum VM protection624 /// maximum VM protection
625 maxprot: vm_prot_t,625 maxprot: vm_prot_t = VM_PROT_NONE,
626626
627 /// initial VM protection627 /// initial VM protection
628 initprot: vm_prot_t,628 initprot: vm_prot_t = VM_PROT_NONE,
629629
630 /// number of sections in segment630 /// number of sections in segment
631 nsects: u32,631 nsects: u32 = 0,
632 flags: u32,632 flags: u32 = 0,
633};633};
634634
635/// A segment is made up of zero or more sections. Non-MH_OBJECT files have635/// A segment is made up of zero or more sections. Non-MH_OBJECT files have
...@@ -700,34 +700,34 @@ pub const section_64 = extern struct {...@@ -700,34 +700,34 @@ pub const section_64 = extern struct {
700 segname: [16]u8,700 segname: [16]u8,
701701
702 /// memory address of this section702 /// memory address of this section
703 addr: u64,703 addr: u64 = 0,
704704
705 /// size in bytes of this section705 /// size in bytes of this section
706 size: u64,706 size: u64 = 0,
707707
708 /// file offset of this section708 /// file offset of this section
709 offset: u32,709 offset: u32 = 0,
710710
711 /// section alignment (power of 2)711 /// section alignment (power of 2)
712 @"align": u32,712 @"align": u32 = 0,
713713
714 /// file offset of relocation entries714 /// file offset of relocation entries
715 reloff: u32,715 reloff: u32 = 0,
716716
717 /// number of relocation entries717 /// number of relocation entries
718 nreloc: u32,718 nreloc: u32 = 0,
719719
720 /// flags (section type and attributes720 /// flags (section type and attributes
721 flags: u32,721 flags: u32 = S_REGULAR,
722722
723 /// reserved (for offset or index)723 /// reserved (for offset or index)
724 reserved1: u32,724 reserved1: u32 = 0,
725725
726 /// reserved (for count or sizeof)726 /// reserved (for count or sizeof)
727 reserved2: u32,727 reserved2: u32 = 0,
728728
729 /// reserved729 /// reserved
730 reserved3: u32,730 reserved3: u32 = 0,
731};731};
732732
733pub const nlist = extern struct {733pub const nlist = extern struct {
lib/std/math.zig+5
...@@ -1415,3 +1415,8 @@ test "boolMask" {...@@ -1415,3 +1415,8 @@ test "boolMask" {
1415 try runTest();1415 try runTest();
1416 comptime try runTest();1416 comptime try runTest();
1417}1417}
1418
1419/// Return the mod of `num` with the smallest integer type
1420pub fn comptimeMod(num: anytype, denom: comptime_int) IntFittingRange(0, denom - 1) {
1421 return @intCast(IntFittingRange(0, denom - 1), @mod(num, denom));
1422}
lib/std/math/big/int.zig+1-2
...@@ -672,10 +672,9 @@ pub const Mutable = struct {...@@ -672,10 +672,9 @@ pub const Mutable = struct {
672 ///672 ///
673 /// `limbs_buffer` is used for temporary storage during the operation.673 /// `limbs_buffer` is used for temporary storage during the operation.
674 pub fn gcdNoAlias(rma: *Mutable, x: Const, y: Const, limbs_buffer: *std.ArrayList(Limb)) !void {674 pub fn gcdNoAlias(rma: *Mutable, x: Const, y: Const, limbs_buffer: *std.ArrayList(Limb)) !void {
675 _ = limbs_buffer;
676 assert(rma.limbs.ptr != x.limbs.ptr); // illegal aliasing675 assert(rma.limbs.ptr != x.limbs.ptr); // illegal aliasing
677 assert(rma.limbs.ptr != y.limbs.ptr); // illegal aliasing676 assert(rma.limbs.ptr != y.limbs.ptr); // illegal aliasing
678 return gcdLehmer(rma, x, y, allocator);677 return gcdLehmer(rma, x, y, limbs_buffer);
679 }678 }
680679
681 fn gcdLehmer(result: *Mutable, xa: Const, ya: Const, limbs_buffer: *std.ArrayList(Limb)) !void {680 fn gcdLehmer(result: *Mutable, xa: Const, ya: Const, limbs_buffer: *std.ArrayList(Limb)) !void {
lib/std/net.zig+97-97
...@@ -10,7 +10,7 @@ const native_endian = builtin.target.cpu.arch.endian();...@@ -10,7 +10,7 @@ const native_endian = builtin.target.cpu.arch.endian();
1010
11// Windows 10 added support for unix sockets in build 17063, redstone 4 is the11// Windows 10 added support for unix sockets in build 17063, redstone 4 is the
12// first release to support them.12// first release to support them.
13pub const has_unix_sockets = @hasDecl(os, "sockaddr_un") and13pub const has_unix_sockets = @hasDecl(os.sockaddr, "un") and
14 (builtin.target.os.tag != .windows or14 (builtin.target.os.tag != .windows or
15 std.Target.current.os.version_range.windows.isAtLeast(.win10_rs4) orelse false);15 std.Target.current.os.version_range.windows.isAtLeast(.win10_rs4) orelse false);
1616
...@@ -18,7 +18,7 @@ pub const Address = extern union {...@@ -18,7 +18,7 @@ pub const Address = extern union {
18 any: os.sockaddr,18 any: os.sockaddr,
19 in: Ip4Address,19 in: Ip4Address,
20 in6: Ip6Address,20 in6: Ip6Address,
21 un: if (has_unix_sockets) os.sockaddr_un else void,21 un: if (has_unix_sockets) os.sockaddr.un else void,
2222
23 /// Parse the given IP address string into an Address value.23 /// Parse the given IP address string into an Address value.
24 /// It is recommended to use `resolveIp` instead, to handle24 /// It is recommended to use `resolveIp` instead, to handle
...@@ -70,9 +70,9 @@ pub const Address = extern union {...@@ -70,9 +70,9 @@ pub const Address = extern union {
7070
71 pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !Address {71 pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !Address {
72 switch (family) {72 switch (family) {
73 os.AF_INET => return parseIp4(name, port),73 os.AF.INET => return parseIp4(name, port),
74 os.AF_INET6 => return parseIp6(name, port),74 os.AF.INET6 => return parseIp6(name, port),
75 os.AF_UNSPEC => return parseIp(name, port),75 os.AF.UNSPEC => return parseIp(name, port),
76 else => unreachable,76 else => unreachable,
77 }77 }
78 }78 }
...@@ -98,8 +98,8 @@ pub const Address = extern union {...@@ -98,8 +98,8 @@ pub const Address = extern union {
98 }98 }
9999
100 pub fn initUnix(path: []const u8) !Address {100 pub fn initUnix(path: []const u8) !Address {
101 var sock_addr = os.sockaddr_un{101 var sock_addr = os.sockaddr.un{
102 .family = os.AF_UNIX,102 .family = os.AF.UNIX,
103 .path = undefined,103 .path = undefined,
104 };104 };
105105
...@@ -116,8 +116,8 @@ pub const Address = extern union {...@@ -116,8 +116,8 @@ pub const Address = extern union {
116 /// Asserts that the address is ip4 or ip6.116 /// Asserts that the address is ip4 or ip6.
117 pub fn getPort(self: Address) u16 {117 pub fn getPort(self: Address) u16 {
118 return switch (self.any.family) {118 return switch (self.any.family) {
119 os.AF_INET => self.in.getPort(),119 os.AF.INET => self.in.getPort(),
120 os.AF_INET6 => self.in6.getPort(),120 os.AF.INET6 => self.in6.getPort(),
121 else => unreachable,121 else => unreachable,
122 };122 };
123 }123 }
...@@ -126,8 +126,8 @@ pub const Address = extern union {...@@ -126,8 +126,8 @@ pub const Address = extern union {
126 /// Asserts that the address is ip4 or ip6.126 /// Asserts that the address is ip4 or ip6.
127 pub fn setPort(self: *Address, port: u16) void {127 pub fn setPort(self: *Address, port: u16) void {
128 switch (self.any.family) {128 switch (self.any.family) {
129 os.AF_INET => self.in.setPort(port),129 os.AF.INET => self.in.setPort(port),
130 os.AF_INET6 => self.in6.setPort(port),130 os.AF.INET6 => self.in6.setPort(port),
131 else => unreachable,131 else => unreachable,
132 }132 }
133 }133 }
...@@ -137,8 +137,8 @@ pub const Address = extern union {...@@ -137,8 +137,8 @@ pub const Address = extern union {
137 /// on the address family.137 /// on the address family.
138 pub fn initPosix(addr: *align(4) const os.sockaddr) Address {138 pub fn initPosix(addr: *align(4) const os.sockaddr) Address {
139 switch (addr.family) {139 switch (addr.family) {
140 os.AF_INET => return Address{ .in = Ip4Address{ .sa = @ptrCast(*const os.sockaddr_in, addr).* } },140 os.AF.INET => return Address{ .in = Ip4Address{ .sa = @ptrCast(*const os.sockaddr.in, addr).* } },
141 os.AF_INET6 => return Address{ .in6 = Ip6Address{ .sa = @ptrCast(*const os.sockaddr_in6, addr).* } },141 os.AF.INET6 => return Address{ .in6 = Ip6Address{ .sa = @ptrCast(*const os.sockaddr.in6, addr).* } },
142 else => unreachable,142 else => unreachable,
143 }143 }
144 }144 }
...@@ -150,9 +150,9 @@ pub const Address = extern union {...@@ -150,9 +150,9 @@ pub const Address = extern union {
150 out_stream: anytype,150 out_stream: anytype,
151 ) !void {151 ) !void {
152 switch (self.any.family) {152 switch (self.any.family) {
153 os.AF_INET => try self.in.format(fmt, options, out_stream),153 os.AF.INET => try self.in.format(fmt, options, out_stream),
154 os.AF_INET6 => try self.in6.format(fmt, options, out_stream),154 os.AF.INET6 => try self.in6.format(fmt, options, out_stream),
155 os.AF_UNIX => {155 os.AF.UNIX => {
156 if (!has_unix_sockets) {156 if (!has_unix_sockets) {
157 unreachable;157 unreachable;
158 }158 }
...@@ -171,15 +171,15 @@ pub const Address = extern union {...@@ -171,15 +171,15 @@ pub const Address = extern union {
171171
172 pub fn getOsSockLen(self: Address) os.socklen_t {172 pub fn getOsSockLen(self: Address) os.socklen_t {
173 switch (self.any.family) {173 switch (self.any.family) {
174 os.AF_INET => return self.in.getOsSockLen(),174 os.AF.INET => return self.in.getOsSockLen(),
175 os.AF_INET6 => return self.in6.getOsSockLen(),175 os.AF.INET6 => return self.in6.getOsSockLen(),
176 os.AF_UNIX => {176 os.AF.UNIX => {
177 if (!has_unix_sockets) {177 if (!has_unix_sockets) {
178 unreachable;178 unreachable;
179 }179 }
180180
181 const path_len = std.mem.len(std.meta.assumeSentinel(&self.un.path, 0));181 const path_len = std.mem.len(std.meta.assumeSentinel(&self.un.path, 0));
182 return @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);182 return @intCast(os.socklen_t, @sizeOf(os.sockaddr.un) - self.un.path.len + path_len);
183 },183 },
184 else => unreachable,184 else => unreachable,
185 }185 }
...@@ -187,7 +187,7 @@ pub const Address = extern union {...@@ -187,7 +187,7 @@ pub const Address = extern union {
187};187};
188188
189pub const Ip4Address = extern struct {189pub const Ip4Address = extern struct {
190 sa: os.sockaddr_in,190 sa: os.sockaddr.in,
191191
192 pub fn parse(buf: []const u8, port: u16) !Ip4Address {192 pub fn parse(buf: []const u8, port: u16) !Ip4Address {
193 var result = Ip4Address{193 var result = Ip4Address{
...@@ -249,7 +249,7 @@ pub const Ip4Address = extern struct {...@@ -249,7 +249,7 @@ pub const Ip4Address = extern struct {
249249
250 pub fn init(addr: [4]u8, port: u16) Ip4Address {250 pub fn init(addr: [4]u8, port: u16) Ip4Address {
251 return Ip4Address{251 return Ip4Address{
252 .sa = os.sockaddr_in{252 .sa = os.sockaddr.in{
253 .port = mem.nativeToBig(u16, port),253 .port = mem.nativeToBig(u16, port),
254 .addr = @ptrCast(*align(1) const u32, &addr).*,254 .addr = @ptrCast(*align(1) const u32, &addr).*,
255 },255 },
...@@ -288,19 +288,19 @@ pub const Ip4Address = extern struct {...@@ -288,19 +288,19 @@ pub const Ip4Address = extern struct {
288288
289 pub fn getOsSockLen(self: Ip4Address) os.socklen_t {289 pub fn getOsSockLen(self: Ip4Address) os.socklen_t {
290 _ = self;290 _ = self;
291 return @sizeOf(os.sockaddr_in);291 return @sizeOf(os.sockaddr.in);
292 }292 }
293};293};
294294
295pub const Ip6Address = extern struct {295pub const Ip6Address = extern struct {
296 sa: os.sockaddr_in6,296 sa: os.sockaddr.in6,
297297
298 /// Parse a given IPv6 address string into an Address.298 /// Parse a given IPv6 address string into an Address.
299 /// Assumes the Scope ID of the address is fully numeric.299 /// Assumes the Scope ID of the address is fully numeric.
300 /// For non-numeric addresses, see `resolveIp6`.300 /// For non-numeric addresses, see `resolveIp6`.
301 pub fn parse(buf: []const u8, port: u16) !Ip6Address {301 pub fn parse(buf: []const u8, port: u16) !Ip6Address {
302 var result = Ip6Address{302 var result = Ip6Address{
303 .sa = os.sockaddr_in6{303 .sa = os.sockaddr.in6{
304 .scope_id = 0,304 .scope_id = 0,
305 .port = mem.nativeToBig(u16, port),305 .port = mem.nativeToBig(u16, port),
306 .flowinfo = 0,306 .flowinfo = 0,
...@@ -407,7 +407,7 @@ pub const Ip6Address = extern struct {...@@ -407,7 +407,7 @@ pub const Ip6Address = extern struct {
407 pub fn resolve(buf: []const u8, port: u16) !Ip6Address {407 pub fn resolve(buf: []const u8, port: u16) !Ip6Address {
408 // TODO: Unify the implementations of resolveIp6 and parseIp6.408 // TODO: Unify the implementations of resolveIp6 and parseIp6.
409 var result = Ip6Address{409 var result = Ip6Address{
410 .sa = os.sockaddr_in6{410 .sa = os.sockaddr.in6{
411 .scope_id = 0,411 .scope_id = 0,
412 .port = mem.nativeToBig(u16, port),412 .port = mem.nativeToBig(u16, port),
413 .flowinfo = 0,413 .flowinfo = 0,
...@@ -536,7 +536,7 @@ pub const Ip6Address = extern struct {...@@ -536,7 +536,7 @@ pub const Ip6Address = extern struct {
536536
537 pub fn init(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Ip6Address {537 pub fn init(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Ip6Address {
538 return Ip6Address{538 return Ip6Address{
539 .sa = os.sockaddr_in6{539 .sa = os.sockaddr.in6{
540 .addr = addr,540 .addr = addr,
541 .port = mem.nativeToBig(u16, port),541 .port = mem.nativeToBig(u16, port),
542 .flowinfo = flowinfo,542 .flowinfo = flowinfo,
...@@ -608,15 +608,15 @@ pub const Ip6Address = extern struct {...@@ -608,15 +608,15 @@ pub const Ip6Address = extern struct {
608608
609 pub fn getOsSockLen(self: Ip6Address) os.socklen_t {609 pub fn getOsSockLen(self: Ip6Address) os.socklen_t {
610 _ = self;610 _ = self;
611 return @sizeOf(os.sockaddr_in6);611 return @sizeOf(os.sockaddr.in6);
612 }612 }
613};613};
614614
615pub fn connectUnixSocket(path: []const u8) !Stream {615pub fn connectUnixSocket(path: []const u8) !Stream {
616 const opt_non_block = if (std.io.is_async) os.SOCK_NONBLOCK else 0;616 const opt_non_block = if (std.io.is_async) os.SOCK.NONBLOCK else 0;
617 const sockfd = try os.socket(617 const sockfd = try os.socket(
618 os.AF_UNIX,618 os.AF.UNIX,
619 os.SOCK_STREAM | os.SOCK_CLOEXEC | opt_non_block,619 os.SOCK.STREAM | os.SOCK.CLOEXEC | opt_non_block,
620 0,620 0,
621 );621 );
622 errdefer os.closeSocket(sockfd);622 errdefer os.closeSocket(sockfd);
...@@ -637,7 +637,7 @@ pub fn connectUnixSocket(path: []const u8) !Stream {...@@ -637,7 +637,7 @@ pub fn connectUnixSocket(path: []const u8) !Stream {
637637
638fn if_nametoindex(name: []const u8) !u32 {638fn if_nametoindex(name: []const u8) !u32 {
639 var ifr: os.ifreq = undefined;639 var ifr: os.ifreq = undefined;
640 var sockfd = try os.socket(os.AF_UNIX, os.SOCK_DGRAM | os.SOCK_CLOEXEC, 0);640 var sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0);
641 defer os.closeSocket(sockfd);641 defer os.closeSocket(sockfd);
642642
643 std.mem.copy(u8, &ifr.ifrn.name, name);643 std.mem.copy(u8, &ifr.ifrn.name, name);
...@@ -682,10 +682,10 @@ pub fn tcpConnectToHost(allocator: *mem.Allocator, name: []const u8, port: u16)...@@ -682,10 +682,10 @@ pub fn tcpConnectToHost(allocator: *mem.Allocator, name: []const u8, port: u16)
682}682}
683683
684pub fn tcpConnectToAddress(address: Address) !Stream {684pub fn tcpConnectToAddress(address: Address) !Stream {
685 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;685 const nonblock = if (std.io.is_async) os.SOCK.NONBLOCK else 0;
686 const sock_flags = os.SOCK_STREAM | nonblock |686 const sock_flags = os.SOCK.STREAM | nonblock |
687 (if (builtin.target.os.tag == .windows) 0 else os.SOCK_CLOEXEC);687 (if (builtin.target.os.tag == .windows) 0 else os.SOCK.CLOEXEC);
688 const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO_TCP);688 const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO.TCP);
689 errdefer os.closeSocket(sockfd);689 errdefer os.closeSocket(sockfd);
690690
691 if (std.io.is_async) {691 if (std.io.is_async) {
...@@ -724,10 +724,10 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -724,10 +724,10 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
724724
725 const sys = if (builtin.target.os.tag == .windows) os.windows.ws2_32 else os.system;725 const sys = if (builtin.target.os.tag == .windows) os.windows.ws2_32 else os.system;
726 const hints = os.addrinfo{726 const hints = os.addrinfo{
727 .flags = sys.AI_NUMERICSERV,727 .flags = sys.AI.NUMERICSERV,
728 .family = os.AF_UNSPEC,728 .family = os.AF.UNSPEC,
729 .socktype = os.SOCK_STREAM,729 .socktype = os.SOCK.STREAM,
730 .protocol = os.IPPROTO_TCP,730 .protocol = os.IPPROTO.TCP,
731 .canonname = null,731 .canonname = null,
732 .addr = null,732 .addr = null,
733 .addrlen = 0,733 .addrlen = 0,
...@@ -794,8 +794,8 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -794,8 +794,8 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
794 return result;794 return result;
795 }795 }
796 if (builtin.target.os.tag == .linux) {796 if (builtin.target.os.tag == .linux) {
797 const flags = std.c.AI_NUMERICSERV;797 const flags = std.c.AI.NUMERICSERV;
798 const family = os.AF_UNSPEC;798 const family = os.AF.UNSPEC;
799 var lookup_addrs = std.ArrayList(LookupAddr).init(allocator);799 var lookup_addrs = std.ArrayList(LookupAddr).init(allocator);
800 defer lookup_addrs.deinit();800 defer lookup_addrs.deinit();
801801
...@@ -846,7 +846,7 @@ fn linuxLookupName(...@@ -846,7 +846,7 @@ fn linuxLookupName(
846 try canon.appendSlice(name);846 try canon.appendSlice(name);
847 if (Address.parseExpectingFamily(name, family, port)) |addr| {847 if (Address.parseExpectingFamily(name, family, port)) |addr| {
848 try addrs.append(LookupAddr{ .addr = addr });848 try addrs.append(LookupAddr{ .addr = addr });
849 } else |name_err| if ((flags & std.c.AI_NUMERICHOST) != 0) {849 } else |name_err| if ((flags & std.c.AI.NUMERICHOST) != 0) {
850 return name_err;850 return name_err;
851 } else {851 } else {
852 try linuxLookupNameFromHosts(addrs, canon, name, family, port);852 try linuxLookupNameFromHosts(addrs, canon, name, family, port);
...@@ -876,9 +876,9 @@ fn linuxLookupName(...@@ -876,9 +876,9 @@ fn linuxLookupName(
876876
877 // No further processing is needed if there are fewer than 2877 // No further processing is needed if there are fewer than 2
878 // results or if there are only IPv4 results.878 // results or if there are only IPv4 results.
879 if (addrs.items.len == 1 or family == os.AF_INET) return;879 if (addrs.items.len == 1 or family == os.AF.INET) return;
880 const all_ip4 = for (addrs.items) |addr| {880 const all_ip4 = for (addrs.items) |addr| {
881 if (addr.addr.any.family != os.AF_INET) break false;881 if (addr.addr.any.family != os.AF.INET) break false;
882 } else true;882 } else true;
883 if (all_ip4) return;883 if (all_ip4) return;
884884
...@@ -891,19 +891,19 @@ fn linuxLookupName(...@@ -891,19 +891,19 @@ fn linuxLookupName(
891 // A more idiomatic "ziggy" implementation would be welcome.891 // A more idiomatic "ziggy" implementation would be welcome.
892 for (addrs.items) |*addr, i| {892 for (addrs.items) |*addr, i| {
893 var key: i32 = 0;893 var key: i32 = 0;
894 var sa6: os.sockaddr_in6 = undefined;894 var sa6: os.sockaddr.in6 = undefined;
895 @memset(@ptrCast([*]u8, &sa6), 0, @sizeOf(os.sockaddr_in6));895 @memset(@ptrCast([*]u8, &sa6), 0, @sizeOf(os.sockaddr.in6));
896 var da6 = os.sockaddr_in6{896 var da6 = os.sockaddr.in6{
897 .family = os.AF_INET6,897 .family = os.AF.INET6,
898 .scope_id = addr.addr.in6.sa.scope_id,898 .scope_id = addr.addr.in6.sa.scope_id,
899 .port = 65535,899 .port = 65535,
900 .flowinfo = 0,900 .flowinfo = 0,
901 .addr = [1]u8{0} ** 16,901 .addr = [1]u8{0} ** 16,
902 };902 };
903 var sa4: os.sockaddr_in = undefined;903 var sa4: os.sockaddr.in = undefined;
904 @memset(@ptrCast([*]u8, &sa4), 0, @sizeOf(os.sockaddr_in));904 @memset(@ptrCast([*]u8, &sa4), 0, @sizeOf(os.sockaddr.in));
905 var da4 = os.sockaddr_in{905 var da4 = os.sockaddr.in{
906 .family = os.AF_INET,906 .family = os.AF.INET,
907 .port = 65535,907 .port = 65535,
908 .addr = 0,908 .addr = 0,
909 .zero = [1]u8{0} ** 8,909 .zero = [1]u8{0} ** 8,
...@@ -912,21 +912,21 @@ fn linuxLookupName(...@@ -912,21 +912,21 @@ fn linuxLookupName(
912 var da: *align(4) os.sockaddr = undefined;912 var da: *align(4) os.sockaddr = undefined;
913 var salen: os.socklen_t = undefined;913 var salen: os.socklen_t = undefined;
914 var dalen: os.socklen_t = undefined;914 var dalen: os.socklen_t = undefined;
915 if (addr.addr.any.family == os.AF_INET6) {915 if (addr.addr.any.family == os.AF.INET6) {
916 mem.copy(u8, &da6.addr, &addr.addr.in6.sa.addr);916 mem.copy(u8, &da6.addr, &addr.addr.in6.sa.addr);
917 da = @ptrCast(*os.sockaddr, &da6);917 da = @ptrCast(*os.sockaddr, &da6);
918 dalen = @sizeOf(os.sockaddr_in6);918 dalen = @sizeOf(os.sockaddr.in6);
919 sa = @ptrCast(*os.sockaddr, &sa6);919 sa = @ptrCast(*os.sockaddr, &sa6);
920 salen = @sizeOf(os.sockaddr_in6);920 salen = @sizeOf(os.sockaddr.in6);
921 } else {921 } else {
922 mem.copy(u8, &sa6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");922 mem.copy(u8, &sa6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
923 mem.copy(u8, &da6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");923 mem.copy(u8, &da6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
924 mem.writeIntNative(u32, da6.addr[12..], addr.addr.in.sa.addr);924 mem.writeIntNative(u32, da6.addr[12..], addr.addr.in.sa.addr);
925 da4.addr = addr.addr.in.sa.addr;925 da4.addr = addr.addr.in.sa.addr;
926 da = @ptrCast(*os.sockaddr, &da4);926 da = @ptrCast(*os.sockaddr, &da4);
927 dalen = @sizeOf(os.sockaddr_in);927 dalen = @sizeOf(os.sockaddr.in);
928 sa = @ptrCast(*os.sockaddr, &sa4);928 sa = @ptrCast(*os.sockaddr, &sa4);
929 salen = @sizeOf(os.sockaddr_in);929 salen = @sizeOf(os.sockaddr.in);
930 }930 }
931 const dpolicy = policyOf(da6.addr);931 const dpolicy = policyOf(da6.addr);
932 const dscope: i32 = scopeOf(da6.addr);932 const dscope: i32 = scopeOf(da6.addr);
...@@ -934,13 +934,13 @@ fn linuxLookupName(...@@ -934,13 +934,13 @@ fn linuxLookupName(
934 const dprec: i32 = dpolicy.prec;934 const dprec: i32 = dpolicy.prec;
935 const MAXADDRS = 3;935 const MAXADDRS = 3;
936 var prefixlen: i32 = 0;936 var prefixlen: i32 = 0;
937 const sock_flags = os.SOCK_DGRAM | os.SOCK_CLOEXEC;937 const sock_flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC;
938 if (os.socket(addr.addr.any.family, sock_flags, os.IPPROTO_UDP)) |fd| syscalls: {938 if (os.socket(addr.addr.any.family, sock_flags, os.IPPROTO.UDP)) |fd| syscalls: {
939 defer os.closeSocket(fd);939 defer os.closeSocket(fd);
940 os.connect(fd, da, dalen) catch break :syscalls;940 os.connect(fd, da, dalen) catch break :syscalls;
941 key |= DAS_USABLE;941 key |= DAS_USABLE;
942 os.getsockname(fd, sa, &salen) catch break :syscalls;942 os.getsockname(fd, sa, &salen) catch break :syscalls;
943 if (addr.addr.any.family == os.AF_INET) {943 if (addr.addr.any.family == os.AF.INET) {
944 // TODO sa6.addr[12..16] should return *[4]u8, making this cast unnecessary.944 // TODO sa6.addr[12..16] should return *[4]u8, making this cast unnecessary.
945 mem.writeIntNative(u32, @ptrCast(*[4]u8, &sa6.addr[12]), sa4.addr);945 mem.writeIntNative(u32, @ptrCast(*[4]u8, &sa6.addr[12]), sa4.addr);
946 }946 }
...@@ -1082,24 +1082,24 @@ fn linuxLookupNameFromNull(...@@ -1082,24 +1082,24 @@ fn linuxLookupNameFromNull(
1082 flags: u32,1082 flags: u32,
1083 port: u16,1083 port: u16,
1084) !void {1084) !void {
1085 if ((flags & std.c.AI_PASSIVE) != 0) {1085 if ((flags & std.c.AI.PASSIVE) != 0) {
1086 if (family != os.AF_INET6) {1086 if (family != os.AF.INET6) {
1087 (try addrs.addOne()).* = LookupAddr{1087 (try addrs.addOne()).* = LookupAddr{
1088 .addr = Address.initIp4([1]u8{0} ** 4, port),1088 .addr = Address.initIp4([1]u8{0} ** 4, port),
1089 };1089 };
1090 }1090 }
1091 if (family != os.AF_INET) {1091 if (family != os.AF.INET) {
1092 (try addrs.addOne()).* = LookupAddr{1092 (try addrs.addOne()).* = LookupAddr{
1093 .addr = Address.initIp6([1]u8{0} ** 16, port, 0, 0),1093 .addr = Address.initIp6([1]u8{0} ** 16, port, 0, 0),
1094 };1094 };
1095 }1095 }
1096 } else {1096 } else {
1097 if (family != os.AF_INET6) {1097 if (family != os.AF.INET6) {
1098 (try addrs.addOne()).* = LookupAddr{1098 (try addrs.addOne()).* = LookupAddr{
1099 .addr = Address.initIp4([4]u8{ 127, 0, 0, 1 }, port),1099 .addr = Address.initIp4([4]u8{ 127, 0, 0, 1 }, port),
1100 };1100 };
1101 }1101 }
1102 if (family != os.AF_INET) {1102 if (family != os.AF.INET) {
1103 (try addrs.addOne()).* = LookupAddr{1103 (try addrs.addOne()).* = LookupAddr{
1104 .addr = Address.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),1104 .addr = Address.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),
1105 };1105 };
...@@ -1252,8 +1252,8 @@ fn linuxLookupNameFromDns(...@@ -1252,8 +1252,8 @@ fn linuxLookupNameFromDns(
1252 rr: u8,1252 rr: u8,
1253 };1253 };
1254 const afrrs = [_]AfRr{1254 const afrrs = [_]AfRr{
1255 AfRr{ .af = os.AF_INET6, .rr = os.RR_A },1255 AfRr{ .af = os.AF.INET6, .rr = os.RR.A },
1256 AfRr{ .af = os.AF_INET, .rr = os.RR_AAAA },1256 AfRr{ .af = os.AF.INET, .rr = os.RR.AAAA },
1257 };1257 };
1258 var qbuf: [2][280]u8 = undefined;1258 var qbuf: [2][280]u8 = undefined;
1259 var abuf: [2][512]u8 = undefined;1259 var abuf: [2][512]u8 = undefined;
...@@ -1386,8 +1386,8 @@ fn resMSendRc(...@@ -1386,8 +1386,8 @@ fn resMSendRc(
1386 const timeout = 1000 * rc.timeout;1386 const timeout = 1000 * rc.timeout;
1387 const attempts = rc.attempts;1387 const attempts = rc.attempts;
13881388
1389 var sl: os.socklen_t = @sizeOf(os.sockaddr_in);1389 var sl: os.socklen_t = @sizeOf(os.sockaddr.in);
1390 var family: os.sa_family_t = os.AF_INET;1390 var family: os.sa_family_t = os.AF.INET;
13911391
1392 var ns_list = std.ArrayList(Address).init(rc.ns.allocator);1392 var ns_list = std.ArrayList(Address).init(rc.ns.allocator);
1393 defer ns_list.deinit();1393 defer ns_list.deinit();
...@@ -1398,9 +1398,9 @@ fn resMSendRc(...@@ -1398,9 +1398,9 @@ fn resMSendRc(
1398 for (rc.ns.items) |iplit, i| {1398 for (rc.ns.items) |iplit, i| {
1399 ns[i] = iplit.addr;1399 ns[i] = iplit.addr;
1400 assert(ns[i].getPort() == 53);1400 assert(ns[i].getPort() == 53);
1401 if (iplit.addr.any.family != os.AF_INET) {1401 if (iplit.addr.any.family != os.AF.INET) {
1402 sl = @sizeOf(os.sockaddr_in6);1402 sl = @sizeOf(os.sockaddr.in6);
1403 family = os.AF_INET6;1403 family = os.AF.INET6;
1404 }1404 }
1405 }1405 }
14061406
...@@ -1408,13 +1408,13 @@ fn resMSendRc(...@@ -1408,13 +1408,13 @@ fn resMSendRc(
1408 var sa: Address = undefined;1408 var sa: Address = undefined;
1409 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));1409 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
1410 sa.any.family = family;1410 sa.any.family = family;
1411 const flags = os.SOCK_DGRAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK;1411 const flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC | os.SOCK.NONBLOCK;
1412 const fd = os.socket(family, flags, 0) catch |err| switch (err) {1412 const fd = os.socket(family, flags, 0) catch |err| switch (err) {
1413 error.AddressFamilyNotSupported => blk: {1413 error.AddressFamilyNotSupported => blk: {
1414 // Handle case where system lacks IPv6 support1414 // Handle case where system lacks IPv6 support
1415 if (family == os.AF_INET6) {1415 if (family == os.AF.INET6) {
1416 family = os.AF_INET;1416 family = os.AF.INET;
1417 break :blk try os.socket(os.AF_INET, flags, 0);1417 break :blk try os.socket(os.AF.INET, flags, 0);
1418 }1418 }
1419 return err;1419 return err;
1420 },1420 },
...@@ -1429,15 +1429,15 @@ fn resMSendRc(...@@ -1429,15 +1429,15 @@ fn resMSendRc(
14291429
1430 // Convert any IPv4 addresses in a mixed environment to v4-mapped1430 // Convert any IPv4 addresses in a mixed environment to v4-mapped
1431 // TODO1431 // TODO
1432 //if (family == AF_INET6) {1432 //if (family == AF.INET6) {
1433 // setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);1433 // setsockopt(fd, IPPROTO.IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
1434 // for (i=0; i<nns; i++) {1434 // for (i=0; i<nns; i++) {
1435 // if (ns[i].sin.sin_family != AF_INET) continue;1435 // if (ns[i].sin.sin_family != AF.INET) continue;
1436 // memcpy(ns[i].sin6.sin6_addr.s6_addr+12,1436 // memcpy(ns[i].sin6.sin6_addr.s6_addr+12,
1437 // &ns[i].sin.sin_addr, 4);1437 // &ns[i].sin.sin_addr, 4);
1438 // memcpy(ns[i].sin6.sin6_addr.s6_addr,1438 // memcpy(ns[i].sin6.sin6_addr.s6_addr,
1439 // "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);1439 // "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
1440 // ns[i].sin6.sin6_family = AF_INET6;1440 // ns[i].sin6.sin6_family = AF.INET6;
1441 // ns[i].sin6.sin6_flowinfo = 0;1441 // ns[i].sin6.sin6_flowinfo = 0;
1442 // ns[i].sin6.sin6_scope_id = 0;1442 // ns[i].sin6.sin6_scope_id = 0;
1443 // }1443 // }
...@@ -1445,7 +1445,7 @@ fn resMSendRc(...@@ -1445,7 +1445,7 @@ fn resMSendRc(
14451445
1446 var pfd = [1]os.pollfd{os.pollfd{1446 var pfd = [1]os.pollfd{os.pollfd{
1447 .fd = fd,1447 .fd = fd,
1448 .events = os.POLLIN,1448 .events = os.POLL.IN,
1449 .revents = undefined,1449 .revents = undefined,
1450 }};1450 }};
1451 const retry_interval = timeout / attempts;1451 const retry_interval = timeout / attempts;
...@@ -1465,9 +1465,9 @@ fn resMSendRc(...@@ -1465,9 +1465,9 @@ fn resMSendRc(
1465 var j: usize = 0;1465 var j: usize = 0;
1466 while (j < ns.len) : (j += 1) {1466 while (j < ns.len) : (j += 1) {
1467 if (std.io.is_async) {1467 if (std.io.is_async) {
1468 _ = std.event.Loop.instance.?.sendto(fd, queries[i], os.MSG_NOSIGNAL, &ns[j].any, sl) catch undefined;1468 _ = std.event.Loop.instance.?.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined;
1469 } else {1469 } else {
1470 _ = os.sendto(fd, queries[i], os.MSG_NOSIGNAL, &ns[j].any, sl) catch undefined;1470 _ = os.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined;
1471 }1471 }
1472 }1472 }
1473 }1473 }
...@@ -1513,9 +1513,9 @@ fn resMSendRc(...@@ -1513,9 +1513,9 @@ fn resMSendRc(
1513 2 => if (servfail_retry != 0) {1513 2 => if (servfail_retry != 0) {
1514 servfail_retry -= 1;1514 servfail_retry -= 1;
1515 if (std.io.is_async) {1515 if (std.io.is_async) {
1516 _ = std.event.Loop.instance.?.sendto(fd, queries[i], os.MSG_NOSIGNAL, &ns[j].any, sl) catch undefined;1516 _ = std.event.Loop.instance.?.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined;
1517 } else {1517 } else {
1518 _ = os.sendto(fd, queries[i], os.MSG_NOSIGNAL, &ns[j].any, sl) catch undefined;1518 _ = os.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined;
1519 }1519 }
1520 },1520 },
1521 else => continue,1521 else => continue,
...@@ -1570,21 +1570,21 @@ fn dnsParse(...@@ -1570,21 +1570,21 @@ fn dnsParse(
15701570
1571fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8) !void {1571fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8) !void {
1572 switch (rr) {1572 switch (rr) {
1573 os.RR_A => {1573 os.RR.A => {
1574 if (data.len != 4) return error.InvalidDnsARecord;1574 if (data.len != 4) return error.InvalidDnsARecord;
1575 const new_addr = try ctx.addrs.addOne();1575 const new_addr = try ctx.addrs.addOne();
1576 new_addr.* = LookupAddr{1576 new_addr.* = LookupAddr{
1577 .addr = Address.initIp4(data[0..4].*, ctx.port),1577 .addr = Address.initIp4(data[0..4].*, ctx.port),
1578 };1578 };
1579 },1579 },
1580 os.RR_AAAA => {1580 os.RR.AAAA => {
1581 if (data.len != 16) return error.InvalidDnsAAAARecord;1581 if (data.len != 16) return error.InvalidDnsAAAARecord;
1582 const new_addr = try ctx.addrs.addOne();1582 const new_addr = try ctx.addrs.addOne();
1583 new_addr.* = LookupAddr{1583 new_addr.* = LookupAddr{
1584 .addr = Address.initIp6(data[0..16].*, ctx.port, 0, 0),1584 .addr = Address.initIp6(data[0..16].*, ctx.port, 0, 0),
1585 };1585 };
1586 },1586 },
1587 os.RR_CNAME => {1587 os.RR.CNAME => {
1588 var tmp: [256]u8 = undefined;1588 var tmp: [256]u8 = undefined;
1589 // Returns len of compressed name. strlen to get canon name.1589 // Returns len of compressed name. strlen to get canon name.
1590 _ = try os.dn_expand(packet, data, &tmp);1590 _ = try os.dn_expand(packet, data, &tmp);
...@@ -1700,7 +1700,7 @@ pub const StreamServer = struct {...@@ -1700,7 +1700,7 @@ pub const StreamServer = struct {
1700 /// seeing "Connection refused".1700 /// seeing "Connection refused".
1701 kernel_backlog: u31 = 128,1701 kernel_backlog: u31 = 128,
17021702
1703 /// Enable SO_REUSEADDR on the socket.1703 /// Enable SO.REUSEADDR on the socket.
1704 reuse_address: bool = false,1704 reuse_address: bool = false,
1705 };1705 };
17061706
...@@ -1722,9 +1722,9 @@ pub const StreamServer = struct {...@@ -1722,9 +1722,9 @@ pub const StreamServer = struct {
1722 }1722 }
17231723
1724 pub fn listen(self: *StreamServer, address: Address) !void {1724 pub fn listen(self: *StreamServer, address: Address) !void {
1725 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;1725 const nonblock = if (std.io.is_async) os.SOCK.NONBLOCK else 0;
1726 const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;1726 const sock_flags = os.SOCK.STREAM | os.SOCK.CLOEXEC | nonblock;
1727 const proto = if (address.any.family == os.AF_UNIX) @as(u32, 0) else os.IPPROTO_TCP;1727 const proto = if (address.any.family == os.AF.UNIX) @as(u32, 0) else os.IPPROTO.TCP;
17281728
1729 const sockfd = try os.socket(address.any.family, sock_flags, proto);1729 const sockfd = try os.socket(address.any.family, sock_flags, proto);
1730 self.sockfd = sockfd;1730 self.sockfd = sockfd;
...@@ -1736,8 +1736,8 @@ pub const StreamServer = struct {...@@ -1736,8 +1736,8 @@ pub const StreamServer = struct {
1736 if (self.reuse_address) {1736 if (self.reuse_address) {
1737 try os.setsockopt(1737 try os.setsockopt(
1738 sockfd,1738 sockfd,
1739 os.SOL_SOCKET,1739 os.SOL.SOCKET,
1740 os.SO_REUSEADDR,1740 os.SO.REUSEADDR,
1741 &mem.toBytes(@as(c_int, 1)),1741 &mem.toBytes(@as(c_int, 1)),
1742 );1742 );
1743 }1743 }
...@@ -1801,9 +1801,9 @@ pub const StreamServer = struct {...@@ -1801,9 +1801,9 @@ pub const StreamServer = struct {
1801 const accept_result = blk: {1801 const accept_result = blk: {
1802 if (std.io.is_async) {1802 if (std.io.is_async) {
1803 const loop = std.event.Loop.instance orelse return error.UnexpectedError;1803 const loop = std.event.Loop.instance orelse return error.UnexpectedError;
1804 break :blk loop.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK_CLOEXEC);1804 break :blk loop.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK.CLOEXEC);
1805 } else {1805 } else {
1806 break :blk os.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK_CLOEXEC);1806 break :blk os.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK.CLOEXEC);
1807 }1807 }
1808 };1808 };
18091809
lib/std/os.zig+239-120
...@@ -16,20 +16,21 @@...@@ -16,20 +16,21 @@
1616
17const root = @import("root");17const root = @import("root");
18const std = @import("std.zig");18const std = @import("std.zig");
19const builtin = std.builtin;19const builtin = @import("builtin");
20const assert = std.debug.assert;20const assert = std.debug.assert;
21const math = std.math;21const math = std.math;
22const mem = std.mem;22const mem = std.mem;
23const elf = std.elf;23const elf = std.elf;
24const dl = @import("dynamic_library.zig");24const dl = @import("dynamic_library.zig");
25const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;25const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
2626const is_windows = builtin.os.tag == .windows;
27pub const darwin = @import("os/darwin.zig");27
28pub const dragonfly = @import("os/dragonfly.zig");28pub const darwin = std.c;
29pub const freebsd = @import("os/freebsd.zig");29pub const dragonfly = std.c;
30pub const haiku = @import("os/haiku.zig");30pub const freebsd = std.c;
31pub const netbsd = @import("os/netbsd.zig");31pub const haiku = std.c;
32pub const openbsd = @import("os/openbsd.zig");32pub const netbsd = std.c;
33pub const openbsd = std.c;
33pub const linux = @import("os/linux.zig");34pub const linux = @import("os/linux.zig");
34pub const uefi = @import("os/uefi.zig");35pub const uefi = @import("os/uefi.zig");
35pub const wasi = @import("os/wasi.zig");36pub const wasi = @import("os/wasi.zig");
...@@ -40,15 +41,10 @@ comptime {...@@ -40,15 +41,10 @@ comptime {
40}41}
4142
42test {43test {
43 _ = darwin;
44 _ = freebsd;
45 _ = linux;44 _ = linux;
46 _ = netbsd;
47 _ = openbsd;
48 _ = uefi;45 _ = uefi;
49 _ = wasi;46 _ = wasi;
50 _ = windows;47 _ = windows;
51 _ = haiku;
5248
53 _ = @import("os/test.zig");49 _ = @import("os/test.zig");
54}50}
...@@ -58,22 +54,150 @@ test {...@@ -58,22 +54,150 @@ test {
58/// When not linking libc, it is the OS-specific system interface.54/// When not linking libc, it is the OS-specific system interface.
59pub const system = if (@hasDecl(root, "os") and root.os != @This())55pub const system = if (@hasDecl(root, "os") and root.os != @This())
60 root.os.system56 root.os.system
61else if (builtin.link_libc)57else if (builtin.link_libc or is_windows)
62 std.c58 std.c
63else switch (builtin.os.tag) {59else switch (builtin.os.tag) {
64 .macos, .ios, .watchos, .tvos => darwin,
65 .freebsd => freebsd,
66 .haiku => haiku,
67 .linux => linux,60 .linux => linux,
68 .netbsd => netbsd,
69 .openbsd => openbsd,
70 .dragonfly => dragonfly,
71 .wasi => wasi,61 .wasi => wasi,
72 .windows => windows,62 .uefi => uefi,
73 else => struct {},63 else => struct {},
74};64};
7565
76pub usingnamespace @import("os/bits.zig");66pub const AF = system.AF;
67pub const ARCH = system.ARCH;
68pub const AT = system.AT;
69pub const CLOCK = system.CLOCK;
70pub const CPU_COUNT = system.CPU_COUNT;
71pub const CTL = system.CTL;
72pub const DT = system.DT;
73pub const E = system.E;
74pub const Elf_Symndx = system.Elf_Symndx;
75pub const F = system.F;
76pub const FD_CLOEXEC = system.FD_CLOEXEC;
77pub const Flock = system.Flock;
78pub const HOST_NAME_MAX = system.HOST_NAME_MAX;
79pub const IFNAMESIZE = system.IFNAMESIZE;
80pub const IOV_MAX = system.IOV_MAX;
81pub const IPPROTO = system.IPPROTO;
82pub const KERN = system.KERN;
83pub const Kevent = system.Kevent;
84pub const LOCK = system.LOCK;
85pub const MADV = system.MADV;
86pub const MAP = system.MAP;
87pub const MAX_ADDR_LEN = system.MAX_ADDR_LEN;
88pub const MMAP2_UNIT = system.MMAP2_UNIT;
89pub const MSG = system.MSG;
90pub const NAME_MAX = system.NAME_MAX;
91pub const O = system.O;
92pub const PATH_MAX = system.PATH_MAX;
93pub const POLL = system.POLL;
94pub const POSIX_FADV = system.POSIX_FADV;
95pub const PR = system.PR;
96pub const PROT = system.PROT;
97pub const REG = system.REG;
98pub const RIGHT = system.RIGHT;
99pub const RLIM = system.RLIM;
100pub const RR = system.RR;
101pub const S = system.S;
102pub const SA = system.SA;
103pub const SC = system.SC;
104pub const SEEK = system.SEEK;
105pub const SHUT = system.SHUT;
106pub const SIG = system.SIG;
107pub const SIOCGIFINDEX = system.SIOCGIFINDEX;
108pub const SO = system.SO;
109pub const SOCK = system.SOCK;
110pub const SOL = system.SOL;
111pub const STDERR_FILENO = system.STDERR_FILENO;
112pub const STDIN_FILENO = system.STDIN_FILENO;
113pub const STDOUT_FILENO = system.STDOUT_FILENO;
114pub const SYS = system.SYS;
115pub const Sigaction = system.Sigaction;
116pub const Stat = system.Stat;
117pub const TCSA = system.TCSA;
118pub const TCP = system.TCP;
119pub const VDSO = system.VDSO;
120pub const W = system.W;
121pub const addrinfo = system.addrinfo;
122pub const blkcnt_t = system.blkcnt_t;
123pub const blksize_t = system.blksize_t;
124pub const clock_t = system.clock_t;
125pub const cpu_set_t = system.cpu_set_t;
126pub const dev_t = system.dev_t;
127pub const dl_phdr_info = system.dl_phdr_info;
128pub const empty_sigset = system.empty_sigset;
129pub const fd_t = system.fd_t;
130pub const fdflags_t = system.fdflags_t;
131pub const fdstat_t = system.fdstat_t;
132pub const gid_t = system.gid_t;
133pub const ifreq = system.ifreq;
134pub const ino_t = system.ino_t;
135pub const lookupflags_t = system.lookupflags_t;
136pub const mcontext_t = system.mcontext_t;
137pub const mode_t = system.mode_t;
138pub const msghdr = system.msghdr;
139pub const msghdr_const = system.msghdr_const;
140pub const nfds_t = system.nfds_t;
141pub const nlink_t = system.nlink_t;
142pub const off_t = system.off_t;
143pub const oflags_t = system.oflags_t;
144pub const pid_t = system.pid_t;
145pub const pollfd = system.pollfd;
146pub const rights_t = system.rights_t;
147pub const rlim_t = system.rlim_t;
148pub const rlimit = system.rlimit;
149pub const rlimit_resource = system.rlimit_resource;
150pub const rusage = system.rusage;
151pub const sa_family_t = system.sa_family_t;
152pub const siginfo_t = system.siginfo_t;
153pub const sigset_t = system.sigset_t;
154pub const sockaddr = system.sockaddr;
155pub const socklen_t = system.socklen_t;
156pub const stack_t = system.stack_t;
157pub const termios = system.termios;
158pub const time_t = system.time_t;
159pub const timespec = system.timespec;
160pub const timestamp_t = system.timestamp_t;
161pub const timeval = system.timeval;
162pub const timezone = system.timezone;
163pub const ucontext_t = system.ucontext_t;
164pub const uid_t = system.uid_t;
165pub const user_desc = system.user_desc;
166pub const utsname = system.utsname;
167
168pub const F_OK = system.F_OK;
169pub const R_OK = system.R_OK;
170pub const W_OK = system.W_OK;
171pub const X_OK = system.X_OK;
172
173pub const iovec = extern struct {
174 iov_base: [*]u8,
175 iov_len: usize,
176};
177
178pub const iovec_const = extern struct {
179 iov_base: [*]const u8,
180 iov_len: usize,
181};
182
183pub const LOG = struct {
184 /// system is unusable
185 pub const EMERG = 0;
186 /// action must be taken immediately
187 pub const ALERT = 1;
188 /// critical conditions
189 pub const CRIT = 2;
190 /// error conditions
191 pub const ERR = 3;
192 /// warning conditions
193 pub const WARNING = 4;
194 /// normal but significant condition
195 pub const NOTICE = 5;
196 /// informational
197 pub const INFO = 6;
198 /// debug-level messages
199 pub const DEBUG = 7;
200};
77201
78pub const socket_t = if (builtin.os.tag == .windows) windows.ws2_32.SOCKET else fd_t;202pub const socket_t = if (builtin.os.tag == .windows) windows.ws2_32.SOCKET else fd_t;
79203
...@@ -136,7 +260,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {...@@ -136,7 +260,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
136 if (builtin.os.tag == .linux or builtin.os.tag == .freebsd) {260 if (builtin.os.tag == .linux or builtin.os.tag == .freebsd) {
137 var buf = buffer;261 var buf = buffer;
138 const use_c = builtin.os.tag != .linux or262 const use_c = builtin.os.tag != .linux or
139 std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok;263 std.c.versionCheck(std.builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok;
140264
141 while (buf.len != 0) {265 while (buf.len != 0) {
142 const res = if (use_c) blk: {266 const res = if (use_c) blk: {
...@@ -178,11 +302,11 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {...@@ -178,11 +302,11 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
178}302}
179303
180fn getRandomBytesDevURandom(buf: []u8) !void {304fn getRandomBytesDevURandom(buf: []u8) !void {
181 const fd = try openZ("/dev/urandom", O_RDONLY | O_CLOEXEC, 0);305 const fd = try openZ("/dev/urandom", O.RDONLY | O.CLOEXEC, 0);
182 defer close(fd);306 defer close(fd);
183307
184 const st = try fstat(fd);308 const st = try fstat(fd);
185 if (!S_ISCHR(st.mode)) {309 if (!S.ISCHR(st.mode)) {
186 return error.NoDevice;310 return error.NoDevice;
187 }311 }
188312
...@@ -210,11 +334,11 @@ pub fn abort() noreturn {...@@ -210,11 +334,11 @@ pub fn abort() noreturn {
210 windows.kernel32.ExitProcess(3);334 windows.kernel32.ExitProcess(3);
211 }335 }
212 if (!builtin.link_libc and builtin.os.tag == .linux) {336 if (!builtin.link_libc and builtin.os.tag == .linux) {
213 raise(SIGABRT) catch {};337 raise(SIG.ABRT) catch {};
214338
215 // TODO the rest of the implementation of abort() from musl libc here339 // TODO the rest of the implementation of abort() from musl libc here
216340
217 raise(SIGKILL) catch {};341 raise(SIG.KILL) catch {};
218 exit(127);342 exit(127);
219 }343 }
220 if (builtin.os.tag == .uefi) {344 if (builtin.os.tag == .uefi) {
...@@ -239,15 +363,15 @@ pub fn raise(sig: u8) RaiseError!void {...@@ -239,15 +363,15 @@ pub fn raise(sig: u8) RaiseError!void {
239 }363 }
240364
241 if (builtin.os.tag == .linux) {365 if (builtin.os.tag == .linux) {
242 var set: linux.sigset_t = undefined;366 var set: sigset_t = undefined;
243 // block application signals367 // block application signals
244 _ = linux.sigprocmask(SIG_BLOCK, &linux.app_mask, &set);368 _ = linux.sigprocmask(SIG.BLOCK, &linux.app_mask, &set);
245369
246 const tid = linux.gettid();370 const tid = linux.gettid();
247 const rc = linux.tkill(tid, sig);371 const rc = linux.tkill(tid, sig);
248372
249 // restore signal mask373 // restore signal mask
250 _ = linux.sigprocmask(SIG_SETMASK, &set, null);374 _ = linux.sigprocmask(SIG.SETMASK, &set, null);
251375
252 switch (errno(rc)) {376 switch (errno(rc)) {
253 .SUCCESS => return,377 .SUCCESS => return,
...@@ -1040,18 +1164,18 @@ pub const OpenError = error{...@@ -1040,18 +1164,18 @@ pub const OpenError = error{
1040 /// for 64-bit targets, as well as when opening directories.1164 /// for 64-bit targets, as well as when opening directories.
1041 FileTooBig,1165 FileTooBig,
10421166
1043 /// The path refers to directory but the `O_DIRECTORY` flag was not provided.1167 /// The path refers to directory but the `O.DIRECTORY` flag was not provided.
1044 IsDir,1168 IsDir,
10451169
1046 /// A new path cannot be created because the device has no room for the new file.1170 /// A new path cannot be created because the device has no room for the new file.
1047 /// This error is only reachable when the `O_CREAT` flag is provided.1171 /// This error is only reachable when the `O.CREAT` flag is provided.
1048 NoSpaceLeft,1172 NoSpaceLeft,
10491173
1050 /// A component used as a directory in the path was not, in fact, a directory, or1174 /// A component used as a directory in the path was not, in fact, a directory, or
1051 /// `O_DIRECTORY` was specified and the path was not a directory.1175 /// `O.DIRECTORY` was specified and the path was not a directory.
1052 NotDir,1176 NotDir,
10531177
1054 /// The path already exists and the `O_CREAT` and `O_EXCL` flags were provided.1178 /// The path already exists and the `O.CREAT` and `O.EXCL` flags were provided.
1055 PathAlreadyExists,1179 PathAlreadyExists,
1056 DeviceBusy,1180 DeviceBusy,
10571181
...@@ -1123,20 +1247,20 @@ fn openOptionsFromFlags(flags: u32) windows.OpenFileOptions {...@@ -1123,20 +1247,20 @@ fn openOptionsFromFlags(flags: u32) windows.OpenFileOptions {
1123 const w = windows;1247 const w = windows;
11241248
1125 var access_mask: w.ULONG = w.READ_CONTROL | w.FILE_WRITE_ATTRIBUTES | w.SYNCHRONIZE;1249 var access_mask: w.ULONG = w.READ_CONTROL | w.FILE_WRITE_ATTRIBUTES | w.SYNCHRONIZE;
1126 if (flags & O_RDWR != 0) {1250 if (flags & O.RDWR != 0) {
1127 access_mask |= w.GENERIC_READ | w.GENERIC_WRITE;1251 access_mask |= w.GENERIC_READ | w.GENERIC_WRITE;
1128 } else if (flags & O_WRONLY != 0) {1252 } else if (flags & O.WRONLY != 0) {
1129 access_mask |= w.GENERIC_WRITE;1253 access_mask |= w.GENERIC_WRITE;
1130 } else {1254 } else {
1131 access_mask |= w.GENERIC_READ | w.GENERIC_WRITE;1255 access_mask |= w.GENERIC_READ | w.GENERIC_WRITE;
1132 }1256 }
11331257
1134 const open_dir: bool = flags & O_DIRECTORY != 0;1258 const open_dir: bool = flags & O.DIRECTORY != 0;
1135 const follow_symlinks: bool = flags & O_NOFOLLOW == 0;1259 const follow_symlinks: bool = flags & O.NOFOLLOW == 0;
11361260
1137 const creation: w.ULONG = blk: {1261 const creation: w.ULONG = blk: {
1138 if (flags & O_CREAT != 0) {1262 if (flags & O.CREAT != 0) {
1139 if (flags & O_EXCL != 0) {1263 if (flags & O.EXCL != 0) {
1140 break :blk w.FILE_CREATE;1264 break :blk w.FILE_CREATE;
1141 }1265 }
1142 }1266 }
...@@ -1842,7 +1966,7 @@ pub fn unlinkW(file_path_w: []const u16) UnlinkError!void {...@@ -1842,7 +1966,7 @@ pub fn unlinkW(file_path_w: []const u16) UnlinkError!void {
1842}1966}
18431967
1844pub const UnlinkatError = UnlinkError || error{1968pub const UnlinkatError = UnlinkError || error{
1845 /// When passing `AT_REMOVEDIR`, this error occurs when the named directory is not empty.1969 /// When passing `AT.REMOVEDIR`, this error occurs when the named directory is not empty.
1846 DirNotEmpty,1970 DirNotEmpty,
1847};1971};
18481972
...@@ -1865,7 +1989,7 @@ pub const unlinkatC = @compileError("deprecated: renamed to unlinkatZ");...@@ -1865,7 +1989,7 @@ pub const unlinkatC = @compileError("deprecated: renamed to unlinkatZ");
1865/// WASI-only. Same as `unlinkat` but targeting WASI.1989/// WASI-only. Same as `unlinkat` but targeting WASI.
1866/// See also `unlinkat`.1990/// See also `unlinkat`.
1867pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {1991pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
1868 const remove_dir = (flags & AT_REMOVEDIR) != 0;1992 const remove_dir = (flags & AT.REMOVEDIR) != 0;
1869 const res = if (remove_dir)1993 const res = if (remove_dir)
1870 wasi.path_remove_directory(dirfd, file_path.ptr, file_path.len)1994 wasi.path_remove_directory(dirfd, file_path.ptr, file_path.len)
1871 else1995 else
...@@ -1925,7 +2049,7 @@ pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatEr...@@ -1925,7 +2049,7 @@ pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatEr
19252049
1926/// Same as `unlinkat` but `sub_path_w` is UTF16LE, NT prefixed. Windows only.2050/// Same as `unlinkat` but `sub_path_w` is UTF16LE, NT prefixed. Windows only.
1927pub fn unlinkatW(dirfd: fd_t, sub_path_w: []const u16, flags: u32) UnlinkatError!void {2051pub fn unlinkatW(dirfd: fd_t, sub_path_w: []const u16, flags: u32) UnlinkatError!void {
1928 const remove_dir = (flags & AT_REMOVEDIR) != 0;2052 const remove_dir = (flags & AT.REMOVEDIR) != 0;
1929 return windows.DeleteFile(sub_path_w, .{ .dir = dirfd, .remove_dir = remove_dir });2053 return windows.DeleteFile(sub_path_w, .{ .dir = dirfd, .remove_dir = remove_dir });
1930}2054}
19312055
...@@ -2663,8 +2787,8 @@ pub fn isatty(handle: fd_t) bool {...@@ -2663,8 +2787,8 @@ pub fn isatty(handle: fd_t) bool {
2663 }2787 }
26642788
2665 // A tty is a character device that we can't seek or tell on.2789 // A tty is a character device that we can't seek or tell on.
2666 if (statbuf.fs_filetype != FILETYPE_CHARACTER_DEVICE or2790 if (statbuf.fs_filetype != .CHARACTER_DEVICE or
2667 (statbuf.fs_rights_base & (RIGHT_FD_SEEK | RIGHT_FD_TELL)) != 0)2791 (statbuf.fs_rights_base & (RIGHT.FD_SEEK | RIGHT.FD_TELL)) != 0)
2668 {2792 {
2669 // errno = ENOTTY;2793 // errno = ENOTTY;
2670 return false;2794 return false;
...@@ -2676,7 +2800,7 @@ pub fn isatty(handle: fd_t) bool {...@@ -2676,7 +2800,7 @@ pub fn isatty(handle: fd_t) bool {
2676 while (true) {2800 while (true) {
2677 var wsz: linux.winsize = undefined;2801 var wsz: linux.winsize = undefined;
2678 const fd = @bitCast(usize, @as(isize, handle));2802 const fd = @bitCast(usize, @as(isize, handle));
2679 const rc = linux.syscall3(.ioctl, fd, linux.TIOCGWINSZ, @ptrToInt(&wsz));2803 const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @ptrToInt(&wsz));
2680 switch (linux.getErrno(rc)) {2804 switch (linux.getErrno(rc)) {
2681 .SUCCESS => return true,2805 .SUCCESS => return true,
2682 .INTR => continue,2806 .INTR => continue,
...@@ -2739,10 +2863,10 @@ pub const SocketError = error{...@@ -2739,10 +2863,10 @@ pub const SocketError = error{
27392863
2740pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t {2864pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t {
2741 if (builtin.os.tag == .windows) {2865 if (builtin.os.tag == .windows) {
2742 // NOTE: windows translates the SOCK_NONBLOCK/SOCK_CLOEXEC flags into2866 // NOTE: windows translates the SOCK.NONBLOCK/SOCK.CLOEXEC flags into
2743 // windows-analagous operations2867 // windows-analagous operations
2744 const filtered_sock_type = socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC);2868 const filtered_sock_type = socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC);
2745 const flags: u32 = if ((socket_type & SOCK_CLOEXEC) != 0)2869 const flags: u32 = if ((socket_type & SOCK.CLOEXEC) != 0)
2746 windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT2870 windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT
2747 else2871 else
2748 0;2872 0;
...@@ -2755,7 +2879,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t...@@ -2755,7 +2879,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
2755 flags,2879 flags,
2756 );2880 );
2757 errdefer windows.closesocket(rc) catch unreachable;2881 errdefer windows.closesocket(rc) catch unreachable;
2758 if ((socket_type & SOCK_NONBLOCK) != 0) {2882 if ((socket_type & SOCK.NONBLOCK) != 0) {
2759 var mode: c_ulong = 1; // nonblocking2883 var mode: c_ulong = 1; // nonblocking
2760 if (windows.ws2_32.SOCKET_ERROR == windows.ws2_32.ioctlsocket(rc, windows.ws2_32.FIONBIO, &mode)) {2884 if (windows.ws2_32.SOCKET_ERROR == windows.ws2_32.ioctlsocket(rc, windows.ws2_32.FIONBIO, &mode)) {
2761 switch (windows.ws2_32.WSAGetLastError()) {2885 switch (windows.ws2_32.WSAGetLastError()) {
...@@ -2769,7 +2893,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t...@@ -2769,7 +2893,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
27692893
2770 const have_sock_flags = comptime !std.Target.current.isDarwin();2894 const have_sock_flags = comptime !std.Target.current.isDarwin();
2771 const filtered_sock_type = if (!have_sock_flags)2895 const filtered_sock_type = if (!have_sock_flags)
2772 socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC)2896 socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC)
2773 else2897 else
2774 socket_type;2898 socket_type;
2775 const rc = system.socket(domain, filtered_sock_type, protocol);2899 const rc = system.socket(domain, filtered_sock_type, protocol);
...@@ -2832,9 +2956,9 @@ pub fn shutdown(sock: socket_t, how: ShutdownHow) ShutdownError!void {...@@ -2832,9 +2956,9 @@ pub fn shutdown(sock: socket_t, how: ShutdownHow) ShutdownError!void {
2832 };2956 };
2833 } else {2957 } else {
2834 const rc = system.shutdown(sock, switch (how) {2958 const rc = system.shutdown(sock, switch (how) {
2835 .recv => SHUT_RD,2959 .recv => SHUT.RD,
2836 .send => SHUT_WR,2960 .send => SHUT.WR,
2837 .both => SHUT_RDWR,2961 .both => SHUT.RDWR,
2838 });2962 });
2839 switch (errno(rc)) {2963 switch (errno(rc)) {
2840 .SUCCESS => return,2964 .SUCCESS => return,
...@@ -3059,15 +3183,15 @@ pub fn accept(...@@ -3059,15 +3183,15 @@ pub fn accept(
3059 /// will return a value greater than was supplied to the call.3183 /// will return a value greater than was supplied to the call.
3060 addr_size: ?*socklen_t,3184 addr_size: ?*socklen_t,
3061 /// The following values can be bitwise ORed in flags to obtain different behavior:3185 /// The following values can be bitwise ORed in flags to obtain different behavior:
3062 /// * `SOCK_NONBLOCK` - Set the `O_NONBLOCK` file status flag on the open file description (see `open`)3186 /// * `SOCK.NONBLOCK` - Set the `O.NONBLOCK` file status flag on the open file description (see `open`)
3063 /// referred to by the new file descriptor. Using this flag saves extra calls to `fcntl` to achieve3187 /// referred to by the new file descriptor. Using this flag saves extra calls to `fcntl` to achieve
3064 /// the same result.3188 /// the same result.
3065 /// * `SOCK_CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the3189 /// * `SOCK.CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the
3066 /// description of the `O_CLOEXEC` flag in `open` for reasons why this may be useful.3190 /// description of the `O.CLOEXEC` flag in `open` for reasons why this may be useful.
3067 flags: u32,3191 flags: u32,
3068) AcceptError!socket_t {3192) AcceptError!socket_t {
3069 const have_accept4 = comptime !(std.Target.current.isDarwin() or builtin.os.tag == .windows);3193 const have_accept4 = comptime !(std.Target.current.isDarwin() or builtin.os.tag == .windows);
3070 assert(0 == (flags & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC))); // Unsupported flag(s)3194 assert(0 == (flags & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC))); // Unsupported flag(s)
30713195
3072 const accepted_sock = while (true) {3196 const accepted_sock = while (true) {
3073 const rc = if (have_accept4)3197 const rc = if (have_accept4)
...@@ -3177,7 +3301,7 @@ pub const EpollCtlError = error{...@@ -3177,7 +3301,7 @@ pub const EpollCtlError = error{
3177 FileDescriptorIncompatibleWithEpoll,3301 FileDescriptorIncompatibleWithEpoll,
3178} || UnexpectedError;3302} || UnexpectedError;
31793303
3180pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*epoll_event) EpollCtlError!void {3304pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*linux.epoll_event) EpollCtlError!void {
3181 const rc = system.epoll_ctl(epfd, op, fd, event);3305 const rc = system.epoll_ctl(epfd, op, fd, event);
3182 switch (errno(rc)) {3306 switch (errno(rc)) {
3183 .SUCCESS => return,3307 .SUCCESS => return,
...@@ -3197,7 +3321,7 @@ pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*epoll_event) EpollCtlErro...@@ -3197,7 +3321,7 @@ pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*epoll_event) EpollCtlErro
3197/// Waits for an I/O event on an epoll file descriptor.3321/// Waits for an I/O event on an epoll file descriptor.
3198/// Returns the number of file descriptors ready for the requested I/O,3322/// Returns the number of file descriptors ready for the requested I/O,
3199/// or zero if no file descriptor became ready during the requested timeout milliseconds.3323/// or zero if no file descriptor became ready during the requested timeout milliseconds.
3200pub fn epoll_wait(epfd: i32, events: []epoll_event, timeout: i32) usize {3324pub fn epoll_wait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize {
3201 while (true) {3325 while (true) {
3202 // TODO get rid of the @intCast3326 // TODO get rid of the @intCast
3203 const rc = system.epoll_wait(epfd, events.ptr, @intCast(u32, events.len), timeout);3327 const rc = system.epoll_wait(epfd, events.ptr, @intCast(u32, events.len), timeout);
...@@ -3399,7 +3523,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne...@@ -3399,7 +3523,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne
3399 .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.3523 .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
3400 .PROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.3524 .PROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
3401 .TIMEDOUT => return error.ConnectionTimedOut,3525 .TIMEDOUT => return error.ConnectionTimedOut,
3402 .NOENT => return error.FileNotFound, // Returned when socket is AF_UNIX and the given path does not exist.3526 .NOENT => return error.FileNotFound, // Returned when socket is AF.UNIX and the given path does not exist.
3403 else => |err| return unexpectedErrno(err),3527 else => |err| return unexpectedErrno(err),
3404 }3528 }
3405 }3529 }
...@@ -3408,7 +3532,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne...@@ -3408,7 +3532,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne
3408pub fn getsockoptError(sockfd: fd_t) ConnectError!void {3532pub fn getsockoptError(sockfd: fd_t) ConnectError!void {
3409 var err_code: i32 = undefined;3533 var err_code: i32 = undefined;
3410 var size: u32 = @sizeOf(u32);3534 var size: u32 = @sizeOf(u32);
3411 const rc = system.getsockopt(sockfd, SOL_SOCKET, SO_ERROR, @ptrCast([*]u8, &err_code), &size);3535 const rc = system.getsockopt(sockfd, SOL.SOCKET, SO.ERROR, @ptrCast([*]u8, &err_code), &size);
3412 assert(size == 4);3536 assert(size == 4);
3413 switch (errno(rc)) {3537 switch (errno(rc)) {
3414 .SUCCESS => switch (@intToEnum(E, err_code)) {3538 .SUCCESS => switch (@intToEnum(E, err_code)) {
...@@ -3463,11 +3587,6 @@ pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {...@@ -3463,11 +3587,6 @@ pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {
3463 }3587 }
3464}3588}
34653589
3466pub const Stat = if (builtin.link_libc)
3467 system.libc_stat
3468else
3469 system.kernel_stat;
3470
3471pub const FStatError = error{3590pub const FStatError = error{
3472 SystemResources,3591 SystemResources,
34733592
...@@ -3745,8 +3864,8 @@ pub const MMapError = error{...@@ -3745,8 +3864,8 @@ pub const MMapError = error{
3745 MemoryMappingNotSupported,3864 MemoryMappingNotSupported,
37463865
3747 /// A file descriptor refers to a non-regular file. Or a file mapping was requested,3866 /// A file descriptor refers to a non-regular file. Or a file mapping was requested,
3748 /// but the file descriptor is not open for reading. Or `MAP_SHARED` was requested3867 /// but the file descriptor is not open for reading. Or `MAP.SHARED` was requested
3749 /// and `PROT_WRITE` is set, but the file descriptor is not open in `O_RDWR` mode.3868 /// and `PROT_WRITE` is set, but the file descriptor is not open in `O.RDWR` mode.
3750 /// Or `PROT_WRITE` is set, but the file is append-only.3869 /// Or `PROT_WRITE` is set, but the file is append-only.
3751 AccessDenied,3870 AccessDenied,
37523871
...@@ -3778,7 +3897,7 @@ pub fn mmap(...@@ -3778,7 +3897,7 @@ pub fn mmap(
3778 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned3897 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
3779 const rc = mmap_sym(ptr, length, prot, flags, fd, ioffset);3898 const rc = mmap_sym(ptr, length, prot, flags, fd, ioffset);
3780 const err = if (builtin.link_libc) blk: {3899 const err = if (builtin.link_libc) blk: {
3781 if (rc != std.c.MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];3900 if (rc != std.c.MAP.FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];
3782 break :blk @intToEnum(E, system._errno().*);3901 break :blk @intToEnum(E, system._errno().*);
3783 } else blk: {3902 } else blk: {
3784 const err = errno(rc);3903 const err = errno(rc);
...@@ -3831,7 +3950,7 @@ pub const AccessError = error{...@@ -3831,7 +3950,7 @@ pub const AccessError = error{
3831} || UnexpectedError;3950} || UnexpectedError;
38323951
3833/// check user's permissions for a file3952/// check user's permissions for a file
3834/// TODO currently this assumes `mode` is `F_OK` on Windows.3953/// TODO currently this assumes `mode` is `F.OK` on Windows.
3835pub fn access(path: []const u8, mode: u32) AccessError!void {3954pub fn access(path: []const u8, mode: u32) AccessError!void {
3836 if (builtin.os.tag == .windows) {3955 if (builtin.os.tag == .windows) {
3837 const path_w = try windows.sliceToPrefixedFileW(path);3956 const path_w = try windows.sliceToPrefixedFileW(path);
...@@ -4001,11 +4120,11 @@ pub fn pipe2(flags: u32) PipeError![2]fd_t {...@@ -4001,11 +4120,11 @@ pub fn pipe2(flags: u32) PipeError![2]fd_t {
4001 if (flags == 0)4120 if (flags == 0)
4002 return fds;4121 return fds;
40034122
4004 // O_CLOEXEC is special, it's a file descriptor flag and must be set using4123 // O.CLOEXEC is special, it's a file descriptor flag and must be set using
4005 // F_SETFD.4124 // F.SETFD.
4006 if (flags & O_CLOEXEC != 0) {4125 if (flags & O.CLOEXEC != 0) {
4007 for (fds) |fd| {4126 for (fds) |fd| {
4008 switch (errno(system.fcntl(fd, F_SETFD, @as(u32, FD_CLOEXEC)))) {4127 switch (errno(system.fcntl(fd, F.SETFD, @as(u32, FD_CLOEXEC)))) {
4009 .SUCCESS => {},4128 .SUCCESS => {},
4010 .INVAL => unreachable, // Invalid flags4129 .INVAL => unreachable, // Invalid flags
4011 .BADF => unreachable, // Always a race condition4130 .BADF => unreachable, // Always a race condition
...@@ -4014,11 +4133,11 @@ pub fn pipe2(flags: u32) PipeError![2]fd_t {...@@ -4014,11 +4133,11 @@ pub fn pipe2(flags: u32) PipeError![2]fd_t {
4014 }4133 }
4015 }4134 }
40164135
4017 const new_flags = flags & ~@as(u32, O_CLOEXEC);4136 const new_flags = flags & ~@as(u32, O.CLOEXEC);
4018 // Set every other flag affecting the file status using F_SETFL.4137 // Set every other flag affecting the file status using F.SETFL.
4019 if (new_flags != 0) {4138 if (new_flags != 0) {
4020 for (fds) |fd| {4139 for (fds) |fd| {
4021 switch (errno(system.fcntl(fd, F_SETFL, new_flags))) {4140 switch (errno(system.fcntl(fd, F.SETFL, new_flags))) {
4022 .SUCCESS => {},4141 .SUCCESS => {},
4023 .INVAL => unreachable, // Invalid flags4142 .INVAL => unreachable, // Invalid flags
4024 .BADF => unreachable, // Always a race condition4143 .BADF => unreachable, // Always a race condition
...@@ -4108,7 +4227,7 @@ pub const SeekError = error{...@@ -4108,7 +4227,7 @@ pub const SeekError = error{
4108pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {4227pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
4109 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {4228 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
4110 var result: u64 = undefined;4229 var result: u64 = undefined;
4111 switch (errno(system.llseek(fd, offset, &result, SEEK_SET))) {4230 switch (errno(system.llseek(fd, offset, &result, SEEK.SET))) {
4112 .SUCCESS => return,4231 .SUCCESS => return,
4113 .BADF => unreachable, // always a race condition4232 .BADF => unreachable, // always a race condition
4114 .INVAL => return error.Unseekable,4233 .INVAL => return error.Unseekable,
...@@ -4123,7 +4242,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -4123,7 +4242,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
4123 }4242 }
4124 if (builtin.os.tag == .wasi and !builtin.link_libc) {4243 if (builtin.os.tag == .wasi and !builtin.link_libc) {
4125 var new_offset: wasi.filesize_t = undefined;4244 var new_offset: wasi.filesize_t = undefined;
4126 switch (wasi.fd_seek(fd, @bitCast(wasi.filedelta_t, offset), wasi.WHENCE_SET, &new_offset)) {4245 switch (wasi.fd_seek(fd, @bitCast(wasi.filedelta_t, offset), .SET, &new_offset)) {
4127 .SUCCESS => return,4246 .SUCCESS => return,
4128 .BADF => unreachable, // always a race condition4247 .BADF => unreachable, // always a race condition
4129 .INVAL => return error.Unseekable,4248 .INVAL => return error.Unseekable,
...@@ -4141,7 +4260,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -4141,7 +4260,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
4141 system.lseek;4260 system.lseek;
41424261
4143 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned4262 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4144 switch (errno(lseek_sym(fd, ioffset, SEEK_SET))) {4263 switch (errno(lseek_sym(fd, ioffset, SEEK.SET))) {
4145 .SUCCESS => return,4264 .SUCCESS => return,
4146 .BADF => unreachable, // always a race condition4265 .BADF => unreachable, // always a race condition
4147 .INVAL => return error.Unseekable,4266 .INVAL => return error.Unseekable,
...@@ -4156,7 +4275,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -4156,7 +4275,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
4156pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {4275pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
4157 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {4276 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
4158 var result: u64 = undefined;4277 var result: u64 = undefined;
4159 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_CUR))) {4278 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK.CUR))) {
4160 .SUCCESS => return,4279 .SUCCESS => return,
4161 .BADF => unreachable, // always a race condition4280 .BADF => unreachable, // always a race condition
4162 .INVAL => return error.Unseekable,4281 .INVAL => return error.Unseekable,
...@@ -4171,7 +4290,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -4171,7 +4290,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
4171 }4290 }
4172 if (builtin.os.tag == .wasi and !builtin.link_libc) {4291 if (builtin.os.tag == .wasi and !builtin.link_libc) {
4173 var new_offset: wasi.filesize_t = undefined;4292 var new_offset: wasi.filesize_t = undefined;
4174 switch (wasi.fd_seek(fd, offset, wasi.WHENCE_CUR, &new_offset)) {4293 switch (wasi.fd_seek(fd, offset, .CUR, &new_offset)) {
4175 .SUCCESS => return,4294 .SUCCESS => return,
4176 .BADF => unreachable, // always a race condition4295 .BADF => unreachable, // always a race condition
4177 .INVAL => return error.Unseekable,4296 .INVAL => return error.Unseekable,
...@@ -4188,7 +4307,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -4188,7 +4307,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
4188 system.lseek;4307 system.lseek;
41894308
4190 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned4309 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4191 switch (errno(lseek_sym(fd, ioffset, SEEK_CUR))) {4310 switch (errno(lseek_sym(fd, ioffset, SEEK.CUR))) {
4192 .SUCCESS => return,4311 .SUCCESS => return,
4193 .BADF => unreachable, // always a race condition4312 .BADF => unreachable, // always a race condition
4194 .INVAL => return error.Unseekable,4313 .INVAL => return error.Unseekable,
...@@ -4203,7 +4322,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -4203,7 +4322,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
4203pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {4322pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
4204 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {4323 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
4205 var result: u64 = undefined;4324 var result: u64 = undefined;
4206 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_END))) {4325 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK.END))) {
4207 .SUCCESS => return,4326 .SUCCESS => return,
4208 .BADF => unreachable, // always a race condition4327 .BADF => unreachable, // always a race condition
4209 .INVAL => return error.Unseekable,4328 .INVAL => return error.Unseekable,
...@@ -4218,7 +4337,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {...@@ -4218,7 +4337,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
4218 }4337 }
4219 if (builtin.os.tag == .wasi and !builtin.link_libc) {4338 if (builtin.os.tag == .wasi and !builtin.link_libc) {
4220 var new_offset: wasi.filesize_t = undefined;4339 var new_offset: wasi.filesize_t = undefined;
4221 switch (wasi.fd_seek(fd, offset, wasi.WHENCE_END, &new_offset)) {4340 switch (wasi.fd_seek(fd, offset, .END, &new_offset)) {
4222 .SUCCESS => return,4341 .SUCCESS => return,
4223 .BADF => unreachable, // always a race condition4342 .BADF => unreachable, // always a race condition
4224 .INVAL => return error.Unseekable,4343 .INVAL => return error.Unseekable,
...@@ -4235,7 +4354,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {...@@ -4235,7 +4354,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
4235 system.lseek;4354 system.lseek;
42364355
4237 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned4356 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4238 switch (errno(lseek_sym(fd, ioffset, SEEK_END))) {4357 switch (errno(lseek_sym(fd, ioffset, SEEK.END))) {
4239 .SUCCESS => return,4358 .SUCCESS => return,
4240 .BADF => unreachable, // always a race condition4359 .BADF => unreachable, // always a race condition
4241 .INVAL => return error.Unseekable,4360 .INVAL => return error.Unseekable,
...@@ -4250,7 +4369,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {...@@ -4250,7 +4369,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
4250pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {4369pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
4251 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {4370 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
4252 var result: u64 = undefined;4371 var result: u64 = undefined;
4253 switch (errno(system.llseek(fd, 0, &result, SEEK_CUR))) {4372 switch (errno(system.llseek(fd, 0, &result, SEEK.CUR))) {
4254 .SUCCESS => return result,4373 .SUCCESS => return result,
4255 .BADF => unreachable, // always a race condition4374 .BADF => unreachable, // always a race condition
4256 .INVAL => return error.Unseekable,4375 .INVAL => return error.Unseekable,
...@@ -4265,7 +4384,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {...@@ -4265,7 +4384,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
4265 }4384 }
4266 if (builtin.os.tag == .wasi and !builtin.link_libc) {4385 if (builtin.os.tag == .wasi and !builtin.link_libc) {
4267 var new_offset: wasi.filesize_t = undefined;4386 var new_offset: wasi.filesize_t = undefined;
4268 switch (wasi.fd_seek(fd, 0, wasi.WHENCE_CUR, &new_offset)) {4387 switch (wasi.fd_seek(fd, 0, .CUR, &new_offset)) {
4269 .SUCCESS => return new_offset,4388 .SUCCESS => return new_offset,
4270 .BADF => unreachable, // always a race condition4389 .BADF => unreachable, // always a race condition
4271 .INVAL => return error.Unseekable,4390 .INVAL => return error.Unseekable,
...@@ -4281,7 +4400,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {...@@ -4281,7 +4400,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
4281 else4400 else
4282 system.lseek;4401 system.lseek;
42834402
4284 const rc = lseek_sym(fd, 0, SEEK_CUR);4403 const rc = lseek_sym(fd, 0, SEEK.CUR);
4285 switch (errno(rc)) {4404 switch (errno(rc)) {
4286 .SUCCESS => return @bitCast(u64, rc),4405 .SUCCESS => return @bitCast(u64, rc),
4287 .BADF => unreachable, // always a race condition4406 .BADF => unreachable, // always a race condition
...@@ -4319,18 +4438,18 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {...@@ -4319,18 +4438,18 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
4319}4438}
43204439
4321fn setSockFlags(sock: socket_t, flags: u32) !void {4440fn setSockFlags(sock: socket_t, flags: u32) !void {
4322 if ((flags & SOCK_CLOEXEC) != 0) {4441 if ((flags & SOCK.CLOEXEC) != 0) {
4323 if (builtin.os.tag == .windows) {4442 if (builtin.os.tag == .windows) {
4324 // TODO: Find out if this is supported for sockets4443 // TODO: Find out if this is supported for sockets
4325 } else {4444 } else {
4326 var fd_flags = fcntl(sock, F_GETFD, 0) catch |err| switch (err) {4445 var fd_flags = fcntl(sock, F.GETFD, 0) catch |err| switch (err) {
4327 error.FileBusy => unreachable,4446 error.FileBusy => unreachable,
4328 error.Locked => unreachable,4447 error.Locked => unreachable,
4329 error.PermissionDenied => unreachable,4448 error.PermissionDenied => unreachable,
4330 else => |e| return e,4449 else => |e| return e,
4331 };4450 };
4332 fd_flags |= FD_CLOEXEC;4451 fd_flags |= FD_CLOEXEC;
4333 _ = fcntl(sock, F_SETFD, fd_flags) catch |err| switch (err) {4452 _ = fcntl(sock, F.SETFD, fd_flags) catch |err| switch (err) {
4334 error.FileBusy => unreachable,4453 error.FileBusy => unreachable,
4335 error.Locked => unreachable,4454 error.Locked => unreachable,
4336 error.PermissionDenied => unreachable,4455 error.PermissionDenied => unreachable,
...@@ -4338,7 +4457,7 @@ fn setSockFlags(sock: socket_t, flags: u32) !void {...@@ -4338,7 +4457,7 @@ fn setSockFlags(sock: socket_t, flags: u32) !void {
4338 };4457 };
4339 }4458 }
4340 }4459 }
4341 if ((flags & SOCK_NONBLOCK) != 0) {4460 if ((flags & SOCK.NONBLOCK) != 0) {
4342 if (builtin.os.tag == .windows) {4461 if (builtin.os.tag == .windows) {
4343 var mode: c_ulong = 1;4462 var mode: c_ulong = 1;
4344 if (windows.ws2_32.ioctlsocket(sock, windows.ws2_32.FIONBIO, &mode) == windows.ws2_32.SOCKET_ERROR) {4463 if (windows.ws2_32.ioctlsocket(sock, windows.ws2_32.FIONBIO, &mode) == windows.ws2_32.SOCKET_ERROR) {
...@@ -4351,14 +4470,14 @@ fn setSockFlags(sock: socket_t, flags: u32) !void {...@@ -4351,14 +4470,14 @@ fn setSockFlags(sock: socket_t, flags: u32) !void {
4351 }4470 }
4352 }4471 }
4353 } else {4472 } else {
4354 var fl_flags = fcntl(sock, F_GETFL, 0) catch |err| switch (err) {4473 var fl_flags = fcntl(sock, F.GETFL, 0) catch |err| switch (err) {
4355 error.FileBusy => unreachable,4474 error.FileBusy => unreachable,
4356 error.Locked => unreachable,4475 error.Locked => unreachable,
4357 error.PermissionDenied => unreachable,4476 error.PermissionDenied => unreachable,
4358 else => |e| return e,4477 else => |e| return e,
4359 };4478 };
4360 fl_flags |= O_NONBLOCK;4479 fl_flags |= O.NONBLOCK;
4361 _ = fcntl(sock, F_SETFL, fl_flags) catch |err| switch (err) {4480 _ = fcntl(sock, F.SETFL, fl_flags) catch |err| switch (err) {
4362 error.FileBusy => unreachable,4481 error.FileBusy => unreachable,
4363 error.Locked => unreachable,4482 error.Locked => unreachable,
4364 error.PermissionDenied => unreachable,4483 error.PermissionDenied => unreachable,
...@@ -4444,7 +4563,7 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealP...@@ -4444,7 +4563,7 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealP
4444 return realpathW(pathname_w.span(), out_buffer);4563 return realpathW(pathname_w.span(), out_buffer);
4445 }4564 }
4446 if (!builtin.link_libc) {4565 if (!builtin.link_libc) {
4447 const flags = if (builtin.os.tag == .linux) O_PATH | O_NONBLOCK | O_CLOEXEC else O_NONBLOCK | O_CLOEXEC;4566 const flags = if (builtin.os.tag == .linux) O.PATH | O.NONBLOCK | O.CLOEXEC else O.NONBLOCK | O.CLOEXEC;
4448 const fd = openZ(pathname, flags, 0) catch |err| switch (err) {4567 const fd = openZ(pathname, flags, 0) catch |err| switch (err) {
4449 error.FileLocksNotSupported => unreachable,4568 error.FileLocksNotSupported => unreachable,
4450 error.WouldBlock => unreachable,4569 error.WouldBlock => unreachable,
...@@ -4523,14 +4642,14 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -4523,14 +4642,14 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
4523 return out_buffer[0..end_index];4642 return out_buffer[0..end_index];
4524 },4643 },
4525 .macos, .ios, .watchos, .tvos => {4644 .macos, .ios, .watchos, .tvos => {
4526 // On macOS, we can use F_GETPATH fcntl command to query the OS for4645 // On macOS, we can use F.GETPATH fcntl command to query the OS for
4527 // the path to the file descriptor.4646 // the path to the file descriptor.
4528 @memset(out_buffer, 0, MAX_PATH_BYTES);4647 @memset(out_buffer, 0, MAX_PATH_BYTES);
4529 switch (errno(system.fcntl(fd, F_GETPATH, out_buffer))) {4648 switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
4530 .SUCCESS => {},4649 .SUCCESS => {},
4531 .BADF => return error.FileNotFound,4650 .BADF => return error.FileNotFound,
4532 // TODO man pages for fcntl on macOS don't really tell you what4651 // TODO man pages for fcntl on macOS don't really tell you what
4533 // errno values to expect when command is F_GETPATH...4652 // errno values to expect when command is F.GETPATH...
4534 else => |err| return unexpectedErrno(err),4653 else => |err| return unexpectedErrno(err),
4535 }4654 }
4536 const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;4655 const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;
...@@ -4679,7 +4798,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {...@@ -4679,7 +4798,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
4679 return;4798 return;
4680 }4799 }
4681 if (std.Target.current.os.tag == .windows) {4800 if (std.Target.current.os.tag == .windows) {
4682 if (clk_id == CLOCK_REALTIME) {4801 if (clk_id == CLOCK.REALTIME) {
4683 var ft: windows.FILETIME = undefined;4802 var ft: windows.FILETIME = undefined;
4684 windows.kernel32.GetSystemTimeAsFileTime(&ft);4803 windows.kernel32.GetSystemTimeAsFileTime(&ft);
4685 // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch.4804 // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch.
...@@ -4691,7 +4810,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {...@@ -4691,7 +4810,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
4691 };4810 };
4692 return;4811 return;
4693 } else {4812 } else {
4694 // TODO POSIX implementation of CLOCK_MONOTONIC on Windows.4813 // TODO POSIX implementation of CLOCK.MONOTONIC on Windows.
4695 return error.UnsupportedClock;4814 return error.UnsupportedClock;
4696 }4815 }
4697 }4816 }
...@@ -4929,7 +5048,7 @@ pub fn res_mkquery(...@@ -4929,7 +5048,7 @@ pub fn res_mkquery(
49295048
4930 // Make a reasonably unpredictable id5049 // Make a reasonably unpredictable id
4931 var ts: timespec = undefined;5050 var ts: timespec = undefined;
4932 clock_gettime(CLOCK_REALTIME, &ts) catch {};5051 clock_gettime(CLOCK.REALTIME, &ts) catch {};
4933 const UInt = std.meta.Int(.unsigned, std.meta.bitCount(@TypeOf(ts.tv_nsec)));5052 const UInt = std.meta.Int(.unsigned, std.meta.bitCount(@TypeOf(ts.tv_nsec)));
4934 const unsec = @bitCast(UInt, ts.tv_nsec);5053 const unsec = @bitCast(UInt, ts.tv_nsec);
4935 const id = @truncate(u32, unsec + unsec / 65536);5054 const id = @truncate(u32, unsec + unsec / 65536);
...@@ -4975,7 +5094,7 @@ pub const SendError = error{...@@ -4975,7 +5094,7 @@ pub const SendError = error{
4975 SystemResources,5094 SystemResources,
49765095
4977 /// The local end has been shut down on a connection oriented socket. In this case, the5096 /// The local end has been shut down on a connection oriented socket. In this case, the
4978 /// process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.5097 /// process will also receive a SIGPIPE unless MSG.NOSIGNAL is set.
4979 BrokenPipe,5098 BrokenPipe,
49805099
4981 FileDescriptorNotASocket,5100 FileDescriptorNotASocket,
...@@ -4991,13 +5110,13 @@ pub const SendMsgError = SendError || error{...@@ -4991,13 +5110,13 @@ pub const SendMsgError = SendError || error{
4991 /// The passed address didn't have the correct address family in its sa_family field.5110 /// The passed address didn't have the correct address family in its sa_family field.
4992 AddressFamilyNotSupported,5111 AddressFamilyNotSupported,
49935112
4994 /// Returned when socket is AF_UNIX and the given path has a symlink loop.5113 /// Returned when socket is AF.UNIX and the given path has a symlink loop.
4995 SymLinkLoop,5114 SymLinkLoop,
49965115
4997 /// Returned when socket is AF_UNIX and the given path length exceeds `MAX_PATH_BYTES` bytes.5116 /// Returned when socket is AF.UNIX and the given path length exceeds `MAX_PATH_BYTES` bytes.
4998 NameTooLong,5117 NameTooLong,
49995118
5000 /// Returned when socket is AF_UNIX and the given path does not point to an existing file.5119 /// Returned when socket is AF.UNIX and the given path does not point to an existing file.
5001 FileNotFound,5120 FileNotFound,
5002 NotDir,5121 NotDir,
50035122
...@@ -5090,7 +5209,7 @@ pub const SendToError = SendMsgError;...@@ -5090,7 +5209,7 @@ pub const SendToError = SendMsgError;
5090///5209///
5091/// sendto(sockfd, buf, len, flags, NULL, 0);5210/// sendto(sockfd, buf, len, flags, NULL, 0);
5092///5211///
5093/// If sendto() is used on a connection-mode (`SOCK_STREAM`, `SOCK_SEQPACKET`) socket, the arguments5212/// If sendto() is used on a connection-mode (`SOCK.STREAM`, `SOCK.SEQPACKET`) socket, the arguments
5094/// `dest_addr` and `addrlen` are asserted to be `null` and `0` respectively, and asserted5213/// `dest_addr` and `addrlen` are asserted to be `null` and `0` respectively, and asserted
5095/// that the socket was actually connected.5214/// that the socket was actually connected.
5096/// Otherwise, the address of the target is given by `dest_addr` with `addrlen` specifying its size.5215/// Otherwise, the address of the target is given by `dest_addr` with `addrlen` specifying its size.
...@@ -5330,7 +5449,7 @@ pub fn sendfile(...@@ -5330,7 +5449,7 @@ pub fn sendfile(
5330 // * Descriptor is not valid or locked5449 // * Descriptor is not valid or locked
5331 // * an mmap(2)-like operation is not available for in_fd5450 // * an mmap(2)-like operation is not available for in_fd
5332 // * count is negative5451 // * count is negative
5333 // * out_fd has the O_APPEND flag set5452 // * out_fd has the O.APPEND flag set
5334 // Because of the "mmap(2)-like operation" possibility, we fall back to doing read/write5453 // Because of the "mmap(2)-like operation" possibility, we fall back to doing read/write
5335 // manually, the same as ENOSYS.5454 // manually, the same as ENOSYS.
5336 break :sf;5455 break :sf;
...@@ -5396,7 +5515,7 @@ pub fn sendfile(...@@ -5396,7 +5515,7 @@ pub fn sendfile(
5396 .INVAL, .OPNOTSUPP, .NOTSOCK, .NOSYS => {5515 .INVAL, .OPNOTSUPP, .NOTSOCK, .NOSYS => {
5397 // EINVAL could be any of the following situations:5516 // EINVAL could be any of the following situations:
5398 // * The fd argument is not a regular file.5517 // * The fd argument is not a regular file.
5399 // * The s argument is not a SOCK_STREAM type socket.5518 // * The s argument is not a SOCK.STREAM type socket.
5400 // * The offset argument is negative.5519 // * The offset argument is negative.
5401 // Because of some of these possibilities, we fall back to doing read/write5520 // Because of some of these possibilities, we fall back to doing read/write
5402 // manually, the same as ENOSYS.5521 // manually, the same as ENOSYS.
...@@ -5538,7 +5657,7 @@ pub const CopyFileRangeError = error{...@@ -5538,7 +5657,7 @@ pub const CopyFileRangeError = error{
5538 FileTooBig,5657 FileTooBig,
5539 InputOutput,5658 InputOutput,
5540 /// `fd_in` is not open for reading; or `fd_out` is not open for writing;5659 /// `fd_in` is not open for reading; or `fd_out` is not open for writing;
5541 /// or the `O_APPEND` flag is set for `fd_out`.5660 /// or the `O.APPEND` flag is set for `fd_out`.
5542 FilesOpenedWithWrongFlags,5661 FilesOpenedWithWrongFlags,
5543 IsDir,5662 IsDir,
5544 OutOfMemory,5663 OutOfMemory,
...@@ -6154,27 +6273,27 @@ pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void...@@ -6154,27 +6273,27 @@ pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void
6154}6273}
61556274
6156pub const MadviseError = error{6275pub const MadviseError = error{
6157 /// advice is MADV_REMOVE, but the specified address range is not a shared writable mapping.6276 /// advice is MADV.REMOVE, but the specified address range is not a shared writable mapping.
6158 AccessDenied,6277 AccessDenied,
6159 /// advice is MADV_HWPOISON, but the caller does not have the CAP_SYS_ADMIN capability.6278 /// advice is MADV.HWPOISON, but the caller does not have the CAP_SYS_ADMIN capability.
6160 PermissionDenied,6279 PermissionDenied,
6161 /// A kernel resource was temporarily unavailable.6280 /// A kernel resource was temporarily unavailable.
6162 SystemResources,6281 SystemResources,
6163 /// One of the following:6282 /// One of the following:
6164 /// * addr is not page-aligned or length is negative6283 /// * addr is not page-aligned or length is negative
6165 /// * advice is not valid6284 /// * advice is not valid
6166 /// * advice is MADV_DONTNEED or MADV_REMOVE and the specified address range6285 /// * advice is MADV.DONTNEED or MADV.REMOVE and the specified address range
6167 /// includes locked, Huge TLB pages, or VM_PFNMAP pages.6286 /// includes locked, Huge TLB pages, or VM_PFNMAP pages.
6168 /// * advice is MADV_MERGEABLE or MADV_UNMERGEABLE, but the kernel was not6287 /// * advice is MADV.MERGEABLE or MADV.UNMERGEABLE, but the kernel was not
6169 /// configured with CONFIG_KSM.6288 /// configured with CONFIG_KSM.
6170 /// * advice is MADV_FREE or MADV_WIPEONFORK but the specified address range6289 /// * advice is MADV.FREE or MADV.WIPEONFORK but the specified address range
6171 /// includes file, Huge TLB, MAP_SHARED, or VM_PFNMAP ranges.6290 /// includes file, Huge TLB, MAP.SHARED, or VM_PFNMAP ranges.
6172 InvalidSyscall,6291 InvalidSyscall,
6173 /// (for MADV_WILLNEED) Paging in this area would exceed the process's6292 /// (for MADV.WILLNEED) Paging in this area would exceed the process's
6174 /// maximum resident set size.6293 /// maximum resident set size.
6175 WouldExceedMaximumResidentSetSize,6294 WouldExceedMaximumResidentSetSize,
6176 /// One of the following:6295 /// One of the following:
6177 /// * (for MADV_WILLNEED) Not enough memory: paging in failed.6296 /// * (for MADV.WILLNEED) Not enough memory: paging in failed.
6178 /// * Addresses in the specified range are not currently mapped, or6297 /// * Addresses in the specified range are not currently mapped, or
6179 /// are outside the address space of the process.6298 /// are outside the address space of the process.
6180 OutOfMemory,6299 OutOfMemory,
lib/std/os/bits.zig deleted-22
...@@ -1,22 +0,0 @@
1//! Platform-dependent types and values that are used along with OS-specific APIs.
2//! These are imported into `std.c`, `std.os`, and `std.os.linux`.
3//! Root source files can define `os.bits` and these will additionally be added
4//! to the namespace.
5
6const std = @import("std");
7const root = @import("root");
8
9pub usingnamespace switch (std.Target.current.os.tag) {
10 .macos, .ios, .tvos, .watchos => @import("bits/darwin.zig"),
11 .dragonfly => @import("bits/dragonfly.zig"),
12 .freebsd => @import("bits/freebsd.zig"),
13 .haiku => @import("bits/haiku.zig"),
14 .linux => @import("bits/linux.zig"),
15 .netbsd => @import("bits/netbsd.zig"),
16 .openbsd => @import("bits/openbsd.zig"),
17 .wasi => @import("bits/wasi.zig"),
18 .windows => @import("bits/windows.zig"),
19 else => struct {},
20};
21
22pub usingnamespace if (@hasDecl(root, "os") and @hasDecl(root.os, "bits")) root.os.bits else struct {};
lib/std/os/bits/darwin.zig deleted-1785
...@@ -1,1785 +0,0 @@
1const std = @import("../../std.zig");
2const assert = std.debug.assert;
3const maxInt = std.math.maxInt;
4
5pub usingnamespace @import("posix.zig");
6
7// See: https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/sys/_types.h.auto.html
8// TODO: audit mode_t/pid_t, should likely be u16/i32
9pub const fd_t = c_int;
10pub const pid_t = c_int;
11pub const mode_t = c_uint;
12pub const uid_t = u32;
13pub const gid_t = u32;
14
15pub const in_port_t = u16;
16pub const sa_family_t = u8;
17pub const socklen_t = u32;
18pub const sockaddr = extern struct {
19 len: u8,
20 family: sa_family_t,
21 data: [14]u8,
22};
23pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
24pub const sockaddr_in = extern struct {
25 len: u8 = @sizeOf(sockaddr_in),
26 family: sa_family_t = AF_INET,
27 port: in_port_t,
28 addr: u32,
29 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
30};
31pub const sockaddr_in6 = extern struct {
32 len: u8 = @sizeOf(sockaddr_in6),
33 family: sa_family_t = AF_INET6,
34 port: in_port_t,
35 flowinfo: u32,
36 addr: [16]u8,
37 scope_id: u32,
38};
39
40/// UNIX domain socket
41pub const sockaddr_un = extern struct {
42 len: u8 = @sizeOf(sockaddr_un),
43 family: sa_family_t = AF_UNIX,
44 path: [104]u8,
45};
46
47pub const timeval = extern struct {
48 tv_sec: c_long,
49 tv_usec: i32,
50};
51
52pub const timezone = extern struct {
53 tz_minuteswest: i32,
54 tz_dsttime: i32,
55};
56
57pub const mach_timebase_info_data = extern struct {
58 numer: u32,
59 denom: u32,
60};
61
62pub const off_t = i64;
63pub const ino_t = u64;
64
65pub const Flock = extern struct {
66 l_start: off_t,
67 l_len: off_t,
68 l_pid: pid_t,
69 l_type: i16,
70 l_whence: i16,
71};
72
73pub const libc_stat = extern struct {
74 dev: i32,
75 mode: u16,
76 nlink: u16,
77 ino: ino_t,
78 uid: uid_t,
79 gid: gid_t,
80 rdev: i32,
81 atimesec: isize,
82 atimensec: isize,
83 mtimesec: isize,
84 mtimensec: isize,
85 ctimesec: isize,
86 ctimensec: isize,
87 birthtimesec: isize,
88 birthtimensec: isize,
89 size: off_t,
90 blocks: i64,
91 blksize: i32,
92 flags: u32,
93 gen: u32,
94 lspare: i32,
95 qspare: [2]i64,
96
97 pub fn atime(self: @This()) timespec {
98 return timespec{
99 .tv_sec = self.atimesec,
100 .tv_nsec = self.atimensec,
101 };
102 }
103
104 pub fn mtime(self: @This()) timespec {
105 return timespec{
106 .tv_sec = self.mtimesec,
107 .tv_nsec = self.mtimensec,
108 };
109 }
110
111 pub fn ctime(self: @This()) timespec {
112 return timespec{
113 .tv_sec = self.ctimesec,
114 .tv_nsec = self.ctimensec,
115 };
116 }
117};
118
119pub const timespec = extern struct {
120 tv_sec: isize,
121 tv_nsec: isize,
122};
123
124pub const sigset_t = u32;
125pub const empty_sigset: sigset_t = 0;
126
127pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
128pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
129pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
130pub const SIG_HOLD = @intToPtr(?Sigaction.sigaction_fn, 5);
131
132pub const siginfo_t = extern struct {
133 signo: c_int,
134 errno: c_int,
135 code: c_int,
136 pid: pid_t,
137 uid: uid_t,
138 status: c_int,
139 addr: *c_void,
140 value: extern union {
141 int: c_int,
142 ptr: *c_void,
143 },
144 si_band: c_long,
145 _pad: [7]c_ulong,
146};
147
148/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
149pub const Sigaction = extern struct {
150 pub const handler_fn = fn (c_int) callconv(.C) void;
151 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
152
153 handler: extern union {
154 handler: ?handler_fn,
155 sigaction: ?sigaction_fn,
156 },
157 mask: sigset_t,
158 flags: c_uint,
159};
160
161pub const dirent = extern struct {
162 d_ino: usize,
163 d_seekoff: usize,
164 d_reclen: u16,
165 d_namlen: u16,
166 d_type: u8,
167 d_name: u8, // field address is address of first byte of name
168
169 pub fn reclen(self: dirent) u16 {
170 return self.d_reclen;
171 }
172};
173
174/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
175pub const Kevent = extern struct {
176 ident: usize,
177 filter: i16,
178 flags: u16,
179 fflags: u32,
180 data: isize,
181 udata: usize,
182};
183
184// sys/types.h on macos uses #pragma pack(4) so these checks are
185// to make sure the struct is laid out the same. These values were
186// produced from C code using the offsetof macro.
187comptime {
188 assert(@offsetOf(Kevent, "ident") == 0);
189 assert(@offsetOf(Kevent, "filter") == 8);
190 assert(@offsetOf(Kevent, "flags") == 10);
191 assert(@offsetOf(Kevent, "fflags") == 12);
192 assert(@offsetOf(Kevent, "data") == 16);
193 assert(@offsetOf(Kevent, "udata") == 24);
194}
195
196pub const kevent64_s = extern struct {
197 ident: u64,
198 filter: i16,
199 flags: u16,
200 fflags: u32,
201 data: i64,
202 udata: u64,
203 ext: [2]u64,
204};
205
206// sys/types.h on macos uses #pragma pack() so these checks are
207// to make sure the struct is laid out the same. These values were
208// produced from C code using the offsetof macro.
209comptime {
210 assert(@offsetOf(kevent64_s, "ident") == 0);
211 assert(@offsetOf(kevent64_s, "filter") == 8);
212 assert(@offsetOf(kevent64_s, "flags") == 10);
213 assert(@offsetOf(kevent64_s, "fflags") == 12);
214 assert(@offsetOf(kevent64_s, "data") == 16);
215 assert(@offsetOf(kevent64_s, "udata") == 24);
216 assert(@offsetOf(kevent64_s, "ext") == 32);
217}
218
219pub const mach_port_t = c_uint;
220pub const clock_serv_t = mach_port_t;
221pub const clock_res_t = c_int;
222pub const mach_port_name_t = natural_t;
223pub const natural_t = c_uint;
224pub const mach_timespec_t = extern struct {
225 tv_sec: c_uint,
226 tv_nsec: clock_res_t,
227};
228pub const kern_return_t = c_int;
229pub const host_t = mach_port_t;
230pub const CALENDAR_CLOCK = 1;
231
232pub const PATH_MAX = 1024;
233pub const IOV_MAX = 16;
234
235pub const STDIN_FILENO = 0;
236pub const STDOUT_FILENO = 1;
237pub const STDERR_FILENO = 2;
238
239/// [MC2] no permissions
240pub const PROT_NONE = 0x00;
241
242/// [MC2] pages can be read
243pub const PROT_READ = 0x01;
244
245/// [MC2] pages can be written
246pub const PROT_WRITE = 0x02;
247
248/// [MC2] pages can be executed
249pub const PROT_EXEC = 0x04;
250
251/// allocated from memory, swap space
252pub const MAP_ANONYMOUS = 0x1000;
253
254/// map from file (default)
255pub const MAP_FILE = 0x0000;
256
257/// interpret addr exactly
258pub const MAP_FIXED = 0x0010;
259
260/// region may contain semaphores
261pub const MAP_HASSEMAPHORE = 0x0200;
262
263/// changes are private
264pub const MAP_PRIVATE = 0x0002;
265
266/// share changes
267pub const MAP_SHARED = 0x0001;
268
269/// don't cache pages for this mapping
270pub const MAP_NOCACHE = 0x0400;
271
272/// don't reserve needed swap area
273pub const MAP_NORESERVE = 0x0040;
274pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
275
276/// [XSI] no hang in wait/no child to reap
277pub const WNOHANG = 0x00000001;
278
279/// [XSI] notify on stop, untraced child
280pub const WUNTRACED = 0x00000002;
281
282/// take signal on signal stack
283pub const SA_ONSTACK = 0x0001;
284
285/// restart system on signal return
286pub const SA_RESTART = 0x0002;
287
288/// reset to SIG_DFL when taking signal
289pub const SA_RESETHAND = 0x0004;
290
291/// do not generate SIGCHLD on child stop
292pub const SA_NOCLDSTOP = 0x0008;
293
294/// don't mask the signal we're delivering
295pub const SA_NODEFER = 0x0010;
296
297/// don't keep zombies around
298pub const SA_NOCLDWAIT = 0x0020;
299
300/// signal handler with SA_SIGINFO args
301pub const SA_SIGINFO = 0x0040;
302
303/// do not bounce off kernel's sigtramp
304pub const SA_USERTRAMP = 0x0100;
305
306/// signal handler with SA_SIGINFO args with 64bit regs information
307pub const SA_64REGSET = 0x0200;
308
309pub const O_PATH = 0x0000;
310
311pub const F_OK = 0;
312pub const X_OK = 1;
313pub const W_OK = 2;
314pub const R_OK = 4;
315
316/// open for reading only
317pub const O_RDONLY = 0x0000;
318
319/// open for writing only
320pub const O_WRONLY = 0x0001;
321
322/// open for reading and writing
323pub const O_RDWR = 0x0002;
324
325/// do not block on open or for data to become available
326pub const O_NONBLOCK = 0x0004;
327
328/// append on each write
329pub const O_APPEND = 0x0008;
330
331/// create file if it does not exist
332pub const O_CREAT = 0x0200;
333
334/// truncate size to 0
335pub const O_TRUNC = 0x0400;
336
337/// error if O_CREAT and the file exists
338pub const O_EXCL = 0x0800;
339
340/// atomically obtain a shared lock
341pub const O_SHLOCK = 0x0010;
342
343/// atomically obtain an exclusive lock
344pub const O_EXLOCK = 0x0020;
345
346/// do not follow symlinks
347pub const O_NOFOLLOW = 0x0100;
348
349/// allow open of symlinks
350pub const O_SYMLINK = 0x200000;
351
352/// descriptor requested for event notifications only
353pub const O_EVTONLY = 0x8000;
354
355/// mark as close-on-exec
356pub const O_CLOEXEC = 0x1000000;
357
358pub const O_ACCMODE = 3;
359pub const O_ALERT = 536870912;
360pub const O_ASYNC = 64;
361pub const O_DIRECTORY = 1048576;
362pub const O_DP_GETRAWENCRYPTED = 1;
363pub const O_DP_GETRAWUNENCRYPTED = 2;
364pub const O_DSYNC = 4194304;
365pub const O_FSYNC = O_SYNC;
366pub const O_NOCTTY = 131072;
367pub const O_POPUP = 2147483648;
368pub const O_SYNC = 128;
369
370pub const SEEK_SET = 0x0;
371pub const SEEK_CUR = 0x1;
372pub const SEEK_END = 0x2;
373
374pub const DT_UNKNOWN = 0;
375pub const DT_FIFO = 1;
376pub const DT_CHR = 2;
377pub const DT_DIR = 4;
378pub const DT_BLK = 6;
379pub const DT_REG = 8;
380pub const DT_LNK = 10;
381pub const DT_SOCK = 12;
382pub const DT_WHT = 14;
383
384/// block specified signal set
385pub const SIG_BLOCK = 1;
386
387/// unblock specified signal set
388pub const SIG_UNBLOCK = 2;
389
390/// set specified signal set
391pub const SIG_SETMASK = 3;
392
393/// hangup
394pub const SIGHUP = 1;
395
396/// interrupt
397pub const SIGINT = 2;
398
399/// quit
400pub const SIGQUIT = 3;
401
402/// illegal instruction (not reset when caught)
403pub const SIGILL = 4;
404
405/// trace trap (not reset when caught)
406pub const SIGTRAP = 5;
407
408/// abort()
409pub const SIGABRT = 6;
410
411/// pollable event ([XSR] generated, not supported)
412pub const SIGPOLL = 7;
413
414/// compatibility
415pub const SIGIOT = SIGABRT;
416
417/// EMT instruction
418pub const SIGEMT = 7;
419
420/// floating point exception
421pub const SIGFPE = 8;
422
423/// kill (cannot be caught or ignored)
424pub const SIGKILL = 9;
425
426/// bus error
427pub const SIGBUS = 10;
428
429/// segmentation violation
430pub const SIGSEGV = 11;
431
432/// bad argument to system call
433pub const SIGSYS = 12;
434
435/// write on a pipe with no one to read it
436pub const SIGPIPE = 13;
437
438/// alarm clock
439pub const SIGALRM = 14;
440
441/// software termination signal from kill
442pub const SIGTERM = 15;
443
444/// urgent condition on IO channel
445pub const SIGURG = 16;
446
447/// sendable stop signal not from tty
448pub const SIGSTOP = 17;
449
450/// stop signal from tty
451pub const SIGTSTP = 18;
452
453/// continue a stopped process
454pub const SIGCONT = 19;
455
456/// to parent on child stop or exit
457pub const SIGCHLD = 20;
458
459/// to readers pgrp upon background tty read
460pub const SIGTTIN = 21;
461
462/// like TTIN for output if (tp->t_local&LTOSTOP)
463pub const SIGTTOU = 22;
464
465/// input/output possible signal
466pub const SIGIO = 23;
467
468/// exceeded CPU time limit
469pub const SIGXCPU = 24;
470
471/// exceeded file size limit
472pub const SIGXFSZ = 25;
473
474/// virtual time alarm
475pub const SIGVTALRM = 26;
476
477/// profiling time alarm
478pub const SIGPROF = 27;
479
480/// window size changes
481pub const SIGWINCH = 28;
482
483/// information request
484pub const SIGINFO = 29;
485
486/// user defined signal 1
487pub const SIGUSR1 = 30;
488
489/// user defined signal 2
490pub const SIGUSR2 = 31;
491
492/// no flag value
493pub const KEVENT_FLAG_NONE = 0x000;
494
495/// immediate timeout
496pub const KEVENT_FLAG_IMMEDIATE = 0x001;
497
498/// output events only include change
499pub const KEVENT_FLAG_ERROR_EVENTS = 0x002;
500
501/// add event to kq (implies enable)
502pub const EV_ADD = 0x0001;
503
504/// delete event from kq
505pub const EV_DELETE = 0x0002;
506
507/// enable event
508pub const EV_ENABLE = 0x0004;
509
510/// disable event (not reported)
511pub const EV_DISABLE = 0x0008;
512
513/// only report one occurrence
514pub const EV_ONESHOT = 0x0010;
515
516/// clear event state after reporting
517pub const EV_CLEAR = 0x0020;
518
519/// force immediate event output
520/// ... with or without EV_ERROR
521/// ... use KEVENT_FLAG_ERROR_EVENTS
522/// on syscalls supporting flags
523pub const EV_RECEIPT = 0x0040;
524
525/// disable event after reporting
526pub const EV_DISPATCH = 0x0080;
527
528/// unique kevent per udata value
529pub const EV_UDATA_SPECIFIC = 0x0100;
530
531/// ... in combination with EV_DELETE
532/// will defer delete until udata-specific
533/// event enabled. EINPROGRESS will be
534/// returned to indicate the deferral
535pub const EV_DISPATCH2 = EV_DISPATCH | EV_UDATA_SPECIFIC;
536
537/// report that source has vanished
538/// ... only valid with EV_DISPATCH2
539pub const EV_VANISHED = 0x0200;
540
541/// reserved by system
542pub const EV_SYSFLAGS = 0xF000;
543
544/// filter-specific flag
545pub const EV_FLAG0 = 0x1000;
546
547/// filter-specific flag
548pub const EV_FLAG1 = 0x2000;
549
550/// EOF detected
551pub const EV_EOF = 0x8000;
552
553/// error, data contains errno
554pub const EV_ERROR = 0x4000;
555
556pub const EV_POLL = EV_FLAG0;
557pub const EV_OOBAND = EV_FLAG1;
558
559pub const EVFILT_READ = -1;
560pub const EVFILT_WRITE = -2;
561
562/// attached to aio requests
563pub const EVFILT_AIO = -3;
564
565/// attached to vnodes
566pub const EVFILT_VNODE = -4;
567
568/// attached to struct proc
569pub const EVFILT_PROC = -5;
570
571/// attached to struct proc
572pub const EVFILT_SIGNAL = -6;
573
574/// timers
575pub const EVFILT_TIMER = -7;
576
577/// Mach portsets
578pub const EVFILT_MACHPORT = -8;
579
580/// Filesystem events
581pub const EVFILT_FS = -9;
582
583/// User events
584pub const EVFILT_USER = -10;
585
586/// Virtual memory events
587pub const EVFILT_VM = -12;
588
589/// Exception events
590pub const EVFILT_EXCEPT = -15;
591
592pub const EVFILT_SYSCOUNT = 17;
593
594/// On input, NOTE_TRIGGER causes the event to be triggered for output.
595pub const NOTE_TRIGGER = 0x01000000;
596
597/// ignore input fflags
598pub const NOTE_FFNOP = 0x00000000;
599
600/// and fflags
601pub const NOTE_FFAND = 0x40000000;
602
603/// or fflags
604pub const NOTE_FFOR = 0x80000000;
605
606/// copy fflags
607pub const NOTE_FFCOPY = 0xc0000000;
608
609/// mask for operations
610pub const NOTE_FFCTRLMASK = 0xc0000000;
611pub const NOTE_FFLAGSMASK = 0x00ffffff;
612
613/// low water mark
614pub const NOTE_LOWAT = 0x00000001;
615
616/// OOB data
617pub const NOTE_OOB = 0x00000002;
618
619/// vnode was removed
620pub const NOTE_DELETE = 0x00000001;
621
622/// data contents changed
623pub const NOTE_WRITE = 0x00000002;
624
625/// size increased
626pub const NOTE_EXTEND = 0x00000004;
627
628/// attributes changed
629pub const NOTE_ATTRIB = 0x00000008;
630
631/// link count changed
632pub const NOTE_LINK = 0x00000010;
633
634/// vnode was renamed
635pub const NOTE_RENAME = 0x00000020;
636
637/// vnode access was revoked
638pub const NOTE_REVOKE = 0x00000040;
639
640/// No specific vnode event: to test for EVFILT_READ activation
641pub const NOTE_NONE = 0x00000080;
642
643/// vnode was unlocked by flock(2)
644pub const NOTE_FUNLOCK = 0x00000100;
645
646/// process exited
647pub const NOTE_EXIT = 0x80000000;
648
649/// process forked
650pub const NOTE_FORK = 0x40000000;
651
652/// process exec'd
653pub const NOTE_EXEC = 0x20000000;
654
655/// shared with EVFILT_SIGNAL
656pub const NOTE_SIGNAL = 0x08000000;
657
658/// exit status to be returned, valid for child process only
659pub const NOTE_EXITSTATUS = 0x04000000;
660
661/// provide details on reasons for exit
662pub const NOTE_EXIT_DETAIL = 0x02000000;
663
664/// mask for signal & exit status
665pub const NOTE_PDATAMASK = 0x000fffff;
666pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK);
667
668pub const NOTE_EXIT_DETAIL_MASK = 0x00070000;
669pub const NOTE_EXIT_DECRYPTFAIL = 0x00010000;
670pub const NOTE_EXIT_MEMORY = 0x00020000;
671pub const NOTE_EXIT_CSERROR = 0x00040000;
672
673/// will react on memory pressure
674pub const NOTE_VM_PRESSURE = 0x80000000;
675
676/// will quit on memory pressure, possibly after cleaning up dirty state
677pub const NOTE_VM_PRESSURE_TERMINATE = 0x40000000;
678
679/// will quit immediately on memory pressure
680pub const NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000;
681
682/// there was an error
683pub const NOTE_VM_ERROR = 0x10000000;
684
685/// data is seconds
686pub const NOTE_SECONDS = 0x00000001;
687
688/// data is microseconds
689pub const NOTE_USECONDS = 0x00000002;
690
691/// data is nanoseconds
692pub const NOTE_NSECONDS = 0x00000004;
693
694/// absolute timeout
695pub const NOTE_ABSOLUTE = 0x00000008;
696
697/// ext[1] holds leeway for power aware timers
698pub const NOTE_LEEWAY = 0x00000010;
699
700/// system does minimal timer coalescing
701pub const NOTE_CRITICAL = 0x00000020;
702
703/// system does maximum timer coalescing
704pub const NOTE_BACKGROUND = 0x00000040;
705pub const NOTE_MACH_CONTINUOUS_TIME = 0x00000080;
706
707/// data is mach absolute time units
708pub const NOTE_MACHTIME = 0x00000100;
709
710pub const AF_UNSPEC = 0;
711pub const AF_LOCAL = 1;
712pub const AF_UNIX = AF_LOCAL;
713pub const AF_INET = 2;
714pub const AF_SYS_CONTROL = 2;
715pub const AF_IMPLINK = 3;
716pub const AF_PUP = 4;
717pub const AF_CHAOS = 5;
718pub const AF_NS = 6;
719pub const AF_ISO = 7;
720pub const AF_OSI = AF_ISO;
721pub const AF_ECMA = 8;
722pub const AF_DATAKIT = 9;
723pub const AF_CCITT = 10;
724pub const AF_SNA = 11;
725pub const AF_DECnet = 12;
726pub const AF_DLI = 13;
727pub const AF_LAT = 14;
728pub const AF_HYLINK = 15;
729pub const AF_APPLETALK = 16;
730pub const AF_ROUTE = 17;
731pub const AF_LINK = 18;
732pub const AF_XTP = 19;
733pub const AF_COIP = 20;
734pub const AF_CNT = 21;
735pub const AF_RTIP = 22;
736pub const AF_IPX = 23;
737pub const AF_SIP = 24;
738pub const AF_PIP = 25;
739pub const AF_ISDN = 28;
740pub const AF_E164 = AF_ISDN;
741pub const AF_KEY = 29;
742pub const AF_INET6 = 30;
743pub const AF_NATM = 31;
744pub const AF_SYSTEM = 32;
745pub const AF_NETBIOS = 33;
746pub const AF_PPP = 34;
747pub const AF_MAX = 40;
748
749pub const PF_UNSPEC = AF_UNSPEC;
750pub const PF_LOCAL = AF_LOCAL;
751pub const PF_UNIX = PF_LOCAL;
752pub const PF_INET = AF_INET;
753pub const PF_IMPLINK = AF_IMPLINK;
754pub const PF_PUP = AF_PUP;
755pub const PF_CHAOS = AF_CHAOS;
756pub const PF_NS = AF_NS;
757pub const PF_ISO = AF_ISO;
758pub const PF_OSI = AF_ISO;
759pub const PF_ECMA = AF_ECMA;
760pub const PF_DATAKIT = AF_DATAKIT;
761pub const PF_CCITT = AF_CCITT;
762pub const PF_SNA = AF_SNA;
763pub const PF_DECnet = AF_DECnet;
764pub const PF_DLI = AF_DLI;
765pub const PF_LAT = AF_LAT;
766pub const PF_HYLINK = AF_HYLINK;
767pub const PF_APPLETALK = AF_APPLETALK;
768pub const PF_ROUTE = AF_ROUTE;
769pub const PF_LINK = AF_LINK;
770pub const PF_XTP = AF_XTP;
771pub const PF_COIP = AF_COIP;
772pub const PF_CNT = AF_CNT;
773pub const PF_SIP = AF_SIP;
774pub const PF_IPX = AF_IPX;
775pub const PF_RTIP = AF_RTIP;
776pub const PF_PIP = AF_PIP;
777pub const PF_ISDN = AF_ISDN;
778pub const PF_KEY = AF_KEY;
779pub const PF_INET6 = AF_INET6;
780pub const PF_NATM = AF_NATM;
781pub const PF_SYSTEM = AF_SYSTEM;
782pub const PF_NETBIOS = AF_NETBIOS;
783pub const PF_PPP = AF_PPP;
784pub const PF_MAX = AF_MAX;
785
786pub const SYSPROTO_EVENT = 1;
787pub const SYSPROTO_CONTROL = 2;
788
789pub const SOCK_STREAM = 1;
790pub const SOCK_DGRAM = 2;
791pub const SOCK_RAW = 3;
792pub const SOCK_RDM = 4;
793pub const SOCK_SEQPACKET = 5;
794pub const SOCK_MAXADDRLEN = 255;
795
796/// Not actually supported by Darwin, but Zig supplies a shim.
797/// This numerical value is not ABI-stable. It need only not conflict
798/// with any other "SOCK_" bits.
799pub const SOCK_CLOEXEC = 1 << 15;
800/// Not actually supported by Darwin, but Zig supplies a shim.
801/// This numerical value is not ABI-stable. It need only not conflict
802/// with any other "SOCK_" bits.
803pub const SOCK_NONBLOCK = 1 << 16;
804
805pub const IPPROTO_ICMP = 1;
806pub const IPPROTO_ICMPV6 = 58;
807pub const IPPROTO_TCP = 6;
808pub const IPPROTO_UDP = 17;
809pub const IPPROTO_IP = 0;
810pub const IPPROTO_IPV6 = 41;
811
812pub const SOL_SOCKET = 0xffff;
813
814pub const SO_DEBUG = 0x0001;
815pub const SO_ACCEPTCONN = 0x0002;
816pub const SO_REUSEADDR = 0x0004;
817pub const SO_KEEPALIVE = 0x0008;
818pub const SO_DONTROUTE = 0x0010;
819pub const SO_BROADCAST = 0x0020;
820pub const SO_USELOOPBACK = 0x0040;
821pub const SO_LINGER = 0x1080;
822pub const SO_OOBINLINE = 0x0100;
823pub const SO_REUSEPORT = 0x0200;
824pub const SO_ACCEPTFILTER = 0x1000;
825pub const SO_SNDBUF = 0x1001;
826pub const SO_RCVBUF = 0x1002;
827pub const SO_SNDLOWAT = 0x1003;
828pub const SO_RCVLOWAT = 0x1004;
829pub const SO_SNDTIMEO = 0x1005;
830pub const SO_RCVTIMEO = 0x1006;
831pub const SO_ERROR = 0x1007;
832pub const SO_TYPE = 0x1008;
833
834pub const SO_NREAD = 0x1020;
835pub const SO_NKE = 0x1021;
836pub const SO_NOSIGPIPE = 0x1022;
837pub const SO_NOADDRERR = 0x1023;
838pub const SO_NWRITE = 0x1024;
839pub const SO_REUSESHAREUID = 0x1025;
840
841fn wstatus(x: u32) u32 {
842 return x & 0o177;
843}
844const wstopped = 0o177;
845pub fn WEXITSTATUS(x: u32) u8 {
846 return @intCast(u8, x >> 8);
847}
848pub fn WTERMSIG(x: u32) u32 {
849 return wstatus(x);
850}
851pub fn WSTOPSIG(x: u32) u32 {
852 return x >> 8;
853}
854pub fn WIFEXITED(x: u32) bool {
855 return wstatus(x) == 0;
856}
857pub fn WIFSTOPPED(x: u32) bool {
858 return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13;
859}
860pub fn WIFSIGNALED(x: u32) bool {
861 return wstatus(x) != wstopped and wstatus(x) != 0;
862}
863
864pub const E = enum(u16) {
865 /// No error occurred.
866 SUCCESS = 0,
867
868 /// Operation not permitted
869 PERM = 1,
870
871 /// No such file or directory
872 NOENT = 2,
873
874 /// No such process
875 SRCH = 3,
876
877 /// Interrupted system call
878 INTR = 4,
879
880 /// Input/output error
881 IO = 5,
882
883 /// Device not configured
884 NXIO = 6,
885
886 /// Argument list too long
887 @"2BIG" = 7,
888
889 /// Exec format error
890 NOEXEC = 8,
891
892 /// Bad file descriptor
893 BADF = 9,
894
895 /// No child processes
896 CHILD = 10,
897
898 /// Resource deadlock avoided
899 DEADLK = 11,
900
901 /// Cannot allocate memory
902 NOMEM = 12,
903
904 /// Permission denied
905 ACCES = 13,
906
907 /// Bad address
908 FAULT = 14,
909
910 /// Block device required
911 NOTBLK = 15,
912
913 /// Device / Resource busy
914 BUSY = 16,
915
916 /// File exists
917 EXIST = 17,
918
919 /// Cross-device link
920 XDEV = 18,
921
922 /// Operation not supported by device
923 NODEV = 19,
924
925 /// Not a directory
926 NOTDIR = 20,
927
928 /// Is a directory
929 ISDIR = 21,
930
931 /// Invalid argument
932 INVAL = 22,
933
934 /// Too many open files in system
935 NFILE = 23,
936
937 /// Too many open files
938 MFILE = 24,
939
940 /// Inappropriate ioctl for device
941 NOTTY = 25,
942
943 /// Text file busy
944 TXTBSY = 26,
945
946 /// File too large
947 FBIG = 27,
948
949 /// No space left on device
950 NOSPC = 28,
951
952 /// Illegal seek
953 SPIPE = 29,
954
955 /// Read-only file system
956 ROFS = 30,
957
958 /// Too many links
959 MLINK = 31,
960
961 /// Broken pipe
962 PIPE = 32,
963
964 // math software
965
966 /// Numerical argument out of domain
967 DOM = 33,
968
969 /// Result too large
970 RANGE = 34,
971
972 // non-blocking and interrupt i/o
973
974 /// Resource temporarily unavailable
975 /// This is the same code used for `WOULDBLOCK`.
976 AGAIN = 35,
977
978 /// Operation now in progress
979 INPROGRESS = 36,
980
981 /// Operation already in progress
982 ALREADY = 37,
983
984 // ipc/network software -- argument errors
985
986 /// Socket operation on non-socket
987 NOTSOCK = 38,
988
989 /// Destination address required
990 DESTADDRREQ = 39,
991
992 /// Message too long
993 MSGSIZE = 40,
994
995 /// Protocol wrong type for socket
996 PROTOTYPE = 41,
997
998 /// Protocol not available
999 NOPROTOOPT = 42,
1000
1001 /// Protocol not supported
1002 PROTONOSUPPORT = 43,
1003
1004 /// Socket type not supported
1005 SOCKTNOSUPPORT = 44,
1006
1007 /// Operation not supported
1008 /// The same code is used for `NOTSUP`.
1009 OPNOTSUPP = 45,
1010
1011 /// Protocol family not supported
1012 PFNOSUPPORT = 46,
1013
1014 /// Address family not supported by protocol family
1015 AFNOSUPPORT = 47,
1016
1017 /// Address already in use
1018 ADDRINUSE = 48,
1019 /// Can't assign requested address
1020
1021 // ipc/network software -- operational errors
1022 ADDRNOTAVAIL = 49,
1023
1024 /// Network is down
1025 NETDOWN = 50,
1026
1027 /// Network is unreachable
1028 NETUNREACH = 51,
1029
1030 /// Network dropped connection on reset
1031 NETRESET = 52,
1032
1033 /// Software caused connection abort
1034 CONNABORTED = 53,
1035
1036 /// Connection reset by peer
1037 CONNRESET = 54,
1038
1039 /// No buffer space available
1040 NOBUFS = 55,
1041
1042 /// Socket is already connected
1043 ISCONN = 56,
1044
1045 /// Socket is not connected
1046 NOTCONN = 57,
1047
1048 /// Can't send after socket shutdown
1049 SHUTDOWN = 58,
1050
1051 /// Too many references: can't splice
1052 TOOMANYREFS = 59,
1053
1054 /// Operation timed out
1055 TIMEDOUT = 60,
1056
1057 /// Connection refused
1058 CONNREFUSED = 61,
1059
1060 /// Too many levels of symbolic links
1061 LOOP = 62,
1062
1063 /// File name too long
1064 NAMETOOLONG = 63,
1065
1066 /// Host is down
1067 HOSTDOWN = 64,
1068
1069 /// No route to host
1070 HOSTUNREACH = 65,
1071 /// Directory not empty
1072
1073 // quotas & mush
1074 NOTEMPTY = 66,
1075
1076 /// Too many processes
1077 PROCLIM = 67,
1078
1079 /// Too many users
1080 USERS = 68,
1081 /// Disc quota exceeded
1082
1083 // Network File System
1084 DQUOT = 69,
1085
1086 /// Stale NFS file handle
1087 STALE = 70,
1088
1089 /// Too many levels of remote in path
1090 REMOTE = 71,
1091
1092 /// RPC struct is bad
1093 BADRPC = 72,
1094
1095 /// RPC version wrong
1096 RPCMISMATCH = 73,
1097
1098 /// RPC prog. not avail
1099 PROGUNAVAIL = 74,
1100
1101 /// Program version wrong
1102 PROGMISMATCH = 75,
1103
1104 /// Bad procedure for program
1105 PROCUNAVAIL = 76,
1106
1107 /// No locks available
1108 NOLCK = 77,
1109
1110 /// Function not implemented
1111 NOSYS = 78,
1112
1113 /// Inappropriate file type or format
1114 FTYPE = 79,
1115
1116 /// Authentication error
1117 AUTH = 80,
1118
1119 /// Need authenticator
1120 NEEDAUTH = 81,
1121
1122 // Intelligent device errors
1123
1124 /// Device power is off
1125 PWROFF = 82,
1126
1127 /// Device error, e.g. paper out
1128 DEVERR = 83,
1129
1130 /// Value too large to be stored in data type
1131 OVERFLOW = 84,
1132
1133 // Program loading errors
1134
1135 /// Bad executable
1136 BADEXEC = 85,
1137
1138 /// Bad CPU type in executable
1139 BADARCH = 86,
1140
1141 /// Shared library version mismatch
1142 SHLIBVERS = 87,
1143
1144 /// Malformed Macho file
1145 BADMACHO = 88,
1146
1147 /// Operation canceled
1148 CANCELED = 89,
1149
1150 /// Identifier removed
1151 IDRM = 90,
1152
1153 /// No message of desired type
1154 NOMSG = 91,
1155
1156 /// Illegal byte sequence
1157 ILSEQ = 92,
1158
1159 /// Attribute not found
1160 NOATTR = 93,
1161
1162 /// Bad message
1163 BADMSG = 94,
1164
1165 /// Reserved
1166 MULTIHOP = 95,
1167
1168 /// No message available on STREAM
1169 NODATA = 96,
1170
1171 /// Reserved
1172 NOLINK = 97,
1173
1174 /// No STREAM resources
1175 NOSR = 98,
1176
1177 /// Not a STREAM
1178 NOSTR = 99,
1179
1180 /// Protocol error
1181 PROTO = 100,
1182
1183 /// STREAM ioctl timeout
1184 TIME = 101,
1185
1186 /// No such policy registered
1187 NOPOLICY = 103,
1188
1189 /// State not recoverable
1190 NOTRECOVERABLE = 104,
1191
1192 /// Previous owner died
1193 OWNERDEAD = 105,
1194
1195 /// Interface output queue is full
1196 QFULL = 106,
1197
1198 _,
1199};
1200
1201pub const SIGSTKSZ = 131072;
1202pub const MINSIGSTKSZ = 32768;
1203
1204pub const SS_ONSTACK = 1;
1205pub const SS_DISABLE = 4;
1206
1207pub const stack_t = extern struct {
1208 ss_sp: [*]u8,
1209 ss_size: isize,
1210 ss_flags: i32,
1211};
1212
1213pub const S_IFMT = 0o170000;
1214
1215pub const S_IFIFO = 0o010000;
1216pub const S_IFCHR = 0o020000;
1217pub const S_IFDIR = 0o040000;
1218pub const S_IFBLK = 0o060000;
1219pub const S_IFREG = 0o100000;
1220pub const S_IFLNK = 0o120000;
1221pub const S_IFSOCK = 0o140000;
1222pub const S_IFWHT = 0o160000;
1223
1224pub const S_ISUID = 0o4000;
1225pub const S_ISGID = 0o2000;
1226pub const S_ISVTX = 0o1000;
1227pub const S_IRWXU = 0o700;
1228pub const S_IRUSR = 0o400;
1229pub const S_IWUSR = 0o200;
1230pub const S_IXUSR = 0o100;
1231pub const S_IRWXG = 0o070;
1232pub const S_IRGRP = 0o040;
1233pub const S_IWGRP = 0o020;
1234pub const S_IXGRP = 0o010;
1235pub const S_IRWXO = 0o007;
1236pub const S_IROTH = 0o004;
1237pub const S_IWOTH = 0o002;
1238pub const S_IXOTH = 0o001;
1239
1240pub fn S_ISFIFO(m: u32) bool {
1241 return m & S_IFMT == S_IFIFO;
1242}
1243
1244pub fn S_ISCHR(m: u32) bool {
1245 return m & S_IFMT == S_IFCHR;
1246}
1247
1248pub fn S_ISDIR(m: u32) bool {
1249 return m & S_IFMT == S_IFDIR;
1250}
1251
1252pub fn S_ISBLK(m: u32) bool {
1253 return m & S_IFMT == S_IFBLK;
1254}
1255
1256pub fn S_ISREG(m: u32) bool {
1257 return m & S_IFMT == S_IFREG;
1258}
1259
1260pub fn S_ISLNK(m: u32) bool {
1261 return m & S_IFMT == S_IFLNK;
1262}
1263
1264pub fn S_ISSOCK(m: u32) bool {
1265 return m & S_IFMT == S_IFSOCK;
1266}
1267
1268pub fn S_IWHT(m: u32) bool {
1269 return m & S_IFMT == S_IFWHT;
1270}
1271
1272pub const HOST_NAME_MAX = 72;
1273
1274pub const AT_FDCWD = -2;
1275
1276/// Use effective ids in access check
1277pub const AT_EACCESS = 0x0010;
1278
1279/// Act on the symlink itself not the target
1280pub const AT_SYMLINK_NOFOLLOW = 0x0020;
1281
1282/// Act on target of symlink
1283pub const AT_SYMLINK_FOLLOW = 0x0040;
1284
1285/// Path refers to directory
1286pub const AT_REMOVEDIR = 0x0080;
1287
1288pub const addrinfo = extern struct {
1289 flags: i32,
1290 family: i32,
1291 socktype: i32,
1292 protocol: i32,
1293 addrlen: socklen_t,
1294 canonname: ?[*:0]u8,
1295 addr: ?*sockaddr,
1296 next: ?*addrinfo,
1297};
1298
1299pub const RTLD_LAZY = 0x1;
1300pub const RTLD_NOW = 0x2;
1301pub const RTLD_LOCAL = 0x4;
1302pub const RTLD_GLOBAL = 0x8;
1303pub const RTLD_NOLOAD = 0x10;
1304pub const RTLD_NODELETE = 0x80;
1305pub const RTLD_FIRST = 0x100;
1306
1307pub const RTLD_NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
1308pub const RTLD_DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
1309pub const RTLD_SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
1310pub const RTLD_MAIN_ONLY = @intToPtr(*c_void, @bitCast(usize, @as(isize, -5)));
1311
1312/// duplicate file descriptor
1313pub const F_DUPFD = 0;
1314
1315/// get file descriptor flags
1316pub const F_GETFD = 1;
1317
1318/// set file descriptor flags
1319pub const F_SETFD = 2;
1320
1321/// get file status flags
1322pub const F_GETFL = 3;
1323
1324/// set file status flags
1325pub const F_SETFL = 4;
1326
1327/// get SIGIO/SIGURG proc/pgrp
1328pub const F_GETOWN = 5;
1329
1330/// set SIGIO/SIGURG proc/pgrp
1331pub const F_SETOWN = 6;
1332
1333/// get record locking information
1334pub const F_GETLK = 7;
1335
1336/// set record locking information
1337pub const F_SETLK = 8;
1338
1339/// F_SETLK; wait if blocked
1340pub const F_SETLKW = 9;
1341
1342/// F_SETLK; wait if blocked, return on timeout
1343pub const F_SETLKWTIMEOUT = 10;
1344pub const F_FLUSH_DATA = 40;
1345
1346/// Used for regression test
1347pub const F_CHKCLEAN = 41;
1348
1349/// Preallocate storage
1350pub const F_PREALLOCATE = 42;
1351
1352/// Truncate a file without zeroing space
1353pub const F_SETSIZE = 43;
1354
1355/// Issue an advisory read async with no copy to user
1356pub const F_RDADVISE = 44;
1357
1358/// turn read ahead off/on for this fd
1359pub const F_RDAHEAD = 45;
1360
1361/// turn data caching off/on for this fd
1362pub const F_NOCACHE = 48;
1363
1364/// file offset to device offset
1365pub const F_LOG2PHYS = 49;
1366
1367/// return the full path of the fd
1368pub const F_GETPATH = 50;
1369
1370/// fsync + ask the drive to flush to the media
1371pub const F_FULLFSYNC = 51;
1372
1373/// find which component (if any) is a package
1374pub const F_PATHPKG_CHECK = 52;
1375
1376/// "freeze" all fs operations
1377pub const F_FREEZE_FS = 53;
1378
1379/// "thaw" all fs operations
1380pub const F_THAW_FS = 54;
1381
1382/// turn data caching off/on (globally) for this file
1383pub const F_GLOBAL_NOCACHE = 55;
1384
1385/// add detached signatures
1386pub const F_ADDSIGS = 59;
1387
1388/// add signature from same file (used by dyld for shared libs)
1389pub const F_ADDFILESIGS = 61;
1390
1391/// used in conjunction with F_NOCACHE to indicate that DIRECT, synchonous writes
1392/// should not be used (i.e. its ok to temporaily create cached pages)
1393pub const F_NODIRECT = 62;
1394
1395///Get the protection class of a file from the EA, returns int
1396pub const F_GETPROTECTIONCLASS = 63;
1397
1398///Set the protection class of a file for the EA, requires int
1399pub const F_SETPROTECTIONCLASS = 64;
1400
1401///file offset to device offset, extended
1402pub const F_LOG2PHYS_EXT = 65;
1403
1404///get record locking information, per-process
1405pub const F_GETLKPID = 66;
1406
1407///Mark the file as being the backing store for another filesystem
1408pub const F_SETBACKINGSTORE = 70;
1409
1410///return the full path of the FD, but error in specific mtmd circumstances
1411pub const F_GETPATH_MTMINFO = 71;
1412
1413///Returns the code directory, with associated hashes, to the caller
1414pub const F_GETCODEDIR = 72;
1415
1416///No SIGPIPE generated on EPIPE
1417pub const F_SETNOSIGPIPE = 73;
1418
1419///Status of SIGPIPE for this fd
1420pub const F_GETNOSIGPIPE = 74;
1421
1422///For some cases, we need to rewrap the key for AKS/MKB
1423pub const F_TRANSCODEKEY = 75;
1424
1425///file being written to a by single writer... if throttling enabled, writes
1426///may be broken into smaller chunks with throttling in between
1427pub const F_SINGLE_WRITER = 76;
1428
1429///Get the protection version number for this filesystem
1430pub const F_GETPROTECTIONLEVEL = 77;
1431
1432///Add detached code signatures (used by dyld for shared libs)
1433pub const F_FINDSIGS = 78;
1434
1435///Add signature from same file, only if it is signed by Apple (used by dyld for simulator)
1436pub const F_ADDFILESIGS_FOR_DYLD_SIM = 83;
1437
1438///fsync + issue barrier to drive
1439pub const F_BARRIERFSYNC = 85;
1440
1441///Add signature from same file, return end offset in structure on success
1442pub const F_ADDFILESIGS_RETURN = 97;
1443
1444///Check if Library Validation allows this Mach-O file to be mapped into the calling process
1445pub const F_CHECK_LV = 98;
1446
1447///Deallocate a range of the file
1448pub const F_PUNCHHOLE = 99;
1449
1450///Trim an active file
1451pub const F_TRIM_ACTIVE_FILE = 100;
1452
1453pub const FCNTL_FS_SPECIFIC_BASE = 0x00010000;
1454
1455///mark the dup with FD_CLOEXEC
1456pub const F_DUPFD_CLOEXEC = 67;
1457
1458///close-on-exec flag
1459pub const FD_CLOEXEC = 1;
1460
1461/// shared or read lock
1462pub const F_RDLCK = 1;
1463
1464/// unlock
1465pub const F_UNLCK = 2;
1466
1467/// exclusive or write lock
1468pub const F_WRLCK = 3;
1469
1470pub const LOCK_SH = 1;
1471pub const LOCK_EX = 2;
1472pub const LOCK_UN = 8;
1473pub const LOCK_NB = 4;
1474
1475pub const nfds_t = u32;
1476pub const pollfd = extern struct {
1477 fd: fd_t,
1478 events: i16,
1479 revents: i16,
1480};
1481
1482pub const POLLIN = 0x001;
1483pub const POLLPRI = 0x002;
1484pub const POLLOUT = 0x004;
1485pub const POLLRDNORM = 0x040;
1486pub const POLLWRNORM = POLLOUT;
1487pub const POLLRDBAND = 0x080;
1488pub const POLLWRBAND = 0x100;
1489
1490pub const POLLEXTEND = 0x0200;
1491pub const POLLATTRIB = 0x0400;
1492pub const POLLNLINK = 0x0800;
1493pub const POLLWRITE = 0x1000;
1494
1495pub const POLLERR = 0x008;
1496pub const POLLHUP = 0x010;
1497pub const POLLNVAL = 0x020;
1498
1499pub const POLLSTANDARD = POLLIN | POLLPRI | POLLOUT | POLLRDNORM | POLLRDBAND | POLLWRBAND | POLLERR | POLLHUP | POLLNVAL;
1500
1501pub const CLOCK_REALTIME = 0;
1502pub const CLOCK_MONOTONIC = 6;
1503pub const CLOCK_MONOTONIC_RAW = 4;
1504pub const CLOCK_MONOTONIC_RAW_APPROX = 5;
1505pub const CLOCK_UPTIME_RAW = 8;
1506pub const CLOCK_UPTIME_RAW_APPROX = 9;
1507pub const CLOCK_PROCESS_CPUTIME_ID = 12;
1508pub const CLOCK_THREAD_CPUTIME_ID = 16;
1509
1510/// Max open files per process
1511/// https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/sys/syslimits.h.auto.html
1512pub const OPEN_MAX = 10240;
1513pub const RUSAGE_SELF = 0;
1514pub const RUSAGE_CHILDREN = -1;
1515
1516pub const rusage = extern struct {
1517 utime: timeval,
1518 stime: timeval,
1519 maxrss: isize,
1520 ixrss: isize,
1521 idrss: isize,
1522 isrss: isize,
1523 minflt: isize,
1524 majflt: isize,
1525 nswap: isize,
1526 inblock: isize,
1527 oublock: isize,
1528 msgsnd: isize,
1529 msgrcv: isize,
1530 nsignals: isize,
1531 nvcsw: isize,
1532 nivcsw: isize,
1533};
1534
1535pub const rlimit_resource = enum(c_int) {
1536 CPU = 0,
1537 FSIZE = 1,
1538 DATA = 2,
1539 STACK = 3,
1540 CORE = 4,
1541 RSS = 5,
1542 MEMLOCK = 6,
1543 NPROC = 7,
1544 NOFILE = 8,
1545 _,
1546
1547 pub const AS: rlimit_resource = .RSS;
1548};
1549
1550pub const rlim_t = u64;
1551
1552/// No limit
1553pub const RLIM_INFINITY: rlim_t = (1 << 63) - 1;
1554
1555pub const RLIM_SAVED_MAX = RLIM_INFINITY;
1556pub const RLIM_SAVED_CUR = RLIM_INFINITY;
1557
1558pub const rlimit = extern struct {
1559 /// Soft limit
1560 cur: rlim_t,
1561 /// Hard limit
1562 max: rlim_t,
1563};
1564
1565pub const SHUT_RD = 0;
1566pub const SHUT_WR = 1;
1567pub const SHUT_RDWR = 2;
1568
1569// Term
1570pub const VEOF = 0;
1571pub const VEOL = 1;
1572pub const VEOL2 = 2;
1573pub const VERASE = 3;
1574pub const VWERASE = 4;
1575pub const VKILL = 5;
1576pub const VREPRINT = 6;
1577pub const VINTR = 8;
1578pub const VQUIT = 9;
1579pub const VSUSP = 10;
1580pub const VDSUSP = 11;
1581pub const VSTART = 12;
1582pub const VSTOP = 13;
1583pub const VLNEXT = 14;
1584pub const VDISCARD = 15;
1585pub const VMIN = 16;
1586pub const VTIME = 17;
1587pub const VSTATUS = 18;
1588pub const NCCS = 20; // 2 spares (7, 19)
1589
1590pub const IGNBRK = 0x00000001; // ignore BREAK condition
1591pub const BRKINT = 0x00000002; // map BREAK to SIGINTR
1592pub const IGNPAR = 0x00000004; // ignore (discard) parity errors
1593pub const PARMRK = 0x00000008; // mark parity and framing errors
1594pub const INPCK = 0x00000010; // enable checking of parity errors
1595pub const ISTRIP = 0x00000020; // strip 8th bit off chars
1596pub const INLCR = 0x00000040; // map NL into CR
1597pub const IGNCR = 0x00000080; // ignore CR
1598pub const ICRNL = 0x00000100; // map CR to NL (ala CRMOD)
1599pub const IXON = 0x00000200; // enable output flow control
1600pub const IXOFF = 0x00000400; // enable input flow control
1601pub const IXANY = 0x00000800; // any char will restart after stop
1602pub const IMAXBEL = 0x00002000; // ring bell on input queue full
1603pub const IUTF8 = 0x00004000; // maintain state for UTF-8 VERASE
1604
1605pub const OPOST = 0x00000001; //enable following output processing
1606pub const ONLCR = 0x00000002; // map NL to CR-NL (ala CRMOD)
1607pub const OXTABS = 0x00000004; // expand tabs to spaces
1608pub const ONOEOT = 0x00000008; // discard EOT's (^D) on output)
1609
1610pub const OCRNL = 0x00000010; // map CR to NL on output
1611pub const ONOCR = 0x00000020; // no CR output at column 0
1612pub const ONLRET = 0x00000040; // NL performs CR function
1613pub const OFILL = 0x00000080; // use fill characters for delay
1614pub const NLDLY = 0x00000300; // \n delay
1615pub const TABDLY = 0x00000c04; // horizontal tab delay
1616pub const CRDLY = 0x00003000; // \r delay
1617pub const FFDLY = 0x00004000; // form feed delay
1618pub const BSDLY = 0x00008000; // \b delay
1619pub const VTDLY = 0x00010000; // vertical tab delay
1620pub const OFDEL = 0x00020000; // fill is DEL, else NUL
1621
1622pub const NL0 = 0x00000000;
1623pub const NL1 = 0x00000100;
1624pub const NL2 = 0x00000200;
1625pub const NL3 = 0x00000300;
1626pub const TAB0 = 0x00000000;
1627pub const TAB1 = 0x00000400;
1628pub const TAB2 = 0x00000800;
1629pub const TAB3 = 0x00000004;
1630pub const CR0 = 0x00000000;
1631pub const CR1 = 0x00001000;
1632pub const CR2 = 0x00002000;
1633pub const CR3 = 0x00003000;
1634pub const FF0 = 0x00000000;
1635pub const FF1 = 0x00004000;
1636pub const BS0 = 0x00000000;
1637pub const BS1 = 0x00008000;
1638pub const VT0 = 0x00000000;
1639pub const VT1 = 0x00010000;
1640
1641pub const CIGNORE = 0x00000001; // ignore control flags
1642pub const CSIZE = 0x00000300; // character size mask
1643pub const CS5 = 0x00000000; // 5 bits (pseudo)
1644pub const CS6 = 0x00000100; // 6 bits
1645pub const CS7 = 0x00000200; // 7 bits
1646pub const CS8 = 0x00000300; // 8 bits
1647pub const CSTOPB = 0x0000040; // send 2 stop bits
1648pub const CREAD = 0x00000800; // enable receiver
1649pub const PARENB = 0x00001000; // parity enable
1650pub const PARODD = 0x00002000; // odd parity, else even
1651pub const HUPCL = 0x00004000; // hang up on last close
1652pub const CLOCAL = 0x00008000; // ignore modem status lines
1653pub const CCTS_OFLOW = 0x00010000; // CTS flow control of output
1654pub const CRTSCTS = (CCTS_OFLOW | CRTS_IFLOW);
1655pub const CRTS_IFLOW = 0x00020000; // RTS flow control of input
1656pub const CDTR_IFLOW = 0x00040000; // DTR flow control of input
1657pub const CDSR_OFLOW = 0x00080000; // DSR flow control of output
1658pub const CCAR_OFLOW = 0x00100000; // DCD flow control of output
1659pub const MDMBUF = 0x00100000; // old name for CCAR_OFLOW
1660
1661pub const ECHOKE = 0x00000001; // visual erase for line kill
1662pub const ECHOE = 0x00000002; // visually erase chars
1663pub const ECHOK = 0x00000004; // echo NL after line kill
1664pub const ECHO = 0x00000008; // enable echoing
1665pub const ECHONL = 0x00000010; // echo NL even if ECHO is off
1666pub const ECHOPRT = 0x00000020; // visual erase mode for hardcopy
1667pub const ECHOCTL = 0x00000040; // echo control chars as ^(Char)
1668pub const ISIG = 0x00000080; // enable signals INTR, QUIT, [D]SUSP
1669pub const ICANON = 0x00000100; // canonicalize input lines
1670pub const ALTWERASE = 0x00000200; // use alternate WERASE algorithm
1671pub const IEXTEN = 0x00000400; // enable DISCARD and LNEXT
1672pub const EXTPROC = 0x00000800; // external processing
1673pub const TOSTOP = 0x00400000; // stop background jobs from output
1674pub const FLUSHO = 0x00800000; // output being flushed (state)
1675pub const NOKERNINFO = 0x02000000; // no kernel output from VSTATUS
1676pub const PENDIN = 0x20000000; // XXX retype pending input (state)
1677pub const NOFLSH = 0x80000000; // don't flush after interrupt
1678
1679pub const TCSANOW = 0; // make change immediate
1680pub const TCSADRAIN = 1; // drain output, then change
1681pub const TCSAFLUSH = 2; // drain output, flush input
1682pub const TCSASOFT = 0x10; // flag - don't alter h.w. state
1683pub const TCSA = enum(c_uint) {
1684 NOW,
1685 DRAIN,
1686 FLUSH,
1687 _,
1688};
1689
1690pub const B0 = 0;
1691pub const B50 = 50;
1692pub const B75 = 75;
1693pub const B110 = 110;
1694pub const B134 = 134;
1695pub const B150 = 150;
1696pub const B200 = 200;
1697pub const B300 = 300;
1698pub const B600 = 600;
1699pub const B1200 = 1200;
1700pub const B1800 = 1800;
1701pub const B2400 = 2400;
1702pub const B4800 = 4800;
1703pub const B9600 = 9600;
1704pub const B19200 = 19200;
1705pub const B38400 = 38400;
1706pub const B7200 = 7200;
1707pub const B14400 = 14400;
1708pub const B28800 = 28800;
1709pub const B57600 = 57600;
1710pub const B76800 = 76800;
1711pub const B115200 = 115200;
1712pub const B230400 = 230400;
1713pub const EXTA = 19200;
1714pub const EXTB = 38400;
1715
1716pub const TCIFLUSH = 1;
1717pub const TCOFLUSH = 2;
1718pub const TCIOFLUSH = 3;
1719pub const TCOOFF = 1;
1720pub const TCOON = 2;
1721pub const TCIOFF = 3;
1722pub const TCION = 4;
1723
1724pub const cc_t = u8;
1725pub const speed_t = u64;
1726pub const tcflag_t = u64;
1727
1728pub const termios = extern struct {
1729 iflag: tcflag_t, // input flags
1730 oflag: tcflag_t, // output flags
1731 cflag: tcflag_t, // control flags
1732 lflag: tcflag_t, // local flags
1733 cc: [NCCS]cc_t, // control chars
1734 ispeed: speed_t align(8), // input speed
1735 ospeed: speed_t, // output speed
1736};
1737
1738pub const winsize = extern struct {
1739 ws_row: u16,
1740 ws_col: u16,
1741 ws_xpixel: u16,
1742 ws_ypixel: u16,
1743};
1744
1745pub const TIOCGWINSZ = ior(0x40000000, 't', 104, @sizeOf(winsize));
1746pub const IOCPARM_MASK = 0x1fff;
1747
1748fn ior(inout: u32, group: usize, num: usize, len: usize) usize {
1749 return (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num));
1750}
1751
1752// CPU families mapping
1753pub const CPUFAMILY = enum(u32) {
1754 UNKNOWN = 0,
1755 POWERPC_G3 = 0xcee41549,
1756 POWERPC_G4 = 0x77c184ae,
1757 POWERPC_G5 = 0xed76d8aa,
1758 INTEL_6_13 = 0xaa33392b,
1759 INTEL_PENRYN = 0x78ea4fbc,
1760 INTEL_NEHALEM = 0x6b5a4cd2,
1761 INTEL_WESTMERE = 0x573b5eec,
1762 INTEL_SANDYBRIDGE = 0x5490b78c,
1763 INTEL_IVYBRIDGE = 0x1f65e835,
1764 INTEL_HASWELL = 0x10b282dc,
1765 INTEL_BROADWELL = 0x582ed09c,
1766 INTEL_SKYLAKE = 0x37fc219f,
1767 INTEL_KABYLAKE = 0x0f817246,
1768 ARM_9 = 0xe73283ae,
1769 ARM_11 = 0x8ff620d8,
1770 ARM_XSCALE = 0x53b005f5,
1771 ARM_12 = 0xbd1b0ae9,
1772 ARM_13 = 0x0cc90e64,
1773 ARM_14 = 0x96077ef1,
1774 ARM_15 = 0xa8511bca,
1775 ARM_SWIFT = 0x1e2d6381,
1776 ARM_CYCLONE = 0x37a09642,
1777 ARM_TYPHOON = 0x2c91a47e,
1778 ARM_TWISTER = 0x92fb37c8,
1779 ARM_HURRICANE = 0x67ceee93,
1780 ARM_MONSOON_MISTRAL = 0xe81e7ef6,
1781 ARM_VORTEX_TEMPEST = 0x07d34b9f,
1782 ARM_LIGHTNING_THUNDER = 0x462504d2,
1783 ARM_FIRESTORM_ICESTORM = 0x1b588bb3,
1784 _,
1785};
lib/std/os/bits/dragonfly.zig deleted-1033
...@@ -1,1033 +0,0 @@
1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3
4pub usingnamespace @import("posix.zig");
5
6pub fn S_ISCHR(m: u32) bool {
7 return m & S_IFMT == S_IFCHR;
8}
9
10// See:
11// - https://gitweb.dragonflybsd.org/dragonfly.git/blob/HEAD:/include/unistd.h
12// - https://gitweb.dragonflybsd.org/dragonfly.git/blob/HEAD:/sys/sys/types.h
13// TODO: mode_t should probably be changed to a u16, audit pid_t/off_t as well
14pub const fd_t = c_int;
15pub const pid_t = c_int;
16pub const off_t = c_long;
17pub const mode_t = c_uint;
18pub const uid_t = u32;
19pub const gid_t = u32;
20pub const time_t = isize;
21pub const suseconds_t = c_long;
22
23pub const E = enum(u16) {
24 /// No error occurred.
25 SUCCESS = 0,
26
27 PERM = 1,
28 NOENT = 2,
29 SRCH = 3,
30 INTR = 4,
31 IO = 5,
32 NXIO = 6,
33 @"2BIG" = 7,
34 NOEXEC = 8,
35 BADF = 9,
36 CHILD = 10,
37 DEADLK = 11,
38 NOMEM = 12,
39 ACCES = 13,
40 FAULT = 14,
41 NOTBLK = 15,
42 BUSY = 16,
43 EXIST = 17,
44 XDEV = 18,
45 NODEV = 19,
46 NOTDIR = 20,
47 ISDIR = 21,
48 INVAL = 22,
49 NFILE = 23,
50 MFILE = 24,
51 NOTTY = 25,
52 TXTBSY = 26,
53 FBIG = 27,
54 NOSPC = 28,
55 SPIPE = 29,
56 ROFS = 30,
57 MLINK = 31,
58 PIPE = 32,
59 DOM = 33,
60 RANGE = 34,
61 /// This code is also used for `WOULDBLOCK`.
62 AGAIN = 35,
63 INPROGRESS = 36,
64 ALREADY = 37,
65 NOTSOCK = 38,
66 DESTADDRREQ = 39,
67 MSGSIZE = 40,
68 PROTOTYPE = 41,
69 NOPROTOOPT = 42,
70 PROTONOSUPPORT = 43,
71 SOCKTNOSUPPORT = 44,
72 /// This code is also used for `NOTSUP`.
73 OPNOTSUPP = 45,
74 PFNOSUPPORT = 46,
75 AFNOSUPPORT = 47,
76 ADDRINUSE = 48,
77 ADDRNOTAVAIL = 49,
78 NETDOWN = 50,
79 NETUNREACH = 51,
80 NETRESET = 52,
81 CONNABORTED = 53,
82 CONNRESET = 54,
83 NOBUFS = 55,
84 ISCONN = 56,
85 NOTCONN = 57,
86 SHUTDOWN = 58,
87 TOOMANYREFS = 59,
88 TIMEDOUT = 60,
89 CONNREFUSED = 61,
90 LOOP = 62,
91 NAMETOOLONG = 63,
92 HOSTDOWN = 64,
93 HOSTUNREACH = 65,
94 NOTEMPTY = 66,
95 PROCLIM = 67,
96 USERS = 68,
97 DQUOT = 69,
98 STALE = 70,
99 REMOTE = 71,
100 BADRPC = 72,
101 RPCMISMATCH = 73,
102 PROGUNAVAIL = 74,
103 PROGMISMATCH = 75,
104 PROCUNAVAIL = 76,
105 NOLCK = 77,
106 NOSYS = 78,
107 FTYPE = 79,
108 AUTH = 80,
109 NEEDAUTH = 81,
110 IDRM = 82,
111 NOMSG = 83,
112 OVERFLOW = 84,
113 CANCELED = 85,
114 ILSEQ = 86,
115 NOATTR = 87,
116 DOOFUS = 88,
117 BADMSG = 89,
118 MULTIHOP = 90,
119 NOLINK = 91,
120 PROTO = 92,
121 NOMEDIUM = 93,
122 ASYNC = 99,
123 _,
124};
125
126pub const STDIN_FILENO = 0;
127pub const STDOUT_FILENO = 1;
128pub const STDERR_FILENO = 2;
129
130pub const PROT_NONE = 0;
131pub const PROT_READ = 1;
132pub const PROT_WRITE = 2;
133pub const PROT_EXEC = 4;
134
135pub const MAP_FILE = 0;
136pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
137pub const MAP_ANONYMOUS = MAP_ANON;
138pub const MAP_COPY = MAP_PRIVATE;
139pub const MAP_SHARED = 1;
140pub const MAP_PRIVATE = 2;
141pub const MAP_FIXED = 16;
142pub const MAP_RENAME = 32;
143pub const MAP_NORESERVE = 64;
144pub const MAP_INHERIT = 128;
145pub const MAP_NOEXTEND = 256;
146pub const MAP_HASSEMAPHORE = 512;
147pub const MAP_STACK = 1024;
148pub const MAP_NOSYNC = 2048;
149pub const MAP_ANON = 4096;
150pub const MAP_VPAGETABLE = 8192;
151pub const MAP_TRYFIXED = 65536;
152pub const MAP_NOCORE = 131072;
153pub const MAP_SIZEALIGN = 262144;
154
155pub const WNOHANG = 0x0001;
156pub const WUNTRACED = 0x0002;
157pub const WCONTINUED = 0x0004;
158pub const WSTOPPED = WUNTRACED;
159pub const WNOWAIT = 0x0008;
160pub const WEXITED = 0x0010;
161pub const WTRAPPED = 0x0020;
162
163pub const SA_ONSTACK = 0x0001;
164pub const SA_RESTART = 0x0002;
165pub const SA_RESETHAND = 0x0004;
166pub const SA_NODEFER = 0x0010;
167pub const SA_NOCLDWAIT = 0x0020;
168pub const SA_SIGINFO = 0x0040;
169
170pub const PATH_MAX = 1024;
171pub const IOV_MAX = KERN_IOV_MAX;
172
173pub const ino_t = c_ulong;
174
175pub const libc_stat = extern struct {
176 ino: ino_t,
177 nlink: c_uint,
178 dev: c_uint,
179 mode: c_ushort,
180 padding1: u16,
181 uid: uid_t,
182 gid: gid_t,
183 rdev: c_uint,
184 atim: timespec,
185 mtim: timespec,
186 ctim: timespec,
187 size: c_ulong,
188 blocks: i64,
189 blksize: u32,
190 flags: u32,
191 gen: u32,
192 lspare: i32,
193 qspare1: i64,
194 qspare2: i64,
195 pub fn atime(self: @This()) timespec {
196 return self.atim;
197 }
198
199 pub fn mtime(self: @This()) timespec {
200 return self.mtim;
201 }
202
203 pub fn ctime(self: @This()) timespec {
204 return self.ctim;
205 }
206};
207
208pub const timespec = extern struct {
209 tv_sec: c_long,
210 tv_nsec: c_long,
211};
212
213pub const timeval = extern struct {
214 /// seconds
215 tv_sec: time_t,
216 /// microseconds
217 tv_usec: suseconds_t,
218};
219
220pub const CTL_UNSPEC = 0;
221pub const CTL_KERN = 1;
222pub const CTL_VM = 2;
223pub const CTL_VFS = 3;
224pub const CTL_NET = 4;
225pub const CTL_DEBUG = 5;
226pub const CTL_HW = 6;
227pub const CTL_MACHDEP = 7;
228pub const CTL_USER = 8;
229pub const CTL_LWKT = 10;
230pub const CTL_MAXID = 11;
231pub const CTL_MAXNAME = 12;
232
233pub const KERN_PROC_ALL = 0;
234pub const KERN_OSTYPE = 1;
235pub const KERN_PROC_PID = 1;
236pub const KERN_OSRELEASE = 2;
237pub const KERN_PROC_PGRP = 2;
238pub const KERN_OSREV = 3;
239pub const KERN_PROC_SESSION = 3;
240pub const KERN_VERSION = 4;
241pub const KERN_PROC_TTY = 4;
242pub const KERN_MAXVNODES = 5;
243pub const KERN_PROC_UID = 5;
244pub const KERN_MAXPROC = 6;
245pub const KERN_PROC_RUID = 6;
246pub const KERN_MAXFILES = 7;
247pub const KERN_PROC_ARGS = 7;
248pub const KERN_ARGMAX = 8;
249pub const KERN_PROC_CWD = 8;
250pub const KERN_PROC_PATHNAME = 9;
251pub const KERN_SECURELVL = 9;
252pub const KERN_PROC_SIGTRAMP = 10;
253pub const KERN_HOSTNAME = 10;
254pub const KERN_HOSTID = 11;
255pub const KERN_CLOCKRATE = 12;
256pub const KERN_VNODE = 13;
257pub const KERN_PROC = 14;
258pub const KERN_FILE = 15;
259pub const KERN_PROC_FLAGMASK = 16;
260pub const KERN_PROF = 16;
261pub const KERN_PROC_FLAG_LWP = 16;
262pub const KERN_POSIX1 = 17;
263pub const KERN_NGROUPS = 18;
264pub const KERN_JOB_CONTROL = 19;
265pub const KERN_SAVED_IDS = 20;
266pub const KERN_BOOTTIME = 21;
267pub const KERN_NISDOMAINNAME = 22;
268pub const KERN_UPDATEINTERVAL = 23;
269pub const KERN_OSRELDATE = 24;
270pub const KERN_NTP_PLL = 25;
271pub const KERN_BOOTFILE = 26;
272pub const KERN_MAXFILESPERPROC = 27;
273pub const KERN_MAXPROCPERUID = 28;
274pub const KERN_DUMPDEV = 29;
275pub const KERN_IPC = 30;
276pub const KERN_DUMMY = 31;
277pub const KERN_PS_STRINGS = 32;
278pub const KERN_USRSTACK = 33;
279pub const KERN_LOGSIGEXIT = 34;
280pub const KERN_IOV_MAX = 35;
281pub const KERN_MAXPOSIXLOCKSPERUID = 36;
282pub const KERN_MAXID = 37;
283
284pub const HOST_NAME_MAX = 255;
285
286// access function
287pub const F_OK = 0; // test for existence of file
288pub const X_OK = 1; // test for execute or search permission
289pub const W_OK = 2; // test for write permission
290pub const R_OK = 4; // test for read permission
291
292pub const O_RDONLY = 0;
293pub const O_NDELAY = O_NONBLOCK;
294pub const O_WRONLY = 1;
295pub const O_RDWR = 2;
296pub const O_ACCMODE = 3;
297pub const O_NONBLOCK = 4;
298pub const O_APPEND = 8;
299pub const O_SHLOCK = 16;
300pub const O_EXLOCK = 32;
301pub const O_ASYNC = 64;
302pub const O_FSYNC = 128;
303pub const O_SYNC = 128;
304pub const O_NOFOLLOW = 256;
305pub const O_CREAT = 512;
306pub const O_TRUNC = 1024;
307pub const O_EXCL = 2048;
308pub const O_NOCTTY = 32768;
309pub const O_DIRECT = 65536;
310pub const O_CLOEXEC = 131072;
311pub const O_FBLOCKING = 262144;
312pub const O_FNONBLOCKING = 524288;
313pub const O_FAPPEND = 1048576;
314pub const O_FOFFSET = 2097152;
315pub const O_FSYNCWRITE = 4194304;
316pub const O_FASYNCWRITE = 8388608;
317pub const O_DIRECTORY = 134217728;
318
319pub const SEEK_SET = 0;
320pub const SEEK_CUR = 1;
321pub const SEEK_END = 2;
322pub const SEEK_DATA = 3;
323pub const SEEK_HOLE = 4;
324
325pub const F_ULOCK = 0;
326pub const F_LOCK = 1;
327pub const F_TLOCK = 2;
328pub const F_TEST = 3;
329
330pub const FD_CLOEXEC = 1;
331
332pub const AT_FDCWD = -328243;
333pub const AT_SYMLINK_NOFOLLOW = 1;
334pub const AT_REMOVEDIR = 2;
335pub const AT_EACCESS = 4;
336pub const AT_SYMLINK_FOLLOW = 8;
337
338pub fn WEXITSTATUS(s: u32) u8 {
339 return @intCast(u8, (s & 0xff00) >> 8);
340}
341pub fn WTERMSIG(s: u32) u32 {
342 return s & 0x7f;
343}
344pub fn WSTOPSIG(s: u32) u32 {
345 return WEXITSTATUS(s);
346}
347pub fn WIFEXITED(s: u32) bool {
348 return WTERMSIG(s) == 0;
349}
350pub fn WIFSTOPPED(s: u32) bool {
351 return @intCast(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
352}
353pub fn WIFSIGNALED(s: u32) bool {
354 return (s & 0xffff) -% 1 < 0xff;
355}
356
357pub const dirent = extern struct {
358 d_fileno: c_ulong,
359 d_namlen: u16,
360 d_type: u8,
361 d_unused1: u8,
362 d_unused2: u32,
363 d_name: [256]u8,
364
365 pub fn reclen(self: dirent) u16 {
366 return (@offsetOf(dirent, "d_name") + self.d_namlen + 1 + 7) & ~@as(u16, 7);
367 }
368};
369
370pub const DT_UNKNOWN = 0;
371pub const DT_FIFO = 1;
372pub const DT_CHR = 2;
373pub const DT_DIR = 4;
374pub const DT_BLK = 6;
375pub const DT_REG = 8;
376pub const DT_LNK = 10;
377pub const DT_SOCK = 12;
378pub const DT_WHT = 14;
379pub const DT_DBF = 15;
380
381pub const CLOCK_REALTIME = 0;
382pub const CLOCK_VIRTUAL = 1;
383pub const CLOCK_PROF = 2;
384pub const CLOCK_MONOTONIC = 4;
385pub const CLOCK_UPTIME = 5;
386pub const CLOCK_UPTIME_PRECISE = 7;
387pub const CLOCK_UPTIME_FAST = 8;
388pub const CLOCK_REALTIME_PRECISE = 9;
389pub const CLOCK_REALTIME_FAST = 10;
390pub const CLOCK_MONOTONIC_PRECISE = 11;
391pub const CLOCK_MONOTONIC_FAST = 12;
392pub const CLOCK_SECOND = 13;
393pub const CLOCK_THREAD_CPUTIME_ID = 14;
394pub const CLOCK_PROCESS_CPUTIME_ID = 15;
395
396pub const sockaddr = extern struct {
397 len: u8,
398 family: u8,
399 data: [14]u8,
400};
401
402pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
403
404pub const Kevent = extern struct {
405 ident: usize,
406 filter: c_short,
407 flags: c_ushort,
408 fflags: c_uint,
409 data: isize,
410 udata: usize,
411};
412
413pub const EVFILT_FS = -10;
414pub const EVFILT_USER = -9;
415pub const EVFILT_EXCEPT = -8;
416pub const EVFILT_TIMER = -7;
417pub const EVFILT_SIGNAL = -6;
418pub const EVFILT_PROC = -5;
419pub const EVFILT_VNODE = -4;
420pub const EVFILT_AIO = -3;
421pub const EVFILT_WRITE = -2;
422pub const EVFILT_READ = -1;
423pub const EVFILT_SYSCOUNT = 10;
424pub const EVFILT_MARKER = 15;
425
426pub const EV_ADD = 1;
427pub const EV_DELETE = 2;
428pub const EV_ENABLE = 4;
429pub const EV_DISABLE = 8;
430pub const EV_ONESHOT = 16;
431pub const EV_CLEAR = 32;
432pub const EV_RECEIPT = 64;
433pub const EV_DISPATCH = 128;
434pub const EV_NODATA = 4096;
435pub const EV_FLAG1 = 8192;
436pub const EV_ERROR = 16384;
437pub const EV_EOF = 32768;
438pub const EV_SYSFLAGS = 61440;
439
440pub const NOTE_FFNOP = 0;
441pub const NOTE_TRACK = 1;
442pub const NOTE_DELETE = 1;
443pub const NOTE_LOWAT = 1;
444pub const NOTE_TRACKERR = 2;
445pub const NOTE_OOB = 2;
446pub const NOTE_WRITE = 2;
447pub const NOTE_EXTEND = 4;
448pub const NOTE_CHILD = 4;
449pub const NOTE_ATTRIB = 8;
450pub const NOTE_LINK = 16;
451pub const NOTE_RENAME = 32;
452pub const NOTE_REVOKE = 64;
453pub const NOTE_PDATAMASK = 1048575;
454pub const NOTE_FFLAGSMASK = 16777215;
455pub const NOTE_TRIGGER = 16777216;
456pub const NOTE_EXEC = 536870912;
457pub const NOTE_FFAND = 1073741824;
458pub const NOTE_FORK = 1073741824;
459pub const NOTE_EXIT = 2147483648;
460pub const NOTE_FFOR = 2147483648;
461pub const NOTE_FFCTRLMASK = 3221225472;
462pub const NOTE_FFCOPY = 3221225472;
463pub const NOTE_PCTRLMASK = 4026531840;
464
465pub const stack_t = extern struct {
466 ss_sp: [*]u8,
467 ss_size: isize,
468 ss_flags: i32,
469};
470
471pub const S_IREAD = S_IRUSR;
472pub const S_IEXEC = S_IXUSR;
473pub const S_IWRITE = S_IWUSR;
474pub const S_IXOTH = 1;
475pub const S_IWOTH = 2;
476pub const S_IROTH = 4;
477pub const S_IRWXO = 7;
478pub const S_IXGRP = 8;
479pub const S_IWGRP = 16;
480pub const S_IRGRP = 32;
481pub const S_IRWXG = 56;
482pub const S_IXUSR = 64;
483pub const S_IWUSR = 128;
484pub const S_IRUSR = 256;
485pub const S_IRWXU = 448;
486pub const S_ISTXT = 512;
487pub const S_BLKSIZE = 512;
488pub const S_ISVTX = 512;
489pub const S_ISGID = 1024;
490pub const S_ISUID = 2048;
491pub const S_IFIFO = 4096;
492pub const S_IFCHR = 8192;
493pub const S_IFDIR = 16384;
494pub const S_IFBLK = 24576;
495pub const S_IFREG = 32768;
496pub const S_IFDB = 36864;
497pub const S_IFLNK = 40960;
498pub const S_IFSOCK = 49152;
499pub const S_IFWHT = 57344;
500pub const S_IFMT = 61440;
501
502pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
503pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
504pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
505pub const BADSIG = SIG_ERR;
506
507pub const SIG_BLOCK = 1;
508pub const SIG_UNBLOCK = 2;
509pub const SIG_SETMASK = 3;
510
511pub const SIGIOT = SIGABRT;
512pub const SIGHUP = 1;
513pub const SIGINT = 2;
514pub const SIGQUIT = 3;
515pub const SIGILL = 4;
516pub const SIGTRAP = 5;
517pub const SIGABRT = 6;
518pub const SIGEMT = 7;
519pub const SIGFPE = 8;
520pub const SIGKILL = 9;
521pub const SIGBUS = 10;
522pub const SIGSEGV = 11;
523pub const SIGSYS = 12;
524pub const SIGPIPE = 13;
525pub const SIGALRM = 14;
526pub const SIGTERM = 15;
527pub const SIGURG = 16;
528pub const SIGSTOP = 17;
529pub const SIGTSTP = 18;
530pub const SIGCONT = 19;
531pub const SIGCHLD = 20;
532pub const SIGTTIN = 21;
533pub const SIGTTOU = 22;
534pub const SIGIO = 23;
535pub const SIGXCPU = 24;
536pub const SIGXFSZ = 25;
537pub const SIGVTALRM = 26;
538pub const SIGPROF = 27;
539pub const SIGWINCH = 28;
540pub const SIGINFO = 29;
541pub const SIGUSR1 = 30;
542pub const SIGUSR2 = 31;
543pub const SIGTHR = 32;
544pub const SIGCKPT = 33;
545pub const SIGCKPTEXIT = 34;
546
547pub const siginfo_t = extern struct {
548 signo: c_int,
549 errno: c_int,
550 code: c_int,
551 pid: c_int,
552 uid: uid_t,
553 status: c_int,
554 addr: ?*c_void,
555 value: sigval,
556 band: c_long,
557 __spare__: [7]c_int,
558};
559
560pub const sigval = extern union {
561 sival_int: c_int,
562 sival_ptr: ?*c_void,
563};
564
565pub const _SIG_WORDS = 4;
566
567pub const sigset_t = extern struct {
568 __bits: [_SIG_WORDS]c_uint,
569};
570
571pub const empty_sigset = sigset_t{ .__bits = [_]c_uint{0} ** _SIG_WORDS };
572
573pub const sig_atomic_t = c_int;
574
575pub const Sigaction = extern struct {
576 pub const handler_fn = fn (c_int) callconv(.C) void;
577 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
578
579 /// signal handler
580 handler: extern union {
581 handler: ?handler_fn,
582 sigaction: ?sigaction_fn,
583 },
584 flags: c_uint,
585 mask: sigset_t,
586};
587
588pub const sig_t = [*c]fn (c_int) callconv(.C) void;
589
590pub const SOCK_STREAM = 1;
591pub const SOCK_DGRAM = 2;
592pub const SOCK_RAW = 3;
593pub const SOCK_RDM = 4;
594pub const SOCK_SEQPACKET = 5;
595pub const SOCK_MAXADDRLEN = 255;
596pub const SOCK_CLOEXEC = 0x10000000;
597pub const SOCK_NONBLOCK = 0x20000000;
598
599pub const SO_DEBUG = 0x0001;
600pub const SO_ACCEPTCONN = 0x0002;
601pub const SO_REUSEADDR = 0x0004;
602pub const SO_KEEPALIVE = 0x0008;
603pub const SO_DONTROUTE = 0x0010;
604pub const SO_BROADCAST = 0x0020;
605pub const SO_USELOOPBACK = 0x0040;
606pub const SO_LINGER = 0x0080;
607pub const SO_OOBINLINE = 0x0100;
608pub const SO_REUSEPORT = 0x0200;
609pub const SO_TIMESTAMP = 0x0400;
610pub const SO_NOSIGPIPE = 0x0800;
611pub const SO_ACCEPTFILTER = 0x1000;
612pub const SO_RERROR = 0x2000;
613pub const SO_PASSCRED = 0x4000;
614
615pub const SO_SNDBUF = 0x1001;
616pub const SO_RCVBUF = 0x1002;
617pub const SO_SNDLOWAT = 0x1003;
618pub const SO_RCVLOWAT = 0x1004;
619pub const SO_SNDTIMEO = 0x1005;
620pub const SO_RCVTIMEO = 0x1006;
621pub const SO_ERROR = 0x1007;
622pub const SO_TYPE = 0x1008;
623pub const SO_SNDSPACE = 0x100a;
624pub const SO_CPUHINT = 0x1030;
625
626pub const SOL_SOCKET = 0xffff;
627
628pub const PF_INET6 = AF_INET6;
629pub const PF_IMPLINK = AF_IMPLINK;
630pub const PF_ROUTE = AF_ROUTE;
631pub const PF_ISO = AF_ISO;
632pub const PF_PIP = pseudo_AF_PIP;
633pub const PF_CHAOS = AF_CHAOS;
634pub const PF_DATAKIT = AF_DATAKIT;
635pub const PF_INET = AF_INET;
636pub const PF_APPLETALK = AF_APPLETALK;
637pub const PF_SIP = AF_SIP;
638pub const PF_OSI = AF_ISO;
639pub const PF_CNT = AF_CNT;
640pub const PF_LINK = AF_LINK;
641pub const PF_HYLINK = AF_HYLINK;
642pub const PF_MAX = AF_MAX;
643pub const PF_KEY = pseudo_AF_KEY;
644pub const PF_PUP = AF_PUP;
645pub const PF_COIP = AF_COIP;
646pub const PF_SNA = AF_SNA;
647pub const PF_LOCAL = AF_LOCAL;
648pub const PF_NETBIOS = AF_NETBIOS;
649pub const PF_NATM = AF_NATM;
650pub const PF_BLUETOOTH = AF_BLUETOOTH;
651pub const PF_UNSPEC = AF_UNSPEC;
652pub const PF_NETGRAPH = AF_NETGRAPH;
653pub const PF_ECMA = AF_ECMA;
654pub const PF_IPX = AF_IPX;
655pub const PF_DLI = AF_DLI;
656pub const PF_ATM = AF_ATM;
657pub const PF_CCITT = AF_CCITT;
658pub const PF_ISDN = AF_ISDN;
659pub const PF_RTIP = pseudo_AF_RTIP;
660pub const PF_LAT = AF_LAT;
661pub const PF_UNIX = PF_LOCAL;
662pub const PF_XTP = pseudo_AF_XTP;
663pub const PF_DECnet = AF_DECnet;
664
665pub const AF_UNSPEC = 0;
666pub const AF_OSI = AF_ISO;
667pub const AF_UNIX = AF_LOCAL;
668pub const AF_LOCAL = 1;
669pub const AF_INET = 2;
670pub const AF_IMPLINK = 3;
671pub const AF_PUP = 4;
672pub const AF_CHAOS = 5;
673pub const AF_NETBIOS = 6;
674pub const AF_ISO = 7;
675pub const AF_ECMA = 8;
676pub const AF_DATAKIT = 9;
677pub const AF_CCITT = 10;
678pub const AF_SNA = 11;
679pub const AF_DLI = 13;
680pub const AF_LAT = 14;
681pub const AF_HYLINK = 15;
682pub const AF_APPLETALK = 16;
683pub const AF_ROUTE = 17;
684pub const AF_LINK = 18;
685pub const AF_COIP = 20;
686pub const AF_CNT = 21;
687pub const AF_IPX = 23;
688pub const AF_SIP = 24;
689pub const AF_ISDN = 26;
690pub const AF_INET6 = 28;
691pub const AF_NATM = 29;
692pub const AF_ATM = 30;
693pub const AF_NETGRAPH = 32;
694pub const AF_BLUETOOTH = 33;
695pub const AF_MPLS = 34;
696pub const AF_MAX = 36;
697
698pub const in_port_t = u16;
699pub const sa_family_t = u8;
700pub const socklen_t = u32;
701
702pub const sockaddr_in = extern struct {
703 len: u8 = @sizeOf(sockaddr_in),
704 family: sa_family_t = AF_INET,
705 port: in_port_t,
706 addr: u32,
707 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
708};
709
710pub const sockaddr_in6 = extern struct {
711 len: u8 = @sizeOf(sockaddr_in6),
712 family: sa_family_t = AF_INET6,
713 port: in_port_t,
714 flowinfo: u32,
715 addr: [16]u8,
716 scope_id: u32,
717};
718
719pub const EAI = enum(c_int) {
720 ADDRFAMILY = 1,
721 AGAIN = 2,
722 BADFLAGS = 3,
723 FAIL = 4,
724 FAMILY = 5,
725 MEMORY = 6,
726 NODATA = 7,
727 NONAME = 8,
728 SERVICE = 9,
729 SOCKTYPE = 10,
730 SYSTEM = 11,
731 BADHINTS = 12,
732 PROTOCOL = 13,
733 OVERFLOW = 14,
734 _,
735};
736
737pub const AI_PASSIVE = 0x00000001;
738pub const AI_CANONNAME = 0x00000002;
739pub const AI_NUMERICHOST = 0x00000004;
740pub const AI_NUMERICSERV = 0x00000008;
741pub const AI_MASK = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG;
742pub const AI_ALL = 0x00000100;
743pub const AI_V4MAPPED_CFG = 0x00000200;
744pub const AI_ADDRCONFIG = 0x00000400;
745pub const AI_V4MAPPED = 0x00000800;
746pub const AI_DEFAULT = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
747
748pub const RTLD_LAZY = 1;
749pub const RTLD_NOW = 2;
750pub const RTLD_MODEMASK = 0x3;
751pub const RTLD_GLOBAL = 0x100;
752pub const RTLD_LOCAL = 0;
753pub const RTLD_TRACE = 0x200;
754pub const RTLD_NODELETE = 0x01000;
755pub const RTLD_NOLOAD = 0x02000;
756
757pub const RTLD_NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
758pub const RTLD_DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
759pub const RTLD_SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
760pub const RTLD_ALL = @intToPtr(*c_void, @bitCast(usize, @as(isize, -4)));
761
762pub const dl_phdr_info = extern struct {
763 dlpi_addr: usize,
764 dlpi_name: ?[*:0]const u8,
765 dlpi_phdr: [*]std.elf.Phdr,
766 dlpi_phnum: u16,
767};
768pub const cmsghdr = extern struct {
769 cmsg_len: socklen_t,
770 cmsg_level: c_int,
771 cmsg_type: c_int,
772};
773pub const msghdr = extern struct {
774 msg_name: ?*c_void,
775 msg_namelen: socklen_t,
776 msg_iov: [*c]iovec,
777 msg_iovlen: c_int,
778 msg_control: ?*c_void,
779 msg_controllen: socklen_t,
780 msg_flags: c_int,
781};
782pub const cmsgcred = extern struct {
783 cmcred_pid: pid_t,
784 cmcred_uid: uid_t,
785 cmcred_euid: uid_t,
786 cmcred_gid: gid_t,
787 cmcred_ngroups: c_short,
788 cmcred_groups: [16]gid_t,
789};
790pub const sf_hdtr = extern struct {
791 headers: [*c]iovec,
792 hdr_cnt: c_int,
793 trailers: [*c]iovec,
794 trl_cnt: c_int,
795};
796
797pub const MS_SYNC = 0;
798pub const MS_ASYNC = 1;
799pub const MS_INVALIDATE = 2;
800
801pub const POSIX_MADV_SEQUENTIAL = 2;
802pub const POSIX_MADV_RANDOM = 1;
803pub const POSIX_MADV_DONTNEED = 4;
804pub const POSIX_MADV_NORMAL = 0;
805pub const POSIX_MADV_WILLNEED = 3;
806
807pub const MADV_SEQUENTIAL = 2;
808pub const MADV_CONTROL_END = MADV_SETMAP;
809pub const MADV_DONTNEED = 4;
810pub const MADV_RANDOM = 1;
811pub const MADV_WILLNEED = 3;
812pub const MADV_NORMAL = 0;
813pub const MADV_CONTROL_START = MADV_INVAL;
814pub const MADV_FREE = 5;
815pub const MADV_NOSYNC = 6;
816pub const MADV_AUTOSYNC = 7;
817pub const MADV_NOCORE = 8;
818pub const MADV_CORE = 9;
819pub const MADV_INVAL = 10;
820pub const MADV_SETMAP = 11;
821
822pub const F_DUPFD = 0;
823pub const F_GETFD = 1;
824pub const F_RDLCK = 1;
825pub const F_SETFD = 2;
826pub const F_UNLCK = 2;
827pub const F_WRLCK = 3;
828pub const F_GETFL = 3;
829pub const F_SETFL = 4;
830pub const F_GETOWN = 5;
831pub const F_SETOWN = 6;
832pub const F_GETLK = 7;
833pub const F_SETLK = 8;
834pub const F_SETLKW = 9;
835pub const F_DUP2FD = 10;
836pub const F_DUPFD_CLOEXEC = 17;
837pub const F_DUP2FD_CLOEXEC = 18;
838
839pub const LOCK_SH = 1;
840pub const LOCK_EX = 2;
841pub const LOCK_UN = 8;
842pub const LOCK_NB = 4;
843
844pub const Flock = extern struct {
845 l_start: off_t,
846 l_len: off_t,
847 l_pid: pid_t,
848 l_type: c_short,
849 l_whence: c_short,
850};
851
852pub const addrinfo = extern struct {
853 flags: i32,
854 family: i32,
855 socktype: i32,
856 protocol: i32,
857 addrlen: socklen_t,
858 canonname: ?[*:0]u8,
859 addr: ?*sockaddr,
860 next: ?*addrinfo,
861};
862
863pub const IPPROTO_IP = 0;
864pub const IPPROTO_ICMP = 1;
865pub const IPPROTO_TCP = 6;
866pub const IPPROTO_UDP = 17;
867pub const IPPROTO_IPV6 = 41;
868pub const IPPROTO_RAW = 255;
869pub const IPPROTO_HOPOPTS = 0;
870pub const IPPROTO_IGMP = 2;
871pub const IPPROTO_GGP = 3;
872pub const IPPROTO_IPV4 = 4;
873pub const IPPROTO_IPIP = IPPROTO_IPV4;
874pub const IPPROTO_ST = 7;
875pub const IPPROTO_EGP = 8;
876pub const IPPROTO_PIGP = 9;
877pub const IPPROTO_RCCMON = 10;
878pub const IPPROTO_NVPII = 11;
879pub const IPPROTO_PUP = 12;
880pub const IPPROTO_ARGUS = 13;
881pub const IPPROTO_EMCON = 14;
882pub const IPPROTO_XNET = 15;
883pub const IPPROTO_CHAOS = 16;
884pub const IPPROTO_MUX = 18;
885pub const IPPROTO_MEAS = 19;
886pub const IPPROTO_HMP = 20;
887pub const IPPROTO_PRM = 21;
888pub const IPPROTO_IDP = 22;
889pub const IPPROTO_TRUNK1 = 23;
890pub const IPPROTO_TRUNK2 = 24;
891pub const IPPROTO_LEAF1 = 25;
892pub const IPPROTO_LEAF2 = 26;
893pub const IPPROTO_RDP = 27;
894pub const IPPROTO_IRTP = 28;
895pub const IPPROTO_TP = 29;
896pub const IPPROTO_BLT = 30;
897pub const IPPROTO_NSP = 31;
898pub const IPPROTO_INP = 32;
899pub const IPPROTO_SEP = 33;
900pub const IPPROTO_3PC = 34;
901pub const IPPROTO_IDPR = 35;
902pub const IPPROTO_XTP = 36;
903pub const IPPROTO_DDP = 37;
904pub const IPPROTO_CMTP = 38;
905pub const IPPROTO_TPXX = 39;
906pub const IPPROTO_IL = 40;
907pub const IPPROTO_SDRP = 42;
908pub const IPPROTO_ROUTING = 43;
909pub const IPPROTO_FRAGMENT = 44;
910pub const IPPROTO_IDRP = 45;
911pub const IPPROTO_RSVP = 46;
912pub const IPPROTO_GRE = 47;
913pub const IPPROTO_MHRP = 48;
914pub const IPPROTO_BHA = 49;
915pub const IPPROTO_ESP = 50;
916pub const IPPROTO_AH = 51;
917pub const IPPROTO_INLSP = 52;
918pub const IPPROTO_SWIPE = 53;
919pub const IPPROTO_NHRP = 54;
920pub const IPPROTO_MOBILE = 55;
921pub const IPPROTO_TLSP = 56;
922pub const IPPROTO_SKIP = 57;
923pub const IPPROTO_ICMPV6 = 58;
924pub const IPPROTO_NONE = 59;
925pub const IPPROTO_DSTOPTS = 60;
926pub const IPPROTO_AHIP = 61;
927pub const IPPROTO_CFTP = 62;
928pub const IPPROTO_HELLO = 63;
929pub const IPPROTO_SATEXPAK = 64;
930pub const IPPROTO_KRYPTOLAN = 65;
931pub const IPPROTO_RVD = 66;
932pub const IPPROTO_IPPC = 67;
933pub const IPPROTO_ADFS = 68;
934pub const IPPROTO_SATMON = 69;
935pub const IPPROTO_VISA = 70;
936pub const IPPROTO_IPCV = 71;
937pub const IPPROTO_CPNX = 72;
938pub const IPPROTO_CPHB = 73;
939pub const IPPROTO_WSN = 74;
940pub const IPPROTO_PVP = 75;
941pub const IPPROTO_BRSATMON = 76;
942pub const IPPROTO_ND = 77;
943pub const IPPROTO_WBMON = 78;
944pub const IPPROTO_WBEXPAK = 79;
945pub const IPPROTO_EON = 80;
946pub const IPPROTO_VMTP = 81;
947pub const IPPROTO_SVMTP = 82;
948pub const IPPROTO_VINES = 83;
949pub const IPPROTO_TTP = 84;
950pub const IPPROTO_IGP = 85;
951pub const IPPROTO_DGP = 86;
952pub const IPPROTO_TCF = 87;
953pub const IPPROTO_IGRP = 88;
954pub const IPPROTO_OSPFIGP = 89;
955pub const IPPROTO_SRPC = 90;
956pub const IPPROTO_LARP = 91;
957pub const IPPROTO_MTP = 92;
958pub const IPPROTO_AX25 = 93;
959pub const IPPROTO_IPEIP = 94;
960pub const IPPROTO_MICP = 95;
961pub const IPPROTO_SCCSP = 96;
962pub const IPPROTO_ETHERIP = 97;
963pub const IPPROTO_ENCAP = 98;
964pub const IPPROTO_APES = 99;
965pub const IPPROTO_GMTP = 100;
966pub const IPPROTO_IPCOMP = 108;
967pub const IPPROTO_PIM = 103;
968pub const IPPROTO_CARP = 112;
969pub const IPPROTO_PGM = 113;
970pub const IPPROTO_PFSYNC = 240;
971pub const IPPROTO_DIVERT = 254;
972pub const IPPROTO_MAX = 256;
973pub const IPPROTO_DONE = 257;
974pub const IPPROTO_UNKNOWN = 258;
975
976pub const rlimit_resource = enum(c_int) {
977 CPU = 0,
978 FSIZE = 1,
979 DATA = 2,
980 STACK = 3,
981 CORE = 4,
982 RSS = 5,
983 MEMLOCK = 6,
984 NPROC = 7,
985 NOFILE = 8,
986 SBSIZE = 9,
987 VMEM = 10,
988 POSIXLOCKS = 11,
989 _,
990
991 pub const AS: rlimit_resource = .VMEM;
992};
993
994pub const rlim_t = i64;
995
996/// No limit
997pub const RLIM_INFINITY: rlim_t = (1 << 63) - 1;
998
999pub const RLIM_SAVED_MAX = RLIM_INFINITY;
1000pub const RLIM_SAVED_CUR = RLIM_INFINITY;
1001
1002pub const rlimit = extern struct {
1003 /// Soft limit
1004 cur: rlim_t,
1005 /// Hard limit
1006 max: rlim_t,
1007};
1008
1009pub const SHUT_RD = 0;
1010pub const SHUT_WR = 1;
1011pub const SHUT_RDWR = 2;
1012
1013pub const nfds_t = u32;
1014
1015pub const pollfd = extern struct {
1016 fd: fd_t,
1017 events: i16,
1018 revents: i16,
1019};
1020
1021/// Requestable events.
1022pub const POLLIN = 0x0001;
1023pub const POLLPRI = 0x0002;
1024pub const POLLOUT = 0x0004;
1025pub const POLLRDNORM = 0x0040;
1026pub const POLLWRNORM = POLLOUT;
1027pub const POLLRDBAND = 0x0080;
1028pub const POLLWRBAND = 0x0100;
1029
1030/// These events are set if they occur regardless of whether they were requested.
1031pub const POLLERR = 0x0008;
1032pub const POLLHUP = 0x0010;
1033pub const POLLNVAL = 0x0020;
lib/std/os/bits/freebsd.zig deleted-1542
...@@ -1,1542 +0,0 @@
1const std = @import("../../std.zig");
2const builtin = @import("builtin");
3const maxInt = std.math.maxInt;
4
5pub usingnamespace @import("posix.zig");
6
7pub const blksize_t = i32;
8pub const blkcnt_t = i64;
9pub const clockid_t = i32;
10pub const fsblkcnt_t = u64;
11pub const fsfilcnt_t = u64;
12pub const nlink_t = u64;
13pub const fd_t = i32;
14pub const pid_t = i32;
15pub const uid_t = u32;
16pub const gid_t = u32;
17pub const mode_t = u16;
18pub const off_t = i64;
19pub const ino_t = u64;
20pub const dev_t = u64;
21pub const time_t = i64;
22// The signedness is not constant across different architectures.
23pub const clock_t = isize;
24
25pub const socklen_t = u32;
26pub const suseconds_t = c_long;
27
28/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
29pub const Kevent = extern struct {
30 ident: usize,
31 filter: i16,
32 flags: u16,
33 fflags: u32,
34 data: i64,
35 udata: usize,
36 // TODO ext
37};
38
39// Modes and flags for dlopen()
40// include/dlfcn.h
41
42/// Bind function calls lazily.
43pub const RTLD_LAZY = 1;
44
45/// Bind function calls immediately.
46pub const RTLD_NOW = 2;
47
48pub const RTLD_MODEMASK = 0x3;
49
50/// Make symbols globally available.
51pub const RTLD_GLOBAL = 0x100;
52
53/// Opposite of RTLD_GLOBAL, and the default.
54pub const RTLD_LOCAL = 0;
55
56/// Trace loaded objects and exit.
57pub const RTLD_TRACE = 0x200;
58
59/// Do not remove members.
60pub const RTLD_NODELETE = 0x01000;
61
62/// Do not load if not already loaded.
63pub const RTLD_NOLOAD = 0x02000;
64
65pub const dl_phdr_info = extern struct {
66 dlpi_addr: usize,
67 dlpi_name: ?[*:0]const u8,
68 dlpi_phdr: [*]std.elf.Phdr,
69 dlpi_phnum: u16,
70};
71
72pub const Flock = extern struct {
73 l_start: off_t,
74 l_len: off_t,
75 l_pid: pid_t,
76 l_type: i16,
77 l_whence: i16,
78 l_sysid: i32,
79 __unused: [4]u8,
80};
81
82pub const msghdr = extern struct {
83 /// optional address
84 msg_name: ?*sockaddr,
85
86 /// size of address
87 msg_namelen: socklen_t,
88
89 /// scatter/gather array
90 msg_iov: [*]iovec,
91
92 /// # elements in msg_iov
93 msg_iovlen: i32,
94
95 /// ancillary data
96 msg_control: ?*c_void,
97
98 /// ancillary data buffer len
99 msg_controllen: socklen_t,
100
101 /// flags on received message
102 msg_flags: i32,
103};
104
105pub const msghdr_const = extern struct {
106 /// optional address
107 msg_name: ?*const sockaddr,
108
109 /// size of address
110 msg_namelen: socklen_t,
111
112 /// scatter/gather array
113 msg_iov: [*]iovec_const,
114
115 /// # elements in msg_iov
116 msg_iovlen: i32,
117
118 /// ancillary data
119 msg_control: ?*c_void,
120
121 /// ancillary data buffer len
122 msg_controllen: socklen_t,
123
124 /// flags on received message
125 msg_flags: i32,
126};
127
128pub const libc_stat = extern struct {
129 dev: dev_t,
130 ino: ino_t,
131 nlink: nlink_t,
132
133 mode: mode_t,
134 __pad0: u16,
135 uid: uid_t,
136 gid: gid_t,
137 __pad1: u32,
138 rdev: dev_t,
139
140 atim: timespec,
141 mtim: timespec,
142 ctim: timespec,
143 birthtim: timespec,
144
145 size: off_t,
146 blocks: i64,
147 blksize: isize,
148 flags: u32,
149 gen: u64,
150 __spare: [10]u64,
151
152 pub fn atime(self: @This()) timespec {
153 return self.atim;
154 }
155
156 pub fn mtime(self: @This()) timespec {
157 return self.mtim;
158 }
159
160 pub fn ctime(self: @This()) timespec {
161 return self.ctim;
162 }
163};
164
165pub const timespec = extern struct {
166 tv_sec: isize,
167 tv_nsec: isize,
168};
169
170pub const timeval = extern struct {
171 /// seconds
172 tv_sec: time_t,
173 /// microseconds
174 tv_usec: suseconds_t,
175};
176
177pub const dirent = extern struct {
178 d_fileno: usize,
179 d_off: i64,
180 d_reclen: u16,
181 d_type: u8,
182 d_pad0: u8,
183 d_namlen: u16,
184 d_pad1: u16,
185 d_name: [256]u8,
186
187 pub fn reclen(self: dirent) u16 {
188 return self.d_reclen;
189 }
190};
191
192pub const in_port_t = u16;
193pub const sa_family_t = u8;
194
195pub const sockaddr = extern struct {
196 /// total length
197 len: u8,
198
199 /// address family
200 family: sa_family_t,
201
202 /// actually longer; address value
203 data: [14]u8,
204};
205
206pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
207
208pub const sockaddr_in = extern struct {
209 len: u8 = @sizeOf(sockaddr_in),
210 family: sa_family_t = AF_INET,
211 port: in_port_t,
212 addr: u32,
213 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
214};
215
216pub const sockaddr_in6 = extern struct {
217 len: u8 = @sizeOf(sockaddr_in6),
218 family: sa_family_t = AF_INET6,
219 port: in_port_t,
220 flowinfo: u32,
221 addr: [16]u8,
222 scope_id: u32,
223};
224
225pub const sockaddr_un = extern struct {
226 len: u8 = @sizeOf(sockaddr_un),
227 family: sa_family_t = AF_UNIX,
228 path: [104]u8,
229};
230
231pub const CTL_KERN = 1;
232pub const CTL_DEBUG = 5;
233
234pub const KERN_PROC = 14; // struct: process entries
235pub const KERN_PROC_PATHNAME = 12; // path to executable
236pub const KERN_IOV_MAX = 35;
237
238pub const PATH_MAX = 1024;
239pub const IOV_MAX = KERN_IOV_MAX;
240
241pub const STDIN_FILENO = 0;
242pub const STDOUT_FILENO = 1;
243pub const STDERR_FILENO = 2;
244
245pub const PROT_NONE = 0;
246pub const PROT_READ = 1;
247pub const PROT_WRITE = 2;
248pub const PROT_EXEC = 4;
249
250pub const CLOCK_REALTIME = 0;
251pub const CLOCK_VIRTUAL = 1;
252pub const CLOCK_PROF = 2;
253pub const CLOCK_MONOTONIC = 4;
254pub const CLOCK_UPTIME = 5;
255pub const CLOCK_UPTIME_PRECISE = 7;
256pub const CLOCK_UPTIME_FAST = 8;
257pub const CLOCK_REALTIME_PRECISE = 9;
258pub const CLOCK_REALTIME_FAST = 10;
259pub const CLOCK_MONOTONIC_PRECISE = 11;
260pub const CLOCK_MONOTONIC_FAST = 12;
261pub const CLOCK_SECOND = 13;
262pub const CLOCK_THREAD_CPUTIME_ID = 14;
263pub const CLOCK_PROCESS_CPUTIME_ID = 15;
264
265pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
266pub const MAP_SHARED = 0x0001;
267pub const MAP_PRIVATE = 0x0002;
268pub const MAP_FIXED = 0x0010;
269pub const MAP_STACK = 0x0400;
270pub const MAP_NOSYNC = 0x0800;
271pub const MAP_ANON = 0x1000;
272pub const MAP_ANONYMOUS = MAP_ANON;
273pub const MAP_FILE = 0;
274
275pub const MAP_GUARD = 0x00002000;
276pub const MAP_EXCL = 0x00004000;
277pub const MAP_NOCORE = 0x00020000;
278pub const MAP_PREFAULT_READ = 0x00040000;
279pub const MAP_32BIT = 0x00080000;
280
281pub const WNOHANG = 1;
282pub const WUNTRACED = 2;
283pub const WSTOPPED = WUNTRACED;
284pub const WCONTINUED = 4;
285pub const WNOWAIT = 8;
286pub const WEXITED = 16;
287pub const WTRAPPED = 32;
288
289pub const SA_ONSTACK = 0x0001;
290pub const SA_RESTART = 0x0002;
291pub const SA_RESETHAND = 0x0004;
292pub const SA_NOCLDSTOP = 0x0008;
293pub const SA_NODEFER = 0x0010;
294pub const SA_NOCLDWAIT = 0x0020;
295pub const SA_SIGINFO = 0x0040;
296
297pub const SIGHUP = 1;
298pub const SIGINT = 2;
299pub const SIGQUIT = 3;
300pub const SIGILL = 4;
301pub const SIGTRAP = 5;
302pub const SIGABRT = 6;
303pub const SIGIOT = SIGABRT;
304pub const SIGEMT = 7;
305pub const SIGFPE = 8;
306pub const SIGKILL = 9;
307pub const SIGBUS = 10;
308pub const SIGSEGV = 11;
309pub const SIGSYS = 12;
310pub const SIGPIPE = 13;
311pub const SIGALRM = 14;
312pub const SIGTERM = 15;
313pub const SIGURG = 16;
314pub const SIGSTOP = 17;
315pub const SIGTSTP = 18;
316pub const SIGCONT = 19;
317pub const SIGCHLD = 20;
318pub const SIGTTIN = 21;
319pub const SIGTTOU = 22;
320pub const SIGIO = 23;
321pub const SIGXCPU = 24;
322pub const SIGXFSZ = 25;
323pub const SIGVTALRM = 26;
324pub const SIGPROF = 27;
325pub const SIGWINCH = 28;
326pub const SIGINFO = 29;
327pub const SIGUSR1 = 30;
328pub const SIGUSR2 = 31;
329pub const SIGTHR = 32;
330pub const SIGLWP = SIGTHR;
331pub const SIGLIBRT = 33;
332
333pub const SIGRTMIN = 65;
334pub const SIGRTMAX = 126;
335
336// access function
337pub const F_OK = 0; // test for existence of file
338pub const X_OK = 1; // test for execute or search permission
339pub const W_OK = 2; // test for write permission
340pub const R_OK = 4; // test for read permission
341
342pub const O_RDONLY = 0x0000;
343pub const O_WRONLY = 0x0001;
344pub const O_RDWR = 0x0002;
345pub const O_ACCMODE = 0x0003;
346
347pub const O_SHLOCK = 0x0010;
348pub const O_EXLOCK = 0x0020;
349
350pub const O_CREAT = 0x0200;
351pub const O_EXCL = 0x0800;
352pub const O_NOCTTY = 0x8000;
353pub const O_TRUNC = 0x0400;
354pub const O_APPEND = 0x0008;
355pub const O_NONBLOCK = 0x0004;
356pub const O_DSYNC = 0o10000;
357pub const O_SYNC = 0x0080;
358pub const O_RSYNC = 0o4010000;
359pub const O_DIRECTORY = 0x20000;
360pub const O_NOFOLLOW = 0x0100;
361pub const O_CLOEXEC = 0x00100000;
362
363pub const O_ASYNC = 0x0040;
364pub const O_DIRECT = 0x00010000;
365pub const O_NOATIME = 0o1000000;
366pub const O_PATH = 0o10000000;
367pub const O_TMPFILE = 0o20200000;
368pub const O_NDELAY = O_NONBLOCK;
369
370pub const F_DUPFD = 0;
371pub const F_GETFD = 1;
372pub const F_SETFD = 2;
373pub const F_GETFL = 3;
374pub const F_SETFL = 4;
375
376pub const F_GETOWN = 5;
377pub const F_SETOWN = 6;
378
379pub const F_GETLK = 11;
380pub const F_SETLK = 12;
381pub const F_SETLKW = 13;
382
383pub const F_RDLCK = 1;
384pub const F_WRLCK = 3;
385pub const F_UNLCK = 2;
386
387pub const LOCK_SH = 1;
388pub const LOCK_EX = 2;
389pub const LOCK_UN = 8;
390pub const LOCK_NB = 4;
391
392pub const F_SETOWN_EX = 15;
393pub const F_GETOWN_EX = 16;
394
395pub const F_GETOWNER_UIDS = 17;
396
397pub const FD_CLOEXEC = 1;
398
399pub const SEEK_SET = 0;
400pub const SEEK_CUR = 1;
401pub const SEEK_END = 2;
402
403pub const SIG_BLOCK = 1;
404pub const SIG_UNBLOCK = 2;
405pub const SIG_SETMASK = 3;
406
407pub const SOCK_STREAM = 1;
408pub const SOCK_DGRAM = 2;
409pub const SOCK_RAW = 3;
410pub const SOCK_RDM = 4;
411pub const SOCK_SEQPACKET = 5;
412
413pub const SOCK_CLOEXEC = 0x10000000;
414pub const SOCK_NONBLOCK = 0x20000000;
415
416pub const SO_DEBUG = 0x00000001;
417pub const SO_ACCEPTCONN = 0x00000002;
418pub const SO_REUSEADDR = 0x00000004;
419pub const SO_KEEPALIVE = 0x00000008;
420pub const SO_DONTROUTE = 0x00000010;
421pub const SO_BROADCAST = 0x00000020;
422pub const SO_USELOOPBACK = 0x00000040;
423pub const SO_LINGER = 0x00000080;
424pub const SO_OOBINLINE = 0x00000100;
425pub const SO_REUSEPORT = 0x00000200;
426pub const SO_TIMESTAMP = 0x00000400;
427pub const SO_NOSIGPIPE = 0x00000800;
428pub const SO_ACCEPTFILTER = 0x00001000;
429pub const SO_BINTIME = 0x00002000;
430pub const SO_NO_OFFLOAD = 0x00004000;
431pub const SO_NO_DDP = 0x00008000;
432pub const SO_REUSEPORT_LB = 0x00010000;
433
434pub const SO_SNDBUF = 0x1001;
435pub const SO_RCVBUF = 0x1002;
436pub const SO_SNDLOWAT = 0x1003;
437pub const SO_RCVLOWAT = 0x1004;
438pub const SO_SNDTIMEO = 0x1005;
439pub const SO_RCVTIMEO = 0x1006;
440pub const SO_ERROR = 0x1007;
441pub const SO_TYPE = 0x1008;
442pub const SO_LABEL = 0x1009;
443pub const SO_PEERLABEL = 0x1010;
444pub const SO_LISTENQLIMIT = 0x1011;
445pub const SO_LISTENQLEN = 0x1012;
446pub const SO_LISTENINCQLEN = 0x1013;
447pub const SO_SETFIB = 0x1014;
448pub const SO_USER_COOKIE = 0x1015;
449pub const SO_PROTOCOL = 0x1016;
450pub const SO_PROTOTYPE = SO_PROTOCOL;
451pub const SO_TS_CLOCK = 0x1017;
452pub const SO_MAX_PACING_RATE = 0x1018;
453pub const SO_DOMAIN = 0x1019;
454
455pub const SOL_SOCKET = 0xffff;
456
457pub const PF_UNSPEC = AF_UNSPEC;
458pub const PF_LOCAL = AF_LOCAL;
459pub const PF_UNIX = PF_LOCAL;
460pub const PF_INET = AF_INET;
461pub const PF_IMPLINK = AF_IMPLINK;
462pub const PF_PUP = AF_PUP;
463pub const PF_CHAOS = AF_CHAOS;
464pub const PF_NETBIOS = AF_NETBIOS;
465pub const PF_ISO = AF_ISO;
466pub const PF_OSI = AF_ISO;
467pub const PF_ECMA = AF_ECMA;
468pub const PF_DATAKIT = AF_DATAKIT;
469pub const PF_CCITT = AF_CCITT;
470pub const PF_DECnet = AF_DECnet;
471pub const PF_DLI = AF_DLI;
472pub const PF_LAT = AF_LAT;
473pub const PF_HYLINK = AF_HYLINK;
474pub const PF_APPLETALK = AF_APPLETALK;
475pub const PF_ROUTE = AF_ROUTE;
476pub const PF_LINK = AF_LINK;
477pub const PF_XTP = pseudo_AF_XTP;
478pub const PF_COIP = AF_COIP;
479pub const PF_CNT = AF_CNT;
480pub const PF_SIP = AF_SIP;
481pub const PF_IPX = AF_IPX;
482pub const PF_RTIP = pseudo_AF_RTIP;
483pub const PF_PIP = psuedo_AF_PIP;
484pub const PF_ISDN = AF_ISDN;
485pub const PF_KEY = pseudo_AF_KEY;
486pub const PF_INET6 = pseudo_AF_INET6;
487pub const PF_NATM = AF_NATM;
488pub const PF_ATM = AF_ATM;
489pub const PF_NETGRAPH = AF_NETGRAPH;
490pub const PF_SLOW = AF_SLOW;
491pub const PF_SCLUSTER = AF_SCLUSTER;
492pub const PF_ARP = AF_ARP;
493pub const PF_BLUETOOTH = AF_BLUETOOTH;
494pub const PF_IEEE80211 = AF_IEEE80211;
495pub const PF_INET_SDP = AF_INET_SDP;
496pub const PF_INET6_SDP = AF_INET6_SDP;
497pub const PF_MAX = AF_MAX;
498
499pub const AF_UNSPEC = 0;
500pub const AF_UNIX = 1;
501pub const AF_LOCAL = AF_UNIX;
502pub const AF_FILE = AF_LOCAL;
503pub const AF_INET = 2;
504pub const AF_IMPLINK = 3;
505pub const AF_PUP = 4;
506pub const AF_CHAOS = 5;
507pub const AF_NETBIOS = 6;
508pub const AF_ISO = 7;
509pub const AF_OSI = AF_ISO;
510pub const AF_ECMA = 8;
511pub const AF_DATAKIT = 9;
512pub const AF_CCITT = 10;
513pub const AF_SNA = 11;
514pub const AF_DECnet = 12;
515pub const AF_DLI = 13;
516pub const AF_LAT = 14;
517pub const AF_HYLINK = 15;
518pub const AF_APPLETALK = 16;
519pub const AF_ROUTE = 17;
520pub const AF_LINK = 18;
521pub const pseudo_AF_XTP = 19;
522pub const AF_COIP = 20;
523pub const AF_CNT = 21;
524pub const pseudo_AF_RTIP = 22;
525pub const AF_IPX = 23;
526pub const AF_SIP = 24;
527pub const pseudo_AF_PIP = 25;
528pub const AF_ISDN = 26;
529pub const AF_E164 = AF_ISDN;
530pub const pseudo_AF_KEY = 27;
531pub const AF_INET6 = 28;
532pub const AF_NATM = 29;
533pub const AF_ATM = 30;
534pub const pseudo_AF_HDRCMPLT = 31;
535pub const AF_NETGRAPH = 32;
536pub const AF_SLOW = 33;
537pub const AF_SCLUSTER = 34;
538pub const AF_ARP = 35;
539pub const AF_BLUETOOTH = 36;
540pub const AF_IEEE80211 = 37;
541pub const AF_INET_SDP = 40;
542pub const AF_INET6_SDP = 42;
543pub const AF_MAX = 42;
544
545pub const DT_UNKNOWN = 0;
546pub const DT_FIFO = 1;
547pub const DT_CHR = 2;
548pub const DT_DIR = 4;
549pub const DT_BLK = 6;
550pub const DT_REG = 8;
551pub const DT_LNK = 10;
552pub const DT_SOCK = 12;
553pub const DT_WHT = 14;
554
555/// add event to kq (implies enable)
556pub const EV_ADD = 0x0001;
557
558/// delete event from kq
559pub const EV_DELETE = 0x0002;
560
561/// enable event
562pub const EV_ENABLE = 0x0004;
563
564/// disable event (not reported)
565pub const EV_DISABLE = 0x0008;
566
567/// only report one occurrence
568pub const EV_ONESHOT = 0x0010;
569
570/// clear event state after reporting
571pub const EV_CLEAR = 0x0020;
572
573/// error, event data contains errno
574pub const EV_ERROR = 0x4000;
575
576/// force immediate event output
577/// ... with or without EV_ERROR
578/// ... use KEVENT_FLAG_ERROR_EVENTS
579/// on syscalls supporting flags
580pub const EV_RECEIPT = 0x0040;
581
582/// disable event after reporting
583pub const EV_DISPATCH = 0x0080;
584
585pub const EVFILT_READ = -1;
586pub const EVFILT_WRITE = -2;
587
588/// attached to aio requests
589pub const EVFILT_AIO = -3;
590
591/// attached to vnodes
592pub const EVFILT_VNODE = -4;
593
594/// attached to struct proc
595pub const EVFILT_PROC = -5;
596
597/// attached to struct proc
598pub const EVFILT_SIGNAL = -6;
599
600/// timers
601pub const EVFILT_TIMER = -7;
602
603/// Process descriptors
604pub const EVFILT_PROCDESC = -8;
605
606/// Filesystem events
607pub const EVFILT_FS = -9;
608
609pub const EVFILT_LIO = -10;
610
611/// User events
612pub const EVFILT_USER = -11;
613
614/// Sendfile events
615pub const EVFILT_SENDFILE = -12;
616
617pub const EVFILT_EMPTY = -13;
618
619/// On input, NOTE_TRIGGER causes the event to be triggered for output.
620pub const NOTE_TRIGGER = 0x01000000;
621
622/// ignore input fflags
623pub const NOTE_FFNOP = 0x00000000;
624
625/// and fflags
626pub const NOTE_FFAND = 0x40000000;
627
628/// or fflags
629pub const NOTE_FFOR = 0x80000000;
630
631/// copy fflags
632pub const NOTE_FFCOPY = 0xc0000000;
633
634/// mask for operations
635pub const NOTE_FFCTRLMASK = 0xc0000000;
636pub const NOTE_FFLAGSMASK = 0x00ffffff;
637
638/// low water mark
639pub const NOTE_LOWAT = 0x00000001;
640
641/// behave like poll()
642pub const NOTE_FILE_POLL = 0x00000002;
643
644/// vnode was removed
645pub const NOTE_DELETE = 0x00000001;
646
647/// data contents changed
648pub const NOTE_WRITE = 0x00000002;
649
650/// size increased
651pub const NOTE_EXTEND = 0x00000004;
652
653/// attributes changed
654pub const NOTE_ATTRIB = 0x00000008;
655
656/// link count changed
657pub const NOTE_LINK = 0x00000010;
658
659/// vnode was renamed
660pub const NOTE_RENAME = 0x00000020;
661
662/// vnode access was revoked
663pub const NOTE_REVOKE = 0x00000040;
664
665/// vnode was opened
666pub const NOTE_OPEN = 0x00000080;
667
668/// file closed, fd did not allow write
669pub const NOTE_CLOSE = 0x00000100;
670
671/// file closed, fd did allow write
672pub const NOTE_CLOSE_WRITE = 0x00000200;
673
674/// file was read
675pub const NOTE_READ = 0x00000400;
676
677/// process exited
678pub const NOTE_EXIT = 0x80000000;
679
680/// process forked
681pub const NOTE_FORK = 0x40000000;
682
683/// process exec'd
684pub const NOTE_EXEC = 0x20000000;
685
686/// mask for signal & exit status
687pub const NOTE_PDATAMASK = 0x000fffff;
688pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK);
689
690/// data is seconds
691pub const NOTE_SECONDS = 0x00000001;
692
693/// data is milliseconds
694pub const NOTE_MSECONDS = 0x00000002;
695
696/// data is microseconds
697pub const NOTE_USECONDS = 0x00000004;
698
699/// data is nanoseconds
700pub const NOTE_NSECONDS = 0x00000008;
701
702/// timeout is absolute
703pub const NOTE_ABSTIME = 0x00000010;
704
705pub const TIOCEXCL = 0x2000740d;
706pub const TIOCNXCL = 0x2000740e;
707pub const TIOCSCTTY = 0x20007461;
708pub const TIOCGPGRP = 0x40047477;
709pub const TIOCSPGRP = 0x80047476;
710pub const TIOCOUTQ = 0x40047473;
711pub const TIOCSTI = 0x80017472;
712pub const TIOCGWINSZ = 0x40087468;
713pub const TIOCSWINSZ = 0x80087467;
714pub const TIOCMGET = 0x4004746a;
715pub const TIOCMBIS = 0x8004746c;
716pub const TIOCMBIC = 0x8004746b;
717pub const TIOCMSET = 0x8004746d;
718pub const FIONREAD = 0x4004667f;
719pub const TIOCCONS = 0x80047462;
720pub const TIOCPKT = 0x80047470;
721pub const FIONBIO = 0x8004667e;
722pub const TIOCNOTTY = 0x20007471;
723pub const TIOCSETD = 0x8004741b;
724pub const TIOCGETD = 0x4004741a;
725pub const TIOCSBRK = 0x2000747b;
726pub const TIOCCBRK = 0x2000747a;
727pub const TIOCGSID = 0x40047463;
728pub const TIOCGPTN = 0x4004740f;
729pub const TIOCSIG = 0x2004745f;
730
731pub fn WEXITSTATUS(s: u32) u8 {
732 return @intCast(u8, (s & 0xff00) >> 8);
733}
734pub fn WTERMSIG(s: u32) u32 {
735 return s & 0x7f;
736}
737pub fn WSTOPSIG(s: u32) u32 {
738 return WEXITSTATUS(s);
739}
740pub fn WIFEXITED(s: u32) bool {
741 return WTERMSIG(s) == 0;
742}
743pub fn WIFSTOPPED(s: u32) bool {
744 return @intCast(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
745}
746pub fn WIFSIGNALED(s: u32) bool {
747 return (s & 0xffff) -% 1 < 0xff;
748}
749
750pub const winsize = extern struct {
751 ws_row: u16,
752 ws_col: u16,
753 ws_xpixel: u16,
754 ws_ypixel: u16,
755};
756
757const NSIG = 32;
758
759pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
760pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
761pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
762
763/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
764pub const Sigaction = extern struct {
765 pub const handler_fn = fn (c_int) callconv(.C) void;
766 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
767
768 /// signal handler
769 handler: extern union {
770 handler: ?handler_fn,
771 sigaction: ?sigaction_fn,
772 },
773
774 /// see signal options
775 flags: c_uint,
776
777 /// signal mask to apply
778 mask: sigset_t,
779};
780
781pub const siginfo_t = extern struct {
782 signo: c_int,
783 errno: c_int,
784 code: c_int,
785 pid: pid_t,
786 uid: uid_t,
787 status: c_int,
788 addr: ?*c_void,
789 value: sigval,
790 reason: extern union {
791 fault: extern struct {
792 trapno: c_int,
793 },
794 timer: extern struct {
795 timerid: c_int,
796 overrun: c_int,
797 },
798 mesgq: extern struct {
799 mqd: c_int,
800 },
801 poll: extern struct {
802 band: c_long,
803 },
804 spare: extern struct {
805 spare1: c_long,
806 spare2: [7]c_int,
807 },
808 },
809};
810
811pub const sigval = extern union {
812 int: c_int,
813 ptr: ?*c_void,
814};
815
816pub const _SIG_WORDS = 4;
817pub const _SIG_MAXSIG = 128;
818
819pub inline fn _SIG_IDX(sig: usize) usize {
820 return sig - 1;
821}
822pub inline fn _SIG_WORD(sig: usize) usize {
823 return_SIG_IDX(sig) >> 5;
824}
825pub inline fn _SIG_BIT(sig: usize) usize {
826 return 1 << (_SIG_IDX(sig) & 31);
827}
828pub inline fn _SIG_VALID(sig: usize) usize {
829 return sig <= _SIG_MAXSIG and sig > 0;
830}
831
832pub const sigset_t = extern struct {
833 __bits: [_SIG_WORDS]u32,
834};
835
836pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** _SIG_WORDS };
837
838pub usingnamespace switch (builtin.target.cpu.arch) {
839 .x86_64 => struct {
840 pub const ucontext_t = extern struct {
841 sigmask: sigset_t,
842 mcontext: mcontext_t,
843 link: ?*ucontext_t,
844 stack: stack_t,
845 flags: c_int,
846 __spare__: [4]c_int,
847 };
848
849 /// XXX x86_64 specific
850 pub const mcontext_t = extern struct {
851 onstack: u64,
852 rdi: u64,
853 rsi: u64,
854 rdx: u64,
855 rcx: u64,
856 r8: u64,
857 r9: u64,
858 rax: u64,
859 rbx: u64,
860 rbp: u64,
861 r10: u64,
862 r11: u64,
863 r12: u64,
864 r13: u64,
865 r14: u64,
866 r15: u64,
867 trapno: u32,
868 fs: u16,
869 gs: u16,
870 addr: u64,
871 flags: u32,
872 es: u16,
873 ds: u16,
874 err: u64,
875 rip: u64,
876 cs: u64,
877 rflags: u64,
878 rsp: u64,
879 ss: u64,
880 };
881 },
882 else => struct {},
883};
884
885pub const E = enum(u16) {
886 /// No error occurred.
887 SUCCESS = 0,
888
889 PERM = 1, // Operation not permitted
890 NOENT = 2, // No such file or directory
891 SRCH = 3, // No such process
892 INTR = 4, // Interrupted system call
893 IO = 5, // Input/output error
894 NXIO = 6, // Device not configured
895 @"2BIG" = 7, // Argument list too long
896 NOEXEC = 8, // Exec format error
897 BADF = 9, // Bad file descriptor
898 CHILD = 10, // No child processes
899 DEADLK = 11, // Resource deadlock avoided
900 // 11 was AGAIN
901 NOMEM = 12, // Cannot allocate memory
902 ACCES = 13, // Permission denied
903 FAULT = 14, // Bad address
904 NOTBLK = 15, // Block device required
905 BUSY = 16, // Device busy
906 EXIST = 17, // File exists
907 XDEV = 18, // Cross-device link
908 NODEV = 19, // Operation not supported by device
909 NOTDIR = 20, // Not a directory
910 ISDIR = 21, // Is a directory
911 INVAL = 22, // Invalid argument
912 NFILE = 23, // Too many open files in system
913 MFILE = 24, // Too many open files
914 NOTTY = 25, // Inappropriate ioctl for device
915 TXTBSY = 26, // Text file busy
916 FBIG = 27, // File too large
917 NOSPC = 28, // No space left on device
918 SPIPE = 29, // Illegal seek
919 ROFS = 30, // Read-only filesystem
920 MLINK = 31, // Too many links
921 PIPE = 32, // Broken pipe
922
923 // math software
924 DOM = 33, // Numerical argument out of domain
925 RANGE = 34, // Result too large
926
927 // non-blocking and interrupt i/o
928
929 /// Resource temporarily unavailable
930 /// This code is also used for `WOULDBLOCK`: operation would block.
931 AGAIN = 35,
932 INPROGRESS = 36, // Operation now in progress
933 ALREADY = 37, // Operation already in progress
934
935 // ipc/network software -- argument errors
936 NOTSOCK = 38, // Socket operation on non-socket
937 DESTADDRREQ = 39, // Destination address required
938 MSGSIZE = 40, // Message too long
939 PROTOTYPE = 41, // Protocol wrong type for socket
940 NOPROTOOPT = 42, // Protocol not available
941 PROTONOSUPPORT = 43, // Protocol not supported
942 SOCKTNOSUPPORT = 44, // Socket type not supported
943 /// Operation not supported
944 /// This code is also used for `NOTSUP`.
945 OPNOTSUPP = 45,
946 PFNOSUPPORT = 46, // Protocol family not supported
947 AFNOSUPPORT = 47, // Address family not supported by protocol family
948 ADDRINUSE = 48, // Address already in use
949 ADDRNOTAVAIL = 49, // Can't assign requested address
950
951 // ipc/network software -- operational errors
952 NETDOWN = 50, // Network is down
953 NETUNREACH = 51, // Network is unreachable
954 NETRESET = 52, // Network dropped connection on reset
955 CONNABORTED = 53, // Software caused connection abort
956 CONNRESET = 54, // Connection reset by peer
957 NOBUFS = 55, // No buffer space available
958 ISCONN = 56, // Socket is already connected
959 NOTCONN = 57, // Socket is not connected
960 SHUTDOWN = 58, // Can't send after socket shutdown
961 TOOMANYREFS = 59, // Too many references: can't splice
962 TIMEDOUT = 60, // Operation timed out
963 CONNREFUSED = 61, // Connection refused
964
965 LOOP = 62, // Too many levels of symbolic links
966 NAMETOOLONG = 63, // File name too long
967
968 // should be rearranged
969 HOSTDOWN = 64, // Host is down
970 HOSTUNREACH = 65, // No route to host
971 NOTEMPTY = 66, // Directory not empty
972
973 // quotas & mush
974 PROCLIM = 67, // Too many processes
975 USERS = 68, // Too many users
976 DQUOT = 69, // Disc quota exceeded
977
978 // Network File System
979 STALE = 70, // Stale NFS file handle
980 REMOTE = 71, // Too many levels of remote in path
981 BADRPC = 72, // RPC struct is bad
982 RPCMISMATCH = 73, // RPC version wrong
983 PROGUNAVAIL = 74, // RPC prog. not avail
984 PROGMISMATCH = 75, // Program version wrong
985 PROCUNAVAIL = 76, // Bad procedure for program
986
987 NOLCK = 77, // No locks available
988 NOSYS = 78, // Function not implemented
989
990 FTYPE = 79, // Inappropriate file type or format
991 AUTH = 80, // Authentication error
992 NEEDAUTH = 81, // Need authenticator
993 IDRM = 82, // Identifier removed
994 NOMSG = 83, // No message of desired type
995 OVERFLOW = 84, // Value too large to be stored in data type
996 CANCELED = 85, // Operation canceled
997 ILSEQ = 86, // Illegal byte sequence
998 NOATTR = 87, // Attribute not found
999
1000 DOOFUS = 88, // Programming error
1001
1002 BADMSG = 89, // Bad message
1003 MULTIHOP = 90, // Multihop attempted
1004 NOLINK = 91, // Link has been severed
1005 PROTO = 92, // Protocol error
1006
1007 NOTCAPABLE = 93, // Capabilities insufficient
1008 CAPMODE = 94, // Not permitted in capability mode
1009 NOTRECOVERABLE = 95, // State not recoverable
1010 OWNERDEAD = 96, // Previous owner died
1011 _,
1012};
1013
1014pub const MINSIGSTKSZ = switch (builtin.target.cpu.arch) {
1015 .i386, .x86_64 => 2048,
1016 .arm, .aarch64 => 4096,
1017 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
1018};
1019pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
1020
1021pub const SS_ONSTACK = 1;
1022pub const SS_DISABLE = 4;
1023
1024pub const stack_t = extern struct {
1025 ss_sp: [*]u8,
1026 ss_size: isize,
1027 ss_flags: i32,
1028};
1029
1030pub const S_IFMT = 0o170000;
1031
1032pub const S_IFIFO = 0o010000;
1033pub const S_IFCHR = 0o020000;
1034pub const S_IFDIR = 0o040000;
1035pub const S_IFBLK = 0o060000;
1036pub const S_IFREG = 0o100000;
1037pub const S_IFLNK = 0o120000;
1038pub const S_IFSOCK = 0o140000;
1039pub const S_IFWHT = 0o160000;
1040
1041pub const S_ISUID = 0o4000;
1042pub const S_ISGID = 0o2000;
1043pub const S_ISVTX = 0o1000;
1044pub const S_IRWXU = 0o700;
1045pub const S_IRUSR = 0o400;
1046pub const S_IWUSR = 0o200;
1047pub const S_IXUSR = 0o100;
1048pub const S_IRWXG = 0o070;
1049pub const S_IRGRP = 0o040;
1050pub const S_IWGRP = 0o020;
1051pub const S_IXGRP = 0o010;
1052pub const S_IRWXO = 0o007;
1053pub const S_IROTH = 0o004;
1054pub const S_IWOTH = 0o002;
1055pub const S_IXOTH = 0o001;
1056
1057pub fn S_ISFIFO(m: u32) bool {
1058 return m & S_IFMT == S_IFIFO;
1059}
1060
1061pub fn S_ISCHR(m: u32) bool {
1062 return m & S_IFMT == S_IFCHR;
1063}
1064
1065pub fn S_ISDIR(m: u32) bool {
1066 return m & S_IFMT == S_IFDIR;
1067}
1068
1069pub fn S_ISBLK(m: u32) bool {
1070 return m & S_IFMT == S_IFBLK;
1071}
1072
1073pub fn S_ISREG(m: u32) bool {
1074 return m & S_IFMT == S_IFREG;
1075}
1076
1077pub fn S_ISLNK(m: u32) bool {
1078 return m & S_IFMT == S_IFLNK;
1079}
1080
1081pub fn S_ISSOCK(m: u32) bool {
1082 return m & S_IFMT == S_IFSOCK;
1083}
1084
1085pub fn S_IWHT(m: u32) bool {
1086 return m & S_IFMT == S_IFWHT;
1087}
1088
1089pub const HOST_NAME_MAX = 255;
1090
1091/// Magic value that specify the use of the current working directory
1092/// to determine the target of relative file paths in the openat() and
1093/// similar syscalls.
1094pub const AT_FDCWD = -100;
1095
1096/// Check access using effective user and group ID
1097pub const AT_EACCESS = 0x0100;
1098
1099/// Do not follow symbolic links
1100pub const AT_SYMLINK_NOFOLLOW = 0x0200;
1101
1102/// Follow symbolic link
1103pub const AT_SYMLINK_FOLLOW = 0x0400;
1104
1105/// Remove directory instead of file
1106pub const AT_REMOVEDIR = 0x0800;
1107
1108pub const addrinfo = extern struct {
1109 flags: i32,
1110 family: i32,
1111 socktype: i32,
1112 protocol: i32,
1113 addrlen: socklen_t,
1114 canonname: ?[*:0]u8,
1115 addr: ?*sockaddr,
1116 next: ?*addrinfo,
1117};
1118
1119/// Fail if not under dirfd
1120pub const AT_BENEATH = 0x1000;
1121
1122/// dummy for IP
1123pub const IPPROTO_IP = 0;
1124
1125/// control message protocol
1126pub const IPPROTO_ICMP = 1;
1127
1128/// tcp
1129pub const IPPROTO_TCP = 6;
1130
1131/// user datagram protocol
1132pub const IPPROTO_UDP = 17;
1133
1134/// IP6 header
1135pub const IPPROTO_IPV6 = 41;
1136
1137/// raw IP packet
1138pub const IPPROTO_RAW = 255;
1139
1140/// IP6 hop-by-hop options
1141pub const IPPROTO_HOPOPTS = 0;
1142
1143/// group mgmt protocol
1144pub const IPPROTO_IGMP = 2;
1145
1146/// gateway^2 (deprecated)
1147pub const IPPROTO_GGP = 3;
1148
1149/// IPv4 encapsulation
1150pub const IPPROTO_IPV4 = 4;
1151
1152/// for compatibility
1153pub const IPPROTO_IPIP = IPPROTO_IPV4;
1154
1155/// Stream protocol II
1156pub const IPPROTO_ST = 7;
1157
1158/// exterior gateway protocol
1159pub const IPPROTO_EGP = 8;
1160
1161/// private interior gateway
1162pub const IPPROTO_PIGP = 9;
1163
1164/// BBN RCC Monitoring
1165pub const IPPROTO_RCCMON = 10;
1166
1167/// network voice protocol
1168pub const IPPROTO_NVPII = 11;
1169
1170/// pup
1171pub const IPPROTO_PUP = 12;
1172
1173/// Argus
1174pub const IPPROTO_ARGUS = 13;
1175
1176/// EMCON
1177pub const IPPROTO_EMCON = 14;
1178
1179/// Cross Net Debugger
1180pub const IPPROTO_XNET = 15;
1181
1182/// Chaos
1183pub const IPPROTO_CHAOS = 16;
1184
1185/// Multiplexing
1186pub const IPPROTO_MUX = 18;
1187
1188/// DCN Measurement Subsystems
1189pub const IPPROTO_MEAS = 19;
1190
1191/// Host Monitoring
1192pub const IPPROTO_HMP = 20;
1193
1194/// Packet Radio Measurement
1195pub const IPPROTO_PRM = 21;
1196
1197/// xns idp
1198pub const IPPROTO_IDP = 22;
1199
1200/// Trunk-1
1201pub const IPPROTO_TRUNK1 = 23;
1202
1203/// Trunk-2
1204pub const IPPROTO_TRUNK2 = 24;
1205
1206/// Leaf-1
1207pub const IPPROTO_LEAF1 = 25;
1208
1209/// Leaf-2
1210pub const IPPROTO_LEAF2 = 26;
1211
1212/// Reliable Data
1213pub const IPPROTO_RDP = 27;
1214
1215/// Reliable Transaction
1216pub const IPPROTO_IRTP = 28;
1217
1218/// tp-4 w/ class negotiation
1219pub const IPPROTO_TP = 29;
1220
1221/// Bulk Data Transfer
1222pub const IPPROTO_BLT = 30;
1223
1224/// Network Services
1225pub const IPPROTO_NSP = 31;
1226
1227/// Merit Internodal
1228pub const IPPROTO_INP = 32;
1229
1230/// Datagram Congestion Control Protocol
1231pub const IPPROTO_DCCP = 33;
1232
1233/// Third Party Connect
1234pub const IPPROTO_3PC = 34;
1235
1236/// InterDomain Policy Routing
1237pub const IPPROTO_IDPR = 35;
1238
1239/// XTP
1240pub const IPPROTO_XTP = 36;
1241
1242/// Datagram Delivery
1243pub const IPPROTO_DDP = 37;
1244
1245/// Control Message Transport
1246pub const IPPROTO_CMTP = 38;
1247
1248/// TP++ Transport
1249pub const IPPROTO_TPXX = 39;
1250
1251/// IL transport protocol
1252pub const IPPROTO_IL = 40;
1253
1254/// Source Demand Routing
1255pub const IPPROTO_SDRP = 42;
1256
1257/// IP6 routing header
1258pub const IPPROTO_ROUTING = 43;
1259
1260/// IP6 fragmentation header
1261pub const IPPROTO_FRAGMENT = 44;
1262
1263/// InterDomain Routing
1264pub const IPPROTO_IDRP = 45;
1265
1266/// resource reservation
1267pub const IPPROTO_RSVP = 46;
1268
1269/// General Routing Encap.
1270pub const IPPROTO_GRE = 47;
1271
1272/// Mobile Host Routing
1273pub const IPPROTO_MHRP = 48;
1274
1275/// BHA
1276pub const IPPROTO_BHA = 49;
1277
1278/// IP6 Encap Sec. Payload
1279pub const IPPROTO_ESP = 50;
1280
1281/// IP6 Auth Header
1282pub const IPPROTO_AH = 51;
1283
1284/// Integ. Net Layer Security
1285pub const IPPROTO_INLSP = 52;
1286
1287/// IP with encryption
1288pub const IPPROTO_SWIPE = 53;
1289
1290/// Next Hop Resolution
1291pub const IPPROTO_NHRP = 54;
1292
1293/// IP Mobility
1294pub const IPPROTO_MOBILE = 55;
1295
1296/// Transport Layer Security
1297pub const IPPROTO_TLSP = 56;
1298
1299/// SKIP
1300pub const IPPROTO_SKIP = 57;
1301
1302/// ICMP6
1303pub const IPPROTO_ICMPV6 = 58;
1304
1305/// IP6 no next header
1306pub const IPPROTO_NONE = 59;
1307
1308/// IP6 destination option
1309pub const IPPROTO_DSTOPTS = 60;
1310
1311/// any host internal protocol
1312pub const IPPROTO_AHIP = 61;
1313
1314/// CFTP
1315pub const IPPROTO_CFTP = 62;
1316
1317/// "hello" routing protocol
1318pub const IPPROTO_HELLO = 63;
1319
1320/// SATNET/Backroom EXPAK
1321pub const IPPROTO_SATEXPAK = 64;
1322
1323/// Kryptolan
1324pub const IPPROTO_KRYPTOLAN = 65;
1325
1326/// Remote Virtual Disk
1327pub const IPPROTO_RVD = 66;
1328
1329/// Pluribus Packet Core
1330pub const IPPROTO_IPPC = 67;
1331
1332/// Any distributed FS
1333pub const IPPROTO_ADFS = 68;
1334
1335/// Satnet Monitoring
1336pub const IPPROTO_SATMON = 69;
1337
1338/// VISA Protocol
1339pub const IPPROTO_VISA = 70;
1340
1341/// Packet Core Utility
1342pub const IPPROTO_IPCV = 71;
1343
1344/// Comp. Prot. Net. Executive
1345pub const IPPROTO_CPNX = 72;
1346
1347/// Comp. Prot. HeartBeat
1348pub const IPPROTO_CPHB = 73;
1349
1350/// Wang Span Network
1351pub const IPPROTO_WSN = 74;
1352
1353/// Packet Video Protocol
1354pub const IPPROTO_PVP = 75;
1355
1356/// BackRoom SATNET Monitoring
1357pub const IPPROTO_BRSATMON = 76;
1358
1359/// Sun net disk proto (temp.)
1360pub const IPPROTO_ND = 77;
1361
1362/// WIDEBAND Monitoring
1363pub const IPPROTO_WBMON = 78;
1364
1365/// WIDEBAND EXPAK
1366pub const IPPROTO_WBEXPAK = 79;
1367
1368/// ISO cnlp
1369pub const IPPROTO_EON = 80;
1370
1371/// VMTP
1372pub const IPPROTO_VMTP = 81;
1373
1374/// Secure VMTP
1375pub const IPPROTO_SVMTP = 82;
1376
1377/// Banyon VINES
1378pub const IPPROTO_VINES = 83;
1379
1380/// TTP
1381pub const IPPROTO_TTP = 84;
1382
1383/// NSFNET-IGP
1384pub const IPPROTO_IGP = 85;
1385
1386/// dissimilar gateway prot.
1387pub const IPPROTO_DGP = 86;
1388
1389/// TCF
1390pub const IPPROTO_TCF = 87;
1391
1392/// Cisco/GXS IGRP
1393pub const IPPROTO_IGRP = 88;
1394
1395/// OSPFIGP
1396pub const IPPROTO_OSPFIGP = 89;
1397
1398/// Strite RPC protocol
1399pub const IPPROTO_SRPC = 90;
1400
1401/// Locus Address Resoloution
1402pub const IPPROTO_LARP = 91;
1403
1404/// Multicast Transport
1405pub const IPPROTO_MTP = 92;
1406
1407/// AX.25 Frames
1408pub const IPPROTO_AX25 = 93;
1409
1410/// IP encapsulated in IP
1411pub const IPPROTO_IPEIP = 94;
1412
1413/// Mobile Int.ing control
1414pub const IPPROTO_MICP = 95;
1415
1416/// Semaphore Comm. security
1417pub const IPPROTO_SCCSP = 96;
1418
1419/// Ethernet IP encapsulation
1420pub const IPPROTO_ETHERIP = 97;
1421
1422/// encapsulation header
1423pub const IPPROTO_ENCAP = 98;
1424
1425/// any private encr. scheme
1426pub const IPPROTO_APES = 99;
1427
1428/// GMTP
1429pub const IPPROTO_GMTP = 100;
1430
1431/// payload compression (IPComp)
1432pub const IPPROTO_IPCOMP = 108;
1433
1434/// SCTP
1435pub const IPPROTO_SCTP = 132;
1436
1437/// IPv6 Mobility Header
1438pub const IPPROTO_MH = 135;
1439
1440/// UDP-Lite
1441pub const IPPROTO_UDPLITE = 136;
1442
1443/// IP6 Host Identity Protocol
1444pub const IPPROTO_HIP = 139;
1445
1446/// IP6 Shim6 Protocol
1447pub const IPPROTO_SHIM6 = 140;
1448
1449/// Protocol Independent Mcast
1450pub const IPPROTO_PIM = 103;
1451
1452/// CARP
1453pub const IPPROTO_CARP = 112;
1454
1455/// PGM
1456pub const IPPROTO_PGM = 113;
1457
1458/// MPLS-in-IP
1459pub const IPPROTO_MPLS = 137;
1460
1461/// PFSYNC
1462pub const IPPROTO_PFSYNC = 240;
1463
1464/// Reserved
1465pub const IPPROTO_RESERVED_253 = 253;
1466
1467/// Reserved
1468pub const IPPROTO_RESERVED_254 = 254;
1469
1470pub const rlimit_resource = enum(c_int) {
1471 CPU = 0,
1472 FSIZE = 1,
1473 DATA = 2,
1474 STACK = 3,
1475 CORE = 4,
1476 RSS = 5,
1477 MEMLOCK = 6,
1478 NPROC = 7,
1479 NOFILE = 8,
1480 SBSIZE = 9,
1481 VMEM = 10,
1482 NPTS = 11,
1483 SWAP = 12,
1484 KQUEUES = 13,
1485 UMTXP = 14,
1486 _,
1487
1488 pub const AS: rlimit_resource = .VMEM;
1489};
1490
1491pub const rlim_t = i64;
1492
1493/// No limit
1494pub const RLIM_INFINITY: rlim_t = (1 << 63) - 1;
1495
1496pub const RLIM_SAVED_MAX = RLIM_INFINITY;
1497pub const RLIM_SAVED_CUR = RLIM_INFINITY;
1498
1499pub const rlimit = extern struct {
1500 /// Soft limit
1501 cur: rlim_t,
1502 /// Hard limit
1503 max: rlim_t,
1504};
1505
1506pub const SHUT_RD = 0;
1507pub const SHUT_WR = 1;
1508pub const SHUT_RDWR = 2;
1509
1510pub const nfds_t = u32;
1511
1512pub const pollfd = extern struct {
1513 fd: fd_t,
1514 events: i16,
1515 revents: i16,
1516};
1517
1518/// any readable data available.
1519pub const POLLIN = 0x0001;
1520/// OOB/Urgent readable data.
1521pub const POLLPRI = 0x0002;
1522/// file descriptor is writeable.
1523pub const POLLOUT = 0x0004;
1524/// non-OOB/URG data available.
1525pub const POLLRDNORM = 0x0040;
1526/// no write type differentiation.
1527pub const POLLWRNORM = POLLOUT;
1528/// OOB/Urgent readable data.
1529pub const POLLRDBAND = 0x0080;
1530/// OOB/Urgent data can be written.
1531pub const POLLWRBAND = 0x0100;
1532/// like POLLIN, except ignore EOF.
1533pub const POLLINIGNEOF = 0x2000;
1534/// some poll error occurred.
1535pub const POLLERR = 0x0008;
1536/// file descriptor was "hung up".
1537pub const POLLHUP = 0x0010;
1538/// requested events "invalid".
1539pub const POLLNVAL = 0x0020;
1540
1541pub const POLLSTANDARD = POLLIN | POLLPRI | POLLOUT | POLLRDNORM | POLLRDBAND |
1542 POLLWRBAND | POLLERR | POLLHUP | POLLNVAL;
lib/std/os/bits/haiku.zig deleted-1375
...@@ -1,1375 +0,0 @@
1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3
4pub usingnamespace @import("posix.zig");
5
6pub const fd_t = c_int;
7pub const pid_t = c_int;
8pub const uid_t = u32;
9pub const gid_t = u32;
10pub const mode_t = c_uint;
11
12pub const socklen_t = u32;
13
14/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
15pub const Kevent = extern struct {
16 ident: usize,
17 filter: i16,
18 flags: u16,
19 fflags: u32,
20 data: i64,
21 udata: usize,
22 // TODO ext
23};
24
25// Modes and flags for dlopen()
26// include/dlfcn.h
27
28pub const POLLIN = 0x0001;
29pub const POLLERR = 0x0004;
30pub const POLLNVAL = 0x1000;
31pub const POLLHUP = 0x0080;
32
33/// Bind function calls lazily.
34pub const RTLD_LAZY = 1;
35
36/// Bind function calls immediately.
37pub const RTLD_NOW = 2;
38
39pub const RTLD_MODEMASK = 0x3;
40
41/// Make symbols globally available.
42pub const RTLD_GLOBAL = 0x100;
43
44/// Opposite of RTLD_GLOBAL, and the default.
45pub const RTLD_LOCAL = 0;
46
47/// Trace loaded objects and exit.
48pub const RTLD_TRACE = 0x200;
49
50/// Do not remove members.
51pub const RTLD_NODELETE = 0x01000;
52
53/// Do not load if not already loaded.
54pub const RTLD_NOLOAD = 0x02000;
55
56pub const dl_phdr_info = extern struct {
57 dlpi_addr: usize,
58 dlpi_name: ?[*:0]const u8,
59 dlpi_phdr: [*]std.elf.Phdr,
60 dlpi_phnum: u16,
61};
62
63pub const Flock = extern struct {
64 l_start: off_t,
65 l_len: off_t,
66 l_pid: pid_t,
67 l_type: i16,
68 l_whence: i16,
69 l_sysid: i32,
70 __unused: [4]u8,
71};
72
73pub const msghdr = extern struct {
74 /// optional address
75 msg_name: ?*sockaddr,
76
77 /// size of address
78 msg_namelen: socklen_t,
79
80 /// scatter/gather array
81 msg_iov: [*]iovec,
82
83 /// # elements in msg_iov
84 msg_iovlen: i32,
85
86 /// ancillary data
87 msg_control: ?*c_void,
88
89 /// ancillary data buffer len
90 msg_controllen: socklen_t,
91
92 /// flags on received message
93 msg_flags: i32,
94};
95
96pub const msghdr_const = extern struct {
97 /// optional address
98 msg_name: ?*const sockaddr,
99
100 /// size of address
101 msg_namelen: socklen_t,
102
103 /// scatter/gather array
104 msg_iov: [*]iovec_const,
105
106 /// # elements in msg_iov
107 msg_iovlen: i32,
108
109 /// ancillary data
110 msg_control: ?*c_void,
111
112 /// ancillary data buffer len
113 msg_controllen: socklen_t,
114
115 /// flags on received message
116 msg_flags: i32,
117};
118
119pub const off_t = i64;
120pub const ino_t = u64;
121
122pub const nfds_t = u32;
123
124pub const pollfd = extern struct {
125 fd: i32,
126 events: i16,
127 revents: i16,
128};
129
130pub const libc_stat = extern struct {
131 dev: i32,
132 ino: u64,
133 mode: u32,
134 nlink: i32,
135 uid: i32,
136 gid: i32,
137 size: i64,
138 rdev: i32,
139 blksize: i32,
140 atim: timespec,
141 mtim: timespec,
142 ctim: timespec,
143 crtim: timespec,
144 st_type: u32,
145 blocks: i64,
146
147 pub fn atime(self: @This()) timespec {
148 return self.atim;
149 }
150 pub fn mtime(self: @This()) timespec {
151 return self.mtim;
152 }
153 pub fn ctime(self: @This()) timespec {
154 return self.ctim;
155 }
156 pub fn crtime(self: @This()) timespec {
157 return self.crtim;
158 }
159};
160
161pub const timespec = extern struct {
162 tv_sec: isize,
163 tv_nsec: isize,
164};
165
166pub const dirent = extern struct {
167 d_dev: i32,
168 d_pdev: i32,
169 d_ino: i64,
170 d_pino: i64,
171 d_reclen: u16,
172 d_name: [256]u8,
173
174 pub fn reclen(self: dirent) u16 {
175 return self.d_reclen;
176 }
177};
178
179pub const image_info = extern struct {
180 id: u32,
181 type: u32,
182 sequence: i32,
183 init_order: i32,
184 init_routine: *c_void,
185 term_routine: *c_void,
186 device: i32,
187 node: i32,
188 name: [1024]u8,
189 text: *c_void,
190 data: *c_void,
191 text_size: i32,
192 data_size: i32,
193 api_version: i32,
194 abi: i32,
195};
196
197pub const system_info = extern struct {
198 boot_time: i64,
199 cpu_count: u32,
200 max_pages: u64,
201 used_pages: u64,
202 cached_pages: u64,
203 block_cache_pages: u64,
204 ignored_pages: u64,
205 needed_memory: u64,
206 free_memory: u64,
207 max_swap_pages: u64,
208 free_swap_pages: u64,
209 page_faults: u32,
210 max_sems: u32,
211 used_sems: u32,
212 max_ports: u32,
213 used_ports: u32,
214 max_threads: u32,
215 used_threads: u32,
216 max_teams: u32,
217 used_teams: u32,
218 kernel_name: [256]u8,
219 kernel_build_date: [32]u8,
220 kernel_build_time: [32]u8,
221 kernel_version: i64,
222 abi: u32,
223};
224
225pub const in_port_t = u16;
226pub const sa_family_t = u8;
227
228pub const sockaddr = extern struct {
229 /// total length
230 len: u8,
231
232 /// address family
233 family: sa_family_t,
234
235 /// actually longer; address value
236 data: [14]u8,
237};
238
239pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
240
241pub const sockaddr_in = extern struct {
242 len: u8 = @sizeOf(sockaddr_in),
243 family: sa_family_t = AF_INET,
244 port: in_port_t,
245 addr: u32,
246 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
247};
248
249pub const sockaddr_in6 = extern struct {
250 len: u8 = @sizeOf(sockaddr_in6),
251 family: sa_family_t = AF_INET6,
252 port: in_port_t,
253 flowinfo: u32,
254 addr: [16]u8,
255 scope_id: u32,
256};
257
258pub const sockaddr_un = extern struct {
259 len: u8 = @sizeOf(sockaddr_un),
260 family: sa_family_t = AF_UNIX,
261 path: [104]u8,
262};
263
264pub const CTL_KERN = 1;
265pub const CTL_DEBUG = 5;
266
267pub const KERN_PROC = 14; // struct: process entries
268pub const KERN_PROC_PATHNAME = 12; // path to executable
269
270pub const PATH_MAX = 1024;
271
272pub const STDIN_FILENO = 0;
273pub const STDOUT_FILENO = 1;
274pub const STDERR_FILENO = 2;
275
276pub const PROT_NONE = 0;
277pub const PROT_READ = 1;
278pub const PROT_WRITE = 2;
279pub const PROT_EXEC = 4;
280
281pub const CLOCK_MONOTONIC = 0;
282pub const CLOCK_REALTIME = -1;
283pub const CLOCK_PROCESS_CPUTIME_ID = -2;
284pub const CLOCK_THREAD_CPUTIME_ID = -3;
285
286pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
287pub const MAP_SHARED = 0x0001;
288pub const MAP_PRIVATE = 0x0002;
289pub const MAP_FIXED = 0x0010;
290pub const MAP_STACK = 0x0400;
291pub const MAP_NOSYNC = 0x0800;
292pub const MAP_ANON = 0x1000;
293pub const MAP_ANONYMOUS = MAP_ANON;
294pub const MAP_FILE = 0;
295
296pub const MAP_GUARD = 0x00002000;
297pub const MAP_EXCL = 0x00004000;
298pub const MAP_NOCORE = 0x00020000;
299pub const MAP_PREFAULT_READ = 0x00040000;
300pub const MAP_32BIT = 0x00080000;
301
302pub const WNOHANG = 0x1;
303pub const WUNTRACED = 0x2;
304pub const WSTOPPED = 0x10;
305pub const WCONTINUED = 0x4;
306pub const WNOWAIT = 0x20;
307pub const WEXITED = 0x08;
308
309pub const SA_ONSTACK = 0x20;
310pub const SA_RESTART = 0x10;
311pub const SA_RESETHAND = 0x04;
312pub const SA_NOCLDSTOP = 0x01;
313pub const SA_NODEFER = 0x08;
314pub const SA_NOCLDWAIT = 0x02;
315pub const SA_SIGINFO = 0x40;
316pub const SA_NOMASK = SA_NODEFER;
317pub const SA_STACK = SA_ONSTACK;
318pub const SA_ONESHOT = SA_RESETHAND;
319
320pub const SIGHUP = 1;
321pub const SIGINT = 2;
322pub const SIGQUIT = 3;
323pub const SIGILL = 4;
324pub const SIGCHLD = 5;
325pub const SIGABRT = 6;
326pub const SIGIOT = SIGABRT;
327pub const SIGPIPE = 7;
328pub const SIGFPE = 8;
329pub const SIGKILL = 9;
330pub const SIGSTOP = 10;
331pub const SIGSEGV = 11;
332pub const SIGCONT = 12;
333pub const SIGTSTP = 13;
334pub const SIGALRM = 14;
335pub const SIGTERM = 15;
336pub const SIGTTIN = 16;
337pub const SIGTTOU = 17;
338pub const SIGUSR1 = 18;
339pub const SIGUSR2 = 19;
340pub const SIGWINCH = 20;
341pub const SIGKILLTHR = 21;
342pub const SIGTRAP = 22;
343pub const SIGPOLL = 23;
344pub const SIGPROF = 24;
345pub const SIGSYS = 25;
346pub const SIGURG = 26;
347pub const SIGVTALRM = 27;
348pub const SIGXCPU = 28;
349pub const SIGXFSZ = 29;
350pub const SIGBUS = 30;
351pub const SIGRESERVED1 = 31;
352pub const SIGRESERVED2 = 32;
353
354// TODO: check
355pub const SIGRTMIN = 65;
356pub const SIGRTMAX = 126;
357
358// access function
359pub const F_OK = 0; // test for existence of file
360pub const X_OK = 1; // test for execute or search permission
361pub const W_OK = 2; // test for write permission
362pub const R_OK = 4; // test for read permission
363
364pub const O_RDONLY = 0x0000;
365pub const O_WRONLY = 0x0001;
366pub const O_RDWR = 0x0002;
367pub const O_ACCMODE = 0x0003;
368
369pub const O_SHLOCK = 0x0010;
370pub const O_EXLOCK = 0x0020;
371
372pub const O_CREAT = 0x0200;
373pub const O_EXCL = 0x0800;
374pub const O_NOCTTY = 0x8000;
375pub const O_TRUNC = 0x0400;
376pub const O_APPEND = 0x0008;
377pub const O_NONBLOCK = 0x0004;
378pub const O_DSYNC = 0o10000;
379pub const O_SYNC = 0x0080;
380pub const O_RSYNC = 0o4010000;
381pub const O_DIRECTORY = 0x20000;
382pub const O_NOFOLLOW = 0x0100;
383pub const O_CLOEXEC = 0x00100000;
384
385pub const O_ASYNC = 0x0040;
386pub const O_DIRECT = 0x00010000;
387pub const O_NOATIME = 0o1000000;
388pub const O_PATH = 0o10000000;
389pub const O_TMPFILE = 0o20200000;
390pub const O_NDELAY = O_NONBLOCK;
391
392pub const F_DUPFD = 0;
393pub const F_GETFD = 1;
394pub const F_SETFD = 2;
395pub const F_GETFL = 3;
396pub const F_SETFL = 4;
397
398pub const F_GETOWN = 5;
399pub const F_SETOWN = 6;
400
401pub const F_GETLK = 11;
402pub const F_SETLK = 12;
403pub const F_SETLKW = 13;
404
405pub const F_RDLCK = 1;
406pub const F_WRLCK = 3;
407pub const F_UNLCK = 2;
408
409pub const LOCK_SH = 1;
410pub const LOCK_EX = 2;
411pub const LOCK_UN = 8;
412pub const LOCK_NB = 4;
413
414pub const F_SETOWN_EX = 15;
415pub const F_GETOWN_EX = 16;
416
417pub const F_GETOWNER_UIDS = 17;
418
419pub const FD_CLOEXEC = 1;
420
421pub const SEEK_SET = 0;
422pub const SEEK_CUR = 1;
423pub const SEEK_END = 2;
424
425pub const SIG_BLOCK = 1;
426pub const SIG_UNBLOCK = 2;
427pub const SIG_SETMASK = 3;
428
429pub const SOCK_STREAM = 1;
430pub const SOCK_DGRAM = 2;
431pub const SOCK_RAW = 3;
432pub const SOCK_RDM = 4;
433pub const SOCK_SEQPACKET = 5;
434
435pub const SOCK_CLOEXEC = 0x10000000;
436pub const SOCK_NONBLOCK = 0x20000000;
437
438pub const SO_DEBUG = 0x00000001;
439pub const SO_ACCEPTCONN = 0x00000002;
440pub const SO_REUSEADDR = 0x00000004;
441pub const SO_KEEPALIVE = 0x00000008;
442pub const SO_DONTROUTE = 0x00000010;
443pub const SO_BROADCAST = 0x00000020;
444pub const SO_USELOOPBACK = 0x00000040;
445pub const SO_LINGER = 0x00000080;
446pub const SO_OOBINLINE = 0x00000100;
447pub const SO_REUSEPORT = 0x00000200;
448pub const SO_TIMESTAMP = 0x00000400;
449pub const SO_NOSIGPIPE = 0x00000800;
450pub const SO_ACCEPTFILTER = 0x00001000;
451pub const SO_BINTIME = 0x00002000;
452pub const SO_NO_OFFLOAD = 0x00004000;
453pub const SO_NO_DDP = 0x00008000;
454pub const SO_REUSEPORT_LB = 0x00010000;
455
456pub const SO_SNDBUF = 0x1001;
457pub const SO_RCVBUF = 0x1002;
458pub const SO_SNDLOWAT = 0x1003;
459pub const SO_RCVLOWAT = 0x1004;
460pub const SO_SNDTIMEO = 0x1005;
461pub const SO_RCVTIMEO = 0x1006;
462pub const SO_ERROR = 0x1007;
463pub const SO_TYPE = 0x1008;
464pub const SO_LABEL = 0x1009;
465pub const SO_PEERLABEL = 0x1010;
466pub const SO_LISTENQLIMIT = 0x1011;
467pub const SO_LISTENQLEN = 0x1012;
468pub const SO_LISTENINCQLEN = 0x1013;
469pub const SO_SETFIB = 0x1014;
470pub const SO_USER_COOKIE = 0x1015;
471pub const SO_PROTOCOL = 0x1016;
472pub const SO_PROTOTYPE = SO_PROTOCOL;
473pub const SO_TS_CLOCK = 0x1017;
474pub const SO_MAX_PACING_RATE = 0x1018;
475pub const SO_DOMAIN = 0x1019;
476
477pub const SOL_SOCKET = 0xffff;
478
479pub const PF_UNSPEC = AF_UNSPEC;
480pub const PF_LOCAL = AF_LOCAL;
481pub const PF_UNIX = PF_LOCAL;
482pub const PF_INET = AF_INET;
483pub const PF_IMPLINK = AF_IMPLINK;
484pub const PF_PUP = AF_PUP;
485pub const PF_CHAOS = AF_CHAOS;
486pub const PF_NETBIOS = AF_NETBIOS;
487pub const PF_ISO = AF_ISO;
488pub const PF_OSI = AF_ISO;
489pub const PF_ECMA = AF_ECMA;
490pub const PF_DATAKIT = AF_DATAKIT;
491pub const PF_CCITT = AF_CCITT;
492pub const PF_DECnet = AF_DECnet;
493pub const PF_DLI = AF_DLI;
494pub const PF_LAT = AF_LAT;
495pub const PF_HYLINK = AF_HYLINK;
496pub const PF_APPLETALK = AF_APPLETALK;
497pub const PF_ROUTE = AF_ROUTE;
498pub const PF_LINK = AF_LINK;
499pub const PF_XTP = pseudo_AF_XTP;
500pub const PF_COIP = AF_COIP;
501pub const PF_CNT = AF_CNT;
502pub const PF_SIP = AF_SIP;
503pub const PF_IPX = AF_IPX;
504pub const PF_RTIP = pseudo_AF_RTIP;
505pub const PF_PIP = psuedo_AF_PIP;
506pub const PF_ISDN = AF_ISDN;
507pub const PF_KEY = pseudo_AF_KEY;
508pub const PF_INET6 = pseudo_AF_INET6;
509pub const PF_NATM = AF_NATM;
510pub const PF_ATM = AF_ATM;
511pub const PF_NETGRAPH = AF_NETGRAPH;
512pub const PF_SLOW = AF_SLOW;
513pub const PF_SCLUSTER = AF_SCLUSTER;
514pub const PF_ARP = AF_ARP;
515pub const PF_BLUETOOTH = AF_BLUETOOTH;
516pub const PF_IEEE80211 = AF_IEEE80211;
517pub const PF_INET_SDP = AF_INET_SDP;
518pub const PF_INET6_SDP = AF_INET6_SDP;
519pub const PF_MAX = AF_MAX;
520
521pub const AF_UNSPEC = 0;
522pub const AF_UNIX = 1;
523pub const AF_LOCAL = AF_UNIX;
524pub const AF_FILE = AF_LOCAL;
525pub const AF_INET = 2;
526pub const AF_IMPLINK = 3;
527pub const AF_PUP = 4;
528pub const AF_CHAOS = 5;
529pub const AF_NETBIOS = 6;
530pub const AF_ISO = 7;
531pub const AF_OSI = AF_ISO;
532pub const AF_ECMA = 8;
533pub const AF_DATAKIT = 9;
534pub const AF_CCITT = 10;
535pub const AF_SNA = 11;
536pub const AF_DECnet = 12;
537pub const AF_DLI = 13;
538pub const AF_LAT = 14;
539pub const AF_HYLINK = 15;
540pub const AF_APPLETALK = 16;
541pub const AF_ROUTE = 17;
542pub const AF_LINK = 18;
543pub const pseudo_AF_XTP = 19;
544pub const AF_COIP = 20;
545pub const AF_CNT = 21;
546pub const pseudo_AF_RTIP = 22;
547pub const AF_IPX = 23;
548pub const AF_SIP = 24;
549pub const pseudo_AF_PIP = 25;
550pub const AF_ISDN = 26;
551pub const AF_E164 = AF_ISDN;
552pub const pseudo_AF_KEY = 27;
553pub const AF_INET6 = 28;
554pub const AF_NATM = 29;
555pub const AF_ATM = 30;
556pub const pseudo_AF_HDRCMPLT = 31;
557pub const AF_NETGRAPH = 32;
558pub const AF_SLOW = 33;
559pub const AF_SCLUSTER = 34;
560pub const AF_ARP = 35;
561pub const AF_BLUETOOTH = 36;
562pub const AF_IEEE80211 = 37;
563pub const AF_INET_SDP = 40;
564pub const AF_INET6_SDP = 42;
565pub const AF_MAX = 42;
566
567pub const DT_UNKNOWN = 0;
568pub const DT_FIFO = 1;
569pub const DT_CHR = 2;
570pub const DT_DIR = 4;
571pub const DT_BLK = 6;
572pub const DT_REG = 8;
573pub const DT_LNK = 10;
574pub const DT_SOCK = 12;
575pub const DT_WHT = 14;
576
577/// add event to kq (implies enable)
578pub const EV_ADD = 0x0001;
579
580/// delete event from kq
581pub const EV_DELETE = 0x0002;
582
583/// enable event
584pub const EV_ENABLE = 0x0004;
585
586/// disable event (not reported)
587pub const EV_DISABLE = 0x0008;
588
589/// only report one occurrence
590pub const EV_ONESHOT = 0x0010;
591
592/// clear event state after reporting
593pub const EV_CLEAR = 0x0020;
594
595/// force immediate event output
596/// ... with or without EV_ERROR
597/// ... use KEVENT_FLAG_ERROR_EVENTS
598/// on syscalls supporting flags
599pub const EV_RECEIPT = 0x0040;
600
601/// disable event after reporting
602pub const EV_DISPATCH = 0x0080;
603
604pub const EVFILT_READ = -1;
605pub const EVFILT_WRITE = -2;
606
607/// attached to aio requests
608pub const EVFILT_AIO = -3;
609
610/// attached to vnodes
611pub const EVFILT_VNODE = -4;
612
613/// attached to struct proc
614pub const EVFILT_PROC = -5;
615
616/// attached to struct proc
617pub const EVFILT_SIGNAL = -6;
618
619/// timers
620pub const EVFILT_TIMER = -7;
621
622/// Process descriptors
623pub const EVFILT_PROCDESC = -8;
624
625/// Filesystem events
626pub const EVFILT_FS = -9;
627
628pub const EVFILT_LIO = -10;
629
630/// User events
631pub const EVFILT_USER = -11;
632
633/// Sendfile events
634pub const EVFILT_SENDFILE = -12;
635
636pub const EVFILT_EMPTY = -13;
637
638pub const TCGETA = 0x8000;
639pub const TCSETA = 0x8001;
640pub const TCSETAW = 0x8004;
641pub const TCSETAF = 0x8003;
642pub const TCSBRK = 08005;
643pub const TCXONC = 0x8007;
644pub const TCFLSH = 0x8006;
645
646pub const TIOCSCTTY = 0x8017;
647pub const TIOCGPGRP = 0x8015;
648pub const TIOCSPGRP = 0x8016;
649pub const TIOCGWINSZ = 0x8012;
650pub const TIOCSWINSZ = 0x8013;
651pub const TIOCMGET = 0x8018;
652pub const TIOCMBIS = 0x8022;
653pub const TIOCMBIC = 0x8023;
654pub const TIOCMSET = 0x8019;
655pub const FIONREAD = 0xbe000001;
656pub const FIONBIO = 0xbe000000;
657pub const TIOCSBRK = 0x8020;
658pub const TIOCCBRK = 0x8021;
659pub const TIOCGSID = 0x8024;
660
661pub fn WEXITSTATUS(s: u32) u8 {
662 return @intCast(u8, s & 0xff);
663}
664
665pub fn WTERMSIG(s: u32) u32 {
666 return (s >> 8) & 0xff;
667}
668
669pub fn WSTOPSIG(s: u32) u32 {
670 return WEXITSTATUS(s);
671}
672
673pub fn WIFEXITED(s: u32) bool {
674 return WTERMSIG(s) == 0;
675}
676
677pub fn WIFSTOPPED(s: u32) bool {
678 return ((s >> 16) & 0xff) != 0;
679}
680
681pub fn WIFSIGNALED(s: u32) bool {
682 return ((s >> 8) & 0xff) != 0;
683}
684
685pub const winsize = extern struct {
686 ws_row: u16,
687 ws_col: u16,
688 ws_xpixel: u16,
689 ws_ypixel: u16,
690};
691
692const NSIG = 32;
693
694pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
695pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
696pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
697
698/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
699pub const Sigaction = extern struct {
700 /// signal handler
701 __sigaction_u: extern union {
702 __sa_handler: fn (i32) callconv(.C) void,
703 __sa_sigaction: fn (i32, *__siginfo, usize) callconv(.C) void,
704 },
705
706 /// see signal options
707 sa_flags: u32,
708
709 /// signal mask to apply
710 sa_mask: sigset_t,
711};
712
713pub const _SIG_WORDS = 4;
714pub const _SIG_MAXSIG = 128;
715pub inline fn _SIG_IDX(sig: usize) usize {
716 return sig - 1;
717}
718pub inline fn _SIG_WORD(sig: usize) usize {
719 return_SIG_IDX(sig) >> 5;
720}
721pub inline fn _SIG_BIT(sig: usize) usize {
722 return 1 << (_SIG_IDX(sig) & 31);
723}
724pub inline fn _SIG_VALID(sig: usize) usize {
725 return sig <= _SIG_MAXSIG and sig > 0;
726}
727
728pub const sigset_t = extern struct {
729 __bits: [_SIG_WORDS]u32,
730};
731
732pub const E = enum(i32) {
733 /// No error occurred.
734 SUCCESS = 0,
735 PERM = -0x7ffffff1, // Operation not permitted
736 NOENT = -0x7fff9ffd, // No such file or directory
737 SRCH = -0x7fff8ff3, // No such process
738 INTR = -0x7ffffff6, // Interrupted system call
739 IO = -0x7fffffff, // Input/output error
740 NXIO = -0x7fff8ff5, // Device not configured
741 @"2BIG" = -0x7fff8fff, // Argument list too long
742 NOEXEC = -0x7fffecfe, // Exec format error
743 CHILD = -0x7fff8ffe, // No child processes
744 DEADLK = -0x7fff8ffd, // Resource deadlock avoided
745 NOMEM = -0x80000000, // Cannot allocate memory
746 ACCES = -0x7ffffffe, // Permission denied
747 FAULT = -0x7fffecff, // Bad address
748 BUSY = -0x7ffffff2, // Device busy
749 EXIST = -0x7fff9ffe, // File exists
750 XDEV = -0x7fff9ff5, // Cross-device link
751 NODEV = -0x7fff8ff9, // Operation not supported by device
752 NOTDIR = -0x7fff9ffb, // Not a directory
753 ISDIR = -0x7fff9ff7, // Is a directory
754 INVAL = -0x7ffffffb, // Invalid argument
755 NFILE = -0x7fff8ffa, // Too many open files in system
756 MFILE = -0x7fff9ff6, // Too many open files
757 NOTTY = -0x7fff8ff6, // Inappropriate ioctl for device
758 TXTBSY = -0x7fff8fc5, // Text file busy
759 FBIG = -0x7fff8ffc, // File too large
760 NOSPC = -0x7fff9ff9, // No space left on device
761 SPIPE = -0x7fff8ff4, // Illegal seek
762 ROFS = -0x7fff9ff8, // Read-only filesystem
763 MLINK = -0x7fff8ffb, // Too many links
764 PIPE = -0x7fff9ff3, // Broken pipe
765 BADF = -0x7fffa000, // Bad file descriptor
766
767 // math software
768 DOM = 33, // Numerical argument out of domain
769 RANGE = 34, // Result too large
770
771 // non-blocking and interrupt i/o
772
773 /// Also used for `WOULDBLOCK`.
774 AGAIN = -0x7ffffff5,
775 INPROGRESS = -0x7fff8fdc,
776 ALREADY = -0x7fff8fdb,
777
778 // ipc/network software -- argument errors
779 NOTSOCK = 38, // Socket operation on non-socket
780 DESTADDRREQ = 39, // Destination address required
781 MSGSIZE = 40, // Message too long
782 PROTOTYPE = 41, // Protocol wrong type for socket
783 NOPROTOOPT = 42, // Protocol not available
784 PROTONOSUPPORT = 43, // Protocol not supported
785 SOCKTNOSUPPORT = 44, // Socket type not supported
786 /// Also used for `NOTSUP`.
787 OPNOTSUPP = 45, // Operation not supported
788 PFNOSUPPORT = 46, // Protocol family not supported
789 AFNOSUPPORT = 47, // Address family not supported by protocol family
790 ADDRINUSE = 48, // Address already in use
791 ADDRNOTAVAIL = 49, // Can't assign requested address
792
793 // ipc/network software -- operational errors
794 NETDOWN = 50, // Network is down
795 NETUNREACH = 51, // Network is unreachable
796 NETRESET = 52, // Network dropped connection on reset
797 CONNABORTED = 53, // Software caused connection abort
798 CONNRESET = 54, // Connection reset by peer
799 NOBUFS = 55, // No buffer space available
800 ISCONN = 56, // Socket is already connected
801 NOTCONN = 57, // Socket is not connected
802 SHUTDOWN = 58, // Can't send after socket shutdown
803 TOOMANYREFS = 59, // Too many references: can't splice
804 TIMEDOUT = 60, // Operation timed out
805 CONNREFUSED = 61, // Connection refused
806
807 LOOP = 62, // Too many levels of symbolic links
808 NAMETOOLONG = 63, // File name too long
809
810 // should be rearranged
811 HOSTDOWN = 64, // Host is down
812 HOSTUNREACH = 65, // No route to host
813 NOTEMPTY = 66, // Directory not empty
814
815 // quotas & mush
816 PROCLIM = 67, // Too many processes
817 USERS = 68, // Too many users
818 DQUOT = 69, // Disc quota exceeded
819
820 // Network File System
821 STALE = 70, // Stale NFS file handle
822 REMOTE = 71, // Too many levels of remote in path
823 BADRPC = 72, // RPC struct is bad
824 RPCMISMATCH = 73, // RPC version wrong
825 PROGUNAVAIL = 74, // RPC prog. not avail
826 PROGMISMATCH = 75, // Program version wrong
827 PROCUNAVAIL = 76, // Bad procedure for program
828
829 NOLCK = 77, // No locks available
830 NOSYS = 78, // Function not implemented
831
832 FTYPE = 79, // Inappropriate file type or format
833 AUTH = 80, // Authentication error
834 NEEDAUTH = 81, // Need authenticator
835 IDRM = 82, // Identifier removed
836 NOMSG = 83, // No message of desired type
837 OVERFLOW = 84, // Value too large to be stored in data type
838 CANCELED = 85, // Operation canceled
839 ILSEQ = 86, // Illegal byte sequence
840 NOATTR = 87, // Attribute not found
841
842 DOOFUS = 88, // Programming error
843
844 BADMSG = 89, // Bad message
845 MULTIHOP = 90, // Multihop attempted
846 NOLINK = 91, // Link has been severed
847 PROTO = 92, // Protocol error
848
849 NOTCAPABLE = 93, // Capabilities insufficient
850 CAPMODE = 94, // Not permitted in capability mode
851 NOTRECOVERABLE = 95, // State not recoverable
852 OWNERDEAD = 96, // Previous owner died
853
854 _,
855};
856
857pub const MINSIGSTKSZ = switch (builtin.cpu.arch) {
858 .i386, .x86_64 => 2048,
859 .arm, .aarch64 => 4096,
860 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
861};
862pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
863
864pub const SS_ONSTACK = 1;
865pub const SS_DISABLE = 4;
866
867pub const stack_t = extern struct {
868 ss_sp: [*]u8,
869 ss_size: isize,
870 ss_flags: i32,
871};
872
873pub const S_IFMT = 0o170000;
874
875pub const S_IFIFO = 0o010000;
876pub const S_IFCHR = 0o020000;
877pub const S_IFDIR = 0o040000;
878pub const S_IFBLK = 0o060000;
879pub const S_IFREG = 0o100000;
880pub const S_IFLNK = 0o120000;
881pub const S_IFSOCK = 0o140000;
882pub const S_IFWHT = 0o160000;
883
884pub const S_ISUID = 0o4000;
885pub const S_ISGID = 0o2000;
886pub const S_ISVTX = 0o1000;
887pub const S_IRWXU = 0o700;
888pub const S_IRUSR = 0o400;
889pub const S_IWUSR = 0o200;
890pub const S_IXUSR = 0o100;
891pub const S_IRWXG = 0o070;
892pub const S_IRGRP = 0o040;
893pub const S_IWGRP = 0o020;
894pub const S_IXGRP = 0o010;
895pub const S_IRWXO = 0o007;
896pub const S_IROTH = 0o004;
897pub const S_IWOTH = 0o002;
898pub const S_IXOTH = 0o001;
899
900pub fn S_ISFIFO(m: u32) bool {
901 return m & S_IFMT == S_IFIFO;
902}
903
904pub fn S_ISCHR(m: u32) bool {
905 return m & S_IFMT == S_IFCHR;
906}
907
908pub fn S_ISDIR(m: u32) bool {
909 return m & S_IFMT == S_IFDIR;
910}
911
912pub fn S_ISBLK(m: u32) bool {
913 return m & S_IFMT == S_IFBLK;
914}
915
916pub fn S_ISREG(m: u32) bool {
917 return m & S_IFMT == S_IFREG;
918}
919
920pub fn S_ISLNK(m: u32) bool {
921 return m & S_IFMT == S_IFLNK;
922}
923
924pub fn S_ISSOCK(m: u32) bool {
925 return m & S_IFMT == S_IFSOCK;
926}
927
928pub fn S_IWHT(m: u32) bool {
929 return m & S_IFMT == S_IFWHT;
930}
931
932pub const HOST_NAME_MAX = 255;
933
934/// Magic value that specify the use of the current working directory
935/// to determine the target of relative file paths in the openat() and
936/// similar syscalls.
937pub const AT_FDCWD = -100;
938
939/// Check access using effective user and group ID
940pub const AT_EACCESS = 0x0100;
941
942/// Do not follow symbolic links
943pub const AT_SYMLINK_NOFOLLOW = 0x0200;
944
945/// Follow symbolic link
946pub const AT_SYMLINK_FOLLOW = 0x0400;
947
948/// Remove directory instead of file
949pub const AT_REMOVEDIR = 0x0800;
950
951pub const addrinfo = extern struct {
952 flags: i32,
953 family: i32,
954 socktype: i32,
955 protocol: i32,
956 addrlen: socklen_t,
957 canonname: ?[*:0]u8,
958 addr: ?*sockaddr,
959 next: ?*addrinfo,
960};
961
962/// Fail if not under dirfd
963pub const AT_BENEATH = 0x1000;
964
965/// dummy for IP
966pub const IPPROTO_IP = 0;
967
968/// control message protocol
969pub const IPPROTO_ICMP = 1;
970
971/// tcp
972pub const IPPROTO_TCP = 6;
973
974/// user datagram protocol
975pub const IPPROTO_UDP = 17;
976
977/// IP6 header
978pub const IPPROTO_IPV6 = 41;
979
980/// raw IP packet
981pub const IPPROTO_RAW = 255;
982
983/// IP6 hop-by-hop options
984pub const IPPROTO_HOPOPTS = 0;
985
986/// group mgmt protocol
987pub const IPPROTO_IGMP = 2;
988
989/// gateway^2 (deprecated)
990pub const IPPROTO_GGP = 3;
991
992/// IPv4 encapsulation
993pub const IPPROTO_IPV4 = 4;
994
995/// for compatibility
996pub const IPPROTO_IPIP = IPPROTO_IPV4;
997
998/// Stream protocol II
999pub const IPPROTO_ST = 7;
1000
1001/// exterior gateway protocol
1002pub const IPPROTO_EGP = 8;
1003
1004/// private interior gateway
1005pub const IPPROTO_PIGP = 9;
1006
1007/// BBN RCC Monitoring
1008pub const IPPROTO_RCCMON = 10;
1009
1010/// network voice protocol
1011pub const IPPROTO_NVPII = 11;
1012
1013/// pup
1014pub const IPPROTO_PUP = 12;
1015
1016/// Argus
1017pub const IPPROTO_ARGUS = 13;
1018
1019/// EMCON
1020pub const IPPROTO_EMCON = 14;
1021
1022/// Cross Net Debugger
1023pub const IPPROTO_XNET = 15;
1024
1025/// Chaos
1026pub const IPPROTO_CHAOS = 16;
1027
1028/// Multiplexing
1029pub const IPPROTO_MUX = 18;
1030
1031/// DCN Measurement Subsystems
1032pub const IPPROTO_MEAS = 19;
1033
1034/// Host Monitoring
1035pub const IPPROTO_HMP = 20;
1036
1037/// Packet Radio Measurement
1038pub const IPPROTO_PRM = 21;
1039
1040/// xns idp
1041pub const IPPROTO_IDP = 22;
1042
1043/// Trunk-1
1044pub const IPPROTO_TRUNK1 = 23;
1045
1046/// Trunk-2
1047pub const IPPROTO_TRUNK2 = 24;
1048
1049/// Leaf-1
1050pub const IPPROTO_LEAF1 = 25;
1051
1052/// Leaf-2
1053pub const IPPROTO_LEAF2 = 26;
1054
1055/// Reliable Data
1056pub const IPPROTO_RDP = 27;
1057
1058/// Reliable Transaction
1059pub const IPPROTO_IRTP = 28;
1060
1061/// tp-4 w/ class negotiation
1062pub const IPPROTO_TP = 29;
1063
1064/// Bulk Data Transfer
1065pub const IPPROTO_BLT = 30;
1066
1067/// Network Services
1068pub const IPPROTO_NSP = 31;
1069
1070/// Merit Internodal
1071pub const IPPROTO_INP = 32;
1072
1073/// Datagram Congestion Control Protocol
1074pub const IPPROTO_DCCP = 33;
1075
1076/// Third Party Connect
1077pub const IPPROTO_3PC = 34;
1078
1079/// InterDomain Policy Routing
1080pub const IPPROTO_IDPR = 35;
1081
1082/// XTP
1083pub const IPPROTO_XTP = 36;
1084
1085/// Datagram Delivery
1086pub const IPPROTO_DDP = 37;
1087
1088/// Control Message Transport
1089pub const IPPROTO_CMTP = 38;
1090
1091/// TP++ Transport
1092pub const IPPROTO_TPXX = 39;
1093
1094/// IL transport protocol
1095pub const IPPROTO_IL = 40;
1096
1097/// Source Demand Routing
1098pub const IPPROTO_SDRP = 42;
1099
1100/// IP6 routing header
1101pub const IPPROTO_ROUTING = 43;
1102
1103/// IP6 fragmentation header
1104pub const IPPROTO_FRAGMENT = 44;
1105
1106/// InterDomain Routing
1107pub const IPPROTO_IDRP = 45;
1108
1109/// resource reservation
1110pub const IPPROTO_RSVP = 46;
1111
1112/// General Routing Encap.
1113pub const IPPROTO_GRE = 47;
1114
1115/// Mobile Host Routing
1116pub const IPPROTO_MHRP = 48;
1117
1118/// BHA
1119pub const IPPROTO_BHA = 49;
1120
1121/// IP6 Encap Sec. Payload
1122pub const IPPROTO_ESP = 50;
1123
1124/// IP6 Auth Header
1125pub const IPPROTO_AH = 51;
1126
1127/// Integ. Net Layer Security
1128pub const IPPROTO_INLSP = 52;
1129
1130/// IP with encryption
1131pub const IPPROTO_SWIPE = 53;
1132
1133/// Next Hop Resolution
1134pub const IPPROTO_NHRP = 54;
1135
1136/// IP Mobility
1137pub const IPPROTO_MOBILE = 55;
1138
1139/// Transport Layer Security
1140pub const IPPROTO_TLSP = 56;
1141
1142/// SKIP
1143pub const IPPROTO_SKIP = 57;
1144
1145/// ICMP6
1146pub const IPPROTO_ICMPV6 = 58;
1147
1148/// IP6 no next header
1149pub const IPPROTO_NONE = 59;
1150
1151/// IP6 destination option
1152pub const IPPROTO_DSTOPTS = 60;
1153
1154/// any host internal protocol
1155pub const IPPROTO_AHIP = 61;
1156
1157/// CFTP
1158pub const IPPROTO_CFTP = 62;
1159
1160/// "hello" routing protocol
1161pub const IPPROTO_HELLO = 63;
1162
1163/// SATNET/Backroom EXPAK
1164pub const IPPROTO_SATEXPAK = 64;
1165
1166/// Kryptolan
1167pub const IPPROTO_KRYPTOLAN = 65;
1168
1169/// Remote Virtual Disk
1170pub const IPPROTO_RVD = 66;
1171
1172/// Pluribus Packet Core
1173pub const IPPROTO_IPPC = 67;
1174
1175/// Any distributed FS
1176pub const IPPROTO_ADFS = 68;
1177
1178/// Satnet Monitoring
1179pub const IPPROTO_SATMON = 69;
1180
1181/// VISA Protocol
1182pub const IPPROTO_VISA = 70;
1183
1184/// Packet Core Utility
1185pub const IPPROTO_IPCV = 71;
1186
1187/// Comp. Prot. Net. Executive
1188pub const IPPROTO_CPNX = 72;
1189
1190/// Comp. Prot. HeartBeat
1191pub const IPPROTO_CPHB = 73;
1192
1193/// Wang Span Network
1194pub const IPPROTO_WSN = 74;
1195
1196/// Packet Video Protocol
1197pub const IPPROTO_PVP = 75;
1198
1199/// BackRoom SATNET Monitoring
1200pub const IPPROTO_BRSATMON = 76;
1201
1202/// Sun net disk proto (temp.)
1203pub const IPPROTO_ND = 77;
1204
1205/// WIDEBAND Monitoring
1206pub const IPPROTO_WBMON = 78;
1207
1208/// WIDEBAND EXPAK
1209pub const IPPROTO_WBEXPAK = 79;
1210
1211/// ISO cnlp
1212pub const IPPROTO_EON = 80;
1213
1214/// VMTP
1215pub const IPPROTO_VMTP = 81;
1216
1217/// Secure VMTP
1218pub const IPPROTO_SVMTP = 82;
1219
1220/// Banyon VINES
1221pub const IPPROTO_VINES = 83;
1222
1223/// TTP
1224pub const IPPROTO_TTP = 84;
1225
1226/// NSFNET-IGP
1227pub const IPPROTO_IGP = 85;
1228
1229/// dissimilar gateway prot.
1230pub const IPPROTO_DGP = 86;
1231
1232/// TCF
1233pub const IPPROTO_TCF = 87;
1234
1235/// Cisco/GXS IGRP
1236pub const IPPROTO_IGRP = 88;
1237
1238/// OSPFIGP
1239pub const IPPROTO_OSPFIGP = 89;
1240
1241/// Strite RPC protocol
1242pub const IPPROTO_SRPC = 90;
1243
1244/// Locus Address Resoloution
1245pub const IPPROTO_LARP = 91;
1246
1247/// Multicast Transport
1248pub const IPPROTO_MTP = 92;
1249
1250/// AX.25 Frames
1251pub const IPPROTO_AX25 = 93;
1252
1253/// IP encapsulated in IP
1254pub const IPPROTO_IPEIP = 94;
1255
1256/// Mobile Int.ing control
1257pub const IPPROTO_MICP = 95;
1258
1259/// Semaphore Comm. security
1260pub const IPPROTO_SCCSP = 96;
1261
1262/// Ethernet IP encapsulation
1263pub const IPPROTO_ETHERIP = 97;
1264
1265/// encapsulation header
1266pub const IPPROTO_ENCAP = 98;
1267
1268/// any private encr. scheme
1269pub const IPPROTO_APES = 99;
1270
1271/// GMTP
1272pub const IPPROTO_GMTP = 100;
1273
1274/// payload compression (IPComp)
1275pub const IPPROTO_IPCOMP = 108;
1276
1277/// SCTP
1278pub const IPPROTO_SCTP = 132;
1279
1280/// IPv6 Mobility Header
1281pub const IPPROTO_MH = 135;
1282
1283/// UDP-Lite
1284pub const IPPROTO_UDPLITE = 136;
1285
1286/// IP6 Host Identity Protocol
1287pub const IPPROTO_HIP = 139;
1288
1289/// IP6 Shim6 Protocol
1290pub const IPPROTO_SHIM6 = 140;
1291
1292/// Protocol Independent Mcast
1293pub const IPPROTO_PIM = 103;
1294
1295/// CARP
1296pub const IPPROTO_CARP = 112;
1297
1298/// PGM
1299pub const IPPROTO_PGM = 113;
1300
1301/// MPLS-in-IP
1302pub const IPPROTO_MPLS = 137;
1303
1304/// PFSYNC
1305pub const IPPROTO_PFSYNC = 240;
1306
1307/// Reserved
1308pub const IPPROTO_RESERVED_253 = 253;
1309
1310/// Reserved
1311pub const IPPROTO_RESERVED_254 = 254;
1312
1313pub const rlimit_resource = enum(c_int) {
1314 CPU = 0,
1315 FSIZE = 1,
1316 DATA = 2,
1317 STACK = 3,
1318 CORE = 4,
1319 RSS = 5,
1320 MEMLOCK = 6,
1321 NPROC = 7,
1322 NOFILE = 8,
1323 SBSIZE = 9,
1324 VMEM = 10,
1325 NPTS = 11,
1326 SWAP = 12,
1327 KQUEUES = 13,
1328 UMTXP = 14,
1329 _,
1330
1331 pub const AS: rlimit_resource = .VMEM;
1332};
1333
1334pub const rlim_t = i64;
1335
1336/// No limit
1337pub const RLIM_INFINITY: rlim_t = (1 << 63) - 1;
1338
1339pub const RLIM_SAVED_MAX = RLIM_INFINITY;
1340pub const RLIM_SAVED_CUR = RLIM_INFINITY;
1341
1342pub const rlimit = extern struct {
1343 /// Soft limit
1344 cur: rlim_t,
1345 /// Hard limit
1346 max: rlim_t,
1347};
1348
1349pub const SHUT_RD = 0;
1350pub const SHUT_WR = 1;
1351pub const SHUT_RDWR = 2;
1352
1353// TODO fill out if needed
1354pub const directory_which = enum(c_int) {
1355 B_USER_SETTINGS_DIRECTORY = 0xbbe,
1356
1357 _,
1358};
1359
1360pub const cc_t = u8;
1361pub const speed_t = u8;
1362pub const tcflag_t = u32;
1363
1364pub const NCCS = 32;
1365
1366pub const termios = extern struct {
1367 c_iflag: tcflag_t,
1368 c_oflag: tcflag_t,
1369 c_cflag: tcflag_t,
1370 c_lflag: tcflag_t,
1371 c_line: cc_t,
1372 c_ispeed: speed_t,
1373 c_ospeed: speed_t,
1374 cc_t: [NCCS]cc_t,
1375};
lib/std/os/bits/linux.zig deleted-2455
...@@ -1,2455 +0,0 @@
1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const arch = @import("builtin").target.cpu.arch;
4pub usingnamespace @import("posix.zig");
5
6pub const E = switch (arch) {
7 .mips, .mipsel => @import("linux/errno/mips.zig").E,
8 .sparc, .sparcel, .sparcv9 => @import("linux/errno/sparc.zig").E,
9 else => @import("linux/errno/generic.zig").E,
10};
11
12pub usingnamespace switch (arch) {
13 .i386 => @import("linux/i386.zig"),
14 .x86_64 => @import("linux/x86_64.zig"),
15 .aarch64 => @import("linux/arm64.zig"),
16 .arm, .thumb => @import("linux/arm-eabi.zig"),
17 .riscv64 => @import("linux/riscv64.zig"),
18 .sparcv9 => @import("linux/sparc64.zig"),
19 .mips, .mipsel => @import("linux/mips.zig"),
20 .powerpc => @import("linux/powerpc.zig"),
21 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
22 else => struct {},
23};
24
25pub usingnamespace @import("linux/netlink.zig");
26pub usingnamespace @import("linux/prctl.zig");
27pub usingnamespace @import("linux/securebits.zig");
28pub usingnamespace @import("linux/xdp.zig");
29
30const is_mips = arch.isMIPS();
31const is_ppc = arch.isPPC();
32const is_ppc64 = arch.isPPC64();
33const is_sparc = arch.isSPARC();
34
35pub const pid_t = i32;
36pub const fd_t = i32;
37pub const uid_t = u32;
38pub const gid_t = u32;
39pub const clock_t = isize;
40
41pub const NAME_MAX = 255;
42pub const PATH_MAX = 4096;
43pub const IOV_MAX = 1024;
44
45/// Largest hardware address length
46/// e.g. a mac address is a type of hardware address
47pub const MAX_ADDR_LEN = 32;
48
49pub const STDIN_FILENO = 0;
50pub const STDOUT_FILENO = 1;
51pub const STDERR_FILENO = 2;
52
53/// Special value used to indicate openat should use the current working directory
54pub const AT_FDCWD = -100;
55
56/// Do not follow symbolic links
57pub const AT_SYMLINK_NOFOLLOW = 0x100;
58
59/// Remove directory instead of unlinking file
60pub const AT_REMOVEDIR = 0x200;
61
62/// Follow symbolic links.
63pub const AT_SYMLINK_FOLLOW = 0x400;
64
65/// Suppress terminal automount traversal
66pub const AT_NO_AUTOMOUNT = 0x800;
67
68/// Allow empty relative pathname
69pub const AT_EMPTY_PATH = 0x1000;
70
71/// Type of synchronisation required from statx()
72pub const AT_STATX_SYNC_TYPE = 0x6000;
73
74/// - Do whatever stat() does
75pub const AT_STATX_SYNC_AS_STAT = 0x0000;
76
77/// - Force the attributes to be sync'd with the server
78pub const AT_STATX_FORCE_SYNC = 0x2000;
79
80/// - Don't sync attributes with the server
81pub const AT_STATX_DONT_SYNC = 0x4000;
82
83/// Apply to the entire subtree
84pub const AT_RECURSIVE = 0x8000;
85
86/// Default is extend size
87pub const FALLOC_FL_KEEP_SIZE = 0x01;
88
89/// De-allocates range
90pub const FALLOC_FL_PUNCH_HOLE = 0x02;
91
92/// Reserved codepoint
93pub const FALLOC_FL_NO_HIDE_STALE = 0x04;
94
95/// Removes a range of a file without leaving a hole in the file
96pub const FALLOC_FL_COLLAPSE_RANGE = 0x08;
97
98/// Converts a range of file to zeros preferably without issuing data IO
99pub const FALLOC_FL_ZERO_RANGE = 0x10;
100
101/// Inserts space within the file size without overwriting any existing data
102pub const FALLOC_FL_INSERT_RANGE = 0x20;
103
104/// Unshares shared blocks within the file size without overwriting any existing data
105pub const FALLOC_FL_UNSHARE_RANGE = 0x40;
106
107pub const FUTEX_WAIT = 0;
108pub const FUTEX_WAKE = 1;
109pub const FUTEX_FD = 2;
110pub const FUTEX_REQUEUE = 3;
111pub const FUTEX_CMP_REQUEUE = 4;
112pub const FUTEX_WAKE_OP = 5;
113pub const FUTEX_LOCK_PI = 6;
114pub const FUTEX_UNLOCK_PI = 7;
115pub const FUTEX_TRYLOCK_PI = 8;
116pub const FUTEX_WAIT_BITSET = 9;
117pub const FUTEX_WAKE_BITSET = 10;
118pub const FUTEX_WAIT_REQUEUE_PI = 11;
119pub const FUTEX_CMP_REQUEUE_PI = 12;
120
121pub const FUTEX_PRIVATE_FLAG = 128;
122
123pub const FUTEX_CLOCK_REALTIME = 256;
124
125/// page can not be accessed
126pub const PROT_NONE = 0x0;
127
128/// page can be read
129pub const PROT_READ = 0x1;
130
131/// page can be written
132pub const PROT_WRITE = 0x2;
133
134/// page can be executed
135pub const PROT_EXEC = 0x4;
136
137/// page may be used for atomic ops
138pub const PROT_SEM = switch (arch) {
139 // TODO: also xtensa
140 .mips, .mipsel, .mips64, .mips64el => 0x10,
141 else => 0x8,
142};
143
144/// mprotect flag: extend change to start of growsdown vma
145pub const PROT_GROWSDOWN = 0x01000000;
146
147/// mprotect flag: extend change to end of growsup vma
148pub const PROT_GROWSUP = 0x02000000;
149
150/// Share changes
151pub const MAP_SHARED = 0x01;
152
153/// Changes are private
154pub const MAP_PRIVATE = 0x02;
155
156/// share + validate extension flags
157pub const MAP_SHARED_VALIDATE = 0x03;
158
159/// Mask for type of mapping
160pub const MAP_TYPE = 0x0f;
161
162/// Interpret addr exactly
163pub const MAP_FIXED = 0x10;
164
165/// don't use a file
166pub const MAP_ANONYMOUS = if (is_mips) 0x800 else 0x20;
167
168// MAP_ 0x0100 - 0x4000 flags are per architecture
169
170/// populate (prefault) pagetables
171pub const MAP_POPULATE = if (is_mips) 0x10000 else 0x8000;
172
173/// do not block on IO
174pub const MAP_NONBLOCK = if (is_mips) 0x20000 else 0x10000;
175
176/// give out an address that is best suited for process/thread stacks
177pub const MAP_STACK = if (is_mips) 0x40000 else 0x20000;
178
179/// create a huge page mapping
180pub const MAP_HUGETLB = if (is_mips) 0x80000 else 0x40000;
181
182/// perform synchronous page faults for the mapping
183pub const MAP_SYNC = 0x80000;
184
185/// MAP_FIXED which doesn't unmap underlying mapping
186pub const MAP_FIXED_NOREPLACE = 0x100000;
187
188/// For anonymous mmap, memory could be uninitialized
189pub const MAP_UNINITIALIZED = 0x4000000;
190
191pub const FD_CLOEXEC = 1;
192
193pub const F_OK = 0;
194pub const X_OK = 1;
195pub const W_OK = 2;
196pub const R_OK = 4;
197
198pub const WNOHANG = 1;
199pub const WUNTRACED = 2;
200pub const WSTOPPED = 2;
201pub const WEXITED = 4;
202pub const WCONTINUED = 8;
203pub const WNOWAIT = 0x1000000;
204
205// waitid id types
206pub const P = enum(c_uint) {
207 ALL = 0,
208 PID = 1,
209 PGID = 2,
210 PIDFD = 3,
211 _,
212};
213
214pub usingnamespace if (is_mips)
215 struct {
216 pub const SA_NOCLDSTOP = 1;
217 pub const SA_NOCLDWAIT = 0x10000;
218 pub const SA_SIGINFO = 8;
219 pub const SA_RESTART = 0x10000000;
220 pub const SA_RESETHAND = 0x80000000;
221 pub const SA_ONSTACK = 0x08000000;
222 pub const SA_NODEFER = 0x40000000;
223 pub const SA_RESTORER = 0x04000000;
224
225 pub const SIG_BLOCK = 1;
226 pub const SIG_UNBLOCK = 2;
227 pub const SIG_SETMASK = 3;
228 }
229else if (is_sparc)
230 struct {
231 pub const SA_NOCLDSTOP = 0x8;
232 pub const SA_NOCLDWAIT = 0x100;
233 pub const SA_SIGINFO = 0x200;
234 pub const SA_RESTART = 0x2;
235 pub const SA_RESETHAND = 0x4;
236 pub const SA_ONSTACK = 0x1;
237 pub const SA_NODEFER = 0x20;
238 pub const SA_RESTORER = 0x04000000;
239
240 pub const SIG_BLOCK = 1;
241 pub const SIG_UNBLOCK = 2;
242 pub const SIG_SETMASK = 4;
243 }
244else
245 struct {
246 pub const SA_NOCLDSTOP = 1;
247 pub const SA_NOCLDWAIT = 2;
248 pub const SA_SIGINFO = 4;
249 pub const SA_RESTART = 0x10000000;
250 pub const SA_RESETHAND = 0x80000000;
251 pub const SA_ONSTACK = 0x08000000;
252 pub const SA_NODEFER = 0x40000000;
253 pub const SA_RESTORER = 0x04000000;
254
255 pub const SIG_BLOCK = 0;
256 pub const SIG_UNBLOCK = 1;
257 pub const SIG_SETMASK = 2;
258 };
259
260pub usingnamespace if (is_sparc) struct {
261 pub const SIGHUP = 1;
262 pub const SIGINT = 2;
263 pub const SIGQUIT = 3;
264 pub const SIGILL = 4;
265 pub const SIGTRAP = 5;
266 pub const SIGABRT = 6;
267 pub const SIGEMT = 7;
268 pub const SIGFPE = 8;
269 pub const SIGKILL = 9;
270 pub const SIGBUS = 10;
271 pub const SIGSEGV = 11;
272 pub const SIGSYS = 12;
273 pub const SIGPIPE = 13;
274 pub const SIGALRM = 14;
275 pub const SIGTERM = 15;
276 pub const SIGURG = 16;
277 pub const SIGSTOP = 17;
278 pub const SIGTSTP = 18;
279 pub const SIGCONT = 19;
280 pub const SIGCHLD = 20;
281 pub const SIGTTIN = 21;
282 pub const SIGTTOU = 22;
283 pub const SIGPOLL = 23;
284 pub const SIGXCPU = 24;
285 pub const SIGXFSZ = 25;
286 pub const SIGVTALRM = 26;
287 pub const SIGPROF = 27;
288 pub const SIGWINCH = 28;
289 pub const SIGLOST = 29;
290 pub const SIGUSR1 = 30;
291 pub const SIGUSR2 = 31;
292 pub const SIGIOT = SIGABRT;
293 pub const SIGCLD = SIGCHLD;
294 pub const SIGPWR = SIGLOST;
295 pub const SIGIO = SIGPOLL;
296} else struct {
297 pub const SIGHUP = 1;
298 pub const SIGINT = 2;
299 pub const SIGQUIT = 3;
300 pub const SIGILL = 4;
301 pub const SIGTRAP = 5;
302 pub const SIGABRT = 6;
303 pub const SIGIOT = SIGABRT;
304 pub const SIGBUS = 7;
305 pub const SIGFPE = 8;
306 pub const SIGKILL = 9;
307 pub const SIGUSR1 = 10;
308 pub const SIGSEGV = 11;
309 pub const SIGUSR2 = 12;
310 pub const SIGPIPE = 13;
311 pub const SIGALRM = 14;
312 pub const SIGTERM = 15;
313 pub const SIGSTKFLT = 16;
314 pub const SIGCHLD = 17;
315 pub const SIGCONT = 18;
316 pub const SIGSTOP = 19;
317 pub const SIGTSTP = 20;
318 pub const SIGTTIN = 21;
319 pub const SIGTTOU = 22;
320 pub const SIGURG = 23;
321 pub const SIGXCPU = 24;
322 pub const SIGXFSZ = 25;
323 pub const SIGVTALRM = 26;
324 pub const SIGPROF = 27;
325 pub const SIGWINCH = 28;
326 pub const SIGIO = 29;
327 pub const SIGPOLL = 29;
328 pub const SIGPWR = 30;
329 pub const SIGSYS = 31;
330 pub const SIGUNUSED = SIGSYS;
331};
332
333pub const O_RDONLY = 0o0;
334pub const O_WRONLY = 0o1;
335pub const O_RDWR = 0o2;
336
337pub const kernel_rwf = u32;
338
339/// high priority request, poll if possible
340pub const RWF_HIPRI: kernel_rwf = 0x00000001;
341
342/// per-IO O_DSYNC
343pub const RWF_DSYNC: kernel_rwf = 0x00000002;
344
345/// per-IO O_SYNC
346pub const RWF_SYNC: kernel_rwf = 0x00000004;
347
348/// per-IO, return -EAGAIN if operation would block
349pub const RWF_NOWAIT: kernel_rwf = 0x00000008;
350
351/// per-IO O_APPEND
352pub const RWF_APPEND: kernel_rwf = 0x00000010;
353
354pub const SEEK_SET = 0;
355pub const SEEK_CUR = 1;
356pub const SEEK_END = 2;
357
358pub const SHUT_RD = 0;
359pub const SHUT_WR = 1;
360pub const SHUT_RDWR = 2;
361
362pub const SOCK_STREAM = if (is_mips) 2 else 1;
363pub const SOCK_DGRAM = if (is_mips) 1 else 2;
364pub const SOCK_RAW = 3;
365pub const SOCK_RDM = 4;
366pub const SOCK_SEQPACKET = 5;
367pub const SOCK_DCCP = 6;
368pub const SOCK_PACKET = 10;
369pub const SOCK_CLOEXEC = 0o2000000;
370pub const SOCK_NONBLOCK = if (is_mips) 0o200 else 0o4000;
371
372pub const PF_UNSPEC = 0;
373pub const PF_LOCAL = 1;
374pub const PF_UNIX = PF_LOCAL;
375pub const PF_FILE = PF_LOCAL;
376pub const PF_INET = 2;
377pub const PF_AX25 = 3;
378pub const PF_IPX = 4;
379pub const PF_APPLETALK = 5;
380pub const PF_NETROM = 6;
381pub const PF_BRIDGE = 7;
382pub const PF_ATMPVC = 8;
383pub const PF_X25 = 9;
384pub const PF_INET6 = 10;
385pub const PF_ROSE = 11;
386pub const PF_DECnet = 12;
387pub const PF_NETBEUI = 13;
388pub const PF_SECURITY = 14;
389pub const PF_KEY = 15;
390pub const PF_NETLINK = 16;
391pub const PF_ROUTE = PF_NETLINK;
392pub const PF_PACKET = 17;
393pub const PF_ASH = 18;
394pub const PF_ECONET = 19;
395pub const PF_ATMSVC = 20;
396pub const PF_RDS = 21;
397pub const PF_SNA = 22;
398pub const PF_IRDA = 23;
399pub const PF_PPPOX = 24;
400pub const PF_WANPIPE = 25;
401pub const PF_LLC = 26;
402pub const PF_IB = 27;
403pub const PF_MPLS = 28;
404pub const PF_CAN = 29;
405pub const PF_TIPC = 30;
406pub const PF_BLUETOOTH = 31;
407pub const PF_IUCV = 32;
408pub const PF_RXRPC = 33;
409pub const PF_ISDN = 34;
410pub const PF_PHONET = 35;
411pub const PF_IEEE802154 = 36;
412pub const PF_CAIF = 37;
413pub const PF_ALG = 38;
414pub const PF_NFC = 39;
415pub const PF_VSOCK = 40;
416pub const PF_KCM = 41;
417pub const PF_QIPCRTR = 42;
418pub const PF_SMC = 43;
419pub const PF_XDP = 44;
420pub const PF_MAX = 45;
421
422pub const AF_UNSPEC = PF_UNSPEC;
423pub const AF_LOCAL = PF_LOCAL;
424pub const AF_UNIX = AF_LOCAL;
425pub const AF_FILE = AF_LOCAL;
426pub const AF_INET = PF_INET;
427pub const AF_AX25 = PF_AX25;
428pub const AF_IPX = PF_IPX;
429pub const AF_APPLETALK = PF_APPLETALK;
430pub const AF_NETROM = PF_NETROM;
431pub const AF_BRIDGE = PF_BRIDGE;
432pub const AF_ATMPVC = PF_ATMPVC;
433pub const AF_X25 = PF_X25;
434pub const AF_INET6 = PF_INET6;
435pub const AF_ROSE = PF_ROSE;
436pub const AF_DECnet = PF_DECnet;
437pub const AF_NETBEUI = PF_NETBEUI;
438pub const AF_SECURITY = PF_SECURITY;
439pub const AF_KEY = PF_KEY;
440pub const AF_NETLINK = PF_NETLINK;
441pub const AF_ROUTE = PF_ROUTE;
442pub const AF_PACKET = PF_PACKET;
443pub const AF_ASH = PF_ASH;
444pub const AF_ECONET = PF_ECONET;
445pub const AF_ATMSVC = PF_ATMSVC;
446pub const AF_RDS = PF_RDS;
447pub const AF_SNA = PF_SNA;
448pub const AF_IRDA = PF_IRDA;
449pub const AF_PPPOX = PF_PPPOX;
450pub const AF_WANPIPE = PF_WANPIPE;
451pub const AF_LLC = PF_LLC;
452pub const AF_IB = PF_IB;
453pub const AF_MPLS = PF_MPLS;
454pub const AF_CAN = PF_CAN;
455pub const AF_TIPC = PF_TIPC;
456pub const AF_BLUETOOTH = PF_BLUETOOTH;
457pub const AF_IUCV = PF_IUCV;
458pub const AF_RXRPC = PF_RXRPC;
459pub const AF_ISDN = PF_ISDN;
460pub const AF_PHONET = PF_PHONET;
461pub const AF_IEEE802154 = PF_IEEE802154;
462pub const AF_CAIF = PF_CAIF;
463pub const AF_ALG = PF_ALG;
464pub const AF_NFC = PF_NFC;
465pub const AF_VSOCK = PF_VSOCK;
466pub const AF_KCM = PF_KCM;
467pub const AF_QIPCRTR = PF_QIPCRTR;
468pub const AF_SMC = PF_SMC;
469pub const AF_XDP = PF_XDP;
470pub const AF_MAX = PF_MAX;
471
472pub usingnamespace if (is_mips)
473 struct {}
474else if (is_ppc or is_ppc64)
475 struct {
476 pub const SO_DEBUG = 1;
477 pub const SO_REUSEADDR = 2;
478 pub const SO_TYPE = 3;
479 pub const SO_ERROR = 4;
480 pub const SO_DONTROUTE = 5;
481 pub const SO_BROADCAST = 6;
482 pub const SO_SNDBUF = 7;
483 pub const SO_RCVBUF = 8;
484 pub const SO_KEEPALIVE = 9;
485 pub const SO_OOBINLINE = 10;
486 pub const SO_NO_CHECK = 11;
487 pub const SO_PRIORITY = 12;
488 pub const SO_LINGER = 13;
489 pub const SO_BSDCOMPAT = 14;
490 pub const SO_REUSEPORT = 15;
491 pub const SO_RCVLOWAT = 16;
492 pub const SO_SNDLOWAT = 17;
493 pub const SO_RCVTIMEO = 18;
494 pub const SO_SNDTIMEO = 19;
495 pub const SO_PASSCRED = 20;
496 pub const SO_PEERCRED = 21;
497 pub const SO_ACCEPTCONN = 30;
498 pub const SO_PEERSEC = 31;
499 pub const SO_SNDBUFFORCE = 32;
500 pub const SO_RCVBUFFORCE = 33;
501 pub const SO_PROTOCOL = 38;
502 pub const SO_DOMAIN = 39;
503 }
504else
505 struct {
506 pub const SO_DEBUG = 1;
507 pub const SO_REUSEADDR = 2;
508 pub const SO_TYPE = 3;
509 pub const SO_ERROR = 4;
510 pub const SO_DONTROUTE = 5;
511 pub const SO_BROADCAST = 6;
512 pub const SO_SNDBUF = 7;
513 pub const SO_RCVBUF = 8;
514 pub const SO_KEEPALIVE = 9;
515 pub const SO_OOBINLINE = 10;
516 pub const SO_NO_CHECK = 11;
517 pub const SO_PRIORITY = 12;
518 pub const SO_LINGER = 13;
519 pub const SO_BSDCOMPAT = 14;
520 pub const SO_REUSEPORT = 15;
521 pub const SO_PASSCRED = 16;
522 pub const SO_PEERCRED = 17;
523 pub const SO_RCVLOWAT = 18;
524 pub const SO_SNDLOWAT = 19;
525 pub const SO_RCVTIMEO = 20;
526 pub const SO_SNDTIMEO = 21;
527 pub const SO_ACCEPTCONN = 30;
528 pub const SO_PEERSEC = 31;
529 pub const SO_SNDBUFFORCE = 32;
530 pub const SO_RCVBUFFORCE = 33;
531 pub const SO_PROTOCOL = 38;
532 pub const SO_DOMAIN = 39;
533 };
534
535pub const SO_SECURITY_AUTHENTICATION = 22;
536pub const SO_SECURITY_ENCRYPTION_TRANSPORT = 23;
537pub const SO_SECURITY_ENCRYPTION_NETWORK = 24;
538
539pub const SO_BINDTODEVICE = 25;
540
541pub const SO_ATTACH_FILTER = 26;
542pub const SO_DETACH_FILTER = 27;
543pub const SO_GET_FILTER = SO_ATTACH_FILTER;
544
545pub const SO_PEERNAME = 28;
546pub const SO_TIMESTAMP_OLD = 29;
547pub const SO_PASSSEC = 34;
548pub const SO_TIMESTAMPNS_OLD = 35;
549pub const SO_MARK = 36;
550pub const SO_TIMESTAMPING_OLD = 37;
551
552pub const SO_RXQ_OVFL = 40;
553pub const SO_WIFI_STATUS = 41;
554pub const SCM_WIFI_STATUS = SO_WIFI_STATUS;
555pub const SO_PEEK_OFF = 42;
556pub const SO_NOFCS = 43;
557pub const SO_LOCK_FILTER = 44;
558pub const SO_SELECT_ERR_QUEUE = 45;
559pub const SO_BUSY_POLL = 46;
560pub const SO_MAX_PACING_RATE = 47;
561pub const SO_BPF_EXTENSIONS = 48;
562pub const SO_INCOMING_CPU = 49;
563pub const SO_ATTACH_BPF = 50;
564pub const SO_DETACH_BPF = SO_DETACH_FILTER;
565pub const SO_ATTACH_REUSEPORT_CBPF = 51;
566pub const SO_ATTACH_REUSEPORT_EBPF = 52;
567pub const SO_CNX_ADVICE = 53;
568pub const SCM_TIMESTAMPING_OPT_STATS = 54;
569pub const SO_MEMINFO = 55;
570pub const SO_INCOMING_NAPI_ID = 56;
571pub const SO_COOKIE = 57;
572pub const SCM_TIMESTAMPING_PKTINFO = 58;
573pub const SO_PEERGROUPS = 59;
574pub const SO_ZEROCOPY = 60;
575pub const SO_TXTIME = 61;
576pub const SCM_TXTIME = SO_TXTIME;
577pub const SO_BINDTOIFINDEX = 62;
578pub const SO_TIMESTAMP_NEW = 63;
579pub const SO_TIMESTAMPNS_NEW = 64;
580pub const SO_TIMESTAMPING_NEW = 65;
581pub const SO_RCVTIMEO_NEW = 66;
582pub const SO_SNDTIMEO_NEW = 67;
583pub const SO_DETACH_REUSEPORT_BPF = 68;
584
585pub const SOL_SOCKET = if (is_mips) 65535 else 1;
586
587pub const SOL_IP = 0;
588pub const SOL_IPV6 = 41;
589pub const SOL_ICMPV6 = 58;
590
591pub const SOL_RAW = 255;
592pub const SOL_DECNET = 261;
593pub const SOL_X25 = 262;
594pub const SOL_PACKET = 263;
595pub const SOL_ATM = 264;
596pub const SOL_AAL = 265;
597pub const SOL_IRDA = 266;
598pub const SOL_NETBEUI = 267;
599pub const SOL_LLC = 268;
600pub const SOL_DCCP = 269;
601pub const SOL_NETLINK = 270;
602pub const SOL_TIPC = 271;
603pub const SOL_RXRPC = 272;
604pub const SOL_PPPOL2TP = 273;
605pub const SOL_BLUETOOTH = 274;
606pub const SOL_PNPIPE = 275;
607pub const SOL_RDS = 276;
608pub const SOL_IUCV = 277;
609pub const SOL_CAIF = 278;
610pub const SOL_ALG = 279;
611pub const SOL_NFC = 280;
612pub const SOL_KCM = 281;
613pub const SOL_TLS = 282;
614pub const SOL_XDP = 283;
615
616pub const SOMAXCONN = 128;
617
618pub const IP_TOS = 1;
619pub const IP_TTL = 2;
620pub const IP_HDRINCL = 3;
621pub const IP_OPTIONS = 4;
622pub const IP_ROUTER_ALERT = 5;
623pub const IP_RECVOPTS = 6;
624pub const IP_RETOPTS = 7;
625pub const IP_PKTINFO = 8;
626pub const IP_PKTOPTIONS = 9;
627pub const IP_PMTUDISC = 10;
628pub const IP_MTU_DISCOVER = 10;
629pub const IP_RECVERR = 11;
630pub const IP_RECVTTL = 12;
631pub const IP_RECVTOS = 13;
632pub const IP_MTU = 14;
633pub const IP_FREEBIND = 15;
634pub const IP_IPSEC_POLICY = 16;
635pub const IP_XFRM_POLICY = 17;
636pub const IP_PASSSEC = 18;
637pub const IP_TRANSPARENT = 19;
638pub const IP_ORIGDSTADDR = 20;
639pub const IP_RECVORIGDSTADDR = IP_ORIGDSTADDR;
640pub const IP_MINTTL = 21;
641pub const IP_NODEFRAG = 22;
642pub const IP_CHECKSUM = 23;
643pub const IP_BIND_ADDRESS_NO_PORT = 24;
644pub const IP_RECVFRAGSIZE = 25;
645pub const IP_MULTICAST_IF = 32;
646pub const IP_MULTICAST_TTL = 33;
647pub const IP_MULTICAST_LOOP = 34;
648pub const IP_ADD_MEMBERSHIP = 35;
649pub const IP_DROP_MEMBERSHIP = 36;
650pub const IP_UNBLOCK_SOURCE = 37;
651pub const IP_BLOCK_SOURCE = 38;
652pub const IP_ADD_SOURCE_MEMBERSHIP = 39;
653pub const IP_DROP_SOURCE_MEMBERSHIP = 40;
654pub const IP_MSFILTER = 41;
655pub const IP_MULTICAST_ALL = 49;
656pub const IP_UNICAST_IF = 50;
657
658pub const IP_RECVRETOPTS = IP_RETOPTS;
659
660pub const IP_PMTUDISC_DONT = 0;
661pub const IP_PMTUDISC_WANT = 1;
662pub const IP_PMTUDISC_DO = 2;
663pub const IP_PMTUDISC_PROBE = 3;
664pub const IP_PMTUDISC_INTERFACE = 4;
665pub const IP_PMTUDISC_OMIT = 5;
666
667pub const IP_DEFAULT_MULTICAST_TTL = 1;
668pub const IP_DEFAULT_MULTICAST_LOOP = 1;
669pub const IP_MAX_MEMBERSHIPS = 20;
670
671// IPv6 socket options
672
673pub const IPV6_ADDRFORM = 1;
674pub const IPV6_2292PKTINFO = 2;
675pub const IPV6_2292HOPOPTS = 3;
676pub const IPV6_2292DSTOPTS = 4;
677pub const IPV6_2292RTHDR = 5;
678pub const IPV6_2292PKTOPTIONS = 6;
679pub const IPV6_CHECKSUM = 7;
680pub const IPV6_2292HOPLIMIT = 8;
681pub const IPV6_NEXTHOP = 9;
682pub const IPV6_AUTHHDR = 10;
683pub const IPV6_FLOWINFO = 11;
684
685pub const IPV6_UNICAST_HOPS = 16;
686pub const IPV6_MULTICAST_IF = 17;
687pub const IPV6_MULTICAST_HOPS = 18;
688pub const IPV6_MULTICAST_LOOP = 19;
689pub const IPV6_ADD_MEMBERSHIP = 20;
690pub const IPV6_DROP_MEMBERSHIP = 21;
691pub const IPV6_ROUTER_ALERT = 22;
692pub const IPV6_MTU_DISCOVER = 23;
693pub const IPV6_MTU = 24;
694pub const IPV6_RECVERR = 25;
695pub const IPV6_V6ONLY = 26;
696pub const IPV6_JOIN_ANYCAST = 27;
697pub const IPV6_LEAVE_ANYCAST = 28;
698
699// IPV6_MTU_DISCOVER values
700pub const IPV6_PMTUDISC_DONT = 0;
701pub const IPV6_PMTUDISC_WANT = 1;
702pub const IPV6_PMTUDISC_DO = 2;
703pub const IPV6_PMTUDISC_PROBE = 3;
704pub const IPV6_PMTUDISC_INTERFACE = 4;
705pub const IPV6_PMTUDISC_OMIT = 5;
706
707// Flowlabel
708pub const IPV6_FLOWLABEL_MGR = 32;
709pub const IPV6_FLOWINFO_SEND = 33;
710pub const IPV6_IPSEC_POLICY = 34;
711pub const IPV6_XFRM_POLICY = 35;
712pub const IPV6_HDRINCL = 36;
713
714// Advanced API (RFC3542) (1)
715pub const IPV6_RECVPKTINFO = 49;
716pub const IPV6_PKTINFO = 50;
717pub const IPV6_RECVHOPLIMIT = 51;
718pub const IPV6_HOPLIMIT = 52;
719pub const IPV6_RECVHOPOPTS = 53;
720pub const IPV6_HOPOPTS = 54;
721pub const IPV6_RTHDRDSTOPTS = 55;
722pub const IPV6_RECVRTHDR = 56;
723pub const IPV6_RTHDR = 57;
724pub const IPV6_RECVDSTOPTS = 58;
725pub const IPV6_DSTOPTS = 59;
726pub const IPV6_RECVPATHMTU = 60;
727pub const IPV6_PATHMTU = 61;
728pub const IPV6_DONTFRAG = 62;
729
730// Advanced API (RFC3542) (2)
731pub const IPV6_RECVTCLASS = 66;
732pub const IPV6_TCLASS = 67;
733
734pub const IPV6_AUTOFLOWLABEL = 70;
735
736// RFC5014: Source address selection
737pub const IPV6_ADDR_PREFERENCES = 72;
738
739pub const IPV6_PREFER_SRC_TMP = 0x0001;
740pub const IPV6_PREFER_SRC_PUBLIC = 0x0002;
741pub const IPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x0100;
742pub const IPV6_PREFER_SRC_COA = 0x0004;
743pub const IPV6_PREFER_SRC_HOME = 0x0400;
744pub const IPV6_PREFER_SRC_CGA = 0x0008;
745pub const IPV6_PREFER_SRC_NONCGA = 0x0800;
746
747// RFC5082: Generalized Ttl Security Mechanism
748pub const IPV6_MINHOPCOUNT = 73;
749
750pub const IPV6_ORIGDSTADDR = 74;
751pub const IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR;
752pub const IPV6_TRANSPARENT = 75;
753pub const IPV6_UNICAST_IF = 76;
754pub const IPV6_RECVFRAGSIZE = 77;
755pub const IPV6_FREEBIND = 78;
756
757pub const MSG_OOB = 0x0001;
758pub const MSG_PEEK = 0x0002;
759pub const MSG_DONTROUTE = 0x0004;
760pub const MSG_CTRUNC = 0x0008;
761pub const MSG_PROXY = 0x0010;
762pub const MSG_TRUNC = 0x0020;
763pub const MSG_DONTWAIT = 0x0040;
764pub const MSG_EOR = 0x0080;
765pub const MSG_WAITALL = 0x0100;
766pub const MSG_FIN = 0x0200;
767pub const MSG_SYN = 0x0400;
768pub const MSG_CONFIRM = 0x0800;
769pub const MSG_RST = 0x1000;
770pub const MSG_ERRQUEUE = 0x2000;
771pub const MSG_NOSIGNAL = 0x4000;
772pub const MSG_MORE = 0x8000;
773pub const MSG_WAITFORONE = 0x10000;
774pub const MSG_BATCH = 0x40000;
775pub const MSG_ZEROCOPY = 0x4000000;
776pub const MSG_FASTOPEN = 0x20000000;
777pub const MSG_CMSG_CLOEXEC = 0x40000000;
778
779pub const DT_UNKNOWN = 0;
780pub const DT_FIFO = 1;
781pub const DT_CHR = 2;
782pub const DT_DIR = 4;
783pub const DT_BLK = 6;
784pub const DT_REG = 8;
785pub const DT_LNK = 10;
786pub const DT_SOCK = 12;
787pub const DT_WHT = 14;
788
789pub const TCGETS = if (is_mips) 0x540D else 0x5401;
790pub const TCSETS = 0x5402;
791pub const TCSETSW = 0x5403;
792pub const TCSETSF = 0x5404;
793pub const TCGETA = 0x5405;
794pub const TCSETA = 0x5406;
795pub const TCSETAW = 0x5407;
796pub const TCSETAF = 0x5408;
797pub const TCSBRK = 0x5409;
798pub const TCXONC = 0x540A;
799pub const TCFLSH = 0x540B;
800pub const TIOCEXCL = 0x540C;
801pub const TIOCNXCL = 0x540D;
802pub const TIOCSCTTY = 0x540E;
803pub const TIOCGPGRP = 0x540F;
804pub const TIOCSPGRP = 0x5410;
805pub const TIOCOUTQ = if (is_mips) 0x7472 else 0x5411;
806pub const TIOCSTI = 0x5412;
807pub const TIOCGWINSZ = if (is_mips or is_ppc64) 0x40087468 else 0x5413;
808pub const TIOCSWINSZ = if (is_mips or is_ppc64) 0x80087467 else 0x5414;
809pub const TIOCMGET = 0x5415;
810pub const TIOCMBIS = 0x5416;
811pub const TIOCMBIC = 0x5417;
812pub const TIOCMSET = 0x5418;
813pub const TIOCGSOFTCAR = 0x5419;
814pub const TIOCSSOFTCAR = 0x541A;
815pub const FIONREAD = if (is_mips) 0x467F else 0x541B;
816pub const TIOCINQ = FIONREAD;
817pub const TIOCLINUX = 0x541C;
818pub const TIOCCONS = 0x541D;
819pub const TIOCGSERIAL = 0x541E;
820pub const TIOCSSERIAL = 0x541F;
821pub const TIOCPKT = 0x5420;
822pub const FIONBIO = 0x5421;
823pub const TIOCNOTTY = 0x5422;
824pub const TIOCSETD = 0x5423;
825pub const TIOCGETD = 0x5424;
826pub const TCSBRKP = 0x5425;
827pub const TIOCSBRK = 0x5427;
828pub const TIOCCBRK = 0x5428;
829pub const TIOCGSID = 0x5429;
830pub const TIOCGRS485 = 0x542E;
831pub const TIOCSRS485 = 0x542F;
832pub const TIOCGPTN = 0x80045430;
833pub const TIOCSPTLCK = 0x40045431;
834pub const TIOCGDEV = 0x80045432;
835pub const TCGETX = 0x5432;
836pub const TCSETX = 0x5433;
837pub const TCSETXF = 0x5434;
838pub const TCSETXW = 0x5435;
839pub const TIOCSIG = 0x40045436;
840pub const TIOCVHANGUP = 0x5437;
841pub const TIOCGPKT = 0x80045438;
842pub const TIOCGPTLCK = 0x80045439;
843pub const TIOCGEXCL = 0x80045440;
844
845pub const EPOLL_CLOEXEC = O_CLOEXEC;
846
847pub const EPOLL_CTL_ADD = 1;
848pub const EPOLL_CTL_DEL = 2;
849pub const EPOLL_CTL_MOD = 3;
850
851pub const EPOLLIN = 0x001;
852pub const EPOLLPRI = 0x002;
853pub const EPOLLOUT = 0x004;
854pub const EPOLLRDNORM = 0x040;
855pub const EPOLLRDBAND = 0x080;
856pub const EPOLLWRNORM = if (is_mips) 0x004 else 0x100;
857pub const EPOLLWRBAND = if (is_mips) 0x100 else 0x200;
858pub const EPOLLMSG = 0x400;
859pub const EPOLLERR = 0x008;
860pub const EPOLLHUP = 0x010;
861pub const EPOLLRDHUP = 0x2000;
862pub const EPOLLEXCLUSIVE = (@as(u32, 1) << 28);
863pub const EPOLLWAKEUP = (@as(u32, 1) << 29);
864pub const EPOLLONESHOT = (@as(u32, 1) << 30);
865pub const EPOLLET = (@as(u32, 1) << 31);
866
867pub const CLOCK_REALTIME = 0;
868pub const CLOCK_MONOTONIC = 1;
869pub const CLOCK_PROCESS_CPUTIME_ID = 2;
870pub const CLOCK_THREAD_CPUTIME_ID = 3;
871pub const CLOCK_MONOTONIC_RAW = 4;
872pub const CLOCK_REALTIME_COARSE = 5;
873pub const CLOCK_MONOTONIC_COARSE = 6;
874pub const CLOCK_BOOTTIME = 7;
875pub const CLOCK_REALTIME_ALARM = 8;
876pub const CLOCK_BOOTTIME_ALARM = 9;
877pub const CLOCK_SGI_CYCLE = 10;
878pub const CLOCK_TAI = 11;
879
880pub const CSIGNAL = 0x000000ff;
881pub const CLONE_VM = 0x00000100;
882pub const CLONE_FS = 0x00000200;
883pub const CLONE_FILES = 0x00000400;
884pub const CLONE_SIGHAND = 0x00000800;
885pub const CLONE_PIDFD = 0x00001000;
886pub const CLONE_PTRACE = 0x00002000;
887pub const CLONE_VFORK = 0x00004000;
888pub const CLONE_PARENT = 0x00008000;
889pub const CLONE_THREAD = 0x00010000;
890pub const CLONE_NEWNS = 0x00020000;
891pub const CLONE_SYSVSEM = 0x00040000;
892pub const CLONE_SETTLS = 0x00080000;
893pub const CLONE_PARENT_SETTID = 0x00100000;
894pub const CLONE_CHILD_CLEARTID = 0x00200000;
895pub const CLONE_DETACHED = 0x00400000;
896pub const CLONE_UNTRACED = 0x00800000;
897pub const CLONE_CHILD_SETTID = 0x01000000;
898pub const CLONE_NEWCGROUP = 0x02000000;
899pub const CLONE_NEWUTS = 0x04000000;
900pub const CLONE_NEWIPC = 0x08000000;
901pub const CLONE_NEWUSER = 0x10000000;
902pub const CLONE_NEWPID = 0x20000000;
903pub const CLONE_NEWNET = 0x40000000;
904pub const CLONE_IO = 0x80000000;
905
906// Flags for the clone3() syscall.
907
908/// Clear any signal handler and reset to SIG_DFL.
909pub const CLONE_CLEAR_SIGHAND = 0x100000000;
910/// Clone into a specific cgroup given the right permissions.
911pub const CLONE_INTO_CGROUP = 0x200000000;
912
913// cloning flags intersect with CSIGNAL so can be used with unshare and clone3 syscalls only.
914
915/// New time namespace
916pub const CLONE_NEWTIME = 0x00000080;
917
918pub const EFD_SEMAPHORE = 1;
919pub const EFD_CLOEXEC = O_CLOEXEC;
920pub const EFD_NONBLOCK = O_NONBLOCK;
921
922pub const MS_RDONLY = 1;
923pub const MS_NOSUID = 2;
924pub const MS_NODEV = 4;
925pub const MS_NOEXEC = 8;
926pub const MS_SYNCHRONOUS = 16;
927pub const MS_REMOUNT = 32;
928pub const MS_MANDLOCK = 64;
929pub const MS_DIRSYNC = 128;
930pub const MS_NOATIME = 1024;
931pub const MS_NODIRATIME = 2048;
932pub const MS_BIND = 4096;
933pub const MS_MOVE = 8192;
934pub const MS_REC = 16384;
935pub const MS_SILENT = 32768;
936pub const MS_POSIXACL = (1 << 16);
937pub const MS_UNBINDABLE = (1 << 17);
938pub const MS_PRIVATE = (1 << 18);
939pub const MS_SLAVE = (1 << 19);
940pub const MS_SHARED = (1 << 20);
941pub const MS_RELATIME = (1 << 21);
942pub const MS_KERNMOUNT = (1 << 22);
943pub const MS_I_VERSION = (1 << 23);
944pub const MS_STRICTATIME = (1 << 24);
945pub const MS_LAZYTIME = (1 << 25);
946pub const MS_NOREMOTELOCK = (1 << 27);
947pub const MS_NOSEC = (1 << 28);
948pub const MS_BORN = (1 << 29);
949pub const MS_ACTIVE = (1 << 30);
950pub const MS_NOUSER = (1 << 31);
951
952pub const MS_RMT_MASK = (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION | MS_LAZYTIME);
953
954pub const MS_MGC_VAL = 0xc0ed0000;
955pub const MS_MGC_MSK = 0xffff0000;
956
957pub const MNT_FORCE = 1;
958pub const MNT_DETACH = 2;
959pub const MNT_EXPIRE = 4;
960pub const UMOUNT_NOFOLLOW = 8;
961
962pub const IN_CLOEXEC = O_CLOEXEC;
963pub const IN_NONBLOCK = O_NONBLOCK;
964
965pub const IN_ACCESS = 0x00000001;
966pub const IN_MODIFY = 0x00000002;
967pub const IN_ATTRIB = 0x00000004;
968pub const IN_CLOSE_WRITE = 0x00000008;
969pub const IN_CLOSE_NOWRITE = 0x00000010;
970pub const IN_CLOSE = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE;
971pub const IN_OPEN = 0x00000020;
972pub const IN_MOVED_FROM = 0x00000040;
973pub const IN_MOVED_TO = 0x00000080;
974pub const IN_MOVE = IN_MOVED_FROM | IN_MOVED_TO;
975pub const IN_CREATE = 0x00000100;
976pub const IN_DELETE = 0x00000200;
977pub const IN_DELETE_SELF = 0x00000400;
978pub const IN_MOVE_SELF = 0x00000800;
979pub const IN_ALL_EVENTS = 0x00000fff;
980
981pub const IN_UNMOUNT = 0x00002000;
982pub const IN_Q_OVERFLOW = 0x00004000;
983pub const IN_IGNORED = 0x00008000;
984
985pub const IN_ONLYDIR = 0x01000000;
986pub const IN_DONT_FOLLOW = 0x02000000;
987pub const IN_EXCL_UNLINK = 0x04000000;
988pub const IN_MASK_ADD = 0x20000000;
989
990pub const IN_ISDIR = 0x40000000;
991pub const IN_ONESHOT = 0x80000000;
992
993pub const S_IFMT = 0o170000;
994
995pub const S_IFDIR = 0o040000;
996pub const S_IFCHR = 0o020000;
997pub const S_IFBLK = 0o060000;
998pub const S_IFREG = 0o100000;
999pub const S_IFIFO = 0o010000;
1000pub const S_IFLNK = 0o120000;
1001pub const S_IFSOCK = 0o140000;
1002
1003pub const S_ISUID = 0o4000;
1004pub const S_ISGID = 0o2000;
1005pub const S_ISVTX = 0o1000;
1006pub const S_IRUSR = 0o400;
1007pub const S_IWUSR = 0o200;
1008pub const S_IXUSR = 0o100;
1009pub const S_IRWXU = 0o700;
1010pub const S_IRGRP = 0o040;
1011pub const S_IWGRP = 0o020;
1012pub const S_IXGRP = 0o010;
1013pub const S_IRWXG = 0o070;
1014pub const S_IROTH = 0o004;
1015pub const S_IWOTH = 0o002;
1016pub const S_IXOTH = 0o001;
1017pub const S_IRWXO = 0o007;
1018
1019pub fn S_ISREG(m: u32) bool {
1020 return m & S_IFMT == S_IFREG;
1021}
1022
1023pub fn S_ISDIR(m: u32) bool {
1024 return m & S_IFMT == S_IFDIR;
1025}
1026
1027pub fn S_ISCHR(m: u32) bool {
1028 return m & S_IFMT == S_IFCHR;
1029}
1030
1031pub fn S_ISBLK(m: u32) bool {
1032 return m & S_IFMT == S_IFBLK;
1033}
1034
1035pub fn S_ISFIFO(m: u32) bool {
1036 return m & S_IFMT == S_IFIFO;
1037}
1038
1039pub fn S_ISLNK(m: u32) bool {
1040 return m & S_IFMT == S_IFLNK;
1041}
1042
1043pub fn S_ISSOCK(m: u32) bool {
1044 return m & S_IFMT == S_IFSOCK;
1045}
1046
1047pub const UTIME_NOW = 0x3fffffff;
1048pub const UTIME_OMIT = 0x3ffffffe;
1049
1050pub const TFD_NONBLOCK = O_NONBLOCK;
1051pub const TFD_CLOEXEC = O_CLOEXEC;
1052
1053pub const TFD_TIMER_ABSTIME = 1;
1054pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);
1055
1056pub fn WEXITSTATUS(s: u32) u8 {
1057 return @intCast(u8, (s & 0xff00) >> 8);
1058}
1059pub fn WTERMSIG(s: u32) u32 {
1060 return s & 0x7f;
1061}
1062pub fn WSTOPSIG(s: u32) u32 {
1063 return WEXITSTATUS(s);
1064}
1065pub fn WIFEXITED(s: u32) bool {
1066 return WTERMSIG(s) == 0;
1067}
1068pub fn WIFSTOPPED(s: u32) bool {
1069 return @intCast(u16, ((s & 0xffff) *% 0x10001) >> 8) > 0x7f00;
1070}
1071pub fn WIFSIGNALED(s: u32) bool {
1072 return (s & 0xffff) -% 1 < 0xff;
1073}
1074
1075pub const winsize = extern struct {
1076 ws_row: u16,
1077 ws_col: u16,
1078 ws_xpixel: u16,
1079 ws_ypixel: u16,
1080};
1081
1082/// NSIG is the total number of signals defined.
1083/// As signal numbers are sequential, NSIG is one greater than the largest defined signal number.
1084pub const NSIG = if (is_mips) 128 else 65;
1085
1086pub const sigset_t = [1024 / 32]u32;
1087
1088pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len;
1089pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30;
1090
1091pub const k_sigaction = switch (arch) {
1092 .mips, .mipsel => extern struct {
1093 flags: c_uint,
1094 handler: ?fn (c_int) callconv(.C) void,
1095 mask: [4]c_ulong,
1096 restorer: fn () callconv(.C) void,
1097 },
1098 .mips64, .mips64el => extern struct {
1099 flags: c_uint,
1100 handler: ?fn (c_int) callconv(.C) void,
1101 mask: [2]c_ulong,
1102 restorer: fn () callconv(.C) void,
1103 },
1104 else => extern struct {
1105 handler: ?fn (c_int) callconv(.C) void,
1106 flags: c_ulong,
1107 restorer: fn () callconv(.C) void,
1108 mask: [2]c_uint,
1109 },
1110};
1111
1112/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
1113pub const Sigaction = extern struct {
1114 pub const handler_fn = fn (c_int) callconv(.C) void;
1115 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
1116
1117 handler: extern union {
1118 handler: ?handler_fn,
1119 sigaction: ?sigaction_fn,
1120 },
1121 mask: sigset_t,
1122 flags: c_uint,
1123 restorer: ?fn () callconv(.C) void = null,
1124};
1125
1126pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
1127pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
1128pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
1129
1130pub const empty_sigset = [_]u32{0} ** @typeInfo(sigset_t).Array.len;
1131
1132pub const SFD_CLOEXEC = O_CLOEXEC;
1133pub const SFD_NONBLOCK = O_NONBLOCK;
1134
1135pub const signalfd_siginfo = extern struct {
1136 signo: u32,
1137 errno: i32,
1138 code: i32,
1139 pid: u32,
1140 uid: uid_t,
1141 fd: i32,
1142 tid: u32,
1143 band: u32,
1144 overrun: u32,
1145 trapno: u32,
1146 status: i32,
1147 int: i32,
1148 ptr: u64,
1149 utime: u64,
1150 stime: u64,
1151 addr: u64,
1152 addr_lsb: u16,
1153 __pad2: u16,
1154 syscall: i32,
1155 call_addr: u64,
1156 arch: u32,
1157 __pad: [28]u8,
1158};
1159
1160pub const in_port_t = u16;
1161pub const sa_family_t = u16;
1162pub const socklen_t = u32;
1163
1164pub const sockaddr = extern struct {
1165 family: sa_family_t,
1166 data: [14]u8,
1167};
1168
1169pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
1170
1171/// IPv4 socket address
1172pub const sockaddr_in = extern struct {
1173 family: sa_family_t = AF_INET,
1174 port: in_port_t,
1175 addr: u32,
1176 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
1177};
1178
1179/// IPv6 socket address
1180pub const sockaddr_in6 = extern struct {
1181 family: sa_family_t = AF_INET6,
1182 port: in_port_t,
1183 flowinfo: u32,
1184 addr: [16]u8,
1185 scope_id: u32,
1186};
1187
1188/// UNIX domain socket address
1189pub const sockaddr_un = extern struct {
1190 family: sa_family_t = AF_UNIX,
1191 path: [108]u8,
1192};
1193
1194pub const mmsghdr = extern struct {
1195 msg_hdr: msghdr,
1196 msg_len: u32,
1197};
1198
1199pub const mmsghdr_const = extern struct {
1200 msg_hdr: msghdr_const,
1201 msg_len: u32,
1202};
1203
1204pub const epoll_data = extern union {
1205 ptr: usize,
1206 fd: i32,
1207 @"u32": u32,
1208 @"u64": u64,
1209};
1210
1211// On x86_64 the structure is packed so that it matches the definition of its
1212// 32bit counterpart
1213pub const epoll_event = switch (arch) {
1214 .x86_64 => packed struct {
1215 events: u32,
1216 data: epoll_data,
1217 },
1218 else => extern struct {
1219 events: u32,
1220 data: epoll_data,
1221 },
1222};
1223
1224pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;
1225pub const _LINUX_CAPABILITY_U32S_1 = 1;
1226
1227pub const _LINUX_CAPABILITY_VERSION_2 = 0x20071026;
1228pub const _LINUX_CAPABILITY_U32S_2 = 2;
1229
1230pub const _LINUX_CAPABILITY_VERSION_3 = 0x20080522;
1231pub const _LINUX_CAPABILITY_U32S_3 = 2;
1232
1233pub const VFS_CAP_REVISION_MASK = 0xFF000000;
1234pub const VFS_CAP_REVISION_SHIFT = 24;
1235pub const VFS_CAP_FLAGS_MASK = ~VFS_CAP_REVISION_MASK;
1236pub const VFS_CAP_FLAGS_EFFECTIVE = 0x000001;
1237
1238pub const VFS_CAP_REVISION_1 = 0x01000000;
1239pub const VFS_CAP_U32_1 = 1;
1240pub const XATTR_CAPS_SZ_1 = @sizeOf(u32) * (1 + 2 * VFS_CAP_U32_1);
1241
1242pub const VFS_CAP_REVISION_2 = 0x02000000;
1243pub const VFS_CAP_U32_2 = 2;
1244pub const XATTR_CAPS_SZ_2 = @sizeOf(u32) * (1 + 2 * VFS_CAP_U32_2);
1245
1246pub const XATTR_CAPS_SZ = XATTR_CAPS_SZ_2;
1247pub const VFS_CAP_U32 = VFS_CAP_U32_2;
1248pub const VFS_CAP_REVISION = VFS_CAP_REVISION_2;
1249
1250pub const vfs_cap_data = extern struct {
1251 //all of these are mandated as little endian
1252 //when on disk.
1253 const Data = struct {
1254 permitted: u32,
1255 inheritable: u32,
1256 };
1257
1258 magic_etc: u32,
1259 data: [VFS_CAP_U32]Data,
1260};
1261
1262pub const CAP_CHOWN = 0;
1263pub const CAP_DAC_OVERRIDE = 1;
1264pub const CAP_DAC_READ_SEARCH = 2;
1265pub const CAP_FOWNER = 3;
1266pub const CAP_FSETID = 4;
1267pub const CAP_KILL = 5;
1268pub const CAP_SETGID = 6;
1269pub const CAP_SETUID = 7;
1270pub const CAP_SETPCAP = 8;
1271pub const CAP_LINUX_IMMUTABLE = 9;
1272pub const CAP_NET_BIND_SERVICE = 10;
1273pub const CAP_NET_BROADCAST = 11;
1274pub const CAP_NET_ADMIN = 12;
1275pub const CAP_NET_RAW = 13;
1276pub const CAP_IPC_LOCK = 14;
1277pub const CAP_IPC_OWNER = 15;
1278pub const CAP_SYS_MODULE = 16;
1279pub const CAP_SYS_RAWIO = 17;
1280pub const CAP_SYS_CHROOT = 18;
1281pub const CAP_SYS_PTRACE = 19;
1282pub const CAP_SYS_PACCT = 20;
1283pub const CAP_SYS_ADMIN = 21;
1284pub const CAP_SYS_BOOT = 22;
1285pub const CAP_SYS_NICE = 23;
1286pub const CAP_SYS_RESOURCE = 24;
1287pub const CAP_SYS_TIME = 25;
1288pub const CAP_SYS_TTY_CONFIG = 26;
1289pub const CAP_MKNOD = 27;
1290pub const CAP_LEASE = 28;
1291pub const CAP_AUDIT_WRITE = 29;
1292pub const CAP_AUDIT_CONTROL = 30;
1293pub const CAP_SETFCAP = 31;
1294pub const CAP_MAC_OVERRIDE = 32;
1295pub const CAP_MAC_ADMIN = 33;
1296pub const CAP_SYSLOG = 34;
1297pub const CAP_WAKE_ALARM = 35;
1298pub const CAP_BLOCK_SUSPEND = 36;
1299pub const CAP_AUDIT_READ = 37;
1300pub const CAP_LAST_CAP = CAP_AUDIT_READ;
1301
1302pub fn cap_valid(x: u8) bool {
1303 return x >= 0 and x <= CAP_LAST_CAP;
1304}
1305
1306pub fn CAP_TO_MASK(cap: u8) u32 {
1307 return @as(u32, 1) << @intCast(u5, cap & 31);
1308}
1309
1310pub fn CAP_TO_INDEX(cap: u8) u8 {
1311 return cap >> 5;
1312}
1313
1314pub const cap_t = extern struct {
1315 hdrp: *cap_user_header_t,
1316 datap: *cap_user_data_t,
1317};
1318
1319pub const cap_user_header_t = extern struct {
1320 version: u32,
1321 pid: usize,
1322};
1323
1324pub const cap_user_data_t = extern struct {
1325 effective: u32,
1326 permitted: u32,
1327 inheritable: u32,
1328};
1329
1330pub const inotify_event = extern struct {
1331 wd: i32,
1332 mask: u32,
1333 cookie: u32,
1334 len: u32,
1335 //name: [?]u8,
1336};
1337
1338pub const dirent64 = extern struct {
1339 d_ino: u64,
1340 d_off: u64,
1341 d_reclen: u16,
1342 d_type: u8,
1343 d_name: u8, // field address is the address of first byte of name https://github.com/ziglang/zig/issues/173
1344
1345 pub fn reclen(self: dirent64) u16 {
1346 return self.d_reclen;
1347 }
1348};
1349
1350pub const dl_phdr_info = extern struct {
1351 dlpi_addr: usize,
1352 dlpi_name: ?[*:0]const u8,
1353 dlpi_phdr: [*]std.elf.Phdr,
1354 dlpi_phnum: u16,
1355};
1356
1357pub const CPU_SETSIZE = 128;
1358pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
1359pub const cpu_count_t = std.meta.Int(.unsigned, std.math.log2(CPU_SETSIZE * 8));
1360
1361pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
1362 var sum: cpu_count_t = 0;
1363 for (set) |x| {
1364 sum += @popCount(usize, x);
1365 }
1366 return sum;
1367}
1368
1369// TODO port these over
1370//#define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)
1371//#define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set)
1372//#define CPU_ISSET(i, set) CPU_ISSET_S(i,sizeof(cpu_set_t),set)
1373//#define CPU_AND(d,s1,s2) CPU_AND_S(sizeof(cpu_set_t),d,s1,s2)
1374//#define CPU_OR(d,s1,s2) CPU_OR_S(sizeof(cpu_set_t),d,s1,s2)
1375//#define CPU_XOR(d,s1,s2) CPU_XOR_S(sizeof(cpu_set_t),d,s1,s2)
1376//#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set)
1377//#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set)
1378//#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2)
1379
1380pub const MINSIGSTKSZ = switch (arch) {
1381 .i386, .x86_64, .arm, .mipsel => 2048,
1382 .aarch64 => 5120,
1383 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
1384};
1385pub const SIGSTKSZ = switch (arch) {
1386 .i386, .x86_64, .arm, .mipsel => 8192,
1387 .aarch64 => 16384,
1388 else => @compileError("SIGSTKSZ not defined for this architecture"),
1389};
1390
1391pub const SS_ONSTACK = 1;
1392pub const SS_DISABLE = 2;
1393pub const SS_AUTODISARM = 1 << 31;
1394
1395pub const stack_t = if (is_mips)
1396 // IRIX compatible stack_t
1397 extern struct {
1398 ss_sp: [*]u8,
1399 ss_size: usize,
1400 ss_flags: i32,
1401 }
1402else
1403 extern struct {
1404 ss_sp: [*]u8,
1405 ss_flags: i32,
1406 ss_size: usize,
1407 };
1408
1409pub const sigval = extern union {
1410 int: i32,
1411 ptr: *c_void,
1412};
1413
1414const siginfo_fields_union = extern union {
1415 pad: [128 - 2 * @sizeOf(c_int) - @sizeOf(c_long)]u8,
1416 common: extern struct {
1417 first: extern union {
1418 piduid: extern struct {
1419 pid: pid_t,
1420 uid: uid_t,
1421 },
1422 timer: extern struct {
1423 timerid: i32,
1424 overrun: i32,
1425 },
1426 },
1427 second: extern union {
1428 value: sigval,
1429 sigchld: extern struct {
1430 status: i32,
1431 utime: clock_t,
1432 stime: clock_t,
1433 },
1434 },
1435 },
1436 sigfault: extern struct {
1437 addr: *c_void,
1438 addr_lsb: i16,
1439 first: extern union {
1440 addr_bnd: extern struct {
1441 lower: *c_void,
1442 upper: *c_void,
1443 },
1444 pkey: u32,
1445 },
1446 },
1447 sigpoll: extern struct {
1448 band: isize,
1449 fd: i32,
1450 },
1451 sigsys: extern struct {
1452 call_addr: *c_void,
1453 syscall: i32,
1454 arch: u32,
1455 },
1456};
1457
1458pub const siginfo_t = if (is_mips)
1459 extern struct {
1460 signo: i32,
1461 code: i32,
1462 errno: i32,
1463 fields: siginfo_fields_union,
1464 }
1465else
1466 extern struct {
1467 signo: i32,
1468 errno: i32,
1469 code: i32,
1470 fields: siginfo_fields_union,
1471 };
1472
1473pub const io_uring_params = extern struct {
1474 sq_entries: u32,
1475 cq_entries: u32,
1476 flags: u32,
1477 sq_thread_cpu: u32,
1478 sq_thread_idle: u32,
1479 features: u32,
1480 wq_fd: u32,
1481 resv: [3]u32,
1482 sq_off: io_sqring_offsets,
1483 cq_off: io_cqring_offsets,
1484};
1485
1486// io_uring_params.features flags
1487
1488pub const IORING_FEAT_SINGLE_MMAP = 1 << 0;
1489pub const IORING_FEAT_NODROP = 1 << 1;
1490pub const IORING_FEAT_SUBMIT_STABLE = 1 << 2;
1491pub const IORING_FEAT_RW_CUR_POS = 1 << 3;
1492pub const IORING_FEAT_CUR_PERSONALITY = 1 << 4;
1493pub const IORING_FEAT_FAST_POLL = 1 << 5;
1494pub const IORING_FEAT_POLL_32BITS = 1 << 6;
1495
1496// io_uring_params.flags
1497
1498/// io_context is polled
1499pub const IORING_SETUP_IOPOLL = 1 << 0;
1500
1501/// SQ poll thread
1502pub const IORING_SETUP_SQPOLL = 1 << 1;
1503
1504/// sq_thread_cpu is valid
1505pub const IORING_SETUP_SQ_AFF = 1 << 2;
1506
1507/// app defines CQ size
1508pub const IORING_SETUP_CQSIZE = 1 << 3;
1509
1510/// clamp SQ/CQ ring sizes
1511pub const IORING_SETUP_CLAMP = 1 << 4;
1512
1513/// attach to existing wq
1514pub const IORING_SETUP_ATTACH_WQ = 1 << 5;
1515
1516/// start with ring disabled
1517pub const IORING_SETUP_R_DISABLED = 1 << 6;
1518
1519pub const io_sqring_offsets = extern struct {
1520 /// offset of ring head
1521 head: u32,
1522
1523 /// offset of ring tail
1524 tail: u32,
1525
1526 /// ring mask value
1527 ring_mask: u32,
1528
1529 /// entries in ring
1530 ring_entries: u32,
1531
1532 /// ring flags
1533 flags: u32,
1534
1535 /// number of sqes not submitted
1536 dropped: u32,
1537
1538 /// sqe index array
1539 array: u32,
1540
1541 resv1: u32,
1542 resv2: u64,
1543};
1544
1545// io_sqring_offsets.flags
1546
1547/// needs io_uring_enter wakeup
1548pub const IORING_SQ_NEED_WAKEUP = 1 << 0;
1549
1550/// kernel has cqes waiting beyond the cq ring
1551pub const IORING_SQ_CQ_OVERFLOW = 1 << 1;
1552
1553pub const io_cqring_offsets = extern struct {
1554 head: u32,
1555 tail: u32,
1556 ring_mask: u32,
1557 ring_entries: u32,
1558 overflow: u32,
1559 cqes: u32,
1560 resv: [2]u64,
1561};
1562
1563pub const io_uring_sqe = extern struct {
1564 opcode: IORING_OP,
1565 flags: u8,
1566 ioprio: u16,
1567 fd: i32,
1568 off: u64,
1569 addr: u64,
1570 len: u32,
1571 rw_flags: u32,
1572 user_data: u64,
1573 buf_index: u16,
1574 personality: u16,
1575 splice_fd_in: i32,
1576 __pad2: [2]u64,
1577};
1578
1579pub const IOSQE_BIT = enum(u8) {
1580 FIXED_FILE,
1581 IO_DRAIN,
1582 IO_LINK,
1583 IO_HARDLINK,
1584 ASYNC,
1585 BUFFER_SELECT,
1586
1587 _,
1588};
1589
1590// io_uring_sqe.flags
1591
1592/// use fixed fileset
1593pub const IOSQE_FIXED_FILE = 1 << @enumToInt(IOSQE_BIT.FIXED_FILE);
1594
1595/// issue after inflight IO
1596pub const IOSQE_IO_DRAIN = 1 << @enumToInt(IOSQE_BIT.IO_DRAIN);
1597
1598/// links next sqe
1599pub const IOSQE_IO_LINK = 1 << @enumToInt(IOSQE_BIT.IO_LINK);
1600
1601/// like LINK, but stronger
1602pub const IOSQE_IO_HARDLINK = 1 << @enumToInt(IOSQE_BIT.IO_HARDLINK);
1603
1604/// always go async
1605pub const IOSQE_ASYNC = 1 << @enumToInt(IOSQE_BIT.ASYNC);
1606
1607/// select buffer from buf_group
1608pub const IOSQE_BUFFER_SELECT = 1 << @enumToInt(IOSQE_BIT.BUFFER_SELECT);
1609
1610pub const IORING_OP = enum(u8) {
1611 NOP,
1612 READV,
1613 WRITEV,
1614 FSYNC,
1615 READ_FIXED,
1616 WRITE_FIXED,
1617 POLL_ADD,
1618 POLL_REMOVE,
1619 SYNC_FILE_RANGE,
1620 SENDMSG,
1621 RECVMSG,
1622 TIMEOUT,
1623 TIMEOUT_REMOVE,
1624 ACCEPT,
1625 ASYNC_CANCEL,
1626 LINK_TIMEOUT,
1627 CONNECT,
1628 FALLOCATE,
1629 OPENAT,
1630 CLOSE,
1631 FILES_UPDATE,
1632 STATX,
1633 READ,
1634 WRITE,
1635 FADVISE,
1636 MADVISE,
1637 SEND,
1638 RECV,
1639 OPENAT2,
1640 EPOLL_CTL,
1641 SPLICE,
1642 PROVIDE_BUFFERS,
1643 REMOVE_BUFFERS,
1644 TEE,
1645
1646 _,
1647};
1648
1649// io_uring_sqe.fsync_flags
1650pub const IORING_FSYNC_DATASYNC = 1 << 0;
1651
1652// io_uring_sqe.timeout_flags
1653pub const IORING_TIMEOUT_ABS = 1 << 0;
1654
1655// IO completion data structure (Completion Queue Entry)
1656pub const io_uring_cqe = extern struct {
1657 /// io_uring_sqe.data submission passed back
1658 user_data: u64,
1659
1660 /// result code for this event
1661 res: i32,
1662 flags: u32,
1663
1664 pub fn err(self: io_uring_cqe) E {
1665 if (self.res > -4096 and self.res < 0) {
1666 return @intToEnum(E, -self.res);
1667 }
1668 return .SUCCESS;
1669 }
1670};
1671
1672// io_uring_cqe.flags
1673
1674/// If set, the upper 16 bits are the buffer ID
1675pub const IORING_CQE_F_BUFFER = 1 << 0;
1676
1677pub const IORING_OFF_SQ_RING = 0;
1678pub const IORING_OFF_CQ_RING = 0x8000000;
1679pub const IORING_OFF_SQES = 0x10000000;
1680
1681// io_uring_enter flags
1682pub const IORING_ENTER_GETEVENTS = 1 << 0;
1683pub const IORING_ENTER_SQ_WAKEUP = 1 << 1;
1684
1685// io_uring_register opcodes and arguments
1686pub const IORING_REGISTER = enum(u8) {
1687 REGISTER_BUFFERS,
1688 UNREGISTER_BUFFERS,
1689 REGISTER_FILES,
1690 UNREGISTER_FILES,
1691 REGISTER_EVENTFD,
1692 UNREGISTER_EVENTFD,
1693 REGISTER_FILES_UPDATE,
1694 REGISTER_EVENTFD_ASYNC,
1695 REGISTER_PROBE,
1696 REGISTER_PERSONALITY,
1697 UNREGISTER_PERSONALITY,
1698 REGISTER_RESTRICTIONS,
1699 REGISTER_ENABLE_RINGS,
1700
1701 _,
1702};
1703
1704pub const io_uring_files_update = extern struct {
1705 offset: u32,
1706 resv: u32,
1707 fds: u64,
1708};
1709
1710pub const IO_URING_OP_SUPPORTED = 1 << 0;
1711
1712pub const io_uring_probe_op = extern struct {
1713 op: IORING_OP,
1714
1715 resv: u8,
1716
1717 /// IO_URING_OP_* flags
1718 flags: u16,
1719
1720 resv2: u32,
1721};
1722
1723pub const io_uring_probe = extern struct {
1724 /// last opcode supported
1725 last_op: IORING_OP,
1726
1727 /// Number of io_uring_probe_op following
1728 ops_len: u8,
1729
1730 resv: u16,
1731 resv2: u32[3],
1732
1733 // Followed by up to `ops_len` io_uring_probe_op structures
1734};
1735
1736pub const io_uring_restriction = extern struct {
1737 opcode: u16,
1738 arg: extern union {
1739 /// IORING_RESTRICTION_REGISTER_OP
1740 register_op: IORING_REGISTER,
1741
1742 /// IORING_RESTRICTION_SQE_OP
1743 sqe_op: IORING_OP,
1744
1745 /// IORING_RESTRICTION_SQE_FLAGS_*
1746 sqe_flags: u8,
1747 },
1748 resv: u8,
1749 resv2: u32[3],
1750};
1751
1752/// io_uring_restriction->opcode values
1753pub const IORING_RESTRICTION = enum(u8) {
1754 /// Allow an io_uring_register(2) opcode
1755 REGISTER_OP = 0,
1756
1757 /// Allow an sqe opcode
1758 SQE_OP = 1,
1759
1760 /// Allow sqe flags
1761 SQE_FLAGS_ALLOWED = 2,
1762
1763 /// Require sqe flags (these flags must be set on each submission)
1764 SQE_FLAGS_REQUIRED = 3,
1765
1766 _,
1767};
1768
1769pub const utsname = extern struct {
1770 sysname: [64:0]u8,
1771 nodename: [64:0]u8,
1772 release: [64:0]u8,
1773 version: [64:0]u8,
1774 machine: [64:0]u8,
1775 domainname: [64:0]u8,
1776};
1777pub const HOST_NAME_MAX = 64;
1778
1779pub const STATX_TYPE = 0x0001;
1780pub const STATX_MODE = 0x0002;
1781pub const STATX_NLINK = 0x0004;
1782pub const STATX_UID = 0x0008;
1783pub const STATX_GID = 0x0010;
1784pub const STATX_ATIME = 0x0020;
1785pub const STATX_MTIME = 0x0040;
1786pub const STATX_CTIME = 0x0080;
1787pub const STATX_INO = 0x0100;
1788pub const STATX_SIZE = 0x0200;
1789pub const STATX_BLOCKS = 0x0400;
1790pub const STATX_BASIC_STATS = 0x07ff;
1791
1792pub const STATX_BTIME = 0x0800;
1793
1794pub const STATX_ATTR_COMPRESSED = 0x0004;
1795pub const STATX_ATTR_IMMUTABLE = 0x0010;
1796pub const STATX_ATTR_APPEND = 0x0020;
1797pub const STATX_ATTR_NODUMP = 0x0040;
1798pub const STATX_ATTR_ENCRYPTED = 0x0800;
1799pub const STATX_ATTR_AUTOMOUNT = 0x1000;
1800
1801pub const statx_timestamp = extern struct {
1802 tv_sec: i64,
1803 tv_nsec: u32,
1804 __pad1: u32,
1805};
1806
1807/// Renamed to `Statx` to not conflict with the `statx` function.
1808pub const Statx = extern struct {
1809 /// Mask of bits indicating filled fields
1810 mask: u32,
1811
1812 /// Block size for filesystem I/O
1813 blksize: u32,
1814
1815 /// Extra file attribute indicators
1816 attributes: u64,
1817
1818 /// Number of hard links
1819 nlink: u32,
1820
1821 /// User ID of owner
1822 uid: uid_t,
1823
1824 /// Group ID of owner
1825 gid: gid_t,
1826
1827 /// File type and mode
1828 mode: u16,
1829 __pad1: u16,
1830
1831 /// Inode number
1832 ino: u64,
1833
1834 /// Total size in bytes
1835 size: u64,
1836
1837 /// Number of 512B blocks allocated
1838 blocks: u64,
1839
1840 /// Mask to show what's supported in `attributes`.
1841 attributes_mask: u64,
1842
1843 /// Last access file timestamp
1844 atime: statx_timestamp,
1845
1846 /// Creation file timestamp
1847 btime: statx_timestamp,
1848
1849 /// Last status change file timestamp
1850 ctime: statx_timestamp,
1851
1852 /// Last modification file timestamp
1853 mtime: statx_timestamp,
1854
1855 /// Major ID, if this file represents a device.
1856 rdev_major: u32,
1857
1858 /// Minor ID, if this file represents a device.
1859 rdev_minor: u32,
1860
1861 /// Major ID of the device containing the filesystem where this file resides.
1862 dev_major: u32,
1863
1864 /// Minor ID of the device containing the filesystem where this file resides.
1865 dev_minor: u32,
1866
1867 __pad2: [14]u64,
1868};
1869
1870pub const addrinfo = extern struct {
1871 flags: i32,
1872 family: i32,
1873 socktype: i32,
1874 protocol: i32,
1875 addrlen: socklen_t,
1876 addr: ?*sockaddr,
1877 canonname: ?[*:0]u8,
1878 next: ?*addrinfo,
1879};
1880
1881pub const IPPORT_RESERVED = 1024;
1882
1883pub const IPPROTO_IP = 0;
1884pub const IPPROTO_HOPOPTS = 0;
1885pub const IPPROTO_ICMP = 1;
1886pub const IPPROTO_IGMP = 2;
1887pub const IPPROTO_IPIP = 4;
1888pub const IPPROTO_TCP = 6;
1889pub const IPPROTO_EGP = 8;
1890pub const IPPROTO_PUP = 12;
1891pub const IPPROTO_UDP = 17;
1892pub const IPPROTO_IDP = 22;
1893pub const IPPROTO_TP = 29;
1894pub const IPPROTO_DCCP = 33;
1895pub const IPPROTO_IPV6 = 41;
1896pub const IPPROTO_ROUTING = 43;
1897pub const IPPROTO_FRAGMENT = 44;
1898pub const IPPROTO_RSVP = 46;
1899pub const IPPROTO_GRE = 47;
1900pub const IPPROTO_ESP = 50;
1901pub const IPPROTO_AH = 51;
1902pub const IPPROTO_ICMPV6 = 58;
1903pub const IPPROTO_NONE = 59;
1904pub const IPPROTO_DSTOPTS = 60;
1905pub const IPPROTO_MTP = 92;
1906pub const IPPROTO_BEETPH = 94;
1907pub const IPPROTO_ENCAP = 98;
1908pub const IPPROTO_PIM = 103;
1909pub const IPPROTO_COMP = 108;
1910pub const IPPROTO_SCTP = 132;
1911pub const IPPROTO_MH = 135;
1912pub const IPPROTO_UDPLITE = 136;
1913pub const IPPROTO_MPLS = 137;
1914pub const IPPROTO_RAW = 255;
1915pub const IPPROTO_MAX = 256;
1916
1917pub const RR_A = 1;
1918pub const RR_CNAME = 5;
1919pub const RR_AAAA = 28;
1920
1921/// Turn off Nagle's algorithm
1922pub const TCP_NODELAY = 1;
1923/// Limit MSS
1924pub const TCP_MAXSEG = 2;
1925/// Never send partially complete segments.
1926pub const TCP_CORK = 3;
1927/// Start keeplives after this period, in seconds
1928pub const TCP_KEEPIDLE = 4;
1929/// Interval between keepalives
1930pub const TCP_KEEPINTVL = 5;
1931/// Number of keepalives before death
1932pub const TCP_KEEPCNT = 6;
1933/// Number of SYN retransmits
1934pub const TCP_SYNCNT = 7;
1935/// Life time of orphaned FIN-WAIT-2 state
1936pub const TCP_LINGER2 = 8;
1937/// Wake up listener only when data arrive
1938pub const TCP_DEFER_ACCEPT = 9;
1939/// Bound advertised window
1940pub const TCP_WINDOW_CLAMP = 10;
1941/// Information about this connection.
1942pub const TCP_INFO = 11;
1943/// Block/reenable quick acks
1944pub const TCP_QUICKACK = 12;
1945/// Congestion control algorithm
1946pub const TCP_CONGESTION = 13;
1947/// TCP MD5 Signature (RFC2385)
1948pub const TCP_MD5SIG = 14;
1949/// Use linear timeouts for thin streams
1950pub const TCP_THIN_LINEAR_TIMEOUTS = 16;
1951/// Fast retrans. after 1 dupack
1952pub const TCP_THIN_DUPACK = 17;
1953/// How long for loss retry before timeout
1954pub const TCP_USER_TIMEOUT = 18;
1955/// TCP sock is under repair right now
1956pub const TCP_REPAIR = 19;
1957pub const TCP_REPAIR_QUEUE = 20;
1958pub const TCP_QUEUE_SEQ = 21;
1959pub const TCP_REPAIR_OPTIONS = 22;
1960/// Enable FastOpen on listeners
1961pub const TCP_FASTOPEN = 23;
1962pub const TCP_TIMESTAMP = 24;
1963/// limit number of unsent bytes in write queue
1964pub const TCP_NOTSENT_LOWAT = 25;
1965/// Get Congestion Control (optional) info
1966pub const TCP_CC_INFO = 26;
1967/// Record SYN headers for new connections
1968pub const TCP_SAVE_SYN = 27;
1969/// Get SYN headers recorded for connection
1970pub const TCP_SAVED_SYN = 28;
1971/// Get/set window parameters
1972pub const TCP_REPAIR_WINDOW = 29;
1973/// Attempt FastOpen with connect
1974pub const TCP_FASTOPEN_CONNECT = 30;
1975/// Attach a ULP to a TCP connection
1976pub const TCP_ULP = 31;
1977/// TCP MD5 Signature with extensions
1978pub const TCP_MD5SIG_EXT = 32;
1979/// Set the key for Fast Open (cookie)
1980pub const TCP_FASTOPEN_KEY = 33;
1981/// Enable TFO without a TFO cookie
1982pub const TCP_FASTOPEN_NO_COOKIE = 34;
1983pub const TCP_ZEROCOPY_RECEIVE = 35;
1984/// Notify bytes available to read as a cmsg on read
1985pub const TCP_INQ = 36;
1986pub const TCP_CM_INQ = TCP_INQ;
1987/// delay outgoing packets by XX usec
1988pub const TCP_TX_DELAY = 37;
1989
1990pub const TCP_REPAIR_ON = 1;
1991pub const TCP_REPAIR_OFF = 0;
1992/// Turn off without window probes
1993pub const TCP_REPAIR_OFF_NO_WP = -1;
1994
1995pub const tcp_repair_opt = extern struct {
1996 opt_code: u32,
1997 opt_val: u32,
1998};
1999
2000pub const tcp_repair_window = extern struct {
2001 snd_wl1: u32,
2002 snd_wnd: u32,
2003 max_window: u32,
2004 rcv_wnd: u32,
2005 rcv_wup: u32,
2006};
2007
2008pub const TcpRepairOption = enum {
2009 TCP_NO_QUEUE,
2010 TCP_RECV_QUEUE,
2011 TCP_SEND_QUEUE,
2012 TCP_QUEUES_NR,
2013};
2014
2015/// why fastopen failed from client perspective
2016pub const tcp_fastopen_client_fail = enum {
2017 /// catch-all
2018 TFO_STATUS_UNSPEC,
2019 /// if not in TFO_CLIENT_NO_COOKIE mode
2020 TFO_COOKIE_UNAVAILABLE,
2021 /// SYN-ACK did not ack SYN data
2022 TFO_DATA_NOT_ACKED,
2023 /// SYN-ACK did not ack SYN data after timeout
2024 TFO_SYN_RETRANSMITTED,
2025};
2026
2027/// for TCP_INFO socket option
2028pub const TCPI_OPT_TIMESTAMPS = 1;
2029pub const TCPI_OPT_SACK = 2;
2030pub const TCPI_OPT_WSCALE = 4;
2031/// ECN was negociated at TCP session init
2032pub const TCPI_OPT_ECN = 8;
2033/// we received at least one packet with ECT
2034pub const TCPI_OPT_ECN_SEEN = 16;
2035/// SYN-ACK acked data in SYN sent or rcvd
2036pub const TCPI_OPT_SYN_DATA = 32;
2037
2038pub const nfds_t = usize;
2039pub const pollfd = extern struct {
2040 fd: fd_t,
2041 events: i16,
2042 revents: i16,
2043};
2044
2045pub const POLLIN = 0x001;
2046pub const POLLPRI = 0x002;
2047pub const POLLOUT = 0x004;
2048pub const POLLERR = 0x008;
2049pub const POLLHUP = 0x010;
2050pub const POLLNVAL = 0x020;
2051pub const POLLRDNORM = 0x040;
2052pub const POLLRDBAND = 0x080;
2053
2054pub const MFD_CLOEXEC = 0x0001;
2055pub const MFD_ALLOW_SEALING = 0x0002;
2056pub const MFD_HUGETLB = 0x0004;
2057pub const MFD_ALL_FLAGS = MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB;
2058
2059pub const HUGETLB_FLAG_ENCODE_SHIFT = 26;
2060pub const HUGETLB_FLAG_ENCODE_MASK = 0x3f;
2061pub const HUGETLB_FLAG_ENCODE_64KB = 16 << HUGETLB_FLAG_ENCODE_SHIFT;
2062pub const HUGETLB_FLAG_ENCODE_512KB = 19 << HUGETLB_FLAG_ENCODE_SHIFT;
2063pub const HUGETLB_FLAG_ENCODE_1MB = 20 << HUGETLB_FLAG_ENCODE_SHIFT;
2064pub const HUGETLB_FLAG_ENCODE_2MB = 21 << HUGETLB_FLAG_ENCODE_SHIFT;
2065pub const HUGETLB_FLAG_ENCODE_8MB = 23 << HUGETLB_FLAG_ENCODE_SHIFT;
2066pub const HUGETLB_FLAG_ENCODE_16MB = 24 << HUGETLB_FLAG_ENCODE_SHIFT;
2067pub const HUGETLB_FLAG_ENCODE_32MB = 25 << HUGETLB_FLAG_ENCODE_SHIFT;
2068pub const HUGETLB_FLAG_ENCODE_256MB = 28 << HUGETLB_FLAG_ENCODE_SHIFT;
2069pub const HUGETLB_FLAG_ENCODE_512MB = 29 << HUGETLB_FLAG_ENCODE_SHIFT;
2070pub const HUGETLB_FLAG_ENCODE_1GB = 30 << HUGETLB_FLAG_ENCODE_SHIFT;
2071pub const HUGETLB_FLAG_ENCODE_2GB = 31 << HUGETLB_FLAG_ENCODE_SHIFT;
2072pub const HUGETLB_FLAG_ENCODE_16GB = 34 << HUGETLB_FLAG_ENCODE_SHIFT;
2073
2074pub const MFD_HUGE_SHIFT = HUGETLB_FLAG_ENCODE_SHIFT;
2075pub const MFD_HUGE_MASK = HUGETLB_FLAG_ENCODE_MASK;
2076pub const MFD_HUGE_64KB = HUGETLB_FLAG_ENCODE_64KB;
2077pub const MFD_HUGE_512KB = HUGETLB_FLAG_ENCODE_512KB;
2078pub const MFD_HUGE_1MB = HUGETLB_FLAG_ENCODE_1MB;
2079pub const MFD_HUGE_2MB = HUGETLB_FLAG_ENCODE_2MB;
2080pub const MFD_HUGE_8MB = HUGETLB_FLAG_ENCODE_8MB;
2081pub const MFD_HUGE_16MB = HUGETLB_FLAG_ENCODE_16MB;
2082pub const MFD_HUGE_32MB = HUGETLB_FLAG_ENCODE_32MB;
2083pub const MFD_HUGE_256MB = HUGETLB_FLAG_ENCODE_256MB;
2084pub const MFD_HUGE_512MB = HUGETLB_FLAG_ENCODE_512MB;
2085pub const MFD_HUGE_1GB = HUGETLB_FLAG_ENCODE_1GB;
2086pub const MFD_HUGE_2GB = HUGETLB_FLAG_ENCODE_2GB;
2087pub const MFD_HUGE_16GB = HUGETLB_FLAG_ENCODE_16GB;
2088
2089pub const RUSAGE_SELF = 0;
2090pub const RUSAGE_CHILDREN = -1;
2091pub const RUSAGE_THREAD = 1;
2092
2093pub const rusage = extern struct {
2094 utime: timeval,
2095 stime: timeval,
2096 maxrss: isize,
2097 ixrss: isize,
2098 idrss: isize,
2099 isrss: isize,
2100 minflt: isize,
2101 majflt: isize,
2102 nswap: isize,
2103 inblock: isize,
2104 oublock: isize,
2105 msgsnd: isize,
2106 msgrcv: isize,
2107 nsignals: isize,
2108 nvcsw: isize,
2109 nivcsw: isize,
2110 __reserved: [16]isize = [1]isize{0} ** 16,
2111};
2112
2113pub const cc_t = u8;
2114pub const speed_t = u32;
2115pub const tcflag_t = u32;
2116
2117pub const NCCS = 32;
2118
2119pub const B0 = 0o0000000;
2120pub const B50 = 0o0000001;
2121pub const B75 = 0o0000002;
2122pub const B110 = 0o0000003;
2123pub const B134 = 0o0000004;
2124pub const B150 = 0o0000005;
2125pub const B200 = 0o0000006;
2126pub const B300 = 0o0000007;
2127pub const B600 = 0o0000010;
2128pub const B1200 = 0o0000011;
2129pub const B1800 = 0o0000012;
2130pub const B2400 = 0o0000013;
2131pub const B4800 = 0o0000014;
2132pub const B9600 = 0o0000015;
2133pub const B19200 = 0o0000016;
2134pub const B38400 = 0o0000017;
2135pub const BOTHER = 0o0010000;
2136pub const B57600 = 0o0010001;
2137pub const B115200 = 0o0010002;
2138pub const B230400 = 0o0010003;
2139pub const B460800 = 0o0010004;
2140pub const B500000 = 0o0010005;
2141pub const B576000 = 0o0010006;
2142pub const B921600 = 0o0010007;
2143pub const B1000000 = 0o0010010;
2144pub const B1152000 = 0o0010011;
2145pub const B1500000 = 0o0010012;
2146pub const B2000000 = 0o0010013;
2147pub const B2500000 = 0o0010014;
2148pub const B3000000 = 0o0010015;
2149pub const B3500000 = 0o0010016;
2150pub const B4000000 = 0o0010017;
2151
2152pub usingnamespace switch (arch) {
2153 .powerpc, .powerpc64, .powerpc64le => struct {
2154 pub const VINTR = 0;
2155 pub const VQUIT = 1;
2156 pub const VERASE = 2;
2157 pub const VKILL = 3;
2158 pub const VEOF = 4;
2159 pub const VMIN = 5;
2160 pub const VEOL = 6;
2161 pub const VTIME = 7;
2162 pub const VEOL2 = 8;
2163 pub const VSWTC = 9;
2164 pub const VWERASE = 10;
2165 pub const VREPRINT = 11;
2166 pub const VSUSP = 12;
2167 pub const VSTART = 13;
2168 pub const VSTOP = 14;
2169 pub const VLNEXT = 15;
2170 pub const VDISCARD = 16;
2171 },
2172 .sparc, .sparcv9 => struct {
2173 pub const VINTR = 0;
2174 pub const VQUIT = 1;
2175 pub const VERASE = 2;
2176 pub const VKILL = 3;
2177 pub const VEOF = 4;
2178 pub const VEOL = 5;
2179 pub const VEOL2 = 6;
2180 pub const VSWTC = 7;
2181 pub const VSTART = 8;
2182 pub const VSTOP = 9;
2183 pub const VSUSP = 10;
2184 pub const VDSUSP = 11;
2185 pub const VREPRINT = 12;
2186 pub const VDISCARD = 13;
2187 pub const VWERASE = 14;
2188 pub const VLNEXT = 15;
2189 pub const VMIN = VEOF;
2190 pub const VTIME = VEOL;
2191 },
2192 .mips, .mipsel, .mips64, .mips64el => struct {
2193 pub const VINTR = 0;
2194 pub const VQUIT = 1;
2195 pub const VERASE = 2;
2196 pub const VKILL = 3;
2197 pub const VMIN = 4;
2198 pub const VTIME = 5;
2199 pub const VEOL2 = 6;
2200 pub const VSWTC = 7;
2201 pub const VSWTCH = 7;
2202 pub const VSTART = 8;
2203 pub const VSTOP = 9;
2204 pub const VSUSP = 10;
2205 pub const VREPRINT = 12;
2206 pub const VDISCARD = 13;
2207 pub const VWERASE = 14;
2208 pub const VLNEXT = 15;
2209 pub const VEOF = 16;
2210 pub const VEOL = 17;
2211 },
2212 else => struct {
2213 pub const VINTR = 0;
2214 pub const VQUIT = 1;
2215 pub const VERASE = 2;
2216 pub const VKILL = 3;
2217 pub const VEOF = 4;
2218 pub const VTIME = 5;
2219 pub const VMIN = 6;
2220 pub const VSWTC = 7;
2221 pub const VSTART = 8;
2222 pub const VSTOP = 9;
2223 pub const VSUSP = 10;
2224 pub const VEOL = 11;
2225 pub const VREPRINT = 12;
2226 pub const VDISCARD = 13;
2227 pub const VWERASE = 14;
2228 pub const VLNEXT = 15;
2229 pub const VEOL2 = 16;
2230 },
2231};
2232
2233pub const IGNBRK = 1;
2234pub const BRKINT = 2;
2235pub const IGNPAR = 4;
2236pub const PARMRK = 8;
2237pub const INPCK = 16;
2238pub const ISTRIP = 32;
2239pub const INLCR = 64;
2240pub const IGNCR = 128;
2241pub const ICRNL = 256;
2242pub const IUCLC = 512;
2243pub const IXON = 1024;
2244pub const IXANY = 2048;
2245pub const IXOFF = 4096;
2246pub const IMAXBEL = 8192;
2247pub const IUTF8 = 16384;
2248
2249pub const OPOST = 1;
2250pub const OLCUC = 2;
2251pub const ONLCR = 4;
2252pub const OCRNL = 8;
2253pub const ONOCR = 16;
2254pub const ONLRET = 32;
2255pub const OFILL = 64;
2256pub const OFDEL = 128;
2257pub const VTDLY = 16384;
2258pub const VT0 = 0;
2259pub const VT1 = 16384;
2260
2261pub const CSIZE = 48;
2262pub const CS5 = 0;
2263pub const CS6 = 16;
2264pub const CS7 = 32;
2265pub const CS8 = 48;
2266pub const CSTOPB = 64;
2267pub const CREAD = 128;
2268pub const PARENB = 256;
2269pub const PARODD = 512;
2270pub const HUPCL = 1024;
2271pub const CLOCAL = 2048;
2272
2273pub const ISIG = 1;
2274pub const ICANON = 2;
2275pub const ECHO = 8;
2276pub const ECHOE = 16;
2277pub const ECHOK = 32;
2278pub const ECHONL = 64;
2279pub const NOFLSH = 128;
2280pub const TOSTOP = 256;
2281pub const IEXTEN = 32768;
2282
2283pub const TCSA = enum(c_uint) {
2284 NOW,
2285 DRAIN,
2286 FLUSH,
2287 _,
2288};
2289
2290pub const termios = extern struct {
2291 iflag: tcflag_t,
2292 oflag: tcflag_t,
2293 cflag: tcflag_t,
2294 lflag: tcflag_t,
2295 line: cc_t,
2296 cc: [NCCS]cc_t,
2297 ispeed: speed_t,
2298 ospeed: speed_t,
2299};
2300
2301pub const SIOCGIFINDEX = 0x8933;
2302pub const IFNAMESIZE = 16;
2303
2304pub const ifmap = extern struct {
2305 mem_start: u32,
2306 mem_end: u32,
2307 base_addr: u16,
2308 irq: u8,
2309 dma: u8,
2310 port: u8,
2311};
2312
2313pub const ifreq = extern struct {
2314 ifrn: extern union {
2315 name: [IFNAMESIZE]u8,
2316 },
2317 ifru: extern union {
2318 addr: sockaddr,
2319 dstaddr: sockaddr,
2320 broadaddr: sockaddr,
2321 netmask: sockaddr,
2322 hwaddr: sockaddr,
2323 flags: i16,
2324 ivalue: i32,
2325 mtu: i32,
2326 map: ifmap,
2327 slave: [IFNAMESIZE - 1:0]u8,
2328 newname: [IFNAMESIZE - 1:0]u8,
2329 data: ?[*]u8,
2330 },
2331};
2332
2333// doc comments copied from musl
2334pub const rlimit_resource = enum(c_int) {
2335 /// Per-process CPU limit, in seconds.
2336 CPU,
2337
2338 /// Largest file that can be created, in bytes.
2339 FSIZE,
2340
2341 /// Maximum size of data segment, in bytes.
2342 DATA,
2343
2344 /// Maximum size of stack segment, in bytes.
2345 STACK,
2346
2347 /// Largest core file that can be created, in bytes.
2348 CORE,
2349
2350 /// Largest resident set size, in bytes.
2351 /// This affects swapping; processes that are exceeding their
2352 /// resident set size will be more likely to have physical memory
2353 /// taken from them.
2354 RSS,
2355
2356 /// Number of processes.
2357 NPROC,
2358
2359 /// Number of open files.
2360 NOFILE,
2361
2362 /// Locked-in-memory address space.
2363 MEMLOCK,
2364
2365 /// Address space limit.
2366 AS,
2367
2368 /// Maximum number of file locks.
2369 LOCKS,
2370
2371 /// Maximum number of pending signals.
2372 SIGPENDING,
2373
2374 /// Maximum bytes in POSIX message queues.
2375 MSGQUEUE,
2376
2377 /// Maximum nice priority allowed to raise to.
2378 /// Nice levels 19 .. -20 correspond to 0 .. 39
2379 /// values of this resource limit.
2380 NICE,
2381
2382 /// Maximum realtime priority allowed for non-priviledged
2383 /// processes.
2384 RTPRIO,
2385
2386 /// Maximum CPU time in µs that a process scheduled under a real-time
2387 /// scheduling policy may consume without making a blocking system
2388 /// call before being forcibly descheduled.
2389 RTTIME,
2390
2391 _,
2392};
2393
2394pub const rlim_t = u64;
2395
2396/// No limit
2397pub const RLIM_INFINITY = ~@as(rlim_t, 0);
2398
2399pub const RLIM_SAVED_MAX = RLIM_INFINITY;
2400pub const RLIM_SAVED_CUR = RLIM_INFINITY;
2401
2402pub const rlimit = extern struct {
2403 /// Soft limit
2404 cur: rlim_t,
2405 /// Hard limit
2406 max: rlim_t,
2407};
2408
2409pub const MADV_NORMAL = 0;
2410pub const MADV_RANDOM = 1;
2411pub const MADV_SEQUENTIAL = 2;
2412pub const MADV_WILLNEED = 3;
2413pub const MADV_DONTNEED = 4;
2414pub const MADV_FREE = 8;
2415pub const MADV_REMOVE = 9;
2416pub const MADV_DONTFORK = 10;
2417pub const MADV_DOFORK = 11;
2418pub const MADV_MERGEABLE = 12;
2419pub const MADV_UNMERGEABLE = 13;
2420pub const MADV_HUGEPAGE = 14;
2421pub const MADV_NOHUGEPAGE = 15;
2422pub const MADV_DONTDUMP = 16;
2423pub const MADV_DODUMP = 17;
2424pub const MADV_WIPEONFORK = 18;
2425pub const MADV_KEEPONFORK = 19;
2426pub const MADV_COLD = 20;
2427pub const MADV_PAGEOUT = 21;
2428pub const MADV_HWPOISON = 100;
2429pub const MADV_SOFT_OFFLINE = 101;
2430
2431pub const POSIX_FADV_NORMAL = 0;
2432pub const POSIX_FADV_RANDOM = 1;
2433pub const POSIX_FADV_SEQUENTIAL = 2;
2434pub const POSIX_FADV_WILLNEED = 3;
2435pub usingnamespace switch (arch) {
2436 .s390x => if (@typeInfo(usize).Int.bits == 64)
2437 struct {
2438 pub const POSIX_FADV_DONTNEED = 6;
2439 pub const POSIX_FADV_NOREUSE = 7;
2440 }
2441 else
2442 struct {
2443 pub const POSIX_FADV_DONTNEED = 4;
2444 pub const POSIX_FADV_NOREUSE = 5;
2445 },
2446 else => struct {
2447 pub const POSIX_FADV_DONTNEED = 4;
2448 pub const POSIX_FADV_NOREUSE = 5;
2449 },
2450};
2451
2452pub const __kernel_timespec = extern struct {
2453 tv_sec: i64,
2454 tv_nsec: i64,
2455};
lib/std/os/bits/linux/arm-eabi.zig deleted-636
...@@ -1,636 +0,0 @@
1// arm-eabi-specific declarations that are intended to be imported into the POSIX namespace.
2const std = @import("../../../std.zig");
3const linux = std.os.linux;
4const socklen_t = linux.socklen_t;
5const iovec = linux.iovec;
6const iovec_const = linux.iovec_const;
7const stack_t = linux.stack_t;
8const sigset_t = linux.sigset_t;
9const uid_t = linux.uid_t;
10const gid_t = linux.gid_t;
11const pid_t = linux.pid_t;
12
13pub const SYS = enum(usize) {
14 restart_syscall = 0,
15 exit = 1,
16 fork = 2,
17 read = 3,
18 write = 4,
19 open = 5,
20 close = 6,
21 creat = 8,
22 link = 9,
23 unlink = 10,
24 execve = 11,
25 chdir = 12,
26 mknod = 14,
27 chmod = 15,
28 lchown = 16,
29 lseek = 19,
30 getpid = 20,
31 mount = 21,
32 setuid = 23,
33 getuid = 24,
34 ptrace = 26,
35 pause = 29,
36 access = 33,
37 nice = 34,
38 sync = 36,
39 kill = 37,
40 rename = 38,
41 mkdir = 39,
42 rmdir = 40,
43 dup = 41,
44 pipe = 42,
45 times = 43,
46 brk = 45,
47 setgid = 46,
48 getgid = 47,
49 geteuid = 49,
50 getegid = 50,
51 acct = 51,
52 umount2 = 52,
53 ioctl = 54,
54 fcntl = 55,
55 setpgid = 57,
56 umask = 60,
57 chroot = 61,
58 ustat = 62,
59 dup2 = 63,
60 getppid = 64,
61 getpgrp = 65,
62 setsid = 66,
63 sigaction = 67,
64 setreuid = 70,
65 setregid = 71,
66 sigsuspend = 72,
67 sigpending = 73,
68 sethostname = 74,
69 setrlimit = 75,
70 getrusage = 77,
71 gettimeofday = 78,
72 settimeofday = 79,
73 getgroups = 80,
74 setgroups = 81,
75 symlink = 83,
76 readlink = 85,
77 uselib = 86,
78 swapon = 87,
79 reboot = 88,
80 munmap = 91,
81 truncate = 92,
82 ftruncate = 93,
83 fchmod = 94,
84 fchown = 95,
85 getpriority = 96,
86 setpriority = 97,
87 statfs = 99,
88 fstatfs = 100,
89 syslog = 103,
90 setitimer = 104,
91 getitimer = 105,
92 stat = 106,
93 lstat = 107,
94 fstat = 108,
95 vhangup = 111,
96 wait4 = 114,
97 swapoff = 115,
98 sysinfo = 116,
99 fsync = 118,
100 sigreturn = 119,
101 clone = 120,
102 setdomainname = 121,
103 uname = 122,
104 adjtimex = 124,
105 mprotect = 125,
106 sigprocmask = 126,
107 init_module = 128,
108 delete_module = 129,
109 quotactl = 131,
110 getpgid = 132,
111 fchdir = 133,
112 bdflush = 134,
113 sysfs = 135,
114 personality = 136,
115 setfsuid = 138,
116 setfsgid = 139,
117 _llseek = 140,
118 getdents = 141,
119 _newselect = 142,
120 flock = 143,
121 msync = 144,
122 readv = 145,
123 writev = 146,
124 getsid = 147,
125 fdatasync = 148,
126 _sysctl = 149,
127 mlock = 150,
128 munlock = 151,
129 mlockall = 152,
130 munlockall = 153,
131 sched_setparam = 154,
132 sched_getparam = 155,
133 sched_setscheduler = 156,
134 sched_getscheduler = 157,
135 sched_yield = 158,
136 sched_get_priority_max = 159,
137 sched_get_priority_min = 160,
138 sched_rr_get_interval = 161,
139 nanosleep = 162,
140 mremap = 163,
141 setresuid = 164,
142 getresuid = 165,
143 poll = 168,
144 nfsservctl = 169,
145 setresgid = 170,
146 getresgid = 171,
147 prctl = 172,
148 rt_sigreturn = 173,
149 rt_sigaction = 174,
150 rt_sigprocmask = 175,
151 rt_sigpending = 176,
152 rt_sigtimedwait = 177,
153 rt_sigqueueinfo = 178,
154 rt_sigsuspend = 179,
155 pread64 = 180,
156 pwrite64 = 181,
157 chown = 182,
158 getcwd = 183,
159 capget = 184,
160 capset = 185,
161 sigaltstack = 186,
162 sendfile = 187,
163 vfork = 190,
164 ugetrlimit = 191,
165 mmap2 = 192,
166 truncate64 = 193,
167 ftruncate64 = 194,
168 stat64 = 195,
169 lstat64 = 196,
170 fstat64 = 197,
171 lchown32 = 198,
172 getuid32 = 199,
173 getgid32 = 200,
174 geteuid32 = 201,
175 getegid32 = 202,
176 setreuid32 = 203,
177 setregid32 = 204,
178 getgroups32 = 205,
179 setgroups32 = 206,
180 fchown32 = 207,
181 setresuid32 = 208,
182 getresuid32 = 209,
183 setresgid32 = 210,
184 getresgid32 = 211,
185 chown32 = 212,
186 setuid32 = 213,
187 setgid32 = 214,
188 setfsuid32 = 215,
189 setfsgid32 = 216,
190 getdents64 = 217,
191 pivot_root = 218,
192 mincore = 219,
193 madvise = 220,
194 fcntl64 = 221,
195 gettid = 224,
196 readahead = 225,
197 setxattr = 226,
198 lsetxattr = 227,
199 fsetxattr = 228,
200 getxattr = 229,
201 lgetxattr = 230,
202 fgetxattr = 231,
203 listxattr = 232,
204 llistxattr = 233,
205 flistxattr = 234,
206 removexattr = 235,
207 lremovexattr = 236,
208 fremovexattr = 237,
209 tkill = 238,
210 sendfile64 = 239,
211 futex = 240,
212 sched_setaffinity = 241,
213 sched_getaffinity = 242,
214 io_setup = 243,
215 io_destroy = 244,
216 io_getevents = 245,
217 io_submit = 246,
218 io_cancel = 247,
219 exit_group = 248,
220 lookup_dcookie = 249,
221 epoll_create = 250,
222 epoll_ctl = 251,
223 epoll_wait = 252,
224 remap_file_pages = 253,
225 set_tid_address = 256,
226 timer_create = 257,
227 timer_settime = 258,
228 timer_gettime = 259,
229 timer_getoverrun = 260,
230 timer_delete = 261,
231 clock_settime = 262,
232 clock_gettime = 263,
233 clock_getres = 264,
234 clock_nanosleep = 265,
235 statfs64 = 266,
236 fstatfs64 = 267,
237 tgkill = 268,
238 utimes = 269,
239 fadvise64_64 = 270,
240 pciconfig_iobase = 271,
241 pciconfig_read = 272,
242 pciconfig_write = 273,
243 mq_open = 274,
244 mq_unlink = 275,
245 mq_timedsend = 276,
246 mq_timedreceive = 277,
247 mq_notify = 278,
248 mq_getsetattr = 279,
249 waitid = 280,
250 socket = 281,
251 bind = 282,
252 connect = 283,
253 listen = 284,
254 accept = 285,
255 getsockname = 286,
256 getpeername = 287,
257 socketpair = 288,
258 send = 289,
259 sendto = 290,
260 recv = 291,
261 recvfrom = 292,
262 shutdown = 293,
263 setsockopt = 294,
264 getsockopt = 295,
265 sendmsg = 296,
266 recvmsg = 297,
267 semop = 298,
268 semget = 299,
269 semctl = 300,
270 msgsnd = 301,
271 msgrcv = 302,
272 msgget = 303,
273 msgctl = 304,
274 shmat = 305,
275 shmdt = 306,
276 shmget = 307,
277 shmctl = 308,
278 add_key = 309,
279 request_key = 310,
280 keyctl = 311,
281 semtimedop = 312,
282 vserver = 313,
283 ioprio_set = 314,
284 ioprio_get = 315,
285 inotify_init = 316,
286 inotify_add_watch = 317,
287 inotify_rm_watch = 318,
288 mbind = 319,
289 get_mempolicy = 320,
290 set_mempolicy = 321,
291 openat = 322,
292 mkdirat = 323,
293 mknodat = 324,
294 fchownat = 325,
295 futimesat = 326,
296 fstatat64 = 327,
297 unlinkat = 328,
298 renameat = 329,
299 linkat = 330,
300 symlinkat = 331,
301 readlinkat = 332,
302 fchmodat = 333,
303 faccessat = 334,
304 pselect6 = 335,
305 ppoll = 336,
306 unshare = 337,
307 set_robust_list = 338,
308 get_robust_list = 339,
309 splice = 340,
310 sync_file_range = 341,
311 tee = 342,
312 vmsplice = 343,
313 move_pages = 344,
314 getcpu = 345,
315 epoll_pwait = 346,
316 kexec_load = 347,
317 utimensat = 348,
318 signalfd = 349,
319 timerfd_create = 350,
320 eventfd = 351,
321 fallocate = 352,
322 timerfd_settime = 353,
323 timerfd_gettime = 354,
324 signalfd4 = 355,
325 eventfd2 = 356,
326 epoll_create1 = 357,
327 dup3 = 358,
328 pipe2 = 359,
329 inotify_init1 = 360,
330 preadv = 361,
331 pwritev = 362,
332 rt_tgsigqueueinfo = 363,
333 perf_event_open = 364,
334 recvmmsg = 365,
335 accept4 = 366,
336 fanotify_init = 367,
337 fanotify_mark = 368,
338 prlimit64 = 369,
339 name_to_handle_at = 370,
340 open_by_handle_at = 371,
341 clock_adjtime = 372,
342 syncfs = 373,
343 sendmmsg = 374,
344 setns = 375,
345 process_vm_readv = 376,
346 process_vm_writev = 377,
347 kcmp = 378,
348 finit_module = 379,
349 sched_setattr = 380,
350 sched_getattr = 381,
351 renameat2 = 382,
352 seccomp = 383,
353 getrandom = 384,
354 memfd_create = 385,
355 bpf = 386,
356 execveat = 387,
357 userfaultfd = 388,
358 membarrier = 389,
359 mlock2 = 390,
360 copy_file_range = 391,
361 preadv2 = 392,
362 pwritev2 = 393,
363 pkey_mprotect = 394,
364 pkey_alloc = 395,
365 pkey_free = 396,
366 statx = 397,
367 rseq = 398,
368 io_pgetevents = 399,
369 migrate_pages = 400,
370 kexec_file_load = 401,
371 clock_gettime64 = 403,
372 clock_settime64 = 404,
373 clock_adjtime64 = 405,
374 clock_getres_time64 = 406,
375 clock_nanosleep_time64 = 407,
376 timer_gettime64 = 408,
377 timer_settime64 = 409,
378 timerfd_gettime64 = 410,
379 timerfd_settime64 = 411,
380 utimensat_time64 = 412,
381 pselect6_time64 = 413,
382 ppoll_time64 = 414,
383 io_pgetevents_time64 = 416,
384 recvmmsg_time64 = 417,
385 mq_timedsend_time64 = 418,
386 mq_timedreceive_time64 = 419,
387 semtimedop_time64 = 420,
388 rt_sigtimedwait_time64 = 421,
389 futex_time64 = 422,
390 sched_rr_get_interval_time64 = 423,
391 pidfd_send_signal = 424,
392 io_uring_setup = 425,
393 io_uring_enter = 426,
394 io_uring_register = 427,
395 open_tree = 428,
396 move_mount = 429,
397 fsopen = 430,
398 fsconfig = 431,
399 fsmount = 432,
400 fspick = 433,
401 pidfd_open = 434,
402 clone3 = 435,
403 close_range = 436,
404 openat2 = 437,
405 pidfd_getfd = 438,
406 faccessat2 = 439,
407 process_madvise = 440,
408 epoll_pwait2 = 441,
409
410 breakpoint = 0x0f0001,
411 cacheflush = 0x0f0002,
412 usr26 = 0x0f0003,
413 usr32 = 0x0f0004,
414 set_tls = 0x0f0005,
415 get_tls = 0x0f0006,
416
417 _,
418};
419
420pub const MMAP2_UNIT = 4096;
421
422pub const O_CREAT = 0o100;
423pub const O_EXCL = 0o200;
424pub const O_NOCTTY = 0o400;
425pub const O_TRUNC = 0o1000;
426pub const O_APPEND = 0o2000;
427pub const O_NONBLOCK = 0o4000;
428pub const O_DSYNC = 0o10000;
429pub const O_SYNC = 0o4010000;
430pub const O_RSYNC = 0o4010000;
431pub const O_DIRECTORY = 0o40000;
432pub const O_NOFOLLOW = 0o100000;
433pub const O_CLOEXEC = 0o2000000;
434
435pub const O_ASYNC = 0o20000;
436pub const O_DIRECT = 0o200000;
437pub const O_LARGEFILE = 0o400000;
438pub const O_NOATIME = 0o1000000;
439pub const O_PATH = 0o10000000;
440pub const O_TMPFILE = 0o20040000;
441pub const O_NDELAY = O_NONBLOCK;
442
443pub const F_DUPFD = 0;
444pub const F_GETFD = 1;
445pub const F_SETFD = 2;
446pub const F_GETFL = 3;
447pub const F_SETFL = 4;
448
449pub const F_SETOWN = 8;
450pub const F_GETOWN = 9;
451pub const F_SETSIG = 10;
452pub const F_GETSIG = 11;
453
454pub const F_GETLK = 12;
455pub const F_SETLK = 13;
456pub const F_SETLKW = 14;
457
458pub const F_RDLCK = 0;
459pub const F_WRLCK = 1;
460pub const F_UNLCK = 2;
461
462pub const F_SETOWN_EX = 15;
463pub const F_GETOWN_EX = 16;
464
465pub const F_GETOWNER_UIDS = 17;
466
467pub const LOCK_SH = 1;
468pub const LOCK_EX = 2;
469pub const LOCK_UN = 8;
470pub const LOCK_NB = 4;
471
472/// stack-like segment
473pub const MAP_GROWSDOWN = 0x0100;
474
475/// ETXTBSY
476pub const MAP_DENYWRITE = 0x0800;
477
478/// mark it as an executable
479pub const MAP_EXECUTABLE = 0x1000;
480
481/// pages are locked
482pub const MAP_LOCKED = 0x2000;
483
484/// don't check for reservations
485pub const MAP_NORESERVE = 0x4000;
486
487pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
488pub const VDSO_CGT_VER = "LINUX_2.6";
489
490pub const HWCAP_SWP = 1 << 0;
491pub const HWCAP_HALF = 1 << 1;
492pub const HWCAP_THUMB = 1 << 2;
493pub const HWCAP_26BIT = 1 << 3;
494pub const HWCAP_FAST_MULT = 1 << 4;
495pub const HWCAP_FPA = 1 << 5;
496pub const HWCAP_VFP = 1 << 6;
497pub const HWCAP_EDSP = 1 << 7;
498pub const HWCAP_JAVA = 1 << 8;
499pub const HWCAP_IWMMXT = 1 << 9;
500pub const HWCAP_CRUNCH = 1 << 10;
501pub const HWCAP_THUMBEE = 1 << 11;
502pub const HWCAP_NEON = 1 << 12;
503pub const HWCAP_VFPv3 = 1 << 13;
504pub const HWCAP_VFPv3D16 = 1 << 14;
505pub const HWCAP_TLS = 1 << 15;
506pub const HWCAP_VFPv4 = 1 << 16;
507pub const HWCAP_IDIVA = 1 << 17;
508pub const HWCAP_IDIVT = 1 << 18;
509pub const HWCAP_VFPD32 = 1 << 19;
510pub const HWCAP_IDIV = HWCAP_IDIVA | HWCAP_IDIVT;
511pub const HWCAP_LPAE = 1 << 20;
512pub const HWCAP_EVTSTRM = 1 << 21;
513
514pub const Flock = extern struct {
515 l_type: i16,
516 l_whence: i16,
517 __pad0: [4]u8,
518 l_start: off_t,
519 l_len: off_t,
520 l_pid: pid_t,
521 __unused: [4]u8,
522};
523
524pub const msghdr = extern struct {
525 msg_name: ?*sockaddr,
526 msg_namelen: socklen_t,
527 msg_iov: [*]iovec,
528 msg_iovlen: i32,
529 msg_control: ?*c_void,
530 msg_controllen: socklen_t,
531 msg_flags: i32,
532};
533
534pub const msghdr_const = extern struct {
535 msg_name: ?*const sockaddr,
536 msg_namelen: socklen_t,
537 msg_iov: [*]iovec_const,
538 msg_iovlen: i32,
539 msg_control: ?*c_void,
540 msg_controllen: socklen_t,
541 msg_flags: i32,
542};
543
544pub const blksize_t = i32;
545pub const nlink_t = u32;
546pub const time_t = isize;
547pub const mode_t = u32;
548pub const off_t = i64;
549pub const ino_t = u64;
550pub const dev_t = u64;
551pub const blkcnt_t = i64;
552
553// The `stat` definition used by the Linux kernel.
554pub const kernel_stat = extern struct {
555 dev: dev_t,
556 __dev_padding: u32,
557 __ino_truncated: u32,
558 mode: mode_t,
559 nlink: nlink_t,
560 uid: uid_t,
561 gid: gid_t,
562 rdev: dev_t,
563 __rdev_padding: u32,
564 size: off_t,
565 blksize: blksize_t,
566 blocks: blkcnt_t,
567 atim: timespec,
568 mtim: timespec,
569 ctim: timespec,
570 ino: ino_t,
571
572 pub fn atime(self: @This()) timespec {
573 return self.atim;
574 }
575
576 pub fn mtime(self: @This()) timespec {
577 return self.mtim;
578 }
579
580 pub fn ctime(self: @This()) timespec {
581 return self.ctim;
582 }
583};
584
585// The `stat64` definition used by the libc.
586pub const libc_stat = kernel_stat;
587
588pub const timespec = extern struct {
589 tv_sec: i32,
590 tv_nsec: i32,
591};
592
593pub const timeval = extern struct {
594 tv_sec: i32,
595 tv_usec: i32,
596};
597
598pub const timezone = extern struct {
599 tz_minuteswest: i32,
600 tz_dsttime: i32,
601};
602
603pub const mcontext_t = extern struct {
604 trap_no: usize,
605 error_code: usize,
606 oldmask: usize,
607 arm_r0: usize,
608 arm_r1: usize,
609 arm_r2: usize,
610 arm_r3: usize,
611 arm_r4: usize,
612 arm_r5: usize,
613 arm_r6: usize,
614 arm_r7: usize,
615 arm_r8: usize,
616 arm_r9: usize,
617 arm_r10: usize,
618 arm_fp: usize,
619 arm_ip: usize,
620 arm_sp: usize,
621 arm_lr: usize,
622 arm_pc: usize,
623 arm_cpsr: usize,
624 fault_address: usize,
625};
626
627pub const ucontext_t = extern struct {
628 flags: usize,
629 link: *ucontext_t,
630 stack: stack_t,
631 mcontext: mcontext_t,
632 sigmask: sigset_t,
633 regspace: [64]u64,
634};
635
636pub const Elf_Symndx = u32;
lib/std/os/bits/linux/arm64.zig deleted-495
...@@ -1,495 +0,0 @@
1// arm64-specific declarations that are intended to be imported into the POSIX namespace.
2// This does include Linux-only APIs.
3
4const std = @import("../../../std.zig");
5const linux = std.os.linux;
6const socklen_t = linux.socklen_t;
7const sockaddr = linux.sockaddr;
8const iovec = linux.iovec;
9const iovec_const = linux.iovec_const;
10const uid_t = linux.uid_t;
11const gid_t = linux.gid_t;
12const pid_t = linux.pid_t;
13const stack_t = linux.stack_t;
14const sigset_t = linux.sigset_t;
15pub const SYS = enum(usize) {
16 io_setup = 0,
17 io_destroy = 1,
18 io_submit = 2,
19 io_cancel = 3,
20 io_getevents = 4,
21 setxattr = 5,
22 lsetxattr = 6,
23 fsetxattr = 7,
24 getxattr = 8,
25 lgetxattr = 9,
26 fgetxattr = 10,
27 listxattr = 11,
28 llistxattr = 12,
29 flistxattr = 13,
30 removexattr = 14,
31 lremovexattr = 15,
32 fremovexattr = 16,
33 getcwd = 17,
34 lookup_dcookie = 18,
35 eventfd2 = 19,
36 epoll_create1 = 20,
37 epoll_ctl = 21,
38 epoll_pwait = 22,
39 dup = 23,
40 dup3 = 24,
41 fcntl = 25,
42 inotify_init1 = 26,
43 inotify_add_watch = 27,
44 inotify_rm_watch = 28,
45 ioctl = 29,
46 ioprio_set = 30,
47 ioprio_get = 31,
48 flock = 32,
49 mknodat = 33,
50 mkdirat = 34,
51 unlinkat = 35,
52 symlinkat = 36,
53 linkat = 37,
54 renameat = 38,
55 umount2 = 39,
56 mount = 40,
57 pivot_root = 41,
58 nfsservctl = 42,
59 statfs = 43,
60 fstatfs = 44,
61 truncate = 45,
62 ftruncate = 46,
63 fallocate = 47,
64 faccessat = 48,
65 chdir = 49,
66 fchdir = 50,
67 chroot = 51,
68 fchmod = 52,
69 fchmodat = 53,
70 fchownat = 54,
71 fchown = 55,
72 openat = 56,
73 close = 57,
74 vhangup = 58,
75 pipe2 = 59,
76 quotactl = 60,
77 getdents64 = 61,
78 lseek = 62,
79 read = 63,
80 write = 64,
81 readv = 65,
82 writev = 66,
83 pread64 = 67,
84 pwrite64 = 68,
85 preadv = 69,
86 pwritev = 70,
87 sendfile = 71,
88 pselect6 = 72,
89 ppoll = 73,
90 signalfd4 = 74,
91 vmsplice = 75,
92 splice = 76,
93 tee = 77,
94 readlinkat = 78,
95 fstatat = 79,
96 fstat = 80,
97 sync = 81,
98 fsync = 82,
99 fdatasync = 83,
100 sync_file_range = 84,
101 timerfd_create = 85,
102 timerfd_settime = 86,
103 timerfd_gettime = 87,
104 utimensat = 88,
105 acct = 89,
106 capget = 90,
107 capset = 91,
108 personality = 92,
109 exit = 93,
110 exit_group = 94,
111 waitid = 95,
112 set_tid_address = 96,
113 unshare = 97,
114 futex = 98,
115 set_robust_list = 99,
116 get_robust_list = 100,
117 nanosleep = 101,
118 getitimer = 102,
119 setitimer = 103,
120 kexec_load = 104,
121 init_module = 105,
122 delete_module = 106,
123 timer_create = 107,
124 timer_gettime = 108,
125 timer_getoverrun = 109,
126 timer_settime = 110,
127 timer_delete = 111,
128 clock_settime = 112,
129 clock_gettime = 113,
130 clock_getres = 114,
131 clock_nanosleep = 115,
132 syslog = 116,
133 ptrace = 117,
134 sched_setparam = 118,
135 sched_setscheduler = 119,
136 sched_getscheduler = 120,
137 sched_getparam = 121,
138 sched_setaffinity = 122,
139 sched_getaffinity = 123,
140 sched_yield = 124,
141 sched_get_priority_max = 125,
142 sched_get_priority_min = 126,
143 sched_rr_get_interval = 127,
144 restart_syscall = 128,
145 kill = 129,
146 tkill = 130,
147 tgkill = 131,
148 sigaltstack = 132,
149 rt_sigsuspend = 133,
150 rt_sigaction = 134,
151 rt_sigprocmask = 135,
152 rt_sigpending = 136,
153 rt_sigtimedwait = 137,
154 rt_sigqueueinfo = 138,
155 rt_sigreturn = 139,
156 setpriority = 140,
157 getpriority = 141,
158 reboot = 142,
159 setregid = 143,
160 setgid = 144,
161 setreuid = 145,
162 setuid = 146,
163 setresuid = 147,
164 getresuid = 148,
165 setresgid = 149,
166 getresgid = 150,
167 setfsuid = 151,
168 setfsgid = 152,
169 times = 153,
170 setpgid = 154,
171 getpgid = 155,
172 getsid = 156,
173 setsid = 157,
174 getgroups = 158,
175 setgroups = 159,
176 uname = 160,
177 sethostname = 161,
178 setdomainname = 162,
179 getrlimit = 163,
180 setrlimit = 164,
181 getrusage = 165,
182 umask = 166,
183 prctl = 167,
184 getcpu = 168,
185 gettimeofday = 169,
186 settimeofday = 170,
187 adjtimex = 171,
188 getpid = 172,
189 getppid = 173,
190 getuid = 174,
191 geteuid = 175,
192 getgid = 176,
193 getegid = 177,
194 gettid = 178,
195 sysinfo = 179,
196 mq_open = 180,
197 mq_unlink = 181,
198 mq_timedsend = 182,
199 mq_timedreceive = 183,
200 mq_notify = 184,
201 mq_getsetattr = 185,
202 msgget = 186,
203 msgctl = 187,
204 msgrcv = 188,
205 msgsnd = 189,
206 semget = 190,
207 semctl = 191,
208 semtimedop = 192,
209 semop = 193,
210 shmget = 194,
211 shmctl = 195,
212 shmat = 196,
213 shmdt = 197,
214 socket = 198,
215 socketpair = 199,
216 bind = 200,
217 listen = 201,
218 accept = 202,
219 connect = 203,
220 getsockname = 204,
221 getpeername = 205,
222 sendto = 206,
223 recvfrom = 207,
224 setsockopt = 208,
225 getsockopt = 209,
226 shutdown = 210,
227 sendmsg = 211,
228 recvmsg = 212,
229 readahead = 213,
230 brk = 214,
231 munmap = 215,
232 mremap = 216,
233 add_key = 217,
234 request_key = 218,
235 keyctl = 219,
236 clone = 220,
237 execve = 221,
238 mmap = 222,
239 fadvise64 = 223,
240 swapon = 224,
241 swapoff = 225,
242 mprotect = 226,
243 msync = 227,
244 mlock = 228,
245 munlock = 229,
246 mlockall = 230,
247 munlockall = 231,
248 mincore = 232,
249 madvise = 233,
250 remap_file_pages = 234,
251 mbind = 235,
252 get_mempolicy = 236,
253 set_mempolicy = 237,
254 migrate_pages = 238,
255 move_pages = 239,
256 rt_tgsigqueueinfo = 240,
257 perf_event_open = 241,
258 accept4 = 242,
259 recvmmsg = 243,
260 arch_specific_syscall = 244,
261 wait4 = 260,
262 prlimit64 = 261,
263 fanotify_init = 262,
264 fanotify_mark = 263,
265 clock_adjtime = 266,
266 syncfs = 267,
267 setns = 268,
268 sendmmsg = 269,
269 process_vm_readv = 270,
270 process_vm_writev = 271,
271 kcmp = 272,
272 finit_module = 273,
273 sched_setattr = 274,
274 sched_getattr = 275,
275 renameat2 = 276,
276 seccomp = 277,
277 getrandom = 278,
278 memfd_create = 279,
279 bpf = 280,
280 execveat = 281,
281 userfaultfd = 282,
282 membarrier = 283,
283 mlock2 = 284,
284 copy_file_range = 285,
285 preadv2 = 286,
286 pwritev2 = 287,
287 pkey_mprotect = 288,
288 pkey_alloc = 289,
289 pkey_free = 290,
290 statx = 291,
291 io_pgetevents = 292,
292 rseq = 293,
293 kexec_file_load = 294,
294 pidfd_send_signal = 424,
295 io_uring_setup = 425,
296 io_uring_enter = 426,
297 io_uring_register = 427,
298 open_tree = 428,
299 move_mount = 429,
300 fsopen = 430,
301 fsconfig = 431,
302 fsmount = 432,
303 fspick = 433,
304 pidfd_open = 434,
305 clone3 = 435,
306 close_range = 436,
307 openat2 = 437,
308 pidfd_getfd = 438,
309 faccessat2 = 439,
310 process_madvise = 440,
311 epoll_pwait2 = 441,
312
313 _,
314};
315
316pub const O_CREAT = 0o100;
317pub const O_EXCL = 0o200;
318pub const O_NOCTTY = 0o400;
319pub const O_TRUNC = 0o1000;
320pub const O_APPEND = 0o2000;
321pub const O_NONBLOCK = 0o4000;
322pub const O_DSYNC = 0o10000;
323pub const O_SYNC = 0o4010000;
324pub const O_RSYNC = 0o4010000;
325pub const O_DIRECTORY = 0o40000;
326pub const O_NOFOLLOW = 0o100000;
327pub const O_CLOEXEC = 0o2000000;
328
329pub const O_ASYNC = 0o20000;
330pub const O_DIRECT = 0o200000;
331pub const O_LARGEFILE = 0o400000;
332pub const O_NOATIME = 0o1000000;
333pub const O_PATH = 0o10000000;
334pub const O_TMPFILE = 0o20040000;
335pub const O_NDELAY = O_NONBLOCK;
336
337pub const F_DUPFD = 0;
338pub const F_GETFD = 1;
339pub const F_SETFD = 2;
340pub const F_GETFL = 3;
341pub const F_SETFL = 4;
342
343pub const F_SETOWN = 8;
344pub const F_GETOWN = 9;
345pub const F_SETSIG = 10;
346pub const F_GETSIG = 11;
347
348pub const F_GETLK = 5;
349pub const F_SETLK = 6;
350pub const F_SETLKW = 7;
351
352pub const F_RDLCK = 0;
353pub const F_WRLCK = 1;
354pub const F_UNLCK = 2;
355
356pub const LOCK_SH = 1;
357pub const LOCK_EX = 2;
358pub const LOCK_UN = 8;
359pub const LOCK_NB = 4;
360
361pub const F_SETOWN_EX = 15;
362pub const F_GETOWN_EX = 16;
363
364pub const F_GETOWNER_UIDS = 17;
365
366/// stack-like segment
367pub const MAP_GROWSDOWN = 0x0100;
368
369/// ETXTBSY
370pub const MAP_DENYWRITE = 0x0800;
371
372/// mark it as an executable
373pub const MAP_EXECUTABLE = 0x1000;
374
375/// pages are locked
376pub const MAP_LOCKED = 0x2000;
377
378/// don't check for reservations
379pub const MAP_NORESERVE = 0x4000;
380
381pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
382pub const VDSO_CGT_VER = "LINUX_2.6.39";
383
384pub const Flock = extern struct {
385 l_type: i16,
386 l_whence: i16,
387 l_start: off_t,
388 l_len: off_t,
389 l_pid: pid_t,
390 __unused: [4]u8,
391};
392
393pub const msghdr = extern struct {
394 msg_name: ?*sockaddr,
395 msg_namelen: socklen_t,
396 msg_iov: [*]iovec,
397 msg_iovlen: i32,
398 __pad1: i32 = 0,
399 msg_control: ?*c_void,
400 msg_controllen: socklen_t,
401 __pad2: socklen_t = 0,
402 msg_flags: i32,
403};
404
405pub const msghdr_const = extern struct {
406 msg_name: ?*const sockaddr,
407 msg_namelen: socklen_t,
408 msg_iov: [*]iovec_const,
409 msg_iovlen: i32,
410 __pad1: i32 = 0,
411 msg_control: ?*c_void,
412 msg_controllen: socklen_t,
413 __pad2: socklen_t = 0,
414 msg_flags: i32,
415};
416
417pub const blksize_t = i32;
418pub const nlink_t = u32;
419pub const time_t = isize;
420pub const mode_t = u32;
421pub const off_t = isize;
422pub const ino_t = usize;
423pub const dev_t = usize;
424pub const blkcnt_t = isize;
425
426// The `stat` definition used by the Linux kernel.
427pub const kernel_stat = extern struct {
428 dev: dev_t,
429 ino: ino_t,
430 mode: mode_t,
431 nlink: nlink_t,
432 uid: uid_t,
433 gid: gid_t,
434 rdev: dev_t,
435 __pad: usize,
436 size: off_t,
437 blksize: blksize_t,
438 __pad2: i32,
439 blocks: blkcnt_t,
440 atim: timespec,
441 mtim: timespec,
442 ctim: timespec,
443 __unused: [2]u32,
444
445 pub fn atime(self: @This()) timespec {
446 return self.atim;
447 }
448
449 pub fn mtime(self: @This()) timespec {
450 return self.mtim;
451 }
452
453 pub fn ctime(self: @This()) timespec {
454 return self.ctim;
455 }
456};
457
458// The `stat64` definition used by the libc.
459pub const libc_stat = kernel_stat;
460
461pub const timespec = extern struct {
462 tv_sec: time_t,
463 tv_nsec: isize,
464};
465
466pub const timeval = extern struct {
467 tv_sec: isize,
468 tv_usec: isize,
469};
470
471pub const timezone = extern struct {
472 tz_minuteswest: i32,
473 tz_dsttime: i32,
474};
475
476pub const mcontext_t = extern struct {
477 fault_address: usize,
478 regs: [31]usize,
479 sp: usize,
480 pc: usize,
481 pstate: usize,
482 // Make sure the field is correctly aligned since this area
483 // holds various FP/vector registers
484 reserved1: [256 * 16]u8 align(16),
485};
486
487pub const ucontext_t = extern struct {
488 flags: usize,
489 link: *ucontext_t,
490 stack: stack_t,
491 sigmask: sigset_t,
492 mcontext: mcontext_t,
493};
494
495pub const Elf_Symndx = u32;
lib/std/os/bits/linux/errno/generic.zig deleted-460
...@@ -1,460 +0,0 @@
1pub const E = enum(u16) {
2 /// No error occurred.
3 /// Same code used for `NSROK`.
4 SUCCESS = 0,
5
6 /// Operation not permitted
7 PERM = 1,
8
9 /// No such file or directory
10 NOENT = 2,
11
12 /// No such process
13 SRCH = 3,
14
15 /// Interrupted system call
16 INTR = 4,
17
18 /// I/O error
19 IO = 5,
20
21 /// No such device or address
22 NXIO = 6,
23
24 /// Arg list too long
25 @"2BIG" = 7,
26
27 /// Exec format error
28 NOEXEC = 8,
29
30 /// Bad file number
31 BADF = 9,
32
33 /// No child processes
34 CHILD = 10,
35
36 /// Try again
37 /// Also means: WOULDBLOCK: operation would block
38 AGAIN = 11,
39
40 /// Out of memory
41 NOMEM = 12,
42
43 /// Permission denied
44 ACCES = 13,
45
46 /// Bad address
47 FAULT = 14,
48
49 /// Block device required
50 NOTBLK = 15,
51
52 /// Device or resource busy
53 BUSY = 16,
54
55 /// File exists
56 EXIST = 17,
57
58 /// Cross-device link
59 XDEV = 18,
60
61 /// No such device
62 NODEV = 19,
63
64 /// Not a directory
65 NOTDIR = 20,
66
67 /// Is a directory
68 ISDIR = 21,
69
70 /// Invalid argument
71 INVAL = 22,
72
73 /// File table overflow
74 NFILE = 23,
75
76 /// Too many open files
77 MFILE = 24,
78
79 /// Not a typewriter
80 NOTTY = 25,
81
82 /// Text file busy
83 TXTBSY = 26,
84
85 /// File too large
86 FBIG = 27,
87
88 /// No space left on device
89 NOSPC = 28,
90
91 /// Illegal seek
92 SPIPE = 29,
93
94 /// Read-only file system
95 ROFS = 30,
96
97 /// Too many links
98 MLINK = 31,
99
100 /// Broken pipe
101 PIPE = 32,
102
103 /// Math argument out of domain of func
104 DOM = 33,
105
106 /// Math result not representable
107 RANGE = 34,
108
109 /// Resource deadlock would occur
110 DEADLK = 35,
111
112 /// File name too long
113 NAMETOOLONG = 36,
114
115 /// No record locks available
116 NOLCK = 37,
117
118 /// Function not implemented
119 NOSYS = 38,
120
121 /// Directory not empty
122 NOTEMPTY = 39,
123
124 /// Too many symbolic links encountered
125 LOOP = 40,
126
127 /// No message of desired type
128 NOMSG = 42,
129
130 /// Identifier removed
131 IDRM = 43,
132
133 /// Channel number out of range
134 CHRNG = 44,
135
136 /// Level 2 not synchronized
137 L2NSYNC = 45,
138
139 /// Level 3 halted
140 L3HLT = 46,
141
142 /// Level 3 reset
143 L3RST = 47,
144
145 /// Link number out of range
146 LNRNG = 48,
147
148 /// Protocol driver not attached
149 UNATCH = 49,
150
151 /// No CSI structure available
152 NOCSI = 50,
153
154 /// Level 2 halted
155 L2HLT = 51,
156
157 /// Invalid exchange
158 BADE = 52,
159
160 /// Invalid request descriptor
161 BADR = 53,
162
163 /// Exchange full
164 XFULL = 54,
165
166 /// No anode
167 NOANO = 55,
168
169 /// Invalid request code
170 BADRQC = 56,
171
172 /// Invalid slot
173 BADSLT = 57,
174
175 /// Bad font file format
176 BFONT = 59,
177
178 /// Device not a stream
179 NOSTR = 60,
180
181 /// No data available
182 NODATA = 61,
183
184 /// Timer expired
185 TIME = 62,
186
187 /// Out of streams resources
188 NOSR = 63,
189
190 /// Machine is not on the network
191 NONET = 64,
192
193 /// Package not installed
194 NOPKG = 65,
195
196 /// Object is remote
197 REMOTE = 66,
198
199 /// Link has been severed
200 NOLINK = 67,
201
202 /// Advertise error
203 ADV = 68,
204
205 /// Srmount error
206 SRMNT = 69,
207
208 /// Communication error on send
209 COMM = 70,
210
211 /// Protocol error
212 PROTO = 71,
213
214 /// Multihop attempted
215 MULTIHOP = 72,
216
217 /// RFS specific error
218 DOTDOT = 73,
219
220 /// Not a data message
221 BADMSG = 74,
222
223 /// Value too large for defined data type
224 OVERFLOW = 75,
225
226 /// Name not unique on network
227 NOTUNIQ = 76,
228
229 /// File descriptor in bad state
230 BADFD = 77,
231
232 /// Remote address changed
233 REMCHG = 78,
234
235 /// Can not access a needed shared library
236 LIBACC = 79,
237
238 /// Accessing a corrupted shared library
239 LIBBAD = 80,
240
241 /// .lib section in a.out corrupted
242 LIBSCN = 81,
243
244 /// Attempting to link in too many shared libraries
245 LIBMAX = 82,
246
247 /// Cannot exec a shared library directly
248 LIBEXEC = 83,
249
250 /// Illegal byte sequence
251 ILSEQ = 84,
252
253 /// Interrupted system call should be restarted
254 RESTART = 85,
255
256 /// Streams pipe error
257 STRPIPE = 86,
258
259 /// Too many users
260 USERS = 87,
261
262 /// Socket operation on non-socket
263 NOTSOCK = 88,
264
265 /// Destination address required
266 DESTADDRREQ = 89,
267
268 /// Message too long
269 MSGSIZE = 90,
270
271 /// Protocol wrong type for socket
272 PROTOTYPE = 91,
273
274 /// Protocol not available
275 NOPROTOOPT = 92,
276
277 /// Protocol not supported
278 PROTONOSUPPORT = 93,
279
280 /// Socket type not supported
281 SOCKTNOSUPPORT = 94,
282
283 /// Operation not supported on transport endpoint
284 /// This code also means `NOTSUP`.
285 OPNOTSUPP = 95,
286
287 /// Protocol family not supported
288 PFNOSUPPORT = 96,
289
290 /// Address family not supported by protocol
291 AFNOSUPPORT = 97,
292
293 /// Address already in use
294 ADDRINUSE = 98,
295
296 /// Cannot assign requested address
297 ADDRNOTAVAIL = 99,
298
299 /// Network is down
300 NETDOWN = 100,
301
302 /// Network is unreachable
303 NETUNREACH = 101,
304
305 /// Network dropped connection because of reset
306 NETRESET = 102,
307
308 /// Software caused connection abort
309 CONNABORTED = 103,
310
311 /// Connection reset by peer
312 CONNRESET = 104,
313
314 /// No buffer space available
315 NOBUFS = 105,
316
317 /// Transport endpoint is already connected
318 ISCONN = 106,
319
320 /// Transport endpoint is not connected
321 NOTCONN = 107,
322
323 /// Cannot send after transport endpoint shutdown
324 SHUTDOWN = 108,
325
326 /// Too many references: cannot splice
327 TOOMANYREFS = 109,
328
329 /// Connection timed out
330 TIMEDOUT = 110,
331
332 /// Connection refused
333 CONNREFUSED = 111,
334
335 /// Host is down
336 HOSTDOWN = 112,
337
338 /// No route to host
339 HOSTUNREACH = 113,
340
341 /// Operation already in progress
342 ALREADY = 114,
343
344 /// Operation now in progress
345 INPROGRESS = 115,
346
347 /// Stale NFS file handle
348 STALE = 116,
349
350 /// Structure needs cleaning
351 UCLEAN = 117,
352
353 /// Not a XENIX named type file
354 NOTNAM = 118,
355
356 /// No XENIX semaphores available
357 NAVAIL = 119,
358
359 /// Is a named type file
360 ISNAM = 120,
361
362 /// Remote I/O error
363 REMOTEIO = 121,
364
365 /// Quota exceeded
366 DQUOT = 122,
367
368 /// No medium found
369 NOMEDIUM = 123,
370
371 /// Wrong medium type
372 MEDIUMTYPE = 124,
373
374 /// Operation canceled
375 CANCELED = 125,
376
377 /// Required key not available
378 NOKEY = 126,
379
380 /// Key has expired
381 KEYEXPIRED = 127,
382
383 /// Key has been revoked
384 KEYREVOKED = 128,
385
386 /// Key was rejected by service
387 KEYREJECTED = 129,
388
389 // for robust mutexes
390
391 /// Owner died
392 OWNERDEAD = 130,
393
394 /// State not recoverable
395 NOTRECOVERABLE = 131,
396
397 /// Operation not possible due to RF-kill
398 RFKILL = 132,
399
400 /// Memory page has hardware error
401 HWPOISON = 133,
402
403 // nameserver query return codes
404
405 /// DNS server returned answer with no data
406 NSRNODATA = 160,
407
408 /// DNS server claims query was misformatted
409 NSRFORMERR = 161,
410
411 /// DNS server returned general failure
412 NSRSERVFAIL = 162,
413
414 /// Domain name not found
415 NSRNOTFOUND = 163,
416
417 /// DNS server does not implement requested operation
418 NSRNOTIMP = 164,
419
420 /// DNS server refused query
421 NSRREFUSED = 165,
422
423 /// Misformatted DNS query
424 NSRBADQUERY = 166,
425
426 /// Misformatted domain name
427 NSRBADNAME = 167,
428
429 /// Unsupported address family
430 NSRBADFAMILY = 168,
431
432 /// Misformatted DNS reply
433 NSRBADRESP = 169,
434
435 /// Could not contact DNS servers
436 NSRCONNREFUSED = 170,
437
438 /// Timeout while contacting DNS servers
439 NSRTIMEOUT = 171,
440
441 /// End of file
442 NSROF = 172,
443
444 /// Error reading file
445 NSRFILE = 173,
446
447 /// Out of memory
448 NSRNOMEM = 174,
449
450 /// Application terminated lookup
451 NSRDESTRUCTION = 175,
452
453 /// Domain name is too long
454 NSRQUERYDOMAINTOOLONG = 176,
455
456 /// Domain name is too long
457 NSRCNAMELOOP = 177,
458
459 _,
460};
lib/std/os/bits/linux/errno/mips.zig deleted-141
...@@ -1,141 +0,0 @@
1//! These are MIPS ABI compatible.
2pub const E = enum(i32) {
3 /// No error occurred.
4 SUCCESS = 0,
5
6 PERM = 1,
7 NOENT = 2,
8 SRCH = 3,
9 INTR = 4,
10 IO = 5,
11 NXIO = 6,
12 @"2BIG" = 7,
13 NOEXEC = 8,
14 BADF = 9,
15 CHILD = 10,
16 /// Also used for WOULDBLOCK.
17 AGAIN = 11,
18 NOMEM = 12,
19 ACCES = 13,
20 FAULT = 14,
21 NOTBLK = 15,
22 BUSY = 16,
23 EXIST = 17,
24 XDEV = 18,
25 NODEV = 19,
26 NOTDIR = 20,
27 ISDIR = 21,
28 INVAL = 22,
29 NFILE = 23,
30 MFILE = 24,
31 NOTTY = 25,
32 TXTBSY = 26,
33 FBIG = 27,
34 NOSPC = 28,
35 SPIPE = 29,
36 ROFS = 30,
37 MLINK = 31,
38 PIPE = 32,
39 DOM = 33,
40 RANGE = 34,
41
42 NOMSG = 35,
43 IDRM = 36,
44 CHRNG = 37,
45 L2NSYNC = 38,
46 L3HLT = 39,
47 L3RST = 40,
48 LNRNG = 41,
49 UNATCH = 42,
50 NOCSI = 43,
51 L2HLT = 44,
52 DEADLK = 45,
53 NOLCK = 46,
54 BADE = 50,
55 BADR = 51,
56 XFULL = 52,
57 NOANO = 53,
58 BADRQC = 54,
59 BADSLT = 55,
60 DEADLOCK = 56,
61 BFONT = 59,
62 NOSTR = 60,
63 NODATA = 61,
64 TIME = 62,
65 NOSR = 63,
66 NONET = 64,
67 NOPKG = 65,
68 REMOTE = 66,
69 NOLINK = 67,
70 ADV = 68,
71 SRMNT = 69,
72 COMM = 70,
73 PROTO = 71,
74 DOTDOT = 73,
75 MULTIHOP = 74,
76 BADMSG = 77,
77 NAMETOOLONG = 78,
78 OVERFLOW = 79,
79 NOTUNIQ = 80,
80 BADFD = 81,
81 REMCHG = 82,
82 LIBACC = 83,
83 LIBBAD = 84,
84 LIBSCN = 85,
85 LIBMAX = 86,
86 LIBEXEC = 87,
87 ILSEQ = 88,
88 NOSYS = 89,
89 LOOP = 90,
90 RESTART = 91,
91 STRPIPE = 92,
92 NOTEMPTY = 93,
93 USERS = 94,
94 NOTSOCK = 95,
95 DESTADDRREQ = 96,
96 MSGSIZE = 97,
97 PROTOTYPE = 98,
98 NOPROTOOPT = 99,
99 PROTONOSUPPORT = 120,
100 SOCKTNOSUPPORT = 121,
101 OPNOTSUPP = 122,
102 PFNOSUPPORT = 123,
103 AFNOSUPPORT = 124,
104 ADDRINUSE = 125,
105 ADDRNOTAVAIL = 126,
106 NETDOWN = 127,
107 NETUNREACH = 128,
108 NETRESET = 129,
109 CONNABORTED = 130,
110 CONNRESET = 131,
111 NOBUFS = 132,
112 ISCONN = 133,
113 NOTCONN = 134,
114 UCLEAN = 135,
115 NOTNAM = 137,
116 NAVAIL = 138,
117 ISNAM = 139,
118 REMOTEIO = 140,
119 SHUTDOWN = 143,
120 TOOMANYREFS = 144,
121 TIMEDOUT = 145,
122 CONNREFUSED = 146,
123 HOSTDOWN = 147,
124 HOSTUNREACH = 148,
125 ALREADY = 149,
126 INPROGRESS = 150,
127 STALE = 151,
128 CANCELED = 158,
129 NOMEDIUM = 159,
130 MEDIUMTYPE = 160,
131 NOKEY = 161,
132 KEYEXPIRED = 162,
133 KEYREVOKED = 163,
134 KEYREJECTED = 164,
135 OWNERDEAD = 165,
136 NOTRECOVERABLE = 166,
137 RFKILL = 167,
138 HWPOISON = 168,
139 DQUOT = 1133,
140 _,
141};
lib/std/os/bits/linux/errno/sparc.zig deleted-144
...@@ -1,144 +0,0 @@
1//! These match the SunOS error numbering scheme.
2pub const E = enum(i32) {
3 /// No error occurred.
4 SUCCESS = 0,
5
6 PERM = 1,
7 NOENT = 2,
8 SRCH = 3,
9 INTR = 4,
10 IO = 5,
11 NXIO = 6,
12 @"2BIG" = 7,
13 NOEXEC = 8,
14 BADF = 9,
15 CHILD = 10,
16 /// Also used for WOULDBLOCK
17 AGAIN = 11,
18 NOMEM = 12,
19 ACCES = 13,
20 FAULT = 14,
21 NOTBLK = 15,
22 BUSY = 16,
23 EXIST = 17,
24 XDEV = 18,
25 NODEV = 19,
26 NOTDIR = 20,
27 ISDIR = 21,
28 INVAL = 22,
29 NFILE = 23,
30 MFILE = 24,
31 NOTTY = 25,
32 TXTBSY = 26,
33 FBIG = 27,
34 NOSPC = 28,
35 SPIPE = 29,
36 ROFS = 30,
37 MLINK = 31,
38 PIPE = 32,
39 DOM = 33,
40 RANGE = 34,
41
42 INPROGRESS = 36,
43 ALREADY = 37,
44 NOTSOCK = 38,
45 DESTADDRREQ = 39,
46 MSGSIZE = 40,
47 PROTOTYPE = 41,
48 NOPROTOOPT = 42,
49 PROTONOSUPPORT = 43,
50 SOCKTNOSUPPORT = 44,
51 /// Also used for NOTSUP
52 OPNOTSUPP = 45,
53 PFNOSUPPORT = 46,
54 AFNOSUPPORT = 47,
55 ADDRINUSE = 48,
56 ADDRNOTAVAIL = 49,
57 NETDOWN = 50,
58 NETUNREACH = 51,
59 NETRESET = 52,
60 CONNABORTED = 53,
61 CONNRESET = 54,
62 NOBUFS = 55,
63 ISCONN = 56,
64 NOTCONN = 57,
65 SHUTDOWN = 58,
66 TOOMANYREFS = 59,
67 TIMEDOUT = 60,
68 CONNREFUSED = 61,
69 LOOP = 62,
70 NAMETOOLONG = 63,
71 HOSTDOWN = 64,
72 HOSTUNREACH = 65,
73 NOTEMPTY = 66,
74 PROCLIM = 67,
75 USERS = 68,
76 DQUOT = 69,
77 STALE = 70,
78 REMOTE = 71,
79 NOSTR = 72,
80 TIME = 73,
81 NOSR = 74,
82 NOMSG = 75,
83 BADMSG = 76,
84 IDRM = 77,
85 DEADLK = 78,
86 NOLCK = 79,
87 NONET = 80,
88 RREMOTE = 81,
89 NOLINK = 82,
90 ADV = 83,
91 SRMNT = 84,
92 COMM = 85,
93 PROTO = 86,
94 MULTIHOP = 87,
95 DOTDOT = 88,
96 REMCHG = 89,
97 NOSYS = 90,
98 STRPIPE = 91,
99 OVERFLOW = 92,
100 BADFD = 93,
101 CHRNG = 94,
102 L2NSYNC = 95,
103 L3HLT = 96,
104 L3RST = 97,
105 LNRNG = 98,
106 UNATCH = 99,
107 NOCSI = 100,
108 L2HLT = 101,
109 BADE = 102,
110 BADR = 103,
111 XFULL = 104,
112 NOANO = 105,
113 BADRQC = 106,
114 BADSLT = 107,
115 DEADLOCK = 108,
116 BFONT = 109,
117 LIBEXEC = 110,
118 NODATA = 111,
119 LIBBAD = 112,
120 NOPKG = 113,
121 LIBACC = 114,
122 NOTUNIQ = 115,
123 RESTART = 116,
124 UCLEAN = 117,
125 NOTNAM = 118,
126 NAVAIL = 119,
127 ISNAM = 120,
128 REMOTEIO = 121,
129 ILSEQ = 122,
130 LIBMAX = 123,
131 LIBSCN = 124,
132 NOMEDIUM = 125,
133 MEDIUMTYPE = 126,
134 CANCELED = 127,
135 NOKEY = 128,
136 KEYEXPIRED = 129,
137 KEYREVOKED = 130,
138 KEYREJECTED = 131,
139 OWNERDEAD = 132,
140 NOTRECOVERABLE = 133,
141 RFKILL = 134,
142 HWPOISON = 135,
143 _,
144};
lib/std/os/bits/linux/i386.zig deleted-670
...@@ -1,670 +0,0 @@
1// i386-specific declarations that are intended to be imported into the POSIX namespace.
2// This does include Linux-only APIs.
3
4const std = @import("../../../std.zig");
5const linux = std.os.linux;
6const socklen_t = linux.socklen_t;
7const iovec = linux.iovec;
8const iovec_const = linux.iovec_const;
9const uid_t = linux.uid_t;
10const gid_t = linux.gid_t;
11const pid_t = linux.pid_t;
12const stack_t = linux.stack_t;
13const sigset_t = linux.sigset_t;
14
15pub const SYS = enum(usize) {
16 restart_syscall = 0,
17 exit = 1,
18 fork = 2,
19 read = 3,
20 write = 4,
21 open = 5,
22 close = 6,
23 waitpid = 7,
24 creat = 8,
25 link = 9,
26 unlink = 10,
27 execve = 11,
28 chdir = 12,
29 time = 13,
30 mknod = 14,
31 chmod = 15,
32 lchown = 16,
33 @"break" = 17,
34 oldstat = 18,
35 lseek = 19,
36 getpid = 20,
37 mount = 21,
38 umount = 22,
39 setuid = 23,
40 getuid = 24,
41 stime = 25,
42 ptrace = 26,
43 alarm = 27,
44 oldfstat = 28,
45 pause = 29,
46 utime = 30,
47 stty = 31,
48 gtty = 32,
49 access = 33,
50 nice = 34,
51 ftime = 35,
52 sync = 36,
53 kill = 37,
54 rename = 38,
55 mkdir = 39,
56 rmdir = 40,
57 dup = 41,
58 pipe = 42,
59 times = 43,
60 prof = 44,
61 brk = 45,
62 setgid = 46,
63 getgid = 47,
64 signal = 48,
65 geteuid = 49,
66 getegid = 50,
67 acct = 51,
68 umount2 = 52,
69 lock = 53,
70 ioctl = 54,
71 fcntl = 55,
72 mpx = 56,
73 setpgid = 57,
74 ulimit = 58,
75 oldolduname = 59,
76 umask = 60,
77 chroot = 61,
78 ustat = 62,
79 dup2 = 63,
80 getppid = 64,
81 getpgrp = 65,
82 setsid = 66,
83 sigaction = 67,
84 sgetmask = 68,
85 ssetmask = 69,
86 setreuid = 70,
87 setregid = 71,
88 sigsuspend = 72,
89 sigpending = 73,
90 sethostname = 74,
91 setrlimit = 75,
92 getrlimit = 76,
93 getrusage = 77,
94 gettimeofday = 78,
95 settimeofday = 79,
96 getgroups = 80,
97 setgroups = 81,
98 select = 82,
99 symlink = 83,
100 oldlstat = 84,
101 readlink = 85,
102 uselib = 86,
103 swapon = 87,
104 reboot = 88,
105 readdir = 89,
106 mmap = 90,
107 munmap = 91,
108 truncate = 92,
109 ftruncate = 93,
110 fchmod = 94,
111 fchown = 95,
112 getpriority = 96,
113 setpriority = 97,
114 profil = 98,
115 statfs = 99,
116 fstatfs = 100,
117 ioperm = 101,
118 socketcall = 102,
119 syslog = 103,
120 setitimer = 104,
121 getitimer = 105,
122 stat = 106,
123 lstat = 107,
124 fstat = 108,
125 olduname = 109,
126 iopl = 110,
127 vhangup = 111,
128 idle = 112,
129 vm86old = 113,
130 wait4 = 114,
131 swapoff = 115,
132 sysinfo = 116,
133 ipc = 117,
134 fsync = 118,
135 sigreturn = 119,
136 clone = 120,
137 setdomainname = 121,
138 uname = 122,
139 modify_ldt = 123,
140 adjtimex = 124,
141 mprotect = 125,
142 sigprocmask = 126,
143 create_module = 127,
144 init_module = 128,
145 delete_module = 129,
146 get_kernel_syms = 130,
147 quotactl = 131,
148 getpgid = 132,
149 fchdir = 133,
150 bdflush = 134,
151 sysfs = 135,
152 personality = 136,
153 afs_syscall = 137,
154 setfsuid = 138,
155 setfsgid = 139,
156 _llseek = 140,
157 getdents = 141,
158 _newselect = 142,
159 flock = 143,
160 msync = 144,
161 readv = 145,
162 writev = 146,
163 getsid = 147,
164 fdatasync = 148,
165 _sysctl = 149,
166 mlock = 150,
167 munlock = 151,
168 mlockall = 152,
169 munlockall = 153,
170 sched_setparam = 154,
171 sched_getparam = 155,
172 sched_setscheduler = 156,
173 sched_getscheduler = 157,
174 sched_yield = 158,
175 sched_get_priority_max = 159,
176 sched_get_priority_min = 160,
177 sched_rr_get_interval = 161,
178 nanosleep = 162,
179 mremap = 163,
180 setresuid = 164,
181 getresuid = 165,
182 vm86 = 166,
183 query_module = 167,
184 poll = 168,
185 nfsservctl = 169,
186 setresgid = 170,
187 getresgid = 171,
188 prctl = 172,
189 rt_sigreturn = 173,
190 rt_sigaction = 174,
191 rt_sigprocmask = 175,
192 rt_sigpending = 176,
193 rt_sigtimedwait = 177,
194 rt_sigqueueinfo = 178,
195 rt_sigsuspend = 179,
196 pread64 = 180,
197 pwrite64 = 181,
198 chown = 182,
199 getcwd = 183,
200 capget = 184,
201 capset = 185,
202 sigaltstack = 186,
203 sendfile = 187,
204 getpmsg = 188,
205 putpmsg = 189,
206 vfork = 190,
207 ugetrlimit = 191,
208 mmap2 = 192,
209 truncate64 = 193,
210 ftruncate64 = 194,
211 stat64 = 195,
212 lstat64 = 196,
213 fstat64 = 197,
214 lchown32 = 198,
215 getuid32 = 199,
216 getgid32 = 200,
217 geteuid32 = 201,
218 getegid32 = 202,
219 setreuid32 = 203,
220 setregid32 = 204,
221 getgroups32 = 205,
222 setgroups32 = 206,
223 fchown32 = 207,
224 setresuid32 = 208,
225 getresuid32 = 209,
226 setresgid32 = 210,
227 getresgid32 = 211,
228 chown32 = 212,
229 setuid32 = 213,
230 setgid32 = 214,
231 setfsuid32 = 215,
232 setfsgid32 = 216,
233 pivot_root = 217,
234 mincore = 218,
235 madvise = 219,
236 getdents64 = 220,
237 fcntl64 = 221,
238 gettid = 224,
239 readahead = 225,
240 setxattr = 226,
241 lsetxattr = 227,
242 fsetxattr = 228,
243 getxattr = 229,
244 lgetxattr = 230,
245 fgetxattr = 231,
246 listxattr = 232,
247 llistxattr = 233,
248 flistxattr = 234,
249 removexattr = 235,
250 lremovexattr = 236,
251 fremovexattr = 237,
252 tkill = 238,
253 sendfile64 = 239,
254 futex = 240,
255 sched_setaffinity = 241,
256 sched_getaffinity = 242,
257 set_thread_area = 243,
258 get_thread_area = 244,
259 io_setup = 245,
260 io_destroy = 246,
261 io_getevents = 247,
262 io_submit = 248,
263 io_cancel = 249,
264 fadvise64 = 250,
265 exit_group = 252,
266 lookup_dcookie = 253,
267 epoll_create = 254,
268 epoll_ctl = 255,
269 epoll_wait = 256,
270 remap_file_pages = 257,
271 set_tid_address = 258,
272 timer_create = 259,
273 timer_settime, // SYS_timer_create + 1
274 timer_gettime, // SYS_timer_create + 2
275 timer_getoverrun, // SYS_timer_create + 3
276 timer_delete, // SYS_timer_create + 4
277 clock_settime, // SYS_timer_create + 5
278 clock_gettime, // SYS_timer_create + 6
279 clock_getres, // SYS_timer_create + 7
280 clock_nanosleep, // SYS_timer_create + 8
281 statfs64 = 268,
282 fstatfs64 = 269,
283 tgkill = 270,
284 utimes = 271,
285 fadvise64_64 = 272,
286 vserver = 273,
287 mbind = 274,
288 get_mempolicy = 275,
289 set_mempolicy = 276,
290 mq_open = 277,
291 mq_unlink, // SYS_mq_open + 1
292 mq_timedsend, // SYS_mq_open + 2
293 mq_timedreceive, // SYS_mq_open + 3
294 mq_notify, // SYS_mq_open + 4
295 mq_getsetattr, // SYS_mq_open + 5
296 kexec_load = 283,
297 waitid = 284,
298 add_key = 286,
299 request_key = 287,
300 keyctl = 288,
301 ioprio_set = 289,
302 ioprio_get = 290,
303 inotify_init = 291,
304 inotify_add_watch = 292,
305 inotify_rm_watch = 293,
306 migrate_pages = 294,
307 openat = 295,
308 mkdirat = 296,
309 mknodat = 297,
310 fchownat = 298,
311 futimesat = 299,
312 fstatat64 = 300,
313 unlinkat = 301,
314 renameat = 302,
315 linkat = 303,
316 symlinkat = 304,
317 readlinkat = 305,
318 fchmodat = 306,
319 faccessat = 307,
320 pselect6 = 308,
321 ppoll = 309,
322 unshare = 310,
323 set_robust_list = 311,
324 get_robust_list = 312,
325 splice = 313,
326 sync_file_range = 314,
327 tee = 315,
328 vmsplice = 316,
329 move_pages = 317,
330 getcpu = 318,
331 epoll_pwait = 319,
332 utimensat = 320,
333 signalfd = 321,
334 timerfd_create = 322,
335 eventfd = 323,
336 fallocate = 324,
337 timerfd_settime = 325,
338 timerfd_gettime = 326,
339 signalfd4 = 327,
340 eventfd2 = 328,
341 epoll_create1 = 329,
342 dup3 = 330,
343 pipe2 = 331,
344 inotify_init1 = 332,
345 preadv = 333,
346 pwritev = 334,
347 rt_tgsigqueueinfo = 335,
348 perf_event_open = 336,
349 recvmmsg = 337,
350 fanotify_init = 338,
351 fanotify_mark = 339,
352 prlimit64 = 340,
353 name_to_handle_at = 341,
354 open_by_handle_at = 342,
355 clock_adjtime = 343,
356 syncfs = 344,
357 sendmmsg = 345,
358 setns = 346,
359 process_vm_readv = 347,
360 process_vm_writev = 348,
361 kcmp = 349,
362 finit_module = 350,
363 sched_setattr = 351,
364 sched_getattr = 352,
365 renameat2 = 353,
366 seccomp = 354,
367 getrandom = 355,
368 memfd_create = 356,
369 bpf = 357,
370 execveat = 358,
371 socket = 359,
372 socketpair = 360,
373 bind = 361,
374 connect = 362,
375 listen = 363,
376 accept4 = 364,
377 getsockopt = 365,
378 setsockopt = 366,
379 getsockname = 367,
380 getpeername = 368,
381 sendto = 369,
382 sendmsg = 370,
383 recvfrom = 371,
384 recvmsg = 372,
385 shutdown = 373,
386 userfaultfd = 374,
387 membarrier = 375,
388 mlock2 = 376,
389 copy_file_range = 377,
390 preadv2 = 378,
391 pwritev2 = 379,
392 pkey_mprotect = 380,
393 pkey_alloc = 381,
394 pkey_free = 382,
395 statx = 383,
396 arch_prctl = 384,
397 io_pgetevents = 385,
398 rseq = 386,
399 semget = 393,
400 semctl = 394,
401 shmget = 395,
402 shmctl = 396,
403 shmat = 397,
404 shmdt = 398,
405 msgget = 399,
406 msgsnd = 400,
407 msgrcv = 401,
408 msgctl = 402,
409 clock_gettime64 = 403,
410 clock_settime64 = 404,
411 clock_adjtime64 = 405,
412 clock_getres_time64 = 406,
413 clock_nanosleep_time64 = 407,
414 timer_gettime64 = 408,
415 timer_settime64 = 409,
416 timerfd_gettime64 = 410,
417 timerfd_settime64 = 411,
418 utimensat_time64 = 412,
419 pselect6_time64 = 413,
420 ppoll_time64 = 414,
421 io_pgetevents_time64 = 416,
422 recvmmsg_time64 = 417,
423 mq_timedsend_time64 = 418,
424 mq_timedreceive_time64 = 419,
425 semtimedop_time64 = 420,
426 rt_sigtimedwait_time64 = 421,
427 futex_time64 = 422,
428 sched_rr_get_interval_time64 = 423,
429 pidfd_send_signal = 424,
430 io_uring_setup = 425,
431 io_uring_enter = 426,
432 io_uring_register = 427,
433 open_tree = 428,
434 move_mount = 429,
435 fsopen = 430,
436 fsconfig = 431,
437 fsmount = 432,
438 fspick = 433,
439 pidfd_open = 434,
440 clone3 = 435,
441 close_range = 436,
442 openat2 = 437,
443 pidfd_getfd = 438,
444 faccessat2 = 439,
445 process_madvise = 440,
446 epoll_pwait2 = 441,
447
448 _,
449};
450
451pub const O_CREAT = 0o100;
452pub const O_EXCL = 0o200;
453pub const O_NOCTTY = 0o400;
454pub const O_TRUNC = 0o1000;
455pub const O_APPEND = 0o2000;
456pub const O_NONBLOCK = 0o4000;
457pub const O_DSYNC = 0o10000;
458pub const O_SYNC = 0o4010000;
459pub const O_RSYNC = 0o4010000;
460pub const O_DIRECTORY = 0o200000;
461pub const O_NOFOLLOW = 0o400000;
462pub const O_CLOEXEC = 0o2000000;
463
464pub const O_ASYNC = 0o20000;
465pub const O_DIRECT = 0o40000;
466pub const O_LARGEFILE = 0o100000;
467pub const O_NOATIME = 0o1000000;
468pub const O_PATH = 0o10000000;
469pub const O_TMPFILE = 0o20200000;
470pub const O_NDELAY = O_NONBLOCK;
471
472pub const F_DUPFD = 0;
473pub const F_GETFD = 1;
474pub const F_SETFD = 2;
475pub const F_GETFL = 3;
476pub const F_SETFL = 4;
477
478pub const F_SETOWN = 8;
479pub const F_GETOWN = 9;
480pub const F_SETSIG = 10;
481pub const F_GETSIG = 11;
482
483pub const F_GETLK = 12;
484pub const F_SETLK = 13;
485pub const F_SETLKW = 14;
486
487pub const F_RDLCK = 0;
488pub const F_WRLCK = 1;
489pub const F_UNLCK = 2;
490
491pub const LOCK_SH = 1;
492pub const LOCK_EX = 2;
493pub const LOCK_UN = 8;
494pub const LOCK_NB = 4;
495
496pub const F_SETOWN_EX = 15;
497pub const F_GETOWN_EX = 16;
498
499pub const F_GETOWNER_UIDS = 17;
500
501pub const MAP_NORESERVE = 0x4000;
502pub const MAP_GROWSDOWN = 0x0100;
503pub const MAP_DENYWRITE = 0x0800;
504pub const MAP_EXECUTABLE = 0x1000;
505pub const MAP_LOCKED = 0x2000;
506pub const MAP_32BIT = 0x40;
507
508pub const MMAP2_UNIT = 4096;
509
510pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
511pub const VDSO_CGT_VER = "LINUX_2.6";
512
513pub const Flock = extern struct {
514 l_type: i16,
515 l_whence: i16,
516 l_start: off_t,
517 l_len: off_t,
518 l_pid: pid_t,
519};
520
521pub const msghdr = extern struct {
522 msg_name: ?*sockaddr,
523 msg_namelen: socklen_t,
524 msg_iov: [*]iovec,
525 msg_iovlen: i32,
526 msg_control: ?*c_void,
527 msg_controllen: socklen_t,
528 msg_flags: i32,
529};
530
531pub const msghdr_const = extern struct {
532 msg_name: ?*const sockaddr,
533 msg_namelen: socklen_t,
534 msg_iov: [*]iovec_const,
535 msg_iovlen: i32,
536 msg_control: ?*c_void,
537 msg_controllen: socklen_t,
538 msg_flags: i32,
539};
540
541pub const blksize_t = i32;
542pub const nlink_t = u32;
543pub const time_t = isize;
544pub const mode_t = u32;
545pub const off_t = i64;
546pub const ino_t = u64;
547pub const dev_t = u64;
548pub const blkcnt_t = i64;
549
550// The `stat` definition used by the Linux kernel.
551pub const kernel_stat = extern struct {
552 dev: dev_t,
553 __dev_padding: u32,
554 __ino_truncated: u32,
555 mode: mode_t,
556 nlink: nlink_t,
557 uid: uid_t,
558 gid: gid_t,
559 rdev: dev_t,
560 __rdev_padding: u32,
561 size: off_t,
562 blksize: blksize_t,
563 blocks: blkcnt_t,
564 atim: timespec,
565 mtim: timespec,
566 ctim: timespec,
567 ino: ino_t,
568
569 pub fn atime(self: @This()) timespec {
570 return self.atim;
571 }
572
573 pub fn mtime(self: @This()) timespec {
574 return self.mtim;
575 }
576
577 pub fn ctime(self: @This()) timespec {
578 return self.ctim;
579 }
580};
581
582// The `stat64` definition used by the libc.
583pub const libc_stat = kernel_stat;
584
585pub const timespec = extern struct {
586 tv_sec: i32,
587 tv_nsec: i32,
588};
589
590pub const timeval = extern struct {
591 tv_sec: i32,
592 tv_usec: i32,
593};
594
595pub const timezone = extern struct {
596 tz_minuteswest: i32,
597 tz_dsttime: i32,
598};
599
600pub const mcontext_t = extern struct {
601 gregs: [19]usize,
602 fpregs: [*]u8,
603 oldmask: usize,
604 cr2: usize,
605};
606
607pub const REG_GS = 0;
608pub const REG_FS = 1;
609pub const REG_ES = 2;
610pub const REG_DS = 3;
611pub const REG_EDI = 4;
612pub const REG_ESI = 5;
613pub const REG_EBP = 6;
614pub const REG_ESP = 7;
615pub const REG_EBX = 8;
616pub const REG_EDX = 9;
617pub const REG_ECX = 10;
618pub const REG_EAX = 11;
619pub const REG_TRAPNO = 12;
620pub const REG_ERR = 13;
621pub const REG_EIP = 14;
622pub const REG_CS = 15;
623pub const REG_EFL = 16;
624pub const REG_UESP = 17;
625pub const REG_SS = 18;
626
627pub const ucontext_t = extern struct {
628 flags: usize,
629 link: *ucontext_t,
630 stack: stack_t,
631 mcontext: mcontext_t,
632 sigmask: sigset_t,
633 regspace: [64]u64,
634};
635
636pub const Elf_Symndx = u32;
637
638pub const user_desc = packed struct {
639 entry_number: u32,
640 base_addr: u32,
641 limit: u32,
642 seg_32bit: u1,
643 contents: u2,
644 read_exec_only: u1,
645 limit_in_pages: u1,
646 seg_not_present: u1,
647 useable: u1,
648};
649
650// socketcall() call numbers
651pub const SC_socket = 1;
652pub const SC_bind = 2;
653pub const SC_connect = 3;
654pub const SC_listen = 4;
655pub const SC_accept = 5;
656pub const SC_getsockname = 6;
657pub const SC_getpeername = 7;
658pub const SC_socketpair = 8;
659pub const SC_send = 9;
660pub const SC_recv = 10;
661pub const SC_sendto = 11;
662pub const SC_recvfrom = 12;
663pub const SC_shutdown = 13;
664pub const SC_setsockopt = 14;
665pub const SC_getsockopt = 15;
666pub const SC_sendmsg = 16;
667pub const SC_recvmsg = 17;
668pub const SC_accept4 = 18;
669pub const SC_recvmmsg = 19;
670pub const SC_sendmmsg = 20;
lib/std/os/bits/linux/mips.zig deleted-622
...@@ -1,622 +0,0 @@
1const std = @import("../../../std.zig");
2const linux = std.os.linux;
3const socklen_t = linux.socklen_t;
4const iovec = linux.iovec;
5const iovec_const = linux.iovec_const;
6const uid_t = linux.uid_t;
7const gid_t = linux.gid_t;
8const pid_t = linux.pid_t;
9
10pub const SYS = enum(usize) {
11 pub const Linux = 4000;
12
13 syscall = Linux + 0,
14 exit = Linux + 1,
15 fork = Linux + 2,
16 read = Linux + 3,
17 write = Linux + 4,
18 open = Linux + 5,
19 close = Linux + 6,
20 waitpid = Linux + 7,
21 creat = Linux + 8,
22 link = Linux + 9,
23 unlink = Linux + 10,
24 execve = Linux + 11,
25 chdir = Linux + 12,
26 time = Linux + 13,
27 mknod = Linux + 14,
28 chmod = Linux + 15,
29 lchown = Linux + 16,
30 @"break" = Linux + 17,
31 unused18 = Linux + 18,
32 lseek = Linux + 19,
33 getpid = Linux + 20,
34 mount = Linux + 21,
35 umount = Linux + 22,
36 setuid = Linux + 23,
37 getuid = Linux + 24,
38 stime = Linux + 25,
39 ptrace = Linux + 26,
40 alarm = Linux + 27,
41 unused28 = Linux + 28,
42 pause = Linux + 29,
43 utime = Linux + 30,
44 stty = Linux + 31,
45 gtty = Linux + 32,
46 access = Linux + 33,
47 nice = Linux + 34,
48 ftime = Linux + 35,
49 sync = Linux + 36,
50 kill = Linux + 37,
51 rename = Linux + 38,
52 mkdir = Linux + 39,
53 rmdir = Linux + 40,
54 dup = Linux + 41,
55 pipe = Linux + 42,
56 times = Linux + 43,
57 prof = Linux + 44,
58 brk = Linux + 45,
59 setgid = Linux + 46,
60 getgid = Linux + 47,
61 signal = Linux + 48,
62 geteuid = Linux + 49,
63 getegid = Linux + 50,
64 acct = Linux + 51,
65 umount2 = Linux + 52,
66 lock = Linux + 53,
67 ioctl = Linux + 54,
68 fcntl = Linux + 55,
69 mpx = Linux + 56,
70 setpgid = Linux + 57,
71 ulimit = Linux + 58,
72 unused59 = Linux + 59,
73 umask = Linux + 60,
74 chroot = Linux + 61,
75 ustat = Linux + 62,
76 dup2 = Linux + 63,
77 getppid = Linux + 64,
78 getpgrp = Linux + 65,
79 setsid = Linux + 66,
80 sigaction = Linux + 67,
81 sgetmask = Linux + 68,
82 ssetmask = Linux + 69,
83 setreuid = Linux + 70,
84 setregid = Linux + 71,
85 sigsuspend = Linux + 72,
86 sigpending = Linux + 73,
87 sethostname = Linux + 74,
88 setrlimit = Linux + 75,
89 getrlimit = Linux + 76,
90 getrusage = Linux + 77,
91 gettimeofday = Linux + 78,
92 settimeofday = Linux + 79,
93 getgroups = Linux + 80,
94 setgroups = Linux + 81,
95 reserved82 = Linux + 82,
96 symlink = Linux + 83,
97 unused84 = Linux + 84,
98 readlink = Linux + 85,
99 uselib = Linux + 86,
100 swapon = Linux + 87,
101 reboot = Linux + 88,
102 readdir = Linux + 89,
103 mmap = Linux + 90,
104 munmap = Linux + 91,
105 truncate = Linux + 92,
106 ftruncate = Linux + 93,
107 fchmod = Linux + 94,
108 fchown = Linux + 95,
109 getpriority = Linux + 96,
110 setpriority = Linux + 97,
111 profil = Linux + 98,
112 statfs = Linux + 99,
113 fstatfs = Linux + 100,
114 ioperm = Linux + 101,
115 socketcall = Linux + 102,
116 syslog = Linux + 103,
117 setitimer = Linux + 104,
118 getitimer = Linux + 105,
119 stat = Linux + 106,
120 lstat = Linux + 107,
121 fstat = Linux + 108,
122 unused109 = Linux + 109,
123 iopl = Linux + 110,
124 vhangup = Linux + 111,
125 idle = Linux + 112,
126 vm86 = Linux + 113,
127 wait4 = Linux + 114,
128 swapoff = Linux + 115,
129 sysinfo = Linux + 116,
130 ipc = Linux + 117,
131 fsync = Linux + 118,
132 sigreturn = Linux + 119,
133 clone = Linux + 120,
134 setdomainname = Linux + 121,
135 uname = Linux + 122,
136 modify_ldt = Linux + 123,
137 adjtimex = Linux + 124,
138 mprotect = Linux + 125,
139 sigprocmask = Linux + 126,
140 create_module = Linux + 127,
141 init_module = Linux + 128,
142 delete_module = Linux + 129,
143 get_kernel_syms = Linux + 130,
144 quotactl = Linux + 131,
145 getpgid = Linux + 132,
146 fchdir = Linux + 133,
147 bdflush = Linux + 134,
148 sysfs = Linux + 135,
149 personality = Linux + 136,
150 afs_syscall = Linux + 137,
151 setfsuid = Linux + 138,
152 setfsgid = Linux + 139,
153 _llseek = Linux + 140,
154 getdents = Linux + 141,
155 _newselect = Linux + 142,
156 flock = Linux + 143,
157 msync = Linux + 144,
158 readv = Linux + 145,
159 writev = Linux + 146,
160 cacheflush = Linux + 147,
161 cachectl = Linux + 148,
162 sysmips = Linux + 149,
163 unused150 = Linux + 150,
164 getsid = Linux + 151,
165 fdatasync = Linux + 152,
166 _sysctl = Linux + 153,
167 mlock = Linux + 154,
168 munlock = Linux + 155,
169 mlockall = Linux + 156,
170 munlockall = Linux + 157,
171 sched_setparam = Linux + 158,
172 sched_getparam = Linux + 159,
173 sched_setscheduler = Linux + 160,
174 sched_getscheduler = Linux + 161,
175 sched_yield = Linux + 162,
176 sched_get_priority_max = Linux + 163,
177 sched_get_priority_min = Linux + 164,
178 sched_rr_get_interval = Linux + 165,
179 nanosleep = Linux + 166,
180 mremap = Linux + 167,
181 accept = Linux + 168,
182 bind = Linux + 169,
183 connect = Linux + 170,
184 getpeername = Linux + 171,
185 getsockname = Linux + 172,
186 getsockopt = Linux + 173,
187 listen = Linux + 174,
188 recv = Linux + 175,
189 recvfrom = Linux + 176,
190 recvmsg = Linux + 177,
191 send = Linux + 178,
192 sendmsg = Linux + 179,
193 sendto = Linux + 180,
194 setsockopt = Linux + 181,
195 shutdown = Linux + 182,
196 socket = Linux + 183,
197 socketpair = Linux + 184,
198 setresuid = Linux + 185,
199 getresuid = Linux + 186,
200 query_module = Linux + 187,
201 poll = Linux + 188,
202 nfsservctl = Linux + 189,
203 setresgid = Linux + 190,
204 getresgid = Linux + 191,
205 prctl = Linux + 192,
206 rt_sigreturn = Linux + 193,
207 rt_sigaction = Linux + 194,
208 rt_sigprocmask = Linux + 195,
209 rt_sigpending = Linux + 196,
210 rt_sigtimedwait = Linux + 197,
211 rt_sigqueueinfo = Linux + 198,
212 rt_sigsuspend = Linux + 199,
213 pread64 = Linux + 200,
214 pwrite64 = Linux + 201,
215 chown = Linux + 202,
216 getcwd = Linux + 203,
217 capget = Linux + 204,
218 capset = Linux + 205,
219 sigaltstack = Linux + 206,
220 sendfile = Linux + 207,
221 getpmsg = Linux + 208,
222 putpmsg = Linux + 209,
223 mmap2 = Linux + 210,
224 truncate64 = Linux + 211,
225 ftruncate64 = Linux + 212,
226 stat64 = Linux + 213,
227 lstat64 = Linux + 214,
228 fstat64 = Linux + 215,
229 pivot_root = Linux + 216,
230 mincore = Linux + 217,
231 madvise = Linux + 218,
232 getdents64 = Linux + 219,
233 fcntl64 = Linux + 220,
234 reserved221 = Linux + 221,
235 gettid = Linux + 222,
236 readahead = Linux + 223,
237 setxattr = Linux + 224,
238 lsetxattr = Linux + 225,
239 fsetxattr = Linux + 226,
240 getxattr = Linux + 227,
241 lgetxattr = Linux + 228,
242 fgetxattr = Linux + 229,
243 listxattr = Linux + 230,
244 llistxattr = Linux + 231,
245 flistxattr = Linux + 232,
246 removexattr = Linux + 233,
247 lremovexattr = Linux + 234,
248 fremovexattr = Linux + 235,
249 tkill = Linux + 236,
250 sendfile64 = Linux + 237,
251 futex = Linux + 238,
252 sched_setaffinity = Linux + 239,
253 sched_getaffinity = Linux + 240,
254 io_setup = Linux + 241,
255 io_destroy = Linux + 242,
256 io_getevents = Linux + 243,
257 io_submit = Linux + 244,
258 io_cancel = Linux + 245,
259 exit_group = Linux + 246,
260 lookup_dcookie = Linux + 247,
261 epoll_create = Linux + 248,
262 epoll_ctl = Linux + 249,
263 epoll_wait = Linux + 250,
264 remap_file_pages = Linux + 251,
265 set_tid_address = Linux + 252,
266 restart_syscall = Linux + 253,
267 fadvise64 = Linux + 254,
268 statfs64 = Linux + 255,
269 fstatfs64 = Linux + 256,
270 timer_create = Linux + 257,
271 timer_settime = Linux + 258,
272 timer_gettime = Linux + 259,
273 timer_getoverrun = Linux + 260,
274 timer_delete = Linux + 261,
275 clock_settime = Linux + 262,
276 clock_gettime = Linux + 263,
277 clock_getres = Linux + 264,
278 clock_nanosleep = Linux + 265,
279 tgkill = Linux + 266,
280 utimes = Linux + 267,
281 mbind = Linux + 268,
282 get_mempolicy = Linux + 269,
283 set_mempolicy = Linux + 270,
284 mq_open = Linux + 271,
285 mq_unlink = Linux + 272,
286 mq_timedsend = Linux + 273,
287 mq_timedreceive = Linux + 274,
288 mq_notify = Linux + 275,
289 mq_getsetattr = Linux + 276,
290 vserver = Linux + 277,
291 waitid = Linux + 278,
292 add_key = Linux + 280,
293 request_key = Linux + 281,
294 keyctl = Linux + 282,
295 set_thread_area = Linux + 283,
296 inotify_init = Linux + 284,
297 inotify_add_watch = Linux + 285,
298 inotify_rm_watch = Linux + 286,
299 migrate_pages = Linux + 287,
300 openat = Linux + 288,
301 mkdirat = Linux + 289,
302 mknodat = Linux + 290,
303 fchownat = Linux + 291,
304 futimesat = Linux + 292,
305 fstatat64 = Linux + 293,
306 unlinkat = Linux + 294,
307 renameat = Linux + 295,
308 linkat = Linux + 296,
309 symlinkat = Linux + 297,
310 readlinkat = Linux + 298,
311 fchmodat = Linux + 299,
312 faccessat = Linux + 300,
313 pselect6 = Linux + 301,
314 ppoll = Linux + 302,
315 unshare = Linux + 303,
316 splice = Linux + 304,
317 sync_file_range = Linux + 305,
318 tee = Linux + 306,
319 vmsplice = Linux + 307,
320 move_pages = Linux + 308,
321 set_robust_list = Linux + 309,
322 get_robust_list = Linux + 310,
323 kexec_load = Linux + 311,
324 getcpu = Linux + 312,
325 epoll_pwait = Linux + 313,
326 ioprio_set = Linux + 314,
327 ioprio_get = Linux + 315,
328 utimensat = Linux + 316,
329 signalfd = Linux + 317,
330 timerfd = Linux + 318,
331 eventfd = Linux + 319,
332 fallocate = Linux + 320,
333 timerfd_create = Linux + 321,
334 timerfd_gettime = Linux + 322,
335 timerfd_settime = Linux + 323,
336 signalfd4 = Linux + 324,
337 eventfd2 = Linux + 325,
338 epoll_create1 = Linux + 326,
339 dup3 = Linux + 327,
340 pipe2 = Linux + 328,
341 inotify_init1 = Linux + 329,
342 preadv = Linux + 330,
343 pwritev = Linux + 331,
344 rt_tgsigqueueinfo = Linux + 332,
345 perf_event_open = Linux + 333,
346 accept4 = Linux + 334,
347 recvmmsg = Linux + 335,
348 fanotify_init = Linux + 336,
349 fanotify_mark = Linux + 337,
350 prlimit64 = Linux + 338,
351 name_to_handle_at = Linux + 339,
352 open_by_handle_at = Linux + 340,
353 clock_adjtime = Linux + 341,
354 syncfs = Linux + 342,
355 sendmmsg = Linux + 343,
356 setns = Linux + 344,
357 process_vm_readv = Linux + 345,
358 process_vm_writev = Linux + 346,
359 kcmp = Linux + 347,
360 finit_module = Linux + 348,
361 sched_setattr = Linux + 349,
362 sched_getattr = Linux + 350,
363 renameat2 = Linux + 351,
364 seccomp = Linux + 352,
365 getrandom = Linux + 353,
366 memfd_create = Linux + 354,
367 bpf = Linux + 355,
368 execveat = Linux + 356,
369 userfaultfd = Linux + 357,
370 membarrier = Linux + 358,
371 mlock2 = Linux + 359,
372 copy_file_range = Linux + 360,
373 preadv2 = Linux + 361,
374 pwritev2 = Linux + 362,
375 pkey_mprotect = Linux + 363,
376 pkey_alloc = Linux + 364,
377 pkey_free = Linux + 365,
378 statx = Linux + 366,
379 rseq = Linux + 367,
380 io_pgetevents = Linux + 368,
381 semget = Linux + 393,
382 semctl = Linux + 394,
383 shmget = Linux + 395,
384 shmctl = Linux + 396,
385 shmat = Linux + 397,
386 shmdt = Linux + 398,
387 msgget = Linux + 399,
388 msgsnd = Linux + 400,
389 msgrcv = Linux + 401,
390 msgctl = Linux + 402,
391 clock_gettime64 = Linux + 403,
392 clock_settime64 = Linux + 404,
393 clock_adjtime64 = Linux + 405,
394 clock_getres_time64 = Linux + 406,
395 clock_nanosleep_time64 = Linux + 407,
396 timer_gettime64 = Linux + 408,
397 timer_settime64 = Linux + 409,
398 timerfd_gettime64 = Linux + 410,
399 timerfd_settime64 = Linux + 411,
400 utimensat_time64 = Linux + 412,
401 pselect6_time64 = Linux + 413,
402 ppoll_time64 = Linux + 414,
403 io_pgetevents_time64 = Linux + 416,
404 recvmmsg_time64 = Linux + 417,
405 mq_timedsend_time64 = Linux + 418,
406 mq_timedreceive_time64 = Linux + 419,
407 semtimedop_time64 = Linux + 420,
408 rt_sigtimedwait_time64 = Linux + 421,
409 futex_time64 = Linux + 422,
410 sched_rr_get_interval_time64 = Linux + 423,
411 pidfd_send_signal = Linux + 424,
412 io_uring_setup = Linux + 425,
413 io_uring_enter = Linux + 426,
414 io_uring_register = Linux + 427,
415 open_tree = Linux + 428,
416 move_mount = Linux + 429,
417 fsopen = Linux + 430,
418 fsconfig = Linux + 431,
419 fsmount = Linux + 432,
420 fspick = Linux + 433,
421 pidfd_open = Linux + 434,
422 clone3 = Linux + 435,
423 close_range = Linux + 436,
424 openat2 = Linux + 437,
425 pidfd_getfd = Linux + 438,
426 faccessat2 = Linux + 439,
427 process_madvise = Linux + 440,
428 epoll_pwait2 = Linux + 441,
429
430 _,
431};
432
433pub const O_CREAT = 0o0400;
434pub const O_EXCL = 0o02000;
435pub const O_NOCTTY = 0o04000;
436pub const O_TRUNC = 0o01000;
437pub const O_APPEND = 0o0010;
438pub const O_NONBLOCK = 0o0200;
439pub const O_DSYNC = 0o0020;
440pub const O_SYNC = 0o040020;
441pub const O_RSYNC = 0o040020;
442pub const O_DIRECTORY = 0o0200000;
443pub const O_NOFOLLOW = 0o0400000;
444pub const O_CLOEXEC = 0o02000000;
445
446pub const O_ASYNC = 0o010000;
447pub const O_DIRECT = 0o0100000;
448pub const O_LARGEFILE = 0o020000;
449pub const O_NOATIME = 0o01000000;
450pub const O_PATH = 0o010000000;
451pub const O_TMPFILE = 0o020200000;
452pub const O_NDELAY = O_NONBLOCK;
453
454pub const F_DUPFD = 0;
455pub const F_GETFD = 1;
456pub const F_SETFD = 2;
457pub const F_GETFL = 3;
458pub const F_SETFL = 4;
459
460pub const F_SETOWN = 24;
461pub const F_GETOWN = 23;
462pub const F_SETSIG = 10;
463pub const F_GETSIG = 11;
464
465pub const F_GETLK = 33;
466pub const F_SETLK = 34;
467pub const F_SETLKW = 35;
468
469pub const F_RDLCK = 0;
470pub const F_WRLCK = 1;
471pub const F_UNLCK = 2;
472
473pub const LOCK_SH = 1;
474pub const LOCK_EX = 2;
475pub const LOCK_UN = 8;
476pub const LOCK_NB = 4;
477
478pub const F_SETOWN_EX = 15;
479pub const F_GETOWN_EX = 16;
480
481pub const F_GETOWNER_UIDS = 17;
482
483pub const MMAP2_UNIT = 4096;
484
485pub const MAP_NORESERVE = 0x0400;
486pub const MAP_GROWSDOWN = 0x1000;
487pub const MAP_DENYWRITE = 0x2000;
488pub const MAP_EXECUTABLE = 0x4000;
489pub const MAP_LOCKED = 0x8000;
490pub const MAP_32BIT = 0x40;
491
492pub const SO_DEBUG = 1;
493pub const SO_REUSEADDR = 0x0004;
494pub const SO_KEEPALIVE = 0x0008;
495pub const SO_DONTROUTE = 0x0010;
496pub const SO_BROADCAST = 0x0020;
497pub const SO_LINGER = 0x0080;
498pub const SO_OOBINLINE = 0x0100;
499pub const SO_REUSEPORT = 0x0200;
500pub const SO_SNDBUF = 0x1001;
501pub const SO_RCVBUF = 0x1002;
502pub const SO_SNDLOWAT = 0x1003;
503pub const SO_RCVLOWAT = 0x1004;
504pub const SO_RCVTIMEO = 0x1006;
505pub const SO_SNDTIMEO = 0x1005;
506pub const SO_ERROR = 0x1007;
507pub const SO_TYPE = 0x1008;
508pub const SO_ACCEPTCONN = 0x1009;
509pub const SO_PROTOCOL = 0x1028;
510pub const SO_DOMAIN = 0x1029;
511pub const SO_NO_CHECK = 11;
512pub const SO_PRIORITY = 12;
513pub const SO_BSDCOMPAT = 14;
514pub const SO_PASSCRED = 17;
515pub const SO_PEERCRED = 18;
516pub const SO_PEERSEC = 30;
517pub const SO_SNDBUFFORCE = 31;
518pub const SO_RCVBUFFORCE = 33;
519
520pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
521pub const VDSO_CGT_VER = "LINUX_2.6.39";
522
523pub const Flock = extern struct {
524 l_type: i16,
525 l_whence: i16,
526 __pad0: [4]u8,
527 l_start: off_t,
528 l_len: off_t,
529 l_pid: pid_t,
530 __unused: [4]u8,
531};
532
533pub const blksize_t = i32;
534pub const nlink_t = u32;
535pub const time_t = i32;
536pub const mode_t = u32;
537pub const off_t = i64;
538pub const ino_t = u64;
539pub const dev_t = u64;
540pub const blkcnt_t = i64;
541
542// The `stat` definition used by the Linux kernel.
543pub const kernel_stat = extern struct {
544 dev: u32,
545 __pad0: [3]u32, // Reserved for st_dev expansion
546 ino: ino_t,
547 mode: mode_t,
548 nlink: nlink_t,
549 uid: uid_t,
550 gid: gid_t,
551 rdev: u32,
552 __pad1: [3]u32,
553 size: off_t,
554 atim: timespec,
555 mtim: timespec,
556 ctim: timespec,
557 blksize: blksize_t,
558 __pad3: u32,
559 blocks: blkcnt_t,
560 __pad4: [14]usize,
561
562 pub fn atime(self: @This()) timespec {
563 return self.atim;
564 }
565
566 pub fn mtime(self: @This()) timespec {
567 return self.mtim;
568 }
569
570 pub fn ctime(self: @This()) timespec {
571 return self.ctim;
572 }
573};
574
575pub const libc_stat = extern struct {
576 dev: dev_t,
577 __pad0: [2]u32,
578 ino: ino_t,
579 mode: mode_t,
580 nlink: nlink_t,
581 uid: uid_t,
582 gid: gid_t,
583 rdev: dev_t,
584 __pad1: [2]u32,
585 size: off_t,
586 atim: timespec,
587 mtim: timespec,
588 ctim: timespec,
589 blksize: blksize_t,
590 __pad3: u32,
591 blocks: blkcnt_t,
592 __pad4: [14]u32,
593
594 pub fn atime(self: @This()) timespec {
595 return self.atim;
596 }
597
598 pub fn mtime(self: @This()) timespec {
599 return self.mtim;
600 }
601
602 pub fn ctime(self: @This()) timespec {
603 return self.ctim;
604 }
605};
606
607pub const timespec = extern struct {
608 tv_sec: isize,
609 tv_nsec: isize,
610};
611
612pub const timeval = extern struct {
613 tv_sec: isize,
614 tv_usec: isize,
615};
616
617pub const timezone = extern struct {
618 tz_minuteswest: i32,
619 tz_dsttime: i32,
620};
621
622pub const Elf_Symndx = u32;
lib/std/os/bits/linux/netlink.zig deleted-498
...@@ -1,498 +0,0 @@
1usingnamespace @import("../linux.zig");
2
3/// Routing/device hook
4pub const NETLINK_ROUTE = 0;
5
6/// Unused number
7pub const NETLINK_UNUSED = 1;
8
9/// Reserved for user mode socket protocols
10pub const NETLINK_USERSOCK = 2;
11
12/// Unused number, formerly ip_queue
13pub const NETLINK_FIREWALL = 3;
14
15/// socket monitoring
16pub const NETLINK_SOCK_DIAG = 4;
17
18/// netfilter/iptables ULOG
19pub const NETLINK_NFLOG = 5;
20
21/// ipsec
22pub const NETLINK_XFRM = 6;
23
24/// SELinux event notifications
25pub const NETLINK_SELINUX = 7;
26
27/// Open-iSCSI
28pub const NETLINK_ISCSI = 8;
29
30/// auditing
31pub const NETLINK_AUDIT = 9;
32
33pub const NETLINK_FIB_LOOKUP = 10;
34
35pub const NETLINK_CONNECTOR = 11;
36
37/// netfilter subsystem
38pub const NETLINK_NETFILTER = 12;
39
40pub const NETLINK_IP6_FW = 13;
41
42/// DECnet routing messages
43pub const NETLINK_DNRTMSG = 14;
44
45/// Kernel messages to userspace
46pub const NETLINK_KOBJECT_UEVENT = 15;
47
48pub const NETLINK_GENERIC = 16;
49
50// leave room for NETLINK_DM (DM Events)
51
52/// SCSI Transports
53pub const NETLINK_SCSITRANSPORT = 18;
54
55pub const NETLINK_ECRYPTFS = 19;
56
57pub const NETLINK_RDMA = 20;
58
59/// Crypto layer
60pub const NETLINK_CRYPTO = 21;
61
62/// SMC monitoring
63pub const NETLINK_SMC = 22;
64
65// Flags values
66
67/// It is request message.
68pub const NLM_F_REQUEST = 0x01;
69
70/// Multipart message, terminated by NLMSG_DONE
71pub const NLM_F_MULTI = 0x02;
72
73/// Reply with ack, with zero or error code
74pub const NLM_F_ACK = 0x04;
75
76/// Echo this request
77pub const NLM_F_ECHO = 0x08;
78
79/// Dump was inconsistent due to sequence change
80pub const NLM_F_DUMP_INTR = 0x10;
81
82/// Dump was filtered as requested
83pub const NLM_F_DUMP_FILTERED = 0x20;
84
85// Modifiers to GET request
86
87/// specify tree root
88pub const NLM_F_ROOT = 0x100;
89
90/// return all matching
91pub const NLM_F_MATCH = 0x200;
92
93/// atomic GET
94pub const NLM_F_ATOMIC = 0x400;
95pub const NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH;
96
97// Modifiers to NEW request
98
99/// Override existing
100pub const NLM_F_REPLACE = 0x100;
101
102/// Do not touch, if it exists
103pub const NLM_F_EXCL = 0x200;
104
105/// Create, if it does not exist
106pub const NLM_F_CREATE = 0x400;
107
108/// Add to end of list
109pub const NLM_F_APPEND = 0x800;
110
111// Modifiers to DELETE request
112
113/// Do not delete recursively
114pub const NLM_F_NONREC = 0x100;
115
116// Flags for ACK message
117
118/// request was capped
119pub const NLM_F_CAPPED = 0x100;
120
121/// extended ACK TVLs were included
122pub const NLM_F_ACK_TLVS = 0x200;
123
124pub const NetlinkMessageType = enum(u16) {
125 /// < 0x10: reserved control messages
126 pub const MIN_TYPE = 0x10;
127
128 /// Nothing.
129 NOOP = 0x1,
130
131 /// Error
132 ERROR = 0x2,
133
134 /// End of a dump
135 DONE = 0x3,
136
137 /// Data lost
138 OVERRUN = 0x4,
139
140 // rtlink types
141
142 RTM_NEWLINK = 16,
143 RTM_DELLINK,
144 RTM_GETLINK,
145 RTM_SETLINK,
146
147 RTM_NEWADDR = 20,
148 RTM_DELADDR,
149 RTM_GETADDR,
150
151 RTM_NEWROUTE = 24,
152 RTM_DELROUTE,
153 RTM_GETROUTE,
154
155 RTM_NEWNEIGH = 28,
156 RTM_DELNEIGH,
157 RTM_GETNEIGH,
158
159 RTM_NEWRULE = 32,
160 RTM_DELRULE,
161 RTM_GETRULE,
162
163 RTM_NEWQDISC = 36,
164 RTM_DELQDISC,
165 RTM_GETQDISC,
166
167 RTM_NEWTCLASS = 40,
168 RTM_DELTCLASS,
169 RTM_GETTCLASS,
170
171 RTM_NEWTFILTER = 44,
172 RTM_DELTFILTER,
173 RTM_GETTFILTER,
174
175 RTM_NEWACTION = 48,
176 RTM_DELACTION,
177 RTM_GETACTION,
178
179 RTM_NEWPREFIX = 52,
180
181 RTM_GETMULTICAST = 58,
182
183 RTM_GETANYCAST = 62,
184
185 RTM_NEWNEIGHTBL = 64,
186 RTM_GETNEIGHTBL = 66,
187 RTM_SETNEIGHTBL,
188
189 RTM_NEWNDUSEROPT = 68,
190
191 RTM_NEWADDRLABEL = 72,
192 RTM_DELADDRLABEL,
193 RTM_GETADDRLABEL,
194
195 RTM_GETDCB = 78,
196 RTM_SETDCB,
197
198 RTM_NEWNETCONF = 80,
199 RTM_DELNETCONF,
200 RTM_GETNETCONF = 82,
201
202 RTM_NEWMDB = 84,
203 RTM_DELMDB = 85,
204 RTM_GETMDB = 86,
205
206 RTM_NEWNSID = 88,
207 RTM_DELNSID = 89,
208 RTM_GETNSID = 90,
209
210 RTM_NEWSTATS = 92,
211 RTM_GETSTATS = 94,
212
213 RTM_NEWCACHEREPORT = 96,
214
215 RTM_NEWCHAIN = 100,
216 RTM_DELCHAIN,
217 RTM_GETCHAIN,
218
219 RTM_NEWNEXTHOP = 104,
220 RTM_DELNEXTHOP,
221 RTM_GETNEXTHOP,
222
223 _,
224};
225
226/// Netlink socket address
227pub const sockaddr_nl = extern struct {
228 family: sa_family_t = AF_NETLINK,
229 __pad1: c_ushort = 0,
230
231 /// port ID
232 pid: u32,
233
234 /// multicast groups mask
235 groups: u32,
236};
237
238/// Netlink message header
239/// Specified in RFC 3549 Section 2.3.2
240pub const nlmsghdr = extern struct {
241 /// Length of message including header
242 len: u32,
243
244 /// Message content
245 @"type": NetlinkMessageType,
246
247 /// Additional flags
248 flags: u16,
249
250 /// Sequence number
251 seq: u32,
252
253 /// Sending process port ID
254 pid: u32,
255};
256
257pub const ifinfomsg = extern struct {
258 family: u8,
259 __pad1: u8 = 0,
260
261 /// ARPHRD_*
262 @"type": c_ushort,
263
264 /// Link index
265 index: c_int,
266
267 /// IFF_* flags
268 flags: c_uint,
269
270 /// IFF_* change mask
271 change: c_uint,
272};
273
274pub const rtattr = extern struct {
275 /// Length of option
276 len: c_ushort,
277
278 /// Type of option
279 @"type": IFLA,
280
281 pub const ALIGNTO = 4;
282};
283
284pub const IFLA = enum(c_ushort) {
285 UNSPEC,
286 ADDRESS,
287 BROADCAST,
288 IFNAME,
289 MTU,
290 LINK,
291 QDISC,
292 STATS,
293 COST,
294 PRIORITY,
295 MASTER,
296
297 /// Wireless Extension event
298 WIRELESS,
299
300 /// Protocol specific information for a link
301 PROTINFO,
302
303 TXQLEN,
304 MAP,
305 WEIGHT,
306 OPERSTATE,
307 LINKMODE,
308 LINKINFO,
309 NET_NS_PID,
310 IFALIAS,
311
312 /// Number of VFs if device is SR-IOV PF
313 NUM_VF,
314
315 VFINFO_LIST,
316 STATS64,
317 VF_PORTS,
318 PORT_SELF,
319 AF_SPEC,
320
321 /// Group the device belongs to
322 GROUP,
323
324 NET_NS_FD,
325
326 /// Extended info mask, VFs, etc
327 EXT_MASK,
328
329 /// Promiscuity count: > 0 means acts PROMISC
330 PROMISCUITY,
331
332 NUM_TX_QUEUES,
333 NUM_RX_QUEUES,
334 CARRIER,
335 PHYS_PORT_ID,
336 CARRIER_CHANGES,
337 PHYS_SWITCH_ID,
338 LINK_NETNSID,
339 PHYS_PORT_NAME,
340 PROTO_DOWN,
341 GSO_MAX_SEGS,
342 GSO_MAX_SIZE,
343 PAD,
344 XDP,
345 EVENT,
346
347 NEW_NETNSID,
348 IF_NETNSID,
349
350 CARRIER_UP_COUNT,
351 CARRIER_DOWN_COUNT,
352 NEW_IFINDEX,
353 MIN_MTU,
354 MAX_MTU,
355
356 _,
357
358 pub const TARGET_NETNSID: IFLA = .IF_NETNSID;
359};
360
361pub const rtnl_link_ifmap = extern struct {
362 mem_start: u64,
363 mem_end: u64,
364 base_addr: u64,
365 irq: u16,
366 dma: u8,
367 port: u8,
368};
369
370pub const rtnl_link_stats = extern struct {
371 /// total packets received
372 rx_packets: u32,
373
374 /// total packets transmitted
375 tx_packets: u32,
376
377 /// total bytes received
378 rx_bytes: u32,
379
380 /// total bytes transmitted
381 tx_bytes: u32,
382
383 /// bad packets received
384 rx_errors: u32,
385
386 /// packet transmit problems
387 tx_errors: u32,
388
389 /// no space in linux buffers
390 rx_dropped: u32,
391
392 /// no space available in linux
393 tx_dropped: u32,
394
395 /// multicast packets received
396 multicast: u32,
397
398 collisions: u32,
399
400 // detailed rx_errors
401
402 rx_length_errors: u32,
403
404 /// receiver ring buff overflow
405 rx_over_errors: u32,
406
407 /// recved pkt with crc error
408 rx_crc_errors: u32,
409
410 /// recv'd frame alignment error
411 rx_frame_errors: u32,
412
413 /// recv'r fifo overrun
414 rx_fifo_errors: u32,
415
416 /// receiver missed packet
417 rx_missed_errors: u32,
418
419 // detailed tx_errors
420 tx_aborted_errors: u32,
421 tx_carrier_errors: u32,
422 tx_fifo_errors: u32,
423 tx_heartbeat_errors: u32,
424 tx_window_errors: u32,
425
426 // for cslip etc
427
428 rx_compressed: u32,
429 tx_compressed: u32,
430
431 /// dropped, no handler found
432 rx_nohandler: u32,
433};
434
435pub const rtnl_link_stats64 = extern struct {
436 /// total packets received
437 rx_packets: u64,
438
439 /// total packets transmitted
440 tx_packets: u64,
441
442 /// total bytes received
443 rx_bytes: u64,
444
445 /// total bytes transmitted
446 tx_bytes: u64,
447
448 /// bad packets received
449 rx_errors: u64,
450
451 /// packet transmit problems
452 tx_errors: u64,
453
454 /// no space in linux buffers
455 rx_dropped: u64,
456
457 /// no space available in linux
458 tx_dropped: u64,
459
460 /// multicast packets received
461 multicast: u64,
462
463 collisions: u64,
464
465 // detailed rx_errors
466
467 rx_length_errors: u64,
468
469 /// receiver ring buff overflow
470 rx_over_errors: u64,
471
472 /// recved pkt with crc error
473 rx_crc_errors: u64,
474
475 /// recv'd frame alignment error
476 rx_frame_errors: u64,
477
478 /// recv'r fifo overrun
479 rx_fifo_errors: u64,
480
481 /// receiver missed packet
482 rx_missed_errors: u64,
483
484 // detailed tx_errors
485 tx_aborted_errors: u64,
486 tx_carrier_errors: u64,
487 tx_fifo_errors: u64,
488 tx_heartbeat_errors: u64,
489 tx_window_errors: u64,
490
491 // for cslip etc
492
493 rx_compressed: u64,
494 tx_compressed: u64,
495
496 /// dropped, no handler found
497 rx_nohandler: u64,
498};
lib/std/os/bits/linux/powerpc.zig deleted-621
...@@ -1,621 +0,0 @@
1const std = @import("../../../std.zig");
2const linux = std.os.linux;
3const socklen_t = linux.socklen_t;
4const iovec = linux.iovec;
5const iovec_const = linux.iovec_const;
6const uid_t = linux.uid_t;
7const gid_t = linux.gid_t;
8const pid_t = linux.pid_t;
9const stack_t = linux.stack_t;
10const sigset_t = linux.sigset_t;
11pub const SYS = enum(usize) {
12 restart_syscall = 0,
13 exit = 1,
14 fork = 2,
15 read = 3,
16 write = 4,
17 open = 5,
18 close = 6,
19 waitpid = 7,
20 creat = 8,
21 link = 9,
22 unlink = 10,
23 execve = 11,
24 chdir = 12,
25 time = 13,
26 mknod = 14,
27 chmod = 15,
28 lchown = 16,
29 @"break" = 17,
30 oldstat = 18,
31 lseek = 19,
32 getpid = 20,
33 mount = 21,
34 umount = 22,
35 setuid = 23,
36 getuid = 24,
37 stime = 25,
38 ptrace = 26,
39 alarm = 27,
40 oldfstat = 28,
41 pause = 29,
42 utime = 30,
43 stty = 31,
44 gtty = 32,
45 access = 33,
46 nice = 34,
47 ftime = 35,
48 sync = 36,
49 kill = 37,
50 rename = 38,
51 mkdir = 39,
52 rmdir = 40,
53 dup = 41,
54 pipe = 42,
55 times = 43,
56 prof = 44,
57 brk = 45,
58 setgid = 46,
59 getgid = 47,
60 signal = 48,
61 geteuid = 49,
62 getegid = 50,
63 acct = 51,
64 umount2 = 52,
65 lock = 53,
66 ioctl = 54,
67 fcntl = 55,
68 mpx = 56,
69 setpgid = 57,
70 ulimit = 58,
71 oldolduname = 59,
72 umask = 60,
73 chroot = 61,
74 ustat = 62,
75 dup2 = 63,
76 getppid = 64,
77 getpgrp = 65,
78 setsid = 66,
79 sigaction = 67,
80 sgetmask = 68,
81 ssetmask = 69,
82 setreuid = 70,
83 setregid = 71,
84 sigsuspend = 72,
85 sigpending = 73,
86 sethostname = 74,
87 setrlimit = 75,
88 getrlimit = 76,
89 getrusage = 77,
90 gettimeofday = 78,
91 settimeofday = 79,
92 getgroups = 80,
93 setgroups = 81,
94 select = 82,
95 symlink = 83,
96 oldlstat = 84,
97 readlink = 85,
98 uselib = 86,
99 swapon = 87,
100 reboot = 88,
101 readdir = 89,
102 mmap = 90,
103 munmap = 91,
104 truncate = 92,
105 ftruncate = 93,
106 fchmod = 94,
107 fchown = 95,
108 getpriority = 96,
109 setpriority = 97,
110 profil = 98,
111 statfs = 99,
112 fstatfs = 100,
113 ioperm = 101,
114 socketcall = 102,
115 syslog = 103,
116 setitimer = 104,
117 getitimer = 105,
118 stat = 106,
119 lstat = 107,
120 fstat = 108,
121 olduname = 109,
122 iopl = 110,
123 vhangup = 111,
124 idle = 112,
125 vm86 = 113,
126 wait4 = 114,
127 swapoff = 115,
128 sysinfo = 116,
129 ipc = 117,
130 fsync = 118,
131 sigreturn = 119,
132 clone = 120,
133 setdomainname = 121,
134 uname = 122,
135 modify_ldt = 123,
136 adjtimex = 124,
137 mprotect = 125,
138 sigprocmask = 126,
139 create_module = 127,
140 init_module = 128,
141 delete_module = 129,
142 get_kernel_syms = 130,
143 quotactl = 131,
144 getpgid = 132,
145 fchdir = 133,
146 bdflush = 134,
147 sysfs = 135,
148 personality = 136,
149 afs_syscall = 137,
150 setfsuid = 138,
151 setfsgid = 139,
152 _llseek = 140,
153 getdents = 141,
154 _newselect = 142,
155 flock = 143,
156 msync = 144,
157 readv = 145,
158 writev = 146,
159 getsid = 147,
160 fdatasync = 148,
161 _sysctl = 149,
162 mlock = 150,
163 munlock = 151,
164 mlockall = 152,
165 munlockall = 153,
166 sched_setparam = 154,
167 sched_getparam = 155,
168 sched_setscheduler = 156,
169 sched_getscheduler = 157,
170 sched_yield = 158,
171 sched_get_priority_max = 159,
172 sched_get_priority_min = 160,
173 sched_rr_get_interval = 161,
174 nanosleep = 162,
175 mremap = 163,
176 setresuid = 164,
177 getresuid = 165,
178 query_module = 166,
179 poll = 167,
180 nfsservctl = 168,
181 setresgid = 169,
182 getresgid = 170,
183 prctl = 171,
184 rt_sigreturn = 172,
185 rt_sigaction = 173,
186 rt_sigprocmask = 174,
187 rt_sigpending = 175,
188 rt_sigtimedwait = 176,
189 rt_sigqueueinfo = 177,
190 rt_sigsuspend = 178,
191 pread64 = 179,
192 pwrite64 = 180,
193 chown = 181,
194 getcwd = 182,
195 capget = 183,
196 capset = 184,
197 sigaltstack = 185,
198 sendfile = 186,
199 getpmsg = 187,
200 putpmsg = 188,
201 vfork = 189,
202 ugetrlimit = 190,
203 readahead = 191,
204 mmap2 = 192,
205 truncate64 = 193,
206 ftruncate64 = 194,
207 stat64 = 195,
208 lstat64 = 196,
209 fstat64 = 197,
210 pciconfig_read = 198,
211 pciconfig_write = 199,
212 pciconfig_iobase = 200,
213 multiplexer = 201,
214 getdents64 = 202,
215 pivot_root = 203,
216 fcntl64 = 204,
217 madvise = 205,
218 mincore = 206,
219 gettid = 207,
220 tkill = 208,
221 setxattr = 209,
222 lsetxattr = 210,
223 fsetxattr = 211,
224 getxattr = 212,
225 lgetxattr = 213,
226 fgetxattr = 214,
227 listxattr = 215,
228 llistxattr = 216,
229 flistxattr = 217,
230 removexattr = 218,
231 lremovexattr = 219,
232 fremovexattr = 220,
233 futex = 221,
234 sched_setaffinity = 222,
235 sched_getaffinity = 223,
236 tuxcall = 225,
237 sendfile64 = 226,
238 io_setup = 227,
239 io_destroy = 228,
240 io_getevents = 229,
241 io_submit = 230,
242 io_cancel = 231,
243 set_tid_address = 232,
244 fadvise64 = 233,
245 exit_group = 234,
246 lookup_dcookie = 235,
247 epoll_create = 236,
248 epoll_ctl = 237,
249 epoll_wait = 238,
250 remap_file_pages = 239,
251 timer_create = 240,
252 timer_settime = 241,
253 timer_gettime = 242,
254 timer_getoverrun = 243,
255 timer_delete = 244,
256 clock_settime = 245,
257 clock_gettime = 246,
258 clock_getres = 247,
259 clock_nanosleep = 248,
260 swapcontext = 249,
261 tgkill = 250,
262 utimes = 251,
263 statfs64 = 252,
264 fstatfs64 = 253,
265 fadvise64_64 = 254,
266 rtas = 255,
267 sys_debug_setcontext = 256,
268 migrate_pages = 258,
269 mbind = 259,
270 get_mempolicy = 260,
271 set_mempolicy = 261,
272 mq_open = 262,
273 mq_unlink = 263,
274 mq_timedsend = 264,
275 mq_timedreceive = 265,
276 mq_notify = 266,
277 mq_getsetattr = 267,
278 kexec_load = 268,
279 add_key = 269,
280 request_key = 270,
281 keyctl = 271,
282 waitid = 272,
283 ioprio_set = 273,
284 ioprio_get = 274,
285 inotify_init = 275,
286 inotify_add_watch = 276,
287 inotify_rm_watch = 277,
288 spu_run = 278,
289 spu_create = 279,
290 pselect6 = 280,
291 ppoll = 281,
292 unshare = 282,
293 splice = 283,
294 tee = 284,
295 vmsplice = 285,
296 openat = 286,
297 mkdirat = 287,
298 mknodat = 288,
299 fchownat = 289,
300 futimesat = 290,
301 fstatat64 = 291,
302 unlinkat = 292,
303 renameat = 293,
304 linkat = 294,
305 symlinkat = 295,
306 readlinkat = 296,
307 fchmodat = 297,
308 faccessat = 298,
309 get_robust_list = 299,
310 set_robust_list = 300,
311 move_pages = 301,
312 getcpu = 302,
313 epoll_pwait = 303,
314 utimensat = 304,
315 signalfd = 305,
316 timerfd_create = 306,
317 eventfd = 307,
318 sync_file_range = 308,
319 fallocate = 309,
320 subpage_prot = 310,
321 timerfd_settime = 311,
322 timerfd_gettime = 312,
323 signalfd4 = 313,
324 eventfd2 = 314,
325 epoll_create1 = 315,
326 dup3 = 316,
327 pipe2 = 317,
328 inotify_init1 = 318,
329 perf_event_open = 319,
330 preadv = 320,
331 pwritev = 321,
332 rt_tgsigqueueinfo = 322,
333 fanotify_init = 323,
334 fanotify_mark = 324,
335 prlimit64 = 325,
336 socket = 326,
337 bind = 327,
338 connect = 328,
339 listen = 329,
340 accept = 330,
341 getsockname = 331,
342 getpeername = 332,
343 socketpair = 333,
344 send = 334,
345 sendto = 335,
346 recv = 336,
347 recvfrom = 337,
348 shutdown = 338,
349 setsockopt = 339,
350 getsockopt = 340,
351 sendmsg = 341,
352 recvmsg = 342,
353 recvmmsg = 343,
354 accept4 = 344,
355 name_to_handle_at = 345,
356 open_by_handle_at = 346,
357 clock_adjtime = 347,
358 syncfs = 348,
359 sendmmsg = 349,
360 setns = 350,
361 process_vm_readv = 351,
362 process_vm_writev = 352,
363 finit_module = 353,
364 kcmp = 354,
365 sched_setattr = 355,
366 sched_getattr = 356,
367 renameat2 = 357,
368 seccomp = 358,
369 getrandom = 359,
370 memfd_create = 360,
371 bpf = 361,
372 execveat = 362,
373 switch_endian = 363,
374 userfaultfd = 364,
375 membarrier = 365,
376 mlock2 = 378,
377 copy_file_range = 379,
378 preadv2 = 380,
379 pwritev2 = 381,
380 kexec_file_load = 382,
381 statx = 383,
382 pkey_alloc = 384,
383 pkey_free = 385,
384 pkey_mprotect = 386,
385 rseq = 387,
386 io_pgetevents = 388,
387 semget = 393,
388 semctl = 394,
389 shmget = 395,
390 shmctl = 396,
391 shmat = 397,
392 shmdt = 398,
393 msgget = 399,
394 msgsnd = 400,
395 msgrcv = 401,
396 msgctl = 402,
397 clock_gettime64 = 403,
398 clock_settime64 = 404,
399 clock_adjtime64 = 405,
400 clock_getres_time64 = 406,
401 clock_nanosleep_time64 = 407,
402 timer_gettime64 = 408,
403 timer_settime64 = 409,
404 timerfd_gettime64 = 410,
405 timerfd_settime64 = 411,
406 utimensat_time64 = 412,
407 pselect6_time64 = 413,
408 ppoll_time64 = 414,
409 io_pgetevents_time64 = 416,
410 recvmmsg_time64 = 417,
411 mq_timedsend_time64 = 418,
412 mq_timedreceive_time64 = 419,
413 semtimedop_time64 = 420,
414 rt_sigtimedwait_time64 = 421,
415 futex_time64 = 422,
416 sched_rr_get_interval_time64 = 423,
417 pidfd_send_signal = 424,
418 io_uring_setup = 425,
419 io_uring_enter = 426,
420 io_uring_register = 427,
421 open_tree = 428,
422 move_mount = 429,
423 fsopen = 430,
424 fsconfig = 431,
425 fsmount = 432,
426 fspick = 433,
427 pidfd_open = 434,
428 clone3 = 435,
429 close_range = 436,
430 openat2 = 437,
431 pidfd_getfd = 438,
432 faccessat2 = 439,
433 process_madvise = 440,
434};
435
436pub const O_CREAT = 0o100;
437pub const O_EXCL = 0o200;
438pub const O_NOCTTY = 0o400;
439pub const O_TRUNC = 0o1000;
440pub const O_APPEND = 0o2000;
441pub const O_NONBLOCK = 0o4000;
442pub const O_DSYNC = 0o10000;
443pub const O_SYNC = 0o4010000;
444pub const O_RSYNC = 0o4010000;
445pub const O_DIRECTORY = 0o40000;
446pub const O_NOFOLLOW = 0o100000;
447pub const O_CLOEXEC = 0o2000000;
448
449pub const O_ASYNC = 0o20000;
450pub const O_DIRECT = 0o400000;
451pub const O_LARGEFILE = 0o200000;
452pub const O_NOATIME = 0o1000000;
453pub const O_PATH = 0o10000000;
454pub const O_TMPFILE = 0o20040000;
455pub const O_NDELAY = O_NONBLOCK;
456
457pub const F_DUPFD = 0;
458pub const F_GETFD = 1;
459pub const F_SETFD = 2;
460pub const F_GETFL = 3;
461pub const F_SETFL = 4;
462
463pub const F_SETOWN = 8;
464pub const F_GETOWN = 9;
465pub const F_SETSIG = 10;
466pub const F_GETSIG = 11;
467
468pub const F_GETLK = 12;
469pub const F_SETLK = 13;
470pub const F_SETLKW = 14;
471
472pub const F_SETOWN_EX = 15;
473pub const F_GETOWN_EX = 16;
474
475pub const F_GETOWNER_UIDS = 17;
476
477pub const F_RDLCK = 0;
478pub const F_WRLCK = 1;
479pub const F_UNLCK = 2;
480
481pub const LOCK_SH = 1;
482pub const LOCK_EX = 2;
483pub const LOCK_UN = 8;
484pub const LOCK_NB = 4;
485
486/// stack-like segment
487pub const MAP_GROWSDOWN = 0x0100;
488
489/// ETXTBSY
490pub const MAP_DENYWRITE = 0x0800;
491
492/// mark it as an executable
493pub const MAP_EXECUTABLE = 0x1000;
494
495/// pages are locked
496pub const MAP_LOCKED = 0x0080;
497
498/// don't check for reservations
499pub const MAP_NORESERVE = 0x0040;
500
501pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
502pub const VDSO_CGT_VER = "LINUX_2.6.15";
503
504pub const Flock = extern struct {
505 l_type: i16,
506 l_whence: i16,
507 l_start: off_t,
508 l_len: off_t,
509 l_pid: pid_t,
510};
511
512pub const msghdr = extern struct {
513 msg_name: ?*sockaddr,
514 msg_namelen: socklen_t,
515 msg_iov: [*]iovec,
516 msg_iovlen: usize,
517 msg_control: ?*c_void,
518 msg_controllen: socklen_t,
519 msg_flags: i32,
520};
521
522pub const msghdr_const = extern struct {
523 msg_name: ?*const sockaddr,
524 msg_namelen: socklen_t,
525 msg_iov: [*]iovec_const,
526 msg_iovlen: usize,
527 msg_control: ?*c_void,
528 msg_controllen: socklen_t,
529 msg_flags: i32,
530};
531
532pub const blksize_t = i32;
533pub const nlink_t = u32;
534pub const time_t = isize;
535pub const mode_t = u32;
536pub const off_t = i64;
537pub const ino_t = u64;
538pub const dev_t = u64;
539pub const blkcnt_t = i64;
540
541// The `stat` definition used by the Linux kernel.
542pub const kernel_stat = extern struct {
543 dev: dev_t,
544 ino: ino_t,
545 mode: mode_t,
546 nlink: nlink_t,
547 uid: uid_t,
548 gid: gid_t,
549 rdev: dev_t,
550 __rdev_padding: i16,
551 size: off_t,
552 blksize: blksize_t,
553 blocks: blkcnt_t,
554 atim: timespec,
555 mtim: timespec,
556 ctim: timespec,
557 __unused: [2]u32,
558
559 pub fn atime(self: @This()) timespec {
560 return self.atim;
561 }
562
563 pub fn mtime(self: @This()) timespec {
564 return self.mtim;
565 }
566
567 pub fn ctime(self: @This()) timespec {
568 return self.ctim;
569 }
570};
571
572// The `stat64` definition used by the libc.
573pub const libc_stat = kernel_stat;
574
575pub const timespec = extern struct {
576 tv_sec: time_t,
577 tv_nsec: isize,
578};
579
580pub const timeval = extern struct {
581 tv_sec: time_t,
582 tv_usec: isize,
583};
584
585pub const timezone = extern struct {
586 tz_minuteswest: i32,
587 tz_dsttime: i32,
588};
589
590pub const greg_t = u32;
591pub const gregset_t = [48]greg_t;
592pub const fpregset_t = [33]f64;
593
594pub const vrregset = extern struct {
595 vrregs: [32][4]u32,
596 vrsave: u32,
597 _pad: [2]u32,
598 vscr: u32,
599};
600pub const vrregset_t = vrregset;
601
602pub const mcontext_t = extern struct {
603 gp_regs: gregset_t,
604 fp_regs: fpregset_t,
605 v_regs: vrregset_t align(16),
606};
607
608pub const ucontext_t = extern struct {
609 flags: u32,
610 link: *ucontext_t,
611 stack: stack_t,
612 pad: [7]i32,
613 regs: *mcontext_t,
614 sigmask: sigset_t,
615 pad2: [3]i32,
616 mcontext: mcontext_t,
617};
618
619pub const Elf_Symndx = u32;
620
621pub const MMAP2_UNIT = 4096;
lib/std/os/bits/linux/powerpc64.zig deleted-604
...@@ -1,604 +0,0 @@
1const std = @import("../../../std.zig");
2const linux = std.os.linux;
3const socklen_t = linux.socklen_t;
4const iovec = linux.iovec;
5const iovec_const = linux.iovec_const;
6const uid_t = linux.uid_t;
7const gid_t = linux.gid_t;
8const pid_t = linux.pid_t;
9const stack_t = linux.stack_t;
10const sigset_t = linux.sigset_t;
11pub const SYS = enum(usize) {
12 restart_syscall = 0,
13 exit = 1,
14 fork = 2,
15 read = 3,
16 write = 4,
17 open = 5,
18 close = 6,
19 waitpid = 7,
20 creat = 8,
21 link = 9,
22 unlink = 10,
23 execve = 11,
24 chdir = 12,
25 time = 13,
26 mknod = 14,
27 chmod = 15,
28 lchown = 16,
29 @"break" = 17,
30 oldstat = 18,
31 lseek = 19,
32 getpid = 20,
33 mount = 21,
34 umount = 22,
35 setuid = 23,
36 getuid = 24,
37 stime = 25,
38 ptrace = 26,
39 alarm = 27,
40 oldfstat = 28,
41 pause = 29,
42 utime = 30,
43 stty = 31,
44 gtty = 32,
45 access = 33,
46 nice = 34,
47 ftime = 35,
48 sync = 36,
49 kill = 37,
50 rename = 38,
51 mkdir = 39,
52 rmdir = 40,
53 dup = 41,
54 pipe = 42,
55 times = 43,
56 prof = 44,
57 brk = 45,
58 setgid = 46,
59 getgid = 47,
60 signal = 48,
61 geteuid = 49,
62 getegid = 50,
63 acct = 51,
64 umount2 = 52,
65 lock = 53,
66 ioctl = 54,
67 fcntl = 55,
68 mpx = 56,
69 setpgid = 57,
70 ulimit = 58,
71 oldolduname = 59,
72 umask = 60,
73 chroot = 61,
74 ustat = 62,
75 dup2 = 63,
76 getppid = 64,
77 getpgrp = 65,
78 setsid = 66,
79 sigaction = 67,
80 sgetmask = 68,
81 ssetmask = 69,
82 setreuid = 70,
83 setregid = 71,
84 sigsuspend = 72,
85 sigpending = 73,
86 sethostname = 74,
87 setrlimit = 75,
88 getrlimit = 76,
89 getrusage = 77,
90 gettimeofday = 78,
91 settimeofday = 79,
92 getgroups = 80,
93 setgroups = 81,
94 select = 82,
95 symlink = 83,
96 oldlstat = 84,
97 readlink = 85,
98 uselib = 86,
99 swapon = 87,
100 reboot = 88,
101 readdir = 89,
102 mmap = 90,
103 munmap = 91,
104 truncate = 92,
105 ftruncate = 93,
106 fchmod = 94,
107 fchown = 95,
108 getpriority = 96,
109 setpriority = 97,
110 profil = 98,
111 statfs = 99,
112 fstatfs = 100,
113 ioperm = 101,
114 socketcall = 102,
115 syslog = 103,
116 setitimer = 104,
117 getitimer = 105,
118 stat = 106,
119 lstat = 107,
120 fstat = 108,
121 olduname = 109,
122 iopl = 110,
123 vhangup = 111,
124 idle = 112,
125 vm86 = 113,
126 wait4 = 114,
127 swapoff = 115,
128 sysinfo = 116,
129 ipc = 117,
130 fsync = 118,
131 sigreturn = 119,
132 clone = 120,
133 setdomainname = 121,
134 uname = 122,
135 modify_ldt = 123,
136 adjtimex = 124,
137 mprotect = 125,
138 sigprocmask = 126,
139 create_module = 127,
140 init_module = 128,
141 delete_module = 129,
142 get_kernel_syms = 130,
143 quotactl = 131,
144 getpgid = 132,
145 fchdir = 133,
146 bdflush = 134,
147 sysfs = 135,
148 personality = 136,
149 afs_syscall = 137,
150 setfsuid = 138,
151 setfsgid = 139,
152 _llseek = 140,
153 getdents = 141,
154 _newselect = 142,
155 flock = 143,
156 msync = 144,
157 readv = 145,
158 writev = 146,
159 getsid = 147,
160 fdatasync = 148,
161 _sysctl = 149,
162 mlock = 150,
163 munlock = 151,
164 mlockall = 152,
165 munlockall = 153,
166 sched_setparam = 154,
167 sched_getparam = 155,
168 sched_setscheduler = 156,
169 sched_getscheduler = 157,
170 sched_yield = 158,
171 sched_get_priority_max = 159,
172 sched_get_priority_min = 160,
173 sched_rr_get_interval = 161,
174 nanosleep = 162,
175 mremap = 163,
176 setresuid = 164,
177 getresuid = 165,
178 query_module = 166,
179 poll = 167,
180 nfsservctl = 168,
181 setresgid = 169,
182 getresgid = 170,
183 prctl = 171,
184 rt_sigreturn = 172,
185 rt_sigaction = 173,
186 rt_sigprocmask = 174,
187 rt_sigpending = 175,
188 rt_sigtimedwait = 176,
189 rt_sigqueueinfo = 177,
190 rt_sigsuspend = 178,
191 pread64 = 179,
192 pwrite64 = 180,
193 chown = 181,
194 getcwd = 182,
195 capget = 183,
196 capset = 184,
197 sigaltstack = 185,
198 sendfile = 186,
199 getpmsg = 187,
200 putpmsg = 188,
201 vfork = 189,
202 ugetrlimit = 190,
203 readahead = 191,
204 pciconfig_read = 198,
205 pciconfig_write = 199,
206 pciconfig_iobase = 200,
207 multiplexer = 201,
208 getdents64 = 202,
209 pivot_root = 203,
210 madvise = 205,
211 mincore = 206,
212 gettid = 207,
213 tkill = 208,
214 setxattr = 209,
215 lsetxattr = 210,
216 fsetxattr = 211,
217 getxattr = 212,
218 lgetxattr = 213,
219 fgetxattr = 214,
220 listxattr = 215,
221 llistxattr = 216,
222 flistxattr = 217,
223 removexattr = 218,
224 lremovexattr = 219,
225 fremovexattr = 220,
226 futex = 221,
227 sched_setaffinity = 222,
228 sched_getaffinity = 223,
229 tuxcall = 225,
230 io_setup = 227,
231 io_destroy = 228,
232 io_getevents = 229,
233 io_submit = 230,
234 io_cancel = 231,
235 set_tid_address = 232,
236 fadvise64 = 233,
237 exit_group = 234,
238 lookup_dcookie = 235,
239 epoll_create = 236,
240 epoll_ctl = 237,
241 epoll_wait = 238,
242 remap_file_pages = 239,
243 timer_create = 240,
244 timer_settime = 241,
245 timer_gettime = 242,
246 timer_getoverrun = 243,
247 timer_delete = 244,
248 clock_settime = 245,
249 clock_gettime = 246,
250 clock_getres = 247,
251 clock_nanosleep = 248,
252 swapcontext = 249,
253 tgkill = 250,
254 utimes = 251,
255 statfs64 = 252,
256 fstatfs64 = 253,
257 rtas = 255,
258 sys_debug_setcontext = 256,
259 migrate_pages = 258,
260 mbind = 259,
261 get_mempolicy = 260,
262 set_mempolicy = 261,
263 mq_open = 262,
264 mq_unlink = 263,
265 mq_timedsend = 264,
266 mq_timedreceive = 265,
267 mq_notify = 266,
268 mq_getsetattr = 267,
269 kexec_load = 268,
270 add_key = 269,
271 request_key = 270,
272 keyctl = 271,
273 waitid = 272,
274 ioprio_set = 273,
275 ioprio_get = 274,
276 inotify_init = 275,
277 inotify_add_watch = 276,
278 inotify_rm_watch = 277,
279 spu_run = 278,
280 spu_create = 279,
281 pselect6 = 280,
282 ppoll = 281,
283 unshare = 282,
284 splice = 283,
285 tee = 284,
286 vmsplice = 285,
287 openat = 286,
288 mkdirat = 287,
289 mknodat = 288,
290 fchownat = 289,
291 futimesat = 290,
292 fstatat = 291,
293 unlinkat = 292,
294 renameat = 293,
295 linkat = 294,
296 symlinkat = 295,
297 readlinkat = 296,
298 fchmodat = 297,
299 faccessat = 298,
300 get_robust_list = 299,
301 set_robust_list = 300,
302 move_pages = 301,
303 getcpu = 302,
304 epoll_pwait = 303,
305 utimensat = 304,
306 signalfd = 305,
307 timerfd_create = 306,
308 eventfd = 307,
309 sync_file_range = 308,
310 fallocate = 309,
311 subpage_prot = 310,
312 timerfd_settime = 311,
313 timerfd_gettime = 312,
314 signalfd4 = 313,
315 eventfd2 = 314,
316 epoll_create1 = 315,
317 dup3 = 316,
318 pipe2 = 317,
319 inotify_init1 = 318,
320 perf_event_open = 319,
321 preadv = 320,
322 pwritev = 321,
323 rt_tgsigqueueinfo = 322,
324 fanotify_init = 323,
325 fanotify_mark = 324,
326 prlimit64 = 325,
327 socket = 326,
328 bind = 327,
329 connect = 328,
330 listen = 329,
331 accept = 330,
332 getsockname = 331,
333 getpeername = 332,
334 socketpair = 333,
335 send = 334,
336 sendto = 335,
337 recv = 336,
338 recvfrom = 337,
339 shutdown = 338,
340 setsockopt = 339,
341 getsockopt = 340,
342 sendmsg = 341,
343 recvmsg = 342,
344 recvmmsg = 343,
345 accept4 = 344,
346 name_to_handle_at = 345,
347 open_by_handle_at = 346,
348 clock_adjtime = 347,
349 syncfs = 348,
350 sendmmsg = 349,
351 setns = 350,
352 process_vm_readv = 351,
353 process_vm_writev = 352,
354 finit_module = 353,
355 kcmp = 354,
356 sched_setattr = 355,
357 sched_getattr = 356,
358 renameat2 = 357,
359 seccomp = 358,
360 getrandom = 359,
361 memfd_create = 360,
362 bpf = 361,
363 execveat = 362,
364 switch_endian = 363,
365 userfaultfd = 364,
366 membarrier = 365,
367 mlock2 = 378,
368 copy_file_range = 379,
369 preadv2 = 380,
370 pwritev2 = 381,
371 kexec_file_load = 382,
372 statx = 383,
373 pkey_alloc = 384,
374 pkey_free = 385,
375 pkey_mprotect = 386,
376 rseq = 387,
377 io_pgetevents = 388,
378 semtimedop = 392,
379 semget = 393,
380 semctl = 394,
381 shmget = 395,
382 shmctl = 396,
383 shmat = 397,
384 shmdt = 398,
385 msgget = 399,
386 msgsnd = 400,
387 msgrcv = 401,
388 msgctl = 402,
389 pidfd_send_signal = 424,
390 io_uring_setup = 425,
391 io_uring_enter = 426,
392 io_uring_register = 427,
393 open_tree = 428,
394 move_mount = 429,
395 fsopen = 430,
396 fsconfig = 431,
397 fsmount = 432,
398 fspick = 433,
399 pidfd_open = 434,
400 clone3 = 435,
401 close_range = 436,
402 openat2 = 437,
403 pidfd_getfd = 438,
404 faccessat2 = 439,
405 process_madvise = 440,
406 epoll_pwait2 = 441,
407
408 _,
409};
410
411pub const O_CREAT = 0o100;
412pub const O_EXCL = 0o200;
413pub const O_NOCTTY = 0o400;
414pub const O_TRUNC = 0o1000;
415pub const O_APPEND = 0o2000;
416pub const O_NONBLOCK = 0o4000;
417pub const O_DSYNC = 0o10000;
418pub const O_SYNC = 0o4010000;
419pub const O_RSYNC = 0o4010000;
420pub const O_DIRECTORY = 0o40000;
421pub const O_NOFOLLOW = 0o100000;
422pub const O_CLOEXEC = 0o2000000;
423
424pub const O_ASYNC = 0o20000;
425pub const O_DIRECT = 0o400000;
426pub const O_LARGEFILE = 0o200000;
427pub const O_NOATIME = 0o1000000;
428pub const O_PATH = 0o10000000;
429pub const O_TMPFILE = 0o20200000;
430pub const O_NDELAY = O_NONBLOCK;
431
432pub const F_DUPFD = 0;
433pub const F_GETFD = 1;
434pub const F_SETFD = 2;
435pub const F_GETFL = 3;
436pub const F_SETFL = 4;
437
438pub const F_SETOWN = 8;
439pub const F_GETOWN = 9;
440pub const F_SETSIG = 10;
441pub const F_GETSIG = 11;
442
443pub const F_GETLK = 5;
444pub const F_SETLK = 6;
445pub const F_SETLKW = 7;
446
447pub const F_RDLCK = 0;
448pub const F_WRLCK = 1;
449pub const F_UNLCK = 2;
450
451pub const LOCK_SH = 1;
452pub const LOCK_EX = 2;
453pub const LOCK_UN = 8;
454pub const LOCK_NB = 4;
455
456pub const F_SETOWN_EX = 15;
457pub const F_GETOWN_EX = 16;
458
459pub const F_GETOWNER_UIDS = 17;
460
461/// stack-like segment
462pub const MAP_GROWSDOWN = 0x0100;
463
464/// ETXTBSY
465pub const MAP_DENYWRITE = 0x0800;
466
467/// mark it as an executable
468pub const MAP_EXECUTABLE = 0x1000;
469
470/// pages are locked
471pub const MAP_LOCKED = 0x0080;
472
473/// don't check for reservations
474pub const MAP_NORESERVE = 0x0040;
475
476pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
477pub const VDSO_CGT_VER = "LINUX_2.6.15";
478
479pub const Flock = extern struct {
480 l_type: i16,
481 l_whence: i16,
482 l_start: off_t,
483 l_len: off_t,
484 l_pid: pid_t,
485 __unused: [4]u8,
486};
487
488pub const msghdr = extern struct {
489 msg_name: ?*sockaddr,
490 msg_namelen: socklen_t,
491 msg_iov: [*]iovec,
492 msg_iovlen: usize,
493 msg_control: ?*c_void,
494 msg_controllen: usize,
495 msg_flags: i32,
496};
497
498pub const msghdr_const = extern struct {
499 msg_name: ?*const sockaddr,
500 msg_namelen: socklen_t,
501 msg_iov: [*]iovec_const,
502 msg_iovlen: usize,
503 msg_control: ?*c_void,
504 msg_controllen: usize,
505 msg_flags: i32,
506};
507
508pub const blksize_t = i64;
509pub const nlink_t = u64;
510pub const time_t = i64;
511pub const mode_t = u32;
512pub const off_t = i64;
513pub const ino_t = u64;
514pub const dev_t = u64;
515pub const blkcnt_t = i64;
516
517// The `stat` definition used by the Linux kernel.
518pub const kernel_stat = extern struct {
519 dev: dev_t,
520 ino: ino_t,
521 nlink: nlink_t,
522 mode: mode_t,
523 uid: uid_t,
524 gid: gid_t,
525 rdev: dev_t,
526 size: off_t,
527 blksize: blksize_t,
528 blocks: blkcnt_t,
529 atim: timespec,
530 mtim: timespec,
531 ctim: timespec,
532 __unused: [3]u64,
533
534 pub fn atime(self: @This()) timespec {
535 return self.atim;
536 }
537
538 pub fn mtime(self: @This()) timespec {
539 return self.mtim;
540 }
541
542 pub fn ctime(self: @This()) timespec {
543 return self.ctim;
544 }
545};
546
547// The `stat64` definition used by the libc.
548pub const libc_stat = kernel_stat;
549
550pub const timespec = extern struct {
551 tv_sec: time_t,
552 tv_nsec: isize,
553};
554
555pub const timeval = extern struct {
556 tv_sec: isize,
557 tv_usec: isize,
558};
559
560pub const timezone = extern struct {
561 tz_minuteswest: i32,
562 tz_dsttime: i32,
563};
564
565pub const greg_t = u64;
566pub const gregset_t = [48]greg_t;
567pub const fpregset_t = [33]f64;
568
569/// The position of the vscr register depends on endianness.
570/// On C, macros are used to change vscr_word's offset to
571/// account for this. Here we'll just define vscr_word_le
572/// and vscr_word_be. Code must take care to use the correct one.
573pub const vrregset = extern struct {
574 vrregs: [32][4]u32 align(16),
575 vscr_word_le: u32,
576 _pad1: [2]u32,
577 vscr_word_be: u32,
578 vrsave: u32,
579 _pad2: [3]u32,
580};
581pub const vrregset_t = vrregset;
582
583pub const mcontext_t = extern struct {
584 __unused: [4]u64,
585 signal: i32,
586 _pad0: i32,
587 handler: u64,
588 oldmask: u64,
589 regs: ?*c_void,
590 gp_regs: gregset_t,
591 fp_regs: fpregset_t,
592 v_regs: *vrregset_t,
593 vmx_reserve: [34 + 34 + 32 + 1]i64,
594};
595
596pub const ucontext_t = extern struct {
597 flags: u32,
598 link: *ucontext_t,
599 stack: stack_t,
600 sigmask: sigset_t,
601 mcontext: mcontext_t,
602};
603
604pub const Elf_Symndx = u32;
lib/std/os/bits/linux/prctl.zig deleted-234
...@@ -1,234 +0,0 @@
1pub const PR = enum(i32) {
2 SET_PDEATHSIG = 1,
3 GET_PDEATHSIG = 2,
4
5 GET_DUMPABLE = 3,
6 SET_DUMPABLE = 4,
7
8 GET_UNALIGN = 5,
9 SET_UNALIGN = 6,
10
11 GET_KEEPCAPS = 7,
12 SET_KEEPCAPS = 8,
13
14 GET_FPEMU = 9,
15 SET_FPEMU = 10,
16
17 GET_FPEXC = 11,
18 SET_FPEXC = 12,
19
20 GET_TIMING = 13,
21 SET_TIMING = 14,
22
23 SET_NAME = 15,
24 GET_NAME = 16,
25
26 GET_ENDIAN = 19,
27 SET_ENDIAN = 20,
28
29 GET_SECCOMP = 21,
30 SET_SECCOMP = 22,
31
32 CAPBSET_READ = 23,
33 CAPBSET_DROP = 24,
34
35 GET_TSC = 25,
36 SET_TSC = 26,
37
38 GET_SECUREBITS = 27,
39 SET_SECUREBITS = 28,
40
41 SET_TIMERSLACK = 29,
42 GET_TIMERSLACK = 30,
43
44 TASK_PERF_EVENTS_DISABLE = 31,
45 TASK_PERF_EVENTS_ENABLE = 32,
46
47 MCE_KILL = 33,
48
49 MCE_KILL_GET = 34,
50
51 SET_MM = 35,
52
53 SET_PTRACER = 0x59616d61,
54
55 SET_CHILD_SUBREAPER = 36,
56 GET_CHILD_SUBREAPER = 37,
57
58 SET_NO_NEW_PRIVS = 38,
59 GET_NO_NEW_PRIVS = 39,
60
61 GET_TID_ADDRESS = 40,
62
63 SET_THP_DISABLE = 41,
64 GET_THP_DISABLE = 42,
65
66 MPX_ENABLE_MANAGEMENT = 43,
67 MPX_DISABLE_MANAGEMENT = 44,
68
69 SET_FP_MODE = 45,
70 GET_FP_MODE = 46,
71
72 CAP_AMBIENT = 47,
73
74 SVE_SET_VL = 50,
75 SVE_GET_VL = 51,
76
77 GET_SPECULATION_CTRL = 52,
78 SET_SPECULATION_CTRL = 53,
79
80 _,
81};
82
83pub const PR_SET_PDEATHSIG = @enumToInt(PR.SET_PDEATHSIG);
84pub const PR_GET_PDEATHSIG = @enumToInt(PR.GET_PDEATHSIG);
85
86pub const PR_GET_DUMPABLE = @enumToInt(PR.GET_DUMPABLE);
87pub const PR_SET_DUMPABLE = @enumToInt(PR.SET_DUMPABLE);
88
89pub const PR_GET_UNALIGN = @enumToInt(PR.GET_UNALIGN);
90pub const PR_SET_UNALIGN = @enumToInt(PR.SET_UNALIGN);
91pub const PR_UNALIGN_NOPRINT = 1;
92pub const PR_UNALIGN_SIGBUS = 2;
93
94pub const PR_GET_KEEPCAPS = @enumToInt(PR.GET_KEEPCAPS);
95pub const PR_SET_KEEPCAPS = @enumToInt(PR.SET_KEEPCAPS);
96
97pub const PR_GET_FPEMU = @enumToInt(PR.GET_FPEMU);
98pub const PR_SET_FPEMU = @enumToInt(PR.SET_FPEMU);
99pub const PR_FPEMU_NOPRINT = 1;
100pub const PR_FPEMU_SIGFPE = 2;
101
102pub const PR_GET_FPEXC = @enumToInt(PR.GET_FPEXC);
103pub const PR_SET_FPEXC = @enumToInt(PR.SET_FPEXC);
104pub const PR_FP_EXC_SW_ENABLE = 0x80;
105pub const PR_FP_EXC_DIV = 0x010000;
106pub const PR_FP_EXC_OVF = 0x020000;
107pub const PR_FP_EXC_UND = 0x040000;
108pub const PR_FP_EXC_RES = 0x080000;
109pub const PR_FP_EXC_INV = 0x100000;
110pub const PR_FP_EXC_DISABLED = 0;
111pub const PR_FP_EXC_NONRECOV = 1;
112pub const PR_FP_EXC_ASYNC = 2;
113pub const PR_FP_EXC_PRECISE = 3;
114
115pub const PR_GET_TIMING = @enumToInt(PR.GET_TIMING);
116pub const PR_SET_TIMING = @enumToInt(PR.SET_TIMING);
117pub const PR_TIMING_STATISTICAL = 0;
118pub const PR_TIMING_TIMESTAMP = 1;
119
120pub const PR_SET_NAME = @enumToInt(PR.SET_NAME);
121pub const PR_GET_NAME = @enumToInt(PR.GET_NAME);
122
123pub const PR_GET_ENDIAN = @enumToInt(PR.GET_ENDIAN);
124pub const PR_SET_ENDIAN = @enumToInt(PR.SET_ENDIAN);
125pub const PR_ENDIAN_BIG = 0;
126pub const PR_ENDIAN_LITTLE = 1;
127pub const PR_ENDIAN_PPC_LITTLE = 2;
128
129pub const PR_GET_SECCOMP = @enumToInt(PR.GET_SECCOMP);
130pub const PR_SET_SECCOMP = @enumToInt(PR.SET_SECCOMP);
131
132pub const PR_CAPBSET_READ = @enumToInt(PR.CAPBSET_READ);
133pub const PR_CAPBSET_DROP = @enumToInt(PR.CAPBSET_DROP);
134
135pub const PR_GET_TSC = @enumToInt(PR.GET_TSC);
136pub const PR_SET_TSC = @enumToInt(PR.SET_TSC);
137pub const PR_TSC_ENABLE = 1;
138pub const PR_TSC_SIGSEGV = 2;
139
140pub const PR_GET_SECUREBITS = @enumToInt(PR.GET_SECUREBITS);
141pub const PR_SET_SECUREBITS = @enumToInt(PR.SET_SECUREBITS);
142
143pub const PR_SET_TIMERSLACK = @enumToInt(PR.SET_TIMERSLACK);
144pub const PR_GET_TIMERSLACK = @enumToInt(PR.GET_TIMERSLACK);
145
146pub const PR_TASK_PERF_EVENTS_DISABLE = @enumToInt(PR.TASK_PERF_EVENTS_DISABLE);
147pub const PR_TASK_PERF_EVENTS_ENABLE = @enumToInt(PR.TASK_PERF_EVENTS_ENABLE);
148
149pub const PR_MCE_KILL = @enumToInt(PR.MCE_KILL);
150pub const PR_MCE_KILL_CLEAR = 0;
151pub const PR_MCE_KILL_SET = 1;
152
153pub const PR_MCE_KILL_LATE = 0;
154pub const PR_MCE_KILL_EARLY = 1;
155pub const PR_MCE_KILL_DEFAULT = 2;
156
157pub const PR_MCE_KILL_GET = @enumToInt(PR.MCE_KILL_GET);
158
159pub const PR_SET_MM = @enumToInt(PR.SET_MM);
160pub const PR_SET_MM_START_CODE = 1;
161pub const PR_SET_MM_END_CODE = 2;
162pub const PR_SET_MM_START_DATA = 3;
163pub const PR_SET_MM_END_DATA = 4;
164pub const PR_SET_MM_START_STACK = 5;
165pub const PR_SET_MM_START_BRK = 6;
166pub const PR_SET_MM_BRK = 7;
167pub const PR_SET_MM_ARG_START = 8;
168pub const PR_SET_MM_ARG_END = 9;
169pub const PR_SET_MM_ENV_START = 10;
170pub const PR_SET_MM_ENV_END = 11;
171pub const PR_SET_MM_AUXV = 12;
172pub const PR_SET_MM_EXE_FILE = 13;
173pub const PR_SET_MM_MAP = 14;
174pub const PR_SET_MM_MAP_SIZE = 15;
175
176pub const prctl_mm_map = extern struct {
177 start_code: u64,
178 end_code: u64,
179 start_data: u64,
180 end_data: u64,
181 start_brk: u64,
182 brk: u64,
183 start_stack: u64,
184 arg_start: u64,
185 arg_end: u64,
186 env_start: u64,
187 env_end: u64,
188 auxv: *u64,
189 auxv_size: u32,
190 exe_fd: u32,
191};
192
193pub const PR_SET_PTRACER = @enumToInt(PR.SET_PTRACER);
194pub const PR_SET_PTRACER_ANY = std.math.maxInt(c_ulong);
195
196pub const PR_SET_CHILD_SUBREAPER = @enumToInt(PR.SET_CHILD_SUBREAPER);
197pub const PR_GET_CHILD_SUBREAPER = @enumToInt(PR.GET_CHILD_SUBREAPER);
198
199pub const PR_SET_NO_NEW_PRIVS = @enumToInt(PR.SET_NO_NEW_PRIVS);
200pub const PR_GET_NO_NEW_PRIVS = @enumToInt(PR.GET_NO_NEW_PRIVS);
201
202pub const PR_GET_TID_ADDRESS = @enumToInt(PR.GET_TID_ADDRESS);
203
204pub const PR_SET_THP_DISABLE = @enumToInt(PR.SET_THP_DISABLE);
205pub const PR_GET_THP_DISABLE = @enumToInt(PR.GET_THP_DISABLE);
206
207pub const PR_MPX_ENABLE_MANAGEMENT = @enumToInt(PR.MPX_ENABLE_MANAGEMENT);
208pub const PR_MPX_DISABLE_MANAGEMENT = @enumToInt(PR.MPX_DISABLE_MANAGEMENT);
209
210pub const PR_SET_FP_MODE = @enumToInt(PR.SET_FP_MODE);
211pub const PR_GET_FP_MODE = @enumToInt(PR.GET_FP_MODE);
212pub const PR_FP_MODE_FR = 1 << 0;
213pub const PR_FP_MODE_FRE = 1 << 1;
214
215pub const PR_CAP_AMBIENT = @enumToInt(PR.CAP_AMBIENT);
216pub const PR_CAP_AMBIENT_IS_SET = 1;
217pub const PR_CAP_AMBIENT_RAISE = 2;
218pub const PR_CAP_AMBIENT_LOWER = 3;
219pub const PR_CAP_AMBIENT_CLEAR_ALL = 4;
220
221pub const PR_SVE_SET_VL = @enumToInt(PR.SVE_SET_VL);
222pub const PR_SVE_SET_VL_ONEXEC = 1 << 18;
223pub const PR_SVE_GET_VL = @enumToInt(PR.SVE_GET_VL);
224pub const PR_SVE_VL_LEN_MASK = 0xffff;
225pub const PR_SVE_VL_INHERIT = 1 << 17;
226
227pub const PR_GET_SPECULATION_CTRL = @enumToInt(PR.GET_SPECULATION_CTRL);
228pub const PR_SET_SPECULATION_CTRL = @enumToInt(PR.SET_SPECULATION_CTRL);
229pub const PR_SPEC_STORE_BYPASS = 0;
230pub const PR_SPEC_NOT_AFFECTED = 0;
231pub const PR_SPEC_PRCTL = 1 << 0;
232pub const PR_SPEC_ENABLE = 1 << 1;
233pub const PR_SPEC_DISABLE = 1 << 2;
234pub const PR_SPEC_FORCE_DISABLE = 1 << 3;
lib/std/os/bits/linux/riscv64.zig deleted-423
...@@ -1,423 +0,0 @@
1// riscv64-specific declarations that are intended to be imported into the POSIX namespace.
2const std = @import("../../../std.zig");
3const uid_t = std.os.linux.uid_t;
4const gid_t = std.os.linux.gid_t;
5const pid_t = std.os.linux.pid_t;
6
7pub const SYS = enum(usize) {
8 pub const arch_specific_syscall = 244;
9
10 io_setup = 0,
11 io_destroy = 1,
12 io_submit = 2,
13 io_cancel = 3,
14 io_getevents = 4,
15 setxattr = 5,
16 lsetxattr = 6,
17 fsetxattr = 7,
18 getxattr = 8,
19 lgetxattr = 9,
20 fgetxattr = 10,
21 listxattr = 11,
22 llistxattr = 12,
23 flistxattr = 13,
24 removexattr = 14,
25 lremovexattr = 15,
26 fremovexattr = 16,
27 getcwd = 17,
28 lookup_dcookie = 18,
29 eventfd2 = 19,
30 epoll_create1 = 20,
31 epoll_ctl = 21,
32 epoll_pwait = 22,
33 dup = 23,
34 dup3 = 24,
35 fcntl = 25,
36 inotify_init1 = 26,
37 inotify_add_watch = 27,
38 inotify_rm_watch = 28,
39 ioctl = 29,
40 ioprio_set = 30,
41 ioprio_get = 31,
42 flock = 32,
43 mknodat = 33,
44 mkdirat = 34,
45 unlinkat = 35,
46 symlinkat = 36,
47 linkat = 37,
48 umount2 = 39,
49 mount = 40,
50 pivot_root = 41,
51 nfsservctl = 42,
52 statfs = 43,
53 fstatfs = 44,
54 truncate = 45,
55 ftruncate = 46,
56 fallocate = 47,
57 faccessat = 48,
58 chdir = 49,
59 fchdir = 50,
60 chroot = 51,
61 fchmod = 52,
62 fchmodat = 53,
63 fchownat = 54,
64 fchown = 55,
65 openat = 56,
66 close = 57,
67 vhangup = 58,
68 pipe2 = 59,
69 quotactl = 60,
70 getdents64 = 61,
71 lseek = 62,
72 read = 63,
73 write = 64,
74 readv = 65,
75 writev = 66,
76 pread64 = 67,
77 pwrite64 = 68,
78 preadv = 69,
79 pwritev = 70,
80 sendfile = 71,
81 pselect6 = 72,
82 ppoll = 73,
83 signalfd4 = 74,
84 vmsplice = 75,
85 splice = 76,
86 tee = 77,
87 readlinkat = 78,
88 fstatat = 79,
89 fstat = 80,
90 sync = 81,
91 fsync = 82,
92 fdatasync = 83,
93 sync_file_range = 84,
94 timerfd_create = 85,
95 timerfd_settime = 86,
96 timerfd_gettime = 87,
97 utimensat = 88,
98 acct = 89,
99 capget = 90,
100 capset = 91,
101 personality = 92,
102 exit = 93,
103 exit_group = 94,
104 waitid = 95,
105 set_tid_address = 96,
106 unshare = 97,
107 futex = 98,
108 set_robust_list = 99,
109 get_robust_list = 100,
110 nanosleep = 101,
111 getitimer = 102,
112 setitimer = 103,
113 kexec_load = 104,
114 init_module = 105,
115 delete_module = 106,
116 timer_create = 107,
117 timer_gettime = 108,
118 timer_getoverrun = 109,
119 timer_settime = 110,
120 timer_delete = 111,
121 clock_settime = 112,
122 clock_gettime = 113,
123 clock_getres = 114,
124 clock_nanosleep = 115,
125 syslog = 116,
126 ptrace = 117,
127 sched_setparam = 118,
128 sched_setscheduler = 119,
129 sched_getscheduler = 120,
130 sched_getparam = 121,
131 sched_setaffinity = 122,
132 sched_getaffinity = 123,
133 sched_yield = 124,
134 sched_get_priority_max = 125,
135 sched_get_priority_min = 126,
136 sched_rr_get_interval = 127,
137 restart_syscall = 128,
138 kill = 129,
139 tkill = 130,
140 tgkill = 131,
141 sigaltstack = 132,
142 rt_sigsuspend = 133,
143 rt_sigaction = 134,
144 rt_sigprocmask = 135,
145 rt_sigpending = 136,
146 rt_sigtimedwait = 137,
147 rt_sigqueueinfo = 138,
148 rt_sigreturn = 139,
149 setpriority = 140,
150 getpriority = 141,
151 reboot = 142,
152 setregid = 143,
153 setgid = 144,
154 setreuid = 145,
155 setuid = 146,
156 setresuid = 147,
157 getresuid = 148,
158 setresgid = 149,
159 getresgid = 150,
160 setfsuid = 151,
161 setfsgid = 152,
162 times = 153,
163 setpgid = 154,
164 getpgid = 155,
165 getsid = 156,
166 setsid = 157,
167 getgroups = 158,
168 setgroups = 159,
169 uname = 160,
170 sethostname = 161,
171 setdomainname = 162,
172 getrlimit = 163,
173 setrlimit = 164,
174 getrusage = 165,
175 umask = 166,
176 prctl = 167,
177 getcpu = 168,
178 gettimeofday = 169,
179 settimeofday = 170,
180 adjtimex = 171,
181 getpid = 172,
182 getppid = 173,
183 getuid = 174,
184 geteuid = 175,
185 getgid = 176,
186 getegid = 177,
187 gettid = 178,
188 sysinfo = 179,
189 mq_open = 180,
190 mq_unlink = 181,
191 mq_timedsend = 182,
192 mq_timedreceive = 183,
193 mq_notify = 184,
194 mq_getsetattr = 185,
195 msgget = 186,
196 msgctl = 187,
197 msgrcv = 188,
198 msgsnd = 189,
199 semget = 190,
200 semctl = 191,
201 semtimedop = 192,
202 semop = 193,
203 shmget = 194,
204 shmctl = 195,
205 shmat = 196,
206 shmdt = 197,
207 socket = 198,
208 socketpair = 199,
209 bind = 200,
210 listen = 201,
211 accept = 202,
212 connect = 203,
213 getsockname = 204,
214 getpeername = 205,
215 sendto = 206,
216 recvfrom = 207,
217 setsockopt = 208,
218 getsockopt = 209,
219 shutdown = 210,
220 sendmsg = 211,
221 recvmsg = 212,
222 readahead = 213,
223 brk = 214,
224 munmap = 215,
225 mremap = 216,
226 add_key = 217,
227 request_key = 218,
228 keyctl = 219,
229 clone = 220,
230 execve = 221,
231 mmap = 222,
232 fadvise64 = 223,
233 swapon = 224,
234 swapoff = 225,
235 mprotect = 226,
236 msync = 227,
237 mlock = 228,
238 munlock = 229,
239 mlockall = 230,
240 munlockall = 231,
241 mincore = 232,
242 madvise = 233,
243 remap_file_pages = 234,
244 mbind = 235,
245 get_mempolicy = 236,
246 set_mempolicy = 237,
247 migrate_pages = 238,
248 move_pages = 239,
249 rt_tgsigqueueinfo = 240,
250 perf_event_open = 241,
251 accept4 = 242,
252 recvmmsg = 243,
253
254 riscv_flush_icache = arch_specific_syscall + 15,
255
256 wait4 = 260,
257 prlimit64 = 261,
258 fanotify_init = 262,
259 fanotify_mark = 263,
260 name_to_handle_at = 264,
261 open_by_handle_at = 265,
262 clock_adjtime = 266,
263 syncfs = 267,
264 setns = 268,
265 sendmmsg = 269,
266 process_vm_readv = 270,
267 process_vm_writev = 271,
268 kcmp = 272,
269 finit_module = 273,
270 sched_setattr = 274,
271 sched_getattr = 275,
272 renameat2 = 276,
273 seccomp = 277,
274 getrandom = 278,
275 memfd_create = 279,
276 bpf = 280,
277 execveat = 281,
278 userfaultfd = 282,
279 membarrier = 283,
280 mlock2 = 284,
281 copy_file_range = 285,
282 preadv2 = 286,
283 pwritev2 = 287,
284 pkey_mprotect = 288,
285 pkey_alloc = 289,
286 pkey_free = 290,
287 statx = 291,
288 io_pgetevents = 292,
289 rseq = 293,
290 kexec_file_load = 294,
291 pidfd_send_signal = 424,
292 io_uring_setup = 425,
293 io_uring_enter = 426,
294 io_uring_register = 427,
295 open_tree = 428,
296 move_mount = 429,
297 fsopen = 430,
298 fsconfig = 431,
299 fsmount = 432,
300 fspick = 433,
301 pidfd_open = 434,
302 clone3 = 435,
303 close_range = 436,
304 openat2 = 437,
305 pidfd_getfd = 438,
306 faccessat2 = 439,
307 process_madvise = 440,
308 epoll_pwait2 = 441,
309
310 _,
311};
312
313pub const O_CREAT = 0o100;
314pub const O_EXCL = 0o200;
315pub const O_NOCTTY = 0o400;
316pub const O_TRUNC = 0o1000;
317pub const O_APPEND = 0o2000;
318pub const O_NONBLOCK = 0o4000;
319pub const O_DSYNC = 0o10000;
320pub const O_SYNC = 0o4010000;
321pub const O_RSYNC = 0o4010000;
322pub const O_DIRECTORY = 0o200000;
323pub const O_NOFOLLOW = 0o400000;
324pub const O_CLOEXEC = 0o2000000;
325
326pub const O_ASYNC = 0o20000;
327pub const O_DIRECT = 0o40000;
328pub const O_LARGEFILE = 0o100000;
329pub const O_NOATIME = 0o1000000;
330pub const O_PATH = 0o10000000;
331pub const O_TMPFILE = 0o20200000;
332pub const O_NDELAY = O_NONBLOCK;
333
334pub const F_DUPFD = 0;
335pub const F_GETFD = 1;
336pub const F_SETFD = 2;
337pub const F_GETFL = 3;
338pub const F_SETFL = 4;
339pub const F_GETLK = 5;
340pub const F_SETLK = 6;
341pub const F_SETLKW = 7;
342pub const F_SETOWN = 8;
343pub const F_GETOWN = 9;
344pub const F_SETSIG = 10;
345pub const F_GETSIG = 11;
346
347pub const F_RDLCK = 0;
348pub const F_WRLCK = 1;
349pub const F_UNLCK = 2;
350
351pub const LOCK_SH = 1;
352pub const LOCK_EX = 2;
353pub const LOCK_UN = 8;
354pub const LOCK_NB = 4;
355
356pub const F_SETOWN_EX = 15;
357pub const F_GETOWN_EX = 16;
358
359pub const F_GETOWNER_UIDS = 17;
360
361pub const blksize_t = i32;
362pub const nlink_t = u32;
363pub const time_t = isize;
364pub const mode_t = u32;
365pub const off_t = isize;
366pub const ino_t = usize;
367pub const dev_t = usize;
368pub const blkcnt_t = isize;
369pub const timespec = extern struct {
370 tv_sec: time_t,
371 tv_nsec: isize,
372};
373
374pub const timeval = extern struct {
375 tv_sec: time_t,
376 tv_usec: i64,
377};
378
379pub const Flock = extern struct {
380 l_type: i16,
381 l_whence: i16,
382 l_start: off_t,
383 l_len: off_t,
384 l_pid: pid_t,
385 __unused: [4]u8,
386};
387
388// The `stat` definition used by the Linux kernel.
389pub const kernel_stat = extern struct {
390 dev: dev_t,
391 ino: ino_t,
392 mode: mode_t,
393 nlink: nlink_t,
394 uid: uid_t,
395 gid: gid_t,
396 rdev: dev_t,
397 __pad: usize,
398 size: off_t,
399 blksize: blksize_t,
400 __pad2: i32,
401 blocks: blkcnt_t,
402 atim: timespec,
403 mtim: timespec,
404 ctim: timespec,
405 __unused: [2]u32,
406
407 pub fn atime(self: @This()) timespec {
408 return self.atim;
409 }
410
411 pub fn mtime(self: @This()) timespec {
412 return self.mtim;
413 }
414
415 pub fn ctime(self: @This()) timespec {
416 return self.ctim;
417 }
418};
419
420// The `stat64` definition used by the libc.
421pub const libc_stat = kernel_stat;
422
423pub const Elf_Symndx = u32;
lib/std/os/bits/linux/securebits.zig deleted-35
...@@ -1,35 +0,0 @@
1fn issecure_mask(comptime x: comptime_int) comptime_int {
2 return 1 << x;
3}
4
5pub const SECUREBITS_DEFAULT = 0x00000000;
6
7pub const SECURE_NOROOT = 0;
8pub const SECURE_NOROOT_LOCKED = 1;
9
10pub const SECBIT_NOROOT = issecure_mask(SECURE_NOROOT);
11pub const SECBIT_NOROOT_LOCKED = issecure_mask(SECURE_NOROOT_LOCKED);
12
13pub const SECURE_NO_SETUID_FIXUP = 2;
14pub const SECURE_NO_SETUID_FIXUP_LOCKED = 3;
15
16pub const SECBIT_NO_SETUID_FIXUP = issecure_mask(SECURE_NO_SETUID_FIXUP);
17pub const SECBIT_NO_SETUID_FIXUP_LOCKED = issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED);
18
19pub const SECURE_KEEP_CAPS = 4;
20pub const SECURE_KEEP_CAPS_LOCKED = 5;
21
22pub const SECBIT_KEEP_CAPS = issecure_mask(SECURE_KEEP_CAPS);
23pub const SECBIT_KEEP_CAPS_LOCKED = issecure_mask(SECURE_KEEP_CAPS_LOCKED);
24
25pub const SECURE_NO_CAP_AMBIENT_RAISE = 6;
26pub const SECURE_NO_CAP_AMBIENT_RAISE_LOCKED = 7;
27
28pub const SECBIT_NO_CAP_AMBIENT_RAISE = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE);
29pub const SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED);
30
31pub const SECURE_ALL_BITS = issecure_mask(SECURE_NOROOT) |
32 issecure_mask(SECURE_NO_SETUID_FIXUP) |
33 issecure_mask(SECURE_KEEP_CAPS) |
34 issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE);
35pub const SECURE_ALL_LOCKS = SECURE_ALL_BITS << 1;
lib/std/os/bits/linux/sparc64.zig deleted-675
...@@ -1,675 +0,0 @@
1// sparc64-specific declarations that are intended to be imported into the POSIX namespace.
2const std = @import("../../../std.zig");
3const pid_t = linux.pid_t;
4const uid_t = linux.uid_t;
5const clock_t = linux.clock_t;
6const stack_t = linux.stack_t;
7const sigset_t = linux.sigset_t;
8
9const linux = std.os.linux;
10const sockaddr = linux.sockaddr;
11const socklen_t = linux.socklen_t;
12const iovec = linux.iovec;
13const iovec_const = linux.iovec_const;
14
15pub const SYS = enum(usize) {
16 restart_syscall = 0,
17 exit = 1,
18 fork = 2,
19 read = 3,
20 write = 4,
21 open = 5,
22 close = 6,
23 wait4 = 7,
24 creat = 8,
25 link = 9,
26 unlink = 10,
27 execv = 11,
28 chdir = 12,
29 chown = 13,
30 mknod = 14,
31 chmod = 15,
32 lchown = 16,
33 brk = 17,
34 perfctr = 18,
35 lseek = 19,
36 getpid = 20,
37 capget = 21,
38 capset = 22,
39 setuid = 23,
40 getuid = 24,
41 vmsplice = 25,
42 ptrace = 26,
43 alarm = 27,
44 sigaltstack = 28,
45 pause = 29,
46 utime = 30,
47 access = 33,
48 nice = 34,
49 sync = 36,
50 kill = 37,
51 stat = 38,
52 sendfile = 39,
53 lstat = 40,
54 dup = 41,
55 pipe = 42,
56 times = 43,
57 umount2 = 45,
58 setgid = 46,
59 getgid = 47,
60 signal = 48,
61 geteuid = 49,
62 getegid = 50,
63 acct = 51,
64 memory_ordering = 52,
65 ioctl = 54,
66 reboot = 55,
67 symlink = 57,
68 readlink = 58,
69 execve = 59,
70 umask = 60,
71 chroot = 61,
72 fstat = 62,
73 fstat64 = 63,
74 getpagesize = 64,
75 msync = 65,
76 vfork = 66,
77 pread64 = 67,
78 pwrite64 = 68,
79 mmap = 71,
80 munmap = 73,
81 mprotect = 74,
82 madvise = 75,
83 vhangup = 76,
84 mincore = 78,
85 getgroups = 79,
86 setgroups = 80,
87 getpgrp = 81,
88 setitimer = 83,
89 swapon = 85,
90 getitimer = 86,
91 sethostname = 88,
92 dup2 = 90,
93 fcntl = 92,
94 select = 93,
95 fsync = 95,
96 setpriority = 96,
97 socket = 97,
98 connect = 98,
99 accept = 99,
100 getpriority = 100,
101 rt_sigreturn = 101,
102 rt_sigaction = 102,
103 rt_sigprocmask = 103,
104 rt_sigpending = 104,
105 rt_sigtimedwait = 105,
106 rt_sigqueueinfo = 106,
107 rt_sigsuspend = 107,
108 setresuid = 108,
109 getresuid = 109,
110 setresgid = 110,
111 getresgid = 111,
112 recvmsg = 113,
113 sendmsg = 114,
114 gettimeofday = 116,
115 getrusage = 117,
116 getsockopt = 118,
117 getcwd = 119,
118 readv = 120,
119 writev = 121,
120 settimeofday = 122,
121 fchown = 123,
122 fchmod = 124,
123 recvfrom = 125,
124 setreuid = 126,
125 setregid = 127,
126 rename = 128,
127 truncate = 129,
128 ftruncate = 130,
129 flock = 131,
130 lstat64 = 132,
131 sendto = 133,
132 shutdown = 134,
133 socketpair = 135,
134 mkdir = 136,
135 rmdir = 137,
136 utimes = 138,
137 stat64 = 139,
138 sendfile64 = 140,
139 getpeername = 141,
140 futex = 142,
141 gettid = 143,
142 getrlimit = 144,
143 setrlimit = 145,
144 pivot_root = 146,
145 prctl = 147,
146 pciconfig_read = 148,
147 pciconfig_write = 149,
148 getsockname = 150,
149 inotify_init = 151,
150 inotify_add_watch = 152,
151 poll = 153,
152 getdents64 = 154,
153 inotify_rm_watch = 156,
154 statfs = 157,
155 fstatfs = 158,
156 umount = 159,
157 sched_set_affinity = 160,
158 sched_get_affinity = 161,
159 getdomainname = 162,
160 setdomainname = 163,
161 utrap_install = 164,
162 quotactl = 165,
163 set_tid_address = 166,
164 mount = 167,
165 ustat = 168,
166 setxattr = 169,
167 lsetxattr = 170,
168 fsetxattr = 171,
169 getxattr = 172,
170 lgetxattr = 173,
171 getdents = 174,
172 setsid = 175,
173 fchdir = 176,
174 fgetxattr = 177,
175 listxattr = 178,
176 llistxattr = 179,
177 flistxattr = 180,
178 removexattr = 181,
179 lremovexattr = 182,
180 sigpending = 183,
181 query_module = 184,
182 setpgid = 185,
183 fremovexattr = 186,
184 tkill = 187,
185 exit_group = 188,
186 uname = 189,
187 init_module = 190,
188 personality = 191,
189 remap_file_pages = 192,
190 epoll_create = 193,
191 epoll_ctl = 194,
192 epoll_wait = 195,
193 ioprio_set = 196,
194 getppid = 197,
195 sigaction = 198,
196 sgetmask = 199,
197 ssetmask = 200,
198 sigsuspend = 201,
199 oldlstat = 202,
200 uselib = 203,
201 readdir = 204,
202 readahead = 205,
203 socketcall = 206,
204 syslog = 207,
205 lookup_dcookie = 208,
206 fadvise64 = 209,
207 fadvise64_64 = 210,
208 tgkill = 211,
209 waitpid = 212,
210 swapoff = 213,
211 sysinfo = 214,
212 ipc = 215,
213 sigreturn = 216,
214 clone = 217,
215 ioprio_get = 218,
216 adjtimex = 219,
217 sigprocmask = 220,
218 create_module = 221,
219 delete_module = 222,
220 get_kernel_syms = 223,
221 getpgid = 224,
222 bdflush = 225,
223 sysfs = 226,
224 afs_syscall = 227,
225 setfsuid = 228,
226 setfsgid = 229,
227 _newselect = 230,
228 splice = 232,
229 stime = 233,
230 statfs64 = 234,
231 fstatfs64 = 235,
232 _llseek = 236,
233 mlock = 237,
234 munlock = 238,
235 mlockall = 239,
236 munlockall = 240,
237 sched_setparam = 241,
238 sched_getparam = 242,
239 sched_setscheduler = 243,
240 sched_getscheduler = 244,
241 sched_yield = 245,
242 sched_get_priority_max = 246,
243 sched_get_priority_min = 247,
244 sched_rr_get_interval = 248,
245 nanosleep = 249,
246 mremap = 250,
247 _sysctl = 251,
248 getsid = 252,
249 fdatasync = 253,
250 nfsservctl = 254,
251 sync_file_range = 255,
252 clock_settime = 256,
253 clock_gettime = 257,
254 clock_getres = 258,
255 clock_nanosleep = 259,
256 sched_getaffinity = 260,
257 sched_setaffinity = 261,
258 timer_settime = 262,
259 timer_gettime = 263,
260 timer_getoverrun = 264,
261 timer_delete = 265,
262 timer_create = 266,
263 vserver = 267,
264 io_setup = 268,
265 io_destroy = 269,
266 io_submit = 270,
267 io_cancel = 271,
268 io_getevents = 272,
269 mq_open = 273,
270 mq_unlink = 274,
271 mq_timedsend = 275,
272 mq_timedreceive = 276,
273 mq_notify = 277,
274 mq_getsetattr = 278,
275 waitid = 279,
276 tee = 280,
277 add_key = 281,
278 request_key = 282,
279 keyctl = 283,
280 openat = 284,
281 mkdirat = 285,
282 mknodat = 286,
283 fchownat = 287,
284 futimesat = 288,
285 fstatat64 = 289,
286 unlinkat = 290,
287 renameat = 291,
288 linkat = 292,
289 symlinkat = 293,
290 readlinkat = 294,
291 fchmodat = 295,
292 faccessat = 296,
293 pselect6 = 297,
294 ppoll = 298,
295 unshare = 299,
296 set_robust_list = 300,
297 get_robust_list = 301,
298 migrate_pages = 302,
299 mbind = 303,
300 get_mempolicy = 304,
301 set_mempolicy = 305,
302 kexec_load = 306,
303 move_pages = 307,
304 getcpu = 308,
305 epoll_pwait = 309,
306 utimensat = 310,
307 signalfd = 311,
308 timerfd_create = 312,
309 eventfd = 313,
310 fallocate = 314,
311 timerfd_settime = 315,
312 timerfd_gettime = 316,
313 signalfd4 = 317,
314 eventfd2 = 318,
315 epoll_create1 = 319,
316 dup3 = 320,
317 pipe2 = 321,
318 inotify_init1 = 322,
319 accept4 = 323,
320 preadv = 324,
321 pwritev = 325,
322 rt_tgsigqueueinfo = 326,
323 perf_event_open = 327,
324 recvmmsg = 328,
325 fanotify_init = 329,
326 fanotify_mark = 330,
327 prlimit64 = 331,
328 name_to_handle_at = 332,
329 open_by_handle_at = 333,
330 clock_adjtime = 334,
331 syncfs = 335,
332 sendmmsg = 336,
333 setns = 337,
334 process_vm_readv = 338,
335 process_vm_writev = 339,
336 kern_features = 340,
337 kcmp = 341,
338 finit_module = 342,
339 sched_setattr = 343,
340 sched_getattr = 344,
341 renameat2 = 345,
342 seccomp = 346,
343 getrandom = 347,
344 memfd_create = 348,
345 bpf = 349,
346 execveat = 350,
347 membarrier = 351,
348 userfaultfd = 352,
349 bind = 353,
350 listen = 354,
351 setsockopt = 355,
352 mlock2 = 356,
353 copy_file_range = 357,
354 preadv2 = 358,
355 pwritev2 = 359,
356 statx = 360,
357 io_pgetevents = 361,
358 pkey_mprotect = 362,
359 pkey_alloc = 363,
360 pkey_free = 364,
361 rseq = 365,
362 semtimedop = 392,
363 semget = 393,
364 semctl = 394,
365 shmget = 395,
366 shmctl = 396,
367 shmat = 397,
368 shmdt = 398,
369 msgget = 399,
370 msgsnd = 400,
371 msgrcv = 401,
372 msgctl = 402,
373 pidfd_send_signal = 424,
374 io_uring_setup = 425,
375 io_uring_enter = 426,
376 io_uring_register = 427,
377 open_tree = 428,
378 move_mount = 429,
379 fsopen = 430,
380 fsconfig = 431,
381 fsmount = 432,
382 fspick = 433,
383 pidfd_open = 434,
384 clone3 = 435,
385 close_range = 436,
386 openat2 = 437,
387 pidfd_getfd = 438,
388 faccessat2 = 439,
389 process_madvise = 440,
390 epoll_pwait2 = 441,
391
392 _,
393};
394
395pub const O_CREAT = 0x200;
396pub const O_EXCL = 0x800;
397pub const O_NOCTTY = 0x8000;
398pub const O_TRUNC = 0x400;
399pub const O_APPEND = 0x8;
400pub const O_NONBLOCK = 0x4000;
401pub const O_SYNC = 0x802000;
402pub const O_DSYNC = 0x2000;
403pub const O_RSYNC = O_SYNC;
404pub const O_DIRECTORY = 0x10000;
405pub const O_NOFOLLOW = 0x20000;
406pub const O_CLOEXEC = 0x400000;
407
408pub const O_ASYNC = 0x40;
409pub const O_DIRECT = 0x100000;
410pub const O_LARGEFILE = 0;
411pub const O_NOATIME = 0x200000;
412pub const O_PATH = 0x1000000;
413pub const O_TMPFILE = 0x2010000;
414pub const O_NDELAY = O_NONBLOCK | 0x4;
415
416pub const F_DUPFD = 0;
417pub const F_GETFD = 1;
418pub const F_SETFD = 2;
419pub const F_GETFL = 3;
420pub const F_SETFL = 4;
421
422pub const F_SETOWN = 5;
423pub const F_GETOWN = 6;
424pub const F_GETLK = 7;
425pub const F_SETLK = 8;
426pub const F_SETLKW = 9;
427
428pub const F_RDLCK = 1;
429pub const F_WRLCK = 2;
430pub const F_UNLCK = 3;
431
432pub const F_SETOWN_EX = 15;
433pub const F_GETOWN_EX = 16;
434
435pub const F_GETOWNER_UIDS = 17;
436
437pub const LOCK_SH = 1;
438pub const LOCK_EX = 2;
439pub const LOCK_NB = 4;
440pub const LOCK_UN = 8;
441
442/// stack-like segment
443pub const MAP_GROWSDOWN = 0x0200;
444
445/// ETXTBSY
446pub const MAP_DENYWRITE = 0x0800;
447
448/// mark it as an executable
449pub const MAP_EXECUTABLE = 0x1000;
450
451/// pages are locked
452pub const MAP_LOCKED = 0x0100;
453
454/// don't check for reservations
455pub const MAP_NORESERVE = 0x0040;
456
457pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
458pub const VDSO_CGT_VER = "LINUX_2.6";
459
460pub const Flock = extern struct {
461 l_type: i16,
462 l_whence: i16,
463 l_start: off_t,
464 l_len: off_t,
465 l_pid: pid_t,
466};
467
468pub const msghdr = extern struct {
469 msg_name: ?*sockaddr,
470 msg_namelen: socklen_t,
471 msg_iov: [*]iovec,
472 msg_iovlen: u64,
473 msg_control: ?*c_void,
474 msg_controllen: u64,
475 msg_flags: i32,
476};
477
478pub const msghdr_const = extern struct {
479 msg_name: ?*const sockaddr,
480 msg_namelen: socklen_t,
481 msg_iov: [*]iovec_const,
482 msg_iovlen: u64,
483 msg_control: ?*c_void,
484 msg_controllen: u64,
485 msg_flags: i32,
486};
487
488pub const off_t = i64;
489pub const ino_t = u64;
490pub const mode_t = u32;
491
492// The `stat64` definition used by the libc.
493pub const libc_stat = extern struct {
494 dev: u64,
495 ino: ino_t,
496 mode: u32,
497 nlink: usize,
498
499 uid: u32,
500 gid: u32,
501 rdev: u64,
502 __pad0: u32,
503
504 size: off_t,
505 blksize: isize,
506 blocks: i64,
507
508 atim: timespec,
509 mtim: timespec,
510 ctim: timespec,
511 __unused: [2]isize,
512
513 pub fn atime(self: libc_stat) timespec {
514 return self.atim;
515 }
516
517 pub fn mtime(self: libc_stat) timespec {
518 return self.mtim;
519 }
520
521 pub fn ctime(self: libc_stat) timespec {
522 return self.ctim;
523 }
524};
525
526// The `stat64` definition used by the kernel.
527pub const kernel_stat = extern struct {
528 dev: u64,
529 ino: u64,
530 nlink: u64,
531
532 mode: u32,
533 uid: u32,
534 gid: u32,
535 __pad0: u32,
536
537 rdev: u64,
538 size: i64,
539 blksize: i64,
540 blocks: i64,
541
542 atim: timespec,
543 mtim: timespec,
544 ctim: timespec,
545 __unused: [3]u64,
546
547 pub fn atime(self: @This()) timespec {
548 return self.atim;
549 }
550
551 pub fn mtime(self: @This()) timespec {
552 return self.mtim;
553 }
554
555 pub fn ctime(self: @This()) timespec {
556 return self.ctim;
557 }
558};
559
560pub const timespec = extern struct {
561 tv_sec: isize,
562 tv_nsec: isize,
563};
564
565pub const timeval = extern struct {
566 tv_sec: isize,
567 tv_usec: isize,
568};
569
570pub const timezone = extern struct {
571 tz_minuteswest: i32,
572 tz_dsttime: i32,
573};
574
575// TODO I'm not sure if the code below is correct, need someone with more
576// knowledge about sparc64 linux internals to look into.
577
578pub const Elf_Symndx = u32;
579
580pub const fpstate = extern struct {
581 regs: [32]u64,
582 fsr: u64,
583 gsr: u64,
584 fprs: u64,
585};
586
587pub const __fpq = extern struct {
588 fpq_addr: *u32,
589 fpq_instr: u32,
590};
591
592pub const __fq = extern struct {
593 FQu: extern union {
594 whole: f64,
595 fpq: __fpq,
596 },
597};
598
599pub const fpregset_t = extern struct {
600 fpu_fr: extern union {
601 fpu_regs: [32]u32,
602 fpu_dregs: [32]f64,
603 fpu_qregs: [16]c_longdouble,
604 },
605 fpu_q: *__fq,
606 fpu_fsr: u64,
607 fpu_qcnt: u8,
608 fpu_q_entrysize: u8,
609 fpu_en: u8,
610};
611
612pub const siginfo_fpu_t = extern struct {
613 float_regs: [64]u32,
614 fsr: u64,
615 gsr: u64,
616 fprs: u64,
617};
618
619pub const sigcontext = extern struct {
620 info: [128]i8,
621 regs: extern struct {
622 u_regs: [16]u64,
623 tstate: u64,
624 tpc: u64,
625 tnpc: u64,
626 y: u64,
627 fprs: u64,
628 },
629 fpu_save: *siginfo_fpu_t,
630 stack: extern struct {
631 sp: usize,
632 flags: i32,
633 size: u64,
634 },
635 mask: u64,
636};
637
638pub const greg_t = u64;
639pub const gregset_t = [19]greg_t;
640
641pub const fq = extern struct {
642 addr: *u64,
643 insn: u32,
644};
645
646pub const fpu_t = extern struct {
647 fregs: extern union {
648 sregs: [32]u32,
649 dregs: [32]u64,
650 qregs: [16]c_longdouble,
651 },
652 fsr: u64,
653 fprs: u64,
654 gsr: u64,
655 fq: *fq,
656 qcnt: u8,
657 qentsz: u8,
658 enab: u8,
659};
660
661pub const mcontext_t = extern struct {
662 gregs: gregset_t,
663 fp: greg_t,
664 @"i7": greg_t,
665 fpregs: fpu_t,
666};
667
668pub const ucontext_t = extern struct {
669 link: *ucontext_t,
670 flags: u64,
671 sigmask: u64,
672 mcontext: mcontext_t,
673 stack: stack_t,
674 sigmask: sigset_t,
675};
lib/std/os/bits/linux/x86_64.zig deleted-638
...@@ -1,638 +0,0 @@
1// x86-64-specific declarations that are intended to be imported into the POSIX namespace.
2const std = @import("../../../std.zig");
3const pid_t = linux.pid_t;
4const uid_t = linux.uid_t;
5const gid_t = linux.gid_t;
6const clock_t = linux.clock_t;
7const stack_t = linux.stack_t;
8const sigset_t = linux.sigset_t;
9
10const linux = std.os.linux;
11const sockaddr = linux.sockaddr;
12const socklen_t = linux.socklen_t;
13const iovec = linux.iovec;
14const iovec_const = linux.iovec_const;
15
16pub const mode_t = usize;
17pub const time_t = isize;
18
19pub const SYS = enum(usize) {
20 read = 0,
21 write = 1,
22 open = 2,
23 close = 3,
24 stat = 4,
25 fstat = 5,
26 lstat = 6,
27 poll = 7,
28 lseek = 8,
29 mmap = 9,
30 mprotect = 10,
31 munmap = 11,
32 brk = 12,
33 rt_sigaction = 13,
34 rt_sigprocmask = 14,
35 rt_sigreturn = 15,
36 ioctl = 16,
37 pread = 17,
38 pwrite = 18,
39 readv = 19,
40 writev = 20,
41 access = 21,
42 pipe = 22,
43 select = 23,
44 sched_yield = 24,
45 mremap = 25,
46 msync = 26,
47 mincore = 27,
48 madvise = 28,
49 shmget = 29,
50 shmat = 30,
51 shmctl = 31,
52 dup = 32,
53 dup2 = 33,
54 pause = 34,
55 nanosleep = 35,
56 getitimer = 36,
57 alarm = 37,
58 setitimer = 38,
59 getpid = 39,
60 sendfile = 40,
61 socket = 41,
62 connect = 42,
63 accept = 43,
64 sendto = 44,
65 recvfrom = 45,
66 sendmsg = 46,
67 recvmsg = 47,
68 shutdown = 48,
69 bind = 49,
70 listen = 50,
71 getsockname = 51,
72 getpeername = 52,
73 socketpair = 53,
74 setsockopt = 54,
75 getsockopt = 55,
76 clone = 56,
77 fork = 57,
78 vfork = 58,
79 execve = 59,
80 exit = 60,
81 wait4 = 61,
82 kill = 62,
83 uname = 63,
84 semget = 64,
85 semop = 65,
86 semctl = 66,
87 shmdt = 67,
88 msgget = 68,
89 msgsnd = 69,
90 msgrcv = 70,
91 msgctl = 71,
92 fcntl = 72,
93 flock = 73,
94 fsync = 74,
95 fdatasync = 75,
96 truncate = 76,
97 ftruncate = 77,
98 getdents = 78,
99 getcwd = 79,
100 chdir = 80,
101 fchdir = 81,
102 rename = 82,
103 mkdir = 83,
104 rmdir = 84,
105 creat = 85,
106 link = 86,
107 unlink = 87,
108 symlink = 88,
109 readlink = 89,
110 chmod = 90,
111 fchmod = 91,
112 chown = 92,
113 fchown = 93,
114 lchown = 94,
115 umask = 95,
116 gettimeofday = 96,
117 getrlimit = 97,
118 getrusage = 98,
119 sysinfo = 99,
120 times = 100,
121 ptrace = 101,
122 getuid = 102,
123 syslog = 103,
124 getgid = 104,
125 setuid = 105,
126 setgid = 106,
127 geteuid = 107,
128 getegid = 108,
129 setpgid = 109,
130 getppid = 110,
131 getpgrp = 111,
132 setsid = 112,
133 setreuid = 113,
134 setregid = 114,
135 getgroups = 115,
136 setgroups = 116,
137 setresuid = 117,
138 getresuid = 118,
139 setresgid = 119,
140 getresgid = 120,
141 getpgid = 121,
142 setfsuid = 122,
143 setfsgid = 123,
144 getsid = 124,
145 capget = 125,
146 capset = 126,
147 rt_sigpending = 127,
148 rt_sigtimedwait = 128,
149 rt_sigqueueinfo = 129,
150 rt_sigsuspend = 130,
151 sigaltstack = 131,
152 utime = 132,
153 mknod = 133,
154 uselib = 134,
155 personality = 135,
156 ustat = 136,
157 statfs = 137,
158 fstatfs = 138,
159 sysfs = 139,
160 getpriority = 140,
161 setpriority = 141,
162 sched_setparam = 142,
163 sched_getparam = 143,
164 sched_setscheduler = 144,
165 sched_getscheduler = 145,
166 sched_get_priority_max = 146,
167 sched_get_priority_min = 147,
168 sched_rr_get_interval = 148,
169 mlock = 149,
170 munlock = 150,
171 mlockall = 151,
172 munlockall = 152,
173 vhangup = 153,
174 modify_ldt = 154,
175 pivot_root = 155,
176 _sysctl = 156,
177 prctl = 157,
178 arch_prctl = 158,
179 adjtimex = 159,
180 setrlimit = 160,
181 chroot = 161,
182 sync = 162,
183 acct = 163,
184 settimeofday = 164,
185 mount = 165,
186 umount2 = 166,
187 swapon = 167,
188 swapoff = 168,
189 reboot = 169,
190 sethostname = 170,
191 setdomainname = 171,
192 iopl = 172,
193 ioperm = 173,
194 create_module = 174,
195 init_module = 175,
196 delete_module = 176,
197 get_kernel_syms = 177,
198 query_module = 178,
199 quotactl = 179,
200 nfsservctl = 180,
201 getpmsg = 181,
202 putpmsg = 182,
203 afs_syscall = 183,
204 tuxcall = 184,
205 security = 185,
206 gettid = 186,
207 readahead = 187,
208 setxattr = 188,
209 lsetxattr = 189,
210 fsetxattr = 190,
211 getxattr = 191,
212 lgetxattr = 192,
213 fgetxattr = 193,
214 listxattr = 194,
215 llistxattr = 195,
216 flistxattr = 196,
217 removexattr = 197,
218 lremovexattr = 198,
219 fremovexattr = 199,
220 tkill = 200,
221 time = 201,
222 futex = 202,
223 sched_setaffinity = 203,
224 sched_getaffinity = 204,
225 set_thread_area = 205,
226 io_setup = 206,
227 io_destroy = 207,
228 io_getevents = 208,
229 io_submit = 209,
230 io_cancel = 210,
231 get_thread_area = 211,
232 lookup_dcookie = 212,
233 epoll_create = 213,
234 epoll_ctl_old = 214,
235 epoll_wait_old = 215,
236 remap_file_pages = 216,
237 getdents64 = 217,
238 set_tid_address = 218,
239 restart_syscall = 219,
240 semtimedop = 220,
241 fadvise64 = 221,
242 timer_create = 222,
243 timer_settime = 223,
244 timer_gettime = 224,
245 timer_getoverrun = 225,
246 timer_delete = 226,
247 clock_settime = 227,
248 clock_gettime = 228,
249 clock_getres = 229,
250 clock_nanosleep = 230,
251 exit_group = 231,
252 epoll_wait = 232,
253 epoll_ctl = 233,
254 tgkill = 234,
255 utimes = 235,
256 vserver = 236,
257 mbind = 237,
258 set_mempolicy = 238,
259 get_mempolicy = 239,
260 mq_open = 240,
261 mq_unlink = 241,
262 mq_timedsend = 242,
263 mq_timedreceive = 243,
264 mq_notify = 244,
265 mq_getsetattr = 245,
266 kexec_load = 246,
267 waitid = 247,
268 add_key = 248,
269 request_key = 249,
270 keyctl = 250,
271 ioprio_set = 251,
272 ioprio_get = 252,
273 inotify_init = 253,
274 inotify_add_watch = 254,
275 inotify_rm_watch = 255,
276 migrate_pages = 256,
277 openat = 257,
278 mkdirat = 258,
279 mknodat = 259,
280 fchownat = 260,
281 futimesat = 261,
282 fstatat = 262,
283 unlinkat = 263,
284 renameat = 264,
285 linkat = 265,
286 symlinkat = 266,
287 readlinkat = 267,
288 fchmodat = 268,
289 faccessat = 269,
290 pselect6 = 270,
291 ppoll = 271,
292 unshare = 272,
293 set_robust_list = 273,
294 get_robust_list = 274,
295 splice = 275,
296 tee = 276,
297 sync_file_range = 277,
298 vmsplice = 278,
299 move_pages = 279,
300 utimensat = 280,
301 epoll_pwait = 281,
302 signalfd = 282,
303 timerfd_create = 283,
304 eventfd = 284,
305 fallocate = 285,
306 timerfd_settime = 286,
307 timerfd_gettime = 287,
308 accept4 = 288,
309 signalfd4 = 289,
310 eventfd2 = 290,
311 epoll_create1 = 291,
312 dup3 = 292,
313 pipe2 = 293,
314 inotify_init1 = 294,
315 preadv = 295,
316 pwritev = 296,
317 rt_tgsigqueueinfo = 297,
318 perf_event_open = 298,
319 recvmmsg = 299,
320 fanotify_init = 300,
321 fanotify_mark = 301,
322 prlimit64 = 302,
323 name_to_handle_at = 303,
324 open_by_handle_at = 304,
325 clock_adjtime = 305,
326 syncfs = 306,
327 sendmmsg = 307,
328 setns = 308,
329 getcpu = 309,
330 process_vm_readv = 310,
331 process_vm_writev = 311,
332 kcmp = 312,
333 finit_module = 313,
334 sched_setattr = 314,
335 sched_getattr = 315,
336 renameat2 = 316,
337 seccomp = 317,
338 getrandom = 318,
339 memfd_create = 319,
340 kexec_file_load = 320,
341 bpf = 321,
342 execveat = 322,
343 userfaultfd = 323,
344 membarrier = 324,
345 mlock2 = 325,
346 copy_file_range = 326,
347 preadv2 = 327,
348 pwritev2 = 328,
349 pkey_mprotect = 329,
350 pkey_alloc = 330,
351 pkey_free = 331,
352 statx = 332,
353 io_pgetevents = 333,
354 rseq = 334,
355 pidfd_send_signal = 424,
356 io_uring_setup = 425,
357 io_uring_enter = 426,
358 io_uring_register = 427,
359 open_tree = 428,
360 move_mount = 429,
361 fsopen = 430,
362 fsconfig = 431,
363 fsmount = 432,
364 fspick = 433,
365 pidfd_open = 434,
366 clone3 = 435,
367 close_range = 436,
368 openat2 = 437,
369 pidfd_getfd = 438,
370 faccessat2 = 439,
371 process_madvise = 440,
372 epoll_pwait2 = 441,
373
374 _,
375};
376
377pub const O_CREAT = 0o100;
378pub const O_EXCL = 0o200;
379pub const O_NOCTTY = 0o400;
380pub const O_TRUNC = 0o1000;
381pub const O_APPEND = 0o2000;
382pub const O_NONBLOCK = 0o4000;
383pub const O_DSYNC = 0o10000;
384pub const O_SYNC = 0o4010000;
385pub const O_RSYNC = 0o4010000;
386pub const O_DIRECTORY = 0o200000;
387pub const O_NOFOLLOW = 0o400000;
388pub const O_CLOEXEC = 0o2000000;
389
390pub const O_ASYNC = 0o20000;
391pub const O_DIRECT = 0o40000;
392pub const O_LARGEFILE = 0;
393pub const O_NOATIME = 0o1000000;
394pub const O_PATH = 0o10000000;
395pub const O_TMPFILE = 0o20200000;
396pub const O_NDELAY = O_NONBLOCK;
397
398pub const F_DUPFD = 0;
399pub const F_GETFD = 1;
400pub const F_SETFD = 2;
401pub const F_GETFL = 3;
402pub const F_SETFL = 4;
403
404pub const F_SETOWN = 8;
405pub const F_GETOWN = 9;
406pub const F_SETSIG = 10;
407pub const F_GETSIG = 11;
408
409pub const F_GETLK = 5;
410pub const F_SETLK = 6;
411pub const F_SETLKW = 7;
412
413pub const F_SETOWN_EX = 15;
414pub const F_GETOWN_EX = 16;
415
416pub const F_GETOWNER_UIDS = 17;
417
418/// only give out 32bit addresses
419pub const MAP_32BIT = 0x40;
420
421/// stack-like segment
422pub const MAP_GROWSDOWN = 0x0100;
423
424/// ETXTBSY
425pub const MAP_DENYWRITE = 0x0800;
426
427/// mark it as an executable
428pub const MAP_EXECUTABLE = 0x1000;
429
430/// pages are locked
431pub const MAP_LOCKED = 0x2000;
432
433/// don't check for reservations
434pub const MAP_NORESERVE = 0x4000;
435
436pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
437pub const VDSO_CGT_VER = "LINUX_2.6";
438pub const VDSO_GETCPU_SYM = "__vdso_getcpu";
439pub const VDSO_GETCPU_VER = "LINUX_2.6";
440
441pub const ARCH_SET_GS = 0x1001;
442pub const ARCH_SET_FS = 0x1002;
443pub const ARCH_GET_FS = 0x1003;
444pub const ARCH_GET_GS = 0x1004;
445
446pub const REG_R8 = 0;
447pub const REG_R9 = 1;
448pub const REG_R10 = 2;
449pub const REG_R11 = 3;
450pub const REG_R12 = 4;
451pub const REG_R13 = 5;
452pub const REG_R14 = 6;
453pub const REG_R15 = 7;
454pub const REG_RDI = 8;
455pub const REG_RSI = 9;
456pub const REG_RBP = 10;
457pub const REG_RBX = 11;
458pub const REG_RDX = 12;
459pub const REG_RAX = 13;
460pub const REG_RCX = 14;
461pub const REG_RSP = 15;
462pub const REG_RIP = 16;
463pub const REG_EFL = 17;
464pub const REG_CSGSFS = 18;
465pub const REG_ERR = 19;
466pub const REG_TRAPNO = 20;
467pub const REG_OLDMASK = 21;
468pub const REG_CR2 = 22;
469
470pub const LOCK_SH = 1;
471pub const LOCK_EX = 2;
472pub const LOCK_UN = 8;
473pub const LOCK_NB = 4;
474
475pub const F_RDLCK = 0;
476pub const F_WRLCK = 1;
477pub const F_UNLCK = 2;
478
479pub const Flock = extern struct {
480 l_type: i16,
481 l_whence: i16,
482 l_start: off_t,
483 l_len: off_t,
484 l_pid: pid_t,
485};
486
487pub const msghdr = extern struct {
488 msg_name: ?*sockaddr,
489 msg_namelen: socklen_t,
490 msg_iov: [*]iovec,
491 msg_iovlen: i32,
492 __pad1: i32 = 0,
493 msg_control: ?*c_void,
494 msg_controllen: socklen_t,
495 __pad2: socklen_t = 0,
496 msg_flags: i32,
497};
498
499pub const msghdr_const = extern struct {
500 msg_name: ?*const sockaddr,
501 msg_namelen: socklen_t,
502 msg_iov: [*]iovec_const,
503 msg_iovlen: i32,
504 __pad1: i32 = 0,
505 msg_control: ?*c_void,
506 msg_controllen: socklen_t,
507 __pad2: socklen_t = 0,
508 msg_flags: i32,
509};
510
511pub const off_t = i64;
512pub const ino_t = u64;
513pub const dev_t = u64;
514
515// The `stat` definition used by the Linux kernel.
516pub const kernel_stat = extern struct {
517 dev: dev_t,
518 ino: ino_t,
519 nlink: usize,
520
521 mode: u32,
522 uid: uid_t,
523 gid: gid_t,
524 __pad0: u32,
525 rdev: dev_t,
526 size: off_t,
527 blksize: isize,
528 blocks: i64,
529
530 atim: timespec,
531 mtim: timespec,
532 ctim: timespec,
533 __unused: [3]isize,
534
535 pub fn atime(self: @This()) timespec {
536 return self.atim;
537 }
538
539 pub fn mtime(self: @This()) timespec {
540 return self.mtim;
541 }
542
543 pub fn ctime(self: @This()) timespec {
544 return self.ctim;
545 }
546};
547
548// The `stat64` definition used by the libc.
549pub const libc_stat = kernel_stat;
550
551pub const timespec = extern struct {
552 tv_sec: isize,
553 tv_nsec: isize,
554};
555
556pub const timeval = extern struct {
557 tv_sec: isize,
558 tv_usec: isize,
559};
560
561pub const timezone = extern struct {
562 tz_minuteswest: i32,
563 tz_dsttime: i32,
564};
565
566pub const Elf_Symndx = u32;
567
568pub const greg_t = usize;
569pub const gregset_t = [23]greg_t;
570pub const fpstate = extern struct {
571 cwd: u16,
572 swd: u16,
573 ftw: u16,
574 fop: u16,
575 rip: usize,
576 rdp: usize,
577 mxcsr: u32,
578 mxcr_mask: u32,
579 st: [8]extern struct {
580 significand: [4]u16,
581 exponent: u16,
582 padding: [3]u16 = undefined,
583 },
584 xmm: [16]extern struct {
585 element: [4]u32,
586 },
587 padding: [24]u32 = undefined,
588};
589pub const fpregset_t = *fpstate;
590pub const sigcontext = extern struct {
591 r8: usize,
592 r9: usize,
593 r10: usize,
594 r11: usize,
595 r12: usize,
596 r13: usize,
597 r14: usize,
598 r15: usize,
599
600 rdi: usize,
601 rsi: usize,
602 rbp: usize,
603 rbx: usize,
604 rdx: usize,
605 rax: usize,
606 rcx: usize,
607 rsp: usize,
608 rip: usize,
609 eflags: usize,
610
611 cs: u16,
612 gs: u16,
613 fs: u16,
614 pad0: u16 = undefined,
615
616 err: usize,
617 trapno: usize,
618 oldmask: usize,
619 cr2: usize,
620
621 fpstate: *fpstate,
622 reserved1: [8]usize = undefined,
623};
624
625pub const mcontext_t = extern struct {
626 gregs: gregset_t,
627 fpregs: fpregset_t,
628 reserved1: [8]usize = undefined,
629};
630
631pub const ucontext_t = extern struct {
632 flags: usize,
633 link: *ucontext_t,
634 stack: stack_t,
635 mcontext: mcontext_t,
636 sigmask: sigset_t,
637 fpregs_mem: [64]usize,
638};
lib/std/os/bits/linux/xdp.zig deleted-77
...@@ -1,77 +0,0 @@
1usingnamespace @import("../linux.zig");
2
3pub const XDP_SHARED_UMEM = (1 << 0);
4pub const XDP_COPY = (1 << 1);
5pub const XDP_ZEROCOPY = (1 << 2);
6
7pub const XDP_UMEM_UNALIGNED_CHUNK_FLAG = (1 << 0);
8
9pub const sockaddr_xdp = extern struct {
10 family: u16 = AF_XDP,
11 flags: u16,
12 ifindex: u32,
13 queue_id: u32,
14 shared_umem_fd: u32,
15};
16
17pub const XDP_USE_NEED_WAKEUP = (1 << 3);
18
19pub const xdp_ring_offset = extern struct {
20 producer: u64,
21 consumer: u64,
22 desc: u64,
23 flags: u64,
24};
25
26pub const xdp_mmap_offsets = extern struct {
27 rx: xdp_ring_offset,
28 tx: xdp_ring_offset,
29 fr: xdp_ring_offset,
30 cr: xdp_ring_offset,
31};
32
33pub const XDP_MMAP_OFFSETS = 1;
34pub const XDP_RX_RING = 2;
35pub const XDP_TX_RING = 3;
36pub const XDP_UMEM_REG = 4;
37pub const XDP_UMEM_FILL_RING = 5;
38pub const XDP_UMEM_COMPLETION_RING = 6;
39pub const XDP_STATISTICS = 7;
40pub const XDP_OPTIONS = 8;
41
42pub const xdp_umem_reg = extern struct {
43 addr: u64,
44 len: u64,
45 chunk_size: u32,
46 headroom: u32,
47 flags: u32,
48};
49
50pub const xdp_statistics = extern struct {
51 rx_dropped: u64,
52 rx_invalid_descs: u64,
53 tx_invalid_descs: u64,
54 rx_ring_full: u64,
55 rx_fill_ring_empty_descs: u64,
56 tx_ring_empty_descs: u64,
57};
58
59pub const xdp_options = extern struct {
60 flags: u32,
61};
62
63pub const XDP_OPTIONS_ZEROCOPY = (1 << 0);
64
65pub const XDP_PGOFF_RX_RING = 0;
66pub const XDP_PGOFF_TX_RING = 0x80000000;
67pub const XDP_UMEM_PGOFF_FILL_RING = 0x100000000;
68pub const XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000;
69
70pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT = 48;
71pub const XSK_UNALIGNED_BUF_ADDR_MASK = (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1;
72
73pub const xdp_desc = extern struct {
74 addr: u64,
75 len: u32,
76 options: u32,
77};
lib/std/os/bits/netbsd.zig deleted-1328
...@@ -1,1328 +0,0 @@
1const std = @import("../../std.zig");
2const builtin = std.builtin;
3const maxInt = std.math.maxInt;
4
5pub usingnamespace @import("posix.zig");
6
7pub const blkcnt_t = i64;
8pub const blksize_t = i32;
9pub const clock_t = u32;
10pub const dev_t = u64;
11pub const fd_t = i32;
12pub const gid_t = u32;
13pub const ino_t = u64;
14pub const mode_t = u32;
15pub const nlink_t = u32;
16pub const off_t = i64;
17pub const pid_t = i32;
18pub const socklen_t = u32;
19pub const time_t = i64;
20pub const uid_t = u32;
21pub const lwpid_t = i32;
22pub const suseconds_t = c_int;
23
24/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
25pub const Kevent = extern struct {
26 ident: usize,
27 filter: i32,
28 flags: u32,
29 fflags: u32,
30 data: i64,
31 udata: usize,
32};
33
34pub const RTLD_LAZY = 1;
35pub const RTLD_NOW = 2;
36pub const RTLD_GLOBAL = 0x100;
37pub const RTLD_LOCAL = 0x200;
38pub const RTLD_NODELETE = 0x01000;
39pub const RTLD_NOLOAD = 0x02000;
40
41pub const RTLD_NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
42pub const RTLD_DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
43pub const RTLD_SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
44
45pub const dl_phdr_info = extern struct {
46 dlpi_addr: usize,
47 dlpi_name: ?[*:0]const u8,
48 dlpi_phdr: [*]std.elf.Phdr,
49 dlpi_phnum: u16,
50};
51
52pub const Flock = extern struct {
53 l_start: off_t,
54 l_len: off_t,
55 l_pid: pid_t,
56 l_type: i16,
57 l_whence: i16,
58};
59
60pub const addrinfo = extern struct {
61 flags: i32,
62 family: i32,
63 socktype: i32,
64 protocol: i32,
65 addrlen: socklen_t,
66 canonname: ?[*:0]u8,
67 addr: ?*sockaddr,
68 next: ?*addrinfo,
69};
70
71pub const EAI = enum(c_int) {
72 /// address family for hostname not supported
73 ADDRFAMILY = 1,
74
75 /// name could not be resolved at this time
76 AGAIN = 2,
77
78 /// flags parameter had an invalid value
79 BADFLAGS = 3,
80
81 /// non-recoverable failure in name resolution
82 FAIL = 4,
83
84 /// address family not recognized
85 FAMILY = 5,
86
87 /// memory allocation failure
88 MEMORY = 6,
89
90 /// no address associated with hostname
91 NODATA = 7,
92
93 /// name does not resolve
94 NONAME = 8,
95
96 /// service not recognized for socket type
97 SERVICE = 9,
98
99 /// intended socket type was not recognized
100 SOCKTYPE = 10,
101
102 /// system error returned in errno
103 SYSTEM = 11,
104
105 /// invalid value for hints
106 BADHINTS = 12,
107
108 /// resolved protocol is unknown
109 PROTOCOL = 13,
110
111 /// argument buffer overflow
112 OVERFLOW = 14,
113
114 _,
115};
116
117pub const EAI_MAX = 15;
118
119pub const msghdr = extern struct {
120 /// optional address
121 msg_name: ?*sockaddr,
122
123 /// size of address
124 msg_namelen: socklen_t,
125
126 /// scatter/gather array
127 msg_iov: [*]iovec,
128
129 /// # elements in msg_iov
130 msg_iovlen: i32,
131
132 /// ancillary data
133 msg_control: ?*c_void,
134
135 /// ancillary data buffer len
136 msg_controllen: socklen_t,
137
138 /// flags on received message
139 msg_flags: i32,
140};
141
142pub const msghdr_const = extern struct {
143 /// optional address
144 msg_name: ?*const sockaddr,
145
146 /// size of address
147 msg_namelen: socklen_t,
148
149 /// scatter/gather array
150 msg_iov: [*]iovec_const,
151
152 /// # elements in msg_iov
153 msg_iovlen: i32,
154
155 /// ancillary data
156 msg_control: ?*c_void,
157
158 /// ancillary data buffer len
159 msg_controllen: socklen_t,
160
161 /// flags on received message
162 msg_flags: i32,
163};
164
165pub const libc_stat = extern struct {
166 dev: dev_t,
167 mode: mode_t,
168 ino: ino_t,
169 nlink: nlink_t,
170 uid: uid_t,
171 gid: gid_t,
172 rdev: dev_t,
173 atim: timespec,
174 mtim: timespec,
175 ctim: timespec,
176 birthtim: timespec,
177 size: off_t,
178 blocks: blkcnt_t,
179 blksize: blksize_t,
180 flags: u32,
181 gen: u32,
182 __spare: [2]u32,
183
184 pub fn atime(self: @This()) timespec {
185 return self.atim;
186 }
187
188 pub fn mtime(self: @This()) timespec {
189 return self.mtim;
190 }
191
192 pub fn ctime(self: @This()) timespec {
193 return self.ctim;
194 }
195};
196
197pub const timespec = extern struct {
198 tv_sec: i64,
199 tv_nsec: isize,
200};
201
202pub const timeval = extern struct {
203 /// seconds
204 tv_sec: time_t,
205 /// microseconds
206 tv_usec: suseconds_t,
207};
208
209pub const MAXNAMLEN = 511;
210
211pub const dirent = extern struct {
212 d_fileno: ino_t,
213 d_reclen: u16,
214 d_namlen: u16,
215 d_type: u8,
216 d_name: [MAXNAMLEN:0]u8,
217
218 pub fn reclen(self: dirent) u16 {
219 return self.d_reclen;
220 }
221};
222
223pub const SOCK_STREAM = 1;
224pub const SOCK_DGRAM = 2;
225pub const SOCK_RAW = 3;
226pub const SOCK_RDM = 4;
227pub const SOCK_SEQPACKET = 5;
228pub const SOCK_CONN_DGRAM = 6;
229pub const SOCK_DCCP = SOCK_CONN_DGRAM;
230
231pub const SOCK_CLOEXEC = 0x10000000;
232pub const SOCK_NONBLOCK = 0x20000000;
233pub const SOCK_NOSIGPIPE = 0x40000000;
234pub const SOCK_FLAGS_MASK = 0xf0000000;
235
236pub const SO_DEBUG = 0x0001;
237pub const SO_ACCEPTCONN = 0x0002;
238pub const SO_REUSEADDR = 0x0004;
239pub const SO_KEEPALIVE = 0x0008;
240pub const SO_DONTROUTE = 0x0010;
241pub const SO_BROADCAST = 0x0020;
242pub const SO_USELOOPBACK = 0x0040;
243pub const SO_LINGER = 0x0080;
244pub const SO_OOBINLINE = 0x0100;
245pub const SO_REUSEPORT = 0x0200;
246pub const SO_NOSIGPIPE = 0x0800;
247pub const SO_ACCEPTFILTER = 0x1000;
248pub const SO_TIMESTAMP = 0x2000;
249pub const SO_RERROR = 0x4000;
250
251pub const SO_SNDBUF = 0x1001;
252pub const SO_RCVBUF = 0x1002;
253pub const SO_SNDLOWAT = 0x1003;
254pub const SO_RCVLOWAT = 0x1004;
255pub const SO_ERROR = 0x1007;
256pub const SO_TYPE = 0x1008;
257pub const SO_OVERFLOWED = 0x1009;
258
259pub const SO_NOHEADER = 0x100a;
260pub const SO_SNDTIMEO = 0x100b;
261pub const SO_RCVTIMEO = 0x100c;
262
263pub const SOL_SOCKET = 0xffff;
264
265pub const PF_UNSPEC = AF_UNSPEC;
266pub const PF_LOCAL = AF_LOCAL;
267pub const PF_UNIX = PF_LOCAL;
268pub const PF_INET = AF_INET;
269pub const PF_IMPLINK = AF_IMPLINK;
270pub const PF_PUP = AF_PUP;
271pub const PF_CHAOS = AF_CHAOS;
272pub const PF_NS = AF_NS;
273pub const PF_ISO = AF_ISO;
274pub const PF_OSI = AF_ISO;
275pub const PF_ECMA = AF_ECMA;
276pub const PF_DATAKIT = AF_DATAKIT;
277pub const PF_CCITT = AF_CCITT;
278pub const PF_SNA = AF_SNA;
279pub const PF_DECnet = AF_DECnet;
280pub const PF_DLI = AF_DLI;
281pub const PF_LAT = AF_LAT;
282pub const PF_HYLINK = AF_HYLINK;
283pub const PF_APPLETALK = AF_APPLETALK;
284pub const PF_OROUTE = AF_OROUTE;
285pub const PF_LINK = AF_LINK;
286pub const PF_COIP = AF_COIP;
287pub const PF_CNT = AF_CNT;
288pub const PF_INET6 = AF_INET6;
289pub const PF_IPX = AF_IPX;
290pub const PF_ISDN = AF_ISDN;
291pub const PF_E164 = AF_E164;
292pub const PF_NATM = AF_NATM;
293pub const PF_ARP = AF_ARP;
294pub const PF_BLUETOOTH = AF_BLUETOOTH;
295pub const PF_MPLS = AF_MPLS;
296pub const PF_ROUTE = AF_ROUTE;
297pub const PF_CAN = AF_CAN;
298pub const PF_ETHER = AF_ETHER;
299pub const PF_MAX = AF_MAX;
300
301pub const AF_UNSPEC = 0;
302pub const AF_LOCAL = 1;
303pub const AF_UNIX = AF_LOCAL;
304pub const AF_INET = 2;
305pub const AF_IMPLINK = 3;
306pub const AF_PUP = 4;
307pub const AF_CHAOS = 5;
308pub const AF_NS = 6;
309pub const AF_ISO = 7;
310pub const AF_OSI = AF_ISO;
311pub const AF_ECMA = 8;
312pub const AF_DATAKIT = 9;
313pub const AF_CCITT = 10;
314pub const AF_SNA = 11;
315pub const AF_DECnet = 12;
316pub const AF_DLI = 13;
317pub const AF_LAT = 14;
318pub const AF_HYLINK = 15;
319pub const AF_APPLETALK = 16;
320pub const AF_OROUTE = 17;
321pub const AF_LINK = 18;
322pub const AF_COIP = 20;
323pub const AF_CNT = 21;
324pub const AF_IPX = 23;
325pub const AF_INET6 = 24;
326pub const AF_ISDN = 26;
327pub const AF_E164 = AF_ISDN;
328pub const AF_NATM = 27;
329pub const AF_ARP = 28;
330pub const AF_BLUETOOTH = 31;
331pub const AF_IEEE80211 = 32;
332pub const AF_MPLS = 33;
333pub const AF_ROUTE = 34;
334pub const AF_CAN = 35;
335pub const AF_ETHER = 36;
336pub const AF_MAX = 37;
337
338pub const in_port_t = u16;
339pub const sa_family_t = u8;
340
341pub const sockaddr = extern struct {
342 /// total length
343 len: u8,
344
345 /// address family
346 family: sa_family_t,
347
348 /// actually longer; address value
349 data: [14]u8,
350};
351
352pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
353
354pub const sockaddr_in = extern struct {
355 len: u8 = @sizeOf(sockaddr_in),
356 family: sa_family_t = AF_INET,
357 port: in_port_t,
358 addr: u32,
359 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
360};
361
362pub const sockaddr_in6 = extern struct {
363 len: u8 = @sizeOf(sockaddr_in6),
364 family: sa_family_t = AF_INET6,
365 port: in_port_t,
366 flowinfo: u32,
367 addr: [16]u8,
368 scope_id: u32,
369};
370
371/// Definitions for UNIX IPC domain.
372pub const sockaddr_un = extern struct {
373 /// total sockaddr length
374 len: u8 = @sizeOf(sockaddr_un),
375
376 /// AF_LOCAL
377 family: sa_family_t = AF_LOCAL,
378
379 /// path name
380 path: [104]u8,
381};
382
383/// get address to use bind()
384pub const AI_PASSIVE = 0x00000001;
385
386/// fill ai_canonname
387pub const AI_CANONNAME = 0x00000002;
388
389/// prevent host name resolution
390pub const AI_NUMERICHOST = 0x00000004;
391
392/// prevent service name resolution
393pub const AI_NUMERICSERV = 0x00000008;
394
395/// only if any address is assigned
396pub const AI_ADDRCONFIG = 0x00000400;
397
398pub const CTL_KERN = 1;
399pub const CTL_DEBUG = 5;
400
401pub const KERN_PROC_ARGS = 48; // struct: process argv/env
402pub const KERN_PROC_PATHNAME = 5; // path to executable
403pub const KERN_IOV_MAX = 38;
404
405pub const PATH_MAX = 1024;
406pub const IOV_MAX = KERN_IOV_MAX;
407
408pub const STDIN_FILENO = 0;
409pub const STDOUT_FILENO = 1;
410pub const STDERR_FILENO = 2;
411
412pub const PROT_NONE = 0;
413pub const PROT_READ = 1;
414pub const PROT_WRITE = 2;
415pub const PROT_EXEC = 4;
416
417pub const CLOCK_REALTIME = 0;
418pub const CLOCK_VIRTUAL = 1;
419pub const CLOCK_PROF = 2;
420pub const CLOCK_MONOTONIC = 3;
421pub const CLOCK_THREAD_CPUTIME_ID = 0x20000000;
422pub const CLOCK_PROCESS_CPUTIME_ID = 0x40000000;
423
424pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
425pub const MAP_SHARED = 0x0001;
426pub const MAP_PRIVATE = 0x0002;
427pub const MAP_REMAPDUP = 0x0004;
428pub const MAP_FIXED = 0x0010;
429pub const MAP_RENAME = 0x0020;
430pub const MAP_NORESERVE = 0x0040;
431pub const MAP_INHERIT = 0x0080;
432pub const MAP_HASSEMAPHORE = 0x0200;
433pub const MAP_TRYFIXED = 0x0400;
434pub const MAP_WIRED = 0x0800;
435
436pub const MAP_FILE = 0x0000;
437pub const MAP_NOSYNC = 0x0800;
438pub const MAP_ANON = 0x1000;
439pub const MAP_ANONYMOUS = MAP_ANON;
440pub const MAP_STACK = 0x2000;
441
442pub const WNOHANG = 0x00000001;
443pub const WUNTRACED = 0x00000002;
444pub const WSTOPPED = WUNTRACED;
445pub const WCONTINUED = 0x00000010;
446pub const WNOWAIT = 0x00010000;
447pub const WEXITED = 0x00000020;
448pub const WTRAPPED = 0x00000040;
449
450pub const SA_ONSTACK = 0x0001;
451pub const SA_RESTART = 0x0002;
452pub const SA_RESETHAND = 0x0004;
453pub const SA_NOCLDSTOP = 0x0008;
454pub const SA_NODEFER = 0x0010;
455pub const SA_NOCLDWAIT = 0x0020;
456pub const SA_SIGINFO = 0x0040;
457
458pub const SIGHUP = 1;
459pub const SIGINT = 2;
460pub const SIGQUIT = 3;
461pub const SIGILL = 4;
462pub const SIGTRAP = 5;
463pub const SIGABRT = 6;
464pub const SIGIOT = SIGABRT;
465pub const SIGEMT = 7;
466pub const SIGFPE = 8;
467pub const SIGKILL = 9;
468pub const SIGBUS = 10;
469pub const SIGSEGV = 11;
470pub const SIGSYS = 12;
471pub const SIGPIPE = 13;
472pub const SIGALRM = 14;
473pub const SIGTERM = 15;
474pub const SIGURG = 16;
475pub const SIGSTOP = 17;
476pub const SIGTSTP = 18;
477pub const SIGCONT = 19;
478pub const SIGCHLD = 20;
479pub const SIGTTIN = 21;
480pub const SIGTTOU = 22;
481pub const SIGIO = 23;
482pub const SIGXCPU = 24;
483pub const SIGXFSZ = 25;
484pub const SIGVTALRM = 26;
485pub const SIGPROF = 27;
486pub const SIGWINCH = 28;
487pub const SIGINFO = 29;
488pub const SIGUSR1 = 30;
489pub const SIGUSR2 = 31;
490pub const SIGPWR = 32;
491
492pub const SIGRTMIN = 33;
493pub const SIGRTMAX = 63;
494
495// access function
496pub const F_OK = 0; // test for existence of file
497pub const X_OK = 1; // test for execute or search permission
498pub const W_OK = 2; // test for write permission
499pub const R_OK = 4; // test for read permission
500
501/// open for reading only
502pub const O_RDONLY = 0x00000000;
503
504/// open for writing only
505pub const O_WRONLY = 0x00000001;
506
507/// open for reading and writing
508pub const O_RDWR = 0x00000002;
509
510/// mask for above modes
511pub const O_ACCMODE = 0x00000003;
512
513/// no delay
514pub const O_NONBLOCK = 0x00000004;
515
516/// set append mode
517pub const O_APPEND = 0x00000008;
518
519/// open with shared file lock
520pub const O_SHLOCK = 0x00000010;
521
522/// open with exclusive file lock
523pub const O_EXLOCK = 0x00000020;
524
525/// signal pgrp when data ready
526pub const O_ASYNC = 0x00000040;
527
528/// synchronous writes
529pub const O_SYNC = 0x00000080;
530
531/// don't follow symlinks on the last
532pub const O_NOFOLLOW = 0x00000100;
533
534/// create if nonexistent
535pub const O_CREAT = 0x00000200;
536
537/// truncate to zero length
538pub const O_TRUNC = 0x00000400;
539
540/// error if already exists
541pub const O_EXCL = 0x00000800;
542
543/// don't assign controlling terminal
544pub const O_NOCTTY = 0x00008000;
545
546/// write: I/O data completion
547pub const O_DSYNC = 0x00010000;
548
549/// read: I/O completion as for write
550pub const O_RSYNC = 0x00020000;
551
552/// use alternate i/o semantics
553pub const O_ALT_IO = 0x00040000;
554
555/// direct I/O hint
556pub const O_DIRECT = 0x00080000;
557
558/// fail if not a directory
559pub const O_DIRECTORY = 0x00200000;
560
561/// set close on exec
562pub const O_CLOEXEC = 0x00400000;
563
564/// skip search permission checks
565pub const O_SEARCH = 0x00800000;
566
567pub const F_DUPFD = 0;
568pub const F_GETFD = 1;
569pub const F_SETFD = 2;
570pub const F_GETFL = 3;
571pub const F_SETFL = 4;
572
573pub const F_GETOWN = 5;
574pub const F_SETOWN = 6;
575
576pub const F_GETLK = 7;
577pub const F_SETLK = 8;
578pub const F_SETLKW = 9;
579
580pub const F_RDLCK = 1;
581pub const F_WRLCK = 3;
582pub const F_UNLCK = 2;
583
584pub const LOCK_SH = 1;
585pub const LOCK_EX = 2;
586pub const LOCK_UN = 8;
587pub const LOCK_NB = 4;
588
589pub const FD_CLOEXEC = 1;
590
591pub const SEEK_SET = 0;
592pub const SEEK_CUR = 1;
593pub const SEEK_END = 2;
594
595pub const SIG_BLOCK = 1;
596pub const SIG_UNBLOCK = 2;
597pub const SIG_SETMASK = 3;
598
599pub const DT_UNKNOWN = 0;
600pub const DT_FIFO = 1;
601pub const DT_CHR = 2;
602pub const DT_DIR = 4;
603pub const DT_BLK = 6;
604pub const DT_REG = 8;
605pub const DT_LNK = 10;
606pub const DT_SOCK = 12;
607pub const DT_WHT = 14;
608
609/// add event to kq (implies enable)
610pub const EV_ADD = 0x0001;
611
612/// delete event from kq
613pub const EV_DELETE = 0x0002;
614
615/// enable event
616pub const EV_ENABLE = 0x0004;
617
618/// disable event (not reported)
619pub const EV_DISABLE = 0x0008;
620
621/// only report one occurrence
622pub const EV_ONESHOT = 0x0010;
623
624/// clear event state after reporting
625pub const EV_CLEAR = 0x0020;
626
627/// force immediate event output
628/// ... with or without EV_ERROR
629/// ... use KEVENT_FLAG_ERROR_EVENTS
630/// on syscalls supporting flags
631pub const EV_RECEIPT = 0x0040;
632
633/// disable event after reporting
634pub const EV_DISPATCH = 0x0080;
635
636pub const EVFILT_READ = 0;
637pub const EVFILT_WRITE = 1;
638
639/// attached to aio requests
640pub const EVFILT_AIO = 2;
641
642/// attached to vnodes
643pub const EVFILT_VNODE = 3;
644
645/// attached to struct proc
646pub const EVFILT_PROC = 4;
647
648/// attached to struct proc
649pub const EVFILT_SIGNAL = 5;
650
651/// timers
652pub const EVFILT_TIMER = 6;
653
654/// Filesystem events
655pub const EVFILT_FS = 7;
656
657/// On input, NOTE_TRIGGER causes the event to be triggered for output.
658pub const NOTE_TRIGGER = 0x08000000;
659
660/// low water mark
661pub const NOTE_LOWAT = 0x00000001;
662
663/// vnode was removed
664pub const NOTE_DELETE = 0x00000001;
665
666/// data contents changed
667pub const NOTE_WRITE = 0x00000002;
668
669/// size increased
670pub const NOTE_EXTEND = 0x00000004;
671
672/// attributes changed
673pub const NOTE_ATTRIB = 0x00000008;
674
675/// link count changed
676pub const NOTE_LINK = 0x00000010;
677
678/// vnode was renamed
679pub const NOTE_RENAME = 0x00000020;
680
681/// vnode access was revoked
682pub const NOTE_REVOKE = 0x00000040;
683
684/// process exited
685pub const NOTE_EXIT = 0x80000000;
686
687/// process forked
688pub const NOTE_FORK = 0x40000000;
689
690/// process exec'd
691pub const NOTE_EXEC = 0x20000000;
692
693/// mask for signal & exit status
694pub const NOTE_PDATAMASK = 0x000fffff;
695pub const NOTE_PCTRLMASK = 0xf0000000;
696
697pub const TIOCCBRK = 0x2000747a;
698pub const TIOCCDTR = 0x20007478;
699pub const TIOCCONS = 0x80047462;
700pub const TIOCDCDTIMESTAMP = 0x40107458;
701pub const TIOCDRAIN = 0x2000745e;
702pub const TIOCEXCL = 0x2000740d;
703pub const TIOCEXT = 0x80047460;
704pub const TIOCFLAG_CDTRCTS = 0x10;
705pub const TIOCFLAG_CLOCAL = 0x2;
706pub const TIOCFLAG_CRTSCTS = 0x4;
707pub const TIOCFLAG_MDMBUF = 0x8;
708pub const TIOCFLAG_SOFTCAR = 0x1;
709pub const TIOCFLUSH = 0x80047410;
710pub const TIOCGETA = 0x402c7413;
711pub const TIOCGETD = 0x4004741a;
712pub const TIOCGFLAGS = 0x4004745d;
713pub const TIOCGLINED = 0x40207442;
714pub const TIOCGPGRP = 0x40047477;
715pub const TIOCGQSIZE = 0x40047481;
716pub const TIOCGRANTPT = 0x20007447;
717pub const TIOCGSID = 0x40047463;
718pub const TIOCGSIZE = 0x40087468;
719pub const TIOCGWINSZ = 0x40087468;
720pub const TIOCMBIC = 0x8004746b;
721pub const TIOCMBIS = 0x8004746c;
722pub const TIOCMGET = 0x4004746a;
723pub const TIOCMSET = 0x8004746d;
724pub const TIOCM_CAR = 0x40;
725pub const TIOCM_CD = 0x40;
726pub const TIOCM_CTS = 0x20;
727pub const TIOCM_DSR = 0x100;
728pub const TIOCM_DTR = 0x2;
729pub const TIOCM_LE = 0x1;
730pub const TIOCM_RI = 0x80;
731pub const TIOCM_RNG = 0x80;
732pub const TIOCM_RTS = 0x4;
733pub const TIOCM_SR = 0x10;
734pub const TIOCM_ST = 0x8;
735pub const TIOCNOTTY = 0x20007471;
736pub const TIOCNXCL = 0x2000740e;
737pub const TIOCOUTQ = 0x40047473;
738pub const TIOCPKT = 0x80047470;
739pub const TIOCPKT_DATA = 0x0;
740pub const TIOCPKT_DOSTOP = 0x20;
741pub const TIOCPKT_FLUSHREAD = 0x1;
742pub const TIOCPKT_FLUSHWRITE = 0x2;
743pub const TIOCPKT_IOCTL = 0x40;
744pub const TIOCPKT_NOSTOP = 0x10;
745pub const TIOCPKT_START = 0x8;
746pub const TIOCPKT_STOP = 0x4;
747pub const TIOCPTMGET = 0x40287446;
748pub const TIOCPTSNAME = 0x40287448;
749pub const TIOCRCVFRAME = 0x80087445;
750pub const TIOCREMOTE = 0x80047469;
751pub const TIOCSBRK = 0x2000747b;
752pub const TIOCSCTTY = 0x20007461;
753pub const TIOCSDTR = 0x20007479;
754pub const TIOCSETA = 0x802c7414;
755pub const TIOCSETAF = 0x802c7416;
756pub const TIOCSETAW = 0x802c7415;
757pub const TIOCSETD = 0x8004741b;
758pub const TIOCSFLAGS = 0x8004745c;
759pub const TIOCSIG = 0x2000745f;
760pub const TIOCSLINED = 0x80207443;
761pub const TIOCSPGRP = 0x80047476;
762pub const TIOCSQSIZE = 0x80047480;
763pub const TIOCSSIZE = 0x80087467;
764pub const TIOCSTART = 0x2000746e;
765pub const TIOCSTAT = 0x80047465;
766pub const TIOCSTI = 0x80017472;
767pub const TIOCSTOP = 0x2000746f;
768pub const TIOCSWINSZ = 0x80087467;
769pub const TIOCUCNTL = 0x80047466;
770pub const TIOCXMTFRAME = 0x80087444;
771
772pub fn WEXITSTATUS(s: u32) u8 {
773 return @intCast(u8, (s >> 8) & 0xff);
774}
775pub fn WTERMSIG(s: u32) u32 {
776 return s & 0x7f;
777}
778pub fn WSTOPSIG(s: u32) u32 {
779 return WEXITSTATUS(s);
780}
781pub fn WIFEXITED(s: u32) bool {
782 return WTERMSIG(s) == 0;
783}
784
785pub fn WIFCONTINUED(s: u32) bool {
786 return ((s & 0x7f) == 0xffff);
787}
788
789pub fn WIFSTOPPED(s: u32) bool {
790 return ((s & 0x7f != 0x7f) and !WIFCONTINUED(s));
791}
792
793pub fn WIFSIGNALED(s: u32) bool {
794 return !WIFSTOPPED(s) and !WIFCONTINUED(s) and !WIFEXITED(s);
795}
796
797pub const winsize = extern struct {
798 ws_row: u16,
799 ws_col: u16,
800 ws_xpixel: u16,
801 ws_ypixel: u16,
802};
803
804const NSIG = 32;
805
806pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
807pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
808pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
809
810/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
811pub const Sigaction = extern struct {
812 pub const handler_fn = fn (c_int) callconv(.C) void;
813 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
814
815 /// signal handler
816 handler: extern union {
817 handler: ?handler_fn,
818 sigaction: ?sigaction_fn,
819 },
820 /// signal mask to apply
821 mask: sigset_t,
822 /// signal options
823 flags: c_uint,
824};
825
826pub const sigval_t = extern union {
827 int: i32,
828 ptr: ?*c_void,
829};
830
831pub const siginfo_t = extern union {
832 pad: [128]u8,
833 info: _ksiginfo,
834};
835
836pub const _ksiginfo = extern struct {
837 signo: i32,
838 code: i32,
839 errno: i32,
840 // 64bit architectures insert 4bytes of padding here, this is done by
841 // correctly aligning the reason field
842 reason: extern union {
843 rt: extern struct {
844 pid: pid_t,
845 uid: uid_t,
846 value: sigval_t,
847 },
848 child: extern struct {
849 pid: pid_t,
850 uid: uid_t,
851 status: i32,
852 utime: clock_t,
853 stime: clock_t,
854 },
855 fault: extern struct {
856 addr: ?*c_void,
857 trap: i32,
858 trap2: i32,
859 trap3: i32,
860 },
861 poll: extern struct {
862 band: i32,
863 fd: i32,
864 },
865 syscall: extern struct {
866 sysnum: i32,
867 retval: [2]i32,
868 @"error": i32,
869 args: [8]u64,
870 },
871 ptrace_state: extern struct {
872 pe_report_event: i32,
873 option: extern union {
874 pe_other_pid: pid_t,
875 pe_lwp: lwpid_t,
876 },
877 },
878 } align(@sizeOf(usize)),
879};
880
881pub const _SIG_WORDS = 4;
882pub const _SIG_MAXSIG = 128;
883
884pub inline fn _SIG_IDX(sig: usize) usize {
885 return sig - 1;
886}
887pub inline fn _SIG_WORD(sig: usize) usize {
888 return_SIG_IDX(sig) >> 5;
889}
890pub inline fn _SIG_BIT(sig: usize) usize {
891 return 1 << (_SIG_IDX(sig) & 31);
892}
893pub inline fn _SIG_VALID(sig: usize) usize {
894 return sig <= _SIG_MAXSIG and sig > 0;
895}
896
897pub const sigset_t = extern struct {
898 __bits: [_SIG_WORDS]u32,
899};
900
901pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** _SIG_WORDS };
902
903// XXX x86_64 specific
904pub const mcontext_t = extern struct {
905 gregs: [26]u64,
906 mc_tlsbase: u64,
907 fpregs: [512]u8 align(8),
908};
909
910pub const REG_RBP = 12;
911pub const REG_RIP = 21;
912pub const REG_RSP = 24;
913
914pub const ucontext_t = extern struct {
915 flags: u32,
916 link: ?*ucontext_t,
917 sigmask: sigset_t,
918 stack: stack_t,
919 mcontext: mcontext_t,
920 __pad: [
921 switch (builtin.cpu.arch) {
922 .i386 => 4,
923 .mips, .mipsel, .mips64, .mips64el => 14,
924 .arm, .armeb, .thumb, .thumbeb => 1,
925 .sparc, .sparcel, .sparcv9 => if (@sizeOf(usize) == 4) 43 else 8,
926 else => 0,
927 }
928 ]u32,
929};
930
931pub const E = enum(u16) {
932 /// No error occurred.
933 SUCCESS = 0,
934 PERM = 1, // Operation not permitted
935 NOENT = 2, // No such file or directory
936 SRCH = 3, // No such process
937 INTR = 4, // Interrupted system call
938 IO = 5, // Input/output error
939 NXIO = 6, // Device not configured
940 @"2BIG" = 7, // Argument list too long
941 NOEXEC = 8, // Exec format error
942 BADF = 9, // Bad file descriptor
943 CHILD = 10, // No child processes
944 DEADLK = 11, // Resource deadlock avoided
945 // 11 was AGAIN
946 NOMEM = 12, // Cannot allocate memory
947 ACCES = 13, // Permission denied
948 FAULT = 14, // Bad address
949 NOTBLK = 15, // Block device required
950 BUSY = 16, // Device busy
951 EXIST = 17, // File exists
952 XDEV = 18, // Cross-device link
953 NODEV = 19, // Operation not supported by device
954 NOTDIR = 20, // Not a directory
955 ISDIR = 21, // Is a directory
956 INVAL = 22, // Invalid argument
957 NFILE = 23, // Too many open files in system
958 MFILE = 24, // Too many open files
959 NOTTY = 25, // Inappropriate ioctl for device
960 TXTBSY = 26, // Text file busy
961 FBIG = 27, // File too large
962 NOSPC = 28, // No space left on device
963 SPIPE = 29, // Illegal seek
964 ROFS = 30, // Read-only file system
965 MLINK = 31, // Too many links
966 PIPE = 32, // Broken pipe
967
968 // math software
969 DOM = 33, // Numerical argument out of domain
970 RANGE = 34, // Result too large or too small
971
972 // non-blocking and interrupt i/o
973 // also: WOULDBLOCK: operation would block
974 AGAIN = 35, // Resource temporarily unavailable
975 INPROGRESS = 36, // Operation now in progress
976 ALREADY = 37, // Operation already in progress
977
978 // ipc/network software -- argument errors
979 NOTSOCK = 38, // Socket operation on non-socket
980 DESTADDRREQ = 39, // Destination address required
981 MSGSIZE = 40, // Message too long
982 PROTOTYPE = 41, // Protocol wrong type for socket
983 NOPROTOOPT = 42, // Protocol option not available
984 PROTONOSUPPORT = 43, // Protocol not supported
985 SOCKTNOSUPPORT = 44, // Socket type not supported
986 OPNOTSUPP = 45, // Operation not supported
987 PFNOSUPPORT = 46, // Protocol family not supported
988 AFNOSUPPORT = 47, // Address family not supported by protocol family
989 ADDRINUSE = 48, // Address already in use
990 ADDRNOTAVAIL = 49, // Can't assign requested address
991
992 // ipc/network software -- operational errors
993 NETDOWN = 50, // Network is down
994 NETUNREACH = 51, // Network is unreachable
995 NETRESET = 52, // Network dropped connection on reset
996 CONNABORTED = 53, // Software caused connection abort
997 CONNRESET = 54, // Connection reset by peer
998 NOBUFS = 55, // No buffer space available
999 ISCONN = 56, // Socket is already connected
1000 NOTCONN = 57, // Socket is not connected
1001 SHUTDOWN = 58, // Can't send after socket shutdown
1002 TOOMANYREFS = 59, // Too many references: can't splice
1003 TIMEDOUT = 60, // Operation timed out
1004 CONNREFUSED = 61, // Connection refused
1005
1006 LOOP = 62, // Too many levels of symbolic links
1007 NAMETOOLONG = 63, // File name too long
1008
1009 // should be rearranged
1010 HOSTDOWN = 64, // Host is down
1011 HOSTUNREACH = 65, // No route to host
1012 NOTEMPTY = 66, // Directory not empty
1013
1014 // quotas & mush
1015 PROCLIM = 67, // Too many processes
1016 USERS = 68, // Too many users
1017 DQUOT = 69, // Disc quota exceeded
1018
1019 // Network File System
1020 STALE = 70, // Stale NFS file handle
1021 REMOTE = 71, // Too many levels of remote in path
1022 BADRPC = 72, // RPC struct is bad
1023 RPCMISMATCH = 73, // RPC version wrong
1024 PROGUNAVAIL = 74, // RPC prog. not avail
1025 PROGMISMATCH = 75, // Program version wrong
1026 PROCUNAVAIL = 76, // Bad procedure for program
1027
1028 NOLCK = 77, // No locks available
1029 NOSYS = 78, // Function not implemented
1030
1031 FTYPE = 79, // Inappropriate file type or format
1032 AUTH = 80, // Authentication error
1033 NEEDAUTH = 81, // Need authenticator
1034
1035 // SystemV IPC
1036 IDRM = 82, // Identifier removed
1037 NOMSG = 83, // No message of desired type
1038 OVERFLOW = 84, // Value too large to be stored in data type
1039
1040 // Wide/multibyte-character handling, ISO/IEC 9899/AMD1:1995
1041 ILSEQ = 85, // Illegal byte sequence
1042
1043 // From IEEE Std 1003.1-2001
1044 // Base, Realtime, Threads or Thread Priority Scheduling option errors
1045 NOTSUP = 86, // Not supported
1046
1047 // Realtime option errors
1048 CANCELED = 87, // Operation canceled
1049
1050 // Realtime, XSI STREAMS option errors
1051 BADMSG = 88, // Bad or Corrupt message
1052
1053 // XSI STREAMS option errors
1054 NODATA = 89, // No message available
1055 NOSR = 90, // No STREAM resources
1056 NOSTR = 91, // Not a STREAM
1057 TIME = 92, // STREAM ioctl timeout
1058
1059 // File system extended attribute errors
1060 NOATTR = 93, // Attribute not found
1061
1062 // Realtime, XSI STREAMS option errors
1063 MULTIHOP = 94, // Multihop attempted
1064 NOLINK = 95, // Link has been severed
1065 PROTO = 96, // Protocol error
1066
1067 _,
1068};
1069
1070pub const MINSIGSTKSZ = 8192;
1071pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
1072
1073pub const SS_ONSTACK = 1;
1074pub const SS_DISABLE = 4;
1075
1076pub const stack_t = extern struct {
1077 ss_sp: [*]u8,
1078 ss_size: isize,
1079 ss_flags: i32,
1080};
1081
1082pub const S_IFMT = 0o170000;
1083
1084pub const S_IFIFO = 0o010000;
1085pub const S_IFCHR = 0o020000;
1086pub const S_IFDIR = 0o040000;
1087pub const S_IFBLK = 0o060000;
1088pub const S_IFREG = 0o100000;
1089pub const S_IFLNK = 0o120000;
1090pub const S_IFSOCK = 0o140000;
1091pub const S_IFWHT = 0o160000;
1092
1093pub const S_ISUID = 0o4000;
1094pub const S_ISGID = 0o2000;
1095pub const S_ISVTX = 0o1000;
1096pub const S_IRWXU = 0o700;
1097pub const S_IRUSR = 0o400;
1098pub const S_IWUSR = 0o200;
1099pub const S_IXUSR = 0o100;
1100pub const S_IRWXG = 0o070;
1101pub const S_IRGRP = 0o040;
1102pub const S_IWGRP = 0o020;
1103pub const S_IXGRP = 0o010;
1104pub const S_IRWXO = 0o007;
1105pub const S_IROTH = 0o004;
1106pub const S_IWOTH = 0o002;
1107pub const S_IXOTH = 0o001;
1108
1109pub fn S_ISFIFO(m: u32) bool {
1110 return m & S_IFMT == S_IFIFO;
1111}
1112
1113pub fn S_ISCHR(m: u32) bool {
1114 return m & S_IFMT == S_IFCHR;
1115}
1116
1117pub fn S_ISDIR(m: u32) bool {
1118 return m & S_IFMT == S_IFDIR;
1119}
1120
1121pub fn S_ISBLK(m: u32) bool {
1122 return m & S_IFMT == S_IFBLK;
1123}
1124
1125pub fn S_ISREG(m: u32) bool {
1126 return m & S_IFMT == S_IFREG;
1127}
1128
1129pub fn S_ISLNK(m: u32) bool {
1130 return m & S_IFMT == S_IFLNK;
1131}
1132
1133pub fn S_ISSOCK(m: u32) bool {
1134 return m & S_IFMT == S_IFSOCK;
1135}
1136
1137pub fn S_IWHT(m: u32) bool {
1138 return m & S_IFMT == S_IFWHT;
1139}
1140
1141/// Magic value that specify the use of the current working directory
1142/// to determine the target of relative file paths in the openat() and
1143/// similar syscalls.
1144pub const AT_FDCWD = -100;
1145
1146/// Check access using effective user and group ID
1147pub const AT_EACCESS = 0x0100;
1148
1149/// Do not follow symbolic links
1150pub const AT_SYMLINK_NOFOLLOW = 0x0200;
1151
1152/// Follow symbolic link
1153pub const AT_SYMLINK_FOLLOW = 0x0400;
1154
1155/// Remove directory instead of file
1156pub const AT_REMOVEDIR = 0x0800;
1157
1158pub const HOST_NAME_MAX = 255;
1159
1160/// dummy for IP
1161pub const IPPROTO_IP = 0;
1162
1163/// IP6 hop-by-hop options
1164pub const IPPROTO_HOPOPTS = 0;
1165
1166/// control message protocol
1167pub const IPPROTO_ICMP = 1;
1168
1169/// group mgmt protocol
1170pub const IPPROTO_IGMP = 2;
1171
1172/// gateway^2 (deprecated)
1173pub const IPPROTO_GGP = 3;
1174
1175/// IP header
1176pub const IPPROTO_IPV4 = 4;
1177
1178/// IP inside IP
1179pub const IPPROTO_IPIP = 4;
1180
1181/// tcp
1182pub const IPPROTO_TCP = 6;
1183
1184/// exterior gateway protocol
1185pub const IPPROTO_EGP = 8;
1186
1187/// pup
1188pub const IPPROTO_PUP = 12;
1189
1190/// user datagram protocol
1191pub const IPPROTO_UDP = 17;
1192
1193/// xns idp
1194pub const IPPROTO_IDP = 22;
1195
1196/// tp-4 w/ class negotiation
1197pub const IPPROTO_TP = 29;
1198
1199/// DCCP
1200pub const IPPROTO_DCCP = 33;
1201
1202/// IP6 header
1203pub const IPPROTO_IPV6 = 41;
1204
1205/// IP6 routing header
1206pub const IPPROTO_ROUTING = 43;
1207
1208/// IP6 fragmentation header
1209pub const IPPROTO_FRAGMENT = 44;
1210
1211/// resource reservation
1212pub const IPPROTO_RSVP = 46;
1213
1214/// GRE encaps RFC 1701
1215pub const IPPROTO_GRE = 47;
1216
1217/// encap. security payload
1218pub const IPPROTO_ESP = 50;
1219
1220/// authentication header
1221pub const IPPROTO_AH = 51;
1222
1223/// IP Mobility RFC 2004
1224pub const IPPROTO_MOBILE = 55;
1225
1226/// IPv6 ICMP
1227pub const IPPROTO_IPV6_ICMP = 58;
1228
1229/// ICMP6
1230pub const IPPROTO_ICMPV6 = 58;
1231
1232/// IP6 no next header
1233pub const IPPROTO_NONE = 59;
1234
1235/// IP6 destination option
1236pub const IPPROTO_DSTOPTS = 60;
1237
1238/// ISO cnlp
1239pub const IPPROTO_EON = 80;
1240
1241/// Ethernet-in-IP
1242pub const IPPROTO_ETHERIP = 97;
1243
1244/// encapsulation header
1245pub const IPPROTO_ENCAP = 98;
1246
1247/// Protocol indep. multicast
1248pub const IPPROTO_PIM = 103;
1249
1250/// IP Payload Comp. Protocol
1251pub const IPPROTO_IPCOMP = 108;
1252
1253/// VRRP RFC 2338
1254pub const IPPROTO_VRRP = 112;
1255
1256/// Common Address Resolution Protocol
1257pub const IPPROTO_CARP = 112;
1258
1259/// L2TPv3
1260pub const IPPROTO_L2TP = 115;
1261
1262/// SCTP
1263pub const IPPROTO_SCTP = 132;
1264
1265/// PFSYNC
1266pub const IPPROTO_PFSYNC = 240;
1267
1268/// raw IP packet
1269pub const IPPROTO_RAW = 255;
1270
1271pub const rlimit_resource = enum(c_int) {
1272 CPU = 0,
1273 FSIZE = 1,
1274 DATA = 2,
1275 STACK = 3,
1276 CORE = 4,
1277 RSS = 5,
1278 MEMLOCK = 6,
1279 NPROC = 7,
1280 NOFILE = 8,
1281 SBSIZE = 9,
1282 VMEM = 10,
1283 NTHR = 11,
1284 _,
1285
1286 pub const AS: rlimit_resource = .VMEM;
1287};
1288
1289pub const rlim_t = u64;
1290
1291/// No limit
1292pub const RLIM_INFINITY: rlim_t = (1 << 63) - 1;
1293
1294pub const RLIM_SAVED_MAX = RLIM_INFINITY;
1295pub const RLIM_SAVED_CUR = RLIM_INFINITY;
1296
1297pub const rlimit = extern struct {
1298 /// Soft limit
1299 cur: rlim_t,
1300 /// Hard limit
1301 max: rlim_t,
1302};
1303
1304pub const SHUT_RD = 0;
1305pub const SHUT_WR = 1;
1306pub const SHUT_RDWR = 2;
1307
1308pub const nfds_t = u32;
1309
1310pub const pollfd = extern struct {
1311 fd: fd_t,
1312 events: i16,
1313 revents: i16,
1314};
1315
1316/// Testable events (may be specified in events field).
1317pub const POLLIN = 0x0001;
1318pub const POLLPRI = 0x0002;
1319pub const POLLOUT = 0x0004;
1320pub const POLLRDNORM = 0x0040;
1321pub const POLLWRNORM = POLLOUT;
1322pub const POLLRDBAND = 0x0080;
1323pub const POLLWRBAND = 0x0100;
1324
1325/// Non-testable events (may not be specified in events field).
1326pub const POLLERR = 0x0008;
1327pub const POLLHUP = 0x0010;
1328pub const POLLNVAL = 0x0020;
lib/std/os/bits/openbsd.zig deleted-1330
...@@ -1,1330 +0,0 @@
1const std = @import("../../std.zig");
2const builtin = std.builtin;
3const maxInt = std.math.maxInt;
4
5pub usingnamespace @import("posix.zig");
6
7pub const blkcnt_t = i64;
8pub const blksize_t = i32;
9pub const clock_t = i64;
10pub const dev_t = i32;
11pub const fd_t = c_int;
12pub const gid_t = u32;
13pub const ino_t = u64;
14pub const mode_t = u32;
15pub const nlink_t = u32;
16pub const off_t = i64;
17pub const pid_t = i32;
18pub const socklen_t = u32;
19pub const time_t = i64;
20pub const uid_t = u32;
21
22/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
23pub const Kevent = extern struct {
24 ident: usize,
25 filter: c_short,
26 flags: u16,
27 fflags: c_uint,
28 data: i64,
29 udata: usize,
30};
31
32// Modes and flags for dlopen()
33// include/dlfcn.h
34
35/// Bind function calls lazily.
36pub const RTLD_LAZY = 1;
37
38/// Bind function calls immediately.
39pub const RTLD_NOW = 2;
40
41/// Make symbols globally available.
42pub const RTLD_GLOBAL = 0x100;
43
44/// Opposite of RTLD_GLOBAL, and the default.
45pub const RTLD_LOCAL = 0x000;
46
47/// Trace loaded objects and exit.
48pub const RTLD_TRACE = 0x200;
49
50pub const dl_phdr_info = extern struct {
51 dlpi_addr: std.elf.Addr,
52 dlpi_name: ?[*:0]const u8,
53 dlpi_phdr: [*]std.elf.Phdr,
54 dlpi_phnum: std.elf.Half,
55};
56
57pub const Flock = extern struct {
58 l_start: off_t,
59 l_len: off_t,
60 l_pid: pid_t,
61 l_type: c_short,
62 l_whence: c_short,
63};
64
65pub const addrinfo = extern struct {
66 flags: c_int,
67 family: c_int,
68 socktype: c_int,
69 protocol: c_int,
70 addrlen: socklen_t,
71 addr: ?*sockaddr,
72 canonname: ?[*:0]u8,
73 next: ?*addrinfo,
74};
75
76pub const EAI = enum(c_int) {
77 /// address family for hostname not supported
78 ADDRFAMILY = -9,
79
80 /// name could not be resolved at this time
81 AGAIN = -3,
82
83 /// flags parameter had an invalid value
84 BADFLAGS = -1,
85
86 /// non-recoverable failure in name resolution
87 FAIL = -4,
88
89 /// address family not recognized
90 FAMILY = -6,
91
92 /// memory allocation failure
93 MEMORY = -10,
94
95 /// no address associated with hostname
96 NODATA = -5,
97
98 /// name does not resolve
99 NONAME = -2,
100
101 /// service not recognized for socket type
102 SERVICE = -8,
103
104 /// intended socket type was not recognized
105 SOCKTYPE = -7,
106
107 /// system error returned in errno
108 SYSTEM = -11,
109
110 /// invalid value for hints
111 BADHINTS = -12,
112
113 /// resolved protocol is unknown
114 PROTOCOL = -13,
115
116 /// argument buffer overflow
117 OVERFLOW = -14,
118
119 _,
120};
121
122pub const EAI_MAX = 15;
123
124pub const msghdr = extern struct {
125 /// optional address
126 msg_name: ?*sockaddr,
127
128 /// size of address
129 msg_namelen: socklen_t,
130
131 /// scatter/gather array
132 msg_iov: [*]iovec,
133
134 /// # elements in msg_iov
135 msg_iovlen: c_uint,
136
137 /// ancillary data
138 msg_control: ?*c_void,
139
140 /// ancillary data buffer len
141 msg_controllen: socklen_t,
142
143 /// flags on received message
144 msg_flags: c_int,
145};
146
147pub const msghdr_const = extern struct {
148 /// optional address
149 msg_name: ?*const sockaddr,
150
151 /// size of address
152 msg_namelen: socklen_t,
153
154 /// scatter/gather array
155 msg_iov: [*]iovec_const,
156
157 /// # elements in msg_iov
158 msg_iovlen: c_uint,
159
160 /// ancillary data
161 msg_control: ?*c_void,
162
163 /// ancillary data buffer len
164 msg_controllen: socklen_t,
165
166 /// flags on received message
167 msg_flags: c_int,
168};
169
170pub const libc_stat = extern struct {
171 mode: mode_t,
172 dev: dev_t,
173 ino: ino_t,
174 nlink: nlink_t,
175 uid: uid_t,
176 gid: gid_t,
177 rdev: dev_t,
178 atim: timespec,
179 mtim: timespec,
180 ctim: timespec,
181 size: off_t,
182 blocks: blkcnt_t,
183 blksize: blksize_t,
184 flags: u32,
185 gen: u32,
186 birthtim: timespec,
187
188 pub fn atime(self: @This()) timespec {
189 return self.atim;
190 }
191
192 pub fn mtime(self: @This()) timespec {
193 return self.mtim;
194 }
195
196 pub fn ctime(self: @This()) timespec {
197 return self.ctim;
198 }
199};
200
201pub const timespec = extern struct {
202 tv_sec: time_t,
203 tv_nsec: c_long,
204};
205
206pub const timeval = extern struct {
207 tv_sec: time_t,
208 tv_usec: c_long,
209};
210
211pub const timezone = extern struct {
212 tz_minuteswest: c_int,
213 tz_dsttime: c_int,
214};
215
216pub const MAXNAMLEN = 255;
217
218pub const dirent = extern struct {
219 d_fileno: ino_t,
220 d_off: off_t,
221 d_reclen: u16,
222 d_type: u8,
223 d_namlen: u8,
224 __d_padding: [4]u8,
225 d_name: [MAXNAMLEN + 1]u8,
226
227 pub fn reclen(self: dirent) u16 {
228 return self.d_reclen;
229 }
230};
231
232pub const in_port_t = u16;
233pub const sa_family_t = u8;
234
235pub const sockaddr = extern struct {
236 /// total length
237 len: u8,
238
239 /// address family
240 family: sa_family_t,
241
242 /// actually longer; address value
243 data: [14]u8,
244};
245
246pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
247
248pub const sockaddr_in = extern struct {
249 len: u8 = @sizeOf(sockaddr_in),
250 family: sa_family_t = AF_INET,
251 port: in_port_t,
252 addr: u32,
253 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
254};
255
256pub const sockaddr_in6 = extern struct {
257 len: u8 = @sizeOf(sockaddr_in6),
258 family: sa_family_t = AF_INET6,
259 port: in_port_t,
260 flowinfo: u32,
261 addr: [16]u8,
262 scope_id: u32,
263};
264
265/// Definitions for UNIX IPC domain.
266pub const sockaddr_un = extern struct {
267 /// total sockaddr length
268 len: u8 = @sizeOf(sockaddr_un),
269
270 /// AF_LOCAL
271 family: sa_family_t = AF_LOCAL,
272
273 /// path name
274 path: [104]u8,
275};
276
277/// get address to use bind()
278pub const AI_PASSIVE = 1;
279
280/// fill ai_canonname
281pub const AI_CANONNAME = 2;
282
283/// prevent host name resolution
284pub const AI_NUMERICHOST = 4;
285
286/// prevent service name resolution
287pub const AI_NUMERICSERV = 16;
288
289/// only if any address is assigned
290pub const AI_ADDRCONFIG = 64;
291
292pub const PATH_MAX = 1024;
293pub const IOV_MAX = 1024;
294
295pub const STDIN_FILENO = 0;
296pub const STDOUT_FILENO = 1;
297pub const STDERR_FILENO = 2;
298
299pub const PROT_NONE = 0;
300pub const PROT_READ = 1;
301pub const PROT_WRITE = 2;
302pub const PROT_EXEC = 4;
303
304pub const CLOCK_REALTIME = 0;
305pub const CLOCK_PROCESS_CPUTIME_ID = 2;
306pub const CLOCK_MONOTONIC = 3;
307pub const CLOCK_THREAD_CPUTIME_ID = 4;
308
309pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
310pub const MAP_SHARED = 0x0001;
311pub const MAP_PRIVATE = 0x0002;
312pub const MAP_FIXED = 0x0010;
313pub const MAP_RENAME = 0;
314pub const MAP_NORESERVE = 0;
315pub const MAP_INHERIT = 0;
316pub const MAP_HASSEMAPHORE = 0;
317pub const MAP_TRYFIXED = 0;
318
319pub const MAP_FILE = 0;
320pub const MAP_ANON = 0x1000;
321pub const MAP_ANONYMOUS = MAP_ANON;
322pub const MAP_STACK = 0x4000;
323pub const MAP_CONCEAL = 0x8000;
324
325pub const WNOHANG = 1;
326pub const WUNTRACED = 2;
327pub const WCONTINUED = 8;
328
329pub const SA_ONSTACK = 0x0001;
330pub const SA_RESTART = 0x0002;
331pub const SA_RESETHAND = 0x0004;
332pub const SA_NOCLDSTOP = 0x0008;
333pub const SA_NODEFER = 0x0010;
334pub const SA_NOCLDWAIT = 0x0020;
335pub const SA_SIGINFO = 0x0040;
336
337pub const SIGHUP = 1;
338pub const SIGINT = 2;
339pub const SIGQUIT = 3;
340pub const SIGILL = 4;
341pub const SIGTRAP = 5;
342pub const SIGABRT = 6;
343pub const SIGIOT = SIGABRT;
344pub const SIGEMT = 7;
345pub const SIGFPE = 8;
346pub const SIGKILL = 9;
347pub const SIGBUS = 10;
348pub const SIGSEGV = 11;
349pub const SIGSYS = 12;
350pub const SIGPIPE = 13;
351pub const SIGALRM = 14;
352pub const SIGTERM = 15;
353pub const SIGURG = 16;
354pub const SIGSTOP = 17;
355pub const SIGTSTP = 18;
356pub const SIGCONT = 19;
357pub const SIGCHLD = 20;
358pub const SIGTTIN = 21;
359pub const SIGTTOU = 22;
360pub const SIGIO = 23;
361pub const SIGXCPU = 24;
362pub const SIGXFSZ = 25;
363pub const SIGVTALRM = 26;
364pub const SIGPROF = 27;
365pub const SIGWINCH = 28;
366pub const SIGINFO = 29;
367pub const SIGUSR1 = 30;
368pub const SIGUSR2 = 31;
369pub const SIGPWR = 32;
370
371// access function
372pub const F_OK = 0; // test for existence of file
373pub const X_OK = 1; // test for execute or search permission
374pub const W_OK = 2; // test for write permission
375pub const R_OK = 4; // test for read permission
376
377/// open for reading only
378pub const O_RDONLY = 0x00000000;
379
380/// open for writing only
381pub const O_WRONLY = 0x00000001;
382
383/// open for reading and writing
384pub const O_RDWR = 0x00000002;
385
386/// mask for above modes
387pub const O_ACCMODE = 0x00000003;
388
389/// no delay
390pub const O_NONBLOCK = 0x00000004;
391
392/// set append mode
393pub const O_APPEND = 0x00000008;
394
395/// open with shared file lock
396pub const O_SHLOCK = 0x00000010;
397
398/// open with exclusive file lock
399pub const O_EXLOCK = 0x00000020;
400
401/// signal pgrp when data ready
402pub const O_ASYNC = 0x00000040;
403
404/// synchronous writes
405pub const O_SYNC = 0x00000080;
406
407/// don't follow symlinks on the last
408pub const O_NOFOLLOW = 0x00000100;
409
410/// create if nonexistent
411pub const O_CREAT = 0x00000200;
412
413/// truncate to zero length
414pub const O_TRUNC = 0x00000400;
415
416/// error if already exists
417pub const O_EXCL = 0x00000800;
418
419/// don't assign controlling terminal
420pub const O_NOCTTY = 0x00008000;
421
422/// write: I/O data completion
423pub const O_DSYNC = O_SYNC;
424
425/// read: I/O completion as for write
426pub const O_RSYNC = O_SYNC;
427
428/// fail if not a directory
429pub const O_DIRECTORY = 0x20000;
430
431/// set close on exec
432pub const O_CLOEXEC = 0x10000;
433
434pub const F_DUPFD = 0;
435pub const F_GETFD = 1;
436pub const F_SETFD = 2;
437pub const F_GETFL = 3;
438pub const F_SETFL = 4;
439
440pub const F_GETOWN = 5;
441pub const F_SETOWN = 6;
442
443pub const F_GETLK = 7;
444pub const F_SETLK = 8;
445pub const F_SETLKW = 9;
446
447pub const F_RDLCK = 1;
448pub const F_UNLCK = 2;
449pub const F_WRLCK = 3;
450
451pub const LOCK_SH = 0x01;
452pub const LOCK_EX = 0x02;
453pub const LOCK_NB = 0x04;
454pub const LOCK_UN = 0x08;
455
456pub const FD_CLOEXEC = 1;
457
458pub const SEEK_SET = 0;
459pub const SEEK_CUR = 1;
460pub const SEEK_END = 2;
461
462pub const SIG_BLOCK = 1;
463pub const SIG_UNBLOCK = 2;
464pub const SIG_SETMASK = 3;
465
466pub const SOCK_STREAM = 1;
467pub const SOCK_DGRAM = 2;
468pub const SOCK_RAW = 3;
469pub const SOCK_RDM = 4;
470pub const SOCK_SEQPACKET = 5;
471
472pub const SOCK_CLOEXEC = 0x8000;
473pub const SOCK_NONBLOCK = 0x4000;
474
475pub const SO_DEBUG = 0x0001;
476pub const SO_ACCEPTCONN = 0x0002;
477pub const SO_REUSEADDR = 0x0004;
478pub const SO_KEEPALIVE = 0x0008;
479pub const SO_DONTROUTE = 0x0010;
480pub const SO_BROADCAST = 0x0020;
481pub const SO_USELOOPBACK = 0x0040;
482pub const SO_LINGER = 0x0080;
483pub const SO_OOBINLINE = 0x0100;
484pub const SO_REUSEPORT = 0x0200;
485pub const SO_TIMESTAMP = 0x0800;
486pub const SO_BINDANY = 0x1000;
487pub const SO_ZEROIZE = 0x2000;
488pub const SO_SNDBUF = 0x1001;
489pub const SO_RCVBUF = 0x1002;
490pub const SO_SNDLOWAT = 0x1003;
491pub const SO_RCVLOWAT = 0x1004;
492pub const SO_SNDTIMEO = 0x1005;
493pub const SO_RCVTIMEO = 0x1006;
494pub const SO_ERROR = 0x1007;
495pub const SO_TYPE = 0x1008;
496pub const SO_NETPROC = 0x1020;
497pub const SO_RTABLE = 0x1021;
498pub const SO_PEERCRED = 0x1022;
499pub const SO_SPLICE = 0x1023;
500pub const SO_DOMAIN = 0x1024;
501pub const SO_PROTOCOL = 0x1025;
502
503pub const SOL_SOCKET = 0xffff;
504
505pub const PF_UNSPEC = AF_UNSPEC;
506pub const PF_LOCAL = AF_LOCAL;
507pub const PF_UNIX = AF_UNIX;
508pub const PF_INET = AF_INET;
509pub const PF_APPLETALK = AF_APPLETALK;
510pub const PF_INET6 = AF_INET6;
511pub const PF_DECnet = AF_DECnet;
512pub const PF_KEY = AF_KEY;
513pub const PF_ROUTE = AF_ROUTE;
514pub const PF_SNA = AF_SNA;
515pub const PF_MPLS = AF_MPLS;
516pub const PF_BLUETOOTH = AF_BLUETOOTH;
517pub const PF_ISDN = AF_ISDN;
518pub const PF_MAX = AF_MAX;
519
520pub const AF_UNSPEC = 0;
521pub const AF_UNIX = 1;
522pub const AF_LOCAL = AF_UNIX;
523pub const AF_INET = 2;
524pub const AF_APPLETALK = 16;
525pub const AF_INET6 = 24;
526pub const AF_KEY = 30;
527pub const AF_ROUTE = 17;
528pub const AF_SNA = 11;
529pub const AF_MPLS = 33;
530pub const AF_BLUETOOTH = 32;
531pub const AF_ISDN = 26;
532pub const AF_MAX = 36;
533
534pub const DT_UNKNOWN = 0;
535pub const DT_FIFO = 1;
536pub const DT_CHR = 2;
537pub const DT_DIR = 4;
538pub const DT_BLK = 6;
539pub const DT_REG = 8;
540pub const DT_LNK = 10;
541pub const DT_SOCK = 12;
542pub const DT_WHT = 14; // XXX
543
544pub const EV_ADD = 0x0001;
545pub const EV_DELETE = 0x0002;
546pub const EV_ENABLE = 0x0004;
547pub const EV_DISABLE = 0x0008;
548pub const EV_ONESHOT = 0x0010;
549pub const EV_CLEAR = 0x0020;
550pub const EV_RECEIPT = 0x0040;
551pub const EV_DISPATCH = 0x0080;
552pub const EV_FLAG1 = 0x2000;
553pub const EV_ERROR = 0x4000;
554pub const EV_EOF = 0x8000;
555
556pub const EVFILT_READ = -1;
557pub const EVFILT_WRITE = -2;
558pub const EVFILT_AIO = -3;
559pub const EVFILT_VNODE = -4;
560pub const EVFILT_PROC = -5;
561pub const EVFILT_SIGNAL = -6;
562pub const EVFILT_TIMER = -7;
563pub const EVFILT_EXCEPT = -9;
564
565// data/hint flags for EVFILT_{READ|WRITE}
566pub const NOTE_LOWAT = 0x0001;
567pub const NOTE_EOF = 0x0002;
568
569// data/hint flags for EVFILT_EXCEPT and EVFILT_{READ|WRITE}
570pub const NOTE_OOB = 0x0004;
571
572// data/hint flags for EVFILT_VNODE
573pub const NOTE_DELETE = 0x0001;
574pub const NOTE_WRITE = 0x0002;
575pub const NOTE_EXTEND = 0x0004;
576pub const NOTE_ATTRIB = 0x0008;
577pub const NOTE_LINK = 0x0010;
578pub const NOTE_RENAME = 0x0020;
579pub const NOTE_REVOKE = 0x0040;
580pub const NOTE_TRUNCATE = 0x0080;
581
582// data/hint flags for EVFILT_PROC
583pub const NOTE_EXIT = 0x80000000;
584pub const NOTE_FORK = 0x40000000;
585pub const NOTE_EXEC = 0x20000000;
586pub const NOTE_PDATAMASK = 0x000fffff;
587pub const NOTE_PCTRLMASK = 0xf0000000;
588pub const NOTE_TRACK = 0x00000001;
589pub const NOTE_TRACKERR = 0x00000002;
590pub const NOTE_CHILD = 0x00000004;
591
592// data/hint flags for EVFILT_DEVICE
593pub const NOTE_CHANGE = 0x00000001;
594
595pub const TIOCCBRK = 0x2000747a;
596pub const TIOCCDTR = 0x20007478;
597pub const TIOCCONS = 0x80047462;
598pub const TIOCDCDTIMESTAMP = 0x40107458;
599pub const TIOCDRAIN = 0x2000745e;
600pub const TIOCEXCL = 0x2000740d;
601pub const TIOCEXT = 0x80047460;
602pub const TIOCFLAG_CDTRCTS = 0x10;
603pub const TIOCFLAG_CLOCAL = 0x2;
604pub const TIOCFLAG_CRTSCTS = 0x4;
605pub const TIOCFLAG_MDMBUF = 0x8;
606pub const TIOCFLAG_SOFTCAR = 0x1;
607pub const TIOCFLUSH = 0x80047410;
608pub const TIOCGETA = 0x402c7413;
609pub const TIOCGETD = 0x4004741a;
610pub const TIOCGFLAGS = 0x4004745d;
611pub const TIOCGLINED = 0x40207442;
612pub const TIOCGPGRP = 0x40047477;
613pub const TIOCGQSIZE = 0x40047481;
614pub const TIOCGRANTPT = 0x20007447;
615pub const TIOCGSID = 0x40047463;
616pub const TIOCGSIZE = 0x40087468;
617pub const TIOCGWINSZ = 0x40087468;
618pub const TIOCMBIC = 0x8004746b;
619pub const TIOCMBIS = 0x8004746c;
620pub const TIOCMGET = 0x4004746a;
621pub const TIOCMSET = 0x8004746d;
622pub const TIOCM_CAR = 0x40;
623pub const TIOCM_CD = 0x40;
624pub const TIOCM_CTS = 0x20;
625pub const TIOCM_DSR = 0x100;
626pub const TIOCM_DTR = 0x2;
627pub const TIOCM_LE = 0x1;
628pub const TIOCM_RI = 0x80;
629pub const TIOCM_RNG = 0x80;
630pub const TIOCM_RTS = 0x4;
631pub const TIOCM_SR = 0x10;
632pub const TIOCM_ST = 0x8;
633pub const TIOCNOTTY = 0x20007471;
634pub const TIOCNXCL = 0x2000740e;
635pub const TIOCOUTQ = 0x40047473;
636pub const TIOCPKT = 0x80047470;
637pub const TIOCPKT_DATA = 0x0;
638pub const TIOCPKT_DOSTOP = 0x20;
639pub const TIOCPKT_FLUSHREAD = 0x1;
640pub const TIOCPKT_FLUSHWRITE = 0x2;
641pub const TIOCPKT_IOCTL = 0x40;
642pub const TIOCPKT_NOSTOP = 0x10;
643pub const TIOCPKT_START = 0x8;
644pub const TIOCPKT_STOP = 0x4;
645pub const TIOCPTMGET = 0x40287446;
646pub const TIOCPTSNAME = 0x40287448;
647pub const TIOCRCVFRAME = 0x80087445;
648pub const TIOCREMOTE = 0x80047469;
649pub const TIOCSBRK = 0x2000747b;
650pub const TIOCSCTTY = 0x20007461;
651pub const TIOCSDTR = 0x20007479;
652pub const TIOCSETA = 0x802c7414;
653pub const TIOCSETAF = 0x802c7416;
654pub const TIOCSETAW = 0x802c7415;
655pub const TIOCSETD = 0x8004741b;
656pub const TIOCSFLAGS = 0x8004745c;
657pub const TIOCSIG = 0x2000745f;
658pub const TIOCSLINED = 0x80207443;
659pub const TIOCSPGRP = 0x80047476;
660pub const TIOCSQSIZE = 0x80047480;
661pub const TIOCSSIZE = 0x80087467;
662pub const TIOCSTART = 0x2000746e;
663pub const TIOCSTAT = 0x80047465;
664pub const TIOCSTI = 0x80017472;
665pub const TIOCSTOP = 0x2000746f;
666pub const TIOCSWINSZ = 0x80087467;
667pub const TIOCUCNTL = 0x80047466;
668pub const TIOCXMTFRAME = 0x80087444;
669
670pub fn WEXITSTATUS(s: u32) u8 {
671 return @intCast(u8, (s >> 8) & 0xff);
672}
673pub fn WTERMSIG(s: u32) u32 {
674 return (s & 0x7f);
675}
676pub fn WSTOPSIG(s: u32) u32 {
677 return WEXITSTATUS(s);
678}
679pub fn WIFEXITED(s: u32) bool {
680 return WTERMSIG(s) == 0;
681}
682
683pub fn WIFCONTINUED(s: u32) bool {
684 return ((s & 0o177777) == 0o177777);
685}
686
687pub fn WIFSTOPPED(s: u32) bool {
688 return (s & 0xff == 0o177);
689}
690
691pub fn WIFSIGNALED(s: u32) bool {
692 return (((s) & 0o177) != 0o177) and (((s) & 0o177) != 0);
693}
694
695pub const winsize = extern struct {
696 ws_row: c_ushort,
697 ws_col: c_ushort,
698 ws_xpixel: c_ushort,
699 ws_ypixel: c_ushort,
700};
701
702const NSIG = 33;
703
704pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
705pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
706pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
707pub const SIG_CATCH = @intToPtr(?Sigaction.sigaction_fn, 2);
708pub const SIG_HOLD = @intToPtr(?Sigaction.sigaction_fn, 3);
709
710/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
711pub const Sigaction = extern struct {
712 pub const handler_fn = fn (c_int) callconv(.C) void;
713 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
714
715 /// signal handler
716 handler: extern union {
717 handler: ?handler_fn,
718 sigaction: ?sigaction_fn,
719 },
720 /// signal mask to apply
721 mask: sigset_t,
722 /// signal options
723 flags: c_uint,
724};
725
726pub const sigval = extern union {
727 int: c_int,
728 ptr: ?*c_void,
729};
730
731pub const siginfo_t = extern struct {
732 signo: c_int,
733 code: c_int,
734 errno: c_int,
735 data: extern union {
736 proc: extern struct {
737 pid: pid_t,
738 pdata: extern union {
739 kill: extern struct {
740 uid: uid_t,
741 value: sigval,
742 },
743 cld: extern struct {
744 utime: clock_t,
745 stime: clock_t,
746 status: c_int,
747 },
748 },
749 },
750 fault: extern struct {
751 addr: ?*c_void,
752 trapno: c_int,
753 },
754 __pad: [128 - 3 * @sizeOf(c_int)]u8,
755 },
756};
757
758comptime {
759 if (@sizeOf(usize) == 4)
760 std.debug.assert(@sizeOf(siginfo_t) == 128)
761 else
762 // Take into account the padding between errno and data fields.
763 std.debug.assert(@sizeOf(siginfo_t) == 136);
764}
765
766pub usingnamespace switch (builtin.target.cpu.arch) {
767 .x86_64 => struct {
768 pub const ucontext_t = extern struct {
769 sc_rdi: c_long,
770 sc_rsi: c_long,
771 sc_rdx: c_long,
772 sc_rcx: c_long,
773 sc_r8: c_long,
774 sc_r9: c_long,
775 sc_r10: c_long,
776 sc_r11: c_long,
777 sc_r12: c_long,
778 sc_r13: c_long,
779 sc_r14: c_long,
780 sc_r15: c_long,
781 sc_rbp: c_long,
782 sc_rbx: c_long,
783 sc_rax: c_long,
784 sc_gs: c_long,
785 sc_fs: c_long,
786 sc_es: c_long,
787 sc_ds: c_long,
788 sc_trapno: c_long,
789 sc_err: c_long,
790 sc_rip: c_long,
791 sc_cs: c_long,
792 sc_rflags: c_long,
793 sc_rsp: c_long,
794 sc_ss: c_long,
795
796 sc_fpstate: fxsave64,
797 __sc_unused: c_int,
798 sc_mask: c_int,
799 sc_cookie: c_long,
800 };
801
802 pub const fxsave64 = packed struct {
803 fx_fcw: u16,
804 fx_fsw: u16,
805 fx_ftw: u8,
806 fx_unused1: u8,
807 fx_fop: u16,
808 fx_rip: u64,
809 fx_rdp: u64,
810 fx_mxcsr: u32,
811 fx_mxcsr_mask: u32,
812 fx_st: [8][2]u64,
813 fx_xmm: [16][2]u64,
814 fx_unused3: [96]u8,
815 };
816 },
817 else => struct {},
818};
819
820pub const sigset_t = c_uint;
821pub const empty_sigset: sigset_t = 0;
822
823pub const E = enum(u16) {
824 /// No error occurred.
825 SUCCESS = 0,
826 PERM = 1, // Operation not permitted
827 NOENT = 2, // No such file or directory
828 SRCH = 3, // No such process
829 INTR = 4, // Interrupted system call
830 IO = 5, // Input/output error
831 NXIO = 6, // Device not configured
832 @"2BIG" = 7, // Argument list too long
833 NOEXEC = 8, // Exec format error
834 BADF = 9, // Bad file descriptor
835 CHILD = 10, // No child processes
836 DEADLK = 11, // Resource deadlock avoided
837 // 11 was AGAIN
838 NOMEM = 12, // Cannot allocate memory
839 ACCES = 13, // Permission denied
840 FAULT = 14, // Bad address
841 NOTBLK = 15, // Block device required
842 BUSY = 16, // Device busy
843 EXIST = 17, // File exists
844 XDEV = 18, // Cross-device link
845 NODEV = 19, // Operation not supported by device
846 NOTDIR = 20, // Not a directory
847 ISDIR = 21, // Is a directory
848 INVAL = 22, // Invalid argument
849 NFILE = 23, // Too many open files in system
850 MFILE = 24, // Too many open files
851 NOTTY = 25, // Inappropriate ioctl for device
852 TXTBSY = 26, // Text file busy
853 FBIG = 27, // File too large
854 NOSPC = 28, // No space left on device
855 SPIPE = 29, // Illegal seek
856 ROFS = 30, // Read-only file system
857 MLINK = 31, // Too many links
858 PIPE = 32, // Broken pipe
859
860 // math software
861 DOM = 33, // Numerical argument out of domain
862 RANGE = 34, // Result too large or too small
863
864 // non-blocking and interrupt i/o
865 // also: WOULDBLOCK: operation would block
866 AGAIN = 35, // Resource temporarily unavailable
867 INPROGRESS = 36, // Operation now in progress
868 ALREADY = 37, // Operation already in progress
869
870 // ipc/network software -- argument errors
871 NOTSOCK = 38, // Socket operation on non-socket
872 DESTADDRREQ = 39, // Destination address required
873 MSGSIZE = 40, // Message too long
874 PROTOTYPE = 41, // Protocol wrong type for socket
875 NOPROTOOPT = 42, // Protocol option not available
876 PROTONOSUPPORT = 43, // Protocol not supported
877 SOCKTNOSUPPORT = 44, // Socket type not supported
878 OPNOTSUPP = 45, // Operation not supported
879 PFNOSUPPORT = 46, // Protocol family not supported
880 AFNOSUPPORT = 47, // Address family not supported by protocol family
881 ADDRINUSE = 48, // Address already in use
882 ADDRNOTAVAIL = 49, // Can't assign requested address
883
884 // ipc/network software -- operational errors
885 NETDOWN = 50, // Network is down
886 NETUNREACH = 51, // Network is unreachable
887 NETRESET = 52, // Network dropped connection on reset
888 CONNABORTED = 53, // Software caused connection abort
889 CONNRESET = 54, // Connection reset by peer
890 NOBUFS = 55, // No buffer space available
891 ISCONN = 56, // Socket is already connected
892 NOTCONN = 57, // Socket is not connected
893 SHUTDOWN = 58, // Can't send after socket shutdown
894 TOOMANYREFS = 59, // Too many references: can't splice
895 TIMEDOUT = 60, // Operation timed out
896 CONNREFUSED = 61, // Connection refused
897
898 LOOP = 62, // Too many levels of symbolic links
899 NAMETOOLONG = 63, // File name too long
900
901 // should be rearranged
902 HOSTDOWN = 64, // Host is down
903 HOSTUNREACH = 65, // No route to host
904 NOTEMPTY = 66, // Directory not empty
905
906 // quotas & mush
907 PROCLIM = 67, // Too many processes
908 USERS = 68, // Too many users
909 DQUOT = 69, // Disc quota exceeded
910
911 // Network File System
912 STALE = 70, // Stale NFS file handle
913 REMOTE = 71, // Too many levels of remote in path
914 BADRPC = 72, // RPC struct is bad
915 RPCMISMATCH = 73, // RPC version wrong
916 PROGUNAVAIL = 74, // RPC prog. not avail
917 PROGMISMATCH = 75, // Program version wrong
918 PROCUNAVAIL = 76, // Bad procedure for program
919
920 NOLCK = 77, // No locks available
921 NOSYS = 78, // Function not implemented
922
923 FTYPE = 79, // Inappropriate file type or format
924 AUTH = 80, // Authentication error
925 NEEDAUTH = 81, // Need authenticator
926 IPSEC = 82, // IPsec processing failure
927 NOATTR = 83, // Attribute not found
928
929 // Wide/multibyte-character handling, ISO/IEC 9899/AMD1:1995
930 ILSEQ = 84, // Illegal byte sequence
931
932 NOMEDIUM = 85, // No medium found
933 MEDIUMTYPE = 86, // Wrong medium type
934 OVERFLOW = 87, // Value too large to be stored in data type
935 CANCELED = 88, // Operation canceled
936 IDRM = 89, // Identifier removed
937 NOMSG = 90, // No message of desired type
938 NOTSUP = 91, // Not supported
939 BADMSG = 92, // Bad or Corrupt message
940 NOTRECOVERABLE = 93, // State not recoverable
941 OWNERDEAD = 94, // Previous owner died
942 PROTO = 95, // Protocol error
943
944 _,
945};
946
947const _MAX_PAGE_SHIFT = switch (builtin.target.cpu.arch) {
948 .i386 => 12,
949 .sparcv9 => 13,
950};
951pub const MINSIGSTKSZ = 1 << _MAX_PAGE_SHIFT;
952pub const SIGSTKSZ = MINSIGSTKSZ + (1 << _MAX_PAGE_SHIFT) * 4;
953
954pub const SS_ONSTACK = 0x0001;
955pub const SS_DISABLE = 0x0004;
956
957pub const stack_t = extern struct {
958 ss_sp: [*]u8,
959 ss_size: usize,
960 ss_flags: c_int,
961};
962
963pub const S_IFMT = 0o170000;
964
965pub const S_IFIFO = 0o010000;
966pub const S_IFCHR = 0o020000;
967pub const S_IFDIR = 0o040000;
968pub const S_IFBLK = 0o060000;
969pub const S_IFREG = 0o100000;
970pub const S_IFLNK = 0o120000;
971pub const S_IFSOCK = 0o140000;
972
973pub const S_ISUID = 0o4000;
974pub const S_ISGID = 0o2000;
975pub const S_ISVTX = 0o1000;
976pub const S_IRWXU = 0o700;
977pub const S_IRUSR = 0o400;
978pub const S_IWUSR = 0o200;
979pub const S_IXUSR = 0o100;
980pub const S_IRWXG = 0o070;
981pub const S_IRGRP = 0o040;
982pub const S_IWGRP = 0o020;
983pub const S_IXGRP = 0o010;
984pub const S_IRWXO = 0o007;
985pub const S_IROTH = 0o004;
986pub const S_IWOTH = 0o002;
987pub const S_IXOTH = 0o001;
988
989pub fn S_ISFIFO(m: u32) bool {
990 return m & S_IFMT == S_IFIFO;
991}
992
993pub fn S_ISCHR(m: u32) bool {
994 return m & S_IFMT == S_IFCHR;
995}
996
997pub fn S_ISDIR(m: u32) bool {
998 return m & S_IFMT == S_IFDIR;
999}
1000
1001pub fn S_ISBLK(m: u32) bool {
1002 return m & S_IFMT == S_IFBLK;
1003}
1004
1005pub fn S_ISREG(m: u32) bool {
1006 return m & S_IFMT == S_IFREG;
1007}
1008
1009pub fn S_ISLNK(m: u32) bool {
1010 return m & S_IFMT == S_IFLNK;
1011}
1012
1013pub fn S_ISSOCK(m: u32) bool {
1014 return m & S_IFMT == S_IFSOCK;
1015}
1016
1017/// Magic value that specify the use of the current working directory
1018/// to determine the target of relative file paths in the openat() and
1019/// similar syscalls.
1020pub const AT_FDCWD = -100;
1021
1022/// Check access using effective user and group ID
1023pub const AT_EACCESS = 0x01;
1024
1025/// Do not follow symbolic links
1026pub const AT_SYMLINK_NOFOLLOW = 0x02;
1027
1028/// Follow symbolic link
1029pub const AT_SYMLINK_FOLLOW = 0x04;
1030
1031/// Remove directory instead of file
1032pub const AT_REMOVEDIR = 0x08;
1033
1034pub const HOST_NAME_MAX = 255;
1035
1036/// dummy for IP
1037pub const IPPROTO_IP = 0;
1038
1039/// IP6 hop-by-hop options
1040pub const IPPROTO_HOPOPTS = IPPROTO_IP;
1041
1042/// control message protocol
1043pub const IPPROTO_ICMP = 1;
1044
1045/// group mgmt protocol
1046pub const IPPROTO_IGMP = 2;
1047
1048/// gateway^2 (deprecated)
1049pub const IPPROTO_GGP = 3;
1050
1051/// IP header
1052pub const IPPROTO_IPV4 = IPPROTO_IPIP;
1053
1054/// IP inside IP
1055pub const IPPROTO_IPIP = 4;
1056
1057/// tcp
1058pub const IPPROTO_TCP = 6;
1059
1060/// exterior gateway protocol
1061pub const IPPROTO_EGP = 8;
1062
1063/// pup
1064pub const IPPROTO_PUP = 12;
1065
1066/// user datagram protocol
1067pub const IPPROTO_UDP = 17;
1068
1069/// xns idp
1070pub const IPPROTO_IDP = 22;
1071
1072/// tp-4 w/ class negotiation
1073pub const IPPROTO_TP = 29;
1074
1075/// IP6 header
1076pub const IPPROTO_IPV6 = 41;
1077
1078/// IP6 routing header
1079pub const IPPROTO_ROUTING = 43;
1080
1081/// IP6 fragmentation header
1082pub const IPPROTO_FRAGMENT = 44;
1083
1084/// resource reservation
1085pub const IPPROTO_RSVP = 46;
1086
1087/// GRE encaps RFC 1701
1088pub const IPPROTO_GRE = 47;
1089
1090/// encap. security payload
1091pub const IPPROTO_ESP = 50;
1092
1093/// authentication header
1094pub const IPPROTO_AH = 51;
1095
1096/// IP Mobility RFC 2004
1097pub const IPPROTO_MOBILE = 55;
1098
1099/// IPv6 ICMP
1100pub const IPPROTO_IPV6_ICMP = 58;
1101
1102/// ICMP6
1103pub const IPPROTO_ICMPV6 = 58;
1104
1105/// IP6 no next header
1106pub const IPPROTO_NONE = 59;
1107
1108/// IP6 destination option
1109pub const IPPROTO_DSTOPTS = 60;
1110
1111/// ISO cnlp
1112pub const IPPROTO_EON = 80;
1113
1114/// Ethernet-in-IP
1115pub const IPPROTO_ETHERIP = 97;
1116
1117/// encapsulation header
1118pub const IPPROTO_ENCAP = 98;
1119
1120/// Protocol indep. multicast
1121pub const IPPROTO_PIM = 103;
1122
1123/// IP Payload Comp. Protocol
1124pub const IPPROTO_IPCOMP = 108;
1125
1126/// VRRP RFC 2338
1127pub const IPPROTO_VRRP = 112;
1128
1129/// Common Address Resolution Protocol
1130pub const IPPROTO_CARP = 112;
1131
1132/// PFSYNC
1133pub const IPPROTO_PFSYNC = 240;
1134
1135/// raw IP packet
1136pub const IPPROTO_RAW = 255;
1137
1138pub const rlimit_resource = enum(c_int) {
1139 CPU,
1140 FSIZE,
1141 DATA,
1142 STACK,
1143 CORE,
1144 RSS,
1145 MEMLOCK,
1146 NPROC,
1147 NOFILE,
1148
1149 _,
1150};
1151
1152pub const rlim_t = u64;
1153
1154/// No limit
1155pub const RLIM_INFINITY: rlim_t = (1 << 63) - 1;
1156
1157pub const RLIM_SAVED_MAX = RLIM_INFINITY;
1158pub const RLIM_SAVED_CUR = RLIM_INFINITY;
1159
1160pub const rlimit = extern struct {
1161 /// Soft limit
1162 cur: rlim_t,
1163 /// Hard limit
1164 max: rlim_t,
1165};
1166
1167pub const SHUT_RD = 0;
1168pub const SHUT_WR = 1;
1169pub const SHUT_RDWR = 2;
1170
1171pub const nfds_t = c_uint;
1172
1173pub const pollfd = extern struct {
1174 fd: fd_t,
1175 events: c_short,
1176 revents: c_short,
1177};
1178
1179pub const POLLIN = 0x0001;
1180pub const POLLPRI = 0x0002;
1181pub const POLLOUT = 0x0004;
1182pub const POLLERR = 0x0008;
1183pub const POLLHUP = 0x0010;
1184pub const POLLNVAL = 0x0020;
1185pub const POLLRDNORM = 0x0040;
1186pub const POLLNORM = POLLRDNORM;
1187pub const POLLWRNORM = POLLOUT;
1188pub const POLLRDBAND = 0x0080;
1189pub const POLLWRBAND = 0x0100;
1190
1191// sysctl mib
1192pub const CTL_UNSPEC = 0;
1193pub const CTL_KERN = 1;
1194pub const CTL_VM = 2;
1195pub const CTL_FS = 3;
1196pub const CTL_NET = 4;
1197pub const CTL_DEBUG = 5;
1198pub const CTL_HW = 6;
1199pub const CTL_MACHDEP = 7;
1200
1201pub const CTL_DDB = 9;
1202pub const CTL_VFS = 10;
1203
1204pub const KERN_OSTYPE = 1;
1205pub const KERN_OSRELEASE = 2;
1206pub const KERN_OSREV = 3;
1207pub const KERN_VERSION = 4;
1208pub const KERN_MAXVNODES = 5;
1209pub const KERN_MAXPROC = 6;
1210pub const KERN_MAXFILES = 7;
1211pub const KERN_ARGMAX = 8;
1212pub const KERN_SECURELVL = 9;
1213pub const KERN_HOSTNAME = 10;
1214pub const KERN_HOSTID = 11;
1215pub const KERN_CLOCKRATE = 12;
1216
1217pub const KERN_PROF = 16;
1218pub const KERN_POSIX1 = 17;
1219pub const KERN_NGROUPS = 18;
1220pub const KERN_JOB_CONTROL = 19;
1221pub const KERN_SAVED_IDS = 20;
1222pub const KERN_BOOTTIME = 21;
1223pub const KERN_DOMAINNAME = 22;
1224pub const KERN_MAXPARTITIONS = 23;
1225pub const KERN_RAWPARTITION = 24;
1226pub const KERN_MAXTHREAD = 25;
1227pub const KERN_NTHREADS = 26;
1228pub const KERN_OSVERSION = 27;
1229pub const KERN_SOMAXCONN = 28;
1230pub const KERN_SOMINCONN = 29;
1231
1232pub const KERN_NOSUIDCOREDUMP = 32;
1233pub const KERN_FSYNC = 33;
1234pub const KERN_SYSVMSG = 34;
1235pub const KERN_SYSVSEM = 35;
1236pub const KERN_SYSVSHM = 36;
1237
1238pub const KERN_MSGBUFSIZE = 38;
1239pub const KERN_MALLOCSTATS = 39;
1240pub const KERN_CPTIME = 40;
1241pub const KERN_NCHSTATS = 41;
1242pub const KERN_FORKSTAT = 42;
1243pub const KERN_NSELCOLL = 43;
1244pub const KERN_TTY = 44;
1245pub const KERN_CCPU = 45;
1246pub const KERN_FSCALE = 46;
1247pub const KERN_NPROCS = 47;
1248pub const KERN_MSGBUF = 48;
1249pub const KERN_POOL = 49;
1250pub const KERN_STACKGAPRANDOM = 50;
1251pub const KERN_SYSVIPC_INFO = 51;
1252pub const KERN_ALLOWKMEM = 52;
1253pub const KERN_WITNESSWATCH = 53;
1254pub const KERN_SPLASSERT = 54;
1255pub const KERN_PROC_ARGS = 55;
1256pub const KERN_NFILES = 56;
1257pub const KERN_TTYCOUNT = 57;
1258pub const KERN_NUMVNODES = 58;
1259pub const KERN_MBSTAT = 59;
1260pub const KERN_WITNESS = 60;
1261pub const KERN_SEMINFO = 61;
1262pub const KERN_SHMINFO = 62;
1263pub const KERN_INTRCNT = 63;
1264pub const KERN_WATCHDOG = 64;
1265pub const KERN_ALLOWDT = 65;
1266pub const KERN_PROC = 66;
1267pub const KERN_MAXCLUSTERS = 67;
1268pub const KERN_EVCOUNT = 68;
1269pub const KERN_TIMECOUNTER = 69;
1270pub const KERN_MAXLOCKSPERUID = 70;
1271pub const KERN_CPTIME2 = 71;
1272pub const KERN_CACHEPCT = 72;
1273pub const KERN_FILE = 73;
1274pub const KERN_WXABORT = 74;
1275pub const KERN_CONSDEV = 75;
1276pub const KERN_NETLIVELOCKS = 76;
1277pub const KERN_POOL_DEBUG = 77;
1278pub const KERN_PROC_CWD = 78;
1279pub const KERN_PROC_NOBROADCASTKILL = 79;
1280pub const KERN_PROC_VMMAP = 80;
1281pub const KERN_GLOBAL_PTRACE = 81;
1282pub const KERN_CONSBUFSIZE = 82;
1283pub const KERN_CONSBUF = 83;
1284pub const KERN_AUDIO = 84;
1285pub const KERN_CPUSTATS = 85;
1286pub const KERN_PFSTATUS = 86;
1287pub const KERN_TIMEOUT_STATS = 87;
1288pub const KERN_UTC_OFFSET = 88;
1289pub const KERN_VIDEO = 89;
1290
1291pub const HW_MACHINE = 1;
1292pub const HW_MODEL = 2;
1293pub const HW_NCPU = 3;
1294pub const HW_BYTEORDER = 4;
1295pub const HW_PHYSMEM = 5;
1296pub const HW_USERMEM = 6;
1297pub const HW_PAGESIZE = 7;
1298pub const HW_DISKNAMES = 8;
1299pub const HW_DISKSTATS = 9;
1300pub const HW_DISKCOUNT = 10;
1301pub const HW_SENSORS = 11;
1302pub const HW_CPUSPEED = 12;
1303pub const HW_SETPERF = 13;
1304pub const HW_VENDOR = 14;
1305pub const HW_PRODUCT = 15;
1306pub const HW_VERSION = 16;
1307pub const HW_SERIALNO = 17;
1308pub const HW_UUID = 18;
1309pub const HW_PHYSMEM64 = 19;
1310pub const HW_USERMEM64 = 20;
1311pub const HW_NCPUFOUND = 21;
1312pub const HW_ALLOWPOWERDOWN = 22;
1313pub const HW_PERFPOLICY = 23;
1314pub const HW_SMT = 24;
1315pub const HW_NCPUONLINE = 25;
1316
1317pub const KERN_PROC_ALL = 0;
1318pub const KERN_PROC_PID = 1;
1319pub const KERN_PROC_PGRP = 2;
1320pub const KERN_PROC_SESSION = 3;
1321pub const KERN_PROC_TTY = 4;
1322pub const KERN_PROC_UID = 5;
1323pub const KERN_PROC_RUID = 6;
1324pub const KERN_PROC_KTHREAD = 7;
1325pub const KERN_PROC_SHOW_THREADS = 0x40000000;
1326
1327pub const KERN_PROC_ARGV = 1;
1328pub const KERN_PROC_NARGV = 2;
1329pub const KERN_PROC_ENV = 3;
1330pub const KERN_PROC_NENV = 4;
lib/std/os/bits/posix.zig deleted-28
...@@ -1,28 +0,0 @@
1pub const iovec = extern struct {
2 iov_base: [*]u8,
3 iov_len: usize,
4};
5
6pub const iovec_const = extern struct {
7 iov_base: [*]const u8,
8 iov_len: usize,
9};
10
11// syslog
12
13/// system is unusable
14pub const LOG_EMERG = 0;
15/// action must be taken immediately
16pub const LOG_ALERT = 1;
17/// critical conditions
18pub const LOG_CRIT = 2;
19/// error conditions
20pub const LOG_ERR = 3;
21/// warning conditions
22pub const LOG_WARNING = 4;
23/// normal but significant condition
24pub const LOG_NOTICE = 5;
25/// informational
26pub const LOG_INFO = 6;
27/// debug-level messages
28pub const LOG_DEBUG = 7;
lib/std/os/bits/wasi.zig deleted-490
...@@ -1,490 +0,0 @@
1// Convenience types and consts used by std.os module
2const builtin = @import("builtin");
3const posix = @import("posix.zig");
4pub const iovec = posix.iovec;
5pub const iovec_const = posix.iovec_const;
6
7pub const STDIN_FILENO = 0;
8pub const STDOUT_FILENO = 1;
9pub const STDERR_FILENO = 2;
10
11pub const mode_t = u32;
12
13pub const time_t = i64; // match https://github.com/CraneStation/wasi-libc
14
15pub const timespec = struct {
16 tv_sec: time_t,
17 tv_nsec: isize,
18
19 pub fn fromTimestamp(tm: timestamp_t) timespec {
20 const tv_sec: timestamp_t = tm / 1_000_000_000;
21 const tv_nsec = tm - tv_sec * 1_000_000_000;
22 return timespec{
23 .tv_sec = @intCast(time_t, tv_sec),
24 .tv_nsec = @intCast(isize, tv_nsec),
25 };
26 }
27
28 pub fn toTimestamp(ts: timespec) timestamp_t {
29 const tm = @intCast(timestamp_t, ts.tv_sec * 1_000_000_000) + @intCast(timestamp_t, ts.tv_nsec);
30 return tm;
31 }
32};
33
34pub const kernel_stat = struct {
35 dev: device_t,
36 ino: inode_t,
37 mode: mode_t,
38 filetype: filetype_t,
39 nlink: linkcount_t,
40 size: filesize_t,
41 atim: timespec,
42 mtim: timespec,
43 ctim: timespec,
44
45 const Self = @This();
46
47 pub fn fromFilestat(stat: filestat_t) Self {
48 return Self{
49 .dev = stat.dev,
50 .ino = stat.ino,
51 .mode = 0,
52 .filetype = stat.filetype,
53 .nlink = stat.nlink,
54 .size = stat.size,
55 .atim = stat.atime(),
56 .mtim = stat.mtime(),
57 .ctim = stat.ctime(),
58 };
59 }
60
61 pub fn atime(self: Self) timespec {
62 return self.atim;
63 }
64
65 pub fn mtime(self: Self) timespec {
66 return self.mtim;
67 }
68
69 pub fn ctime(self: Self) timespec {
70 return self.ctim;
71 }
72};
73
74pub const IOV_MAX = 1024;
75
76pub const AT_REMOVEDIR: u32 = 0x4;
77pub const AT_FDCWD: fd_t = -2;
78
79// As defined in the wasi_snapshot_preview1 spec file:
80// https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx
81pub const advice_t = u8;
82pub const ADVICE_NORMAL: advice_t = 0;
83pub const ADVICE_SEQUENTIAL: advice_t = 1;
84pub const ADVICE_RANDOM: advice_t = 2;
85pub const ADVICE_WILLNEED: advice_t = 3;
86pub const ADVICE_DONTNEED: advice_t = 4;
87pub const ADVICE_NOREUSE: advice_t = 5;
88
89pub const clockid_t = u32;
90pub const CLOCK_REALTIME: clockid_t = 0;
91pub const CLOCK_MONOTONIC: clockid_t = 1;
92pub const CLOCK_PROCESS_CPUTIME_ID: clockid_t = 2;
93pub const CLOCK_THREAD_CPUTIME_ID: clockid_t = 3;
94
95pub const device_t = u64;
96
97pub const dircookie_t = u64;
98pub const DIRCOOKIE_START: dircookie_t = 0;
99
100pub const dirnamlen_t = u32;
101
102pub const dirent_t = extern struct {
103 d_next: dircookie_t,
104 d_ino: inode_t,
105 d_namlen: dirnamlen_t,
106 d_type: filetype_t,
107};
108
109pub const errno_t = enum(u16) {
110 SUCCESS = 0,
111 @"2BIG" = 1,
112 ACCES = 2,
113 ADDRINUSE = 3,
114 ADDRNOTAVAIL = 4,
115 AFNOSUPPORT = 5,
116 /// This is also the error code used for `WOULDBLOCK`.
117 AGAIN = 6,
118 ALREADY = 7,
119 BADF = 8,
120 BADMSG = 9,
121 BUSY = 10,
122 CANCELED = 11,
123 CHILD = 12,
124 CONNABORTED = 13,
125 CONNREFUSED = 14,
126 CONNRESET = 15,
127 DEADLK = 16,
128 DESTADDRREQ = 17,
129 DOM = 18,
130 DQUOT = 19,
131 EXIST = 20,
132 FAULT = 21,
133 FBIG = 22,
134 HOSTUNREACH = 23,
135 IDRM = 24,
136 ILSEQ = 25,
137 INPROGRESS = 26,
138 INTR = 27,
139 INVAL = 28,
140 IO = 29,
141 ISCONN = 30,
142 ISDIR = 31,
143 LOOP = 32,
144 MFILE = 33,
145 MLINK = 34,
146 MSGSIZE = 35,
147 MULTIHOP = 36,
148 NAMETOOLONG = 37,
149 NETDOWN = 38,
150 NETRESET = 39,
151 NETUNREACH = 40,
152 NFILE = 41,
153 NOBUFS = 42,
154 NODEV = 43,
155 NOENT = 44,
156 NOEXEC = 45,
157 NOLCK = 46,
158 NOLINK = 47,
159 NOMEM = 48,
160 NOMSG = 49,
161 NOPROTOOPT = 50,
162 NOSPC = 51,
163 NOSYS = 52,
164 NOTCONN = 53,
165 NOTDIR = 54,
166 NOTEMPTY = 55,
167 NOTRECOVERABLE = 56,
168 NOTSOCK = 57,
169 /// This is also the code used for `NOTSUP`.
170 OPNOTSUPP = 58,
171 NOTTY = 59,
172 NXIO = 60,
173 OVERFLOW = 61,
174 OWNERDEAD = 62,
175 PERM = 63,
176 PIPE = 64,
177 PROTO = 65,
178 PROTONOSUPPORT = 66,
179 PROTOTYPE = 67,
180 RANGE = 68,
181 ROFS = 69,
182 SPIPE = 70,
183 SRCH = 71,
184 STALE = 72,
185 TIMEDOUT = 73,
186 TXTBSY = 74,
187 XDEV = 75,
188 NOTCAPABLE = 76,
189 _,
190};
191pub const E = errno_t;
192
193pub const event_t = extern struct {
194 userdata: userdata_t,
195 @"error": errno_t,
196 @"type": eventtype_t,
197 fd_readwrite: eventfdreadwrite_t,
198};
199
200pub const eventfdreadwrite_t = extern struct {
201 nbytes: filesize_t,
202 flags: eventrwflags_t,
203};
204
205pub const eventrwflags_t = u16;
206pub const EVENT_FD_READWRITE_HANGUP: eventrwflags_t = 0x0001;
207
208pub const eventtype_t = u8;
209pub const EVENTTYPE_CLOCK: eventtype_t = 0;
210pub const EVENTTYPE_FD_READ: eventtype_t = 1;
211pub const EVENTTYPE_FD_WRITE: eventtype_t = 2;
212
213pub const exitcode_t = u32;
214
215pub const fd_t = if (builtin.link_libc) c_int else u32;
216
217pub const fdflags_t = u16;
218pub const FDFLAG_APPEND: fdflags_t = 0x0001;
219pub const FDFLAG_DSYNC: fdflags_t = 0x0002;
220pub const FDFLAG_NONBLOCK: fdflags_t = 0x0004;
221pub const FDFLAG_RSYNC: fdflags_t = 0x0008;
222pub const FDFLAG_SYNC: fdflags_t = 0x0010;
223
224pub const fdstat_t = extern struct {
225 fs_filetype: filetype_t,
226 fs_flags: fdflags_t,
227 fs_rights_base: rights_t,
228 fs_rights_inheriting: rights_t,
229};
230
231pub const filedelta_t = i64;
232
233pub const filesize_t = u64;
234
235pub const filestat_t = extern struct {
236 dev: device_t,
237 ino: inode_t,
238 filetype: filetype_t,
239 nlink: linkcount_t,
240 size: filesize_t,
241 atim: timestamp_t,
242 mtim: timestamp_t,
243 ctim: timestamp_t,
244
245 pub fn atime(self: filestat_t) timespec {
246 return timespec.fromTimestamp(self.atim);
247 }
248
249 pub fn mtime(self: filestat_t) timespec {
250 return timespec.fromTimestamp(self.mtim);
251 }
252
253 pub fn ctime(self: filestat_t) timespec {
254 return timespec.fromTimestamp(self.ctim);
255 }
256};
257
258pub const filetype_t = u8;
259pub const FILETYPE_UNKNOWN: filetype_t = 0;
260pub const FILETYPE_BLOCK_DEVICE: filetype_t = 1;
261pub const FILETYPE_CHARACTER_DEVICE: filetype_t = 2;
262pub const FILETYPE_DIRECTORY: filetype_t = 3;
263pub const FILETYPE_REGULAR_FILE: filetype_t = 4;
264pub const FILETYPE_SOCKET_DGRAM: filetype_t = 5;
265pub const FILETYPE_SOCKET_STREAM: filetype_t = 6;
266pub const FILETYPE_SYMBOLIC_LINK: filetype_t = 7;
267
268pub const fstflags_t = u16;
269pub const FILESTAT_SET_ATIM: fstflags_t = 0x0001;
270pub const FILESTAT_SET_ATIM_NOW: fstflags_t = 0x0002;
271pub const FILESTAT_SET_MTIM: fstflags_t = 0x0004;
272pub const FILESTAT_SET_MTIM_NOW: fstflags_t = 0x0008;
273
274pub const inode_t = u64;
275pub const ino_t = inode_t;
276
277pub const linkcount_t = u64;
278
279pub const lookupflags_t = u32;
280pub const LOOKUP_SYMLINK_FOLLOW: lookupflags_t = 0x00000001;
281
282pub usingnamespace if (builtin.link_libc) struct {
283 // Derived from https://github.com/WebAssembly/wasi-libc/blob/main/expected/wasm32-wasi/predefined-macros.txt
284 pub const O_ACCMODE = (O_EXEC | O_RDWR | O_SEARCH);
285 pub const O_APPEND = FDFLAG_APPEND;
286 pub const O_CLOEXEC = (0);
287 pub const O_CREAT = ((1 << 0) << 12); // = __WASI_OFLAGS_CREAT << 12
288 pub const O_DIRECTORY = ((1 << 1) << 12); // = __WASI_OFLAGS_DIRECTORY << 12
289 pub const O_DSYNC = FDFLAG_DSYNC;
290 pub const O_EXCL = ((1 << 2) << 12); // = __WASI_OFLAGS_EXCL << 12
291 pub const O_EXEC = (0x02000000);
292 pub const O_NOCTTY = (0);
293 pub const O_NOFOLLOW = (0x01000000);
294 pub const O_NONBLOCK = (1 << FDFLAG_NONBLOCK);
295 pub const O_RDONLY = (0x04000000);
296 pub const O_RDWR = (O_RDONLY | O_WRONLY);
297 pub const O_RSYNC = (1 << FDFLAG_RSYNC);
298 pub const O_SEARCH = (0x08000000);
299 pub const O_SYNC = (1 << FDFLAG_SYNC);
300 pub const O_TRUNC = ((1 << 3) << 12); // = __WASI_OFLAGS_TRUNC << 12
301 pub const O_TTY_INIT = (0);
302 pub const O_WRONLY = (0x10000000);
303} else struct {
304 pub const oflags_t = u16;
305 pub const O_CREAT: oflags_t = 0x0001;
306 pub const O_DIRECTORY: oflags_t = 0x0002;
307 pub const O_EXCL: oflags_t = 0x0004;
308 pub const O_TRUNC: oflags_t = 0x0008;
309};
310
311pub const preopentype_t = u8;
312pub const PREOPENTYPE_DIR: preopentype_t = 0;
313
314pub const prestat_t = extern struct {
315 pr_type: preopentype_t,
316 u: prestat_u_t,
317};
318
319pub const prestat_dir_t = extern struct {
320 pr_name_len: usize,
321};
322
323pub const prestat_u_t = extern union {
324 dir: prestat_dir_t,
325};
326
327pub const riflags_t = u16;
328pub const SOCK_RECV_PEEK: riflags_t = 0x0001;
329pub const SOCK_RECV_WAITALL: riflags_t = 0x0002;
330
331pub const rights_t = u64;
332pub const RIGHT_FD_DATASYNC: rights_t = 0x0000000000000001;
333pub const RIGHT_FD_READ: rights_t = 0x0000000000000002;
334pub const RIGHT_FD_SEEK: rights_t = 0x0000000000000004;
335pub const RIGHT_FD_FDSTAT_SET_FLAGS: rights_t = 0x0000000000000008;
336pub const RIGHT_FD_SYNC: rights_t = 0x0000000000000010;
337pub const RIGHT_FD_TELL: rights_t = 0x0000000000000020;
338pub const RIGHT_FD_WRITE: rights_t = 0x0000000000000040;
339pub const RIGHT_FD_ADVISE: rights_t = 0x0000000000000080;
340pub const RIGHT_FD_ALLOCATE: rights_t = 0x0000000000000100;
341pub const RIGHT_PATH_CREATE_DIRECTORY: rights_t = 0x0000000000000200;
342pub const RIGHT_PATH_CREATE_FILE: rights_t = 0x0000000000000400;
343pub const RIGHT_PATH_LINK_SOURCE: rights_t = 0x0000000000000800;
344pub const RIGHT_PATH_LINK_TARGET: rights_t = 0x0000000000001000;
345pub const RIGHT_PATH_OPEN: rights_t = 0x0000000000002000;
346pub const RIGHT_FD_READDIR: rights_t = 0x0000000000004000;
347pub const RIGHT_PATH_READLINK: rights_t = 0x0000000000008000;
348pub const RIGHT_PATH_RENAME_SOURCE: rights_t = 0x0000000000010000;
349pub const RIGHT_PATH_RENAME_TARGET: rights_t = 0x0000000000020000;
350pub const RIGHT_PATH_FILESTAT_GET: rights_t = 0x0000000000040000;
351pub const RIGHT_PATH_FILESTAT_SET_SIZE: rights_t = 0x0000000000080000;
352pub const RIGHT_PATH_FILESTAT_SET_TIMES: rights_t = 0x0000000000100000;
353pub const RIGHT_FD_FILESTAT_GET: rights_t = 0x0000000000200000;
354pub const RIGHT_FD_FILESTAT_SET_SIZE: rights_t = 0x0000000000400000;
355pub const RIGHT_FD_FILESTAT_SET_TIMES: rights_t = 0x0000000000800000;
356pub const RIGHT_PATH_SYMLINK: rights_t = 0x0000000001000000;
357pub const RIGHT_PATH_REMOVE_DIRECTORY: rights_t = 0x0000000002000000;
358pub const RIGHT_PATH_UNLINK_FILE: rights_t = 0x0000000004000000;
359pub const RIGHT_POLL_FD_READWRITE: rights_t = 0x0000000008000000;
360pub const RIGHT_SOCK_SHUTDOWN: rights_t = 0x0000000010000000;
361pub const RIGHT_ALL: rights_t = RIGHT_FD_DATASYNC |
362 RIGHT_FD_READ |
363 RIGHT_FD_SEEK |
364 RIGHT_FD_FDSTAT_SET_FLAGS |
365 RIGHT_FD_SYNC |
366 RIGHT_FD_TELL |
367 RIGHT_FD_WRITE |
368 RIGHT_FD_ADVISE |
369 RIGHT_FD_ALLOCATE |
370 RIGHT_PATH_CREATE_DIRECTORY |
371 RIGHT_PATH_CREATE_FILE |
372 RIGHT_PATH_LINK_SOURCE |
373 RIGHT_PATH_LINK_TARGET |
374 RIGHT_PATH_OPEN |
375 RIGHT_FD_READDIR |
376 RIGHT_PATH_READLINK |
377 RIGHT_PATH_RENAME_SOURCE |
378 RIGHT_PATH_RENAME_TARGET |
379 RIGHT_PATH_FILESTAT_GET |
380 RIGHT_PATH_FILESTAT_SET_SIZE |
381 RIGHT_PATH_FILESTAT_SET_TIMES |
382 RIGHT_FD_FILESTAT_GET |
383 RIGHT_FD_FILESTAT_SET_SIZE |
384 RIGHT_FD_FILESTAT_SET_TIMES |
385 RIGHT_PATH_SYMLINK |
386 RIGHT_PATH_REMOVE_DIRECTORY |
387 RIGHT_PATH_UNLINK_FILE |
388 RIGHT_POLL_FD_READWRITE |
389 RIGHT_SOCK_SHUTDOWN;
390
391pub const roflags_t = u16;
392pub const SOCK_RECV_DATA_TRUNCATED: roflags_t = 0x0001;
393
394pub const sdflags_t = u8;
395pub const SHUT_RD: sdflags_t = 0x01;
396pub const SHUT_WR: sdflags_t = 0x02;
397
398pub const siflags_t = u16;
399
400pub const signal_t = u8;
401pub const SIGNONE: signal_t = 0;
402pub const SIGHUP: signal_t = 1;
403pub const SIGINT: signal_t = 2;
404pub const SIGQUIT: signal_t = 3;
405pub const SIGILL: signal_t = 4;
406pub const SIGTRAP: signal_t = 5;
407pub const SIGABRT: signal_t = 6;
408pub const SIGBUS: signal_t = 7;
409pub const SIGFPE: signal_t = 8;
410pub const SIGKILL: signal_t = 9;
411pub const SIGUSR1: signal_t = 10;
412pub const SIGSEGV: signal_t = 11;
413pub const SIGUSR2: signal_t = 12;
414pub const SIGPIPE: signal_t = 13;
415pub const SIGALRM: signal_t = 14;
416pub const SIGTERM: signal_t = 15;
417pub const SIGCHLD: signal_t = 16;
418pub const SIGCONT: signal_t = 17;
419pub const SIGSTOP: signal_t = 18;
420pub const SIGTSTP: signal_t = 19;
421pub const SIGTTIN: signal_t = 20;
422pub const SIGTTOU: signal_t = 21;
423pub const SIGURG: signal_t = 22;
424pub const SIGXCPU: signal_t = 23;
425pub const SIGXFSZ: signal_t = 24;
426pub const SIGVTALRM: signal_t = 25;
427pub const SIGPROF: signal_t = 26;
428pub const SIGWINCH: signal_t = 27;
429pub const SIGPOLL: signal_t = 28;
430pub const SIGPWR: signal_t = 29;
431pub const SIGSYS: signal_t = 30;
432
433pub const subclockflags_t = u16;
434pub const SUBSCRIPTION_CLOCK_ABSTIME: subclockflags_t = 0x0001;
435
436pub const subscription_t = extern struct {
437 userdata: userdata_t,
438 u: subscription_u_t,
439};
440
441pub const subscription_clock_t = extern struct {
442 id: clockid_t,
443 timeout: timestamp_t,
444 precision: timestamp_t,
445 flags: subclockflags_t,
446};
447
448pub const subscription_fd_readwrite_t = extern struct {
449 fd: fd_t,
450};
451
452pub const subscription_u_t = extern struct {
453 tag: eventtype_t,
454 u: subscription_u_u_t,
455};
456
457pub const subscription_u_u_t = extern union {
458 clock: subscription_clock_t,
459 fd_read: subscription_fd_readwrite_t,
460 fd_write: subscription_fd_readwrite_t,
461};
462
463pub const timestamp_t = u64;
464
465pub const userdata_t = u64;
466
467pub const whence_t = u8;
468pub const WHENCE_SET: whence_t = 0;
469pub const WHENCE_CUR: whence_t = 1;
470pub const WHENCE_END: whence_t = 2;
471
472pub const S_IEXEC = S_IXUSR;
473pub const S_IFBLK = 0x6000;
474pub const S_IFCHR = 0x2000;
475pub const S_IFDIR = 0x4000;
476pub const S_IFIFO = 0xc000;
477pub const S_IFLNK = 0xa000;
478pub const S_IFMT = S_IFBLK | S_IFCHR | S_IFDIR | S_IFIFO | S_IFLNK | S_IFREG | S_IFSOCK;
479pub const S_IFREG = 0x8000;
480// There's no concept of UNIX domain socket but we define this value here in order to line with other OSes.
481pub const S_IFSOCK = 0x1;
482
483pub const SEEK_SET = WHENCE_SET;
484pub const SEEK_CUR = WHENCE_CUR;
485pub const SEEK_END = WHENCE_END;
486
487pub const LOCK_SH = 0x1;
488pub const LOCK_EX = 0x2;
489pub const LOCK_NB = 0x4;
490pub const LOCK_UN = 0x8;
lib/std/os/bits/windows.zig deleted-329
...@@ -1,329 +0,0 @@
1// The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime).
2
3usingnamespace @import("../windows/bits.zig");
4const ws2_32 = @import("../windows/ws2_32.zig");
5
6// TODO: Stop using os.iovec in std.fs et al on Windows in the future
7const posix = @import("posix.zig");
8pub const iovec = posix.iovec;
9pub const iovec_const = posix.iovec_const;
10
11pub const fd_t = HANDLE;
12pub const ino_t = LARGE_INTEGER;
13pub const pid_t = HANDLE;
14pub const mode_t = u0;
15
16pub const PATH_MAX = 260;
17
18pub const time_t = c_longlong;
19
20pub const timespec = extern struct {
21 tv_sec: time_t,
22 tv_nsec: c_long,
23};
24
25pub const timeval = extern struct {
26 tv_sec: c_long,
27 tv_usec: c_long,
28};
29
30pub const sig_atomic_t = c_int;
31
32/// maximum signal number + 1
33pub const NSIG = 23;
34
35// Signal types
36
37/// interrupt
38pub const SIGINT = 2;
39
40/// illegal instruction - invalid function image
41pub const SIGILL = 4;
42
43/// floating point exception
44pub const SIGFPE = 8;
45
46/// segment violation
47pub const SIGSEGV = 11;
48
49/// Software termination signal from kill
50pub const SIGTERM = 15;
51
52/// Ctrl-Break sequence
53pub const SIGBREAK = 21;
54
55/// abnormal termination triggered by abort call
56pub const SIGABRT = 22;
57
58/// SIGABRT compatible with other platforms, same as SIGABRT
59pub const SIGABRT_COMPAT = 6;
60
61// Signal action codes
62
63/// default signal action
64pub const SIG_DFL = 0;
65
66/// ignore signal
67pub const SIG_IGN = 1;
68
69/// return current value
70pub const SIG_GET = 2;
71
72/// signal gets error
73pub const SIG_SGE = 3;
74
75/// acknowledge
76pub const SIG_ACK = 4;
77
78/// Signal error value (returned by signal call on error)
79pub const SIG_ERR = -1;
80
81pub const SEEK_SET = 0;
82pub const SEEK_CUR = 1;
83pub const SEEK_END = 2;
84
85pub const E = enum(u16) {
86 /// No error occurred.
87 SUCCESS = 0,
88 PERM = 1,
89 NOENT = 2,
90 SRCH = 3,
91 INTR = 4,
92 IO = 5,
93 NXIO = 6,
94 @"2BIG" = 7,
95 NOEXEC = 8,
96 BADF = 9,
97 CHILD = 10,
98 AGAIN = 11,
99 NOMEM = 12,
100 ACCES = 13,
101 FAULT = 14,
102 BUSY = 16,
103 EXIST = 17,
104 XDEV = 18,
105 NODEV = 19,
106 NOTDIR = 20,
107 ISDIR = 21,
108 NFILE = 23,
109 MFILE = 24,
110 NOTTY = 25,
111 FBIG = 27,
112 NOSPC = 28,
113 SPIPE = 29,
114 ROFS = 30,
115 MLINK = 31,
116 PIPE = 32,
117 DOM = 33,
118 /// Also means `DEADLOCK`.
119 DEADLK = 36,
120 NAMETOOLONG = 38,
121 NOLCK = 39,
122 NOSYS = 40,
123 NOTEMPTY = 41,
124
125 INVAL = 22,
126 RANGE = 34,
127 ILSEQ = 42,
128
129 // POSIX Supplement
130 ADDRINUSE = 100,
131 ADDRNOTAVAIL = 101,
132 AFNOSUPPORT = 102,
133 ALREADY = 103,
134 BADMSG = 104,
135 CANCELED = 105,
136 CONNABORTED = 106,
137 CONNREFUSED = 107,
138 CONNRESET = 108,
139 DESTADDRREQ = 109,
140 HOSTUNREACH = 110,
141 IDRM = 111,
142 INPROGRESS = 112,
143 ISCONN = 113,
144 LOOP = 114,
145 MSGSIZE = 115,
146 NETDOWN = 116,
147 NETRESET = 117,
148 NETUNREACH = 118,
149 NOBUFS = 119,
150 NODATA = 120,
151 NOLINK = 121,
152 NOMSG = 122,
153 NOPROTOOPT = 123,
154 NOSR = 124,
155 NOSTR = 125,
156 NOTCONN = 126,
157 NOTRECOVERABLE = 127,
158 NOTSOCK = 128,
159 NOTSUP = 129,
160 OPNOTSUPP = 130,
161 OTHER = 131,
162 OVERFLOW = 132,
163 OWNERDEAD = 133,
164 PROTO = 134,
165 PROTONOSUPPORT = 135,
166 PROTOTYPE = 136,
167 TIME = 137,
168 TIMEDOUT = 138,
169 TXTBSY = 139,
170 WOULDBLOCK = 140,
171 DQUOT = 10069,
172 _,
173};
174
175pub const STRUNCATE = 80;
176
177pub const F_OK = 0;
178
179/// Remove directory instead of unlinking file
180pub const AT_REMOVEDIR = 0x200;
181
182pub const in_port_t = u16;
183pub const sa_family_t = ws2_32.ADDRESS_FAMILY;
184pub const socklen_t = ws2_32.socklen_t;
185
186pub const sockaddr = ws2_32.sockaddr;
187pub const sockaddr_in = ws2_32.sockaddr_in;
188pub const sockaddr_in6 = ws2_32.sockaddr_in6;
189pub const sockaddr_un = ws2_32.sockaddr_un;
190
191pub const in6_addr = [16]u8;
192pub const in_addr = u32;
193
194pub const addrinfo = ws2_32.addrinfo;
195
196pub const AF_UNSPEC = ws2_32.AF_UNSPEC;
197pub const AF_UNIX = ws2_32.AF_UNIX;
198pub const AF_INET = ws2_32.AF_INET;
199pub const AF_IMPLINK = ws2_32.AF_IMPLINK;
200pub const AF_PUP = ws2_32.AF_PUP;
201pub const AF_CHAOS = ws2_32.AF_CHAOS;
202pub const AF_NS = ws2_32.AF_NS;
203pub const AF_IPX = ws2_32.AF_IPX;
204pub const AF_ISO = ws2_32.AF_ISO;
205pub const AF_OSI = ws2_32.AF_OSI;
206pub const AF_ECMA = ws2_32.AF_ECMA;
207pub const AF_DATAKIT = ws2_32.AF_DATAKIT;
208pub const AF_CCITT = ws2_32.AF_CCITT;
209pub const AF_SNA = ws2_32.AF_SNA;
210pub const AF_DECnet = ws2_32.AF_DECnet;
211pub const AF_DLI = ws2_32.AF_DLI;
212pub const AF_LAT = ws2_32.AF_LAT;
213pub const AF_HYLINK = ws2_32.AF_HYLINK;
214pub const AF_APPLETALK = ws2_32.AF_APPLETALK;
215pub const AF_NETBIOS = ws2_32.AF_NETBIOS;
216pub const AF_VOICEVIEW = ws2_32.AF_VOICEVIEW;
217pub const AF_FIREFOX = ws2_32.AF_FIREFOX;
218pub const AF_UNKNOWN1 = ws2_32.AF_UNKNOWN1;
219pub const AF_BAN = ws2_32.AF_BAN;
220pub const AF_ATM = ws2_32.AF_ATM;
221pub const AF_INET6 = ws2_32.AF_INET6;
222pub const AF_CLUSTER = ws2_32.AF_CLUSTER;
223pub const AF_12844 = ws2_32.AF_12844;
224pub const AF_IRDA = ws2_32.AF_IRDA;
225pub const AF_NETDES = ws2_32.AF_NETDES;
226pub const AF_TCNPROCESS = ws2_32.AF_TCNPROCESS;
227pub const AF_TCNMESSAGE = ws2_32.AF_TCNMESSAGE;
228pub const AF_ICLFXBM = ws2_32.AF_ICLFXBM;
229pub const AF_BTH = ws2_32.AF_BTH;
230pub const AF_MAX = ws2_32.AF_MAX;
231
232pub const SOCK_STREAM = ws2_32.SOCK_STREAM;
233pub const SOCK_DGRAM = ws2_32.SOCK_DGRAM;
234pub const SOCK_RAW = ws2_32.SOCK_RAW;
235pub const SOCK_RDM = ws2_32.SOCK_RDM;
236pub const SOCK_SEQPACKET = ws2_32.SOCK_SEQPACKET;
237
238/// WARNING: this flag is not supported by windows socket functions directly,
239/// it is only supported by std.os.socket. Be sure that this value does
240/// not share any bits with any of the SOCK_* values.
241pub const SOCK_CLOEXEC = 0x10000;
242/// WARNING: this flag is not supported by windows socket functions directly,
243/// it is only supported by std.os.socket. Be sure that this value does
244/// not share any bits with any of the SOCK_* values.
245pub const SOCK_NONBLOCK = 0x20000;
246
247pub const IPPROTO_ICMP = ws2_32.IPPROTO_ICMP;
248pub const IPPROTO_IGMP = ws2_32.IPPROTO_IGMP;
249pub const BTHPROTO_RFCOMM = ws2_32.BTHPROTO_RFCOMM;
250pub const IPPROTO_TCP = ws2_32.IPPROTO_TCP;
251pub const IPPROTO_UDP = ws2_32.IPPROTO_UDP;
252pub const IPPROTO_ICMPV6 = ws2_32.IPPROTO_ICMPV6;
253pub const IPPROTO_RM = ws2_32.IPPROTO_RM;
254
255pub const nfds_t = c_ulong;
256pub const pollfd = ws2_32.pollfd;
257
258pub const POLLRDNORM = ws2_32.POLLRDNORM;
259pub const POLLRDBAND = ws2_32.POLLRDBAND;
260pub const POLLIN = ws2_32.POLLIN;
261pub const POLLPRI = ws2_32.POLLPRI;
262pub const POLLWRNORM = ws2_32.POLLWRNORM;
263pub const POLLOUT = ws2_32.POLLOUT;
264pub const POLLWRBAND = ws2_32.POLLWRBAND;
265pub const POLLERR = ws2_32.POLLERR;
266pub const POLLHUP = ws2_32.POLLHUP;
267pub const POLLNVAL = ws2_32.POLLNVAL;
268
269pub const SOL_SOCKET = ws2_32.SOL_SOCKET;
270
271pub const SO_DEBUG = ws2_32.SO_DEBUG;
272pub const SO_ACCEPTCONN = ws2_32.SO_ACCEPTCONN;
273pub const SO_REUSEADDR = ws2_32.SO_REUSEADDR;
274pub const SO_KEEPALIVE = ws2_32.SO_KEEPALIVE;
275pub const SO_DONTROUTE = ws2_32.SO_DONTROUTE;
276pub const SO_BROADCAST = ws2_32.SO_BROADCAST;
277pub const SO_USELOOPBACK = ws2_32.SO_USELOOPBACK;
278pub const SO_LINGER = ws2_32.SO_LINGER;
279pub const SO_OOBINLINE = ws2_32.SO_OOBINLINE;
280
281pub const SO_DONTLINGER = ws2_32.SO_DONTLINGER;
282pub const SO_EXCLUSIVEADDRUSE = ws2_32.SO_EXCLUSIVEADDRUSE;
283
284pub const SO_SNDBUF = ws2_32.SO_SNDBUF;
285pub const SO_RCVBUF = ws2_32.SO_RCVBUF;
286pub const SO_SNDLOWAT = ws2_32.SO_SNDLOWAT;
287pub const SO_RCVLOWAT = ws2_32.SO_RCVLOWAT;
288pub const SO_SNDTIMEO = ws2_32.SO_SNDTIMEO;
289pub const SO_RCVTIMEO = ws2_32.SO_RCVTIMEO;
290pub const SO_ERROR = ws2_32.SO_ERROR;
291pub const SO_TYPE = ws2_32.SO_TYPE;
292
293pub const SO_GROUP_ID = ws2_32.SO_GROUP_ID;
294pub const SO_GROUP_PRIORITY = ws2_32.SO_GROUP_PRIORITY;
295pub const SO_MAX_MSG_SIZE = ws2_32.SO_MAX_MSG_SIZE;
296pub const SO_PROTOCOL_INFOA = ws2_32.SO_PROTOCOL_INFOA;
297pub const SO_PROTOCOL_INFOW = ws2_32.SO_PROTOCOL_INFOW;
298
299pub const PVD_CONFIG = ws2_32.PVD_CONFIG;
300pub const SO_CONDITIONAL_ACCEPT = ws2_32.SO_CONDITIONAL_ACCEPT;
301
302pub const TCP_NODELAY = ws2_32.TCP_NODELAY;
303
304pub const O_RDONLY = 0o0;
305pub const O_WRONLY = 0o1;
306pub const O_RDWR = 0o2;
307
308pub const O_CREAT = 0o100;
309pub const O_EXCL = 0o200;
310pub const O_NOCTTY = 0o400;
311pub const O_TRUNC = 0o1000;
312pub const O_APPEND = 0o2000;
313pub const O_NONBLOCK = 0o4000;
314pub const O_DSYNC = 0o10000;
315pub const O_SYNC = 0o4010000;
316pub const O_RSYNC = 0o4010000;
317pub const O_DIRECTORY = 0o200000;
318pub const O_NOFOLLOW = 0o400000;
319pub const O_CLOEXEC = 0o2000000;
320
321pub const O_ASYNC = 0o20000;
322pub const O_DIRECT = 0o40000;
323pub const O_LARGEFILE = 0;
324pub const O_NOATIME = 0o1000000;
325pub const O_PATH = 0o10000000;
326pub const O_TMPFILE = 0o20200000;
327pub const O_NDELAY = O_NONBLOCK;
328
329pub const IFNAMESIZE = 30;
lib/std/os/darwin.zig deleted-3
...@@ -1,3 +0,0 @@
1const std = @import("../std.zig");
2pub usingnamespace std.c;
3pub usingnamespace @import("bits.zig");
lib/std/os/dragonfly.zig deleted-3
...@@ -1,3 +0,0 @@
1const std = @import("../std.zig");
2pub usingnamespace std.c;
3pub usingnamespace @import("bits.zig");
lib/std/os/freebsd.zig deleted-3
...@@ -1,3 +0,0 @@
1const std = @import("../std.zig");
2pub usingnamespace std.c;
3pub usingnamespace @import("bits.zig");
lib/std/os/haiku.zig deleted-3
...@@ -1,3 +0,0 @@
1const std = @import("../std.zig");
2pub usingnamespace std.c;
3pub usingnamespace @import("bits.zig");
lib/std/os/linux.zig+3448-62
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1// This file provides the system interface functions for Linux matching those1//! This file provides the system interface functions for Linux matching those
2// that are provided by libc, whether or not libc is linked. The following2//! that are provided by libc, whether or not libc is linked. The following
3// abstractions are made:3//! abstractions are made:
4// * Work around kernel bugs and limitations. For example, see sendmmsg.4//! * Work around kernel bugs and limitations. For example, see sendmmsg.
5// * Implement all the syscalls in the same way that libc functions will5//! * Implement all the syscalls in the same way that libc functions will
6// provide `rename` when only the `renameat` syscall exists.6//! provide `rename` when only the `renameat` syscall exists.
7// * Does not support POSIX thread cancellation.7//! * Does not support POSIX thread cancellation.
8const std = @import("../std.zig");8const std = @import("../std.zig");
9const assert = std.debug.assert;9const assert = std.debug.assert;
10const maxInt = std.math.maxInt;10const maxInt = std.math.maxInt;
...@@ -13,13 +13,29 @@ const vdso = @import("linux/vdso.zig");...@@ -13,13 +13,29 @@ const vdso = @import("linux/vdso.zig");
13const dl = @import("../dynamic_library.zig");13const dl = @import("../dynamic_library.zig");
14const native_arch = std.Target.current.cpu.arch;14const native_arch = std.Target.current.cpu.arch;
15const native_endian = native_arch.endian();15const native_endian = native_arch.endian();
16const is_mips = native_arch.isMIPS();
17const is_ppc = native_arch.isPPC();
18const is_ppc64 = native_arch.isPPC64();
19const is_sparc = native_arch.isSPARC();
20const iovec = std.os.iovec;
21const iovec_const = std.os.iovec_const;
1622
17pub usingnamespace switch (native_arch) {23test {
24 if (std.Target.current.os.tag == .linux) {
25 _ = @import("linux/test.zig");
26 }
27}
28
29const syscall_bits = switch (native_arch) {
30 .thumb => @import("linux/thumb.zig"),
31 else => arch_bits,
32};
33
34const arch_bits = switch (native_arch) {
18 .i386 => @import("linux/i386.zig"),35 .i386 => @import("linux/i386.zig"),
19 .x86_64 => @import("linux/x86_64.zig"),36 .x86_64 => @import("linux/x86_64.zig"),
20 .aarch64 => @import("linux/arm64.zig"),37 .aarch64 => @import("linux/arm64.zig"),
21 .arm => @import("linux/arm-eabi.zig"),38 .arm, .thumb => @import("linux/arm-eabi.zig"),
22 .thumb => @import("linux/thumb.zig"),
23 .riscv64 => @import("linux/riscv64.zig"),39 .riscv64 => @import("linux/riscv64.zig"),
24 .sparcv9 => @import("linux/sparc64.zig"),40 .sparcv9 => @import("linux/sparc64.zig"),
25 .mips, .mipsel => @import("linux/mips.zig"),41 .mips, .mipsel => @import("linux/mips.zig"),
...@@ -27,10 +43,93 @@ pub usingnamespace switch (native_arch) {...@@ -27,10 +43,93 @@ pub usingnamespace switch (native_arch) {
27 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),43 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
28 else => struct {},44 else => struct {},
29};45};
30pub usingnamespace @import("bits.zig");46pub const syscall0 = syscall_bits.syscall0;
47pub const syscall1 = syscall_bits.syscall1;
48pub const syscall2 = syscall_bits.syscall2;
49pub const syscall3 = syscall_bits.syscall3;
50pub const syscall4 = syscall_bits.syscall4;
51pub const syscall5 = syscall_bits.syscall5;
52pub const syscall6 = syscall_bits.syscall6;
53pub const syscall7 = syscall_bits.syscall7;
54pub const restore = syscall_bits.restore;
55pub const restore_rt = syscall_bits.restore_rt;
56pub const socketcall = syscall_bits.socketcall;
57pub const syscall_pipe = syscall_bits.syscall_pipe;
58pub const syscall_fork = syscall_bits.syscall_fork;
59
60pub const ARCH = arch_bits.ARCH;
61pub const Elf_Symndx = arch_bits.Elf_Symndx;
62pub const F = arch_bits.F;
63pub const Flock = arch_bits.Flock;
64pub const HWCAP = arch_bits.HWCAP;
65pub const LOCK = arch_bits.LOCK;
66pub const MMAP2_UNIT = arch_bits.MMAP2_UNIT;
67pub const REG = arch_bits.REG;
68pub const SC = arch_bits.SC;
69pub const SYS = arch_bits.SYS;
70pub const Stat = arch_bits.Stat;
71pub const VDSO = arch_bits.VDSO;
72pub const blkcnt_t = arch_bits.blkcnt_t;
73pub const blksize_t = arch_bits.blksize_t;
74pub const clone = arch_bits.clone;
75pub const dev_t = arch_bits.dev_t;
76pub const ino_t = arch_bits.ino_t;
77pub const mcontext_t = arch_bits.mcontext_t;
78pub const mode_t = arch_bits.mode_t;
79pub const msghdr = arch_bits.msghdr;
80pub const msghdr_const = arch_bits.msghdr_const;
81pub const nlink_t = arch_bits.nlink_t;
82pub const off_t = arch_bits.off_t;
83pub const time_t = arch_bits.time_t;
84pub const timeval = arch_bits.timeval;
85pub const timezone = arch_bits.timezone;
86pub const ucontext_t = arch_bits.ucontext_t;
87pub const user_desc = arch_bits.user_desc;
88
31pub const tls = @import("linux/tls.zig");89pub const tls = @import("linux/tls.zig");
32pub const pie = @import("linux/start_pie.zig");90pub const pie = @import("linux/start_pie.zig");
33pub const BPF = @import("linux/bpf.zig");91pub const BPF = @import("linux/bpf.zig");
92
93pub const MAP = struct {
94 pub usingnamespace arch_bits.MAP;
95
96 /// Share changes
97 pub const SHARED = 0x01;
98 /// Changes are private
99 pub const PRIVATE = 0x02;
100 /// share + validate extension flags
101 pub const SHARED_VALIDATE = 0x03;
102 /// Mask for type of mapping
103 pub const TYPE = 0x0f;
104 /// Interpret addr exactly
105 pub const FIXED = 0x10;
106 /// don't use a file
107 pub const ANONYMOUS = if (is_mips) 0x800 else 0x20;
108 // MAP_ 0x0100 - 0x4000 flags are per architecture
109 /// populate (prefault) pagetables
110 pub const POPULATE = if (is_mips) 0x10000 else 0x8000;
111 /// do not block on IO
112 pub const NONBLOCK = if (is_mips) 0x20000 else 0x10000;
113 /// give out an address that is best suited for process/thread stacks
114 pub const STACK = if (is_mips) 0x40000 else 0x20000;
115 /// create a huge page mapping
116 pub const HUGETLB = if (is_mips) 0x80000 else 0x40000;
117 /// perform synchronous page faults for the mapping
118 pub const SYNC = 0x80000;
119 /// MAP_FIXED which doesn't unmap underlying mapping
120 pub const FIXED_NOREPLACE = 0x100000;
121 /// For anonymous mmap, memory could be uninitialized
122 pub const UNINITIALIZED = 0x4000000;
123};
124
125pub const O = struct {
126 pub usingnamespace arch_bits.O;
127
128 pub const RDONLY = 0o0;
129 pub const WRONLY = 0o1;
130 pub const RDWR = 0o2;
131};
132
34pub usingnamespace @import("linux/io_uring.zig");133pub usingnamespace @import("linux/io_uring.zig");
35134
36/// Set by startup code, used by `getauxval`.135/// Set by startup code, used by `getauxval`.
...@@ -102,7 +201,7 @@ pub fn dup2(old: i32, new: i32) usize {...@@ -102,7 +201,7 @@ pub fn dup2(old: i32, new: i32) usize {
102 } else {201 } else {
103 if (old == new) {202 if (old == new) {
104 if (std.debug.runtime_safety) {203 if (std.debug.runtime_safety) {
105 const rc = syscall2(.fcntl, @bitCast(usize, @as(isize, old)), F_GETFD);204 const rc = syscall2(.fcntl, @bitCast(usize, @as(isize, old)), F.GETFD);
106 if (@bitCast(isize, rc) < 0) return rc;205 if (@bitCast(isize, rc) < 0) return rc;
107 }206 }
108 return @intCast(usize, old);207 return @intCast(usize, old);
...@@ -138,7 +237,7 @@ pub fn fork() usize {...@@ -138,7 +237,7 @@ pub fn fork() usize {
138 } else if (@hasField(SYS, "fork")) {237 } else if (@hasField(SYS, "fork")) {
139 return syscall0(.fork);238 return syscall0(.fork);
140 } else {239 } else {
141 return syscall2(.clone, SIGCHLD, 0);240 return syscall2(.clone, SIG.CHLD, 0);
142 }241 }
143}242}
144243
...@@ -229,7 +328,7 @@ pub fn readlink(noalias path: [*:0]const u8, noalias buf_ptr: [*]u8, buf_len: us...@@ -229,7 +328,7 @@ pub fn readlink(noalias path: [*:0]const u8, noalias buf_ptr: [*]u8, buf_len: us
229 if (@hasField(SYS, "readlink")) {328 if (@hasField(SYS, "readlink")) {
230 return syscall3(.readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);329 return syscall3(.readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
231 } else {330 } else {
232 return syscall4(.readlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);331 return syscall4(.readlinkat, @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
233 }332 }
234}333}
235334
...@@ -241,7 +340,7 @@ pub fn mkdir(path: [*:0]const u8, mode: u32) usize {...@@ -241,7 +340,7 @@ pub fn mkdir(path: [*:0]const u8, mode: u32) usize {
241 if (@hasField(SYS, "mkdir")) {340 if (@hasField(SYS, "mkdir")) {
242 return syscall2(.mkdir, @ptrToInt(path), mode);341 return syscall2(.mkdir, @ptrToInt(path), mode);
243 } else {342 } else {
244 return syscall3(.mkdirat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), mode);343 return syscall3(.mkdirat, @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(path), mode);
245 }344 }
246}345}
247346
...@@ -253,7 +352,7 @@ pub fn mknod(path: [*:0]const u8, mode: u32, dev: u32) usize {...@@ -253,7 +352,7 @@ pub fn mknod(path: [*:0]const u8, mode: u32, dev: u32) usize {
253 if (@hasField(SYS, "mknod")) {352 if (@hasField(SYS, "mknod")) {
254 return syscall3(.mknod, @ptrToInt(path), mode, dev);353 return syscall3(.mknod, @ptrToInt(path), mode, dev);
255 } else {354 } else {
256 return mknodat(AT_FDCWD, path, mode, dev);355 return mknodat(AT.FDCWD, path, mode, dev);
257 }356 }
258}357}
259358
...@@ -400,7 +499,7 @@ pub fn rmdir(path: [*:0]const u8) usize {...@@ -400,7 +499,7 @@ pub fn rmdir(path: [*:0]const u8) usize {
400 if (@hasField(SYS, "rmdir")) {499 if (@hasField(SYS, "rmdir")) {
401 return syscall1(.rmdir, @ptrToInt(path));500 return syscall1(.rmdir, @ptrToInt(path));
402 } else {501 } else {
403 return syscall3(.unlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), AT_REMOVEDIR);502 return syscall3(.unlinkat, @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(path), AT.REMOVEDIR);
404 }503 }
405}504}
406505
...@@ -408,7 +507,7 @@ pub fn symlink(existing: [*:0]const u8, new: [*:0]const u8) usize {...@@ -408,7 +507,7 @@ pub fn symlink(existing: [*:0]const u8, new: [*:0]const u8) usize {
408 if (@hasField(SYS, "symlink")) {507 if (@hasField(SYS, "symlink")) {
409 return syscall2(.symlink, @ptrToInt(existing), @ptrToInt(new));508 return syscall2(.symlink, @ptrToInt(existing), @ptrToInt(new));
410 } else {509 } else {
411 return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new));510 return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(new));
412 }511 }
413}512}
414513
...@@ -441,9 +540,12 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: i64) usize {...@@ -441,9 +540,12 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: i64) usize {
441 }540 }
442 } else {541 } else {
443 // Some architectures (eg. 64bit SPARC) pread is called pread64.542 // Some architectures (eg. 64bit SPARC) pread is called pread64.
444 const S = if (!@hasField(SYS, "pread") and @hasField(SYS, "pread64")) .pread64 else .pread;543 const syscall_number = if (!@hasField(SYS, "pread") and @hasField(SYS, "pread64"))
544 .pread64
545 else
546 .pread;
445 return syscall4(547 return syscall4(
446 S,548 syscall_number,
447 @bitCast(usize, @as(isize, fd)),549 @bitCast(usize, @as(isize, fd)),
448 @ptrToInt(buf),550 @ptrToInt(buf),
449 count,551 count,
...@@ -456,7 +558,7 @@ pub fn access(path: [*:0]const u8, mode: u32) usize {...@@ -456,7 +558,7 @@ pub fn access(path: [*:0]const u8, mode: u32) usize {
456 if (@hasField(SYS, "access")) {558 if (@hasField(SYS, "access")) {
457 return syscall2(.access, @ptrToInt(path), mode);559 return syscall2(.access, @ptrToInt(path), mode);
458 } else {560 } else {
459 return syscall4(.faccessat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), mode, 0);561 return syscall4(.faccessat, @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(path), mode, 0);
460 }562 }
461}563}
462564
...@@ -536,9 +638,12 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: i64) usize {...@@ -536,9 +638,12 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: i64) usize {
536 }638 }
537 } else {639 } else {
538 // Some architectures (eg. 64bit SPARC) pwrite is called pwrite64.640 // Some architectures (eg. 64bit SPARC) pwrite is called pwrite64.
539 const S = if (!@hasField(SYS, "pwrite") and @hasField(SYS, "pwrite64")) .pwrite64 else .pwrite;641 const syscall_number = if (!@hasField(SYS, "pwrite") and @hasField(SYS, "pwrite64"))
642 .pwrite64
643 else
644 .pwrite;
540 return syscall4(645 return syscall4(
541 S,646 syscall_number,
542 @bitCast(usize, @as(isize, fd)),647 @bitCast(usize, @as(isize, fd)),
543 @ptrToInt(buf),648 @ptrToInt(buf),
544 count,649 count,
...@@ -551,9 +656,9 @@ pub fn rename(old: [*:0]const u8, new: [*:0]const u8) usize {...@@ -551,9 +656,9 @@ pub fn rename(old: [*:0]const u8, new: [*:0]const u8) usize {
551 if (@hasField(SYS, "rename")) {656 if (@hasField(SYS, "rename")) {
552 return syscall2(.rename, @ptrToInt(old), @ptrToInt(new));657 return syscall2(.rename, @ptrToInt(old), @ptrToInt(new));
553 } else if (@hasField(SYS, "renameat")) {658 } else if (@hasField(SYS, "renameat")) {
554 return syscall4(.renameat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(old), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new));659 return syscall4(.renameat, @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(old), @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(new));
555 } else {660 } else {
556 return syscall5(.renameat2, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(old), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new), 0);661 return syscall5(.renameat2, @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(old), @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(new), 0);
557 }662 }
558}663}
559664
...@@ -595,7 +700,7 @@ pub fn open(path: [*:0]const u8, flags: u32, perm: mode_t) usize {...@@ -595,7 +700,7 @@ pub fn open(path: [*:0]const u8, flags: u32, perm: mode_t) usize {
595 } else {700 } else {
596 return syscall4(701 return syscall4(
597 .openat,702 .openat,
598 @bitCast(usize, @as(isize, AT_FDCWD)),703 @bitCast(usize, @as(isize, AT.FDCWD)),
599 @ptrToInt(path),704 @ptrToInt(path),
600 flags,705 flags,
601 perm,706 perm,
...@@ -608,7 +713,7 @@ pub fn create(path: [*:0]const u8, perm: mode_t) usize {...@@ -608,7 +713,7 @@ pub fn create(path: [*:0]const u8, perm: mode_t) usize {
608}713}
609714
610pub fn openat(dirfd: i32, path: [*:0]const u8, flags: u32, mode: mode_t) usize {715pub fn openat(dirfd: i32, path: [*:0]const u8, flags: u32, mode: mode_t) usize {
611 // dirfd could be negative, for example AT_FDCWD is -100716 // dirfd could be negative, for example AT.FDCWD is -100
612 return syscall4(.openat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), flags, mode);717 return syscall4(.openat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), flags, mode);
613}718}
614719
...@@ -682,9 +787,9 @@ pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) usize {...@@ -682,9 +787,9 @@ pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) usize {
682 } else {787 } else {
683 return syscall5(788 return syscall5(
684 .linkat,789 .linkat,
685 @bitCast(usize, @as(isize, AT_FDCWD)),790 @bitCast(usize, @as(isize, AT.FDCWD)),
686 @ptrToInt(oldpath),791 @ptrToInt(oldpath),
687 @bitCast(usize, @as(isize, AT_FDCWD)),792 @bitCast(usize, @as(isize, AT.FDCWD)),
688 @ptrToInt(newpath),793 @ptrToInt(newpath),
689 @bitCast(usize, @as(isize, flags)),794 @bitCast(usize, @as(isize, flags)),
690 );795 );
...@@ -706,7 +811,7 @@ pub fn unlink(path: [*:0]const u8) usize {...@@ -706,7 +811,7 @@ pub fn unlink(path: [*:0]const u8) usize {
706 if (@hasField(SYS, "unlink")) {811 if (@hasField(SYS, "unlink")) {
707 return syscall1(.unlink, @ptrToInt(path));812 return syscall1(.unlink, @ptrToInt(path));
708 } else {813 } else {
709 return syscall3(.unlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), 0);814 return syscall3(.unlinkat, @bitCast(usize, @as(isize, AT.FDCWD)), @ptrToInt(path), 0);
710 }815 }
711}816}
712817
...@@ -736,7 +841,7 @@ var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);...@@ -736,7 +841,7 @@ var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
736const vdso_clock_gettime_ty = fn (i32, *timespec) callconv(.C) usize;841const vdso_clock_gettime_ty = fn (i32, *timespec) callconv(.C) usize;
737842
738pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {843pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
739 if (@hasDecl(@This(), "VDSO_CGT_SYM")) {844 if (@hasDecl(VDSO, "CGT_SYM")) {
740 const ptr = @atomicLoad(?*const c_void, &vdso_clock_gettime, .Unordered);845 const ptr = @atomicLoad(?*const c_void, &vdso_clock_gettime, .Unordered);
741 if (ptr) |fn_ptr| {846 if (ptr) |fn_ptr| {
742 const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);847 const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);
...@@ -751,7 +856,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {...@@ -751,7 +856,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
751}856}
752857
753fn init_vdso_clock_gettime(clk: i32, ts: *timespec) callconv(.C) usize {858fn init_vdso_clock_gettime(clk: i32, ts: *timespec) callconv(.C) usize {
754 const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM));859 const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO.CGT_VER, VDSO.CGT_SYM));
755 // Note that we may not have a VDSO at all, update the stub address anyway860 // Note that we may not have a VDSO at all, update the stub address anyway
756 // so that clock_gettime will fall back on the good old (and slow) syscall861 // so that clock_gettime will fall back on the good old (and slow) syscall
757 @atomicStore(?*const c_void, &vdso_clock_gettime, ptr, .Monotonic);862 @atomicStore(?*const c_void, &vdso_clock_gettime, ptr, .Monotonic);
...@@ -931,18 +1036,18 @@ pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*...@@ -931,18 +1036,18 @@ pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*
9311036
932pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize {1037pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize {
933 assert(sig >= 1);1038 assert(sig >= 1);
934 assert(sig != SIGKILL);1039 assert(sig != SIG.KILL);
935 assert(sig != SIGSTOP);1040 assert(sig != SIG.STOP);
9361041
937 var ksa: k_sigaction = undefined;1042 var ksa: k_sigaction = undefined;
938 var oldksa: k_sigaction = undefined;1043 var oldksa: k_sigaction = undefined;
939 const mask_size = @sizeOf(@TypeOf(ksa.mask));1044 const mask_size = @sizeOf(@TypeOf(ksa.mask));
9401045
941 if (act) |new| {1046 if (act) |new| {
942 const restorer_fn = if ((new.flags & SA_SIGINFO) != 0) restore_rt else restore;1047 const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) restore_rt else restore;
943 ksa = k_sigaction{1048 ksa = k_sigaction{
944 .handler = new.handler.handler,1049 .handler = new.handler.handler,
945 .flags = new.flags | SA_RESTORER,1050 .flags = new.flags | SA.RESTORER,
946 .mask = undefined,1051 .mask = undefined,
947 .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn),1052 .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn),
948 };1053 };
...@@ -985,42 +1090,42 @@ pub fn sigismember(set: *const sigset_t, sig: u6) bool {...@@ -985,42 +1090,42 @@ pub fn sigismember(set: *const sigset_t, sig: u6) bool {
9851090
986pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {1091pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
987 if (native_arch == .i386) {1092 if (native_arch == .i386) {
988 return socketcall(SC_getsockname, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len) });1093 return socketcall(SC.getsockname, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len) });
989 }1094 }
990 return syscall3(.getsockname, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));1095 return syscall3(.getsockname, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));
991}1096}
9921097
993pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {1098pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
994 if (native_arch == .i386) {1099 if (native_arch == .i386) {
995 return socketcall(SC_getpeername, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len) });1100 return socketcall(SC.getpeername, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len) });
996 }1101 }
997 return syscall3(.getpeername, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));1102 return syscall3(.getpeername, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));
998}1103}
9991104
1000pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {1105pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
1001 if (native_arch == .i386) {1106 if (native_arch == .i386) {
1002 return socketcall(SC_socket, &[3]usize{ domain, socket_type, protocol });1107 return socketcall(SC.socket, &[3]usize{ domain, socket_type, protocol });
1003 }1108 }
1004 return syscall3(.socket, domain, socket_type, protocol);1109 return syscall3(.socket, domain, socket_type, protocol);
1005}1110}
10061111
1007pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {1112pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {
1008 if (native_arch == .i386) {1113 if (native_arch == .i386) {
1009 return socketcall(SC_setsockopt, &[5]usize{ @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen) });1114 return socketcall(SC.setsockopt, &[5]usize{ @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen) });
1010 }1115 }
1011 return syscall5(.setsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));1116 return syscall5(.setsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));
1012}1117}
10131118
1014pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {1119pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {
1015 if (native_arch == .i386) {1120 if (native_arch == .i386) {
1016 return socketcall(SC_getsockopt, &[5]usize{ @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen) });1121 return socketcall(SC.getsockopt, &[5]usize{ @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen) });
1017 }1122 }
1018 return syscall5(.getsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));1123 return syscall5(.getsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
1019}1124}
10201125
1021pub fn sendmsg(fd: i32, msg: *const std.x.os.Socket.Message, flags: c_int) usize {1126pub fn sendmsg(fd: i32, msg: *const std.x.os.Socket.Message, flags: c_int) usize {
1022 if (native_arch == .i386) {1127 if (native_arch == .i386) {
1023 return socketcall(SC_sendmsg, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), @bitCast(usize, @as(isize, flags)) });1128 return socketcall(SC.sendmsg, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), @bitCast(usize, @as(isize, flags)) });
1024 }1129 }
1025 return syscall3(.sendmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), @bitCast(usize, @as(isize, flags)));1130 return syscall3(.sendmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), @bitCast(usize, @as(isize, flags)));
1026}1131}
...@@ -1054,7 +1159,7 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize...@@ -1054,7 +1159,7 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
1054 }1159 }
1055 }1160 }
1056 }1161 }
1057 if (next_unsent < kvlen or next_unsent == 0) { // want to make sure at least one syscall occurs (e.g. to trigger MSG_EOR)1162 if (next_unsent < kvlen or next_unsent == 0) { // want to make sure at least one syscall occurs (e.g. to trigger MSG.EOR)
1058 const batch_size = kvlen - next_unsent;1163 const batch_size = kvlen - next_unsent;
1059 const r = syscall4(.sendmmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);1164 const r = syscall4(.sendmmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
1060 if (getErrno(r) != 0) return r;1165 if (getErrno(r) != 0) return r;
...@@ -1067,49 +1172,49 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize...@@ -1067,49 +1172,49 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
10671172
1068pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {1173pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {
1069 if (native_arch == .i386) {1174 if (native_arch == .i386) {
1070 return socketcall(SC_connect, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len });1175 return socketcall(SC.connect, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len });
1071 }1176 }
1072 return syscall3(.connect, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len);1177 return syscall3(.connect, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len);
1073}1178}
10741179
1075pub fn recvmsg(fd: i32, msg: *std.x.os.Socket.Message, flags: c_int) usize {1180pub fn recvmsg(fd: i32, msg: *std.x.os.Socket.Message, flags: c_int) usize {
1076 if (native_arch == .i386) {1181 if (native_arch == .i386) {
1077 return socketcall(SC_recvmsg, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), @bitCast(usize, @as(isize, flags)) });1182 return socketcall(SC.recvmsg, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), @bitCast(usize, @as(isize, flags)) });
1078 }1183 }
1079 return syscall3(.recvmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), @bitCast(usize, @as(isize, flags)));1184 return syscall3(.recvmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), @bitCast(usize, @as(isize, flags)));
1080}1185}
10811186
1082pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {1187pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {
1083 if (native_arch == .i386) {1188 if (native_arch == .i386) {
1084 return socketcall(SC_recvfrom, &[6]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen) });1189 return socketcall(SC.recvfrom, &[6]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen) });
1085 }1190 }
1086 return syscall6(.recvfrom, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));1191 return syscall6(.recvfrom, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
1087}1192}
10881193
1089pub fn shutdown(fd: i32, how: i32) usize {1194pub fn shutdown(fd: i32, how: i32) usize {
1090 if (native_arch == .i386) {1195 if (native_arch == .i386) {
1091 return socketcall(SC_shutdown, &[2]usize{ @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)) });1196 return socketcall(SC.shutdown, &[2]usize{ @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)) });
1092 }1197 }
1093 return syscall2(.shutdown, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)));1198 return syscall2(.shutdown, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)));
1094}1199}
10951200
1096pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {1201pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {
1097 if (native_arch == .i386) {1202 if (native_arch == .i386) {
1098 return socketcall(SC_bind, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len) });1203 return socketcall(SC.bind, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len) });
1099 }1204 }
1100 return syscall3(.bind, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len));1205 return syscall3(.bind, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len));
1101}1206}
11021207
1103pub fn listen(fd: i32, backlog: u32) usize {1208pub fn listen(fd: i32, backlog: u32) usize {
1104 if (native_arch == .i386) {1209 if (native_arch == .i386) {
1105 return socketcall(SC_listen, &[2]usize{ @bitCast(usize, @as(isize, fd)), backlog });1210 return socketcall(SC.listen, &[2]usize{ @bitCast(usize, @as(isize, fd)), backlog });
1106 }1211 }
1107 return syscall2(.listen, @bitCast(usize, @as(isize, fd)), backlog);1212 return syscall2(.listen, @bitCast(usize, @as(isize, fd)), backlog);
1108}1213}
11091214
1110pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {1215pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {
1111 if (native_arch == .i386) {1216 if (native_arch == .i386) {
1112 return socketcall(SC_sendto, &[6]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen) });1217 return socketcall(SC.sendto, &[6]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen) });
1113 }1218 }
1114 return syscall6(.sendto, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));1219 return syscall6(.sendto, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));
1115}1220}
...@@ -1136,26 +1241,26 @@ pub fn sendfile(outfd: i32, infd: i32, offset: ?*i64, count: usize) usize {...@@ -1136,26 +1241,26 @@ pub fn sendfile(outfd: i32, infd: i32, offset: ?*i64, count: usize) usize {
11361241
1137pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {1242pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {
1138 if (native_arch == .i386) {1243 if (native_arch == .i386) {
1139 return socketcall(SC_socketpair, &[4]usize{ @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0]) });1244 return socketcall(SC.socketpair, &[4]usize{ @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0]) });
1140 }1245 }
1141 return syscall4(.socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0]));1246 return syscall4(.socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0]));
1142}1247}
11431248
1144pub fn accept(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t) usize {1249pub fn accept(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t) usize {
1145 if (native_arch == .i386) {1250 if (native_arch == .i386) {
1146 return socketcall(SC_accept, &[4]usize{ fd, addr, len, 0 });1251 return socketcall(SC.accept, &[4]usize{ fd, addr, len, 0 });
1147 }1252 }
1148 return accept4(fd, addr, len, 0);1253 return accept4(fd, addr, len, 0);
1149}1254}
11501255
1151pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flags: u32) usize {1256pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flags: u32) usize {
1152 if (native_arch == .i386) {1257 if (native_arch == .i386) {
1153 return socketcall(SC_accept4, &[4]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags });1258 return socketcall(SC.accept4, &[4]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags });
1154 }1259 }
1155 return syscall4(.accept4, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags);1260 return syscall4(.accept4, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags);
1156}1261}
11571262
1158pub fn fstat(fd: i32, stat_buf: *kernel_stat) usize {1263pub fn fstat(fd: i32, stat_buf: *Stat) usize {
1159 if (@hasField(SYS, "fstat64")) {1264 if (@hasField(SYS, "fstat64")) {
1160 return syscall2(.fstat64, @bitCast(usize, @as(isize, fd)), @ptrToInt(stat_buf));1265 return syscall2(.fstat64, @bitCast(usize, @as(isize, fd)), @ptrToInt(stat_buf));
1161 } else {1266 } else {
...@@ -1163,7 +1268,7 @@ pub fn fstat(fd: i32, stat_buf: *kernel_stat) usize {...@@ -1163,7 +1268,7 @@ pub fn fstat(fd: i32, stat_buf: *kernel_stat) usize {
1163 }1268 }
1164}1269}
11651270
1166pub fn stat(pathname: [*:0]const u8, statbuf: *kernel_stat) usize {1271pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize {
1167 if (@hasField(SYS, "stat64")) {1272 if (@hasField(SYS, "stat64")) {
1168 return syscall2(.stat64, @ptrToInt(pathname), @ptrToInt(statbuf));1273 return syscall2(.stat64, @ptrToInt(pathname), @ptrToInt(statbuf));
1169 } else {1274 } else {
...@@ -1171,7 +1276,7 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *kernel_stat) usize {...@@ -1171,7 +1276,7 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *kernel_stat) usize {
1171 }1276 }
1172}1277}
11731278
1174pub fn lstat(pathname: [*:0]const u8, statbuf: *kernel_stat) usize {1279pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize {
1175 if (@hasField(SYS, "lstat64")) {1280 if (@hasField(SYS, "lstat64")) {
1176 return syscall2(.lstat64, @ptrToInt(pathname), @ptrToInt(statbuf));1281 return syscall2(.lstat64, @ptrToInt(pathname), @ptrToInt(statbuf));
1177 } else {1282 } else {
...@@ -1179,7 +1284,7 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *kernel_stat) usize {...@@ -1179,7 +1284,7 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *kernel_stat) usize {
1179 }1284 }
1180}1285}
11811286
1182pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *kernel_stat, flags: u32) usize {1287pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usize {
1183 if (@hasField(SYS, "fstatat64")) {1288 if (@hasField(SYS, "fstatat64")) {
1184 return syscall4(.fstatat64, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);1289 return syscall4(.fstatat64, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
1185 } else {1290 } else {
...@@ -1350,11 +1455,11 @@ pub fn getrusage(who: i32, usage: *rusage) usize {...@@ -1350,11 +1455,11 @@ pub fn getrusage(who: i32, usage: *rusage) usize {
1350}1455}
13511456
1352pub fn tcgetattr(fd: fd_t, termios_p: *termios) usize {1457pub fn tcgetattr(fd: fd_t, termios_p: *termios) usize {
1353 return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), TCGETS, @ptrToInt(termios_p));1458 return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), T.CGETS, @ptrToInt(termios_p));
1354}1459}
13551460
1356pub fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) usize {1461pub fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) usize {
1357 return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), TCSETS + @enumToInt(optional_action), @ptrToInt(termios_p));1462 return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), T.CSETS + @enumToInt(optional_action), @ptrToInt(termios_p));
1358}1463}
13591464
1360pub fn ioctl(fd: fd_t, request: u32, arg: usize) usize {1465pub fn ioctl(fd: fd_t, request: u32, arg: usize) usize {
...@@ -1531,8 +1636,3289 @@ pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize {...@@ -1531,8 +1636,3289 @@ pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize {
1531 }1636 }
1532}1637}
15331638
1534test {1639pub const E = switch (native_arch) {
1535 if (std.Target.current.os.tag == .linux) {1640 .mips, .mipsel => @import("linux/errno/mips.zig").E,
1536 _ = @import("linux/test.zig");1641 .sparc, .sparcel, .sparcv9 => @import("linux/errno/sparc.zig").E,
1642 else => @import("linux/errno/generic.zig").E,
1643};
1644
1645pub const pid_t = i32;
1646pub const fd_t = i32;
1647pub const uid_t = u32;
1648pub const gid_t = u32;
1649pub const clock_t = isize;
1650
1651pub const NAME_MAX = 255;
1652pub const PATH_MAX = 4096;
1653pub const IOV_MAX = 1024;
1654
1655/// Largest hardware address length
1656/// e.g. a mac address is a type of hardware address
1657pub const MAX_ADDR_LEN = 32;
1658
1659pub const STDIN_FILENO = 0;
1660pub const STDOUT_FILENO = 1;
1661pub const STDERR_FILENO = 2;
1662
1663pub const AT = struct {
1664 /// Special value used to indicate openat should use the current working directory
1665 pub const FDCWD = -100;
1666
1667 /// Do not follow symbolic links
1668 pub const SYMLINK_NOFOLLOW = 0x100;
1669
1670 /// Remove directory instead of unlinking file
1671 pub const REMOVEDIR = 0x200;
1672
1673 /// Follow symbolic links.
1674 pub const SYMLINK_FOLLOW = 0x400;
1675
1676 /// Suppress terminal automount traversal
1677 pub const NO_AUTOMOUNT = 0x800;
1678
1679 /// Allow empty relative pathname
1680 pub const EMPTY_PATH = 0x1000;
1681
1682 /// Type of synchronisation required from statx()
1683 pub const STATX_SYNC_TYPE = 0x6000;
1684
1685 /// - Do whatever stat() does
1686 pub const STATX_SYNC_AS_STAT = 0x0000;
1687
1688 /// - Force the attributes to be sync'd with the server
1689 pub const STATX_FORCE_SYNC = 0x2000;
1690
1691 /// - Don't sync attributes with the server
1692 pub const STATX_DONT_SYNC = 0x4000;
1693
1694 /// Apply to the entire subtree
1695 pub const RECURSIVE = 0x8000;
1696};
1697
1698pub const FALLOC = struct {
1699 /// Default is extend size
1700 pub const FL_KEEP_SIZE = 0x01;
1701
1702 /// De-allocates range
1703 pub const FL_PUNCH_HOLE = 0x02;
1704
1705 /// Reserved codepoint
1706 pub const FL_NO_HIDE_STALE = 0x04;
1707
1708 /// Removes a range of a file without leaving a hole in the file
1709 pub const FL_COLLAPSE_RANGE = 0x08;
1710
1711 /// Converts a range of file to zeros preferably without issuing data IO
1712 pub const FL_ZERO_RANGE = 0x10;
1713
1714 /// Inserts space within the file size without overwriting any existing data
1715 pub const FL_INSERT_RANGE = 0x20;
1716
1717 /// Unshares shared blocks within the file size without overwriting any existing data
1718 pub const FL_UNSHARE_RANGE = 0x40;
1719};
1720
1721pub const FUTEX = struct {
1722 pub const WAIT = 0;
1723 pub const WAKE = 1;
1724 pub const FD = 2;
1725 pub const REQUEUE = 3;
1726 pub const CMP_REQUEUE = 4;
1727 pub const WAKE_OP = 5;
1728 pub const LOCK_PI = 6;
1729 pub const UNLOCK_PI = 7;
1730 pub const TRYLOCK_PI = 8;
1731 pub const WAIT_BITSET = 9;
1732 pub const WAKE_BITSET = 10;
1733 pub const WAIT_REQUEUE_PI = 11;
1734 pub const CMP_REQUEUE_PI = 12;
1735
1736 pub const PRIVATE_FLAG = 128;
1737
1738 pub const CLOCK_REALTIME = 256;
1739};
1740
1741pub const PROT = struct {
1742 /// page can not be accessed
1743 pub const NONE = 0x0;
1744 /// page can be read
1745 pub const READ = 0x1;
1746 /// page can be written
1747 pub const WRITE = 0x2;
1748 /// page can be executed
1749 pub const EXEC = 0x4;
1750 /// page may be used for atomic ops
1751 pub const SEM = switch (native_arch) {
1752 // TODO: also xtensa
1753 .mips, .mipsel, .mips64, .mips64el => 0x10,
1754 else => 0x8,
1755 };
1756 /// mprotect flag: extend change to start of growsdown vma
1757 pub const GROWSDOWN = 0x01000000;
1758 /// mprotect flag: extend change to end of growsup vma
1759 pub const GROWSUP = 0x02000000;
1760};
1761
1762pub const FD_CLOEXEC = 1;
1763
1764pub const F_OK = 0;
1765pub const X_OK = 1;
1766pub const W_OK = 2;
1767pub const R_OK = 4;
1768
1769pub const W = struct {
1770 pub const NOHANG = 1;
1771 pub const UNTRACED = 2;
1772 pub const STOPPED = 2;
1773 pub const EXITED = 4;
1774 pub const CONTINUED = 8;
1775 pub const NOWAIT = 0x1000000;
1776
1777 pub fn EXITSTATUS(s: u32) u8 {
1778 return @intCast(u8, (s & 0xff00) >> 8);
1779 }
1780 pub fn TERMSIG(s: u32) u32 {
1781 return s & 0x7f;
1782 }
1783 pub fn STOPSIG(s: u32) u32 {
1784 return EXITSTATUS(s);
1785 }
1786 pub fn IFEXITED(s: u32) bool {
1787 return TERMSIG(s) == 0;
1788 }
1789 pub fn IFSTOPPED(s: u32) bool {
1790 return @truncate(u16, ((s & 0xffff) *% 0x10001) >> 8) > 0x7f00;
1791 }
1792 pub fn IFSIGNALED(s: u32) bool {
1793 return (s & 0xffff) -% 1 < 0xff;
1794 }
1795};
1796
1797// waitid id types
1798pub const P = enum(c_uint) {
1799 ALL = 0,
1800 PID = 1,
1801 PGID = 2,
1802 PIDFD = 3,
1803 _,
1804};
1805
1806pub const SA = if (is_mips) struct {
1807 pub const NOCLDSTOP = 1;
1808 pub const NOCLDWAIT = 0x10000;
1809 pub const SIGINFO = 8;
1810 pub const RESTART = 0x10000000;
1811 pub const RESETHAND = 0x80000000;
1812 pub const ONSTACK = 0x08000000;
1813 pub const NODEFER = 0x40000000;
1814 pub const RESTORER = 0x04000000;
1815} else if (is_sparc) struct {
1816 pub const NOCLDSTOP = 0x8;
1817 pub const NOCLDWAIT = 0x100;
1818 pub const SIGINFO = 0x200;
1819 pub const RESTART = 0x2;
1820 pub const RESETHAND = 0x4;
1821 pub const ONSTACK = 0x1;
1822 pub const NODEFER = 0x20;
1823 pub const RESTORER = 0x04000000;
1824} else struct {
1825 pub const NOCLDSTOP = 1;
1826 pub const NOCLDWAIT = 2;
1827 pub const SIGINFO = 4;
1828 pub const RESTART = 0x10000000;
1829 pub const RESETHAND = 0x80000000;
1830 pub const ONSTACK = 0x08000000;
1831 pub const NODEFER = 0x40000000;
1832 pub const RESTORER = 0x04000000;
1833};
1834
1835pub const SIG = if (is_mips) struct {
1836 pub const BLOCK = 1;
1837 pub const UNBLOCK = 2;
1838 pub const SETMASK = 3;
1839
1840 pub const HUP = 1;
1841 pub const INT = 2;
1842 pub const QUIT = 3;
1843 pub const ILL = 4;
1844 pub const TRAP = 5;
1845 pub const ABRT = 6;
1846 pub const IOT = ABRT;
1847 pub const BUS = 7;
1848 pub const FPE = 8;
1849 pub const KILL = 9;
1850 pub const USR1 = 10;
1851 pub const SEGV = 11;
1852 pub const USR2 = 12;
1853 pub const PIPE = 13;
1854 pub const ALRM = 14;
1855 pub const TERM = 15;
1856 pub const STKFLT = 16;
1857 pub const CHLD = 17;
1858 pub const CONT = 18;
1859 pub const STOP = 19;
1860 pub const TSTP = 20;
1861 pub const TTIN = 21;
1862 pub const TTOU = 22;
1863 pub const URG = 23;
1864 pub const XCPU = 24;
1865 pub const XFSZ = 25;
1866 pub const VTALRM = 26;
1867 pub const PROF = 27;
1868 pub const WINCH = 28;
1869 pub const IO = 29;
1870 pub const POLL = 29;
1871 pub const PWR = 30;
1872 pub const SYS = 31;
1873 pub const UNUSED = SIG.SYS;
1874
1875 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
1876 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
1877 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
1878} else if (is_sparc) struct {
1879 pub const BLOCK = 1;
1880 pub const UNBLOCK = 2;
1881 pub const SETMASK = 4;
1882
1883 pub const HUP = 1;
1884 pub const INT = 2;
1885 pub const QUIT = 3;
1886 pub const ILL = 4;
1887 pub const TRAP = 5;
1888 pub const ABRT = 6;
1889 pub const EMT = 7;
1890 pub const FPE = 8;
1891 pub const KILL = 9;
1892 pub const BUS = 10;
1893 pub const SEGV = 11;
1894 pub const SYS = 12;
1895 pub const PIPE = 13;
1896 pub const ALRM = 14;
1897 pub const TERM = 15;
1898 pub const URG = 16;
1899 pub const STOP = 17;
1900 pub const TSTP = 18;
1901 pub const CONT = 19;
1902 pub const CHLD = 20;
1903 pub const TTIN = 21;
1904 pub const TTOU = 22;
1905 pub const POLL = 23;
1906 pub const XCPU = 24;
1907 pub const XFSZ = 25;
1908 pub const VTALRM = 26;
1909 pub const PROF = 27;
1910 pub const WINCH = 28;
1911 pub const LOST = 29;
1912 pub const USR1 = 30;
1913 pub const USR2 = 31;
1914 pub const IOT = ABRT;
1915 pub const CLD = CHLD;
1916 pub const PWR = LOST;
1917 pub const IO = SIG.POLL;
1918
1919 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
1920 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
1921 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
1922} else struct {
1923 pub const BLOCK = 0;
1924 pub const UNBLOCK = 1;
1925 pub const SETMASK = 2;
1926
1927 pub const HUP = 1;
1928 pub const INT = 2;
1929 pub const QUIT = 3;
1930 pub const ILL = 4;
1931 pub const TRAP = 5;
1932 pub const ABRT = 6;
1933 pub const IOT = ABRT;
1934 pub const BUS = 7;
1935 pub const FPE = 8;
1936 pub const KILL = 9;
1937 pub const USR1 = 10;
1938 pub const SEGV = 11;
1939 pub const USR2 = 12;
1940 pub const PIPE = 13;
1941 pub const ALRM = 14;
1942 pub const TERM = 15;
1943 pub const STKFLT = 16;
1944 pub const CHLD = 17;
1945 pub const CONT = 18;
1946 pub const STOP = 19;
1947 pub const TSTP = 20;
1948 pub const TTIN = 21;
1949 pub const TTOU = 22;
1950 pub const URG = 23;
1951 pub const XCPU = 24;
1952 pub const XFSZ = 25;
1953 pub const VTALRM = 26;
1954 pub const PROF = 27;
1955 pub const WINCH = 28;
1956 pub const IO = 29;
1957 pub const POLL = 29;
1958 pub const PWR = 30;
1959 pub const SYS = 31;
1960 pub const UNUSED = SIG.SYS;
1961
1962 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
1963 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
1964 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
1965};
1966
1967pub const kernel_rwf = u32;
1968
1969pub const RWF = struct {
1970 /// high priority request, poll if possible
1971 pub const HIPRI: kernel_rwf = 0x00000001;
1972
1973 /// per-IO O.DSYNC
1974 pub const DSYNC: kernel_rwf = 0x00000002;
1975
1976 /// per-IO O.SYNC
1977 pub const SYNC: kernel_rwf = 0x00000004;
1978
1979 /// per-IO, return -EAGAIN if operation would block
1980 pub const NOWAIT: kernel_rwf = 0x00000008;
1981
1982 /// per-IO O.APPEND
1983 pub const APPEND: kernel_rwf = 0x00000010;
1984};
1985
1986pub const SEEK = struct {
1987 pub const SET = 0;
1988 pub const CUR = 1;
1989 pub const END = 2;
1990};
1991
1992pub const SHUT = struct {
1993 pub const RD = 0;
1994 pub const WR = 1;
1995 pub const RDWR = 2;
1996};
1997
1998pub const SOCK = struct {
1999 pub const STREAM = if (is_mips) 2 else 1;
2000 pub const DGRAM = if (is_mips) 1 else 2;
2001 pub const RAW = 3;
2002 pub const RDM = 4;
2003 pub const SEQPACKET = 5;
2004 pub const DCCP = 6;
2005 pub const PACKET = 10;
2006 pub const CLOEXEC = 0o2000000;
2007 pub const NONBLOCK = if (is_mips) 0o200 else 0o4000;
2008};
2009
2010pub const TCP = struct {
2011 /// Turn off Nagle's algorithm
2012 pub const NODELAY = 1;
2013 /// Limit MSS
2014 pub const MAXSEG = 2;
2015 /// Never send partially complete segments.
2016 pub const CORK = 3;
2017 /// Start keeplives after this period, in seconds
2018 pub const KEEPIDLE = 4;
2019 /// Interval between keepalives
2020 pub const KEEPINTVL = 5;
2021 /// Number of keepalives before death
2022 pub const KEEPCNT = 6;
2023 /// Number of SYN retransmits
2024 pub const SYNCNT = 7;
2025 /// Life time of orphaned FIN-WAIT-2 state
2026 pub const LINGER2 = 8;
2027 /// Wake up listener only when data arrive
2028 pub const DEFER_ACCEPT = 9;
2029 /// Bound advertised window
2030 pub const WINDOW_CLAMP = 10;
2031 /// Information about this connection.
2032 pub const INFO = 11;
2033 /// Block/reenable quick acks
2034 pub const QUICKACK = 12;
2035 /// Congestion control algorithm
2036 pub const CONGESTION = 13;
2037 /// TCP MD5 Signature (RFC2385)
2038 pub const MD5SIG = 14;
2039 /// Use linear timeouts for thin streams
2040 pub const THIN_LINEAR_TIMEOUTS = 16;
2041 /// Fast retrans. after 1 dupack
2042 pub const THIN_DUPACK = 17;
2043 /// How long for loss retry before timeout
2044 pub const USER_TIMEOUT = 18;
2045 /// TCP sock is under repair right now
2046 pub const REPAIR = 19;
2047 pub const REPAIR_QUEUE = 20;
2048 pub const QUEUE_SEQ = 21;
2049 pub const REPAIR_OPTIONS = 22;
2050 /// Enable FastOpen on listeners
2051 pub const FASTOPEN = 23;
2052 pub const TIMESTAMP = 24;
2053 /// limit number of unsent bytes in write queue
2054 pub const NOTSENT_LOWAT = 25;
2055 /// Get Congestion Control (optional) info
2056 pub const CC_INFO = 26;
2057 /// Record SYN headers for new connections
2058 pub const SAVE_SYN = 27;
2059 /// Get SYN headers recorded for connection
2060 pub const SAVED_SYN = 28;
2061 /// Get/set window parameters
2062 pub const REPAIR_WINDOW = 29;
2063 /// Attempt FastOpen with connect
2064 pub const FASTOPEN_CONNECT = 30;
2065 /// Attach a ULP to a TCP connection
2066 pub const ULP = 31;
2067 /// TCP MD5 Signature with extensions
2068 pub const MD5SIG_EXT = 32;
2069 /// Set the key for Fast Open (cookie)
2070 pub const FASTOPEN_KEY = 33;
2071 /// Enable TFO without a TFO cookie
2072 pub const FASTOPEN_NO_COOKIE = 34;
2073 pub const ZEROCOPY_RECEIVE = 35;
2074 /// Notify bytes available to read as a cmsg on read
2075 pub const INQ = 36;
2076 pub const CM_INQ = INQ;
2077 /// delay outgoing packets by XX usec
2078 pub const TX_DELAY = 37;
2079
2080 pub const REPAIR_ON = 1;
2081 pub const REPAIR_OFF = 0;
2082 /// Turn off without window probes
2083 pub const REPAIR_OFF_NO_WP = -1;
2084};
2085
2086pub const PF = struct {
2087 pub const UNSPEC = 0;
2088 pub const LOCAL = 1;
2089 pub const UNIX = LOCAL;
2090 pub const FILE = LOCAL;
2091 pub const INET = 2;
2092 pub const AX25 = 3;
2093 pub const IPX = 4;
2094 pub const APPLETALK = 5;
2095 pub const NETROM = 6;
2096 pub const BRIDGE = 7;
2097 pub const ATMPVC = 8;
2098 pub const X25 = 9;
2099 pub const INET6 = 10;
2100 pub const ROSE = 11;
2101 pub const DECnet = 12;
2102 pub const NETBEUI = 13;
2103 pub const SECURITY = 14;
2104 pub const KEY = 15;
2105 pub const NETLINK = 16;
2106 pub const ROUTE = PF.NETLINK;
2107 pub const PACKET = 17;
2108 pub const ASH = 18;
2109 pub const ECONET = 19;
2110 pub const ATMSVC = 20;
2111 pub const RDS = 21;
2112 pub const SNA = 22;
2113 pub const IRDA = 23;
2114 pub const PPPOX = 24;
2115 pub const WANPIPE = 25;
2116 pub const LLC = 26;
2117 pub const IB = 27;
2118 pub const MPLS = 28;
2119 pub const CAN = 29;
2120 pub const TIPC = 30;
2121 pub const BLUETOOTH = 31;
2122 pub const IUCV = 32;
2123 pub const RXRPC = 33;
2124 pub const ISDN = 34;
2125 pub const PHONET = 35;
2126 pub const IEEE802154 = 36;
2127 pub const CAIF = 37;
2128 pub const ALG = 38;
2129 pub const NFC = 39;
2130 pub const VSOCK = 40;
2131 pub const KCM = 41;
2132 pub const QIPCRTR = 42;
2133 pub const SMC = 43;
2134 pub const XDP = 44;
2135 pub const MAX = 45;
2136};
2137
2138pub const AF = struct {
2139 pub const UNSPEC = PF.UNSPEC;
2140 pub const LOCAL = PF.LOCAL;
2141 pub const UNIX = AF.LOCAL;
2142 pub const FILE = AF.LOCAL;
2143 pub const INET = PF.INET;
2144 pub const AX25 = PF.AX25;
2145 pub const IPX = PF.IPX;
2146 pub const APPLETALK = PF.APPLETALK;
2147 pub const NETROM = PF.NETROM;
2148 pub const BRIDGE = PF.BRIDGE;
2149 pub const ATMPVC = PF.ATMPVC;
2150 pub const X25 = PF.X25;
2151 pub const INET6 = PF.INET6;
2152 pub const ROSE = PF.ROSE;
2153 pub const DECnet = PF.DECnet;
2154 pub const NETBEUI = PF.NETBEUI;
2155 pub const SECURITY = PF.SECURITY;
2156 pub const KEY = PF.KEY;
2157 pub const NETLINK = PF.NETLINK;
2158 pub const ROUTE = PF.ROUTE;
2159 pub const PACKET = PF.PACKET;
2160 pub const ASH = PF.ASH;
2161 pub const ECONET = PF.ECONET;
2162 pub const ATMSVC = PF.ATMSVC;
2163 pub const RDS = PF.RDS;
2164 pub const SNA = PF.SNA;
2165 pub const IRDA = PF.IRDA;
2166 pub const PPPOX = PF.PPPOX;
2167 pub const WANPIPE = PF.WANPIPE;
2168 pub const LLC = PF.LLC;
2169 pub const IB = PF.IB;
2170 pub const MPLS = PF.MPLS;
2171 pub const CAN = PF.CAN;
2172 pub const TIPC = PF.TIPC;
2173 pub const BLUETOOTH = PF.BLUETOOTH;
2174 pub const IUCV = PF.IUCV;
2175 pub const RXRPC = PF.RXRPC;
2176 pub const ISDN = PF.ISDN;
2177 pub const PHONET = PF.PHONET;
2178 pub const IEEE802154 = PF.IEEE802154;
2179 pub const CAIF = PF.CAIF;
2180 pub const ALG = PF.ALG;
2181 pub const NFC = PF.NFC;
2182 pub const VSOCK = PF.VSOCK;
2183 pub const KCM = PF.KCM;
2184 pub const QIPCRTR = PF.QIPCRTR;
2185 pub const SMC = PF.SMC;
2186 pub const XDP = PF.XDP;
2187 pub const MAX = PF.MAX;
2188};
2189
2190pub const SO = struct {
2191 pub usingnamespace if (is_mips) struct {
2192 pub const DEBUG = 1;
2193 pub const REUSEADDR = 0x0004;
2194 pub const KEEPALIVE = 0x0008;
2195 pub const DONTROUTE = 0x0010;
2196 pub const BROADCAST = 0x0020;
2197 pub const LINGER = 0x0080;
2198 pub const OOBINLINE = 0x0100;
2199 pub const REUSEPORT = 0x0200;
2200 pub const SNDBUF = 0x1001;
2201 pub const RCVBUF = 0x1002;
2202 pub const SNDLOWAT = 0x1003;
2203 pub const RCVLOWAT = 0x1004;
2204 pub const RCVTIMEO = 0x1006;
2205 pub const SNDTIMEO = 0x1005;
2206 pub const ERROR = 0x1007;
2207 pub const TYPE = 0x1008;
2208 pub const ACCEPTCONN = 0x1009;
2209 pub const PROTOCOL = 0x1028;
2210 pub const DOMAIN = 0x1029;
2211 pub const NO_CHECK = 11;
2212 pub const PRIORITY = 12;
2213 pub const BSDCOMPAT = 14;
2214 pub const PASSCRED = 17;
2215 pub const PEERCRED = 18;
2216 pub const PEERSEC = 30;
2217 pub const SNDBUFFORCE = 31;
2218 pub const RCVBUFFORCE = 33;
2219 } else if (is_ppc or is_ppc64) struct {
2220 pub const DEBUG = 1;
2221 pub const REUSEADDR = 2;
2222 pub const TYPE = 3;
2223 pub const ERROR = 4;
2224 pub const DONTROUTE = 5;
2225 pub const BROADCAST = 6;
2226 pub const SNDBUF = 7;
2227 pub const RCVBUF = 8;
2228 pub const KEEPALIVE = 9;
2229 pub const OOBINLINE = 10;
2230 pub const NO_CHECK = 11;
2231 pub const PRIORITY = 12;
2232 pub const LINGER = 13;
2233 pub const BSDCOMPAT = 14;
2234 pub const REUSEPORT = 15;
2235 pub const RCVLOWAT = 16;
2236 pub const SNDLOWAT = 17;
2237 pub const RCVTIMEO = 18;
2238 pub const SNDTIMEO = 19;
2239 pub const PASSCRED = 20;
2240 pub const PEERCRED = 21;
2241 pub const ACCEPTCONN = 30;
2242 pub const PEERSEC = 31;
2243 pub const SNDBUFFORCE = 32;
2244 pub const RCVBUFFORCE = 33;
2245 pub const PROTOCOL = 38;
2246 pub const DOMAIN = 39;
2247 } else struct {
2248 pub const DEBUG = 1;
2249 pub const REUSEADDR = 2;
2250 pub const TYPE = 3;
2251 pub const ERROR = 4;
2252 pub const DONTROUTE = 5;
2253 pub const BROADCAST = 6;
2254 pub const SNDBUF = 7;
2255 pub const RCVBUF = 8;
2256 pub const KEEPALIVE = 9;
2257 pub const OOBINLINE = 10;
2258 pub const NO_CHECK = 11;
2259 pub const PRIORITY = 12;
2260 pub const LINGER = 13;
2261 pub const BSDCOMPAT = 14;
2262 pub const REUSEPORT = 15;
2263 pub const PASSCRED = 16;
2264 pub const PEERCRED = 17;
2265 pub const RCVLOWAT = 18;
2266 pub const SNDLOWAT = 19;
2267 pub const RCVTIMEO = 20;
2268 pub const SNDTIMEO = 21;
2269 pub const ACCEPTCONN = 30;
2270 pub const PEERSEC = 31;
2271 pub const SNDBUFFORCE = 32;
2272 pub const RCVBUFFORCE = 33;
2273 pub const PROTOCOL = 38;
2274 pub const DOMAIN = 39;
2275 };
2276
2277 pub const SECURITY_AUTHENTICATION = 22;
2278 pub const SECURITY_ENCRYPTION_TRANSPORT = 23;
2279 pub const SECURITY_ENCRYPTION_NETWORK = 24;
2280
2281 pub const BINDTODEVICE = 25;
2282
2283 pub const ATTACH_FILTER = 26;
2284 pub const DETACH_FILTER = 27;
2285 pub const GET_FILTER = ATTACH_FILTER;
2286
2287 pub const PEERNAME = 28;
2288 pub const TIMESTAMP_OLD = 29;
2289 pub const PASSSEC = 34;
2290 pub const TIMESTAMPNS_OLD = 35;
2291 pub const MARK = 36;
2292 pub const TIMESTAMPING_OLD = 37;
2293
2294 pub const RXQ_OVFL = 40;
2295 pub const WIFI_STATUS = 41;
2296 pub const PEEK_OFF = 42;
2297 pub const NOFCS = 43;
2298 pub const LOCK_FILTER = 44;
2299 pub const SELECT_ERR_QUEUE = 45;
2300 pub const BUSY_POLL = 46;
2301 pub const MAX_PACING_RATE = 47;
2302 pub const BPF_EXTENSIONS = 48;
2303 pub const INCOMING_CPU = 49;
2304 pub const ATTACH_BPF = 50;
2305 pub const DETACH_BPF = DETACH_FILTER;
2306 pub const ATTACH_REUSEPORT_CBPF = 51;
2307 pub const ATTACH_REUSEPORT_EBPF = 52;
2308 pub const CNX_ADVICE = 53;
2309 pub const MEMINFO = 55;
2310 pub const INCOMING_NAPI_ID = 56;
2311 pub const COOKIE = 57;
2312 pub const PEERGROUPS = 59;
2313 pub const ZEROCOPY = 60;
2314 pub const TXTIME = 61;
2315 pub const BINDTOIFINDEX = 62;
2316 pub const TIMESTAMP_NEW = 63;
2317 pub const TIMESTAMPNS_NEW = 64;
2318 pub const TIMESTAMPING_NEW = 65;
2319 pub const RCVTIMEO_NEW = 66;
2320 pub const SNDTIMEO_NEW = 67;
2321 pub const DETACH_REUSEPORT_BPF = 68;
2322};
2323
2324pub const SCM = struct {
2325 pub const WIFI_STATUS = SO.WIFI_STATUS;
2326 pub const TIMESTAMPING_OPT_STATS = 54;
2327 pub const TIMESTAMPING_PKTINFO = 58;
2328 pub const TXTIME = SO.TXTIME;
2329};
2330
2331pub const SOL = struct {
2332 pub const SOCKET = if (is_mips) 65535 else 1;
2333
2334 pub const IP = 0;
2335 pub const IPV6 = 41;
2336 pub const ICMPV6 = 58;
2337
2338 pub const RAW = 255;
2339 pub const DECNET = 261;
2340 pub const X25 = 262;
2341 pub const PACKET = 263;
2342 pub const ATM = 264;
2343 pub const AAL = 265;
2344 pub const IRDA = 266;
2345 pub const NETBEUI = 267;
2346 pub const LLC = 268;
2347 pub const DCCP = 269;
2348 pub const NETLINK = 270;
2349 pub const TIPC = 271;
2350 pub const RXRPC = 272;
2351 pub const PPPOL2TP = 273;
2352 pub const BLUETOOTH = 274;
2353 pub const PNPIPE = 275;
2354 pub const RDS = 276;
2355 pub const IUCV = 277;
2356 pub const CAIF = 278;
2357 pub const ALG = 279;
2358 pub const NFC = 280;
2359 pub const KCM = 281;
2360 pub const TLS = 282;
2361 pub const XDP = 283;
2362};
2363
2364pub const SOMAXCONN = 128;
2365
2366pub const IP = struct {
2367 pub const TOS = 1;
2368 pub const TTL = 2;
2369 pub const HDRINCL = 3;
2370 pub const OPTIONS = 4;
2371 pub const ROUTER_ALERT = 5;
2372 pub const RECVOPTS = 6;
2373 pub const RETOPTS = 7;
2374 pub const PKTINFO = 8;
2375 pub const PKTOPTIONS = 9;
2376 pub const PMTUDISC = 10;
2377 pub const MTU_DISCOVER = 10;
2378 pub const RECVERR = 11;
2379 pub const RECVTTL = 12;
2380 pub const RECVTOS = 13;
2381 pub const MTU = 14;
2382 pub const FREEBIND = 15;
2383 pub const IPSEC_POLICY = 16;
2384 pub const XFRM_POLICY = 17;
2385 pub const PASSSEC = 18;
2386 pub const TRANSPARENT = 19;
2387 pub const ORIGDSTADDR = 20;
2388 pub const RECVORIGDSTADDR = IP.ORIGDSTADDR;
2389 pub const MINTTL = 21;
2390 pub const NODEFRAG = 22;
2391 pub const CHECKSUM = 23;
2392 pub const BIND_ADDRESS_NO_PORT = 24;
2393 pub const RECVFRAGSIZE = 25;
2394 pub const MULTICAST_IF = 32;
2395 pub const MULTICAST_TTL = 33;
2396 pub const MULTICAST_LOOP = 34;
2397 pub const ADD_MEMBERSHIP = 35;
2398 pub const DROP_MEMBERSHIP = 36;
2399 pub const UNBLOCK_SOURCE = 37;
2400 pub const BLOCK_SOURCE = 38;
2401 pub const ADD_SOURCE_MEMBERSHIP = 39;
2402 pub const DROP_SOURCE_MEMBERSHIP = 40;
2403 pub const MSFILTER = 41;
2404 pub const MULTICAST_ALL = 49;
2405 pub const UNICAST_IF = 50;
2406
2407 pub const RECVRETOPTS = IP.RETOPTS;
2408
2409 pub const PMTUDISC_DONT = 0;
2410 pub const PMTUDISC_WANT = 1;
2411 pub const PMTUDISC_DO = 2;
2412 pub const PMTUDISC_PROBE = 3;
2413 pub const PMTUDISC_INTERFACE = 4;
2414 pub const PMTUDISC_OMIT = 5;
2415
2416 pub const DEFAULT_MULTICAST_TTL = 1;
2417 pub const DEFAULT_MULTICAST_LOOP = 1;
2418 pub const MAX_MEMBERSHIPS = 20;
2419};
2420
2421/// IPv6 socket options
2422pub const IPV6 = struct {
2423 pub const ADDRFORM = 1;
2424 pub const @"2292PKTINFO" = 2;
2425 pub const @"2292HOPOPTS" = 3;
2426 pub const @"2292DSTOPTS" = 4;
2427 pub const @"2292RTHDR" = 5;
2428 pub const @"2292PKTOPTIONS" = 6;
2429 pub const CHECKSUM = 7;
2430 pub const @"2292HOPLIMIT" = 8;
2431 pub const NEXTHOP = 9;
2432 pub const AUTHHDR = 10;
2433 pub const FLOWINFO = 11;
2434
2435 pub const UNICAST_HOPS = 16;
2436 pub const MULTICAST_IF = 17;
2437 pub const MULTICAST_HOPS = 18;
2438 pub const MULTICAST_LOOP = 19;
2439 pub const ADD_MEMBERSHIP = 20;
2440 pub const DROP_MEMBERSHIP = 21;
2441 pub const ROUTER_ALERT = 22;
2442 pub const MTU_DISCOVER = 23;
2443 pub const MTU = 24;
2444 pub const RECVERR = 25;
2445 pub const V6ONLY = 26;
2446 pub const JOIN_ANYCAST = 27;
2447 pub const LEAVE_ANYCAST = 28;
2448
2449 // IPV6.MTU_DISCOVER values
2450 pub const PMTUDISC_DONT = 0;
2451 pub const PMTUDISC_WANT = 1;
2452 pub const PMTUDISC_DO = 2;
2453 pub const PMTUDISC_PROBE = 3;
2454 pub const PMTUDISC_INTERFACE = 4;
2455 pub const PMTUDISC_OMIT = 5;
2456
2457 // Flowlabel
2458 pub const FLOWLABEL_MGR = 32;
2459 pub const FLOWINFO_SEND = 33;
2460 pub const IPSEC_POLICY = 34;
2461 pub const XFRM_POLICY = 35;
2462 pub const HDRINCL = 36;
2463
2464 // Advanced API (RFC3542) (1)
2465 pub const RECVPKTINFO = 49;
2466 pub const PKTINFO = 50;
2467 pub const RECVHOPLIMIT = 51;
2468 pub const HOPLIMIT = 52;
2469 pub const RECVHOPOPTS = 53;
2470 pub const HOPOPTS = 54;
2471 pub const RTHDRDSTOPTS = 55;
2472 pub const RECVRTHDR = 56;
2473 pub const RTHDR = 57;
2474 pub const RECVDSTOPTS = 58;
2475 pub const DSTOPTS = 59;
2476 pub const RECVPATHMTU = 60;
2477 pub const PATHMTU = 61;
2478 pub const DONTFRAG = 62;
2479
2480 // Advanced API (RFC3542) (2)
2481 pub const RECVTCLASS = 66;
2482 pub const TCLASS = 67;
2483
2484 pub const AUTOFLOWLABEL = 70;
2485
2486 // RFC5014: Source address selection
2487 pub const ADDR_PREFERENCES = 72;
2488
2489 pub const PREFER_SRC_TMP = 0x0001;
2490 pub const PREFER_SRC_PUBLIC = 0x0002;
2491 pub const PREFER_SRC_PUBTMP_DEFAULT = 0x0100;
2492 pub const PREFER_SRC_COA = 0x0004;
2493 pub const PREFER_SRC_HOME = 0x0400;
2494 pub const PREFER_SRC_CGA = 0x0008;
2495 pub const PREFER_SRC_NONCGA = 0x0800;
2496
2497 // RFC5082: Generalized Ttl Security Mechanism
2498 pub const MINHOPCOUNT = 73;
2499
2500 pub const ORIGDSTADDR = 74;
2501 pub const RECVORIGDSTADDR = IPV6.ORIGDSTADDR;
2502 pub const TRANSPARENT = 75;
2503 pub const UNICAST_IF = 76;
2504 pub const RECVFRAGSIZE = 77;
2505 pub const FREEBIND = 78;
2506};
2507
2508pub const MSG = struct {
2509 pub const OOB = 0x0001;
2510 pub const PEEK = 0x0002;
2511 pub const DONTROUTE = 0x0004;
2512 pub const CTRUNC = 0x0008;
2513 pub const PROXY = 0x0010;
2514 pub const TRUNC = 0x0020;
2515 pub const DONTWAIT = 0x0040;
2516 pub const EOR = 0x0080;
2517 pub const WAITALL = 0x0100;
2518 pub const FIN = 0x0200;
2519 pub const SYN = 0x0400;
2520 pub const CONFIRM = 0x0800;
2521 pub const RST = 0x1000;
2522 pub const ERRQUEUE = 0x2000;
2523 pub const NOSIGNAL = 0x4000;
2524 pub const MORE = 0x8000;
2525 pub const WAITFORONE = 0x10000;
2526 pub const BATCH = 0x40000;
2527 pub const ZEROCOPY = 0x4000000;
2528 pub const FASTOPEN = 0x20000000;
2529 pub const CMSG_CLOEXEC = 0x40000000;
2530};
2531
2532pub const DT = struct {
2533 pub const UNKNOWN = 0;
2534 pub const FIFO = 1;
2535 pub const CHR = 2;
2536 pub const DIR = 4;
2537 pub const BLK = 6;
2538 pub const REG = 8;
2539 pub const LNK = 10;
2540 pub const SOCK = 12;
2541 pub const WHT = 14;
2542};
2543
2544pub const T = struct {
2545 pub const CGETS = if (is_mips) 0x540D else 0x5401;
2546 pub const CSETS = 0x5402;
2547 pub const CSETSW = 0x5403;
2548 pub const CSETSF = 0x5404;
2549 pub const CGETA = 0x5405;
2550 pub const CSETA = 0x5406;
2551 pub const CSETAW = 0x5407;
2552 pub const CSETAF = 0x5408;
2553 pub const CSBRK = 0x5409;
2554 pub const CXONC = 0x540A;
2555 pub const CFLSH = 0x540B;
2556 pub const IOCEXCL = 0x540C;
2557 pub const IOCNXCL = 0x540D;
2558 pub const IOCSCTTY = 0x540E;
2559 pub const IOCGPGRP = 0x540F;
2560 pub const IOCSPGRP = 0x5410;
2561 pub const IOCOUTQ = if (is_mips) 0x7472 else 0x5411;
2562 pub const IOCSTI = 0x5412;
2563 pub const IOCGWINSZ = if (is_mips or is_ppc64) 0x40087468 else 0x5413;
2564 pub const IOCSWINSZ = if (is_mips or is_ppc64) 0x80087467 else 0x5414;
2565 pub const IOCMGET = 0x5415;
2566 pub const IOCMBIS = 0x5416;
2567 pub const IOCMBIC = 0x5417;
2568 pub const IOCMSET = 0x5418;
2569 pub const IOCGSOFTCAR = 0x5419;
2570 pub const IOCSSOFTCAR = 0x541A;
2571 pub const FIONREAD = if (is_mips) 0x467F else 0x541B;
2572 pub const IOCINQ = FIONREAD;
2573 pub const IOCLINUX = 0x541C;
2574 pub const IOCCONS = 0x541D;
2575 pub const IOCGSERIAL = 0x541E;
2576 pub const IOCSSERIAL = 0x541F;
2577 pub const IOCPKT = 0x5420;
2578 pub const FIONBIO = 0x5421;
2579 pub const IOCNOTTY = 0x5422;
2580 pub const IOCSETD = 0x5423;
2581 pub const IOCGETD = 0x5424;
2582 pub const CSBRKP = 0x5425;
2583 pub const IOCSBRK = 0x5427;
2584 pub const IOCCBRK = 0x5428;
2585 pub const IOCGSID = 0x5429;
2586 pub const IOCGRS485 = 0x542E;
2587 pub const IOCSRS485 = 0x542F;
2588 pub const IOCGPTN = 0x80045430;
2589 pub const IOCSPTLCK = 0x40045431;
2590 pub const IOCGDEV = 0x80045432;
2591 pub const CGETX = 0x5432;
2592 pub const CSETX = 0x5433;
2593 pub const CSETXF = 0x5434;
2594 pub const CSETXW = 0x5435;
2595 pub const IOCSIG = 0x40045436;
2596 pub const IOCVHANGUP = 0x5437;
2597 pub const IOCGPKT = 0x80045438;
2598 pub const IOCGPTLCK = 0x80045439;
2599 pub const IOCGEXCL = 0x80045440;
2600};
2601
2602pub const EPOLL = struct {
2603 pub const CLOEXEC = O.CLOEXEC;
2604
2605 pub const CTL_ADD = 1;
2606 pub const CTL_DEL = 2;
2607 pub const CTL_MOD = 3;
2608
2609 pub const IN = 0x001;
2610 pub const PRI = 0x002;
2611 pub const OUT = 0x004;
2612 pub const RDNORM = 0x040;
2613 pub const RDBAND = 0x080;
2614 pub const WRNORM = if (is_mips) 0x004 else 0x100;
2615 pub const WRBAND = if (is_mips) 0x100 else 0x200;
2616 pub const MSG = 0x400;
2617 pub const ERR = 0x008;
2618 pub const HUP = 0x010;
2619 pub const RDHUP = 0x2000;
2620 pub const EXCLUSIVE = (@as(u32, 1) << 28);
2621 pub const WAKEUP = (@as(u32, 1) << 29);
2622 pub const ONESHOT = (@as(u32, 1) << 30);
2623 pub const ET = (@as(u32, 1) << 31);
2624};
2625
2626pub const CLOCK = struct {
2627 pub const REALTIME = 0;
2628 pub const MONOTONIC = 1;
2629 pub const PROCESS_CPUTIME_ID = 2;
2630 pub const THREAD_CPUTIME_ID = 3;
2631 pub const MONOTONIC_RAW = 4;
2632 pub const REALTIME_COARSE = 5;
2633 pub const MONOTONIC_COARSE = 6;
2634 pub const BOOTTIME = 7;
2635 pub const REALTIME_ALARM = 8;
2636 pub const BOOTTIME_ALARM = 9;
2637 pub const SGI_CYCLE = 10;
2638 pub const TAI = 11;
2639};
2640
2641pub const CSIGNAL = 0x000000ff;
2642
2643pub const CLONE = struct {
2644 pub const VM = 0x00000100;
2645 pub const FS = 0x00000200;
2646 pub const FILES = 0x00000400;
2647 pub const SIGHAND = 0x00000800;
2648 pub const PIDFD = 0x00001000;
2649 pub const PTRACE = 0x00002000;
2650 pub const VFORK = 0x00004000;
2651 pub const PARENT = 0x00008000;
2652 pub const THREAD = 0x00010000;
2653 pub const NEWNS = 0x00020000;
2654 pub const SYSVSEM = 0x00040000;
2655 pub const SETTLS = 0x00080000;
2656 pub const PARENT_SETTID = 0x00100000;
2657 pub const CHILD_CLEARTID = 0x00200000;
2658 pub const DETACHED = 0x00400000;
2659 pub const UNTRACED = 0x00800000;
2660 pub const CHILD_SETTID = 0x01000000;
2661 pub const NEWCGROUP = 0x02000000;
2662 pub const NEWUTS = 0x04000000;
2663 pub const NEWIPC = 0x08000000;
2664 pub const NEWUSER = 0x10000000;
2665 pub const NEWPID = 0x20000000;
2666 pub const NEWNET = 0x40000000;
2667 pub const IO = 0x80000000;
2668
2669 // Flags for the clone3() syscall.
2670
2671 /// Clear any signal handler and reset to SIG_DFL.
2672 pub const CLEAR_SIGHAND = 0x100000000;
2673 /// Clone into a specific cgroup given the right permissions.
2674 pub const INTO_CGROUP = 0x200000000;
2675
2676 // cloning flags intersect with CSIGNAL so can be used with unshare and clone3 syscalls only.
2677
2678 /// New time namespace
2679 pub const NEWTIME = 0x00000080;
2680};
2681
2682pub const EFD = struct {
2683 pub const SEMAPHORE = 1;
2684 pub const CLOEXEC = O.CLOEXEC;
2685 pub const NONBLOCK = O.NONBLOCK;
2686};
2687
2688pub const MS = struct {
2689 pub const RDONLY = 1;
2690 pub const NOSUID = 2;
2691 pub const NODEV = 4;
2692 pub const NOEXEC = 8;
2693 pub const SYNCHRONOUS = 16;
2694 pub const REMOUNT = 32;
2695 pub const MANDLOCK = 64;
2696 pub const DIRSYNC = 128;
2697 pub const NOATIME = 1024;
2698 pub const NODIRATIME = 2048;
2699 pub const BIND = 4096;
2700 pub const MOVE = 8192;
2701 pub const REC = 16384;
2702 pub const SILENT = 32768;
2703 pub const POSIXACL = (1 << 16);
2704 pub const UNBINDABLE = (1 << 17);
2705 pub const PRIVATE = (1 << 18);
2706 pub const SLAVE = (1 << 19);
2707 pub const SHARED = (1 << 20);
2708 pub const RELATIME = (1 << 21);
2709 pub const KERNMOUNT = (1 << 22);
2710 pub const I_VERSION = (1 << 23);
2711 pub const STRICTATIME = (1 << 24);
2712 pub const LAZYTIME = (1 << 25);
2713 pub const NOREMOTELOCK = (1 << 27);
2714 pub const NOSEC = (1 << 28);
2715 pub const BORN = (1 << 29);
2716 pub const ACTIVE = (1 << 30);
2717 pub const NOUSER = (1 << 31);
2718
2719 pub const RMT_MASK = (RDONLY | SYNCHRONOUS | MANDLOCK | I_VERSION | LAZYTIME);
2720
2721 pub const MGC_VAL = 0xc0ed0000;
2722 pub const MGC_MSK = 0xffff0000;
2723};
2724
2725pub const MNT = struct {
2726 pub const FORCE = 1;
2727 pub const DETACH = 2;
2728 pub const EXPIRE = 4;
2729};
2730
2731pub const UMOUNT_NOFOLLOW = 8;
2732
2733pub const IN = struct {
2734 pub const CLOEXEC = O.CLOEXEC;
2735 pub const NONBLOCK = O.NONBLOCK;
2736
2737 pub const ACCESS = 0x00000001;
2738 pub const MODIFY = 0x00000002;
2739 pub const ATTRIB = 0x00000004;
2740 pub const CLOSE_WRITE = 0x00000008;
2741 pub const CLOSE_NOWRITE = 0x00000010;
2742 pub const CLOSE = CLOSE_WRITE | CLOSE_NOWRITE;
2743 pub const OPEN = 0x00000020;
2744 pub const MOVED_FROM = 0x00000040;
2745 pub const MOVED_TO = 0x00000080;
2746 pub const MOVE = MOVED_FROM | MOVED_TO;
2747 pub const CREATE = 0x00000100;
2748 pub const DELETE = 0x00000200;
2749 pub const DELETE_SELF = 0x00000400;
2750 pub const MOVE_SELF = 0x00000800;
2751 pub const ALL_EVENTS = 0x00000fff;
2752
2753 pub const UNMOUNT = 0x00002000;
2754 pub const Q_OVERFLOW = 0x00004000;
2755 pub const IGNORED = 0x00008000;
2756
2757 pub const ONLYDIR = 0x01000000;
2758 pub const DONT_FOLLOW = 0x02000000;
2759 pub const EXCL_UNLINK = 0x04000000;
2760 pub const MASK_ADD = 0x20000000;
2761
2762 pub const ISDIR = 0x40000000;
2763 pub const ONESHOT = 0x80000000;
2764};
2765
2766pub const S = struct {
2767 pub const IFMT = 0o170000;
2768
2769 pub const IFDIR = 0o040000;
2770 pub const IFCHR = 0o020000;
2771 pub const IFBLK = 0o060000;
2772 pub const IFREG = 0o100000;
2773 pub const IFIFO = 0o010000;
2774 pub const IFLNK = 0o120000;
2775 pub const IFSOCK = 0o140000;
2776
2777 pub const ISUID = 0o4000;
2778 pub const ISGID = 0o2000;
2779 pub const ISVTX = 0o1000;
2780 pub const IRUSR = 0o400;
2781 pub const IWUSR = 0o200;
2782 pub const IXUSR = 0o100;
2783 pub const IRWXU = 0o700;
2784 pub const IRGRP = 0o040;
2785 pub const IWGRP = 0o020;
2786 pub const IXGRP = 0o010;
2787 pub const IRWXG = 0o070;
2788 pub const IROTH = 0o004;
2789 pub const IWOTH = 0o002;
2790 pub const IXOTH = 0o001;
2791 pub const IRWXO = 0o007;
2792
2793 pub fn ISREG(m: u32) bool {
2794 return m & IFMT == IFREG;
2795 }
2796
2797 pub fn ISDIR(m: u32) bool {
2798 return m & IFMT == IFDIR;
2799 }
2800
2801 pub fn ISCHR(m: u32) bool {
2802 return m & IFMT == IFCHR;
2803 }
2804
2805 pub fn ISBLK(m: u32) bool {
2806 return m & IFMT == IFBLK;
2807 }
2808
2809 pub fn ISFIFO(m: u32) bool {
2810 return m & IFMT == IFIFO;
2811 }
2812
2813 pub fn ISLNK(m: u32) bool {
2814 return m & IFMT == IFLNK;
2815 }
2816
2817 pub fn ISSOCK(m: u32) bool {
2818 return m & IFMT == IFSOCK;
2819 }
2820};
2821
2822pub const UTIME = struct {
2823 pub const NOW = 0x3fffffff;
2824 pub const OMIT = 0x3ffffffe;
2825};
2826
2827pub const TFD = struct {
2828 pub const NONBLOCK = O.NONBLOCK;
2829 pub const CLOEXEC = O.CLOEXEC;
2830
2831 pub const TIMER_ABSTIME = 1;
2832 pub const TIMER_CANCEL_ON_SET = (1 << 1);
2833};
2834
2835pub const winsize = extern struct {
2836 ws_row: u16,
2837 ws_col: u16,
2838 ws_xpixel: u16,
2839 ws_ypixel: u16,
2840};
2841
2842/// NSIG is the total number of signals defined.
2843/// As signal numbers are sequential, NSIG is one greater than the largest defined signal number.
2844pub const NSIG = if (is_mips) 128 else 65;
2845
2846pub const sigset_t = [1024 / 32]u32;
2847
2848pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len;
2849pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30;
2850
2851pub const k_sigaction = switch (native_arch) {
2852 .mips, .mipsel => extern struct {
2853 flags: c_uint,
2854 handler: ?fn (c_int) callconv(.C) void,
2855 mask: [4]c_ulong,
2856 restorer: fn () callconv(.C) void,
2857 },
2858 .mips64, .mips64el => extern struct {
2859 flags: c_uint,
2860 handler: ?fn (c_int) callconv(.C) void,
2861 mask: [2]c_ulong,
2862 restorer: fn () callconv(.C) void,
2863 },
2864 else => extern struct {
2865 handler: ?fn (c_int) callconv(.C) void,
2866 flags: c_ulong,
2867 restorer: fn () callconv(.C) void,
2868 mask: [2]c_uint,
2869 },
2870};
2871
2872/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
2873pub const Sigaction = extern struct {
2874 pub const handler_fn = fn (c_int) callconv(.C) void;
2875 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
2876
2877 handler: extern union {
2878 handler: ?handler_fn,
2879 sigaction: ?sigaction_fn,
2880 },
2881 mask: sigset_t,
2882 flags: c_uint,
2883 restorer: ?fn () callconv(.C) void = null,
2884};
2885
2886pub const empty_sigset = [_]u32{0} ** @typeInfo(sigset_t).Array.len;
2887
2888pub const SFD = struct {
2889 pub const CLOEXEC = O.CLOEXEC;
2890 pub const NONBLOCK = O.NONBLOCK;
2891};
2892
2893pub const signalfd_siginfo = extern struct {
2894 signo: u32,
2895 errno: i32,
2896 code: i32,
2897 pid: u32,
2898 uid: uid_t,
2899 fd: i32,
2900 tid: u32,
2901 band: u32,
2902 overrun: u32,
2903 trapno: u32,
2904 status: i32,
2905 int: i32,
2906 ptr: u64,
2907 utime: u64,
2908 stime: u64,
2909 addr: u64,
2910 addr_lsb: u16,
2911 __pad2: u16,
2912 syscall: i32,
2913 call_addr: u64,
2914 native_arch: u32,
2915 __pad: [28]u8,
2916};
2917
2918pub const in_port_t = u16;
2919pub const sa_family_t = u16;
2920pub const socklen_t = u32;
2921
2922pub const sockaddr = extern struct {
2923 family: sa_family_t,
2924 data: [14]u8,
2925
2926 pub const storage = std.x.os.Socket.Address.Native.Storage;
2927
2928 /// IPv4 socket address
2929 pub const in = extern struct {
2930 family: sa_family_t = AF.INET,
2931 port: in_port_t,
2932 addr: u32,
2933 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
2934 };
2935
2936 /// IPv6 socket address
2937 pub const in6 = extern struct {
2938 family: sa_family_t = AF.INET6,
2939 port: in_port_t,
2940 flowinfo: u32,
2941 addr: [16]u8,
2942 scope_id: u32,
2943 };
2944
2945 /// UNIX domain socket address
2946 pub const un = extern struct {
2947 family: sa_family_t = AF.UNIX,
2948 path: [108]u8,
2949 };
2950
2951 /// Netlink socket address
2952 pub const nl = extern struct {
2953 family: sa_family_t = AF.NETLINK,
2954 __pad1: c_ushort = 0,
2955
2956 /// port ID
2957 pid: u32,
2958
2959 /// multicast groups mask
2960 groups: u32,
2961 };
2962
2963 pub const xdp = extern struct {
2964 family: u16 = AF.XDP,
2965 flags: u16,
2966 ifindex: u32,
2967 queue_id: u32,
2968 shared_umem_fd: u32,
2969 };
2970};
2971
2972pub const mmsghdr = extern struct {
2973 msg_hdr: msghdr,
2974 msg_len: u32,
2975};
2976
2977pub const mmsghdr_const = extern struct {
2978 msg_hdr: msghdr_const,
2979 msg_len: u32,
2980};
2981
2982pub const epoll_data = extern union {
2983 ptr: usize,
2984 fd: i32,
2985 @"u32": u32,
2986 @"u64": u64,
2987};
2988
2989// On x86_64 the structure is packed so that it matches the definition of its
2990// 32bit counterpart
2991pub const epoll_event = switch (native_arch) {
2992 .x86_64 => packed struct {
2993 events: u32,
2994 data: epoll_data,
2995 },
2996 else => extern struct {
2997 events: u32,
2998 data: epoll_data,
2999 },
3000};
3001
3002pub const VFS_CAP_REVISION_MASK = 0xFF000000;
3003pub const VFS_CAP_REVISION_SHIFT = 24;
3004pub const VFS_CAP_FLAGS_MASK = ~VFS_CAP_REVISION_MASK;
3005pub const VFS_CAP_FLAGS_EFFECTIVE = 0x000001;
3006
3007pub const VFS_CAP_REVISION_1 = 0x01000000;
3008pub const VFS_CAP_U32_1 = 1;
3009pub const XATTR_CAPS_SZ_1 = @sizeOf(u32) * (1 + 2 * VFS_CAP_U32_1);
3010
3011pub const VFS_CAP_REVISION_2 = 0x02000000;
3012pub const VFS_CAP_U32_2 = 2;
3013pub const XATTR_CAPS_SZ_2 = @sizeOf(u32) * (1 + 2 * VFS_CAP_U32_2);
3014
3015pub const XATTR_CAPS_SZ = XATTR_CAPS_SZ_2;
3016pub const VFS_CAP_U32 = VFS_CAP_U32_2;
3017pub const VFS_CAP_REVISION = VFS_CAP_REVISION_2;
3018
3019pub const vfs_cap_data = extern struct {
3020 //all of these are mandated as little endian
3021 //when on disk.
3022 const Data = struct {
3023 permitted: u32,
3024 inheritable: u32,
3025 };
3026
3027 magic_etc: u32,
3028 data: [VFS_CAP_U32]Data,
3029};
3030
3031pub const CAP = struct {
3032 pub const CHOWN = 0;
3033 pub const DAC_OVERRIDE = 1;
3034 pub const DAC_READ_SEARCH = 2;
3035 pub const FOWNER = 3;
3036 pub const FSETID = 4;
3037 pub const KILL = 5;
3038 pub const SETGID = 6;
3039 pub const SETUID = 7;
3040 pub const SETPCAP = 8;
3041 pub const LINUX_IMMUTABLE = 9;
3042 pub const NET_BIND_SERVICE = 10;
3043 pub const NET_BROADCAST = 11;
3044 pub const NET_ADMIN = 12;
3045 pub const NET_RAW = 13;
3046 pub const IPC_LOCK = 14;
3047 pub const IPC_OWNER = 15;
3048 pub const SYS_MODULE = 16;
3049 pub const SYS_RAWIO = 17;
3050 pub const SYS_CHROOT = 18;
3051 pub const SYS_PTRACE = 19;
3052 pub const SYS_PACCT = 20;
3053 pub const SYS_ADMIN = 21;
3054 pub const SYS_BOOT = 22;
3055 pub const SYS_NICE = 23;
3056 pub const SYS_RESOURCE = 24;
3057 pub const SYS_TIME = 25;
3058 pub const SYS_TTY_CONFIG = 26;
3059 pub const MKNOD = 27;
3060 pub const LEASE = 28;
3061 pub const AUDIT_WRITE = 29;
3062 pub const AUDIT_CONTROL = 30;
3063 pub const SETFCAP = 31;
3064 pub const MAC_OVERRIDE = 32;
3065 pub const MAC_ADMIN = 33;
3066 pub const SYSLOG = 34;
3067 pub const WAKE_ALARM = 35;
3068 pub const BLOCK_SUSPEND = 36;
3069 pub const AUDIT_READ = 37;
3070 pub const LAST_CAP = AUDIT_READ;
3071
3072 pub fn valid(x: u8) bool {
3073 return x >= 0 and x <= LAST_CAP;
3074 }
3075
3076 pub fn TO_MASK(cap: u8) u32 {
3077 return @as(u32, 1) << @intCast(u5, cap & 31);
3078 }
3079
3080 pub fn TO_INDEX(cap: u8) u8 {
3081 return cap >> 5;
3082 }
3083};
3084
3085pub const cap_t = extern struct {
3086 hdrp: *cap_user_header_t,
3087 datap: *cap_user_data_t,
3088};
3089
3090pub const cap_user_header_t = extern struct {
3091 version: u32,
3092 pid: usize,
3093};
3094
3095pub const cap_user_data_t = extern struct {
3096 effective: u32,
3097 permitted: u32,
3098 inheritable: u32,
3099};
3100
3101pub const inotify_event = extern struct {
3102 wd: i32,
3103 mask: u32,
3104 cookie: u32,
3105 len: u32,
3106 //name: [?]u8,
3107};
3108
3109pub const dirent64 = extern struct {
3110 d_ino: u64,
3111 d_off: u64,
3112 d_reclen: u16,
3113 d_type: u8,
3114 d_name: u8, // field address is the address of first byte of name https://github.com/ziglang/zig/issues/173
3115
3116 pub fn reclen(self: dirent64) u16 {
3117 return self.d_reclen;
3118 }
3119};
3120
3121pub const dl_phdr_info = extern struct {
3122 dlpi_addr: usize,
3123 dlpi_name: ?[*:0]const u8,
3124 dlpi_phdr: [*]std.elf.Phdr,
3125 dlpi_phnum: u16,
3126};
3127
3128pub const CPU_SETSIZE = 128;
3129pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
3130pub const cpu_count_t = std.meta.Int(.unsigned, std.math.log2(CPU_SETSIZE * 8));
3131
3132pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
3133 var sum: cpu_count_t = 0;
3134 for (set) |x| {
3135 sum += @popCount(usize, x);
1537 }3136 }
3137 return sum;
1538}3138}
3139
3140pub const MINSIGSTKSZ = switch (native_arch) {
3141 .i386, .x86_64, .arm, .mipsel => 2048,
3142 .aarch64 => 5120,
3143 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
3144};
3145pub const SIGSTKSZ = switch (native_arch) {
3146 .i386, .x86_64, .arm, .mipsel => 8192,
3147 .aarch64 => 16384,
3148 else => @compileError("SIGSTKSZ not defined for this architecture"),
3149};
3150
3151pub const SS_ONSTACK = 1;
3152pub const SS_DISABLE = 2;
3153pub const SS_AUTODISARM = 1 << 31;
3154
3155pub const stack_t = if (is_mips)
3156 // IRIX compatible stack_t
3157 extern struct {
3158 sp: [*]u8,
3159 size: usize,
3160 flags: i32,
3161 }
3162else
3163 extern struct {
3164 sp: [*]u8,
3165 flags: i32,
3166 size: usize,
3167 };
3168
3169pub const sigval = extern union {
3170 int: i32,
3171 ptr: *c_void,
3172};
3173
3174const siginfo_fields_union = extern union {
3175 pad: [128 - 2 * @sizeOf(c_int) - @sizeOf(c_long)]u8,
3176 common: extern struct {
3177 first: extern union {
3178 piduid: extern struct {
3179 pid: pid_t,
3180 uid: uid_t,
3181 },
3182 timer: extern struct {
3183 timerid: i32,
3184 overrun: i32,
3185 },
3186 },
3187 second: extern union {
3188 value: sigval,
3189 sigchld: extern struct {
3190 status: i32,
3191 utime: clock_t,
3192 stime: clock_t,
3193 },
3194 },
3195 },
3196 sigfault: extern struct {
3197 addr: *c_void,
3198 addr_lsb: i16,
3199 first: extern union {
3200 addr_bnd: extern struct {
3201 lower: *c_void,
3202 upper: *c_void,
3203 },
3204 pkey: u32,
3205 },
3206 },
3207 sigpoll: extern struct {
3208 band: isize,
3209 fd: i32,
3210 },
3211 sigsys: extern struct {
3212 call_addr: *c_void,
3213 syscall: i32,
3214 native_arch: u32,
3215 },
3216};
3217
3218pub const siginfo_t = if (is_mips)
3219 extern struct {
3220 signo: i32,
3221 code: i32,
3222 errno: i32,
3223 fields: siginfo_fields_union,
3224 }
3225else
3226 extern struct {
3227 signo: i32,
3228 errno: i32,
3229 code: i32,
3230 fields: siginfo_fields_union,
3231 };
3232
3233pub const io_uring_params = extern struct {
3234 sq_entries: u32,
3235 cq_entries: u32,
3236 flags: u32,
3237 sq_thread_cpu: u32,
3238 sq_thread_idle: u32,
3239 features: u32,
3240 wq_fd: u32,
3241 resv: [3]u32,
3242 sq_off: io_sqring_offsets,
3243 cq_off: io_cqring_offsets,
3244};
3245
3246// io_uring_params.features flags
3247
3248pub const IORING_FEAT_SINGLE_MMAP = 1 << 0;
3249pub const IORING_FEAT_NODROP = 1 << 1;
3250pub const IORING_FEAT_SUBMIT_STABLE = 1 << 2;
3251pub const IORING_FEAT_RW_CUR_POS = 1 << 3;
3252pub const IORING_FEAT_CUR_PERSONALITY = 1 << 4;
3253pub const IORING_FEAT_FAST_POLL = 1 << 5;
3254pub const IORING_FEAT_POLL_32BITS = 1 << 6;
3255
3256// io_uring_params.flags
3257
3258/// io_context is polled
3259pub const IORING_SETUP_IOPOLL = 1 << 0;
3260
3261/// SQ poll thread
3262pub const IORING_SETUP_SQPOLL = 1 << 1;
3263
3264/// sq_thread_cpu is valid
3265pub const IORING_SETUP_SQ_AFF = 1 << 2;
3266
3267/// app defines CQ size
3268pub const IORING_SETUP_CQSIZE = 1 << 3;
3269
3270/// clamp SQ/CQ ring sizes
3271pub const IORING_SETUP_CLAMP = 1 << 4;
3272
3273/// attach to existing wq
3274pub const IORING_SETUP_ATTACH_WQ = 1 << 5;
3275
3276/// start with ring disabled
3277pub const IORING_SETUP_R_DISABLED = 1 << 6;
3278
3279pub const io_sqring_offsets = extern struct {
3280 /// offset of ring head
3281 head: u32,
3282
3283 /// offset of ring tail
3284 tail: u32,
3285
3286 /// ring mask value
3287 ring_mask: u32,
3288
3289 /// entries in ring
3290 ring_entries: u32,
3291
3292 /// ring flags
3293 flags: u32,
3294
3295 /// number of sqes not submitted
3296 dropped: u32,
3297
3298 /// sqe index array
3299 array: u32,
3300
3301 resv1: u32,
3302 resv2: u64,
3303};
3304
3305// io_sqring_offsets.flags
3306
3307/// needs io_uring_enter wakeup
3308pub const IORING_SQ_NEED_WAKEUP = 1 << 0;
3309
3310/// kernel has cqes waiting beyond the cq ring
3311pub const IORING_SQ_CQ_OVERFLOW = 1 << 1;
3312
3313pub const io_cqring_offsets = extern struct {
3314 head: u32,
3315 tail: u32,
3316 ring_mask: u32,
3317 ring_entries: u32,
3318 overflow: u32,
3319 cqes: u32,
3320 resv: [2]u64,
3321};
3322
3323pub const io_uring_sqe = extern struct {
3324 opcode: IORING_OP,
3325 flags: u8,
3326 ioprio: u16,
3327 fd: i32,
3328 off: u64,
3329 addr: u64,
3330 len: u32,
3331 rw_flags: u32,
3332 user_data: u64,
3333 buf_index: u16,
3334 personality: u16,
3335 splice_fd_in: i32,
3336 __pad2: [2]u64,
3337};
3338
3339pub const IOSQE_BIT = enum(u8) {
3340 FIXED_FILE,
3341 IO_DRAIN,
3342 IO_LINK,
3343 IO_HARDLINK,
3344 ASYNC,
3345 BUFFER_SELECT,
3346
3347 _,
3348};
3349
3350// io_uring_sqe.flags
3351
3352/// use fixed fileset
3353pub const IOSQE_FIXED_FILE = 1 << @enumToInt(IOSQE_BIT.FIXED_FILE);
3354
3355/// issue after inflight IO
3356pub const IOSQE_IO_DRAIN = 1 << @enumToInt(IOSQE_BIT.IO_DRAIN);
3357
3358/// links next sqe
3359pub const IOSQE_IO_LINK = 1 << @enumToInt(IOSQE_BIT.IO_LINK);
3360
3361/// like LINK, but stronger
3362pub const IOSQE_IO_HARDLINK = 1 << @enumToInt(IOSQE_BIT.IO_HARDLINK);
3363
3364/// always go async
3365pub const IOSQE_ASYNC = 1 << @enumToInt(IOSQE_BIT.ASYNC);
3366
3367/// select buffer from buf_group
3368pub const IOSQE_BUFFER_SELECT = 1 << @enumToInt(IOSQE_BIT.BUFFER_SELECT);
3369
3370pub const IORING_OP = enum(u8) {
3371 NOP,
3372 READV,
3373 WRITEV,
3374 FSYNC,
3375 READ_FIXED,
3376 WRITE_FIXED,
3377 POLL_ADD,
3378 POLL_REMOVE,
3379 SYNC_FILE_RANGE,
3380 SENDMSG,
3381 RECVMSG,
3382 TIMEOUT,
3383 TIMEOUT_REMOVE,
3384 ACCEPT,
3385 ASYNC_CANCEL,
3386 LINK_TIMEOUT,
3387 CONNECT,
3388 FALLOCATE,
3389 OPENAT,
3390 CLOSE,
3391 FILES_UPDATE,
3392 STATX,
3393 READ,
3394 WRITE,
3395 FADVISE,
3396 MADVISE,
3397 SEND,
3398 RECV,
3399 OPENAT2,
3400 EPOLL_CTL,
3401 SPLICE,
3402 PROVIDE_BUFFERS,
3403 REMOVE_BUFFERS,
3404 TEE,
3405
3406 _,
3407};
3408
3409// io_uring_sqe.fsync_flags
3410pub const IORING_FSYNC_DATASYNC = 1 << 0;
3411
3412// io_uring_sqe.timeout_flags
3413pub const IORING_TIMEOUT_ABS = 1 << 0;
3414
3415// IO completion data structure (Completion Queue Entry)
3416pub const io_uring_cqe = extern struct {
3417 /// io_uring_sqe.data submission passed back
3418 user_data: u64,
3419
3420 /// result code for this event
3421 res: i32,
3422 flags: u32,
3423
3424 pub fn err(self: io_uring_cqe) E {
3425 if (self.res > -4096 and self.res < 0) {
3426 return @intToEnum(E, -self.res);
3427 }
3428 return .SUCCESS;
3429 }
3430};
3431
3432// io_uring_cqe.flags
3433
3434/// If set, the upper 16 bits are the buffer ID
3435pub const IORING_CQE_F_BUFFER = 1 << 0;
3436
3437pub const IORING_OFF_SQ_RING = 0;
3438pub const IORING_OFF_CQ_RING = 0x8000000;
3439pub const IORING_OFF_SQES = 0x10000000;
3440
3441// io_uring_enter flags
3442pub const IORING_ENTER_GETEVENTS = 1 << 0;
3443pub const IORING_ENTER_SQ_WAKEUP = 1 << 1;
3444
3445// io_uring_register opcodes and arguments
3446pub const IORING_REGISTER = enum(u8) {
3447 REGISTER_BUFFERS,
3448 UNREGISTER_BUFFERS,
3449 REGISTER_FILES,
3450 UNREGISTER_FILES,
3451 REGISTER_EVENTFD,
3452 UNREGISTER_EVENTFD,
3453 REGISTER_FILES_UPDATE,
3454 REGISTER_EVENTFD_ASYNC,
3455 REGISTER_PROBE,
3456 REGISTER_PERSONALITY,
3457 UNREGISTER_PERSONALITY,
3458 REGISTER_RESTRICTIONS,
3459 REGISTER_ENABLE_RINGS,
3460
3461 _,
3462};
3463
3464pub const io_uring_files_update = extern struct {
3465 offset: u32,
3466 resv: u32,
3467 fds: u64,
3468};
3469
3470pub const IO_URING_OP_SUPPORTED = 1 << 0;
3471
3472pub const io_uring_probe_op = extern struct {
3473 op: IORING_OP,
3474
3475 resv: u8,
3476
3477 /// IO_URING_OP_* flags
3478 flags: u16,
3479
3480 resv2: u32,
3481};
3482
3483pub const io_uring_probe = extern struct {
3484 /// last opcode supported
3485 last_op: IORING_OP,
3486
3487 /// Number of io_uring_probe_op following
3488 ops_len: u8,
3489
3490 resv: u16,
3491 resv2: u32[3],
3492
3493 // Followed by up to `ops_len` io_uring_probe_op structures
3494};
3495
3496pub const io_uring_restriction = extern struct {
3497 opcode: u16,
3498 arg: extern union {
3499 /// IORING_RESTRICTION_REGISTER_OP
3500 register_op: IORING_REGISTER,
3501
3502 /// IORING_RESTRICTION_SQE_OP
3503 sqe_op: IORING_OP,
3504
3505 /// IORING_RESTRICTION_SQE_FLAGS_*
3506 sqe_flags: u8,
3507 },
3508 resv: u8,
3509 resv2: u32[3],
3510};
3511
3512/// io_uring_restriction->opcode values
3513pub const IORING_RESTRICTION = enum(u8) {
3514 /// Allow an io_uring_register(2) opcode
3515 REGISTER_OP = 0,
3516
3517 /// Allow an sqe opcode
3518 SQE_OP = 1,
3519
3520 /// Allow sqe flags
3521 SQE_FLAGS_ALLOWED = 2,
3522
3523 /// Require sqe flags (these flags must be set on each submission)
3524 SQE_FLAGS_REQUIRED = 3,
3525
3526 _,
3527};
3528
3529pub const utsname = extern struct {
3530 sysname: [64:0]u8,
3531 nodename: [64:0]u8,
3532 release: [64:0]u8,
3533 version: [64:0]u8,
3534 machine: [64:0]u8,
3535 domainname: [64:0]u8,
3536};
3537pub const HOST_NAME_MAX = 64;
3538
3539pub const STATX_TYPE = 0x0001;
3540pub const STATX_MODE = 0x0002;
3541pub const STATX_NLINK = 0x0004;
3542pub const STATX_UID = 0x0008;
3543pub const STATX_GID = 0x0010;
3544pub const STATX_ATIME = 0x0020;
3545pub const STATX_MTIME = 0x0040;
3546pub const STATX_CTIME = 0x0080;
3547pub const STATX_INO = 0x0100;
3548pub const STATX_SIZE = 0x0200;
3549pub const STATX_BLOCKS = 0x0400;
3550pub const STATX_BASIC_STATS = 0x07ff;
3551
3552pub const STATX_BTIME = 0x0800;
3553
3554pub const STATX_ATTR_COMPRESSED = 0x0004;
3555pub const STATX_ATTR_IMMUTABLE = 0x0010;
3556pub const STATX_ATTR_APPEND = 0x0020;
3557pub const STATX_ATTR_NODUMP = 0x0040;
3558pub const STATX_ATTR_ENCRYPTED = 0x0800;
3559pub const STATX_ATTR_AUTOMOUNT = 0x1000;
3560
3561pub const statx_timestamp = extern struct {
3562 tv_sec: i64,
3563 tv_nsec: u32,
3564 __pad1: u32,
3565};
3566
3567/// Renamed to `Statx` to not conflict with the `statx` function.
3568pub const Statx = extern struct {
3569 /// Mask of bits indicating filled fields
3570 mask: u32,
3571
3572 /// Block size for filesystem I/O
3573 blksize: u32,
3574
3575 /// Extra file attribute indicators
3576 attributes: u64,
3577
3578 /// Number of hard links
3579 nlink: u32,
3580
3581 /// User ID of owner
3582 uid: uid_t,
3583
3584 /// Group ID of owner
3585 gid: gid_t,
3586
3587 /// File type and mode
3588 mode: u16,
3589 __pad1: u16,
3590
3591 /// Inode number
3592 ino: u64,
3593
3594 /// Total size in bytes
3595 size: u64,
3596
3597 /// Number of 512B blocks allocated
3598 blocks: u64,
3599
3600 /// Mask to show what's supported in `attributes`.
3601 attributes_mask: u64,
3602
3603 /// Last access file timestamp
3604 atime: statx_timestamp,
3605
3606 /// Creation file timestamp
3607 btime: statx_timestamp,
3608
3609 /// Last status change file timestamp
3610 ctime: statx_timestamp,
3611
3612 /// Last modification file timestamp
3613 mtime: statx_timestamp,
3614
3615 /// Major ID, if this file represents a device.
3616 rdev_major: u32,
3617
3618 /// Minor ID, if this file represents a device.
3619 rdev_minor: u32,
3620
3621 /// Major ID of the device containing the filesystem where this file resides.
3622 dev_major: u32,
3623
3624 /// Minor ID of the device containing the filesystem where this file resides.
3625 dev_minor: u32,
3626
3627 __pad2: [14]u64,
3628};
3629
3630pub const addrinfo = extern struct {
3631 flags: i32,
3632 family: i32,
3633 socktype: i32,
3634 protocol: i32,
3635 addrlen: socklen_t,
3636 addr: ?*sockaddr,
3637 canonname: ?[*:0]u8,
3638 next: ?*addrinfo,
3639};
3640
3641pub const IPPORT_RESERVED = 1024;
3642
3643pub const IPPROTO = struct {
3644 pub const IP = 0;
3645 pub const HOPOPTS = 0;
3646 pub const ICMP = 1;
3647 pub const IGMP = 2;
3648 pub const IPIP = 4;
3649 pub const TCP = 6;
3650 pub const EGP = 8;
3651 pub const PUP = 12;
3652 pub const UDP = 17;
3653 pub const IDP = 22;
3654 pub const TP = 29;
3655 pub const DCCP = 33;
3656 pub const IPV6 = 41;
3657 pub const ROUTING = 43;
3658 pub const FRAGMENT = 44;
3659 pub const RSVP = 46;
3660 pub const GRE = 47;
3661 pub const ESP = 50;
3662 pub const AH = 51;
3663 pub const ICMPV6 = 58;
3664 pub const NONE = 59;
3665 pub const DSTOPTS = 60;
3666 pub const MTP = 92;
3667 pub const BEETPH = 94;
3668 pub const ENCAP = 98;
3669 pub const PIM = 103;
3670 pub const COMP = 108;
3671 pub const SCTP = 132;
3672 pub const MH = 135;
3673 pub const UDPLITE = 136;
3674 pub const MPLS = 137;
3675 pub const RAW = 255;
3676 pub const MAX = 256;
3677};
3678
3679pub const RR = struct {
3680 pub const A = 1;
3681 pub const CNAME = 5;
3682 pub const AAAA = 28;
3683};
3684
3685pub const tcp_repair_opt = extern struct {
3686 opt_code: u32,
3687 opt_val: u32,
3688};
3689
3690pub const tcp_repair_window = extern struct {
3691 snd_wl1: u32,
3692 snd_wnd: u32,
3693 max_window: u32,
3694 rcv_wnd: u32,
3695 rcv_wup: u32,
3696};
3697
3698pub const TcpRepairOption = enum {
3699 TCP_NO_QUEUE,
3700 TCP_RECV_QUEUE,
3701 TCP_SEND_QUEUE,
3702 TCP_QUEUES_NR,
3703};
3704
3705/// why fastopen failed from client perspective
3706pub const tcp_fastopen_client_fail = enum {
3707 /// catch-all
3708 TFO_STATUS_UNSPEC,
3709 /// if not in TFO_CLIENT_NO_COOKIE mode
3710 TFO_COOKIE_UNAVAILABLE,
3711 /// SYN-ACK did not ack SYN data
3712 TFO_DATA_NOT_ACKED,
3713 /// SYN-ACK did not ack SYN data after timeout
3714 TFO_SYN_RETRANSMITTED,
3715};
3716
3717/// for TCP_INFO socket option
3718pub const TCPI_OPT_TIMESTAMPS = 1;
3719pub const TCPI_OPT_SACK = 2;
3720pub const TCPI_OPT_WSCALE = 4;
3721/// ECN was negociated at TCP session init
3722pub const TCPI_OPT_ECN = 8;
3723/// we received at least one packet with ECT
3724pub const TCPI_OPT_ECN_SEEN = 16;
3725/// SYN-ACK acked data in SYN sent or rcvd
3726pub const TCPI_OPT_SYN_DATA = 32;
3727
3728pub const nfds_t = usize;
3729pub const pollfd = extern struct {
3730 fd: fd_t,
3731 events: i16,
3732 revents: i16,
3733};
3734
3735pub const POLL = struct {
3736 pub const IN = 0x001;
3737 pub const PRI = 0x002;
3738 pub const OUT = 0x004;
3739 pub const ERR = 0x008;
3740 pub const HUP = 0x010;
3741 pub const NVAL = 0x020;
3742 pub const RDNORM = 0x040;
3743 pub const RDBAND = 0x080;
3744};
3745
3746pub const MFD_CLOEXEC = 0x0001;
3747pub const MFD_ALLOW_SEALING = 0x0002;
3748pub const MFD_HUGETLB = 0x0004;
3749pub const MFD_ALL_FLAGS = MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB;
3750
3751pub const HUGETLB_FLAG_ENCODE_SHIFT = 26;
3752pub const HUGETLB_FLAG_ENCODE_MASK = 0x3f;
3753pub const HUGETLB_FLAG_ENCODE_64KB = 16 << HUGETLB_FLAG_ENCODE_SHIFT;
3754pub const HUGETLB_FLAG_ENCODE_512KB = 19 << HUGETLB_FLAG_ENCODE_SHIFT;
3755pub const HUGETLB_FLAG_ENCODE_1MB = 20 << HUGETLB_FLAG_ENCODE_SHIFT;
3756pub const HUGETLB_FLAG_ENCODE_2MB = 21 << HUGETLB_FLAG_ENCODE_SHIFT;
3757pub const HUGETLB_FLAG_ENCODE_8MB = 23 << HUGETLB_FLAG_ENCODE_SHIFT;
3758pub const HUGETLB_FLAG_ENCODE_16MB = 24 << HUGETLB_FLAG_ENCODE_SHIFT;
3759pub const HUGETLB_FLAG_ENCODE_32MB = 25 << HUGETLB_FLAG_ENCODE_SHIFT;
3760pub const HUGETLB_FLAG_ENCODE_256MB = 28 << HUGETLB_FLAG_ENCODE_SHIFT;
3761pub const HUGETLB_FLAG_ENCODE_512MB = 29 << HUGETLB_FLAG_ENCODE_SHIFT;
3762pub const HUGETLB_FLAG_ENCODE_1GB = 30 << HUGETLB_FLAG_ENCODE_SHIFT;
3763pub const HUGETLB_FLAG_ENCODE_2GB = 31 << HUGETLB_FLAG_ENCODE_SHIFT;
3764pub const HUGETLB_FLAG_ENCODE_16GB = 34 << HUGETLB_FLAG_ENCODE_SHIFT;
3765
3766pub const MFD_HUGE_SHIFT = HUGETLB_FLAG_ENCODE_SHIFT;
3767pub const MFD_HUGE_MASK = HUGETLB_FLAG_ENCODE_MASK;
3768pub const MFD_HUGE_64KB = HUGETLB_FLAG_ENCODE_64KB;
3769pub const MFD_HUGE_512KB = HUGETLB_FLAG_ENCODE_512KB;
3770pub const MFD_HUGE_1MB = HUGETLB_FLAG_ENCODE_1MB;
3771pub const MFD_HUGE_2MB = HUGETLB_FLAG_ENCODE_2MB;
3772pub const MFD_HUGE_8MB = HUGETLB_FLAG_ENCODE_8MB;
3773pub const MFD_HUGE_16MB = HUGETLB_FLAG_ENCODE_16MB;
3774pub const MFD_HUGE_32MB = HUGETLB_FLAG_ENCODE_32MB;
3775pub const MFD_HUGE_256MB = HUGETLB_FLAG_ENCODE_256MB;
3776pub const MFD_HUGE_512MB = HUGETLB_FLAG_ENCODE_512MB;
3777pub const MFD_HUGE_1GB = HUGETLB_FLAG_ENCODE_1GB;
3778pub const MFD_HUGE_2GB = HUGETLB_FLAG_ENCODE_2GB;
3779pub const MFD_HUGE_16GB = HUGETLB_FLAG_ENCODE_16GB;
3780
3781pub const RUSAGE_SELF = 0;
3782pub const RUSAGE_CHILDREN = -1;
3783pub const RUSAGE_THREAD = 1;
3784
3785pub const rusage = extern struct {
3786 utime: timeval,
3787 stime: timeval,
3788 maxrss: isize,
3789 ixrss: isize,
3790 idrss: isize,
3791 isrss: isize,
3792 minflt: isize,
3793 majflt: isize,
3794 nswap: isize,
3795 inblock: isize,
3796 oublock: isize,
3797 msgsnd: isize,
3798 msgrcv: isize,
3799 nsignals: isize,
3800 nvcsw: isize,
3801 nivcsw: isize,
3802 __reserved: [16]isize = [1]isize{0} ** 16,
3803};
3804
3805pub const cc_t = u8;
3806pub const speed_t = u32;
3807pub const tcflag_t = u32;
3808
3809pub const NCCS = 32;
3810
3811pub const B0 = 0o0000000;
3812pub const B50 = 0o0000001;
3813pub const B75 = 0o0000002;
3814pub const B110 = 0o0000003;
3815pub const B134 = 0o0000004;
3816pub const B150 = 0o0000005;
3817pub const B200 = 0o0000006;
3818pub const B300 = 0o0000007;
3819pub const B600 = 0o0000010;
3820pub const B1200 = 0o0000011;
3821pub const B1800 = 0o0000012;
3822pub const B2400 = 0o0000013;
3823pub const B4800 = 0o0000014;
3824pub const B9600 = 0o0000015;
3825pub const B19200 = 0o0000016;
3826pub const B38400 = 0o0000017;
3827pub const BOTHER = 0o0010000;
3828pub const B57600 = 0o0010001;
3829pub const B115200 = 0o0010002;
3830pub const B230400 = 0o0010003;
3831pub const B460800 = 0o0010004;
3832pub const B500000 = 0o0010005;
3833pub const B576000 = 0o0010006;
3834pub const B921600 = 0o0010007;
3835pub const B1000000 = 0o0010010;
3836pub const B1152000 = 0o0010011;
3837pub const B1500000 = 0o0010012;
3838pub const B2000000 = 0o0010013;
3839pub const B2500000 = 0o0010014;
3840pub const B3000000 = 0o0010015;
3841pub const B3500000 = 0o0010016;
3842pub const B4000000 = 0o0010017;
3843
3844pub const V = switch (native_arch) {
3845 .powerpc, .powerpc64, .powerpc64le => struct {
3846 pub const INTR = 0;
3847 pub const QUIT = 1;
3848 pub const ERASE = 2;
3849 pub const KILL = 3;
3850 pub const EOF = 4;
3851 pub const MIN = 5;
3852 pub const EOL = 6;
3853 pub const TIME = 7;
3854 pub const EOL2 = 8;
3855 pub const SWTC = 9;
3856 pub const WERASE = 10;
3857 pub const REPRINT = 11;
3858 pub const SUSP = 12;
3859 pub const START = 13;
3860 pub const STOP = 14;
3861 pub const LNEXT = 15;
3862 pub const DISCARD = 16;
3863 },
3864 .sparc, .sparcv9 => struct {
3865 pub const INTR = 0;
3866 pub const QUIT = 1;
3867 pub const ERASE = 2;
3868 pub const KILL = 3;
3869 pub const EOF = 4;
3870 pub const EOL = 5;
3871 pub const EOL2 = 6;
3872 pub const SWTC = 7;
3873 pub const START = 8;
3874 pub const STOP = 9;
3875 pub const SUSP = 10;
3876 pub const DSUSP = 11;
3877 pub const REPRINT = 12;
3878 pub const DISCARD = 13;
3879 pub const WERASE = 14;
3880 pub const LNEXT = 15;
3881 pub const MIN = EOF;
3882 pub const TIME = EOL;
3883 },
3884 .mips, .mipsel, .mips64, .mips64el => struct {
3885 pub const INTR = 0;
3886 pub const QUIT = 1;
3887 pub const ERASE = 2;
3888 pub const KILL = 3;
3889 pub const MIN = 4;
3890 pub const TIME = 5;
3891 pub const EOL2 = 6;
3892 pub const SWTC = 7;
3893 pub const SWTCH = 7;
3894 pub const START = 8;
3895 pub const STOP = 9;
3896 pub const SUSP = 10;
3897 pub const REPRINT = 12;
3898 pub const DISCARD = 13;
3899 pub const WERASE = 14;
3900 pub const LNEXT = 15;
3901 pub const EOF = 16;
3902 pub const EOL = 17;
3903 },
3904 else => struct {
3905 pub const INTR = 0;
3906 pub const QUIT = 1;
3907 pub const ERASE = 2;
3908 pub const KILL = 3;
3909 pub const EOF = 4;
3910 pub const TIME = 5;
3911 pub const MIN = 6;
3912 pub const SWTC = 7;
3913 pub const START = 8;
3914 pub const STOP = 9;
3915 pub const SUSP = 10;
3916 pub const EOL = 11;
3917 pub const REPRINT = 12;
3918 pub const DISCARD = 13;
3919 pub const WERASE = 14;
3920 pub const LNEXT = 15;
3921 pub const EOL2 = 16;
3922 },
3923};
3924
3925pub const IGNBRK = 1;
3926pub const BRKINT = 2;
3927pub const IGNPAR = 4;
3928pub const PARMRK = 8;
3929pub const INPCK = 16;
3930pub const ISTRIP = 32;
3931pub const INLCR = 64;
3932pub const IGNCR = 128;
3933pub const ICRNL = 256;
3934pub const IUCLC = 512;
3935pub const IXON = 1024;
3936pub const IXANY = 2048;
3937pub const IXOFF = 4096;
3938pub const IMAXBEL = 8192;
3939pub const IUTF8 = 16384;
3940
3941pub const OPOST = 1;
3942pub const OLCUC = 2;
3943pub const ONLCR = 4;
3944pub const OCRNL = 8;
3945pub const ONOCR = 16;
3946pub const ONLRET = 32;
3947pub const OFILL = 64;
3948pub const OFDEL = 128;
3949pub const VTDLY = 16384;
3950pub const VT0 = 0;
3951pub const VT1 = 16384;
3952
3953pub const CSIZE = 48;
3954pub const CS5 = 0;
3955pub const CS6 = 16;
3956pub const CS7 = 32;
3957pub const CS8 = 48;
3958pub const CSTOPB = 64;
3959pub const CREAD = 128;
3960pub const PARENB = 256;
3961pub const PARODD = 512;
3962pub const HUPCL = 1024;
3963pub const CLOCAL = 2048;
3964
3965pub const ISIG = 1;
3966pub const ICANON = 2;
3967pub const ECHO = 8;
3968pub const ECHOE = 16;
3969pub const ECHOK = 32;
3970pub const ECHONL = 64;
3971pub const NOFLSH = 128;
3972pub const TOSTOP = 256;
3973pub const IEXTEN = 32768;
3974
3975pub const TCSA = enum(c_uint) {
3976 NOW,
3977 DRAIN,
3978 FLUSH,
3979 _,
3980};
3981
3982pub const termios = extern struct {
3983 iflag: tcflag_t,
3984 oflag: tcflag_t,
3985 cflag: tcflag_t,
3986 lflag: tcflag_t,
3987 line: cc_t,
3988 cc: [NCCS]cc_t,
3989 ispeed: speed_t,
3990 ospeed: speed_t,
3991};
3992
3993pub const SIOCGIFINDEX = 0x8933;
3994pub const IFNAMESIZE = 16;
3995
3996pub const ifmap = extern struct {
3997 mem_start: u32,
3998 mem_end: u32,
3999 base_addr: u16,
4000 irq: u8,
4001 dma: u8,
4002 port: u8,
4003};
4004
4005pub const ifreq = extern struct {
4006 ifrn: extern union {
4007 name: [IFNAMESIZE]u8,
4008 },
4009 ifru: extern union {
4010 addr: sockaddr,
4011 dstaddr: sockaddr,
4012 broadaddr: sockaddr,
4013 netmask: sockaddr,
4014 hwaddr: sockaddr,
4015 flags: i16,
4016 ivalue: i32,
4017 mtu: i32,
4018 map: ifmap,
4019 slave: [IFNAMESIZE - 1:0]u8,
4020 newname: [IFNAMESIZE - 1:0]u8,
4021 data: ?[*]u8,
4022 },
4023};
4024
4025// doc comments copied from musl
4026pub const rlimit_resource = enum(c_int) {
4027 /// Per-process CPU limit, in seconds.
4028 CPU,
4029
4030 /// Largest file that can be created, in bytes.
4031 FSIZE,
4032
4033 /// Maximum size of data segment, in bytes.
4034 DATA,
4035
4036 /// Maximum size of stack segment, in bytes.
4037 STACK,
4038
4039 /// Largest core file that can be created, in bytes.
4040 CORE,
4041
4042 /// Largest resident set size, in bytes.
4043 /// This affects swapping; processes that are exceeding their
4044 /// resident set size will be more likely to have physical memory
4045 /// taken from them.
4046 RSS,
4047
4048 /// Number of processes.
4049 NPROC,
4050
4051 /// Number of open files.
4052 NOFILE,
4053
4054 /// Locked-in-memory address space.
4055 MEMLOCK,
4056
4057 /// Address space limit.
4058 AS,
4059
4060 /// Maximum number of file locks.
4061 LOCKS,
4062
4063 /// Maximum number of pending signals.
4064 SIGPENDING,
4065
4066 /// Maximum bytes in POSIX message queues.
4067 MSGQUEUE,
4068
4069 /// Maximum nice priority allowed to raise to.
4070 /// Nice levels 19 .. -20 correspond to 0 .. 39
4071 /// values of this resource limit.
4072 NICE,
4073
4074 /// Maximum realtime priority allowed for non-priviledged
4075 /// processes.
4076 RTPRIO,
4077
4078 /// Maximum CPU time in µs that a process scheduled under a real-time
4079 /// scheduling policy may consume without making a blocking system
4080 /// call before being forcibly descheduled.
4081 RTTIME,
4082
4083 _,
4084};
4085
4086pub const rlim_t = u64;
4087
4088pub const RLIM = struct {
4089 /// No limit
4090 pub const INFINITY = ~@as(rlim_t, 0);
4091
4092 pub const SAVED_MAX = INFINITY;
4093 pub const SAVED_CUR = INFINITY;
4094};
4095
4096pub const rlimit = extern struct {
4097 /// Soft limit
4098 cur: rlim_t,
4099 /// Hard limit
4100 max: rlim_t,
4101};
4102
4103pub const MADV = struct {
4104 pub const NORMAL = 0;
4105 pub const RANDOM = 1;
4106 pub const SEQUENTIAL = 2;
4107 pub const WILLNEED = 3;
4108 pub const DONTNEED = 4;
4109 pub const FREE = 8;
4110 pub const REMOVE = 9;
4111 pub const DONTFORK = 10;
4112 pub const DOFORK = 11;
4113 pub const MERGEABLE = 12;
4114 pub const UNMERGEABLE = 13;
4115 pub const HUGEPAGE = 14;
4116 pub const NOHUGEPAGE = 15;
4117 pub const DONTDUMP = 16;
4118 pub const DODUMP = 17;
4119 pub const WIPEONFORK = 18;
4120 pub const KEEPONFORK = 19;
4121 pub const COLD = 20;
4122 pub const PAGEOUT = 21;
4123 pub const HWPOISON = 100;
4124 pub const SOFT_OFFLINE = 101;
4125};
4126
4127pub const POSIX_FADV = switch (native_arch) {
4128 .s390x => if (@typeInfo(usize).Int.bits == 64) struct {
4129 pub const NORMAL = 0;
4130 pub const RANDOM = 1;
4131 pub const SEQUENTIAL = 2;
4132 pub const WILLNEED = 3;
4133 pub const DONTNEED = 6;
4134 pub const NOREUSE = 7;
4135 } else struct {
4136 pub const NORMAL = 0;
4137 pub const RANDOM = 1;
4138 pub const SEQUENTIAL = 2;
4139 pub const WILLNEED = 3;
4140 pub const DONTNEED = 4;
4141 pub const NOREUSE = 5;
4142 },
4143 else => struct {
4144 pub const NORMAL = 0;
4145 pub const RANDOM = 1;
4146 pub const SEQUENTIAL = 2;
4147 pub const WILLNEED = 3;
4148 pub const DONTNEED = 4;
4149 pub const NOREUSE = 5;
4150 },
4151};
4152
4153/// The timespec struct used by the kernel.
4154pub const kernel_timespec = if (@sizeOf(usize) >= 8) timespec else extern struct {
4155 tv_sec: i64,
4156 tv_nsec: i64,
4157};
4158
4159pub const timespec = extern struct {
4160 tv_sec: isize,
4161 tv_nsec: isize,
4162};
4163
4164pub const XDP = struct {
4165 pub const SHARED_UMEM = (1 << 0);
4166 pub const COPY = (1 << 1);
4167 pub const ZEROCOPY = (1 << 2);
4168 pub const UMEM_UNALIGNED_CHUNK_FLAG = (1 << 0);
4169 pub const USE_NEED_WAKEUP = (1 << 3);
4170
4171 pub const MMAP_OFFSETS = 1;
4172 pub const RX_RING = 2;
4173 pub const TX_RING = 3;
4174 pub const UMEM_REG = 4;
4175 pub const UMEM_FILL_RING = 5;
4176 pub const UMEM_COMPLETION_RING = 6;
4177 pub const STATISTICS = 7;
4178 pub const OPTIONS = 8;
4179
4180 pub const OPTIONS_ZEROCOPY = (1 << 0);
4181
4182 pub const PGOFF_RX_RING = 0;
4183 pub const PGOFF_TX_RING = 0x80000000;
4184 pub const UMEM_PGOFF_FILL_RING = 0x100000000;
4185 pub const UMEM_PGOFF_COMPLETION_RING = 0x180000000;
4186};
4187
4188pub const xdp_ring_offset = extern struct {
4189 producer: u64,
4190 consumer: u64,
4191 desc: u64,
4192 flags: u64,
4193};
4194
4195pub const xdp_mmap_offsets = extern struct {
4196 rx: xdp_ring_offset,
4197 tx: xdp_ring_offset,
4198 fr: xdp_ring_offset,
4199 cr: xdp_ring_offset,
4200};
4201
4202pub const xdp_umem_reg = extern struct {
4203 addr: u64,
4204 len: u64,
4205 chunk_size: u32,
4206 headroom: u32,
4207 flags: u32,
4208};
4209
4210pub const xdp_statistics = extern struct {
4211 rx_dropped: u64,
4212 rx_invalid_descs: u64,
4213 tx_invalid_descs: u64,
4214 rx_ring_full: u64,
4215 rx_fill_ring_empty_descs: u64,
4216 tx_ring_empty_descs: u64,
4217};
4218
4219pub const xdp_options = extern struct {
4220 flags: u32,
4221};
4222
4223pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT = 48;
4224pub const XSK_UNALIGNED_BUF_ADDR_MASK = (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1;
4225
4226pub const xdp_desc = extern struct {
4227 addr: u64,
4228 len: u32,
4229 options: u32,
4230};
4231
4232fn issecure_mask(comptime x: comptime_int) comptime_int {
4233 return 1 << x;
4234}
4235
4236pub const SECUREBITS_DEFAULT = 0x00000000;
4237
4238pub const SECURE_NOROOT = 0;
4239pub const SECURE_NOROOT_LOCKED = 1;
4240
4241pub const SECBIT_NOROOT = issecure_mask(SECURE_NOROOT);
4242pub const SECBIT_NOROOT_LOCKED = issecure_mask(SECURE_NOROOT_LOCKED);
4243
4244pub const SECURE_NO_SETUID_FIXUP = 2;
4245pub const SECURE_NO_SETUID_FIXUP_LOCKED = 3;
4246
4247pub const SECBIT_NO_SETUID_FIXUP = issecure_mask(SECURE_NO_SETUID_FIXUP);
4248pub const SECBIT_NO_SETUID_FIXUP_LOCKED = issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED);
4249
4250pub const SECURE_KEEP_CAPS = 4;
4251pub const SECURE_KEEP_CAPS_LOCKED = 5;
4252
4253pub const SECBIT_KEEP_CAPS = issecure_mask(SECURE_KEEP_CAPS);
4254pub const SECBIT_KEEP_CAPS_LOCKED = issecure_mask(SECURE_KEEP_CAPS_LOCKED);
4255
4256pub const SECURE_NO_CAP_AMBIENT_RAISE = 6;
4257pub const SECURE_NO_CAP_AMBIENT_RAISE_LOCKED = 7;
4258
4259pub const SECBIT_NO_CAP_AMBIENT_RAISE = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE);
4260pub const SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED);
4261
4262pub const SECURE_ALL_BITS = issecure_mask(SECURE_NOROOT) |
4263 issecure_mask(SECURE_NO_SETUID_FIXUP) |
4264 issecure_mask(SECURE_KEEP_CAPS) |
4265 issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE);
4266pub const SECURE_ALL_LOCKS = SECURE_ALL_BITS << 1;
4267
4268pub const PR = enum(i32) {
4269 SET_PDEATHSIG = 1,
4270 GET_PDEATHSIG = 2,
4271
4272 GET_DUMPABLE = 3,
4273 SET_DUMPABLE = 4,
4274
4275 GET_UNALIGN = 5,
4276 SET_UNALIGN = 6,
4277
4278 GET_KEEPCAPS = 7,
4279 SET_KEEPCAPS = 8,
4280
4281 GET_FPEMU = 9,
4282 SET_FPEMU = 10,
4283
4284 GET_FPEXC = 11,
4285 SET_FPEXC = 12,
4286
4287 GET_TIMING = 13,
4288 SET_TIMING = 14,
4289
4290 SET_NAME = 15,
4291 GET_NAME = 16,
4292
4293 GET_ENDIAN = 19,
4294 SET_ENDIAN = 20,
4295
4296 GET_SECCOMP = 21,
4297 SET_SECCOMP = 22,
4298
4299 CAPBSET_READ = 23,
4300 CAPBSET_DROP = 24,
4301
4302 GET_TSC = 25,
4303 SET_TSC = 26,
4304
4305 GET_SECUREBITS = 27,
4306 SET_SECUREBITS = 28,
4307
4308 SET_TIMERSLACK = 29,
4309 GET_TIMERSLACK = 30,
4310
4311 TASK_PERF_EVENTS_DISABLE = 31,
4312 TASK_PERF_EVENTS_ENABLE = 32,
4313
4314 MCE_KILL = 33,
4315
4316 MCE_KILL_GET = 34,
4317
4318 SET_MM = 35,
4319
4320 SET_PTRACER = 0x59616d61,
4321
4322 SET_CHILD_SUBREAPER = 36,
4323 GET_CHILD_SUBREAPER = 37,
4324
4325 SET_NO_NEW_PRIVS = 38,
4326 GET_NO_NEW_PRIVS = 39,
4327
4328 GET_TID_ADDRESS = 40,
4329
4330 SET_THP_DISABLE = 41,
4331 GET_THP_DISABLE = 42,
4332
4333 MPX_ENABLE_MANAGEMENT = 43,
4334 MPX_DISABLE_MANAGEMENT = 44,
4335
4336 SET_FP_MODE = 45,
4337 GET_FP_MODE = 46,
4338
4339 CAP_AMBIENT = 47,
4340
4341 SVE_SET_VL = 50,
4342 SVE_GET_VL = 51,
4343
4344 GET_SPECULATION_CTRL = 52,
4345 SET_SPECULATION_CTRL = 53,
4346
4347 _,
4348
4349 pub const UNALIGN_NOPRINT = 1;
4350 pub const UNALIGN_SIGBUS = 2;
4351
4352 pub const FPEMU_NOPRINT = 1;
4353 pub const FPEMU_SIGFPE = 2;
4354
4355 pub const FP_EXC_SW_ENABLE = 0x80;
4356 pub const FP_EXC_DIV = 0x010000;
4357 pub const FP_EXC_OVF = 0x020000;
4358 pub const FP_EXC_UND = 0x040000;
4359 pub const FP_EXC_RES = 0x080000;
4360 pub const FP_EXC_INV = 0x100000;
4361 pub const FP_EXC_DISABLED = 0;
4362 pub const FP_EXC_NONRECOV = 1;
4363 pub const FP_EXC_ASYNC = 2;
4364 pub const FP_EXC_PRECISE = 3;
4365
4366 pub const TIMING_STATISTICAL = 0;
4367 pub const TIMING_TIMESTAMP = 1;
4368
4369 pub const ENDIAN_BIG = 0;
4370 pub const ENDIAN_LITTLE = 1;
4371 pub const ENDIAN_PPC_LITTLE = 2;
4372
4373 pub const TSC_ENABLE = 1;
4374 pub const TSC_SIGSEGV = 2;
4375
4376 pub const MCE_KILL_CLEAR = 0;
4377 pub const MCE_KILL_SET = 1;
4378
4379 pub const MCE_KILL_LATE = 0;
4380 pub const MCE_KILL_EARLY = 1;
4381 pub const MCE_KILL_DEFAULT = 2;
4382
4383 pub const SET_MM_START_CODE = 1;
4384 pub const SET_MM_END_CODE = 2;
4385 pub const SET_MM_START_DATA = 3;
4386 pub const SET_MM_END_DATA = 4;
4387 pub const SET_MM_START_STACK = 5;
4388 pub const SET_MM_START_BRK = 6;
4389 pub const SET_MM_BRK = 7;
4390 pub const SET_MM_ARG_START = 8;
4391 pub const SET_MM_ARG_END = 9;
4392 pub const SET_MM_ENV_START = 10;
4393 pub const SET_MM_ENV_END = 11;
4394 pub const SET_MM_AUXV = 12;
4395 pub const SET_MM_EXE_FILE = 13;
4396 pub const SET_MM_MAP = 14;
4397 pub const SET_MM_MAP_SIZE = 15;
4398
4399 pub const SET_PTRACER_ANY = std.math.maxInt(c_ulong);
4400
4401 pub const FP_MODE_FR = 1 << 0;
4402 pub const FP_MODE_FRE = 1 << 1;
4403
4404 pub const CAP_AMBIENT_IS_SET = 1;
4405 pub const CAP_AMBIENT_RAISE = 2;
4406 pub const CAP_AMBIENT_LOWER = 3;
4407 pub const CAP_AMBIENT_CLEAR_ALL = 4;
4408
4409 pub const SVE_SET_VL_ONEXEC = 1 << 18;
4410 pub const SVE_VL_LEN_MASK = 0xffff;
4411 pub const SVE_VL_INHERIT = 1 << 17;
4412
4413 pub const SPEC_STORE_BYPASS = 0;
4414 pub const SPEC_NOT_AFFECTED = 0;
4415 pub const SPEC_PRCTL = 1 << 0;
4416 pub const SPEC_ENABLE = 1 << 1;
4417 pub const SPEC_DISABLE = 1 << 2;
4418 pub const SPEC_FORCE_DISABLE = 1 << 3;
4419};
4420
4421pub const prctl_mm_map = extern struct {
4422 start_code: u64,
4423 end_code: u64,
4424 start_data: u64,
4425 end_data: u64,
4426 start_brk: u64,
4427 brk: u64,
4428 start_stack: u64,
4429 arg_start: u64,
4430 arg_end: u64,
4431 env_start: u64,
4432 env_end: u64,
4433 auxv: *u64,
4434 auxv_size: u32,
4435 exe_fd: u32,
4436};
4437
4438pub const NETLINK = struct {
4439
4440 /// Routing/device hook
4441 pub const ROUTE = 0;
4442
4443 /// Unused number
4444 pub const UNUSED = 1;
4445
4446 /// Reserved for user mode socket protocols
4447 pub const USERSOCK = 2;
4448
4449 /// Unused number, formerly ip_queue
4450 pub const FIREWALL = 3;
4451
4452 /// socket monitoring
4453 pub const SOCK_DIAG = 4;
4454
4455 /// netfilter/iptables ULOG
4456 pub const NFLOG = 5;
4457
4458 /// ipsec
4459 pub const XFRM = 6;
4460
4461 /// SELinux event notifications
4462 pub const SELINUX = 7;
4463
4464 /// Open-iSCSI
4465 pub const ISCSI = 8;
4466
4467 /// auditing
4468 pub const AUDIT = 9;
4469
4470 pub const FIB_LOOKUP = 10;
4471
4472 pub const CONNECTOR = 11;
4473
4474 /// netfilter subsystem
4475 pub const NETFILTER = 12;
4476
4477 pub const IP6_FW = 13;
4478
4479 /// DECnet routing messages
4480 pub const DNRTMSG = 14;
4481
4482 /// Kernel messages to userspace
4483 pub const KOBJECT_UEVENT = 15;
4484
4485 pub const GENERIC = 16;
4486
4487 // leave room for NETLINK_DM (DM Events)
4488
4489 /// SCSI Transports
4490 pub const SCSITRANSPORT = 18;
4491
4492 pub const ECRYPTFS = 19;
4493
4494 pub const RDMA = 20;
4495
4496 /// Crypto layer
4497 pub const CRYPTO = 21;
4498
4499 /// SMC monitoring
4500 pub const SMC = 22;
4501};
4502
4503// Flags values
4504
4505/// It is request message.
4506pub const NLM_F_REQUEST = 0x01;
4507
4508/// Multipart message, terminated by NLMSG_DONE
4509pub const NLM_F_MULTI = 0x02;
4510
4511/// Reply with ack, with zero or error code
4512pub const NLM_F_ACK = 0x04;
4513
4514/// Echo this request
4515pub const NLM_F_ECHO = 0x08;
4516
4517/// Dump was inconsistent due to sequence change
4518pub const NLM_F_DUMP_INTR = 0x10;
4519
4520/// Dump was filtered as requested
4521pub const NLM_F_DUMP_FILTERED = 0x20;
4522
4523// Modifiers to GET request
4524
4525/// specify tree root
4526pub const NLM_F_ROOT = 0x100;
4527
4528/// return all matching
4529pub const NLM_F_MATCH = 0x200;
4530
4531/// atomic GET
4532pub const NLM_F_ATOMIC = 0x400;
4533pub const NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH;
4534
4535// Modifiers to NEW request
4536
4537/// Override existing
4538pub const NLM_F_REPLACE = 0x100;
4539
4540/// Do not touch, if it exists
4541pub const NLM_F_EXCL = 0x200;
4542
4543/// Create, if it does not exist
4544pub const NLM_F_CREATE = 0x400;
4545
4546/// Add to end of list
4547pub const NLM_F_APPEND = 0x800;
4548
4549// Modifiers to DELETE request
4550
4551/// Do not delete recursively
4552pub const NLM_F_NONREC = 0x100;
4553
4554// Flags for ACK message
4555
4556/// request was capped
4557pub const NLM_F_CAPPED = 0x100;
4558
4559/// extended ACK TVLs were included
4560pub const NLM_F_ACK_TLVS = 0x200;
4561
4562pub const NetlinkMessageType = enum(u16) {
4563 /// < 0x10: reserved control messages
4564 pub const MIN_TYPE = 0x10;
4565
4566 /// Nothing.
4567 NOOP = 0x1,
4568
4569 /// Error
4570 ERROR = 0x2,
4571
4572 /// End of a dump
4573 DONE = 0x3,
4574
4575 /// Data lost
4576 OVERRUN = 0x4,
4577
4578 // rtlink types
4579
4580 RTM_NEWLINK = 16,
4581 RTM_DELLINK,
4582 RTM_GETLINK,
4583 RTM_SETLINK,
4584
4585 RTM_NEWADDR = 20,
4586 RTM_DELADDR,
4587 RTM_GETADDR,
4588
4589 RTM_NEWROUTE = 24,
4590 RTM_DELROUTE,
4591 RTM_GETROUTE,
4592
4593 RTM_NEWNEIGH = 28,
4594 RTM_DELNEIGH,
4595 RTM_GETNEIGH,
4596
4597 RTM_NEWRULE = 32,
4598 RTM_DELRULE,
4599 RTM_GETRULE,
4600
4601 RTM_NEWQDISC = 36,
4602 RTM_DELQDISC,
4603 RTM_GETQDISC,
4604
4605 RTM_NEWTCLASS = 40,
4606 RTM_DELTCLASS,
4607 RTM_GETTCLASS,
4608
4609 RTM_NEWTFILTER = 44,
4610 RTM_DELTFILTER,
4611 RTM_GETTFILTER,
4612
4613 RTM_NEWACTION = 48,
4614 RTM_DELACTION,
4615 RTM_GETACTION,
4616
4617 RTM_NEWPREFIX = 52,
4618
4619 RTM_GETMULTICAST = 58,
4620
4621 RTM_GETANYCAST = 62,
4622
4623 RTM_NEWNEIGHTBL = 64,
4624 RTM_GETNEIGHTBL = 66,
4625 RTM_SETNEIGHTBL,
4626
4627 RTM_NEWNDUSEROPT = 68,
4628
4629 RTM_NEWADDRLABEL = 72,
4630 RTM_DELADDRLABEL,
4631 RTM_GETADDRLABEL,
4632
4633 RTM_GETDCB = 78,
4634 RTM_SETDCB,
4635
4636 RTM_NEWNETCONF = 80,
4637 RTM_DELNETCONF,
4638 RTM_GETNETCONF = 82,
4639
4640 RTM_NEWMDB = 84,
4641 RTM_DELMDB = 85,
4642 RTM_GETMDB = 86,
4643
4644 RTM_NEWNSID = 88,
4645 RTM_DELNSID = 89,
4646 RTM_GETNSID = 90,
4647
4648 RTM_NEWSTATS = 92,
4649 RTM_GETSTATS = 94,
4650
4651 RTM_NEWCACHEREPORT = 96,
4652
4653 RTM_NEWCHAIN = 100,
4654 RTM_DELCHAIN,
4655 RTM_GETCHAIN,
4656
4657 RTM_NEWNEXTHOP = 104,
4658 RTM_DELNEXTHOP,
4659 RTM_GETNEXTHOP,
4660
4661 _,
4662};
4663
4664/// Netlink message header
4665/// Specified in RFC 3549 Section 2.3.2
4666pub const nlmsghdr = extern struct {
4667 /// Length of message including header
4668 len: u32,
4669
4670 /// Message content
4671 @"type": NetlinkMessageType,
4672
4673 /// Additional flags
4674 flags: u16,
4675
4676 /// Sequence number
4677 seq: u32,
4678
4679 /// Sending process port ID
4680 pid: u32,
4681};
4682
4683pub const ifinfomsg = extern struct {
4684 family: u8,
4685 __pad1: u8 = 0,
4686
4687 /// ARPHRD_*
4688 @"type": c_ushort,
4689
4690 /// Link index
4691 index: c_int,
4692
4693 /// IFF_* flags
4694 flags: c_uint,
4695
4696 /// IFF_* change mask
4697 change: c_uint,
4698};
4699
4700pub const rtattr = extern struct {
4701 /// Length of option
4702 len: c_ushort,
4703
4704 /// Type of option
4705 @"type": IFLA,
4706
4707 pub const ALIGNTO = 4;
4708};
4709
4710pub const IFLA = enum(c_ushort) {
4711 UNSPEC,
4712 ADDRESS,
4713 BROADCAST,
4714 IFNAME,
4715 MTU,
4716 LINK,
4717 QDISC,
4718 STATS,
4719 COST,
4720 PRIORITY,
4721 MASTER,
4722
4723 /// Wireless Extension event
4724 WIRELESS,
4725
4726 /// Protocol specific information for a link
4727 PROTINFO,
4728
4729 TXQLEN,
4730 MAP,
4731 WEIGHT,
4732 OPERSTATE,
4733 LINKMODE,
4734 LINKINFO,
4735 NET_NS_PID,
4736 IFALIAS,
4737
4738 /// Number of VFs if device is SR-IOV PF
4739 NUM_VF,
4740
4741 VFINFO_LIST,
4742 STATS64,
4743 VF_PORTS,
4744 PORT_SELF,
4745 AF_SPEC,
4746
4747 /// Group the device belongs to
4748 GROUP,
4749
4750 NET_NS_FD,
4751
4752 /// Extended info mask, VFs, etc
4753 EXT_MASK,
4754
4755 /// Promiscuity count: > 0 means acts PROMISC
4756 PROMISCUITY,
4757
4758 NUM_TX_QUEUES,
4759 NUM_RX_QUEUES,
4760 CARRIER,
4761 PHYS_PORT_ID,
4762 CARRIER_CHANGES,
4763 PHYS_SWITCH_ID,
4764 LINK_NETNSID,
4765 PHYS_PORT_NAME,
4766 PROTO_DOWN,
4767 GSO_MAX_SEGS,
4768 GSO_MAX_SIZE,
4769 PAD,
4770 XDP,
4771 EVENT,
4772
4773 NEW_NETNSID,
4774 IF_NETNSID,
4775
4776 CARRIER_UP_COUNT,
4777 CARRIER_DOWN_COUNT,
4778 NEW_IFINDEX,
4779 MIN_MTU,
4780 MAX_MTU,
4781
4782 _,
4783
4784 pub const TARGET_NETNSID: IFLA = .IF_NETNSID;
4785};
4786
4787pub const rtnl_link_ifmap = extern struct {
4788 mem_start: u64,
4789 mem_end: u64,
4790 base_addr: u64,
4791 irq: u16,
4792 dma: u8,
4793 port: u8,
4794};
4795
4796pub const rtnl_link_stats = extern struct {
4797 /// total packets received
4798 rx_packets: u32,
4799
4800 /// total packets transmitted
4801 tx_packets: u32,
4802
4803 /// total bytes received
4804 rx_bytes: u32,
4805
4806 /// total bytes transmitted
4807 tx_bytes: u32,
4808
4809 /// bad packets received
4810 rx_errors: u32,
4811
4812 /// packet transmit problems
4813 tx_errors: u32,
4814
4815 /// no space in linux buffers
4816 rx_dropped: u32,
4817
4818 /// no space available in linux
4819 tx_dropped: u32,
4820
4821 /// multicast packets received
4822 multicast: u32,
4823
4824 collisions: u32,
4825
4826 // detailed rx_errors
4827
4828 rx_length_errors: u32,
4829
4830 /// receiver ring buff overflow
4831 rx_over_errors: u32,
4832
4833 /// recved pkt with crc error
4834 rx_crc_errors: u32,
4835
4836 /// recv'd frame alignment error
4837 rx_frame_errors: u32,
4838
4839 /// recv'r fifo overrun
4840 rx_fifo_errors: u32,
4841
4842 /// receiver missed packet
4843 rx_missed_errors: u32,
4844
4845 // detailed tx_errors
4846 tx_aborted_errors: u32,
4847 tx_carrier_errors: u32,
4848 tx_fifo_errors: u32,
4849 tx_heartbeat_errors: u32,
4850 tx_window_errors: u32,
4851
4852 // for cslip etc
4853
4854 rx_compressed: u32,
4855 tx_compressed: u32,
4856
4857 /// dropped, no handler found
4858 rx_nohandler: u32,
4859};
4860
4861pub const rtnl_link_stats64 = extern struct {
4862 /// total packets received
4863 rx_packets: u64,
4864
4865 /// total packets transmitted
4866 tx_packets: u64,
4867
4868 /// total bytes received
4869 rx_bytes: u64,
4870
4871 /// total bytes transmitted
4872 tx_bytes: u64,
4873
4874 /// bad packets received
4875 rx_errors: u64,
4876
4877 /// packet transmit problems
4878 tx_errors: u64,
4879
4880 /// no space in linux buffers
4881 rx_dropped: u64,
4882
4883 /// no space available in linux
4884 tx_dropped: u64,
4885
4886 /// multicast packets received
4887 multicast: u64,
4888
4889 collisions: u64,
4890
4891 // detailed rx_errors
4892
4893 rx_length_errors: u64,
4894
4895 /// receiver ring buff overflow
4896 rx_over_errors: u64,
4897
4898 /// recved pkt with crc error
4899 rx_crc_errors: u64,
4900
4901 /// recv'd frame alignment error
4902 rx_frame_errors: u64,
4903
4904 /// recv'r fifo overrun
4905 rx_fifo_errors: u64,
4906
4907 /// receiver missed packet
4908 rx_missed_errors: u64,
4909
4910 // detailed tx_errors
4911 tx_aborted_errors: u64,
4912 tx_carrier_errors: u64,
4913 tx_fifo_errors: u64,
4914 tx_heartbeat_errors: u64,
4915 tx_window_errors: u64,
4916
4917 // for cslip etc
4918
4919 rx_compressed: u64,
4920 tx_compressed: u64,
4921
4922 /// dropped, no handler found
4923 rx_nohandler: u64,
4924};
lib/std/os/linux/arm-eabi.zig+647-2
...@@ -1,4 +1,16 @@...@@ -1,4 +1,16 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const iovec = std.os.iovec;
5const iovec_const = std.os.iovec_const;
6const socklen_t = linux.socklen_t;
7const stack_t = linux.stack_t;
8const sigset_t = linux.sigset_t;
9const uid_t = linux.uid_t;
10const gid_t = linux.gid_t;
11const pid_t = linux.pid_t;
12const sockaddr = linux.sockaddr;
13const timespec = linux.timespec;
214
3pub fn syscall0(number: SYS) usize {15pub fn syscall0(number: SYS) usize {
4 return asm volatile ("svc #0"16 return asm volatile ("svc #0"
...@@ -86,7 +98,15 @@ pub fn syscall6(...@@ -86,7 +98,15 @@ pub fn syscall6(
86}98}
8799
88/// This matches the libc clone function.100/// This matches the libc clone function.
89pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;101pub extern fn clone(
102 func: fn (arg: usize) callconv(.C) u8,
103 stack: usize,
104 flags: u32,
105 arg: usize,
106 ptid: *i32,
107 tls: usize,
108 ctid: *i32,
109) usize;
90110
91pub fn restore() callconv(.Naked) void {111pub fn restore() callconv(.Naked) void {
92 return asm volatile ("svc #0"112 return asm volatile ("svc #0"
...@@ -103,3 +123,628 @@ pub fn restore_rt() callconv(.Naked) void {...@@ -103,3 +123,628 @@ pub fn restore_rt() callconv(.Naked) void {
103 : "memory"123 : "memory"
104 );124 );
105}125}
126
127pub const SYS = enum(usize) {
128 restart_syscall = 0,
129 exit = 1,
130 fork = 2,
131 read = 3,
132 write = 4,
133 open = 5,
134 close = 6,
135 creat = 8,
136 link = 9,
137 unlink = 10,
138 execve = 11,
139 chdir = 12,
140 mknod = 14,
141 chmod = 15,
142 lchown = 16,
143 lseek = 19,
144 getpid = 20,
145 mount = 21,
146 setuid = 23,
147 getuid = 24,
148 ptrace = 26,
149 pause = 29,
150 access = 33,
151 nice = 34,
152 sync = 36,
153 kill = 37,
154 rename = 38,
155 mkdir = 39,
156 rmdir = 40,
157 dup = 41,
158 pipe = 42,
159 times = 43,
160 brk = 45,
161 setgid = 46,
162 getgid = 47,
163 geteuid = 49,
164 getegid = 50,
165 acct = 51,
166 umount2 = 52,
167 ioctl = 54,
168 fcntl = 55,
169 setpgid = 57,
170 umask = 60,
171 chroot = 61,
172 ustat = 62,
173 dup2 = 63,
174 getppid = 64,
175 getpgrp = 65,
176 setsid = 66,
177 sigaction = 67,
178 setreuid = 70,
179 setregid = 71,
180 sigsuspend = 72,
181 sigpending = 73,
182 sethostname = 74,
183 setrlimit = 75,
184 getrusage = 77,
185 gettimeofday = 78,
186 settimeofday = 79,
187 getgroups = 80,
188 setgroups = 81,
189 symlink = 83,
190 readlink = 85,
191 uselib = 86,
192 swapon = 87,
193 reboot = 88,
194 munmap = 91,
195 truncate = 92,
196 ftruncate = 93,
197 fchmod = 94,
198 fchown = 95,
199 getpriority = 96,
200 setpriority = 97,
201 statfs = 99,
202 fstatfs = 100,
203 syslog = 103,
204 setitimer = 104,
205 getitimer = 105,
206 stat = 106,
207 lstat = 107,
208 fstat = 108,
209 vhangup = 111,
210 wait4 = 114,
211 swapoff = 115,
212 sysinfo = 116,
213 fsync = 118,
214 sigreturn = 119,
215 clone = 120,
216 setdomainname = 121,
217 uname = 122,
218 adjtimex = 124,
219 mprotect = 125,
220 sigprocmask = 126,
221 init_module = 128,
222 delete_module = 129,
223 quotactl = 131,
224 getpgid = 132,
225 fchdir = 133,
226 bdflush = 134,
227 sysfs = 135,
228 personality = 136,
229 setfsuid = 138,
230 setfsgid = 139,
231 _llseek = 140,
232 getdents = 141,
233 _newselect = 142,
234 flock = 143,
235 msync = 144,
236 readv = 145,
237 writev = 146,
238 getsid = 147,
239 fdatasync = 148,
240 _sysctl = 149,
241 mlock = 150,
242 munlock = 151,
243 mlockall = 152,
244 munlockall = 153,
245 sched_setparam = 154,
246 sched_getparam = 155,
247 sched_setscheduler = 156,
248 sched_getscheduler = 157,
249 sched_yield = 158,
250 sched_get_priority_max = 159,
251 sched_get_priority_min = 160,
252 sched_rr_get_interval = 161,
253 nanosleep = 162,
254 mremap = 163,
255 setresuid = 164,
256 getresuid = 165,
257 poll = 168,
258 nfsservctl = 169,
259 setresgid = 170,
260 getresgid = 171,
261 prctl = 172,
262 rt_sigreturn = 173,
263 rt_sigaction = 174,
264 rt_sigprocmask = 175,
265 rt_sigpending = 176,
266 rt_sigtimedwait = 177,
267 rt_sigqueueinfo = 178,
268 rt_sigsuspend = 179,
269 pread64 = 180,
270 pwrite64 = 181,
271 chown = 182,
272 getcwd = 183,
273 capget = 184,
274 capset = 185,
275 sigaltstack = 186,
276 sendfile = 187,
277 vfork = 190,
278 ugetrlimit = 191,
279 mmap2 = 192,
280 truncate64 = 193,
281 ftruncate64 = 194,
282 stat64 = 195,
283 lstat64 = 196,
284 fstat64 = 197,
285 lchown32 = 198,
286 getuid32 = 199,
287 getgid32 = 200,
288 geteuid32 = 201,
289 getegid32 = 202,
290 setreuid32 = 203,
291 setregid32 = 204,
292 getgroups32 = 205,
293 setgroups32 = 206,
294 fchown32 = 207,
295 setresuid32 = 208,
296 getresuid32 = 209,
297 setresgid32 = 210,
298 getresgid32 = 211,
299 chown32 = 212,
300 setuid32 = 213,
301 setgid32 = 214,
302 setfsuid32 = 215,
303 setfsgid32 = 216,
304 getdents64 = 217,
305 pivot_root = 218,
306 mincore = 219,
307 madvise = 220,
308 fcntl64 = 221,
309 gettid = 224,
310 readahead = 225,
311 setxattr = 226,
312 lsetxattr = 227,
313 fsetxattr = 228,
314 getxattr = 229,
315 lgetxattr = 230,
316 fgetxattr = 231,
317 listxattr = 232,
318 llistxattr = 233,
319 flistxattr = 234,
320 removexattr = 235,
321 lremovexattr = 236,
322 fremovexattr = 237,
323 tkill = 238,
324 sendfile64 = 239,
325 futex = 240,
326 sched_setaffinity = 241,
327 sched_getaffinity = 242,
328 io_setup = 243,
329 io_destroy = 244,
330 io_getevents = 245,
331 io_submit = 246,
332 io_cancel = 247,
333 exit_group = 248,
334 lookup_dcookie = 249,
335 epoll_create = 250,
336 epoll_ctl = 251,
337 epoll_wait = 252,
338 remap_file_pages = 253,
339 set_tid_address = 256,
340 timer_create = 257,
341 timer_settime = 258,
342 timer_gettime = 259,
343 timer_getoverrun = 260,
344 timer_delete = 261,
345 clock_settime = 262,
346 clock_gettime = 263,
347 clock_getres = 264,
348 clock_nanosleep = 265,
349 statfs64 = 266,
350 fstatfs64 = 267,
351 tgkill = 268,
352 utimes = 269,
353 fadvise64_64 = 270,
354 pciconfig_iobase = 271,
355 pciconfig_read = 272,
356 pciconfig_write = 273,
357 mq_open = 274,
358 mq_unlink = 275,
359 mq_timedsend = 276,
360 mq_timedreceive = 277,
361 mq_notify = 278,
362 mq_getsetattr = 279,
363 waitid = 280,
364 socket = 281,
365 bind = 282,
366 connect = 283,
367 listen = 284,
368 accept = 285,
369 getsockname = 286,
370 getpeername = 287,
371 socketpair = 288,
372 send = 289,
373 sendto = 290,
374 recv = 291,
375 recvfrom = 292,
376 shutdown = 293,
377 setsockopt = 294,
378 getsockopt = 295,
379 sendmsg = 296,
380 recvmsg = 297,
381 semop = 298,
382 semget = 299,
383 semctl = 300,
384 msgsnd = 301,
385 msgrcv = 302,
386 msgget = 303,
387 msgctl = 304,
388 shmat = 305,
389 shmdt = 306,
390 shmget = 307,
391 shmctl = 308,
392 add_key = 309,
393 request_key = 310,
394 keyctl = 311,
395 semtimedop = 312,
396 vserver = 313,
397 ioprio_set = 314,
398 ioprio_get = 315,
399 inotify_init = 316,
400 inotify_add_watch = 317,
401 inotify_rm_watch = 318,
402 mbind = 319,
403 get_mempolicy = 320,
404 set_mempolicy = 321,
405 openat = 322,
406 mkdirat = 323,
407 mknodat = 324,
408 fchownat = 325,
409 futimesat = 326,
410 fstatat64 = 327,
411 unlinkat = 328,
412 renameat = 329,
413 linkat = 330,
414 symlinkat = 331,
415 readlinkat = 332,
416 fchmodat = 333,
417 faccessat = 334,
418 pselect6 = 335,
419 ppoll = 336,
420 unshare = 337,
421 set_robust_list = 338,
422 get_robust_list = 339,
423 splice = 340,
424 sync_file_range = 341,
425 tee = 342,
426 vmsplice = 343,
427 move_pages = 344,
428 getcpu = 345,
429 epoll_pwait = 346,
430 kexec_load = 347,
431 utimensat = 348,
432 signalfd = 349,
433 timerfd_create = 350,
434 eventfd = 351,
435 fallocate = 352,
436 timerfd_settime = 353,
437 timerfd_gettime = 354,
438 signalfd4 = 355,
439 eventfd2 = 356,
440 epoll_create1 = 357,
441 dup3 = 358,
442 pipe2 = 359,
443 inotify_init1 = 360,
444 preadv = 361,
445 pwritev = 362,
446 rt_tgsigqueueinfo = 363,
447 perf_event_open = 364,
448 recvmmsg = 365,
449 accept4 = 366,
450 fanotify_init = 367,
451 fanotify_mark = 368,
452 prlimit64 = 369,
453 name_to_handle_at = 370,
454 open_by_handle_at = 371,
455 clock_adjtime = 372,
456 syncfs = 373,
457 sendmmsg = 374,
458 setns = 375,
459 process_vm_readv = 376,
460 process_vm_writev = 377,
461 kcmp = 378,
462 finit_module = 379,
463 sched_setattr = 380,
464 sched_getattr = 381,
465 renameat2 = 382,
466 seccomp = 383,
467 getrandom = 384,
468 memfd_create = 385,
469 bpf = 386,
470 execveat = 387,
471 userfaultfd = 388,
472 membarrier = 389,
473 mlock2 = 390,
474 copy_file_range = 391,
475 preadv2 = 392,
476 pwritev2 = 393,
477 pkey_mprotect = 394,
478 pkey_alloc = 395,
479 pkey_free = 396,
480 statx = 397,
481 rseq = 398,
482 io_pgetevents = 399,
483 migrate_pages = 400,
484 kexec_file_load = 401,
485 clock_gettime64 = 403,
486 clock_settime64 = 404,
487 clock_adjtime64 = 405,
488 clock_getres_time64 = 406,
489 clock_nanosleep_time64 = 407,
490 timer_gettime64 = 408,
491 timer_settime64 = 409,
492 timerfd_gettime64 = 410,
493 timerfd_settime64 = 411,
494 utimensat_time64 = 412,
495 pselect6_time64 = 413,
496 ppoll_time64 = 414,
497 io_pgetevents_time64 = 416,
498 recvmmsg_time64 = 417,
499 mq_timedsend_time64 = 418,
500 mq_timedreceive_time64 = 419,
501 semtimedop_time64 = 420,
502 rt_sigtimedwait_time64 = 421,
503 futex_time64 = 422,
504 sched_rr_get_interval_time64 = 423,
505 pidfd_send_signal = 424,
506 io_uring_setup = 425,
507 io_uring_enter = 426,
508 io_uring_register = 427,
509 open_tree = 428,
510 move_mount = 429,
511 fsopen = 430,
512 fsconfig = 431,
513 fsmount = 432,
514 fspick = 433,
515 pidfd_open = 434,
516 clone3 = 435,
517 close_range = 436,
518 openat2 = 437,
519 pidfd_getfd = 438,
520 faccessat2 = 439,
521 process_madvise = 440,
522 epoll_pwait2 = 441,
523
524 breakpoint = 0x0f0001,
525 cacheflush = 0x0f0002,
526 usr26 = 0x0f0003,
527 usr32 = 0x0f0004,
528 set_tls = 0x0f0005,
529 get_tls = 0x0f0006,
530
531 _,
532};
533
534pub const MMAP2_UNIT = 4096;
535
536pub const O = struct {
537 pub const CREAT = 0o100;
538 pub const EXCL = 0o200;
539 pub const NOCTTY = 0o400;
540 pub const TRUNC = 0o1000;
541 pub const APPEND = 0o2000;
542 pub const NONBLOCK = 0o4000;
543 pub const DSYNC = 0o10000;
544 pub const SYNC = 0o4010000;
545 pub const RSYNC = 0o4010000;
546 pub const DIRECTORY = 0o40000;
547 pub const NOFOLLOW = 0o100000;
548 pub const CLOEXEC = 0o2000000;
549
550 pub const ASYNC = 0o20000;
551 pub const DIRECT = 0o200000;
552 pub const LARGEFILE = 0o400000;
553 pub const NOATIME = 0o1000000;
554 pub const PATH = 0o10000000;
555 pub const TMPFILE = 0o20040000;
556 pub const NDELAY = NONBLOCK;
557};
558
559pub const F = struct {
560 pub const DUPFD = 0;
561 pub const GETFD = 1;
562 pub const SETFD = 2;
563 pub const GETFL = 3;
564 pub const SETFL = 4;
565
566 pub const SETOWN = 8;
567 pub const GETOWN = 9;
568 pub const SETSIG = 10;
569 pub const GETSIG = 11;
570
571 pub const GETLK = 12;
572 pub const SETLK = 13;
573 pub const SETLKW = 14;
574
575 pub const RDLCK = 0;
576 pub const WRLCK = 1;
577 pub const UNLCK = 2;
578
579 pub const SETOWN_EX = 15;
580 pub const GETOWN_EX = 16;
581
582 pub const GETOWNER_UIDS = 17;
583};
584
585pub const LOCK = struct {
586 pub const SH = 1;
587 pub const EX = 2;
588 pub const UN = 8;
589 pub const NB = 4;
590};
591
592pub const MAP = struct {
593 /// stack-like segment
594 pub const GROWSDOWN = 0x0100;
595 /// ETXTBSY
596 pub const DENYWRITE = 0x0800;
597 /// mark it as an executable
598 pub const EXECUTABLE = 0x1000;
599 /// pages are locked
600 pub const LOCKED = 0x2000;
601 /// don't check for reservations
602 pub const NORESERVE = 0x4000;
603};
604
605pub const VDSO = struct {
606 pub const CGT_SYM = "__vdso_clock_gettime";
607 pub const CGT_VER = "LINUX_2.6";
608};
609
610pub const HWCAP = struct {
611 pub const SWP = 1 << 0;
612 pub const HALF = 1 << 1;
613 pub const THUMB = 1 << 2;
614 pub const @"26BIT" = 1 << 3;
615 pub const FAST_MULT = 1 << 4;
616 pub const FPA = 1 << 5;
617 pub const VFP = 1 << 6;
618 pub const EDSP = 1 << 7;
619 pub const JAVA = 1 << 8;
620 pub const IWMMXT = 1 << 9;
621 pub const CRUNCH = 1 << 10;
622 pub const THUMBEE = 1 << 11;
623 pub const NEON = 1 << 12;
624 pub const VFPv3 = 1 << 13;
625 pub const VFPv3D16 = 1 << 14;
626 pub const TLS = 1 << 15;
627 pub const VFPv4 = 1 << 16;
628 pub const IDIVA = 1 << 17;
629 pub const IDIVT = 1 << 18;
630 pub const VFPD32 = 1 << 19;
631 pub const IDIV = IDIVA | IDIVT;
632 pub const LPAE = 1 << 20;
633 pub const EVTSTRM = 1 << 21;
634};
635
636pub const Flock = extern struct {
637 l_type: i16,
638 l_whence: i16,
639 __pad0: [4]u8,
640 l_start: off_t,
641 l_len: off_t,
642 l_pid: pid_t,
643 __unused: [4]u8,
644};
645
646pub const msghdr = extern struct {
647 msg_name: ?*sockaddr,
648 msg_namelen: socklen_t,
649 msg_iov: [*]iovec,
650 msg_iovlen: i32,
651 msg_control: ?*c_void,
652 msg_controllen: socklen_t,
653 msg_flags: i32,
654};
655
656pub const msghdr_const = extern struct {
657 msg_name: ?*const sockaddr,
658 msg_namelen: socklen_t,
659 msg_iov: [*]iovec_const,
660 msg_iovlen: i32,
661 msg_control: ?*c_void,
662 msg_controllen: socklen_t,
663 msg_flags: i32,
664};
665
666pub const blksize_t = i32;
667pub const nlink_t = u32;
668pub const time_t = isize;
669pub const mode_t = u32;
670pub const off_t = i64;
671pub const ino_t = u64;
672pub const dev_t = u64;
673pub const blkcnt_t = i64;
674
675// The `stat` definition used by the Linux kernel.
676pub const Stat = extern struct {
677 dev: dev_t,
678 __dev_padding: u32,
679 __ino_truncated: u32,
680 mode: mode_t,
681 nlink: nlink_t,
682 uid: uid_t,
683 gid: gid_t,
684 rdev: dev_t,
685 __rdev_padding: u32,
686 size: off_t,
687 blksize: blksize_t,
688 blocks: blkcnt_t,
689 atim: timespec,
690 mtim: timespec,
691 ctim: timespec,
692 ino: ino_t,
693
694 pub fn atime(self: @This()) timespec {
695 return self.atim;
696 }
697
698 pub fn mtime(self: @This()) timespec {
699 return self.mtim;
700 }
701
702 pub fn ctime(self: @This()) timespec {
703 return self.ctim;
704 }
705};
706
707pub const timeval = extern struct {
708 tv_sec: i32,
709 tv_usec: i32,
710};
711
712pub const timezone = extern struct {
713 tz_minuteswest: i32,
714 tz_dsttime: i32,
715};
716
717pub const mcontext_t = extern struct {
718 trap_no: usize,
719 error_code: usize,
720 oldmask: usize,
721 arm_r0: usize,
722 arm_r1: usize,
723 arm_r2: usize,
724 arm_r3: usize,
725 arm_r4: usize,
726 arm_r5: usize,
727 arm_r6: usize,
728 arm_r7: usize,
729 arm_r8: usize,
730 arm_r9: usize,
731 arm_r10: usize,
732 arm_fp: usize,
733 arm_ip: usize,
734 arm_sp: usize,
735 arm_lr: usize,
736 arm_pc: usize,
737 arm_cpsr: usize,
738 fault_address: usize,
739};
740
741pub const ucontext_t = extern struct {
742 flags: usize,
743 link: *ucontext_t,
744 stack: stack_t,
745 mcontext: mcontext_t,
746 sigmask: sigset_t,
747 regspace: [64]u64,
748};
749
750pub const Elf_Symndx = u32;
lib/std/os/linux/arm64.zig+493-1
...@@ -1,4 +1,16 @@...@@ -1,4 +1,16 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const socklen_t = linux.socklen_t;
5const sockaddr = linux.sockaddr;
6const iovec = linux.iovec;
7const iovec_const = linux.iovec_const;
8const uid_t = linux.uid_t;
9const gid_t = linux.gid_t;
10const pid_t = linux.pid_t;
11const stack_t = linux.stack_t;
12const sigset_t = linux.sigset_t;
13const timespec = std.os.linux.timespec;
214
3pub fn syscall0(number: SYS) usize {15pub fn syscall0(number: SYS) usize {
4 return asm volatile ("svc #0"16 return asm volatile ("svc #0"
...@@ -97,3 +109,483 @@ pub fn restore_rt() callconv(.Naked) void {...@@ -97,3 +109,483 @@ pub fn restore_rt() callconv(.Naked) void {
97 : "memory", "cc"109 : "memory", "cc"
98 );110 );
99}111}
112
113pub const SYS = enum(usize) {
114 io_setup = 0,
115 io_destroy = 1,
116 io_submit = 2,
117 io_cancel = 3,
118 io_getevents = 4,
119 setxattr = 5,
120 lsetxattr = 6,
121 fsetxattr = 7,
122 getxattr = 8,
123 lgetxattr = 9,
124 fgetxattr = 10,
125 listxattr = 11,
126 llistxattr = 12,
127 flistxattr = 13,
128 removexattr = 14,
129 lremovexattr = 15,
130 fremovexattr = 16,
131 getcwd = 17,
132 lookup_dcookie = 18,
133 eventfd2 = 19,
134 epoll_create1 = 20,
135 epoll_ctl = 21,
136 epoll_pwait = 22,
137 dup = 23,
138 dup3 = 24,
139 fcntl = 25,
140 inotify_init1 = 26,
141 inotify_add_watch = 27,
142 inotify_rm_watch = 28,
143 ioctl = 29,
144 ioprio_set = 30,
145 ioprio_get = 31,
146 flock = 32,
147 mknodat = 33,
148 mkdirat = 34,
149 unlinkat = 35,
150 symlinkat = 36,
151 linkat = 37,
152 renameat = 38,
153 umount2 = 39,
154 mount = 40,
155 pivot_root = 41,
156 nfsservctl = 42,
157 statfs = 43,
158 fstatfs = 44,
159 truncate = 45,
160 ftruncate = 46,
161 fallocate = 47,
162 faccessat = 48,
163 chdir = 49,
164 fchdir = 50,
165 chroot = 51,
166 fchmod = 52,
167 fchmodat = 53,
168 fchownat = 54,
169 fchown = 55,
170 openat = 56,
171 close = 57,
172 vhangup = 58,
173 pipe2 = 59,
174 quotactl = 60,
175 getdents64 = 61,
176 lseek = 62,
177 read = 63,
178 write = 64,
179 readv = 65,
180 writev = 66,
181 pread64 = 67,
182 pwrite64 = 68,
183 preadv = 69,
184 pwritev = 70,
185 sendfile = 71,
186 pselect6 = 72,
187 ppoll = 73,
188 signalfd4 = 74,
189 vmsplice = 75,
190 splice = 76,
191 tee = 77,
192 readlinkat = 78,
193 fstatat = 79,
194 fstat = 80,
195 sync = 81,
196 fsync = 82,
197 fdatasync = 83,
198 sync_file_range = 84,
199 timerfd_create = 85,
200 timerfd_settime = 86,
201 timerfd_gettime = 87,
202 utimensat = 88,
203 acct = 89,
204 capget = 90,
205 capset = 91,
206 personality = 92,
207 exit = 93,
208 exit_group = 94,
209 waitid = 95,
210 set_tid_address = 96,
211 unshare = 97,
212 futex = 98,
213 set_robust_list = 99,
214 get_robust_list = 100,
215 nanosleep = 101,
216 getitimer = 102,
217 setitimer = 103,
218 kexec_load = 104,
219 init_module = 105,
220 delete_module = 106,
221 timer_create = 107,
222 timer_gettime = 108,
223 timer_getoverrun = 109,
224 timer_settime = 110,
225 timer_delete = 111,
226 clock_settime = 112,
227 clock_gettime = 113,
228 clock_getres = 114,
229 clock_nanosleep = 115,
230 syslog = 116,
231 ptrace = 117,
232 sched_setparam = 118,
233 sched_setscheduler = 119,
234 sched_getscheduler = 120,
235 sched_getparam = 121,
236 sched_setaffinity = 122,
237 sched_getaffinity = 123,
238 sched_yield = 124,
239 sched_get_priority_max = 125,
240 sched_get_priority_min = 126,
241 sched_rr_get_interval = 127,
242 restart_syscall = 128,
243 kill = 129,
244 tkill = 130,
245 tgkill = 131,
246 sigaltstack = 132,
247 rt_sigsuspend = 133,
248 rt_sigaction = 134,
249 rt_sigprocmask = 135,
250 rt_sigpending = 136,
251 rt_sigtimedwait = 137,
252 rt_sigqueueinfo = 138,
253 rt_sigreturn = 139,
254 setpriority = 140,
255 getpriority = 141,
256 reboot = 142,
257 setregid = 143,
258 setgid = 144,
259 setreuid = 145,
260 setuid = 146,
261 setresuid = 147,
262 getresuid = 148,
263 setresgid = 149,
264 getresgid = 150,
265 setfsuid = 151,
266 setfsgid = 152,
267 times = 153,
268 setpgid = 154,
269 getpgid = 155,
270 getsid = 156,
271 setsid = 157,
272 getgroups = 158,
273 setgroups = 159,
274 uname = 160,
275 sethostname = 161,
276 setdomainname = 162,
277 getrlimit = 163,
278 setrlimit = 164,
279 getrusage = 165,
280 umask = 166,
281 prctl = 167,
282 getcpu = 168,
283 gettimeofday = 169,
284 settimeofday = 170,
285 adjtimex = 171,
286 getpid = 172,
287 getppid = 173,
288 getuid = 174,
289 geteuid = 175,
290 getgid = 176,
291 getegid = 177,
292 gettid = 178,
293 sysinfo = 179,
294 mq_open = 180,
295 mq_unlink = 181,
296 mq_timedsend = 182,
297 mq_timedreceive = 183,
298 mq_notify = 184,
299 mq_getsetattr = 185,
300 msgget = 186,
301 msgctl = 187,
302 msgrcv = 188,
303 msgsnd = 189,
304 semget = 190,
305 semctl = 191,
306 semtimedop = 192,
307 semop = 193,
308 shmget = 194,
309 shmctl = 195,
310 shmat = 196,
311 shmdt = 197,
312 socket = 198,
313 socketpair = 199,
314 bind = 200,
315 listen = 201,
316 accept = 202,
317 connect = 203,
318 getsockname = 204,
319 getpeername = 205,
320 sendto = 206,
321 recvfrom = 207,
322 setsockopt = 208,
323 getsockopt = 209,
324 shutdown = 210,
325 sendmsg = 211,
326 recvmsg = 212,
327 readahead = 213,
328 brk = 214,
329 munmap = 215,
330 mremap = 216,
331 add_key = 217,
332 request_key = 218,
333 keyctl = 219,
334 clone = 220,
335 execve = 221,
336 mmap = 222,
337 fadvise64 = 223,
338 swapon = 224,
339 swapoff = 225,
340 mprotect = 226,
341 msync = 227,
342 mlock = 228,
343 munlock = 229,
344 mlockall = 230,
345 munlockall = 231,
346 mincore = 232,
347 madvise = 233,
348 remap_file_pages = 234,
349 mbind = 235,
350 get_mempolicy = 236,
351 set_mempolicy = 237,
352 migrate_pages = 238,
353 move_pages = 239,
354 rt_tgsigqueueinfo = 240,
355 perf_event_open = 241,
356 accept4 = 242,
357 recvmmsg = 243,
358 arch_specific_syscall = 244,
359 wait4 = 260,
360 prlimit64 = 261,
361 fanotify_init = 262,
362 fanotify_mark = 263,
363 clock_adjtime = 266,
364 syncfs = 267,
365 setns = 268,
366 sendmmsg = 269,
367 process_vm_readv = 270,
368 process_vm_writev = 271,
369 kcmp = 272,
370 finit_module = 273,
371 sched_setattr = 274,
372 sched_getattr = 275,
373 renameat2 = 276,
374 seccomp = 277,
375 getrandom = 278,
376 memfd_create = 279,
377 bpf = 280,
378 execveat = 281,
379 userfaultfd = 282,
380 membarrier = 283,
381 mlock2 = 284,
382 copy_file_range = 285,
383 preadv2 = 286,
384 pwritev2 = 287,
385 pkey_mprotect = 288,
386 pkey_alloc = 289,
387 pkey_free = 290,
388 statx = 291,
389 io_pgetevents = 292,
390 rseq = 293,
391 kexec_file_load = 294,
392 pidfd_send_signal = 424,
393 io_uring_setup = 425,
394 io_uring_enter = 426,
395 io_uring_register = 427,
396 open_tree = 428,
397 move_mount = 429,
398 fsopen = 430,
399 fsconfig = 431,
400 fsmount = 432,
401 fspick = 433,
402 pidfd_open = 434,
403 clone3 = 435,
404 close_range = 436,
405 openat2 = 437,
406 pidfd_getfd = 438,
407 faccessat2 = 439,
408 process_madvise = 440,
409 epoll_pwait2 = 441,
410
411 _,
412};
413
414pub const O = struct {
415 pub const CREAT = 0o100;
416 pub const EXCL = 0o200;
417 pub const NOCTTY = 0o400;
418 pub const TRUNC = 0o1000;
419 pub const APPEND = 0o2000;
420 pub const NONBLOCK = 0o4000;
421 pub const DSYNC = 0o10000;
422 pub const SYNC = 0o4010000;
423 pub const RSYNC = 0o4010000;
424 pub const DIRECTORY = 0o40000;
425 pub const NOFOLLOW = 0o100000;
426 pub const CLOEXEC = 0o2000000;
427
428 pub const ASYNC = 0o20000;
429 pub const DIRECT = 0o200000;
430 pub const LARGEFILE = 0o400000;
431 pub const NOATIME = 0o1000000;
432 pub const PATH = 0o10000000;
433 pub const TMPFILE = 0o20040000;
434 pub const NDELAY = NONBLOCK;
435};
436
437pub const F = struct {
438 pub const DUPFD = 0;
439 pub const GETFD = 1;
440 pub const SETFD = 2;
441 pub const GETFL = 3;
442 pub const SETFL = 4;
443
444 pub const SETOWN = 8;
445 pub const GETOWN = 9;
446 pub const SETSIG = 10;
447 pub const GETSIG = 11;
448
449 pub const GETLK = 5;
450 pub const SETLK = 6;
451 pub const SETLKW = 7;
452
453 pub const RDLCK = 0;
454 pub const WRLCK = 1;
455 pub const UNLCK = 2;
456
457 pub const SETOWN_EX = 15;
458 pub const GETOWN_EX = 16;
459
460 pub const GETOWNER_UIDS = 17;
461};
462
463pub const LOCK = struct {
464 pub const SH = 1;
465 pub const EX = 2;
466 pub const UN = 8;
467 pub const NB = 4;
468};
469
470pub const MAP = struct {
471 /// stack-like segment
472 pub const GROWSDOWN = 0x0100;
473 /// ETXTBSY
474 pub const DENYWRITE = 0x0800;
475 /// mark it as an executable
476 pub const EXECUTABLE = 0x1000;
477 /// pages are locked
478 pub const LOCKED = 0x2000;
479 /// don't check for reservations
480 pub const NORESERVE = 0x4000;
481};
482
483pub const VDSO = struct {
484 pub const CGT_SYM = "__kernel_clock_gettime";
485 pub const CGT_VER = "LINUX_2.6.39";
486};
487
488pub const Flock = extern struct {
489 l_type: i16,
490 l_whence: i16,
491 l_start: off_t,
492 l_len: off_t,
493 l_pid: pid_t,
494 __unused: [4]u8,
495};
496
497pub const msghdr = extern struct {
498 msg_name: ?*sockaddr,
499 msg_namelen: socklen_t,
500 msg_iov: [*]iovec,
501 msg_iovlen: i32,
502 __pad1: i32 = 0,
503 msg_control: ?*c_void,
504 msg_controllen: socklen_t,
505 __pad2: socklen_t = 0,
506 msg_flags: i32,
507};
508
509pub const msghdr_const = extern struct {
510 msg_name: ?*const sockaddr,
511 msg_namelen: socklen_t,
512 msg_iov: [*]iovec_const,
513 msg_iovlen: i32,
514 __pad1: i32 = 0,
515 msg_control: ?*c_void,
516 msg_controllen: socklen_t,
517 __pad2: socklen_t = 0,
518 msg_flags: i32,
519};
520
521pub const blksize_t = i32;
522pub const nlink_t = u32;
523pub const time_t = isize;
524pub const mode_t = u32;
525pub const off_t = isize;
526pub const ino_t = usize;
527pub const dev_t = usize;
528pub const blkcnt_t = isize;
529
530// The `stat` definition used by the Linux kernel.
531pub const Stat = extern struct {
532 dev: dev_t,
533 ino: ino_t,
534 mode: mode_t,
535 nlink: nlink_t,
536 uid: uid_t,
537 gid: gid_t,
538 rdev: dev_t,
539 __pad: usize,
540 size: off_t,
541 blksize: blksize_t,
542 __pad2: i32,
543 blocks: blkcnt_t,
544 atim: timespec,
545 mtim: timespec,
546 ctim: timespec,
547 __unused: [2]u32,
548
549 pub fn atime(self: @This()) timespec {
550 return self.atim;
551 }
552
553 pub fn mtime(self: @This()) timespec {
554 return self.mtim;
555 }
556
557 pub fn ctime(self: @This()) timespec {
558 return self.ctim;
559 }
560};
561
562pub const timeval = extern struct {
563 tv_sec: isize,
564 tv_usec: isize,
565};
566
567pub const timezone = extern struct {
568 tz_minuteswest: i32,
569 tz_dsttime: i32,
570};
571
572pub const mcontext_t = extern struct {
573 fault_address: usize,
574 regs: [31]usize,
575 sp: usize,
576 pc: usize,
577 pstate: usize,
578 // Make sure the field is correctly aligned since this area
579 // holds various FP/vector registers
580 reserved1: [256 * 16]u8 align(16),
581};
582
583pub const ucontext_t = extern struct {
584 flags: usize,
585 link: *ucontext_t,
586 stack: stack_t,
587 sigmask: sigset_t,
588 mcontext: mcontext_t,
589};
590
591pub const Elf_Symndx = u32;
lib/std/os/linux/bpf.zig+10-6
...@@ -1,4 +1,3 @@...@@ -1,4 +1,3 @@
1usingnamespace std.os.linux;
2const std = @import("../../std.zig");1const std = @import("../../std.zig");
3const errno = getErrno;2const errno = getErrno;
4const unexpectedErrno = std.os.unexpectedErrno;3const unexpectedErrno = std.os.unexpectedErrno;
...@@ -6,6 +5,11 @@ const expectEqual = std.testing.expectEqual;...@@ -6,6 +5,11 @@ const expectEqual = std.testing.expectEqual;
6const expectError = std.testing.expectError;5const expectError = std.testing.expectError;
7const expect = std.testing.expect;6const expect = std.testing.expect;
87
8const linux = std.os.linux;
9const fd_t = linux.fd_t;
10const pid_t = linux.pid_t;
11const getErrno = linux.getErrno;
12
9pub const btf = @import("bpf/btf.zig");13pub const btf = @import("bpf/btf.zig");
10pub const kern = @import("bpf/kern.zig");14pub const kern = @import("bpf/kern.zig");
1115
...@@ -1502,7 +1506,7 @@ pub fn map_create(map_type: MapType, key_size: u32, value_size: u32, max_entries...@@ -1502,7 +1506,7 @@ pub fn map_create(map_type: MapType, key_size: u32, value_size: u32, max_entries
1502 attr.map_create.value_size = value_size;1506 attr.map_create.value_size = value_size;
1503 attr.map_create.max_entries = max_entries;1507 attr.map_create.max_entries = max_entries;
15041508
1505 const rc = bpf(.map_create, &attr, @sizeOf(MapCreateAttr));1509 const rc = linux.bpf(.map_create, &attr, @sizeOf(MapCreateAttr));
1506 switch (errno(rc)) {1510 switch (errno(rc)) {
1507 .SUCCESS => return @intCast(fd_t, rc),1511 .SUCCESS => return @intCast(fd_t, rc),
1508 .INVAL => return error.MapTypeOrAttrInvalid,1512 .INVAL => return error.MapTypeOrAttrInvalid,
...@@ -1526,7 +1530,7 @@ pub fn map_lookup_elem(fd: fd_t, key: []const u8, value: []u8) !void {...@@ -1526,7 +1530,7 @@ pub fn map_lookup_elem(fd: fd_t, key: []const u8, value: []u8) !void {
1526 attr.map_elem.key = @ptrToInt(key.ptr);1530 attr.map_elem.key = @ptrToInt(key.ptr);
1527 attr.map_elem.result.value = @ptrToInt(value.ptr);1531 attr.map_elem.result.value = @ptrToInt(value.ptr);
15281532
1529 const rc = bpf(.map_lookup_elem, &attr, @sizeOf(MapElemAttr));1533 const rc = linux.bpf(.map_lookup_elem, &attr, @sizeOf(MapElemAttr));
1530 switch (errno(rc)) {1534 switch (errno(rc)) {
1531 .SUCCESS => return,1535 .SUCCESS => return,
1532 .BADF => return error.BadFd,1536 .BADF => return error.BadFd,
...@@ -1548,7 +1552,7 @@ pub fn map_update_elem(fd: fd_t, key: []const u8, value: []const u8, flags: u64)...@@ -1548,7 +1552,7 @@ pub fn map_update_elem(fd: fd_t, key: []const u8, value: []const u8, flags: u64)
1548 attr.map_elem.result = .{ .value = @ptrToInt(value.ptr) };1552 attr.map_elem.result = .{ .value = @ptrToInt(value.ptr) };
1549 attr.map_elem.flags = flags;1553 attr.map_elem.flags = flags;
15501554
1551 const rc = bpf(.map_update_elem, &attr, @sizeOf(MapElemAttr));1555 const rc = linux.bpf(.map_update_elem, &attr, @sizeOf(MapElemAttr));
1552 switch (errno(rc)) {1556 switch (errno(rc)) {
1553 .SUCCESS => return,1557 .SUCCESS => return,
1554 .@"2BIG" => return error.ReachedMaxEntries,1558 .@"2BIG" => return error.ReachedMaxEntries,
...@@ -1569,7 +1573,7 @@ pub fn map_delete_elem(fd: fd_t, key: []const u8) !void {...@@ -1569,7 +1573,7 @@ pub fn map_delete_elem(fd: fd_t, key: []const u8) !void {
1569 attr.map_elem.map_fd = fd;1573 attr.map_elem.map_fd = fd;
1570 attr.map_elem.key = @ptrToInt(key.ptr);1574 attr.map_elem.key = @ptrToInt(key.ptr);
15711575
1572 const rc = bpf(.map_delete_elem, &attr, @sizeOf(MapElemAttr));1576 const rc = linux.bpf(.map_delete_elem, &attr, @sizeOf(MapElemAttr));
1573 switch (errno(rc)) {1577 switch (errno(rc)) {
1574 .SUCCESS => return,1578 .SUCCESS => return,
1575 .BADF => return error.BadFd,1579 .BADF => return error.BadFd,
...@@ -1632,7 +1636,7 @@ pub fn prog_load(...@@ -1632,7 +1636,7 @@ pub fn prog_load(
1632 attr.prog_load.log_level = l.level;1636 attr.prog_load.log_level = l.level;
1633 }1637 }
16341638
1635 const rc = bpf(.prog_load, &attr, @sizeOf(ProgLoadAttr));1639 const rc = linux.bpf(.prog_load, &attr, @sizeOf(ProgLoadAttr));
1636 return switch (errno(rc)) {1640 return switch (errno(rc)) {
1637 .SUCCESS => @intCast(fd_t, rc),1641 .SUCCESS => @intCast(fd_t, rc),
1638 .ACCES => error.UnsafeProgram,1642 .ACCES => error.UnsafeProgram,
lib/std/os/linux/bpf/btf.zig+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1const std = @import("../../../std.zig");
2
1const magic = 0xeb9f;3const magic = 0xeb9f;
2const version = 1;4const version = 1;
35
lib/std/os/linux/bpf/helpers.zig+5
...@@ -1,5 +1,10 @@...@@ -1,5 +1,10 @@
1const std = @import("../../../std.zig");
1const kern = @import("kern.zig");2const kern = @import("kern.zig");
23
4const PtRegs = @compileError("TODO missing os bits: PtRegs");
5const TcpHdr = @compileError("TODO missing os bits: TcpHdr");
6const SkFullSock = @compileError("TODO missing os bits: SkFullSock");
7
3// in BPF, all the helper calls8// in BPF, all the helper calls
4// TODO: when https://github.com/ziglang/zig/issues/1717 is here, make a nice9// TODO: when https://github.com/ziglang/zig/issues/1717 is here, make a nice
5// function that uses the Helper enum10// function that uses the Helper enum
lib/std/os/linux/errno/generic.zig created+460
...@@ -0,0 +1,460 @@
1pub const E = enum(u16) {
2 /// No error occurred.
3 /// Same code used for `NSROK`.
4 SUCCESS = 0,
5
6 /// Operation not permitted
7 PERM = 1,
8
9 /// No such file or directory
10 NOENT = 2,
11
12 /// No such process
13 SRCH = 3,
14
15 /// Interrupted system call
16 INTR = 4,
17
18 /// I/O error
19 IO = 5,
20
21 /// No such device or address
22 NXIO = 6,
23
24 /// Arg list too long
25 @"2BIG" = 7,
26
27 /// Exec format error
28 NOEXEC = 8,
29
30 /// Bad file number
31 BADF = 9,
32
33 /// No child processes
34 CHILD = 10,
35
36 /// Try again
37 /// Also means: WOULDBLOCK: operation would block
38 AGAIN = 11,
39
40 /// Out of memory
41 NOMEM = 12,
42
43 /// Permission denied
44 ACCES = 13,
45
46 /// Bad address
47 FAULT = 14,
48
49 /// Block device required
50 NOTBLK = 15,
51
52 /// Device or resource busy
53 BUSY = 16,
54
55 /// File exists
56 EXIST = 17,
57
58 /// Cross-device link
59 XDEV = 18,
60
61 /// No such device
62 NODEV = 19,
63
64 /// Not a directory
65 NOTDIR = 20,
66
67 /// Is a directory
68 ISDIR = 21,
69
70 /// Invalid argument
71 INVAL = 22,
72
73 /// File table overflow
74 NFILE = 23,
75
76 /// Too many open files
77 MFILE = 24,
78
79 /// Not a typewriter
80 NOTTY = 25,
81
82 /// Text file busy
83 TXTBSY = 26,
84
85 /// File too large
86 FBIG = 27,
87
88 /// No space left on device
89 NOSPC = 28,
90
91 /// Illegal seek
92 SPIPE = 29,
93
94 /// Read-only file system
95 ROFS = 30,
96
97 /// Too many links
98 MLINK = 31,
99
100 /// Broken pipe
101 PIPE = 32,
102
103 /// Math argument out of domain of func
104 DOM = 33,
105
106 /// Math result not representable
107 RANGE = 34,
108
109 /// Resource deadlock would occur
110 DEADLK = 35,
111
112 /// File name too long
113 NAMETOOLONG = 36,
114
115 /// No record locks available
116 NOLCK = 37,
117
118 /// Function not implemented
119 NOSYS = 38,
120
121 /// Directory not empty
122 NOTEMPTY = 39,
123
124 /// Too many symbolic links encountered
125 LOOP = 40,
126
127 /// No message of desired type
128 NOMSG = 42,
129
130 /// Identifier removed
131 IDRM = 43,
132
133 /// Channel number out of range
134 CHRNG = 44,
135
136 /// Level 2 not synchronized
137 L2NSYNC = 45,
138
139 /// Level 3 halted
140 L3HLT = 46,
141
142 /// Level 3 reset
143 L3RST = 47,
144
145 /// Link number out of range
146 LNRNG = 48,
147
148 /// Protocol driver not attached
149 UNATCH = 49,
150
151 /// No CSI structure available
152 NOCSI = 50,
153
154 /// Level 2 halted
155 L2HLT = 51,
156
157 /// Invalid exchange
158 BADE = 52,
159
160 /// Invalid request descriptor
161 BADR = 53,
162
163 /// Exchange full
164 XFULL = 54,
165
166 /// No anode
167 NOANO = 55,
168
169 /// Invalid request code
170 BADRQC = 56,
171
172 /// Invalid slot
173 BADSLT = 57,
174
175 /// Bad font file format
176 BFONT = 59,
177
178 /// Device not a stream
179 NOSTR = 60,
180
181 /// No data available
182 NODATA = 61,
183
184 /// Timer expired
185 TIME = 62,
186
187 /// Out of streams resources
188 NOSR = 63,
189
190 /// Machine is not on the network
191 NONET = 64,
192
193 /// Package not installed
194 NOPKG = 65,
195
196 /// Object is remote
197 REMOTE = 66,
198
199 /// Link has been severed
200 NOLINK = 67,
201
202 /// Advertise error
203 ADV = 68,
204
205 /// Srmount error
206 SRMNT = 69,
207
208 /// Communication error on send
209 COMM = 70,
210
211 /// Protocol error
212 PROTO = 71,
213
214 /// Multihop attempted
215 MULTIHOP = 72,
216
217 /// RFS specific error
218 DOTDOT = 73,
219
220 /// Not a data message
221 BADMSG = 74,
222
223 /// Value too large for defined data type
224 OVERFLOW = 75,
225
226 /// Name not unique on network
227 NOTUNIQ = 76,
228
229 /// File descriptor in bad state
230 BADFD = 77,
231
232 /// Remote address changed
233 REMCHG = 78,
234
235 /// Can not access a needed shared library
236 LIBACC = 79,
237
238 /// Accessing a corrupted shared library
239 LIBBAD = 80,
240
241 /// .lib section in a.out corrupted
242 LIBSCN = 81,
243
244 /// Attempting to link in too many shared libraries
245 LIBMAX = 82,
246
247 /// Cannot exec a shared library directly
248 LIBEXEC = 83,
249
250 /// Illegal byte sequence
251 ILSEQ = 84,
252
253 /// Interrupted system call should be restarted
254 RESTART = 85,
255
256 /// Streams pipe error
257 STRPIPE = 86,
258
259 /// Too many users
260 USERS = 87,
261
262 /// Socket operation on non-socket
263 NOTSOCK = 88,
264
265 /// Destination address required
266 DESTADDRREQ = 89,
267
268 /// Message too long
269 MSGSIZE = 90,
270
271 /// Protocol wrong type for socket
272 PROTOTYPE = 91,
273
274 /// Protocol not available
275 NOPROTOOPT = 92,
276
277 /// Protocol not supported
278 PROTONOSUPPORT = 93,
279
280 /// Socket type not supported
281 SOCKTNOSUPPORT = 94,
282
283 /// Operation not supported on transport endpoint
284 /// This code also means `NOTSUP`.
285 OPNOTSUPP = 95,
286
287 /// Protocol family not supported
288 PFNOSUPPORT = 96,
289
290 /// Address family not supported by protocol
291 AFNOSUPPORT = 97,
292
293 /// Address already in use
294 ADDRINUSE = 98,
295
296 /// Cannot assign requested address
297 ADDRNOTAVAIL = 99,
298
299 /// Network is down
300 NETDOWN = 100,
301
302 /// Network is unreachable
303 NETUNREACH = 101,
304
305 /// Network dropped connection because of reset
306 NETRESET = 102,
307
308 /// Software caused connection abort
309 CONNABORTED = 103,
310
311 /// Connection reset by peer
312 CONNRESET = 104,
313
314 /// No buffer space available
315 NOBUFS = 105,
316
317 /// Transport endpoint is already connected
318 ISCONN = 106,
319
320 /// Transport endpoint is not connected
321 NOTCONN = 107,
322
323 /// Cannot send after transport endpoint shutdown
324 SHUTDOWN = 108,
325
326 /// Too many references: cannot splice
327 TOOMANYREFS = 109,
328
329 /// Connection timed out
330 TIMEDOUT = 110,
331
332 /// Connection refused
333 CONNREFUSED = 111,
334
335 /// Host is down
336 HOSTDOWN = 112,
337
338 /// No route to host
339 HOSTUNREACH = 113,
340
341 /// Operation already in progress
342 ALREADY = 114,
343
344 /// Operation now in progress
345 INPROGRESS = 115,
346
347 /// Stale NFS file handle
348 STALE = 116,
349
350 /// Structure needs cleaning
351 UCLEAN = 117,
352
353 /// Not a XENIX named type file
354 NOTNAM = 118,
355
356 /// No XENIX semaphores available
357 NAVAIL = 119,
358
359 /// Is a named type file
360 ISNAM = 120,
361
362 /// Remote I/O error
363 REMOTEIO = 121,
364
365 /// Quota exceeded
366 DQUOT = 122,
367
368 /// No medium found
369 NOMEDIUM = 123,
370
371 /// Wrong medium type
372 MEDIUMTYPE = 124,
373
374 /// Operation canceled
375 CANCELED = 125,
376
377 /// Required key not available
378 NOKEY = 126,
379
380 /// Key has expired
381 KEYEXPIRED = 127,
382
383 /// Key has been revoked
384 KEYREVOKED = 128,
385
386 /// Key was rejected by service
387 KEYREJECTED = 129,
388
389 // for robust mutexes
390
391 /// Owner died
392 OWNERDEAD = 130,
393
394 /// State not recoverable
395 NOTRECOVERABLE = 131,
396
397 /// Operation not possible due to RF-kill
398 RFKILL = 132,
399
400 /// Memory page has hardware error
401 HWPOISON = 133,
402
403 // nameserver query return codes
404
405 /// DNS server returned answer with no data
406 NSRNODATA = 160,
407
408 /// DNS server claims query was misformatted
409 NSRFORMERR = 161,
410
411 /// DNS server returned general failure
412 NSRSERVFAIL = 162,
413
414 /// Domain name not found
415 NSRNOTFOUND = 163,
416
417 /// DNS server does not implement requested operation
418 NSRNOTIMP = 164,
419
420 /// DNS server refused query
421 NSRREFUSED = 165,
422
423 /// Misformatted DNS query
424 NSRBADQUERY = 166,
425
426 /// Misformatted domain name
427 NSRBADNAME = 167,
428
429 /// Unsupported address family
430 NSRBADFAMILY = 168,
431
432 /// Misformatted DNS reply
433 NSRBADRESP = 169,
434
435 /// Could not contact DNS servers
436 NSRCONNREFUSED = 170,
437
438 /// Timeout while contacting DNS servers
439 NSRTIMEOUT = 171,
440
441 /// End of file
442 NSROF = 172,
443
444 /// Error reading file
445 NSRFILE = 173,
446
447 /// Out of memory
448 NSRNOMEM = 174,
449
450 /// Application terminated lookup
451 NSRDESTRUCTION = 175,
452
453 /// Domain name is too long
454 NSRQUERYDOMAINTOOLONG = 176,
455
456 /// Domain name is too long
457 NSRCNAMELOOP = 177,
458
459 _,
460};
lib/std/os/linux/errno/mips.zig created+141
...@@ -0,0 +1,141 @@
1//! These are MIPS ABI compatible.
2pub const E = enum(i32) {
3 /// No error occurred.
4 SUCCESS = 0,
5
6 PERM = 1,
7 NOENT = 2,
8 SRCH = 3,
9 INTR = 4,
10 IO = 5,
11 NXIO = 6,
12 @"2BIG" = 7,
13 NOEXEC = 8,
14 BADF = 9,
15 CHILD = 10,
16 /// Also used for WOULDBLOCK.
17 AGAIN = 11,
18 NOMEM = 12,
19 ACCES = 13,
20 FAULT = 14,
21 NOTBLK = 15,
22 BUSY = 16,
23 EXIST = 17,
24 XDEV = 18,
25 NODEV = 19,
26 NOTDIR = 20,
27 ISDIR = 21,
28 INVAL = 22,
29 NFILE = 23,
30 MFILE = 24,
31 NOTTY = 25,
32 TXTBSY = 26,
33 FBIG = 27,
34 NOSPC = 28,
35 SPIPE = 29,
36 ROFS = 30,
37 MLINK = 31,
38 PIPE = 32,
39 DOM = 33,
40 RANGE = 34,
41
42 NOMSG = 35,
43 IDRM = 36,
44 CHRNG = 37,
45 L2NSYNC = 38,
46 L3HLT = 39,
47 L3RST = 40,
48 LNRNG = 41,
49 UNATCH = 42,
50 NOCSI = 43,
51 L2HLT = 44,
52 DEADLK = 45,
53 NOLCK = 46,
54 BADE = 50,
55 BADR = 51,
56 XFULL = 52,
57 NOANO = 53,
58 BADRQC = 54,
59 BADSLT = 55,
60 DEADLOCK = 56,
61 BFONT = 59,
62 NOSTR = 60,
63 NODATA = 61,
64 TIME = 62,
65 NOSR = 63,
66 NONET = 64,
67 NOPKG = 65,
68 REMOTE = 66,
69 NOLINK = 67,
70 ADV = 68,
71 SRMNT = 69,
72 COMM = 70,
73 PROTO = 71,
74 DOTDOT = 73,
75 MULTIHOP = 74,
76 BADMSG = 77,
77 NAMETOOLONG = 78,
78 OVERFLOW = 79,
79 NOTUNIQ = 80,
80 BADFD = 81,
81 REMCHG = 82,
82 LIBACC = 83,
83 LIBBAD = 84,
84 LIBSCN = 85,
85 LIBMAX = 86,
86 LIBEXEC = 87,
87 ILSEQ = 88,
88 NOSYS = 89,
89 LOOP = 90,
90 RESTART = 91,
91 STRPIPE = 92,
92 NOTEMPTY = 93,
93 USERS = 94,
94 NOTSOCK = 95,
95 DESTADDRREQ = 96,
96 MSGSIZE = 97,
97 PROTOTYPE = 98,
98 NOPROTOOPT = 99,
99 PROTONOSUPPORT = 120,
100 SOCKTNOSUPPORT = 121,
101 OPNOTSUPP = 122,
102 PFNOSUPPORT = 123,
103 AFNOSUPPORT = 124,
104 ADDRINUSE = 125,
105 ADDRNOTAVAIL = 126,
106 NETDOWN = 127,
107 NETUNREACH = 128,
108 NETRESET = 129,
109 CONNABORTED = 130,
110 CONNRESET = 131,
111 NOBUFS = 132,
112 ISCONN = 133,
113 NOTCONN = 134,
114 UCLEAN = 135,
115 NOTNAM = 137,
116 NAVAIL = 138,
117 ISNAM = 139,
118 REMOTEIO = 140,
119 SHUTDOWN = 143,
120 TOOMANYREFS = 144,
121 TIMEDOUT = 145,
122 CONNREFUSED = 146,
123 HOSTDOWN = 147,
124 HOSTUNREACH = 148,
125 ALREADY = 149,
126 INPROGRESS = 150,
127 STALE = 151,
128 CANCELED = 158,
129 NOMEDIUM = 159,
130 MEDIUMTYPE = 160,
131 NOKEY = 161,
132 KEYEXPIRED = 162,
133 KEYREVOKED = 163,
134 KEYREJECTED = 164,
135 OWNERDEAD = 165,
136 NOTRECOVERABLE = 166,
137 RFKILL = 167,
138 HWPOISON = 168,
139 DQUOT = 1133,
140 _,
141};
lib/std/os/linux/errno/sparc.zig created+144
...@@ -0,0 +1,144 @@
1//! These match the SunOS error numbering scheme.
2pub const E = enum(i32) {
3 /// No error occurred.
4 SUCCESS = 0,
5
6 PERM = 1,
7 NOENT = 2,
8 SRCH = 3,
9 INTR = 4,
10 IO = 5,
11 NXIO = 6,
12 @"2BIG" = 7,
13 NOEXEC = 8,
14 BADF = 9,
15 CHILD = 10,
16 /// Also used for WOULDBLOCK
17 AGAIN = 11,
18 NOMEM = 12,
19 ACCES = 13,
20 FAULT = 14,
21 NOTBLK = 15,
22 BUSY = 16,
23 EXIST = 17,
24 XDEV = 18,
25 NODEV = 19,
26 NOTDIR = 20,
27 ISDIR = 21,
28 INVAL = 22,
29 NFILE = 23,
30 MFILE = 24,
31 NOTTY = 25,
32 TXTBSY = 26,
33 FBIG = 27,
34 NOSPC = 28,
35 SPIPE = 29,
36 ROFS = 30,
37 MLINK = 31,
38 PIPE = 32,
39 DOM = 33,
40 RANGE = 34,
41
42 INPROGRESS = 36,
43 ALREADY = 37,
44 NOTSOCK = 38,
45 DESTADDRREQ = 39,
46 MSGSIZE = 40,
47 PROTOTYPE = 41,
48 NOPROTOOPT = 42,
49 PROTONOSUPPORT = 43,
50 SOCKTNOSUPPORT = 44,
51 /// Also used for NOTSUP
52 OPNOTSUPP = 45,
53 PFNOSUPPORT = 46,
54 AFNOSUPPORT = 47,
55 ADDRINUSE = 48,
56 ADDRNOTAVAIL = 49,
57 NETDOWN = 50,
58 NETUNREACH = 51,
59 NETRESET = 52,
60 CONNABORTED = 53,
61 CONNRESET = 54,
62 NOBUFS = 55,
63 ISCONN = 56,
64 NOTCONN = 57,
65 SHUTDOWN = 58,
66 TOOMANYREFS = 59,
67 TIMEDOUT = 60,
68 CONNREFUSED = 61,
69 LOOP = 62,
70 NAMETOOLONG = 63,
71 HOSTDOWN = 64,
72 HOSTUNREACH = 65,
73 NOTEMPTY = 66,
74 PROCLIM = 67,
75 USERS = 68,
76 DQUOT = 69,
77 STALE = 70,
78 REMOTE = 71,
79 NOSTR = 72,
80 TIME = 73,
81 NOSR = 74,
82 NOMSG = 75,
83 BADMSG = 76,
84 IDRM = 77,
85 DEADLK = 78,
86 NOLCK = 79,
87 NONET = 80,
88 RREMOTE = 81,
89 NOLINK = 82,
90 ADV = 83,
91 SRMNT = 84,
92 COMM = 85,
93 PROTO = 86,
94 MULTIHOP = 87,
95 DOTDOT = 88,
96 REMCHG = 89,
97 NOSYS = 90,
98 STRPIPE = 91,
99 OVERFLOW = 92,
100 BADFD = 93,
101 CHRNG = 94,
102 L2NSYNC = 95,
103 L3HLT = 96,
104 L3RST = 97,
105 LNRNG = 98,
106 UNATCH = 99,
107 NOCSI = 100,
108 L2HLT = 101,
109 BADE = 102,
110 BADR = 103,
111 XFULL = 104,
112 NOANO = 105,
113 BADRQC = 106,
114 BADSLT = 107,
115 DEADLOCK = 108,
116 BFONT = 109,
117 LIBEXEC = 110,
118 NODATA = 111,
119 LIBBAD = 112,
120 NOPKG = 113,
121 LIBACC = 114,
122 NOTUNIQ = 115,
123 RESTART = 116,
124 UCLEAN = 117,
125 NOTNAM = 118,
126 NAVAIL = 119,
127 ISNAM = 120,
128 REMOTEIO = 121,
129 ILSEQ = 122,
130 LIBMAX = 123,
131 LIBSCN = 124,
132 NOMEDIUM = 125,
133 MEDIUMTYPE = 126,
134 CANCELED = 127,
135 NOKEY = 128,
136 KEYEXPIRED = 129,
137 KEYREVOKED = 130,
138 KEYREJECTED = 131,
139 OWNERDEAD = 132,
140 NOTRECOVERABLE = 133,
141 RFKILL = 134,
142 HWPOISON = 135,
143 _,
144};
lib/std/os/linux/i386.zig+674-1
...@@ -1,4 +1,16 @@...@@ -1,4 +1,16 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const socklen_t = linux.socklen_t;
5const iovec = linux.iovec;
6const iovec_const = linux.iovec_const;
7const uid_t = linux.uid_t;
8const gid_t = linux.gid_t;
9const pid_t = linux.pid_t;
10const stack_t = linux.stack_t;
11const sigset_t = linux.sigset_t;
12const sockaddr = linux.sockaddr;
13const timespec = linux.timespec;
214
3pub fn syscall0(number: SYS) usize {15pub fn syscall0(number: SYS) usize {
4 return asm volatile ("int $0x80"16 return asm volatile ("int $0x80"
...@@ -123,3 +135,664 @@ pub fn restore_rt() callconv(.Naked) void {...@@ -123,3 +135,664 @@ pub fn restore_rt() callconv(.Naked) void {
123 : "memory"135 : "memory"
124 );136 );
125}137}
138
139pub const SYS = enum(usize) {
140 restart_syscall = 0,
141 exit = 1,
142 fork = 2,
143 read = 3,
144 write = 4,
145 open = 5,
146 close = 6,
147 waitpid = 7,
148 creat = 8,
149 link = 9,
150 unlink = 10,
151 execve = 11,
152 chdir = 12,
153 time = 13,
154 mknod = 14,
155 chmod = 15,
156 lchown = 16,
157 @"break" = 17,
158 oldstat = 18,
159 lseek = 19,
160 getpid = 20,
161 mount = 21,
162 umount = 22,
163 setuid = 23,
164 getuid = 24,
165 stime = 25,
166 ptrace = 26,
167 alarm = 27,
168 oldfstat = 28,
169 pause = 29,
170 utime = 30,
171 stty = 31,
172 gtty = 32,
173 access = 33,
174 nice = 34,
175 ftime = 35,
176 sync = 36,
177 kill = 37,
178 rename = 38,
179 mkdir = 39,
180 rmdir = 40,
181 dup = 41,
182 pipe = 42,
183 times = 43,
184 prof = 44,
185 brk = 45,
186 setgid = 46,
187 getgid = 47,
188 signal = 48,
189 geteuid = 49,
190 getegid = 50,
191 acct = 51,
192 umount2 = 52,
193 lock = 53,
194 ioctl = 54,
195 fcntl = 55,
196 mpx = 56,
197 setpgid = 57,
198 ulimit = 58,
199 oldolduname = 59,
200 umask = 60,
201 chroot = 61,
202 ustat = 62,
203 dup2 = 63,
204 getppid = 64,
205 getpgrp = 65,
206 setsid = 66,
207 sigaction = 67,
208 sgetmask = 68,
209 ssetmask = 69,
210 setreuid = 70,
211 setregid = 71,
212 sigsuspend = 72,
213 sigpending = 73,
214 sethostname = 74,
215 setrlimit = 75,
216 getrlimit = 76,
217 getrusage = 77,
218 gettimeofday = 78,
219 settimeofday = 79,
220 getgroups = 80,
221 setgroups = 81,
222 select = 82,
223 symlink = 83,
224 oldlstat = 84,
225 readlink = 85,
226 uselib = 86,
227 swapon = 87,
228 reboot = 88,
229 readdir = 89,
230 mmap = 90,
231 munmap = 91,
232 truncate = 92,
233 ftruncate = 93,
234 fchmod = 94,
235 fchown = 95,
236 getpriority = 96,
237 setpriority = 97,
238 profil = 98,
239 statfs = 99,
240 fstatfs = 100,
241 ioperm = 101,
242 socketcall = 102,
243 syslog = 103,
244 setitimer = 104,
245 getitimer = 105,
246 stat = 106,
247 lstat = 107,
248 fstat = 108,
249 olduname = 109,
250 iopl = 110,
251 vhangup = 111,
252 idle = 112,
253 vm86old = 113,
254 wait4 = 114,
255 swapoff = 115,
256 sysinfo = 116,
257 ipc = 117,
258 fsync = 118,
259 sigreturn = 119,
260 clone = 120,
261 setdomainname = 121,
262 uname = 122,
263 modify_ldt = 123,
264 adjtimex = 124,
265 mprotect = 125,
266 sigprocmask = 126,
267 create_module = 127,
268 init_module = 128,
269 delete_module = 129,
270 get_kernel_syms = 130,
271 quotactl = 131,
272 getpgid = 132,
273 fchdir = 133,
274 bdflush = 134,
275 sysfs = 135,
276 personality = 136,
277 afs_syscall = 137,
278 setfsuid = 138,
279 setfsgid = 139,
280 _llseek = 140,
281 getdents = 141,
282 _newselect = 142,
283 flock = 143,
284 msync = 144,
285 readv = 145,
286 writev = 146,
287 getsid = 147,
288 fdatasync = 148,
289 _sysctl = 149,
290 mlock = 150,
291 munlock = 151,
292 mlockall = 152,
293 munlockall = 153,
294 sched_setparam = 154,
295 sched_getparam = 155,
296 sched_setscheduler = 156,
297 sched_getscheduler = 157,
298 sched_yield = 158,
299 sched_get_priority_max = 159,
300 sched_get_priority_min = 160,
301 sched_rr_get_interval = 161,
302 nanosleep = 162,
303 mremap = 163,
304 setresuid = 164,
305 getresuid = 165,
306 vm86 = 166,
307 query_module = 167,
308 poll = 168,
309 nfsservctl = 169,
310 setresgid = 170,
311 getresgid = 171,
312 prctl = 172,
313 rt_sigreturn = 173,
314 rt_sigaction = 174,
315 rt_sigprocmask = 175,
316 rt_sigpending = 176,
317 rt_sigtimedwait = 177,
318 rt_sigqueueinfo = 178,
319 rt_sigsuspend = 179,
320 pread64 = 180,
321 pwrite64 = 181,
322 chown = 182,
323 getcwd = 183,
324 capget = 184,
325 capset = 185,
326 sigaltstack = 186,
327 sendfile = 187,
328 getpmsg = 188,
329 putpmsg = 189,
330 vfork = 190,
331 ugetrlimit = 191,
332 mmap2 = 192,
333 truncate64 = 193,
334 ftruncate64 = 194,
335 stat64 = 195,
336 lstat64 = 196,
337 fstat64 = 197,
338 lchown32 = 198,
339 getuid32 = 199,
340 getgid32 = 200,
341 geteuid32 = 201,
342 getegid32 = 202,
343 setreuid32 = 203,
344 setregid32 = 204,
345 getgroups32 = 205,
346 setgroups32 = 206,
347 fchown32 = 207,
348 setresuid32 = 208,
349 getresuid32 = 209,
350 setresgid32 = 210,
351 getresgid32 = 211,
352 chown32 = 212,
353 setuid32 = 213,
354 setgid32 = 214,
355 setfsuid32 = 215,
356 setfsgid32 = 216,
357 pivot_root = 217,
358 mincore = 218,
359 madvise = 219,
360 getdents64 = 220,
361 fcntl64 = 221,
362 gettid = 224,
363 readahead = 225,
364 setxattr = 226,
365 lsetxattr = 227,
366 fsetxattr = 228,
367 getxattr = 229,
368 lgetxattr = 230,
369 fgetxattr = 231,
370 listxattr = 232,
371 llistxattr = 233,
372 flistxattr = 234,
373 removexattr = 235,
374 lremovexattr = 236,
375 fremovexattr = 237,
376 tkill = 238,
377 sendfile64 = 239,
378 futex = 240,
379 sched_setaffinity = 241,
380 sched_getaffinity = 242,
381 set_thread_area = 243,
382 get_thread_area = 244,
383 io_setup = 245,
384 io_destroy = 246,
385 io_getevents = 247,
386 io_submit = 248,
387 io_cancel = 249,
388 fadvise64 = 250,
389 exit_group = 252,
390 lookup_dcookie = 253,
391 epoll_create = 254,
392 epoll_ctl = 255,
393 epoll_wait = 256,
394 remap_file_pages = 257,
395 set_tid_address = 258,
396 timer_create = 259,
397 timer_settime, // SYS_timer_create + 1
398 timer_gettime, // SYS_timer_create + 2
399 timer_getoverrun, // SYS_timer_create + 3
400 timer_delete, // SYS_timer_create + 4
401 clock_settime, // SYS_timer_create + 5
402 clock_gettime, // SYS_timer_create + 6
403 clock_getres, // SYS_timer_create + 7
404 clock_nanosleep, // SYS_timer_create + 8
405 statfs64 = 268,
406 fstatfs64 = 269,
407 tgkill = 270,
408 utimes = 271,
409 fadvise64_64 = 272,
410 vserver = 273,
411 mbind = 274,
412 get_mempolicy = 275,
413 set_mempolicy = 276,
414 mq_open = 277,
415 mq_unlink, // SYS_mq_open + 1
416 mq_timedsend, // SYS_mq_open + 2
417 mq_timedreceive, // SYS_mq_open + 3
418 mq_notify, // SYS_mq_open + 4
419 mq_getsetattr, // SYS_mq_open + 5
420 kexec_load = 283,
421 waitid = 284,
422 add_key = 286,
423 request_key = 287,
424 keyctl = 288,
425 ioprio_set = 289,
426 ioprio_get = 290,
427 inotify_init = 291,
428 inotify_add_watch = 292,
429 inotify_rm_watch = 293,
430 migrate_pages = 294,
431 openat = 295,
432 mkdirat = 296,
433 mknodat = 297,
434 fchownat = 298,
435 futimesat = 299,
436 fstatat64 = 300,
437 unlinkat = 301,
438 renameat = 302,
439 linkat = 303,
440 symlinkat = 304,
441 readlinkat = 305,
442 fchmodat = 306,
443 faccessat = 307,
444 pselect6 = 308,
445 ppoll = 309,
446 unshare = 310,
447 set_robust_list = 311,
448 get_robust_list = 312,
449 splice = 313,
450 sync_file_range = 314,
451 tee = 315,
452 vmsplice = 316,
453 move_pages = 317,
454 getcpu = 318,
455 epoll_pwait = 319,
456 utimensat = 320,
457 signalfd = 321,
458 timerfd_create = 322,
459 eventfd = 323,
460 fallocate = 324,
461 timerfd_settime = 325,
462 timerfd_gettime = 326,
463 signalfd4 = 327,
464 eventfd2 = 328,
465 epoll_create1 = 329,
466 dup3 = 330,
467 pipe2 = 331,
468 inotify_init1 = 332,
469 preadv = 333,
470 pwritev = 334,
471 rt_tgsigqueueinfo = 335,
472 perf_event_open = 336,
473 recvmmsg = 337,
474 fanotify_init = 338,
475 fanotify_mark = 339,
476 prlimit64 = 340,
477 name_to_handle_at = 341,
478 open_by_handle_at = 342,
479 clock_adjtime = 343,
480 syncfs = 344,
481 sendmmsg = 345,
482 setns = 346,
483 process_vm_readv = 347,
484 process_vm_writev = 348,
485 kcmp = 349,
486 finit_module = 350,
487 sched_setattr = 351,
488 sched_getattr = 352,
489 renameat2 = 353,
490 seccomp = 354,
491 getrandom = 355,
492 memfd_create = 356,
493 bpf = 357,
494 execveat = 358,
495 socket = 359,
496 socketpair = 360,
497 bind = 361,
498 connect = 362,
499 listen = 363,
500 accept4 = 364,
501 getsockopt = 365,
502 setsockopt = 366,
503 getsockname = 367,
504 getpeername = 368,
505 sendto = 369,
506 sendmsg = 370,
507 recvfrom = 371,
508 recvmsg = 372,
509 shutdown = 373,
510 userfaultfd = 374,
511 membarrier = 375,
512 mlock2 = 376,
513 copy_file_range = 377,
514 preadv2 = 378,
515 pwritev2 = 379,
516 pkey_mprotect = 380,
517 pkey_alloc = 381,
518 pkey_free = 382,
519 statx = 383,
520 arch_prctl = 384,
521 io_pgetevents = 385,
522 rseq = 386,
523 semget = 393,
524 semctl = 394,
525 shmget = 395,
526 shmctl = 396,
527 shmat = 397,
528 shmdt = 398,
529 msgget = 399,
530 msgsnd = 400,
531 msgrcv = 401,
532 msgctl = 402,
533 clock_gettime64 = 403,
534 clock_settime64 = 404,
535 clock_adjtime64 = 405,
536 clock_getres_time64 = 406,
537 clock_nanosleep_time64 = 407,
538 timer_gettime64 = 408,
539 timer_settime64 = 409,
540 timerfd_gettime64 = 410,
541 timerfd_settime64 = 411,
542 utimensat_time64 = 412,
543 pselect6_time64 = 413,
544 ppoll_time64 = 414,
545 io_pgetevents_time64 = 416,
546 recvmmsg_time64 = 417,
547 mq_timedsend_time64 = 418,
548 mq_timedreceive_time64 = 419,
549 semtimedop_time64 = 420,
550 rt_sigtimedwait_time64 = 421,
551 futex_time64 = 422,
552 sched_rr_get_interval_time64 = 423,
553 pidfd_send_signal = 424,
554 io_uring_setup = 425,
555 io_uring_enter = 426,
556 io_uring_register = 427,
557 open_tree = 428,
558 move_mount = 429,
559 fsopen = 430,
560 fsconfig = 431,
561 fsmount = 432,
562 fspick = 433,
563 pidfd_open = 434,
564 clone3 = 435,
565 close_range = 436,
566 openat2 = 437,
567 pidfd_getfd = 438,
568 faccessat2 = 439,
569 process_madvise = 440,
570 epoll_pwait2 = 441,
571
572 _,
573};
574
575pub const O = struct {
576 pub const CREAT = 0o100;
577 pub const EXCL = 0o200;
578 pub const NOCTTY = 0o400;
579 pub const TRUNC = 0o1000;
580 pub const APPEND = 0o2000;
581 pub const NONBLOCK = 0o4000;
582 pub const DSYNC = 0o10000;
583 pub const SYNC = 0o4010000;
584 pub const RSYNC = 0o4010000;
585 pub const DIRECTORY = 0o200000;
586 pub const NOFOLLOW = 0o400000;
587 pub const CLOEXEC = 0o2000000;
588
589 pub const ASYNC = 0o20000;
590 pub const DIRECT = 0o40000;
591 pub const LARGEFILE = 0o100000;
592 pub const NOATIME = 0o1000000;
593 pub const PATH = 0o10000000;
594 pub const TMPFILE = 0o20200000;
595 pub const NDELAY = NONBLOCK;
596};
597
598pub const F = struct {
599 pub const DUPFD = 0;
600 pub const GETFD = 1;
601 pub const SETFD = 2;
602 pub const GETFL = 3;
603 pub const SETFL = 4;
604 pub const SETOWN = 8;
605 pub const GETOWN = 9;
606 pub const SETSIG = 10;
607 pub const GETSIG = 11;
608 pub const GETLK = 12;
609 pub const SETLK = 13;
610 pub const SETLKW = 14;
611 pub const SETOWN_EX = 15;
612 pub const GETOWN_EX = 16;
613 pub const GETOWNER_UIDS = 17;
614
615 pub const RDLCK = 0;
616 pub const WRLCK = 1;
617 pub const UNLCK = 2;
618};
619
620pub const LOCK = struct {
621 pub const SH = 1;
622 pub const EX = 2;
623 pub const NB = 4;
624 pub const UN = 8;
625};
626
627pub const MAP = struct {
628 pub const NORESERVE = 0x4000;
629 pub const GROWSDOWN = 0x0100;
630 pub const DENYWRITE = 0x0800;
631 pub const EXECUTABLE = 0x1000;
632 pub const LOCKED = 0x2000;
633 pub const @"32BIT" = 0x40;
634};
635
636pub const MMAP2_UNIT = 4096;
637
638pub const VDSO = struct {
639 pub const CGT_SYM = "__vdso_clock_gettime";
640 pub const CGT_VER = "LINUX_2.6";
641};
642
643pub const ARCH = struct {};
644
645pub const Flock = extern struct {
646 type: i16,
647 whence: i16,
648 start: off_t,
649 len: off_t,
650 pid: pid_t,
651};
652
653pub const msghdr = extern struct {
654 name: ?*sockaddr,
655 namelen: socklen_t,
656 iov: [*]iovec,
657 iovlen: i32,
658 control: ?*c_void,
659 controllen: socklen_t,
660 flags: i32,
661};
662
663pub const msghdr_const = extern struct {
664 name: ?*const sockaddr,
665 namelen: socklen_t,
666 iov: [*]iovec_const,
667 iovlen: i32,
668 control: ?*c_void,
669 controllen: socklen_t,
670 flags: i32,
671};
672
673pub const blksize_t = i32;
674pub const nlink_t = u32;
675pub const time_t = isize;
676pub const mode_t = u32;
677pub const off_t = i64;
678pub const ino_t = u64;
679pub const dev_t = u64;
680pub const blkcnt_t = i64;
681
682// The `stat` definition used by the Linux kernel.
683pub const Stat = extern struct {
684 dev: dev_t,
685 __dev_padding: u32,
686 __ino_truncated: u32,
687 mode: mode_t,
688 nlink: nlink_t,
689 uid: uid_t,
690 gid: gid_t,
691 rdev: dev_t,
692 __rdev_padding: u32,
693 size: off_t,
694 blksize: blksize_t,
695 blocks: blkcnt_t,
696 atim: timespec,
697 mtim: timespec,
698 ctim: timespec,
699 ino: ino_t,
700
701 pub fn atime(self: @This()) timespec {
702 return self.atim;
703 }
704
705 pub fn mtime(self: @This()) timespec {
706 return self.mtim;
707 }
708
709 pub fn ctime(self: @This()) timespec {
710 return self.ctim;
711 }
712};
713
714pub const timeval = extern struct {
715 tv_sec: i32,
716 tv_usec: i32,
717};
718
719pub const timezone = extern struct {
720 tz_minuteswest: i32,
721 tz_dsttime: i32,
722};
723
724pub const mcontext_t = extern struct {
725 gregs: [19]usize,
726 fpregs: [*]u8,
727 oldmask: usize,
728 cr2: usize,
729};
730
731pub const REG = struct {
732 pub const GS = 0;
733 pub const FS = 1;
734 pub const ES = 2;
735 pub const DS = 3;
736 pub const EDI = 4;
737 pub const ESI = 5;
738 pub const EBP = 6;
739 pub const ESP = 7;
740 pub const EBX = 8;
741 pub const EDX = 9;
742 pub const ECX = 10;
743 pub const EAX = 11;
744 pub const TRAPNO = 12;
745 pub const ERR = 13;
746 pub const EIP = 14;
747 pub const CS = 15;
748 pub const EFL = 16;
749 pub const UESP = 17;
750 pub const SS = 18;
751};
752
753pub const ucontext_t = extern struct {
754 flags: usize,
755 link: *ucontext_t,
756 stack: stack_t,
757 mcontext: mcontext_t,
758 sigmask: sigset_t,
759 regspace: [64]u64,
760};
761
762pub const Elf_Symndx = u32;
763
764pub const user_desc = packed struct {
765 entry_number: u32,
766 base_addr: u32,
767 limit: u32,
768 seg_32bit: u1,
769 contents: u2,
770 read_exec_only: u1,
771 limit_in_pages: u1,
772 seg_not_present: u1,
773 useable: u1,
774};
775
776/// socketcall() call numbers
777pub const SC = struct {
778 pub const socket = 1;
779 pub const bind = 2;
780 pub const connect = 3;
781 pub const listen = 4;
782 pub const accept = 5;
783 pub const getsockname = 6;
784 pub const getpeername = 7;
785 pub const socketpair = 8;
786 pub const send = 9;
787 pub const recv = 10;
788 pub const sendto = 11;
789 pub const recvfrom = 12;
790 pub const shutdown = 13;
791 pub const setsockopt = 14;
792 pub const getsockopt = 15;
793 pub const sendmsg = 16;
794 pub const recvmsg = 17;
795 pub const accept4 = 18;
796 pub const recvmmsg = 19;
797 pub const sendmmsg = 20;
798};
lib/std/os/linux/io_uring.zig+18-18
...@@ -535,11 +535,11 @@ pub const IO_Uring = struct {...@@ -535,11 +535,11 @@ pub const IO_Uring = struct {
535 /// `0` if the timeout completed after the specified number of events, or `-ECANCELED` if the535 /// `0` if the timeout completed after the specified number of events, or `-ECANCELED` if the
536 /// timeout was removed before it expired.536 /// timeout was removed before it expired.
537 ///537 ///
538 /// io_uring timeouts use the `CLOCK_MONOTONIC` clock source.538 /// io_uring timeouts use the `CLOCK.MONOTONIC` clock source.
539 pub fn timeout(539 pub fn timeout(
540 self: *IO_Uring,540 self: *IO_Uring,
541 user_data: u64,541 user_data: u64,
542 ts: *const os.__kernel_timespec,542 ts: *const os.linux.kernel_timespec,
543 count: u32,543 count: u32,
544 flags: u32,544 flags: u32,
545 ) !*io_uring_sqe {545 ) !*io_uring_sqe {
...@@ -736,8 +736,8 @@ pub const SubmissionQueue = struct {...@@ -736,8 +736,8 @@ pub const SubmissionQueue = struct {
736 const mmap = try os.mmap(736 const mmap = try os.mmap(
737 null,737 null,
738 size,738 size,
739 os.PROT_READ | os.PROT_WRITE,739 os.PROT.READ | os.PROT.WRITE,
740 os.MAP_SHARED | os.MAP_POPULATE,740 os.MAP.SHARED | os.MAP.POPULATE,
741 fd,741 fd,
742 linux.IORING_OFF_SQ_RING,742 linux.IORING_OFF_SQ_RING,
743 );743 );
...@@ -750,8 +750,8 @@ pub const SubmissionQueue = struct {...@@ -750,8 +750,8 @@ pub const SubmissionQueue = struct {
750 const mmap_sqes = try os.mmap(750 const mmap_sqes = try os.mmap(
751 null,751 null,
752 size_sqes,752 size_sqes,
753 os.PROT_READ | os.PROT_WRITE,753 os.PROT.READ | os.PROT.WRITE,
754 os.MAP_SHARED | os.MAP_POPULATE,754 os.MAP.SHARED | os.MAP.POPULATE,
755 fd,755 fd,
756 linux.IORING_OFF_SQES,756 linux.IORING_OFF_SQES,
757 );757 );
...@@ -979,7 +979,7 @@ pub fn io_uring_prep_close(sqe: *io_uring_sqe, fd: os.fd_t) void {...@@ -979,7 +979,7 @@ pub fn io_uring_prep_close(sqe: *io_uring_sqe, fd: os.fd_t) void {
979979
980pub fn io_uring_prep_timeout(980pub fn io_uring_prep_timeout(
981 sqe: *io_uring_sqe,981 sqe: *io_uring_sqe,
982 ts: *const os.__kernel_timespec,982 ts: *const os.linux.kernel_timespec,
983 count: u32,983 count: u32,
984 flags: u32,984 flags: u32,
985) void {985) void {
...@@ -1136,7 +1136,7 @@ test "readv" {...@@ -1136,7 +1136,7 @@ test "readv" {
1136 };1136 };
1137 defer ring.deinit();1137 defer ring.deinit();
11381138
1139 const fd = try os.openZ("/dev/zero", os.O_RDONLY | os.O_CLOEXEC, 0);1139 const fd = try os.openZ("/dev/zero", os.O.RDONLY | os.O.CLOEXEC, 0);
1140 defer os.close(fd);1140 defer os.close(fd);
11411141
1142 // Linux Kernel 5.4 supports IORING_REGISTER_FILES but not sparse fd sets (i.e. an fd of -1).1142 // Linux Kernel 5.4 supports IORING_REGISTER_FILES but not sparse fd sets (i.e. an fd of -1).
...@@ -1295,14 +1295,14 @@ test "openat" {...@@ -1295,14 +1295,14 @@ test "openat" {
1295 const path = "test_io_uring_openat";1295 const path = "test_io_uring_openat";
1296 defer std.fs.cwd().deleteFile(path) catch {};1296 defer std.fs.cwd().deleteFile(path) catch {};
12971297
1298 const flags: u32 = os.O_CLOEXEC | os.O_RDWR | os.O_CREAT;1298 const flags: u32 = os.O.CLOEXEC | os.O.RDWR | os.O.CREAT;
1299 const mode: os.mode_t = 0o666;1299 const mode: os.mode_t = 0o666;
1300 const sqe_openat = try ring.openat(0x33333333, linux.AT_FDCWD, path, flags, mode);1300 const sqe_openat = try ring.openat(0x33333333, linux.AT.FDCWD, path, flags, mode);
1301 try testing.expectEqual(io_uring_sqe{1301 try testing.expectEqual(io_uring_sqe{
1302 .opcode = .OPENAT,1302 .opcode = .OPENAT,
1303 .flags = 0,1303 .flags = 0,
1304 .ioprio = 0,1304 .ioprio = 0,
1305 .fd = linux.AT_FDCWD,1305 .fd = linux.AT.FDCWD,
1306 .off = 0,1306 .off = 0,
1307 .addr = @ptrToInt(path),1307 .addr = @ptrToInt(path),
1308 .len = mode,1308 .len = mode,
...@@ -1318,7 +1318,7 @@ test "openat" {...@@ -1318,7 +1318,7 @@ test "openat" {
1318 const cqe_openat = try ring.copy_cqe();1318 const cqe_openat = try ring.copy_cqe();
1319 try testing.expectEqual(@as(u64, 0x33333333), cqe_openat.user_data);1319 try testing.expectEqual(@as(u64, 0x33333333), cqe_openat.user_data);
1320 if (cqe_openat.err() == .INVAL) return error.SkipZigTest;1320 if (cqe_openat.err() == .INVAL) return error.SkipZigTest;
1321 // AT_FDCWD is not fully supported before kernel 5.6:1321 // AT.FDCWD is not fully supported before kernel 5.6:
1322 // See https://lore.kernel.org/io-uring/20200207155039.12819-1-axboe@kernel.dk/T/1322 // See https://lore.kernel.org/io-uring/20200207155039.12819-1-axboe@kernel.dk/T/
1323 // We use IORING_FEAT_RW_CUR_POS to know if we are pre-5.6 since that feature was added in 5.6.1323 // We use IORING_FEAT_RW_CUR_POS to know if we are pre-5.6 since that feature was added in 5.6.
1324 if (cqe_openat.err() == .BADF and (ring.features & linux.IORING_FEAT_RW_CUR_POS) == 0) {1324 if (cqe_openat.err() == .BADF and (ring.features & linux.IORING_FEAT_RW_CUR_POS) == 0) {
...@@ -1372,9 +1372,9 @@ test "accept/connect/send/recv" {...@@ -1372,9 +1372,9 @@ test "accept/connect/send/recv" {
13721372
1373 const address = try net.Address.parseIp4("127.0.0.1", 3131);1373 const address = try net.Address.parseIp4("127.0.0.1", 3131);
1374 const kernel_backlog = 1;1374 const kernel_backlog = 1;
1375 const server = try os.socket(address.any.family, os.SOCK_STREAM | os.SOCK_CLOEXEC, 0);1375 const server = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
1376 defer os.close(server);1376 defer os.close(server);
1377 try os.setsockopt(server, os.SOL_SOCKET, os.SO_REUSEADDR, &mem.toBytes(@as(c_int, 1)));1377 try os.setsockopt(server, os.SOL.SOCKET, os.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)));
1378 try os.bind(server, &address.any, address.getOsSockLen());1378 try os.bind(server, &address.any, address.getOsSockLen());
1379 try os.listen(server, kernel_backlog);1379 try os.listen(server, kernel_backlog);
13801380
...@@ -1386,7 +1386,7 @@ test "accept/connect/send/recv" {...@@ -1386,7 +1386,7 @@ test "accept/connect/send/recv" {
1386 _ = try ring.accept(0xaaaaaaaa, server, &accept_addr, &accept_addr_len, 0);1386 _ = try ring.accept(0xaaaaaaaa, server, &accept_addr, &accept_addr_len, 0);
1387 try testing.expectEqual(@as(u32, 1), try ring.submit());1387 try testing.expectEqual(@as(u32, 1), try ring.submit());
13881388
1389 const client = try os.socket(address.any.family, os.SOCK_STREAM | os.SOCK_CLOEXEC, 0);1389 const client = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
1390 defer os.close(client);1390 defer os.close(client);
1391 _ = try ring.connect(0xcccccccc, client, &address.any, address.getOsSockLen());1391 _ = try ring.connect(0xcccccccc, client, &address.any, address.getOsSockLen());
1392 try testing.expectEqual(@as(u32, 1), try ring.submit());1392 try testing.expectEqual(@as(u32, 1), try ring.submit());
...@@ -1450,7 +1450,7 @@ test "timeout (after a relative time)" {...@@ -1450,7 +1450,7 @@ test "timeout (after a relative time)" {
14501450
1451 const ms = 10;1451 const ms = 10;
1452 const margin = 5;1452 const margin = 5;
1453 const ts = os.__kernel_timespec{ .tv_sec = 0, .tv_nsec = ms * 1000000 };1453 const ts = os.linux.kernel_timespec{ .tv_sec = 0, .tv_nsec = ms * 1000000 };
14541454
1455 const started = std.time.milliTimestamp();1455 const started = std.time.milliTimestamp();
1456 const sqe = try ring.timeout(0x55555555, &ts, 0, 0);1456 const sqe = try ring.timeout(0x55555555, &ts, 0, 0);
...@@ -1479,7 +1479,7 @@ test "timeout (after a number of completions)" {...@@ -1479,7 +1479,7 @@ test "timeout (after a number of completions)" {
1479 };1479 };
1480 defer ring.deinit();1480 defer ring.deinit();
14811481
1482 const ts = os.__kernel_timespec{ .tv_sec = 3, .tv_nsec = 0 };1482 const ts = os.linux.kernel_timespec{ .tv_sec = 3, .tv_nsec = 0 };
1483 const count_completions: u64 = 1;1483 const count_completions: u64 = 1;
1484 const sqe_timeout = try ring.timeout(0x66666666, &ts, count_completions, 0);1484 const sqe_timeout = try ring.timeout(0x66666666, &ts, count_completions, 0);
1485 try testing.expectEqual(linux.IORING_OP.TIMEOUT, sqe_timeout.opcode);1485 try testing.expectEqual(linux.IORING_OP.TIMEOUT, sqe_timeout.opcode);
...@@ -1512,7 +1512,7 @@ test "timeout_remove" {...@@ -1512,7 +1512,7 @@ test "timeout_remove" {
1512 };1512 };
1513 defer ring.deinit();1513 defer ring.deinit();
15141514
1515 const ts = os.__kernel_timespec{ .tv_sec = 3, .tv_nsec = 0 };1515 const ts = os.linux.kernel_timespec{ .tv_sec = 3, .tv_nsec = 0 };
1516 const sqe_timeout = try ring.timeout(0x88888888, &ts, 0, 0);1516 const sqe_timeout = try ring.timeout(0x88888888, &ts, 0, 0);
1517 try testing.expectEqual(linux.IORING_OP.TIMEOUT, sqe_timeout.opcode);1517 try testing.expectEqual(linux.IORING_OP.TIMEOUT, sqe_timeout.opcode);
1518 try testing.expectEqual(@as(u64, 0x88888888), sqe_timeout.user_data);1518 try testing.expectEqual(@as(u64, 0x88888888), sqe_timeout.user_data);
lib/std/os/linux/mips.zig+569-1
...@@ -1,4 +1,13 @@...@@ -1,4 +1,13 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const socklen_t = linux.socklen_t;
5const iovec = linux.iovec;
6const iovec_const = linux.iovec_const;
7const uid_t = linux.uid_t;
8const gid_t = linux.gid_t;
9const pid_t = linux.pid_t;
10const timespec = linux.timespec;
211
3pub fn syscall0(number: SYS) usize {12pub fn syscall0(number: SYS) usize {
4 return asm volatile (13 return asm volatile (
...@@ -197,3 +206,562 @@ pub fn restore_rt() callconv(.Naked) void {...@@ -197,3 +206,562 @@ pub fn restore_rt() callconv(.Naked) void {
197 : "memory", "cc", "$7"206 : "memory", "cc", "$7"
198 );207 );
199}208}
209
210pub const SYS = enum(usize) {
211 pub const Linux = 4000;
212
213 syscall = Linux + 0,
214 exit = Linux + 1,
215 fork = Linux + 2,
216 read = Linux + 3,
217 write = Linux + 4,
218 open = Linux + 5,
219 close = Linux + 6,
220 waitpid = Linux + 7,
221 creat = Linux + 8,
222 link = Linux + 9,
223 unlink = Linux + 10,
224 execve = Linux + 11,
225 chdir = Linux + 12,
226 time = Linux + 13,
227 mknod = Linux + 14,
228 chmod = Linux + 15,
229 lchown = Linux + 16,
230 @"break" = Linux + 17,
231 unused18 = Linux + 18,
232 lseek = Linux + 19,
233 getpid = Linux + 20,
234 mount = Linux + 21,
235 umount = Linux + 22,
236 setuid = Linux + 23,
237 getuid = Linux + 24,
238 stime = Linux + 25,
239 ptrace = Linux + 26,
240 alarm = Linux + 27,
241 unused28 = Linux + 28,
242 pause = Linux + 29,
243 utime = Linux + 30,
244 stty = Linux + 31,
245 gtty = Linux + 32,
246 access = Linux + 33,
247 nice = Linux + 34,
248 ftime = Linux + 35,
249 sync = Linux + 36,
250 kill = Linux + 37,
251 rename = Linux + 38,
252 mkdir = Linux + 39,
253 rmdir = Linux + 40,
254 dup = Linux + 41,
255 pipe = Linux + 42,
256 times = Linux + 43,
257 prof = Linux + 44,
258 brk = Linux + 45,
259 setgid = Linux + 46,
260 getgid = Linux + 47,
261 signal = Linux + 48,
262 geteuid = Linux + 49,
263 getegid = Linux + 50,
264 acct = Linux + 51,
265 umount2 = Linux + 52,
266 lock = Linux + 53,
267 ioctl = Linux + 54,
268 fcntl = Linux + 55,
269 mpx = Linux + 56,
270 setpgid = Linux + 57,
271 ulimit = Linux + 58,
272 unused59 = Linux + 59,
273 umask = Linux + 60,
274 chroot = Linux + 61,
275 ustat = Linux + 62,
276 dup2 = Linux + 63,
277 getppid = Linux + 64,
278 getpgrp = Linux + 65,
279 setsid = Linux + 66,
280 sigaction = Linux + 67,
281 sgetmask = Linux + 68,
282 ssetmask = Linux + 69,
283 setreuid = Linux + 70,
284 setregid = Linux + 71,
285 sigsuspend = Linux + 72,
286 sigpending = Linux + 73,
287 sethostname = Linux + 74,
288 setrlimit = Linux + 75,
289 getrlimit = Linux + 76,
290 getrusage = Linux + 77,
291 gettimeofday = Linux + 78,
292 settimeofday = Linux + 79,
293 getgroups = Linux + 80,
294 setgroups = Linux + 81,
295 reserved82 = Linux + 82,
296 symlink = Linux + 83,
297 unused84 = Linux + 84,
298 readlink = Linux + 85,
299 uselib = Linux + 86,
300 swapon = Linux + 87,
301 reboot = Linux + 88,
302 readdir = Linux + 89,
303 mmap = Linux + 90,
304 munmap = Linux + 91,
305 truncate = Linux + 92,
306 ftruncate = Linux + 93,
307 fchmod = Linux + 94,
308 fchown = Linux + 95,
309 getpriority = Linux + 96,
310 setpriority = Linux + 97,
311 profil = Linux + 98,
312 statfs = Linux + 99,
313 fstatfs = Linux + 100,
314 ioperm = Linux + 101,
315 socketcall = Linux + 102,
316 syslog = Linux + 103,
317 setitimer = Linux + 104,
318 getitimer = Linux + 105,
319 stat = Linux + 106,
320 lstat = Linux + 107,
321 fstat = Linux + 108,
322 unused109 = Linux + 109,
323 iopl = Linux + 110,
324 vhangup = Linux + 111,
325 idle = Linux + 112,
326 vm86 = Linux + 113,
327 wait4 = Linux + 114,
328 swapoff = Linux + 115,
329 sysinfo = Linux + 116,
330 ipc = Linux + 117,
331 fsync = Linux + 118,
332 sigreturn = Linux + 119,
333 clone = Linux + 120,
334 setdomainname = Linux + 121,
335 uname = Linux + 122,
336 modify_ldt = Linux + 123,
337 adjtimex = Linux + 124,
338 mprotect = Linux + 125,
339 sigprocmask = Linux + 126,
340 create_module = Linux + 127,
341 init_module = Linux + 128,
342 delete_module = Linux + 129,
343 get_kernel_syms = Linux + 130,
344 quotactl = Linux + 131,
345 getpgid = Linux + 132,
346 fchdir = Linux + 133,
347 bdflush = Linux + 134,
348 sysfs = Linux + 135,
349 personality = Linux + 136,
350 afs_syscall = Linux + 137,
351 setfsuid = Linux + 138,
352 setfsgid = Linux + 139,
353 _llseek = Linux + 140,
354 getdents = Linux + 141,
355 _newselect = Linux + 142,
356 flock = Linux + 143,
357 msync = Linux + 144,
358 readv = Linux + 145,
359 writev = Linux + 146,
360 cacheflush = Linux + 147,
361 cachectl = Linux + 148,
362 sysmips = Linux + 149,
363 unused150 = Linux + 150,
364 getsid = Linux + 151,
365 fdatasync = Linux + 152,
366 _sysctl = Linux + 153,
367 mlock = Linux + 154,
368 munlock = Linux + 155,
369 mlockall = Linux + 156,
370 munlockall = Linux + 157,
371 sched_setparam = Linux + 158,
372 sched_getparam = Linux + 159,
373 sched_setscheduler = Linux + 160,
374 sched_getscheduler = Linux + 161,
375 sched_yield = Linux + 162,
376 sched_get_priority_max = Linux + 163,
377 sched_get_priority_min = Linux + 164,
378 sched_rr_get_interval = Linux + 165,
379 nanosleep = Linux + 166,
380 mremap = Linux + 167,
381 accept = Linux + 168,
382 bind = Linux + 169,
383 connect = Linux + 170,
384 getpeername = Linux + 171,
385 getsockname = Linux + 172,
386 getsockopt = Linux + 173,
387 listen = Linux + 174,
388 recv = Linux + 175,
389 recvfrom = Linux + 176,
390 recvmsg = Linux + 177,
391 send = Linux + 178,
392 sendmsg = Linux + 179,
393 sendto = Linux + 180,
394 setsockopt = Linux + 181,
395 shutdown = Linux + 182,
396 socket = Linux + 183,
397 socketpair = Linux + 184,
398 setresuid = Linux + 185,
399 getresuid = Linux + 186,
400 query_module = Linux + 187,
401 poll = Linux + 188,
402 nfsservctl = Linux + 189,
403 setresgid = Linux + 190,
404 getresgid = Linux + 191,
405 prctl = Linux + 192,
406 rt_sigreturn = Linux + 193,
407 rt_sigaction = Linux + 194,
408 rt_sigprocmask = Linux + 195,
409 rt_sigpending = Linux + 196,
410 rt_sigtimedwait = Linux + 197,
411 rt_sigqueueinfo = Linux + 198,
412 rt_sigsuspend = Linux + 199,
413 pread64 = Linux + 200,
414 pwrite64 = Linux + 201,
415 chown = Linux + 202,
416 getcwd = Linux + 203,
417 capget = Linux + 204,
418 capset = Linux + 205,
419 sigaltstack = Linux + 206,
420 sendfile = Linux + 207,
421 getpmsg = Linux + 208,
422 putpmsg = Linux + 209,
423 mmap2 = Linux + 210,
424 truncate64 = Linux + 211,
425 ftruncate64 = Linux + 212,
426 stat64 = Linux + 213,
427 lstat64 = Linux + 214,
428 fstat64 = Linux + 215,
429 pivot_root = Linux + 216,
430 mincore = Linux + 217,
431 madvise = Linux + 218,
432 getdents64 = Linux + 219,
433 fcntl64 = Linux + 220,
434 reserved221 = Linux + 221,
435 gettid = Linux + 222,
436 readahead = Linux + 223,
437 setxattr = Linux + 224,
438 lsetxattr = Linux + 225,
439 fsetxattr = Linux + 226,
440 getxattr = Linux + 227,
441 lgetxattr = Linux + 228,
442 fgetxattr = Linux + 229,
443 listxattr = Linux + 230,
444 llistxattr = Linux + 231,
445 flistxattr = Linux + 232,
446 removexattr = Linux + 233,
447 lremovexattr = Linux + 234,
448 fremovexattr = Linux + 235,
449 tkill = Linux + 236,
450 sendfile64 = Linux + 237,
451 futex = Linux + 238,
452 sched_setaffinity = Linux + 239,
453 sched_getaffinity = Linux + 240,
454 io_setup = Linux + 241,
455 io_destroy = Linux + 242,
456 io_getevents = Linux + 243,
457 io_submit = Linux + 244,
458 io_cancel = Linux + 245,
459 exit_group = Linux + 246,
460 lookup_dcookie = Linux + 247,
461 epoll_create = Linux + 248,
462 epoll_ctl = Linux + 249,
463 epoll_wait = Linux + 250,
464 remap_file_pages = Linux + 251,
465 set_tid_address = Linux + 252,
466 restart_syscall = Linux + 253,
467 fadvise64 = Linux + 254,
468 statfs64 = Linux + 255,
469 fstatfs64 = Linux + 256,
470 timer_create = Linux + 257,
471 timer_settime = Linux + 258,
472 timer_gettime = Linux + 259,
473 timer_getoverrun = Linux + 260,
474 timer_delete = Linux + 261,
475 clock_settime = Linux + 262,
476 clock_gettime = Linux + 263,
477 clock_getres = Linux + 264,
478 clock_nanosleep = Linux + 265,
479 tgkill = Linux + 266,
480 utimes = Linux + 267,
481 mbind = Linux + 268,
482 get_mempolicy = Linux + 269,
483 set_mempolicy = Linux + 270,
484 mq_open = Linux + 271,
485 mq_unlink = Linux + 272,
486 mq_timedsend = Linux + 273,
487 mq_timedreceive = Linux + 274,
488 mq_notify = Linux + 275,
489 mq_getsetattr = Linux + 276,
490 vserver = Linux + 277,
491 waitid = Linux + 278,
492 add_key = Linux + 280,
493 request_key = Linux + 281,
494 keyctl = Linux + 282,
495 set_thread_area = Linux + 283,
496 inotify_init = Linux + 284,
497 inotify_add_watch = Linux + 285,
498 inotify_rm_watch = Linux + 286,
499 migrate_pages = Linux + 287,
500 openat = Linux + 288,
501 mkdirat = Linux + 289,
502 mknodat = Linux + 290,
503 fchownat = Linux + 291,
504 futimesat = Linux + 292,
505 fstatat64 = Linux + 293,
506 unlinkat = Linux + 294,
507 renameat = Linux + 295,
508 linkat = Linux + 296,
509 symlinkat = Linux + 297,
510 readlinkat = Linux + 298,
511 fchmodat = Linux + 299,
512 faccessat = Linux + 300,
513 pselect6 = Linux + 301,
514 ppoll = Linux + 302,
515 unshare = Linux + 303,
516 splice = Linux + 304,
517 sync_file_range = Linux + 305,
518 tee = Linux + 306,
519 vmsplice = Linux + 307,
520 move_pages = Linux + 308,
521 set_robust_list = Linux + 309,
522 get_robust_list = Linux + 310,
523 kexec_load = Linux + 311,
524 getcpu = Linux + 312,
525 epoll_pwait = Linux + 313,
526 ioprio_set = Linux + 314,
527 ioprio_get = Linux + 315,
528 utimensat = Linux + 316,
529 signalfd = Linux + 317,
530 timerfd = Linux + 318,
531 eventfd = Linux + 319,
532 fallocate = Linux + 320,
533 timerfd_create = Linux + 321,
534 timerfd_gettime = Linux + 322,
535 timerfd_settime = Linux + 323,
536 signalfd4 = Linux + 324,
537 eventfd2 = Linux + 325,
538 epoll_create1 = Linux + 326,
539 dup3 = Linux + 327,
540 pipe2 = Linux + 328,
541 inotify_init1 = Linux + 329,
542 preadv = Linux + 330,
543 pwritev = Linux + 331,
544 rt_tgsigqueueinfo = Linux + 332,
545 perf_event_open = Linux + 333,
546 accept4 = Linux + 334,
547 recvmmsg = Linux + 335,
548 fanotify_init = Linux + 336,
549 fanotify_mark = Linux + 337,
550 prlimit64 = Linux + 338,
551 name_to_handle_at = Linux + 339,
552 open_by_handle_at = Linux + 340,
553 clock_adjtime = Linux + 341,
554 syncfs = Linux + 342,
555 sendmmsg = Linux + 343,
556 setns = Linux + 344,
557 process_vm_readv = Linux + 345,
558 process_vm_writev = Linux + 346,
559 kcmp = Linux + 347,
560 finit_module = Linux + 348,
561 sched_setattr = Linux + 349,
562 sched_getattr = Linux + 350,
563 renameat2 = Linux + 351,
564 seccomp = Linux + 352,
565 getrandom = Linux + 353,
566 memfd_create = Linux + 354,
567 bpf = Linux + 355,
568 execveat = Linux + 356,
569 userfaultfd = Linux + 357,
570 membarrier = Linux + 358,
571 mlock2 = Linux + 359,
572 copy_file_range = Linux + 360,
573 preadv2 = Linux + 361,
574 pwritev2 = Linux + 362,
575 pkey_mprotect = Linux + 363,
576 pkey_alloc = Linux + 364,
577 pkey_free = Linux + 365,
578 statx = Linux + 366,
579 rseq = Linux + 367,
580 io_pgetevents = Linux + 368,
581 semget = Linux + 393,
582 semctl = Linux + 394,
583 shmget = Linux + 395,
584 shmctl = Linux + 396,
585 shmat = Linux + 397,
586 shmdt = Linux + 398,
587 msgget = Linux + 399,
588 msgsnd = Linux + 400,
589 msgrcv = Linux + 401,
590 msgctl = Linux + 402,
591 clock_gettime64 = Linux + 403,
592 clock_settime64 = Linux + 404,
593 clock_adjtime64 = Linux + 405,
594 clock_getres_time64 = Linux + 406,
595 clock_nanosleep_time64 = Linux + 407,
596 timer_gettime64 = Linux + 408,
597 timer_settime64 = Linux + 409,
598 timerfd_gettime64 = Linux + 410,
599 timerfd_settime64 = Linux + 411,
600 utimensat_time64 = Linux + 412,
601 pselect6_time64 = Linux + 413,
602 ppoll_time64 = Linux + 414,
603 io_pgetevents_time64 = Linux + 416,
604 recvmmsg_time64 = Linux + 417,
605 mq_timedsend_time64 = Linux + 418,
606 mq_timedreceive_time64 = Linux + 419,
607 semtimedop_time64 = Linux + 420,
608 rt_sigtimedwait_time64 = Linux + 421,
609 futex_time64 = Linux + 422,
610 sched_rr_get_interval_time64 = Linux + 423,
611 pidfd_send_signal = Linux + 424,
612 io_uring_setup = Linux + 425,
613 io_uring_enter = Linux + 426,
614 io_uring_register = Linux + 427,
615 open_tree = Linux + 428,
616 move_mount = Linux + 429,
617 fsopen = Linux + 430,
618 fsconfig = Linux + 431,
619 fsmount = Linux + 432,
620 fspick = Linux + 433,
621 pidfd_open = Linux + 434,
622 clone3 = Linux + 435,
623 close_range = Linux + 436,
624 openat2 = Linux + 437,
625 pidfd_getfd = Linux + 438,
626 faccessat2 = Linux + 439,
627 process_madvise = Linux + 440,
628 epoll_pwait2 = Linux + 441,
629
630 _,
631};
632
633pub const O = struct {
634 pub const CREAT = 0o0400;
635 pub const EXCL = 0o02000;
636 pub const NOCTTY = 0o04000;
637 pub const TRUNC = 0o01000;
638 pub const APPEND = 0o0010;
639 pub const NONBLOCK = 0o0200;
640 pub const DSYNC = 0o0020;
641 pub const SYNC = 0o040020;
642 pub const RSYNC = 0o040020;
643 pub const DIRECTORY = 0o0200000;
644 pub const NOFOLLOW = 0o0400000;
645 pub const CLOEXEC = 0o02000000;
646
647 pub const ASYNC = 0o010000;
648 pub const DIRECT = 0o0100000;
649 pub const LARGEFILE = 0o020000;
650 pub const NOATIME = 0o01000000;
651 pub const PATH = 0o010000000;
652 pub const TMPFILE = 0o020200000;
653 pub const NDELAY = NONBLOCK;
654};
655
656pub const F = struct {
657 pub const DUPFD = 0;
658 pub const GETFD = 1;
659 pub const SETFD = 2;
660 pub const GETFL = 3;
661 pub const SETFL = 4;
662
663 pub const SETOWN = 24;
664 pub const GETOWN = 23;
665 pub const SETSIG = 10;
666 pub const GETSIG = 11;
667
668 pub const GETLK = 33;
669 pub const SETLK = 34;
670 pub const SETLKW = 35;
671
672 pub const RDLCK = 0;
673 pub const WRLCK = 1;
674 pub const UNLCK = 2;
675
676 pub const SETOWN_EX = 15;
677 pub const GETOWN_EX = 16;
678
679 pub const GETOWNER_UIDS = 17;
680};
681
682pub const LOCK = struct {
683 pub const SH = 1;
684 pub const EX = 2;
685 pub const UN = 8;
686 pub const NB = 4;
687};
688
689pub const MMAP2_UNIT = 4096;
690
691pub const MAP = struct {
692 pub const NORESERVE = 0x0400;
693 pub const GROWSDOWN = 0x1000;
694 pub const DENYWRITE = 0x2000;
695 pub const EXECUTABLE = 0x4000;
696 pub const LOCKED = 0x8000;
697 pub const @"32BIT" = 0x40;
698};
699
700pub const VDSO = struct {
701 pub const CGT_SYM = "__kernel_clock_gettime";
702 pub const CGT_VER = "LINUX_2.6.39";
703};
704
705pub const Flock = extern struct {
706 l_type: i16,
707 l_whence: i16,
708 __pad0: [4]u8,
709 l_start: off_t,
710 l_len: off_t,
711 l_pid: pid_t,
712 __unused: [4]u8,
713};
714
715pub const blksize_t = i32;
716pub const nlink_t = u32;
717pub const time_t = i32;
718pub const mode_t = u32;
719pub const off_t = i64;
720pub const ino_t = u64;
721pub const dev_t = u64;
722pub const blkcnt_t = i64;
723
724// The `stat` definition used by the Linux kernel.
725pub const Stat = extern struct {
726 dev: u32,
727 __pad0: [3]u32, // Reserved for st_dev expansion
728 ino: ino_t,
729 mode: mode_t,
730 nlink: nlink_t,
731 uid: uid_t,
732 gid: gid_t,
733 rdev: u32,
734 __pad1: [3]u32,
735 size: off_t,
736 atim: timespec,
737 mtim: timespec,
738 ctim: timespec,
739 blksize: blksize_t,
740 __pad3: u32,
741 blocks: blkcnt_t,
742 __pad4: [14]usize,
743
744 pub fn atime(self: @This()) timespec {
745 return self.atim;
746 }
747
748 pub fn mtime(self: @This()) timespec {
749 return self.mtim;
750 }
751
752 pub fn ctime(self: @This()) timespec {
753 return self.ctim;
754 }
755};
756
757pub const timeval = extern struct {
758 tv_sec: isize,
759 tv_usec: isize,
760};
761
762pub const timezone = extern struct {
763 tz_minuteswest: i32,
764 tz_dsttime: i32,
765};
766
767pub const Elf_Symndx = u32;
lib/std/os/linux/powerpc.zig+623-1
...@@ -1,4 +1,16 @@...@@ -1,4 +1,16 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const socklen_t = linux.socklen_t;
5const iovec = linux.iovec;
6const iovec_const = linux.iovec_const;
7const uid_t = linux.uid_t;
8const gid_t = linux.gid_t;
9const pid_t = linux.pid_t;
10const stack_t = linux.stack_t;
11const sigset_t = linux.sigset_t;
12const sockaddr = linux.sockaddr;
13const timespec = linux.timespec;
214
3pub fn syscall0(number: SYS) usize {15pub fn syscall0(number: SYS) usize {
4 return asm volatile (16 return asm volatile (
...@@ -125,3 +137,613 @@ pub fn restore_rt() callconv(.Naked) void {...@@ -125,3 +137,613 @@ pub fn restore_rt() callconv(.Naked) void {
125 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"137 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
126 );138 );
127}139}
140
141pub const SYS = enum(usize) {
142 restart_syscall = 0,
143 exit = 1,
144 fork = 2,
145 read = 3,
146 write = 4,
147 open = 5,
148 close = 6,
149 waitpid = 7,
150 creat = 8,
151 link = 9,
152 unlink = 10,
153 execve = 11,
154 chdir = 12,
155 time = 13,
156 mknod = 14,
157 chmod = 15,
158 lchown = 16,
159 @"break" = 17,
160 oldstat = 18,
161 lseek = 19,
162 getpid = 20,
163 mount = 21,
164 umount = 22,
165 setuid = 23,
166 getuid = 24,
167 stime = 25,
168 ptrace = 26,
169 alarm = 27,
170 oldfstat = 28,
171 pause = 29,
172 utime = 30,
173 stty = 31,
174 gtty = 32,
175 access = 33,
176 nice = 34,
177 ftime = 35,
178 sync = 36,
179 kill = 37,
180 rename = 38,
181 mkdir = 39,
182 rmdir = 40,
183 dup = 41,
184 pipe = 42,
185 times = 43,
186 prof = 44,
187 brk = 45,
188 setgid = 46,
189 getgid = 47,
190 signal = 48,
191 geteuid = 49,
192 getegid = 50,
193 acct = 51,
194 umount2 = 52,
195 lock = 53,
196 ioctl = 54,
197 fcntl = 55,
198 mpx = 56,
199 setpgid = 57,
200 ulimit = 58,
201 oldolduname = 59,
202 umask = 60,
203 chroot = 61,
204 ustat = 62,
205 dup2 = 63,
206 getppid = 64,
207 getpgrp = 65,
208 setsid = 66,
209 sigaction = 67,
210 sgetmask = 68,
211 ssetmask = 69,
212 setreuid = 70,
213 setregid = 71,
214 sigsuspend = 72,
215 sigpending = 73,
216 sethostname = 74,
217 setrlimit = 75,
218 getrlimit = 76,
219 getrusage = 77,
220 gettimeofday = 78,
221 settimeofday = 79,
222 getgroups = 80,
223 setgroups = 81,
224 select = 82,
225 symlink = 83,
226 oldlstat = 84,
227 readlink = 85,
228 uselib = 86,
229 swapon = 87,
230 reboot = 88,
231 readdir = 89,
232 mmap = 90,
233 munmap = 91,
234 truncate = 92,
235 ftruncate = 93,
236 fchmod = 94,
237 fchown = 95,
238 getpriority = 96,
239 setpriority = 97,
240 profil = 98,
241 statfs = 99,
242 fstatfs = 100,
243 ioperm = 101,
244 socketcall = 102,
245 syslog = 103,
246 setitimer = 104,
247 getitimer = 105,
248 stat = 106,
249 lstat = 107,
250 fstat = 108,
251 olduname = 109,
252 iopl = 110,
253 vhangup = 111,
254 idle = 112,
255 vm86 = 113,
256 wait4 = 114,
257 swapoff = 115,
258 sysinfo = 116,
259 ipc = 117,
260 fsync = 118,
261 sigreturn = 119,
262 clone = 120,
263 setdomainname = 121,
264 uname = 122,
265 modify_ldt = 123,
266 adjtimex = 124,
267 mprotect = 125,
268 sigprocmask = 126,
269 create_module = 127,
270 init_module = 128,
271 delete_module = 129,
272 get_kernel_syms = 130,
273 quotactl = 131,
274 getpgid = 132,
275 fchdir = 133,
276 bdflush = 134,
277 sysfs = 135,
278 personality = 136,
279 afs_syscall = 137,
280 setfsuid = 138,
281 setfsgid = 139,
282 _llseek = 140,
283 getdents = 141,
284 _newselect = 142,
285 flock = 143,
286 msync = 144,
287 readv = 145,
288 writev = 146,
289 getsid = 147,
290 fdatasync = 148,
291 _sysctl = 149,
292 mlock = 150,
293 munlock = 151,
294 mlockall = 152,
295 munlockall = 153,
296 sched_setparam = 154,
297 sched_getparam = 155,
298 sched_setscheduler = 156,
299 sched_getscheduler = 157,
300 sched_yield = 158,
301 sched_get_priority_max = 159,
302 sched_get_priority_min = 160,
303 sched_rr_get_interval = 161,
304 nanosleep = 162,
305 mremap = 163,
306 setresuid = 164,
307 getresuid = 165,
308 query_module = 166,
309 poll = 167,
310 nfsservctl = 168,
311 setresgid = 169,
312 getresgid = 170,
313 prctl = 171,
314 rt_sigreturn = 172,
315 rt_sigaction = 173,
316 rt_sigprocmask = 174,
317 rt_sigpending = 175,
318 rt_sigtimedwait = 176,
319 rt_sigqueueinfo = 177,
320 rt_sigsuspend = 178,
321 pread64 = 179,
322 pwrite64 = 180,
323 chown = 181,
324 getcwd = 182,
325 capget = 183,
326 capset = 184,
327 sigaltstack = 185,
328 sendfile = 186,
329 getpmsg = 187,
330 putpmsg = 188,
331 vfork = 189,
332 ugetrlimit = 190,
333 readahead = 191,
334 mmap2 = 192,
335 truncate64 = 193,
336 ftruncate64 = 194,
337 stat64 = 195,
338 lstat64 = 196,
339 fstat64 = 197,
340 pciconfig_read = 198,
341 pciconfig_write = 199,
342 pciconfig_iobase = 200,
343 multiplexer = 201,
344 getdents64 = 202,
345 pivot_root = 203,
346 fcntl64 = 204,
347 madvise = 205,
348 mincore = 206,
349 gettid = 207,
350 tkill = 208,
351 setxattr = 209,
352 lsetxattr = 210,
353 fsetxattr = 211,
354 getxattr = 212,
355 lgetxattr = 213,
356 fgetxattr = 214,
357 listxattr = 215,
358 llistxattr = 216,
359 flistxattr = 217,
360 removexattr = 218,
361 lremovexattr = 219,
362 fremovexattr = 220,
363 futex = 221,
364 sched_setaffinity = 222,
365 sched_getaffinity = 223,
366 tuxcall = 225,
367 sendfile64 = 226,
368 io_setup = 227,
369 io_destroy = 228,
370 io_getevents = 229,
371 io_submit = 230,
372 io_cancel = 231,
373 set_tid_address = 232,
374 fadvise64 = 233,
375 exit_group = 234,
376 lookup_dcookie = 235,
377 epoll_create = 236,
378 epoll_ctl = 237,
379 epoll_wait = 238,
380 remap_file_pages = 239,
381 timer_create = 240,
382 timer_settime = 241,
383 timer_gettime = 242,
384 timer_getoverrun = 243,
385 timer_delete = 244,
386 clock_settime = 245,
387 clock_gettime = 246,
388 clock_getres = 247,
389 clock_nanosleep = 248,
390 swapcontext = 249,
391 tgkill = 250,
392 utimes = 251,
393 statfs64 = 252,
394 fstatfs64 = 253,
395 fadvise64_64 = 254,
396 rtas = 255,
397 sys_debug_setcontext = 256,
398 migrate_pages = 258,
399 mbind = 259,
400 get_mempolicy = 260,
401 set_mempolicy = 261,
402 mq_open = 262,
403 mq_unlink = 263,
404 mq_timedsend = 264,
405 mq_timedreceive = 265,
406 mq_notify = 266,
407 mq_getsetattr = 267,
408 kexec_load = 268,
409 add_key = 269,
410 request_key = 270,
411 keyctl = 271,
412 waitid = 272,
413 ioprio_set = 273,
414 ioprio_get = 274,
415 inotify_init = 275,
416 inotify_add_watch = 276,
417 inotify_rm_watch = 277,
418 spu_run = 278,
419 spu_create = 279,
420 pselect6 = 280,
421 ppoll = 281,
422 unshare = 282,
423 splice = 283,
424 tee = 284,
425 vmsplice = 285,
426 openat = 286,
427 mkdirat = 287,
428 mknodat = 288,
429 fchownat = 289,
430 futimesat = 290,
431 fstatat64 = 291,
432 unlinkat = 292,
433 renameat = 293,
434 linkat = 294,
435 symlinkat = 295,
436 readlinkat = 296,
437 fchmodat = 297,
438 faccessat = 298,
439 get_robust_list = 299,
440 set_robust_list = 300,
441 move_pages = 301,
442 getcpu = 302,
443 epoll_pwait = 303,
444 utimensat = 304,
445 signalfd = 305,
446 timerfd_create = 306,
447 eventfd = 307,
448 sync_file_range = 308,
449 fallocate = 309,
450 subpage_prot = 310,
451 timerfd_settime = 311,
452 timerfd_gettime = 312,
453 signalfd4 = 313,
454 eventfd2 = 314,
455 epoll_create1 = 315,
456 dup3 = 316,
457 pipe2 = 317,
458 inotify_init1 = 318,
459 perf_event_open = 319,
460 preadv = 320,
461 pwritev = 321,
462 rt_tgsigqueueinfo = 322,
463 fanotify_init = 323,
464 fanotify_mark = 324,
465 prlimit64 = 325,
466 socket = 326,
467 bind = 327,
468 connect = 328,
469 listen = 329,
470 accept = 330,
471 getsockname = 331,
472 getpeername = 332,
473 socketpair = 333,
474 send = 334,
475 sendto = 335,
476 recv = 336,
477 recvfrom = 337,
478 shutdown = 338,
479 setsockopt = 339,
480 getsockopt = 340,
481 sendmsg = 341,
482 recvmsg = 342,
483 recvmmsg = 343,
484 accept4 = 344,
485 name_to_handle_at = 345,
486 open_by_handle_at = 346,
487 clock_adjtime = 347,
488 syncfs = 348,
489 sendmmsg = 349,
490 setns = 350,
491 process_vm_readv = 351,
492 process_vm_writev = 352,
493 finit_module = 353,
494 kcmp = 354,
495 sched_setattr = 355,
496 sched_getattr = 356,
497 renameat2 = 357,
498 seccomp = 358,
499 getrandom = 359,
500 memfd_create = 360,
501 bpf = 361,
502 execveat = 362,
503 switch_endian = 363,
504 userfaultfd = 364,
505 membarrier = 365,
506 mlock2 = 378,
507 copy_file_range = 379,
508 preadv2 = 380,
509 pwritev2 = 381,
510 kexec_file_load = 382,
511 statx = 383,
512 pkey_alloc = 384,
513 pkey_free = 385,
514 pkey_mprotect = 386,
515 rseq = 387,
516 io_pgetevents = 388,
517 semget = 393,
518 semctl = 394,
519 shmget = 395,
520 shmctl = 396,
521 shmat = 397,
522 shmdt = 398,
523 msgget = 399,
524 msgsnd = 400,
525 msgrcv = 401,
526 msgctl = 402,
527 clock_gettime64 = 403,
528 clock_settime64 = 404,
529 clock_adjtime64 = 405,
530 clock_getres_time64 = 406,
531 clock_nanosleep_time64 = 407,
532 timer_gettime64 = 408,
533 timer_settime64 = 409,
534 timerfd_gettime64 = 410,
535 timerfd_settime64 = 411,
536 utimensat_time64 = 412,
537 pselect6_time64 = 413,
538 ppoll_time64 = 414,
539 io_pgetevents_time64 = 416,
540 recvmmsg_time64 = 417,
541 mq_timedsend_time64 = 418,
542 mq_timedreceive_time64 = 419,
543 semtimedop_time64 = 420,
544 rt_sigtimedwait_time64 = 421,
545 futex_time64 = 422,
546 sched_rr_get_interval_time64 = 423,
547 pidfd_send_signal = 424,
548 io_uring_setup = 425,
549 io_uring_enter = 426,
550 io_uring_register = 427,
551 open_tree = 428,
552 move_mount = 429,
553 fsopen = 430,
554 fsconfig = 431,
555 fsmount = 432,
556 fspick = 433,
557 pidfd_open = 434,
558 clone3 = 435,
559 close_range = 436,
560 openat2 = 437,
561 pidfd_getfd = 438,
562 faccessat2 = 439,
563 process_madvise = 440,
564};
565
566pub const O = struct {
567 pub const CREAT = 0o100;
568 pub const EXCL = 0o200;
569 pub const NOCTTY = 0o400;
570 pub const TRUNC = 0o1000;
571 pub const APPEND = 0o2000;
572 pub const NONBLOCK = 0o4000;
573 pub const DSYNC = 0o10000;
574 pub const SYNC = 0o4010000;
575 pub const RSYNC = 0o4010000;
576 pub const DIRECTORY = 0o40000;
577 pub const NOFOLLOW = 0o100000;
578 pub const CLOEXEC = 0o2000000;
579
580 pub const ASYNC = 0o20000;
581 pub const DIRECT = 0o400000;
582 pub const LARGEFILE = 0o200000;
583 pub const NOATIME = 0o1000000;
584 pub const PATH = 0o10000000;
585 pub const TMPFILE = 0o20040000;
586 pub const NDELAY = NONBLOCK;
587};
588
589pub const F = struct {
590 pub const DUPFD = 0;
591 pub const GETFD = 1;
592 pub const SETFD = 2;
593 pub const GETFL = 3;
594 pub const SETFL = 4;
595
596 pub const SETOWN = 8;
597 pub const GETOWN = 9;
598 pub const SETSIG = 10;
599 pub const GETSIG = 11;
600
601 pub const GETLK = 12;
602 pub const SETLK = 13;
603 pub const SETLKW = 14;
604
605 pub const SETOWN_EX = 15;
606 pub const GETOWN_EX = 16;
607
608 pub const GETOWNER_UIDS = 17;
609
610 pub const RDLCK = 0;
611 pub const WRLCK = 1;
612 pub const UNLCK = 2;
613};
614
615pub const LOCK = struct {
616 pub const SH = 1;
617 pub const EX = 2;
618 pub const UN = 8;
619 pub const NB = 4;
620};
621
622pub const MAP = struct {
623 /// stack-like segment
624 pub const GROWSDOWN = 0x0100;
625 /// ETXTBSY
626 pub const DENYWRITE = 0x0800;
627 /// mark it as an executable
628 pub const EXECUTABLE = 0x1000;
629 /// pages are locked
630 pub const LOCKED = 0x0080;
631 /// don't check for reservations
632 pub const NORESERVE = 0x0040;
633};
634
635pub const VDSO = struct {
636 pub const CGT_SYM = "__kernel_clock_gettime";
637 pub const CGT_VER = "LINUX_2.6.15";
638};
639
640pub const Flock = extern struct {
641 l_type: i16,
642 l_whence: i16,
643 l_start: off_t,
644 l_len: off_t,
645 l_pid: pid_t,
646};
647
648pub const msghdr = extern struct {
649 msg_name: ?*sockaddr,
650 msg_namelen: socklen_t,
651 msg_iov: [*]iovec,
652 msg_iovlen: usize,
653 msg_control: ?*c_void,
654 msg_controllen: socklen_t,
655 msg_flags: i32,
656};
657
658pub const msghdr_const = extern struct {
659 msg_name: ?*const sockaddr,
660 msg_namelen: socklen_t,
661 msg_iov: [*]iovec_const,
662 msg_iovlen: usize,
663 msg_control: ?*c_void,
664 msg_controllen: socklen_t,
665 msg_flags: i32,
666};
667
668pub const blksize_t = i32;
669pub const nlink_t = u32;
670pub const time_t = isize;
671pub const mode_t = u32;
672pub const off_t = i64;
673pub const ino_t = u64;
674pub const dev_t = u64;
675pub const blkcnt_t = i64;
676
677// The `stat` definition used by the Linux kernel.
678pub const Stat = extern struct {
679 dev: dev_t,
680 ino: ino_t,
681 mode: mode_t,
682 nlink: nlink_t,
683 uid: uid_t,
684 gid: gid_t,
685 rdev: dev_t,
686 __rdev_padding: i16,
687 size: off_t,
688 blksize: blksize_t,
689 blocks: blkcnt_t,
690 atim: timespec,
691 mtim: timespec,
692 ctim: timespec,
693 __unused: [2]u32,
694
695 pub fn atime(self: @This()) timespec {
696 return self.atim;
697 }
698
699 pub fn mtime(self: @This()) timespec {
700 return self.mtim;
701 }
702
703 pub fn ctime(self: @This()) timespec {
704 return self.ctim;
705 }
706};
707
708pub const timeval = extern struct {
709 tv_sec: time_t,
710 tv_usec: isize,
711};
712
713pub const timezone = extern struct {
714 tz_minuteswest: i32,
715 tz_dsttime: i32,
716};
717
718pub const greg_t = u32;
719pub const gregset_t = [48]greg_t;
720pub const fpregset_t = [33]f64;
721
722pub const vrregset = extern struct {
723 vrregs: [32][4]u32,
724 vrsave: u32,
725 _pad: [2]u32,
726 vscr: u32,
727};
728pub const vrregset_t = vrregset;
729
730pub const mcontext_t = extern struct {
731 gp_regs: gregset_t,
732 fp_regs: fpregset_t,
733 v_regs: vrregset_t align(16),
734};
735
736pub const ucontext_t = extern struct {
737 flags: u32,
738 link: *ucontext_t,
739 stack: stack_t,
740 pad: [7]i32,
741 regs: *mcontext_t,
742 sigmask: sigset_t,
743 pad2: [3]i32,
744 mcontext: mcontext_t,
745};
746
747pub const Elf_Symndx = u32;
748
749pub const MMAP2_UNIT = 4096;
lib/std/os/linux/powerpc64.zig+606-1
...@@ -1,4 +1,16 @@...@@ -1,4 +1,16 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const socklen_t = linux.socklen_t;
5const iovec = linux.iovec;
6const iovec_const = linux.iovec_const;
7const uid_t = linux.uid_t;
8const gid_t = linux.gid_t;
9const pid_t = linux.pid_t;
10const stack_t = linux.stack_t;
11const sigset_t = linux.sigset_t;
12const sockaddr = linux.sockaddr;
13const timespec = linux.timespec;
214
3pub fn syscall0(number: SYS) usize {15pub fn syscall0(number: SYS) usize {
4 return asm volatile (16 return asm volatile (
...@@ -125,3 +137,596 @@ pub fn restore_rt() callconv(.Naked) void {...@@ -125,3 +137,596 @@ pub fn restore_rt() callconv(.Naked) void {
125 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"137 : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
126 );138 );
127}139}
140
141pub const SYS = enum(usize) {
142 restart_syscall = 0,
143 exit = 1,
144 fork = 2,
145 read = 3,
146 write = 4,
147 open = 5,
148 close = 6,
149 waitpid = 7,
150 creat = 8,
151 link = 9,
152 unlink = 10,
153 execve = 11,
154 chdir = 12,
155 time = 13,
156 mknod = 14,
157 chmod = 15,
158 lchown = 16,
159 @"break" = 17,
160 oldstat = 18,
161 lseek = 19,
162 getpid = 20,
163 mount = 21,
164 umount = 22,
165 setuid = 23,
166 getuid = 24,
167 stime = 25,
168 ptrace = 26,
169 alarm = 27,
170 oldfstat = 28,
171 pause = 29,
172 utime = 30,
173 stty = 31,
174 gtty = 32,
175 access = 33,
176 nice = 34,
177 ftime = 35,
178 sync = 36,
179 kill = 37,
180 rename = 38,
181 mkdir = 39,
182 rmdir = 40,
183 dup = 41,
184 pipe = 42,
185 times = 43,
186 prof = 44,
187 brk = 45,
188 setgid = 46,
189 getgid = 47,
190 signal = 48,
191 geteuid = 49,
192 getegid = 50,
193 acct = 51,
194 umount2 = 52,
195 lock = 53,
196 ioctl = 54,
197 fcntl = 55,
198 mpx = 56,
199 setpgid = 57,
200 ulimit = 58,
201 oldolduname = 59,
202 umask = 60,
203 chroot = 61,
204 ustat = 62,
205 dup2 = 63,
206 getppid = 64,
207 getpgrp = 65,
208 setsid = 66,
209 sigaction = 67,
210 sgetmask = 68,
211 ssetmask = 69,
212 setreuid = 70,
213 setregid = 71,
214 sigsuspend = 72,
215 sigpending = 73,
216 sethostname = 74,
217 setrlimit = 75,
218 getrlimit = 76,
219 getrusage = 77,
220 gettimeofday = 78,
221 settimeofday = 79,
222 getgroups = 80,
223 setgroups = 81,
224 select = 82,
225 symlink = 83,
226 oldlstat = 84,
227 readlink = 85,
228 uselib = 86,
229 swapon = 87,
230 reboot = 88,
231 readdir = 89,
232 mmap = 90,
233 munmap = 91,
234 truncate = 92,
235 ftruncate = 93,
236 fchmod = 94,
237 fchown = 95,
238 getpriority = 96,
239 setpriority = 97,
240 profil = 98,
241 statfs = 99,
242 fstatfs = 100,
243 ioperm = 101,
244 socketcall = 102,
245 syslog = 103,
246 setitimer = 104,
247 getitimer = 105,
248 stat = 106,
249 lstat = 107,
250 fstat = 108,
251 olduname = 109,
252 iopl = 110,
253 vhangup = 111,
254 idle = 112,
255 vm86 = 113,
256 wait4 = 114,
257 swapoff = 115,
258 sysinfo = 116,
259 ipc = 117,
260 fsync = 118,
261 sigreturn = 119,
262 clone = 120,
263 setdomainname = 121,
264 uname = 122,
265 modify_ldt = 123,
266 adjtimex = 124,
267 mprotect = 125,
268 sigprocmask = 126,
269 create_module = 127,
270 init_module = 128,
271 delete_module = 129,
272 get_kernel_syms = 130,
273 quotactl = 131,
274 getpgid = 132,
275 fchdir = 133,
276 bdflush = 134,
277 sysfs = 135,
278 personality = 136,
279 afs_syscall = 137,
280 setfsuid = 138,
281 setfsgid = 139,
282 _llseek = 140,
283 getdents = 141,
284 _newselect = 142,
285 flock = 143,
286 msync = 144,
287 readv = 145,
288 writev = 146,
289 getsid = 147,
290 fdatasync = 148,
291 _sysctl = 149,
292 mlock = 150,
293 munlock = 151,
294 mlockall = 152,
295 munlockall = 153,
296 sched_setparam = 154,
297 sched_getparam = 155,
298 sched_setscheduler = 156,
299 sched_getscheduler = 157,
300 sched_yield = 158,
301 sched_get_priority_max = 159,
302 sched_get_priority_min = 160,
303 sched_rr_get_interval = 161,
304 nanosleep = 162,
305 mremap = 163,
306 setresuid = 164,
307 getresuid = 165,
308 query_module = 166,
309 poll = 167,
310 nfsservctl = 168,
311 setresgid = 169,
312 getresgid = 170,
313 prctl = 171,
314 rt_sigreturn = 172,
315 rt_sigaction = 173,
316 rt_sigprocmask = 174,
317 rt_sigpending = 175,
318 rt_sigtimedwait = 176,
319 rt_sigqueueinfo = 177,
320 rt_sigsuspend = 178,
321 pread64 = 179,
322 pwrite64 = 180,
323 chown = 181,
324 getcwd = 182,
325 capget = 183,
326 capset = 184,
327 sigaltstack = 185,
328 sendfile = 186,
329 getpmsg = 187,
330 putpmsg = 188,
331 vfork = 189,
332 ugetrlimit = 190,
333 readahead = 191,
334 pciconfig_read = 198,
335 pciconfig_write = 199,
336 pciconfig_iobase = 200,
337 multiplexer = 201,
338 getdents64 = 202,
339 pivot_root = 203,
340 madvise = 205,
341 mincore = 206,
342 gettid = 207,
343 tkill = 208,
344 setxattr = 209,
345 lsetxattr = 210,
346 fsetxattr = 211,
347 getxattr = 212,
348 lgetxattr = 213,
349 fgetxattr = 214,
350 listxattr = 215,
351 llistxattr = 216,
352 flistxattr = 217,
353 removexattr = 218,
354 lremovexattr = 219,
355 fremovexattr = 220,
356 futex = 221,
357 sched_setaffinity = 222,
358 sched_getaffinity = 223,
359 tuxcall = 225,
360 io_setup = 227,
361 io_destroy = 228,
362 io_getevents = 229,
363 io_submit = 230,
364 io_cancel = 231,
365 set_tid_address = 232,
366 fadvise64 = 233,
367 exit_group = 234,
368 lookup_dcookie = 235,
369 epoll_create = 236,
370 epoll_ctl = 237,
371 epoll_wait = 238,
372 remap_file_pages = 239,
373 timer_create = 240,
374 timer_settime = 241,
375 timer_gettime = 242,
376 timer_getoverrun = 243,
377 timer_delete = 244,
378 clock_settime = 245,
379 clock_gettime = 246,
380 clock_getres = 247,
381 clock_nanosleep = 248,
382 swapcontext = 249,
383 tgkill = 250,
384 utimes = 251,
385 statfs64 = 252,
386 fstatfs64 = 253,
387 rtas = 255,
388 sys_debug_setcontext = 256,
389 migrate_pages = 258,
390 mbind = 259,
391 get_mempolicy = 260,
392 set_mempolicy = 261,
393 mq_open = 262,
394 mq_unlink = 263,
395 mq_timedsend = 264,
396 mq_timedreceive = 265,
397 mq_notify = 266,
398 mq_getsetattr = 267,
399 kexec_load = 268,
400 add_key = 269,
401 request_key = 270,
402 keyctl = 271,
403 waitid = 272,
404 ioprio_set = 273,
405 ioprio_get = 274,
406 inotify_init = 275,
407 inotify_add_watch = 276,
408 inotify_rm_watch = 277,
409 spu_run = 278,
410 spu_create = 279,
411 pselect6 = 280,
412 ppoll = 281,
413 unshare = 282,
414 splice = 283,
415 tee = 284,
416 vmsplice = 285,
417 openat = 286,
418 mkdirat = 287,
419 mknodat = 288,
420 fchownat = 289,
421 futimesat = 290,
422 fstatat = 291,
423 unlinkat = 292,
424 renameat = 293,
425 linkat = 294,
426 symlinkat = 295,
427 readlinkat = 296,
428 fchmodat = 297,
429 faccessat = 298,
430 get_robust_list = 299,
431 set_robust_list = 300,
432 move_pages = 301,
433 getcpu = 302,
434 epoll_pwait = 303,
435 utimensat = 304,
436 signalfd = 305,
437 timerfd_create = 306,
438 eventfd = 307,
439 sync_file_range = 308,
440 fallocate = 309,
441 subpage_prot = 310,
442 timerfd_settime = 311,
443 timerfd_gettime = 312,
444 signalfd4 = 313,
445 eventfd2 = 314,
446 epoll_create1 = 315,
447 dup3 = 316,
448 pipe2 = 317,
449 inotify_init1 = 318,
450 perf_event_open = 319,
451 preadv = 320,
452 pwritev = 321,
453 rt_tgsigqueueinfo = 322,
454 fanotify_init = 323,
455 fanotify_mark = 324,
456 prlimit64 = 325,
457 socket = 326,
458 bind = 327,
459 connect = 328,
460 listen = 329,
461 accept = 330,
462 getsockname = 331,
463 getpeername = 332,
464 socketpair = 333,
465 send = 334,
466 sendto = 335,
467 recv = 336,
468 recvfrom = 337,
469 shutdown = 338,
470 setsockopt = 339,
471 getsockopt = 340,
472 sendmsg = 341,
473 recvmsg = 342,
474 recvmmsg = 343,
475 accept4 = 344,
476 name_to_handle_at = 345,
477 open_by_handle_at = 346,
478 clock_adjtime = 347,
479 syncfs = 348,
480 sendmmsg = 349,
481 setns = 350,
482 process_vm_readv = 351,
483 process_vm_writev = 352,
484 finit_module = 353,
485 kcmp = 354,
486 sched_setattr = 355,
487 sched_getattr = 356,
488 renameat2 = 357,
489 seccomp = 358,
490 getrandom = 359,
491 memfd_create = 360,
492 bpf = 361,
493 execveat = 362,
494 switch_endian = 363,
495 userfaultfd = 364,
496 membarrier = 365,
497 mlock2 = 378,
498 copy_file_range = 379,
499 preadv2 = 380,
500 pwritev2 = 381,
501 kexec_file_load = 382,
502 statx = 383,
503 pkey_alloc = 384,
504 pkey_free = 385,
505 pkey_mprotect = 386,
506 rseq = 387,
507 io_pgetevents = 388,
508 semtimedop = 392,
509 semget = 393,
510 semctl = 394,
511 shmget = 395,
512 shmctl = 396,
513 shmat = 397,
514 shmdt = 398,
515 msgget = 399,
516 msgsnd = 400,
517 msgrcv = 401,
518 msgctl = 402,
519 pidfd_send_signal = 424,
520 io_uring_setup = 425,
521 io_uring_enter = 426,
522 io_uring_register = 427,
523 open_tree = 428,
524 move_mount = 429,
525 fsopen = 430,
526 fsconfig = 431,
527 fsmount = 432,
528 fspick = 433,
529 pidfd_open = 434,
530 clone3 = 435,
531 close_range = 436,
532 openat2 = 437,
533 pidfd_getfd = 438,
534 faccessat2 = 439,
535 process_madvise = 440,
536 epoll_pwait2 = 441,
537
538 _,
539};
540
541pub const O = struct {
542 pub const CREAT = 0o100;
543 pub const EXCL = 0o200;
544 pub const NOCTTY = 0o400;
545 pub const TRUNC = 0o1000;
546 pub const APPEND = 0o2000;
547 pub const NONBLOCK = 0o4000;
548 pub const DSYNC = 0o10000;
549 pub const SYNC = 0o4010000;
550 pub const RSYNC = 0o4010000;
551 pub const DIRECTORY = 0o40000;
552 pub const NOFOLLOW = 0o100000;
553 pub const CLOEXEC = 0o2000000;
554
555 pub const ASYNC = 0o20000;
556 pub const DIRECT = 0o400000;
557 pub const LARGEFILE = 0o200000;
558 pub const NOATIME = 0o1000000;
559 pub const PATH = 0o10000000;
560 pub const TMPFILE = 0o20200000;
561 pub const NDELAY = NONBLOCK;
562};
563
564pub const F = struct {
565 pub const DUPFD = 0;
566 pub const GETFD = 1;
567 pub const SETFD = 2;
568 pub const GETFL = 3;
569 pub const SETFL = 4;
570
571 pub const SETOWN = 8;
572 pub const GETOWN = 9;
573 pub const SETSIG = 10;
574 pub const GETSIG = 11;
575
576 pub const GETLK = 5;
577 pub const SETLK = 6;
578 pub const SETLKW = 7;
579
580 pub const RDLCK = 0;
581 pub const WRLCK = 1;
582 pub const UNLCK = 2;
583
584 pub const SETOWN_EX = 15;
585 pub const GETOWN_EX = 16;
586
587 pub const GETOWNER_UIDS = 17;
588};
589
590pub const LOCK = struct {
591 pub const SH = 1;
592 pub const EX = 2;
593 pub const UN = 8;
594 pub const NB = 4;
595};
596
597pub const MAP = struct {
598 /// stack-like segment
599 pub const GROWSDOWN = 0x0100;
600 /// ETXTBSY
601 pub const DENYWRITE = 0x0800;
602 /// mark it as an executable
603 pub const EXECUTABLE = 0x1000;
604 /// pages are locked
605 pub const LOCKED = 0x0080;
606 /// don't check for reservations
607 pub const NORESERVE = 0x0040;
608};
609
610pub const VDSO = struct {
611 pub const CGT_SYM = "__kernel_clock_gettime";
612 pub const CGT_VER = "LINUX_2.6.15";
613};
614
615pub const Flock = extern struct {
616 l_type: i16,
617 l_whence: i16,
618 l_start: off_t,
619 l_len: off_t,
620 l_pid: pid_t,
621 __unused: [4]u8,
622};
623
624pub const msghdr = extern struct {
625 msg_name: ?*sockaddr,
626 msg_namelen: socklen_t,
627 msg_iov: [*]iovec,
628 msg_iovlen: usize,
629 msg_control: ?*c_void,
630 msg_controllen: usize,
631 msg_flags: i32,
632};
633
634pub const msghdr_const = extern struct {
635 msg_name: ?*const sockaddr,
636 msg_namelen: socklen_t,
637 msg_iov: [*]iovec_const,
638 msg_iovlen: usize,
639 msg_control: ?*c_void,
640 msg_controllen: usize,
641 msg_flags: i32,
642};
643
644pub const blksize_t = i64;
645pub const nlink_t = u64;
646pub const time_t = i64;
647pub const mode_t = u32;
648pub const off_t = i64;
649pub const ino_t = u64;
650pub const dev_t = u64;
651pub const blkcnt_t = i64;
652
653// The `stat` definition used by the Linux kernel.
654pub const Stat = extern struct {
655 dev: dev_t,
656 ino: ino_t,
657 nlink: nlink_t,
658 mode: mode_t,
659 uid: uid_t,
660 gid: gid_t,
661 rdev: dev_t,
662 size: off_t,
663 blksize: blksize_t,
664 blocks: blkcnt_t,
665 atim: timespec,
666 mtim: timespec,
667 ctim: timespec,
668 __unused: [3]u64,
669
670 pub fn atime(self: @This()) timespec {
671 return self.atim;
672 }
673
674 pub fn mtime(self: @This()) timespec {
675 return self.mtim;
676 }
677
678 pub fn ctime(self: @This()) timespec {
679 return self.ctim;
680 }
681};
682
683pub const timeval = extern struct {
684 tv_sec: isize,
685 tv_usec: isize,
686};
687
688pub const timezone = extern struct {
689 tz_minuteswest: i32,
690 tz_dsttime: i32,
691};
692
693pub const greg_t = u64;
694pub const gregset_t = [48]greg_t;
695pub const fpregset_t = [33]f64;
696
697/// The position of the vscr register depends on endianness.
698/// On C, macros are used to change vscr_word's offset to
699/// account for this. Here we'll just define vscr_word_le
700/// and vscr_word_be. Code must take care to use the correct one.
701pub const vrregset = extern struct {
702 vrregs: [32][4]u32 align(16),
703 vscr_word_le: u32,
704 _pad1: [2]u32,
705 vscr_word_be: u32,
706 vrsave: u32,
707 _pad2: [3]u32,
708};
709pub const vrregset_t = vrregset;
710
711pub const mcontext_t = extern struct {
712 __unused: [4]u64,
713 signal: i32,
714 _pad0: i32,
715 handler: u64,
716 oldmask: u64,
717 regs: ?*c_void,
718 gp_regs: gregset_t,
719 fp_regs: fpregset_t,
720 v_regs: *vrregset_t,
721 vmx_reserve: [34 + 34 + 32 + 1]i64,
722};
723
724pub const ucontext_t = extern struct {
725 flags: u32,
726 link: *ucontext_t,
727 stack: stack_t,
728 sigmask: sigset_t,
729 mcontext: mcontext_t,
730};
731
732pub const Elf_Symndx = u32;
lib/std/os/linux/riscv64.zig+425-1
...@@ -1,4 +1,8 @@...@@ -1,4 +1,8 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const uid_t = std.os.linux.uid_t;
3const gid_t = std.os.linux.gid_t;
4const pid_t = std.os.linux.pid_t;
5const timespec = std.os.linux.timespec;
26
3pub fn syscall0(number: SYS) usize {7pub fn syscall0(number: SYS) usize {
4 return asm volatile ("ecall"8 return asm volatile ("ecall"
...@@ -96,3 +100,423 @@ pub fn restore_rt() callconv(.Naked) void {...@@ -96,3 +100,423 @@ pub fn restore_rt() callconv(.Naked) void {
96 : "memory"100 : "memory"
97 );101 );
98}102}
103
104pub const SYS = enum(usize) {
105 pub const arch_specific_syscall = 244;
106
107 io_setup = 0,
108 io_destroy = 1,
109 io_submit = 2,
110 io_cancel = 3,
111 io_getevents = 4,
112 setxattr = 5,
113 lsetxattr = 6,
114 fsetxattr = 7,
115 getxattr = 8,
116 lgetxattr = 9,
117 fgetxattr = 10,
118 listxattr = 11,
119 llistxattr = 12,
120 flistxattr = 13,
121 removexattr = 14,
122 lremovexattr = 15,
123 fremovexattr = 16,
124 getcwd = 17,
125 lookup_dcookie = 18,
126 eventfd2 = 19,
127 epoll_create1 = 20,
128 epoll_ctl = 21,
129 epoll_pwait = 22,
130 dup = 23,
131 dup3 = 24,
132 fcntl = 25,
133 inotify_init1 = 26,
134 inotify_add_watch = 27,
135 inotify_rm_watch = 28,
136 ioctl = 29,
137 ioprio_set = 30,
138 ioprio_get = 31,
139 flock = 32,
140 mknodat = 33,
141 mkdirat = 34,
142 unlinkat = 35,
143 symlinkat = 36,
144 linkat = 37,
145 umount2 = 39,
146 mount = 40,
147 pivot_root = 41,
148 nfsservctl = 42,
149 statfs = 43,
150 fstatfs = 44,
151 truncate = 45,
152 ftruncate = 46,
153 fallocate = 47,
154 faccessat = 48,
155 chdir = 49,
156 fchdir = 50,
157 chroot = 51,
158 fchmod = 52,
159 fchmodat = 53,
160 fchownat = 54,
161 fchown = 55,
162 openat = 56,
163 close = 57,
164 vhangup = 58,
165 pipe2 = 59,
166 quotactl = 60,
167 getdents64 = 61,
168 lseek = 62,
169 read = 63,
170 write = 64,
171 readv = 65,
172 writev = 66,
173 pread64 = 67,
174 pwrite64 = 68,
175 preadv = 69,
176 pwritev = 70,
177 sendfile = 71,
178 pselect6 = 72,
179 ppoll = 73,
180 signalfd4 = 74,
181 vmsplice = 75,
182 splice = 76,
183 tee = 77,
184 readlinkat = 78,
185 fstatat = 79,
186 fstat = 80,
187 sync = 81,
188 fsync = 82,
189 fdatasync = 83,
190 sync_file_range = 84,
191 timerfd_create = 85,
192 timerfd_settime = 86,
193 timerfd_gettime = 87,
194 utimensat = 88,
195 acct = 89,
196 capget = 90,
197 capset = 91,
198 personality = 92,
199 exit = 93,
200 exit_group = 94,
201 waitid = 95,
202 set_tid_address = 96,
203 unshare = 97,
204 futex = 98,
205 set_robust_list = 99,
206 get_robust_list = 100,
207 nanosleep = 101,
208 getitimer = 102,
209 setitimer = 103,
210 kexec_load = 104,
211 init_module = 105,
212 delete_module = 106,
213 timer_create = 107,
214 timer_gettime = 108,
215 timer_getoverrun = 109,
216 timer_settime = 110,
217 timer_delete = 111,
218 clock_settime = 112,
219 clock_gettime = 113,
220 clock_getres = 114,
221 clock_nanosleep = 115,
222 syslog = 116,
223 ptrace = 117,
224 sched_setparam = 118,
225 sched_setscheduler = 119,
226 sched_getscheduler = 120,
227 sched_getparam = 121,
228 sched_setaffinity = 122,
229 sched_getaffinity = 123,
230 sched_yield = 124,
231 sched_get_priority_max = 125,
232 sched_get_priority_min = 126,
233 sched_rr_get_interval = 127,
234 restart_syscall = 128,
235 kill = 129,
236 tkill = 130,
237 tgkill = 131,
238 sigaltstack = 132,
239 rt_sigsuspend = 133,
240 rt_sigaction = 134,
241 rt_sigprocmask = 135,
242 rt_sigpending = 136,
243 rt_sigtimedwait = 137,
244 rt_sigqueueinfo = 138,
245 rt_sigreturn = 139,
246 setpriority = 140,
247 getpriority = 141,
248 reboot = 142,
249 setregid = 143,
250 setgid = 144,
251 setreuid = 145,
252 setuid = 146,
253 setresuid = 147,
254 getresuid = 148,
255 setresgid = 149,
256 getresgid = 150,
257 setfsuid = 151,
258 setfsgid = 152,
259 times = 153,
260 setpgid = 154,
261 getpgid = 155,
262 getsid = 156,
263 setsid = 157,
264 getgroups = 158,
265 setgroups = 159,
266 uname = 160,
267 sethostname = 161,
268 setdomainname = 162,
269 getrlimit = 163,
270 setrlimit = 164,
271 getrusage = 165,
272 umask = 166,
273 prctl = 167,
274 getcpu = 168,
275 gettimeofday = 169,
276 settimeofday = 170,
277 adjtimex = 171,
278 getpid = 172,
279 getppid = 173,
280 getuid = 174,
281 geteuid = 175,
282 getgid = 176,
283 getegid = 177,
284 gettid = 178,
285 sysinfo = 179,
286 mq_open = 180,
287 mq_unlink = 181,
288 mq_timedsend = 182,
289 mq_timedreceive = 183,
290 mq_notify = 184,
291 mq_getsetattr = 185,
292 msgget = 186,
293 msgctl = 187,
294 msgrcv = 188,
295 msgsnd = 189,
296 semget = 190,
297 semctl = 191,
298 semtimedop = 192,
299 semop = 193,
300 shmget = 194,
301 shmctl = 195,
302 shmat = 196,
303 shmdt = 197,
304 socket = 198,
305 socketpair = 199,
306 bind = 200,
307 listen = 201,
308 accept = 202,
309 connect = 203,
310 getsockname = 204,
311 getpeername = 205,
312 sendto = 206,
313 recvfrom = 207,
314 setsockopt = 208,
315 getsockopt = 209,
316 shutdown = 210,
317 sendmsg = 211,
318 recvmsg = 212,
319 readahead = 213,
320 brk = 214,
321 munmap = 215,
322 mremap = 216,
323 add_key = 217,
324 request_key = 218,
325 keyctl = 219,
326 clone = 220,
327 execve = 221,
328 mmap = 222,
329 fadvise64 = 223,
330 swapon = 224,
331 swapoff = 225,
332 mprotect = 226,
333 msync = 227,
334 mlock = 228,
335 munlock = 229,
336 mlockall = 230,
337 munlockall = 231,
338 mincore = 232,
339 madvise = 233,
340 remap_file_pages = 234,
341 mbind = 235,
342 get_mempolicy = 236,
343 set_mempolicy = 237,
344 migrate_pages = 238,
345 move_pages = 239,
346 rt_tgsigqueueinfo = 240,
347 perf_event_open = 241,
348 accept4 = 242,
349 recvmmsg = 243,
350
351 riscv_flush_icache = arch_specific_syscall + 15,
352
353 wait4 = 260,
354 prlimit64 = 261,
355 fanotify_init = 262,
356 fanotify_mark = 263,
357 name_to_handle_at = 264,
358 open_by_handle_at = 265,
359 clock_adjtime = 266,
360 syncfs = 267,
361 setns = 268,
362 sendmmsg = 269,
363 process_vm_readv = 270,
364 process_vm_writev = 271,
365 kcmp = 272,
366 finit_module = 273,
367 sched_setattr = 274,
368 sched_getattr = 275,
369 renameat2 = 276,
370 seccomp = 277,
371 getrandom = 278,
372 memfd_create = 279,
373 bpf = 280,
374 execveat = 281,
375 userfaultfd = 282,
376 membarrier = 283,
377 mlock2 = 284,
378 copy_file_range = 285,
379 preadv2 = 286,
380 pwritev2 = 287,
381 pkey_mprotect = 288,
382 pkey_alloc = 289,
383 pkey_free = 290,
384 statx = 291,
385 io_pgetevents = 292,
386 rseq = 293,
387 kexec_file_load = 294,
388 pidfd_send_signal = 424,
389 io_uring_setup = 425,
390 io_uring_enter = 426,
391 io_uring_register = 427,
392 open_tree = 428,
393 move_mount = 429,
394 fsopen = 430,
395 fsconfig = 431,
396 fsmount = 432,
397 fspick = 433,
398 pidfd_open = 434,
399 clone3 = 435,
400 close_range = 436,
401 openat2 = 437,
402 pidfd_getfd = 438,
403 faccessat2 = 439,
404 process_madvise = 440,
405 epoll_pwait2 = 441,
406
407 _,
408};
409
410pub const O = struct {
411 pub const CREAT = 0o100;
412 pub const EXCL = 0o200;
413 pub const NOCTTY = 0o400;
414 pub const TRUNC = 0o1000;
415 pub const APPEND = 0o2000;
416 pub const NONBLOCK = 0o4000;
417 pub const DSYNC = 0o10000;
418 pub const SYNC = 0o4010000;
419 pub const RSYNC = 0o4010000;
420 pub const DIRECTORY = 0o200000;
421 pub const NOFOLLOW = 0o400000;
422 pub const CLOEXEC = 0o2000000;
423
424 pub const ASYNC = 0o20000;
425 pub const DIRECT = 0o40000;
426 pub const LARGEFILE = 0o100000;
427 pub const NOATIME = 0o1000000;
428 pub const PATH = 0o10000000;
429 pub const TMPFILE = 0o20200000;
430 pub const NDELAY = NONBLOCK;
431};
432
433pub const F = struct {
434 pub const DUPFD = 0;
435 pub const GETFD = 1;
436 pub const SETFD = 2;
437 pub const GETFL = 3;
438 pub const SETFL = 4;
439 pub const GETLK = 5;
440 pub const SETLK = 6;
441 pub const SETLKW = 7;
442 pub const SETOWN = 8;
443 pub const GETOWN = 9;
444 pub const SETSIG = 10;
445 pub const GETSIG = 11;
446
447 pub const RDLCK = 0;
448 pub const WRLCK = 1;
449 pub const UNLCK = 2;
450
451 pub const SETOWN_EX = 15;
452 pub const GETOWN_EX = 16;
453
454 pub const GETOWNER_UIDS = 17;
455};
456
457pub const LOCK = struct {
458 pub const SH = 1;
459 pub const EX = 2;
460 pub const UN = 8;
461 pub const NB = 4;
462};
463
464pub const blksize_t = i32;
465pub const nlink_t = u32;
466pub const time_t = isize;
467pub const mode_t = u32;
468pub const off_t = isize;
469pub const ino_t = usize;
470pub const dev_t = usize;
471pub const blkcnt_t = isize;
472
473pub const timeval = extern struct {
474 tv_sec: time_t,
475 tv_usec: i64,
476};
477
478pub const Flock = extern struct {
479 l_type: i16,
480 l_whence: i16,
481 l_start: off_t,
482 l_len: off_t,
483 l_pid: pid_t,
484 __unused: [4]u8,
485};
486
487// The `stat` definition used by the Linux kernel.
488pub const Stat = extern struct {
489 dev: dev_t,
490 ino: ino_t,
491 mode: mode_t,
492 nlink: nlink_t,
493 uid: uid_t,
494 gid: gid_t,
495 rdev: dev_t,
496 __pad: usize,
497 size: off_t,
498 blksize: blksize_t,
499 __pad2: i32,
500 blocks: blkcnt_t,
501 atim: timespec,
502 mtim: timespec,
503 ctim: timespec,
504 __unused: [2]u32,
505
506 pub fn atime(self: @This()) timespec {
507 return self.atim;
508 }
509
510 pub fn mtime(self: @This()) timespec {
511 return self.mtim;
512 }
513
514 pub fn ctime(self: @This()) timespec {
515 return self.ctim;
516 }
517};
518
519pub const Elf_Symndx = u32;
520
521pub const VDSO = struct {};
522pub const MAP = struct {};
lib/std/os/linux/sparc64.zig+643-1
...@@ -1,4 +1,17 @@...@@ -1,4 +1,17 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const pid_t = linux.pid_t;
4const uid_t = linux.uid_t;
5const clock_t = linux.clock_t;
6const stack_t = linux.stack_t;
7const sigset_t = linux.sigset_t;
8
9const linux = std.os.linux;
10const sockaddr = linux.sockaddr;
11const socklen_t = linux.socklen_t;
12const iovec = linux.iovec;
13const iovec_const = linux.iovec_const;
14const timespec = linux.timespec;
215
3pub fn syscall_pipe(fd: *[2]i32) usize {16pub fn syscall_pipe(fd: *[2]i32) usize {
4 return asm volatile (17 return asm volatile (
...@@ -178,3 +191,632 @@ pub fn restore_rt() callconv(.C) void {...@@ -178,3 +191,632 @@ pub fn restore_rt() callconv(.C) void {
178 : "memory", "xcc", "o0", "o1", "o2", "o3", "o4", "o5", "o7"191 : "memory", "xcc", "o0", "o1", "o2", "o3", "o4", "o5", "o7"
179 );192 );
180}193}
194
195pub const SYS = enum(usize) {
196 restart_syscall = 0,
197 exit = 1,
198 fork = 2,
199 read = 3,
200 write = 4,
201 open = 5,
202 close = 6,
203 wait4 = 7,
204 creat = 8,
205 link = 9,
206 unlink = 10,
207 execv = 11,
208 chdir = 12,
209 chown = 13,
210 mknod = 14,
211 chmod = 15,
212 lchown = 16,
213 brk = 17,
214 perfctr = 18,
215 lseek = 19,
216 getpid = 20,
217 capget = 21,
218 capset = 22,
219 setuid = 23,
220 getuid = 24,
221 vmsplice = 25,
222 ptrace = 26,
223 alarm = 27,
224 sigaltstack = 28,
225 pause = 29,
226 utime = 30,
227 access = 33,
228 nice = 34,
229 sync = 36,
230 kill = 37,
231 stat = 38,
232 sendfile = 39,
233 lstat = 40,
234 dup = 41,
235 pipe = 42,
236 times = 43,
237 umount2 = 45,
238 setgid = 46,
239 getgid = 47,
240 signal = 48,
241 geteuid = 49,
242 getegid = 50,
243 acct = 51,
244 memory_ordering = 52,
245 ioctl = 54,
246 reboot = 55,
247 symlink = 57,
248 readlink = 58,
249 execve = 59,
250 umask = 60,
251 chroot = 61,
252 fstat = 62,
253 fstat64 = 63,
254 getpagesize = 64,
255 msync = 65,
256 vfork = 66,
257 pread64 = 67,
258 pwrite64 = 68,
259 mmap = 71,
260 munmap = 73,
261 mprotect = 74,
262 madvise = 75,
263 vhangup = 76,
264 mincore = 78,
265 getgroups = 79,
266 setgroups = 80,
267 getpgrp = 81,
268 setitimer = 83,
269 swapon = 85,
270 getitimer = 86,
271 sethostname = 88,
272 dup2 = 90,
273 fcntl = 92,
274 select = 93,
275 fsync = 95,
276 setpriority = 96,
277 socket = 97,
278 connect = 98,
279 accept = 99,
280 getpriority = 100,
281 rt_sigreturn = 101,
282 rt_sigaction = 102,
283 rt_sigprocmask = 103,
284 rt_sigpending = 104,
285 rt_sigtimedwait = 105,
286 rt_sigqueueinfo = 106,
287 rt_sigsuspend = 107,
288 setresuid = 108,
289 getresuid = 109,
290 setresgid = 110,
291 getresgid = 111,
292 recvmsg = 113,
293 sendmsg = 114,
294 gettimeofday = 116,
295 getrusage = 117,
296 getsockopt = 118,
297 getcwd = 119,
298 readv = 120,
299 writev = 121,
300 settimeofday = 122,
301 fchown = 123,
302 fchmod = 124,
303 recvfrom = 125,
304 setreuid = 126,
305 setregid = 127,
306 rename = 128,
307 truncate = 129,
308 ftruncate = 130,
309 flock = 131,
310 lstat64 = 132,
311 sendto = 133,
312 shutdown = 134,
313 socketpair = 135,
314 mkdir = 136,
315 rmdir = 137,
316 utimes = 138,
317 stat64 = 139,
318 sendfile64 = 140,
319 getpeername = 141,
320 futex = 142,
321 gettid = 143,
322 getrlimit = 144,
323 setrlimit = 145,
324 pivot_root = 146,
325 prctl = 147,
326 pciconfig_read = 148,
327 pciconfig_write = 149,
328 getsockname = 150,
329 inotify_init = 151,
330 inotify_add_watch = 152,
331 poll = 153,
332 getdents64 = 154,
333 inotify_rm_watch = 156,
334 statfs = 157,
335 fstatfs = 158,
336 umount = 159,
337 sched_set_affinity = 160,
338 sched_get_affinity = 161,
339 getdomainname = 162,
340 setdomainname = 163,
341 utrap_install = 164,
342 quotactl = 165,
343 set_tid_address = 166,
344 mount = 167,
345 ustat = 168,
346 setxattr = 169,
347 lsetxattr = 170,
348 fsetxattr = 171,
349 getxattr = 172,
350 lgetxattr = 173,
351 getdents = 174,
352 setsid = 175,
353 fchdir = 176,
354 fgetxattr = 177,
355 listxattr = 178,
356 llistxattr = 179,
357 flistxattr = 180,
358 removexattr = 181,
359 lremovexattr = 182,
360 sigpending = 183,
361 query_module = 184,
362 setpgid = 185,
363 fremovexattr = 186,
364 tkill = 187,
365 exit_group = 188,
366 uname = 189,
367 init_module = 190,
368 personality = 191,
369 remap_file_pages = 192,
370 epoll_create = 193,
371 epoll_ctl = 194,
372 epoll_wait = 195,
373 ioprio_set = 196,
374 getppid = 197,
375 sigaction = 198,
376 sgetmask = 199,
377 ssetmask = 200,
378 sigsuspend = 201,
379 oldlstat = 202,
380 uselib = 203,
381 readdir = 204,
382 readahead = 205,
383 socketcall = 206,
384 syslog = 207,
385 lookup_dcookie = 208,
386 fadvise64 = 209,
387 fadvise64_64 = 210,
388 tgkill = 211,
389 waitpid = 212,
390 swapoff = 213,
391 sysinfo = 214,
392 ipc = 215,
393 sigreturn = 216,
394 clone = 217,
395 ioprio_get = 218,
396 adjtimex = 219,
397 sigprocmask = 220,
398 create_module = 221,
399 delete_module = 222,
400 get_kernel_syms = 223,
401 getpgid = 224,
402 bdflush = 225,
403 sysfs = 226,
404 afs_syscall = 227,
405 setfsuid = 228,
406 setfsgid = 229,
407 _newselect = 230,
408 splice = 232,
409 stime = 233,
410 statfs64 = 234,
411 fstatfs64 = 235,
412 _llseek = 236,
413 mlock = 237,
414 munlock = 238,
415 mlockall = 239,
416 munlockall = 240,
417 sched_setparam = 241,
418 sched_getparam = 242,
419 sched_setscheduler = 243,
420 sched_getscheduler = 244,
421 sched_yield = 245,
422 sched_get_priority_max = 246,
423 sched_get_priority_min = 247,
424 sched_rr_get_interval = 248,
425 nanosleep = 249,
426 mremap = 250,
427 _sysctl = 251,
428 getsid = 252,
429 fdatasync = 253,
430 nfsservctl = 254,
431 sync_file_range = 255,
432 clock_settime = 256,
433 clock_gettime = 257,
434 clock_getres = 258,
435 clock_nanosleep = 259,
436 sched_getaffinity = 260,
437 sched_setaffinity = 261,
438 timer_settime = 262,
439 timer_gettime = 263,
440 timer_getoverrun = 264,
441 timer_delete = 265,
442 timer_create = 266,
443 vserver = 267,
444 io_setup = 268,
445 io_destroy = 269,
446 io_submit = 270,
447 io_cancel = 271,
448 io_getevents = 272,
449 mq_open = 273,
450 mq_unlink = 274,
451 mq_timedsend = 275,
452 mq_timedreceive = 276,
453 mq_notify = 277,
454 mq_getsetattr = 278,
455 waitid = 279,
456 tee = 280,
457 add_key = 281,
458 request_key = 282,
459 keyctl = 283,
460 openat = 284,
461 mkdirat = 285,
462 mknodat = 286,
463 fchownat = 287,
464 futimesat = 288,
465 fstatat64 = 289,
466 unlinkat = 290,
467 renameat = 291,
468 linkat = 292,
469 symlinkat = 293,
470 readlinkat = 294,
471 fchmodat = 295,
472 faccessat = 296,
473 pselect6 = 297,
474 ppoll = 298,
475 unshare = 299,
476 set_robust_list = 300,
477 get_robust_list = 301,
478 migrate_pages = 302,
479 mbind = 303,
480 get_mempolicy = 304,
481 set_mempolicy = 305,
482 kexec_load = 306,
483 move_pages = 307,
484 getcpu = 308,
485 epoll_pwait = 309,
486 utimensat = 310,
487 signalfd = 311,
488 timerfd_create = 312,
489 eventfd = 313,
490 fallocate = 314,
491 timerfd_settime = 315,
492 timerfd_gettime = 316,
493 signalfd4 = 317,
494 eventfd2 = 318,
495 epoll_create1 = 319,
496 dup3 = 320,
497 pipe2 = 321,
498 inotify_init1 = 322,
499 accept4 = 323,
500 preadv = 324,
501 pwritev = 325,
502 rt_tgsigqueueinfo = 326,
503 perf_event_open = 327,
504 recvmmsg = 328,
505 fanotify_init = 329,
506 fanotify_mark = 330,
507 prlimit64 = 331,
508 name_to_handle_at = 332,
509 open_by_handle_at = 333,
510 clock_adjtime = 334,
511 syncfs = 335,
512 sendmmsg = 336,
513 setns = 337,
514 process_vm_readv = 338,
515 process_vm_writev = 339,
516 kern_features = 340,
517 kcmp = 341,
518 finit_module = 342,
519 sched_setattr = 343,
520 sched_getattr = 344,
521 renameat2 = 345,
522 seccomp = 346,
523 getrandom = 347,
524 memfd_create = 348,
525 bpf = 349,
526 execveat = 350,
527 membarrier = 351,
528 userfaultfd = 352,
529 bind = 353,
530 listen = 354,
531 setsockopt = 355,
532 mlock2 = 356,
533 copy_file_range = 357,
534 preadv2 = 358,
535 pwritev2 = 359,
536 statx = 360,
537 io_pgetevents = 361,
538 pkey_mprotect = 362,
539 pkey_alloc = 363,
540 pkey_free = 364,
541 rseq = 365,
542 semtimedop = 392,
543 semget = 393,
544 semctl = 394,
545 shmget = 395,
546 shmctl = 396,
547 shmat = 397,
548 shmdt = 398,
549 msgget = 399,
550 msgsnd = 400,
551 msgrcv = 401,
552 msgctl = 402,
553 pidfd_send_signal = 424,
554 io_uring_setup = 425,
555 io_uring_enter = 426,
556 io_uring_register = 427,
557 open_tree = 428,
558 move_mount = 429,
559 fsopen = 430,
560 fsconfig = 431,
561 fsmount = 432,
562 fspick = 433,
563 pidfd_open = 434,
564 clone3 = 435,
565 close_range = 436,
566 openat2 = 437,
567 pidfd_getfd = 438,
568 faccessat2 = 439,
569 process_madvise = 440,
570 epoll_pwait2 = 441,
571
572 _,
573};
574
575pub const O = struct {
576 pub const CREAT = 0x200;
577 pub const EXCL = 0x800;
578 pub const NOCTTY = 0x8000;
579 pub const TRUNC = 0x400;
580 pub const APPEND = 0x8;
581 pub const NONBLOCK = 0x4000;
582 pub const SYNC = 0x802000;
583 pub const DSYNC = 0x2000;
584 pub const RSYNC = SYNC;
585 pub const DIRECTORY = 0x10000;
586 pub const NOFOLLOW = 0x20000;
587 pub const CLOEXEC = 0x400000;
588
589 pub const ASYNC = 0x40;
590 pub const DIRECT = 0x100000;
591 pub const LARGEFILE = 0;
592 pub const NOATIME = 0x200000;
593 pub const PATH = 0x1000000;
594 pub const TMPFILE = 0x2010000;
595 pub const NDELAY = NONBLOCK | 0x4;
596};
597
598pub const F = struct {
599 pub const DUPFD = 0;
600 pub const GETFD = 1;
601 pub const SETFD = 2;
602 pub const GETFL = 3;
603 pub const SETFL = 4;
604
605 pub const SETOWN = 5;
606 pub const GETOWN = 6;
607 pub const GETLK = 7;
608 pub const SETLK = 8;
609 pub const SETLKW = 9;
610
611 pub const RDLCK = 1;
612 pub const WRLCK = 2;
613 pub const UNLCK = 3;
614
615 pub const SETOWN_EX = 15;
616 pub const GETOWN_EX = 16;
617
618 pub const GETOWNER_UIDS = 17;
619};
620
621pub const LOCK = struct {
622 pub const SH = 1;
623 pub const EX = 2;
624 pub const NB = 4;
625 pub const UN = 8;
626};
627
628pub const MAP = struct {
629 /// stack-like segment
630 pub const GROWSDOWN = 0x0200;
631 /// ETXTBSY
632 pub const DENYWRITE = 0x0800;
633 /// mark it as an executable
634 pub const EXECUTABLE = 0x1000;
635 /// pages are locked
636 pub const LOCKED = 0x0100;
637 /// don't check for reservations
638 pub const NORESERVE = 0x0040;
639};
640
641pub const VDSO = struct {
642 pub const CGT_SYM = "__vdso_clock_gettime";
643 pub const CGT_VER = "LINUX_2.6";
644};
645
646pub const Flock = extern struct {
647 l_type: i16,
648 l_whence: i16,
649 l_start: off_t,
650 l_len: off_t,
651 l_pid: pid_t,
652};
653
654pub const msghdr = extern struct {
655 msg_name: ?*sockaddr,
656 msg_namelen: socklen_t,
657 msg_iov: [*]iovec,
658 msg_iovlen: u64,
659 msg_control: ?*c_void,
660 msg_controllen: u64,
661 msg_flags: i32,
662};
663
664pub const msghdr_const = extern struct {
665 msg_name: ?*const sockaddr,
666 msg_namelen: socklen_t,
667 msg_iov: [*]iovec_const,
668 msg_iovlen: u64,
669 msg_control: ?*c_void,
670 msg_controllen: u64,
671 msg_flags: i32,
672};
673
674pub const off_t = i64;
675pub const ino_t = u64;
676pub const mode_t = u32;
677
678// The `stat64` definition used by the kernel.
679pub const Stat = extern struct {
680 dev: u64,
681 ino: u64,
682 nlink: u64,
683
684 mode: u32,
685 uid: u32,
686 gid: u32,
687 __pad0: u32,
688
689 rdev: u64,
690 size: i64,
691 blksize: i64,
692 blocks: i64,
693
694 atim: timespec,
695 mtim: timespec,
696 ctim: timespec,
697 __unused: [3]u64,
698
699 pub fn atime(self: @This()) timespec {
700 return self.atim;
701 }
702
703 pub fn mtime(self: @This()) timespec {
704 return self.mtim;
705 }
706
707 pub fn ctime(self: @This()) timespec {
708 return self.ctim;
709 }
710};
711
712pub const timeval = extern struct {
713 tv_sec: isize,
714 tv_usec: isize,
715};
716
717pub const timezone = extern struct {
718 tz_minuteswest: i32,
719 tz_dsttime: i32,
720};
721
722// TODO I'm not sure if the code below is correct, need someone with more
723// knowledge about sparc64 linux internals to look into.
724
725pub const Elf_Symndx = u32;
726
727pub const fpstate = extern struct {
728 regs: [32]u64,
729 fsr: u64,
730 gsr: u64,
731 fprs: u64,
732};
733
734pub const __fpq = extern struct {
735 fpq_addr: *u32,
736 fpq_instr: u32,
737};
738
739pub const __fq = extern struct {
740 FQu: extern union {
741 whole: f64,
742 fpq: __fpq,
743 },
744};
745
746pub const fpregset_t = extern struct {
747 fpu_fr: extern union {
748 fpu_regs: [32]u32,
749 fpu_dregs: [32]f64,
750 fpu_qregs: [16]c_longdouble,
751 },
752 fpu_q: *__fq,
753 fpu_fsr: u64,
754 fpu_qcnt: u8,
755 fpu_q_entrysize: u8,
756 fpu_en: u8,
757};
758
759pub const siginfo_fpu_t = extern struct {
760 float_regs: [64]u32,
761 fsr: u64,
762 gsr: u64,
763 fprs: u64,
764};
765
766pub const sigcontext = extern struct {
767 info: [128]i8,
768 regs: extern struct {
769 u_regs: [16]u64,
770 tstate: u64,
771 tpc: u64,
772 tnpc: u64,
773 y: u64,
774 fprs: u64,
775 },
776 fpu_save: *siginfo_fpu_t,
777 stack: extern struct {
778 sp: usize,
779 flags: i32,
780 size: u64,
781 },
782 mask: u64,
783};
784
785pub const greg_t = u64;
786pub const gregset_t = [19]greg_t;
787
788pub const fq = extern struct {
789 addr: *u64,
790 insn: u32,
791};
792
793pub const fpu_t = extern struct {
794 fregs: extern union {
795 sregs: [32]u32,
796 dregs: [32]u64,
797 qregs: [16]c_longdouble,
798 },
799 fsr: u64,
800 fprs: u64,
801 gsr: u64,
802 fq: *fq,
803 qcnt: u8,
804 qentsz: u8,
805 enab: u8,
806};
807
808pub const mcontext_t = extern struct {
809 gregs: gregset_t,
810 fp: greg_t,
811 @"i7": greg_t,
812 fpregs: fpu_t,
813};
814
815pub const ucontext_t = extern struct {
816 link: *ucontext_t,
817 flags: u64,
818 sigmask: u64,
819 mcontext: mcontext_t,
820 stack: stack_t,
821 sigmask: sigset_t,
822};
lib/std/os/linux/test.zig+7-7
...@@ -35,7 +35,7 @@ test "timer" {...@@ -35,7 +35,7 @@ test "timer" {
35 var err: linux.E = linux.getErrno(epoll_fd);35 var err: linux.E = linux.getErrno(epoll_fd);
36 try expect(err == .SUCCESS);36 try expect(err == .SUCCESS);
3737
38 const timer_fd = linux.timerfd_create(linux.CLOCK_MONOTONIC, 0);38 const timer_fd = linux.timerfd_create(linux.CLOCK.MONOTONIC, 0);
39 try expect(linux.getErrno(timer_fd) == .SUCCESS);39 try expect(linux.getErrno(timer_fd) == .SUCCESS);
4040
41 const time_interval = linux.timespec{41 const time_interval = linux.timespec{
...@@ -52,11 +52,11 @@ test "timer" {...@@ -52,11 +52,11 @@ test "timer" {
52 try expect(err == .SUCCESS);52 try expect(err == .SUCCESS);
5353
54 var event = linux.epoll_event{54 var event = linux.epoll_event{
55 .events = linux.EPOLLIN | linux.EPOLLOUT | linux.EPOLLET,55 .events = linux.EPOLL.IN | linux.EPOLL.OUT | linux.EPOLL.ET,
56 .data = linux.epoll_data{ .ptr = 0 },56 .data = linux.epoll_data{ .ptr = 0 },
57 };57 };
5858
59 err = linux.getErrno(linux.epoll_ctl(@intCast(i32, epoll_fd), linux.EPOLL_CTL_ADD, @intCast(i32, timer_fd), &event));59 err = linux.getErrno(linux.epoll_ctl(@intCast(i32, epoll_fd), linux.EPOLL.CTL_ADD, @intCast(i32, timer_fd), &event));
60 try expect(err == .SUCCESS);60 try expect(err == .SUCCESS);
6161
62 const events_one: linux.epoll_event = undefined;62 const events_one: linux.epoll_event = undefined;
...@@ -75,15 +75,15 @@ test "statx" {...@@ -75,15 +75,15 @@ test "statx" {
75 }75 }
7676
77 var statx_buf: linux.Statx = undefined;77 var statx_buf: linux.Statx = undefined;
78 switch (linux.getErrno(linux.statx(file.handle, "", linux.AT_EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {78 switch (linux.getErrno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
79 .SUCCESS => {},79 .SUCCESS => {},
80 // The statx syscall was only introduced in linux 4.1180 // The statx syscall was only introduced in linux 4.11
81 .NOSYS => return error.SkipZigTest,81 .NOSYS => return error.SkipZigTest,
82 else => unreachable,82 else => unreachable,
83 }83 }
8484
85 var stat_buf: linux.kernel_stat = undefined;85 var stat_buf: linux.Stat = undefined;
86 switch (linux.getErrno(linux.fstatat(file.handle, "", &stat_buf, linux.AT_EMPTY_PATH))) {86 switch (linux.getErrno(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {
87 .SUCCESS => {},87 .SUCCESS => {},
88 else => unreachable,88 else => unreachable,
89 }89 }
...@@ -119,7 +119,7 @@ test "fadvise" {...@@ -119,7 +119,7 @@ test "fadvise" {
119 file.handle,119 file.handle,
120 0,120 0,
121 0,121 0,
122 linux.POSIX_FADV_SEQUENTIAL,122 linux.POSIX_FADV.SEQUENTIAL,
123 );123 );
124 try expectEqual(@as(usize, 0), ret);124 try expectEqual(@as(usize, 0), ret);
125}125}
lib/std/os/linux/thumb.zig+8-10
...@@ -1,10 +1,11 @@...@@ -1,10 +1,11 @@
1usingnamespace @import("../bits/linux.zig");1//! The syscall interface is identical to the ARM one but we're facing an extra
22//! challenge: r7, the register where the syscall number is stored, may be
3// The syscall interface is identical to the ARM one but we're facing an extra3//! reserved for the frame pointer.
4// challenge: r7, the register where the syscall number is stored, may be4//! Save and restore r7 around the syscall without touching the stack pointer not
5// reserved for the frame pointer.5//! to break the frame chain.
6// Save and restore r7 around the syscall without touching the stack pointer not6const std = @import("../../std.zig");
7// to break the frame chain.7const linux = std.os.linux;
8const SYS = linux.SYS;
89
9pub fn syscall0(number: SYS) usize {10pub fn syscall0(number: SYS) usize {
10 @setRuntimeSafety(false);11 @setRuntimeSafety(false);
...@@ -140,9 +141,6 @@ pub fn syscall6(...@@ -140,9 +141,6 @@ pub fn syscall6(
140 );141 );
141}142}
142143
143/// This matches the libc clone function.
144pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
145
146pub fn restore() callconv(.Naked) void {144pub fn restore() callconv(.Naked) void {
147 return asm volatile (145 return asm volatile (
148 \\ mov r7, %[number]146 \\ mov r7, %[number]
lib/std/os/linux/tls.zig+3-3
...@@ -135,7 +135,7 @@ pub fn setThreadPointer(addr: usize) void {...@@ -135,7 +135,7 @@ pub fn setThreadPointer(addr: usize) void {
135 );135 );
136 },136 },
137 .x86_64 => {137 .x86_64 => {
138 const rc = std.os.linux.syscall2(.arch_prctl, std.os.linux.ARCH_SET_FS, addr);138 const rc = std.os.linux.syscall2(.arch_prctl, std.os.linux.ARCH.SET_FS, addr);
139 assert(rc == 0);139 assert(rc == 0);
140 },140 },
141 .aarch64 => {141 .aarch64 => {
...@@ -319,8 +319,8 @@ pub fn initStaticTLS(phdrs: []elf.Phdr) void {...@@ -319,8 +319,8 @@ pub fn initStaticTLS(phdrs: []elf.Phdr) void {
319 const alloc_tls_area = os.mmap(319 const alloc_tls_area = os.mmap(
320 null,320 null,
321 tls_image.alloc_size + tls_image.alloc_align - 1,321 tls_image.alloc_size + tls_image.alloc_align - 1,
322 os.PROT_READ | os.PROT_WRITE,322 os.PROT.READ | os.PROT.WRITE,
323 os.MAP_PRIVATE | os.MAP_ANONYMOUS,323 os.MAP.PRIVATE | os.MAP.ANONYMOUS,
324 -1,324 -1,
325 0,325 0,
326 ) catch os.abort();326 ) catch os.abort();
lib/std/os/linux/x86_64.zig+641-1
...@@ -1,4 +1,18 @@...@@ -1,4 +1,18 @@
1usingnamespace @import("../bits/linux.zig");1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const iovec = std.os.iovec;
5const iovec_const = std.os.iovec_const;
6
7const pid_t = linux.pid_t;
8const uid_t = linux.uid_t;
9const gid_t = linux.gid_t;
10const clock_t = linux.clock_t;
11const stack_t = linux.stack_t;
12const sigset_t = linux.sigset_t;
13const sockaddr = linux.sockaddr;
14const socklen_t = linux.socklen_t;
15const timespec = linux.timespec;
216
3pub fn syscall0(number: SYS) usize {17pub fn syscall0(number: SYS) usize {
4 return asm volatile ("syscall"18 return asm volatile ("syscall"
...@@ -97,3 +111,629 @@ pub fn restore_rt() callconv(.Naked) void {...@@ -97,3 +111,629 @@ pub fn restore_rt() callconv(.Naked) void {
97 : "rcx", "r11", "memory"111 : "rcx", "r11", "memory"
98 );112 );
99}113}
114
115pub const mode_t = usize;
116pub const time_t = isize;
117pub const nlink_t = usize;
118pub const blksize_t = isize;
119pub const blkcnt_t = isize;
120
121pub const SYS = enum(usize) {
122 read = 0,
123 write = 1,
124 open = 2,
125 close = 3,
126 stat = 4,
127 fstat = 5,
128 lstat = 6,
129 poll = 7,
130 lseek = 8,
131 mmap = 9,
132 mprotect = 10,
133 munmap = 11,
134 brk = 12,
135 rt_sigaction = 13,
136 rt_sigprocmask = 14,
137 rt_sigreturn = 15,
138 ioctl = 16,
139 pread = 17,
140 pwrite = 18,
141 readv = 19,
142 writev = 20,
143 access = 21,
144 pipe = 22,
145 select = 23,
146 sched_yield = 24,
147 mremap = 25,
148 msync = 26,
149 mincore = 27,
150 madvise = 28,
151 shmget = 29,
152 shmat = 30,
153 shmctl = 31,
154 dup = 32,
155 dup2 = 33,
156 pause = 34,
157 nanosleep = 35,
158 getitimer = 36,
159 alarm = 37,
160 setitimer = 38,
161 getpid = 39,
162 sendfile = 40,
163 socket = 41,
164 connect = 42,
165 accept = 43,
166 sendto = 44,
167 recvfrom = 45,
168 sendmsg = 46,
169 recvmsg = 47,
170 shutdown = 48,
171 bind = 49,
172 listen = 50,
173 getsockname = 51,
174 getpeername = 52,
175 socketpair = 53,
176 setsockopt = 54,
177 getsockopt = 55,
178 clone = 56,
179 fork = 57,
180 vfork = 58,
181 execve = 59,
182 exit = 60,
183 wait4 = 61,
184 kill = 62,
185 uname = 63,
186 semget = 64,
187 semop = 65,
188 semctl = 66,
189 shmdt = 67,
190 msgget = 68,
191 msgsnd = 69,
192 msgrcv = 70,
193 msgctl = 71,
194 fcntl = 72,
195 flock = 73,
196 fsync = 74,
197 fdatasync = 75,
198 truncate = 76,
199 ftruncate = 77,
200 getdents = 78,
201 getcwd = 79,
202 chdir = 80,
203 fchdir = 81,
204 rename = 82,
205 mkdir = 83,
206 rmdir = 84,
207 creat = 85,
208 link = 86,
209 unlink = 87,
210 symlink = 88,
211 readlink = 89,
212 chmod = 90,
213 fchmod = 91,
214 chown = 92,
215 fchown = 93,
216 lchown = 94,
217 umask = 95,
218 gettimeofday = 96,
219 getrlimit = 97,
220 getrusage = 98,
221 sysinfo = 99,
222 times = 100,
223 ptrace = 101,
224 getuid = 102,
225 syslog = 103,
226 getgid = 104,
227 setuid = 105,
228 setgid = 106,
229 geteuid = 107,
230 getegid = 108,
231 setpgid = 109,
232 getppid = 110,
233 getpgrp = 111,
234 setsid = 112,
235 setreuid = 113,
236 setregid = 114,
237 getgroups = 115,
238 setgroups = 116,
239 setresuid = 117,
240 getresuid = 118,
241 setresgid = 119,
242 getresgid = 120,
243 getpgid = 121,
244 setfsuid = 122,
245 setfsgid = 123,
246 getsid = 124,
247 capget = 125,
248 capset = 126,
249 rt_sigpending = 127,
250 rt_sigtimedwait = 128,
251 rt_sigqueueinfo = 129,
252 rt_sigsuspend = 130,
253 sigaltstack = 131,
254 utime = 132,
255 mknod = 133,
256 uselib = 134,
257 personality = 135,
258 ustat = 136,
259 statfs = 137,
260 fstatfs = 138,
261 sysfs = 139,
262 getpriority = 140,
263 setpriority = 141,
264 sched_setparam = 142,
265 sched_getparam = 143,
266 sched_setscheduler = 144,
267 sched_getscheduler = 145,
268 sched_get_priority_max = 146,
269 sched_get_priority_min = 147,
270 sched_rr_get_interval = 148,
271 mlock = 149,
272 munlock = 150,
273 mlockall = 151,
274 munlockall = 152,
275 vhangup = 153,
276 modify_ldt = 154,
277 pivot_root = 155,
278 _sysctl = 156,
279 prctl = 157,
280 arch_prctl = 158,
281 adjtimex = 159,
282 setrlimit = 160,
283 chroot = 161,
284 sync = 162,
285 acct = 163,
286 settimeofday = 164,
287 mount = 165,
288 umount2 = 166,
289 swapon = 167,
290 swapoff = 168,
291 reboot = 169,
292 sethostname = 170,
293 setdomainname = 171,
294 iopl = 172,
295 ioperm = 173,
296 create_module = 174,
297 init_module = 175,
298 delete_module = 176,
299 get_kernel_syms = 177,
300 query_module = 178,
301 quotactl = 179,
302 nfsservctl = 180,
303 getpmsg = 181,
304 putpmsg = 182,
305 afs_syscall = 183,
306 tuxcall = 184,
307 security = 185,
308 gettid = 186,
309 readahead = 187,
310 setxattr = 188,
311 lsetxattr = 189,
312 fsetxattr = 190,
313 getxattr = 191,
314 lgetxattr = 192,
315 fgetxattr = 193,
316 listxattr = 194,
317 llistxattr = 195,
318 flistxattr = 196,
319 removexattr = 197,
320 lremovexattr = 198,
321 fremovexattr = 199,
322 tkill = 200,
323 time = 201,
324 futex = 202,
325 sched_setaffinity = 203,
326 sched_getaffinity = 204,
327 set_thread_area = 205,
328 io_setup = 206,
329 io_destroy = 207,
330 io_getevents = 208,
331 io_submit = 209,
332 io_cancel = 210,
333 get_thread_area = 211,
334 lookup_dcookie = 212,
335 epoll_create = 213,
336 epoll_ctl_old = 214,
337 epoll_wait_old = 215,
338 remap_file_pages = 216,
339 getdents64 = 217,
340 set_tid_address = 218,
341 restart_syscall = 219,
342 semtimedop = 220,
343 fadvise64 = 221,
344 timer_create = 222,
345 timer_settime = 223,
346 timer_gettime = 224,
347 timer_getoverrun = 225,
348 timer_delete = 226,
349 clock_settime = 227,
350 clock_gettime = 228,
351 clock_getres = 229,
352 clock_nanosleep = 230,
353 exit_group = 231,
354 epoll_wait = 232,
355 epoll_ctl = 233,
356 tgkill = 234,
357 utimes = 235,
358 vserver = 236,
359 mbind = 237,
360 set_mempolicy = 238,
361 get_mempolicy = 239,
362 mq_open = 240,
363 mq_unlink = 241,
364 mq_timedsend = 242,
365 mq_timedreceive = 243,
366 mq_notify = 244,
367 mq_getsetattr = 245,
368 kexec_load = 246,
369 waitid = 247,
370 add_key = 248,
371 request_key = 249,
372 keyctl = 250,
373 ioprio_set = 251,
374 ioprio_get = 252,
375 inotify_init = 253,
376 inotify_add_watch = 254,
377 inotify_rm_watch = 255,
378 migrate_pages = 256,
379 openat = 257,
380 mkdirat = 258,
381 mknodat = 259,
382 fchownat = 260,
383 futimesat = 261,
384 fstatat = 262,
385 unlinkat = 263,
386 renameat = 264,
387 linkat = 265,
388 symlinkat = 266,
389 readlinkat = 267,
390 fchmodat = 268,
391 faccessat = 269,
392 pselect6 = 270,
393 ppoll = 271,
394 unshare = 272,
395 set_robust_list = 273,
396 get_robust_list = 274,
397 splice = 275,
398 tee = 276,
399 sync_file_range = 277,
400 vmsplice = 278,
401 move_pages = 279,
402 utimensat = 280,
403 epoll_pwait = 281,
404 signalfd = 282,
405 timerfd_create = 283,
406 eventfd = 284,
407 fallocate = 285,
408 timerfd_settime = 286,
409 timerfd_gettime = 287,
410 accept4 = 288,
411 signalfd4 = 289,
412 eventfd2 = 290,
413 epoll_create1 = 291,
414 dup3 = 292,
415 pipe2 = 293,
416 inotify_init1 = 294,
417 preadv = 295,
418 pwritev = 296,
419 rt_tgsigqueueinfo = 297,
420 perf_event_open = 298,
421 recvmmsg = 299,
422 fanotify_init = 300,
423 fanotify_mark = 301,
424 prlimit64 = 302,
425 name_to_handle_at = 303,
426 open_by_handle_at = 304,
427 clock_adjtime = 305,
428 syncfs = 306,
429 sendmmsg = 307,
430 setns = 308,
431 getcpu = 309,
432 process_vm_readv = 310,
433 process_vm_writev = 311,
434 kcmp = 312,
435 finit_module = 313,
436 sched_setattr = 314,
437 sched_getattr = 315,
438 renameat2 = 316,
439 seccomp = 317,
440 getrandom = 318,
441 memfd_create = 319,
442 kexec_file_load = 320,
443 bpf = 321,
444 execveat = 322,
445 userfaultfd = 323,
446 membarrier = 324,
447 mlock2 = 325,
448 copy_file_range = 326,
449 preadv2 = 327,
450 pwritev2 = 328,
451 pkey_mprotect = 329,
452 pkey_alloc = 330,
453 pkey_free = 331,
454 statx = 332,
455 io_pgetevents = 333,
456 rseq = 334,
457 pidfd_send_signal = 424,
458 io_uring_setup = 425,
459 io_uring_enter = 426,
460 io_uring_register = 427,
461 open_tree = 428,
462 move_mount = 429,
463 fsopen = 430,
464 fsconfig = 431,
465 fsmount = 432,
466 fspick = 433,
467 pidfd_open = 434,
468 clone3 = 435,
469 close_range = 436,
470 openat2 = 437,
471 pidfd_getfd = 438,
472 faccessat2 = 439,
473 process_madvise = 440,
474 epoll_pwait2 = 441,
475
476 _,
477};
478
479pub const O = struct {
480 pub const CREAT = 0o100;
481 pub const EXCL = 0o200;
482 pub const NOCTTY = 0o400;
483 pub const TRUNC = 0o1000;
484 pub const APPEND = 0o2000;
485 pub const NONBLOCK = 0o4000;
486 pub const DSYNC = 0o10000;
487 pub const SYNC = 0o4010000;
488 pub const RSYNC = 0o4010000;
489 pub const DIRECTORY = 0o200000;
490 pub const NOFOLLOW = 0o400000;
491 pub const CLOEXEC = 0o2000000;
492
493 pub const ASYNC = 0o20000;
494 pub const DIRECT = 0o40000;
495 pub const LARGEFILE = 0;
496 pub const NOATIME = 0o1000000;
497 pub const PATH = 0o10000000;
498 pub const TMPFILE = 0o20200000;
499 pub const NDELAY = NONBLOCK;
500};
501
502pub const F = struct {
503 pub const DUPFD = 0;
504 pub const GETFD = 1;
505 pub const SETFD = 2;
506 pub const GETFL = 3;
507 pub const SETFL = 4;
508 pub const GETLK = 5;
509 pub const SETLK = 6;
510 pub const SETLKW = 7;
511 pub const SETOWN = 8;
512 pub const GETOWN = 9;
513 pub const SETSIG = 10;
514 pub const GETSIG = 11;
515
516 pub const SETOWN_EX = 15;
517 pub const GETOWN_EX = 16;
518 pub const GETOWNER_UIDS = 17;
519
520 pub const RDLCK = 0;
521 pub const WRLCK = 1;
522 pub const UNLCK = 2;
523};
524
525pub const MAP = struct {
526 /// only give out 32bit addresses
527 pub const @"32BIT" = 0x40;
528 /// stack-like segment
529 pub const GROWSDOWN = 0x0100;
530 /// ETXTBSY
531 pub const DENYWRITE = 0x0800;
532 /// mark it as an executable
533 pub const EXECUTABLE = 0x1000;
534 /// pages are locked
535 pub const LOCKED = 0x2000;
536 /// don't check for reservations
537 pub const NORESERVE = 0x4000;
538};
539
540pub const VDSO = struct {
541 pub const CGT_SYM = "__vdso_clock_gettime";
542 pub const CGT_VER = "LINUX_2.6";
543
544 pub const GETCPU_SYM = "__vdso_getcpu";
545 pub const GETCPU_VER = "LINUX_2.6";
546};
547
548pub const ARCH = struct {
549 pub const SET_GS = 0x1001;
550 pub const SET_FS = 0x1002;
551 pub const GET_FS = 0x1003;
552 pub const GET_GS = 0x1004;
553};
554
555pub const REG = struct {
556 pub const R8 = 0;
557 pub const R9 = 1;
558 pub const R10 = 2;
559 pub const R11 = 3;
560 pub const R12 = 4;
561 pub const R13 = 5;
562 pub const R14 = 6;
563 pub const R15 = 7;
564 pub const RDI = 8;
565 pub const RSI = 9;
566 pub const RBP = 10;
567 pub const RBX = 11;
568 pub const RDX = 12;
569 pub const RAX = 13;
570 pub const RCX = 14;
571 pub const RSP = 15;
572 pub const RIP = 16;
573 pub const EFL = 17;
574 pub const CSGSFS = 18;
575 pub const ERR = 19;
576 pub const TRAPNO = 20;
577 pub const OLDMASK = 21;
578 pub const CR2 = 22;
579};
580
581pub const LOCK = struct {
582 pub const SH = 1;
583 pub const EX = 2;
584 pub const NB = 4;
585 pub const UN = 8;
586};
587
588pub const Flock = extern struct {
589 type: i16,
590 whence: i16,
591 start: off_t,
592 len: off_t,
593 pid: pid_t,
594};
595
596pub const msghdr = extern struct {
597 name: ?*sockaddr,
598 namelen: socklen_t,
599 iov: [*]iovec,
600 iovlen: i32,
601 __pad1: i32 = 0,
602 control: ?*c_void,
603 controllen: socklen_t,
604 __pad2: socklen_t = 0,
605 flags: i32,
606};
607
608pub const msghdr_const = extern struct {
609 name: ?*const sockaddr,
610 namelen: socklen_t,
611 iov: [*]iovec_const,
612 iovlen: i32,
613 __pad1: i32 = 0,
614 control: ?*c_void,
615 controllen: socklen_t,
616 __pad2: socklen_t = 0,
617 flags: i32,
618};
619
620pub const off_t = i64;
621pub const ino_t = u64;
622pub const dev_t = u64;
623
624// The `stat` definition used by the Linux kernel.
625pub const Stat = extern struct {
626 dev: dev_t,
627 ino: ino_t,
628 nlink: usize,
629
630 mode: u32,
631 uid: uid_t,
632 gid: gid_t,
633 __pad0: u32,
634 rdev: dev_t,
635 size: off_t,
636 blksize: isize,
637 blocks: i64,
638
639 atim: timespec,
640 mtim: timespec,
641 ctim: timespec,
642 __unused: [3]isize,
643
644 pub fn atime(self: @This()) timespec {
645 return self.atim;
646 }
647
648 pub fn mtime(self: @This()) timespec {
649 return self.mtim;
650 }
651
652 pub fn ctime(self: @This()) timespec {
653 return self.ctim;
654 }
655};
656
657pub const timeval = extern struct {
658 tv_sec: isize,
659 tv_usec: isize,
660};
661
662pub const timezone = extern struct {
663 tz_minuteswest: i32,
664 tz_dsttime: i32,
665};
666
667pub const Elf_Symndx = u32;
668
669pub const greg_t = usize;
670pub const gregset_t = [23]greg_t;
671pub const fpstate = extern struct {
672 cwd: u16,
673 swd: u16,
674 ftw: u16,
675 fop: u16,
676 rip: usize,
677 rdp: usize,
678 mxcsr: u32,
679 mxcr_mask: u32,
680 st: [8]extern struct {
681 significand: [4]u16,
682 exponent: u16,
683 padding: [3]u16 = undefined,
684 },
685 xmm: [16]extern struct {
686 element: [4]u32,
687 },
688 padding: [24]u32 = undefined,
689};
690pub const fpregset_t = *fpstate;
691pub const sigcontext = extern struct {
692 r8: usize,
693 r9: usize,
694 r10: usize,
695 r11: usize,
696 r12: usize,
697 r13: usize,
698 r14: usize,
699 r15: usize,
700
701 rdi: usize,
702 rsi: usize,
703 rbp: usize,
704 rbx: usize,
705 rdx: usize,
706 rax: usize,
707 rcx: usize,
708 rsp: usize,
709 rip: usize,
710 eflags: usize,
711
712 cs: u16,
713 gs: u16,
714 fs: u16,
715 pad0: u16 = undefined,
716
717 err: usize,
718 trapno: usize,
719 oldmask: usize,
720 cr2: usize,
721
722 fpstate: *fpstate,
723 reserved1: [8]usize = undefined,
724};
725
726pub const mcontext_t = extern struct {
727 gregs: gregset_t,
728 fpregs: fpregset_t,
729 reserved1: [8]usize = undefined,
730};
731
732pub const ucontext_t = extern struct {
733 flags: usize,
734 link: *ucontext_t,
735 stack: stack_t,
736 mcontext: mcontext_t,
737 sigmask: sigset_t,
738 fpregs_mem: [64]usize,
739};
lib/std/os/netbsd.zig deleted-3
...@@ -1,3 +0,0 @@
1const std = @import("../std.zig");
2pub usingnamespace std.c;
3pub usingnamespace @import("bits.zig");
lib/std/os/openbsd.zig deleted-3
...@@ -1,3 +0,0 @@
1const std = @import("../std.zig");
2pub usingnamespace std.c;
3pub usingnamespace @import("bits.zig");
lib/std/os/test.zig+41-41
...@@ -70,21 +70,21 @@ test "open smoke test" {...@@ -70,21 +70,21 @@ test "open smoke test" {
7070
71 // Create some file using `open`.71 // Create some file using `open`.
72 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });72 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });
73 fd = try os.open(file_path, os.O_RDWR | os.O_CREAT | os.O_EXCL, mode);73 fd = try os.open(file_path, os.O.RDWR | os.O.CREAT | os.O.EXCL, mode);
74 os.close(fd);74 os.close(fd);
7575
76 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.76 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.
77 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });77 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });
78 try expectError(error.PathAlreadyExists, os.open(file_path, os.O_RDWR | os.O_CREAT | os.O_EXCL, mode));78 try expectError(error.PathAlreadyExists, os.open(file_path, os.O.RDWR | os.O.CREAT | os.O.EXCL, mode));
7979
80 // Try opening without `O_EXCL` flag.80 // Try opening without `O.EXCL` flag.
81 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });81 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });
82 fd = try os.open(file_path, os.O_RDWR | os.O_CREAT, mode);82 fd = try os.open(file_path, os.O.RDWR | os.O.CREAT, mode);
83 os.close(fd);83 os.close(fd);
8484
85 // Try opening as a directory which should fail.85 // Try opening as a directory which should fail.
86 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });86 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_file" });
87 try expectError(error.NotDir, os.open(file_path, os.O_RDWR | os.O_DIRECTORY, mode));87 try expectError(error.NotDir, os.open(file_path, os.O.RDWR | os.O.DIRECTORY, mode));
8888
89 // Create some directory89 // Create some directory
90 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });90 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });
...@@ -92,12 +92,12 @@ test "open smoke test" {...@@ -92,12 +92,12 @@ test "open smoke test" {
9292
93 // Open dir using `open`93 // Open dir using `open`
94 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });94 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });
95 fd = try os.open(file_path, os.O_RDONLY | os.O_DIRECTORY, mode);95 fd = try os.open(file_path, os.O.RDONLY | os.O.DIRECTORY, mode);
96 os.close(fd);96 os.close(fd);
9797
98 // Try opening as file which should fail.98 // Try opening as file which should fail.
99 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });99 file_path = try fs.path.join(&arena.allocator, &[_][]const u8{ base_path, "some_dir" });
100 try expectError(error.IsDir, os.open(file_path, os.O_RDWR, mode));100 try expectError(error.IsDir, os.open(file_path, os.O.RDWR, mode));
101}101}
102102
103test "openat smoke test" {103test "openat smoke test" {
...@@ -112,28 +112,28 @@ test "openat smoke test" {...@@ -112,28 +112,28 @@ test "openat smoke test" {
112 const mode: os.mode_t = if (native_os == .windows) 0 else 0o666;112 const mode: os.mode_t = if (native_os == .windows) 0 else 0o666;
113113
114 // Create some file using `openat`.114 // Create some file using `openat`.
115 fd = try os.openat(tmp.dir.fd, "some_file", os.O_RDWR | os.O_CREAT | os.O_EXCL, mode);115 fd = try os.openat(tmp.dir.fd, "some_file", os.O.RDWR | os.O.CREAT | os.O.EXCL, mode);
116 os.close(fd);116 os.close(fd);
117117
118 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.118 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.
119 try expectError(error.PathAlreadyExists, os.openat(tmp.dir.fd, "some_file", os.O_RDWR | os.O_CREAT | os.O_EXCL, mode));119 try expectError(error.PathAlreadyExists, os.openat(tmp.dir.fd, "some_file", os.O.RDWR | os.O.CREAT | os.O.EXCL, mode));
120120
121 // Try opening without `O_EXCL` flag.121 // Try opening without `O.EXCL` flag.
122 fd = try os.openat(tmp.dir.fd, "some_file", os.O_RDWR | os.O_CREAT, mode);122 fd = try os.openat(tmp.dir.fd, "some_file", os.O.RDWR | os.O.CREAT, mode);
123 os.close(fd);123 os.close(fd);
124124
125 // Try opening as a directory which should fail.125 // Try opening as a directory which should fail.
126 try expectError(error.NotDir, os.openat(tmp.dir.fd, "some_file", os.O_RDWR | os.O_DIRECTORY, mode));126 try expectError(error.NotDir, os.openat(tmp.dir.fd, "some_file", os.O.RDWR | os.O.DIRECTORY, mode));
127127
128 // Create some directory128 // Create some directory
129 try os.mkdirat(tmp.dir.fd, "some_dir", mode);129 try os.mkdirat(tmp.dir.fd, "some_dir", mode);
130130
131 // Open dir using `open`131 // Open dir using `open`
132 fd = try os.openat(tmp.dir.fd, "some_dir", os.O_RDONLY | os.O_DIRECTORY, mode);132 fd = try os.openat(tmp.dir.fd, "some_dir", os.O.RDONLY | os.O.DIRECTORY, mode);
133 os.close(fd);133 os.close(fd);
134134
135 // Try opening as file which should fail.135 // Try opening as file which should fail.
136 try expectError(error.IsDir, os.openat(tmp.dir.fd, "some_dir", os.O_RDWR, mode));136 try expectError(error.IsDir, os.openat(tmp.dir.fd, "some_dir", os.O.RDWR, mode));
137}137}
138138
139test "symlink with relative paths" {139test "symlink with relative paths" {
...@@ -273,7 +273,7 @@ test "fstatat" {...@@ -273,7 +273,7 @@ test "fstatat" {
273 defer file.close();273 defer file.close();
274274
275 // now repeat but using `fstatat` instead275 // now repeat but using `fstatat` instead
276 const flags = if (native_os == .wasi) 0x0 else os.AT_SYMLINK_NOFOLLOW;276 const flags = if (native_os == .wasi) 0x0 else os.AT.SYMLINK_NOFOLLOW;
277 const statat = try os.fstatat(tmp.dir.fd, "file.txt", flags);277 const statat = try os.fstatat(tmp.dir.fd, "file.txt", flags);
278 try expectEqual(stat, statat);278 try expectEqual(stat, statat);
279}279}
...@@ -394,14 +394,14 @@ test "sigaltstack" {...@@ -394,14 +394,14 @@ test "sigaltstack" {
394 var st: os.stack_t = undefined;394 var st: os.stack_t = undefined;
395 try os.sigaltstack(null, &st);395 try os.sigaltstack(null, &st);
396 // Setting a stack size less than MINSIGSTKSZ returns ENOMEM396 // Setting a stack size less than MINSIGSTKSZ returns ENOMEM
397 st.ss_flags = 0;397 st.flags = 0;
398 st.ss_size = 1;398 st.size = 1;
399 try testing.expectError(error.SizeTooSmall, os.sigaltstack(&st, null));399 try testing.expectError(error.SizeTooSmall, os.sigaltstack(&st, null));
400}400}
401401
402// If the type is not available use void to avoid erroring out when `iter_fn` is402// If the type is not available use void to avoid erroring out when `iter_fn` is
403// analyzed403// analyzed
404const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void;404const dl_phdr_info = if (@hasDecl(os.system, "dl_phdr_info")) os.dl_phdr_info else c_void;
405405
406const IterFnError = error{406const IterFnError = error{
407 MissingPtLoadSegment,407 MissingPtLoadSegment,
...@@ -508,8 +508,8 @@ test "mmap" {...@@ -508,8 +508,8 @@ test "mmap" {
508 const data = try os.mmap(508 const data = try os.mmap(
509 null,509 null,
510 1234,510 1234,
511 os.PROT_READ | os.PROT_WRITE,511 os.PROT.READ | os.PROT.WRITE,
512 os.MAP_ANONYMOUS | os.MAP_PRIVATE,512 os.MAP.ANONYMOUS | os.MAP.PRIVATE,
513 -1,513 -1,
514 0,514 0,
515 );515 );
...@@ -550,8 +550,8 @@ test "mmap" {...@@ -550,8 +550,8 @@ test "mmap" {
550 const data = try os.mmap(550 const data = try os.mmap(
551 null,551 null,
552 alloc_size,552 alloc_size,
553 os.PROT_READ,553 os.PROT.READ,
554 os.MAP_PRIVATE,554 os.MAP.PRIVATE,
555 file.handle,555 file.handle,
556 0,556 0,
557 );557 );
...@@ -574,8 +574,8 @@ test "mmap" {...@@ -574,8 +574,8 @@ test "mmap" {
574 const data = try os.mmap(574 const data = try os.mmap(
575 null,575 null,
576 alloc_size / 2,576 alloc_size / 2,
577 os.PROT_READ,577 os.PROT.READ,
578 os.MAP_PRIVATE,578 os.MAP.PRIVATE,
579 file.handle,579 file.handle,
580 alloc_size / 2,580 alloc_size / 2,
581 );581 );
...@@ -616,19 +616,19 @@ test "fcntl" {...@@ -616,19 +616,19 @@ test "fcntl" {
616 tmp.dir.deleteFile(test_out_file) catch {};616 tmp.dir.deleteFile(test_out_file) catch {};
617 }617 }
618618
619 // Note: The test assumes createFile opens the file with O_CLOEXEC619 // Note: The test assumes createFile opens the file with O.CLOEXEC
620 {620 {
621 const flags = try os.fcntl(file.handle, os.F_GETFD, 0);621 const flags = try os.fcntl(file.handle, os.F.GETFD, 0);
622 try expect((flags & os.FD_CLOEXEC) != 0);622 try expect((flags & os.FD_CLOEXEC) != 0);
623 }623 }
624 {624 {
625 _ = try os.fcntl(file.handle, os.F_SETFD, 0);625 _ = try os.fcntl(file.handle, os.F.SETFD, 0);
626 const flags = try os.fcntl(file.handle, os.F_GETFD, 0);626 const flags = try os.fcntl(file.handle, os.F.GETFD, 0);
627 try expect((flags & os.FD_CLOEXEC) == 0);627 try expect((flags & os.FD_CLOEXEC) == 0);
628 }628 }
629 {629 {
630 _ = try os.fcntl(file.handle, os.F_SETFD, os.FD_CLOEXEC);630 _ = try os.fcntl(file.handle, os.F.SETFD, os.FD_CLOEXEC);
631 const flags = try os.fcntl(file.handle, os.F_GETFD, 0);631 const flags = try os.fcntl(file.handle, os.F.GETFD, 0);
632 try expect((flags & os.FD_CLOEXEC) != 0);632 try expect((flags & os.FD_CLOEXEC) != 0);
633 }633 }
634}634}
...@@ -676,7 +676,7 @@ test "fsync" {...@@ -676,7 +676,7 @@ test "fsync" {
676}676}
677677
678test "getrlimit and setrlimit" {678test "getrlimit and setrlimit" {
679 if (!@hasDecl(os, "rlimit")) {679 if (!@hasDecl(os.system, "rlimit")) {
680 return error.SkipZigTest;680 return error.SkipZigTest;
681 }681 }
682682
...@@ -698,7 +698,7 @@ test "shutdown socket" {...@@ -698,7 +698,7 @@ test "shutdown socket" {
698 std.os.windows.WSACleanup() catch unreachable;698 std.os.windows.WSACleanup() catch unreachable;
699 }699 }
700 }700 }
701 const sock = try os.socket(os.AF_INET, os.SOCK_STREAM, 0);701 const sock = try os.socket(os.AF.INET, os.SOCK.STREAM, 0);
702 os.shutdown(sock, .both) catch |err| switch (err) {702 os.shutdown(sock, .both) catch |err| switch (err) {
703 error.SocketNotConnected => {},703 error.SocketNotConnected => {},
704 else => |e| return e,704 else => |e| return e,
...@@ -722,11 +722,11 @@ test "sigaction" {...@@ -722,11 +722,11 @@ test "sigaction" {
722 // Check that we received the correct signal.722 // Check that we received the correct signal.
723 switch (native_os) {723 switch (native_os) {
724 .netbsd => {724 .netbsd => {
725 if (sig == os.SIGUSR1 and sig == info.info.signo)725 if (sig == os.SIG.USR1 and sig == info.info.signo)
726 signal_test_failed = false;726 signal_test_failed = false;
727 },727 },
728 else => {728 else => {
729 if (sig == os.SIGUSR1 and sig == info.signo)729 if (sig == os.SIG.USR1 and sig == info.signo)
730 signal_test_failed = false;730 signal_test_failed = false;
731 },731 },
732 }732 }
...@@ -736,21 +736,21 @@ test "sigaction" {...@@ -736,21 +736,21 @@ test "sigaction" {
736 var sa = os.Sigaction{736 var sa = os.Sigaction{
737 .handler = .{ .sigaction = S.handler },737 .handler = .{ .sigaction = S.handler },
738 .mask = os.empty_sigset,738 .mask = os.empty_sigset,
739 .flags = os.SA_SIGINFO | os.SA_RESETHAND,739 .flags = os.SA.SIGINFO | os.SA.RESETHAND,
740 };740 };
741 var old_sa: os.Sigaction = undefined;741 var old_sa: os.Sigaction = undefined;
742 // Install the new signal handler.742 // Install the new signal handler.
743 os.sigaction(os.SIGUSR1, &sa, null);743 os.sigaction(os.SIG.USR1, &sa, null);
744 // Check that we can read it back correctly.744 // Check that we can read it back correctly.
745 os.sigaction(os.SIGUSR1, null, &old_sa);745 os.sigaction(os.SIG.USR1, null, &old_sa);
746 try testing.expectEqual(S.handler, old_sa.handler.sigaction.?);746 try testing.expectEqual(S.handler, old_sa.handler.sigaction.?);
747 try testing.expect((old_sa.flags & os.SA_SIGINFO) != 0);747 try testing.expect((old_sa.flags & os.SA.SIGINFO) != 0);
748 // Invoke the handler.748 // Invoke the handler.
749 try os.raise(os.SIGUSR1);749 try os.raise(os.SIG.USR1);
750 try testing.expect(signal_test_failed == false);750 try testing.expect(signal_test_failed == false);
751 // Check if the handler has been correctly reset to SIG_DFL751 // Check if the handler has been correctly reset to SIG_DFL
752 os.sigaction(os.SIGUSR1, null, &old_sa);752 os.sigaction(os.SIG.USR1, null, &old_sa);
753 try testing.expectEqual(os.SIG_DFL, old_sa.handler.sigaction);753 try testing.expectEqual(os.SIG.DFL, old_sa.handler.sigaction);
754}754}
755755
756test "dup & dup2" {756test "dup & dup2" {
lib/std/os/wasi.zig+480-4
...@@ -4,8 +4,6 @@...@@ -4,8 +4,6 @@
4const std = @import("std");4const std = @import("std");
5const assert = std.debug.assert;5const assert = std.debug.assert;
66
7pub usingnamespace @import("bits.zig");
8
9comptime {7comptime {
10 assert(@alignOf(i8) == 1);8 assert(@alignOf(i8) == 1);
11 assert(@alignOf(u8) == 1);9 assert(@alignOf(u8) == 1);
...@@ -17,8 +15,8 @@ comptime {...@@ -17,8 +15,8 @@ comptime {
17 // assert(@alignOf(u64) == 8);15 // assert(@alignOf(u64) == 8);
18}16}
1917
20pub const iovec_t = iovec;18pub const iovec_t = std.os.iovec;
21pub const ciovec_t = iovec_const;19pub const ciovec_t = std.os.iovec_const;
2220
23pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;21pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
24pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;22pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
...@@ -81,3 +79,481 @@ pub extern "wasi_snapshot_preview1" fn sock_shutdown(sock: fd_t, how: sdflags_t)...@@ -81,3 +79,481 @@ pub extern "wasi_snapshot_preview1" fn sock_shutdown(sock: fd_t, how: sdflags_t)
81pub fn getErrno(r: errno_t) errno_t {79pub fn getErrno(r: errno_t) errno_t {
82 return r;80 return r;
83}81}
82
83pub const STDIN_FILENO = 0;
84pub const STDOUT_FILENO = 1;
85pub const STDERR_FILENO = 2;
86
87pub const mode_t = u32;
88
89pub const time_t = i64; // match https://github.com/CraneStation/wasi-libc
90
91pub const timespec = struct {
92 tv_sec: time_t,
93 tv_nsec: isize,
94
95 pub fn fromTimestamp(tm: timestamp_t) timespec {
96 const tv_sec: timestamp_t = tm / 1_000_000_000;
97 const tv_nsec = tm - tv_sec * 1_000_000_000;
98 return timespec{
99 .tv_sec = @intCast(time_t, tv_sec),
100 .tv_nsec = @intCast(isize, tv_nsec),
101 };
102 }
103
104 pub fn toTimestamp(ts: timespec) timestamp_t {
105 const tm = @intCast(timestamp_t, ts.tv_sec * 1_000_000_000) + @intCast(timestamp_t, ts.tv_nsec);
106 return tm;
107 }
108};
109
110pub const Stat = struct {
111 dev: device_t,
112 ino: inode_t,
113 mode: mode_t,
114 filetype: filetype_t,
115 nlink: linkcount_t,
116 size: filesize_t,
117 atim: timespec,
118 mtim: timespec,
119 ctim: timespec,
120
121 const Self = @This();
122
123 pub fn fromFilestat(stat: filestat_t) Self {
124 return Self{
125 .dev = stat.dev,
126 .ino = stat.ino,
127 .mode = 0,
128 .filetype = stat.filetype,
129 .nlink = stat.nlink,
130 .size = stat.size,
131 .atim = stat.atime(),
132 .mtim = stat.mtime(),
133 .ctim = stat.ctime(),
134 };
135 }
136
137 pub fn atime(self: Self) timespec {
138 return self.atim;
139 }
140
141 pub fn mtime(self: Self) timespec {
142 return self.mtim;
143 }
144
145 pub fn ctime(self: Self) timespec {
146 return self.ctim;
147 }
148};
149
150pub const IOV_MAX = 1024;
151
152pub const AT = struct {
153 pub const REMOVEDIR: u32 = 0x4;
154 pub const FDCWD: fd_t = -2;
155};
156
157// As defined in the wasi_snapshot_preview1 spec file:
158// https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx
159pub const advice_t = u8;
160pub const ADVICE_NORMAL: advice_t = 0;
161pub const ADVICE_SEQUENTIAL: advice_t = 1;
162pub const ADVICE_RANDOM: advice_t = 2;
163pub const ADVICE_WILLNEED: advice_t = 3;
164pub const ADVICE_DONTNEED: advice_t = 4;
165pub const ADVICE_NOREUSE: advice_t = 5;
166
167pub const clockid_t = u32;
168pub const CLOCK = struct {
169 pub const REALTIME: clockid_t = 0;
170 pub const MONOTONIC: clockid_t = 1;
171 pub const PROCESS_CPUTIME_ID: clockid_t = 2;
172 pub const THREAD_CPUTIME_ID: clockid_t = 3;
173};
174
175pub const device_t = u64;
176
177pub const dircookie_t = u64;
178pub const DIRCOOKIE_START: dircookie_t = 0;
179
180pub const dirnamlen_t = u32;
181
182pub const dirent_t = extern struct {
183 d_next: dircookie_t,
184 d_ino: inode_t,
185 d_namlen: dirnamlen_t,
186 d_type: filetype_t,
187};
188
189pub const errno_t = enum(u16) {
190 SUCCESS = 0,
191 @"2BIG" = 1,
192 ACCES = 2,
193 ADDRINUSE = 3,
194 ADDRNOTAVAIL = 4,
195 AFNOSUPPORT = 5,
196 /// This is also the error code used for `WOULDBLOCK`.
197 AGAIN = 6,
198 ALREADY = 7,
199 BADF = 8,
200 BADMSG = 9,
201 BUSY = 10,
202 CANCELED = 11,
203 CHILD = 12,
204 CONNABORTED = 13,
205 CONNREFUSED = 14,
206 CONNRESET = 15,
207 DEADLK = 16,
208 DESTADDRREQ = 17,
209 DOM = 18,
210 DQUOT = 19,
211 EXIST = 20,
212 FAULT = 21,
213 FBIG = 22,
214 HOSTUNREACH = 23,
215 IDRM = 24,
216 ILSEQ = 25,
217 INPROGRESS = 26,
218 INTR = 27,
219 INVAL = 28,
220 IO = 29,
221 ISCONN = 30,
222 ISDIR = 31,
223 LOOP = 32,
224 MFILE = 33,
225 MLINK = 34,
226 MSGSIZE = 35,
227 MULTIHOP = 36,
228 NAMETOOLONG = 37,
229 NETDOWN = 38,
230 NETRESET = 39,
231 NETUNREACH = 40,
232 NFILE = 41,
233 NOBUFS = 42,
234 NODEV = 43,
235 NOENT = 44,
236 NOEXEC = 45,
237 NOLCK = 46,
238 NOLINK = 47,
239 NOMEM = 48,
240 NOMSG = 49,
241 NOPROTOOPT = 50,
242 NOSPC = 51,
243 NOSYS = 52,
244 NOTCONN = 53,
245 NOTDIR = 54,
246 NOTEMPTY = 55,
247 NOTRECOVERABLE = 56,
248 NOTSOCK = 57,
249 /// This is also the code used for `NOTSUP`.
250 OPNOTSUPP = 58,
251 NOTTY = 59,
252 NXIO = 60,
253 OVERFLOW = 61,
254 OWNERDEAD = 62,
255 PERM = 63,
256 PIPE = 64,
257 PROTO = 65,
258 PROTONOSUPPORT = 66,
259 PROTOTYPE = 67,
260 RANGE = 68,
261 ROFS = 69,
262 SPIPE = 70,
263 SRCH = 71,
264 STALE = 72,
265 TIMEDOUT = 73,
266 TXTBSY = 74,
267 XDEV = 75,
268 NOTCAPABLE = 76,
269 _,
270};
271pub const E = errno_t;
272
273pub const event_t = extern struct {
274 userdata: userdata_t,
275 @"error": errno_t,
276 @"type": eventtype_t,
277 fd_readwrite: eventfdreadwrite_t,
278};
279
280pub const eventfdreadwrite_t = extern struct {
281 nbytes: filesize_t,
282 flags: eventrwflags_t,
283};
284
285pub const eventrwflags_t = u16;
286pub const EVENT_FD_READWRITE_HANGUP: eventrwflags_t = 0x0001;
287
288pub const eventtype_t = u8;
289pub const EVENTTYPE_CLOCK: eventtype_t = 0;
290pub const EVENTTYPE_FD_READ: eventtype_t = 1;
291pub const EVENTTYPE_FD_WRITE: eventtype_t = 2;
292
293pub const exitcode_t = u32;
294
295pub const fd_t = i32;
296
297pub const fdflags_t = u16;
298pub const FDFLAG = struct {
299 pub const APPEND: fdflags_t = 0x0001;
300 pub const DSYNC: fdflags_t = 0x0002;
301 pub const NONBLOCK: fdflags_t = 0x0004;
302 pub const RSYNC: fdflags_t = 0x0008;
303 pub const SYNC: fdflags_t = 0x0010;
304};
305
306pub const fdstat_t = extern struct {
307 fs_filetype: filetype_t,
308 fs_flags: fdflags_t,
309 fs_rights_base: rights_t,
310 fs_rights_inheriting: rights_t,
311};
312
313pub const filedelta_t = i64;
314
315pub const filesize_t = u64;
316
317pub const filestat_t = extern struct {
318 dev: device_t,
319 ino: inode_t,
320 filetype: filetype_t,
321 nlink: linkcount_t,
322 size: filesize_t,
323 atim: timestamp_t,
324 mtim: timestamp_t,
325 ctim: timestamp_t,
326
327 pub fn atime(self: filestat_t) timespec {
328 return timespec.fromTimestamp(self.atim);
329 }
330
331 pub fn mtime(self: filestat_t) timespec {
332 return timespec.fromTimestamp(self.mtim);
333 }
334
335 pub fn ctime(self: filestat_t) timespec {
336 return timespec.fromTimestamp(self.ctim);
337 }
338};
339
340/// Also known as `FILETYPE`.
341pub const filetype_t = enum(u8) {
342 UNKNOWN,
343 BLOCK_DEVICE,
344 CHARACTER_DEVICE,
345 DIRECTORY,
346 REGULAR_FILE,
347 SOCKET_DGRAM,
348 SOCKET_STREAM,
349 SYMBOLIC_LINK,
350 _,
351};
352
353pub const fstflags_t = u16;
354pub const FILESTAT_SET_ATIM: fstflags_t = 0x0001;
355pub const FILESTAT_SET_ATIM_NOW: fstflags_t = 0x0002;
356pub const FILESTAT_SET_MTIM: fstflags_t = 0x0004;
357pub const FILESTAT_SET_MTIM_NOW: fstflags_t = 0x0008;
358
359pub const inode_t = u64;
360pub const ino_t = inode_t;
361
362pub const linkcount_t = u64;
363
364pub const lookupflags_t = u32;
365pub const LOOKUP_SYMLINK_FOLLOW: lookupflags_t = 0x00000001;
366
367pub const oflags_t = u16;
368pub const O = struct {
369 pub const CREAT: oflags_t = 0x0001;
370 pub const DIRECTORY: oflags_t = 0x0002;
371 pub const EXCL: oflags_t = 0x0004;
372 pub const TRUNC: oflags_t = 0x0008;
373};
374
375pub const preopentype_t = u8;
376pub const PREOPENTYPE_DIR: preopentype_t = 0;
377
378pub const prestat_t = extern struct {
379 pr_type: preopentype_t,
380 u: prestat_u_t,
381};
382
383pub const prestat_dir_t = extern struct {
384 pr_name_len: usize,
385};
386
387pub const prestat_u_t = extern union {
388 dir: prestat_dir_t,
389};
390
391pub const riflags_t = u16;
392pub const roflags_t = u16;
393
394pub const SOCK = struct {
395 pub const RECV_PEEK: riflags_t = 0x0001;
396 pub const RECV_WAITALL: riflags_t = 0x0002;
397
398 pub const RECV_DATA_TRUNCATED: roflags_t = 0x0001;
399};
400
401pub const rights_t = u64;
402pub const RIGHT = struct {
403 pub const FD_DATASYNC: rights_t = 0x0000000000000001;
404 pub const FD_READ: rights_t = 0x0000000000000002;
405 pub const FD_SEEK: rights_t = 0x0000000000000004;
406 pub const FD_FDSTAT_SET_FLAGS: rights_t = 0x0000000000000008;
407 pub const FD_SYNC: rights_t = 0x0000000000000010;
408 pub const FD_TELL: rights_t = 0x0000000000000020;
409 pub const FD_WRITE: rights_t = 0x0000000000000040;
410 pub const FD_ADVISE: rights_t = 0x0000000000000080;
411 pub const FD_ALLOCATE: rights_t = 0x0000000000000100;
412 pub const PATH_CREATE_DIRECTORY: rights_t = 0x0000000000000200;
413 pub const PATH_CREATE_FILE: rights_t = 0x0000000000000400;
414 pub const PATH_LINK_SOURCE: rights_t = 0x0000000000000800;
415 pub const PATH_LINK_TARGET: rights_t = 0x0000000000001000;
416 pub const PATH_OPEN: rights_t = 0x0000000000002000;
417 pub const FD_READDIR: rights_t = 0x0000000000004000;
418 pub const PATH_READLINK: rights_t = 0x0000000000008000;
419 pub const PATH_RENAME_SOURCE: rights_t = 0x0000000000010000;
420 pub const PATH_RENAME_TARGET: rights_t = 0x0000000000020000;
421 pub const PATH_FILESTAT_GET: rights_t = 0x0000000000040000;
422 pub const PATH_FILESTAT_SET_SIZE: rights_t = 0x0000000000080000;
423 pub const PATH_FILESTAT_SET_TIMES: rights_t = 0x0000000000100000;
424 pub const FD_FILESTAT_GET: rights_t = 0x0000000000200000;
425 pub const FD_FILESTAT_SET_SIZE: rights_t = 0x0000000000400000;
426 pub const FD_FILESTAT_SET_TIMES: rights_t = 0x0000000000800000;
427 pub const PATH_SYMLINK: rights_t = 0x0000000001000000;
428 pub const PATH_REMOVE_DIRECTORY: rights_t = 0x0000000002000000;
429 pub const PATH_UNLINK_FILE: rights_t = 0x0000000004000000;
430 pub const POLL_FD_READWRITE: rights_t = 0x0000000008000000;
431 pub const SOCK_SHUTDOWN: rights_t = 0x0000000010000000;
432 pub const ALL: rights_t = FD_DATASYNC |
433 FD_READ |
434 FD_SEEK |
435 FD_FDSTAT_SET_FLAGS |
436 FD_SYNC |
437 FD_TELL |
438 FD_WRITE |
439 FD_ADVISE |
440 FD_ALLOCATE |
441 PATH_CREATE_DIRECTORY |
442 PATH_CREATE_FILE |
443 PATH_LINK_SOURCE |
444 PATH_LINK_TARGET |
445 PATH_OPEN |
446 FD_READDIR |
447 PATH_READLINK |
448 PATH_RENAME_SOURCE |
449 PATH_RENAME_TARGET |
450 PATH_FILESTAT_GET |
451 PATH_FILESTAT_SET_SIZE |
452 PATH_FILESTAT_SET_TIMES |
453 FD_FILESTAT_GET |
454 FD_FILESTAT_SET_SIZE |
455 FD_FILESTAT_SET_TIMES |
456 PATH_SYMLINK |
457 PATH_REMOVE_DIRECTORY |
458 PATH_UNLINK_FILE |
459 POLL_FD_READWRITE |
460 SOCK_SHUTDOWN;
461};
462
463pub const sdflags_t = u8;
464pub const SHUT = struct {
465 pub const RD: sdflags_t = 0x01;
466 pub const WR: sdflags_t = 0x02;
467};
468
469pub const siflags_t = u16;
470
471pub const signal_t = u8;
472pub const SIGNONE: signal_t = 0;
473pub const SIGHUP: signal_t = 1;
474pub const SIGINT: signal_t = 2;
475pub const SIGQUIT: signal_t = 3;
476pub const SIGILL: signal_t = 4;
477pub const SIGTRAP: signal_t = 5;
478pub const SIGABRT: signal_t = 6;
479pub const SIGBUS: signal_t = 7;
480pub const SIGFPE: signal_t = 8;
481pub const SIGKILL: signal_t = 9;
482pub const SIGUSR1: signal_t = 10;
483pub const SIGSEGV: signal_t = 11;
484pub const SIGUSR2: signal_t = 12;
485pub const SIGPIPE: signal_t = 13;
486pub const SIGALRM: signal_t = 14;
487pub const SIGTERM: signal_t = 15;
488pub const SIGCHLD: signal_t = 16;
489pub const SIGCONT: signal_t = 17;
490pub const SIGSTOP: signal_t = 18;
491pub const SIGTSTP: signal_t = 19;
492pub const SIGTTIN: signal_t = 20;
493pub const SIGTTOU: signal_t = 21;
494pub const SIGURG: signal_t = 22;
495pub const SIGXCPU: signal_t = 23;
496pub const SIGXFSZ: signal_t = 24;
497pub const SIGVTALRM: signal_t = 25;
498pub const SIGPROF: signal_t = 26;
499pub const SIGWINCH: signal_t = 27;
500pub const SIGPOLL: signal_t = 28;
501pub const SIGPWR: signal_t = 29;
502pub const SIGSYS: signal_t = 30;
503
504pub const subclockflags_t = u16;
505pub const SUBSCRIPTION_CLOCK_ABSTIME: subclockflags_t = 0x0001;
506
507pub const subscription_t = extern struct {
508 userdata: userdata_t,
509 u: subscription_u_t,
510};
511
512pub const subscription_clock_t = extern struct {
513 id: clockid_t,
514 timeout: timestamp_t,
515 precision: timestamp_t,
516 flags: subclockflags_t,
517};
518
519pub const subscription_fd_readwrite_t = extern struct {
520 fd: fd_t,
521};
522
523pub const subscription_u_t = extern struct {
524 tag: eventtype_t,
525 u: subscription_u_u_t,
526};
527
528pub const subscription_u_u_t = extern union {
529 clock: subscription_clock_t,
530 fd_read: subscription_fd_readwrite_t,
531 fd_write: subscription_fd_readwrite_t,
532};
533
534pub const timestamp_t = u64;
535
536pub const userdata_t = u64;
537
538/// Also known as `WHENCE`.
539pub const whence_t = enum(u8) { SET, CUR, END };
540
541pub const S = struct {
542 pub const IEXEC = @compileError("TODO audit this");
543 pub const IFBLK = 0x6000;
544 pub const IFCHR = 0x2000;
545 pub const IFDIR = 0x4000;
546 pub const IFIFO = 0xc000;
547 pub const IFLNK = 0xa000;
548 pub const IFMT = IFBLK | IFCHR | IFDIR | IFIFO | IFLNK | IFREG | IFSOCK;
549 pub const IFREG = 0x8000;
550 // There's no concept of UNIX domain socket but we define this value here in order to line with other OSes.
551 pub const IFSOCK = 0x1;
552};
553
554pub const LOCK = struct {
555 pub const SH = 0x1;
556 pub const EX = 0x2;
557 pub const NB = 0x4;
558 pub const UN = 0x8;
559};
lib/std/os/windows.zig+1646-16
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1// This file contains thin wrappers around Windows-specific APIs, with these1//! This file contains thin wrappers around Windows-specific APIs, with these
2// specific goals in mind:2//! specific goals in mind:
3// * Convert "errno"-style error codes into Zig errors.3//! * Convert "errno"-style error codes into Zig errors.
4// * When null-terminated or UTF16LE byte buffers are required, provide APIs which accept4//! * When null-terminated or UTF16LE byte buffers are required, provide APIs which accept
5// slices as well as APIs which accept null-terminated UTF16LE byte buffers.5//! slices as well as APIs which accept null-terminated UTF16LE byte buffers.
66
7const builtin = @import("builtin");7const builtin = @import("builtin");
8const std = @import("../std.zig");8const std = @import("../std.zig");
...@@ -10,6 +10,13 @@ const mem = std.mem;...@@ -10,6 +10,13 @@ const mem = std.mem;
10const assert = std.debug.assert;10const assert = std.debug.assert;
11const math = std.math;11const math = std.math;
12const maxInt = std.math.maxInt;12const maxInt = std.math.maxInt;
13const native_arch = builtin.cpu.arch;
14
15test {
16 if (builtin.os.tag == .windows) {
17 _ = @import("windows/test.zig");
18 }
19}
1320
14pub const advapi32 = @import("windows/advapi32.zig");21pub const advapi32 = @import("windows/advapi32.zig");
15pub const kernel32 = @import("windows/kernel32.zig");22pub const kernel32 = @import("windows/kernel32.zig");
...@@ -22,8 +29,6 @@ pub const ws2_32 = @import("windows/ws2_32.zig");...@@ -22,8 +29,6 @@ pub const ws2_32 = @import("windows/ws2_32.zig");
22pub const gdi32 = @import("windows/gdi32.zig");29pub const gdi32 = @import("windows/gdi32.zig");
23pub const winmm = @import("windows/winmm.zig");30pub const winmm = @import("windows/winmm.zig");
2431
25pub usingnamespace @import("windows/bits.zig");
26
27pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize));32pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize));
2833
29pub const OpenError = error{34pub const OpenError = error{
...@@ -1017,7 +1022,7 @@ pub fn QueryObjectName(...@@ -1017,7 +1022,7 @@ pub fn QueryObjectName(
1017 }1022 }
1018}1023}
1019test "QueryObjectName" {1024test "QueryObjectName" {
1020 if (comptime builtin.target.os.tag != .windows)1025 if (builtin.os.tag != .windows)
1021 return;1026 return;
10221027
1023 //any file will do; canonicalization works on NTFS junctions and symlinks, hardlinks remain separate paths.1028 //any file will do; canonicalization works on NTFS junctions and symlinks, hardlinks remain separate paths.
...@@ -1171,7 +1176,7 @@ pub fn GetFinalPathNameByHandle(...@@ -1171,7 +1176,7 @@ pub fn GetFinalPathNameByHandle(
1171}1176}
11721177
1173test "GetFinalPathNameByHandle" {1178test "GetFinalPathNameByHandle" {
1174 if (comptime builtin.target.os.tag != .windows)1179 if (builtin.os.tag != .windows)
1175 return;1180 return;
11761181
1177 //any file will do1182 //any file will do
...@@ -1416,8 +1421,8 @@ pub fn WSAIoctl(...@@ -1416,8 +1421,8 @@ pub fn WSAIoctl(
1416 dwIoControlCode: DWORD,1421 dwIoControlCode: DWORD,
1417 inBuffer: ?[]const u8,1422 inBuffer: ?[]const u8,
1418 outBuffer: []u8,1423 outBuffer: []u8,
1419 overlapped: ?*ws2_32.WSAOVERLAPPED,1424 overlapped: ?*OVERLAPPED,
1420 completionRoutine: ?ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE,1425 completionRoutine: ?ws2_32.LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1421) !DWORD {1426) !DWORD {
1422 var bytes: DWORD = undefined;1427 var bytes: DWORD = undefined;
1423 switch (ws2_32.WSAIoctl(1428 switch (ws2_32.WSAIoctl(
...@@ -1720,7 +1725,7 @@ pub fn UnlockFile(...@@ -1720,7 +1725,7 @@ pub fn UnlockFile(
1720}1725}
17211726
1722pub fn teb() *TEB {1727pub fn teb() *TEB {
1723 return switch (builtin.target.cpu.arch) {1728 return switch (native_arch) {
1724 .i386 => asm volatile (1729 .i386 => asm volatile (
1725 \\ movl %%fs:0x18, %[ptr]1730 \\ movl %%fs:0x18, %[ptr]
1726 : [ptr] "=r" (-> *TEB),1731 : [ptr] "=r" (-> *TEB),
...@@ -2025,8 +2030,1633 @@ pub fn GetThreadDescription(hThread: HANDLE, ppszThreadDescription: *LPWSTR) !vo...@@ -2025,8 +2030,1633 @@ pub fn GetThreadDescription(hThread: HANDLE, ppszThreadDescription: *LPWSTR) !vo
2025 }2030 }
2026}2031}
20272032
2028test "" {2033pub const Win32Error = @import("windows/win32error.zig").Win32Error;
2029 if (builtin.os.tag == .windows) {2034pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS;
2030 _ = @import("windows/test.zig");2035pub const LANG = @import("windows/lang.zig");
2031 }2036pub const SUBLANG = @import("windows/sublang.zig");
2037
2038/// The standard input device. Initially, this is the console input buffer, CONIN$.
2039pub const STD_INPUT_HANDLE = maxInt(DWORD) - 10 + 1;
2040
2041/// The standard output device. Initially, this is the active console screen buffer, CONOUT$.
2042pub const STD_OUTPUT_HANDLE = maxInt(DWORD) - 11 + 1;
2043
2044/// The standard error device. Initially, this is the active console screen buffer, CONOUT$.
2045pub const STD_ERROR_HANDLE = maxInt(DWORD) - 12 + 1;
2046
2047pub const WINAPI: std.builtin.CallingConvention = if (native_arch == .i386)
2048 .Stdcall
2049else
2050 .C;
2051
2052pub const BOOL = c_int;
2053pub const BOOLEAN = BYTE;
2054pub const BYTE = u8;
2055pub const CHAR = u8;
2056pub const UCHAR = u8;
2057pub const FLOAT = f32;
2058pub const HANDLE = *c_void;
2059pub const HCRYPTPROV = ULONG_PTR;
2060pub const ATOM = u16;
2061pub const HBRUSH = *opaque {};
2062pub const HCURSOR = *opaque {};
2063pub const HICON = *opaque {};
2064pub const HINSTANCE = *opaque {};
2065pub const HMENU = *opaque {};
2066pub const HMODULE = *opaque {};
2067pub const HWND = *opaque {};
2068pub const HDC = *opaque {};
2069pub const HGLRC = *opaque {};
2070pub const FARPROC = *opaque {};
2071pub const INT = c_int;
2072pub const LPCSTR = [*:0]const CHAR;
2073pub const LPCVOID = *const c_void;
2074pub const LPSTR = [*:0]CHAR;
2075pub const LPVOID = *c_void;
2076pub const LPWSTR = [*:0]WCHAR;
2077pub const LPCWSTR = [*:0]const WCHAR;
2078pub const PVOID = *c_void;
2079pub const PWSTR = [*:0]WCHAR;
2080pub const SIZE_T = usize;
2081pub const UINT = c_uint;
2082pub const ULONG_PTR = usize;
2083pub const LONG_PTR = isize;
2084pub const DWORD_PTR = ULONG_PTR;
2085pub const WCHAR = u16;
2086pub const WORD = u16;
2087pub const DWORD = u32;
2088pub const DWORD64 = u64;
2089pub const LARGE_INTEGER = i64;
2090pub const ULARGE_INTEGER = u64;
2091pub const USHORT = u16;
2092pub const SHORT = i16;
2093pub const ULONG = u32;
2094pub const LONG = i32;
2095pub const ULONGLONG = u64;
2096pub const LONGLONG = i64;
2097pub const HLOCAL = HANDLE;
2098pub const LANGID = c_ushort;
2099
2100pub const WPARAM = usize;
2101pub const LPARAM = LONG_PTR;
2102pub const LRESULT = LONG_PTR;
2103
2104pub const va_list = *opaque {};
2105
2106pub const TRUE = 1;
2107pub const FALSE = 0;
2108
2109pub const DEVICE_TYPE = ULONG;
2110pub const FILE_DEVICE_BEEP: DEVICE_TYPE = 0x0001;
2111pub const FILE_DEVICE_CD_ROM: DEVICE_TYPE = 0x0002;
2112pub const FILE_DEVICE_CD_ROM_FILE_SYSTEM: DEVICE_TYPE = 0x0003;
2113pub const FILE_DEVICE_CONTROLLER: DEVICE_TYPE = 0x0004;
2114pub const FILE_DEVICE_DATALINK: DEVICE_TYPE = 0x0005;
2115pub const FILE_DEVICE_DFS: DEVICE_TYPE = 0x0006;
2116pub const FILE_DEVICE_DISK: DEVICE_TYPE = 0x0007;
2117pub const FILE_DEVICE_DISK_FILE_SYSTEM: DEVICE_TYPE = 0x0008;
2118pub const FILE_DEVICE_FILE_SYSTEM: DEVICE_TYPE = 0x0009;
2119pub const FILE_DEVICE_INPORT_PORT: DEVICE_TYPE = 0x000a;
2120pub const FILE_DEVICE_KEYBOARD: DEVICE_TYPE = 0x000b;
2121pub const FILE_DEVICE_MAILSLOT: DEVICE_TYPE = 0x000c;
2122pub const FILE_DEVICE_MIDI_IN: DEVICE_TYPE = 0x000d;
2123pub const FILE_DEVICE_MIDI_OUT: DEVICE_TYPE = 0x000e;
2124pub const FILE_DEVICE_MOUSE: DEVICE_TYPE = 0x000f;
2125pub const FILE_DEVICE_MULTI_UNC_PROVIDER: DEVICE_TYPE = 0x0010;
2126pub const FILE_DEVICE_NAMED_PIPE: DEVICE_TYPE = 0x0011;
2127pub const FILE_DEVICE_NETWORK: DEVICE_TYPE = 0x0012;
2128pub const FILE_DEVICE_NETWORK_BROWSER: DEVICE_TYPE = 0x0013;
2129pub const FILE_DEVICE_NETWORK_FILE_SYSTEM: DEVICE_TYPE = 0x0014;
2130pub const FILE_DEVICE_NULL: DEVICE_TYPE = 0x0015;
2131pub const FILE_DEVICE_PARALLEL_PORT: DEVICE_TYPE = 0x0016;
2132pub const FILE_DEVICE_PHYSICAL_NETCARD: DEVICE_TYPE = 0x0017;
2133pub const FILE_DEVICE_PRINTER: DEVICE_TYPE = 0x0018;
2134pub const FILE_DEVICE_SCANNER: DEVICE_TYPE = 0x0019;
2135pub const FILE_DEVICE_SERIAL_MOUSE_PORT: DEVICE_TYPE = 0x001a;
2136pub const FILE_DEVICE_SERIAL_PORT: DEVICE_TYPE = 0x001b;
2137pub const FILE_DEVICE_SCREEN: DEVICE_TYPE = 0x001c;
2138pub const FILE_DEVICE_SOUND: DEVICE_TYPE = 0x001d;
2139pub const FILE_DEVICE_STREAMS: DEVICE_TYPE = 0x001e;
2140pub const FILE_DEVICE_TAPE: DEVICE_TYPE = 0x001f;
2141pub const FILE_DEVICE_TAPE_FILE_SYSTEM: DEVICE_TYPE = 0x0020;
2142pub const FILE_DEVICE_TRANSPORT: DEVICE_TYPE = 0x0021;
2143pub const FILE_DEVICE_UNKNOWN: DEVICE_TYPE = 0x0022;
2144pub const FILE_DEVICE_VIDEO: DEVICE_TYPE = 0x0023;
2145pub const FILE_DEVICE_VIRTUAL_DISK: DEVICE_TYPE = 0x0024;
2146pub const FILE_DEVICE_WAVE_IN: DEVICE_TYPE = 0x0025;
2147pub const FILE_DEVICE_WAVE_OUT: DEVICE_TYPE = 0x0026;
2148pub const FILE_DEVICE_8042_PORT: DEVICE_TYPE = 0x0027;
2149pub const FILE_DEVICE_NETWORK_REDIRECTOR: DEVICE_TYPE = 0x0028;
2150pub const FILE_DEVICE_BATTERY: DEVICE_TYPE = 0x0029;
2151pub const FILE_DEVICE_BUS_EXTENDER: DEVICE_TYPE = 0x002a;
2152pub const FILE_DEVICE_MODEM: DEVICE_TYPE = 0x002b;
2153pub const FILE_DEVICE_VDM: DEVICE_TYPE = 0x002c;
2154pub const FILE_DEVICE_MASS_STORAGE: DEVICE_TYPE = 0x002d;
2155pub const FILE_DEVICE_SMB: DEVICE_TYPE = 0x002e;
2156pub const FILE_DEVICE_KS: DEVICE_TYPE = 0x002f;
2157pub const FILE_DEVICE_CHANGER: DEVICE_TYPE = 0x0030;
2158pub const FILE_DEVICE_SMARTCARD: DEVICE_TYPE = 0x0031;
2159pub const FILE_DEVICE_ACPI: DEVICE_TYPE = 0x0032;
2160pub const FILE_DEVICE_DVD: DEVICE_TYPE = 0x0033;
2161pub const FILE_DEVICE_FULLSCREEN_VIDEO: DEVICE_TYPE = 0x0034;
2162pub const FILE_DEVICE_DFS_FILE_SYSTEM: DEVICE_TYPE = 0x0035;
2163pub const FILE_DEVICE_DFS_VOLUME: DEVICE_TYPE = 0x0036;
2164pub const FILE_DEVICE_SERENUM: DEVICE_TYPE = 0x0037;
2165pub const FILE_DEVICE_TERMSRV: DEVICE_TYPE = 0x0038;
2166pub const FILE_DEVICE_KSEC: DEVICE_TYPE = 0x0039;
2167pub const FILE_DEVICE_FIPS: DEVICE_TYPE = 0x003a;
2168pub const FILE_DEVICE_INFINIBAND: DEVICE_TYPE = 0x003b;
2169// TODO: missing values?
2170pub const FILE_DEVICE_VMBUS: DEVICE_TYPE = 0x003e;
2171pub const FILE_DEVICE_CRYPT_PROVIDER: DEVICE_TYPE = 0x003f;
2172pub const FILE_DEVICE_WPD: DEVICE_TYPE = 0x0040;
2173pub const FILE_DEVICE_BLUETOOTH: DEVICE_TYPE = 0x0041;
2174pub const FILE_DEVICE_MT_COMPOSITE: DEVICE_TYPE = 0x0042;
2175pub const FILE_DEVICE_MT_TRANSPORT: DEVICE_TYPE = 0x0043;
2176pub const FILE_DEVICE_BIOMETRIC: DEVICE_TYPE = 0x0044;
2177pub const FILE_DEVICE_PMI: DEVICE_TYPE = 0x0045;
2178pub const FILE_DEVICE_EHSTOR: DEVICE_TYPE = 0x0046;
2179pub const FILE_DEVICE_DEVAPI: DEVICE_TYPE = 0x0047;
2180pub const FILE_DEVICE_GPIO: DEVICE_TYPE = 0x0048;
2181pub const FILE_DEVICE_USBEX: DEVICE_TYPE = 0x0049;
2182pub const FILE_DEVICE_CONSOLE: DEVICE_TYPE = 0x0050;
2183pub const FILE_DEVICE_NFP: DEVICE_TYPE = 0x0051;
2184pub const FILE_DEVICE_SYSENV: DEVICE_TYPE = 0x0052;
2185pub const FILE_DEVICE_VIRTUAL_BLOCK: DEVICE_TYPE = 0x0053;
2186pub const FILE_DEVICE_POINT_OF_SERVICE: DEVICE_TYPE = 0x0054;
2187pub const FILE_DEVICE_STORAGE_REPLICATION: DEVICE_TYPE = 0x0055;
2188pub const FILE_DEVICE_TRUST_ENV: DEVICE_TYPE = 0x0056;
2189pub const FILE_DEVICE_UCM: DEVICE_TYPE = 0x0057;
2190pub const FILE_DEVICE_UCMTCPCI: DEVICE_TYPE = 0x0058;
2191pub const FILE_DEVICE_PERSISTENT_MEMORY: DEVICE_TYPE = 0x0059;
2192pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a;
2193pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b;
2194pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c;
2195
2196/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes
2197pub const TransferType = enum(u2) {
2198 METHOD_BUFFERED = 0,
2199 METHOD_IN_DIRECT = 1,
2200 METHOD_OUT_DIRECT = 2,
2201 METHOD_NEITHER = 3,
2202};
2203
2204pub const FILE_ANY_ACCESS = 0;
2205pub const FILE_READ_ACCESS = 1;
2206pub const FILE_WRITE_ACCESS = 2;
2207
2208/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
2209pub fn CTL_CODE(deviceType: u16, function: u12, method: TransferType, access: u2) DWORD {
2210 return (@as(DWORD, deviceType) << 16) |
2211 (@as(DWORD, access) << 14) |
2212 (@as(DWORD, function) << 2) |
2213 @enumToInt(method);
2032}2214}
2215
2216pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
2217
2218pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
2219
2220pub const FILE_ALL_INFORMATION = extern struct {
2221 BasicInformation: FILE_BASIC_INFORMATION,
2222 StandardInformation: FILE_STANDARD_INFORMATION,
2223 InternalInformation: FILE_INTERNAL_INFORMATION,
2224 EaInformation: FILE_EA_INFORMATION,
2225 AccessInformation: FILE_ACCESS_INFORMATION,
2226 PositionInformation: FILE_POSITION_INFORMATION,
2227 ModeInformation: FILE_MODE_INFORMATION,
2228 AlignmentInformation: FILE_ALIGNMENT_INFORMATION,
2229 NameInformation: FILE_NAME_INFORMATION,
2230};
2231
2232pub const FILE_BASIC_INFORMATION = extern struct {
2233 CreationTime: LARGE_INTEGER,
2234 LastAccessTime: LARGE_INTEGER,
2235 LastWriteTime: LARGE_INTEGER,
2236 ChangeTime: LARGE_INTEGER,
2237 FileAttributes: ULONG,
2238};
2239
2240pub const FILE_STANDARD_INFORMATION = extern struct {
2241 AllocationSize: LARGE_INTEGER,
2242 EndOfFile: LARGE_INTEGER,
2243 NumberOfLinks: ULONG,
2244 DeletePending: BOOLEAN,
2245 Directory: BOOLEAN,
2246};
2247
2248pub const FILE_INTERNAL_INFORMATION = extern struct {
2249 IndexNumber: LARGE_INTEGER,
2250};
2251
2252pub const FILE_EA_INFORMATION = extern struct {
2253 EaSize: ULONG,
2254};
2255
2256pub const FILE_ACCESS_INFORMATION = extern struct {
2257 AccessFlags: ACCESS_MASK,
2258};
2259
2260pub const FILE_POSITION_INFORMATION = extern struct {
2261 CurrentByteOffset: LARGE_INTEGER,
2262};
2263
2264pub const FILE_END_OF_FILE_INFORMATION = extern struct {
2265 EndOfFile: LARGE_INTEGER,
2266};
2267
2268pub const FILE_MODE_INFORMATION = extern struct {
2269 Mode: ULONG,
2270};
2271
2272pub const FILE_ALIGNMENT_INFORMATION = extern struct {
2273 AlignmentRequirement: ULONG,
2274};
2275
2276pub const FILE_NAME_INFORMATION = extern struct {
2277 FileNameLength: ULONG,
2278 FileName: [1]WCHAR,
2279};
2280
2281pub const FILE_RENAME_INFORMATION = extern struct {
2282 ReplaceIfExists: BOOLEAN,
2283 RootDirectory: ?HANDLE,
2284 FileNameLength: ULONG,
2285 FileName: [1]WCHAR,
2286};
2287
2288pub const IO_STATUS_BLOCK = extern struct {
2289 // "DUMMYUNIONNAME" expands to "u"
2290 u: extern union {
2291 Status: NTSTATUS,
2292 Pointer: ?*c_void,
2293 },
2294 Information: ULONG_PTR,
2295};
2296
2297pub const FILE_INFORMATION_CLASS = enum(c_int) {
2298 FileDirectoryInformation = 1,
2299 FileFullDirectoryInformation,
2300 FileBothDirectoryInformation,
2301 FileBasicInformation,
2302 FileStandardInformation,
2303 FileInternalInformation,
2304 FileEaInformation,
2305 FileAccessInformation,
2306 FileNameInformation,
2307 FileRenameInformation,
2308 FileLinkInformation,
2309 FileNamesInformation,
2310 FileDispositionInformation,
2311 FilePositionInformation,
2312 FileFullEaInformation,
2313 FileModeInformation,
2314 FileAlignmentInformation,
2315 FileAllInformation,
2316 FileAllocationInformation,
2317 FileEndOfFileInformation,
2318 FileAlternateNameInformation,
2319 FileStreamInformation,
2320 FilePipeInformation,
2321 FilePipeLocalInformation,
2322 FilePipeRemoteInformation,
2323 FileMailslotQueryInformation,
2324 FileMailslotSetInformation,
2325 FileCompressionInformation,
2326 FileObjectIdInformation,
2327 FileCompletionInformation,
2328 FileMoveClusterInformation,
2329 FileQuotaInformation,
2330 FileReparsePointInformation,
2331 FileNetworkOpenInformation,
2332 FileAttributeTagInformation,
2333 FileTrackingInformation,
2334 FileIdBothDirectoryInformation,
2335 FileIdFullDirectoryInformation,
2336 FileValidDataLengthInformation,
2337 FileShortNameInformation,
2338 FileIoCompletionNotificationInformation,
2339 FileIoStatusBlockRangeInformation,
2340 FileIoPriorityHintInformation,
2341 FileSfioReserveInformation,
2342 FileSfioVolumeInformation,
2343 FileHardLinkInformation,
2344 FileProcessIdsUsingFileInformation,
2345 FileNormalizedNameInformation,
2346 FileNetworkPhysicalNameInformation,
2347 FileIdGlobalTxDirectoryInformation,
2348 FileIsRemoteDeviceInformation,
2349 FileUnusedInformation,
2350 FileNumaNodeInformation,
2351 FileStandardLinkInformation,
2352 FileRemoteProtocolInformation,
2353 FileRenameInformationBypassAccessCheck,
2354 FileLinkInformationBypassAccessCheck,
2355 FileVolumeNameInformation,
2356 FileIdInformation,
2357 FileIdExtdDirectoryInformation,
2358 FileReplaceCompletionInformation,
2359 FileHardLinkFullIdInformation,
2360 FileIdExtdBothDirectoryInformation,
2361 FileDispositionInformationEx,
2362 FileRenameInformationEx,
2363 FileRenameInformationExBypassAccessCheck,
2364 FileDesiredStorageClassInformation,
2365 FileStatInformation,
2366 FileMemoryPartitionInformation,
2367 FileStatLxInformation,
2368 FileCaseSensitiveInformation,
2369 FileLinkInformationEx,
2370 FileLinkInformationExBypassAccessCheck,
2371 FileStorageReserveIdInformation,
2372 FileCaseSensitiveInformationForceAccessCheck,
2373 FileMaximumInformation,
2374};
2375
2376pub const OVERLAPPED = extern struct {
2377 Internal: ULONG_PTR,
2378 InternalHigh: ULONG_PTR,
2379 DUMMYUNIONNAME: extern union {
2380 DUMMYSTRUCTNAME: extern struct {
2381 Offset: DWORD,
2382 OffsetHigh: DWORD,
2383 },
2384 Pointer: ?PVOID,
2385 },
2386 hEvent: ?HANDLE,
2387};
2388
2389pub const OVERLAPPED_ENTRY = extern struct {
2390 lpCompletionKey: ULONG_PTR,
2391 lpOverlapped: *OVERLAPPED,
2392 Internal: ULONG_PTR,
2393 dwNumberOfBytesTransferred: DWORD,
2394};
2395
2396pub const MAX_PATH = 260;
2397
2398// TODO issue #305
2399pub const FILE_INFO_BY_HANDLE_CLASS = u32;
2400pub const FileBasicInfo = 0;
2401pub const FileStandardInfo = 1;
2402pub const FileNameInfo = 2;
2403pub const FileRenameInfo = 3;
2404pub const FileDispositionInfo = 4;
2405pub const FileAllocationInfo = 5;
2406pub const FileEndOfFileInfo = 6;
2407pub const FileStreamInfo = 7;
2408pub const FileCompressionInfo = 8;
2409pub const FileAttributeTagInfo = 9;
2410pub const FileIdBothDirectoryInfo = 10;
2411pub const FileIdBothDirectoryRestartInfo = 11;
2412pub const FileIoPriorityHintInfo = 12;
2413pub const FileRemoteProtocolInfo = 13;
2414pub const FileFullDirectoryInfo = 14;
2415pub const FileFullDirectoryRestartInfo = 15;
2416pub const FileStorageInfo = 16;
2417pub const FileAlignmentInfo = 17;
2418pub const FileIdInfo = 18;
2419pub const FileIdExtdDirectoryInfo = 19;
2420pub const FileIdExtdDirectoryRestartInfo = 20;
2421
2422pub const BY_HANDLE_FILE_INFORMATION = extern struct {
2423 dwFileAttributes: DWORD,
2424 ftCreationTime: FILETIME,
2425 ftLastAccessTime: FILETIME,
2426 ftLastWriteTime: FILETIME,
2427 dwVolumeSerialNumber: DWORD,
2428 nFileSizeHigh: DWORD,
2429 nFileSizeLow: DWORD,
2430 nNumberOfLinks: DWORD,
2431 nFileIndexHigh: DWORD,
2432 nFileIndexLow: DWORD,
2433};
2434
2435pub const FILE_NAME_INFO = extern struct {
2436 FileNameLength: DWORD,
2437 FileName: [1]WCHAR,
2438};
2439
2440/// Return the normalized drive name. This is the default.
2441pub const FILE_NAME_NORMALIZED = 0x0;
2442
2443/// Return the opened file name (not normalized).
2444pub const FILE_NAME_OPENED = 0x8;
2445
2446/// Return the path with the drive letter. This is the default.
2447pub const VOLUME_NAME_DOS = 0x0;
2448
2449/// Return the path with a volume GUID path instead of the drive name.
2450pub const VOLUME_NAME_GUID = 0x1;
2451
2452/// Return the path with no drive information.
2453pub const VOLUME_NAME_NONE = 0x4;
2454
2455/// Return the path with the volume device path.
2456pub const VOLUME_NAME_NT = 0x2;
2457
2458pub const SECURITY_ATTRIBUTES = extern struct {
2459 nLength: DWORD,
2460 lpSecurityDescriptor: ?*c_void,
2461 bInheritHandle: BOOL,
2462};
2463
2464pub const PIPE_ACCESS_INBOUND = 0x00000001;
2465pub const PIPE_ACCESS_OUTBOUND = 0x00000002;
2466pub const PIPE_ACCESS_DUPLEX = 0x00000003;
2467
2468pub const PIPE_TYPE_BYTE = 0x00000000;
2469pub const PIPE_TYPE_MESSAGE = 0x00000004;
2470
2471pub const PIPE_READMODE_BYTE = 0x00000000;
2472pub const PIPE_READMODE_MESSAGE = 0x00000002;
2473
2474pub const PIPE_WAIT = 0x00000000;
2475pub const PIPE_NOWAIT = 0x00000001;
2476
2477pub const GENERIC_READ = 0x80000000;
2478pub const GENERIC_WRITE = 0x40000000;
2479pub const GENERIC_EXECUTE = 0x20000000;
2480pub const GENERIC_ALL = 0x10000000;
2481
2482pub const FILE_SHARE_DELETE = 0x00000004;
2483pub const FILE_SHARE_READ = 0x00000001;
2484pub const FILE_SHARE_WRITE = 0x00000002;
2485
2486pub const DELETE = 0x00010000;
2487pub const READ_CONTROL = 0x00020000;
2488pub const WRITE_DAC = 0x00040000;
2489pub const WRITE_OWNER = 0x00080000;
2490pub const SYNCHRONIZE = 0x00100000;
2491pub const STANDARD_RIGHTS_READ = READ_CONTROL;
2492pub const STANDARD_RIGHTS_WRITE = READ_CONTROL;
2493pub const STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
2494pub const STANDARD_RIGHTS_REQUIRED = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER;
2495
2496// disposition for NtCreateFile
2497pub const FILE_SUPERSEDE = 0;
2498pub const FILE_OPEN = 1;
2499pub const FILE_CREATE = 2;
2500pub const FILE_OPEN_IF = 3;
2501pub const FILE_OVERWRITE = 4;
2502pub const FILE_OVERWRITE_IF = 5;
2503pub const FILE_MAXIMUM_DISPOSITION = 5;
2504
2505// flags for NtCreateFile and NtOpenFile
2506pub const FILE_READ_DATA = 0x00000001;
2507pub const FILE_LIST_DIRECTORY = 0x00000001;
2508pub const FILE_WRITE_DATA = 0x00000002;
2509pub const FILE_ADD_FILE = 0x00000002;
2510pub const FILE_APPEND_DATA = 0x00000004;
2511pub const FILE_ADD_SUBDIRECTORY = 0x00000004;
2512pub const FILE_CREATE_PIPE_INSTANCE = 0x00000004;
2513pub const FILE_READ_EA = 0x00000008;
2514pub const FILE_WRITE_EA = 0x00000010;
2515pub const FILE_EXECUTE = 0x00000020;
2516pub const FILE_TRAVERSE = 0x00000020;
2517pub const FILE_DELETE_CHILD = 0x00000040;
2518pub const FILE_READ_ATTRIBUTES = 0x00000080;
2519pub const FILE_WRITE_ATTRIBUTES = 0x00000100;
2520
2521pub const FILE_DIRECTORY_FILE = 0x00000001;
2522pub const FILE_WRITE_THROUGH = 0x00000002;
2523pub const FILE_SEQUENTIAL_ONLY = 0x00000004;
2524pub const FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008;
2525pub const FILE_SYNCHRONOUS_IO_ALERT = 0x00000010;
2526pub const FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020;
2527pub const FILE_NON_DIRECTORY_FILE = 0x00000040;
2528pub const FILE_CREATE_TREE_CONNECTION = 0x00000080;
2529pub const FILE_COMPLETE_IF_OPLOCKED = 0x00000100;
2530pub const FILE_NO_EA_KNOWLEDGE = 0x00000200;
2531pub const FILE_OPEN_FOR_RECOVERY = 0x00000400;
2532pub const FILE_RANDOM_ACCESS = 0x00000800;
2533pub const FILE_DELETE_ON_CLOSE = 0x00001000;
2534pub const FILE_OPEN_BY_FILE_ID = 0x00002000;
2535pub const FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000;
2536pub const FILE_NO_COMPRESSION = 0x00008000;
2537pub const FILE_RESERVE_OPFILTER = 0x00100000;
2538pub const FILE_OPEN_REPARSE_POINT = 0x00200000;
2539pub const FILE_OPEN_OFFLINE_FILE = 0x00400000;
2540pub const FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000;
2541
2542pub const CREATE_ALWAYS = 2;
2543pub const CREATE_NEW = 1;
2544pub const OPEN_ALWAYS = 4;
2545pub const OPEN_EXISTING = 3;
2546pub const TRUNCATE_EXISTING = 5;
2547
2548pub const FILE_ATTRIBUTE_ARCHIVE = 0x20;
2549pub const FILE_ATTRIBUTE_COMPRESSED = 0x800;
2550pub const FILE_ATTRIBUTE_DEVICE = 0x40;
2551pub const FILE_ATTRIBUTE_DIRECTORY = 0x10;
2552pub const FILE_ATTRIBUTE_ENCRYPTED = 0x4000;
2553pub const FILE_ATTRIBUTE_HIDDEN = 0x2;
2554pub const FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000;
2555pub const FILE_ATTRIBUTE_NORMAL = 0x80;
2556pub const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000;
2557pub const FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x20000;
2558pub const FILE_ATTRIBUTE_OFFLINE = 0x1000;
2559pub const FILE_ATTRIBUTE_READONLY = 0x1;
2560pub const FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x400000;
2561pub const FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x40000;
2562pub const FILE_ATTRIBUTE_REPARSE_POINT = 0x400;
2563pub const FILE_ATTRIBUTE_SPARSE_FILE = 0x200;
2564pub const FILE_ATTRIBUTE_SYSTEM = 0x4;
2565pub const FILE_ATTRIBUTE_TEMPORARY = 0x100;
2566pub const FILE_ATTRIBUTE_VIRTUAL = 0x10000;
2567
2568// flags for CreateEvent
2569pub const CREATE_EVENT_INITIAL_SET = 0x00000002;
2570pub const CREATE_EVENT_MANUAL_RESET = 0x00000001;
2571
2572pub const EVENT_ALL_ACCESS = 0x1F0003;
2573pub const EVENT_MODIFY_STATE = 0x0002;
2574
2575pub const PROCESS_INFORMATION = extern struct {
2576 hProcess: HANDLE,
2577 hThread: HANDLE,
2578 dwProcessId: DWORD,
2579 dwThreadId: DWORD,
2580};
2581
2582pub const STARTUPINFOW = extern struct {
2583 cb: DWORD,
2584 lpReserved: ?LPWSTR,
2585 lpDesktop: ?LPWSTR,
2586 lpTitle: ?LPWSTR,
2587 dwX: DWORD,
2588 dwY: DWORD,
2589 dwXSize: DWORD,
2590 dwYSize: DWORD,
2591 dwXCountChars: DWORD,
2592 dwYCountChars: DWORD,
2593 dwFillAttribute: DWORD,
2594 dwFlags: DWORD,
2595 wShowWindow: WORD,
2596 cbReserved2: WORD,
2597 lpReserved2: ?*BYTE,
2598 hStdInput: ?HANDLE,
2599 hStdOutput: ?HANDLE,
2600 hStdError: ?HANDLE,
2601};
2602
2603pub const STARTF_FORCEONFEEDBACK = 0x00000040;
2604pub const STARTF_FORCEOFFFEEDBACK = 0x00000080;
2605pub const STARTF_PREVENTPINNING = 0x00002000;
2606pub const STARTF_RUNFULLSCREEN = 0x00000020;
2607pub const STARTF_TITLEISAPPID = 0x00001000;
2608pub const STARTF_TITLEISLINKNAME = 0x00000800;
2609pub const STARTF_UNTRUSTEDSOURCE = 0x00008000;
2610pub const STARTF_USECOUNTCHARS = 0x00000008;
2611pub const STARTF_USEFILLATTRIBUTE = 0x00000010;
2612pub const STARTF_USEHOTKEY = 0x00000200;
2613pub const STARTF_USEPOSITION = 0x00000004;
2614pub const STARTF_USESHOWWINDOW = 0x00000001;
2615pub const STARTF_USESIZE = 0x00000002;
2616pub const STARTF_USESTDHANDLES = 0x00000100;
2617
2618pub const INFINITE = 4294967295;
2619
2620pub const MAXIMUM_WAIT_OBJECTS = 64;
2621
2622pub const WAIT_ABANDONED = 0x00000080;
2623pub const WAIT_ABANDONED_0 = WAIT_ABANDONED + 0;
2624pub const WAIT_OBJECT_0 = 0x00000000;
2625pub const WAIT_TIMEOUT = 0x00000102;
2626pub const WAIT_FAILED = 0xFFFFFFFF;
2627
2628pub const HANDLE_FLAG_INHERIT = 0x00000001;
2629pub const HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002;
2630
2631pub const MOVEFILE_COPY_ALLOWED = 2;
2632pub const MOVEFILE_CREATE_HARDLINK = 16;
2633pub const MOVEFILE_DELAY_UNTIL_REBOOT = 4;
2634pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE = 32;
2635pub const MOVEFILE_REPLACE_EXISTING = 1;
2636pub const MOVEFILE_WRITE_THROUGH = 8;
2637
2638pub const FILE_BEGIN = 0;
2639pub const FILE_CURRENT = 1;
2640pub const FILE_END = 2;
2641
2642pub const HEAP_CREATE_ENABLE_EXECUTE = 0x00040000;
2643pub const HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010;
2644pub const HEAP_GENERATE_EXCEPTIONS = 0x00000004;
2645pub const HEAP_NO_SERIALIZE = 0x00000001;
2646
2647// AllocationType values
2648pub const MEM_COMMIT = 0x1000;
2649pub const MEM_RESERVE = 0x2000;
2650pub const MEM_RESET = 0x80000;
2651pub const MEM_RESET_UNDO = 0x1000000;
2652pub const MEM_LARGE_PAGES = 0x20000000;
2653pub const MEM_PHYSICAL = 0x400000;
2654pub const MEM_TOP_DOWN = 0x100000;
2655pub const MEM_WRITE_WATCH = 0x200000;
2656
2657// Protect values
2658pub const PAGE_EXECUTE = 0x10;
2659pub const PAGE_EXECUTE_READ = 0x20;
2660pub const PAGE_EXECUTE_READWRITE = 0x40;
2661pub const PAGE_EXECUTE_WRITECOPY = 0x80;
2662pub const PAGE_NOACCESS = 0x01;
2663pub const PAGE_READONLY = 0x02;
2664pub const PAGE_READWRITE = 0x04;
2665pub const PAGE_WRITECOPY = 0x08;
2666pub const PAGE_TARGETS_INVALID = 0x40000000;
2667pub const PAGE_TARGETS_NO_UPDATE = 0x40000000; // Same as PAGE_TARGETS_INVALID
2668pub const PAGE_GUARD = 0x100;
2669pub const PAGE_NOCACHE = 0x200;
2670pub const PAGE_WRITECOMBINE = 0x400;
2671
2672// FreeType values
2673pub const MEM_COALESCE_PLACEHOLDERS = 0x1;
2674pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
2675pub const MEM_DECOMMIT = 0x4000;
2676pub const MEM_RELEASE = 0x8000;
2677
2678pub const PTHREAD_START_ROUTINE = fn (LPVOID) callconv(.C) DWORD;
2679pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
2680
2681pub const WIN32_FIND_DATAW = extern struct {
2682 dwFileAttributes: DWORD,
2683 ftCreationTime: FILETIME,
2684 ftLastAccessTime: FILETIME,
2685 ftLastWriteTime: FILETIME,
2686 nFileSizeHigh: DWORD,
2687 nFileSizeLow: DWORD,
2688 dwReserved0: DWORD,
2689 dwReserved1: DWORD,
2690 cFileName: [260]u16,
2691 cAlternateFileName: [14]u16,
2692};
2693
2694pub const FILETIME = extern struct {
2695 dwLowDateTime: DWORD,
2696 dwHighDateTime: DWORD,
2697};
2698
2699pub const SYSTEM_INFO = extern struct {
2700 anon1: extern union {
2701 dwOemId: DWORD,
2702 anon2: extern struct {
2703 wProcessorArchitecture: WORD,
2704 wReserved: WORD,
2705 },
2706 },
2707 dwPageSize: DWORD,
2708 lpMinimumApplicationAddress: LPVOID,
2709 lpMaximumApplicationAddress: LPVOID,
2710 dwActiveProcessorMask: DWORD_PTR,
2711 dwNumberOfProcessors: DWORD,
2712 dwProcessorType: DWORD,
2713 dwAllocationGranularity: DWORD,
2714 wProcessorLevel: WORD,
2715 wProcessorRevision: WORD,
2716};
2717
2718pub const HRESULT = c_long;
2719
2720pub const KNOWNFOLDERID = GUID;
2721pub const GUID = extern struct {
2722 Data1: c_ulong,
2723 Data2: c_ushort,
2724 Data3: c_ushort,
2725 Data4: [8]u8,
2726
2727 pub fn parse(str: []const u8) GUID {
2728 var guid: GUID = undefined;
2729 var index: usize = 0;
2730 assert(str[index] == '{');
2731 index += 1;
2732
2733 guid.Data1 = std.fmt.parseUnsigned(c_ulong, str[index .. index + 8], 16) catch unreachable;
2734 index += 8;
2735
2736 assert(str[index] == '-');
2737 index += 1;
2738
2739 guid.Data2 = std.fmt.parseUnsigned(c_ushort, str[index .. index + 4], 16) catch unreachable;
2740 index += 4;
2741
2742 assert(str[index] == '-');
2743 index += 1;
2744
2745 guid.Data3 = std.fmt.parseUnsigned(c_ushort, str[index .. index + 4], 16) catch unreachable;
2746 index += 4;
2747
2748 assert(str[index] == '-');
2749 index += 1;
2750
2751 guid.Data4[0] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable;
2752 index += 2;
2753 guid.Data4[1] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable;
2754 index += 2;
2755
2756 assert(str[index] == '-');
2757 index += 1;
2758
2759 var i: usize = 2;
2760 while (i < guid.Data4.len) : (i += 1) {
2761 guid.Data4[i] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable;
2762 index += 2;
2763 }
2764
2765 assert(str[index] == '}');
2766 index += 1;
2767 return guid;
2768 }
2769};
2770
2771pub const FOLDERID_LocalAppData = GUID.parse("{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}");
2772
2773pub const KF_FLAG_DEFAULT = 0;
2774pub const KF_FLAG_NO_APPCONTAINER_REDIRECTION = 65536;
2775pub const KF_FLAG_CREATE = 32768;
2776pub const KF_FLAG_DONT_VERIFY = 16384;
2777pub const KF_FLAG_DONT_UNEXPAND = 8192;
2778pub const KF_FLAG_NO_ALIAS = 4096;
2779pub const KF_FLAG_INIT = 2048;
2780pub const KF_FLAG_DEFAULT_PATH = 1024;
2781pub const KF_FLAG_NOT_PARENT_RELATIVE = 512;
2782pub const KF_FLAG_SIMPLE_IDLIST = 256;
2783pub const KF_FLAG_ALIAS_ONLY = -2147483648;
2784
2785pub const S_OK = 0;
2786pub const E_NOTIMPL = @bitCast(c_long, @as(c_ulong, 0x80004001));
2787pub const E_NOINTERFACE = @bitCast(c_long, @as(c_ulong, 0x80004002));
2788pub const E_POINTER = @bitCast(c_long, @as(c_ulong, 0x80004003));
2789pub const E_ABORT = @bitCast(c_long, @as(c_ulong, 0x80004004));
2790pub const E_FAIL = @bitCast(c_long, @as(c_ulong, 0x80004005));
2791pub const E_UNEXPECTED = @bitCast(c_long, @as(c_ulong, 0x8000FFFF));
2792pub const E_ACCESSDENIED = @bitCast(c_long, @as(c_ulong, 0x80070005));
2793pub const E_HANDLE = @bitCast(c_long, @as(c_ulong, 0x80070006));
2794pub const E_OUTOFMEMORY = @bitCast(c_long, @as(c_ulong, 0x8007000E));
2795pub const E_INVALIDARG = @bitCast(c_long, @as(c_ulong, 0x80070057));
2796
2797pub const FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
2798pub const FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
2799pub const FILE_FLAG_NO_BUFFERING = 0x20000000;
2800pub const FILE_FLAG_OPEN_NO_RECALL = 0x00100000;
2801pub const FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000;
2802pub const FILE_FLAG_OVERLAPPED = 0x40000000;
2803pub const FILE_FLAG_POSIX_SEMANTICS = 0x0100000;
2804pub const FILE_FLAG_RANDOM_ACCESS = 0x10000000;
2805pub const FILE_FLAG_SESSION_AWARE = 0x00800000;
2806pub const FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000;
2807pub const FILE_FLAG_WRITE_THROUGH = 0x80000000;
2808
2809pub const RECT = extern struct {
2810 left: LONG,
2811 top: LONG,
2812 right: LONG,
2813 bottom: LONG,
2814};
2815
2816pub const SMALL_RECT = extern struct {
2817 Left: SHORT,
2818 Top: SHORT,
2819 Right: SHORT,
2820 Bottom: SHORT,
2821};
2822
2823pub const POINT = extern struct {
2824 x: LONG,
2825 y: LONG,
2826};
2827
2828pub const COORD = extern struct {
2829 X: SHORT,
2830 Y: SHORT,
2831};
2832
2833pub const CREATE_UNICODE_ENVIRONMENT = 1024;
2834
2835pub const TLS_OUT_OF_INDEXES = 4294967295;
2836pub const IMAGE_TLS_DIRECTORY = extern struct {
2837 StartAddressOfRawData: usize,
2838 EndAddressOfRawData: usize,
2839 AddressOfIndex: usize,
2840 AddressOfCallBacks: usize,
2841 SizeOfZeroFill: u32,
2842 Characteristics: u32,
2843};
2844pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;
2845pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;
2846
2847pub const PIMAGE_TLS_CALLBACK = ?fn (PVOID, DWORD, PVOID) callconv(.C) void;
2848
2849pub const PROV_RSA_FULL = 1;
2850
2851pub const REGSAM = ACCESS_MASK;
2852pub const ACCESS_MASK = DWORD;
2853pub const HKEY = *HKEY__;
2854pub const HKEY__ = extern struct {
2855 unused: c_int,
2856};
2857pub const LSTATUS = LONG;
2858
2859pub const FILE_NOTIFY_INFORMATION = extern struct {
2860 NextEntryOffset: DWORD,
2861 Action: DWORD,
2862 FileNameLength: DWORD,
2863 // Flexible array member
2864 // FileName: [1]WCHAR,
2865};
2866
2867pub const FILE_ACTION_ADDED = 0x00000001;
2868pub const FILE_ACTION_REMOVED = 0x00000002;
2869pub const FILE_ACTION_MODIFIED = 0x00000003;
2870pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;
2871pub const FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;
2872
2873pub const LPOVERLAPPED_COMPLETION_ROUTINE = ?fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void;
2874
2875pub const FILE_NOTIFY_CHANGE_CREATION = 64;
2876pub const FILE_NOTIFY_CHANGE_SIZE = 8;
2877pub const FILE_NOTIFY_CHANGE_SECURITY = 256;
2878pub const FILE_NOTIFY_CHANGE_LAST_ACCESS = 32;
2879pub const FILE_NOTIFY_CHANGE_LAST_WRITE = 16;
2880pub const FILE_NOTIFY_CHANGE_DIR_NAME = 2;
2881pub const FILE_NOTIFY_CHANGE_FILE_NAME = 1;
2882pub const FILE_NOTIFY_CHANGE_ATTRIBUTES = 4;
2883
2884pub const CONSOLE_SCREEN_BUFFER_INFO = extern struct {
2885 dwSize: COORD,
2886 dwCursorPosition: COORD,
2887 wAttributes: WORD,
2888 srWindow: SMALL_RECT,
2889 dwMaximumWindowSize: COORD,
2890};
2891
2892pub const FOREGROUND_BLUE = 1;
2893pub const FOREGROUND_GREEN = 2;
2894pub const FOREGROUND_RED = 4;
2895pub const FOREGROUND_INTENSITY = 8;
2896
2897pub const LIST_ENTRY = extern struct {
2898 Flink: *LIST_ENTRY,
2899 Blink: *LIST_ENTRY,
2900};
2901
2902pub const RTL_CRITICAL_SECTION_DEBUG = extern struct {
2903 Type: WORD,
2904 CreatorBackTraceIndex: WORD,
2905 CriticalSection: *RTL_CRITICAL_SECTION,
2906 ProcessLocksList: LIST_ENTRY,
2907 EntryCount: DWORD,
2908 ContentionCount: DWORD,
2909 Flags: DWORD,
2910 CreatorBackTraceIndexHigh: WORD,
2911 SpareWORD: WORD,
2912};
2913
2914pub const RTL_CRITICAL_SECTION = extern struct {
2915 DebugInfo: *RTL_CRITICAL_SECTION_DEBUG,
2916 LockCount: LONG,
2917 RecursionCount: LONG,
2918 OwningThread: HANDLE,
2919 LockSemaphore: HANDLE,
2920 SpinCount: ULONG_PTR,
2921};
2922
2923pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;
2924pub const INIT_ONCE = RTL_RUN_ONCE;
2925pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT;
2926pub const INIT_ONCE_FN = fn (InitOnce: *INIT_ONCE, Parameter: ?*c_void, Context: ?*c_void) callconv(.C) BOOL;
2927
2928pub const RTL_RUN_ONCE = extern struct {
2929 Ptr: ?*c_void,
2930};
2931
2932pub const RTL_RUN_ONCE_INIT = RTL_RUN_ONCE{ .Ptr = null };
2933
2934pub const COINIT_APARTMENTTHREADED = COINIT.COINIT_APARTMENTTHREADED;
2935pub const COINIT_MULTITHREADED = COINIT.COINIT_MULTITHREADED;
2936pub const COINIT_DISABLE_OLE1DDE = COINIT.COINIT_DISABLE_OLE1DDE;
2937pub const COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
2938pub const COINIT = enum(c_int) {
2939 COINIT_APARTMENTTHREADED = 2,
2940 COINIT_MULTITHREADED = 0,
2941 COINIT_DISABLE_OLE1DDE = 4,
2942 COINIT_SPEED_OVER_MEMORY = 8,
2943};
2944
2945/// > The maximum path of 32,767 characters is approximate, because the "\\?\"
2946/// > prefix may be expanded to a longer string by the system at run time, and
2947/// > this expansion applies to the total length.
2948/// from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
2949pub const PATH_MAX_WIDE = 32767;
2950
2951pub const FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
2952pub const FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
2953pub const FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
2954pub const FORMAT_MESSAGE_FROM_STRING = 0x00000400;
2955pub const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
2956pub const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
2957pub const FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF;
2958
2959pub const EXCEPTION_DATATYPE_MISALIGNMENT = 0x80000002;
2960pub const EXCEPTION_ACCESS_VIOLATION = 0xc0000005;
2961pub const EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d;
2962pub const EXCEPTION_STACK_OVERFLOW = 0xc00000fd;
2963pub const EXCEPTION_CONTINUE_SEARCH = 0;
2964
2965pub const EXCEPTION_RECORD = extern struct {
2966 ExceptionCode: u32,
2967 ExceptionFlags: u32,
2968 ExceptionRecord: *EXCEPTION_RECORD,
2969 ExceptionAddress: *c_void,
2970 NumberParameters: u32,
2971 ExceptionInformation: [15]usize,
2972};
2973
2974pub usingnamespace switch (native_arch) {
2975 .i386 => struct {
2976 pub const FLOATING_SAVE_AREA = extern struct {
2977 ControlWord: DWORD,
2978 StatusWord: DWORD,
2979 TagWord: DWORD,
2980 ErrorOffset: DWORD,
2981 ErrorSelector: DWORD,
2982 DataOffset: DWORD,
2983 DataSelector: DWORD,
2984 RegisterArea: [80]BYTE,
2985 Cr0NpxState: DWORD,
2986 };
2987
2988 pub const CONTEXT = extern struct {
2989 ContextFlags: DWORD,
2990 Dr0: DWORD,
2991 Dr1: DWORD,
2992 Dr2: DWORD,
2993 Dr3: DWORD,
2994 Dr6: DWORD,
2995 Dr7: DWORD,
2996 FloatSave: FLOATING_SAVE_AREA,
2997 SegGs: DWORD,
2998 SegFs: DWORD,
2999 SegEs: DWORD,
3000 SegDs: DWORD,
3001 Edi: DWORD,
3002 Esi: DWORD,
3003 Ebx: DWORD,
3004 Edx: DWORD,
3005 Ecx: DWORD,
3006 Eax: DWORD,
3007 Ebp: DWORD,
3008 Eip: DWORD,
3009 SegCs: DWORD,
3010 EFlags: DWORD,
3011 Esp: DWORD,
3012 SegSs: DWORD,
3013 ExtendedRegisters: [512]BYTE,
3014
3015 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize } {
3016 return .{ .bp = ctx.Ebp, .ip = ctx.Eip };
3017 }
3018 };
3019 },
3020 .x86_64 => struct {
3021 pub const M128A = extern struct {
3022 Low: ULONGLONG,
3023 High: LONGLONG,
3024 };
3025
3026 pub const XMM_SAVE_AREA32 = extern struct {
3027 ControlWord: WORD,
3028 StatusWord: WORD,
3029 TagWord: BYTE,
3030 Reserved1: BYTE,
3031 ErrorOpcode: WORD,
3032 ErrorOffset: DWORD,
3033 ErrorSelector: WORD,
3034 Reserved2: WORD,
3035 DataOffset: DWORD,
3036 DataSelector: WORD,
3037 Reserved3: WORD,
3038 MxCsr: DWORD,
3039 MxCsr_Mask: DWORD,
3040 FloatRegisters: [8]M128A,
3041 XmmRegisters: [16]M128A,
3042 Reserved4: [96]BYTE,
3043 };
3044
3045 pub const CONTEXT = extern struct {
3046 P1Home: DWORD64,
3047 P2Home: DWORD64,
3048 P3Home: DWORD64,
3049 P4Home: DWORD64,
3050 P5Home: DWORD64,
3051 P6Home: DWORD64,
3052 ContextFlags: DWORD,
3053 MxCsr: DWORD,
3054 SegCs: WORD,
3055 SegDs: WORD,
3056 SegEs: WORD,
3057 SegFs: WORD,
3058 SegGs: WORD,
3059 SegSs: WORD,
3060 EFlags: DWORD,
3061 Dr0: DWORD64,
3062 Dr1: DWORD64,
3063 Dr2: DWORD64,
3064 Dr3: DWORD64,
3065 Dr6: DWORD64,
3066 Dr7: DWORD64,
3067 Rax: DWORD64,
3068 Rcx: DWORD64,
3069 Rdx: DWORD64,
3070 Rbx: DWORD64,
3071 Rsp: DWORD64,
3072 Rbp: DWORD64,
3073 Rsi: DWORD64,
3074 Rdi: DWORD64,
3075 R8: DWORD64,
3076 R9: DWORD64,
3077 R10: DWORD64,
3078 R11: DWORD64,
3079 R12: DWORD64,
3080 R13: DWORD64,
3081 R14: DWORD64,
3082 R15: DWORD64,
3083 Rip: DWORD64,
3084 DUMMYUNIONNAME: extern union {
3085 FltSave: XMM_SAVE_AREA32,
3086 FloatSave: XMM_SAVE_AREA32,
3087 DUMMYSTRUCTNAME: extern struct {
3088 Header: [2]M128A,
3089 Legacy: [8]M128A,
3090 Xmm0: M128A,
3091 Xmm1: M128A,
3092 Xmm2: M128A,
3093 Xmm3: M128A,
3094 Xmm4: M128A,
3095 Xmm5: M128A,
3096 Xmm6: M128A,
3097 Xmm7: M128A,
3098 Xmm8: M128A,
3099 Xmm9: M128A,
3100 Xmm10: M128A,
3101 Xmm11: M128A,
3102 Xmm12: M128A,
3103 Xmm13: M128A,
3104 Xmm14: M128A,
3105 Xmm15: M128A,
3106 },
3107 },
3108 VectorRegister: [26]M128A,
3109 VectorControl: DWORD64,
3110 DebugControl: DWORD64,
3111 LastBranchToRip: DWORD64,
3112 LastBranchFromRip: DWORD64,
3113 LastExceptionToRip: DWORD64,
3114 LastExceptionFromRip: DWORD64,
3115
3116 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize } {
3117 return .{ .bp = ctx.Rbp, .ip = ctx.Rip };
3118 }
3119 };
3120 },
3121 .aarch64 => struct {
3122 pub const NEON128 = extern union {
3123 DUMMYSTRUCTNAME: extern struct {
3124 Low: ULONGLONG,
3125 High: LONGLONG,
3126 },
3127 D: [2]f64,
3128 S: [4]f32,
3129 H: [8]WORD,
3130 B: [16]BYTE,
3131 };
3132
3133 pub const CONTEXT = extern struct {
3134 ContextFlags: ULONG,
3135 Cpsr: ULONG,
3136 DUMMYUNIONNAME: extern union {
3137 DUMMYSTRUCTNAME: extern struct {
3138 X0: DWORD64,
3139 X1: DWORD64,
3140 X2: DWORD64,
3141 X3: DWORD64,
3142 X4: DWORD64,
3143 X5: DWORD64,
3144 X6: DWORD64,
3145 X7: DWORD64,
3146 X8: DWORD64,
3147 X9: DWORD64,
3148 X10: DWORD64,
3149 X11: DWORD64,
3150 X12: DWORD64,
3151 X13: DWORD64,
3152 X14: DWORD64,
3153 X15: DWORD64,
3154 X16: DWORD64,
3155 X17: DWORD64,
3156 X18: DWORD64,
3157 X19: DWORD64,
3158 X20: DWORD64,
3159 X21: DWORD64,
3160 X22: DWORD64,
3161 X23: DWORD64,
3162 X24: DWORD64,
3163 X25: DWORD64,
3164 X26: DWORD64,
3165 X27: DWORD64,
3166 X28: DWORD64,
3167 Fp: DWORD64,
3168 Lr: DWORD64,
3169 },
3170 X: [31]DWORD64,
3171 },
3172 Sp: DWORD64,
3173 Pc: DWORD64,
3174 V: [32]NEON128,
3175 Fpcr: DWORD,
3176 Fpsr: DWORD,
3177 Bcr: [8]DWORD,
3178 Bvr: [8]DWORD64,
3179 Wcr: [2]DWORD,
3180 Wvr: [2]DWORD64,
3181
3182 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize } {
3183 return .{
3184 .bp = ctx.DUMMYUNIONNAME.DUMMYSTRUCTNAME.Fp,
3185 .ip = ctx.Pc,
3186 };
3187 }
3188 };
3189 },
3190 else => struct {},
3191};
3192
3193pub const EXCEPTION_POINTERS = extern struct {
3194 ExceptionRecord: *EXCEPTION_RECORD,
3195 ContextRecord: *std.os.windows.CONTEXT,
3196};
3197
3198pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long;
3199
3200pub const OBJECT_ATTRIBUTES = extern struct {
3201 Length: ULONG,
3202 RootDirectory: ?HANDLE,
3203 ObjectName: *UNICODE_STRING,
3204 Attributes: ULONG,
3205 SecurityDescriptor: ?*c_void,
3206 SecurityQualityOfService: ?*c_void,
3207};
3208
3209pub const OBJ_INHERIT = 0x00000002;
3210pub const OBJ_PERMANENT = 0x00000010;
3211pub const OBJ_EXCLUSIVE = 0x00000020;
3212pub const OBJ_CASE_INSENSITIVE = 0x00000040;
3213pub const OBJ_OPENIF = 0x00000080;
3214pub const OBJ_OPENLINK = 0x00000100;
3215pub const OBJ_KERNEL_HANDLE = 0x00000200;
3216pub const OBJ_VALID_ATTRIBUTES = 0x000003F2;
3217
3218pub const UNICODE_STRING = extern struct {
3219 Length: c_ushort,
3220 MaximumLength: c_ushort,
3221 Buffer: [*]WCHAR,
3222};
3223
3224pub const ACTIVATION_CONTEXT_DATA = opaque {};
3225pub const ASSEMBLY_STORAGE_MAP = opaque {};
3226pub const FLS_CALLBACK_INFO = opaque {};
3227pub const RTL_BITMAP = opaque {};
3228pub const KAFFINITY = usize;
3229
3230pub const TEB = extern struct {
3231 Reserved1: [12]PVOID,
3232 ProcessEnvironmentBlock: *PEB,
3233 Reserved2: [399]PVOID,
3234 Reserved3: [1952]u8,
3235 TlsSlots: [64]PVOID,
3236 Reserved4: [8]u8,
3237 Reserved5: [26]PVOID,
3238 ReservedForOle: PVOID,
3239 Reserved6: [4]PVOID,
3240 TlsExpansionSlots: PVOID,
3241};
3242
3243/// Process Environment Block
3244/// Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
3245/// - https://github.com/wine-mirror/wine/blob/1aff1e6a370ee8c0213a0fd4b220d121da8527aa/include/winternl.h#L269
3246/// - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/index.htm
3247pub const PEB = extern struct {
3248 // Versions: All
3249 InheritedAddressSpace: BOOLEAN,
3250
3251 // Versions: 3.51+
3252 ReadImageFileExecOptions: BOOLEAN,
3253 BeingDebugged: BOOLEAN,
3254
3255 // Versions: 5.2+ (previously was padding)
3256 BitField: UCHAR,
3257
3258 // Versions: all
3259 Mutant: HANDLE,
3260 ImageBaseAddress: HMODULE,
3261 Ldr: *PEB_LDR_DATA,
3262 ProcessParameters: *RTL_USER_PROCESS_PARAMETERS,
3263 SubSystemData: PVOID,
3264 ProcessHeap: HANDLE,
3265
3266 // Versions: 5.1+
3267 FastPebLock: *RTL_CRITICAL_SECTION,
3268
3269 // Versions: 5.2+
3270 AtlThunkSListPtr: PVOID,
3271 IFEOKey: PVOID,
3272
3273 // Versions: 6.0+
3274
3275 /// https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/crossprocessflags.htm
3276 CrossProcessFlags: ULONG,
3277
3278 // Versions: 6.0+
3279 union1: extern union {
3280 KernelCallbackTable: PVOID,
3281 UserSharedInfoPtr: PVOID,
3282 },
3283
3284 // Versions: 5.1+
3285 SystemReserved: ULONG,
3286
3287 // Versions: 5.1, (not 5.2, not 6.0), 6.1+
3288 AtlThunkSListPtr32: ULONG,
3289
3290 // Versions: 6.1+
3291 ApiSetMap: PVOID,
3292
3293 // Versions: all
3294 TlsExpansionCounter: ULONG,
3295 // note: there is padding here on 64 bit
3296 TlsBitmap: *RTL_BITMAP,
3297 TlsBitmapBits: [2]ULONG,
3298 ReadOnlySharedMemoryBase: PVOID,
3299
3300 // Versions: 1703+
3301 SharedData: PVOID,
3302
3303 // Versions: all
3304 ReadOnlyStaticServerData: *PVOID,
3305 AnsiCodePageData: PVOID,
3306 OemCodePageData: PVOID,
3307 UnicodeCaseTableData: PVOID,
3308
3309 // Versions: 3.51+
3310 NumberOfProcessors: ULONG,
3311 NtGlobalFlag: ULONG,
3312
3313 // Versions: all
3314 CriticalSectionTimeout: LARGE_INTEGER,
3315
3316 // End of Original PEB size
3317
3318 // Fields appended in 3.51:
3319 HeapSegmentReserve: ULONG_PTR,
3320 HeapSegmentCommit: ULONG_PTR,
3321 HeapDeCommitTotalFreeThreshold: ULONG_PTR,
3322 HeapDeCommitFreeBlockThreshold: ULONG_PTR,
3323 NumberOfHeaps: ULONG,
3324 MaximumNumberOfHeaps: ULONG,
3325 ProcessHeaps: *PVOID,
3326
3327 // Fields appended in 4.0:
3328 GdiSharedHandleTable: PVOID,
3329 ProcessStarterHelper: PVOID,
3330 GdiDCAttributeList: ULONG,
3331 // note: there is padding here on 64 bit
3332 LoaderLock: *RTL_CRITICAL_SECTION,
3333 OSMajorVersion: ULONG,
3334 OSMinorVersion: ULONG,
3335 OSBuildNumber: USHORT,
3336 OSCSDVersion: USHORT,
3337 OSPlatformId: ULONG,
3338 ImageSubSystem: ULONG,
3339 ImageSubSystemMajorVersion: ULONG,
3340 ImageSubSystemMinorVersion: ULONG,
3341 // note: there is padding here on 64 bit
3342 ActiveProcessAffinityMask: KAFFINITY,
3343 GdiHandleBuffer: [
3344 switch (@sizeOf(usize)) {
3345 4 => 0x22,
3346 8 => 0x3C,
3347 else => unreachable,
3348 }
3349 ]ULONG,
3350
3351 // Fields appended in 5.0 (Windows 2000):
3352 PostProcessInitRoutine: PVOID,
3353 TlsExpansionBitmap: *RTL_BITMAP,
3354 TlsExpansionBitmapBits: [32]ULONG,
3355 SessionId: ULONG,
3356 // note: there is padding here on 64 bit
3357 // Versions: 5.1+
3358 AppCompatFlags: ULARGE_INTEGER,
3359 AppCompatFlagsUser: ULARGE_INTEGER,
3360 ShimData: PVOID,
3361 // Versions: 5.0+
3362 AppCompatInfo: PVOID,
3363 CSDVersion: UNICODE_STRING,
3364
3365 // Fields appended in 5.1 (Windows XP):
3366 ActivationContextData: *const ACTIVATION_CONTEXT_DATA,
3367 ProcessAssemblyStorageMap: *ASSEMBLY_STORAGE_MAP,
3368 SystemDefaultActivationData: *const ACTIVATION_CONTEXT_DATA,
3369 SystemAssemblyStorageMap: *ASSEMBLY_STORAGE_MAP,
3370 MinimumStackCommit: ULONG_PTR,
3371
3372 // Fields appended in 5.2 (Windows Server 2003):
3373 FlsCallback: *FLS_CALLBACK_INFO,
3374 FlsListHead: LIST_ENTRY,
3375 FlsBitmap: *RTL_BITMAP,
3376 FlsBitmapBits: [4]ULONG,
3377 FlsHighIndex: ULONG,
3378
3379 // Fields appended in 6.0 (Windows Vista):
3380 WerRegistrationData: PVOID,
3381 WerShipAssertPtr: PVOID,
3382
3383 // Fields appended in 6.1 (Windows 7):
3384 pUnused: PVOID, // previously pContextData
3385 pImageHeaderHash: PVOID,
3386
3387 /// TODO: https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/tracingflags.htm
3388 TracingFlags: ULONG,
3389
3390 // Fields appended in 6.2 (Windows 8):
3391 CsrServerReadOnlySharedMemoryBase: ULONGLONG,
3392
3393 // Fields appended in 1511:
3394 TppWorkerpListLock: ULONG,
3395 TppWorkerpList: LIST_ENTRY,
3396 WaitOnAddressHashTable: [0x80]PVOID,
3397
3398 // Fields appended in 1709:
3399 TelemetryCoverageHeader: PVOID,
3400 CloudFileFlags: ULONG,
3401};
3402
3403/// The `PEB_LDR_DATA` structure is the main record of what modules are loaded in a process.
3404/// It is essentially the head of three double-linked lists of `LDR_DATA_TABLE_ENTRY` structures which each represent one loaded module.
3405///
3406/// Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
3407/// - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb_ldr_data.htm
3408pub const PEB_LDR_DATA = extern struct {
3409 // Versions: 3.51 and higher
3410 /// The size in bytes of the structure
3411 Length: ULONG,
3412
3413 /// TRUE if the structure is prepared.
3414 Initialized: BOOLEAN,
3415
3416 SsHandle: PVOID,
3417 InLoadOrderModuleList: LIST_ENTRY,
3418 InMemoryOrderModuleList: LIST_ENTRY,
3419 InInitializationOrderModuleList: LIST_ENTRY,
3420
3421 // Versions: 5.1 and higher
3422
3423 /// No known use of this field is known in Windows 8 and higher.
3424 EntryInProgress: PVOID,
3425
3426 // Versions: 6.0 from Windows Vista SP1, and higher
3427 ShutdownInProgress: BOOLEAN,
3428
3429 /// Though ShutdownThreadId is declared as a HANDLE,
3430 /// it is indeed the thread ID as suggested by its name.
3431 /// It is picked up from the UniqueThread member of the CLIENT_ID in the
3432 /// TEB of the thread that asks to terminate the process.
3433 ShutdownThreadId: HANDLE,
3434};
3435
3436pub const RTL_USER_PROCESS_PARAMETERS = extern struct {
3437 AllocationSize: ULONG,
3438 Size: ULONG,
3439 Flags: ULONG,
3440 DebugFlags: ULONG,
3441 ConsoleHandle: HANDLE,
3442 ConsoleFlags: ULONG,
3443 hStdInput: HANDLE,
3444 hStdOutput: HANDLE,
3445 hStdError: HANDLE,
3446 CurrentDirectory: CURDIR,
3447 DllPath: UNICODE_STRING,
3448 ImagePathName: UNICODE_STRING,
3449 CommandLine: UNICODE_STRING,
3450 Environment: [*:0]WCHAR,
3451 dwX: ULONG,
3452 dwY: ULONG,
3453 dwXSize: ULONG,
3454 dwYSize: ULONG,
3455 dwXCountChars: ULONG,
3456 dwYCountChars: ULONG,
3457 dwFillAttribute: ULONG,
3458 dwFlags: ULONG,
3459 dwShowWindow: ULONG,
3460 WindowTitle: UNICODE_STRING,
3461 Desktop: UNICODE_STRING,
3462 ShellInfo: UNICODE_STRING,
3463 RuntimeInfo: UNICODE_STRING,
3464 DLCurrentDirectory: [0x20]RTL_DRIVE_LETTER_CURDIR,
3465};
3466
3467pub const RTL_DRIVE_LETTER_CURDIR = extern struct {
3468 Flags: c_ushort,
3469 Length: c_ushort,
3470 TimeStamp: ULONG,
3471 DosPath: UNICODE_STRING,
3472};
3473
3474pub const PPS_POST_PROCESS_INIT_ROUTINE = ?fn () callconv(.C) void;
3475
3476pub const FILE_BOTH_DIR_INFORMATION = extern struct {
3477 NextEntryOffset: ULONG,
3478 FileIndex: ULONG,
3479 CreationTime: LARGE_INTEGER,
3480 LastAccessTime: LARGE_INTEGER,
3481 LastWriteTime: LARGE_INTEGER,
3482 ChangeTime: LARGE_INTEGER,
3483 EndOfFile: LARGE_INTEGER,
3484 AllocationSize: LARGE_INTEGER,
3485 FileAttributes: ULONG,
3486 FileNameLength: ULONG,
3487 EaSize: ULONG,
3488 ShortNameLength: CHAR,
3489 ShortName: [12]WCHAR,
3490 FileName: [1]WCHAR,
3491};
3492pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION;
3493
3494pub const IO_APC_ROUTINE = fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void;
3495
3496pub const CURDIR = extern struct {
3497 DosPath: UNICODE_STRING,
3498 Handle: HANDLE,
3499};
3500
3501pub const DUPLICATE_SAME_ACCESS = 2;
3502
3503pub const MODULEINFO = extern struct {
3504 lpBaseOfDll: LPVOID,
3505 SizeOfImage: DWORD,
3506 EntryPoint: LPVOID,
3507};
3508
3509pub const PSAPI_WS_WATCH_INFORMATION = extern struct {
3510 FaultingPc: LPVOID,
3511 FaultingVa: LPVOID,
3512};
3513
3514pub const PROCESS_MEMORY_COUNTERS = extern struct {
3515 cb: DWORD,
3516 PageFaultCount: DWORD,
3517 PeakWorkingSetSize: SIZE_T,
3518 WorkingSetSize: SIZE_T,
3519 QuotaPeakPagedPoolUsage: SIZE_T,
3520 QuotaPagedPoolUsage: SIZE_T,
3521 QuotaPeakNonPagedPoolUsage: SIZE_T,
3522 QuotaNonPagedPoolUsage: SIZE_T,
3523 PagefileUsage: SIZE_T,
3524 PeakPagefileUsage: SIZE_T,
3525};
3526
3527pub const PROCESS_MEMORY_COUNTERS_EX = extern struct {
3528 cb: DWORD,
3529 PageFaultCount: DWORD,
3530 PeakWorkingSetSize: SIZE_T,
3531 WorkingSetSize: SIZE_T,
3532 QuotaPeakPagedPoolUsage: SIZE_T,
3533 QuotaPagedPoolUsage: SIZE_T,
3534 QuotaPeakNonPagedPoolUsage: SIZE_T,
3535 QuotaNonPagedPoolUsage: SIZE_T,
3536 PagefileUsage: SIZE_T,
3537 PeakPagefileUsage: SIZE_T,
3538 PrivateUsage: SIZE_T,
3539};
3540
3541pub const PERFORMANCE_INFORMATION = extern struct {
3542 cb: DWORD,
3543 CommitTotal: SIZE_T,
3544 CommitLimit: SIZE_T,
3545 CommitPeak: SIZE_T,
3546 PhysicalTotal: SIZE_T,
3547 PhysicalAvailable: SIZE_T,
3548 SystemCache: SIZE_T,
3549 KernelTotal: SIZE_T,
3550 KernelPaged: SIZE_T,
3551 KernelNonpaged: SIZE_T,
3552 PageSize: SIZE_T,
3553 HandleCount: DWORD,
3554 ProcessCount: DWORD,
3555 ThreadCount: DWORD,
3556};
3557
3558pub const ENUM_PAGE_FILE_INFORMATION = extern struct {
3559 cb: DWORD,
3560 Reserved: DWORD,
3561 TotalSize: SIZE_T,
3562 TotalInUse: SIZE_T,
3563 PeakUsage: SIZE_T,
3564};
3565
3566pub const PENUM_PAGE_FILE_CALLBACKW = ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCWSTR) callconv(.C) BOOL;
3567pub const PENUM_PAGE_FILE_CALLBACKA = ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCSTR) callconv(.C) BOOL;
3568
3569pub const PSAPI_WS_WATCH_INFORMATION_EX = extern struct {
3570 BasicInfo: PSAPI_WS_WATCH_INFORMATION,
3571 FaultingThreadId: ULONG_PTR,
3572 Flags: ULONG_PTR,
3573};
3574
3575pub const OSVERSIONINFOW = extern struct {
3576 dwOSVersionInfoSize: ULONG,
3577 dwMajorVersion: ULONG,
3578 dwMinorVersion: ULONG,
3579 dwBuildNumber: ULONG,
3580 dwPlatformId: ULONG,
3581 szCSDVersion: [128]WCHAR,
3582};
3583pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
3584
3585pub const REPARSE_DATA_BUFFER = extern struct {
3586 ReparseTag: ULONG,
3587 ReparseDataLength: USHORT,
3588 Reserved: USHORT,
3589 DataBuffer: [1]UCHAR,
3590};
3591pub const SYMBOLIC_LINK_REPARSE_BUFFER = extern struct {
3592 SubstituteNameOffset: USHORT,
3593 SubstituteNameLength: USHORT,
3594 PrintNameOffset: USHORT,
3595 PrintNameLength: USHORT,
3596 Flags: ULONG,
3597 PathBuffer: [1]WCHAR,
3598};
3599pub const MOUNT_POINT_REPARSE_BUFFER = extern struct {
3600 SubstituteNameOffset: USHORT,
3601 SubstituteNameLength: USHORT,
3602 PrintNameOffset: USHORT,
3603 PrintNameLength: USHORT,
3604 PathBuffer: [1]WCHAR,
3605};
3606pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024;
3607pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
3608pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
3609pub const IO_REPARSE_TAG_SYMLINK: ULONG = 0xa000000c;
3610pub const IO_REPARSE_TAG_MOUNT_POINT: ULONG = 0xa0000003;
3611pub const SYMLINK_FLAG_RELATIVE: ULONG = 0x1;
3612
3613pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
3614pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
3615
3616pub const MOUNTMGR_MOUNT_POINT = extern struct {
3617 SymbolicLinkNameOffset: ULONG,
3618 SymbolicLinkNameLength: USHORT,
3619 Reserved1: USHORT,
3620 UniqueIdOffset: ULONG,
3621 UniqueIdLength: USHORT,
3622 Reserved2: USHORT,
3623 DeviceNameOffset: ULONG,
3624 DeviceNameLength: USHORT,
3625 Reserved3: USHORT,
3626};
3627pub const MOUNTMGR_MOUNT_POINTS = extern struct {
3628 Size: ULONG,
3629 NumberOfMountPoints: ULONG,
3630 MountPoints: [1]MOUNTMGR_MOUNT_POINT,
3631};
3632pub const IOCTL_MOUNTMGR_QUERY_POINTS: ULONG = 0x6d0008;
3633
3634pub const OBJECT_INFORMATION_CLASS = enum(c_int) {
3635 ObjectBasicInformation = 0,
3636 ObjectNameInformation = 1,
3637 ObjectTypeInformation = 2,
3638 ObjectTypesInformation = 3,
3639 ObjectHandleFlagInformation = 4,
3640 ObjectSessionInformation = 5,
3641 MaxObjectInfoClass,
3642};
3643
3644pub const OBJECT_NAME_INFORMATION = extern struct {
3645 Name: UNICODE_STRING,
3646};
3647
3648pub const SRWLOCK = usize;
3649pub const SRWLOCK_INIT: SRWLOCK = 0;
3650pub const CONDITION_VARIABLE = usize;
3651pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = 0;
3652
3653pub const FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 0x1;
3654pub const FILE_SKIP_SET_EVENT_ON_HANDLE = 0x2;
3655
3656pub const CTRL_C_EVENT: DWORD = 0;
3657pub const CTRL_BREAK_EVENT: DWORD = 1;
3658pub const CTRL_CLOSE_EVENT: DWORD = 2;
3659pub const CTRL_LOGOFF_EVENT: DWORD = 5;
3660pub const CTRL_SHUTDOWN_EVENT: DWORD = 6;
3661
3662pub const HANDLER_ROUTINE = fn (dwCtrlType: DWORD) callconv(.C) BOOL;
lib/std/os/windows/advapi32.zig+15-5
...@@ -1,4 +1,14 @@...@@ -1,4 +1,14 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;
3const BOOL = windows.BOOL;
4const DWORD = windows.DWORD;
5const HKEY = windows.HKEY;
6const BYTE = windows.BYTE;
7const LPCWSTR = windows.LPCWSTR;
8const LSTATUS = windows.LSTATUS;
9const REGSAM = windows.REGSAM;
10const ULONG = windows.ULONG;
11const WINAPI = windows.WINAPI;
212
3pub extern "advapi32" fn RegOpenKeyExW(13pub extern "advapi32" fn RegOpenKeyExW(
4 hKey: HKEY,14 hKey: HKEY,
...@@ -11,10 +21,10 @@ pub extern "advapi32" fn RegOpenKeyExW(...@@ -11,10 +21,10 @@ pub extern "advapi32" fn RegOpenKeyExW(
11pub extern "advapi32" fn RegQueryValueExW(21pub extern "advapi32" fn RegQueryValueExW(
12 hKey: HKEY,22 hKey: HKEY,
13 lpValueName: LPCWSTR,23 lpValueName: LPCWSTR,
14 lpReserved: LPDWORD,24 lpReserved: *DWORD,
15 lpType: LPDWORD,25 lpType: *DWORD,
16 lpData: LPBYTE,26 lpData: *BYTE,
17 lpcbData: LPDWORD,27 lpcbData: *DWORD,
18) callconv(WINAPI) LSTATUS;28) callconv(WINAPI) LSTATUS;
1929
20// RtlGenRandom is known as SystemFunction036 under advapi3230// RtlGenRandom is known as SystemFunction036 under advapi32
lib/std/os/windows/bits.zig deleted-1668
...@@ -1,1668 +0,0 @@
1// Platform-dependent types and values that are used along with OS-specific APIs.
2
3const std = @import("../../std.zig");
4const assert = std.debug.assert;
5const maxInt = std.math.maxInt;
6const arch = std.Target.current.cpu.arch;
7
8pub usingnamespace @import("win32error.zig");
9pub usingnamespace @import("ntstatus.zig");
10pub const LANG = @import("lang.zig");
11pub const SUBLANG = @import("sublang.zig");
12
13/// The standard input device. Initially, this is the console input buffer, CONIN$.
14pub const STD_INPUT_HANDLE = maxInt(DWORD) - 10 + 1;
15
16/// The standard output device. Initially, this is the active console screen buffer, CONOUT$.
17pub const STD_OUTPUT_HANDLE = maxInt(DWORD) - 11 + 1;
18
19/// The standard error device. Initially, this is the active console screen buffer, CONOUT$.
20pub const STD_ERROR_HANDLE = maxInt(DWORD) - 12 + 1;
21
22pub const WINAPI: std.builtin.CallingConvention = if (arch == .i386)
23 .Stdcall
24else
25 .C;
26
27pub const BOOL = c_int;
28pub const BOOLEAN = BYTE;
29pub const BYTE = u8;
30pub const CHAR = u8;
31pub const UCHAR = u8;
32pub const FLOAT = f32;
33pub const HANDLE = *c_void;
34pub const HCRYPTPROV = ULONG_PTR;
35pub const ATOM = u16;
36pub const HBRUSH = *opaque {};
37pub const HCURSOR = *opaque {};
38pub const HICON = *opaque {};
39pub const HINSTANCE = *opaque {};
40pub const HMENU = *opaque {};
41pub const HMODULE = *opaque {};
42pub const HWND = *opaque {};
43pub const HDC = *opaque {};
44pub const HGLRC = *opaque {};
45pub const FARPROC = *opaque {};
46pub const INT = c_int;
47pub const LPBYTE = *BYTE;
48pub const LPCH = *CHAR;
49pub const LPCSTR = [*:0]const CHAR;
50pub const LPCVOID = *const c_void;
51pub const LPDWORD = *DWORD;
52pub const LPSTR = [*:0]CHAR;
53pub const LPVOID = *c_void;
54pub const LPWSTR = [*:0]WCHAR;
55pub const LPCWSTR = [*:0]const WCHAR;
56pub const PVOID = *c_void;
57pub const PWSTR = [*:0]WCHAR;
58pub const SIZE_T = usize;
59pub const UINT = c_uint;
60pub const ULONG_PTR = usize;
61pub const LONG_PTR = isize;
62pub const DWORD_PTR = ULONG_PTR;
63pub const WCHAR = u16;
64pub const WORD = u16;
65pub const DWORD = u32;
66pub const DWORD64 = u64;
67pub const LARGE_INTEGER = i64;
68pub const ULARGE_INTEGER = u64;
69pub const USHORT = u16;
70pub const SHORT = i16;
71pub const ULONG = u32;
72pub const LONG = i32;
73pub const ULONGLONG = u64;
74pub const LONGLONG = i64;
75pub const HLOCAL = HANDLE;
76pub const LANGID = c_ushort;
77
78pub const WPARAM = usize;
79pub const LPARAM = LONG_PTR;
80pub const LRESULT = LONG_PTR;
81
82pub const va_list = *opaque {};
83
84pub const TRUE = 1;
85pub const FALSE = 0;
86
87pub const DEVICE_TYPE = ULONG;
88pub const FILE_DEVICE_BEEP: DEVICE_TYPE = 0x0001;
89pub const FILE_DEVICE_CD_ROM: DEVICE_TYPE = 0x0002;
90pub const FILE_DEVICE_CD_ROM_FILE_SYSTEM: DEVICE_TYPE = 0x0003;
91pub const FILE_DEVICE_CONTROLLER: DEVICE_TYPE = 0x0004;
92pub const FILE_DEVICE_DATALINK: DEVICE_TYPE = 0x0005;
93pub const FILE_DEVICE_DFS: DEVICE_TYPE = 0x0006;
94pub const FILE_DEVICE_DISK: DEVICE_TYPE = 0x0007;
95pub const FILE_DEVICE_DISK_FILE_SYSTEM: DEVICE_TYPE = 0x0008;
96pub const FILE_DEVICE_FILE_SYSTEM: DEVICE_TYPE = 0x0009;
97pub const FILE_DEVICE_INPORT_PORT: DEVICE_TYPE = 0x000a;
98pub const FILE_DEVICE_KEYBOARD: DEVICE_TYPE = 0x000b;
99pub const FILE_DEVICE_MAILSLOT: DEVICE_TYPE = 0x000c;
100pub const FILE_DEVICE_MIDI_IN: DEVICE_TYPE = 0x000d;
101pub const FILE_DEVICE_MIDI_OUT: DEVICE_TYPE = 0x000e;
102pub const FILE_DEVICE_MOUSE: DEVICE_TYPE = 0x000f;
103pub const FILE_DEVICE_MULTI_UNC_PROVIDER: DEVICE_TYPE = 0x0010;
104pub const FILE_DEVICE_NAMED_PIPE: DEVICE_TYPE = 0x0011;
105pub const FILE_DEVICE_NETWORK: DEVICE_TYPE = 0x0012;
106pub const FILE_DEVICE_NETWORK_BROWSER: DEVICE_TYPE = 0x0013;
107pub const FILE_DEVICE_NETWORK_FILE_SYSTEM: DEVICE_TYPE = 0x0014;
108pub const FILE_DEVICE_NULL: DEVICE_TYPE = 0x0015;
109pub const FILE_DEVICE_PARALLEL_PORT: DEVICE_TYPE = 0x0016;
110pub const FILE_DEVICE_PHYSICAL_NETCARD: DEVICE_TYPE = 0x0017;
111pub const FILE_DEVICE_PRINTER: DEVICE_TYPE = 0x0018;
112pub const FILE_DEVICE_SCANNER: DEVICE_TYPE = 0x0019;
113pub const FILE_DEVICE_SERIAL_MOUSE_PORT: DEVICE_TYPE = 0x001a;
114pub const FILE_DEVICE_SERIAL_PORT: DEVICE_TYPE = 0x001b;
115pub const FILE_DEVICE_SCREEN: DEVICE_TYPE = 0x001c;
116pub const FILE_DEVICE_SOUND: DEVICE_TYPE = 0x001d;
117pub const FILE_DEVICE_STREAMS: DEVICE_TYPE = 0x001e;
118pub const FILE_DEVICE_TAPE: DEVICE_TYPE = 0x001f;
119pub const FILE_DEVICE_TAPE_FILE_SYSTEM: DEVICE_TYPE = 0x0020;
120pub const FILE_DEVICE_TRANSPORT: DEVICE_TYPE = 0x0021;
121pub const FILE_DEVICE_UNKNOWN: DEVICE_TYPE = 0x0022;
122pub const FILE_DEVICE_VIDEO: DEVICE_TYPE = 0x0023;
123pub const FILE_DEVICE_VIRTUAL_DISK: DEVICE_TYPE = 0x0024;
124pub const FILE_DEVICE_WAVE_IN: DEVICE_TYPE = 0x0025;
125pub const FILE_DEVICE_WAVE_OUT: DEVICE_TYPE = 0x0026;
126pub const FILE_DEVICE_8042_PORT: DEVICE_TYPE = 0x0027;
127pub const FILE_DEVICE_NETWORK_REDIRECTOR: DEVICE_TYPE = 0x0028;
128pub const FILE_DEVICE_BATTERY: DEVICE_TYPE = 0x0029;
129pub const FILE_DEVICE_BUS_EXTENDER: DEVICE_TYPE = 0x002a;
130pub const FILE_DEVICE_MODEM: DEVICE_TYPE = 0x002b;
131pub const FILE_DEVICE_VDM: DEVICE_TYPE = 0x002c;
132pub const FILE_DEVICE_MASS_STORAGE: DEVICE_TYPE = 0x002d;
133pub const FILE_DEVICE_SMB: DEVICE_TYPE = 0x002e;
134pub const FILE_DEVICE_KS: DEVICE_TYPE = 0x002f;
135pub const FILE_DEVICE_CHANGER: DEVICE_TYPE = 0x0030;
136pub const FILE_DEVICE_SMARTCARD: DEVICE_TYPE = 0x0031;
137pub const FILE_DEVICE_ACPI: DEVICE_TYPE = 0x0032;
138pub const FILE_DEVICE_DVD: DEVICE_TYPE = 0x0033;
139pub const FILE_DEVICE_FULLSCREEN_VIDEO: DEVICE_TYPE = 0x0034;
140pub const FILE_DEVICE_DFS_FILE_SYSTEM: DEVICE_TYPE = 0x0035;
141pub const FILE_DEVICE_DFS_VOLUME: DEVICE_TYPE = 0x0036;
142pub const FILE_DEVICE_SERENUM: DEVICE_TYPE = 0x0037;
143pub const FILE_DEVICE_TERMSRV: DEVICE_TYPE = 0x0038;
144pub const FILE_DEVICE_KSEC: DEVICE_TYPE = 0x0039;
145pub const FILE_DEVICE_FIPS: DEVICE_TYPE = 0x003a;
146pub const FILE_DEVICE_INFINIBAND: DEVICE_TYPE = 0x003b;
147// TODO: missing values?
148pub const FILE_DEVICE_VMBUS: DEVICE_TYPE = 0x003e;
149pub const FILE_DEVICE_CRYPT_PROVIDER: DEVICE_TYPE = 0x003f;
150pub const FILE_DEVICE_WPD: DEVICE_TYPE = 0x0040;
151pub const FILE_DEVICE_BLUETOOTH: DEVICE_TYPE = 0x0041;
152pub const FILE_DEVICE_MT_COMPOSITE: DEVICE_TYPE = 0x0042;
153pub const FILE_DEVICE_MT_TRANSPORT: DEVICE_TYPE = 0x0043;
154pub const FILE_DEVICE_BIOMETRIC: DEVICE_TYPE = 0x0044;
155pub const FILE_DEVICE_PMI: DEVICE_TYPE = 0x0045;
156pub const FILE_DEVICE_EHSTOR: DEVICE_TYPE = 0x0046;
157pub const FILE_DEVICE_DEVAPI: DEVICE_TYPE = 0x0047;
158pub const FILE_DEVICE_GPIO: DEVICE_TYPE = 0x0048;
159pub const FILE_DEVICE_USBEX: DEVICE_TYPE = 0x0049;
160pub const FILE_DEVICE_CONSOLE: DEVICE_TYPE = 0x0050;
161pub const FILE_DEVICE_NFP: DEVICE_TYPE = 0x0051;
162pub const FILE_DEVICE_SYSENV: DEVICE_TYPE = 0x0052;
163pub const FILE_DEVICE_VIRTUAL_BLOCK: DEVICE_TYPE = 0x0053;
164pub const FILE_DEVICE_POINT_OF_SERVICE: DEVICE_TYPE = 0x0054;
165pub const FILE_DEVICE_STORAGE_REPLICATION: DEVICE_TYPE = 0x0055;
166pub const FILE_DEVICE_TRUST_ENV: DEVICE_TYPE = 0x0056;
167pub const FILE_DEVICE_UCM: DEVICE_TYPE = 0x0057;
168pub const FILE_DEVICE_UCMTCPCI: DEVICE_TYPE = 0x0058;
169pub const FILE_DEVICE_PERSISTENT_MEMORY: DEVICE_TYPE = 0x0059;
170pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a;
171pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b;
172pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c;
173
174/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes
175pub const TransferType = enum(u2) {
176 METHOD_BUFFERED = 0,
177 METHOD_IN_DIRECT = 1,
178 METHOD_OUT_DIRECT = 2,
179 METHOD_NEITHER = 3,
180};
181
182pub const FILE_ANY_ACCESS = 0;
183pub const FILE_READ_ACCESS = 1;
184pub const FILE_WRITE_ACCESS = 2;
185
186/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
187pub fn CTL_CODE(deviceType: u16, function: u12, method: TransferType, access: u2) DWORD {
188 return (@as(DWORD, deviceType) << 16) |
189 (@as(DWORD, access) << 14) |
190 (@as(DWORD, function) << 2) |
191 @enumToInt(method);
192}
193
194pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
195
196pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
197
198pub const FILE_ALL_INFORMATION = extern struct {
199 BasicInformation: FILE_BASIC_INFORMATION,
200 StandardInformation: FILE_STANDARD_INFORMATION,
201 InternalInformation: FILE_INTERNAL_INFORMATION,
202 EaInformation: FILE_EA_INFORMATION,
203 AccessInformation: FILE_ACCESS_INFORMATION,
204 PositionInformation: FILE_POSITION_INFORMATION,
205 ModeInformation: FILE_MODE_INFORMATION,
206 AlignmentInformation: FILE_ALIGNMENT_INFORMATION,
207 NameInformation: FILE_NAME_INFORMATION,
208};
209
210pub const FILE_BASIC_INFORMATION = extern struct {
211 CreationTime: LARGE_INTEGER,
212 LastAccessTime: LARGE_INTEGER,
213 LastWriteTime: LARGE_INTEGER,
214 ChangeTime: LARGE_INTEGER,
215 FileAttributes: ULONG,
216};
217
218pub const FILE_STANDARD_INFORMATION = extern struct {
219 AllocationSize: LARGE_INTEGER,
220 EndOfFile: LARGE_INTEGER,
221 NumberOfLinks: ULONG,
222 DeletePending: BOOLEAN,
223 Directory: BOOLEAN,
224};
225
226pub const FILE_INTERNAL_INFORMATION = extern struct {
227 IndexNumber: LARGE_INTEGER,
228};
229
230pub const FILE_EA_INFORMATION = extern struct {
231 EaSize: ULONG,
232};
233
234pub const FILE_ACCESS_INFORMATION = extern struct {
235 AccessFlags: ACCESS_MASK,
236};
237
238pub const FILE_POSITION_INFORMATION = extern struct {
239 CurrentByteOffset: LARGE_INTEGER,
240};
241
242pub const FILE_END_OF_FILE_INFORMATION = extern struct {
243 EndOfFile: LARGE_INTEGER,
244};
245
246pub const FILE_MODE_INFORMATION = extern struct {
247 Mode: ULONG,
248};
249
250pub const FILE_ALIGNMENT_INFORMATION = extern struct {
251 AlignmentRequirement: ULONG,
252};
253
254pub const FILE_NAME_INFORMATION = extern struct {
255 FileNameLength: ULONG,
256 FileName: [1]WCHAR,
257};
258
259pub const FILE_RENAME_INFORMATION = extern struct {
260 ReplaceIfExists: BOOLEAN,
261 RootDirectory: ?HANDLE,
262 FileNameLength: ULONG,
263 FileName: [1]WCHAR,
264};
265
266pub const IO_STATUS_BLOCK = extern struct {
267 // "DUMMYUNIONNAME" expands to "u"
268 u: extern union {
269 Status: NTSTATUS,
270 Pointer: ?*c_void,
271 },
272 Information: ULONG_PTR,
273};
274
275pub const FILE_INFORMATION_CLASS = enum(c_int) {
276 FileDirectoryInformation = 1,
277 FileFullDirectoryInformation,
278 FileBothDirectoryInformation,
279 FileBasicInformation,
280 FileStandardInformation,
281 FileInternalInformation,
282 FileEaInformation,
283 FileAccessInformation,
284 FileNameInformation,
285 FileRenameInformation,
286 FileLinkInformation,
287 FileNamesInformation,
288 FileDispositionInformation,
289 FilePositionInformation,
290 FileFullEaInformation,
291 FileModeInformation,
292 FileAlignmentInformation,
293 FileAllInformation,
294 FileAllocationInformation,
295 FileEndOfFileInformation,
296 FileAlternateNameInformation,
297 FileStreamInformation,
298 FilePipeInformation,
299 FilePipeLocalInformation,
300 FilePipeRemoteInformation,
301 FileMailslotQueryInformation,
302 FileMailslotSetInformation,
303 FileCompressionInformation,
304 FileObjectIdInformation,
305 FileCompletionInformation,
306 FileMoveClusterInformation,
307 FileQuotaInformation,
308 FileReparsePointInformation,
309 FileNetworkOpenInformation,
310 FileAttributeTagInformation,
311 FileTrackingInformation,
312 FileIdBothDirectoryInformation,
313 FileIdFullDirectoryInformation,
314 FileValidDataLengthInformation,
315 FileShortNameInformation,
316 FileIoCompletionNotificationInformation,
317 FileIoStatusBlockRangeInformation,
318 FileIoPriorityHintInformation,
319 FileSfioReserveInformation,
320 FileSfioVolumeInformation,
321 FileHardLinkInformation,
322 FileProcessIdsUsingFileInformation,
323 FileNormalizedNameInformation,
324 FileNetworkPhysicalNameInformation,
325 FileIdGlobalTxDirectoryInformation,
326 FileIsRemoteDeviceInformation,
327 FileUnusedInformation,
328 FileNumaNodeInformation,
329 FileStandardLinkInformation,
330 FileRemoteProtocolInformation,
331 FileRenameInformationBypassAccessCheck,
332 FileLinkInformationBypassAccessCheck,
333 FileVolumeNameInformation,
334 FileIdInformation,
335 FileIdExtdDirectoryInformation,
336 FileReplaceCompletionInformation,
337 FileHardLinkFullIdInformation,
338 FileIdExtdBothDirectoryInformation,
339 FileDispositionInformationEx,
340 FileRenameInformationEx,
341 FileRenameInformationExBypassAccessCheck,
342 FileDesiredStorageClassInformation,
343 FileStatInformation,
344 FileMemoryPartitionInformation,
345 FileStatLxInformation,
346 FileCaseSensitiveInformation,
347 FileLinkInformationEx,
348 FileLinkInformationExBypassAccessCheck,
349 FileStorageReserveIdInformation,
350 FileCaseSensitiveInformationForceAccessCheck,
351 FileMaximumInformation,
352};
353
354pub const OVERLAPPED = extern struct {
355 Internal: ULONG_PTR,
356 InternalHigh: ULONG_PTR,
357 DUMMYUNIONNAME: extern union {
358 DUMMYSTRUCTNAME: extern struct {
359 Offset: DWORD,
360 OffsetHigh: DWORD,
361 },
362 Pointer: ?PVOID,
363 },
364 hEvent: ?HANDLE,
365};
366pub const LPOVERLAPPED = *OVERLAPPED;
367
368pub const OVERLAPPED_ENTRY = extern struct {
369 lpCompletionKey: ULONG_PTR,
370 lpOverlapped: LPOVERLAPPED,
371 Internal: ULONG_PTR,
372 dwNumberOfBytesTransferred: DWORD,
373};
374pub const LPOVERLAPPED_ENTRY = *OVERLAPPED_ENTRY;
375
376pub const MAX_PATH = 260;
377
378// TODO issue #305
379pub const FILE_INFO_BY_HANDLE_CLASS = u32;
380pub const FileBasicInfo = 0;
381pub const FileStandardInfo = 1;
382pub const FileNameInfo = 2;
383pub const FileRenameInfo = 3;
384pub const FileDispositionInfo = 4;
385pub const FileAllocationInfo = 5;
386pub const FileEndOfFileInfo = 6;
387pub const FileStreamInfo = 7;
388pub const FileCompressionInfo = 8;
389pub const FileAttributeTagInfo = 9;
390pub const FileIdBothDirectoryInfo = 10;
391pub const FileIdBothDirectoryRestartInfo = 11;
392pub const FileIoPriorityHintInfo = 12;
393pub const FileRemoteProtocolInfo = 13;
394pub const FileFullDirectoryInfo = 14;
395pub const FileFullDirectoryRestartInfo = 15;
396pub const FileStorageInfo = 16;
397pub const FileAlignmentInfo = 17;
398pub const FileIdInfo = 18;
399pub const FileIdExtdDirectoryInfo = 19;
400pub const FileIdExtdDirectoryRestartInfo = 20;
401
402pub const BY_HANDLE_FILE_INFORMATION = extern struct {
403 dwFileAttributes: DWORD,
404 ftCreationTime: FILETIME,
405 ftLastAccessTime: FILETIME,
406 ftLastWriteTime: FILETIME,
407 dwVolumeSerialNumber: DWORD,
408 nFileSizeHigh: DWORD,
409 nFileSizeLow: DWORD,
410 nNumberOfLinks: DWORD,
411 nFileIndexHigh: DWORD,
412 nFileIndexLow: DWORD,
413};
414
415pub const FILE_NAME_INFO = extern struct {
416 FileNameLength: DWORD,
417 FileName: [1]WCHAR,
418};
419
420/// Return the normalized drive name. This is the default.
421pub const FILE_NAME_NORMALIZED = 0x0;
422
423/// Return the opened file name (not normalized).
424pub const FILE_NAME_OPENED = 0x8;
425
426/// Return the path with the drive letter. This is the default.
427pub const VOLUME_NAME_DOS = 0x0;
428
429/// Return the path with a volume GUID path instead of the drive name.
430pub const VOLUME_NAME_GUID = 0x1;
431
432/// Return the path with no drive information.
433pub const VOLUME_NAME_NONE = 0x4;
434
435/// Return the path with the volume device path.
436pub const VOLUME_NAME_NT = 0x2;
437
438pub const SECURITY_ATTRIBUTES = extern struct {
439 nLength: DWORD,
440 lpSecurityDescriptor: ?*c_void,
441 bInheritHandle: BOOL,
442};
443pub const PSECURITY_ATTRIBUTES = *SECURITY_ATTRIBUTES;
444pub const LPSECURITY_ATTRIBUTES = *SECURITY_ATTRIBUTES;
445
446pub const PIPE_ACCESS_INBOUND = 0x00000001;
447pub const PIPE_ACCESS_OUTBOUND = 0x00000002;
448pub const PIPE_ACCESS_DUPLEX = 0x00000003;
449
450pub const PIPE_TYPE_BYTE = 0x00000000;
451pub const PIPE_TYPE_MESSAGE = 0x00000004;
452
453pub const PIPE_READMODE_BYTE = 0x00000000;
454pub const PIPE_READMODE_MESSAGE = 0x00000002;
455
456pub const PIPE_WAIT = 0x00000000;
457pub const PIPE_NOWAIT = 0x00000001;
458
459pub const GENERIC_READ = 0x80000000;
460pub const GENERIC_WRITE = 0x40000000;
461pub const GENERIC_EXECUTE = 0x20000000;
462pub const GENERIC_ALL = 0x10000000;
463
464pub const FILE_SHARE_DELETE = 0x00000004;
465pub const FILE_SHARE_READ = 0x00000001;
466pub const FILE_SHARE_WRITE = 0x00000002;
467
468pub const DELETE = 0x00010000;
469pub const READ_CONTROL = 0x00020000;
470pub const WRITE_DAC = 0x00040000;
471pub const WRITE_OWNER = 0x00080000;
472pub const SYNCHRONIZE = 0x00100000;
473pub const STANDARD_RIGHTS_READ = READ_CONTROL;
474pub const STANDARD_RIGHTS_WRITE = READ_CONTROL;
475pub const STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
476pub const STANDARD_RIGHTS_REQUIRED = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER;
477
478// disposition for NtCreateFile
479pub const FILE_SUPERSEDE = 0;
480pub const FILE_OPEN = 1;
481pub const FILE_CREATE = 2;
482pub const FILE_OPEN_IF = 3;
483pub const FILE_OVERWRITE = 4;
484pub const FILE_OVERWRITE_IF = 5;
485pub const FILE_MAXIMUM_DISPOSITION = 5;
486
487// flags for NtCreateFile and NtOpenFile
488pub const FILE_READ_DATA = 0x00000001;
489pub const FILE_LIST_DIRECTORY = 0x00000001;
490pub const FILE_WRITE_DATA = 0x00000002;
491pub const FILE_ADD_FILE = 0x00000002;
492pub const FILE_APPEND_DATA = 0x00000004;
493pub const FILE_ADD_SUBDIRECTORY = 0x00000004;
494pub const FILE_CREATE_PIPE_INSTANCE = 0x00000004;
495pub const FILE_READ_EA = 0x00000008;
496pub const FILE_WRITE_EA = 0x00000010;
497pub const FILE_EXECUTE = 0x00000020;
498pub const FILE_TRAVERSE = 0x00000020;
499pub const FILE_DELETE_CHILD = 0x00000040;
500pub const FILE_READ_ATTRIBUTES = 0x00000080;
501pub const FILE_WRITE_ATTRIBUTES = 0x00000100;
502
503pub const FILE_DIRECTORY_FILE = 0x00000001;
504pub const FILE_WRITE_THROUGH = 0x00000002;
505pub const FILE_SEQUENTIAL_ONLY = 0x00000004;
506pub const FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008;
507pub const FILE_SYNCHRONOUS_IO_ALERT = 0x00000010;
508pub const FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020;
509pub const FILE_NON_DIRECTORY_FILE = 0x00000040;
510pub const FILE_CREATE_TREE_CONNECTION = 0x00000080;
511pub const FILE_COMPLETE_IF_OPLOCKED = 0x00000100;
512pub const FILE_NO_EA_KNOWLEDGE = 0x00000200;
513pub const FILE_OPEN_FOR_RECOVERY = 0x00000400;
514pub const FILE_RANDOM_ACCESS = 0x00000800;
515pub const FILE_DELETE_ON_CLOSE = 0x00001000;
516pub const FILE_OPEN_BY_FILE_ID = 0x00002000;
517pub const FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000;
518pub const FILE_NO_COMPRESSION = 0x00008000;
519pub const FILE_RESERVE_OPFILTER = 0x00100000;
520pub const FILE_OPEN_REPARSE_POINT = 0x00200000;
521pub const FILE_OPEN_OFFLINE_FILE = 0x00400000;
522pub const FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000;
523
524pub const CREATE_ALWAYS = 2;
525pub const CREATE_NEW = 1;
526pub const OPEN_ALWAYS = 4;
527pub const OPEN_EXISTING = 3;
528pub const TRUNCATE_EXISTING = 5;
529
530pub const FILE_ATTRIBUTE_ARCHIVE = 0x20;
531pub const FILE_ATTRIBUTE_COMPRESSED = 0x800;
532pub const FILE_ATTRIBUTE_DEVICE = 0x40;
533pub const FILE_ATTRIBUTE_DIRECTORY = 0x10;
534pub const FILE_ATTRIBUTE_ENCRYPTED = 0x4000;
535pub const FILE_ATTRIBUTE_HIDDEN = 0x2;
536pub const FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000;
537pub const FILE_ATTRIBUTE_NORMAL = 0x80;
538pub const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000;
539pub const FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x20000;
540pub const FILE_ATTRIBUTE_OFFLINE = 0x1000;
541pub const FILE_ATTRIBUTE_READONLY = 0x1;
542pub const FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x400000;
543pub const FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x40000;
544pub const FILE_ATTRIBUTE_REPARSE_POINT = 0x400;
545pub const FILE_ATTRIBUTE_SPARSE_FILE = 0x200;
546pub const FILE_ATTRIBUTE_SYSTEM = 0x4;
547pub const FILE_ATTRIBUTE_TEMPORARY = 0x100;
548pub const FILE_ATTRIBUTE_VIRTUAL = 0x10000;
549
550// flags for CreateEvent
551pub const CREATE_EVENT_INITIAL_SET = 0x00000002;
552pub const CREATE_EVENT_MANUAL_RESET = 0x00000001;
553
554pub const EVENT_ALL_ACCESS = 0x1F0003;
555pub const EVENT_MODIFY_STATE = 0x0002;
556
557pub const PROCESS_INFORMATION = extern struct {
558 hProcess: HANDLE,
559 hThread: HANDLE,
560 dwProcessId: DWORD,
561 dwThreadId: DWORD,
562};
563
564pub const STARTUPINFOW = extern struct {
565 cb: DWORD,
566 lpReserved: ?LPWSTR,
567 lpDesktop: ?LPWSTR,
568 lpTitle: ?LPWSTR,
569 dwX: DWORD,
570 dwY: DWORD,
571 dwXSize: DWORD,
572 dwYSize: DWORD,
573 dwXCountChars: DWORD,
574 dwYCountChars: DWORD,
575 dwFillAttribute: DWORD,
576 dwFlags: DWORD,
577 wShowWindow: WORD,
578 cbReserved2: WORD,
579 lpReserved2: ?LPBYTE,
580 hStdInput: ?HANDLE,
581 hStdOutput: ?HANDLE,
582 hStdError: ?HANDLE,
583};
584
585pub const STARTF_FORCEONFEEDBACK = 0x00000040;
586pub const STARTF_FORCEOFFFEEDBACK = 0x00000080;
587pub const STARTF_PREVENTPINNING = 0x00002000;
588pub const STARTF_RUNFULLSCREEN = 0x00000020;
589pub const STARTF_TITLEISAPPID = 0x00001000;
590pub const STARTF_TITLEISLINKNAME = 0x00000800;
591pub const STARTF_UNTRUSTEDSOURCE = 0x00008000;
592pub const STARTF_USECOUNTCHARS = 0x00000008;
593pub const STARTF_USEFILLATTRIBUTE = 0x00000010;
594pub const STARTF_USEHOTKEY = 0x00000200;
595pub const STARTF_USEPOSITION = 0x00000004;
596pub const STARTF_USESHOWWINDOW = 0x00000001;
597pub const STARTF_USESIZE = 0x00000002;
598pub const STARTF_USESTDHANDLES = 0x00000100;
599
600pub const INFINITE = 4294967295;
601
602pub const MAXIMUM_WAIT_OBJECTS = 64;
603
604pub const WAIT_ABANDONED = 0x00000080;
605pub const WAIT_ABANDONED_0 = WAIT_ABANDONED + 0;
606pub const WAIT_OBJECT_0 = 0x00000000;
607pub const WAIT_TIMEOUT = 0x00000102;
608pub const WAIT_FAILED = 0xFFFFFFFF;
609
610pub const HANDLE_FLAG_INHERIT = 0x00000001;
611pub const HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002;
612
613pub const MOVEFILE_COPY_ALLOWED = 2;
614pub const MOVEFILE_CREATE_HARDLINK = 16;
615pub const MOVEFILE_DELAY_UNTIL_REBOOT = 4;
616pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE = 32;
617pub const MOVEFILE_REPLACE_EXISTING = 1;
618pub const MOVEFILE_WRITE_THROUGH = 8;
619
620pub const FILE_BEGIN = 0;
621pub const FILE_CURRENT = 1;
622pub const FILE_END = 2;
623
624pub const HEAP_CREATE_ENABLE_EXECUTE = 0x00040000;
625pub const HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010;
626pub const HEAP_GENERATE_EXCEPTIONS = 0x00000004;
627pub const HEAP_NO_SERIALIZE = 0x00000001;
628
629// AllocationType values
630pub const MEM_COMMIT = 0x1000;
631pub const MEM_RESERVE = 0x2000;
632pub const MEM_RESET = 0x80000;
633pub const MEM_RESET_UNDO = 0x1000000;
634pub const MEM_LARGE_PAGES = 0x20000000;
635pub const MEM_PHYSICAL = 0x400000;
636pub const MEM_TOP_DOWN = 0x100000;
637pub const MEM_WRITE_WATCH = 0x200000;
638
639// Protect values
640pub const PAGE_EXECUTE = 0x10;
641pub const PAGE_EXECUTE_READ = 0x20;
642pub const PAGE_EXECUTE_READWRITE = 0x40;
643pub const PAGE_EXECUTE_WRITECOPY = 0x80;
644pub const PAGE_NOACCESS = 0x01;
645pub const PAGE_READONLY = 0x02;
646pub const PAGE_READWRITE = 0x04;
647pub const PAGE_WRITECOPY = 0x08;
648pub const PAGE_TARGETS_INVALID = 0x40000000;
649pub const PAGE_TARGETS_NO_UPDATE = 0x40000000; // Same as PAGE_TARGETS_INVALID
650pub const PAGE_GUARD = 0x100;
651pub const PAGE_NOCACHE = 0x200;
652pub const PAGE_WRITECOMBINE = 0x400;
653
654// FreeType values
655pub const MEM_COALESCE_PLACEHOLDERS = 0x1;
656pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
657pub const MEM_DECOMMIT = 0x4000;
658pub const MEM_RELEASE = 0x8000;
659
660pub const PTHREAD_START_ROUTINE = fn (LPVOID) callconv(.C) DWORD;
661pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
662
663pub const WIN32_FIND_DATAW = extern struct {
664 dwFileAttributes: DWORD,
665 ftCreationTime: FILETIME,
666 ftLastAccessTime: FILETIME,
667 ftLastWriteTime: FILETIME,
668 nFileSizeHigh: DWORD,
669 nFileSizeLow: DWORD,
670 dwReserved0: DWORD,
671 dwReserved1: DWORD,
672 cFileName: [260]u16,
673 cAlternateFileName: [14]u16,
674};
675
676pub const FILETIME = extern struct {
677 dwLowDateTime: DWORD,
678 dwHighDateTime: DWORD,
679};
680
681pub const SYSTEM_INFO = extern struct {
682 anon1: extern union {
683 dwOemId: DWORD,
684 anon2: extern struct {
685 wProcessorArchitecture: WORD,
686 wReserved: WORD,
687 },
688 },
689 dwPageSize: DWORD,
690 lpMinimumApplicationAddress: LPVOID,
691 lpMaximumApplicationAddress: LPVOID,
692 dwActiveProcessorMask: DWORD_PTR,
693 dwNumberOfProcessors: DWORD,
694 dwProcessorType: DWORD,
695 dwAllocationGranularity: DWORD,
696 wProcessorLevel: WORD,
697 wProcessorRevision: WORD,
698};
699
700pub const HRESULT = c_long;
701
702pub const KNOWNFOLDERID = GUID;
703pub const GUID = extern struct {
704 Data1: c_ulong,
705 Data2: c_ushort,
706 Data3: c_ushort,
707 Data4: [8]u8,
708
709 pub fn parse(str: []const u8) GUID {
710 var guid: GUID = undefined;
711 var index: usize = 0;
712 assert(str[index] == '{');
713 index += 1;
714
715 guid.Data1 = std.fmt.parseUnsigned(c_ulong, str[index .. index + 8], 16) catch unreachable;
716 index += 8;
717
718 assert(str[index] == '-');
719 index += 1;
720
721 guid.Data2 = std.fmt.parseUnsigned(c_ushort, str[index .. index + 4], 16) catch unreachable;
722 index += 4;
723
724 assert(str[index] == '-');
725 index += 1;
726
727 guid.Data3 = std.fmt.parseUnsigned(c_ushort, str[index .. index + 4], 16) catch unreachable;
728 index += 4;
729
730 assert(str[index] == '-');
731 index += 1;
732
733 guid.Data4[0] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable;
734 index += 2;
735 guid.Data4[1] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable;
736 index += 2;
737
738 assert(str[index] == '-');
739 index += 1;
740
741 var i: usize = 2;
742 while (i < guid.Data4.len) : (i += 1) {
743 guid.Data4[i] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable;
744 index += 2;
745 }
746
747 assert(str[index] == '}');
748 index += 1;
749 return guid;
750 }
751};
752
753pub const FOLDERID_LocalAppData = GUID.parse("{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}");
754
755pub const KF_FLAG_DEFAULT = 0;
756pub const KF_FLAG_NO_APPCONTAINER_REDIRECTION = 65536;
757pub const KF_FLAG_CREATE = 32768;
758pub const KF_FLAG_DONT_VERIFY = 16384;
759pub const KF_FLAG_DONT_UNEXPAND = 8192;
760pub const KF_FLAG_NO_ALIAS = 4096;
761pub const KF_FLAG_INIT = 2048;
762pub const KF_FLAG_DEFAULT_PATH = 1024;
763pub const KF_FLAG_NOT_PARENT_RELATIVE = 512;
764pub const KF_FLAG_SIMPLE_IDLIST = 256;
765pub const KF_FLAG_ALIAS_ONLY = -2147483648;
766
767pub const S_OK = 0;
768pub const E_NOTIMPL = @bitCast(c_long, @as(c_ulong, 0x80004001));
769pub const E_NOINTERFACE = @bitCast(c_long, @as(c_ulong, 0x80004002));
770pub const E_POINTER = @bitCast(c_long, @as(c_ulong, 0x80004003));
771pub const E_ABORT = @bitCast(c_long, @as(c_ulong, 0x80004004));
772pub const E_FAIL = @bitCast(c_long, @as(c_ulong, 0x80004005));
773pub const E_UNEXPECTED = @bitCast(c_long, @as(c_ulong, 0x8000FFFF));
774pub const E_ACCESSDENIED = @bitCast(c_long, @as(c_ulong, 0x80070005));
775pub const E_HANDLE = @bitCast(c_long, @as(c_ulong, 0x80070006));
776pub const E_OUTOFMEMORY = @bitCast(c_long, @as(c_ulong, 0x8007000E));
777pub const E_INVALIDARG = @bitCast(c_long, @as(c_ulong, 0x80070057));
778
779pub const FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
780pub const FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
781pub const FILE_FLAG_NO_BUFFERING = 0x20000000;
782pub const FILE_FLAG_OPEN_NO_RECALL = 0x00100000;
783pub const FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000;
784pub const FILE_FLAG_OVERLAPPED = 0x40000000;
785pub const FILE_FLAG_POSIX_SEMANTICS = 0x0100000;
786pub const FILE_FLAG_RANDOM_ACCESS = 0x10000000;
787pub const FILE_FLAG_SESSION_AWARE = 0x00800000;
788pub const FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000;
789pub const FILE_FLAG_WRITE_THROUGH = 0x80000000;
790
791pub const RECT = extern struct {
792 left: LONG,
793 top: LONG,
794 right: LONG,
795 bottom: LONG,
796};
797
798pub const SMALL_RECT = extern struct {
799 Left: SHORT,
800 Top: SHORT,
801 Right: SHORT,
802 Bottom: SHORT,
803};
804
805pub const POINT = extern struct {
806 x: LONG,
807 y: LONG,
808};
809
810pub const COORD = extern struct {
811 X: SHORT,
812 Y: SHORT,
813};
814
815pub const CREATE_UNICODE_ENVIRONMENT = 1024;
816
817pub const TLS_OUT_OF_INDEXES = 4294967295;
818pub const IMAGE_TLS_DIRECTORY = extern struct {
819 StartAddressOfRawData: usize,
820 EndAddressOfRawData: usize,
821 AddressOfIndex: usize,
822 AddressOfCallBacks: usize,
823 SizeOfZeroFill: u32,
824 Characteristics: u32,
825};
826pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;
827pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;
828
829pub const PIMAGE_TLS_CALLBACK = ?fn (PVOID, DWORD, PVOID) callconv(.C) void;
830
831pub const PROV_RSA_FULL = 1;
832
833pub const REGSAM = ACCESS_MASK;
834pub const ACCESS_MASK = DWORD;
835pub const PHKEY = *HKEY;
836pub const HKEY = *HKEY__;
837pub const HKEY__ = extern struct {
838 unused: c_int,
839};
840pub const LSTATUS = LONG;
841
842pub const FILE_NOTIFY_INFORMATION = extern struct {
843 NextEntryOffset: DWORD,
844 Action: DWORD,
845 FileNameLength: DWORD,
846 // Flexible array member
847 // FileName: [1]WCHAR,
848};
849
850pub const FILE_ACTION_ADDED = 0x00000001;
851pub const FILE_ACTION_REMOVED = 0x00000002;
852pub const FILE_ACTION_MODIFIED = 0x00000003;
853pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;
854pub const FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;
855
856pub const LPOVERLAPPED_COMPLETION_ROUTINE = ?fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void;
857
858pub const FILE_NOTIFY_CHANGE_CREATION = 64;
859pub const FILE_NOTIFY_CHANGE_SIZE = 8;
860pub const FILE_NOTIFY_CHANGE_SECURITY = 256;
861pub const FILE_NOTIFY_CHANGE_LAST_ACCESS = 32;
862pub const FILE_NOTIFY_CHANGE_LAST_WRITE = 16;
863pub const FILE_NOTIFY_CHANGE_DIR_NAME = 2;
864pub const FILE_NOTIFY_CHANGE_FILE_NAME = 1;
865pub const FILE_NOTIFY_CHANGE_ATTRIBUTES = 4;
866
867pub const CONSOLE_SCREEN_BUFFER_INFO = extern struct {
868 dwSize: COORD,
869 dwCursorPosition: COORD,
870 wAttributes: WORD,
871 srWindow: SMALL_RECT,
872 dwMaximumWindowSize: COORD,
873};
874
875pub const FOREGROUND_BLUE = 1;
876pub const FOREGROUND_GREEN = 2;
877pub const FOREGROUND_RED = 4;
878pub const FOREGROUND_INTENSITY = 8;
879
880pub const LIST_ENTRY = extern struct {
881 Flink: *LIST_ENTRY,
882 Blink: *LIST_ENTRY,
883};
884
885pub const RTL_CRITICAL_SECTION_DEBUG = extern struct {
886 Type: WORD,
887 CreatorBackTraceIndex: WORD,
888 CriticalSection: *RTL_CRITICAL_SECTION,
889 ProcessLocksList: LIST_ENTRY,
890 EntryCount: DWORD,
891 ContentionCount: DWORD,
892 Flags: DWORD,
893 CreatorBackTraceIndexHigh: WORD,
894 SpareWORD: WORD,
895};
896
897pub const RTL_CRITICAL_SECTION = extern struct {
898 DebugInfo: *RTL_CRITICAL_SECTION_DEBUG,
899 LockCount: LONG,
900 RecursionCount: LONG,
901 OwningThread: HANDLE,
902 LockSemaphore: HANDLE,
903 SpinCount: ULONG_PTR,
904};
905
906pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;
907pub const INIT_ONCE = RTL_RUN_ONCE;
908pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT;
909pub const INIT_ONCE_FN = fn (InitOnce: *INIT_ONCE, Parameter: ?*c_void, Context: ?*c_void) callconv(.C) BOOL;
910
911pub const RTL_RUN_ONCE = extern struct {
912 Ptr: ?*c_void,
913};
914
915pub const RTL_RUN_ONCE_INIT = RTL_RUN_ONCE{ .Ptr = null };
916
917pub const COINIT_APARTMENTTHREADED = COINIT.COINIT_APARTMENTTHREADED;
918pub const COINIT_MULTITHREADED = COINIT.COINIT_MULTITHREADED;
919pub const COINIT_DISABLE_OLE1DDE = COINIT.COINIT_DISABLE_OLE1DDE;
920pub const COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
921pub const COINIT = enum(c_int) {
922 COINIT_APARTMENTTHREADED = 2,
923 COINIT_MULTITHREADED = 0,
924 COINIT_DISABLE_OLE1DDE = 4,
925 COINIT_SPEED_OVER_MEMORY = 8,
926};
927
928/// > The maximum path of 32,767 characters is approximate, because the "\\?\"
929/// > prefix may be expanded to a longer string by the system at run time, and
930/// > this expansion applies to the total length.
931/// from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
932pub const PATH_MAX_WIDE = 32767;
933
934pub const FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
935pub const FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
936pub const FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
937pub const FORMAT_MESSAGE_FROM_STRING = 0x00000400;
938pub const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
939pub const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
940pub const FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF;
941
942pub const EXCEPTION_DATATYPE_MISALIGNMENT = 0x80000002;
943pub const EXCEPTION_ACCESS_VIOLATION = 0xc0000005;
944pub const EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d;
945pub const EXCEPTION_STACK_OVERFLOW = 0xc00000fd;
946pub const EXCEPTION_CONTINUE_SEARCH = 0;
947
948pub const EXCEPTION_RECORD = extern struct {
949 ExceptionCode: u32,
950 ExceptionFlags: u32,
951 ExceptionRecord: *EXCEPTION_RECORD,
952 ExceptionAddress: *c_void,
953 NumberParameters: u32,
954 ExceptionInformation: [15]usize,
955};
956
957pub usingnamespace switch (arch) {
958 .i386 => struct {
959 pub const FLOATING_SAVE_AREA = extern struct {
960 ControlWord: DWORD,
961 StatusWord: DWORD,
962 TagWord: DWORD,
963 ErrorOffset: DWORD,
964 ErrorSelector: DWORD,
965 DataOffset: DWORD,
966 DataSelector: DWORD,
967 RegisterArea: [80]BYTE,
968 Cr0NpxState: DWORD,
969 };
970
971 pub const CONTEXT = extern struct {
972 ContextFlags: DWORD,
973 Dr0: DWORD,
974 Dr1: DWORD,
975 Dr2: DWORD,
976 Dr3: DWORD,
977 Dr6: DWORD,
978 Dr7: DWORD,
979 FloatSave: FLOATING_SAVE_AREA,
980 SegGs: DWORD,
981 SegFs: DWORD,
982 SegEs: DWORD,
983 SegDs: DWORD,
984 Edi: DWORD,
985 Esi: DWORD,
986 Ebx: DWORD,
987 Edx: DWORD,
988 Ecx: DWORD,
989 Eax: DWORD,
990 Ebp: DWORD,
991 Eip: DWORD,
992 SegCs: DWORD,
993 EFlags: DWORD,
994 Esp: DWORD,
995 SegSs: DWORD,
996 ExtendedRegisters: [512]BYTE,
997
998 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize } {
999 return .{ .bp = ctx.Ebp, .ip = ctx.Eip };
1000 }
1001 };
1002
1003 pub const PCONTEXT = *CONTEXT;
1004 },
1005 .x86_64 => struct {
1006 pub const M128A = extern struct {
1007 Low: ULONGLONG,
1008 High: LONGLONG,
1009 };
1010
1011 pub const XMM_SAVE_AREA32 = extern struct {
1012 ControlWord: WORD,
1013 StatusWord: WORD,
1014 TagWord: BYTE,
1015 Reserved1: BYTE,
1016 ErrorOpcode: WORD,
1017 ErrorOffset: DWORD,
1018 ErrorSelector: WORD,
1019 Reserved2: WORD,
1020 DataOffset: DWORD,
1021 DataSelector: WORD,
1022 Reserved3: WORD,
1023 MxCsr: DWORD,
1024 MxCsr_Mask: DWORD,
1025 FloatRegisters: [8]M128A,
1026 XmmRegisters: [16]M128A,
1027 Reserved4: [96]BYTE,
1028 };
1029
1030 pub const CONTEXT = extern struct {
1031 P1Home: DWORD64,
1032 P2Home: DWORD64,
1033 P3Home: DWORD64,
1034 P4Home: DWORD64,
1035 P5Home: DWORD64,
1036 P6Home: DWORD64,
1037 ContextFlags: DWORD,
1038 MxCsr: DWORD,
1039 SegCs: WORD,
1040 SegDs: WORD,
1041 SegEs: WORD,
1042 SegFs: WORD,
1043 SegGs: WORD,
1044 SegSs: WORD,
1045 EFlags: DWORD,
1046 Dr0: DWORD64,
1047 Dr1: DWORD64,
1048 Dr2: DWORD64,
1049 Dr3: DWORD64,
1050 Dr6: DWORD64,
1051 Dr7: DWORD64,
1052 Rax: DWORD64,
1053 Rcx: DWORD64,
1054 Rdx: DWORD64,
1055 Rbx: DWORD64,
1056 Rsp: DWORD64,
1057 Rbp: DWORD64,
1058 Rsi: DWORD64,
1059 Rdi: DWORD64,
1060 R8: DWORD64,
1061 R9: DWORD64,
1062 R10: DWORD64,
1063 R11: DWORD64,
1064 R12: DWORD64,
1065 R13: DWORD64,
1066 R14: DWORD64,
1067 R15: DWORD64,
1068 Rip: DWORD64,
1069 DUMMYUNIONNAME: extern union {
1070 FltSave: XMM_SAVE_AREA32,
1071 FloatSave: XMM_SAVE_AREA32,
1072 DUMMYSTRUCTNAME: extern struct {
1073 Header: [2]M128A,
1074 Legacy: [8]M128A,
1075 Xmm0: M128A,
1076 Xmm1: M128A,
1077 Xmm2: M128A,
1078 Xmm3: M128A,
1079 Xmm4: M128A,
1080 Xmm5: M128A,
1081 Xmm6: M128A,
1082 Xmm7: M128A,
1083 Xmm8: M128A,
1084 Xmm9: M128A,
1085 Xmm10: M128A,
1086 Xmm11: M128A,
1087 Xmm12: M128A,
1088 Xmm13: M128A,
1089 Xmm14: M128A,
1090 Xmm15: M128A,
1091 },
1092 },
1093 VectorRegister: [26]M128A,
1094 VectorControl: DWORD64,
1095 DebugControl: DWORD64,
1096 LastBranchToRip: DWORD64,
1097 LastBranchFromRip: DWORD64,
1098 LastExceptionToRip: DWORD64,
1099 LastExceptionFromRip: DWORD64,
1100
1101 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize } {
1102 return .{ .bp = ctx.Rbp, .ip = ctx.Rip };
1103 }
1104 };
1105
1106 pub const PCONTEXT = *CONTEXT;
1107 },
1108 .aarch64 => struct {
1109 pub const NEON128 = extern union {
1110 DUMMYSTRUCTNAME: extern struct {
1111 Low: ULONGLONG,
1112 High: LONGLONG,
1113 },
1114 D: [2]f64,
1115 S: [4]f32,
1116 H: [8]WORD,
1117 B: [16]BYTE,
1118 };
1119
1120 pub const CONTEXT = extern struct {
1121 ContextFlags: ULONG,
1122 Cpsr: ULONG,
1123 DUMMYUNIONNAME: extern union {
1124 DUMMYSTRUCTNAME: extern struct {
1125 X0: DWORD64,
1126 X1: DWORD64,
1127 X2: DWORD64,
1128 X3: DWORD64,
1129 X4: DWORD64,
1130 X5: DWORD64,
1131 X6: DWORD64,
1132 X7: DWORD64,
1133 X8: DWORD64,
1134 X9: DWORD64,
1135 X10: DWORD64,
1136 X11: DWORD64,
1137 X12: DWORD64,
1138 X13: DWORD64,
1139 X14: DWORD64,
1140 X15: DWORD64,
1141 X16: DWORD64,
1142 X17: DWORD64,
1143 X18: DWORD64,
1144 X19: DWORD64,
1145 X20: DWORD64,
1146 X21: DWORD64,
1147 X22: DWORD64,
1148 X23: DWORD64,
1149 X24: DWORD64,
1150 X25: DWORD64,
1151 X26: DWORD64,
1152 X27: DWORD64,
1153 X28: DWORD64,
1154 Fp: DWORD64,
1155 Lr: DWORD64,
1156 },
1157 X: [31]DWORD64,
1158 },
1159 Sp: DWORD64,
1160 Pc: DWORD64,
1161 V: [32]NEON128,
1162 Fpcr: DWORD,
1163 Fpsr: DWORD,
1164 Bcr: [8]DWORD,
1165 Bvr: [8]DWORD64,
1166 Wcr: [2]DWORD,
1167 Wvr: [2]DWORD64,
1168
1169 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize } {
1170 return .{
1171 .bp = ctx.DUMMYUNIONNAME.DUMMYSTRUCTNAME.Fp,
1172 .ip = ctx.Pc,
1173 };
1174 }
1175 };
1176
1177 pub const PCONTEXT = *CONTEXT;
1178 },
1179 else => struct {
1180 pub const PCONTEXT = *c_void;
1181 },
1182};
1183
1184pub const EXCEPTION_POINTERS = extern struct {
1185 ExceptionRecord: *EXCEPTION_RECORD,
1186 ContextRecord: PCONTEXT,
1187};
1188
1189pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long;
1190
1191pub const OBJECT_ATTRIBUTES = extern struct {
1192 Length: ULONG,
1193 RootDirectory: ?HANDLE,
1194 ObjectName: *UNICODE_STRING,
1195 Attributes: ULONG,
1196 SecurityDescriptor: ?*c_void,
1197 SecurityQualityOfService: ?*c_void,
1198};
1199
1200pub const OBJ_INHERIT = 0x00000002;
1201pub const OBJ_PERMANENT = 0x00000010;
1202pub const OBJ_EXCLUSIVE = 0x00000020;
1203pub const OBJ_CASE_INSENSITIVE = 0x00000040;
1204pub const OBJ_OPENIF = 0x00000080;
1205pub const OBJ_OPENLINK = 0x00000100;
1206pub const OBJ_KERNEL_HANDLE = 0x00000200;
1207pub const OBJ_VALID_ATTRIBUTES = 0x000003F2;
1208
1209pub const UNICODE_STRING = extern struct {
1210 Length: c_ushort,
1211 MaximumLength: c_ushort,
1212 Buffer: [*]WCHAR,
1213};
1214
1215const ACTIVATION_CONTEXT_DATA = opaque {};
1216const ASSEMBLY_STORAGE_MAP = opaque {};
1217const FLS_CALLBACK_INFO = opaque {};
1218const RTL_BITMAP = opaque {};
1219pub const PRTL_BITMAP = *RTL_BITMAP;
1220const KAFFINITY = usize;
1221
1222pub const TEB = extern struct {
1223 Reserved1: [12]PVOID,
1224 ProcessEnvironmentBlock: *PEB,
1225 Reserved2: [399]PVOID,
1226 Reserved3: [1952]u8,
1227 TlsSlots: [64]PVOID,
1228 Reserved4: [8]u8,
1229 Reserved5: [26]PVOID,
1230 ReservedForOle: PVOID,
1231 Reserved6: [4]PVOID,
1232 TlsExpansionSlots: PVOID,
1233};
1234
1235/// Process Environment Block
1236/// Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
1237/// - https://github.com/wine-mirror/wine/blob/1aff1e6a370ee8c0213a0fd4b220d121da8527aa/include/winternl.h#L269
1238/// - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/index.htm
1239pub const PEB = extern struct {
1240 // Versions: All
1241 InheritedAddressSpace: BOOLEAN,
1242
1243 // Versions: 3.51+
1244 ReadImageFileExecOptions: BOOLEAN,
1245 BeingDebugged: BOOLEAN,
1246
1247 // Versions: 5.2+ (previously was padding)
1248 BitField: UCHAR,
1249
1250 // Versions: all
1251 Mutant: HANDLE,
1252 ImageBaseAddress: HMODULE,
1253 Ldr: *PEB_LDR_DATA,
1254 ProcessParameters: *RTL_USER_PROCESS_PARAMETERS,
1255 SubSystemData: PVOID,
1256 ProcessHeap: HANDLE,
1257
1258 // Versions: 5.1+
1259 FastPebLock: *RTL_CRITICAL_SECTION,
1260
1261 // Versions: 5.2+
1262 AtlThunkSListPtr: PVOID,
1263 IFEOKey: PVOID,
1264
1265 // Versions: 6.0+
1266
1267 /// https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/crossprocessflags.htm
1268 CrossProcessFlags: ULONG,
1269
1270 // Versions: 6.0+
1271 union1: extern union {
1272 KernelCallbackTable: PVOID,
1273 UserSharedInfoPtr: PVOID,
1274 },
1275
1276 // Versions: 5.1+
1277 SystemReserved: ULONG,
1278
1279 // Versions: 5.1, (not 5.2, not 6.0), 6.1+
1280 AtlThunkSListPtr32: ULONG,
1281
1282 // Versions: 6.1+
1283 ApiSetMap: PVOID,
1284
1285 // Versions: all
1286 TlsExpansionCounter: ULONG,
1287 // note: there is padding here on 64 bit
1288 TlsBitmap: PRTL_BITMAP,
1289 TlsBitmapBits: [2]ULONG,
1290 ReadOnlySharedMemoryBase: PVOID,
1291
1292 // Versions: 1703+
1293 SharedData: PVOID,
1294
1295 // Versions: all
1296 ReadOnlyStaticServerData: *PVOID,
1297 AnsiCodePageData: PVOID,
1298 OemCodePageData: PVOID,
1299 UnicodeCaseTableData: PVOID,
1300
1301 // Versions: 3.51+
1302 NumberOfProcessors: ULONG,
1303 NtGlobalFlag: ULONG,
1304
1305 // Versions: all
1306 CriticalSectionTimeout: LARGE_INTEGER,
1307
1308 // End of Original PEB size
1309
1310 // Fields appended in 3.51:
1311 HeapSegmentReserve: ULONG_PTR,
1312 HeapSegmentCommit: ULONG_PTR,
1313 HeapDeCommitTotalFreeThreshold: ULONG_PTR,
1314 HeapDeCommitFreeBlockThreshold: ULONG_PTR,
1315 NumberOfHeaps: ULONG,
1316 MaximumNumberOfHeaps: ULONG,
1317 ProcessHeaps: *PVOID,
1318
1319 // Fields appended in 4.0:
1320 GdiSharedHandleTable: PVOID,
1321 ProcessStarterHelper: PVOID,
1322 GdiDCAttributeList: ULONG,
1323 // note: there is padding here on 64 bit
1324 LoaderLock: *RTL_CRITICAL_SECTION,
1325 OSMajorVersion: ULONG,
1326 OSMinorVersion: ULONG,
1327 OSBuildNumber: USHORT,
1328 OSCSDVersion: USHORT,
1329 OSPlatformId: ULONG,
1330 ImageSubSystem: ULONG,
1331 ImageSubSystemMajorVersion: ULONG,
1332 ImageSubSystemMinorVersion: ULONG,
1333 // note: there is padding here on 64 bit
1334 ActiveProcessAffinityMask: KAFFINITY,
1335 GdiHandleBuffer: [
1336 switch (@sizeOf(usize)) {
1337 4 => 0x22,
1338 8 => 0x3C,
1339 else => unreachable,
1340 }
1341 ]ULONG,
1342
1343 // Fields appended in 5.0 (Windows 2000):
1344 PostProcessInitRoutine: PVOID,
1345 TlsExpansionBitmap: PRTL_BITMAP,
1346 TlsExpansionBitmapBits: [32]ULONG,
1347 SessionId: ULONG,
1348 // note: there is padding here on 64 bit
1349 // Versions: 5.1+
1350 AppCompatFlags: ULARGE_INTEGER,
1351 AppCompatFlagsUser: ULARGE_INTEGER,
1352 ShimData: PVOID,
1353 // Versions: 5.0+
1354 AppCompatInfo: PVOID,
1355 CSDVersion: UNICODE_STRING,
1356
1357 // Fields appended in 5.1 (Windows XP):
1358 ActivationContextData: *const ACTIVATION_CONTEXT_DATA,
1359 ProcessAssemblyStorageMap: *ASSEMBLY_STORAGE_MAP,
1360 SystemDefaultActivationData: *const ACTIVATION_CONTEXT_DATA,
1361 SystemAssemblyStorageMap: *ASSEMBLY_STORAGE_MAP,
1362 MinimumStackCommit: ULONG_PTR,
1363
1364 // Fields appended in 5.2 (Windows Server 2003):
1365 FlsCallback: *FLS_CALLBACK_INFO,
1366 FlsListHead: LIST_ENTRY,
1367 FlsBitmap: PRTL_BITMAP,
1368 FlsBitmapBits: [4]ULONG,
1369 FlsHighIndex: ULONG,
1370
1371 // Fields appended in 6.0 (Windows Vista):
1372 WerRegistrationData: PVOID,
1373 WerShipAssertPtr: PVOID,
1374
1375 // Fields appended in 6.1 (Windows 7):
1376 pUnused: PVOID, // previously pContextData
1377 pImageHeaderHash: PVOID,
1378
1379 /// TODO: https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/tracingflags.htm
1380 TracingFlags: ULONG,
1381
1382 // Fields appended in 6.2 (Windows 8):
1383 CsrServerReadOnlySharedMemoryBase: ULONGLONG,
1384
1385 // Fields appended in 1511:
1386 TppWorkerpListLock: ULONG,
1387 TppWorkerpList: LIST_ENTRY,
1388 WaitOnAddressHashTable: [0x80]PVOID,
1389
1390 // Fields appended in 1709:
1391 TelemetryCoverageHeader: PVOID,
1392 CloudFileFlags: ULONG,
1393};
1394
1395/// The `PEB_LDR_DATA` structure is the main record of what modules are loaded in a process.
1396/// It is essentially the head of three double-linked lists of `LDR_DATA_TABLE_ENTRY` structures which each represent one loaded module.
1397///
1398/// Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
1399/// - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb_ldr_data.htm
1400pub const PEB_LDR_DATA = extern struct {
1401 // Versions: 3.51 and higher
1402 /// The size in bytes of the structure
1403 Length: ULONG,
1404
1405 /// TRUE if the structure is prepared.
1406 Initialized: BOOLEAN,
1407
1408 SsHandle: PVOID,
1409 InLoadOrderModuleList: LIST_ENTRY,
1410 InMemoryOrderModuleList: LIST_ENTRY,
1411 InInitializationOrderModuleList: LIST_ENTRY,
1412
1413 // Versions: 5.1 and higher
1414
1415 /// No known use of this field is known in Windows 8 and higher.
1416 EntryInProgress: PVOID,
1417
1418 // Versions: 6.0 from Windows Vista SP1, and higher
1419 ShutdownInProgress: BOOLEAN,
1420
1421 /// Though ShutdownThreadId is declared as a HANDLE,
1422 /// it is indeed the thread ID as suggested by its name.
1423 /// It is picked up from the UniqueThread member of the CLIENT_ID in the
1424 /// TEB of the thread that asks to terminate the process.
1425 ShutdownThreadId: HANDLE,
1426};
1427
1428pub const RTL_USER_PROCESS_PARAMETERS = extern struct {
1429 AllocationSize: ULONG,
1430 Size: ULONG,
1431 Flags: ULONG,
1432 DebugFlags: ULONG,
1433 ConsoleHandle: HANDLE,
1434 ConsoleFlags: ULONG,
1435 hStdInput: HANDLE,
1436 hStdOutput: HANDLE,
1437 hStdError: HANDLE,
1438 CurrentDirectory: CURDIR,
1439 DllPath: UNICODE_STRING,
1440 ImagePathName: UNICODE_STRING,
1441 CommandLine: UNICODE_STRING,
1442 Environment: [*:0]WCHAR,
1443 dwX: ULONG,
1444 dwY: ULONG,
1445 dwXSize: ULONG,
1446 dwYSize: ULONG,
1447 dwXCountChars: ULONG,
1448 dwYCountChars: ULONG,
1449 dwFillAttribute: ULONG,
1450 dwFlags: ULONG,
1451 dwShowWindow: ULONG,
1452 WindowTitle: UNICODE_STRING,
1453 Desktop: UNICODE_STRING,
1454 ShellInfo: UNICODE_STRING,
1455 RuntimeInfo: UNICODE_STRING,
1456 DLCurrentDirectory: [0x20]RTL_DRIVE_LETTER_CURDIR,
1457};
1458
1459pub const RTL_DRIVE_LETTER_CURDIR = extern struct {
1460 Flags: c_ushort,
1461 Length: c_ushort,
1462 TimeStamp: ULONG,
1463 DosPath: UNICODE_STRING,
1464};
1465
1466pub const PPS_POST_PROCESS_INIT_ROUTINE = ?fn () callconv(.C) void;
1467
1468pub const FILE_BOTH_DIR_INFORMATION = extern struct {
1469 NextEntryOffset: ULONG,
1470 FileIndex: ULONG,
1471 CreationTime: LARGE_INTEGER,
1472 LastAccessTime: LARGE_INTEGER,
1473 LastWriteTime: LARGE_INTEGER,
1474 ChangeTime: LARGE_INTEGER,
1475 EndOfFile: LARGE_INTEGER,
1476 AllocationSize: LARGE_INTEGER,
1477 FileAttributes: ULONG,
1478 FileNameLength: ULONG,
1479 EaSize: ULONG,
1480 ShortNameLength: CHAR,
1481 ShortName: [12]WCHAR,
1482 FileName: [1]WCHAR,
1483};
1484pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION;
1485
1486pub const IO_APC_ROUTINE = fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void;
1487
1488pub const CURDIR = extern struct {
1489 DosPath: UNICODE_STRING,
1490 Handle: HANDLE,
1491};
1492
1493pub const DUPLICATE_SAME_ACCESS = 2;
1494
1495pub const MODULEINFO = extern struct {
1496 lpBaseOfDll: LPVOID,
1497 SizeOfImage: DWORD,
1498 EntryPoint: LPVOID,
1499};
1500pub const LPMODULEINFO = *MODULEINFO;
1501
1502pub const PSAPI_WS_WATCH_INFORMATION = extern struct {
1503 FaultingPc: LPVOID,
1504 FaultingVa: LPVOID,
1505};
1506pub const PPSAPI_WS_WATCH_INFORMATION = *PSAPI_WS_WATCH_INFORMATION;
1507
1508pub const PROCESS_MEMORY_COUNTERS = extern struct {
1509 cb: DWORD,
1510 PageFaultCount: DWORD,
1511 PeakWorkingSetSize: SIZE_T,
1512 WorkingSetSize: SIZE_T,
1513 QuotaPeakPagedPoolUsage: SIZE_T,
1514 QuotaPagedPoolUsage: SIZE_T,
1515 QuotaPeakNonPagedPoolUsage: SIZE_T,
1516 QuotaNonPagedPoolUsage: SIZE_T,
1517 PagefileUsage: SIZE_T,
1518 PeakPagefileUsage: SIZE_T,
1519};
1520pub const PPROCESS_MEMORY_COUNTERS = *PROCESS_MEMORY_COUNTERS;
1521
1522pub const PROCESS_MEMORY_COUNTERS_EX = extern struct {
1523 cb: DWORD,
1524 PageFaultCount: DWORD,
1525 PeakWorkingSetSize: SIZE_T,
1526 WorkingSetSize: SIZE_T,
1527 QuotaPeakPagedPoolUsage: SIZE_T,
1528 QuotaPagedPoolUsage: SIZE_T,
1529 QuotaPeakNonPagedPoolUsage: SIZE_T,
1530 QuotaNonPagedPoolUsage: SIZE_T,
1531 PagefileUsage: SIZE_T,
1532 PeakPagefileUsage: SIZE_T,
1533 PrivateUsage: SIZE_T,
1534};
1535pub const PPROCESS_MEMORY_COUNTERS_EX = *PROCESS_MEMORY_COUNTERS_EX;
1536
1537pub const PERFORMANCE_INFORMATION = extern struct {
1538 cb: DWORD,
1539 CommitTotal: SIZE_T,
1540 CommitLimit: SIZE_T,
1541 CommitPeak: SIZE_T,
1542 PhysicalTotal: SIZE_T,
1543 PhysicalAvailable: SIZE_T,
1544 SystemCache: SIZE_T,
1545 KernelTotal: SIZE_T,
1546 KernelPaged: SIZE_T,
1547 KernelNonpaged: SIZE_T,
1548 PageSize: SIZE_T,
1549 HandleCount: DWORD,
1550 ProcessCount: DWORD,
1551 ThreadCount: DWORD,
1552};
1553pub const PPERFORMANCE_INFORMATION = *PERFORMANCE_INFORMATION;
1554
1555pub const PERFORMACE_INFORMATION = PERFORMANCE_INFORMATION;
1556pub const PPERFORMACE_INFORMATION = *PERFORMANCE_INFORMATION;
1557
1558pub const ENUM_PAGE_FILE_INFORMATION = extern struct {
1559 cb: DWORD,
1560 Reserved: DWORD,
1561 TotalSize: SIZE_T,
1562 TotalInUse: SIZE_T,
1563 PeakUsage: SIZE_T,
1564};
1565pub const PENUM_PAGE_FILE_INFORMATION = *ENUM_PAGE_FILE_INFORMATION;
1566
1567pub const PENUM_PAGE_FILE_CALLBACKW = ?fn (?LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCWSTR) callconv(.C) BOOL;
1568pub const PENUM_PAGE_FILE_CALLBACKA = ?fn (?LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCSTR) callconv(.C) BOOL;
1569
1570pub const PSAPI_WS_WATCH_INFORMATION_EX = extern struct {
1571 BasicInfo: PSAPI_WS_WATCH_INFORMATION,
1572 FaultingThreadId: ULONG_PTR,
1573 Flags: ULONG_PTR,
1574};
1575pub const PPSAPI_WS_WATCH_INFORMATION_EX = *PSAPI_WS_WATCH_INFORMATION_EX;
1576
1577pub const OSVERSIONINFOW = extern struct {
1578 dwOSVersionInfoSize: ULONG,
1579 dwMajorVersion: ULONG,
1580 dwMinorVersion: ULONG,
1581 dwBuildNumber: ULONG,
1582 dwPlatformId: ULONG,
1583 szCSDVersion: [128]WCHAR,
1584};
1585pub const POSVERSIONINFOW = *OSVERSIONINFOW;
1586pub const LPOSVERSIONINFOW = *OSVERSIONINFOW;
1587pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
1588pub const PRTL_OSVERSIONINFOW = *RTL_OSVERSIONINFOW;
1589
1590pub const REPARSE_DATA_BUFFER = extern struct {
1591 ReparseTag: ULONG,
1592 ReparseDataLength: USHORT,
1593 Reserved: USHORT,
1594 DataBuffer: [1]UCHAR,
1595};
1596pub const SYMBOLIC_LINK_REPARSE_BUFFER = extern struct {
1597 SubstituteNameOffset: USHORT,
1598 SubstituteNameLength: USHORT,
1599 PrintNameOffset: USHORT,
1600 PrintNameLength: USHORT,
1601 Flags: ULONG,
1602 PathBuffer: [1]WCHAR,
1603};
1604pub const MOUNT_POINT_REPARSE_BUFFER = extern struct {
1605 SubstituteNameOffset: USHORT,
1606 SubstituteNameLength: USHORT,
1607 PrintNameOffset: USHORT,
1608 PrintNameLength: USHORT,
1609 PathBuffer: [1]WCHAR,
1610};
1611pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024;
1612pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
1613pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
1614pub const IO_REPARSE_TAG_SYMLINK: ULONG = 0xa000000c;
1615pub const IO_REPARSE_TAG_MOUNT_POINT: ULONG = 0xa0000003;
1616pub const SYMLINK_FLAG_RELATIVE: ULONG = 0x1;
1617
1618pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
1619pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
1620
1621pub const MOUNTMGR_MOUNT_POINT = extern struct {
1622 SymbolicLinkNameOffset: ULONG,
1623 SymbolicLinkNameLength: USHORT,
1624 Reserved1: USHORT,
1625 UniqueIdOffset: ULONG,
1626 UniqueIdLength: USHORT,
1627 Reserved2: USHORT,
1628 DeviceNameOffset: ULONG,
1629 DeviceNameLength: USHORT,
1630 Reserved3: USHORT,
1631};
1632pub const MOUNTMGR_MOUNT_POINTS = extern struct {
1633 Size: ULONG,
1634 NumberOfMountPoints: ULONG,
1635 MountPoints: [1]MOUNTMGR_MOUNT_POINT,
1636};
1637pub const IOCTL_MOUNTMGR_QUERY_POINTS: ULONG = 0x6d0008;
1638
1639pub const OBJECT_INFORMATION_CLASS = enum(c_int) {
1640 ObjectBasicInformation = 0,
1641 ObjectNameInformation = 1,
1642 ObjectTypeInformation = 2,
1643 ObjectTypesInformation = 3,
1644 ObjectHandleFlagInformation = 4,
1645 ObjectSessionInformation = 5,
1646 MaxObjectInfoClass,
1647};
1648
1649pub const OBJECT_NAME_INFORMATION = extern struct {
1650 Name: UNICODE_STRING,
1651};
1652pub const POBJECT_NAME_INFORMATION = *OBJECT_NAME_INFORMATION;
1653
1654pub const SRWLOCK = usize;
1655pub const SRWLOCK_INIT: SRWLOCK = 0;
1656pub const CONDITION_VARIABLE = usize;
1657pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = 0;
1658
1659pub const FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 0x1;
1660pub const FILE_SKIP_SET_EVENT_ON_HANDLE = 0x2;
1661
1662pub const CTRL_C_EVENT: DWORD = 0;
1663pub const CTRL_BREAK_EVENT: DWORD = 1;
1664pub const CTRL_CLOSE_EVENT: DWORD = 2;
1665pub const CTRL_LOGOFF_EVENT: DWORD = 5;
1666pub const CTRL_SHUTDOWN_EVENT: DWORD = 6;
1667
1668pub const HANDLER_ROUTINE = fn (dwCtrlType: DWORD) callconv(.C) BOOL;
lib/std/os/windows/gdi32.zig+9-1
...@@ -1,4 +1,12 @@...@@ -1,4 +1,12 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;
3const BOOL = windows.BOOL;
4const DWORD = windows.DWORD;
5const WINAPI = windows.WINAPI;
6const HDC = windows.HDC;
7const HGLRC = windows.HGLRC;
8const WORD = windows.WORD;
9const BYTE = windows.BYTE;
210
3pub const PIXELFORMATDESCRIPTOR = extern struct {11pub const PIXELFORMATDESCRIPTOR = extern struct {
4 nSize: WORD = @sizeOf(PIXELFORMATDESCRIPTOR),12 nSize: WORD = @sizeOf(PIXELFORMATDESCRIPTOR),
lib/std/os/windows/kernel32.zig+75-18
...@@ -1,10 +1,67 @@...@@ -1,10 +1,67 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;
3
4const BOOL = windows.BOOL;
5const BOOLEAN = windows.BOOLEAN;
6const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;
7const CONSOLE_SCREEN_BUFFER_INFO = windows.CONSOLE_SCREEN_BUFFER_INFO;
8const COORD = windows.COORD;
9const DWORD = windows.DWORD;
10const FILE_INFO_BY_HANDLE_CLASS = windows.FILE_INFO_BY_HANDLE_CLASS;
11const HANDLE = windows.HANDLE;
12const HMODULE = windows.HMODULE;
13const HRESULT = windows.HRESULT;
14const LARGE_INTEGER = windows.LARGE_INTEGER;
15const LPCWSTR = windows.LPCWSTR;
16const LPTHREAD_START_ROUTINE = windows.LPTHREAD_START_ROUTINE;
17const LPVOID = windows.LPVOID;
18const LPWSTR = windows.LPWSTR;
19const MODULEINFO = windows.MODULEINFO;
20const OVERLAPPED = windows.OVERLAPPED;
21const PERFORMANCE_INFORMATION = windows.PERFORMANCE_INFORMATION;
22const PROCESS_MEMORY_COUNTERS = windows.PROCESS_MEMORY_COUNTERS;
23const PSAPI_WS_WATCH_INFORMATION = windows.PSAPI_WS_WATCH_INFORMATION;
24const PSAPI_WS_WATCH_INFORMATION_EX = windows.PSAPI_WS_WATCH_INFORMATION_EX;
25const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;
26const SIZE_T = windows.SIZE_T;
27const SRWLOCK = windows.SRWLOCK;
28const UINT = windows.UINT;
29const VECTORED_EXCEPTION_HANDLER = windows.VECTORED_EXCEPTION_HANDLER;
30const WCHAR = windows.WCHAR;
31const WINAPI = windows.WINAPI;
32const WORD = windows.WORD;
33const Win32Error = windows.Win32Error;
34const va_list = windows.va_list;
35const HLOCAL = windows.HLOCAL;
36const FILETIME = windows.FILETIME;
37const STARTUPINFOW = windows.STARTUPINFOW;
38const PROCESS_INFORMATION = windows.PROCESS_INFORMATION;
39const OVERLAPPED_ENTRY = windows.OVERLAPPED_ENTRY;
40const LPHEAP_SUMMARY = windows.LPHEAP_SUMMARY;
41const ULONG_PTR = windows.ULONG_PTR;
42const FILE_NOTIFY_INFORMATION = windows.FILE_NOTIFY_INFORMATION;
43const HANDLER_ROUTINE = windows.HANDLER_ROUTINE;
44const ULONG = windows.ULONG;
45const PVOID = windows.PVOID;
46const LPSTR = windows.LPSTR;
47const PENUM_PAGE_FILE_CALLBACKA = windows.PENUM_PAGE_FILE_CALLBACKA;
48const PENUM_PAGE_FILE_CALLBACKW = windows.PENUM_PAGE_FILE_CALLBACKW;
49const INIT_ONCE = windows.INIT_ONCE;
50const CRITICAL_SECTION = windows.CRITICAL_SECTION;
51const WIN32_FIND_DATAW = windows.WIN32_FIND_DATAW;
52const CHAR = windows.CHAR;
53const BY_HANDLE_FILE_INFORMATION = windows.BY_HANDLE_FILE_INFORMATION;
54const SYSTEM_INFO = windows.SYSTEM_INFO;
55const LPOVERLAPPED_COMPLETION_ROUTINE = windows.LPOVERLAPPED_COMPLETION_ROUTINE;
56const UCHAR = windows.UCHAR;
57const FARPROC = windows.FARPROC;
58const INIT_ONCE_FN = windows.INIT_ONCE_FN;
259
3pub extern "kernel32" fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) callconv(WINAPI) ?*c_void;60pub extern "kernel32" fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) callconv(WINAPI) ?*c_void;
4pub extern "kernel32" fn RemoveVectoredExceptionHandler(Handle: HANDLE) callconv(WINAPI) c_ulong;61pub extern "kernel32" fn RemoveVectoredExceptionHandler(Handle: HANDLE) callconv(WINAPI) c_ulong;
562
6pub extern "kernel32" fn CancelIo(hFile: HANDLE) callconv(WINAPI) BOOL;63pub extern "kernel32" fn CancelIo(hFile: HANDLE) callconv(WINAPI) BOOL;
7pub extern "kernel32" fn CancelIoEx(hFile: HANDLE, lpOverlapped: ?LPOVERLAPPED) callconv(WINAPI) BOOL;64pub extern "kernel32" fn CancelIoEx(hFile: HANDLE, lpOverlapped: ?*OVERLAPPED) callconv(WINAPI) BOOL;
865
9pub extern "kernel32" fn CloseHandle(hObject: HANDLE) callconv(WINAPI) BOOL;66pub extern "kernel32" fn CloseHandle(hObject: HANDLE) callconv(WINAPI) BOOL;
1067
...@@ -22,7 +79,7 @@ pub extern "kernel32" fn CreateFileW(...@@ -22,7 +79,7 @@ pub extern "kernel32" fn CreateFileW(
22 lpFileName: [*:0]const u16,79 lpFileName: [*:0]const u16,
23 dwDesiredAccess: DWORD,80 dwDesiredAccess: DWORD,
24 dwShareMode: DWORD,81 dwShareMode: DWORD,
25 lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES,82 lpSecurityAttributes: ?*SECURITY_ATTRIBUTES,
26 dwCreationDisposition: DWORD,83 dwCreationDisposition: DWORD,
27 dwFlagsAndAttributes: DWORD,84 dwFlagsAndAttributes: DWORD,
28 hTemplateFile: ?HANDLE,85 hTemplateFile: ?HANDLE,
...@@ -63,7 +120,7 @@ pub extern "kernel32" fn CreateSymbolicLinkW(lpSymlinkFileName: [*:0]const u16,...@@ -63,7 +120,7 @@ pub extern "kernel32" fn CreateSymbolicLinkW(lpSymlinkFileName: [*:0]const u16,
63120
64pub extern "kernel32" fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) callconv(WINAPI) ?HANDLE;121pub extern "kernel32" fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) callconv(WINAPI) ?HANDLE;
65122
66pub extern "kernel32" fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) callconv(WINAPI) ?HANDLE;123pub extern "kernel32" fn CreateThread(lpThreadAttributes: ?*SECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?*DWORD) callconv(WINAPI) ?HANDLE;
67124
68pub extern "kernel32" fn DeviceIoControl(125pub extern "kernel32" fn DeviceIoControl(
69 h: HANDLE,126 h: HANDLE,
...@@ -96,9 +153,9 @@ pub extern "kernel32" fn GetCommandLineW() callconv(WINAPI) LPWSTR;...@@ -96,9 +153,9 @@ pub extern "kernel32" fn GetCommandLineW() callconv(WINAPI) LPWSTR;
96pub extern "kernel32" fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) callconv(WINAPI) BOOL;153pub extern "kernel32" fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) callconv(WINAPI) BOOL;
97154
98pub extern "kernel32" fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) callconv(WINAPI) BOOL;155pub extern "kernel32" fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) callconv(WINAPI) BOOL;
99pub extern "kernel32" fn FillConsoleOutputCharacterA(hConsoleOutput: HANDLE, cCharacter: CHAR, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD) callconv(WINAPI) BOOL;156pub extern "kernel32" fn FillConsoleOutputCharacterA(hConsoleOutput: HANDLE, cCharacter: CHAR, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: *DWORD) callconv(WINAPI) BOOL;
100pub extern "kernel32" fn FillConsoleOutputCharacterW(hConsoleOutput: HANDLE, cCharacter: WCHAR, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD) callconv(WINAPI) BOOL;157pub extern "kernel32" fn FillConsoleOutputCharacterW(hConsoleOutput: HANDLE, cCharacter: WCHAR, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: *DWORD) callconv(WINAPI) BOOL;
101pub extern "kernel32" fn FillConsoleOutputAttribute(hConsoleOutput: HANDLE, wAttribute: WORD, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfAttrsWritten: LPDWORD) callconv(WINAPI) BOOL;158pub extern "kernel32" fn FillConsoleOutputAttribute(hConsoleOutput: HANDLE, wAttribute: WORD, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfAttrsWritten: *DWORD) callconv(WINAPI) BOOL;
102pub extern "kernel32" fn SetConsoleCursorPosition(hConsoleOutput: HANDLE, dwCursorPosition: COORD) callconv(WINAPI) BOOL;159pub extern "kernel32" fn SetConsoleCursorPosition(hConsoleOutput: HANDLE, dwCursorPosition: COORD) callconv(WINAPI) BOOL;
103160
104pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(WINAPI) DWORD;161pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(WINAPI) DWORD;
...@@ -156,7 +213,7 @@ pub extern "kernel32" fn GetFullPathNameW(...@@ -156,7 +213,7 @@ pub extern "kernel32" fn GetFullPathNameW(
156pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(WINAPI) BOOL;213pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(WINAPI) BOOL;
157214
158pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE;215pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE;
159pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(WINAPI) BOOL;216pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: *DWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(WINAPI) BOOL;
160pub extern "kernel32" fn GetQueuedCompletionStatusEx(217pub extern "kernel32" fn GetQueuedCompletionStatusEx(
161 CompletionPort: HANDLE,218 CompletionPort: HANDLE,
162 lpCompletionPortEntries: [*]OVERLAPPED_ENTRY,219 lpCompletionPortEntries: [*]OVERLAPPED_ENTRY,
...@@ -282,7 +339,7 @@ pub extern "kernel32" fn WriteFile(...@@ -282,7 +339,7 @@ pub extern "kernel32" fn WriteFile(
282 in_out_lpOverlapped: ?*OVERLAPPED,339 in_out_lpOverlapped: ?*OVERLAPPED,
283) callconv(WINAPI) BOOL;340) callconv(WINAPI) BOOL;
284341
285pub extern "kernel32" fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) callconv(WINAPI) BOOL;342pub extern "kernel32" fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: *OVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) callconv(WINAPI) BOOL;
286343
287pub extern "kernel32" fn LoadLibraryW(lpLibFileName: [*:0]const u16) callconv(WINAPI) ?HMODULE;344pub extern "kernel32" fn LoadLibraryW(lpLibFileName: [*:0]const u16) callconv(WINAPI) ?HMODULE;
288345
...@@ -298,12 +355,12 @@ pub extern "kernel32" fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECT...@@ -298,12 +355,12 @@ pub extern "kernel32" fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECT
298pub extern "kernel32" fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) callconv(WINAPI) BOOL;355pub extern "kernel32" fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) callconv(WINAPI) BOOL;
299356
300pub extern "kernel32" fn K32EmptyWorkingSet(hProcess: HANDLE) callconv(WINAPI) BOOL;357pub extern "kernel32" fn K32EmptyWorkingSet(hProcess: HANDLE) callconv(WINAPI) BOOL;
301pub extern "kernel32" fn K32EnumDeviceDrivers(lpImageBase: [*]LPVOID, cb: DWORD, lpcbNeeded: LPDWORD) callconv(WINAPI) BOOL;358pub extern "kernel32" fn K32EnumDeviceDrivers(lpImageBase: [*]LPVOID, cb: DWORD, lpcbNeeded: *DWORD) callconv(WINAPI) BOOL;
302pub extern "kernel32" fn K32EnumPageFilesA(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKA, pContext: LPVOID) callconv(WINAPI) BOOL;359pub extern "kernel32" fn K32EnumPageFilesA(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKA, pContext: LPVOID) callconv(WINAPI) BOOL;
303pub extern "kernel32" fn K32EnumPageFilesW(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKW, pContext: LPVOID) callconv(WINAPI) BOOL;360pub extern "kernel32" fn K32EnumPageFilesW(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKW, pContext: LPVOID) callconv(WINAPI) BOOL;
304pub extern "kernel32" fn K32EnumProcessModules(hProcess: HANDLE, lphModule: [*]HMODULE, cb: DWORD, lpcbNeeded: LPDWORD) callconv(WINAPI) BOOL;361pub extern "kernel32" fn K32EnumProcessModules(hProcess: HANDLE, lphModule: [*]HMODULE, cb: DWORD, lpcbNeeded: *DWORD) callconv(WINAPI) BOOL;
305pub extern "kernel32" fn K32EnumProcessModulesEx(hProcess: HANDLE, lphModule: [*]HMODULE, cb: DWORD, lpcbNeeded: LPDWORD, dwFilterFlag: DWORD) callconv(WINAPI) BOOL;362pub extern "kernel32" fn K32EnumProcessModulesEx(hProcess: HANDLE, lphModule: [*]HMODULE, cb: DWORD, lpcbNeeded: *DWORD, dwFilterFlag: DWORD) callconv(WINAPI) BOOL;
306pub extern "kernel32" fn K32EnumProcesses(lpidProcess: [*]DWORD, cb: DWORD, cbNeeded: LPDWORD) callconv(WINAPI) BOOL;363pub extern "kernel32" fn K32EnumProcesses(lpidProcess: [*]DWORD, cb: DWORD, cbNeeded: *DWORD) callconv(WINAPI) BOOL;
307pub extern "kernel32" fn K32GetDeviceDriverBaseNameA(ImageBase: LPVOID, lpBaseName: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;364pub extern "kernel32" fn K32GetDeviceDriverBaseNameA(ImageBase: LPVOID, lpBaseName: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;
308pub extern "kernel32" fn K32GetDeviceDriverBaseNameW(ImageBase: LPVOID, lpBaseName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;365pub extern "kernel32" fn K32GetDeviceDriverBaseNameW(ImageBase: LPVOID, lpBaseName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;
309pub extern "kernel32" fn K32GetDeviceDriverFileNameA(ImageBase: LPVOID, lpFilename: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;366pub extern "kernel32" fn K32GetDeviceDriverFileNameA(ImageBase: LPVOID, lpFilename: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;
...@@ -314,13 +371,13 @@ pub extern "kernel32" fn K32GetModuleBaseNameA(hProcess: HANDLE, hModule: ?HMODU...@@ -314,13 +371,13 @@ pub extern "kernel32" fn K32GetModuleBaseNameA(hProcess: HANDLE, hModule: ?HMODU
314pub extern "kernel32" fn K32GetModuleBaseNameW(hProcess: HANDLE, hModule: ?HMODULE, lpBaseName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;371pub extern "kernel32" fn K32GetModuleBaseNameW(hProcess: HANDLE, hModule: ?HMODULE, lpBaseName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;
315pub extern "kernel32" fn K32GetModuleFileNameExA(hProcess: HANDLE, hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;372pub extern "kernel32" fn K32GetModuleFileNameExA(hProcess: HANDLE, hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;
316pub extern "kernel32" fn K32GetModuleFileNameExW(hProcess: HANDLE, hModule: ?HMODULE, lpFilename: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;373pub extern "kernel32" fn K32GetModuleFileNameExW(hProcess: HANDLE, hModule: ?HMODULE, lpFilename: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;
317pub extern "kernel32" fn K32GetModuleInformation(hProcess: HANDLE, hModule: HMODULE, lpmodinfo: LPMODULEINFO, cb: DWORD) callconv(WINAPI) BOOL;374pub extern "kernel32" fn K32GetModuleInformation(hProcess: HANDLE, hModule: HMODULE, lpmodinfo: *MODULEINFO, cb: DWORD) callconv(WINAPI) BOOL;
318pub extern "kernel32" fn K32GetPerformanceInfo(pPerformanceInformation: PPERFORMACE_INFORMATION, cb: DWORD) callconv(WINAPI) BOOL;375pub extern "kernel32" fn K32GetPerformanceInfo(pPerformanceInformation: *PERFORMANCE_INFORMATION, cb: DWORD) callconv(WINAPI) BOOL;
319pub extern "kernel32" fn K32GetProcessImageFileNameA(hProcess: HANDLE, lpImageFileName: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;376pub extern "kernel32" fn K32GetProcessImageFileNameA(hProcess: HANDLE, lpImageFileName: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;
320pub extern "kernel32" fn K32GetProcessImageFileNameW(hProcess: HANDLE, lpImageFileName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;377pub extern "kernel32" fn K32GetProcessImageFileNameW(hProcess: HANDLE, lpImageFileName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;
321pub extern "kernel32" fn K32GetProcessMemoryInfo(Process: HANDLE, ppsmemCounters: PPROCESS_MEMORY_COUNTERS, cb: DWORD) callconv(WINAPI) BOOL;378pub extern "kernel32" fn K32GetProcessMemoryInfo(Process: HANDLE, ppsmemCounters: *PROCESS_MEMORY_COUNTERS, cb: DWORD) callconv(WINAPI) BOOL;
322pub extern "kernel32" fn K32GetWsChanges(hProcess: HANDLE, lpWatchInfo: PPSAPI_WS_WATCH_INFORMATION, cb: DWORD) callconv(WINAPI) BOOL;379pub extern "kernel32" fn K32GetWsChanges(hProcess: HANDLE, lpWatchInfo: *PSAPI_WS_WATCH_INFORMATION, cb: DWORD) callconv(WINAPI) BOOL;
323pub extern "kernel32" fn K32GetWsChangesEx(hProcess: HANDLE, lpWatchInfoEx: PPSAPI_WS_WATCH_INFORMATION_EX, cb: DWORD) callconv(WINAPI) BOOL;380pub extern "kernel32" fn K32GetWsChangesEx(hProcess: HANDLE, lpWatchInfoEx: *PSAPI_WS_WATCH_INFORMATION_EX, cb: DWORD) callconv(WINAPI) BOOL;
324pub extern "kernel32" fn K32InitializeProcessForWsWatch(hProcess: HANDLE) callconv(WINAPI) BOOL;381pub extern "kernel32" fn K32InitializeProcessForWsWatch(hProcess: HANDLE) callconv(WINAPI) BOOL;
325pub extern "kernel32" fn K32QueryWorkingSet(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(WINAPI) BOOL;382pub extern "kernel32" fn K32QueryWorkingSet(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(WINAPI) BOOL;
326pub extern "kernel32" fn K32QueryWorkingSetEx(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(WINAPI) BOOL;383pub extern "kernel32" fn K32QueryWorkingSetEx(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(WINAPI) BOOL;
lib/std/os/windows/ntdll.zig+25-2
...@@ -1,7 +1,30 @@...@@ -1,7 +1,30 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;
3
4const BOOL = windows.BOOL;
5const DWORD = windows.DWORD;
6const ULONG = windows.ULONG;
7const WINAPI = windows.WINAPI;
8const NTSTATUS = windows.NTSTATUS;
9const WORD = windows.WORD;
10const HANDLE = windows.HANDLE;
11const ACCESS_MASK = windows.ACCESS_MASK;
12const IO_APC_ROUTINE = windows.IO_APC_ROUTINE;
13const BOOLEAN = windows.BOOLEAN;
14const OBJECT_ATTRIBUTES = windows.OBJECT_ATTRIBUTES;
15const PVOID = windows.PVOID;
16const IO_STATUS_BLOCK = windows.IO_STATUS_BLOCK;
17const LARGE_INTEGER = windows.LARGE_INTEGER;
18const OBJECT_INFORMATION_CLASS = windows.OBJECT_INFORMATION_CLASS;
19const FILE_INFORMATION_CLASS = windows.FILE_INFORMATION_CLASS;
20const UNICODE_STRING = windows.UNICODE_STRING;
21const RTL_OSVERSIONINFOW = windows.RTL_OSVERSIONINFOW;
22const FILE_BASIC_INFORMATION = windows.FILE_BASIC_INFORMATION;
23const SIZE_T = windows.SIZE_T;
24const CURDIR = windows.CURDIR;
225
3pub extern "NtDll" fn RtlGetVersion(26pub extern "NtDll" fn RtlGetVersion(
4 lpVersionInformation: PRTL_OSVERSIONINFOW,27 lpVersionInformation: *RTL_OSVERSIONINFOW,
5) callconv(WINAPI) NTSTATUS;28) callconv(WINAPI) NTSTATUS;
6pub extern "NtDll" fn RtlCaptureStackBackTrace(29pub extern "NtDll" fn RtlCaptureStackBackTrace(
7 FramesToSkip: DWORD,30 FramesToSkip: DWORD,
lib/std/os/windows/ole32.zig+6-1
...@@ -1,4 +1,9 @@...@@ -1,4 +1,9 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;
3const WINAPI = windows.WINAPI;
4const LPVOID = windows.LPVOID;
5const DWORD = windows.DWORD;
6const HRESULT = windows.HRESULT;
27
3pub extern "ole32" fn CoTaskMemFree(pv: LPVOID) callconv(WINAPI) void;8pub extern "ole32" fn CoTaskMemFree(pv: LPVOID) callconv(WINAPI) void;
4pub extern "ole32" fn CoUninitialize() callconv(WINAPI) void;9pub extern "ole32" fn CoUninitialize() callconv(WINAPI) void;
lib/std/os/windows/psapi.zig+56-10
...@@ -1,12 +1,58 @@...@@ -1,12 +1,58 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;
3const WINAPI = windows.WINAPI;
4const DWORD = windows.DWORD;
5const HANDLE = windows.HANDLE;
6const PENUM_PAGE_FILE_CALLBACKW = windows.PENUM_PAGE_FILE_CALLBACKW;
7const HMODULE = windows.HMODULE;
8const BOOL = windows.BOOL;
9const BOOLEAN = windows.BOOLEAN;
10const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;
11const CONSOLE_SCREEN_BUFFER_INFO = windows.CONSOLE_SCREEN_BUFFER_INFO;
12const COORD = windows.COORD;
13const FILE_INFO_BY_HANDLE_CLASS = windows.FILE_INFO_BY_HANDLE_CLASS;
14const HRESULT = windows.HRESULT;
15const LARGE_INTEGER = windows.LARGE_INTEGER;
16const LPCWSTR = windows.LPCWSTR;
17const LPTHREAD_START_ROUTINE = windows.LPTHREAD_START_ROUTINE;
18const LPVOID = windows.LPVOID;
19const LPWSTR = windows.LPWSTR;
20const MODULEINFO = windows.MODULEINFO;
21const OVERLAPPED = windows.OVERLAPPED;
22const PERFORMANCE_INFORMATION = windows.PERFORMANCE_INFORMATION;
23const PROCESS_MEMORY_COUNTERS = windows.PROCESS_MEMORY_COUNTERS;
24const PSAPI_WS_WATCH_INFORMATION = windows.PSAPI_WS_WATCH_INFORMATION;
25const PSAPI_WS_WATCH_INFORMATION_EX = windows.PSAPI_WS_WATCH_INFORMATION_EX;
26const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;
27const SIZE_T = windows.SIZE_T;
28const SRWLOCK = windows.SRWLOCK;
29const UINT = windows.UINT;
30const VECTORED_EXCEPTION_HANDLER = windows.VECTORED_EXCEPTION_HANDLER;
31const WCHAR = windows.WCHAR;
32const WORD = windows.WORD;
33const Win32Error = windows.Win32Error;
34const va_list = windows.va_list;
35const HLOCAL = windows.HLOCAL;
36const FILETIME = windows.FILETIME;
37const STARTUPINFOW = windows.STARTUPINFOW;
38const PROCESS_INFORMATION = windows.PROCESS_INFORMATION;
39const OVERLAPPED_ENTRY = windows.OVERLAPPED_ENTRY;
40const LPHEAP_SUMMARY = windows.LPHEAP_SUMMARY;
41const ULONG_PTR = windows.ULONG_PTR;
42const FILE_NOTIFY_INFORMATION = windows.FILE_NOTIFY_INFORMATION;
43const HANDLER_ROUTINE = windows.HANDLER_ROUTINE;
44const ULONG = windows.ULONG;
45const PVOID = windows.PVOID;
46const LPSTR = windows.LPSTR;
47const PENUM_PAGE_FILE_CALLBACKA = windows.PENUM_PAGE_FILE_CALLBACKA;
248
3pub extern "psapi" fn EmptyWorkingSet(hProcess: HANDLE) callconv(WINAPI) BOOL;49pub extern "psapi" fn EmptyWorkingSet(hProcess: HANDLE) callconv(WINAPI) BOOL;
4pub extern "psapi" fn EnumDeviceDrivers(lpImageBase: [*]LPVOID, cb: DWORD, lpcbNeeded: LPDWORD) callconv(WINAPI) BOOL;50pub extern "psapi" fn EnumDeviceDrivers(lpImageBase: [*]LPVOID, cb: DWORD, lpcbNeeded: *DWORD) callconv(WINAPI) BOOL;
5pub extern "psapi" fn EnumPageFilesA(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKA, pContext: LPVOID) callconv(WINAPI) BOOL;51pub extern "psapi" fn EnumPageFilesA(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKA, pContext: LPVOID) callconv(WINAPI) BOOL;
6pub extern "psapi" fn EnumPageFilesW(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKW, pContext: LPVOID) callconv(WINAPI) BOOL;52pub extern "psapi" fn EnumPageFilesW(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKW, pContext: LPVOID) callconv(WINAPI) BOOL;
7pub extern "psapi" fn EnumProcessModules(hProcess: HANDLE, lphModule: [*]HMODULE, cb: DWORD, lpcbNeeded: LPDWORD) callconv(WINAPI) BOOL;53pub extern "psapi" fn EnumProcessModules(hProcess: HANDLE, lphModule: [*]HMODULE, cb: DWORD, lpcbNeeded: *DWORD) callconv(WINAPI) BOOL;
8pub extern "psapi" fn EnumProcessModulesEx(hProcess: HANDLE, lphModule: [*]HMODULE, cb: DWORD, lpcbNeeded: LPDWORD, dwFilterFlag: DWORD) callconv(WINAPI) BOOL;54pub extern "psapi" fn EnumProcessModulesEx(hProcess: HANDLE, lphModule: [*]HMODULE, cb: DWORD, lpcbNeeded: *DWORD, dwFilterFlag: DWORD) callconv(WINAPI) BOOL;
9pub extern "psapi" fn EnumProcesses(lpidProcess: [*]DWORD, cb: DWORD, cbNeeded: LPDWORD) callconv(WINAPI) BOOL;55pub extern "psapi" fn EnumProcesses(lpidProcess: [*]DWORD, cb: DWORD, cbNeeded: *DWORD) callconv(WINAPI) BOOL;
10pub extern "psapi" fn GetDeviceDriverBaseNameA(ImageBase: LPVOID, lpBaseName: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;56pub extern "psapi" fn GetDeviceDriverBaseNameA(ImageBase: LPVOID, lpBaseName: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;
11pub extern "psapi" fn GetDeviceDriverBaseNameW(ImageBase: LPVOID, lpBaseName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;57pub extern "psapi" fn GetDeviceDriverBaseNameW(ImageBase: LPVOID, lpBaseName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;
12pub extern "psapi" fn GetDeviceDriverFileNameA(ImageBase: LPVOID, lpFilename: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;58pub extern "psapi" fn GetDeviceDriverFileNameA(ImageBase: LPVOID, lpFilename: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;
...@@ -17,13 +63,13 @@ pub extern "psapi" fn GetModuleBaseNameA(hProcess: HANDLE, hModule: ?HMODULE, lp...@@ -17,13 +63,13 @@ pub extern "psapi" fn GetModuleBaseNameA(hProcess: HANDLE, hModule: ?HMODULE, lp
17pub extern "psapi" fn GetModuleBaseNameW(hProcess: HANDLE, hModule: ?HMODULE, lpBaseName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;63pub extern "psapi" fn GetModuleBaseNameW(hProcess: HANDLE, hModule: ?HMODULE, lpBaseName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;
18pub extern "psapi" fn GetModuleFileNameExA(hProcess: HANDLE, hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;64pub extern "psapi" fn GetModuleFileNameExA(hProcess: HANDLE, hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;
19pub extern "psapi" fn GetModuleFileNameExW(hProcess: HANDLE, hModule: ?HMODULE, lpFilename: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;65pub extern "psapi" fn GetModuleFileNameExW(hProcess: HANDLE, hModule: ?HMODULE, lpFilename: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;
20pub extern "psapi" fn GetModuleInformation(hProcess: HANDLE, hModule: HMODULE, lpmodinfo: LPMODULEINFO, cb: DWORD) callconv(WINAPI) BOOL;66pub extern "psapi" fn GetModuleInformation(hProcess: HANDLE, hModule: HMODULE, lpmodinfo: *MODULEINFO, cb: DWORD) callconv(WINAPI) BOOL;
21pub extern "psapi" fn GetPerformanceInfo(pPerformanceInformation: PPERFORMACE_INFORMATION, cb: DWORD) callconv(WINAPI) BOOL;67pub extern "psapi" fn GetPerformanceInfo(pPerformanceInformation: *PERFORMANCE_INFORMATION, cb: DWORD) callconv(WINAPI) BOOL;
22pub extern "psapi" fn GetProcessImageFileNameA(hProcess: HANDLE, lpImageFileName: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;68pub extern "psapi" fn GetProcessImageFileNameA(hProcess: HANDLE, lpImageFileName: LPSTR, nSize: DWORD) callconv(WINAPI) DWORD;
23pub extern "psapi" fn GetProcessImageFileNameW(hProcess: HANDLE, lpImageFileName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;69pub extern "psapi" fn GetProcessImageFileNameW(hProcess: HANDLE, lpImageFileName: LPWSTR, nSize: DWORD) callconv(WINAPI) DWORD;
24pub extern "psapi" fn GetProcessMemoryInfo(Process: HANDLE, ppsmemCounters: PPROCESS_MEMORY_COUNTERS, cb: DWORD) callconv(WINAPI) BOOL;70pub extern "psapi" fn GetProcessMemoryInfo(Process: HANDLE, ppsmemCounters: *PROCESS_MEMORY_COUNTERS, cb: DWORD) callconv(WINAPI) BOOL;
25pub extern "psapi" fn GetWsChanges(hProcess: HANDLE, lpWatchInfo: PPSAPI_WS_WATCH_INFORMATION, cb: DWORD) callconv(WINAPI) BOOL;71pub extern "psapi" fn GetWsChanges(hProcess: HANDLE, lpWatchInfo: *PSAPI_WS_WATCH_INFORMATION, cb: DWORD) callconv(WINAPI) BOOL;
26pub extern "psapi" fn GetWsChangesEx(hProcess: HANDLE, lpWatchInfoEx: PPSAPI_WS_WATCH_INFORMATION_EX, cb: DWORD) callconv(WINAPI) BOOL;72pub extern "psapi" fn GetWsChangesEx(hProcess: HANDLE, lpWatchInfoEx: *PSAPI_WS_WATCH_INFORMATION_EX, cb: DWORD) callconv(WINAPI) BOOL;
27pub extern "psapi" fn InitializeProcessForWsWatch(hProcess: HANDLE) callconv(WINAPI) BOOL;73pub extern "psapi" fn InitializeProcessForWsWatch(hProcess: HANDLE) callconv(WINAPI) BOOL;
28pub extern "psapi" fn QueryWorkingSet(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(WINAPI) BOOL;74pub extern "psapi" fn QueryWorkingSet(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(WINAPI) BOOL;
29pub extern "psapi" fn QueryWorkingSetEx(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(WINAPI) BOOL;75pub extern "psapi" fn QueryWorkingSetEx(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(WINAPI) BOOL;
lib/std/os/windows/shell32.zig+14-2
...@@ -1,3 +1,15 @@...@@ -1,3 +1,15 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;
3const WINAPI = windows.WINAPI;
4const KNOWNFOLDERID = windows.KNOWNFOLDERID;
5const DWORD = windows.DWORD;
6const HANDLE = windows.HANDLE;
7const WCHAR = windows.WCHAR;
8const HRESULT = windows.HRESULT;
29
3pub extern "shell32" fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*:0]WCHAR) callconv(WINAPI) HRESULT;10pub extern "shell32" fn SHGetKnownFolderPath(
11 rfid: *const KNOWNFOLDERID,
12 dwFlags: DWORD,
13 hToken: ?HANDLE,
14 ppszPath: *[*:0]WCHAR,
15) callconv(WINAPI) HRESULT;
lib/std/os/windows/user32.zig+26-6
...@@ -1,11 +1,31 @@...@@ -1,11 +1,31 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const std = @import("std");
3const builtin = std.builtin;
4const assert = std.debug.assert;2const assert = std.debug.assert;
5const windows = @import("../windows.zig");3
6const unexpectedError = windows.unexpectedError;4const windows = std.os.windows;
7const GetLastError = windows.kernel32.GetLastError;5const GetLastError = windows.kernel32.GetLastError;
8const SetLastError = windows.kernel32.SetLastError;6const SetLastError = windows.kernel32.SetLastError;
7const unexpectedError = windows.unexpectedError;
8const HWND = windows.HWND;
9const UINT = windows.UINT;
10const HDC = windows.HDC;
11const LONG = windows.LONG;
12const LONG_PTR = windows.LONG_PTR;
13const WINAPI = windows.WINAPI;
14const RECT = windows.RECT;
15const DWORD = windows.DWORD;
16const BOOL = windows.BOOL;
17const TRUE = windows.TRUE;
18const HMENU = windows.HMENU;
19const HINSTANCE = windows.HINSTANCE;
20const LPVOID = windows.LPVOID;
21const ATOM = windows.ATOM;
22const WPARAM = windows.WPARAM;
23const LRESULT = windows.LRESULT;
24const HICON = windows.HICON;
25const LPARAM = windows.LPARAM;
26const POINT = windows.POINT;
27const HCURSOR = windows.HCURSOR;
28const HBRUSH = windows.HBRUSH;
929
10fn selectSymbol(comptime function_static: anytype, function_dynamic: @TypeOf(function_static), comptime os: std.Target.Os.WindowsVersion) @TypeOf(function_static) {30fn selectSymbol(comptime function_static: anytype, function_dynamic: @TypeOf(function_static), comptime os: std.Target.Os.WindowsVersion) @TypeOf(function_static) {
11 comptime {31 comptime {
...@@ -1318,7 +1338,7 @@ pub fn showWindow(hWnd: HWND, nCmdShow: i32) bool {...@@ -1318,7 +1338,7 @@ pub fn showWindow(hWnd: HWND, nCmdShow: i32) bool {
13181338
1319pub extern "user32" fn UpdateWindow(hWnd: HWND) callconv(WINAPI) BOOL;1339pub extern "user32" fn UpdateWindow(hWnd: HWND) callconv(WINAPI) BOOL;
1320pub fn updateWindow(hWnd: HWND) !void {1340pub fn updateWindow(hWnd: HWND) !void {
1321 if (ShowWindow(hWnd, nCmdShow) == 0) {1341 if (UpdateWindow(hWnd) == 0) {
1322 switch (GetLastError()) {1342 switch (GetLastError()) {
1323 .INVALID_WINDOW_HANDLE => unreachable,1343 .INVALID_WINDOW_HANDLE => unreachable,
1324 .INVALID_PARAMETER => unreachable,1344 .INVALID_PARAMETER => unreachable,
lib/std/os/windows/win32error.zig+1-1190
...@@ -1,3696 +1,2507 @@...@@ -1,3696 +1,2507 @@
1// Codes are from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/18d8fbe8-a967-4f1c-ae50-99ca8e491d2d1/// Codes are from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/18d8fbe8-a967-4f1c-ae50-99ca8e491d2d
2pub const Win32Error = enum(u16) {2pub const Win32Error = enum(u16) {
3 /// The operation completed successfully.3 /// The operation completed successfully.
4 SUCCESS = 0,4 SUCCESS = 0,
5
6 /// Incorrect function.5 /// Incorrect function.
7 INVALID_FUNCTION = 1,6 INVALID_FUNCTION = 1,
8
9 /// The system cannot find the file specified.7 /// The system cannot find the file specified.
10 FILE_NOT_FOUND = 2,8 FILE_NOT_FOUND = 2,
11
12 /// The system cannot find the path specified.9 /// The system cannot find the path specified.
13 PATH_NOT_FOUND = 3,10 PATH_NOT_FOUND = 3,
14
15 /// The system cannot open the file.11 /// The system cannot open the file.
16 TOO_MANY_OPEN_FILES = 4,12 TOO_MANY_OPEN_FILES = 4,
17
18 /// Access is denied.13 /// Access is denied.
19 ACCESS_DENIED = 5,14 ACCESS_DENIED = 5,
20
21 /// The handle is invalid.15 /// The handle is invalid.
22 INVALID_HANDLE = 6,16 INVALID_HANDLE = 6,
23
24 /// The storage control blocks were destroyed.17 /// The storage control blocks were destroyed.
25 ARENA_TRASHED = 7,18 ARENA_TRASHED = 7,
26
27 /// Not enough storage is available to process this command.19 /// Not enough storage is available to process this command.
28 NOT_ENOUGH_MEMORY = 8,20 NOT_ENOUGH_MEMORY = 8,
29
30 /// The storage control block address is invalid.21 /// The storage control block address is invalid.
31 INVALID_BLOCK = 9,22 INVALID_BLOCK = 9,
32
33 /// The environment is incorrect.23 /// The environment is incorrect.
34 BAD_ENVIRONMENT = 10,24 BAD_ENVIRONMENT = 10,
35
36 /// An attempt was made to load a program with an incorrect format.25 /// An attempt was made to load a program with an incorrect format.
37 BAD_FORMAT = 11,26 BAD_FORMAT = 11,
38
39 /// The access code is invalid.27 /// The access code is invalid.
40 INVALID_ACCESS = 12,28 INVALID_ACCESS = 12,
41
42 /// The data is invalid.29 /// The data is invalid.
43 INVALID_DATA = 13,30 INVALID_DATA = 13,
44
45 /// Not enough storage is available to complete this operation.31 /// Not enough storage is available to complete this operation.
46 OUTOFMEMORY = 14,32 OUTOFMEMORY = 14,
47
48 /// The system cannot find the drive specified.33 /// The system cannot find the drive specified.
49 INVALID_DRIVE = 15,34 INVALID_DRIVE = 15,
50
51 /// The directory cannot be removed.35 /// The directory cannot be removed.
52 CURRENT_DIRECTORY = 16,36 CURRENT_DIRECTORY = 16,
53
54 /// The system cannot move the file to a different disk drive.37 /// The system cannot move the file to a different disk drive.
55 NOT_SAME_DEVICE = 17,38 NOT_SAME_DEVICE = 17,
56
57 /// There are no more files.39 /// There are no more files.
58 NO_MORE_FILES = 18,40 NO_MORE_FILES = 18,
59
60 /// The media is write protected.41 /// The media is write protected.
61 WRITE_PROTECT = 19,42 WRITE_PROTECT = 19,
62
63 /// The system cannot find the device specified.43 /// The system cannot find the device specified.
64 BAD_UNIT = 20,44 BAD_UNIT = 20,
65
66 /// The device is not ready.45 /// The device is not ready.
67 NOT_READY = 21,46 NOT_READY = 21,
68
69 /// The device does not recognize the command.47 /// The device does not recognize the command.
70 BAD_COMMAND = 22,48 BAD_COMMAND = 22,
71
72 /// Data error (cyclic redundancy check).49 /// Data error (cyclic redundancy check).
73 CRC = 23,50 CRC = 23,
74
75 /// The program issued a command but the command length is incorrect.51 /// The program issued a command but the command length is incorrect.
76 BAD_LENGTH = 24,52 BAD_LENGTH = 24,
77
78 /// The drive cannot locate a specific area or track on the disk.53 /// The drive cannot locate a specific area or track on the disk.
79 SEEK = 25,54 SEEK = 25,
80
81 /// The specified disk or diskette cannot be accessed.55 /// The specified disk or diskette cannot be accessed.
82 NOT_DOS_DISK = 26,56 NOT_DOS_DISK = 26,
83
84 /// The drive cannot find the sector requested.57 /// The drive cannot find the sector requested.
85 SECTOR_NOT_FOUND = 27,58 SECTOR_NOT_FOUND = 27,
86
87 /// The printer is out of paper.59 /// The printer is out of paper.
88 OUT_OF_PAPER = 28,60 OUT_OF_PAPER = 28,
89
90 /// The system cannot write to the specified device.61 /// The system cannot write to the specified device.
91 WRITE_FAULT = 29,62 WRITE_FAULT = 29,
92
93 /// The system cannot read from the specified device.63 /// The system cannot read from the specified device.
94 READ_FAULT = 30,64 READ_FAULT = 30,
95
96 /// A device attached to the system is not functioning.65 /// A device attached to the system is not functioning.
97 GEN_FAILURE = 31,66 GEN_FAILURE = 31,
98
99 /// The process cannot access the file because it is being used by another process.67 /// The process cannot access the file because it is being used by another process.
100 SHARING_VIOLATION = 32,68 SHARING_VIOLATION = 32,
101
102 /// The process cannot access the file because another process has locked a portion of the file.69 /// The process cannot access the file because another process has locked a portion of the file.
103 LOCK_VIOLATION = 33,70 LOCK_VIOLATION = 33,
104
105 /// The wrong diskette is in the drive.71 /// The wrong diskette is in the drive.
106 /// Insert %2 (Volume Serial Number: %3) into drive %1.72 /// Insert %2 (Volume Serial Number: %3) into drive %1.
107 WRONG_DISK = 34,73 WRONG_DISK = 34,
108
109 /// Too many files opened for sharing.74 /// Too many files opened for sharing.
110 SHARING_BUFFER_EXCEEDED = 36,75 SHARING_BUFFER_EXCEEDED = 36,
111
112 /// Reached the end of the file.76 /// Reached the end of the file.
113 HANDLE_EOF = 38,77 HANDLE_EOF = 38,
114
115 /// The disk is full.78 /// The disk is full.
116 HANDLE_DISK_FULL = 39,79 HANDLE_DISK_FULL = 39,
117
118 /// The request is not supported.80 /// The request is not supported.
119 NOT_SUPPORTED = 50,81 NOT_SUPPORTED = 50,
120
121 /// Windows cannot find the network path.82 /// Windows cannot find the network path.
122 /// Verify that the network path is correct and the destination computer is not busy or turned off.83 /// Verify that the network path is correct and the destination computer is not busy or turned off.
123 /// If Windows still cannot find the network path, contact your network administrator.84 /// If Windows still cannot find the network path, contact your network administrator.
124 REM_NOT_LIST = 51,85 REM_NOT_LIST = 51,
125
126 /// You were not connected because a duplicate name exists on the network.86 /// You were not connected because a duplicate name exists on the network.
127 /// If joining a domain, go to System in Control Panel to change the computer name and try again.87 /// If joining a domain, go to System in Control Panel to change the computer name and try again.
128 /// If joining a workgroup, choose another workgroup name.88 /// If joining a workgroup, choose another workgroup name.
129 DUP_NAME = 52,89 DUP_NAME = 52,
130
131 /// The network path was not found.90 /// The network path was not found.
132 BAD_NETPATH = 53,91 BAD_NETPATH = 53,
133
134 /// The network is busy.92 /// The network is busy.
135 NETWORK_BUSY = 54,93 NETWORK_BUSY = 54,
136
137 /// The specified network resource or device is no longer available.94 /// The specified network resource or device is no longer available.
138 DEV_NOT_EXIST = 55,95 DEV_NOT_EXIST = 55,
139
140 /// The network BIOS command limit has been reached.96 /// The network BIOS command limit has been reached.
141 TOO_MANY_CMDS = 56,97 TOO_MANY_CMDS = 56,
142
143 /// A network adapter hardware error occurred.98 /// A network adapter hardware error occurred.
144 ADAP_HDW_ERR = 57,99 ADAP_HDW_ERR = 57,
145
146 /// The specified server cannot perform the requested operation.100 /// The specified server cannot perform the requested operation.
147 BAD_NET_RESP = 58,101 BAD_NET_RESP = 58,
148
149 /// An unexpected network error occurred.102 /// An unexpected network error occurred.
150 UNEXP_NET_ERR = 59,103 UNEXP_NET_ERR = 59,
151
152 /// The remote adapter is not compatible.104 /// The remote adapter is not compatible.
153 BAD_REM_ADAP = 60,105 BAD_REM_ADAP = 60,
154
155 /// The printer queue is full.106 /// The printer queue is full.
156 PRINTQ_FULL = 61,107 PRINTQ_FULL = 61,
157
158 /// Space to store the file waiting to be printed is not available on the server.108 /// Space to store the file waiting to be printed is not available on the server.
159 NO_SPOOL_SPACE = 62,109 NO_SPOOL_SPACE = 62,
160
161 /// Your file waiting to be printed was deleted.110 /// Your file waiting to be printed was deleted.
162 PRINT_CANCELLED = 63,111 PRINT_CANCELLED = 63,
163
164 /// The specified network name is no longer available.112 /// The specified network name is no longer available.
165 NETNAME_DELETED = 64,113 NETNAME_DELETED = 64,
166
167 /// Network access is denied.114 /// Network access is denied.
168 NETWORK_ACCESS_DENIED = 65,115 NETWORK_ACCESS_DENIED = 65,
169
170 /// The network resource type is not correct.116 /// The network resource type is not correct.
171 BAD_DEV_TYPE = 66,117 BAD_DEV_TYPE = 66,
172
173 /// The network name cannot be found.118 /// The network name cannot be found.
174 BAD_NET_NAME = 67,119 BAD_NET_NAME = 67,
175
176 /// The name limit for the local computer network adapter card was exceeded.120 /// The name limit for the local computer network adapter card was exceeded.
177 TOO_MANY_NAMES = 68,121 TOO_MANY_NAMES = 68,
178
179 /// The network BIOS session limit was exceeded.122 /// The network BIOS session limit was exceeded.
180 TOO_MANY_SESS = 69,123 TOO_MANY_SESS = 69,
181
182 /// The remote server has been paused or is in the process of being started.124 /// The remote server has been paused or is in the process of being started.
183 SHARING_PAUSED = 70,125 SHARING_PAUSED = 70,
184
185 /// No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.126 /// No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.
186 REQ_NOT_ACCEP = 71,127 REQ_NOT_ACCEP = 71,
187
188 /// The specified printer or disk device has been paused.128 /// The specified printer or disk device has been paused.
189 REDIR_PAUSED = 72,129 REDIR_PAUSED = 72,
190
191 /// The file exists.130 /// The file exists.
192 FILE_EXISTS = 80,131 FILE_EXISTS = 80,
193
194 /// The directory or file cannot be created.132 /// The directory or file cannot be created.
195 CANNOT_MAKE = 82,133 CANNOT_MAKE = 82,
196
197 /// Fail on INT 24.134 /// Fail on INT 24.
198 FAIL_I24 = 83,135 FAIL_I24 = 83,
199
200 /// Storage to process this request is not available.136 /// Storage to process this request is not available.
201 OUT_OF_STRUCTURES = 84,137 OUT_OF_STRUCTURES = 84,
202
203 /// The local device name is already in use.138 /// The local device name is already in use.
204 ALREADY_ASSIGNED = 85,139 ALREADY_ASSIGNED = 85,
205
206 /// The specified network password is not correct.140 /// The specified network password is not correct.
207 INVALID_PASSWORD = 86,141 INVALID_PASSWORD = 86,
208
209 /// The parameter is incorrect.142 /// The parameter is incorrect.
210 INVALID_PARAMETER = 87,143 INVALID_PARAMETER = 87,
211
212 /// A write fault occurred on the network.144 /// A write fault occurred on the network.
213 NET_WRITE_FAULT = 88,145 NET_WRITE_FAULT = 88,
214
215 /// The system cannot start another process at this time.146 /// The system cannot start another process at this time.
216 NO_PROC_SLOTS = 89,147 NO_PROC_SLOTS = 89,
217
218 /// Cannot create another system semaphore.148 /// Cannot create another system semaphore.
219 TOO_MANY_SEMAPHORES = 100,149 TOO_MANY_SEMAPHORES = 100,
220
221 /// The exclusive semaphore is owned by another process.150 /// The exclusive semaphore is owned by another process.
222 EXCL_SEM_ALREADY_OWNED = 101,151 EXCL_SEM_ALREADY_OWNED = 101,
223
224 /// The semaphore is set and cannot be closed.152 /// The semaphore is set and cannot be closed.
225 SEM_IS_SET = 102,153 SEM_IS_SET = 102,
226
227 /// The semaphore cannot be set again.154 /// The semaphore cannot be set again.
228 TOO_MANY_SEM_REQUESTS = 103,155 TOO_MANY_SEM_REQUESTS = 103,
229
230 /// Cannot request exclusive semaphores at interrupt time.156 /// Cannot request exclusive semaphores at interrupt time.
231 INVALID_AT_INTERRUPT_TIME = 104,157 INVALID_AT_INTERRUPT_TIME = 104,
232
233 /// The previous ownership of this semaphore has ended.158 /// The previous ownership of this semaphore has ended.
234 SEM_OWNER_DIED = 105,159 SEM_OWNER_DIED = 105,
235
236 /// Insert the diskette for drive %1.160 /// Insert the diskette for drive %1.
237 SEM_USER_LIMIT = 106,161 SEM_USER_LIMIT = 106,
238
239 /// The program stopped because an alternate diskette was not inserted.162 /// The program stopped because an alternate diskette was not inserted.
240 DISK_CHANGE = 107,163 DISK_CHANGE = 107,
241
242 /// The disk is in use or locked by another process.164 /// The disk is in use or locked by another process.
243 DRIVE_LOCKED = 108,165 DRIVE_LOCKED = 108,
244
245 /// The pipe has been ended.166 /// The pipe has been ended.
246 BROKEN_PIPE = 109,167 BROKEN_PIPE = 109,
247
248 /// The system cannot open the device or file specified.168 /// The system cannot open the device or file specified.
249 OPEN_FAILED = 110,169 OPEN_FAILED = 110,
250
251 /// The file name is too long.170 /// The file name is too long.
252 BUFFER_OVERFLOW = 111,171 BUFFER_OVERFLOW = 111,
253
254 /// There is not enough space on the disk.172 /// There is not enough space on the disk.
255 DISK_FULL = 112,173 DISK_FULL = 112,
256
257 /// No more internal file identifiers available.174 /// No more internal file identifiers available.
258 NO_MORE_SEARCH_HANDLES = 113,175 NO_MORE_SEARCH_HANDLES = 113,
259
260 /// The target internal file identifier is incorrect.176 /// The target internal file identifier is incorrect.
261 INVALID_TARGET_HANDLE = 114,177 INVALID_TARGET_HANDLE = 114,
262
263 /// The IOCTL call made by the application program is not correct.178 /// The IOCTL call made by the application program is not correct.
264 INVALID_CATEGORY = 117,179 INVALID_CATEGORY = 117,
265
266 /// The verify-on-write switch parameter value is not correct.180 /// The verify-on-write switch parameter value is not correct.
267 INVALID_VERIFY_SWITCH = 118,181 INVALID_VERIFY_SWITCH = 118,
268
269 /// The system does not support the command requested.182 /// The system does not support the command requested.
270 BAD_DRIVER_LEVEL = 119,183 BAD_DRIVER_LEVEL = 119,
271
272 /// This function is not supported on this system.184 /// This function is not supported on this system.
273 CALL_NOT_IMPLEMENTED = 120,185 CALL_NOT_IMPLEMENTED = 120,
274
275 /// The semaphore timeout period has expired.186 /// The semaphore timeout period has expired.
276 SEM_TIMEOUT = 121,187 SEM_TIMEOUT = 121,
277
278 /// The data area passed to a system call is too small.188 /// The data area passed to a system call is too small.
279 INSUFFICIENT_BUFFER = 122,189 INSUFFICIENT_BUFFER = 122,
280
281 /// The filename, directory name, or volume label syntax is incorrect.190 /// The filename, directory name, or volume label syntax is incorrect.
282 INVALID_NAME = 123,191 INVALID_NAME = 123,
283
284 /// The system call level is not correct.192 /// The system call level is not correct.
285 INVALID_LEVEL = 124,193 INVALID_LEVEL = 124,
286
287 /// The disk has no volume label.194 /// The disk has no volume label.
288 NO_VOLUME_LABEL = 125,195 NO_VOLUME_LABEL = 125,
289
290 /// The specified module could not be found.196 /// The specified module could not be found.
291 MOD_NOT_FOUND = 126,197 MOD_NOT_FOUND = 126,
292
293 /// The specified procedure could not be found.198 /// The specified procedure could not be found.
294 PROC_NOT_FOUND = 127,199 PROC_NOT_FOUND = 127,
295
296 /// There are no child processes to wait for.200 /// There are no child processes to wait for.
297 WAIT_NO_CHILDREN = 128,201 WAIT_NO_CHILDREN = 128,
298
299 /// The %1 application cannot be run in Win32 mode.202 /// The %1 application cannot be run in Win32 mode.
300 CHILD_NOT_COMPLETE = 129,203 CHILD_NOT_COMPLETE = 129,
301
302 /// Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O.204 /// Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O.
303 DIRECT_ACCESS_HANDLE = 130,205 DIRECT_ACCESS_HANDLE = 130,
304
305 /// An attempt was made to move the file pointer before the beginning of the file.206 /// An attempt was made to move the file pointer before the beginning of the file.
306 NEGATIVE_SEEK = 131,207 NEGATIVE_SEEK = 131,
307
308 /// The file pointer cannot be set on the specified device or file.208 /// The file pointer cannot be set on the specified device or file.
309 SEEK_ON_DEVICE = 132,209 SEEK_ON_DEVICE = 132,
310
311 /// A JOIN or SUBST command cannot be used for a drive that contains previously joined drives.210 /// A JOIN or SUBST command cannot be used for a drive that contains previously joined drives.
312 IS_JOIN_TARGET = 133,211 IS_JOIN_TARGET = 133,
313
314 /// An attempt was made to use a JOIN or SUBST command on a drive that has already been joined.212 /// An attempt was made to use a JOIN or SUBST command on a drive that has already been joined.
315 IS_JOINED = 134,213 IS_JOINED = 134,
316
317 /// An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted.214 /// An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted.
318 IS_SUBSTED = 135,215 IS_SUBSTED = 135,
319
320 /// The system tried to delete the JOIN of a drive that is not joined.216 /// The system tried to delete the JOIN of a drive that is not joined.
321 NOT_JOINED = 136,217 NOT_JOINED = 136,
322
323 /// The system tried to delete the substitution of a drive that is not substituted.218 /// The system tried to delete the substitution of a drive that is not substituted.
324 NOT_SUBSTED = 137,219 NOT_SUBSTED = 137,
325
326 /// The system tried to join a drive to a directory on a joined drive.220 /// The system tried to join a drive to a directory on a joined drive.
327 JOIN_TO_JOIN = 138,221 JOIN_TO_JOIN = 138,
328
329 /// The system tried to substitute a drive to a directory on a substituted drive.222 /// The system tried to substitute a drive to a directory on a substituted drive.
330 SUBST_TO_SUBST = 139,223 SUBST_TO_SUBST = 139,
331
332 /// The system tried to join a drive to a directory on a substituted drive.224 /// The system tried to join a drive to a directory on a substituted drive.
333 JOIN_TO_SUBST = 140,225 JOIN_TO_SUBST = 140,
334
335 /// The system tried to SUBST a drive to a directory on a joined drive.226 /// The system tried to SUBST a drive to a directory on a joined drive.
336 SUBST_TO_JOIN = 141,227 SUBST_TO_JOIN = 141,
337
338 /// The system cannot perform a JOIN or SUBST at this time.228 /// The system cannot perform a JOIN or SUBST at this time.
339 BUSY_DRIVE = 142,229 BUSY_DRIVE = 142,
340
341 /// The system cannot join or substitute a drive to or for a directory on the same drive.230 /// The system cannot join or substitute a drive to or for a directory on the same drive.
342 SAME_DRIVE = 143,231 SAME_DRIVE = 143,
343
344 /// The directory is not a subdirectory of the root directory.232 /// The directory is not a subdirectory of the root directory.
345 DIR_NOT_ROOT = 144,233 DIR_NOT_ROOT = 144,
346
347 /// The directory is not empty.234 /// The directory is not empty.
348 DIR_NOT_EMPTY = 145,235 DIR_NOT_EMPTY = 145,
349
350 /// The path specified is being used in a substitute.236 /// The path specified is being used in a substitute.
351 IS_SUBST_PATH = 146,237 IS_SUBST_PATH = 146,
352
353 /// Not enough resources are available to process this command.238 /// Not enough resources are available to process this command.
354 IS_JOIN_PATH = 147,239 IS_JOIN_PATH = 147,
355
356 /// The path specified cannot be used at this time.240 /// The path specified cannot be used at this time.
357 PATH_BUSY = 148,241 PATH_BUSY = 148,
358
359 /// An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute.242 /// An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute.
360 IS_SUBST_TARGET = 149,243 IS_SUBST_TARGET = 149,
361
362 /// System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed.244 /// System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed.
363 SYSTEM_TRACE = 150,245 SYSTEM_TRACE = 150,
364
365 /// The number of specified semaphore events for DosMuxSemWait is not correct.246 /// The number of specified semaphore events for DosMuxSemWait is not correct.
366 INVALID_EVENT_COUNT = 151,247 INVALID_EVENT_COUNT = 151,
367
368 /// DosMuxSemWait did not execute; too many semaphores are already set.248 /// DosMuxSemWait did not execute; too many semaphores are already set.
369 TOO_MANY_MUXWAITERS = 152,249 TOO_MANY_MUXWAITERS = 152,
370
371 /// The DosMuxSemWait list is not correct.250 /// The DosMuxSemWait list is not correct.
372 INVALID_LIST_FORMAT = 153,251 INVALID_LIST_FORMAT = 153,
373
374 /// The volume label you entered exceeds the label character limit of the target file system.252 /// The volume label you entered exceeds the label character limit of the target file system.
375 LABEL_TOO_LONG = 154,253 LABEL_TOO_LONG = 154,
376
377 /// Cannot create another thread.254 /// Cannot create another thread.
378 TOO_MANY_TCBS = 155,255 TOO_MANY_TCBS = 155,
379
380 /// The recipient process has refused the signal.256 /// The recipient process has refused the signal.
381 SIGNAL_REFUSED = 156,257 SIGNAL_REFUSED = 156,
382
383 /// The segment is already discarded and cannot be locked.258 /// The segment is already discarded and cannot be locked.
384 DISCARDED = 157,259 DISCARDED = 157,
385
386 /// The segment is already unlocked.260 /// The segment is already unlocked.
387 NOT_LOCKED = 158,261 NOT_LOCKED = 158,
388
389 /// The address for the thread ID is not correct.262 /// The address for the thread ID is not correct.
390 BAD_THREADID_ADDR = 159,263 BAD_THREADID_ADDR = 159,
391
392 /// One or more arguments are not correct.264 /// One or more arguments are not correct.
393 BAD_ARGUMENTS = 160,265 BAD_ARGUMENTS = 160,
394
395 /// The specified path is invalid.266 /// The specified path is invalid.
396 BAD_PATHNAME = 161,267 BAD_PATHNAME = 161,
397
398 /// A signal is already pending.268 /// A signal is already pending.
399 SIGNAL_PENDING = 162,269 SIGNAL_PENDING = 162,
400
401 /// No more threads can be created in the system.270 /// No more threads can be created in the system.
402 MAX_THRDS_REACHED = 164,271 MAX_THRDS_REACHED = 164,
403
404 /// Unable to lock a region of a file.272 /// Unable to lock a region of a file.
405 LOCK_FAILED = 167,273 LOCK_FAILED = 167,
406
407 /// The requested resource is in use.274 /// The requested resource is in use.
408 BUSY = 170,275 BUSY = 170,
409
410 /// Device's command support detection is in progress.276 /// Device's command support detection is in progress.
411 DEVICE_SUPPORT_IN_PROGRESS = 171,277 DEVICE_SUPPORT_IN_PROGRESS = 171,
412
413 /// A lock request was not outstanding for the supplied cancel region.278 /// A lock request was not outstanding for the supplied cancel region.
414 CANCEL_VIOLATION = 173,279 CANCEL_VIOLATION = 173,
415
416 /// The file system does not support atomic changes to the lock type.280 /// The file system does not support atomic changes to the lock type.
417 ATOMIC_LOCKS_NOT_SUPPORTED = 174,281 ATOMIC_LOCKS_NOT_SUPPORTED = 174,
418
419 /// The system detected a segment number that was not correct.282 /// The system detected a segment number that was not correct.
420 INVALID_SEGMENT_NUMBER = 180,283 INVALID_SEGMENT_NUMBER = 180,
421
422 /// The operating system cannot run %1.284 /// The operating system cannot run %1.
423 INVALID_ORDINAL = 182,285 INVALID_ORDINAL = 182,
424
425 /// Cannot create a file when that file already exists.286 /// Cannot create a file when that file already exists.
426 ALREADY_EXISTS = 183,287 ALREADY_EXISTS = 183,
427
428 /// The flag passed is not correct.288 /// The flag passed is not correct.
429 INVALID_FLAG_NUMBER = 186,289 INVALID_FLAG_NUMBER = 186,
430
431 /// The specified system semaphore name was not found.290 /// The specified system semaphore name was not found.
432 SEM_NOT_FOUND = 187,291 SEM_NOT_FOUND = 187,
433
434 /// The operating system cannot run %1.292 /// The operating system cannot run %1.
435 INVALID_STARTING_CODESEG = 188,293 INVALID_STARTING_CODESEG = 188,
436
437 /// The operating system cannot run %1.294 /// The operating system cannot run %1.
438 INVALID_STACKSEG = 189,295 INVALID_STACKSEG = 189,
439
440 /// The operating system cannot run %1.296 /// The operating system cannot run %1.
441 INVALID_MODULETYPE = 190,297 INVALID_MODULETYPE = 190,
442
443 /// Cannot run %1 in Win32 mode.298 /// Cannot run %1 in Win32 mode.
444 INVALID_EXE_SIGNATURE = 191,299 INVALID_EXE_SIGNATURE = 191,
445
446 /// The operating system cannot run %1.300 /// The operating system cannot run %1.
447 EXE_MARKED_INVALID = 192,301 EXE_MARKED_INVALID = 192,
448
449 /// %1 is not a valid Win32 application.302 /// %1 is not a valid Win32 application.
450 BAD_EXE_FORMAT = 193,303 BAD_EXE_FORMAT = 193,
451
452 /// The operating system cannot run %1.304 /// The operating system cannot run %1.
453 ITERATED_DATA_EXCEEDS_64k = 194,305 ITERATED_DATA_EXCEEDS_64k = 194,
454
455 /// The operating system cannot run %1.306 /// The operating system cannot run %1.
456 INVALID_MINALLOCSIZE = 195,307 INVALID_MINALLOCSIZE = 195,
457
458 /// The operating system cannot run this application program.308 /// The operating system cannot run this application program.
459 DYNLINK_FROM_INVALID_RING = 196,309 DYNLINK_FROM_INVALID_RING = 196,
460
461 /// The operating system is not presently configured to run this application.310 /// The operating system is not presently configured to run this application.
462 IOPL_NOT_ENABLED = 197,311 IOPL_NOT_ENABLED = 197,
463
464 /// The operating system cannot run %1.312 /// The operating system cannot run %1.
465 INVALID_SEGDPL = 198,313 INVALID_SEGDPL = 198,
466
467 /// The operating system cannot run this application program.314 /// The operating system cannot run this application program.
468 AUTODATASEG_EXCEEDS_64k = 199,315 AUTODATASEG_EXCEEDS_64k = 199,
469
470 /// The code segment cannot be greater than or equal to 64K.316 /// The code segment cannot be greater than or equal to 64K.
471 RING2SEG_MUST_BE_MOVABLE = 200,317 RING2SEG_MUST_BE_MOVABLE = 200,
472
473 /// The operating system cannot run %1.318 /// The operating system cannot run %1.
474 RELOC_CHAIN_XEEDS_SEGLIM = 201,319 RELOC_CHAIN_XEEDS_SEGLIM = 201,
475
476 /// The operating system cannot run %1.320 /// The operating system cannot run %1.
477 INFLOOP_IN_RELOC_CHAIN = 202,321 INFLOOP_IN_RELOC_CHAIN = 202,
478
479 /// The system could not find the environment option that was entered.322 /// The system could not find the environment option that was entered.
480 ENVVAR_NOT_FOUND = 203,323 ENVVAR_NOT_FOUND = 203,
481
482 /// No process in the command subtree has a signal handler.324 /// No process in the command subtree has a signal handler.
483 NO_SIGNAL_SENT = 205,325 NO_SIGNAL_SENT = 205,
484
485 /// The filename or extension is too long.326 /// The filename or extension is too long.
486 FILENAME_EXCED_RANGE = 206,327 FILENAME_EXCED_RANGE = 206,
487
488 /// The ring 2 stack is in use.328 /// The ring 2 stack is in use.
489 RING2_STACK_IN_USE = 207,329 RING2_STACK_IN_USE = 207,
490
491 /// The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified.330 /// The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified.
492 META_EXPANSION_TOO_LONG = 208,331 META_EXPANSION_TOO_LONG = 208,
493
494 /// The signal being posted is not correct.332 /// The signal being posted is not correct.
495 INVALID_SIGNAL_NUMBER = 209,333 INVALID_SIGNAL_NUMBER = 209,
496
497 /// The signal handler cannot be set.334 /// The signal handler cannot be set.
498 THREAD_1_INACTIVE = 210,335 THREAD_1_INACTIVE = 210,
499
500 /// The segment is locked and cannot be reallocated.336 /// The segment is locked and cannot be reallocated.
501 LOCKED = 212,337 LOCKED = 212,
502
503 /// Too many dynamic-link modules are attached to this program or dynamic-link module.338 /// Too many dynamic-link modules are attached to this program or dynamic-link module.
504 TOO_MANY_MODULES = 214,339 TOO_MANY_MODULES = 214,
505
506 /// Cannot nest calls to LoadModule.340 /// Cannot nest calls to LoadModule.
507 NESTING_NOT_ALLOWED = 215,341 NESTING_NOT_ALLOWED = 215,
508
509 /// This version of %1 is not compatible with the version of Windows you're running.342 /// This version of %1 is not compatible with the version of Windows you're running.
510 /// Check your computer's system information and then contact the software publisher.343 /// Check your computer's system information and then contact the software publisher.
511 EXE_MACHINE_TYPE_MISMATCH = 216,344 EXE_MACHINE_TYPE_MISMATCH = 216,
512
513 /// The image file %1 is signed, unable to modify.345 /// The image file %1 is signed, unable to modify.
514 EXE_CANNOT_MODIFY_SIGNED_BINARY = 217,346 EXE_CANNOT_MODIFY_SIGNED_BINARY = 217,
515
516 /// The image file %1 is strong signed, unable to modify.347 /// The image file %1 is strong signed, unable to modify.
517 EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY = 218,348 EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY = 218,
518
519 /// This file is checked out or locked for editing by another user.349 /// This file is checked out or locked for editing by another user.
520 FILE_CHECKED_OUT = 220,350 FILE_CHECKED_OUT = 220,
521
522 /// The file must be checked out before saving changes.351 /// The file must be checked out before saving changes.
523 CHECKOUT_REQUIRED = 221,352 CHECKOUT_REQUIRED = 221,
524
525 /// The file type being saved or retrieved has been blocked.353 /// The file type being saved or retrieved has been blocked.
526 BAD_FILE_TYPE = 222,354 BAD_FILE_TYPE = 222,
527
528 /// The file size exceeds the limit allowed and cannot be saved.355 /// The file size exceeds the limit allowed and cannot be saved.
529 FILE_TOO_LARGE = 223,356 FILE_TOO_LARGE = 223,
530
531 /// Access Denied. Before opening files in this location, you must first add the web site to your trusted sites list, browse to the web site, and select the option to login automatically.357 /// Access Denied. Before opening files in this location, you must first add the web site to your trusted sites list, browse to the web site, and select the option to login automatically.
532 FORMS_AUTH_REQUIRED = 224,358 FORMS_AUTH_REQUIRED = 224,
533
534 /// Operation did not complete successfully because the file contains a virus or potentially unwanted software.359 /// Operation did not complete successfully because the file contains a virus or potentially unwanted software.
535 VIRUS_INFECTED = 225,360 VIRUS_INFECTED = 225,
536
537 /// This file contains a virus or potentially unwanted software and cannot be opened.361 /// This file contains a virus or potentially unwanted software and cannot be opened.
538 /// Due to the nature of this virus or potentially unwanted software, the file has been removed from this location.362 /// Due to the nature of this virus or potentially unwanted software, the file has been removed from this location.
539 VIRUS_DELETED = 226,363 VIRUS_DELETED = 226,
540
541 /// The pipe is local.364 /// The pipe is local.
542 PIPE_LOCAL = 229,365 PIPE_LOCAL = 229,
543
544 /// The pipe state is invalid.366 /// The pipe state is invalid.
545 BAD_PIPE = 230,367 BAD_PIPE = 230,
546
547 /// All pipe instances are busy.368 /// All pipe instances are busy.
548 PIPE_BUSY = 231,369 PIPE_BUSY = 231,
549
550 /// The pipe is being closed.370 /// The pipe is being closed.
551 NO_DATA = 232,371 NO_DATA = 232,
552
553 /// No process is on the other end of the pipe.372 /// No process is on the other end of the pipe.
554 PIPE_NOT_CONNECTED = 233,373 PIPE_NOT_CONNECTED = 233,
555
556 /// More data is available.374 /// More data is available.
557 MORE_DATA = 234,375 MORE_DATA = 234,
558
559 /// The session was canceled.376 /// The session was canceled.
560 VC_DISCONNECTED = 240,377 VC_DISCONNECTED = 240,
561
562 /// The specified extended attribute name was invalid.378 /// The specified extended attribute name was invalid.
563 INVALID_EA_NAME = 254,379 INVALID_EA_NAME = 254,
564
565 /// The extended attributes are inconsistent.380 /// The extended attributes are inconsistent.
566 EA_LIST_INCONSISTENT = 255,381 EA_LIST_INCONSISTENT = 255,
567
568 /// The wait operation timed out.382 /// The wait operation timed out.
569 IMEOUT = 258,383 IMEOUT = 258,
570
571 /// No more data is available.384 /// No more data is available.
572 NO_MORE_ITEMS = 259,385 NO_MORE_ITEMS = 259,
573
574 /// The copy functions cannot be used.386 /// The copy functions cannot be used.
575 CANNOT_COPY = 266,387 CANNOT_COPY = 266,
576
577 /// The directory name is invalid.388 /// The directory name is invalid.
578 DIRECTORY = 267,389 DIRECTORY = 267,
579
580 /// The extended attributes did not fit in the buffer.390 /// The extended attributes did not fit in the buffer.
581 EAS_DIDNT_FIT = 275,391 EAS_DIDNT_FIT = 275,
582
583 /// The extended attribute file on the mounted file system is corrupt.392 /// The extended attribute file on the mounted file system is corrupt.
584 EA_FILE_CORRUPT = 276,393 EA_FILE_CORRUPT = 276,
585
586 /// The extended attribute table file is full.394 /// The extended attribute table file is full.
587 EA_TABLE_FULL = 277,395 EA_TABLE_FULL = 277,
588
589 /// The specified extended attribute handle is invalid.396 /// The specified extended attribute handle is invalid.
590 INVALID_EA_HANDLE = 278,397 INVALID_EA_HANDLE = 278,
591
592 /// The mounted file system does not support extended attributes.398 /// The mounted file system does not support extended attributes.
593 EAS_NOT_SUPPORTED = 282,399 EAS_NOT_SUPPORTED = 282,
594
595 /// Attempt to release mutex not owned by caller.400 /// Attempt to release mutex not owned by caller.
596 NOT_OWNER = 288,401 NOT_OWNER = 288,
597
598 /// Too many posts were made to a semaphore.402 /// Too many posts were made to a semaphore.
599 TOO_MANY_POSTS = 298,403 TOO_MANY_POSTS = 298,
600
601 /// Only part of a ReadProcessMemory or WriteProcessMemory request was completed.404 /// Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
602 PARTIAL_COPY = 299,405 PARTIAL_COPY = 299,
603
604 /// The oplock request is denied.406 /// The oplock request is denied.
605 OPLOCK_NOT_GRANTED = 300,407 OPLOCK_NOT_GRANTED = 300,
606
607 /// An invalid oplock acknowledgment was received by the system.408 /// An invalid oplock acknowledgment was received by the system.
608 INVALID_OPLOCK_PROTOCOL = 301,409 INVALID_OPLOCK_PROTOCOL = 301,
609
610 /// The volume is too fragmented to complete this operation.410 /// The volume is too fragmented to complete this operation.
611 DISK_TOO_FRAGMENTED = 302,411 DISK_TOO_FRAGMENTED = 302,
612
613 /// The file cannot be opened because it is in the process of being deleted.412 /// The file cannot be opened because it is in the process of being deleted.
614 DELETE_PENDING = 303,413 DELETE_PENDING = 303,
615
616 /// Short name settings may not be changed on this volume due to the global registry setting.414 /// Short name settings may not be changed on this volume due to the global registry setting.
617 INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING = 304,415 INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING = 304,
618
619 /// Short names are not enabled on this volume.416 /// Short names are not enabled on this volume.
620 SHORT_NAMES_NOT_ENABLED_ON_VOLUME = 305,417 SHORT_NAMES_NOT_ENABLED_ON_VOLUME = 305,
621
622 /// The security stream for the given volume is in an inconsistent state. Please run CHKDSK on the volume.418 /// The security stream for the given volume is in an inconsistent state. Please run CHKDSK on the volume.
623 SECURITY_STREAM_IS_INCONSISTENT = 306,419 SECURITY_STREAM_IS_INCONSISTENT = 306,
624
625 /// A requested file lock operation cannot be processed due to an invalid byte range.420 /// A requested file lock operation cannot be processed due to an invalid byte range.
626 INVALID_LOCK_RANGE = 307,421 INVALID_LOCK_RANGE = 307,
627
628 /// The subsystem needed to support the image type is not present.422 /// The subsystem needed to support the image type is not present.
629 IMAGE_SUBSYSTEM_NOT_PRESENT = 308,423 IMAGE_SUBSYSTEM_NOT_PRESENT = 308,
630
631 /// The specified file already has a notification GUID associated with it.424 /// The specified file already has a notification GUID associated with it.
632 NOTIFICATION_GUID_ALREADY_DEFINED = 309,425 NOTIFICATION_GUID_ALREADY_DEFINED = 309,
633
634 /// An invalid exception handler routine has been detected.426 /// An invalid exception handler routine has been detected.
635 INVALID_EXCEPTION_HANDLER = 310,427 INVALID_EXCEPTION_HANDLER = 310,
636
637 /// Duplicate privileges were specified for the token.428 /// Duplicate privileges were specified for the token.
638 DUPLICATE_PRIVILEGES = 311,429 DUPLICATE_PRIVILEGES = 311,
639
640 /// No ranges for the specified operation were able to be processed.430 /// No ranges for the specified operation were able to be processed.
641 NO_RANGES_PROCESSED = 312,431 NO_RANGES_PROCESSED = 312,
642
643 /// Operation is not allowed on a file system internal file.432 /// Operation is not allowed on a file system internal file.
644 NOT_ALLOWED_ON_SYSTEM_FILE = 313,433 NOT_ALLOWED_ON_SYSTEM_FILE = 313,
645
646 /// The physical resources of this disk have been exhausted.434 /// The physical resources of this disk have been exhausted.
647 DISK_RESOURCES_EXHAUSTED = 314,435 DISK_RESOURCES_EXHAUSTED = 314,
648
649 /// The token representing the data is invalid.436 /// The token representing the data is invalid.
650 INVALID_TOKEN = 315,437 INVALID_TOKEN = 315,
651
652 /// The device does not support the command feature.438 /// The device does not support the command feature.
653 DEVICE_FEATURE_NOT_SUPPORTED = 316,439 DEVICE_FEATURE_NOT_SUPPORTED = 316,
654
655 /// The system cannot find message text for message number 0x%1 in the message file for %2.440 /// The system cannot find message text for message number 0x%1 in the message file for %2.
656 MR_MID_NOT_FOUND = 317,441 MR_MID_NOT_FOUND = 317,
657
658 /// The scope specified was not found.442 /// The scope specified was not found.
659 SCOPE_NOT_FOUND = 318,443 SCOPE_NOT_FOUND = 318,
660
661 /// The Central Access Policy specified is not defined on the target machine.444 /// The Central Access Policy specified is not defined on the target machine.
662 UNDEFINED_SCOPE = 319,445 UNDEFINED_SCOPE = 319,
663
664 /// The Central Access Policy obtained from Active Directory is invalid.446 /// The Central Access Policy obtained from Active Directory is invalid.
665 INVALID_CAP = 320,447 INVALID_CAP = 320,
666
667 /// The device is unreachable.448 /// The device is unreachable.
668 DEVICE_UNREACHABLE = 321,449 DEVICE_UNREACHABLE = 321,
669
670 /// The target device has insufficient resources to complete the operation.450 /// The target device has insufficient resources to complete the operation.
671 DEVICE_NO_RESOURCES = 322,451 DEVICE_NO_RESOURCES = 322,
672
673 /// A data integrity checksum error occurred. Data in the file stream is corrupt.452 /// A data integrity checksum error occurred. Data in the file stream is corrupt.
674 DATA_CHECKSUM_ERROR = 323,453 DATA_CHECKSUM_ERROR = 323,
675
676 /// An attempt was made to modify both a KERNEL and normal Extended Attribute (EA) in the same operation.454 /// An attempt was made to modify both a KERNEL and normal Extended Attribute (EA) in the same operation.
677 INTERMIXED_KERNEL_EA_OPERATION = 324,455 INTERMIXED_KERNEL_EA_OPERATION = 324,
678
679 /// Device does not support file-level TRIM.456 /// Device does not support file-level TRIM.
680 FILE_LEVEL_TRIM_NOT_SUPPORTED = 326,457 FILE_LEVEL_TRIM_NOT_SUPPORTED = 326,
681
682 /// The command specified a data offset that does not align to the device's granularity/alignment.458 /// The command specified a data offset that does not align to the device's granularity/alignment.
683 OFFSET_ALIGNMENT_VIOLATION = 327,459 OFFSET_ALIGNMENT_VIOLATION = 327,
684
685 /// The command specified an invalid field in its parameter list.460 /// The command specified an invalid field in its parameter list.
686 INVALID_FIELD_IN_PARAMETER_LIST = 328,461 INVALID_FIELD_IN_PARAMETER_LIST = 328,
687
688 /// An operation is currently in progress with the device.462 /// An operation is currently in progress with the device.
689 OPERATION_IN_PROGRESS = 329,463 OPERATION_IN_PROGRESS = 329,
690
691 /// An attempt was made to send down the command via an invalid path to the target device.464 /// An attempt was made to send down the command via an invalid path to the target device.
692 BAD_DEVICE_PATH = 330,465 BAD_DEVICE_PATH = 330,
693
694 /// The command specified a number of descriptors that exceeded the maximum supported by the device.466 /// The command specified a number of descriptors that exceeded the maximum supported by the device.
695 TOO_MANY_DESCRIPTORS = 331,467 TOO_MANY_DESCRIPTORS = 331,
696
697 /// Scrub is disabled on the specified file.468 /// Scrub is disabled on the specified file.
698 SCRUB_DATA_DISABLED = 332,469 SCRUB_DATA_DISABLED = 332,
699
700 /// The storage device does not provide redundancy.470 /// The storage device does not provide redundancy.
701 NOT_REDUNDANT_STORAGE = 333,471 NOT_REDUNDANT_STORAGE = 333,
702
703 /// An operation is not supported on a resident file.472 /// An operation is not supported on a resident file.
704 RESIDENT_FILE_NOT_SUPPORTED = 334,473 RESIDENT_FILE_NOT_SUPPORTED = 334,
705
706 /// An operation is not supported on a compressed file.474 /// An operation is not supported on a compressed file.
707 COMPRESSED_FILE_NOT_SUPPORTED = 335,475 COMPRESSED_FILE_NOT_SUPPORTED = 335,
708
709 /// An operation is not supported on a directory.476 /// An operation is not supported on a directory.
710 DIRECTORY_NOT_SUPPORTED = 336,477 DIRECTORY_NOT_SUPPORTED = 336,
711
712 /// The specified copy of the requested data could not be read.478 /// The specified copy of the requested data could not be read.
713 NOT_READ_FROM_COPY = 337,479 NOT_READ_FROM_COPY = 337,
714
715 /// No action was taken as a system reboot is required.480 /// No action was taken as a system reboot is required.
716 FAIL_NOACTION_REBOOT = 350,481 FAIL_NOACTION_REBOOT = 350,
717
718 /// The shutdown operation failed.482 /// The shutdown operation failed.
719 FAIL_SHUTDOWN = 351,483 FAIL_SHUTDOWN = 351,
720
721 /// The restart operation failed.484 /// The restart operation failed.
722 FAIL_RESTART = 352,485 FAIL_RESTART = 352,
723
724 /// The maximum number of sessions has been reached.486 /// The maximum number of sessions has been reached.
725 MAX_SESSIONS_REACHED = 353,487 MAX_SESSIONS_REACHED = 353,
726
727 /// The thread is already in background processing mode.488 /// The thread is already in background processing mode.
728 THREAD_MODE_ALREADY_BACKGROUND = 400,489 THREAD_MODE_ALREADY_BACKGROUND = 400,
729
730 /// The thread is not in background processing mode.490 /// The thread is not in background processing mode.
731 THREAD_MODE_NOT_BACKGROUND = 401,491 THREAD_MODE_NOT_BACKGROUND = 401,
732
733 /// The process is already in background processing mode.492 /// The process is already in background processing mode.
734 PROCESS_MODE_ALREADY_BACKGROUND = 402,493 PROCESS_MODE_ALREADY_BACKGROUND = 402,
735
736 /// The process is not in background processing mode.494 /// The process is not in background processing mode.
737 PROCESS_MODE_NOT_BACKGROUND = 403,495 PROCESS_MODE_NOT_BACKGROUND = 403,
738
739 /// Attempt to access invalid address.496 /// Attempt to access invalid address.
740 INVALID_ADDRESS = 487,497 INVALID_ADDRESS = 487,
741
742 /// User profile cannot be loaded.498 /// User profile cannot be loaded.
743 USER_PROFILE_LOAD = 500,499 USER_PROFILE_LOAD = 500,
744
745 /// Arithmetic result exceeded 32 bits.500 /// Arithmetic result exceeded 32 bits.
746 ARITHMETIC_OVERFLOW = 534,501 ARITHMETIC_OVERFLOW = 534,
747
748 /// There is a process on other end of the pipe.502 /// There is a process on other end of the pipe.
749 PIPE_CONNECTED = 535,503 PIPE_CONNECTED = 535,
750
751 /// Waiting for a process to open the other end of the pipe.504 /// Waiting for a process to open the other end of the pipe.
752 PIPE_LISTENING = 536,505 PIPE_LISTENING = 536,
753
754 /// Application verifier has found an error in the current process.506 /// Application verifier has found an error in the current process.
755 VERIFIER_STOP = 537,507 VERIFIER_STOP = 537,
756
757 /// An error occurred in the ABIOS subsystem.508 /// An error occurred in the ABIOS subsystem.
758 ABIOS_ERROR = 538,509 ABIOS_ERROR = 538,
759
760 /// A warning occurred in the WX86 subsystem.510 /// A warning occurred in the WX86 subsystem.
761 WX86_WARNING = 539,511 WX86_WARNING = 539,
762
763 /// An error occurred in the WX86 subsystem.512 /// An error occurred in the WX86 subsystem.
764 WX86_ERROR = 540,513 WX86_ERROR = 540,
765
766 /// An attempt was made to cancel or set a timer that has an associated APC and the subject thread is not the thread that originally set the timer with an associated APC routine.514 /// An attempt was made to cancel or set a timer that has an associated APC and the subject thread is not the thread that originally set the timer with an associated APC routine.
767 TIMER_NOT_CANCELED = 541,515 TIMER_NOT_CANCELED = 541,
768
769 /// Unwind exception code.516 /// Unwind exception code.
770 UNWIND = 542,517 UNWIND = 542,
771
772 /// An invalid or unaligned stack was encountered during an unwind operation.518 /// An invalid or unaligned stack was encountered during an unwind operation.
773 BAD_STACK = 543,519 BAD_STACK = 543,
774
775 /// An invalid unwind target was encountered during an unwind operation.520 /// An invalid unwind target was encountered during an unwind operation.
776 INVALID_UNWIND_TARGET = 544,521 INVALID_UNWIND_TARGET = 544,
777
778 /// Invalid Object Attributes specified to NtCreatePort or invalid Port Attributes specified to NtConnectPort522 /// Invalid Object Attributes specified to NtCreatePort or invalid Port Attributes specified to NtConnectPort
779 INVALID_PORT_ATTRIBUTES = 545,523 INVALID_PORT_ATTRIBUTES = 545,
780
781 /// Length of message passed to NtRequestPort or NtRequestWaitReplyPort was longer than the maximum message allowed by the port.524 /// Length of message passed to NtRequestPort or NtRequestWaitReplyPort was longer than the maximum message allowed by the port.
782 PORT_MESSAGE_TOO_LONG = 546,525 PORT_MESSAGE_TOO_LONG = 546,
783
784 /// An attempt was made to lower a quota limit below the current usage.526 /// An attempt was made to lower a quota limit below the current usage.
785 INVALID_QUOTA_LOWER = 547,527 INVALID_QUOTA_LOWER = 547,
786
787 /// An attempt was made to attach to a device that was already attached to another device.528 /// An attempt was made to attach to a device that was already attached to another device.
788 DEVICE_ALREADY_ATTACHED = 548,529 DEVICE_ALREADY_ATTACHED = 548,
789
790 /// An attempt was made to execute an instruction at an unaligned address and the host system does not support unaligned instruction references.530 /// An attempt was made to execute an instruction at an unaligned address and the host system does not support unaligned instruction references.
791 INSTRUCTION_MISALIGNMENT = 549,531 INSTRUCTION_MISALIGNMENT = 549,
792
793 /// Profiling not started.532 /// Profiling not started.
794 PROFILING_NOT_STARTED = 550,533 PROFILING_NOT_STARTED = 550,
795
796 /// Profiling not stopped.534 /// Profiling not stopped.
797 PROFILING_NOT_STOPPED = 551,535 PROFILING_NOT_STOPPED = 551,
798
799 /// The passed ACL did not contain the minimum required information.536 /// The passed ACL did not contain the minimum required information.
800 COULD_NOT_INTERPRET = 552,537 COULD_NOT_INTERPRET = 552,
801
802 /// The number of active profiling objects is at the maximum and no more may be started.538 /// The number of active profiling objects is at the maximum and no more may be started.
803 PROFILING_AT_LIMIT = 553,539 PROFILING_AT_LIMIT = 553,
804
805 /// Used to indicate that an operation cannot continue without blocking for I/O.540 /// Used to indicate that an operation cannot continue without blocking for I/O.
806 CANT_WAIT = 554,541 CANT_WAIT = 554,
807
808 /// Indicates that a thread attempted to terminate itself by default (called NtTerminateThread with NULL) and it was the last thread in the current process.542 /// Indicates that a thread attempted to terminate itself by default (called NtTerminateThread with NULL) and it was the last thread in the current process.
809 CANT_TERMINATE_SELF = 555,543 CANT_TERMINATE_SELF = 555,
810
811 /// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter.544 /// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter.
812 /// In this case information is lost, however, the filter correctly handles the exception.545 /// In this case information is lost, however, the filter correctly handles the exception.
813 UNEXPECTED_MM_CREATE_ERR = 556,546 UNEXPECTED_MM_CREATE_ERR = 556,
814
815 /// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter.547 /// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter.
816 /// In this case information is lost, however, the filter correctly handles the exception.548 /// In this case information is lost, however, the filter correctly handles the exception.
817 UNEXPECTED_MM_MAP_ERROR = 557,549 UNEXPECTED_MM_MAP_ERROR = 557,
818
819 /// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter.550 /// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter.
820 /// In this case information is lost, however, the filter correctly handles the exception.551 /// In this case information is lost, however, the filter correctly handles the exception.
821 UNEXPECTED_MM_EXTEND_ERR = 558,552 UNEXPECTED_MM_EXTEND_ERR = 558,
822
823 /// A malformed function table was encountered during an unwind operation.553 /// A malformed function table was encountered during an unwind operation.
824 BAD_FUNCTION_TABLE = 559,554 BAD_FUNCTION_TABLE = 559,
825
826 /// Indicates that an attempt was made to assign protection to a file system file or directory and one of the SIDs in the security descriptor could not be translated into a GUID that could be stored by the file system.555 /// Indicates that an attempt was made to assign protection to a file system file or directory and one of the SIDs in the security descriptor could not be translated into a GUID that could be stored by the file system.
827 /// This causes the protection attempt to fail, which may cause a file creation attempt to fail.556 /// This causes the protection attempt to fail, which may cause a file creation attempt to fail.
828 NO_GUID_TRANSLATION = 560,557 NO_GUID_TRANSLATION = 560,
829
830 /// Indicates that an attempt was made to grow an LDT by setting its size, or that the size was not an even number of selectors.558 /// Indicates that an attempt was made to grow an LDT by setting its size, or that the size was not an even number of selectors.
831 INVALID_LDT_SIZE = 561,559 INVALID_LDT_SIZE = 561,
832
833 /// Indicates that the starting value for the LDT information was not an integral multiple of the selector size.560 /// Indicates that the starting value for the LDT information was not an integral multiple of the selector size.
834 INVALID_LDT_OFFSET = 563,561 INVALID_LDT_OFFSET = 563,
835
836 /// Indicates that the user supplied an invalid descriptor when trying to set up Ldt descriptors.562 /// Indicates that the user supplied an invalid descriptor when trying to set up Ldt descriptors.
837 INVALID_LDT_DESCRIPTOR = 564,563 INVALID_LDT_DESCRIPTOR = 564,
838
839 /// Indicates a process has too many threads to perform the requested action.564 /// Indicates a process has too many threads to perform the requested action.
840 /// For example, assignment of a primary token may only be performed when a process has zero or one threads.565 /// For example, assignment of a primary token may only be performed when a process has zero or one threads.
841 TOO_MANY_THREADS = 565,566 TOO_MANY_THREADS = 565,
842
843 /// An attempt was made to operate on a thread within a specific process, but the thread specified is not in the process specified.567 /// An attempt was made to operate on a thread within a specific process, but the thread specified is not in the process specified.
844 THREAD_NOT_IN_PROCESS = 566,568 THREAD_NOT_IN_PROCESS = 566,
845
846 /// Page file quota was exceeded.569 /// Page file quota was exceeded.
847 PAGEFILE_QUOTA_EXCEEDED = 567,570 PAGEFILE_QUOTA_EXCEEDED = 567,
848
849 /// The Netlogon service cannot start because another Netlogon service running in the domain conflicts with the specified role.571 /// The Netlogon service cannot start because another Netlogon service running in the domain conflicts with the specified role.
850 LOGON_SERVER_CONFLICT = 568,572 LOGON_SERVER_CONFLICT = 568,
851
852 /// The SAM database on a Windows Server is significantly out of synchronization with the copy on the Domain Controller. A complete synchronization is required.573 /// The SAM database on a Windows Server is significantly out of synchronization with the copy on the Domain Controller. A complete synchronization is required.
853 SYNCHRONIZATION_REQUIRED = 569,574 SYNCHRONIZATION_REQUIRED = 569,
854
855 /// The NtCreateFile API failed. This error should never be returned to an application, it is a place holder for the Windows Lan Manager Redirector to use in its internal error mapping routines.575 /// The NtCreateFile API failed. This error should never be returned to an application, it is a place holder for the Windows Lan Manager Redirector to use in its internal error mapping routines.
856 NET_OPEN_FAILED = 570,576 NET_OPEN_FAILED = 570,
857
858 /// {Privilege Failed} The I/O permissions for the process could not be changed.577 /// {Privilege Failed} The I/O permissions for the process could not be changed.
859 IO_PRIVILEGE_FAILED = 571,578 IO_PRIVILEGE_FAILED = 571,
860
861 /// {Application Exit by CTRL+C} The application terminated as a result of a CTRL+C.579 /// {Application Exit by CTRL+C} The application terminated as a result of a CTRL+C.
862 CONTROL_C_EXIT = 572,580 CONTROL_C_EXIT = 572,
863
864 /// {Missing System File} The required system file %hs is bad or missing.581 /// {Missing System File} The required system file %hs is bad or missing.
865 MISSING_SYSTEMFILE = 573,582 MISSING_SYSTEMFILE = 573,
866
867 /// {Application Error} The exception %s (0x%08lx) occurred in the application at location 0x%08lx.583 /// {Application Error} The exception %s (0x%08lx) occurred in the application at location 0x%08lx.
868 UNHANDLED_EXCEPTION = 574,584 UNHANDLED_EXCEPTION = 574,
869
870 /// {Application Error} The application was unable to start correctly (0x%lx). Click OK to close the application.585 /// {Application Error} The application was unable to start correctly (0x%lx). Click OK to close the application.
871 APP_INIT_FAILURE = 575,586 APP_INIT_FAILURE = 575,
872
873 /// {Unable to Create Paging File} The creation of the paging file %hs failed (%lx). The requested size was %ld.587 /// {Unable to Create Paging File} The creation of the paging file %hs failed (%lx). The requested size was %ld.
874 PAGEFILE_CREATE_FAILED = 576,588 PAGEFILE_CREATE_FAILED = 576,
875
876 /// Windows cannot verify the digital signature for this file.589 /// Windows cannot verify the digital signature for this file.
877 /// A recent hardware or software change might have installed a file that is signed incorrectly or damaged, or that might be malicious software from an unknown source.590 /// A recent hardware or software change might have installed a file that is signed incorrectly or damaged, or that might be malicious software from an unknown source.
878 INVALID_IMAGE_HASH = 577,591 INVALID_IMAGE_HASH = 577,
879
880 /// {No Paging File Specified} No paging file was specified in the system configuration.592 /// {No Paging File Specified} No paging file was specified in the system configuration.
881 NO_PAGEFILE = 578,593 NO_PAGEFILE = 578,
882
883 /// {EXCEPTION} A real-mode application issued a floating-point instruction and floating-point hardware is not present.594 /// {EXCEPTION} A real-mode application issued a floating-point instruction and floating-point hardware is not present.
884 ILLEGAL_FLOAT_CONTEXT = 579,595 ILLEGAL_FLOAT_CONTEXT = 579,
885
886 /// An event pair synchronization operation was performed using the thread specific client/server event pair object, but no event pair object was associated with the thread.596 /// An event pair synchronization operation was performed using the thread specific client/server event pair object, but no event pair object was associated with the thread.
887 NO_EVENT_PAIR = 580,597 NO_EVENT_PAIR = 580,
888
889 /// A Windows Server has an incorrect configuration.598 /// A Windows Server has an incorrect configuration.
890 DOMAIN_CTRLR_CONFIG_ERROR = 581,599 DOMAIN_CTRLR_CONFIG_ERROR = 581,
891
892 /// An illegal character was encountered.600 /// An illegal character was encountered.
893 /// For a multi-byte character set this includes a lead byte without a succeeding trail byte.601 /// For a multi-byte character set this includes a lead byte without a succeeding trail byte.
894 /// For the Unicode character set this includes the characters 0xFFFF and 0xFFFE.602 /// For the Unicode character set this includes the characters 0xFFFF and 0xFFFE.
895 ILLEGAL_CHARACTER = 582,603 ILLEGAL_CHARACTER = 582,
896
897 /// The Unicode character is not defined in the Unicode character set installed on the system.604 /// The Unicode character is not defined in the Unicode character set installed on the system.
898 UNDEFINED_CHARACTER = 583,605 UNDEFINED_CHARACTER = 583,
899
900 /// The paging file cannot be created on a floppy diskette.606 /// The paging file cannot be created on a floppy diskette.
901 FLOPPY_VOLUME = 584,607 FLOPPY_VOLUME = 584,
902
903 /// The system BIOS failed to connect a system interrupt to the device or bus for which the device is connected.608 /// The system BIOS failed to connect a system interrupt to the device or bus for which the device is connected.
904 BIOS_FAILED_TO_CONNECT_INTERRUPT = 585,609 BIOS_FAILED_TO_CONNECT_INTERRUPT = 585,
905
906 /// This operation is only allowed for the Primary Domain Controller of the domain.610 /// This operation is only allowed for the Primary Domain Controller of the domain.
907 BACKUP_CONTROLLER = 586,611 BACKUP_CONTROLLER = 586,
908
909 /// An attempt was made to acquire a mutant such that its maximum count would have been exceeded.612 /// An attempt was made to acquire a mutant such that its maximum count would have been exceeded.
910 MUTANT_LIMIT_EXCEEDED = 587,613 MUTANT_LIMIT_EXCEEDED = 587,
911
912 /// A volume has been accessed for which a file system driver is required that has not yet been loaded.614 /// A volume has been accessed for which a file system driver is required that has not yet been loaded.
913 FS_DRIVER_REQUIRED = 588,615 FS_DRIVER_REQUIRED = 588,
914
915 /// {Registry File Failure} The registry cannot load the hive (file): %hs or its log or alternate. It is corrupt, absent, or not writable.616 /// {Registry File Failure} The registry cannot load the hive (file): %hs or its log or alternate. It is corrupt, absent, or not writable.
916 CANNOT_LOAD_REGISTRY_FILE = 589,617 CANNOT_LOAD_REGISTRY_FILE = 589,
917
918 /// {Unexpected Failure in DebugActiveProcess} An unexpected failure occurred while processing a DebugActiveProcess API request.618 /// {Unexpected Failure in DebugActiveProcess} An unexpected failure occurred while processing a DebugActiveProcess API request.
919 /// You may choose OK to terminate the process, or Cancel to ignore the error.619 /// You may choose OK to terminate the process, or Cancel to ignore the error.
920 DEBUG_ATTACH_FAILED = 590,620 DEBUG_ATTACH_FAILED = 590,
921
922 /// {Fatal System Error} The %hs system process terminated unexpectedly with a status of 0x%08x (0x%08x 0x%08x). The system has been shut down.621 /// {Fatal System Error} The %hs system process terminated unexpectedly with a status of 0x%08x (0x%08x 0x%08x). The system has been shut down.
923 SYSTEM_PROCESS_TERMINATED = 591,622 SYSTEM_PROCESS_TERMINATED = 591,
924
925 /// {Data Not Accepted} The TDI client could not handle the data received during an indication.623 /// {Data Not Accepted} The TDI client could not handle the data received during an indication.
926 DATA_NOT_ACCEPTED = 592,624 DATA_NOT_ACCEPTED = 592,
927
928 /// NTVDM encountered a hard error.625 /// NTVDM encountered a hard error.
929 VDM_HARD_ERROR = 593,626 VDM_HARD_ERROR = 593,
930
931 /// {Cancel Timeout} The driver %hs failed to complete a cancelled I/O request in the allotted time.627 /// {Cancel Timeout} The driver %hs failed to complete a cancelled I/O request in the allotted time.
932 DRIVER_CANCEL_TIMEOUT = 594,628 DRIVER_CANCEL_TIMEOUT = 594,
933
934 /// {Reply Message Mismatch} An attempt was made to reply to an LPC message, but the thread specified by the client ID in the message was not waiting on that message.629 /// {Reply Message Mismatch} An attempt was made to reply to an LPC message, but the thread specified by the client ID in the message was not waiting on that message.
935 REPLY_MESSAGE_MISMATCH = 595,630 REPLY_MESSAGE_MISMATCH = 595,
936
937 /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs. The data has been lost.631 /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs. The data has been lost.
938 /// This error may be caused by a failure of your computer hardware or network connection. Please try to save this file elsewhere.632 /// This error may be caused by a failure of your computer hardware or network connection. Please try to save this file elsewhere.
939 LOST_WRITEBEHIND_DATA = 596,633 LOST_WRITEBEHIND_DATA = 596,
940
941 /// The parameter(s) passed to the server in the client/server shared memory window were invalid.634 /// The parameter(s) passed to the server in the client/server shared memory window were invalid.
942 /// Too much data may have been put in the shared memory window.635 /// Too much data may have been put in the shared memory window.
943 CLIENT_SERVER_PARAMETERS_INVALID = 597,636 CLIENT_SERVER_PARAMETERS_INVALID = 597,
944
945 /// The stream is not a tiny stream.637 /// The stream is not a tiny stream.
946 NOT_TINY_STREAM = 598,638 NOT_TINY_STREAM = 598,
947
948 /// The request must be handled by the stack overflow code.639 /// The request must be handled by the stack overflow code.
949 STACK_OVERFLOW_READ = 599,640 STACK_OVERFLOW_READ = 599,
950
951 /// Internal OFS status codes indicating how an allocation operation is handled.641 /// Internal OFS status codes indicating how an allocation operation is handled.
952 /// Either it is retried after the containing onode is moved or the extent stream is converted to a large stream.642 /// Either it is retried after the containing onode is moved or the extent stream is converted to a large stream.
953 CONVERT_TO_LARGE = 600,643 CONVERT_TO_LARGE = 600,
954
955 /// The attempt to find the object found an object matching by ID on the volume but it is out of the scope of the handle used for the operation.644 /// The attempt to find the object found an object matching by ID on the volume but it is out of the scope of the handle used for the operation.
956 FOUND_OUT_OF_SCOPE = 601,645 FOUND_OUT_OF_SCOPE = 601,
957
958 /// The bucket array must be grown. Retry transaction after doing so.646 /// The bucket array must be grown. Retry transaction after doing so.
959 ALLOCATE_BUCKET = 602,647 ALLOCATE_BUCKET = 602,
960
961 /// The user/kernel marshalling buffer has overflowed.648 /// The user/kernel marshalling buffer has overflowed.
962 MARSHALL_OVERFLOW = 603,649 MARSHALL_OVERFLOW = 603,
963
964 /// The supplied variant structure contains invalid data.650 /// The supplied variant structure contains invalid data.
965 INVALID_VARIANT = 604,651 INVALID_VARIANT = 604,
966
967 /// The specified buffer contains ill-formed data.652 /// The specified buffer contains ill-formed data.
968 BAD_COMPRESSION_BUFFER = 605,653 BAD_COMPRESSION_BUFFER = 605,
969
970 /// {Audit Failed} An attempt to generate a security audit failed.654 /// {Audit Failed} An attempt to generate a security audit failed.
971 AUDIT_FAILED = 606,655 AUDIT_FAILED = 606,
972
973 /// The timer resolution was not previously set by the current process.656 /// The timer resolution was not previously set by the current process.
974 TIMER_RESOLUTION_NOT_SET = 607,657 TIMER_RESOLUTION_NOT_SET = 607,
975
976 /// There is insufficient account information to log you on.658 /// There is insufficient account information to log you on.
977 INSUFFICIENT_LOGON_INFO = 608,659 INSUFFICIENT_LOGON_INFO = 608,
978
979 /// {Invalid DLL Entrypoint} The dynamic link library %hs is not written correctly.660 /// {Invalid DLL Entrypoint} The dynamic link library %hs is not written correctly.
980 /// The stack pointer has been left in an inconsistent state.661 /// The stack pointer has been left in an inconsistent state.
981 /// The entrypoint should be declared as WINAPI or STDCALL.662 /// The entrypoint should be declared as WINAPI or STDCALL.
982 /// Select YES to fail the DLL load. Select NO to continue execution.663 /// Select YES to fail the DLL load. Select NO to continue execution.
983 /// Selecting NO may cause the application to operate incorrectly.664 /// Selecting NO may cause the application to operate incorrectly.
984 BAD_DLL_ENTRYPOINT = 609,665 BAD_DLL_ENTRYPOINT = 609,
985
986 /// {Invalid Service Callback Entrypoint} The %hs service is not written correctly.666 /// {Invalid Service Callback Entrypoint} The %hs service is not written correctly.
987 /// The stack pointer has been left in an inconsistent state.667 /// The stack pointer has been left in an inconsistent state.
988 /// The callback entrypoint should be declared as WINAPI or STDCALL.668 /// The callback entrypoint should be declared as WINAPI or STDCALL.
989 /// Selecting OK will cause the service to continue operation.669 /// Selecting OK will cause the service to continue operation.
990 /// However, the service process may operate incorrectly.670 /// However, the service process may operate incorrectly.
991 BAD_SERVICE_ENTRYPOINT = 610,671 BAD_SERVICE_ENTRYPOINT = 610,
992
993 /// There is an IP address conflict with another system on the network.672 /// There is an IP address conflict with another system on the network.
994 IP_ADDRESS_CONFLICT1 = 611,673 IP_ADDRESS_CONFLICT1 = 611,
995
996 /// There is an IP address conflict with another system on the network.674 /// There is an IP address conflict with another system on the network.
997 IP_ADDRESS_CONFLICT2 = 612,675 IP_ADDRESS_CONFLICT2 = 612,
998
999 /// {Low On Registry Space} The system has reached the maximum size allowed for the system part of the registry. Additional storage requests will be ignored.676 /// {Low On Registry Space} The system has reached the maximum size allowed for the system part of the registry. Additional storage requests will be ignored.
1000 REGISTRY_QUOTA_LIMIT = 613,677 REGISTRY_QUOTA_LIMIT = 613,
1001
1002 /// A callback return system service cannot be executed when no callback is active.678 /// A callback return system service cannot be executed when no callback is active.
1003 NO_CALLBACK_ACTIVE = 614,679 NO_CALLBACK_ACTIVE = 614,
1004
1005 /// The password provided is too short to meet the policy of your user account. Please choose a longer password.680 /// The password provided is too short to meet the policy of your user account. Please choose a longer password.
1006 PWD_TOO_SHORT = 615,681 PWD_TOO_SHORT = 615,
1007
1008 /// The policy of your user account does not allow you to change passwords too frequently.682 /// The policy of your user account does not allow you to change passwords too frequently.
1009 /// This is done to prevent users from changing back to a familiar, but potentially discovered, password.683 /// This is done to prevent users from changing back to a familiar, but potentially discovered, password.
1010 /// If you feel your password has been compromised then please contact your administrator immediately to have a new one assigned.684 /// If you feel your password has been compromised then please contact your administrator immediately to have a new one assigned.
1011 PWD_TOO_RECENT = 616,685 PWD_TOO_RECENT = 616,
1012
1013 /// You have attempted to change your password to one that you have used in the past.686 /// You have attempted to change your password to one that you have used in the past.
1014 /// The policy of your user account does not allow this.687 /// The policy of your user account does not allow this.
1015 /// Please select a password that you have not previously used.688 /// Please select a password that you have not previously used.
1016 PWD_HISTORY_CONFLICT = 617,689 PWD_HISTORY_CONFLICT = 617,
1017
1018 /// The specified compression format is unsupported.690 /// The specified compression format is unsupported.
1019 UNSUPPORTED_COMPRESSION = 618,691 UNSUPPORTED_COMPRESSION = 618,
1020
1021 /// The specified hardware profile configuration is invalid.692 /// The specified hardware profile configuration is invalid.
1022 INVALID_HW_PROFILE = 619,693 INVALID_HW_PROFILE = 619,
1023
1024 /// The specified Plug and Play registry device path is invalid.694 /// The specified Plug and Play registry device path is invalid.
1025 INVALID_PLUGPLAY_DEVICE_PATH = 620,695 INVALID_PLUGPLAY_DEVICE_PATH = 620,
1026
1027 /// The specified quota list is internally inconsistent with its descriptor.696 /// The specified quota list is internally inconsistent with its descriptor.
1028 QUOTA_LIST_INCONSISTENT = 621,697 QUOTA_LIST_INCONSISTENT = 621,
1029
1030 /// {Windows Evaluation Notification} The evaluation period for this installation of Windows has expired. This system will shutdown in 1 hour.698 /// {Windows Evaluation Notification} The evaluation period for this installation of Windows has expired. This system will shutdown in 1 hour.
1031 /// To restore access to this installation of Windows, please upgrade this installation using a licensed distribution of this product.699 /// To restore access to this installation of Windows, please upgrade this installation using a licensed distribution of this product.
1032 EVALUATION_EXPIRATION = 622,700 EVALUATION_EXPIRATION = 622,
1033
1034 /// {Illegal System DLL Relocation} The system DLL %hs was relocated in memory. The application will not run properly.701 /// {Illegal System DLL Relocation} The system DLL %hs was relocated in memory. The application will not run properly.
1035 /// The relocation occurred because the DLL %hs occupied an address range reserved for Windows system DLLs.702 /// The relocation occurred because the DLL %hs occupied an address range reserved for Windows system DLLs.
1036 /// The vendor supplying the DLL should be contacted for a new DLL.703 /// The vendor supplying the DLL should be contacted for a new DLL.
1037 ILLEGAL_DLL_RELOCATION = 623,704 ILLEGAL_DLL_RELOCATION = 623,
1038
1039 /// {DLL Initialization Failed} The application failed to initialize because the window station is shutting down.705 /// {DLL Initialization Failed} The application failed to initialize because the window station is shutting down.
1040 DLL_INIT_FAILED_LOGOFF = 624,706 DLL_INIT_FAILED_LOGOFF = 624,
1041
1042 /// The validation process needs to continue on to the next step.707 /// The validation process needs to continue on to the next step.
1043 VALIDATE_CONTINUE = 625,708 VALIDATE_CONTINUE = 625,
1044
1045 /// There are no more matches for the current index enumeration.709 /// There are no more matches for the current index enumeration.
1046 NO_MORE_MATCHES = 626,710 NO_MORE_MATCHES = 626,
1047
1048 /// The range could not be added to the range list because of a conflict.711 /// The range could not be added to the range list because of a conflict.
1049 RANGE_LIST_CONFLICT = 627,712 RANGE_LIST_CONFLICT = 627,
1050
1051 /// The server process is running under a SID different than that required by client.713 /// The server process is running under a SID different than that required by client.
1052 SERVER_SID_MISMATCH = 628,714 SERVER_SID_MISMATCH = 628,
1053
1054 /// A group marked use for deny only cannot be enabled.715 /// A group marked use for deny only cannot be enabled.
1055 CANT_ENABLE_DENY_ONLY = 629,716 CANT_ENABLE_DENY_ONLY = 629,
1056
1057 /// {EXCEPTION} Multiple floating point faults.717 /// {EXCEPTION} Multiple floating point faults.
1058 FLOAT_MULTIPLE_FAULTS = 630,718 FLOAT_MULTIPLE_FAULTS = 630,
1059
1060 /// {EXCEPTION} Multiple floating point traps.719 /// {EXCEPTION} Multiple floating point traps.
1061 FLOAT_MULTIPLE_TRAPS = 631,720 FLOAT_MULTIPLE_TRAPS = 631,
1062
1063 /// The requested interface is not supported.721 /// The requested interface is not supported.
1064 NOINTERFACE = 632,722 NOINTERFACE = 632,
1065
1066 /// {System Standby Failed} The driver %hs does not support standby mode.723 /// {System Standby Failed} The driver %hs does not support standby mode.
1067 /// Updating this driver may allow the system to go to standby mode.724 /// Updating this driver may allow the system to go to standby mode.
1068 DRIVER_FAILED_SLEEP = 633,725 DRIVER_FAILED_SLEEP = 633,
1069
1070 /// The system file %1 has become corrupt and has been replaced.726 /// The system file %1 has become corrupt and has been replaced.
1071 CORRUPT_SYSTEM_FILE = 634,727 CORRUPT_SYSTEM_FILE = 634,
1072
1073 /// {Virtual Memory Minimum Too Low} Your system is low on virtual memory.728 /// {Virtual Memory Minimum Too Low} Your system is low on virtual memory.
1074 /// Windows is increasing the size of your virtual memory paging file.729 /// Windows is increasing the size of your virtual memory paging file.
1075 /// During this process, memory requests for some applications may be denied. For more information, see Help.730 /// During this process, memory requests for some applications may be denied. For more information, see Help.
1076 COMMITMENT_MINIMUM = 635,731 COMMITMENT_MINIMUM = 635,
1077
1078 /// A device was removed so enumeration must be restarted.732 /// A device was removed so enumeration must be restarted.
1079 PNP_RESTART_ENUMERATION = 636,733 PNP_RESTART_ENUMERATION = 636,
1080
1081 /// {Fatal System Error} The system image %s is not properly signed.734 /// {Fatal System Error} The system image %s is not properly signed.
1082 /// The file has been replaced with the signed file. The system has been shut down.735 /// The file has been replaced with the signed file. The system has been shut down.
1083 SYSTEM_IMAGE_BAD_SIGNATURE = 637,736 SYSTEM_IMAGE_BAD_SIGNATURE = 637,
1084
1085 /// Device will not start without a reboot.737 /// Device will not start without a reboot.
1086 PNP_REBOOT_REQUIRED = 638,738 PNP_REBOOT_REQUIRED = 638,
1087
1088 /// There is not enough power to complete the requested operation.739 /// There is not enough power to complete the requested operation.
1089 INSUFFICIENT_POWER = 639,740 INSUFFICIENT_POWER = 639,
1090
1091 /// ERROR_MULTIPLE_FAULT_VIOLATION741 /// ERROR_MULTIPLE_FAULT_VIOLATION
1092 MULTIPLE_FAULT_VIOLATION = 640,742 MULTIPLE_FAULT_VIOLATION = 640,
1093
1094 /// The system is in the process of shutting down.743 /// The system is in the process of shutting down.
1095 SYSTEM_SHUTDOWN = 641,744 SYSTEM_SHUTDOWN = 641,
1096
1097 /// An attempt to remove a processes DebugPort was made, but a port was not already associated with the process.745 /// An attempt to remove a processes DebugPort was made, but a port was not already associated with the process.
1098 PORT_NOT_SET = 642,746 PORT_NOT_SET = 642,
1099
1100 /// This version of Windows is not compatible with the behavior version of directory forest, domain or domain controller.747 /// This version of Windows is not compatible with the behavior version of directory forest, domain or domain controller.
1101 DS_VERSION_CHECK_FAILURE = 643,748 DS_VERSION_CHECK_FAILURE = 643,
1102
1103 /// The specified range could not be found in the range list.749 /// The specified range could not be found in the range list.
1104 RANGE_NOT_FOUND = 644,750 RANGE_NOT_FOUND = 644,
1105
1106 /// The driver was not loaded because the system is booting into safe mode.751 /// The driver was not loaded because the system is booting into safe mode.
1107 NOT_SAFE_MODE_DRIVER = 646,752 NOT_SAFE_MODE_DRIVER = 646,
1108
1109 /// The driver was not loaded because it failed its initialization call.753 /// The driver was not loaded because it failed its initialization call.
1110 FAILED_DRIVER_ENTRY = 647,754 FAILED_DRIVER_ENTRY = 647,
1111
1112 /// The "%hs" encountered an error while applying power or reading the device configuration.755 /// The "%hs" encountered an error while applying power or reading the device configuration.
1113 /// This may be caused by a failure of your hardware or by a poor connection.756 /// This may be caused by a failure of your hardware or by a poor connection.
1114 DEVICE_ENUMERATION_ERROR = 648,757 DEVICE_ENUMERATION_ERROR = 648,
1115
1116 /// The create operation failed because the name contained at least one mount point which resolves to a volume to which the specified device object is not attached.758 /// The create operation failed because the name contained at least one mount point which resolves to a volume to which the specified device object is not attached.
1117 MOUNT_POINT_NOT_RESOLVED = 649,759 MOUNT_POINT_NOT_RESOLVED = 649,
1118
1119 /// The device object parameter is either not a valid device object or is not attached to the volume specified by the file name.760 /// The device object parameter is either not a valid device object or is not attached to the volume specified by the file name.
1120 INVALID_DEVICE_OBJECT_PARAMETER = 650,761 INVALID_DEVICE_OBJECT_PARAMETER = 650,
1121
1122 /// A Machine Check Error has occurred.762 /// A Machine Check Error has occurred.
1123 /// Please check the system eventlog for additional information.763 /// Please check the system eventlog for additional information.
1124 MCA_OCCURED = 651,764 MCA_OCCURED = 651,
1125
1126 /// There was error [%2] processing the driver database.765 /// There was error [%2] processing the driver database.
1127 DRIVER_DATABASE_ERROR = 652,766 DRIVER_DATABASE_ERROR = 652,
1128
1129 /// System hive size has exceeded its limit.767 /// System hive size has exceeded its limit.
1130 SYSTEM_HIVE_TOO_LARGE = 653,768 SYSTEM_HIVE_TOO_LARGE = 653,
1131
1132 /// The driver could not be loaded because a previous version of the driver is still in memory.769 /// The driver could not be loaded because a previous version of the driver is still in memory.
1133 DRIVER_FAILED_PRIOR_UNLOAD = 654,770 DRIVER_FAILED_PRIOR_UNLOAD = 654,
1134
1135 /// {Volume Shadow Copy Service} Please wait while the Volume Shadow Copy Service prepares volume %hs for hibernation.771 /// {Volume Shadow Copy Service} Please wait while the Volume Shadow Copy Service prepares volume %hs for hibernation.
1136 VOLSNAP_PREPARE_HIBERNATE = 655,772 VOLSNAP_PREPARE_HIBERNATE = 655,
1137
1138 /// The system has failed to hibernate (The error code is %hs).773 /// The system has failed to hibernate (The error code is %hs).
1139 /// Hibernation will be disabled until the system is restarted.774 /// Hibernation will be disabled until the system is restarted.
1140 HIBERNATION_FAILURE = 656,775 HIBERNATION_FAILURE = 656,
1141
1142 /// The password provided is too long to meet the policy of your user account. Please choose a shorter password.776 /// The password provided is too long to meet the policy of your user account. Please choose a shorter password.
1143 PWD_TOO_LONG = 657,777 PWD_TOO_LONG = 657,
1144
1145 /// The requested operation could not be completed due to a file system limitation.778 /// The requested operation could not be completed due to a file system limitation.
1146 FILE_SYSTEM_LIMITATION = 665,779 FILE_SYSTEM_LIMITATION = 665,
1147
1148 /// An assertion failure has occurred.780 /// An assertion failure has occurred.
1149 ASSERTION_FAILURE = 668,781 ASSERTION_FAILURE = 668,
1150
1151 /// An error occurred in the ACPI subsystem.782 /// An error occurred in the ACPI subsystem.
1152 ACPI_ERROR = 669,783 ACPI_ERROR = 669,
1153
1154 /// WOW Assertion Error.784 /// WOW Assertion Error.
1155 WOW_ASSERTION = 670,785 WOW_ASSERTION = 670,
1156
1157 /// A device is missing in the system BIOS MPS table. This device will not be used.786 /// A device is missing in the system BIOS MPS table. This device will not be used.
1158 /// Please contact your system vendor for system BIOS update.787 /// Please contact your system vendor for system BIOS update.
1159 PNP_BAD_MPS_TABLE = 671,788 PNP_BAD_MPS_TABLE = 671,
1160
1161 /// A translator failed to translate resources.789 /// A translator failed to translate resources.
1162 PNP_TRANSLATION_FAILED = 672,790 PNP_TRANSLATION_FAILED = 672,
1163
1164 /// A IRQ translator failed to translate resources.791 /// A IRQ translator failed to translate resources.
1165 PNP_IRQ_TRANSLATION_FAILED = 673,792 PNP_IRQ_TRANSLATION_FAILED = 673,
1166
1167 /// Driver %2 returned invalid ID for a child device (%3).793 /// Driver %2 returned invalid ID for a child device (%3).
1168 PNP_INVALID_ID = 674,794 PNP_INVALID_ID = 674,
1169
1170 /// {Kernel Debugger Awakened} the system debugger was awakened by an interrupt.795 /// {Kernel Debugger Awakened} the system debugger was awakened by an interrupt.
1171 WAKE_SYSTEM_DEBUGGER = 675,796 WAKE_SYSTEM_DEBUGGER = 675,
1172
1173 /// {Handles Closed} Handles to objects have been automatically closed as a result of the requested operation.797 /// {Handles Closed} Handles to objects have been automatically closed as a result of the requested operation.
1174 HANDLES_CLOSED = 676,798 HANDLES_CLOSED = 676,
1175
1176 /// {Too Much Information} The specified access control list (ACL) contained more information than was expected.799 /// {Too Much Information} The specified access control list (ACL) contained more information than was expected.
1177 EXTRANEOUS_INFORMATION = 677,800 EXTRANEOUS_INFORMATION = 677,
1178
1179 /// This warning level status indicates that the transaction state already exists for the registry sub-tree, but that a transaction commit was previously aborted.801 /// This warning level status indicates that the transaction state already exists for the registry sub-tree, but that a transaction commit was previously aborted.
1180 /// The commit has NOT been completed, but has not been rolled back either (so it may still be committed if desired).802 /// The commit has NOT been completed, but has not been rolled back either (so it may still be committed if desired).
1181 RXACT_COMMIT_NECESSARY = 678,803 RXACT_COMMIT_NECESSARY = 678,
1182
1183 /// {Media Changed} The media may have changed.804 /// {Media Changed} The media may have changed.
1184 MEDIA_CHECK = 679,805 MEDIA_CHECK = 679,
1185
1186 /// {GUID Substitution} During the translation of a global identifier (GUID) to a Windows security ID (SID), no administratively-defined GUID prefix was found.806 /// {GUID Substitution} During the translation of a global identifier (GUID) to a Windows security ID (SID), no administratively-defined GUID prefix was found.
1187 /// A substitute prefix was used, which will not compromise system security.807 /// A substitute prefix was used, which will not compromise system security.
1188 /// However, this may provide a more restrictive access than intended.808 /// However, this may provide a more restrictive access than intended.
1189 GUID_SUBSTITUTION_MADE = 680,809 GUID_SUBSTITUTION_MADE = 680,
1190
1191 /// The create operation stopped after reaching a symbolic link.810 /// The create operation stopped after reaching a symbolic link.
1192 STOPPED_ON_SYMLINK = 681,811 STOPPED_ON_SYMLINK = 681,
1193
1194 /// A long jump has been executed.812 /// A long jump has been executed.
1195 LONGJUMP = 682,813 LONGJUMP = 682,
1196
1197 /// The Plug and Play query operation was not successful.814 /// The Plug and Play query operation was not successful.
1198 PLUGPLAY_QUERY_VETOED = 683,815 PLUGPLAY_QUERY_VETOED = 683,
1199
1200 /// A frame consolidation has been executed.816 /// A frame consolidation has been executed.
1201 UNWIND_CONSOLIDATE = 684,817 UNWIND_CONSOLIDATE = 684,
1202
1203 /// {Registry Hive Recovered} Registry hive (file): %hs was corrupted and it has been recovered. Some data might have been lost.818 /// {Registry Hive Recovered} Registry hive (file): %hs was corrupted and it has been recovered. Some data might have been lost.
1204 REGISTRY_HIVE_RECOVERED = 685,819 REGISTRY_HIVE_RECOVERED = 685,
1205
1206 /// The application is attempting to run executable code from the module %hs. This may be insecure.820 /// The application is attempting to run executable code from the module %hs. This may be insecure.
1207 /// An alternative, %hs, is available. Should the application use the secure module %hs?821 /// An alternative, %hs, is available. Should the application use the secure module %hs?
1208 DLL_MIGHT_BE_INSECURE = 686,822 DLL_MIGHT_BE_INSECURE = 686,
1209
1210 /// The application is loading executable code from the module %hs.823 /// The application is loading executable code from the module %hs.
1211 /// This is secure, but may be incompatible with previous releases of the operating system.824 /// This is secure, but may be incompatible with previous releases of the operating system.
1212 /// An alternative, %hs, is available. Should the application use the secure module %hs?825 /// An alternative, %hs, is available. Should the application use the secure module %hs?
1213 DLL_MIGHT_BE_INCOMPATIBLE = 687,826 DLL_MIGHT_BE_INCOMPATIBLE = 687,
1214
1215 /// Debugger did not handle the exception.827 /// Debugger did not handle the exception.
1216 DBG_EXCEPTION_NOT_HANDLED = 688,828 DBG_EXCEPTION_NOT_HANDLED = 688,
1217
1218 /// Debugger will reply later.829 /// Debugger will reply later.
1219 DBG_REPLY_LATER = 689,830 DBG_REPLY_LATER = 689,
1220
1221 /// Debugger cannot provide handle.831 /// Debugger cannot provide handle.
1222 DBG_UNABLE_TO_PROVIDE_HANDLE = 690,832 DBG_UNABLE_TO_PROVIDE_HANDLE = 690,
1223
1224 /// Debugger terminated thread.833 /// Debugger terminated thread.
1225 DBG_TERMINATE_THREAD = 691,834 DBG_TERMINATE_THREAD = 691,
1226
1227 /// Debugger terminated process.835 /// Debugger terminated process.
1228 DBG_TERMINATE_PROCESS = 692,836 DBG_TERMINATE_PROCESS = 692,
1229
1230 /// Debugger got control C.837 /// Debugger got control C.
1231 DBG_CONTROL_C = 693,838 DBG_CONTROL_C = 693,
1232
1233 /// Debugger printed exception on control C.839 /// Debugger printed exception on control C.
1234 DBG_PRINTEXCEPTION_C = 694,840 DBG_PRINTEXCEPTION_C = 694,
1235
1236 /// Debugger received RIP exception.841 /// Debugger received RIP exception.
1237 DBG_RIPEXCEPTION = 695,842 DBG_RIPEXCEPTION = 695,
1238
1239 /// Debugger received control break.843 /// Debugger received control break.
1240 DBG_CONTROL_BREAK = 696,844 DBG_CONTROL_BREAK = 696,
1241
1242 /// Debugger command communication exception.845 /// Debugger command communication exception.
1243 DBG_COMMAND_EXCEPTION = 697,846 DBG_COMMAND_EXCEPTION = 697,
1244
1245 /// {Object Exists} An attempt was made to create an object and the object name already existed.847 /// {Object Exists} An attempt was made to create an object and the object name already existed.
1246 OBJECT_NAME_EXISTS = 698,848 OBJECT_NAME_EXISTS = 698,
1247
1248 /// {Thread Suspended} A thread termination occurred while the thread was suspended.849 /// {Thread Suspended} A thread termination occurred while the thread was suspended.
1249 /// The thread was resumed, and termination proceeded.850 /// The thread was resumed, and termination proceeded.
1250 THREAD_WAS_SUSPENDED = 699,851 THREAD_WAS_SUSPENDED = 699,
1251
1252 /// {Image Relocated} An image file could not be mapped at the address specified in the image file. Local fixups must be performed on this image.852 /// {Image Relocated} An image file could not be mapped at the address specified in the image file. Local fixups must be performed on this image.
1253 IMAGE_NOT_AT_BASE = 700,853 IMAGE_NOT_AT_BASE = 700,
1254
1255 /// This informational level status indicates that a specified registry sub-tree transaction state did not yet exist and had to be created.854 /// This informational level status indicates that a specified registry sub-tree transaction state did not yet exist and had to be created.
1256 RXACT_STATE_CREATED = 701,855 RXACT_STATE_CREATED = 701,
1257
1258 /// {Segment Load} A virtual DOS machine (VDM) is loading, unloading, or moving an MS-DOS or Win16 program segment image.856 /// {Segment Load} A virtual DOS machine (VDM) is loading, unloading, or moving an MS-DOS or Win16 program segment image.
1259 /// An exception is raised so a debugger can load, unload or track symbols and breakpoints within these 16-bit segments.857 /// An exception is raised so a debugger can load, unload or track symbols and breakpoints within these 16-bit segments.
1260 SEGMENT_NOTIFICATION = 702,858 SEGMENT_NOTIFICATION = 702,
1261
1262 /// {Invalid Current Directory} The process cannot switch to the startup current directory %hs.859 /// {Invalid Current Directory} The process cannot switch to the startup current directory %hs.
1263 /// Select OK to set current directory to %hs, or select CANCEL to exit.860 /// Select OK to set current directory to %hs, or select CANCEL to exit.
1264 BAD_CURRENT_DIRECTORY = 703,861 BAD_CURRENT_DIRECTORY = 703,
1265
1266 /// {Redundant Read} To satisfy a read request, the NT fault-tolerant file system successfully read the requested data from a redundant copy.862 /// {Redundant Read} To satisfy a read request, the NT fault-tolerant file system successfully read the requested data from a redundant copy.
1267 /// This was done because the file system encountered a failure on a member of the fault-tolerant volume, but was unable to reassign the failing area of the device.863 /// This was done because the file system encountered a failure on a member of the fault-tolerant volume, but was unable to reassign the failing area of the device.
1268 FT_READ_RECOVERY_FROM_BACKUP = 704,864 FT_READ_RECOVERY_FROM_BACKUP = 704,
1269
1270 /// {Redundant Write} To satisfy a write request, the NT fault-tolerant file system successfully wrote a redundant copy of the information.865 /// {Redundant Write} To satisfy a write request, the NT fault-tolerant file system successfully wrote a redundant copy of the information.
1271 /// This was done because the file system encountered a failure on a member of the fault-tolerant volume, but was not able to reassign the failing area of the device.866 /// This was done because the file system encountered a failure on a member of the fault-tolerant volume, but was not able to reassign the failing area of the device.
1272 FT_WRITE_RECOVERY = 705,867 FT_WRITE_RECOVERY = 705,
1273
1274 /// {Machine Type Mismatch} The image file %hs is valid, but is for a machine type other than the current machine.868 /// {Machine Type Mismatch} The image file %hs is valid, but is for a machine type other than the current machine.
1275 /// Select OK to continue, or CANCEL to fail the DLL load.869 /// Select OK to continue, or CANCEL to fail the DLL load.
1276 IMAGE_MACHINE_TYPE_MISMATCH = 706,870 IMAGE_MACHINE_TYPE_MISMATCH = 706,
1277
1278 /// {Partial Data Received} The network transport returned partial data to its client. The remaining data will be sent later.871 /// {Partial Data Received} The network transport returned partial data to its client. The remaining data will be sent later.
1279 RECEIVE_PARTIAL = 707,872 RECEIVE_PARTIAL = 707,
1280
1281 /// {Expedited Data Received} The network transport returned data to its client that was marked as expedited by the remote system.873 /// {Expedited Data Received} The network transport returned data to its client that was marked as expedited by the remote system.
1282 RECEIVE_EXPEDITED = 708,874 RECEIVE_EXPEDITED = 708,
1283
1284 /// {Partial Expedited Data Received} The network transport returned partial data to its client and this data was marked as expedited by the remote system. The remaining data will be sent later.875 /// {Partial Expedited Data Received} The network transport returned partial data to its client and this data was marked as expedited by the remote system. The remaining data will be sent later.
1285 RECEIVE_PARTIAL_EXPEDITED = 709,876 RECEIVE_PARTIAL_EXPEDITED = 709,
1286
1287 /// {TDI Event Done} The TDI indication has completed successfully.877 /// {TDI Event Done} The TDI indication has completed successfully.
1288 EVENT_DONE = 710,878 EVENT_DONE = 710,
1289
1290 /// {TDI Event Pending} The TDI indication has entered the pending state.879 /// {TDI Event Pending} The TDI indication has entered the pending state.
1291 EVENT_PENDING = 711,880 EVENT_PENDING = 711,
1292
1293 /// Checking file system on %wZ.881 /// Checking file system on %wZ.
1294 CHECKING_FILE_SYSTEM = 712,882 CHECKING_FILE_SYSTEM = 712,
1295
1296 /// {Fatal Application Exit} %hs.883 /// {Fatal Application Exit} %hs.
1297 FATAL_APP_EXIT = 713,884 FATAL_APP_EXIT = 713,
1298
1299 /// The specified registry key is referenced by a predefined handle.885 /// The specified registry key is referenced by a predefined handle.
1300 PREDEFINED_HANDLE = 714,886 PREDEFINED_HANDLE = 714,
1301
1302 /// {Page Unlocked} The page protection of a locked page was changed to 'No Access' and the page was unlocked from memory and from the process.887 /// {Page Unlocked} The page protection of a locked page was changed to 'No Access' and the page was unlocked from memory and from the process.
1303 WAS_UNLOCKED = 715,888 WAS_UNLOCKED = 715,
1304
1305 /// %hs889 /// %hs
1306 SERVICE_NOTIFICATION = 716,890 SERVICE_NOTIFICATION = 716,
1307
1308 /// {Page Locked} One of the pages to lock was already locked.891 /// {Page Locked} One of the pages to lock was already locked.
1309 WAS_LOCKED = 717,892 WAS_LOCKED = 717,
1310
1311 /// Application popup: %1 : %2893 /// Application popup: %1 : %2
1312 LOG_HARD_ERROR = 718,894 LOG_HARD_ERROR = 718,
1313
1314 /// ERROR_ALREADY_WIN32895 /// ERROR_ALREADY_WIN32
1315 ALREADY_WIN32 = 719,896 ALREADY_WIN32 = 719,
1316
1317 /// {Machine Type Mismatch} The image file %hs is valid, but is for a machine type other than the current machine.897 /// {Machine Type Mismatch} The image file %hs is valid, but is for a machine type other than the current machine.
1318 IMAGE_MACHINE_TYPE_MISMATCH_EXE = 720,898 IMAGE_MACHINE_TYPE_MISMATCH_EXE = 720,
1319
1320 /// A yield execution was performed and no thread was available to run.899 /// A yield execution was performed and no thread was available to run.
1321 NO_YIELD_PERFORMED = 721,900 NO_YIELD_PERFORMED = 721,
1322
1323 /// The resumable flag to a timer API was ignored.901 /// The resumable flag to a timer API was ignored.
1324 TIMER_RESUME_IGNORED = 722,902 TIMER_RESUME_IGNORED = 722,
1325
1326 /// The arbiter has deferred arbitration of these resources to its parent.903 /// The arbiter has deferred arbitration of these resources to its parent.
1327 ARBITRATION_UNHANDLED = 723,904 ARBITRATION_UNHANDLED = 723,
1328
1329 /// The inserted CardBus device cannot be started because of a configuration error on "%hs".905 /// The inserted CardBus device cannot be started because of a configuration error on "%hs".
1330 CARDBUS_NOT_SUPPORTED = 724,906 CARDBUS_NOT_SUPPORTED = 724,
1331
1332 /// The CPUs in this multiprocessor system are not all the same revision level.907 /// The CPUs in this multiprocessor system are not all the same revision level.
1333 /// To use all processors the operating system restricts itself to the features of the least capable processor in the system.908 /// To use all processors the operating system restricts itself to the features of the least capable processor in the system.
1334 /// Should problems occur with this system, contact the CPU manufacturer to see if this mix of processors is supported.909 /// Should problems occur with this system, contact the CPU manufacturer to see if this mix of processors is supported.
1335 MP_PROCESSOR_MISMATCH = 725,910 MP_PROCESSOR_MISMATCH = 725,
1336
1337 /// The system was put into hibernation.911 /// The system was put into hibernation.
1338 HIBERNATED = 726,912 HIBERNATED = 726,
1339
1340 /// The system was resumed from hibernation.913 /// The system was resumed from hibernation.
1341 RESUME_HIBERNATION = 727,914 RESUME_HIBERNATION = 727,
1342
1343 /// Windows has detected that the system firmware (BIOS) was updated [previous firmware date = %2, current firmware date %3].915 /// Windows has detected that the system firmware (BIOS) was updated [previous firmware date = %2, current firmware date %3].
1344 FIRMWARE_UPDATED = 728,916 FIRMWARE_UPDATED = 728,
1345
1346 /// A device driver is leaking locked I/O pages causing system degradation.917 /// A device driver is leaking locked I/O pages causing system degradation.
1347 /// The system has automatically enabled tracking code in order to try and catch the culprit.918 /// The system has automatically enabled tracking code in order to try and catch the culprit.
1348 DRIVERS_LEAKING_LOCKED_PAGES = 729,919 DRIVERS_LEAKING_LOCKED_PAGES = 729,
1349
1350 /// The system has awoken.920 /// The system has awoken.
1351 WAKE_SYSTEM = 730,921 WAKE_SYSTEM = 730,
1352
1353 /// ERROR_WAIT_1922 /// ERROR_WAIT_1
1354 WAIT_1 = 731,923 WAIT_1 = 731,
1355
1356 /// ERROR_WAIT_2924 /// ERROR_WAIT_2
1357 WAIT_2 = 732,925 WAIT_2 = 732,
1358
1359 /// ERROR_WAIT_3926 /// ERROR_WAIT_3
1360 WAIT_3 = 733,927 WAIT_3 = 733,
1361
1362 /// ERROR_WAIT_63928 /// ERROR_WAIT_63
1363 WAIT_63 = 734,929 WAIT_63 = 734,
1364
1365 /// ERROR_ABANDONED_WAIT_0930 /// ERROR_ABANDONED_WAIT_0
1366 ABANDONED_WAIT_0 = 735,931 ABANDONED_WAIT_0 = 735,
1367
1368 /// ERROR_ABANDONED_WAIT_63932 /// ERROR_ABANDONED_WAIT_63
1369 ABANDONED_WAIT_63 = 736,933 ABANDONED_WAIT_63 = 736,
1370
1371 /// ERROR_USER_APC934 /// ERROR_USER_APC
1372 USER_APC = 737,935 USER_APC = 737,
1373
1374 /// ERROR_KERNEL_APC936 /// ERROR_KERNEL_APC
1375 KERNEL_APC = 738,937 KERNEL_APC = 738,
1376
1377 /// ERROR_ALERTED938 /// ERROR_ALERTED
1378 ALERTED = 739,939 ALERTED = 739,
1379
1380 /// The requested operation requires elevation.940 /// The requested operation requires elevation.
1381 ELEVATION_REQUIRED = 740,941 ELEVATION_REQUIRED = 740,
1382
1383 /// A reparse should be performed by the Object Manager since the name of the file resulted in a symbolic link.942 /// A reparse should be performed by the Object Manager since the name of the file resulted in a symbolic link.
1384 REPARSE = 741,943 REPARSE = 741,
1385
1386 /// An open/create operation completed while an oplock break is underway.944 /// An open/create operation completed while an oplock break is underway.
1387 OPLOCK_BREAK_IN_PROGRESS = 742,945 OPLOCK_BREAK_IN_PROGRESS = 742,
1388
1389 /// A new volume has been mounted by a file system.946 /// A new volume has been mounted by a file system.
1390 VOLUME_MOUNTED = 743,947 VOLUME_MOUNTED = 743,
1391
1392 /// This success level status indicates that the transaction state already exists for the registry sub-tree, but that a transaction commit was previously aborted. The commit has now been completed.948 /// This success level status indicates that the transaction state already exists for the registry sub-tree, but that a transaction commit was previously aborted. The commit has now been completed.
1393 RXACT_COMMITTED = 744,949 RXACT_COMMITTED = 744,
1394
1395 /// This indicates that a notify change request has been completed due to closing the handle which made the notify change request.950 /// This indicates that a notify change request has been completed due to closing the handle which made the notify change request.
1396 NOTIFY_CLEANUP = 745,951 NOTIFY_CLEANUP = 745,
1397
1398 /// {Connect Failure on Primary Transport} An attempt was made to connect to the remote server %hs on the primary transport, but the connection failed.952 /// {Connect Failure on Primary Transport} An attempt was made to connect to the remote server %hs on the primary transport, but the connection failed.
1399 /// The computer WAS able to connect on a secondary transport.953 /// The computer WAS able to connect on a secondary transport.
1400 PRIMARY_TRANSPORT_CONNECT_FAILED = 746,954 PRIMARY_TRANSPORT_CONNECT_FAILED = 746,
1401
1402 /// Page fault was a transition fault.955 /// Page fault was a transition fault.
1403 PAGE_FAULT_TRANSITION = 747,956 PAGE_FAULT_TRANSITION = 747,
1404
1405 /// Page fault was a demand zero fault.957 /// Page fault was a demand zero fault.
1406 PAGE_FAULT_DEMAND_ZERO = 748,958 PAGE_FAULT_DEMAND_ZERO = 748,
1407
1408 /// Page fault was a demand zero fault.959 /// Page fault was a demand zero fault.
1409 PAGE_FAULT_COPY_ON_WRITE = 749,960 PAGE_FAULT_COPY_ON_WRITE = 749,
1410
1411 /// Page fault was a demand zero fault.961 /// Page fault was a demand zero fault.
1412 PAGE_FAULT_GUARD_PAGE = 750,962 PAGE_FAULT_GUARD_PAGE = 750,
1413
1414 /// Page fault was satisfied by reading from a secondary storage device.963 /// Page fault was satisfied by reading from a secondary storage device.
1415 PAGE_FAULT_PAGING_FILE = 751,964 PAGE_FAULT_PAGING_FILE = 751,
1416
1417 /// Cached page was locked during operation.965 /// Cached page was locked during operation.
1418 CACHE_PAGE_LOCKED = 752,966 CACHE_PAGE_LOCKED = 752,
1419
1420 /// Crash dump exists in paging file.967 /// Crash dump exists in paging file.
1421 CRASH_DUMP = 753,968 CRASH_DUMP = 753,
1422
1423 /// Specified buffer contains all zeros.969 /// Specified buffer contains all zeros.
1424 BUFFER_ALL_ZEROS = 754,970 BUFFER_ALL_ZEROS = 754,
1425
1426 /// A reparse should be performed by the Object Manager since the name of the file resulted in a symbolic link.971 /// A reparse should be performed by the Object Manager since the name of the file resulted in a symbolic link.
1427 REPARSE_OBJECT = 755,972 REPARSE_OBJECT = 755,
1428
1429 /// The device has succeeded a query-stop and its resource requirements have changed.973 /// The device has succeeded a query-stop and its resource requirements have changed.
1430 RESOURCE_REQUIREMENTS_CHANGED = 756,974 RESOURCE_REQUIREMENTS_CHANGED = 756,
1431
1432 /// The translator has translated these resources into the global space and no further translations should be performed.975 /// The translator has translated these resources into the global space and no further translations should be performed.
1433 TRANSLATION_COMPLETE = 757,976 TRANSLATION_COMPLETE = 757,
1434
1435 /// A process being terminated has no threads to terminate.977 /// A process being terminated has no threads to terminate.
1436 NOTHING_TO_TERMINATE = 758,978 NOTHING_TO_TERMINATE = 758,
1437
1438 /// The specified process is not part of a job.979 /// The specified process is not part of a job.
1439 PROCESS_NOT_IN_JOB = 759,980 PROCESS_NOT_IN_JOB = 759,
1440
1441 /// The specified process is part of a job.981 /// The specified process is part of a job.
1442 PROCESS_IN_JOB = 760,982 PROCESS_IN_JOB = 760,
1443
1444 /// {Volume Shadow Copy Service} The system is now ready for hibernation.983 /// {Volume Shadow Copy Service} The system is now ready for hibernation.
1445 VOLSNAP_HIBERNATE_READY = 761,984 VOLSNAP_HIBERNATE_READY = 761,
1446
1447 /// A file system or file system filter driver has successfully completed an FsFilter operation.985 /// A file system or file system filter driver has successfully completed an FsFilter operation.
1448 FSFILTER_OP_COMPLETED_SUCCESSFULLY = 762,986 FSFILTER_OP_COMPLETED_SUCCESSFULLY = 762,
1449
1450 /// The specified interrupt vector was already connected.987 /// The specified interrupt vector was already connected.
1451 INTERRUPT_VECTOR_ALREADY_CONNECTED = 763,988 INTERRUPT_VECTOR_ALREADY_CONNECTED = 763,
1452
1453 /// The specified interrupt vector is still connected.989 /// The specified interrupt vector is still connected.
1454 INTERRUPT_STILL_CONNECTED = 764,990 INTERRUPT_STILL_CONNECTED = 764,
1455
1456 /// An operation is blocked waiting for an oplock.991 /// An operation is blocked waiting for an oplock.
1457 WAIT_FOR_OPLOCK = 765,992 WAIT_FOR_OPLOCK = 765,
1458
1459 /// Debugger handled exception.993 /// Debugger handled exception.
1460 DBG_EXCEPTION_HANDLED = 766,994 DBG_EXCEPTION_HANDLED = 766,
1461
1462 /// Debugger continued.995 /// Debugger continued.
1463 DBG_CONTINUE = 767,996 DBG_CONTINUE = 767,
1464
1465 /// An exception occurred in a user mode callback and the kernel callback frame should be removed.997 /// An exception occurred in a user mode callback and the kernel callback frame should be removed.
1466 CALLBACK_POP_STACK = 768,998 CALLBACK_POP_STACK = 768,
1467
1468 /// Compression is disabled for this volume.999 /// Compression is disabled for this volume.
1469 COMPRESSION_DISABLED = 769,1000 COMPRESSION_DISABLED = 769,
1470
1471 /// The data provider cannot fetch backwards through a result set.1001 /// The data provider cannot fetch backwards through a result set.
1472 CANTFETCHBACKWARDS = 770,1002 CANTFETCHBACKWARDS = 770,
1473
1474 /// The data provider cannot scroll backwards through a result set.1003 /// The data provider cannot scroll backwards through a result set.
1475 CANTSCROLLBACKWARDS = 771,1004 CANTSCROLLBACKWARDS = 771,
1476
1477 /// The data provider requires that previously fetched data is released before asking for more data.1005 /// The data provider requires that previously fetched data is released before asking for more data.
1478 ROWSNOTRELEASED = 772,1006 ROWSNOTRELEASED = 772,
1479
1480 /// The data provider was not able to interpret the flags set for a column binding in an accessor.1007 /// The data provider was not able to interpret the flags set for a column binding in an accessor.
1481 BAD_ACCESSOR_FLAGS = 773,1008 BAD_ACCESSOR_FLAGS = 773,
1482
1483 /// One or more errors occurred while processing the request.1009 /// One or more errors occurred while processing the request.
1484 ERRORS_ENCOUNTERED = 774,1010 ERRORS_ENCOUNTERED = 774,
1485
1486 /// The implementation is not capable of performing the request.1011 /// The implementation is not capable of performing the request.
1487 NOT_CAPABLE = 775,1012 NOT_CAPABLE = 775,
1488
1489 /// The client of a component requested an operation which is not valid given the state of the component instance.1013 /// The client of a component requested an operation which is not valid given the state of the component instance.
1490 REQUEST_OUT_OF_SEQUENCE = 776,1014 REQUEST_OUT_OF_SEQUENCE = 776,
1491
1492 /// A version number could not be parsed.1015 /// A version number could not be parsed.
1493 VERSION_PARSE_ERROR = 777,1016 VERSION_PARSE_ERROR = 777,
1494
1495 /// The iterator's start position is invalid.1017 /// The iterator's start position is invalid.
1496 BADSTARTPOSITION = 778,1018 BADSTARTPOSITION = 778,
1497
1498 /// The hardware has reported an uncorrectable memory error.1019 /// The hardware has reported an uncorrectable memory error.
1499 MEMORY_HARDWARE = 779,1020 MEMORY_HARDWARE = 779,
1500
1501 /// The attempted operation required self healing to be enabled.1021 /// The attempted operation required self healing to be enabled.
1502 DISK_REPAIR_DISABLED = 780,1022 DISK_REPAIR_DISABLED = 780,
1503
1504 /// The Desktop heap encountered an error while allocating session memory.1023 /// The Desktop heap encountered an error while allocating session memory.
1505 /// There is more information in the system event log.1024 /// There is more information in the system event log.
1506 INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE = 781,1025 INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE = 781,
1507
1508 /// The system power state is transitioning from %2 to %3.1026 /// The system power state is transitioning from %2 to %3.
1509 SYSTEM_POWERSTATE_TRANSITION = 782,1027 SYSTEM_POWERSTATE_TRANSITION = 782,
1510
1511 /// The system power state is transitioning from %2 to %3 but could enter %4.1028 /// The system power state is transitioning from %2 to %3 but could enter %4.
1512 SYSTEM_POWERSTATE_COMPLEX_TRANSITION = 783,1029 SYSTEM_POWERSTATE_COMPLEX_TRANSITION = 783,
1513
1514 /// A thread is getting dispatched with MCA EXCEPTION because of MCA.1030 /// A thread is getting dispatched with MCA EXCEPTION because of MCA.
1515 MCA_EXCEPTION = 784,1031 MCA_EXCEPTION = 784,
1516
1517 /// Access to %1 is monitored by policy rule %2.1032 /// Access to %1 is monitored by policy rule %2.
1518 ACCESS_AUDIT_BY_POLICY = 785,1033 ACCESS_AUDIT_BY_POLICY = 785,
1519
1520 /// Access to %1 has been restricted by your Administrator by policy rule %2.1034 /// Access to %1 has been restricted by your Administrator by policy rule %2.
1521 ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY = 786,1035 ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY = 786,
1522
1523 /// A valid hibernation file has been invalidated and should be abandoned.1036 /// A valid hibernation file has been invalidated and should be abandoned.
1524 ABANDON_HIBERFILE = 787,1037 ABANDON_HIBERFILE = 787,
1525
1526 /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost.1038 /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost.
1527 /// This error may be caused by network connectivity issues. Please try to save this file elsewhere.1039 /// This error may be caused by network connectivity issues. Please try to save this file elsewhere.
1528 LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED = 788,1040 LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED = 788,
1529
1530 /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost.1041 /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost.
1531 /// This error was returned by the server on which the file exists. Please try to save this file elsewhere.1042 /// This error was returned by the server on which the file exists. Please try to save this file elsewhere.
1532 LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR = 789,1043 LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR = 789,
1533
1534 /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost.1044 /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost.
1535 /// This error may be caused if the device has been removed or the media is write-protected.1045 /// This error may be caused if the device has been removed or the media is write-protected.
1536 LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR = 790,1046 LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR = 790,
1537
1538 /// The resources required for this device conflict with the MCFG table.1047 /// The resources required for this device conflict with the MCFG table.
1539 BAD_MCFG_TABLE = 791,1048 BAD_MCFG_TABLE = 791,
1540
1541 /// The volume repair could not be performed while it is online.1049 /// The volume repair could not be performed while it is online.
1542 /// Please schedule to take the volume offline so that it can be repaired.1050 /// Please schedule to take the volume offline so that it can be repaired.
1543 DISK_REPAIR_REDIRECTED = 792,1051 DISK_REPAIR_REDIRECTED = 792,
1544
1545 /// The volume repair was not successful.1052 /// The volume repair was not successful.
1546 DISK_REPAIR_UNSUCCESSFUL = 793,1053 DISK_REPAIR_UNSUCCESSFUL = 793,
1547
1548 /// One of the volume corruption logs is full.1054 /// One of the volume corruption logs is full.
1549 /// Further corruptions that may be detected won't be logged.1055 /// Further corruptions that may be detected won't be logged.
1550 CORRUPT_LOG_OVERFULL = 794,1056 CORRUPT_LOG_OVERFULL = 794,
1551
1552 /// One of the volume corruption logs is internally corrupted and needs to be recreated.1057 /// One of the volume corruption logs is internally corrupted and needs to be recreated.
1553 /// The volume may contain undetected corruptions and must be scanned.1058 /// The volume may contain undetected corruptions and must be scanned.
1554 CORRUPT_LOG_CORRUPTED = 795,1059 CORRUPT_LOG_CORRUPTED = 795,
1555
1556 /// One of the volume corruption logs is unavailable for being operated on.1060 /// One of the volume corruption logs is unavailable for being operated on.
1557 CORRUPT_LOG_UNAVAILABLE = 796,1061 CORRUPT_LOG_UNAVAILABLE = 796,
1558
1559 /// One of the volume corruption logs was deleted while still having corruption records in them.1062 /// One of the volume corruption logs was deleted while still having corruption records in them.
1560 /// The volume contains detected corruptions and must be scanned.1063 /// The volume contains detected corruptions and must be scanned.
1561 CORRUPT_LOG_DELETED_FULL = 797,1064 CORRUPT_LOG_DELETED_FULL = 797,
1562
1563 /// One of the volume corruption logs was cleared by chkdsk and no longer contains real corruptions.1065 /// One of the volume corruption logs was cleared by chkdsk and no longer contains real corruptions.
1564 CORRUPT_LOG_CLEARED = 798,1066 CORRUPT_LOG_CLEARED = 798,
1565
1566 /// Orphaned files exist on the volume but could not be recovered because no more new names could be created in the recovery directory. Files must be moved from the recovery directory.1067 /// Orphaned files exist on the volume but could not be recovered because no more new names could be created in the recovery directory. Files must be moved from the recovery directory.
1567 ORPHAN_NAME_EXHAUSTED = 799,1068 ORPHAN_NAME_EXHAUSTED = 799,
1568
1569 /// The oplock that was associated with this handle is now associated with a different handle.1069 /// The oplock that was associated with this handle is now associated with a different handle.
1570 OPLOCK_SWITCHED_TO_NEW_HANDLE = 800,1070 OPLOCK_SWITCHED_TO_NEW_HANDLE = 800,
1571
1572 /// An oplock of the requested level cannot be granted. An oplock of a lower level may be available.1071 /// An oplock of the requested level cannot be granted. An oplock of a lower level may be available.
1573 CANNOT_GRANT_REQUESTED_OPLOCK = 801,1072 CANNOT_GRANT_REQUESTED_OPLOCK = 801,
1574
1575 /// The operation did not complete successfully because it would cause an oplock to be broken.1073 /// The operation did not complete successfully because it would cause an oplock to be broken.
1576 /// The caller has requested that existing oplocks not be broken.1074 /// The caller has requested that existing oplocks not be broken.
1577 CANNOT_BREAK_OPLOCK = 802,1075 CANNOT_BREAK_OPLOCK = 802,
1578
1579 /// The handle with which this oplock was associated has been closed. The oplock is now broken.1076 /// The handle with which this oplock was associated has been closed. The oplock is now broken.
1580 OPLOCK_HANDLE_CLOSED = 803,1077 OPLOCK_HANDLE_CLOSED = 803,
1581
1582 /// The specified access control entry (ACE) does not contain a condition.1078 /// The specified access control entry (ACE) does not contain a condition.
1583 NO_ACE_CONDITION = 804,1079 NO_ACE_CONDITION = 804,
1584
1585 /// The specified access control entry (ACE) contains an invalid condition.1080 /// The specified access control entry (ACE) contains an invalid condition.
1586 INVALID_ACE_CONDITION = 805,1081 INVALID_ACE_CONDITION = 805,
1587
1588 /// Access to the specified file handle has been revoked.1082 /// Access to the specified file handle has been revoked.
1589 FILE_HANDLE_REVOKED = 806,1083 FILE_HANDLE_REVOKED = 806,
1590
1591 /// An image file was mapped at a different address from the one specified in the image file but fixups will still be automatically performed on the image.1084 /// An image file was mapped at a different address from the one specified in the image file but fixups will still be automatically performed on the image.
1592 IMAGE_AT_DIFFERENT_BASE = 807,1085 IMAGE_AT_DIFFERENT_BASE = 807,
1593
1594 /// Access to the extended attribute was denied.1086 /// Access to the extended attribute was denied.
1595 EA_ACCESS_DENIED = 994,1087 EA_ACCESS_DENIED = 994,
1596
1597 /// The I/O operation has been aborted because of either a thread exit or an application request.1088 /// The I/O operation has been aborted because of either a thread exit or an application request.
1598 OPERATION_ABORTED = 995,1089 OPERATION_ABORTED = 995,
1599
1600 /// Overlapped I/O event is not in a signaled state.1090 /// Overlapped I/O event is not in a signaled state.
1601 IO_INCOMPLETE = 996,1091 IO_INCOMPLETE = 996,
1602
1603 /// Overlapped I/O operation is in progress.1092 /// Overlapped I/O operation is in progress.
1604 IO_PENDING = 997,1093 IO_PENDING = 997,
1605
1606 /// Invalid access to memory location.1094 /// Invalid access to memory location.
1607 NOACCESS = 998,1095 NOACCESS = 998,
1608
1609 /// Error performing inpage operation.1096 /// Error performing inpage operation.
1610 SWAPERROR = 999,1097 SWAPERROR = 999,
1611
1612 /// Recursion too deep; the stack overflowed.1098 /// Recursion too deep; the stack overflowed.
1613 STACK_OVERFLOW = 1001,1099 STACK_OVERFLOW = 1001,
1614
1615 /// The window cannot act on the sent message.1100 /// The window cannot act on the sent message.
1616 INVALID_MESSAGE = 1002,1101 INVALID_MESSAGE = 1002,
1617
1618 /// Cannot complete this function.1102 /// Cannot complete this function.
1619 CAN_NOT_COMPLETE = 1003,1103 CAN_NOT_COMPLETE = 1003,
1620
1621 /// Invalid flags.1104 /// Invalid flags.
1622 INVALID_FLAGS = 1004,1105 INVALID_FLAGS = 1004,
1623
1624 /// The volume does not contain a recognized file system.1106 /// The volume does not contain a recognized file system.
1625 /// Please make sure that all required file system drivers are loaded and that the volume is not corrupted.1107 /// Please make sure that all required file system drivers are loaded and that the volume is not corrupted.
1626 UNRECOGNIZED_VOLUME = 1005,1108 UNRECOGNIZED_VOLUME = 1005,
1627
1628 /// The volume for a file has been externally altered so that the opened file is no longer valid.1109 /// The volume for a file has been externally altered so that the opened file is no longer valid.
1629 FILE_INVALID = 1006,1110 FILE_INVALID = 1006,
1630
1631 /// The requested operation cannot be performed in full-screen mode.1111 /// The requested operation cannot be performed in full-screen mode.
1632 FULLSCREEN_MODE = 1007,1112 FULLSCREEN_MODE = 1007,
1633
1634 /// An attempt was made to reference a token that does not exist.1113 /// An attempt was made to reference a token that does not exist.
1635 NO_TOKEN = 1008,1114 NO_TOKEN = 1008,
1636
1637 /// The configuration registry database is corrupt.1115 /// The configuration registry database is corrupt.
1638 BADDB = 1009,1116 BADDB = 1009,
1639
1640 /// The configuration registry key is invalid.1117 /// The configuration registry key is invalid.
1641 BADKEY = 1010,1118 BADKEY = 1010,
1642
1643 /// The configuration registry key could not be opened.1119 /// The configuration registry key could not be opened.
1644 CANTOPEN = 1011,1120 CANTOPEN = 1011,
1645
1646 /// The configuration registry key could not be read.1121 /// The configuration registry key could not be read.
1647 CANTREAD = 1012,1122 CANTREAD = 1012,
1648
1649 /// The configuration registry key could not be written.1123 /// The configuration registry key could not be written.
1650 CANTWRITE = 1013,1124 CANTWRITE = 1013,
1651
1652 /// One of the files in the registry database had to be recovered by use of a log or alternate copy. The recovery was successful.1125 /// One of the files in the registry database had to be recovered by use of a log or alternate copy. The recovery was successful.
1653 REGISTRY_RECOVERED = 1014,1126 REGISTRY_RECOVERED = 1014,
1654
1655 /// The registry is corrupted. The structure of one of the files containing registry data is corrupted, or the system's memory image of the file is corrupted, or the file could not be recovered because the alternate copy or log was absent or corrupted.1127 /// The registry is corrupted. The structure of one of the files containing registry data is corrupted, or the system's memory image of the file is corrupted, or the file could not be recovered because the alternate copy or log was absent or corrupted.
1656 REGISTRY_CORRUPT = 1015,1128 REGISTRY_CORRUPT = 1015,
1657
1658 /// An I/O operation initiated by the registry failed unrecoverably.1129 /// An I/O operation initiated by the registry failed unrecoverably.
1659 /// The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry.1130 /// The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry.
1660 REGISTRY_IO_FAILED = 1016,1131 REGISTRY_IO_FAILED = 1016,
1661
1662 /// The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format.1132 /// The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format.
1663 NOT_REGISTRY_FILE = 1017,1133 NOT_REGISTRY_FILE = 1017,
1664
1665 /// Illegal operation attempted on a registry key that has been marked for deletion.1134 /// Illegal operation attempted on a registry key that has been marked for deletion.
1666 KEY_DELETED = 1018,1135 KEY_DELETED = 1018,
1667
1668 /// System could not allocate the required space in a registry log.1136 /// System could not allocate the required space in a registry log.
1669 NO_LOG_SPACE = 1019,1137 NO_LOG_SPACE = 1019,
1670
1671 /// Cannot create a symbolic link in a registry key that already has subkeys or values.1138 /// Cannot create a symbolic link in a registry key that already has subkeys or values.
1672 KEY_HAS_CHILDREN = 1020,1139 KEY_HAS_CHILDREN = 1020,
1673
1674 /// Cannot create a stable subkey under a volatile parent key.1140 /// Cannot create a stable subkey under a volatile parent key.
1675 CHILD_MUST_BE_VOLATILE = 1021,1141 CHILD_MUST_BE_VOLATILE = 1021,
1676
1677 /// A notify change request is being completed and the information is not being returned in the caller's buffer.1142 /// A notify change request is being completed and the information is not being returned in the caller's buffer.
1678 /// The caller now needs to enumerate the files to find the changes.1143 /// The caller now needs to enumerate the files to find the changes.
1679 NOTIFY_ENUM_DIR = 1022,1144 NOTIFY_ENUM_DIR = 1022,
1680
1681 /// A stop control has been sent to a service that other running services are dependent on.1145 /// A stop control has been sent to a service that other running services are dependent on.
1682 DEPENDENT_SERVICES_RUNNING = 1051,1146 DEPENDENT_SERVICES_RUNNING = 1051,
1683
1684 /// The requested control is not valid for this service.1147 /// The requested control is not valid for this service.
1685 INVALID_SERVICE_CONTROL = 1052,1148 INVALID_SERVICE_CONTROL = 1052,
1686
1687 /// The service did not respond to the start or control request in a timely fashion.1149 /// The service did not respond to the start or control request in a timely fashion.
1688 SERVICE_REQUEST_TIMEOUT = 1053,1150 SERVICE_REQUEST_TIMEOUT = 1053,
1689
1690 /// A thread could not be created for the service.1151 /// A thread could not be created for the service.
1691 SERVICE_NO_THREAD = 1054,1152 SERVICE_NO_THREAD = 1054,
1692
1693 /// The service database is locked.1153 /// The service database is locked.
1694 SERVICE_DATABASE_LOCKED = 1055,1154 SERVICE_DATABASE_LOCKED = 1055,
1695
1696 /// An instance of the service is already running.1155 /// An instance of the service is already running.
1697 SERVICE_ALREADY_RUNNING = 1056,1156 SERVICE_ALREADY_RUNNING = 1056,
1698
1699 /// The account name is invalid or does not exist, or the password is invalid for the account name specified.1157 /// The account name is invalid or does not exist, or the password is invalid for the account name specified.
1700 INVALID_SERVICE_ACCOUNT = 1057,1158 INVALID_SERVICE_ACCOUNT = 1057,
1701
1702 /// The service cannot be started, either because it is disabled or because it has no enabled devices associated with it.1159 /// The service cannot be started, either because it is disabled or because it has no enabled devices associated with it.
1703 SERVICE_DISABLED = 1058,1160 SERVICE_DISABLED = 1058,
1704
1705 /// Circular service dependency was specified.1161 /// Circular service dependency was specified.
1706 CIRCULAR_DEPENDENCY = 1059,1162 CIRCULAR_DEPENDENCY = 1059,
1707
1708 /// The specified service does not exist as an installed service.1163 /// The specified service does not exist as an installed service.
1709 SERVICE_DOES_NOT_EXIST = 1060,1164 SERVICE_DOES_NOT_EXIST = 1060,
1710
1711 /// The service cannot accept control messages at this time.1165 /// The service cannot accept control messages at this time.
1712 SERVICE_CANNOT_ACCEPT_CTRL = 1061,1166 SERVICE_CANNOT_ACCEPT_CTRL = 1061,
1713
1714 /// The service has not been started.1167 /// The service has not been started.
1715 SERVICE_NOT_ACTIVE = 1062,1168 SERVICE_NOT_ACTIVE = 1062,
1716
1717 /// The service process could not connect to the service controller.1169 /// The service process could not connect to the service controller.
1718 FAILED_SERVICE_CONTROLLER_CONNECT = 1063,1170 FAILED_SERVICE_CONTROLLER_CONNECT = 1063,
1719
1720 /// An exception occurred in the service when handling the control request.1171 /// An exception occurred in the service when handling the control request.
1721 EXCEPTION_IN_SERVICE = 1064,1172 EXCEPTION_IN_SERVICE = 1064,
1722
1723 /// The database specified does not exist.1173 /// The database specified does not exist.
1724 DATABASE_DOES_NOT_EXIST = 1065,1174 DATABASE_DOES_NOT_EXIST = 1065,
1725
1726 /// The service has returned a service-specific error code.1175 /// The service has returned a service-specific error code.
1727 SERVICE_SPECIFIC_ERROR = 1066,1176 SERVICE_SPECIFIC_ERROR = 1066,
1728
1729 /// The process terminated unexpectedly.1177 /// The process terminated unexpectedly.
1730 PROCESS_ABORTED = 1067,1178 PROCESS_ABORTED = 1067,
1731
1732 /// The dependency service or group failed to start.1179 /// The dependency service or group failed to start.
1733 SERVICE_DEPENDENCY_FAIL = 1068,1180 SERVICE_DEPENDENCY_FAIL = 1068,
1734
1735 /// The service did not start due to a logon failure.1181 /// The service did not start due to a logon failure.
1736 SERVICE_LOGON_FAILED = 1069,1182 SERVICE_LOGON_FAILED = 1069,
1737
1738 /// After starting, the service hung in a start-pending state.1183 /// After starting, the service hung in a start-pending state.
1739 SERVICE_START_HANG = 1070,1184 SERVICE_START_HANG = 1070,
1740
1741 /// The specified service database lock is invalid.1185 /// The specified service database lock is invalid.
1742 INVALID_SERVICE_LOCK = 1071,1186 INVALID_SERVICE_LOCK = 1071,
1743
1744 /// The specified service has been marked for deletion.1187 /// The specified service has been marked for deletion.
1745 SERVICE_MARKED_FOR_DELETE = 1072,1188 SERVICE_MARKED_FOR_DELETE = 1072,
1746
1747 /// The specified service already exists.1189 /// The specified service already exists.
1748 SERVICE_EXISTS = 1073,1190 SERVICE_EXISTS = 1073,
1749
1750 /// The system is currently running with the last-known-good configuration.1191 /// The system is currently running with the last-known-good configuration.
1751 ALREADY_RUNNING_LKG = 1074,1192 ALREADY_RUNNING_LKG = 1074,
1752
1753 /// The dependency service does not exist or has been marked for deletion.1193 /// The dependency service does not exist or has been marked for deletion.
1754 SERVICE_DEPENDENCY_DELETED = 1075,1194 SERVICE_DEPENDENCY_DELETED = 1075,
1755
1756 /// The current boot has already been accepted for use as the last-known-good control set.1195 /// The current boot has already been accepted for use as the last-known-good control set.
1757 BOOT_ALREADY_ACCEPTED = 1076,1196 BOOT_ALREADY_ACCEPTED = 1076,
1758
1759 /// No attempts to start the service have been made since the last boot.1197 /// No attempts to start the service have been made since the last boot.
1760 SERVICE_NEVER_STARTED = 1077,1198 SERVICE_NEVER_STARTED = 1077,
1761
1762 /// The name is already in use as either a service name or a service display name.1199 /// The name is already in use as either a service name or a service display name.
1763 DUPLICATE_SERVICE_NAME = 1078,1200 DUPLICATE_SERVICE_NAME = 1078,
1764
1765 /// The account specified for this service is different from the account specified for other services running in the same process.1201 /// The account specified for this service is different from the account specified for other services running in the same process.
1766 DIFFERENT_SERVICE_ACCOUNT = 1079,1202 DIFFERENT_SERVICE_ACCOUNT = 1079,
1767
1768 /// Failure actions can only be set for Win32 services, not for drivers.1203 /// Failure actions can only be set for Win32 services, not for drivers.
1769 CANNOT_DETECT_DRIVER_FAILURE = 1080,1204 CANNOT_DETECT_DRIVER_FAILURE = 1080,
1770
1771 /// This service runs in the same process as the service control manager.1205 /// This service runs in the same process as the service control manager.
1772 /// Therefore, the service control manager cannot take action if this service's process terminates unexpectedly.1206 /// Therefore, the service control manager cannot take action if this service's process terminates unexpectedly.
1773 CANNOT_DETECT_PROCESS_ABORT = 1081,1207 CANNOT_DETECT_PROCESS_ABORT = 1081,
1774
1775 /// No recovery program has been configured for this service.1208 /// No recovery program has been configured for this service.
1776 NO_RECOVERY_PROGRAM = 1082,1209 NO_RECOVERY_PROGRAM = 1082,
1777
1778 /// The executable program that this service is configured to run in does not implement the service.1210 /// The executable program that this service is configured to run in does not implement the service.
1779 SERVICE_NOT_IN_EXE = 1083,1211 SERVICE_NOT_IN_EXE = 1083,
1780
1781 /// This service cannot be started in Safe Mode.1212 /// This service cannot be started in Safe Mode.
1782 NOT_SAFEBOOT_SERVICE = 1084,1213 NOT_SAFEBOOT_SERVICE = 1084,
1783
1784 /// The physical end of the tape has been reached.1214 /// The physical end of the tape has been reached.
1785 END_OF_MEDIA = 1100,1215 END_OF_MEDIA = 1100,
1786
1787 /// A tape access reached a filemark.1216 /// A tape access reached a filemark.
1788 FILEMARK_DETECTED = 1101,1217 FILEMARK_DETECTED = 1101,
1789
1790 /// The beginning of the tape or a partition was encountered.1218 /// The beginning of the tape or a partition was encountered.
1791 BEGINNING_OF_MEDIA = 1102,1219 BEGINNING_OF_MEDIA = 1102,
1792
1793 /// A tape access reached the end of a set of files.1220 /// A tape access reached the end of a set of files.
1794 SETMARK_DETECTED = 1103,1221 SETMARK_DETECTED = 1103,
1795
1796 /// No more data is on the tape.1222 /// No more data is on the tape.
1797 NO_DATA_DETECTED = 1104,1223 NO_DATA_DETECTED = 1104,
1798
1799 /// Tape could not be partitioned.1224 /// Tape could not be partitioned.
1800 PARTITION_FAILURE = 1105,1225 PARTITION_FAILURE = 1105,
1801
1802 /// When accessing a new tape of a multivolume partition, the current block size is incorrect.1226 /// When accessing a new tape of a multivolume partition, the current block size is incorrect.
1803 INVALID_BLOCK_LENGTH = 1106,1227 INVALID_BLOCK_LENGTH = 1106,
1804
1805 /// Tape partition information could not be found when loading a tape.1228 /// Tape partition information could not be found when loading a tape.
1806 DEVICE_NOT_PARTITIONED = 1107,1229 DEVICE_NOT_PARTITIONED = 1107,
1807
1808 /// Unable to lock the media eject mechanism.1230 /// Unable to lock the media eject mechanism.
1809 UNABLE_TO_LOCK_MEDIA = 1108,1231 UNABLE_TO_LOCK_MEDIA = 1108,
1810
1811 /// Unable to unload the media.1232 /// Unable to unload the media.
1812 UNABLE_TO_UNLOAD_MEDIA = 1109,1233 UNABLE_TO_UNLOAD_MEDIA = 1109,
1813
1814 /// The media in the drive may have changed.1234 /// The media in the drive may have changed.
1815 MEDIA_CHANGED = 1110,1235 MEDIA_CHANGED = 1110,
1816
1817 /// The I/O bus was reset.1236 /// The I/O bus was reset.
1818 BUS_RESET = 1111,1237 BUS_RESET = 1111,
1819
1820 /// No media in drive.1238 /// No media in drive.
1821 NO_MEDIA_IN_DRIVE = 1112,1239 NO_MEDIA_IN_DRIVE = 1112,
1822
1823 /// No mapping for the Unicode character exists in the target multi-byte code page.1240 /// No mapping for the Unicode character exists in the target multi-byte code page.
1824 NO_UNICODE_TRANSLATION = 1113,1241 NO_UNICODE_TRANSLATION = 1113,
1825
1826 /// A dynamic link library (DLL) initialization routine failed.1242 /// A dynamic link library (DLL) initialization routine failed.
1827 DLL_INIT_FAILED = 1114,1243 DLL_INIT_FAILED = 1114,
1828
1829 /// A system shutdown is in progress.1244 /// A system shutdown is in progress.
1830 SHUTDOWN_IN_PROGRESS = 1115,1245 SHUTDOWN_IN_PROGRESS = 1115,
1831
1832 /// Unable to abort the system shutdown because no shutdown was in progress.1246 /// Unable to abort the system shutdown because no shutdown was in progress.
1833 NO_SHUTDOWN_IN_PROGRESS = 1116,1247 NO_SHUTDOWN_IN_PROGRESS = 1116,
1834
1835 /// The request could not be performed because of an I/O device error.1248 /// The request could not be performed because of an I/O device error.
1836 IO_DEVICE = 1117,1249 IO_DEVICE = 1117,
1837
1838 /// No serial device was successfully initialized. The serial driver will unload.1250 /// No serial device was successfully initialized. The serial driver will unload.
1839 SERIAL_NO_DEVICE = 1118,1251 SERIAL_NO_DEVICE = 1118,
1840
1841 /// Unable to open a device that was sharing an interrupt request (IRQ) with other devices.1252 /// Unable to open a device that was sharing an interrupt request (IRQ) with other devices.
1842 /// At least one other device that uses that IRQ was already opened.1253 /// At least one other device that uses that IRQ was already opened.
1843 IRQ_BUSY = 1119,1254 IRQ_BUSY = 1119,
1844
1845 /// A serial I/O operation was completed by another write to the serial port. The IOCTL_SERIAL_XOFF_COUNTER reached zero.)1255 /// A serial I/O operation was completed by another write to the serial port. The IOCTL_SERIAL_XOFF_COUNTER reached zero.)
1846 MORE_WRITES = 1120,1256 MORE_WRITES = 1120,
1847
1848 /// A serial I/O operation completed because the timeout period expired.1257 /// A serial I/O operation completed because the timeout period expired.
1849 /// The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.)1258 /// The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.)
1850 COUNTER_TIMEOUT = 1121,1259 COUNTER_TIMEOUT = 1121,
1851
1852 /// No ID address mark was found on the floppy disk.1260 /// No ID address mark was found on the floppy disk.
1853 FLOPPY_ID_MARK_NOT_FOUND = 1122,1261 FLOPPY_ID_MARK_NOT_FOUND = 1122,
1854
1855 /// Mismatch between the floppy disk sector ID field and the floppy disk controller track address.1262 /// Mismatch between the floppy disk sector ID field and the floppy disk controller track address.
1856 FLOPPY_WRONG_CYLINDER = 1123,1263 FLOPPY_WRONG_CYLINDER = 1123,
1857
1858 /// The floppy disk controller reported an error that is not recognized by the floppy disk driver.1264 /// The floppy disk controller reported an error that is not recognized by the floppy disk driver.
1859 FLOPPY_UNKNOWN_ERROR = 1124,1265 FLOPPY_UNKNOWN_ERROR = 1124,
1860
1861 /// The floppy disk controller returned inconsistent results in its registers.1266 /// The floppy disk controller returned inconsistent results in its registers.
1862 FLOPPY_BAD_REGISTERS = 1125,1267 FLOPPY_BAD_REGISTERS = 1125,
1863
1864 /// While accessing the hard disk, a recalibrate operation failed, even after retries.1268 /// While accessing the hard disk, a recalibrate operation failed, even after retries.
1865 DISK_RECALIBRATE_FAILED = 1126,1269 DISK_RECALIBRATE_FAILED = 1126,
1866
1867 /// While accessing the hard disk, a disk operation failed even after retries.1270 /// While accessing the hard disk, a disk operation failed even after retries.
1868 DISK_OPERATION_FAILED = 1127,1271 DISK_OPERATION_FAILED = 1127,
1869
1870 /// While accessing the hard disk, a disk controller reset was needed, but even that failed.1272 /// While accessing the hard disk, a disk controller reset was needed, but even that failed.
1871 DISK_RESET_FAILED = 1128,1273 DISK_RESET_FAILED = 1128,
1872
1873 /// Physical end of tape encountered.1274 /// Physical end of tape encountered.
1874 EOM_OVERFLOW = 1129,1275 EOM_OVERFLOW = 1129,
1875
1876 /// Not enough server storage is available to process this command.1276 /// Not enough server storage is available to process this command.
1877 NOT_ENOUGH_SERVER_MEMORY = 1130,1277 NOT_ENOUGH_SERVER_MEMORY = 1130,
1878
1879 /// A potential deadlock condition has been detected.1278 /// A potential deadlock condition has been detected.
1880 POSSIBLE_DEADLOCK = 1131,1279 POSSIBLE_DEADLOCK = 1131,
1881
1882 /// The base address or the file offset specified does not have the proper alignment.1280 /// The base address or the file offset specified does not have the proper alignment.
1883 MAPPED_ALIGNMENT = 1132,1281 MAPPED_ALIGNMENT = 1132,
1884
1885 /// An attempt to change the system power state was vetoed by another application or driver.1282 /// An attempt to change the system power state was vetoed by another application or driver.
1886 SET_POWER_STATE_VETOED = 1140,1283 SET_POWER_STATE_VETOED = 1140,
1887
1888 /// The system BIOS failed an attempt to change the system power state.1284 /// The system BIOS failed an attempt to change the system power state.
1889 SET_POWER_STATE_FAILED = 1141,1285 SET_POWER_STATE_FAILED = 1141,
1890
1891 /// An attempt was made to create more links on a file than the file system supports.1286 /// An attempt was made to create more links on a file than the file system supports.
1892 TOO_MANY_LINKS = 1142,1287 TOO_MANY_LINKS = 1142,
1893
1894 /// The specified program requires a newer version of Windows.1288 /// The specified program requires a newer version of Windows.
1895 OLD_WIN_VERSION = 1150,1289 OLD_WIN_VERSION = 1150,
1896
1897 /// The specified program is not a Windows or MS-DOS program.1290 /// The specified program is not a Windows or MS-DOS program.
1898 APP_WRONG_OS = 1151,1291 APP_WRONG_OS = 1151,
1899
1900 /// Cannot start more than one instance of the specified program.1292 /// Cannot start more than one instance of the specified program.
1901 SINGLE_INSTANCE_APP = 1152,1293 SINGLE_INSTANCE_APP = 1152,
1902
1903 /// The specified program was written for an earlier version of Windows.1294 /// The specified program was written for an earlier version of Windows.
1904 RMODE_APP = 1153,1295 RMODE_APP = 1153,
1905
1906 /// One of the library files needed to run this application is damaged.1296 /// One of the library files needed to run this application is damaged.
1907 INVALID_DLL = 1154,1297 INVALID_DLL = 1154,
1908
1909 /// No application is associated with the specified file for this operation.1298 /// No application is associated with the specified file for this operation.
1910 NO_ASSOCIATION = 1155,1299 NO_ASSOCIATION = 1155,
1911
1912 /// An error occurred in sending the command to the application.1300 /// An error occurred in sending the command to the application.
1913 DDE_FAIL = 1156,1301 DDE_FAIL = 1156,
1914
1915 /// One of the library files needed to run this application cannot be found.1302 /// One of the library files needed to run this application cannot be found.
1916 DLL_NOT_FOUND = 1157,1303 DLL_NOT_FOUND = 1157,
1917
1918 /// The current process has used all of its system allowance of handles for Window Manager objects.1304 /// The current process has used all of its system allowance of handles for Window Manager objects.
1919 NO_MORE_USER_HANDLES = 1158,1305 NO_MORE_USER_HANDLES = 1158,
1920
1921 /// The message can be used only with synchronous operations.1306 /// The message can be used only with synchronous operations.
1922 MESSAGE_SYNC_ONLY = 1159,1307 MESSAGE_SYNC_ONLY = 1159,
1923
1924 /// The indicated source element has no media.1308 /// The indicated source element has no media.
1925 SOURCE_ELEMENT_EMPTY = 1160,1309 SOURCE_ELEMENT_EMPTY = 1160,
1926
1927 /// The indicated destination element already contains media.1310 /// The indicated destination element already contains media.
1928 DESTINATION_ELEMENT_FULL = 1161,1311 DESTINATION_ELEMENT_FULL = 1161,
1929
1930 /// The indicated element does not exist.1312 /// The indicated element does not exist.
1931 ILLEGAL_ELEMENT_ADDRESS = 1162,1313 ILLEGAL_ELEMENT_ADDRESS = 1162,
1932
1933 /// The indicated element is part of a magazine that is not present.1314 /// The indicated element is part of a magazine that is not present.
1934 MAGAZINE_NOT_PRESENT = 1163,1315 MAGAZINE_NOT_PRESENT = 1163,
1935
1936 /// The indicated device requires reinitialization due to hardware errors.1316 /// The indicated device requires reinitialization due to hardware errors.
1937 DEVICE_REINITIALIZATION_NEEDED = 1164,1317 DEVICE_REINITIALIZATION_NEEDED = 1164,
1938
1939 /// The device has indicated that cleaning is required before further operations are attempted.1318 /// The device has indicated that cleaning is required before further operations are attempted.
1940 DEVICE_REQUIRES_CLEANING = 1165,1319 DEVICE_REQUIRES_CLEANING = 1165,
1941
1942 /// The device has indicated that its door is open.1320 /// The device has indicated that its door is open.
1943 DEVICE_DOOR_OPEN = 1166,1321 DEVICE_DOOR_OPEN = 1166,
1944
1945 /// The device is not connected.1322 /// The device is not connected.
1946 DEVICE_NOT_CONNECTED = 1167,1323 DEVICE_NOT_CONNECTED = 1167,
1947
1948 /// Element not found.1324 /// Element not found.
1949 NOT_FOUND = 1168,1325 NOT_FOUND = 1168,
1950
1951 /// There was no match for the specified key in the index.1326 /// There was no match for the specified key in the index.
1952 NO_MATCH = 1169,1327 NO_MATCH = 1169,
1953
1954 /// The property set specified does not exist on the object.1328 /// The property set specified does not exist on the object.
1955 SET_NOT_FOUND = 1170,1329 SET_NOT_FOUND = 1170,
1956
1957 /// The point passed to GetMouseMovePoints is not in the buffer.1330 /// The point passed to GetMouseMovePoints is not in the buffer.
1958 POINT_NOT_FOUND = 1171,1331 POINT_NOT_FOUND = 1171,
1959
1960 /// The tracking (workstation) service is not running.1332 /// The tracking (workstation) service is not running.
1961 NO_TRACKING_SERVICE = 1172,1333 NO_TRACKING_SERVICE = 1172,
1962
1963 /// The Volume ID could not be found.1334 /// The Volume ID could not be found.
1964 NO_VOLUME_ID = 1173,1335 NO_VOLUME_ID = 1173,
1965
1966 /// Unable to remove the file to be replaced.1336 /// Unable to remove the file to be replaced.
1967 UNABLE_TO_REMOVE_REPLACED = 1175,1337 UNABLE_TO_REMOVE_REPLACED = 1175,
1968
1969 /// Unable to move the replacement file to the file to be replaced.1338 /// Unable to move the replacement file to the file to be replaced.
1970 /// The file to be replaced has retained its original name.1339 /// The file to be replaced has retained its original name.
1971 UNABLE_TO_MOVE_REPLACEMENT = 1176,1340 UNABLE_TO_MOVE_REPLACEMENT = 1176,
1972
1973 /// Unable to move the replacement file to the file to be replaced.1341 /// Unable to move the replacement file to the file to be replaced.
1974 /// The file to be replaced has been renamed using the backup name.1342 /// The file to be replaced has been renamed using the backup name.
1975 UNABLE_TO_MOVE_REPLACEMENT_2 = 1177,1343 UNABLE_TO_MOVE_REPLACEMENT_2 = 1177,
1976
1977 /// The volume change journal is being deleted.1344 /// The volume change journal is being deleted.
1978 JOURNAL_DELETE_IN_PROGRESS = 1178,1345 JOURNAL_DELETE_IN_PROGRESS = 1178,
1979
1980 /// The volume change journal is not active.1346 /// The volume change journal is not active.
1981 JOURNAL_NOT_ACTIVE = 1179,1347 JOURNAL_NOT_ACTIVE = 1179,
1982
1983 /// A file was found, but it may not be the correct file.1348 /// A file was found, but it may not be the correct file.
1984 POTENTIAL_FILE_FOUND = 1180,1349 POTENTIAL_FILE_FOUND = 1180,
1985
1986 /// The journal entry has been deleted from the journal.1350 /// The journal entry has been deleted from the journal.
1987 JOURNAL_ENTRY_DELETED = 1181,1351 JOURNAL_ENTRY_DELETED = 1181,
1988
1989 /// A system shutdown has already been scheduled.1352 /// A system shutdown has already been scheduled.
1990 SHUTDOWN_IS_SCHEDULED = 1190,1353 SHUTDOWN_IS_SCHEDULED = 1190,
1991
1992 /// The system shutdown cannot be initiated because there are other users logged on to the computer.1354 /// The system shutdown cannot be initiated because there are other users logged on to the computer.
1993 SHUTDOWN_USERS_LOGGED_ON = 1191,1355 SHUTDOWN_USERS_LOGGED_ON = 1191,
1994
1995 /// The specified device name is invalid.1356 /// The specified device name is invalid.
1996 BAD_DEVICE = 1200,1357 BAD_DEVICE = 1200,
1997
1998 /// The device is not currently connected but it is a remembered connection.1358 /// The device is not currently connected but it is a remembered connection.
1999 CONNECTION_UNAVAIL = 1201,1359 CONNECTION_UNAVAIL = 1201,
2000
2001 /// The local device name has a remembered connection to another network resource.1360 /// The local device name has a remembered connection to another network resource.
2002 DEVICE_ALREADY_REMEMBERED = 1202,1361 DEVICE_ALREADY_REMEMBERED = 1202,
2003
2004 /// The network path was either typed incorrectly, does not exist, or the network provider is not currently available.1362 /// The network path was either typed incorrectly, does not exist, or the network provider is not currently available.
2005 /// Please try retyping the path or contact your network administrator.1363 /// Please try retyping the path or contact your network administrator.
2006 NO_NET_OR_BAD_PATH = 1203,1364 NO_NET_OR_BAD_PATH = 1203,
2007
2008 /// The specified network provider name is invalid.1365 /// The specified network provider name is invalid.
2009 BAD_PROVIDER = 1204,1366 BAD_PROVIDER = 1204,
2010
2011 /// Unable to open the network connection profile.1367 /// Unable to open the network connection profile.
2012 CANNOT_OPEN_PROFILE = 1205,1368 CANNOT_OPEN_PROFILE = 1205,
2013
2014 /// The network connection profile is corrupted.1369 /// The network connection profile is corrupted.
2015 BAD_PROFILE = 1206,1370 BAD_PROFILE = 1206,
2016
2017 /// Cannot enumerate a noncontainer.1371 /// Cannot enumerate a noncontainer.
2018 NOT_CONTAINER = 1207,1372 NOT_CONTAINER = 1207,
2019
2020 /// An extended error has occurred.1373 /// An extended error has occurred.
2021 EXTENDED_ERROR = 1208,1374 EXTENDED_ERROR = 1208,
2022
2023 /// The format of the specified group name is invalid.1375 /// The format of the specified group name is invalid.
2024 INVALID_GROUPNAME = 1209,1376 INVALID_GROUPNAME = 1209,
2025
2026 /// The format of the specified computer name is invalid.1377 /// The format of the specified computer name is invalid.
2027 INVALID_COMPUTERNAME = 1210,1378 INVALID_COMPUTERNAME = 1210,
2028
2029 /// The format of the specified event name is invalid.1379 /// The format of the specified event name is invalid.
2030 INVALID_EVENTNAME = 1211,1380 INVALID_EVENTNAME = 1211,
2031
2032 /// The format of the specified domain name is invalid.1381 /// The format of the specified domain name is invalid.
2033 INVALID_DOMAINNAME = 1212,1382 INVALID_DOMAINNAME = 1212,
2034
2035 /// The format of the specified service name is invalid.1383 /// The format of the specified service name is invalid.
2036 INVALID_SERVICENAME = 1213,1384 INVALID_SERVICENAME = 1213,
2037
2038 /// The format of the specified network name is invalid.1385 /// The format of the specified network name is invalid.
2039 INVALID_NETNAME = 1214,1386 INVALID_NETNAME = 1214,
2040
2041 /// The format of the specified share name is invalid.1387 /// The format of the specified share name is invalid.
2042 INVALID_SHARENAME = 1215,1388 INVALID_SHARENAME = 1215,
2043
2044 /// The format of the specified password is invalid.1389 /// The format of the specified password is invalid.
2045 INVALID_PASSWORDNAME = 1216,1390 INVALID_PASSWORDNAME = 1216,
2046
2047 /// The format of the specified message name is invalid.1391 /// The format of the specified message name is invalid.
2048 INVALID_MESSAGENAME = 1217,1392 INVALID_MESSAGENAME = 1217,
2049
2050 /// The format of the specified message destination is invalid.1393 /// The format of the specified message destination is invalid.
2051 INVALID_MESSAGEDEST = 1218,1394 INVALID_MESSAGEDEST = 1218,
2052
2053 /// Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed.1395 /// Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed.
2054 /// Disconnect all previous connections to the server or shared resource and try again.1396 /// Disconnect all previous connections to the server or shared resource and try again.
2055 SESSION_CREDENTIAL_CONFLICT = 1219,1397 SESSION_CREDENTIAL_CONFLICT = 1219,
2056
2057 /// An attempt was made to establish a session to a network server, but there are already too many sessions established to that server.1398 /// An attempt was made to establish a session to a network server, but there are already too many sessions established to that server.
2058 REMOTE_SESSION_LIMIT_EXCEEDED = 1220,1399 REMOTE_SESSION_LIMIT_EXCEEDED = 1220,
2059
2060 /// The workgroup or domain name is already in use by another computer on the network.1400 /// The workgroup or domain name is already in use by another computer on the network.
2061 DUP_DOMAINNAME = 1221,1401 DUP_DOMAINNAME = 1221,
2062
2063 /// The network is not present or not started.1402 /// The network is not present or not started.
2064 NO_NETWORK = 1222,1403 NO_NETWORK = 1222,
2065
2066 /// The operation was canceled by the user.1404 /// The operation was canceled by the user.
2067 CANCELLED = 1223,1405 CANCELLED = 1223,
2068
2069 /// The requested operation cannot be performed on a file with a user-mapped section open.1406 /// The requested operation cannot be performed on a file with a user-mapped section open.
2070 USER_MAPPED_FILE = 1224,1407 USER_MAPPED_FILE = 1224,
2071
2072 /// The remote computer refused the network connection.1408 /// The remote computer refused the network connection.
2073 CONNECTION_REFUSED = 1225,1409 CONNECTION_REFUSED = 1225,
2074
2075 /// The network connection was gracefully closed.1410 /// The network connection was gracefully closed.
2076 GRACEFUL_DISCONNECT = 1226,1411 GRACEFUL_DISCONNECT = 1226,
2077
2078 /// The network transport endpoint already has an address associated with it.1412 /// The network transport endpoint already has an address associated with it.
2079 ADDRESS_ALREADY_ASSOCIATED = 1227,1413 ADDRESS_ALREADY_ASSOCIATED = 1227,
2080
2081 /// An address has not yet been associated with the network endpoint.1414 /// An address has not yet been associated with the network endpoint.
2082 ADDRESS_NOT_ASSOCIATED = 1228,1415 ADDRESS_NOT_ASSOCIATED = 1228,
2083
2084 /// An operation was attempted on a nonexistent network connection.1416 /// An operation was attempted on a nonexistent network connection.
2085 CONNECTION_INVALID = 1229,1417 CONNECTION_INVALID = 1229,
2086
2087 /// An invalid operation was attempted on an active network connection.1418 /// An invalid operation was attempted on an active network connection.
2088 CONNECTION_ACTIVE = 1230,1419 CONNECTION_ACTIVE = 1230,
2089
2090 /// The network location cannot be reached.1420 /// The network location cannot be reached.
2091 /// For information about network troubleshooting, see Windows Help.1421 /// For information about network troubleshooting, see Windows Help.
2092 NETWORK_UNREACHABLE = 1231,1422 NETWORK_UNREACHABLE = 1231,
2093
2094 /// The network location cannot be reached.1423 /// The network location cannot be reached.
2095 /// For information about network troubleshooting, see Windows Help.1424 /// For information about network troubleshooting, see Windows Help.
2096 HOST_UNREACHABLE = 1232,1425 HOST_UNREACHABLE = 1232,
2097
2098 /// The network location cannot be reached.1426 /// The network location cannot be reached.
2099 /// For information about network troubleshooting, see Windows Help.1427 /// For information about network troubleshooting, see Windows Help.
2100 PROTOCOL_UNREACHABLE = 1233,1428 PROTOCOL_UNREACHABLE = 1233,
2101
2102 /// No service is operating at the destination network endpoint on the remote system.1429 /// No service is operating at the destination network endpoint on the remote system.
2103 PORT_UNREACHABLE = 1234,1430 PORT_UNREACHABLE = 1234,
2104
2105 /// The request was aborted.1431 /// The request was aborted.
2106 REQUEST_ABORTED = 1235,1432 REQUEST_ABORTED = 1235,
2107
2108 /// The network connection was aborted by the local system.1433 /// The network connection was aborted by the local system.
2109 CONNECTION_ABORTED = 1236,1434 CONNECTION_ABORTED = 1236,
2110
2111 /// The operation could not be completed. A retry should be performed.1435 /// The operation could not be completed. A retry should be performed.
2112 RETRY = 1237,1436 RETRY = 1237,
2113
2114 /// A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached.1437 /// A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached.
2115 CONNECTION_COUNT_LIMIT = 1238,1438 CONNECTION_COUNT_LIMIT = 1238,
2116
2117 /// Attempting to log in during an unauthorized time of day for this account.1439 /// Attempting to log in during an unauthorized time of day for this account.
2118 LOGIN_TIME_RESTRICTION = 1239,1440 LOGIN_TIME_RESTRICTION = 1239,
2119
2120 /// The account is not authorized to log in from this station.1441 /// The account is not authorized to log in from this station.
2121 LOGIN_WKSTA_RESTRICTION = 1240,1442 LOGIN_WKSTA_RESTRICTION = 1240,
2122
2123 /// The network address could not be used for the operation requested.1443 /// The network address could not be used for the operation requested.
2124 INCORRECT_ADDRESS = 1241,1444 INCORRECT_ADDRESS = 1241,
2125
2126 /// The service is already registered.1445 /// The service is already registered.
2127 ALREADY_REGISTERED = 1242,1446 ALREADY_REGISTERED = 1242,
2128
2129 /// The specified service does not exist.1447 /// The specified service does not exist.
2130 SERVICE_NOT_FOUND = 1243,1448 SERVICE_NOT_FOUND = 1243,
2131
2132 /// The operation being requested was not performed because the user has not been authenticated.1449 /// The operation being requested was not performed because the user has not been authenticated.
2133 NOT_AUTHENTICATED = 1244,1450 NOT_AUTHENTICATED = 1244,
2134
2135 /// The operation being requested was not performed because the user has not logged on to the network. The specified service does not exist.1451 /// The operation being requested was not performed because the user has not logged on to the network. The specified service does not exist.
2136 NOT_LOGGED_ON = 1245,1452 NOT_LOGGED_ON = 1245,
2137
2138 /// Continue with work in progress.1453 /// Continue with work in progress.
2139 CONTINUE = 1246,1454 CONTINUE = 1246,
2140
2141 /// An attempt was made to perform an initialization operation when initialization has already been completed.1455 /// An attempt was made to perform an initialization operation when initialization has already been completed.
2142 ALREADY_INITIALIZED = 1247,1456 ALREADY_INITIALIZED = 1247,
2143
2144 /// No more local devices.1457 /// No more local devices.
2145 NO_MORE_DEVICES = 1248,1458 NO_MORE_DEVICES = 1248,
2146
2147 /// The specified site does not exist.1459 /// The specified site does not exist.
2148 NO_SUCH_SITE = 1249,1460 NO_SUCH_SITE = 1249,
2149
2150 /// A domain controller with the specified name already exists.1461 /// A domain controller with the specified name already exists.
2151 DOMAIN_CONTROLLER_EXISTS = 1250,1462 DOMAIN_CONTROLLER_EXISTS = 1250,
2152
2153 /// This operation is supported only when you are connected to the server.1463 /// This operation is supported only when you are connected to the server.
2154 ONLY_IF_CONNECTED = 1251,1464 ONLY_IF_CONNECTED = 1251,
2155
2156 /// The group policy framework should call the extension even if there are no changes.1465 /// The group policy framework should call the extension even if there are no changes.
2157 OVERRIDE_NOCHANGES = 1252,1466 OVERRIDE_NOCHANGES = 1252,
2158
2159 /// The specified user does not have a valid profile.1467 /// The specified user does not have a valid profile.
2160 BAD_USER_PROFILE = 1253,1468 BAD_USER_PROFILE = 1253,
2161
2162 /// This operation is not supported on a computer running Windows Server 2003 for Small Business Server.1469 /// This operation is not supported on a computer running Windows Server 2003 for Small Business Server.
2163 NOT_SUPPORTED_ON_SBS = 1254,1470 NOT_SUPPORTED_ON_SBS = 1254,
2164
2165 /// The server machine is shutting down.1471 /// The server machine is shutting down.
2166 SERVER_SHUTDOWN_IN_PROGRESS = 1255,1472 SERVER_SHUTDOWN_IN_PROGRESS = 1255,
2167
2168 /// The remote system is not available.1473 /// The remote system is not available.
2169 /// For information about network troubleshooting, see Windows Help.1474 /// For information about network troubleshooting, see Windows Help.
2170 HOST_DOWN = 1256,1475 HOST_DOWN = 1256,
2171
2172 /// The security identifier provided is not from an account domain.1476 /// The security identifier provided is not from an account domain.
2173 NON_ACCOUNT_SID = 1257,1477 NON_ACCOUNT_SID = 1257,
2174
2175 /// The security identifier provided does not have a domain component.1478 /// The security identifier provided does not have a domain component.
2176 NON_DOMAIN_SID = 1258,1479 NON_DOMAIN_SID = 1258,
2177
2178 /// AppHelp dialog canceled thus preventing the application from starting.1480 /// AppHelp dialog canceled thus preventing the application from starting.
2179 APPHELP_BLOCK = 1259,1481 APPHELP_BLOCK = 1259,
2180
2181 /// This program is blocked by group policy.1482 /// This program is blocked by group policy.
2182 /// For more information, contact your system administrator.1483 /// For more information, contact your system administrator.
2183 ACCESS_DISABLED_BY_POLICY = 1260,1484 ACCESS_DISABLED_BY_POLICY = 1260,
2184
2185 /// A program attempt to use an invalid register value.1485 /// A program attempt to use an invalid register value.
2186 /// Normally caused by an uninitialized register. This error is Itanium specific.1486 /// Normally caused by an uninitialized register. This error is Itanium specific.
2187 REG_NAT_CONSUMPTION = 1261,1487 REG_NAT_CONSUMPTION = 1261,
2188
2189 /// The share is currently offline or does not exist.1488 /// The share is currently offline or does not exist.
2190 CSCSHARE_OFFLINE = 1262,1489 CSCSHARE_OFFLINE = 1262,
2191
2192 /// The Kerberos protocol encountered an error while validating the KDC certificate during smartcard logon.1490 /// The Kerberos protocol encountered an error while validating the KDC certificate during smartcard logon.
2193 /// There is more information in the system event log.1491 /// There is more information in the system event log.
2194 PKINIT_FAILURE = 1263,1492 PKINIT_FAILURE = 1263,
2195
2196 /// The Kerberos protocol encountered an error while attempting to utilize the smartcard subsystem.1493 /// The Kerberos protocol encountered an error while attempting to utilize the smartcard subsystem.
2197 SMARTCARD_SUBSYSTEM_FAILURE = 1264,1494 SMARTCARD_SUBSYSTEM_FAILURE = 1264,
2198
2199 /// The system cannot contact a domain controller to service the authentication request. Please try again later.1495 /// The system cannot contact a domain controller to service the authentication request. Please try again later.
2200 DOWNGRADE_DETECTED = 1265,1496 DOWNGRADE_DETECTED = 1265,
2201
2202 /// The machine is locked and cannot be shut down without the force option.1497 /// The machine is locked and cannot be shut down without the force option.
2203 MACHINE_LOCKED = 1271,1498 MACHINE_LOCKED = 1271,
2204
2205 /// An application-defined callback gave invalid data when called.1499 /// An application-defined callback gave invalid data when called.
2206 CALLBACK_SUPPLIED_INVALID_DATA = 1273,1500 CALLBACK_SUPPLIED_INVALID_DATA = 1273,
2207
2208 /// The group policy framework should call the extension in the synchronous foreground policy refresh.1501 /// The group policy framework should call the extension in the synchronous foreground policy refresh.
2209 SYNC_FOREGROUND_REFRESH_REQUIRED = 1274,1502 SYNC_FOREGROUND_REFRESH_REQUIRED = 1274,
2210
2211 /// This driver has been blocked from loading.1503 /// This driver has been blocked from loading.
2212 DRIVER_BLOCKED = 1275,1504 DRIVER_BLOCKED = 1275,
2213
2214 /// A dynamic link library (DLL) referenced a module that was neither a DLL nor the process's executable image.1505 /// A dynamic link library (DLL) referenced a module that was neither a DLL nor the process's executable image.
2215 INVALID_IMPORT_OF_NON_DLL = 1276,1506 INVALID_IMPORT_OF_NON_DLL = 1276,
2216
2217 /// Windows cannot open this program since it has been disabled.1507 /// Windows cannot open this program since it has been disabled.
2218 ACCESS_DISABLED_WEBBLADE = 1277,1508 ACCESS_DISABLED_WEBBLADE = 1277,
2219
2220 /// Windows cannot open this program because the license enforcement system has been tampered with or become corrupted.1509 /// Windows cannot open this program because the license enforcement system has been tampered with or become corrupted.
2221 ACCESS_DISABLED_WEBBLADE_TAMPER = 1278,1510 ACCESS_DISABLED_WEBBLADE_TAMPER = 1278,
2222
2223 /// A transaction recover failed.1511 /// A transaction recover failed.
2224 RECOVERY_FAILURE = 1279,1512 RECOVERY_FAILURE = 1279,
2225
2226 /// The current thread has already been converted to a fiber.1513 /// The current thread has already been converted to a fiber.
2227 ALREADY_FIBER = 1280,1514 ALREADY_FIBER = 1280,
2228
2229 /// The current thread has already been converted from a fiber.1515 /// The current thread has already been converted from a fiber.
2230 ALREADY_THREAD = 1281,1516 ALREADY_THREAD = 1281,
2231
2232 /// The system detected an overrun of a stack-based buffer in this application.1517 /// The system detected an overrun of a stack-based buffer in this application.
2233 /// This overrun could potentially allow a malicious user to gain control of this application.1518 /// This overrun could potentially allow a malicious user to gain control of this application.
2234 STACK_BUFFER_OVERRUN = 1282,1519 STACK_BUFFER_OVERRUN = 1282,
2235
2236 /// Data present in one of the parameters is more than the function can operate on.1520 /// Data present in one of the parameters is more than the function can operate on.
2237 PARAMETER_QUOTA_EXCEEDED = 1283,1521 PARAMETER_QUOTA_EXCEEDED = 1283,
2238
2239 /// An attempt to do an operation on a debug object failed because the object is in the process of being deleted.1522 /// An attempt to do an operation on a debug object failed because the object is in the process of being deleted.
2240 DEBUGGER_INACTIVE = 1284,1523 DEBUGGER_INACTIVE = 1284,
2241
2242 /// An attempt to delay-load a .dll or get a function address in a delay-loaded .dll failed.1524 /// An attempt to delay-load a .dll or get a function address in a delay-loaded .dll failed.
2243 DELAY_LOAD_FAILED = 1285,1525 DELAY_LOAD_FAILED = 1285,
2244
2245 /// %1 is a 16-bit application. You do not have permissions to execute 16-bit applications.1526 /// %1 is a 16-bit application. You do not have permissions to execute 16-bit applications.
2246 /// Check your permissions with your system administrator.1527 /// Check your permissions with your system administrator.
2247 VDM_DISALLOWED = 1286,1528 VDM_DISALLOWED = 1286,
2248
2249 /// Insufficient information exists to identify the cause of failure.1529 /// Insufficient information exists to identify the cause of failure.
2250 UNIDENTIFIED_ERROR = 1287,1530 UNIDENTIFIED_ERROR = 1287,
2251
2252 /// The parameter passed to a C runtime function is incorrect.1531 /// The parameter passed to a C runtime function is incorrect.
2253 INVALID_CRUNTIME_PARAMETER = 1288,1532 INVALID_CRUNTIME_PARAMETER = 1288,
2254
2255 /// The operation occurred beyond the valid data length of the file.1533 /// The operation occurred beyond the valid data length of the file.
2256 BEYOND_VDL = 1289,1534 BEYOND_VDL = 1289,
2257
2258 /// The service start failed since one or more services in the same process have an incompatible service SID type setting.1535 /// The service start failed since one or more services in the same process have an incompatible service SID type setting.
2259 /// A service with restricted service SID type can only coexist in the same process with other services with a restricted SID type.1536 /// A service with restricted service SID type can only coexist in the same process with other services with a restricted SID type.
2260 /// If the service SID type for this service was just configured, the hosting process must be restarted in order to start this service.1537 /// If the service SID type for this service was just configured, the hosting process must be restarted in order to start this service.
2261 /// On Windows Server 2003 and Windows XP, an unrestricted service cannot coexist in the same process with other services.1538 /// On Windows Server 2003 and Windows XP, an unrestricted service cannot coexist in the same process with other services.
2262 /// The service with the unrestricted service SID type must be moved to an owned process in order to start this service.1539 /// The service with the unrestricted service SID type must be moved to an owned process in order to start this service.
2263 INCOMPATIBLE_SERVICE_SID_TYPE = 1290,1540 INCOMPATIBLE_SERVICE_SID_TYPE = 1290,
2264
2265 /// The process hosting the driver for this device has been terminated.1541 /// The process hosting the driver for this device has been terminated.
2266 DRIVER_PROCESS_TERMINATED = 1291,1542 DRIVER_PROCESS_TERMINATED = 1291,
2267
2268 /// An operation attempted to exceed an implementation-defined limit.1543 /// An operation attempted to exceed an implementation-defined limit.
2269 IMPLEMENTATION_LIMIT = 1292,1544 IMPLEMENTATION_LIMIT = 1292,
2270
2271 /// Either the target process, or the target thread's containing process, is a protected process.1545 /// Either the target process, or the target thread's containing process, is a protected process.
2272 PROCESS_IS_PROTECTED = 1293,1546 PROCESS_IS_PROTECTED = 1293,
2273
2274 /// The service notification client is lagging too far behind the current state of services in the machine.1547 /// The service notification client is lagging too far behind the current state of services in the machine.
2275 SERVICE_NOTIFY_CLIENT_LAGGING = 1294,1548 SERVICE_NOTIFY_CLIENT_LAGGING = 1294,
2276
2277 /// The requested file operation failed because the storage quota was exceeded.1549 /// The requested file operation failed because the storage quota was exceeded.
2278 /// To free up disk space, move files to a different location or delete unnecessary files.1550 /// To free up disk space, move files to a different location or delete unnecessary files.
2279 /// For more information, contact your system administrator.1551 /// For more information, contact your system administrator.
2280 DISK_QUOTA_EXCEEDED = 1295,1552 DISK_QUOTA_EXCEEDED = 1295,
2281
2282 /// The requested file operation failed because the storage policy blocks that type of file.1553 /// The requested file operation failed because the storage policy blocks that type of file.
2283 /// For more information, contact your system administrator.1554 /// For more information, contact your system administrator.
2284 CONTENT_BLOCKED = 1296,1555 CONTENT_BLOCKED = 1296,
2285
2286 /// A privilege that the service requires to function properly does not exist in the service account configuration.1556 /// A privilege that the service requires to function properly does not exist in the service account configuration.
2287 /// You may use the Services Microsoft Management Console (MMC) snap-in (services.msc) and the Local Security Settings MMC snap-in (secpol.msc) to view the service configuration and the account configuration.1557 /// You may use the Services Microsoft Management Console (MMC) snap-in (services.msc) and the Local Security Settings MMC snap-in (secpol.msc) to view the service configuration and the account configuration.
2288 INCOMPATIBLE_SERVICE_PRIVILEGE = 1297,1558 INCOMPATIBLE_SERVICE_PRIVILEGE = 1297,
2289
2290 /// A thread involved in this operation appears to be unresponsive.1559 /// A thread involved in this operation appears to be unresponsive.
2291 APP_HANG = 1298,1560 APP_HANG = 1298,
2292
2293 /// Indicates a particular Security ID may not be assigned as the label of an object.1561 /// Indicates a particular Security ID may not be assigned as the label of an object.
2294 INVALID_LABEL = 1299,1562 INVALID_LABEL = 1299,
2295
2296 /// Not all privileges or groups referenced are assigned to the caller.1563 /// Not all privileges or groups referenced are assigned to the caller.
2297 NOT_ALL_ASSIGNED = 1300,1564 NOT_ALL_ASSIGNED = 1300,
2298
2299 /// Some mapping between account names and security IDs was not done.1565 /// Some mapping between account names and security IDs was not done.
2300 SOME_NOT_MAPPED = 1301,1566 SOME_NOT_MAPPED = 1301,
2301
2302 /// No system quota limits are specifically set for this account.1567 /// No system quota limits are specifically set for this account.
2303 NO_QUOTAS_FOR_ACCOUNT = 1302,1568 NO_QUOTAS_FOR_ACCOUNT = 1302,
2304
2305 /// No encryption key is available. A well-known encryption key was returned.1569 /// No encryption key is available. A well-known encryption key was returned.
2306 LOCAL_USER_SESSION_KEY = 1303,1570 LOCAL_USER_SESSION_KEY = 1303,
2307
2308 /// The password is too complex to be converted to a LAN Manager password.1571 /// The password is too complex to be converted to a LAN Manager password.
2309 /// The LAN Manager password returned is a NULL string.1572 /// The LAN Manager password returned is a NULL string.
2310 NULL_LM_PASSWORD = 1304,1573 NULL_LM_PASSWORD = 1304,
2311
2312 /// The revision level is unknown.1574 /// The revision level is unknown.
2313 UNKNOWN_REVISION = 1305,1575 UNKNOWN_REVISION = 1305,
2314
2315 /// Indicates two revision levels are incompatible.1576 /// Indicates two revision levels are incompatible.
2316 REVISION_MISMATCH = 1306,1577 REVISION_MISMATCH = 1306,
2317
2318 /// This security ID may not be assigned as the owner of this object.1578 /// This security ID may not be assigned as the owner of this object.
2319 INVALID_OWNER = 1307,1579 INVALID_OWNER = 1307,
2320
2321 /// This security ID may not be assigned as the primary group of an object.1580 /// This security ID may not be assigned as the primary group of an object.
2322 INVALID_PRIMARY_GROUP = 1308,1581 INVALID_PRIMARY_GROUP = 1308,
2323
2324 /// An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client.1582 /// An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client.
2325 NO_IMPERSONATION_TOKEN = 1309,1583 NO_IMPERSONATION_TOKEN = 1309,
2326
2327 /// The group may not be disabled.1584 /// The group may not be disabled.
2328 CANT_DISABLE_MANDATORY = 1310,1585 CANT_DISABLE_MANDATORY = 1310,
2329
2330 /// There are currently no logon servers available to service the logon request.1586 /// There are currently no logon servers available to service the logon request.
2331 NO_LOGON_SERVERS = 1311,1587 NO_LOGON_SERVERS = 1311,
2332
2333 /// A specified logon session does not exist. It may already have been terminated.1588 /// A specified logon session does not exist. It may already have been terminated.
2334 NO_SUCH_LOGON_SESSION = 1312,1589 NO_SUCH_LOGON_SESSION = 1312,
2335
2336 /// A specified privilege does not exist.1590 /// A specified privilege does not exist.
2337 NO_SUCH_PRIVILEGE = 1313,1591 NO_SUCH_PRIVILEGE = 1313,
2338
2339 /// A required privilege is not held by the client.1592 /// A required privilege is not held by the client.
2340 PRIVILEGE_NOT_HELD = 1314,1593 PRIVILEGE_NOT_HELD = 1314,
2341
2342 /// The name provided is not a properly formed account name.1594 /// The name provided is not a properly formed account name.
2343 INVALID_ACCOUNT_NAME = 1315,1595 INVALID_ACCOUNT_NAME = 1315,
2344
2345 /// The specified account already exists.1596 /// The specified account already exists.
2346 USER_EXISTS = 1316,1597 USER_EXISTS = 1316,
2347
2348 /// The specified account does not exist.1598 /// The specified account does not exist.
2349 NO_SUCH_USER = 1317,1599 NO_SUCH_USER = 1317,
2350
2351 /// The specified group already exists.1600 /// The specified group already exists.
2352 GROUP_EXISTS = 1318,1601 GROUP_EXISTS = 1318,
2353
2354 /// The specified group does not exist.1602 /// The specified group does not exist.
2355 NO_SUCH_GROUP = 1319,1603 NO_SUCH_GROUP = 1319,
2356
2357 /// Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member.1604 /// Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member.
2358 MEMBER_IN_GROUP = 1320,1605 MEMBER_IN_GROUP = 1320,
2359
2360 /// The specified user account is not a member of the specified group account.1606 /// The specified user account is not a member of the specified group account.
2361 MEMBER_NOT_IN_GROUP = 1321,1607 MEMBER_NOT_IN_GROUP = 1321,
2362
2363 /// This operation is disallowed as it could result in an administration account being disabled, deleted or unable to log on.1608 /// This operation is disallowed as it could result in an administration account being disabled, deleted or unable to log on.
2364 LAST_ADMIN = 1322,1609 LAST_ADMIN = 1322,
2365
2366 /// Unable to update the password. The value provided as the current password is incorrect.1610 /// Unable to update the password. The value provided as the current password is incorrect.
2367 WRONG_PASSWORD = 1323,1611 WRONG_PASSWORD = 1323,
2368
2369 /// Unable to update the password. The value provided for the new password contains values that are not allowed in passwords.1612 /// Unable to update the password. The value provided for the new password contains values that are not allowed in passwords.
2370 ILL_FORMED_PASSWORD = 1324,1613 ILL_FORMED_PASSWORD = 1324,
2371
2372 /// Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain.1614 /// Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain.
2373 PASSWORD_RESTRICTION = 1325,1615 PASSWORD_RESTRICTION = 1325,
2374
2375 /// The user name or password is incorrect.1616 /// The user name or password is incorrect.
2376 LOGON_FAILURE = 1326,1617 LOGON_FAILURE = 1326,
2377
2378 /// Account restrictions are preventing this user from signing in.1618 /// Account restrictions are preventing this user from signing in.
2379 /// For example: blank passwords aren't allowed, sign-in times are limited, or a policy restriction has been enforced.1619 /// For example: blank passwords aren't allowed, sign-in times are limited, or a policy restriction has been enforced.
2380 ACCOUNT_RESTRICTION = 1327,1620 ACCOUNT_RESTRICTION = 1327,
2381
2382 /// Your account has time restrictions that keep you from signing in right now.1621 /// Your account has time restrictions that keep you from signing in right now.
2383 INVALID_LOGON_HOURS = 1328,1622 INVALID_LOGON_HOURS = 1328,
2384
2385 /// This user isn't allowed to sign in to this computer.1623 /// This user isn't allowed to sign in to this computer.
2386 INVALID_WORKSTATION = 1329,1624 INVALID_WORKSTATION = 1329,
2387
2388 /// The password for this account has expired.1625 /// The password for this account has expired.
2389 PASSWORD_EXPIRED = 1330,1626 PASSWORD_EXPIRED = 1330,
2390
2391 /// This user can't sign in because this account is currently disabled.1627 /// This user can't sign in because this account is currently disabled.
2392 ACCOUNT_DISABLED = 1331,1628 ACCOUNT_DISABLED = 1331,
2393
2394 /// No mapping between account names and security IDs was done.1629 /// No mapping between account names and security IDs was done.
2395 NONE_MAPPED = 1332,1630 NONE_MAPPED = 1332,
2396
2397 /// Too many local user identifiers (LUIDs) were requested at one time.1631 /// Too many local user identifiers (LUIDs) were requested at one time.
2398 TOO_MANY_LUIDS_REQUESTED = 1333,1632 TOO_MANY_LUIDS_REQUESTED = 1333,
2399
2400 /// No more local user identifiers (LUIDs) are available.1633 /// No more local user identifiers (LUIDs) are available.
2401 LUIDS_EXHAUSTED = 1334,1634 LUIDS_EXHAUSTED = 1334,
2402
2403 /// The subauthority part of a security ID is invalid for this particular use.1635 /// The subauthority part of a security ID is invalid for this particular use.
2404 INVALID_SUB_AUTHORITY = 1335,1636 INVALID_SUB_AUTHORITY = 1335,
2405
2406 /// The access control list (ACL) structure is invalid.1637 /// The access control list (ACL) structure is invalid.
2407 INVALID_ACL = 1336,1638 INVALID_ACL = 1336,
2408
2409 /// The security ID structure is invalid.1639 /// The security ID structure is invalid.
2410 INVALID_SID = 1337,1640 INVALID_SID = 1337,
2411
2412 /// The security descriptor structure is invalid.1641 /// The security descriptor structure is invalid.
2413 INVALID_SECURITY_DESCR = 1338,1642 INVALID_SECURITY_DESCR = 1338,
2414
2415 /// The inherited access control list (ACL) or access control entry (ACE) could not be built.1643 /// The inherited access control list (ACL) or access control entry (ACE) could not be built.
2416 BAD_INHERITANCE_ACL = 1340,1644 BAD_INHERITANCE_ACL = 1340,
2417
2418 /// The server is currently disabled.1645 /// The server is currently disabled.
2419 SERVER_DISABLED = 1341,1646 SERVER_DISABLED = 1341,
2420
2421 /// The server is currently enabled.1647 /// The server is currently enabled.
2422 SERVER_NOT_DISABLED = 1342,1648 SERVER_NOT_DISABLED = 1342,
2423
2424 /// The value provided was an invalid value for an identifier authority.1649 /// The value provided was an invalid value for an identifier authority.
2425 INVALID_ID_AUTHORITY = 1343,1650 INVALID_ID_AUTHORITY = 1343,
2426
2427 /// No more memory is available for security information updates.1651 /// No more memory is available for security information updates.
2428 ALLOTTED_SPACE_EXCEEDED = 1344,1652 ALLOTTED_SPACE_EXCEEDED = 1344,
2429
2430 /// The specified attributes are invalid, or incompatible with the attributes for the group as a whole.1653 /// The specified attributes are invalid, or incompatible with the attributes for the group as a whole.
2431 INVALID_GROUP_ATTRIBUTES = 1345,1654 INVALID_GROUP_ATTRIBUTES = 1345,
2432
2433 /// Either a required impersonation level was not provided, or the provided impersonation level is invalid.1655 /// Either a required impersonation level was not provided, or the provided impersonation level is invalid.
2434 BAD_IMPERSONATION_LEVEL = 1346,1656 BAD_IMPERSONATION_LEVEL = 1346,
2435
2436 /// Cannot open an anonymous level security token.1657 /// Cannot open an anonymous level security token.
2437 CANT_OPEN_ANONYMOUS = 1347,1658 CANT_OPEN_ANONYMOUS = 1347,
2438
2439 /// The validation information class requested was invalid.1659 /// The validation information class requested was invalid.
2440 BAD_VALIDATION_CLASS = 1348,1660 BAD_VALIDATION_CLASS = 1348,
2441
2442 /// The type of the token is inappropriate for its attempted use.1661 /// The type of the token is inappropriate for its attempted use.
2443 BAD_TOKEN_TYPE = 1349,1662 BAD_TOKEN_TYPE = 1349,
2444
2445 /// Unable to perform a security operation on an object that has no associated security.1663 /// Unable to perform a security operation on an object that has no associated security.
2446 NO_SECURITY_ON_OBJECT = 1350,1664 NO_SECURITY_ON_OBJECT = 1350,
2447
2448 /// Configuration information could not be read from the domain controller, either because the machine is unavailable, or access has been denied.1665 /// Configuration information could not be read from the domain controller, either because the machine is unavailable, or access has been denied.
2449 CANT_ACCESS_DOMAIN_INFO = 1351,1666 CANT_ACCESS_DOMAIN_INFO = 1351,
2450
2451 /// The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation.1667 /// The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation.
2452 INVALID_SERVER_STATE = 1352,1668 INVALID_SERVER_STATE = 1352,
2453
2454 /// The domain was in the wrong state to perform the security operation.1669 /// The domain was in the wrong state to perform the security operation.
2455 INVALID_DOMAIN_STATE = 1353,1670 INVALID_DOMAIN_STATE = 1353,
2456
2457 /// This operation is only allowed for the Primary Domain Controller of the domain.1671 /// This operation is only allowed for the Primary Domain Controller of the domain.
2458 INVALID_DOMAIN_ROLE = 1354,1672 INVALID_DOMAIN_ROLE = 1354,
2459
2460 /// The specified domain either does not exist or could not be contacted.1673 /// The specified domain either does not exist or could not be contacted.
2461 NO_SUCH_DOMAIN = 1355,1674 NO_SUCH_DOMAIN = 1355,
2462
2463 /// The specified domain already exists.1675 /// The specified domain already exists.
2464 DOMAIN_EXISTS = 1356,1676 DOMAIN_EXISTS = 1356,
2465
2466 /// An attempt was made to exceed the limit on the number of domains per server.1677 /// An attempt was made to exceed the limit on the number of domains per server.
2467 DOMAIN_LIMIT_EXCEEDED = 1357,1678 DOMAIN_LIMIT_EXCEEDED = 1357,
2468
2469 /// Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk.1679 /// Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk.
2470 INTERNAL_DB_CORRUPTION = 1358,1680 INTERNAL_DB_CORRUPTION = 1358,
2471
2472 /// An internal error occurred.1681 /// An internal error occurred.
2473 INTERNAL_ERROR = 1359,1682 INTERNAL_ERROR = 1359,
2474
2475 /// Generic access types were contained in an access mask which should already be mapped to nongeneric types.1683 /// Generic access types were contained in an access mask which should already be mapped to nongeneric types.
2476 GENERIC_NOT_MAPPED = 1360,1684 GENERIC_NOT_MAPPED = 1360,
2477
2478 /// A security descriptor is not in the right format (absolute or self-relative).1685 /// A security descriptor is not in the right format (absolute or self-relative).
2479 BAD_DESCRIPTOR_FORMAT = 1361,1686 BAD_DESCRIPTOR_FORMAT = 1361,
2480
2481 /// The requested action is restricted for use by logon processes only.1687 /// The requested action is restricted for use by logon processes only.
2482 /// The calling process has not registered as a logon process.1688 /// The calling process has not registered as a logon process.
2483 NOT_LOGON_PROCESS = 1362,1689 NOT_LOGON_PROCESS = 1362,
2484
2485 /// Cannot start a new logon session with an ID that is already in use.1690 /// Cannot start a new logon session with an ID that is already in use.
2486 LOGON_SESSION_EXISTS = 1363,1691 LOGON_SESSION_EXISTS = 1363,
2487
2488 /// A specified authentication package is unknown.1692 /// A specified authentication package is unknown.
2489 NO_SUCH_PACKAGE = 1364,1693 NO_SUCH_PACKAGE = 1364,
2490
2491 /// The logon session is not in a state that is consistent with the requested operation.1694 /// The logon session is not in a state that is consistent with the requested operation.
2492 BAD_LOGON_SESSION_STATE = 1365,1695 BAD_LOGON_SESSION_STATE = 1365,
2493
2494 /// The logon session ID is already in use.1696 /// The logon session ID is already in use.
2495 LOGON_SESSION_COLLISION = 1366,1697 LOGON_SESSION_COLLISION = 1366,
2496
2497 /// A logon request contained an invalid logon type value.1698 /// A logon request contained an invalid logon type value.
2498 INVALID_LOGON_TYPE = 1367,1699 INVALID_LOGON_TYPE = 1367,
2499
2500 /// Unable to impersonate using a named pipe until data has been read from that pipe.1700 /// Unable to impersonate using a named pipe until data has been read from that pipe.
2501 CANNOT_IMPERSONATE = 1368,1701 CANNOT_IMPERSONATE = 1368,
2502
2503 /// The transaction state of a registry subtree is incompatible with the requested operation.1702 /// The transaction state of a registry subtree is incompatible with the requested operation.
2504 RXACT_INVALID_STATE = 1369,1703 RXACT_INVALID_STATE = 1369,
2505
2506 /// An internal security database corruption has been encountered.1704 /// An internal security database corruption has been encountered.
2507 RXACT_COMMIT_FAILURE = 1370,1705 RXACT_COMMIT_FAILURE = 1370,
2508
2509 /// Cannot perform this operation on built-in accounts.1706 /// Cannot perform this operation on built-in accounts.
2510 SPECIAL_ACCOUNT = 1371,1707 SPECIAL_ACCOUNT = 1371,
2511
2512 /// Cannot perform this operation on this built-in special group.1708 /// Cannot perform this operation on this built-in special group.
2513 SPECIAL_GROUP = 1372,1709 SPECIAL_GROUP = 1372,
2514
2515 /// Cannot perform this operation on this built-in special user.1710 /// Cannot perform this operation on this built-in special user.
2516 SPECIAL_USER = 1373,1711 SPECIAL_USER = 1373,
2517
2518 /// The user cannot be removed from a group because the group is currently the user's primary group.1712 /// The user cannot be removed from a group because the group is currently the user's primary group.
2519 MEMBERS_PRIMARY_GROUP = 1374,1713 MEMBERS_PRIMARY_GROUP = 1374,
2520
2521 /// The token is already in use as a primary token.1714 /// The token is already in use as a primary token.
2522 TOKEN_ALREADY_IN_USE = 1375,1715 TOKEN_ALREADY_IN_USE = 1375,
2523
2524 /// The specified local group does not exist.1716 /// The specified local group does not exist.
2525 NO_SUCH_ALIAS = 1376,1717 NO_SUCH_ALIAS = 1376,
2526
2527 /// The specified account name is not a member of the group.1718 /// The specified account name is not a member of the group.
2528 MEMBER_NOT_IN_ALIAS = 1377,1719 MEMBER_NOT_IN_ALIAS = 1377,
2529
2530 /// The specified account name is already a member of the group.1720 /// The specified account name is already a member of the group.
2531 MEMBER_IN_ALIAS = 1378,1721 MEMBER_IN_ALIAS = 1378,
2532
2533 /// The specified local group already exists.1722 /// The specified local group already exists.
2534 ALIAS_EXISTS = 1379,1723 ALIAS_EXISTS = 1379,
2535
2536 /// Logon failure: the user has not been granted the requested logon type at this computer.1724 /// Logon failure: the user has not been granted the requested logon type at this computer.
2537 LOGON_NOT_GRANTED = 1380,1725 LOGON_NOT_GRANTED = 1380,
2538
2539 /// The maximum number of secrets that may be stored in a single system has been exceeded.1726 /// The maximum number of secrets that may be stored in a single system has been exceeded.
2540 TOO_MANY_SECRETS = 1381,1727 TOO_MANY_SECRETS = 1381,
2541
2542 /// The length of a secret exceeds the maximum length allowed.1728 /// The length of a secret exceeds the maximum length allowed.
2543 SECRET_TOO_LONG = 1382,1729 SECRET_TOO_LONG = 1382,
2544
2545 /// The local security authority database contains an internal inconsistency.1730 /// The local security authority database contains an internal inconsistency.
2546 INTERNAL_DB_ERROR = 1383,1731 INTERNAL_DB_ERROR = 1383,
2547
2548 /// During a logon attempt, the user's security context accumulated too many security IDs.1732 /// During a logon attempt, the user's security context accumulated too many security IDs.
2549 TOO_MANY_CONTEXT_IDS = 1384,1733 TOO_MANY_CONTEXT_IDS = 1384,
2550
2551 /// Logon failure: the user has not been granted the requested logon type at this computer.1734 /// Logon failure: the user has not been granted the requested logon type at this computer.
2552 LOGON_TYPE_NOT_GRANTED = 1385,1735 LOGON_TYPE_NOT_GRANTED = 1385,
2553
2554 /// A cross-encrypted password is necessary to change a user password.1736 /// A cross-encrypted password is necessary to change a user password.
2555 NT_CROSS_ENCRYPTION_REQUIRED = 1386,1737 NT_CROSS_ENCRYPTION_REQUIRED = 1386,
2556
2557 /// A member could not be added to or removed from the local group because the member does not exist.1738 /// A member could not be added to or removed from the local group because the member does not exist.
2558 NO_SUCH_MEMBER = 1387,1739 NO_SUCH_MEMBER = 1387,
2559
2560 /// A new member could not be added to a local group because the member has the wrong account type.1740 /// A new member could not be added to a local group because the member has the wrong account type.
2561 INVALID_MEMBER = 1388,1741 INVALID_MEMBER = 1388,
2562
2563 /// Too many security IDs have been specified.1742 /// Too many security IDs have been specified.
2564 TOO_MANY_SIDS = 1389,1743 TOO_MANY_SIDS = 1389,
2565
2566 /// A cross-encrypted password is necessary to change this user password.1744 /// A cross-encrypted password is necessary to change this user password.
2567 LM_CROSS_ENCRYPTION_REQUIRED = 1390,1745 LM_CROSS_ENCRYPTION_REQUIRED = 1390,
2568
2569 /// Indicates an ACL contains no inheritable components.1746 /// Indicates an ACL contains no inheritable components.
2570 NO_INHERITANCE = 1391,1747 NO_INHERITANCE = 1391,
2571
2572 /// The file or directory is corrupted and unreadable.1748 /// The file or directory is corrupted and unreadable.
2573 FILE_CORRUPT = 1392,1749 FILE_CORRUPT = 1392,
2574
2575 /// The disk structure is corrupted and unreadable.1750 /// The disk structure is corrupted and unreadable.
2576 DISK_CORRUPT = 1393,1751 DISK_CORRUPT = 1393,
2577
2578 /// There is no user session key for the specified logon session.1752 /// There is no user session key for the specified logon session.
2579 NO_USER_SESSION_KEY = 1394,1753 NO_USER_SESSION_KEY = 1394,
2580
2581 /// The service being accessed is licensed for a particular number of connections.1754 /// The service being accessed is licensed for a particular number of connections.
2582 /// No more connections can be made to the service at this time because there are already as many connections as the service can accept.1755 /// No more connections can be made to the service at this time because there are already as many connections as the service can accept.
2583 LICENSE_QUOTA_EXCEEDED = 1395,1756 LICENSE_QUOTA_EXCEEDED = 1395,
2584
2585 /// The target account name is incorrect.1757 /// The target account name is incorrect.
2586 WRONG_TARGET_NAME = 1396,1758 WRONG_TARGET_NAME = 1396,
2587
2588 /// Mutual Authentication failed. The server's password is out of date at the domain controller.1759 /// Mutual Authentication failed. The server's password is out of date at the domain controller.
2589 MUTUAL_AUTH_FAILED = 1397,1760 MUTUAL_AUTH_FAILED = 1397,
2590
2591 /// There is a time and/or date difference between the client and server.1761 /// There is a time and/or date difference between the client and server.
2592 TIME_SKEW = 1398,1762 TIME_SKEW = 1398,
2593
2594 /// This operation cannot be performed on the current domain.1763 /// This operation cannot be performed on the current domain.
2595 CURRENT_DOMAIN_NOT_ALLOWED = 1399,1764 CURRENT_DOMAIN_NOT_ALLOWED = 1399,
2596
2597 /// Invalid window handle.1765 /// Invalid window handle.
2598 INVALID_WINDOW_HANDLE = 1400,1766 INVALID_WINDOW_HANDLE = 1400,
2599
2600 /// Invalid menu handle.1767 /// Invalid menu handle.
2601 INVALID_MENU_HANDLE = 1401,1768 INVALID_MENU_HANDLE = 1401,
2602
2603 /// Invalid cursor handle.1769 /// Invalid cursor handle.
2604 INVALID_CURSOR_HANDLE = 1402,1770 INVALID_CURSOR_HANDLE = 1402,
2605
2606 /// Invalid accelerator table handle.1771 /// Invalid accelerator table handle.
2607 INVALID_ACCEL_HANDLE = 1403,1772 INVALID_ACCEL_HANDLE = 1403,
2608
2609 /// Invalid hook handle.1773 /// Invalid hook handle.
2610 INVALID_HOOK_HANDLE = 1404,1774 INVALID_HOOK_HANDLE = 1404,
2611
2612 /// Invalid handle to a multiple-window position structure.1775 /// Invalid handle to a multiple-window position structure.
2613 INVALID_DWP_HANDLE = 1405,1776 INVALID_DWP_HANDLE = 1405,
2614
2615 /// Cannot create a top-level child window.1777 /// Cannot create a top-level child window.
2616 TLW_WITH_WSCHILD = 1406,1778 TLW_WITH_WSCHILD = 1406,
2617
2618 /// Cannot find window class.1779 /// Cannot find window class.
2619 CANNOT_FIND_WND_CLASS = 1407,1780 CANNOT_FIND_WND_CLASS = 1407,
2620
2621 /// Invalid window; it belongs to other thread.1781 /// Invalid window; it belongs to other thread.
2622 WINDOW_OF_OTHER_THREAD = 1408,1782 WINDOW_OF_OTHER_THREAD = 1408,
2623
2624 /// Hot key is already registered.1783 /// Hot key is already registered.
2625 HOTKEY_ALREADY_REGISTERED = 1409,1784 HOTKEY_ALREADY_REGISTERED = 1409,
2626
2627 /// Class already exists.1785 /// Class already exists.
2628 CLASS_ALREADY_EXISTS = 1410,1786 CLASS_ALREADY_EXISTS = 1410,
2629
2630 /// Class does not exist.1787 /// Class does not exist.
2631 CLASS_DOES_NOT_EXIST = 1411,1788 CLASS_DOES_NOT_EXIST = 1411,
2632
2633 /// Class still has open windows.1789 /// Class still has open windows.
2634 CLASS_HAS_WINDOWS = 1412,1790 CLASS_HAS_WINDOWS = 1412,
2635
2636 /// Invalid index.1791 /// Invalid index.
2637 INVALID_INDEX = 1413,1792 INVALID_INDEX = 1413,
2638
2639 /// Invalid icon handle.1793 /// Invalid icon handle.
2640 INVALID_ICON_HANDLE = 1414,1794 INVALID_ICON_HANDLE = 1414,
2641
2642 /// Using private DIALOG window words.1795 /// Using private DIALOG window words.
2643 PRIVATE_DIALOG_INDEX = 1415,1796 PRIVATE_DIALOG_INDEX = 1415,
2644
2645 /// The list box identifier was not found.1797 /// The list box identifier was not found.
2646 LISTBOX_ID_NOT_FOUND = 1416,1798 LISTBOX_ID_NOT_FOUND = 1416,
2647
2648 /// No wildcards were found.1799 /// No wildcards were found.
2649 NO_WILDCARD_CHARACTERS = 1417,1800 NO_WILDCARD_CHARACTERS = 1417,
2650
2651 /// Thread does not have a clipboard open.1801 /// Thread does not have a clipboard open.
2652 CLIPBOARD_NOT_OPEN = 1418,1802 CLIPBOARD_NOT_OPEN = 1418,
2653
2654 /// Hot key is not registered.1803 /// Hot key is not registered.
2655 HOTKEY_NOT_REGISTERED = 1419,1804 HOTKEY_NOT_REGISTERED = 1419,
2656
2657 /// The window is not a valid dialog window.1805 /// The window is not a valid dialog window.
2658 WINDOW_NOT_DIALOG = 1420,1806 WINDOW_NOT_DIALOG = 1420,
2659
2660 /// Control ID not found.1807 /// Control ID not found.
2661 CONTROL_ID_NOT_FOUND = 1421,1808 CONTROL_ID_NOT_FOUND = 1421,
2662
2663 /// Invalid message for a combo box because it does not have an edit control.1809 /// Invalid message for a combo box because it does not have an edit control.
2664 INVALID_COMBOBOX_MESSAGE = 1422,1810 INVALID_COMBOBOX_MESSAGE = 1422,
2665
2666 /// The window is not a combo box.1811 /// The window is not a combo box.
2667 WINDOW_NOT_COMBOBOX = 1423,1812 WINDOW_NOT_COMBOBOX = 1423,
2668
2669 /// Height must be less than 256.1813 /// Height must be less than 256.
2670 INVALID_EDIT_HEIGHT = 1424,1814 INVALID_EDIT_HEIGHT = 1424,
2671
2672 /// Invalid device context (DC) handle.1815 /// Invalid device context (DC) handle.
2673 DC_NOT_FOUND = 1425,1816 DC_NOT_FOUND = 1425,
2674
2675 /// Invalid hook procedure type.1817 /// Invalid hook procedure type.
2676 INVALID_HOOK_FILTER = 1426,1818 INVALID_HOOK_FILTER = 1426,
2677
2678 /// Invalid hook procedure.1819 /// Invalid hook procedure.
2679 INVALID_FILTER_PROC = 1427,1820 INVALID_FILTER_PROC = 1427,
2680
2681 /// Cannot set nonlocal hook without a module handle.1821 /// Cannot set nonlocal hook without a module handle.
2682 HOOK_NEEDS_HMOD = 1428,1822 HOOK_NEEDS_HMOD = 1428,
2683
2684 /// This hook procedure can only be set globally.1823 /// This hook procedure can only be set globally.
2685 GLOBAL_ONLY_HOOK = 1429,1824 GLOBAL_ONLY_HOOK = 1429,
2686
2687 /// The journal hook procedure is already installed.1825 /// The journal hook procedure is already installed.
2688 JOURNAL_HOOK_SET = 1430,1826 JOURNAL_HOOK_SET = 1430,
2689
2690 /// The hook procedure is not installed.1827 /// The hook procedure is not installed.
2691 HOOK_NOT_INSTALLED = 1431,1828 HOOK_NOT_INSTALLED = 1431,
2692
2693 /// Invalid message for single-selection list box.1829 /// Invalid message for single-selection list box.
2694 INVALID_LB_MESSAGE = 1432,1830 INVALID_LB_MESSAGE = 1432,
2695
2696 /// LB_SETCOUNT sent to non-lazy list box.1831 /// LB_SETCOUNT sent to non-lazy list box.
2697 SETCOUNT_ON_BAD_LB = 1433,1832 SETCOUNT_ON_BAD_LB = 1433,
2698
2699 /// This list box does not support tab stops.1833 /// This list box does not support tab stops.
2700 LB_WITHOUT_TABSTOPS = 1434,1834 LB_WITHOUT_TABSTOPS = 1434,
2701
2702 /// Cannot destroy object created by another thread.1835 /// Cannot destroy object created by another thread.
2703 DESTROY_OBJECT_OF_OTHER_THREAD = 1435,1836 DESTROY_OBJECT_OF_OTHER_THREAD = 1435,
2704
2705 /// Child windows cannot have menus.1837 /// Child windows cannot have menus.
2706 CHILD_WINDOW_MENU = 1436,1838 CHILD_WINDOW_MENU = 1436,
2707
2708 /// The window does not have a system menu.1839 /// The window does not have a system menu.
2709 NO_SYSTEM_MENU = 1437,1840 NO_SYSTEM_MENU = 1437,
2710
2711 /// Invalid message box style.1841 /// Invalid message box style.
2712 INVALID_MSGBOX_STYLE = 1438,1842 INVALID_MSGBOX_STYLE = 1438,
2713
2714 /// Invalid system-wide (SPI_*) parameter.1843 /// Invalid system-wide (SPI_*) parameter.
2715 INVALID_SPI_VALUE = 1439,1844 INVALID_SPI_VALUE = 1439,
2716
2717 /// Screen already locked.1845 /// Screen already locked.
2718 SCREEN_ALREADY_LOCKED = 1440,1846 SCREEN_ALREADY_LOCKED = 1440,
2719
2720 /// All handles to windows in a multiple-window position structure must have the same parent.1847 /// All handles to windows in a multiple-window position structure must have the same parent.
2721 HWNDS_HAVE_DIFF_PARENT = 1441,1848 HWNDS_HAVE_DIFF_PARENT = 1441,
2722
2723 /// The window is not a child window.1849 /// The window is not a child window.
2724 NOT_CHILD_WINDOW = 1442,1850 NOT_CHILD_WINDOW = 1442,
2725
2726 /// Invalid GW_* command.1851 /// Invalid GW_* command.
2727 INVALID_GW_COMMAND = 1443,1852 INVALID_GW_COMMAND = 1443,
2728
2729 /// Invalid thread identifier.1853 /// Invalid thread identifier.
2730 INVALID_THREAD_ID = 1444,1854 INVALID_THREAD_ID = 1444,
2731
2732 /// Cannot process a message from a window that is not a multiple document interface (MDI) window.1855 /// Cannot process a message from a window that is not a multiple document interface (MDI) window.
2733 NON_MDICHILD_WINDOW = 1445,1856 NON_MDICHILD_WINDOW = 1445,
2734
2735 /// Popup menu already active.1857 /// Popup menu already active.
2736 POPUP_ALREADY_ACTIVE = 1446,1858 POPUP_ALREADY_ACTIVE = 1446,
2737
2738 /// The window does not have scroll bars.1859 /// The window does not have scroll bars.
2739 NO_SCROLLBARS = 1447,1860 NO_SCROLLBARS = 1447,
2740
2741 /// Scroll bar range cannot be greater than MAXLONG.1861 /// Scroll bar range cannot be greater than MAXLONG.
2742 INVALID_SCROLLBAR_RANGE = 1448,1862 INVALID_SCROLLBAR_RANGE = 1448,
2743
2744 /// Cannot show or remove the window in the way specified.1863 /// Cannot show or remove the window in the way specified.
2745 INVALID_SHOWWIN_COMMAND = 1449,1864 INVALID_SHOWWIN_COMMAND = 1449,
2746
2747 /// Insufficient system resources exist to complete the requested service.1865 /// Insufficient system resources exist to complete the requested service.
2748 NO_SYSTEM_RESOURCES = 1450,1866 NO_SYSTEM_RESOURCES = 1450,
2749
2750 /// Insufficient system resources exist to complete the requested service.1867 /// Insufficient system resources exist to complete the requested service.
2751 NONPAGED_SYSTEM_RESOURCES = 1451,1868 NONPAGED_SYSTEM_RESOURCES = 1451,
2752
2753 /// Insufficient system resources exist to complete the requested service.1869 /// Insufficient system resources exist to complete the requested service.
2754 PAGED_SYSTEM_RESOURCES = 1452,1870 PAGED_SYSTEM_RESOURCES = 1452,
2755
2756 /// Insufficient quota to complete the requested service.1871 /// Insufficient quota to complete the requested service.
2757 WORKING_SET_QUOTA = 1453,1872 WORKING_SET_QUOTA = 1453,
2758
2759 /// Insufficient quota to complete the requested service.1873 /// Insufficient quota to complete the requested service.
2760 PAGEFILE_QUOTA = 1454,1874 PAGEFILE_QUOTA = 1454,
2761
2762 /// The paging file is too small for this operation to complete.1875 /// The paging file is too small for this operation to complete.
2763 COMMITMENT_LIMIT = 1455,1876 COMMITMENT_LIMIT = 1455,
2764
2765 /// A menu item was not found.1877 /// A menu item was not found.
2766 MENU_ITEM_NOT_FOUND = 1456,1878 MENU_ITEM_NOT_FOUND = 1456,
2767
2768 /// Invalid keyboard layout handle.1879 /// Invalid keyboard layout handle.
2769 INVALID_KEYBOARD_HANDLE = 1457,1880 INVALID_KEYBOARD_HANDLE = 1457,
2770
2771 /// Hook type not allowed.1881 /// Hook type not allowed.
2772 HOOK_TYPE_NOT_ALLOWED = 1458,1882 HOOK_TYPE_NOT_ALLOWED = 1458,
2773
2774 /// This operation requires an interactive window station.1883 /// This operation requires an interactive window station.
2775 REQUIRES_INTERACTIVE_WINDOWSTATION = 1459,1884 REQUIRES_INTERACTIVE_WINDOWSTATION = 1459,
2776
2777 /// This operation returned because the timeout period expired.1885 /// This operation returned because the timeout period expired.
2778 TIMEOUT = 1460,1886 TIMEOUT = 1460,
2779
2780 /// Invalid monitor handle.1887 /// Invalid monitor handle.
2781 INVALID_MONITOR_HANDLE = 1461,1888 INVALID_MONITOR_HANDLE = 1461,
2782
2783 /// Incorrect size argument.1889 /// Incorrect size argument.
2784 INCORRECT_SIZE = 1462,1890 INCORRECT_SIZE = 1462,
2785
2786 /// The symbolic link cannot be followed because its type is disabled.1891 /// The symbolic link cannot be followed because its type is disabled.
2787 SYMLINK_CLASS_DISABLED = 1463,1892 SYMLINK_CLASS_DISABLED = 1463,
2788
2789 /// This application does not support the current operation on symbolic links.1893 /// This application does not support the current operation on symbolic links.
2790 SYMLINK_NOT_SUPPORTED = 1464,1894 SYMLINK_NOT_SUPPORTED = 1464,
2791
2792 /// Windows was unable to parse the requested XML data.1895 /// Windows was unable to parse the requested XML data.
2793 XML_PARSE_ERROR = 1465,1896 XML_PARSE_ERROR = 1465,
2794
2795 /// An error was encountered while processing an XML digital signature.1897 /// An error was encountered while processing an XML digital signature.
2796 XMLDSIG_ERROR = 1466,1898 XMLDSIG_ERROR = 1466,
2797
2798 /// This application must be restarted.1899 /// This application must be restarted.
2799 RESTART_APPLICATION = 1467,1900 RESTART_APPLICATION = 1467,
2800
2801 /// The caller made the connection request in the wrong routing compartment.1901 /// The caller made the connection request in the wrong routing compartment.
2802 WRONG_COMPARTMENT = 1468,1902 WRONG_COMPARTMENT = 1468,
2803
2804 /// There was an AuthIP failure when attempting to connect to the remote host.1903 /// There was an AuthIP failure when attempting to connect to the remote host.
2805 AUTHIP_FAILURE = 1469,1904 AUTHIP_FAILURE = 1469,
2806
2807 /// Insufficient NVRAM resources exist to complete the requested service. A reboot might be required.1905 /// Insufficient NVRAM resources exist to complete the requested service. A reboot might be required.
2808 NO_NVRAM_RESOURCES = 1470,1906 NO_NVRAM_RESOURCES = 1470,
2809
2810 /// Unable to finish the requested operation because the specified process is not a GUI process.1907 /// Unable to finish the requested operation because the specified process is not a GUI process.
2811 NOT_GUI_PROCESS = 1471,1908 NOT_GUI_PROCESS = 1471,
2812
2813 /// The event log file is corrupted.1909 /// The event log file is corrupted.
2814 EVENTLOG_FILE_CORRUPT = 1500,1910 EVENTLOG_FILE_CORRUPT = 1500,
2815
2816 /// No event log file could be opened, so the event logging service did not start.1911 /// No event log file could be opened, so the event logging service did not start.
2817 EVENTLOG_CANT_START = 1501,1912 EVENTLOG_CANT_START = 1501,
2818
2819 /// The event log file is full.1913 /// The event log file is full.
2820 LOG_FILE_FULL = 1502,1914 LOG_FILE_FULL = 1502,
2821
2822 /// The event log file has changed between read operations.1915 /// The event log file has changed between read operations.
2823 EVENTLOG_FILE_CHANGED = 1503,1916 EVENTLOG_FILE_CHANGED = 1503,
2824
2825 /// The specified task name is invalid.1917 /// The specified task name is invalid.
2826 INVALID_TASK_NAME = 1550,1918 INVALID_TASK_NAME = 1550,
2827
2828 /// The specified task index is invalid.1919 /// The specified task index is invalid.
2829 INVALID_TASK_INDEX = 1551,1920 INVALID_TASK_INDEX = 1551,
2830
2831 /// The specified thread is already joining a task.1921 /// The specified thread is already joining a task.
2832 THREAD_ALREADY_IN_TASK = 1552,1922 THREAD_ALREADY_IN_TASK = 1552,
2833
2834 /// The Windows Installer Service could not be accessed.1923 /// The Windows Installer Service could not be accessed.
2835 /// This can occur if the Windows Installer is not correctly installed. Contact your support personnel for assistance.1924 /// This can occur if the Windows Installer is not correctly installed. Contact your support personnel for assistance.
2836 INSTALL_SERVICE_FAILURE = 1601,1925 INSTALL_SERVICE_FAILURE = 1601,
2837
2838 /// User cancelled installation.1926 /// User cancelled installation.
2839 INSTALL_USEREXIT = 1602,1927 INSTALL_USEREXIT = 1602,
2840
2841 /// Fatal error during installation.1928 /// Fatal error during installation.
2842 INSTALL_FAILURE = 1603,1929 INSTALL_FAILURE = 1603,
2843
2844 /// Installation suspended, incomplete.1930 /// Installation suspended, incomplete.
2845 INSTALL_SUSPEND = 1604,1931 INSTALL_SUSPEND = 1604,
2846
2847 /// This action is only valid for products that are currently installed.1932 /// This action is only valid for products that are currently installed.
2848 UNKNOWN_PRODUCT = 1605,1933 UNKNOWN_PRODUCT = 1605,
2849
2850 /// Feature ID not registered.1934 /// Feature ID not registered.
2851 UNKNOWN_FEATURE = 1606,1935 UNKNOWN_FEATURE = 1606,
2852
2853 /// Component ID not registered.1936 /// Component ID not registered.
2854 UNKNOWN_COMPONENT = 1607,1937 UNKNOWN_COMPONENT = 1607,
2855
2856 /// Unknown property.1938 /// Unknown property.
2857 UNKNOWN_PROPERTY = 1608,1939 UNKNOWN_PROPERTY = 1608,
2858
2859 /// Handle is in an invalid state.1940 /// Handle is in an invalid state.
2860 INVALID_HANDLE_STATE = 1609,1941 INVALID_HANDLE_STATE = 1609,
2861
2862 /// The configuration data for this product is corrupt. Contact your support personnel.1942 /// The configuration data for this product is corrupt. Contact your support personnel.
2863 BAD_CONFIGURATION = 1610,1943 BAD_CONFIGURATION = 1610,
2864
2865 /// Component qualifier not present.1944 /// Component qualifier not present.
2866 INDEX_ABSENT = 1611,1945 INDEX_ABSENT = 1611,
2867
2868 /// The installation source for this product is not available.1946 /// The installation source for this product is not available.
2869 /// Verify that the source exists and that you can access it.1947 /// Verify that the source exists and that you can access it.
2870 INSTALL_SOURCE_ABSENT = 1612,1948 INSTALL_SOURCE_ABSENT = 1612,
2871
2872 /// This installation package cannot be installed by the Windows Installer service.1949 /// This installation package cannot be installed by the Windows Installer service.
2873 /// You must install a Windows service pack that contains a newer version of the Windows Installer service.1950 /// You must install a Windows service pack that contains a newer version of the Windows Installer service.
2874 INSTALL_PACKAGE_VERSION = 1613,1951 INSTALL_PACKAGE_VERSION = 1613,
2875
2876 /// Product is uninstalled.1952 /// Product is uninstalled.
2877 PRODUCT_UNINSTALLED = 1614,1953 PRODUCT_UNINSTALLED = 1614,
2878
2879 /// SQL query syntax invalid or unsupported.1954 /// SQL query syntax invalid or unsupported.
2880 BAD_QUERY_SYNTAX = 1615,1955 BAD_QUERY_SYNTAX = 1615,
2881
2882 /// Record field does not exist.1956 /// Record field does not exist.
2883 INVALID_FIELD = 1616,1957 INVALID_FIELD = 1616,
2884
2885 /// The device has been removed.1958 /// The device has been removed.
2886 DEVICE_REMOVED = 1617,1959 DEVICE_REMOVED = 1617,
2887
2888 /// Another installation is already in progress.1960 /// Another installation is already in progress.
2889 /// Complete that installation before proceeding with this install.1961 /// Complete that installation before proceeding with this install.
2890 INSTALL_ALREADY_RUNNING = 1618,1962 INSTALL_ALREADY_RUNNING = 1618,
2891
2892 /// This installation package could not be opened.1963 /// This installation package could not be opened.
2893 /// Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.1964 /// Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.
2894 INSTALL_PACKAGE_OPEN_FAILED = 1619,1965 INSTALL_PACKAGE_OPEN_FAILED = 1619,
2895
2896 /// This installation package could not be opened.1966 /// This installation package could not be opened.
2897 /// Contact the application vendor to verify that this is a valid Windows Installer package.1967 /// Contact the application vendor to verify that this is a valid Windows Installer package.
2898 INSTALL_PACKAGE_INVALID = 1620,1968 INSTALL_PACKAGE_INVALID = 1620,
2899
2900 /// There was an error starting the Windows Installer service user interface. Contact your support personnel.1969 /// There was an error starting the Windows Installer service user interface. Contact your support personnel.
2901 INSTALL_UI_FAILURE = 1621,1970 INSTALL_UI_FAILURE = 1621,
2902
2903 /// Error opening installation log file.1971 /// Error opening installation log file.
2904 /// Verify that the specified log file location exists and that you can write to it.1972 /// Verify that the specified log file location exists and that you can write to it.
2905 INSTALL_LOG_FAILURE = 1622,1973 INSTALL_LOG_FAILURE = 1622,
2906
2907 /// The language of this installation package is not supported by your system.1974 /// The language of this installation package is not supported by your system.
2908 INSTALL_LANGUAGE_UNSUPPORTED = 1623,1975 INSTALL_LANGUAGE_UNSUPPORTED = 1623,
2909
2910 /// Error applying transforms. Verify that the specified transform paths are valid.1976 /// Error applying transforms. Verify that the specified transform paths are valid.
2911 INSTALL_TRANSFORM_FAILURE = 1624,1977 INSTALL_TRANSFORM_FAILURE = 1624,
2912
2913 /// This installation is forbidden by system policy. Contact your system administrator.1978 /// This installation is forbidden by system policy. Contact your system administrator.
2914 INSTALL_PACKAGE_REJECTED = 1625,1979 INSTALL_PACKAGE_REJECTED = 1625,
2915
2916 /// Function could not be executed.1980 /// Function could not be executed.
2917 FUNCTION_NOT_CALLED = 1626,1981 FUNCTION_NOT_CALLED = 1626,
2918
2919 /// Function failed during execution.1982 /// Function failed during execution.
2920 FUNCTION_FAILED = 1627,1983 FUNCTION_FAILED = 1627,
2921
2922 /// Invalid or unknown table specified.1984 /// Invalid or unknown table specified.
2923 INVALID_TABLE = 1628,1985 INVALID_TABLE = 1628,
2924
2925 /// Data supplied is of wrong type.1986 /// Data supplied is of wrong type.
2926 DATATYPE_MISMATCH = 1629,1987 DATATYPE_MISMATCH = 1629,
2927
2928 /// Data of this type is not supported.1988 /// Data of this type is not supported.
2929 UNSUPPORTED_TYPE = 1630,1989 UNSUPPORTED_TYPE = 1630,
2930
2931 /// The Windows Installer service failed to start. Contact your support personnel.1990 /// The Windows Installer service failed to start. Contact your support personnel.
2932 CREATE_FAILED = 1631,1991 CREATE_FAILED = 1631,
2933
2934 /// The Temp folder is on a drive that is full or is inaccessible.1992 /// The Temp folder is on a drive that is full or is inaccessible.
2935 /// Free up space on the drive or verify that you have write permission on the Temp folder.1993 /// Free up space on the drive or verify that you have write permission on the Temp folder.
2936 INSTALL_TEMP_UNWRITABLE = 1632,1994 INSTALL_TEMP_UNWRITABLE = 1632,
2937
2938 /// This installation package is not supported by this processor type. Contact your product vendor.1995 /// This installation package is not supported by this processor type. Contact your product vendor.
2939 INSTALL_PLATFORM_UNSUPPORTED = 1633,1996 INSTALL_PLATFORM_UNSUPPORTED = 1633,
2940
2941 /// Component not used on this computer.1997 /// Component not used on this computer.
2942 INSTALL_NOTUSED = 1634,1998 INSTALL_NOTUSED = 1634,
2943
2944 /// This update package could not be opened.1999 /// This update package could not be opened.
2945 /// Verify that the update package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer update package.2000 /// Verify that the update package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer update package.
2946 PATCH_PACKAGE_OPEN_FAILED = 1635,2001 PATCH_PACKAGE_OPEN_FAILED = 1635,
2947
2948 /// This update package could not be opened.2002 /// This update package could not be opened.
2949 /// Contact the application vendor to verify that this is a valid Windows Installer update package.2003 /// Contact the application vendor to verify that this is a valid Windows Installer update package.
2950 PATCH_PACKAGE_INVALID = 1636,2004 PATCH_PACKAGE_INVALID = 1636,
2951
2952 /// This update package cannot be processed by the Windows Installer service.2005 /// This update package cannot be processed by the Windows Installer service.
2953 /// You must install a Windows service pack that contains a newer version of the Windows Installer service.2006 /// You must install a Windows service pack that contains a newer version of the Windows Installer service.
2954 PATCH_PACKAGE_UNSUPPORTED = 1637,2007 PATCH_PACKAGE_UNSUPPORTED = 1637,
2955
2956 /// Another version of this product is already installed. Installation of this version cannot continue.2008 /// Another version of this product is already installed. Installation of this version cannot continue.
2957 /// To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.2009 /// To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.
2958 PRODUCT_VERSION = 1638,2010 PRODUCT_VERSION = 1638,
2959
2960 /// Invalid command line argument. Consult the Windows Installer SDK for detailed command line help.2011 /// Invalid command line argument. Consult the Windows Installer SDK for detailed command line help.
2961 INVALID_COMMAND_LINE = 1639,2012 INVALID_COMMAND_LINE = 1639,
2962
2963 /// Only administrators have permission to add, remove, or configure server software during a Terminal services remote session.2013 /// Only administrators have permission to add, remove, or configure server software during a Terminal services remote session.
2964 /// If you want to install or configure software on the server, contact your network administrator.2014 /// If you want to install or configure software on the server, contact your network administrator.
2965 INSTALL_REMOTE_DISALLOWED = 1640,2015 INSTALL_REMOTE_DISALLOWED = 1640,
2966
2967 /// The requested operation completed successfully.2016 /// The requested operation completed successfully.
2968 /// The system will be restarted so the changes can take effect.2017 /// The system will be restarted so the changes can take effect.
2969 SUCCESS_REBOOT_INITIATED = 1641,2018 SUCCESS_REBOOT_INITIATED = 1641,
2970
2971 /// The upgrade cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade may update a different version of the program.2019 /// The upgrade cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade may update a different version of the program.
2972 /// Verify that the program to be upgraded exists on your computer and that you have the correct upgrade.2020 /// Verify that the program to be upgraded exists on your computer and that you have the correct upgrade.
2973 PATCH_TARGET_NOT_FOUND = 1642,2021 PATCH_TARGET_NOT_FOUND = 1642,
2974
2975 /// The update package is not permitted by software restriction policy.2022 /// The update package is not permitted by software restriction policy.
2976 PATCH_PACKAGE_REJECTED = 1643,2023 PATCH_PACKAGE_REJECTED = 1643,
2977
2978 /// One or more customizations are not permitted by software restriction policy.2024 /// One or more customizations are not permitted by software restriction policy.
2979 INSTALL_TRANSFORM_REJECTED = 1644,2025 INSTALL_TRANSFORM_REJECTED = 1644,
2980
2981 /// The Windows Installer does not permit installation from a Remote Desktop Connection.2026 /// The Windows Installer does not permit installation from a Remote Desktop Connection.
2982 INSTALL_REMOTE_PROHIBITED = 1645,2027 INSTALL_REMOTE_PROHIBITED = 1645,
2983
2984 /// Uninstallation of the update package is not supported.2028 /// Uninstallation of the update package is not supported.
2985 PATCH_REMOVAL_UNSUPPORTED = 1646,2029 PATCH_REMOVAL_UNSUPPORTED = 1646,
2986
2987 /// The update is not applied to this product.2030 /// The update is not applied to this product.
2988 UNKNOWN_PATCH = 1647,2031 UNKNOWN_PATCH = 1647,
2989
2990 /// No valid sequence could be found for the set of updates.2032 /// No valid sequence could be found for the set of updates.
2991 PATCH_NO_SEQUENCE = 1648,2033 PATCH_NO_SEQUENCE = 1648,
2992
2993 /// Update removal was disallowed by policy.2034 /// Update removal was disallowed by policy.
2994 PATCH_REMOVAL_DISALLOWED = 1649,2035 PATCH_REMOVAL_DISALLOWED = 1649,
2995
2996 /// The XML update data is invalid.2036 /// The XML update data is invalid.
2997 INVALID_PATCH_XML = 1650,2037 INVALID_PATCH_XML = 1650,
2998
2999 /// Windows Installer does not permit updating of managed advertised products.2038 /// Windows Installer does not permit updating of managed advertised products.
3000 /// At least one feature of the product must be installed before applying the update.2039 /// At least one feature of the product must be installed before applying the update.
3001 PATCH_MANAGED_ADVERTISED_PRODUCT = 1651,2040 PATCH_MANAGED_ADVERTISED_PRODUCT = 1651,
3002
3003 /// The Windows Installer service is not accessible in Safe Mode.2041 /// The Windows Installer service is not accessible in Safe Mode.
3004 /// Please try again when your computer is not in Safe Mode or you can use System Restore to return your machine to a previous good state.2042 /// Please try again when your computer is not in Safe Mode or you can use System Restore to return your machine to a previous good state.
3005 INSTALL_SERVICE_SAFEBOOT = 1652,2043 INSTALL_SERVICE_SAFEBOOT = 1652,
3006
3007 /// A fail fast exception occurred.2044 /// A fail fast exception occurred.
3008 /// Exception handlers will not be invoked and the process will be terminated immediately.2045 /// Exception handlers will not be invoked and the process will be terminated immediately.
3009 FAIL_FAST_EXCEPTION = 1653,2046 FAIL_FAST_EXCEPTION = 1653,
3010
3011 /// The app that you are trying to run is not supported on this version of Windows.2047 /// The app that you are trying to run is not supported on this version of Windows.
3012 INSTALL_REJECTED = 1654,2048 INSTALL_REJECTED = 1654,
3013
3014 /// The string binding is invalid.2049 /// The string binding is invalid.
3015 RPC_S_INVALID_STRING_BINDING = 1700,2050 RPC_S_INVALID_STRING_BINDING = 1700,
3016
3017 /// The binding handle is not the correct type.2051 /// The binding handle is not the correct type.
3018 RPC_S_WRONG_KIND_OF_BINDING = 1701,2052 RPC_S_WRONG_KIND_OF_BINDING = 1701,
3019
3020 /// The binding handle is invalid.2053 /// The binding handle is invalid.
3021 RPC_S_INVALID_BINDING = 1702,2054 RPC_S_INVALID_BINDING = 1702,
3022
3023 /// The RPC protocol sequence is not supported.2055 /// The RPC protocol sequence is not supported.
3024 RPC_S_PROTSEQ_NOT_SUPPORTED = 1703,2056 RPC_S_PROTSEQ_NOT_SUPPORTED = 1703,
3025
3026 /// The RPC protocol sequence is invalid.2057 /// The RPC protocol sequence is invalid.
3027 RPC_S_INVALID_RPC_PROTSEQ = 1704,2058 RPC_S_INVALID_RPC_PROTSEQ = 1704,
3028
3029 /// The string universal unique identifier (UUID) is invalid.2059 /// The string universal unique identifier (UUID) is invalid.
3030 RPC_S_INVALID_STRING_UUID = 1705,2060 RPC_S_INVALID_STRING_UUID = 1705,
3031
3032 /// The endpoint format is invalid.2061 /// The endpoint format is invalid.
3033 RPC_S_INVALID_ENDPOINT_FORMAT = 1706,2062 RPC_S_INVALID_ENDPOINT_FORMAT = 1706,
3034
3035 /// The network address is invalid.2063 /// The network address is invalid.
3036 RPC_S_INVALID_NET_ADDR = 1707,2064 RPC_S_INVALID_NET_ADDR = 1707,
3037
3038 /// No endpoint was found.2065 /// No endpoint was found.
3039 RPC_S_NO_ENDPOINT_FOUND = 1708,2066 RPC_S_NO_ENDPOINT_FOUND = 1708,
3040
3041 /// The timeout value is invalid.2067 /// The timeout value is invalid.
3042 RPC_S_INVALID_TIMEOUT = 1709,2068 RPC_S_INVALID_TIMEOUT = 1709,
3043
3044 /// The object universal unique identifier (UUID) was not found.2069 /// The object universal unique identifier (UUID) was not found.
3045 RPC_S_OBJECT_NOT_FOUND = 1710,2070 RPC_S_OBJECT_NOT_FOUND = 1710,
3046
3047 /// The object universal unique identifier (UUID) has already been registered.2071 /// The object universal unique identifier (UUID) has already been registered.
3048 RPC_S_ALREADY_REGISTERED = 1711,2072 RPC_S_ALREADY_REGISTERED = 1711,
3049
3050 /// The type universal unique identifier (UUID) has already been registered.2073 /// The type universal unique identifier (UUID) has already been registered.
3051 RPC_S_TYPE_ALREADY_REGISTERED = 1712,2074 RPC_S_TYPE_ALREADY_REGISTERED = 1712,
3052
3053 /// The RPC server is already listening.2075 /// The RPC server is already listening.
3054 RPC_S_ALREADY_LISTENING = 1713,2076 RPC_S_ALREADY_LISTENING = 1713,
3055
3056 /// No protocol sequences have been registered.2077 /// No protocol sequences have been registered.
3057 RPC_S_NO_PROTSEQS_REGISTERED = 1714,2078 RPC_S_NO_PROTSEQS_REGISTERED = 1714,
3058
3059 /// The RPC server is not listening.2079 /// The RPC server is not listening.
3060 RPC_S_NOT_LISTENING = 1715,2080 RPC_S_NOT_LISTENING = 1715,
3061
3062 /// The manager type is unknown.2081 /// The manager type is unknown.
3063 RPC_S_UNKNOWN_MGR_TYPE = 1716,2082 RPC_S_UNKNOWN_MGR_TYPE = 1716,
3064
3065 /// The interface is unknown.2083 /// The interface is unknown.
3066 RPC_S_UNKNOWN_IF = 1717,2084 RPC_S_UNKNOWN_IF = 1717,
3067
3068 /// There are no bindings.2085 /// There are no bindings.
3069 RPC_S_NO_BINDINGS = 1718,2086 RPC_S_NO_BINDINGS = 1718,
3070
3071 /// There are no protocol sequences.2087 /// There are no protocol sequences.
3072 RPC_S_NO_PROTSEQS = 1719,2088 RPC_S_NO_PROTSEQS = 1719,
3073
3074 /// The endpoint cannot be created.2089 /// The endpoint cannot be created.
3075 RPC_S_CANT_CREATE_ENDPOINT = 1720,2090 RPC_S_CANT_CREATE_ENDPOINT = 1720,
3076
3077 /// Not enough resources are available to complete this operation.2091 /// Not enough resources are available to complete this operation.
3078 RPC_S_OUT_OF_RESOURCES = 1721,2092 RPC_S_OUT_OF_RESOURCES = 1721,
3079
3080 /// The RPC server is unavailable.2093 /// The RPC server is unavailable.
3081 RPC_S_SERVER_UNAVAILABLE = 1722,2094 RPC_S_SERVER_UNAVAILABLE = 1722,
3082
3083 /// The RPC server is too busy to complete this operation.2095 /// The RPC server is too busy to complete this operation.
3084 RPC_S_SERVER_TOO_BUSY = 1723,2096 RPC_S_SERVER_TOO_BUSY = 1723,
3085
3086 /// The network options are invalid.2097 /// The network options are invalid.
3087 RPC_S_INVALID_NETWORK_OPTIONS = 1724,2098 RPC_S_INVALID_NETWORK_OPTIONS = 1724,
3088
3089 /// There are no remote procedure calls active on this thread.2099 /// There are no remote procedure calls active on this thread.
3090 RPC_S_NO_CALL_ACTIVE = 1725,2100 RPC_S_NO_CALL_ACTIVE = 1725,
3091
3092 /// The remote procedure call failed.2101 /// The remote procedure call failed.
3093 RPC_S_CALL_FAILED = 1726,2102 RPC_S_CALL_FAILED = 1726,
3094
3095 /// The remote procedure call failed and did not execute.2103 /// The remote procedure call failed and did not execute.
3096 RPC_S_CALL_FAILED_DNE = 1727,2104 RPC_S_CALL_FAILED_DNE = 1727,
3097
3098 /// A remote procedure call (RPC) protocol error occurred.2105 /// A remote procedure call (RPC) protocol error occurred.
3099 RPC_S_PROTOCOL_ERROR = 1728,2106 RPC_S_PROTOCOL_ERROR = 1728,
3100
3101 /// Access to the HTTP proxy is denied.2107 /// Access to the HTTP proxy is denied.
3102 RPC_S_PROXY_ACCESS_DENIED = 1729,2108 RPC_S_PROXY_ACCESS_DENIED = 1729,
3103
3104 /// The transfer syntax is not supported by the RPC server.2109 /// The transfer syntax is not supported by the RPC server.
3105 RPC_S_UNSUPPORTED_TRANS_SYN = 1730,2110 RPC_S_UNSUPPORTED_TRANS_SYN = 1730,
3106
3107 /// The universal unique identifier (UUID) type is not supported.2111 /// The universal unique identifier (UUID) type is not supported.
3108 RPC_S_UNSUPPORTED_TYPE = 1732,2112 RPC_S_UNSUPPORTED_TYPE = 1732,
3109
3110 /// The tag is invalid.2113 /// The tag is invalid.
3111 RPC_S_INVALID_TAG = 1733,2114 RPC_S_INVALID_TAG = 1733,
3112
3113 /// The array bounds are invalid.2115 /// The array bounds are invalid.
3114 RPC_S_INVALID_BOUND = 1734,2116 RPC_S_INVALID_BOUND = 1734,
3115
3116 /// The binding does not contain an entry name.2117 /// The binding does not contain an entry name.
3117 RPC_S_NO_ENTRY_NAME = 1735,2118 RPC_S_NO_ENTRY_NAME = 1735,
3118
3119 /// The name syntax is invalid.2119 /// The name syntax is invalid.
3120 RPC_S_INVALID_NAME_SYNTAX = 1736,2120 RPC_S_INVALID_NAME_SYNTAX = 1736,
3121
3122 /// The name syntax is not supported.2121 /// The name syntax is not supported.
3123 RPC_S_UNSUPPORTED_NAME_SYNTAX = 1737,2122 RPC_S_UNSUPPORTED_NAME_SYNTAX = 1737,
3124
3125 /// No network address is available to use to construct a universal unique identifier (UUID).2123 /// No network address is available to use to construct a universal unique identifier (UUID).
3126 RPC_S_UUID_NO_ADDRESS = 1739,2124 RPC_S_UUID_NO_ADDRESS = 1739,
3127
3128 /// The endpoint is a duplicate.2125 /// The endpoint is a duplicate.
3129 RPC_S_DUPLICATE_ENDPOINT = 1740,2126 RPC_S_DUPLICATE_ENDPOINT = 1740,
3130
3131 /// The authentication type is unknown.2127 /// The authentication type is unknown.
3132 RPC_S_UNKNOWN_AUTHN_TYPE = 1741,2128 RPC_S_UNKNOWN_AUTHN_TYPE = 1741,
3133
3134 /// The maximum number of calls is too small.2129 /// The maximum number of calls is too small.
3135 RPC_S_MAX_CALLS_TOO_SMALL = 1742,2130 RPC_S_MAX_CALLS_TOO_SMALL = 1742,
3136
3137 /// The string is too long.2131 /// The string is too long.
3138 RPC_S_STRING_TOO_LONG = 1743,2132 RPC_S_STRING_TOO_LONG = 1743,
3139
3140 /// The RPC protocol sequence was not found.2133 /// The RPC protocol sequence was not found.
3141 RPC_S_PROTSEQ_NOT_FOUND = 1744,2134 RPC_S_PROTSEQ_NOT_FOUND = 1744,
3142
3143 /// The procedure number is out of range.2135 /// The procedure number is out of range.
3144 RPC_S_PROCNUM_OUT_OF_RANGE = 1745,2136 RPC_S_PROCNUM_OUT_OF_RANGE = 1745,
3145
3146 /// The binding does not contain any authentication information.2137 /// The binding does not contain any authentication information.
3147 RPC_S_BINDING_HAS_NO_AUTH = 1746,2138 RPC_S_BINDING_HAS_NO_AUTH = 1746,
3148
3149 /// The authentication service is unknown.2139 /// The authentication service is unknown.
3150 RPC_S_UNKNOWN_AUTHN_SERVICE = 1747,2140 RPC_S_UNKNOWN_AUTHN_SERVICE = 1747,
3151
3152 /// The authentication level is unknown.2141 /// The authentication level is unknown.
3153 RPC_S_UNKNOWN_AUTHN_LEVEL = 1748,2142 RPC_S_UNKNOWN_AUTHN_LEVEL = 1748,
3154
3155 /// The security context is invalid.2143 /// The security context is invalid.
3156 RPC_S_INVALID_AUTH_IDENTITY = 1749,2144 RPC_S_INVALID_AUTH_IDENTITY = 1749,
3157
3158 /// The authorization service is unknown.2145 /// The authorization service is unknown.
3159 RPC_S_UNKNOWN_AUTHZ_SERVICE = 1750,2146 RPC_S_UNKNOWN_AUTHZ_SERVICE = 1750,
3160
3161 /// The entry is invalid.2147 /// The entry is invalid.
3162 EPT_S_INVALID_ENTRY = 1751,2148 EPT_S_INVALID_ENTRY = 1751,
3163
3164 /// The server endpoint cannot perform the operation.2149 /// The server endpoint cannot perform the operation.
3165 EPT_S_CANT_PERFORM_OP = 1752,2150 EPT_S_CANT_PERFORM_OP = 1752,
3166
3167 /// There are no more endpoints available from the endpoint mapper.2151 /// There are no more endpoints available from the endpoint mapper.
3168 EPT_S_NOT_REGISTERED = 1753,2152 EPT_S_NOT_REGISTERED = 1753,
3169
3170 /// No interfaces have been exported.2153 /// No interfaces have been exported.
3171 RPC_S_NOTHING_TO_EXPORT = 1754,2154 RPC_S_NOTHING_TO_EXPORT = 1754,
3172
3173 /// The entry name is incomplete.2155 /// The entry name is incomplete.
3174 RPC_S_INCOMPLETE_NAME = 1755,2156 RPC_S_INCOMPLETE_NAME = 1755,
3175
3176 /// The version option is invalid.2157 /// The version option is invalid.
3177 RPC_S_INVALID_VERS_OPTION = 1756,2158 RPC_S_INVALID_VERS_OPTION = 1756,
3178
3179 /// There are no more members.2159 /// There are no more members.
3180 RPC_S_NO_MORE_MEMBERS = 1757,2160 RPC_S_NO_MORE_MEMBERS = 1757,
3181
3182 /// There is nothing to unexport.2161 /// There is nothing to unexport.
3183 RPC_S_NOT_ALL_OBJS_UNEXPORTED = 1758,2162 RPC_S_NOT_ALL_OBJS_UNEXPORTED = 1758,
3184
3185 /// The interface was not found.2163 /// The interface was not found.
3186 RPC_S_INTERFACE_NOT_FOUND = 1759,2164 RPC_S_INTERFACE_NOT_FOUND = 1759,
3187
3188 /// The entry already exists.2165 /// The entry already exists.
3189 RPC_S_ENTRY_ALREADY_EXISTS = 1760,2166 RPC_S_ENTRY_ALREADY_EXISTS = 1760,
3190
3191 /// The entry is not found.2167 /// The entry is not found.
3192 RPC_S_ENTRY_NOT_FOUND = 1761,2168 RPC_S_ENTRY_NOT_FOUND = 1761,
3193
3194 /// The name service is unavailable.2169 /// The name service is unavailable.
3195 RPC_S_NAME_SERVICE_UNAVAILABLE = 1762,2170 RPC_S_NAME_SERVICE_UNAVAILABLE = 1762,
3196
3197 /// The network address family is invalid.2171 /// The network address family is invalid.
3198 RPC_S_INVALID_NAF_ID = 1763,2172 RPC_S_INVALID_NAF_ID = 1763,
3199
3200 /// The requested operation is not supported.2173 /// The requested operation is not supported.
3201 RPC_S_CANNOT_SUPPORT = 1764,2174 RPC_S_CANNOT_SUPPORT = 1764,
3202
3203 /// No security context is available to allow impersonation.2175 /// No security context is available to allow impersonation.
3204 RPC_S_NO_CONTEXT_AVAILABLE = 1765,2176 RPC_S_NO_CONTEXT_AVAILABLE = 1765,
3205
3206 /// An internal error occurred in a remote procedure call (RPC).2177 /// An internal error occurred in a remote procedure call (RPC).
3207 RPC_S_INTERNAL_ERROR = 1766,2178 RPC_S_INTERNAL_ERROR = 1766,
3208
3209 /// The RPC server attempted an integer division by zero.2179 /// The RPC server attempted an integer division by zero.
3210 RPC_S_ZERO_DIVIDE = 1767,2180 RPC_S_ZERO_DIVIDE = 1767,
3211
3212 /// An addressing error occurred in the RPC server.2181 /// An addressing error occurred in the RPC server.
3213 RPC_S_ADDRESS_ERROR = 1768,2182 RPC_S_ADDRESS_ERROR = 1768,
3214
3215 /// A floating-point operation at the RPC server caused a division by zero.2183 /// A floating-point operation at the RPC server caused a division by zero.
3216 RPC_S_FP_DIV_ZERO = 1769,2184 RPC_S_FP_DIV_ZERO = 1769,
3217
3218 /// A floating-point underflow occurred at the RPC server.2185 /// A floating-point underflow occurred at the RPC server.
3219 RPC_S_FP_UNDERFLOW = 1770,2186 RPC_S_FP_UNDERFLOW = 1770,
3220
3221 /// A floating-point overflow occurred at the RPC server.2187 /// A floating-point overflow occurred at the RPC server.
3222 RPC_S_FP_OVERFLOW = 1771,2188 RPC_S_FP_OVERFLOW = 1771,
3223
3224 /// The list of RPC servers available for the binding of auto handles has been exhausted.2189 /// The list of RPC servers available for the binding of auto handles has been exhausted.
3225 RPC_X_NO_MORE_ENTRIES = 1772,2190 RPC_X_NO_MORE_ENTRIES = 1772,
3226
3227 /// Unable to open the character translation table file.2191 /// Unable to open the character translation table file.
3228 RPC_X_SS_CHAR_TRANS_OPEN_FAIL = 1773,2192 RPC_X_SS_CHAR_TRANS_OPEN_FAIL = 1773,
3229
3230 /// The file containing the character translation table has fewer than 512 bytes.2193 /// The file containing the character translation table has fewer than 512 bytes.
3231 RPC_X_SS_CHAR_TRANS_SHORT_FILE = 1774,2194 RPC_X_SS_CHAR_TRANS_SHORT_FILE = 1774,
3232
3233 /// A null context handle was passed from the client to the host during a remote procedure call.2195 /// A null context handle was passed from the client to the host during a remote procedure call.
3234 RPC_X_SS_IN_NULL_CONTEXT = 1775,2196 RPC_X_SS_IN_NULL_CONTEXT = 1775,
3235
3236 /// The context handle changed during a remote procedure call.2197 /// The context handle changed during a remote procedure call.
3237 RPC_X_SS_CONTEXT_DAMAGED = 1777,2198 RPC_X_SS_CONTEXT_DAMAGED = 1777,
3238
3239 /// The binding handles passed to a remote procedure call do not match.2199 /// The binding handles passed to a remote procedure call do not match.
3240 RPC_X_SS_HANDLES_MISMATCH = 1778,2200 RPC_X_SS_HANDLES_MISMATCH = 1778,
3241
3242 /// The stub is unable to get the remote procedure call handle.2201 /// The stub is unable to get the remote procedure call handle.
3243 RPC_X_SS_CANNOT_GET_CALL_HANDLE = 1779,2202 RPC_X_SS_CANNOT_GET_CALL_HANDLE = 1779,
3244
3245 /// A null reference pointer was passed to the stub.2203 /// A null reference pointer was passed to the stub.
3246 RPC_X_NULL_REF_POINTER = 1780,2204 RPC_X_NULL_REF_POINTER = 1780,
3247
3248 /// The enumeration value is out of range.2205 /// The enumeration value is out of range.
3249 RPC_X_ENUM_VALUE_OUT_OF_RANGE = 1781,2206 RPC_X_ENUM_VALUE_OUT_OF_RANGE = 1781,
3250
3251 /// The byte count is too small.2207 /// The byte count is too small.
3252 RPC_X_BYTE_COUNT_TOO_SMALL = 1782,2208 RPC_X_BYTE_COUNT_TOO_SMALL = 1782,
3253
3254 /// The stub received bad data.2209 /// The stub received bad data.
3255 RPC_X_BAD_STUB_DATA = 1783,2210 RPC_X_BAD_STUB_DATA = 1783,
3256
3257 /// The supplied user buffer is not valid for the requested operation.2211 /// The supplied user buffer is not valid for the requested operation.
3258 INVALID_USER_BUFFER = 1784,2212 INVALID_USER_BUFFER = 1784,
3259
3260 /// The disk media is not recognized. It may not be formatted.2213 /// The disk media is not recognized. It may not be formatted.
3261 UNRECOGNIZED_MEDIA = 1785,2214 UNRECOGNIZED_MEDIA = 1785,
3262
3263 /// The workstation does not have a trust secret.2215 /// The workstation does not have a trust secret.
3264 NO_TRUST_LSA_SECRET = 1786,2216 NO_TRUST_LSA_SECRET = 1786,
3265
3266 /// The security database on the server does not have a computer account for this workstation trust relationship.2217 /// The security database on the server does not have a computer account for this workstation trust relationship.
3267 NO_TRUST_SAM_ACCOUNT = 1787,2218 NO_TRUST_SAM_ACCOUNT = 1787,
3268
3269 /// The trust relationship between the primary domain and the trusted domain failed.2219 /// The trust relationship between the primary domain and the trusted domain failed.
3270 TRUSTED_DOMAIN_FAILURE = 1788,2220 TRUSTED_DOMAIN_FAILURE = 1788,
3271
3272 /// The trust relationship between this workstation and the primary domain failed.2221 /// The trust relationship between this workstation and the primary domain failed.
3273 TRUSTED_RELATIONSHIP_FAILURE = 1789,2222 TRUSTED_RELATIONSHIP_FAILURE = 1789,
3274
3275 /// The network logon failed.2223 /// The network logon failed.
3276 TRUST_FAILURE = 1790,2224 TRUST_FAILURE = 1790,
3277
3278 /// A remote procedure call is already in progress for this thread.2225 /// A remote procedure call is already in progress for this thread.
3279 RPC_S_CALL_IN_PROGRESS = 1791,2226 RPC_S_CALL_IN_PROGRESS = 1791,
3280
3281 /// An attempt was made to logon, but the network logon service was not started.2227 /// An attempt was made to logon, but the network logon service was not started.
3282 NETLOGON_NOT_STARTED = 1792,2228 NETLOGON_NOT_STARTED = 1792,
3283
3284 /// The user's account has expired.2229 /// The user's account has expired.
3285 ACCOUNT_EXPIRED = 1793,2230 ACCOUNT_EXPIRED = 1793,
3286
3287 /// The redirector is in use and cannot be unloaded.2231 /// The redirector is in use and cannot be unloaded.
3288 REDIRECTOR_HAS_OPEN_HANDLES = 1794,2232 REDIRECTOR_HAS_OPEN_HANDLES = 1794,
3289
3290 /// The specified printer driver is already installed.2233 /// The specified printer driver is already installed.
3291 PRINTER_DRIVER_ALREADY_INSTALLED = 1795,2234 PRINTER_DRIVER_ALREADY_INSTALLED = 1795,
3292
3293 /// The specified port is unknown.2235 /// The specified port is unknown.
3294 UNKNOWN_PORT = 1796,2236 UNKNOWN_PORT = 1796,
3295
3296 /// The printer driver is unknown.2237 /// The printer driver is unknown.
3297 UNKNOWN_PRINTER_DRIVER = 1797,2238 UNKNOWN_PRINTER_DRIVER = 1797,
3298
3299 /// The print processor is unknown.2239 /// The print processor is unknown.
3300 UNKNOWN_PRINTPROCESSOR = 1798,2240 UNKNOWN_PRINTPROCESSOR = 1798,
3301
3302 /// The specified separator file is invalid.2241 /// The specified separator file is invalid.
3303 INVALID_SEPARATOR_FILE = 1799,2242 INVALID_SEPARATOR_FILE = 1799,
3304
3305 /// The specified priority is invalid.2243 /// The specified priority is invalid.
3306 INVALID_PRIORITY = 1800,2244 INVALID_PRIORITY = 1800,
3307
3308 /// The printer name is invalid.2245 /// The printer name is invalid.
3309 INVALID_PRINTER_NAME = 1801,2246 INVALID_PRINTER_NAME = 1801,
3310
3311 /// The printer already exists.2247 /// The printer already exists.
3312 PRINTER_ALREADY_EXISTS = 1802,2248 PRINTER_ALREADY_EXISTS = 1802,
3313
3314 /// The printer command is invalid.2249 /// The printer command is invalid.
3315 INVALID_PRINTER_COMMAND = 1803,2250 INVALID_PRINTER_COMMAND = 1803,
3316
3317 /// The specified datatype is invalid.2251 /// The specified datatype is invalid.
3318 INVALID_DATATYPE = 1804,2252 INVALID_DATATYPE = 1804,
3319
3320 /// The environment specified is invalid.2253 /// The environment specified is invalid.
3321 INVALID_ENVIRONMENT = 1805,2254 INVALID_ENVIRONMENT = 1805,
3322
3323 /// There are no more bindings.2255 /// There are no more bindings.
3324 RPC_S_NO_MORE_BINDINGS = 1806,2256 RPC_S_NO_MORE_BINDINGS = 1806,
3325
3326 /// The account used is an interdomain trust account.2257 /// The account used is an interdomain trust account.
3327 /// Use your global user account or local user account to access this server.2258 /// Use your global user account or local user account to access this server.
3328 NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 1807,2259 NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 1807,
3329
3330 /// The account used is a computer account.2260 /// The account used is a computer account.
3331 /// Use your global user account or local user account to access this server.2261 /// Use your global user account or local user account to access this server.
3332 NOLOGON_WORKSTATION_TRUST_ACCOUNT = 1808,2262 NOLOGON_WORKSTATION_TRUST_ACCOUNT = 1808,
3333
3334 /// The account used is a server trust account.2263 /// The account used is a server trust account.
3335 /// Use your global user account or local user account to access this server.2264 /// Use your global user account or local user account to access this server.
3336 NOLOGON_SERVER_TRUST_ACCOUNT = 1809,2265 NOLOGON_SERVER_TRUST_ACCOUNT = 1809,
3337
3338 /// The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.2266 /// The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.
3339 DOMAIN_TRUST_INCONSISTENT = 1810,2267 DOMAIN_TRUST_INCONSISTENT = 1810,
3340
3341 /// The server is in use and cannot be unloaded.2268 /// The server is in use and cannot be unloaded.
3342 SERVER_HAS_OPEN_HANDLES = 1811,2269 SERVER_HAS_OPEN_HANDLES = 1811,
3343
3344 /// The specified image file did not contain a resource section.2270 /// The specified image file did not contain a resource section.
3345 RESOURCE_DATA_NOT_FOUND = 1812,2271 RESOURCE_DATA_NOT_FOUND = 1812,
3346
3347 /// The specified resource type cannot be found in the image file.2272 /// The specified resource type cannot be found in the image file.
3348 RESOURCE_TYPE_NOT_FOUND = 1813,2273 RESOURCE_TYPE_NOT_FOUND = 1813,
3349
3350 /// The specified resource name cannot be found in the image file.2274 /// The specified resource name cannot be found in the image file.
3351 RESOURCE_NAME_NOT_FOUND = 1814,2275 RESOURCE_NAME_NOT_FOUND = 1814,
3352
3353 /// The specified resource language ID cannot be found in the image file.2276 /// The specified resource language ID cannot be found in the image file.
3354 RESOURCE_LANG_NOT_FOUND = 1815,2277 RESOURCE_LANG_NOT_FOUND = 1815,
3355
3356 /// Not enough quota is available to process this command.2278 /// Not enough quota is available to process this command.
3357 NOT_ENOUGH_QUOTA = 1816,2279 NOT_ENOUGH_QUOTA = 1816,
3358
3359 /// No interfaces have been registered.2280 /// No interfaces have been registered.
3360 RPC_S_NO_INTERFACES = 1817,2281 RPC_S_NO_INTERFACES = 1817,
3361
3362 /// The remote procedure call was cancelled.2282 /// The remote procedure call was cancelled.
3363 RPC_S_CALL_CANCELLED = 1818,2283 RPC_S_CALL_CANCELLED = 1818,
3364
3365 /// The binding handle does not contain all required information.2284 /// The binding handle does not contain all required information.
3366 RPC_S_BINDING_INCOMPLETE = 1819,2285 RPC_S_BINDING_INCOMPLETE = 1819,
3367
3368 /// A communications failure occurred during a remote procedure call.2286 /// A communications failure occurred during a remote procedure call.
3369 RPC_S_COMM_FAILURE = 1820,2287 RPC_S_COMM_FAILURE = 1820,
3370
3371 /// The requested authentication level is not supported.2288 /// The requested authentication level is not supported.
3372 RPC_S_UNSUPPORTED_AUTHN_LEVEL = 1821,2289 RPC_S_UNSUPPORTED_AUTHN_LEVEL = 1821,
3373
3374 /// No principal name registered.2290 /// No principal name registered.
3375 RPC_S_NO_PRINC_NAME = 1822,2291 RPC_S_NO_PRINC_NAME = 1822,
3376
3377 /// The error specified is not a valid Windows RPC error code.2292 /// The error specified is not a valid Windows RPC error code.
3378 RPC_S_NOT_RPC_ERROR = 1823,2293 RPC_S_NOT_RPC_ERROR = 1823,
3379
3380 /// A UUID that is valid only on this computer has been allocated.2294 /// A UUID that is valid only on this computer has been allocated.
3381 RPC_S_UUID_LOCAL_ONLY = 1824,2295 RPC_S_UUID_LOCAL_ONLY = 1824,
3382
3383 /// A security package specific error occurred.2296 /// A security package specific error occurred.
3384 RPC_S_SEC_PKG_ERROR = 1825,2297 RPC_S_SEC_PKG_ERROR = 1825,
3385
3386 /// Thread is not canceled.2298 /// Thread is not canceled.
3387 RPC_S_NOT_CANCELLED = 1826,2299 RPC_S_NOT_CANCELLED = 1826,
3388
3389 /// Invalid operation on the encoding/decoding handle.2300 /// Invalid operation on the encoding/decoding handle.
3390 RPC_X_INVALID_ES_ACTION = 1827,2301 RPC_X_INVALID_ES_ACTION = 1827,
3391
3392 /// Incompatible version of the serializing package.2302 /// Incompatible version of the serializing package.
3393 RPC_X_WRONG_ES_VERSION = 1828,2303 RPC_X_WRONG_ES_VERSION = 1828,
3394
3395 /// Incompatible version of the RPC stub.2304 /// Incompatible version of the RPC stub.
3396 RPC_X_WRONG_STUB_VERSION = 1829,2305 RPC_X_WRONG_STUB_VERSION = 1829,
3397
3398 /// The RPC pipe object is invalid or corrupted.2306 /// The RPC pipe object is invalid or corrupted.
3399 RPC_X_INVALID_PIPE_OBJECT = 1830,2307 RPC_X_INVALID_PIPE_OBJECT = 1830,
3400
3401 /// An invalid operation was attempted on an RPC pipe object.2308 /// An invalid operation was attempted on an RPC pipe object.
3402 RPC_X_WRONG_PIPE_ORDER = 1831,2309 RPC_X_WRONG_PIPE_ORDER = 1831,
3403
3404 /// Unsupported RPC pipe version.2310 /// Unsupported RPC pipe version.
3405 RPC_X_WRONG_PIPE_VERSION = 1832,2311 RPC_X_WRONG_PIPE_VERSION = 1832,
3406
3407 /// HTTP proxy server rejected the connection because the cookie authentication failed.2312 /// HTTP proxy server rejected the connection because the cookie authentication failed.
3408 RPC_S_COOKIE_AUTH_FAILED = 1833,2313 RPC_S_COOKIE_AUTH_FAILED = 1833,
3409
3410 /// The group member was not found.2314 /// The group member was not found.
3411 RPC_S_GROUP_MEMBER_NOT_FOUND = 1898,2315 RPC_S_GROUP_MEMBER_NOT_FOUND = 1898,
3412
3413 /// The endpoint mapper database entry could not be created.2316 /// The endpoint mapper database entry could not be created.
3414 EPT_S_CANT_CREATE = 1899,2317 EPT_S_CANT_CREATE = 1899,
3415
3416 /// The object universal unique identifier (UUID) is the nil UUID.2318 /// The object universal unique identifier (UUID) is the nil UUID.
3417 RPC_S_INVALID_OBJECT = 1900,2319 RPC_S_INVALID_OBJECT = 1900,
3418
3419 /// The specified time is invalid.2320 /// The specified time is invalid.
3420 INVALID_TIME = 1901,2321 INVALID_TIME = 1901,
3421
3422 /// The specified form name is invalid.2322 /// The specified form name is invalid.
3423 INVALID_FORM_NAME = 1902,2323 INVALID_FORM_NAME = 1902,
3424
3425 /// The specified form size is invalid.2324 /// The specified form size is invalid.
3426 INVALID_FORM_SIZE = 1903,2325 INVALID_FORM_SIZE = 1903,
3427
3428 /// The specified printer handle is already being waited on.2326 /// The specified printer handle is already being waited on.
3429 ALREADY_WAITING = 1904,2327 ALREADY_WAITING = 1904,
3430
3431 /// The specified printer has been deleted.2328 /// The specified printer has been deleted.
3432 PRINTER_DELETED = 1905,2329 PRINTER_DELETED = 1905,
3433
3434 /// The state of the printer is invalid.2330 /// The state of the printer is invalid.
3435 INVALID_PRINTER_STATE = 1906,2331 INVALID_PRINTER_STATE = 1906,
3436
3437 /// The user's password must be changed before signing in.2332 /// The user's password must be changed before signing in.
3438 PASSWORD_MUST_CHANGE = 1907,2333 PASSWORD_MUST_CHANGE = 1907,
3439
3440 /// Could not find the domain controller for this domain.2334 /// Could not find the domain controller for this domain.
3441 DOMAIN_CONTROLLER_NOT_FOUND = 1908,2335 DOMAIN_CONTROLLER_NOT_FOUND = 1908,
3442
3443 /// The referenced account is currently locked out and may not be logged on to.2336 /// The referenced account is currently locked out and may not be logged on to.
3444 ACCOUNT_LOCKED_OUT = 1909,2337 ACCOUNT_LOCKED_OUT = 1909,
3445
3446 /// The object exporter specified was not found.2338 /// The object exporter specified was not found.
3447 OR_INVALID_OXID = 1910,2339 OR_INVALID_OXID = 1910,
3448
3449 /// The object specified was not found.2340 /// The object specified was not found.
3450 OR_INVALID_OID = 1911,2341 OR_INVALID_OID = 1911,
3451
3452 /// The object resolver set specified was not found.2342 /// The object resolver set specified was not found.
3453 OR_INVALID_SET = 1912,2343 OR_INVALID_SET = 1912,
3454
3455 /// Some data remains to be sent in the request buffer.2344 /// Some data remains to be sent in the request buffer.
3456 RPC_S_SEND_INCOMPLETE = 1913,2345 RPC_S_SEND_INCOMPLETE = 1913,
3457
3458 /// Invalid asynchronous remote procedure call handle.2346 /// Invalid asynchronous remote procedure call handle.
3459 RPC_S_INVALID_ASYNC_HANDLE = 1914,2347 RPC_S_INVALID_ASYNC_HANDLE = 1914,
3460
3461 /// Invalid asynchronous RPC call handle for this operation.2348 /// Invalid asynchronous RPC call handle for this operation.
3462 RPC_S_INVALID_ASYNC_CALL = 1915,2349 RPC_S_INVALID_ASYNC_CALL = 1915,
3463
3464 /// The RPC pipe object has already been closed.2350 /// The RPC pipe object has already been closed.
3465 RPC_X_PIPE_CLOSED = 1916,2351 RPC_X_PIPE_CLOSED = 1916,
3466
3467 /// The RPC call completed before all pipes were processed.2352 /// The RPC call completed before all pipes were processed.
3468 RPC_X_PIPE_DISCIPLINE_ERROR = 1917,2353 RPC_X_PIPE_DISCIPLINE_ERROR = 1917,
3469
3470 /// No more data is available from the RPC pipe.2354 /// No more data is available from the RPC pipe.
3471 RPC_X_PIPE_EMPTY = 1918,2355 RPC_X_PIPE_EMPTY = 1918,
3472
3473 /// No site name is available for this machine.2356 /// No site name is available for this machine.
3474 NO_SITENAME = 1919,2357 NO_SITENAME = 1919,
3475
3476 /// The file cannot be accessed by the system.2358 /// The file cannot be accessed by the system.
3477 CANT_ACCESS_FILE = 1920,2359 CANT_ACCESS_FILE = 1920,
3478
3479 /// The name of the file cannot be resolved by the system.2360 /// The name of the file cannot be resolved by the system.
3480 CANT_RESOLVE_FILENAME = 1921,2361 CANT_RESOLVE_FILENAME = 1921,
3481
3482 /// The entry is not of the expected type.2362 /// The entry is not of the expected type.
3483 RPC_S_ENTRY_TYPE_MISMATCH = 1922,2363 RPC_S_ENTRY_TYPE_MISMATCH = 1922,
3484
3485 /// Not all object UUIDs could be exported to the specified entry.2364 /// Not all object UUIDs could be exported to the specified entry.
3486 RPC_S_NOT_ALL_OBJS_EXPORTED = 1923,2365 RPC_S_NOT_ALL_OBJS_EXPORTED = 1923,
3487
3488 /// Interface could not be exported to the specified entry.2366 /// Interface could not be exported to the specified entry.
3489 RPC_S_INTERFACE_NOT_EXPORTED = 1924,2367 RPC_S_INTERFACE_NOT_EXPORTED = 1924,
3490
3491 /// The specified profile entry could not be added.2368 /// The specified profile entry could not be added.
3492 RPC_S_PROFILE_NOT_ADDED = 1925,2369 RPC_S_PROFILE_NOT_ADDED = 1925,
3493
3494 /// The specified profile element could not be added.2370 /// The specified profile element could not be added.
3495 RPC_S_PRF_ELT_NOT_ADDED = 1926,2371 RPC_S_PRF_ELT_NOT_ADDED = 1926,
3496
3497 /// The specified profile element could not be removed.2372 /// The specified profile element could not be removed.
3498 RPC_S_PRF_ELT_NOT_REMOVED = 1927,2373 RPC_S_PRF_ELT_NOT_REMOVED = 1927,
3499
3500 /// The group element could not be added.2374 /// The group element could not be added.
3501 RPC_S_GRP_ELT_NOT_ADDED = 1928,2375 RPC_S_GRP_ELT_NOT_ADDED = 1928,
3502
3503 /// The group element could not be removed.2376 /// The group element could not be removed.
3504 RPC_S_GRP_ELT_NOT_REMOVED = 1929,2377 RPC_S_GRP_ELT_NOT_REMOVED = 1929,
3505
3506 /// The printer driver is not compatible with a policy enabled on your computer that blocks NT 4.0 drivers.2378 /// The printer driver is not compatible with a policy enabled on your computer that blocks NT 4.0 drivers.
3507 KM_DRIVER_BLOCKED = 1930,2379 KM_DRIVER_BLOCKED = 1930,
3508
3509 /// The context has expired and can no longer be used.2380 /// The context has expired and can no longer be used.
3510 CONTEXT_EXPIRED = 1931,2381 CONTEXT_EXPIRED = 1931,
3511
3512 /// The current user's delegated trust creation quota has been exceeded.2382 /// The current user's delegated trust creation quota has been exceeded.
3513 PER_USER_TRUST_QUOTA_EXCEEDED = 1932,2383 PER_USER_TRUST_QUOTA_EXCEEDED = 1932,
3514
3515 /// The total delegated trust creation quota has been exceeded.2384 /// The total delegated trust creation quota has been exceeded.
3516 ALL_USER_TRUST_QUOTA_EXCEEDED = 1933,2385 ALL_USER_TRUST_QUOTA_EXCEEDED = 1933,
3517
3518 /// The current user's delegated trust deletion quota has been exceeded.2386 /// The current user's delegated trust deletion quota has been exceeded.
3519 USER_DELETE_TRUST_QUOTA_EXCEEDED = 1934,2387 USER_DELETE_TRUST_QUOTA_EXCEEDED = 1934,
3520
3521 /// The computer you are signing into is protected by an authentication firewall.2388 /// The computer you are signing into is protected by an authentication firewall.
3522 /// The specified account is not allowed to authenticate to the computer.2389 /// The specified account is not allowed to authenticate to the computer.
3523 AUTHENTICATION_FIREWALL_FAILED = 1935,2390 AUTHENTICATION_FIREWALL_FAILED = 1935,
3524
3525 /// Remote connections to the Print Spooler are blocked by a policy set on your machine.2391 /// Remote connections to the Print Spooler are blocked by a policy set on your machine.
3526 REMOTE_PRINT_CONNECTIONS_BLOCKED = 1936,2392 REMOTE_PRINT_CONNECTIONS_BLOCKED = 1936,
3527
3528 /// Authentication failed because NTLM authentication has been disabled.2393 /// Authentication failed because NTLM authentication has been disabled.
3529 NTLM_BLOCKED = 1937,2394 NTLM_BLOCKED = 1937,
3530
3531 /// Logon Failure: EAS policy requires that the user change their password before this operation can be performed.2395 /// Logon Failure: EAS policy requires that the user change their password before this operation can be performed.
3532 PASSWORD_CHANGE_REQUIRED = 1938,2396 PASSWORD_CHANGE_REQUIRED = 1938,
3533
3534 /// The pixel format is invalid.2397 /// The pixel format is invalid.
3535 INVALID_PIXEL_FORMAT = 2000,2398 INVALID_PIXEL_FORMAT = 2000,
3536
3537 /// The specified driver is invalid.2399 /// The specified driver is invalid.
3538 BAD_DRIVER = 2001,2400 BAD_DRIVER = 2001,
3539
3540 /// The window style or class attribute is invalid for this operation.2401 /// The window style or class attribute is invalid for this operation.
3541 INVALID_WINDOW_STYLE = 2002,2402 INVALID_WINDOW_STYLE = 2002,
3542
3543 /// The requested metafile operation is not supported.2403 /// The requested metafile operation is not supported.
3544 METAFILE_NOT_SUPPORTED = 2003,2404 METAFILE_NOT_SUPPORTED = 2003,
3545
3546 /// The requested transformation operation is not supported.2405 /// The requested transformation operation is not supported.
3547 TRANSFORM_NOT_SUPPORTED = 2004,2406 TRANSFORM_NOT_SUPPORTED = 2004,
3548
3549 /// The requested clipping operation is not supported.2407 /// The requested clipping operation is not supported.
3550 CLIPPING_NOT_SUPPORTED = 2005,2408 CLIPPING_NOT_SUPPORTED = 2005,
3551
3552 /// The specified color management module is invalid.2409 /// The specified color management module is invalid.
3553 INVALID_CMM = 2010,2410 INVALID_CMM = 2010,
3554
3555 /// The specified color profile is invalid.2411 /// The specified color profile is invalid.
3556 INVALID_PROFILE = 2011,2412 INVALID_PROFILE = 2011,
3557
3558 /// The specified tag was not found.2413 /// The specified tag was not found.
3559 TAG_NOT_FOUND = 2012,2414 TAG_NOT_FOUND = 2012,
3560
3561 /// A required tag is not present.2415 /// A required tag is not present.
3562 TAG_NOT_PRESENT = 2013,2416 TAG_NOT_PRESENT = 2013,
3563
3564 /// The specified tag is already present.2417 /// The specified tag is already present.
3565 DUPLICATE_TAG = 2014,2418 DUPLICATE_TAG = 2014,
3566
3567 /// The specified color profile is not associated with the specified device.2419 /// The specified color profile is not associated with the specified device.
3568 PROFILE_NOT_ASSOCIATED_WITH_DEVICE = 2015,2420 PROFILE_NOT_ASSOCIATED_WITH_DEVICE = 2015,
3569
3570 /// The specified color profile was not found.2421 /// The specified color profile was not found.
3571 PROFILE_NOT_FOUND = 2016,2422 PROFILE_NOT_FOUND = 2016,
3572
3573 /// The specified color space is invalid.2423 /// The specified color space is invalid.
3574 INVALID_COLORSPACE = 2017,2424 INVALID_COLORSPACE = 2017,
3575
3576 /// Image Color Management is not enabled.2425 /// Image Color Management is not enabled.
3577 ICM_NOT_ENABLED = 2018,2426 ICM_NOT_ENABLED = 2018,
3578
3579 /// There was an error while deleting the color transform.2427 /// There was an error while deleting the color transform.
3580 DELETING_ICM_XFORM = 2019,2428 DELETING_ICM_XFORM = 2019,
3581
3582 /// The specified color transform is invalid.2429 /// The specified color transform is invalid.
3583 INVALID_TRANSFORM = 2020,2430 INVALID_TRANSFORM = 2020,
3584
3585 /// The specified transform does not match the bitmap's color space.2431 /// The specified transform does not match the bitmap's color space.
3586 COLORSPACE_MISMATCH = 2021,2432 COLORSPACE_MISMATCH = 2021,
3587
3588 /// The specified named color index is not present in the profile.2433 /// The specified named color index is not present in the profile.
3589 INVALID_COLORINDEX = 2022,2434 INVALID_COLORINDEX = 2022,
3590
3591 /// The specified profile is intended for a device of a different type than the specified device.2435 /// The specified profile is intended for a device of a different type than the specified device.
3592 PROFILE_DOES_NOT_MATCH_DEVICE = 2023,2436 PROFILE_DOES_NOT_MATCH_DEVICE = 2023,
3593
3594 /// The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified.2437 /// The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified.
3595 CONNECTED_OTHER_PASSWORD = 2108,2438 CONNECTED_OTHER_PASSWORD = 2108,
3596
3597 /// The network connection was made successfully using default credentials.2439 /// The network connection was made successfully using default credentials.
3598 CONNECTED_OTHER_PASSWORD_DEFAULT = 2109,2440 CONNECTED_OTHER_PASSWORD_DEFAULT = 2109,
3599
3600 /// The specified username is invalid.2441 /// The specified username is invalid.
3601 BAD_USERNAME = 2202,2442 BAD_USERNAME = 2202,
3602
3603 /// This network connection does not exist.2443 /// This network connection does not exist.
3604 NOT_CONNECTED = 2250,2444 NOT_CONNECTED = 2250,
3605
3606 /// This network connection has files open or requests pending.2445 /// This network connection has files open or requests pending.
3607 OPEN_FILES = 2401,2446 OPEN_FILES = 2401,
3608
3609 /// Active connections still exist.2447 /// Active connections still exist.
3610 ACTIVE_CONNECTIONS = 2402,2448 ACTIVE_CONNECTIONS = 2402,
3611
3612 /// The device is in use by an active process and cannot be disconnected.2449 /// The device is in use by an active process and cannot be disconnected.
3613 DEVICE_IN_USE = 2404,2450 DEVICE_IN_USE = 2404,
3614
3615 /// The specified print monitor is unknown.2451 /// The specified print monitor is unknown.
3616 UNKNOWN_PRINT_MONITOR = 3000,2452 UNKNOWN_PRINT_MONITOR = 3000,
3617
3618 /// The specified printer driver is currently in use.2453 /// The specified printer driver is currently in use.
3619 PRINTER_DRIVER_IN_USE = 3001,2454 PRINTER_DRIVER_IN_USE = 3001,
3620
3621 /// The spool file was not found.2455 /// The spool file was not found.
3622 SPOOL_FILE_NOT_FOUND = 3002,2456 SPOOL_FILE_NOT_FOUND = 3002,
3623
3624 /// A StartDocPrinter call was not issued.2457 /// A StartDocPrinter call was not issued.
3625 SPL_NO_STARTDOC = 3003,2458 SPL_NO_STARTDOC = 3003,
3626
3627 /// An AddJob call was not issued.2459 /// An AddJob call was not issued.
3628 SPL_NO_ADDJOB = 3004,2460 SPL_NO_ADDJOB = 3004,
3629
3630 /// The specified print processor has already been installed.2461 /// The specified print processor has already been installed.
3631 PRINT_PROCESSOR_ALREADY_INSTALLED = 3005,2462 PRINT_PROCESSOR_ALREADY_INSTALLED = 3005,
3632
3633 /// The specified print monitor has already been installed.2463 /// The specified print monitor has already been installed.
3634 PRINT_MONITOR_ALREADY_INSTALLED = 3006,2464 PRINT_MONITOR_ALREADY_INSTALLED = 3006,
3635
3636 /// The specified print monitor does not have the required functions.2465 /// The specified print monitor does not have the required functions.
3637 INVALID_PRINT_MONITOR = 3007,2466 INVALID_PRINT_MONITOR = 3007,
3638
3639 /// The specified print monitor is currently in use.2467 /// The specified print monitor is currently in use.
3640 PRINT_MONITOR_IN_USE = 3008,2468 PRINT_MONITOR_IN_USE = 3008,
3641
3642 /// The requested operation is not allowed when there are jobs queued to the printer.2469 /// The requested operation is not allowed when there are jobs queued to the printer.
3643 PRINTER_HAS_JOBS_QUEUED = 3009,2470 PRINTER_HAS_JOBS_QUEUED = 3009,
3644
3645 /// The requested operation is successful.2471 /// The requested operation is successful.
3646 /// Changes will not be effective until the system is rebooted.2472 /// Changes will not be effective until the system is rebooted.
3647 SUCCESS_REBOOT_REQUIRED = 3010,2473 SUCCESS_REBOOT_REQUIRED = 3010,
3648
3649 /// The requested operation is successful.2474 /// The requested operation is successful.
3650 /// Changes will not be effective until the service is restarted.2475 /// Changes will not be effective until the service is restarted.
3651 SUCCESS_RESTART_REQUIRED = 3011,2476 SUCCESS_RESTART_REQUIRED = 3011,
3652
3653 /// No printers were found.2477 /// No printers were found.
3654 PRINTER_NOT_FOUND = 3012,2478 PRINTER_NOT_FOUND = 3012,
3655
3656 /// The printer driver is known to be unreliable.2479 /// The printer driver is known to be unreliable.
3657 PRINTER_DRIVER_WARNED = 3013,2480 PRINTER_DRIVER_WARNED = 3013,
3658
3659 /// The printer driver is known to harm the system.2481 /// The printer driver is known to harm the system.
3660 PRINTER_DRIVER_BLOCKED = 3014,2482 PRINTER_DRIVER_BLOCKED = 3014,
3661
3662 /// The specified printer driver package is currently in use.2483 /// The specified printer driver package is currently in use.
3663 PRINTER_DRIVER_PACKAGE_IN_USE = 3015,2484 PRINTER_DRIVER_PACKAGE_IN_USE = 3015,
3664
3665 /// Unable to find a core driver package that is required by the printer driver package.2485 /// Unable to find a core driver package that is required by the printer driver package.
3666 CORE_DRIVER_PACKAGE_NOT_FOUND = 3016,2486 CORE_DRIVER_PACKAGE_NOT_FOUND = 3016,
3667
3668 /// The requested operation failed.2487 /// The requested operation failed.
3669 /// A system reboot is required to roll back changes made.2488 /// A system reboot is required to roll back changes made.
3670 FAIL_REBOOT_REQUIRED = 3017,2489 FAIL_REBOOT_REQUIRED = 3017,
3671
3672 /// The requested operation failed.2490 /// The requested operation failed.
3673 /// A system reboot has been initiated to roll back changes made.2491 /// A system reboot has been initiated to roll back changes made.
3674 FAIL_REBOOT_INITIATED = 3018,2492 FAIL_REBOOT_INITIATED = 3018,
3675
3676 /// The specified printer driver was not found on the system and needs to be downloaded.2493 /// The specified printer driver was not found on the system and needs to be downloaded.
3677 PRINTER_DRIVER_DOWNLOAD_NEEDED = 3019,2494 PRINTER_DRIVER_DOWNLOAD_NEEDED = 3019,
3678
3679 /// The requested print job has failed to print.2495 /// The requested print job has failed to print.
3680 /// A print system update requires the job to be resubmitted.2496 /// A print system update requires the job to be resubmitted.
3681 PRINT_JOB_RESTART_REQUIRED = 3020,2497 PRINT_JOB_RESTART_REQUIRED = 3020,
3682
3683 /// The printer driver does not contain a valid manifest, or contains too many manifests.2498 /// The printer driver does not contain a valid manifest, or contains too many manifests.
3684 INVALID_PRINTER_DRIVER_MANIFEST = 3021,2499 INVALID_PRINTER_DRIVER_MANIFEST = 3021,
3685
3686 /// The specified printer cannot be shared.2500 /// The specified printer cannot be shared.
3687 PRINTER_NOT_SHAREABLE = 3022,2501 PRINTER_NOT_SHAREABLE = 3022,
3688
3689 /// The operation was paused.2502 /// The operation was paused.
3690 REQUEST_PAUSED = 3050,2503 REQUEST_PAUSED = 3050,
3691
3692 /// Reissue the given operation as a cached IO operation.2504 /// Reissue the given operation as a cached IO operation.
3693 IO_REISSUE_AS_CACHED = 3950,2505 IO_REISSUE_AS_CACHED = 3950,
3694
3695 _,2506 _,
3696};2507};
lib/std/os/windows/winmm.zig+6-1
...@@ -1,4 +1,9 @@...@@ -1,4 +1,9 @@
1usingnamespace @import("bits.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;
3const WINAPI = windows.WINAPI;
4const UINT = windows.UINT;
5const BYTE = windows.BYTE;
6const DWORD = windows.DWORD;
27
3pub const MMRESULT = UINT;8pub const MMRESULT = UINT;
4pub const MMSYSERR_BASE = 0;9pub const MMSYSERR_BASE = 0;
lib/std/os/windows/ws2_32.zig+253-201
...@@ -1,5 +1,23 @@...@@ -1,5 +1,23 @@
1const std = @import("../../std.zig");1const std = @import("../../std.zig");
2usingnamespace @import("bits.zig");2const windows = std.os.windows;
3
4const WINAPI = windows.WINAPI;
5const OVERLAPPED = windows.OVERLAPPED;
6const WORD = windows.WORD;
7const DWORD = windows.DWORD;
8const GUID = windows.GUID;
9const USHORT = windows.USHORT;
10const WCHAR = windows.WCHAR;
11const BOOL = windows.BOOL;
12const HANDLE = windows.HANDLE;
13const timeval = windows.timeval;
14const HWND = windows.HWND;
15const INT = windows.INT;
16const SHORT = windows.SHORT;
17const CHAR = windows.CHAR;
18const ULONG = windows.ULONG;
19const LPARAM = windows.LPARAM;
20const FARPROC = windows.FARPROC;
321
4pub const SOCKET = *opaque {};22pub const SOCKET = *opaque {};
5pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0));23pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0));
...@@ -179,7 +197,6 @@ pub const RIO_CORRUPT_CQ = 4294967295;...@@ -179,7 +197,6 @@ pub const RIO_CORRUPT_CQ = 4294967295;
179pub const WINDOWS_AF_IRDA = 26;197pub const WINDOWS_AF_IRDA = 26;
180pub const WCE_AF_IRDA = 22;198pub const WCE_AF_IRDA = 22;
181pub const IRDA_PROTO_SOCK_STREAM = 1;199pub const IRDA_PROTO_SOCK_STREAM = 1;
182pub const SOL_IRLMP = 255;
183pub const IRLMP_ENUMDEVICES = 16;200pub const IRLMP_ENUMDEVICES = 16;
184pub const IRLMP_IAS_SET = 17;201pub const IRLMP_IAS_SET = 17;
185pub const IRLMP_IAS_QUERY = 18;202pub const IRLMP_IAS_QUERY = 18;
...@@ -238,7 +255,6 @@ pub const IPX_MAX_ADAPTER_NUM = 16397;...@@ -238,7 +255,6 @@ pub const IPX_MAX_ADAPTER_NUM = 16397;
238pub const IPX_RERIPNETNUMBER = 16398;255pub const IPX_RERIPNETNUMBER = 16398;
239pub const IPX_RECEIVE_BROADCAST = 16399;256pub const IPX_RECEIVE_BROADCAST = 16399;
240pub const IPX_IMMEDIATESPXACK = 16400;257pub const IPX_IMMEDIATESPXACK = 16400;
241pub const IPPROTO_RM = 113;
242pub const MAX_MCAST_TTL = 255;258pub const MAX_MCAST_TTL = 255;
243pub const RM_OPTIONSBASE = 1000;259pub const RM_OPTIONSBASE = 1000;
244pub const RM_RATE_WINDOW_SIZE = 1001;260pub const RM_RATE_WINDOW_SIZE = 1001;
...@@ -426,101 +442,148 @@ pub const PROTECTION_LEVEL_EDGERESTRICTED = 20;...@@ -426,101 +442,148 @@ pub const PROTECTION_LEVEL_EDGERESTRICTED = 20;
426pub const PROTECTION_LEVEL_RESTRICTED = 30;442pub const PROTECTION_LEVEL_RESTRICTED = 30;
427pub const INET_ADDRSTRLEN = 22;443pub const INET_ADDRSTRLEN = 22;
428pub const INET6_ADDRSTRLEN = 65;444pub const INET6_ADDRSTRLEN = 65;
429pub const TCP_OFFLOAD_NO_PREFERENCE = 0;445
430pub const TCP_OFFLOAD_NOT_PREFERRED = 1;446pub const TCP = struct {
431pub const TCP_OFFLOAD_PREFERRED = 2;447 pub const NODELAY = 1;
432pub const TCP_EXPEDITED_1122 = 2;448 pub const EXPEDITED_1122 = 2;
433pub const TCP_KEEPALIVE = 3;449 pub const OFFLOAD_NO_PREFERENCE = 0;
434pub const TCP_MAXSEG = 4;450 pub const OFFLOAD_NOT_PREFERRED = 1;
435pub const TCP_MAXRT = 5;451 pub const OFFLOAD_PREFERRED = 2;
436pub const TCP_STDURG = 6;452 pub const KEEPALIVE = 3;
437pub const TCP_NOURG = 7;453 pub const MAXSEG = 4;
438pub const TCP_ATMARK = 8;454 pub const MAXRT = 5;
439pub const TCP_NOSYNRETRIES = 9;455 pub const STDURG = 6;
440pub const TCP_TIMESTAMPS = 10;456 pub const NOURG = 7;
441pub const TCP_OFFLOAD_PREFERENCE = 11;457 pub const ATMARK = 8;
442pub const TCP_CONGESTION_ALGORITHM = 12;458 pub const NOSYNRETRIES = 9;
443pub const TCP_DELAY_FIN_ACK = 13;459 pub const TIMESTAMPS = 10;
444pub const TCP_MAXRTMS = 14;460 pub const OFFLOAD_PREFERENCE = 11;
445pub const TCP_FASTOPEN = 15;461 pub const CONGESTION_ALGORITHM = 12;
446pub const TCP_KEEPCNT = 16;462 pub const DELAY_FIN_ACK = 13;
447pub const TCP_KEEPINTVL = 17;463 pub const MAXRTMS = 14;
448pub const TCP_FAIL_CONNECT_ON_ICMP_ERROR = 18;464 pub const FASTOPEN = 15;
449pub const TCP_ICMP_ERROR_INFO = 19;465 pub const KEEPCNT = 16;
466 pub const KEEPINTVL = 17;
467 pub const FAIL_CONNECT_ON_ICMP_ERROR = 18;
468 pub const ICMP_ERROR_INFO = 19;
469 pub const BSDURGENT = 28672;
470};
471
450pub const UDP_SEND_MSG_SIZE = 2;472pub const UDP_SEND_MSG_SIZE = 2;
451pub const UDP_RECV_MAX_COALESCED_SIZE = 3;473pub const UDP_RECV_MAX_COALESCED_SIZE = 3;
452pub const UDP_COALESCED_INFO = 3;474pub const UDP_COALESCED_INFO = 3;
453pub const AF_UNSPEC = 0;475
454pub const AF_UNIX = 1;476pub const AF = struct {
455pub const AF_INET = 2;477 pub const UNSPEC = 0;
456pub const AF_IMPLINK = 3;478 pub const UNIX = 1;
457pub const AF_PUP = 4;479 pub const INET = 2;
458pub const AF_CHAOS = 5;480 pub const IMPLINK = 3;
459pub const AF_NS = 6;481 pub const PUP = 4;
460pub const AF_ISO = 7;482 pub const CHAOS = 5;
461pub const AF_ECMA = 8;483 pub const NS = 6;
462pub const AF_DATAKIT = 9;484 pub const IPX = 6;
463pub const AF_CCITT = 10;485 pub const ISO = 7;
464pub const AF_SNA = 11;486 pub const ECMA = 8;
465pub const AF_DECnet = 12;487 pub const DATAKIT = 9;
466pub const AF_DLI = 13;488 pub const CCITT = 10;
467pub const AF_LAT = 14;489 pub const SNA = 11;
468pub const AF_HYLINK = 15;490 pub const DECnet = 12;
469pub const AF_APPLETALK = 16;491 pub const DLI = 13;
470pub const AF_NETBIOS = 17;492 pub const LAT = 14;
471pub const AF_VOICEVIEW = 18;493 pub const HYLINK = 15;
472pub const AF_FIREFOX = 19;494 pub const APPLETALK = 16;
473pub const AF_UNKNOWN1 = 20;495 pub const NETBIOS = 17;
474pub const AF_BAN = 21;496 pub const VOICEVIEW = 18;
475pub const AF_ATM = 22;497 pub const FIREFOX = 19;
476pub const AF_INET6 = 23;498 pub const UNKNOWN1 = 20;
477pub const AF_CLUSTER = 24;499 pub const BAN = 21;
478pub const AF_12844 = 25;500 pub const ATM = 22;
479pub const AF_IRDA = 26;501 pub const INET6 = 23;
480pub const AF_NETDES = 28;502 pub const CLUSTER = 24;
481pub const AF_MAX = 29;503 pub const @"12844" = 25;
482pub const AF_TCNPROCESS = 29;504 pub const IRDA = 26;
483pub const AF_TCNMESSAGE = 30;505 pub const NETDES = 28;
484pub const AF_ICLFXBM = 31;506 pub const MAX = 29;
485pub const AF_LINK = 33;507 pub const TCNPROCESS = 29;
486pub const AF_HYPERV = 34;508 pub const TCNMESSAGE = 30;
487pub const SOCK_STREAM = 1;509 pub const ICLFXBM = 31;
488pub const SOCK_DGRAM = 2;510 pub const LINK = 33;
489pub const SOCK_RAW = 3;511 pub const HYPERV = 34;
490pub const SOCK_RDM = 4;512};
491pub const SOCK_SEQPACKET = 5;513
492pub const SOL_SOCKET = 65535;514pub const SOCK = struct {
493pub const SO_DEBUG = 1;515 pub const STREAM = 1;
494pub const SO_ACCEPTCONN = 2;516 pub const DGRAM = 2;
495pub const SO_REUSEADDR = 4;517 pub const RAW = 3;
496pub const SO_KEEPALIVE = 8;518 pub const RDM = 4;
497pub const SO_DONTROUTE = 16;519 pub const SEQPACKET = 5;
498pub const SO_BROADCAST = 32;520
499pub const SO_USELOOPBACK = 64;521 /// WARNING: this flag is not supported by windows socket functions directly,
500pub const SO_LINGER = 128;522 /// it is only supported by std.os.socket. Be sure that this value does
501pub const SO_OOBINLINE = 256;523 /// not share any bits with any of the `SOCK` values.
502pub const SO_SNDBUF = 4097;524 pub const CLOEXEC = 0x10000;
503pub const SO_RCVBUF = 4098;525 /// WARNING: this flag is not supported by windows socket functions directly,
504pub const SO_SNDLOWAT = 4099;526 /// it is only supported by std.os.socket. Be sure that this value does
505pub const SO_RCVLOWAT = 4100;527 /// not share any bits with any of the `SOCK` values.
506pub const SO_SNDTIMEO = 4101;528 pub const NONBLOCK = 0x20000;
507pub const SO_RCVTIMEO = 4102;529};
508pub const SO_ERROR = 4103;530
509pub const SO_TYPE = 4104;531pub const SOL = struct {
510pub const SO_BSP_STATE = 4105;532 pub const IRLMP = 255;
511pub const SO_GROUP_ID = 8193;533 pub const SOCKET = 65535;
512pub const SO_GROUP_PRIORITY = 8194;534};
513pub const SO_MAX_MSG_SIZE = 8195;535
514pub const SO_CONDITIONAL_ACCEPT = 12290;536pub const SO = struct {
515pub const SO_PAUSE_ACCEPT = 12291;537 pub const DEBUG = 1;
516pub const SO_COMPARTMENT_ID = 12292;538 pub const ACCEPTCONN = 2;
517pub const SO_RANDOMIZE_PORT = 12293;539 pub const REUSEADDR = 4;
518pub const SO_PORT_SCALABILITY = 12294;540 pub const KEEPALIVE = 8;
519pub const SO_REUSE_UNICASTPORT = 12295;541 pub const DONTROUTE = 16;
520pub const SO_REUSE_MULTICASTPORT = 12296;542 pub const BROADCAST = 32;
521pub const SO_ORIGINAL_DST = 12303;543 pub const USELOOPBACK = 64;
544 pub const LINGER = 128;
545 pub const OOBINLINE = 256;
546 pub const SNDBUF = 4097;
547 pub const RCVBUF = 4098;
548 pub const SNDLOWAT = 4099;
549 pub const RCVLOWAT = 4100;
550 pub const SNDTIMEO = 4101;
551 pub const RCVTIMEO = 4102;
552 pub const ERROR = 4103;
553 pub const TYPE = 4104;
554 pub const BSP_STATE = 4105;
555 pub const GROUP_ID = 8193;
556 pub const GROUP_PRIORITY = 8194;
557 pub const MAX_MSG_SIZE = 8195;
558 pub const CONDITIONAL_ACCEPT = 12290;
559 pub const PAUSE_ACCEPT = 12291;
560 pub const COMPARTMENT_ID = 12292;
561 pub const RANDOMIZE_PORT = 12293;
562 pub const PORT_SCALABILITY = 12294;
563 pub const REUSE_UNICASTPORT = 12295;
564 pub const REUSE_MULTICASTPORT = 12296;
565 pub const ORIGINAL_DST = 12303;
566 pub const PROTOCOL_INFOA = 8196;
567 pub const PROTOCOL_INFOW = 8197;
568 pub const CONNDATA = 28672;
569 pub const CONNOPT = 28673;
570 pub const DISCDATA = 28674;
571 pub const DISCOPT = 28675;
572 pub const CONNDATALEN = 28676;
573 pub const CONNOPTLEN = 28677;
574 pub const DISCDATALEN = 28678;
575 pub const DISCOPTLEN = 28679;
576 pub const OPENTYPE = 28680;
577 pub const SYNCHRONOUS_ALERT = 16;
578 pub const SYNCHRONOUS_NONALERT = 32;
579 pub const MAXDG = 28681;
580 pub const MAXPATHDG = 28682;
581 pub const UPDATE_ACCEPT_CONTEXT = 28683;
582 pub const CONNECT_TIME = 28684;
583 pub const UPDATE_CONNECT_CONTEXT = 28688;
584};
585
522pub const WSK_SO_BASE = 16384;586pub const WSK_SO_BASE = 16384;
523pub const TCP_NODELAY = 1;
524pub const IOC_UNIX = 0;587pub const IOC_UNIX = 0;
525pub const IOC_WS2 = 134217728;588pub const IOC_WS2 = 134217728;
526pub const IOC_PROTOCOL = 268435456;589pub const IOC_PROTOCOL = 268435456;
...@@ -530,7 +593,6 @@ pub const SIO_BSP_HANDLE = IOC_OUT | IOC_WS2 | 27;...@@ -530,7 +593,6 @@ pub const SIO_BSP_HANDLE = IOC_OUT | IOC_WS2 | 27;
530pub const SIO_BSP_HANDLE_SELECT = IOC_OUT | IOC_WS2 | 28;593pub const SIO_BSP_HANDLE_SELECT = IOC_OUT | IOC_WS2 | 28;
531pub const SIO_BSP_HANDLE_POLL = IOC_OUT | IOC_WS2 | 29;594pub const SIO_BSP_HANDLE_POLL = IOC_OUT | IOC_WS2 | 29;
532pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;595pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;
533pub const IPPROTO_IP = 0;
534pub const IPPORT_TCPMUX = 1;596pub const IPPORT_TCPMUX = 1;
535pub const IPPORT_ECHO = 7;597pub const IPPORT_ECHO = 7;
536pub const IPPORT_DISCARD = 9;598pub const IPPORT_DISCARD = 9;
...@@ -597,27 +659,41 @@ pub const IOCPARM_MASK = 127;...@@ -597,27 +659,41 @@ pub const IOCPARM_MASK = 127;
597pub const IOC_VOID = 536870912;659pub const IOC_VOID = 536870912;
598pub const IOC_OUT = 1073741824;660pub const IOC_OUT = 1073741824;
599pub const IOC_IN = 2147483648;661pub const IOC_IN = 2147483648;
600pub const MSG_TRUNC = 256;662
601pub const MSG_CTRUNC = 512;663pub const MSG = struct {
602pub const MSG_BCAST = 1024;664 pub const TRUNC = 256;
603pub const MSG_MCAST = 2048;665 pub const CTRUNC = 512;
604pub const MSG_ERRQUEUE = 4096;666 pub const BCAST = 1024;
605pub const AI_PASSIVE = 1;667 pub const MCAST = 2048;
606pub const AI_CANONNAME = 2;668 pub const ERRQUEUE = 4096;
607pub const AI_NUMERICHOST = 4;669
608pub const AI_NUMERICSERV = 8;670 pub const PEEK = 2;
609pub const AI_DNS_ONLY = 16;671 pub const WAITALL = 8;
610pub const AI_ALL = 256;672 pub const PUSH_IMMEDIATE = 32;
611pub const AI_ADDRCONFIG = 1024;673 pub const PARTIAL = 32768;
612pub const AI_V4MAPPED = 2048;674 pub const INTERRUPT = 16;
613pub const AI_NON_AUTHORITATIVE = 16384;675 pub const MAXIOVLEN = 16;
614pub const AI_SECURE = 32768;676};
615pub const AI_RETURN_PREFERRED_NAMES = 65536;677
616pub const AI_FQDN = 131072;678pub const AI = struct {
617pub const AI_FILESERVER = 262144;679 pub const PASSIVE = 1;
618pub const AI_DISABLE_IDN_ENCODING = 524288;680 pub const CANONNAME = 2;
619pub const AI_EXTENDED = 2147483648;681 pub const NUMERICHOST = 4;
620pub const AI_RESOLUTION_HANDLE = 1073741824;682 pub const NUMERICSERV = 8;
683 pub const DNS_ONLY = 16;
684 pub const ALL = 256;
685 pub const ADDRCONFIG = 1024;
686 pub const V4MAPPED = 2048;
687 pub const NON_AUTHORITATIVE = 16384;
688 pub const SECURE = 32768;
689 pub const RETURN_PREFERRED_NAMES = 65536;
690 pub const FQDN = 131072;
691 pub const FILESERVER = 262144;
692 pub const DISABLE_IDN_ENCODING = 524288;
693 pub const EXTENDED = 2147483648;
694 pub const RESOLUTION_HANDLE = 1073741824;
695};
696
621pub const FIONBIO = -2147195266;697pub const FIONBIO = -2147195266;
622pub const ADDRINFOEX_VERSION_2 = 2;698pub const ADDRINFOEX_VERSION_2 = 2;
623pub const ADDRINFOEX_VERSION_3 = 3;699pub const ADDRINFOEX_VERSION_3 = 3;
...@@ -661,16 +737,8 @@ pub const WSADESCRIPTION_LEN = 256;...@@ -661,16 +737,8 @@ pub const WSADESCRIPTION_LEN = 256;
661pub const WSASYS_STATUS_LEN = 128;737pub const WSASYS_STATUS_LEN = 128;
662pub const SOCKET_ERROR = -1;738pub const SOCKET_ERROR = -1;
663pub const FROM_PROTOCOL_INFO = -1;739pub const FROM_PROTOCOL_INFO = -1;
664pub const SO_PROTOCOL_INFOA = 8196;
665pub const SO_PROTOCOL_INFOW = 8197;
666pub const PVD_CONFIG = 12289;740pub const PVD_CONFIG = 12289;
667pub const SOMAXCONN = 2147483647;741pub const SOMAXCONN = 2147483647;
668pub const MSG_PEEK = 2;
669pub const MSG_WAITALL = 8;
670pub const MSG_PUSH_IMMEDIATE = 32;
671pub const MSG_PARTIAL = 32768;
672pub const MSG_INTERRUPT = 16;
673pub const MSG_MAXIOVLEN = 16;
674pub const MAXGETHOSTSTRUCT = 1024;742pub const MAXGETHOSTSTRUCT = 1024;
675pub const FD_READ_BIT = 0;743pub const FD_READ_BIT = 0;
676pub const FD_WRITE_BIT = 1;744pub const FD_WRITE_BIT = 1;
...@@ -771,31 +839,18 @@ pub const RESULT_IS_ALIAS = 1;...@@ -771,31 +839,18 @@ pub const RESULT_IS_ALIAS = 1;
771pub const RESULT_IS_ADDED = 16;839pub const RESULT_IS_ADDED = 16;
772pub const RESULT_IS_CHANGED = 32;840pub const RESULT_IS_CHANGED = 32;
773pub const RESULT_IS_DELETED = 64;841pub const RESULT_IS_DELETED = 64;
774pub const POLLRDNORM = 256;842
775pub const POLLRDBAND = 512;843pub const POLL = struct {
776pub const POLLPRI = 1024;844 pub const RDNORM = 256;
777pub const POLLWRNORM = 16;845 pub const RDBAND = 512;
778pub const POLLWRBAND = 32;846 pub const PRI = 1024;
779pub const POLLERR = 1;847 pub const WRNORM = 16;
780pub const POLLHUP = 2;848 pub const WRBAND = 32;
781pub const POLLNVAL = 4;849 pub const ERR = 1;
782pub const SO_CONNDATA = 28672;850 pub const HUP = 2;
783pub const SO_CONNOPT = 28673;851 pub const NVAL = 4;
784pub const SO_DISCDATA = 28674;852};
785pub const SO_DISCOPT = 28675;853
786pub const SO_CONNDATALEN = 28676;
787pub const SO_CONNOPTLEN = 28677;
788pub const SO_DISCDATALEN = 28678;
789pub const SO_DISCOPTLEN = 28679;
790pub const SO_OPENTYPE = 28680;
791pub const SO_SYNCHRONOUS_ALERT = 16;
792pub const SO_SYNCHRONOUS_NONALERT = 32;
793pub const SO_MAXDG = 28681;
794pub const SO_MAXPATHDG = 28682;
795pub const SO_UPDATE_ACCEPT_CONTEXT = 28683;
796pub const SO_CONNECT_TIME = 28684;
797pub const SO_UPDATE_CONNECT_CONTEXT = 28688;
798pub const TCP_BSDURGENT = 28672;
799pub const TF_DISCONNECT = 1;854pub const TF_DISCONNECT = 1;
800pub const TF_REUSE_SOCKET = 2;855pub const TF_REUSE_SOCKET = 2;
801pub const TF_WRITE_BEHIND = 4;856pub const TF_WRITE_BEHIND = 4;
...@@ -818,20 +873,25 @@ pub const LSP_INBOUND_MODIFY = 16;...@@ -818,20 +873,25 @@ pub const LSP_INBOUND_MODIFY = 16;
818pub const LSP_OUTBOUND_MODIFY = 32;873pub const LSP_OUTBOUND_MODIFY = 32;
819pub const LSP_CRYPTO_COMPRESS = 64;874pub const LSP_CRYPTO_COMPRESS = 64;
820pub const LSP_LOCAL_CACHE = 128;875pub const LSP_LOCAL_CACHE = 128;
821pub const IPPROTO_ICMP = 1;876
822pub const IPPROTO_IGMP = 2;877pub const IPPROTO = struct {
823pub const IPPROTO_GGP = 3;878 pub const IP = 0;
824pub const IPPROTO_TCP = 6;879 pub const ICMP = 1;
825pub const IPPROTO_PUP = 12;880 pub const IGMP = 2;
826pub const IPPROTO_UDP = 17;881 pub const GGP = 3;
827pub const IPPROTO_IDP = 22;882 pub const TCP = 6;
828pub const IPPROTO_ND = 77;883 pub const PUP = 12;
829pub const IPPROTO_RAW = 255;884 pub const UDP = 17;
830pub const IPPROTO_MAX = 256;885 pub const IDP = 22;
886 pub const ND = 77;
887 pub const RM = 113;
888 pub const RAW = 255;
889 pub const MAX = 256;
890};
891
831pub const IP_DEFAULT_MULTICAST_TTL = 1;892pub const IP_DEFAULT_MULTICAST_TTL = 1;
832pub const IP_DEFAULT_MULTICAST_LOOP = 1;893pub const IP_DEFAULT_MULTICAST_LOOP = 1;
833pub const IP_MAX_MEMBERSHIPS = 20;894pub const IP_MAX_MEMBERSHIPS = 20;
834pub const AF_IPX = 6;
835pub const FD_READ = 1;895pub const FD_READ = 1;
836pub const FD_WRITE = 2;896pub const FD_WRITE = 2;
837pub const FD_OOB = 4;897pub const FD_OOB = 4;
...@@ -1014,14 +1074,6 @@ pub const WSANETWORKEVENTS = extern struct {...@@ -1014,14 +1074,6 @@ pub const WSANETWORKEVENTS = extern struct {
1014 iErrorCode: [10]i32,1074 iErrorCode: [10]i32,
1015};1075};
10161076
1017pub const WSAOVERLAPPED = extern struct {
1018 Internal: DWORD,
1019 InternalHigh: DWORD,
1020 Offset: DWORD,
1021 OffsetHigh: DWORD,
1022 hEvent: ?WSAEVENT,
1023};
1024
1025pub const addrinfo = addrinfoa;1077pub const addrinfo = addrinfoa;
10261078
1027pub const addrinfoa = extern struct {1079pub const addrinfoa = extern struct {
...@@ -1052,31 +1104,31 @@ pub const addrinfoexA = extern struct {...@@ -1052,31 +1104,31 @@ pub const addrinfoexA = extern struct {
1052pub const sockaddr = extern struct {1104pub const sockaddr = extern struct {
1053 family: ADDRESS_FAMILY,1105 family: ADDRESS_FAMILY,
1054 data: [14]u8,1106 data: [14]u8,
1055};
10561107
1057pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;1108 pub const storage = std.x.os.Socket.Address.Native.Storage;
10581109
1059/// IPv4 socket address1110 /// IPv4 socket address
1060pub const sockaddr_in = extern struct {1111 pub const in = extern struct {
1061 family: ADDRESS_FAMILY = AF_INET,1112 family: ADDRESS_FAMILY = AF.INET,
1062 port: USHORT,1113 port: USHORT,
1063 addr: u32,1114 addr: u32,
1064 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },1115 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
1065};1116 };
10661117
1067/// IPv6 socket address1118 /// IPv6 socket address
1068pub const sockaddr_in6 = extern struct {1119 pub const in6 = extern struct {
1069 family: ADDRESS_FAMILY = AF_INET6,1120 family: ADDRESS_FAMILY = AF.INET6,
1070 port: USHORT,1121 port: USHORT,
1071 flowinfo: u32,1122 flowinfo: u32,
1072 addr: [16]u8,1123 addr: [16]u8,
1073 scope_id: u32,1124 scope_id: u32,
1074};1125 };
10751126
1076/// UNIX domain socket address1127 /// UNIX domain socket address
1077pub const sockaddr_un = extern struct {1128 pub const un = extern struct {
1078 family: ADDRESS_FAMILY = AF_UNIX,1129 family: ADDRESS_FAMILY = AF.UNIX,
1079 path: [108]u8,1130 path: [108]u8,
1131 };
1080};1132};
10811133
1082pub const WSABUF = extern struct {1134pub const WSABUF = extern struct {
...@@ -1238,9 +1290,9 @@ pub const WinsockError = enum(u16) {...@@ -1238,9 +1290,9 @@ pub const WinsockError = enum(u16) {
12381290
1239 /// Permission denied.1291 /// Permission denied.
1240 /// An attempt was made to access a socket in a way forbidden by its access permissions.1292 /// An attempt was made to access a socket in a way forbidden by its access permissions.
1241 /// An example is using a broadcast address for sendto without broadcast permission being set using setsockopt(SO_BROADCAST).1293 /// An example is using a broadcast address for sendto without broadcast permission being set using setsockopt(SO.BROADCAST).
1242 /// Another possible reason for the WSAEACCES error is that when the bind function is called (on Windows NT 4.0 with SP4 and later), another application, service, or kernel mode driver is bound to the same address with exclusive access.1294 /// Another possible reason for the WSAEACCES error is that when the bind function is called (on Windows NT 4.0 with SP4 and later), another application, service, or kernel mode driver is bound to the same address with exclusive access.
1243 /// Such exclusive access is a new feature of Windows NT 4.0 with SP4 and later, and is implemented by using the SO_EXCLUSIVEADDRUSE option.1295 /// Such exclusive access is a new feature of Windows NT 4.0 with SP4 and later, and is implemented by using the SO.EXCLUSIVEADDRUSE option.
1244 WSAEACCES = 10013,1296 WSAEACCES = 10013,
12451297
1246 /// Bad address.1298 /// Bad address.
...@@ -1261,7 +1313,7 @@ pub const WinsockError = enum(u16) {...@@ -1261,7 +1313,7 @@ pub const WinsockError = enum(u16) {
1261 /// Resource temporarily unavailable.1313 /// Resource temporarily unavailable.
1262 /// This error is returned from operations on nonblocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket.1314 /// This error is returned from operations on nonblocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket.
1263 /// It is a nonfatal error, and the operation should be retried later.1315 /// It is a nonfatal error, and the operation should be retried later.
1264 /// It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a nonblocking SOCK_STREAM socket, since some time must elapse for the connection to be established.1316 /// It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a nonblocking SOCK.STREAM socket, since some time must elapse for the connection to be established.
1265 WSAEWOULDBLOCK = 10035,1317 WSAEWOULDBLOCK = 10035,
12661318
1267 /// Operation now in progress.1319 /// Operation now in progress.
...@@ -1289,7 +1341,7 @@ pub const WinsockError = enum(u16) {...@@ -1289,7 +1341,7 @@ pub const WinsockError = enum(u16) {
12891341
1290 /// Protocol wrong type for socket.1342 /// Protocol wrong type for socket.
1291 /// A protocol was specified in the socket function call that does not support the semantics of the socket type requested.1343 /// A protocol was specified in the socket function call that does not support the semantics of the socket type requested.
1292 /// For example, the ARPA Internet UDP protocol cannot be specified with a socket type of SOCK_STREAM.1344 /// For example, the ARPA Internet UDP protocol cannot be specified with a socket type of SOCK.STREAM.
1293 WSAEPROTOTYPE = 10041,1345 WSAEPROTOTYPE = 10041,
12941346
1295 /// Bad protocol option.1347 /// Bad protocol option.
...@@ -1298,12 +1350,12 @@ pub const WinsockError = enum(u16) {...@@ -1298,12 +1350,12 @@ pub const WinsockError = enum(u16) {
12981350
1299 /// Protocol not supported.1351 /// Protocol not supported.
1300 /// The requested protocol has not been configured into the system, or no implementation for it exists.1352 /// The requested protocol has not been configured into the system, or no implementation for it exists.
1301 /// For example, a socket call requests a SOCK_DGRAM socket, but specifies a stream protocol.1353 /// For example, a socket call requests a SOCK.DGRAM socket, but specifies a stream protocol.
1302 WSAEPROTONOSUPPORT = 10043,1354 WSAEPROTONOSUPPORT = 10043,
13031355
1304 /// Socket type not supported.1356 /// Socket type not supported.
1305 /// The support for the specified socket type does not exist in this address family.1357 /// The support for the specified socket type does not exist in this address family.
1306 /// For example, the optional type SOCK_RAW might be selected in a socket call, and the implementation does not support SOCK_RAW sockets at all.1358 /// For example, the optional type SOCK.RAW might be selected in a socket call, and the implementation does not support SOCK.RAW sockets at all.
1307 WSAESOCKTNOSUPPORT = 10044,1359 WSAESOCKTNOSUPPORT = 10044,
13081360
1309 /// Operation not supported.1361 /// Operation not supported.
...@@ -1319,14 +1371,14 @@ pub const WinsockError = enum(u16) {...@@ -1319,14 +1371,14 @@ pub const WinsockError = enum(u16) {
13191371
1320 /// Address family not supported by protocol family.1372 /// Address family not supported by protocol family.
1321 /// An address incompatible with the requested protocol was used.1373 /// An address incompatible with the requested protocol was used.
1322 /// All sockets are created with an associated address family (that is, AF_INET for Internet Protocols) and a generic protocol type (that is, SOCK_STREAM).1374 /// All sockets are created with an associated address family (that is, AF.INET for Internet Protocols) and a generic protocol type (that is, SOCK.STREAM).
1323 /// This error is returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, for example, in sendto.1375 /// This error is returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, for example, in sendto.
1324 WSAEAFNOSUPPORT = 10047,1376 WSAEAFNOSUPPORT = 10047,
13251377
1326 /// Address already in use.1378 /// Address already in use.
1327 /// Typically, only one usage of each socket address (protocol/IP address/port) is permitted.1379 /// Typically, only one usage of each socket address (protocol/IP address/port) is permitted.
1328 /// This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that was not closed properly, or one that is still in the process of closing.1380 /// This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that was not closed properly, or one that is still in the process of closing.
1329 /// For server applications that need to bind multiple sockets to the same port number, consider using setsockopt (SO_REUSEADDR).1381 /// For server applications that need to bind multiple sockets to the same port number, consider using setsockopt (SO.REUSEADDR).
1330 /// Client applications usually need not call bind at all—connect chooses an unused port automatically.1382 /// Client applications usually need not call bind at all—connect chooses an unused port automatically.
1331 /// When bind is called with a wildcard address (involving ADDR_ANY), a WSAEADDRINUSE error could be delayed until the specific address is committed.1383 /// When bind is called with a wildcard address (involving ADDR_ANY), a WSAEADDRINUSE error could be delayed until the specific address is committed.
1332 /// This could happen with a call to another function later, including connect, listen, WSAConnect, or WSAJoinLeaf.1384 /// This could happen with a call to another function later, including connect, listen, WSAConnect, or WSAJoinLeaf.
...@@ -1350,7 +1402,7 @@ pub const WinsockError = enum(u16) {...@@ -1350,7 +1402,7 @@ pub const WinsockError = enum(u16) {
13501402
1351 /// Network dropped connection on reset.1403 /// Network dropped connection on reset.
1352 /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress.1404 /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress.
1353 /// It can also be returned by setsockopt if an attempt is made to set SO_KEEPALIVE on a connection that has already failed.1405 /// It can also be returned by setsockopt if an attempt is made to set SO.KEEPALIVE on a connection that has already failed.
1354 WSAENETRESET = 10052,1406 WSAENETRESET = 10052,
13551407
1356 /// Software caused connection abort.1408 /// Software caused connection abort.
...@@ -1359,7 +1411,7 @@ pub const WinsockError = enum(u16) {...@@ -1359,7 +1411,7 @@ pub const WinsockError = enum(u16) {
13591411
1360 /// Connection reset by peer.1412 /// Connection reset by peer.
1361 /// An existing connection was forcibly closed by the remote host.1413 /// An existing connection was forcibly closed by the remote host.
1362 /// This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket).1414 /// This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO.LINGER option on the remote socket).
1363 /// This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress.1415 /// This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress.
1364 /// Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.1416 /// Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
1365 WSAECONNRESET = 10054,1417 WSAECONNRESET = 10054,
...@@ -1370,12 +1422,12 @@ pub const WinsockError = enum(u16) {...@@ -1370,12 +1422,12 @@ pub const WinsockError = enum(u16) {
13701422
1371 /// Socket is already connected.1423 /// Socket is already connected.
1372 /// A connect request was made on an already-connected socket.1424 /// A connect request was made on an already-connected socket.
1373 /// Some implementations also return this error if sendto is called on a connected SOCK_DGRAM socket (for SOCK_STREAM sockets, the to parameter in sendto is ignored) although other implementations treat this as a legal occurrence.1425 /// Some implementations also return this error if sendto is called on a connected SOCK.DGRAM socket (for SOCK.STREAM sockets, the to parameter in sendto is ignored) although other implementations treat this as a legal occurrence.
1374 WSAEISCONN = 10056,1426 WSAEISCONN = 10056,
13751427
1376 /// Socket is not connected.1428 /// Socket is not connected.
1377 /// A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using sendto) no address was supplied.1429 /// A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using sendto) no address was supplied.
1378 /// Any other type of operation might also return this error—for example, setsockopt setting SO_KEEPALIVE if the connection has been reset.1430 /// Any other type of operation might also return this error—for example, setsockopt setting SO.KEEPALIVE if the connection has been reset.
1379 WSAENOTCONN = 10057,1431 WSAENOTCONN = 10057,
13801432
1381 /// Cannot send after socket shutdown.1433 /// Cannot send after socket shutdown.
lib/std/special/compiler_rt.zig+17-1
...@@ -269,8 +269,12 @@ comptime {...@@ -269,8 +269,12 @@ comptime {
269 const __negdf2 = @import("compiler_rt/negXf2.zig").__negdf2;269 const __negdf2 = @import("compiler_rt/negXf2.zig").__negdf2;
270 @export(__negdf2, .{ .name = "__negdf2", .linkage = linkage });270 @export(__negdf2, .{ .name = "__negdf2", .linkage = linkage });
271271
272 const __clzsi2 = @import("compiler_rt/clzsi2.zig").__clzsi2;272 const __clzsi2 = @import("compiler_rt/count0bits.zig").__clzsi2;
273 @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });273 @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
274 const __clzdi2 = @import("compiler_rt/count0bits.zig").__clzdi2;
275 @export(__clzdi2, .{ .name = "__clzdi2", .linkage = linkage });
276 const __clzti2 = @import("compiler_rt/count0bits.zig").__clzti2;
277 @export(__clzti2, .{ .name = "__clzti2", .linkage = linkage });
274278
275 if (builtin.link_libc and os_tag == .openbsd) {279 if (builtin.link_libc and os_tag == .openbsd) {
276 const __emutls_get_address = @import("compiler_rt/emutls.zig").__emutls_get_address;280 const __emutls_get_address = @import("compiler_rt/emutls.zig").__emutls_get_address;
...@@ -572,6 +576,18 @@ comptime {...@@ -572,6 +576,18 @@ comptime {
572 },576 },
573 else => {},577 else => {},
574 }578 }
579 if (arch.isAARCH64()) {
580 const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
581 @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
582 const __divti3_windows = @import("compiler_rt/divti3.zig").__divti3;
583 @export(__divti3_windows, .{ .name = "__divti3", .linkage = linkage });
584 const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
585 @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
586 const __udivti3_windows = @import("compiler_rt/udivti3.zig").__udivti3;
587 @export(__udivti3_windows, .{ .name = "__udivti3", .linkage = linkage });
588 const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
589 @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
590 }
575 } else {591 } else {
576 const __divti3 = @import("compiler_rt/divti3.zig").__divti3;592 const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
577 @export(__divti3, .{ .name = "__divti3", .linkage = linkage });593 @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
lib/std/special/compiler_rt/addXf3.zig+1-1
...@@ -225,6 +225,6 @@ fn addXf3(comptime T: type, a: T, b: T) T {...@@ -225,6 +225,6 @@ fn addXf3(comptime T: type, a: T, b: T) T {
225 return @bitCast(T, result);225 return @bitCast(T, result);
226}226}
227227
228test "import addXf3" {228test {
229 _ = @import("addXf3_test.zig");229 _ = @import("addXf3_test.zig");
230}230}
lib/std/special/compiler_rt/clzdi2_test.zig created+329
...@@ -0,0 +1,329 @@
1const clz = @import("count0bits.zig");
2const testing = @import("std").testing;
3
4fn test__clzdi2(a: u64, expected: i64) !void {
5 // XXX At high optimization levels this test may be horribly miscompiled if
6 // one of the naked implementations is selected.
7 var nakedClzdi2 = clz.__clzdi2;
8 var actualClzdi2 = @ptrCast(fn (a: i64) callconv(.C) i32, nakedClzdi2);
9 var x = @bitCast(i64, a);
10 var result = actualClzdi2(x);
11 try testing.expectEqual(expected, result);
12}
13
14test "clzdi2" {
15 try test__clzdi2(0x00800000_00000000, 8);
16 try test__clzdi2(0x01000000_00000000, 7);
17 try test__clzdi2(0x02000000_00000000, 6);
18 try test__clzdi2(0x03000000_00000000, 6);
19 try test__clzdi2(0x04000000_00000000, 5);
20 try test__clzdi2(0x05000000_00000000, 5);
21 try test__clzdi2(0x06000000_00000000, 5);
22 try test__clzdi2(0x07000000_00000000, 5);
23 try test__clzdi2(0x08000000_00000000, 4);
24 try test__clzdi2(0x09000000_00000000, 4);
25 try test__clzdi2(0x0A000000_00000000, 4);
26 try test__clzdi2(0x0B000000_00000000, 4);
27 try test__clzdi2(0x0C000000_00000000, 4);
28 try test__clzdi2(0x0D000000_00000000, 4);
29 try test__clzdi2(0x0E000000_00000000, 4);
30 try test__clzdi2(0x0F000000_00000000, 4);
31 try test__clzdi2(0x10000000_00000000, 3);
32 try test__clzdi2(0x11000000_00000000, 3);
33 try test__clzdi2(0x12000000_00000000, 3);
34 try test__clzdi2(0x13000000_00000000, 3);
35 try test__clzdi2(0x14000000_00000000, 3);
36 try test__clzdi2(0x15000000_00000000, 3);
37 try test__clzdi2(0x16000000_00000000, 3);
38 try test__clzdi2(0x17000000_00000000, 3);
39 try test__clzdi2(0x18000000_00000000, 3);
40 try test__clzdi2(0x19000000_00000000, 3);
41 try test__clzdi2(0x1A000000_00000000, 3);
42 try test__clzdi2(0x1B000000_00000000, 3);
43 try test__clzdi2(0x1C000000_00000000, 3);
44 try test__clzdi2(0x1D000000_00000000, 3);
45 try test__clzdi2(0x1E000000_00000000, 3);
46 try test__clzdi2(0x1F000000_00000000, 3);
47 try test__clzdi2(0x20000000_00000000, 2);
48 try test__clzdi2(0x21000000_00000000, 2);
49 try test__clzdi2(0x22000000_00000000, 2);
50 try test__clzdi2(0x23000000_00000000, 2);
51 try test__clzdi2(0x24000000_00000000, 2);
52 try test__clzdi2(0x25000000_00000000, 2);
53 try test__clzdi2(0x26000000_00000000, 2);
54 try test__clzdi2(0x27000000_00000000, 2);
55 try test__clzdi2(0x28000000_00000000, 2);
56 try test__clzdi2(0x29000000_00000000, 2);
57 try test__clzdi2(0x2A000000_00000000, 2);
58 try test__clzdi2(0x2B000000_00000000, 2);
59 try test__clzdi2(0x2C000000_00000000, 2);
60 try test__clzdi2(0x2D000000_00000000, 2);
61 try test__clzdi2(0x2E000000_00000000, 2);
62 try test__clzdi2(0x2F000000_00000000, 2);
63 try test__clzdi2(0x30000000_00000000, 2);
64 try test__clzdi2(0x31000000_00000000, 2);
65 try test__clzdi2(0x32000000_00000000, 2);
66 try test__clzdi2(0x33000000_00000000, 2);
67 try test__clzdi2(0x34000000_00000000, 2);
68 try test__clzdi2(0x35000000_00000000, 2);
69 try test__clzdi2(0x36000000_00000000, 2);
70 try test__clzdi2(0x37000000_00000000, 2);
71 try test__clzdi2(0x38000000_00000000, 2);
72 try test__clzdi2(0x39000000_00000000, 2);
73 try test__clzdi2(0x3A000000_00000000, 2);
74 try test__clzdi2(0x3B000000_00000000, 2);
75 try test__clzdi2(0x3C000000_00000000, 2);
76 try test__clzdi2(0x3D000000_00000000, 2);
77 try test__clzdi2(0x3E000000_00000000, 2);
78 try test__clzdi2(0x3F000000_00000000, 2);
79 try test__clzdi2(0x40000000_00000000, 1);
80 try test__clzdi2(0x41000000_00000000, 1);
81 try test__clzdi2(0x42000000_00000000, 1);
82 try test__clzdi2(0x43000000_00000000, 1);
83 try test__clzdi2(0x44000000_00000000, 1);
84 try test__clzdi2(0x45000000_00000000, 1);
85 try test__clzdi2(0x46000000_00000000, 1);
86 try test__clzdi2(0x47000000_00000000, 1);
87 try test__clzdi2(0x48000000_00000000, 1);
88 try test__clzdi2(0x49000000_00000000, 1);
89 try test__clzdi2(0x4A000000_00000000, 1);
90 try test__clzdi2(0x4B000000_00000000, 1);
91 try test__clzdi2(0x4C000000_00000000, 1);
92 try test__clzdi2(0x4D000000_00000000, 1);
93 try test__clzdi2(0x4E000000_00000000, 1);
94 try test__clzdi2(0x4F000000_00000000, 1);
95 try test__clzdi2(0x50000000_00000000, 1);
96 try test__clzdi2(0x51000000_00000000, 1);
97 try test__clzdi2(0x52000000_00000000, 1);
98 try test__clzdi2(0x53000000_00000000, 1);
99 try test__clzdi2(0x54000000_00000000, 1);
100 try test__clzdi2(0x55000000_00000000, 1);
101 try test__clzdi2(0x56000000_00000000, 1);
102 try test__clzdi2(0x57000000_00000000, 1);
103 try test__clzdi2(0x58000000_00000000, 1);
104 try test__clzdi2(0x59000000_00000000, 1);
105 try test__clzdi2(0x5A000000_00000000, 1);
106 try test__clzdi2(0x5B000000_00000000, 1);
107 try test__clzdi2(0x5C000000_00000000, 1);
108 try test__clzdi2(0x5D000000_00000000, 1);
109 try test__clzdi2(0x5E000000_00000000, 1);
110 try test__clzdi2(0x5F000000_00000000, 1);
111 try test__clzdi2(0x60000000_00000000, 1);
112 try test__clzdi2(0x61000000_00000000, 1);
113 try test__clzdi2(0x62000000_00000000, 1);
114 try test__clzdi2(0x63000000_00000000, 1);
115 try test__clzdi2(0x64000000_00000000, 1);
116 try test__clzdi2(0x65000000_00000000, 1);
117 try test__clzdi2(0x66000000_00000000, 1);
118 try test__clzdi2(0x67000000_00000000, 1);
119 try test__clzdi2(0x68000000_00000000, 1);
120 try test__clzdi2(0x69000000_00000000, 1);
121 try test__clzdi2(0x6A000000_00000000, 1);
122 try test__clzdi2(0x6B000000_00000000, 1);
123 try test__clzdi2(0x6C000000_00000000, 1);
124 try test__clzdi2(0x6D000000_00000000, 1);
125 try test__clzdi2(0x6E000000_00000000, 1);
126 try test__clzdi2(0x6F000000_00000000, 1);
127 try test__clzdi2(0x70000000_00000000, 1);
128 try test__clzdi2(0x71000000_00000000, 1);
129 try test__clzdi2(0x72000000_00000000, 1);
130 try test__clzdi2(0x73000000_00000000, 1);
131 try test__clzdi2(0x74000000_00000000, 1);
132 try test__clzdi2(0x75000000_00000000, 1);
133 try test__clzdi2(0x76000000_00000000, 1);
134 try test__clzdi2(0x77000000_00000000, 1);
135 try test__clzdi2(0x78000000_00000000, 1);
136 try test__clzdi2(0x79000000_00000000, 1);
137 try test__clzdi2(0x7A000000_00000000, 1);
138 try test__clzdi2(0x7B000000_00000000, 1);
139 try test__clzdi2(0x7C000000_00000000, 1);
140 try test__clzdi2(0x7D000000_00000000, 1);
141 try test__clzdi2(0x7E000000_00000000, 1);
142 try test__clzdi2(0x7F000000_00000000, 1);
143 try test__clzdi2(0x80000000_00000000, 0);
144 try test__clzdi2(0x81000000_00000000, 0);
145 try test__clzdi2(0x82000000_00000000, 0);
146 try test__clzdi2(0x83000000_00000000, 0);
147 try test__clzdi2(0x84000000_00000000, 0);
148 try test__clzdi2(0x85000000_00000000, 0);
149 try test__clzdi2(0x86000000_00000000, 0);
150 try test__clzdi2(0x87000000_00000000, 0);
151 try test__clzdi2(0x88000000_00000000, 0);
152 try test__clzdi2(0x89000000_00000000, 0);
153 try test__clzdi2(0x8A000000_00000000, 0);
154 try test__clzdi2(0x8B000000_00000000, 0);
155 try test__clzdi2(0x8C000000_00000000, 0);
156 try test__clzdi2(0x8D000000_00000000, 0);
157 try test__clzdi2(0x8E000000_00000000, 0);
158 try test__clzdi2(0x8F000000_00000000, 0);
159 try test__clzdi2(0x90000000_00000000, 0);
160 try test__clzdi2(0x91000000_00000000, 0);
161 try test__clzdi2(0x92000000_00000000, 0);
162 try test__clzdi2(0x93000000_00000000, 0);
163 try test__clzdi2(0x94000000_00000000, 0);
164 try test__clzdi2(0x95000000_00000000, 0);
165 try test__clzdi2(0x96000000_00000000, 0);
166 try test__clzdi2(0x97000000_00000000, 0);
167 try test__clzdi2(0x98000000_00000000, 0);
168 try test__clzdi2(0x99000000_00000000, 0);
169 try test__clzdi2(0x9A000000_00000000, 0);
170 try test__clzdi2(0x9B000000_00000000, 0);
171 try test__clzdi2(0x9C000000_00000000, 0);
172 try test__clzdi2(0x9D000000_00000000, 0);
173 try test__clzdi2(0x9E000000_00000000, 0);
174 try test__clzdi2(0x9F000000_00000000, 0);
175 try test__clzdi2(0xA0000000_00000000, 0);
176 try test__clzdi2(0xA1000000_00000000, 0);
177 try test__clzdi2(0xA2000000_00000000, 0);
178 try test__clzdi2(0xA3000000_00000000, 0);
179 try test__clzdi2(0xA4000000_00000000, 0);
180 try test__clzdi2(0xA5000000_00000000, 0);
181 try test__clzdi2(0xA6000000_00000000, 0);
182 try test__clzdi2(0xA7000000_00000000, 0);
183 try test__clzdi2(0xA8000000_00000000, 0);
184 try test__clzdi2(0xA9000000_00000000, 0);
185 try test__clzdi2(0xAA000000_00000000, 0);
186 try test__clzdi2(0xAB000000_00000000, 0);
187 try test__clzdi2(0xAC000000_00000000, 0);
188 try test__clzdi2(0xAD000000_00000000, 0);
189 try test__clzdi2(0xAE000000_00000000, 0);
190 try test__clzdi2(0xAF000000_00000000, 0);
191 try test__clzdi2(0xB0000000_00000000, 0);
192 try test__clzdi2(0xB1000000_00000000, 0);
193 try test__clzdi2(0xB2000000_00000000, 0);
194 try test__clzdi2(0xB3000000_00000000, 0);
195 try test__clzdi2(0xB4000000_00000000, 0);
196 try test__clzdi2(0xB5000000_00000000, 0);
197 try test__clzdi2(0xB6000000_00000000, 0);
198 try test__clzdi2(0xB7000000_00000000, 0);
199 try test__clzdi2(0xB8000000_00000000, 0);
200 try test__clzdi2(0xB9000000_00000000, 0);
201 try test__clzdi2(0xBA000000_00000000, 0);
202 try test__clzdi2(0xBB000000_00000000, 0);
203 try test__clzdi2(0xBC000000_00000000, 0);
204 try test__clzdi2(0xBD000000_00000000, 0);
205 try test__clzdi2(0xBE000000_00000000, 0);
206 try test__clzdi2(0xBF000000_00000000, 0);
207 try test__clzdi2(0xC0000000_00000000, 0);
208 try test__clzdi2(0xC1000000_00000000, 0);
209 try test__clzdi2(0xC2000000_00000000, 0);
210 try test__clzdi2(0xC3000000_00000000, 0);
211 try test__clzdi2(0xC4000000_00000000, 0);
212 try test__clzdi2(0xC5000000_00000000, 0);
213 try test__clzdi2(0xC6000000_00000000, 0);
214 try test__clzdi2(0xC7000000_00000000, 0);
215 try test__clzdi2(0xC8000000_00000000, 0);
216 try test__clzdi2(0xC9000000_00000000, 0);
217 try test__clzdi2(0xCA000000_00000000, 0);
218 try test__clzdi2(0xCB000000_00000000, 0);
219 try test__clzdi2(0xCC000000_00000000, 0);
220 try test__clzdi2(0xCD000000_00000000, 0);
221 try test__clzdi2(0xCE000000_00000000, 0);
222 try test__clzdi2(0xCF000000_00000000, 0);
223 try test__clzdi2(0xD0000000_00000000, 0);
224 try test__clzdi2(0xD1000000_00000000, 0);
225 try test__clzdi2(0xD2000000_00000000, 0);
226 try test__clzdi2(0xD3000000_00000000, 0);
227 try test__clzdi2(0xD4000000_00000000, 0);
228 try test__clzdi2(0xD5000000_00000000, 0);
229 try test__clzdi2(0xD6000000_00000000, 0);
230 try test__clzdi2(0xD7000000_00000000, 0);
231 try test__clzdi2(0xD8000000_00000000, 0);
232 try test__clzdi2(0xD9000000_00000000, 0);
233 try test__clzdi2(0xDA000000_00000000, 0);
234 try test__clzdi2(0xDB000000_00000000, 0);
235 try test__clzdi2(0xDC000000_00000000, 0);
236 try test__clzdi2(0xDD000000_00000000, 0);
237 try test__clzdi2(0xDE000000_00000000, 0);
238 try test__clzdi2(0xDF000000_00000000, 0);
239 try test__clzdi2(0xE0000000_00000000, 0);
240 try test__clzdi2(0xE1000000_00000000, 0);
241 try test__clzdi2(0xE2000000_00000000, 0);
242 try test__clzdi2(0xE3000000_00000000, 0);
243 try test__clzdi2(0xE4000000_00000000, 0);
244 try test__clzdi2(0xE5000000_00000000, 0);
245 try test__clzdi2(0xE6000000_00000000, 0);
246 try test__clzdi2(0xE7000000_00000000, 0);
247 try test__clzdi2(0xE8000000_00000000, 0);
248 try test__clzdi2(0xE9000000_00000000, 0);
249 try test__clzdi2(0xEA000000_00000000, 0);
250 try test__clzdi2(0xEB000000_00000000, 0);
251 try test__clzdi2(0xEC000000_00000000, 0);
252 try test__clzdi2(0xED000000_00000000, 0);
253 try test__clzdi2(0xEE000000_00000000, 0);
254 try test__clzdi2(0xEF000000_00000000, 0);
255 try test__clzdi2(0xF0000000_00000000, 0);
256 try test__clzdi2(0xF1000000_00000000, 0);
257 try test__clzdi2(0xF2000000_00000000, 0);
258 try test__clzdi2(0xF3000000_00000000, 0);
259 try test__clzdi2(0xF4000000_00000000, 0);
260 try test__clzdi2(0xF5000000_00000000, 0);
261 try test__clzdi2(0xF6000000_00000000, 0);
262 try test__clzdi2(0xF7000000_00000000, 0);
263 try test__clzdi2(0xF8000000_00000000, 0);
264 try test__clzdi2(0xF9000000_00000000, 0);
265 try test__clzdi2(0xFA000000_00000000, 0);
266 try test__clzdi2(0xFB000000_00000000, 0);
267 try test__clzdi2(0xFC000000_00000000, 0);
268 try test__clzdi2(0xFD000000_00000000, 0);
269 try test__clzdi2(0xFE000000_00000000, 0);
270 try test__clzdi2(0xFF000000_00000000, 0);
271
272 try test__clzdi2(0x00000000_00000000, 64);
273 try test__clzdi2(0x00000000_00000001, 63);
274 try test__clzdi2(0x00000000_00000002, 62);
275 try test__clzdi2(0x00000000_00000004, 61);
276 try test__clzdi2(0x00000000_00000008, 60);
277 try test__clzdi2(0x00000000_00000010, 59);
278 try test__clzdi2(0x00000000_00000020, 58);
279 try test__clzdi2(0x00000000_00000040, 57);
280 try test__clzdi2(0x00000000_00000080, 56);
281 try test__clzdi2(0x00000000_00000100, 55);
282 try test__clzdi2(0x00000000_00000200, 54);
283 try test__clzdi2(0x00000000_00000400, 53);
284 try test__clzdi2(0x00000000_00000800, 52);
285 try test__clzdi2(0x00000000_00001000, 51);
286 try test__clzdi2(0x00000000_00002000, 50);
287 try test__clzdi2(0x00000000_00004000, 49);
288 try test__clzdi2(0x00000000_00008000, 48);
289 try test__clzdi2(0x00000000_00010000, 47);
290 try test__clzdi2(0x00000000_00020000, 46);
291 try test__clzdi2(0x00000000_00040000, 45);
292 try test__clzdi2(0x00000000_00080000, 44);
293 try test__clzdi2(0x00000000_00100000, 43);
294 try test__clzdi2(0x00000000_00200000, 42);
295 try test__clzdi2(0x00000000_00400000, 41);
296 try test__clzdi2(0x00000000_00800000, 40);
297 try test__clzdi2(0x00000000_01000000, 39);
298 try test__clzdi2(0x00000000_02000000, 38);
299 try test__clzdi2(0x00000000_04000000, 37);
300 try test__clzdi2(0x00000000_08000000, 36);
301 try test__clzdi2(0x00000000_10000000, 35);
302 try test__clzdi2(0x00000000_20000000, 34);
303 try test__clzdi2(0x00000000_40000000, 33);
304 try test__clzdi2(0x00000000_80000000, 32);
305
306 try test__clzdi2(0x00000001_00000000, 31);
307 try test__clzdi2(0x00000002_00000000, 30);
308 try test__clzdi2(0x00000004_00000000, 29);
309 try test__clzdi2(0x00000008_00000000, 28);
310 try test__clzdi2(0x00000010_00000000, 27);
311 try test__clzdi2(0x00000020_00000000, 26);
312 try test__clzdi2(0x00000040_00000000, 25);
313 try test__clzdi2(0x00000080_00000000, 24);
314 try test__clzdi2(0x00000100_00000000, 23);
315 try test__clzdi2(0x00000200_00000000, 22);
316 try test__clzdi2(0x00000400_00000000, 21);
317 try test__clzdi2(0x00000800_00000000, 20);
318 try test__clzdi2(0x00001000_00000000, 19);
319 try test__clzdi2(0x00002000_00000000, 18);
320 try test__clzdi2(0x00004000_00000000, 17);
321 try test__clzdi2(0x00008000_00000000, 16);
322 try test__clzdi2(0x00010000_00000000, 15);
323 try test__clzdi2(0x00020000_00000000, 14);
324 try test__clzdi2(0x00040000_00000000, 13);
325 try test__clzdi2(0x00080000_00000000, 12);
326 try test__clzdi2(0x00100000_00000000, 11);
327 try test__clzdi2(0x00200000_00000000, 10);
328 try test__clzdi2(0x00400000_00000000, 9);
329}
lib/std/special/compiler_rt/clzsi2.zig deleted-126
...@@ -1,126 +0,0 @@
1const std = @import("std");
2const builtin = std.builtin;
3
4fn __clzsi2_generic(a: i32) callconv(.C) i32 {
5 @setRuntimeSafety(builtin.is_test);
6
7 var x = @bitCast(u32, a);
8 var n: i32 = 32;
9
10 // Count first bit set using binary search, from Hacker's Delight
11 var y: u32 = 0;
12 inline for ([_]i32{ 16, 8, 4, 2, 1 }) |shift| {
13 y = x >> shift;
14 if (y != 0) {
15 n = n - shift;
16 x = y;
17 }
18 }
19
20 return n - @bitCast(i32, x);
21}
22
23fn __clzsi2_thumb1() callconv(.Naked) void {
24 @setRuntimeSafety(false);
25
26 // Similar to the generic version with the last two rounds replaced by a LUT
27 asm volatile (
28 \\ movs r1, #32
29 \\ lsrs r2, r0, #16
30 \\ beq 1f
31 \\ subs r1, #16
32 \\ movs r0, r2
33 \\ 1:
34 \\ lsrs r2, r0, #8
35 \\ beq 1f
36 \\ subs r1, #8
37 \\ movs r0, r2
38 \\ 1:
39 \\ lsrs r2, r0, #4
40 \\ beq 1f
41 \\ subs r1, #4
42 \\ movs r0, r2
43 \\ 1:
44 \\ ldr r3, =LUT
45 \\ ldrb r0, [r3, r0]
46 \\ subs r0, r1, r0
47 \\ bx lr
48 \\ .p2align 2
49 \\ // Number of bits set in the 0-15 range
50 \\ LUT:
51 \\ .byte 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4
52 );
53
54 unreachable;
55}
56
57fn __clzsi2_arm32() callconv(.Naked) void {
58 @setRuntimeSafety(false);
59
60 asm volatile (
61 \\ // Assumption: n != 0
62 \\ // r0: n
63 \\ // r1: count of leading zeros in n + 1
64 \\ // r2: scratch register for shifted r0
65 \\ mov r1, #1
66 \\
67 \\ // Basic block:
68 \\ // if ((r0 >> SHIFT) == 0)
69 \\ // r1 += SHIFT;
70 \\ // else
71 \\ // r0 >>= SHIFT;
72 \\ // for descending powers of two as SHIFT.
73 \\ lsrs r2, r0, #16
74 \\ movne r0, r2
75 \\ addeq r1, #16
76 \\
77 \\ lsrs r2, r0, #8
78 \\ movne r0, r2
79 \\ addeq r1, #8
80 \\
81 \\ lsrs r2, r0, #4
82 \\ movne r0, r2
83 \\ addeq r1, #4
84 \\
85 \\ lsrs r2, r0, #2
86 \\ movne r0, r2
87 \\ addeq r1, #2
88 \\
89 \\ // The basic block invariants at this point are (r0 >> 2) == 0 and
90 \\ // r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1.
91 \\ //
92 \\ // r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)f
93 \\ // ---+----------------+----------------+------------+--------------
94 \\ // 1 | 1 | 0 | 0 | 1
95 \\ // 2 | 0 | 1 | -1 | 0
96 \\ // 3 | 0 | 1 | -1 | 0
97 \\ //
98 \\ // The r1's initial value of 1 compensates for the 1 here.
99 \\ sub r0, r1, r0, lsr #1
100 \\ bx lr
101 );
102
103 unreachable;
104}
105
106pub const __clzsi2 = impl: {
107 switch (std.Target.current.cpu.arch) {
108 .arm, .armeb, .thumb, .thumbeb => {
109 const use_thumb1 =
110 (std.Target.current.cpu.arch.isThumb() or
111 std.Target.arm.featureSetHas(std.Target.current.cpu.features, .noarm)) and
112 !std.Target.arm.featureSetHas(std.Target.current.cpu.features, .thumb2);
113
114 if (use_thumb1) break :impl __clzsi2_thumb1
115 // From here on we're either targeting Thumb2 or ARM.
116 else if (!std.Target.current.cpu.arch.isThumb()) break :impl __clzsi2_arm32
117 // Use the generic implementation otherwise.
118 else break :impl __clzsi2_generic;
119 },
120 else => break :impl __clzsi2_generic,
121 }
122};
123
124test "test clzsi2" {
125 _ = @import("clzsi2_test.zig");
126}
lib/std/special/compiler_rt/clzsi2_test.zig+4-2
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1const clzsi2 = @import("clzsi2.zig");1const clz = @import("count0bits.zig");
2const testing = @import("std").testing;2const testing = @import("std").testing;
33
4fn test__clzsi2(a: u32, expected: i32) !void {4fn test__clzsi2(a: u32, expected: i32) !void {
5 // XXX At high optimization levels this test may be horribly miscompiled if5 // XXX At high optimization levels this test may be horribly miscompiled if
6 // one of the naked implementations is selected.6 // one of the naked implementations is selected.
7 var nakedClzsi2 = clzsi2.__clzsi2;7 var nakedClzsi2 = clz.__clzsi2;
8 var actualClzsi2 = @ptrCast(fn (a: i32) callconv(.C) i32, nakedClzsi2);8 var actualClzsi2 = @ptrCast(fn (a: i32) callconv(.C) i32, nakedClzsi2);
9 var x = @bitCast(i32, a);9 var x = @bitCast(i32, a);
10 var result = actualClzsi2(x);10 var result = actualClzsi2(x);
...@@ -268,6 +268,8 @@ test "clzsi2" {...@@ -268,6 +268,8 @@ test "clzsi2" {
268 try test__clzsi2(0xFD000000, 0);268 try test__clzsi2(0xFD000000, 0);
269 try test__clzsi2(0xFE000000, 0);269 try test__clzsi2(0xFE000000, 0);
270 try test__clzsi2(0xFF000000, 0);270 try test__clzsi2(0xFF000000, 0);
271 // arm and thumb1 assume input a != 0
272 //try test__clzsi2(0x00000000, 32);
271 try test__clzsi2(0x00000001, 31);273 try test__clzsi2(0x00000001, 31);
272 try test__clzsi2(0x00000002, 30);274 try test__clzsi2(0x00000002, 30);
273 try test__clzsi2(0x00000004, 29);275 try test__clzsi2(0x00000004, 29);
lib/std/special/compiler_rt/clzti2_test.zig created+395
...@@ -0,0 +1,395 @@
1const clz = @import("count0bits.zig");
2const testing = @import("std").testing;
3
4fn test__clzti2(a: u128, expected: i64) !void {
5 // XXX At high optimization levels this test may be horribly miscompiled if
6 // one of the naked implementations is selected.
7 var nakedClzti2 = clz.__clzti2;
8 var actualClzti2 = @ptrCast(fn (a: i128) callconv(.C) i32, nakedClzti2);
9 var x = @bitCast(i128, a);
10 var result = actualClzti2(x);
11 try testing.expectEqual(expected, result);
12}
13
14test "clzti2" {
15 try test__clzti2(0x00800000_00000000_00000000_00000000, 8);
16 try test__clzti2(0x01000000_00000000_00000000_00000000, 7);
17 try test__clzti2(0x02000000_00000000_00000000_00000000, 6);
18 try test__clzti2(0x03000000_00000000_00000000_00000000, 6);
19 try test__clzti2(0x04000000_00000000_00000000_00000000, 5);
20 try test__clzti2(0x05000000_00000000_00000000_00000000, 5);
21 try test__clzti2(0x06000000_00000000_00000000_00000000, 5);
22 try test__clzti2(0x07000000_00000000_00000000_00000000, 5);
23 try test__clzti2(0x08000000_00000000_00000000_00000000, 4);
24 try test__clzti2(0x09000000_00000000_00000000_00000000, 4);
25 try test__clzti2(0x0A000000_00000000_00000000_00000000, 4);
26 try test__clzti2(0x0B000000_00000000_00000000_00000000, 4);
27 try test__clzti2(0x0C000000_00000000_00000000_00000000, 4);
28 try test__clzti2(0x0D000000_00000000_00000000_00000000, 4);
29 try test__clzti2(0x0E000000_00000000_00000000_00000000, 4);
30 try test__clzti2(0x0F000000_00000000_00000000_00000000, 4);
31 try test__clzti2(0x10000000_00000000_00000000_00000000, 3);
32 try test__clzti2(0x11000000_00000000_00000000_00000000, 3);
33 try test__clzti2(0x12000000_00000000_00000000_00000000, 3);
34 try test__clzti2(0x13000000_00000000_00000000_00000000, 3);
35 try test__clzti2(0x14000000_00000000_00000000_00000000, 3);
36 try test__clzti2(0x15000000_00000000_00000000_00000000, 3);
37 try test__clzti2(0x16000000_00000000_00000000_00000000, 3);
38 try test__clzti2(0x17000000_00000000_00000000_00000000, 3);
39 try test__clzti2(0x18000000_00000000_00000000_00000000, 3);
40 try test__clzti2(0x19000000_00000000_00000000_00000000, 3);
41 try test__clzti2(0x1A000000_00000000_00000000_00000000, 3);
42 try test__clzti2(0x1B000000_00000000_00000000_00000000, 3);
43 try test__clzti2(0x1C000000_00000000_00000000_00000000, 3);
44 try test__clzti2(0x1D000000_00000000_00000000_00000000, 3);
45 try test__clzti2(0x1E000000_00000000_00000000_00000000, 3);
46 try test__clzti2(0x1F000000_00000000_00000000_00000000, 3);
47 try test__clzti2(0x20000000_00000000_00000000_00000000, 2);
48 try test__clzti2(0x21000000_00000000_00000000_00000000, 2);
49 try test__clzti2(0x22000000_00000000_00000000_00000000, 2);
50 try test__clzti2(0x23000000_00000000_00000000_00000000, 2);
51 try test__clzti2(0x24000000_00000000_00000000_00000000, 2);
52 try test__clzti2(0x25000000_00000000_00000000_00000000, 2);
53 try test__clzti2(0x26000000_00000000_00000000_00000000, 2);
54 try test__clzti2(0x27000000_00000000_00000000_00000000, 2);
55 try test__clzti2(0x28000000_00000000_00000000_00000000, 2);
56 try test__clzti2(0x29000000_00000000_00000000_00000000, 2);
57 try test__clzti2(0x2A000000_00000000_00000000_00000000, 2);
58 try test__clzti2(0x2B000000_00000000_00000000_00000000, 2);
59 try test__clzti2(0x2C000000_00000000_00000000_00000000, 2);
60 try test__clzti2(0x2D000000_00000000_00000000_00000000, 2);
61 try test__clzti2(0x2E000000_00000000_00000000_00000000, 2);
62 try test__clzti2(0x2F000000_00000000_00000000_00000000, 2);
63 try test__clzti2(0x30000000_00000000_00000000_00000000, 2);
64 try test__clzti2(0x31000000_00000000_00000000_00000000, 2);
65 try test__clzti2(0x32000000_00000000_00000000_00000000, 2);
66 try test__clzti2(0x33000000_00000000_00000000_00000000, 2);
67 try test__clzti2(0x34000000_00000000_00000000_00000000, 2);
68 try test__clzti2(0x35000000_00000000_00000000_00000000, 2);
69 try test__clzti2(0x36000000_00000000_00000000_00000000, 2);
70 try test__clzti2(0x37000000_00000000_00000000_00000000, 2);
71 try test__clzti2(0x38000000_00000000_00000000_00000000, 2);
72 try test__clzti2(0x39000000_00000000_00000000_00000000, 2);
73 try test__clzti2(0x3A000000_00000000_00000000_00000000, 2);
74 try test__clzti2(0x3B000000_00000000_00000000_00000000, 2);
75 try test__clzti2(0x3C000000_00000000_00000000_00000000, 2);
76 try test__clzti2(0x3D000000_00000000_00000000_00000000, 2);
77 try test__clzti2(0x3E000000_00000000_00000000_00000000, 2);
78 try test__clzti2(0x3F000000_00000000_00000000_00000000, 2);
79 try test__clzti2(0x40000000_00000000_00000000_00000000, 1);
80 try test__clzti2(0x41000000_00000000_00000000_00000000, 1);
81 try test__clzti2(0x42000000_00000000_00000000_00000000, 1);
82 try test__clzti2(0x43000000_00000000_00000000_00000000, 1);
83 try test__clzti2(0x44000000_00000000_00000000_00000000, 1);
84 try test__clzti2(0x45000000_00000000_00000000_00000000, 1);
85 try test__clzti2(0x46000000_00000000_00000000_00000000, 1);
86 try test__clzti2(0x47000000_00000000_00000000_00000000, 1);
87 try test__clzti2(0x48000000_00000000_00000000_00000000, 1);
88 try test__clzti2(0x49000000_00000000_00000000_00000000, 1);
89 try test__clzti2(0x4A000000_00000000_00000000_00000000, 1);
90 try test__clzti2(0x4B000000_00000000_00000000_00000000, 1);
91 try test__clzti2(0x4C000000_00000000_00000000_00000000, 1);
92 try test__clzti2(0x4D000000_00000000_00000000_00000000, 1);
93 try test__clzti2(0x4E000000_00000000_00000000_00000000, 1);
94 try test__clzti2(0x4F000000_00000000_00000000_00000000, 1);
95 try test__clzti2(0x50000000_00000000_00000000_00000000, 1);
96 try test__clzti2(0x51000000_00000000_00000000_00000000, 1);
97 try test__clzti2(0x52000000_00000000_00000000_00000000, 1);
98 try test__clzti2(0x53000000_00000000_00000000_00000000, 1);
99 try test__clzti2(0x54000000_00000000_00000000_00000000, 1);
100 try test__clzti2(0x55000000_00000000_00000000_00000000, 1);
101 try test__clzti2(0x56000000_00000000_00000000_00000000, 1);
102 try test__clzti2(0x57000000_00000000_00000000_00000000, 1);
103 try test__clzti2(0x58000000_00000000_00000000_00000000, 1);
104 try test__clzti2(0x59000000_00000000_00000000_00000000, 1);
105 try test__clzti2(0x5A000000_00000000_00000000_00000000, 1);
106 try test__clzti2(0x5B000000_00000000_00000000_00000000, 1);
107 try test__clzti2(0x5C000000_00000000_00000000_00000000, 1);
108 try test__clzti2(0x5D000000_00000000_00000000_00000000, 1);
109 try test__clzti2(0x5E000000_00000000_00000000_00000000, 1);
110 try test__clzti2(0x5F000000_00000000_00000000_00000000, 1);
111 try test__clzti2(0x60000000_00000000_00000000_00000000, 1);
112 try test__clzti2(0x61000000_00000000_00000000_00000000, 1);
113 try test__clzti2(0x62000000_00000000_00000000_00000000, 1);
114 try test__clzti2(0x63000000_00000000_00000000_00000000, 1);
115 try test__clzti2(0x64000000_00000000_00000000_00000000, 1);
116 try test__clzti2(0x65000000_00000000_00000000_00000000, 1);
117 try test__clzti2(0x66000000_00000000_00000000_00000000, 1);
118 try test__clzti2(0x67000000_00000000_00000000_00000000, 1);
119 try test__clzti2(0x68000000_00000000_00000000_00000000, 1);
120 try test__clzti2(0x69000000_00000000_00000000_00000000, 1);
121 try test__clzti2(0x6A000000_00000000_00000000_00000000, 1);
122 try test__clzti2(0x6B000000_00000000_00000000_00000000, 1);
123 try test__clzti2(0x6C000000_00000000_00000000_00000000, 1);
124 try test__clzti2(0x6D000000_00000000_00000000_00000000, 1);
125 try test__clzti2(0x6E000000_00000000_00000000_00000000, 1);
126 try test__clzti2(0x6F000000_00000000_00000000_00000000, 1);
127 try test__clzti2(0x70000000_00000000_00000000_00000000, 1);
128 try test__clzti2(0x71000000_00000000_00000000_00000000, 1);
129 try test__clzti2(0x72000000_00000000_00000000_00000000, 1);
130 try test__clzti2(0x73000000_00000000_00000000_00000000, 1);
131 try test__clzti2(0x74000000_00000000_00000000_00000000, 1);
132 try test__clzti2(0x75000000_00000000_00000000_00000000, 1);
133 try test__clzti2(0x76000000_00000000_00000000_00000000, 1);
134 try test__clzti2(0x77000000_00000000_00000000_00000000, 1);
135 try test__clzti2(0x78000000_00000000_00000000_00000000, 1);
136 try test__clzti2(0x79000000_00000000_00000000_00000000, 1);
137 try test__clzti2(0x7A000000_00000000_00000000_00000000, 1);
138 try test__clzti2(0x7B000000_00000000_00000000_00000000, 1);
139 try test__clzti2(0x7C000000_00000000_00000000_00000000, 1);
140 try test__clzti2(0x7D000000_00000000_00000000_00000000, 1);
141 try test__clzti2(0x7E000000_00000000_00000000_00000000, 1);
142 try test__clzti2(0x7F000000_00000000_00000000_00000000, 1);
143 try test__clzti2(0x80000000_00000000_00000000_00000000, 0);
144 try test__clzti2(0x81000000_00000000_00000000_00000000, 0);
145 try test__clzti2(0x82000000_00000000_00000000_00000000, 0);
146 try test__clzti2(0x83000000_00000000_00000000_00000000, 0);
147 try test__clzti2(0x84000000_00000000_00000000_00000000, 0);
148 try test__clzti2(0x85000000_00000000_00000000_00000000, 0);
149 try test__clzti2(0x86000000_00000000_00000000_00000000, 0);
150 try test__clzti2(0x87000000_00000000_00000000_00000000, 0);
151 try test__clzti2(0x88000000_00000000_00000000_00000000, 0);
152 try test__clzti2(0x89000000_00000000_00000000_00000000, 0);
153 try test__clzti2(0x8A000000_00000000_00000000_00000000, 0);
154 try test__clzti2(0x8B000000_00000000_00000000_00000000, 0);
155 try test__clzti2(0x8C000000_00000000_00000000_00000000, 0);
156 try test__clzti2(0x8D000000_00000000_00000000_00000000, 0);
157 try test__clzti2(0x8E000000_00000000_00000000_00000000, 0);
158 try test__clzti2(0x8F000000_00000000_00000000_00000000, 0);
159 try test__clzti2(0x90000000_00000000_00000000_00000000, 0);
160 try test__clzti2(0x91000000_00000000_00000000_00000000, 0);
161 try test__clzti2(0x92000000_00000000_00000000_00000000, 0);
162 try test__clzti2(0x93000000_00000000_00000000_00000000, 0);
163 try test__clzti2(0x94000000_00000000_00000000_00000000, 0);
164 try test__clzti2(0x95000000_00000000_00000000_00000000, 0);
165 try test__clzti2(0x96000000_00000000_00000000_00000000, 0);
166 try test__clzti2(0x97000000_00000000_00000000_00000000, 0);
167 try test__clzti2(0x98000000_00000000_00000000_00000000, 0);
168 try test__clzti2(0x99000000_00000000_00000000_00000000, 0);
169 try test__clzti2(0x9A000000_00000000_00000000_00000000, 0);
170 try test__clzti2(0x9B000000_00000000_00000000_00000000, 0);
171 try test__clzti2(0x9C000000_00000000_00000000_00000000, 0);
172 try test__clzti2(0x9D000000_00000000_00000000_00000000, 0);
173 try test__clzti2(0x9E000000_00000000_00000000_00000000, 0);
174 try test__clzti2(0x9F000000_00000000_00000000_00000000, 0);
175 try test__clzti2(0xA0000000_00000000_00000000_00000000, 0);
176 try test__clzti2(0xA1000000_00000000_00000000_00000000, 0);
177 try test__clzti2(0xA2000000_00000000_00000000_00000000, 0);
178 try test__clzti2(0xA3000000_00000000_00000000_00000000, 0);
179 try test__clzti2(0xA4000000_00000000_00000000_00000000, 0);
180 try test__clzti2(0xA5000000_00000000_00000000_00000000, 0);
181 try test__clzti2(0xA6000000_00000000_00000000_00000000, 0);
182 try test__clzti2(0xA7000000_00000000_00000000_00000000, 0);
183 try test__clzti2(0xA8000000_00000000_00000000_00000000, 0);
184 try test__clzti2(0xA9000000_00000000_00000000_00000000, 0);
185 try test__clzti2(0xAA000000_00000000_00000000_00000000, 0);
186 try test__clzti2(0xAB000000_00000000_00000000_00000000, 0);
187 try test__clzti2(0xAC000000_00000000_00000000_00000000, 0);
188 try test__clzti2(0xAD000000_00000000_00000000_00000000, 0);
189 try test__clzti2(0xAE000000_00000000_00000000_00000000, 0);
190 try test__clzti2(0xAF000000_00000000_00000000_00000000, 0);
191 try test__clzti2(0xB0000000_00000000_00000000_00000000, 0);
192 try test__clzti2(0xB1000000_00000000_00000000_00000000, 0);
193 try test__clzti2(0xB2000000_00000000_00000000_00000000, 0);
194 try test__clzti2(0xB3000000_00000000_00000000_00000000, 0);
195 try test__clzti2(0xB4000000_00000000_00000000_00000000, 0);
196 try test__clzti2(0xB5000000_00000000_00000000_00000000, 0);
197 try test__clzti2(0xB6000000_00000000_00000000_00000000, 0);
198 try test__clzti2(0xB7000000_00000000_00000000_00000000, 0);
199 try test__clzti2(0xB8000000_00000000_00000000_00000000, 0);
200 try test__clzti2(0xB9000000_00000000_00000000_00000000, 0);
201 try test__clzti2(0xBA000000_00000000_00000000_00000000, 0);
202 try test__clzti2(0xBB000000_00000000_00000000_00000000, 0);
203 try test__clzti2(0xBC000000_00000000_00000000_00000000, 0);
204 try test__clzti2(0xBD000000_00000000_00000000_00000000, 0);
205 try test__clzti2(0xBE000000_00000000_00000000_00000000, 0);
206 try test__clzti2(0xBF000000_00000000_00000000_00000000, 0);
207 try test__clzti2(0xC0000000_00000000_00000000_00000000, 0);
208 try test__clzti2(0xC1000000_00000000_00000000_00000000, 0);
209 try test__clzti2(0xC2000000_00000000_00000000_00000000, 0);
210 try test__clzti2(0xC3000000_00000000_00000000_00000000, 0);
211 try test__clzti2(0xC4000000_00000000_00000000_00000000, 0);
212 try test__clzti2(0xC5000000_00000000_00000000_00000000, 0);
213 try test__clzti2(0xC6000000_00000000_00000000_00000000, 0);
214 try test__clzti2(0xC7000000_00000000_00000000_00000000, 0);
215 try test__clzti2(0xC8000000_00000000_00000000_00000000, 0);
216 try test__clzti2(0xC9000000_00000000_00000000_00000000, 0);
217 try test__clzti2(0xCA000000_00000000_00000000_00000000, 0);
218 try test__clzti2(0xCB000000_00000000_00000000_00000000, 0);
219 try test__clzti2(0xCC000000_00000000_00000000_00000000, 0);
220 try test__clzti2(0xCD000000_00000000_00000000_00000000, 0);
221 try test__clzti2(0xCE000000_00000000_00000000_00000000, 0);
222 try test__clzti2(0xCF000000_00000000_00000000_00000000, 0);
223 try test__clzti2(0xD0000000_00000000_00000000_00000000, 0);
224 try test__clzti2(0xD1000000_00000000_00000000_00000000, 0);
225 try test__clzti2(0xD2000000_00000000_00000000_00000000, 0);
226 try test__clzti2(0xD3000000_00000000_00000000_00000000, 0);
227 try test__clzti2(0xD4000000_00000000_00000000_00000000, 0);
228 try test__clzti2(0xD5000000_00000000_00000000_00000000, 0);
229 try test__clzti2(0xD6000000_00000000_00000000_00000000, 0);
230 try test__clzti2(0xD7000000_00000000_00000000_00000000, 0);
231 try test__clzti2(0xD8000000_00000000_00000000_00000000, 0);
232 try test__clzti2(0xD9000000_00000000_00000000_00000000, 0);
233 try test__clzti2(0xDA000000_00000000_00000000_00000000, 0);
234 try test__clzti2(0xDB000000_00000000_00000000_00000000, 0);
235 try test__clzti2(0xDC000000_00000000_00000000_00000000, 0);
236 try test__clzti2(0xDD000000_00000000_00000000_00000000, 0);
237 try test__clzti2(0xDE000000_00000000_00000000_00000000, 0);
238 try test__clzti2(0xDF000000_00000000_00000000_00000000, 0);
239 try test__clzti2(0xE0000000_00000000_00000000_00000000, 0);
240 try test__clzti2(0xE1000000_00000000_00000000_00000000, 0);
241 try test__clzti2(0xE2000000_00000000_00000000_00000000, 0);
242 try test__clzti2(0xE3000000_00000000_00000000_00000000, 0);
243 try test__clzti2(0xE4000000_00000000_00000000_00000000, 0);
244 try test__clzti2(0xE5000000_00000000_00000000_00000000, 0);
245 try test__clzti2(0xE6000000_00000000_00000000_00000000, 0);
246 try test__clzti2(0xE7000000_00000000_00000000_00000000, 0);
247 try test__clzti2(0xE8000000_00000000_00000000_00000000, 0);
248 try test__clzti2(0xE9000000_00000000_00000000_00000000, 0);
249 try test__clzti2(0xEA000000_00000000_00000000_00000000, 0);
250 try test__clzti2(0xEB000000_00000000_00000000_00000000, 0);
251 try test__clzti2(0xEC000000_00000000_00000000_00000000, 0);
252 try test__clzti2(0xED000000_00000000_00000000_00000000, 0);
253 try test__clzti2(0xEE000000_00000000_00000000_00000000, 0);
254 try test__clzti2(0xEF000000_00000000_00000000_00000000, 0);
255 try test__clzti2(0xF0000000_00000000_00000000_00000000, 0);
256 try test__clzti2(0xF1000000_00000000_00000000_00000000, 0);
257 try test__clzti2(0xF2000000_00000000_00000000_00000000, 0);
258 try test__clzti2(0xF3000000_00000000_00000000_00000000, 0);
259 try test__clzti2(0xF4000000_00000000_00000000_00000000, 0);
260 try test__clzti2(0xF5000000_00000000_00000000_00000000, 0);
261 try test__clzti2(0xF6000000_00000000_00000000_00000000, 0);
262 try test__clzti2(0xF7000000_00000000_00000000_00000000, 0);
263 try test__clzti2(0xF8000000_00000000_00000000_00000000, 0);
264 try test__clzti2(0xF9000000_00000000_00000000_00000000, 0);
265 try test__clzti2(0xFA000000_00000000_00000000_00000000, 0);
266 try test__clzti2(0xFB000000_00000000_00000000_00000000, 0);
267 try test__clzti2(0xFC000000_00000000_00000000_00000000, 0);
268 try test__clzti2(0xFD000000_00000000_00000000_00000000, 0);
269 try test__clzti2(0xFE000000_00000000_00000000_00000000, 0);
270 try test__clzti2(0xFF000000_00000000_00000000_00000000, 0);
271
272 try test__clzti2(0x00000000_00000000_00000000_00000000, 128);
273 try test__clzti2(0x00000000_00000000_00000000_00000001, 127);
274 try test__clzti2(0x00000000_00000000_00000000_00000002, 126);
275 try test__clzti2(0x00000000_00000000_00000000_00000004, 125);
276 try test__clzti2(0x00000000_00000000_00000000_00000008, 124);
277 try test__clzti2(0x00000000_00000000_00000000_00000010, 123);
278 try test__clzti2(0x00000000_00000000_00000000_00000020, 122);
279 try test__clzti2(0x00000000_00000000_00000000_00000040, 121);
280 try test__clzti2(0x00000000_00000000_00000000_00000080, 120);
281 try test__clzti2(0x00000000_00000000_00000000_00000100, 119);
282 try test__clzti2(0x00000000_00000000_00000000_00000200, 118);
283 try test__clzti2(0x00000000_00000000_00000000_00000400, 117);
284 try test__clzti2(0x00000000_00000000_00000000_00000800, 116);
285 try test__clzti2(0x00000000_00000000_00000000_00001000, 115);
286 try test__clzti2(0x00000000_00000000_00000000_00002000, 114);
287 try test__clzti2(0x00000000_00000000_00000000_00004000, 113);
288 try test__clzti2(0x00000000_00000000_00000000_00008000, 112);
289 try test__clzti2(0x00000000_00000000_00000000_00010000, 111);
290 try test__clzti2(0x00000000_00000000_00000000_00020000, 110);
291 try test__clzti2(0x00000000_00000000_00000000_00040000, 109);
292 try test__clzti2(0x00000000_00000000_00000000_00080000, 108);
293 try test__clzti2(0x00000000_00000000_00000000_00100000, 107);
294 try test__clzti2(0x00000000_00000000_00000000_00200000, 106);
295 try test__clzti2(0x00000000_00000000_00000000_00400000, 105);
296 try test__clzti2(0x00000000_00000000_00000000_00800000, 104);
297 try test__clzti2(0x00000000_00000000_00000000_01000000, 103);
298 try test__clzti2(0x00000000_00000000_00000000_02000000, 102);
299 try test__clzti2(0x00000000_00000000_00000000_04000000, 101);
300 try test__clzti2(0x00000000_00000000_00000000_08000000, 100);
301 try test__clzti2(0x00000000_00000000_00000000_10000000, 99);
302 try test__clzti2(0x00000000_00000000_00000000_20000000, 98);
303 try test__clzti2(0x00000000_00000000_00000000_40000000, 97);
304 try test__clzti2(0x00000000_00000000_00000000_80000000, 96);
305
306 try test__clzti2(0x00000000_00000000_00000001_00000000, 95);
307 try test__clzti2(0x00000000_00000000_00000002_00000000, 94);
308 try test__clzti2(0x00000000_00000000_00000004_00000000, 93);
309 try test__clzti2(0x00000000_00000000_00000008_00000000, 92);
310 try test__clzti2(0x00000000_00000000_00000010_00000000, 91);
311 try test__clzti2(0x00000000_00000000_00000020_00000000, 90);
312 try test__clzti2(0x00000000_00000000_00000040_00000000, 89);
313 try test__clzti2(0x00000000_00000000_00000080_00000000, 88);
314 try test__clzti2(0x00000000_00000000_00000100_00000000, 87);
315 try test__clzti2(0x00000000_00000000_00000200_00000000, 86);
316 try test__clzti2(0x00000000_00000000_00000400_00000000, 85);
317 try test__clzti2(0x00000000_00000000_00000800_00000000, 84);
318 try test__clzti2(0x00000000_00000000_00001000_00000000, 83);
319 try test__clzti2(0x00000000_00000000_00002000_00000000, 82);
320 try test__clzti2(0x00000000_00000000_00004000_00000000, 81);
321 try test__clzti2(0x00000000_00000000_00008000_00000000, 80);
322 try test__clzti2(0x00000000_00000000_00010000_00000000, 79);
323 try test__clzti2(0x00000000_00000000_00020000_00000000, 78);
324 try test__clzti2(0x00000000_00000000_00040000_00000000, 77);
325 try test__clzti2(0x00000000_00000000_00080000_00000000, 76);
326 try test__clzti2(0x00000000_00000000_00100000_00000000, 75);
327 try test__clzti2(0x00000000_00000000_00200000_00000000, 74);
328 try test__clzti2(0x00000000_00000000_00400000_00000000, 73);
329 try test__clzti2(0x00000000_00000000_00800000_00000000, 72);
330 try test__clzti2(0x00000000_00000000_01000000_00000000, 71);
331 try test__clzti2(0x00000000_00000000_02000000_00000000, 70);
332 try test__clzti2(0x00000000_00000000_04000000_00000000, 69);
333 try test__clzti2(0x00000000_00000000_08000000_00000000, 68);
334 try test__clzti2(0x00000000_00000000_10000000_00000000, 67);
335 try test__clzti2(0x00000000_00000000_20000000_00000000, 66);
336 try test__clzti2(0x00000000_00000000_40000000_00000000, 65);
337 try test__clzti2(0x00000000_00000000_80000000_00000000, 64);
338
339 try test__clzti2(0x00000000_00000001_00000000_00000000, 63);
340 try test__clzti2(0x00000000_00000002_00000000_00000000, 62);
341 try test__clzti2(0x00000000_00000004_00000000_00000000, 61);
342 try test__clzti2(0x00000000_00000008_00000000_00000000, 60);
343 try test__clzti2(0x00000000_00000010_00000000_00000000, 59);
344 try test__clzti2(0x00000000_00000020_00000000_00000000, 58);
345 try test__clzti2(0x00000000_00000040_00000000_00000000, 57);
346 try test__clzti2(0x00000000_00000080_00000000_00000000, 56);
347 try test__clzti2(0x00000000_00000100_00000000_00000000, 55);
348 try test__clzti2(0x00000000_00000200_00000000_00000000, 54);
349 try test__clzti2(0x00000000_00000400_00000000_00000000, 53);
350 try test__clzti2(0x00000000_00000800_00000000_00000000, 52);
351 try test__clzti2(0x00000000_00001000_00000000_00000000, 51);
352 try test__clzti2(0x00000000_00002000_00000000_00000000, 50);
353 try test__clzti2(0x00000000_00004000_00000000_00000000, 49);
354 try test__clzti2(0x00000000_00008000_00000000_00000000, 48);
355 try test__clzti2(0x00000000_00010000_00000000_00000000, 47);
356 try test__clzti2(0x00000000_00020000_00000000_00000000, 46);
357 try test__clzti2(0x00000000_00040000_00000000_00000000, 45);
358 try test__clzti2(0x00000000_00080000_00000000_00000000, 44);
359 try test__clzti2(0x00000000_00100000_00000000_00000000, 43);
360 try test__clzti2(0x00000000_00200000_00000000_00000000, 42);
361 try test__clzti2(0x00000000_00400000_00000000_00000000, 41);
362 try test__clzti2(0x00000000_00800000_00000000_00000000, 40);
363 try test__clzti2(0x00000000_01000000_00000000_00000000, 39);
364 try test__clzti2(0x00000000_02000000_00000000_00000000, 38);
365 try test__clzti2(0x00000000_04000000_00000000_00000000, 37);
366 try test__clzti2(0x00000000_08000000_00000000_00000000, 36);
367 try test__clzti2(0x00000000_10000000_00000000_00000000, 35);
368 try test__clzti2(0x00000000_20000000_00000000_00000000, 34);
369 try test__clzti2(0x00000000_40000000_00000000_00000000, 33);
370 try test__clzti2(0x00000000_80000000_00000000_00000000, 32);
371
372 try test__clzti2(0x00000001_00000000_00000000_00000000, 31);
373 try test__clzti2(0x00000002_00000000_00000000_00000000, 30);
374 try test__clzti2(0x00000004_00000000_00000000_00000000, 29);
375 try test__clzti2(0x00000008_00000000_00000000_00000000, 28);
376 try test__clzti2(0x00000010_00000000_00000000_00000000, 27);
377 try test__clzti2(0x00000020_00000000_00000000_00000000, 26);
378 try test__clzti2(0x00000040_00000000_00000000_00000000, 25);
379 try test__clzti2(0x00000080_00000000_00000000_00000000, 24);
380 try test__clzti2(0x00000100_00000000_00000000_00000000, 23);
381 try test__clzti2(0x00000200_00000000_00000000_00000000, 22);
382 try test__clzti2(0x00000400_00000000_00000000_00000000, 21);
383 try test__clzti2(0x00000800_00000000_00000000_00000000, 20);
384 try test__clzti2(0x00001000_00000000_00000000_00000000, 19);
385 try test__clzti2(0x00002000_00000000_00000000_00000000, 18);
386 try test__clzti2(0x00004000_00000000_00000000_00000000, 17);
387 try test__clzti2(0x00008000_00000000_00000000_00000000, 16);
388 try test__clzti2(0x00010000_00000000_00000000_00000000, 15);
389 try test__clzti2(0x00020000_00000000_00000000_00000000, 14);
390 try test__clzti2(0x00040000_00000000_00000000_00000000, 13);
391 try test__clzti2(0x00080000_00000000_00000000_00000000, 12);
392 try test__clzti2(0x00100000_00000000_00000000_00000000, 11);
393 try test__clzti2(0x00200000_00000000_00000000_00000000, 10);
394 try test__clzti2(0x00400000_00000000_00000000_00000000, 9);
395}
lib/std/special/compiler_rt/count0bits.zig created+160
...@@ -0,0 +1,160 @@
1const std = @import("std");
2const builtin = std.builtin;
3
4// clz - count leading zeroes
5// - clzXi2_generic for little endian
6// - __clzsi2_thumb1: assume a != 0
7// - __clzsi2_arm32: assume a != 0
8
9fn clzXi2_generic(comptime T: type) fn (a: T) callconv(.C) i32 {
10 return struct {
11 fn f(a: T) callconv(.C) i32 {
12 @setRuntimeSafety(builtin.is_test);
13
14 var x = switch (@bitSizeOf(T)) {
15 32 => @bitCast(u32, a),
16 64 => @bitCast(u64, a),
17 128 => @bitCast(u128, a),
18 else => unreachable,
19 };
20 var n: T = @bitSizeOf(T);
21 // Count first bit set using binary search, from Hacker's Delight
22 var y: @TypeOf(x) = 0;
23 comptime var shift: u8 = @bitSizeOf(T);
24 inline while (shift > 0) {
25 shift = shift >> 1;
26 y = x >> shift;
27 if (y != 0) {
28 n = n - shift;
29 x = y;
30 }
31 }
32 return @intCast(i32, n - @bitCast(T, x));
33 }
34 }.f;
35}
36
37fn __clzsi2_thumb1() callconv(.Naked) void {
38 @setRuntimeSafety(false);
39
40 // Similar to the generic version with the last two rounds replaced by a LUT
41 asm volatile (
42 \\ movs r1, #32
43 \\ lsrs r2, r0, #16
44 \\ beq 1f
45 \\ subs r1, #16
46 \\ movs r0, r2
47 \\ 1:
48 \\ lsrs r2, r0, #8
49 \\ beq 1f
50 \\ subs r1, #8
51 \\ movs r0, r2
52 \\ 1:
53 \\ lsrs r2, r0, #4
54 \\ beq 1f
55 \\ subs r1, #4
56 \\ movs r0, r2
57 \\ 1:
58 \\ ldr r3, =LUT
59 \\ ldrb r0, [r3, r0]
60 \\ subs r0, r1, r0
61 \\ bx lr
62 \\ .p2align 2
63 \\ // Number of bits set in the 0-15 range
64 \\ LUT:
65 \\ .byte 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4
66 );
67
68 unreachable;
69}
70
71fn __clzsi2_arm32() callconv(.Naked) void {
72 @setRuntimeSafety(false);
73
74 asm volatile (
75 \\ // Assumption: n != 0
76 \\ // r0: n
77 \\ // r1: count of leading zeros in n + 1
78 \\ // r2: scratch register for shifted r0
79 \\ mov r1, #1
80 \\
81 \\ // Basic block:
82 \\ // if ((r0 >> SHIFT) == 0)
83 \\ // r1 += SHIFT;
84 \\ // else
85 \\ // r0 >>= SHIFT;
86 \\ // for descending powers of two as SHIFT.
87 \\ lsrs r2, r0, #16
88 \\ movne r0, r2
89 \\ addeq r1, #16
90 \\
91 \\ lsrs r2, r0, #8
92 \\ movne r0, r2
93 \\ addeq r1, #8
94 \\
95 \\ lsrs r2, r0, #4
96 \\ movne r0, r2
97 \\ addeq r1, #4
98 \\
99 \\ lsrs r2, r0, #2
100 \\ movne r0, r2
101 \\ addeq r1, #2
102 \\
103 \\ // The basic block invariants at this point are (r0 >> 2) == 0 and
104 \\ // r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1.
105 \\ //
106 \\ // r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)f
107 \\ // ---+----------------+----------------+------------+--------------
108 \\ // 1 | 1 | 0 | 0 | 1
109 \\ // 2 | 0 | 1 | -1 | 0
110 \\ // 3 | 0 | 1 | -1 | 0
111 \\ //
112 \\ // The r1's initial value of 1 compensates for the 1 here.
113 \\ sub r0, r1, r0, lsr #1
114 \\ bx lr
115 );
116
117 unreachable;
118}
119
120pub const __clzsi2 = impl: {
121 switch (std.Target.current.cpu.arch) {
122 .arm, .armeb, .thumb, .thumbeb => {
123 const use_thumb1 =
124 (std.Target.current.cpu.arch.isThumb() or
125 std.Target.arm.featureSetHas(std.Target.current.cpu.features, .noarm)) and
126 !std.Target.arm.featureSetHas(std.Target.current.cpu.features, .thumb2);
127
128 if (use_thumb1) {
129 break :impl __clzsi2_thumb1;
130 }
131 // From here on we're either targeting Thumb2 or ARM.
132 else if (!std.Target.current.cpu.arch.isThumb()) {
133 break :impl __clzsi2_arm32;
134 }
135 // Use the generic implementation otherwise.
136 else break :impl clzXi2_generic(i32);
137 },
138 else => break :impl clzXi2_generic(i32),
139 }
140};
141
142pub const __clzdi2 = impl: {
143 switch (std.Target.current.cpu.arch) {
144 // TODO architecture optimised versions
145 else => break :impl clzXi2_generic(i64),
146 }
147};
148
149pub const __clzti2 = impl: {
150 switch (std.Target.current.cpu.arch) {
151 // TODO architecture optimised versions
152 else => break :impl clzXi2_generic(i128),
153 }
154};
155
156test {
157 _ = @import("clzsi2_test.zig");
158 _ = @import("clzdi2_test.zig");
159 _ = @import("clzti2_test.zig");
160}
lib/std/special/compiler_rt/divdf3.zig+1-1
...@@ -327,6 +327,6 @@ pub fn __aeabi_ddiv(a: f64, b: f64) callconv(.AAPCS) f64 {...@@ -327,6 +327,6 @@ pub fn __aeabi_ddiv(a: f64, b: f64) callconv(.AAPCS) f64 {
327 return @call(.{ .modifier = .always_inline }, __divdf3, .{ a, b });327 return @call(.{ .modifier = .always_inline }, __divdf3, .{ a, b });
328}328}
329329
330test "import divdf3" {330test {
331 _ = @import("divdf3_test.zig");331 _ = @import("divdf3_test.zig");
332}332}
lib/std/special/compiler_rt/divsf3.zig+1-1
...@@ -200,6 +200,6 @@ pub fn __aeabi_fdiv(a: f32, b: f32) callconv(.AAPCS) f32 {...@@ -200,6 +200,6 @@ pub fn __aeabi_fdiv(a: f32, b: f32) callconv(.AAPCS) f32 {
200 return @call(.{ .modifier = .always_inline }, __divsf3, .{ a, b });200 return @call(.{ .modifier = .always_inline }, __divsf3, .{ a, b });
201}201}
202202
203test "import divsf3" {203test {
204 _ = @import("divsf3_test.zig");204 _ = @import("divsf3_test.zig");
205}205}
lib/std/special/compiler_rt/divtf3.zig+1-1
...@@ -221,6 +221,6 @@ pub fn __divtf3(a: f128, b: f128) callconv(.C) f128 {...@@ -221,6 +221,6 @@ pub fn __divtf3(a: f128, b: f128) callconv(.C) f128 {
221 }221 }
222}222}
223223
224test "import divtf3" {224test {
225 _ = @import("divtf3_test.zig");225 _ = @import("divtf3_test.zig");
226}226}
lib/std/special/compiler_rt/divti3.zig+1-1
...@@ -23,6 +23,6 @@ pub fn __divti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {...@@ -23,6 +23,6 @@ pub fn __divti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {
23 }));23 }));
24}24}
2525
26test "import divti3" {26test {
27 _ = @import("divti3_test.zig");27 _ = @import("divti3_test.zig");
28}28}
lib/std/special/compiler_rt/extendXfYf2.zig+1-1
...@@ -104,6 +104,6 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: std.meta.Int(.unsi...@@ -104,6 +104,6 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: std.meta.Int(.unsi
104 return @bitCast(dst_t, result);104 return @bitCast(dst_t, result);
105}105}
106106
107test "import extendXfYf2" {107test {
108 _ = @import("extendXfYf2_test.zig");108 _ = @import("extendXfYf2_test.zig");
109}109}
lib/std/special/compiler_rt/fixdfdi.zig+1-1
...@@ -11,6 +11,6 @@ pub fn __aeabi_d2lz(arg: f64) callconv(.AAPCS) i64 {...@@ -11,6 +11,6 @@ pub fn __aeabi_d2lz(arg: f64) callconv(.AAPCS) i64 {
11 return @call(.{ .modifier = .always_inline }, __fixdfdi, .{arg});11 return @call(.{ .modifier = .always_inline }, __fixdfdi, .{arg});
12}12}
1313
14test "import fixdfdi" {14test {
15 _ = @import("fixdfdi_test.zig");15 _ = @import("fixdfdi_test.zig");
16}16}
lib/std/special/compiler_rt/fixdfsi.zig+1-1
...@@ -11,6 +11,6 @@ pub fn __aeabi_d2iz(a: f64) callconv(.AAPCS) i32 {...@@ -11,6 +11,6 @@ pub fn __aeabi_d2iz(a: f64) callconv(.AAPCS) i32 {
11 return @call(.{ .modifier = .always_inline }, __fixdfsi, .{a});11 return @call(.{ .modifier = .always_inline }, __fixdfsi, .{a});
12}12}
1313
14test "import fixdfsi" {14test {
15 _ = @import("fixdfsi_test.zig");15 _ = @import("fixdfsi_test.zig");
16}16}
lib/std/special/compiler_rt/fixdfti.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixdfti(a: f64) callconv(.C) i128 {...@@ -6,6 +6,6 @@ pub fn __fixdfti(a: f64) callconv(.C) i128 {
6 return fixint(f64, i128, a);6 return fixint(f64, i128, a);
7}7}
88
9test "import fixdfti" {9test {
10 _ = @import("fixdfti_test.zig");10 _ = @import("fixdfti_test.zig");
11}11}
lib/std/special/compiler_rt/fixint.zig+1-1
...@@ -70,6 +70,6 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {...@@ -70,6 +70,6 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
70 }70 }
71}71}
7272
73test "import fixint" {73test {
74 _ = @import("fixint_test.zig");74 _ = @import("fixint_test.zig");
75}75}
lib/std/special/compiler_rt/fixsfdi.zig+1-1
...@@ -11,6 +11,6 @@ pub fn __aeabi_f2lz(arg: f32) callconv(.AAPCS) i64 {...@@ -11,6 +11,6 @@ pub fn __aeabi_f2lz(arg: f32) callconv(.AAPCS) i64 {
11 return @call(.{ .modifier = .always_inline }, __fixsfdi, .{arg});11 return @call(.{ .modifier = .always_inline }, __fixsfdi, .{arg});
12}12}
1313
14test "import fixsfdi" {14test {
15 _ = @import("fixsfdi_test.zig");15 _ = @import("fixsfdi_test.zig");
16}16}
lib/std/special/compiler_rt/fixsfsi.zig+1-1
...@@ -11,6 +11,6 @@ pub fn __aeabi_f2iz(a: f32) callconv(.AAPCS) i32 {...@@ -11,6 +11,6 @@ pub fn __aeabi_f2iz(a: f32) callconv(.AAPCS) i32 {
11 return @call(.{ .modifier = .always_inline }, __fixsfsi, .{a});11 return @call(.{ .modifier = .always_inline }, __fixsfsi, .{a});
12}12}
1313
14test "import fixsfsi" {14test {
15 _ = @import("fixsfsi_test.zig");15 _ = @import("fixsfsi_test.zig");
16}16}
lib/std/special/compiler_rt/fixsfti.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixsfti(a: f32) callconv(.C) i128 {...@@ -6,6 +6,6 @@ pub fn __fixsfti(a: f32) callconv(.C) i128 {
6 return fixint(f32, i128, a);6 return fixint(f32, i128, a);
7}7}
88
9test "import fixsfti" {9test {
10 _ = @import("fixsfti_test.zig");10 _ = @import("fixsfti_test.zig");
11}11}
lib/std/special/compiler_rt/fixtfdi.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixtfdi(a: f128) callconv(.C) i64 {...@@ -6,6 +6,6 @@ pub fn __fixtfdi(a: f128) callconv(.C) i64 {
6 return fixint(f128, i64, a);6 return fixint(f128, i64, a);
7}7}
88
9test "import fixtfdi" {9test {
10 _ = @import("fixtfdi_test.zig");10 _ = @import("fixtfdi_test.zig");
11}11}
lib/std/special/compiler_rt/fixtfsi.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixtfsi(a: f128) callconv(.C) i32 {...@@ -6,6 +6,6 @@ pub fn __fixtfsi(a: f128) callconv(.C) i32 {
6 return fixint(f128, i32, a);6 return fixint(f128, i32, a);
7}7}
88
9test "import fixtfsi" {9test {
10 _ = @import("fixtfsi_test.zig");10 _ = @import("fixtfsi_test.zig");
11}11}
lib/std/special/compiler_rt/fixtfti.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixtfti(a: f128) callconv(.C) i128 {...@@ -6,6 +6,6 @@ pub fn __fixtfti(a: f128) callconv(.C) i128 {
6 return fixint(f128, i128, a);6 return fixint(f128, i128, a);
7}7}
88
9test "import fixtfti" {9test {
10 _ = @import("fixtfti_test.zig");10 _ = @import("fixtfti_test.zig");
11}11}
lib/std/special/compiler_rt/fixunsdfdi.zig+1-1
...@@ -11,6 +11,6 @@ pub fn __aeabi_d2ulz(a: f64) callconv(.AAPCS) u64 {...@@ -11,6 +11,6 @@ pub fn __aeabi_d2ulz(a: f64) callconv(.AAPCS) u64 {
11 return @call(.{ .modifier = .always_inline }, __fixunsdfdi, .{a});11 return @call(.{ .modifier = .always_inline }, __fixunsdfdi, .{a});
12}12}
1313
14test "import fixunsdfdi" {14test {
15 _ = @import("fixunsdfdi_test.zig");15 _ = @import("fixunsdfdi_test.zig");
16}16}
lib/std/special/compiler_rt/fixunsdfsi.zig+1-1
...@@ -11,6 +11,6 @@ pub fn __aeabi_d2uiz(arg: f64) callconv(.AAPCS) u32 {...@@ -11,6 +11,6 @@ pub fn __aeabi_d2uiz(arg: f64) callconv(.AAPCS) u32 {
11 return @call(.{ .modifier = .always_inline }, __fixunsdfsi, .{arg});11 return @call(.{ .modifier = .always_inline }, __fixunsdfsi, .{arg});
12}12}
1313
14test "import fixunsdfsi" {14test {
15 _ = @import("fixunsdfsi_test.zig");15 _ = @import("fixunsdfsi_test.zig");
16}16}
lib/std/special/compiler_rt/fixunsdfti.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixunsdfti(a: f64) callconv(.C) u128 {...@@ -6,6 +6,6 @@ pub fn __fixunsdfti(a: f64) callconv(.C) u128 {
6 return fixuint(f64, u128, a);6 return fixuint(f64, u128, a);
7}7}
88
9test "import fixunsdfti" {9test {
10 _ = @import("fixunsdfti_test.zig");10 _ = @import("fixunsdfti_test.zig");
11}11}
lib/std/special/compiler_rt/fixunssfdi.zig+1-1
...@@ -11,6 +11,6 @@ pub fn __aeabi_f2ulz(a: f32) callconv(.AAPCS) u64 {...@@ -11,6 +11,6 @@ pub fn __aeabi_f2ulz(a: f32) callconv(.AAPCS) u64 {
11 return @call(.{ .modifier = .always_inline }, __fixunssfdi, .{a});11 return @call(.{ .modifier = .always_inline }, __fixunssfdi, .{a});
12}12}
1313
14test "import fixunssfdi" {14test {
15 _ = @import("fixunssfdi_test.zig");15 _ = @import("fixunssfdi_test.zig");
16}16}
lib/std/special/compiler_rt/fixunssfsi.zig+1-1
...@@ -11,6 +11,6 @@ pub fn __aeabi_f2uiz(a: f32) callconv(.AAPCS) u32 {...@@ -11,6 +11,6 @@ pub fn __aeabi_f2uiz(a: f32) callconv(.AAPCS) u32 {
11 return @call(.{ .modifier = .always_inline }, __fixunssfsi, .{a});11 return @call(.{ .modifier = .always_inline }, __fixunssfsi, .{a});
12}12}
1313
14test "import fixunssfsi" {14test {
15 _ = @import("fixunssfsi_test.zig");15 _ = @import("fixunssfsi_test.zig");
16}16}
lib/std/special/compiler_rt/fixunssfti.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixunssfti(a: f32) callconv(.C) u128 {...@@ -6,6 +6,6 @@ pub fn __fixunssfti(a: f32) callconv(.C) u128 {
6 return fixuint(f32, u128, a);6 return fixuint(f32, u128, a);
7}7}
88
9test "import fixunssfti" {9test {
10 _ = @import("fixunssfti_test.zig");10 _ = @import("fixunssfti_test.zig");
11}11}
lib/std/special/compiler_rt/fixunstfdi.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixunstfdi(a: f128) callconv(.C) u64 {...@@ -6,6 +6,6 @@ pub fn __fixunstfdi(a: f128) callconv(.C) u64 {
6 return fixuint(f128, u64, a);6 return fixuint(f128, u64, a);
7}7}
88
9test "import fixunstfdi" {9test {
10 _ = @import("fixunstfdi_test.zig");10 _ = @import("fixunstfdi_test.zig");
11}11}
lib/std/special/compiler_rt/fixunstfsi.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixunstfsi(a: f128) callconv(.C) u32 {...@@ -6,6 +6,6 @@ pub fn __fixunstfsi(a: f128) callconv(.C) u32 {
6 return fixuint(f128, u32, a);6 return fixuint(f128, u32, a);
7}7}
88
9test "import fixunstfsi" {9test {
10 _ = @import("fixunstfsi_test.zig");10 _ = @import("fixunstfsi_test.zig");
11}11}
lib/std/special/compiler_rt/fixunstfti.zig+1-1
...@@ -6,6 +6,6 @@ pub fn __fixunstfti(a: f128) callconv(.C) u128 {...@@ -6,6 +6,6 @@ pub fn __fixunstfti(a: f128) callconv(.C) u128 {
6 return fixuint(f128, u128, a);6 return fixuint(f128, u128, a);
7}7}
88
9test "import fixunstfti" {9test {
10 _ = @import("fixunstfti_test.zig");10 _ = @import("fixunstfti_test.zig");
11}11}
lib/std/special/compiler_rt/floatXisf.zig+2-2
...@@ -85,9 +85,9 @@ pub fn __aeabi_l2f(arg: i64) callconv(.AAPCS) f32 {...@@ -85,9 +85,9 @@ pub fn __aeabi_l2f(arg: i64) callconv(.AAPCS) f32 {
85 return @call(.{ .modifier = .always_inline }, __floatdisf, .{arg});85 return @call(.{ .modifier = .always_inline }, __floatdisf, .{arg});
86}86}
8787
88test "import floattisf" {88test {
89 _ = @import("floattisf_test.zig");89 _ = @import("floattisf_test.zig");
90}90}
91test "import floatdisf" {91test {
92 _ = @import("floattisf_test.zig");92 _ = @import("floattisf_test.zig");
93}93}
lib/std/special/compiler_rt/floatdidf.zig+1-1
...@@ -22,6 +22,6 @@ pub fn __aeabi_l2d(arg: i64) callconv(.AAPCS) f64 {...@@ -22,6 +22,6 @@ pub fn __aeabi_l2d(arg: i64) callconv(.AAPCS) f64 {
22 return @call(.{ .modifier = .always_inline }, __floatdidf, .{arg});22 return @call(.{ .modifier = .always_inline }, __floatdidf, .{arg});
23}23}
2424
25test "import floatdidf" {25test {
26 _ = @import("floatdidf_test.zig");26 _ = @import("floatdidf_test.zig");
27}27}
lib/std/special/compiler_rt/floatditf.zig+1-1
...@@ -33,6 +33,6 @@ pub fn __floatditf(arg: i64) callconv(.C) f128 {...@@ -33,6 +33,6 @@ pub fn __floatditf(arg: i64) callconv(.C) f128 {
33 return @bitCast(f128, result | sign);33 return @bitCast(f128, result | sign);
34}34}
3535
36test "import floatditf" {36test {
37 _ = @import("floatditf_test.zig");37 _ = @import("floatditf_test.zig");
38}38}
lib/std/special/compiler_rt/floattidf.zig+1-1
...@@ -66,6 +66,6 @@ pub fn __floattidf(arg: i128) callconv(.C) f64 {...@@ -66,6 +66,6 @@ pub fn __floattidf(arg: i128) callconv(.C) f64 {
66 return @bitCast(f64, low | (high << 32));66 return @bitCast(f64, low | (high << 32));
67}67}
6868
69test "import floattidf" {69test {
70 _ = @import("floattidf_test.zig");70 _ = @import("floattidf_test.zig");
71}71}
lib/std/special/compiler_rt/floattitf.zig+1-1
...@@ -66,6 +66,6 @@ pub fn __floattitf(arg: i128) callconv(.C) f128 {...@@ -66,6 +66,6 @@ pub fn __floattitf(arg: i128) callconv(.C) f128 {
66 return @bitCast(f128, low | (high << 64));66 return @bitCast(f128, low | (high << 64));
67}67}
6868
69test "import floattitf" {69test {
70 _ = @import("floattitf_test.zig");70 _ = @import("floattitf_test.zig");
71}71}
lib/std/special/compiler_rt/floatundidf.zig+1-1
...@@ -24,6 +24,6 @@ pub fn __aeabi_ul2d(arg: u64) callconv(.AAPCS) f64 {...@@ -24,6 +24,6 @@ pub fn __aeabi_ul2d(arg: u64) callconv(.AAPCS) f64 {
24 return @call(.{ .modifier = .always_inline }, __floatundidf, .{arg});24 return @call(.{ .modifier = .always_inline }, __floatundidf, .{arg});
25}25}
2626
27test "import floatundidf" {27test {
28 _ = @import("floatundidf_test.zig");28 _ = @import("floatundidf_test.zig");
29}29}
lib/std/special/compiler_rt/floatunditf.zig+1-1
...@@ -23,6 +23,6 @@ pub fn __floatunditf(a: u64) callconv(.C) f128 {...@@ -23,6 +23,6 @@ pub fn __floatunditf(a: u64) callconv(.C) f128 {
23 return @bitCast(f128, result);23 return @bitCast(f128, result);
24}24}
2525
26test "import floatunditf" {26test {
27 _ = @import("floatunditf_test.zig");27 _ = @import("floatunditf_test.zig");
28}28}
lib/std/special/compiler_rt/floatunsitf.zig+1-1
...@@ -24,6 +24,6 @@ pub fn __floatunsitf(a: u32) callconv(.C) f128 {...@@ -24,6 +24,6 @@ pub fn __floatunsitf(a: u32) callconv(.C) f128 {
24 return @bitCast(f128, result);24 return @bitCast(f128, result);
25}25}
2626
27test "import floatunsitf" {27test {
28 _ = @import("floatunsitf_test.zig");28 _ = @import("floatunsitf_test.zig");
29}29}
lib/std/special/compiler_rt/floatuntidf.zig+1-1
...@@ -57,6 +57,6 @@ pub fn __floatuntidf(arg: u128) callconv(.C) f64 {...@@ -57,6 +57,6 @@ pub fn __floatuntidf(arg: u128) callconv(.C) f64 {
57 return @bitCast(f64, low | (high << 32));57 return @bitCast(f64, low | (high << 32));
58}58}
5959
60test "import floatuntidf" {60test {
61 _ = @import("floatuntidf_test.zig");61 _ = @import("floatuntidf_test.zig");
62}62}
lib/std/special/compiler_rt/floatuntisf.zig+1-1
...@@ -56,6 +56,6 @@ pub fn __floatuntisf(arg: u128) callconv(.C) f32 {...@@ -56,6 +56,6 @@ pub fn __floatuntisf(arg: u128) callconv(.C) f32 {
56 return @bitCast(f32, high | low);56 return @bitCast(f32, high | low);
57}57}
5858
59test "import floatuntisf" {59test {
60 _ = @import("floatuntisf_test.zig");60 _ = @import("floatuntisf_test.zig");
61}61}
lib/std/special/compiler_rt/floatuntitf.zig+1-1
...@@ -57,6 +57,6 @@ pub fn __floatuntitf(arg: u128) callconv(.C) f128 {...@@ -57,6 +57,6 @@ pub fn __floatuntitf(arg: u128) callconv(.C) f128 {
57 return @bitCast(f128, low | (high << 64));57 return @bitCast(f128, low | (high << 64));
58}58}
5959
60test "import floatuntitf" {60test {
61 _ = @import("floatuntitf_test.zig");61 _ = @import("floatuntitf_test.zig");
62}62}
lib/std/special/compiler_rt/modti3.zig+1-1
...@@ -28,6 +28,6 @@ pub fn __modti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {...@@ -28,6 +28,6 @@ pub fn __modti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {
28 }));28 }));
29}29}
3030
31test "import modti3" {31test {
32 _ = @import("modti3_test.zig");32 _ = @import("modti3_test.zig");
33}33}
lib/std/special/compiler_rt/mulXf3.zig+1-1
...@@ -294,6 +294,6 @@ fn wideRightShiftWithSticky(comptime Z: type, hi: *Z, lo: *Z, count: u32) void {...@@ -294,6 +294,6 @@ fn wideRightShiftWithSticky(comptime Z: type, hi: *Z, lo: *Z, count: u32) void {
294 }294 }
295}295}
296296
297test "import mulXf3" {297test {
298 _ = @import("mulXf3_test.zig");298 _ = @import("mulXf3_test.zig");
299}299}
lib/std/special/compiler_rt/muldi3.zig+1-1
...@@ -51,6 +51,6 @@ pub fn __muldi3(a: i64, b: i64) callconv(.C) i64 {...@@ -51,6 +51,6 @@ pub fn __muldi3(a: i64, b: i64) callconv(.C) i64 {
51 return r.all;51 return r.all;
52}52}
5353
54test "import muldi3" {54test {
55 _ = @import("muldi3_test.zig");55 _ = @import("muldi3_test.zig");
56}56}
lib/std/special/compiler_rt/mulodi4.zig+1-3
...@@ -1,7 +1,5 @@...@@ -1,7 +1,5 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");2const compiler_rt = @import("../compiler_rt.zig");
3const maxInt = std.math.maxInt;
4const minInt = std.math.minInt;
53
6pub fn __mulodi4(a: i64, b: i64, overflow: *c_int) callconv(.C) i64 {4pub fn __mulodi4(a: i64, b: i64, overflow: *c_int) callconv(.C) i64 {
7 @setRuntimeSafety(builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
...@@ -39,6 +37,6 @@ pub fn __mulodi4(a: i64, b: i64, overflow: *c_int) callconv(.C) i64 {...@@ -39,6 +37,6 @@ pub fn __mulodi4(a: i64, b: i64, overflow: *c_int) callconv(.C) i64 {
39 return result;37 return result;
40}38}
4139
42test "import mulodi4" {40test {
43 _ = @import("mulodi4_test.zig");41 _ = @import("mulodi4_test.zig");
44}42}
lib/std/special/compiler_rt/muloti4.zig+1-1
...@@ -44,6 +44,6 @@ pub fn __muloti4(a: i128, b: i128, overflow: *c_int) callconv(.C) i128 {...@@ -44,6 +44,6 @@ pub fn __muloti4(a: i128, b: i128, overflow: *c_int) callconv(.C) i128 {
44 return r;44 return r;
45}45}
4646
47test "import muloti4" {47test {
48 _ = @import("muloti4_test.zig");48 _ = @import("muloti4_test.zig");
49}49}
lib/std/special/compiler_rt/multi3.zig+1-1
...@@ -59,6 +59,6 @@ const twords = extern union {...@@ -59,6 +59,6 @@ const twords = extern union {
59 };59 };
60};60};
6161
62test "import multi3" {62test {
63 _ = @import("multi3_test.zig");63 _ = @import("multi3_test.zig");
64}64}
lib/std/special/compiler_rt/popcountdi2.zig+1-1
...@@ -19,6 +19,6 @@ pub fn __popcountdi2(a: i64) callconv(.C) i32 {...@@ -19,6 +19,6 @@ pub fn __popcountdi2(a: i64) callconv(.C) i32 {
19 return @bitCast(i32, (x + (x >> 8)) & 0x0000007F); // (7 significant bits)19 return @bitCast(i32, (x + (x >> 8)) & 0x0000007F); // (7 significant bits)
20}20}
2121
22test "import popcountdi2" {22test {
23 _ = @import("popcountdi2_test.zig");23 _ = @import("popcountdi2_test.zig");
24}24}
lib/std/special/compiler_rt/stack_probe.zig+13
...@@ -53,6 +53,19 @@ pub fn zig_probe_stack() callconv(.Naked) void {...@@ -53,6 +53,19 @@ pub fn zig_probe_stack() callconv(.Naked) void {
53 },53 },
54 else => {},54 else => {},
55 }55 }
56 if (comptime native_arch.isAARCH64()) {
57 asm volatile (
58 \\ lsl x16, x15, #4
59 \\ mov x17, sp
60 \\1:
61 \\ sub x17, x17, #PAGE_SIZE
62 \\ subs x16, x16, #PAGE_SIZE
63 \\ ldr xzr, [x17]
64 \\ b.gt 1b
65 \\
66 \\ ret
67 );
68 }
5669
57 unreachable;70 unreachable;
58}71}
lib/std/special/compiler_rt/truncXfYf2.zig+1-1
...@@ -138,6 +138,6 @@ fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {...@@ -138,6 +138,6 @@ fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {
138 return @bitCast(dst_t, result);138 return @bitCast(dst_t, result);
139}139}
140140
141test "import truncXfYf2" {141test {
142 _ = @import("truncXfYf2_test.zig");142 _ = @import("truncXfYf2_test.zig");
143}143}
lib/std/special/compiler_rt/udivmodti4.zig+1-1
...@@ -13,6 +13,6 @@ pub fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) callconv...@@ -13,6 +13,6 @@ pub fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) callconv
13 return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem));13 return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem));
14}14}
1515
16test "import udivmodti4" {16test {
17 _ = @import("udivmodti4_test.zig");17 _ = @import("udivmodti4_test.zig");
18}18}
lib/std/special/ssp.zig+1-3
...@@ -25,9 +25,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn...@@ -25,9 +25,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn
25 _ = msg;25 _ = msg;
26 _ = error_return_trace;26 _ = error_return_trace;
27 @setCold(true);27 @setCold(true);
28 if (@hasDecl(std.os, "abort"))28 std.os.abort();
29 std.os.abort();
30 while (true) {}
31}29}
3230
33export fn __stack_chk_fail() callconv(.C) noreturn {31export fn __stack_chk_fail() callconv(.C) noreturn {
lib/std/start.zig+2-2
...@@ -92,7 +92,7 @@ fn _start2() callconv(.Naked) noreturn {...@@ -92,7 +92,7 @@ fn _start2() callconv(.Naked) noreturn {
92}92}
9393
94fn exit2(code: usize) noreturn {94fn exit2(code: usize) noreturn {
95 switch (builtin.stage2_os) {95 switch (native_os) {
96 .linux => switch (builtin.stage2_arch) {96 .linux => switch (builtin.stage2_arch) {
97 .x86_64 => {97 .x86_64 => {
98 asm volatile ("syscall"98 asm volatile ("syscall"
...@@ -345,7 +345,7 @@ fn posixCallMainAndExit() noreturn {...@@ -345,7 +345,7 @@ fn posixCallMainAndExit() noreturn {
345 // FIXME: Elide the check for targets >= ARMv7 when the target feature API345 // FIXME: Elide the check for targets >= ARMv7 when the target feature API
346 // becomes less verbose (and more usable).346 // becomes less verbose (and more usable).
347 if (comptime native_arch.isARM()) {347 if (comptime native_arch.isARM()) {
348 if (at_hwcap & std.os.linux.HWCAP_TLS == 0) {348 if (at_hwcap & std.os.linux.HWCAP.TLS == 0) {
349 // FIXME: Make __aeabi_read_tp call the kernel helper kuser_get_tls349 // FIXME: Make __aeabi_read_tp call the kernel helper kuser_get_tls
350 // For the time being use a simple abort instead of a @panic call to350 // For the time being use a simple abort instead of a @panic call to
351 // keep the binary bloat under control.351 // keep the binary bloat under control.
lib/std/time.zig+9-7
...@@ -24,7 +24,7 @@ pub fn sleep(nanoseconds: u64) void {...@@ -24,7 +24,7 @@ pub fn sleep(nanoseconds: u64) void {
24 const w = std.os.wasi;24 const w = std.os.wasi;
25 const userdata: w.userdata_t = 0x0123_45678;25 const userdata: w.userdata_t = 0x0123_45678;
26 const clock = w.subscription_clock_t{26 const clock = w.subscription_clock_t{
27 .id = w.CLOCK_MONOTONIC,27 .id = w.CLOCK.MONOTONIC,
28 .timeout = nanoseconds,28 .timeout = nanoseconds,
29 .precision = 0,29 .precision = 0,
30 .flags = 0,30 .flags = 0,
...@@ -86,12 +86,12 @@ pub fn nanoTimestamp() i128 {...@@ -86,12 +86,12 @@ pub fn nanoTimestamp() i128 {
86 }86 }
87 if (builtin.os.tag == .wasi and !builtin.link_libc) {87 if (builtin.os.tag == .wasi and !builtin.link_libc) {
88 var ns: os.wasi.timestamp_t = undefined;88 var ns: os.wasi.timestamp_t = undefined;
89 const err = os.wasi.clock_time_get(os.wasi.CLOCK_REALTIME, 1, &ns);89 const err = os.wasi.clock_time_get(os.wasi.CLOCK.REALTIME, 1, &ns);
90 assert(err == .SUCCESS);90 assert(err == .SUCCESS);
91 return ns;91 return ns;
92 }92 }
93 var ts: os.timespec = undefined;93 var ts: os.timespec = undefined;
94 os.clock_gettime(os.CLOCK_REALTIME, &ts) catch |err| switch (err) {94 os.clock_gettime(os.CLOCK.REALTIME, &ts) catch |err| switch (err) {
95 error.UnsupportedClock, error.Unexpected => return 0, // "Precision of timing depends on hardware and OS".95 error.UnsupportedClock, error.Unexpected => return 0, // "Precision of timing depends on hardware and OS".
96 };96 };
97 return (@as(i128, ts.tv_sec) * ns_per_s) + ts.tv_nsec;97 return (@as(i128, ts.tv_sec) * ns_per_s) + ts.tv_nsec;
...@@ -152,7 +152,7 @@ pub const Timer = struct {...@@ -152,7 +152,7 @@ pub const Timer = struct {
152 /// At some point we may change our minds on RAW, but for now we're152 /// At some point we may change our minds on RAW, but for now we're
153 /// sticking with posix standard MONOTONIC. For more information, see:153 /// sticking with posix standard MONOTONIC. For more information, see:
154 /// https://github.com/ziglang/zig/pull/933154 /// https://github.com/ziglang/zig/pull/933
155 const monotonic_clock_id = os.CLOCK_MONOTONIC;155 const monotonic_clock_id = os.CLOCK.MONOTONIC;
156156
157 /// Initialize the timer structure.157 /// Initialize the timer structure.
158 /// Can only fail when running in a hostile environment that intentionally injects158 /// Can only fail when running in a hostile environment that intentionally injects
...@@ -161,7 +161,7 @@ pub const Timer = struct {...@@ -161,7 +161,7 @@ pub const Timer = struct {
161 pub fn start() Error!Timer {161 pub fn start() Error!Timer {
162 // This gives us an opportunity to grab the counter frequency in windows.162 // This gives us an opportunity to grab the counter frequency in windows.
163 // On Windows: QueryPerformanceCounter will succeed on anything >= XP/2000.163 // On Windows: QueryPerformanceCounter will succeed on anything >= XP/2000.
164 // On Posix: CLOCK_MONOTONIC will only fail if the monotonic counter is not164 // On Posix: CLOCK.MONOTONIC will only fail if the monotonic counter is not
165 // supported, or if the timespec pointer is out of bounds, which should be165 // supported, or if the timespec pointer is out of bounds, which should be
166 // impossible here barring cosmic rays or other such occurrences of166 // impossible here barring cosmic rays or other such occurrences of
167 // incredibly bad luck.167 // incredibly bad luck.
...@@ -200,8 +200,6 @@ pub const Timer = struct {...@@ -200,8 +200,6 @@ pub const Timer = struct {
200 .frequency = {},200 .frequency = {},
201 };201 };
202 }202 }
203
204 return self;
205 }203 }
206204
207 /// Reads the timer value since start or the last reset in nanoseconds205 /// Reads the timer value since start or the last reset in nanoseconds
...@@ -287,3 +285,7 @@ test "Timer" {...@@ -287,3 +285,7 @@ test "Timer" {
287 timer.reset();285 timer.reset();
288 try testing.expect(timer.read() < time_1);286 try testing.expect(timer.read() < time_1);
289}287}
288
289test {
290 _ = @import("time/epoch.zig");
291}
lib/std/time/epoch.zig+190
...@@ -1,5 +1,8 @@...@@ -1,5 +1,8 @@
1//! Epoch reference times in terms of their difference from1//! Epoch reference times in terms of their difference from
2//! UTC 1970-01-01 in seconds.2//! UTC 1970-01-01 in seconds.
3const std = @import("../std.zig");
4const testing = std.testing;
5const math = std.math;
36
4/// Jan 01, 1970 AD7/// Jan 01, 1970 AD
5pub const posix = 0;8pub const posix = 0;
...@@ -35,3 +38,190 @@ pub const morphos = amiga;...@@ -35,3 +38,190 @@ pub const morphos = amiga;
35pub const brew = gps;38pub const brew = gps;
36pub const atsc = gps;39pub const atsc = gps;
37pub const go = clr;40pub const go = clr;
41
42/// The type that holds the current year, i.e. 2016
43pub const Year = u16;
44
45pub const epoch_year = 1970;
46pub const secs_per_day: u17 = 24 * 60 * 60;
47
48pub fn isLeapYear(year: Year) bool {
49 if (@mod(year, 4) != 0)
50 return false;
51 if (@mod(year, 100) != 0)
52 return true;
53 return (0 == @mod(year, 400));
54}
55
56test "isLeapYear" {
57 try testing.expectEqual(false, isLeapYear(2095));
58 try testing.expectEqual(true, isLeapYear(2096));
59 try testing.expectEqual(false, isLeapYear(2100));
60 try testing.expectEqual(true, isLeapYear(2400));
61}
62
63pub fn getDaysInYear(year: Year) u9 {
64 return if (isLeapYear(year)) 366 else 365;
65}
66
67pub const YearLeapKind = enum(u1) { not_leap, leap };
68
69pub const Month = enum(u4) {
70 jan = 1,
71 feb,
72 mar,
73 apr,
74 may,
75 jun,
76 jul,
77 aug,
78 sep,
79 oct,
80 nov,
81 dec,
82
83 /// return the numeric calendar value for the given month
84 /// i.e. jan=1, feb=2, etc
85 pub fn numeric(self: Month) u4 {
86 return @enumToInt(self);
87 }
88};
89
90/// Get the number of days in the given month
91pub fn getDaysInMonth(leap_year: YearLeapKind, month: Month) u5 {
92 return switch (month) {
93 .jan => 31,
94 .feb => @as(u5, switch (leap_year) {
95 .leap => 29,
96 .not_leap => 28,
97 }),
98 .mar => 31,
99 .apr => 30,
100 .may => 31,
101 .jun => 30,
102 .jul => 31,
103 .aug => 31,
104 .sep => 30,
105 .oct => 31,
106 .nov => 30,
107 .dec => 31,
108 };
109}
110
111pub const YearAndDay = struct {
112 year: Year,
113 /// The number of days into the year (0 to 365)
114 day: u9,
115
116 pub fn calculateMonthDay(self: YearAndDay) MonthAndDay {
117 var month: Month = .jan;
118 var days_left = self.day;
119 const leap_kind: YearLeapKind = if (isLeapYear(self.year)) .leap else .not_leap;
120 while (true) {
121 const days_in_month = getDaysInMonth(leap_kind, month);
122 if (days_left < days_in_month)
123 break;
124 days_left -= days_in_month;
125 month = @intToEnum(Month, @enumToInt(month) + 1);
126 }
127 return .{ .month = month, .day_index = @intCast(u5, days_left) };
128 }
129};
130
131pub const MonthAndDay = struct {
132 month: Month,
133 day_index: u5, // days into the month (0 to 30)
134};
135
136// days since epoch Oct 1, 1970
137pub const EpochDay = struct {
138 day: u47, // u47 = u64 - u17 (because day = sec(u64) / secs_per_day(u17)
139 pub fn calculateYearDay(self: EpochDay) YearAndDay {
140 var year_day = self.day;
141 var year: Year = epoch_year;
142 while (true) {
143 const year_size = getDaysInYear(year);
144 if (year_day < year_size)
145 break;
146 year_day -= year_size;
147 year += 1;
148 }
149 return .{ .year = year, .day = @intCast(u9, year_day) };
150 }
151};
152
153/// seconds since start of day
154pub const DaySeconds = struct {
155 secs: u17, // max is 24*60*60 = 86400
156
157 /// the number of hours past the start of the day (0 to 11)
158 pub fn getHoursIntoDay(self: DaySeconds) u5 {
159 return @intCast(u5, @divTrunc(self.secs, 3600));
160 }
161 /// the number of minutes past the hour (0 to 59)
162 pub fn getMinutesIntoHour(self: DaySeconds) u6 {
163 return @intCast(u6, @divTrunc(@mod(self.secs, 3600), 60));
164 }
165 /// the number of seconds past the start of the minute (0 to 59)
166 pub fn getSecondsIntoMinute(self: DaySeconds) u6 {
167 return math.comptimeMod(self.secs, 60);
168 }
169};
170
171/// seconds since epoch Oct 1, 1970 at 12:00 AM
172pub const EpochSeconds = struct {
173 secs: u64,
174
175 /// Returns the number of days since the epoch as an EpochDay.
176 /// Use EpochDay to get information about the day of this time.
177 pub fn getEpochDay(self: EpochSeconds) EpochDay {
178 return EpochDay{ .day = @intCast(u47, @divTrunc(self.secs, secs_per_day)) };
179 }
180
181 /// Returns the number of seconds into the day as DaySeconds.
182 /// Use DaySeconds to get information about the time.
183 pub fn getDaySeconds(self: EpochSeconds) DaySeconds {
184 return DaySeconds{ .secs = math.comptimeMod(self.secs, secs_per_day) };
185 }
186};
187
188fn testEpoch(secs: u64, expected_year_day: YearAndDay, expected_month_day: MonthAndDay, expected_day_seconds: struct {
189 /// 0 to 23
190 hours_into_day: u5,
191 /// 0 to 59
192 minutes_into_hour: u6,
193 /// 0 to 59
194 seconds_into_minute: u6,
195}) !void {
196 const epoch_seconds = EpochSeconds{ .secs = secs };
197 const epoch_day = epoch_seconds.getEpochDay();
198 const day_seconds = epoch_seconds.getDaySeconds();
199 const year_day = epoch_day.calculateYearDay();
200 try testing.expectEqual(expected_year_day, year_day);
201 try testing.expectEqual(expected_month_day, year_day.calculateMonthDay());
202 try testing.expectEqual(expected_day_seconds.hours_into_day, day_seconds.getHoursIntoDay());
203 try testing.expectEqual(expected_day_seconds.minutes_into_hour, day_seconds.getMinutesIntoHour());
204 try testing.expectEqual(expected_day_seconds.seconds_into_minute, day_seconds.getSecondsIntoMinute());
205}
206
207test "epoch decoding" {
208 try testEpoch(0, .{ .year = 1970, .day = 0 }, .{
209 .month = .jan,
210 .day_index = 0,
211 }, .{ .hours_into_day = 0, .minutes_into_hour = 0, .seconds_into_minute = 0 });
212
213 try testEpoch(31535999, .{ .year = 1970, .day = 364 }, .{
214 .month = .dec,
215 .day_index = 30,
216 }, .{ .hours_into_day = 23, .minutes_into_hour = 59, .seconds_into_minute = 59 });
217
218 try testEpoch(1622924906, .{ .year = 2021, .day = 31 + 28 + 31 + 30 + 31 + 4 }, .{
219 .month = .jun,
220 .day_index = 4,
221 }, .{ .hours_into_day = 20, .minutes_into_hour = 28, .seconds_into_minute = 26 });
222
223 try testEpoch(1625159473, .{ .year = 2021, .day = 31 + 28 + 31 + 30 + 31 + 30 }, .{
224 .month = .jul,
225 .day_index = 0,
226 }, .{ .hours_into_day = 17, .minutes_into_hour = 11, .seconds_into_minute = 13 });
227}
lib/std/x/net/tcp.zig+12-12
...@@ -46,8 +46,8 @@ pub const Connection = struct {...@@ -46,8 +46,8 @@ pub const Connection = struct {
4646
47/// Possible domains that a TCP client/listener may operate over.47/// Possible domains that a TCP client/listener may operate over.
48pub const Domain = enum(u16) {48pub const Domain = enum(u16) {
49 ip = os.AF_INET,49 ip = os.AF.INET,
50 ipv6 = os.AF_INET6,50 ipv6 = os.AF.INET6,
51};51};
5252
53/// A TCP client.53/// A TCP client.
...@@ -81,8 +81,8 @@ pub const Client = struct {...@@ -81,8 +81,8 @@ pub const Client = struct {
81 return Client{81 return Client{
82 .socket = try Socket.init(82 .socket = try Socket.init(
83 @enumToInt(domain),83 @enumToInt(domain),
84 os.SOCK_STREAM,84 os.SOCK.STREAM,
85 os.IPPROTO_TCP,85 os.IPPROTO.TCP,
86 flags,86 flags,
87 ),87 ),
88 };88 };
...@@ -193,9 +193,9 @@ pub const Client = struct {...@@ -193,9 +193,9 @@ pub const Client = struct {
193 /// Disable Nagle's algorithm on a TCP socket. It returns `error.UnsupportedSocketOption` if193 /// Disable Nagle's algorithm on a TCP socket. It returns `error.UnsupportedSocketOption` if
194 /// the host does not support sockets disabling Nagle's algorithm.194 /// the host does not support sockets disabling Nagle's algorithm.
195 pub fn setNoDelay(self: Client, enabled: bool) !void {195 pub fn setNoDelay(self: Client, enabled: bool) !void {
196 if (comptime @hasDecl(os, "TCP_NODELAY")) {196 if (@hasDecl(os.TCP, "NODELAY")) {
197 const bytes = mem.asBytes(&@as(usize, @boolToInt(enabled)));197 const bytes = mem.asBytes(&@as(usize, @boolToInt(enabled)));
198 return self.socket.setOption(os.IPPROTO_TCP, os.TCP_NODELAY, bytes);198 return self.socket.setOption(os.IPPROTO.TCP, os.TCP.NODELAY, bytes);
199 }199 }
200 return error.UnsupportedSocketOption;200 return error.UnsupportedSocketOption;
201 }201 }
...@@ -203,8 +203,8 @@ pub const Client = struct {...@@ -203,8 +203,8 @@ pub const Client = struct {
203 /// Enables TCP Quick ACK on a TCP socket to immediately send rather than delay ACKs when necessary. It returns203 /// Enables TCP Quick ACK on a TCP socket to immediately send rather than delay ACKs when necessary. It returns
204 /// `error.UnsupportedSocketOption` if the host does not support TCP Quick ACK.204 /// `error.UnsupportedSocketOption` if the host does not support TCP Quick ACK.
205 pub fn setQuickACK(self: Client, enabled: bool) !void {205 pub fn setQuickACK(self: Client, enabled: bool) !void {
206 if (comptime @hasDecl(os, "TCP_QUICKACK")) {206 if (@hasDecl(os.TCP, "QUICKACK")) {
207 return self.socket.setOption(os.IPPROTO_TCP, os.TCP_QUICKACK, mem.asBytes(&@as(u32, @boolToInt(enabled))));207 return self.socket.setOption(os.IPPROTO.TCP, os.TCP.QUICKACK, mem.asBytes(&@as(u32, @boolToInt(enabled))));
208 }208 }
209 return error.UnsupportedSocketOption;209 return error.UnsupportedSocketOption;
210 }210 }
...@@ -244,8 +244,8 @@ pub const Listener = struct {...@@ -244,8 +244,8 @@ pub const Listener = struct {
244 return Listener{244 return Listener{
245 .socket = try Socket.init(245 .socket = try Socket.init(
246 @enumToInt(domain),246 @enumToInt(domain),
247 os.SOCK_STREAM,247 os.SOCK.STREAM,
248 os.IPPROTO_TCP,248 os.IPPROTO.TCP,
249 flags,249 flags,
250 ),250 ),
251 };251 };
...@@ -304,8 +304,8 @@ pub const Listener = struct {...@@ -304,8 +304,8 @@ pub const Listener = struct {
304 /// Enables TCP Fast Open (RFC 7413) on a TCP socket. It returns `error.UnsupportedSocketOption` if the host does not304 /// Enables TCP Fast Open (RFC 7413) on a TCP socket. It returns `error.UnsupportedSocketOption` if the host does not
305 /// support TCP Fast Open.305 /// support TCP Fast Open.
306 pub fn setFastOpen(self: Listener, enabled: bool) !void {306 pub fn setFastOpen(self: Listener, enabled: bool) !void {
307 if (comptime @hasDecl(os, "TCP_FASTOPEN")) {307 if (@hasDecl(os.TCP, "FASTOPEN")) {
308 return self.socket.setOption(os.IPPROTO_TCP, os.TCP_FASTOPEN, mem.asBytes(&@as(u32, @boolToInt(enabled))));308 return self.socket.setOption(os.IPPROTO.TCP, os.TCP.FASTOPEN, mem.asBytes(&@as(u32, @boolToInt(enabled))));
309 }309 }
310 return error.UnsupportedSocketOption;310 return error.UnsupportedSocketOption;
311 }311 }
lib/std/x/os/io.zig+14-13
...@@ -4,6 +4,7 @@ const os = std.os;...@@ -4,6 +4,7 @@ const os = std.os;
4const mem = std.mem;4const mem = std.mem;
5const testing = std.testing;5const testing = std.testing;
6const native_os = std.Target.current.os;6const native_os = std.Target.current.os;
7const linux = std.os.linux;
78
8/// POSIX `iovec`, or Windows `WSABUF`. The difference between the two are the ordering9/// POSIX `iovec`, or Windows `WSABUF`. The difference between the two are the ordering
9/// of fields, alongside the length being represented as either a ULONG or a size_t.10/// of fields, alongside the length being represented as either a ULONG or a size_t.
...@@ -67,7 +68,7 @@ pub const Reactor = struct {...@@ -67,7 +68,7 @@ pub const Reactor = struct {
67 pub fn init(flags: std.enums.EnumFieldStruct(Reactor.InitFlags, bool, false)) !Reactor {68 pub fn init(flags: std.enums.EnumFieldStruct(Reactor.InitFlags, bool, false)) !Reactor {
68 var raw_flags: u32 = 0;69 var raw_flags: u32 = 0;
69 const set = std.EnumSet(Reactor.InitFlags).init(flags);70 const set = std.EnumSet(Reactor.InitFlags).init(flags);
70 if (set.contains(.close_on_exec)) raw_flags |= os.EPOLL_CLOEXEC;71 if (set.contains(.close_on_exec)) raw_flags |= linux.EPOLL.CLOEXEC;
71 return Reactor{ .fd = try os.epoll_create1(raw_flags) };72 return Reactor{ .fd = try os.epoll_create1(raw_flags) };
72 }73 }
7374
...@@ -77,31 +78,31 @@ pub const Reactor = struct {...@@ -77,31 +78,31 @@ pub const Reactor = struct {
7778
78 pub fn update(self: Reactor, fd: os.fd_t, identifier: usize, interest: Reactor.Interest) !void {79 pub fn update(self: Reactor, fd: os.fd_t, identifier: usize, interest: Reactor.Interest) !void {
79 var flags: u32 = 0;80 var flags: u32 = 0;
80 flags |= if (interest.oneshot) os.EPOLLONESHOT else os.EPOLLET;81 flags |= if (interest.oneshot) linux.EPOLL.ONESHOT else linux.EPOLL.ET;
81 if (interest.hup) flags |= os.EPOLLRDHUP;82 if (interest.hup) flags |= linux.EPOLL.RDHUP;
82 if (interest.readable) flags |= os.EPOLLIN;83 if (interest.readable) flags |= linux.EPOLL.IN;
83 if (interest.writable) flags |= os.EPOLLOUT;84 if (interest.writable) flags |= linux.EPOLL.OUT;
8485
85 const event = &os.epoll_event{86 const event = &linux.epoll_event{
86 .events = flags,87 .events = flags,
87 .data = .{ .ptr = identifier },88 .data = .{ .ptr = identifier },
88 };89 };
8990
90 os.epoll_ctl(self.fd, os.EPOLL_CTL_MOD, fd, event) catch |err| switch (err) {91 os.epoll_ctl(self.fd, linux.EPOLL.CTL_MOD, fd, event) catch |err| switch (err) {
91 error.FileDescriptorNotRegistered => try os.epoll_ctl(self.fd, os.EPOLL_CTL_ADD, fd, event),92 error.FileDescriptorNotRegistered => try os.epoll_ctl(self.fd, linux.EPOLL.CTL_ADD, fd, event),
92 else => return err,93 else => return err,
93 };94 };
94 }95 }
9596
96 pub fn poll(self: Reactor, comptime max_num_events: comptime_int, closure: anytype, timeout_milliseconds: ?u64) !void {97 pub fn poll(self: Reactor, comptime max_num_events: comptime_int, closure: anytype, timeout_milliseconds: ?u64) !void {
97 var events: [max_num_events]os.epoll_event = undefined;98 var events: [max_num_events]linux.epoll_event = undefined;
9899
99 const num_events = os.epoll_wait(self.fd, &events, if (timeout_milliseconds) |ms| @intCast(i32, ms) else -1);100 const num_events = os.epoll_wait(self.fd, &events, if (timeout_milliseconds) |ms| @intCast(i32, ms) else -1);
100 for (events[0..num_events]) |ev| {101 for (events[0..num_events]) |ev| {
101 const is_error = ev.events & os.EPOLLERR != 0;102 const is_error = ev.events & linux.EPOLL.ERR != 0;
102 const is_hup = ev.events & (os.EPOLLHUP | os.EPOLLRDHUP) != 0;103 const is_hup = ev.events & (linux.EPOLL.HUP | linux.EPOLL.RDHUP) != 0;
103 const is_readable = ev.events & os.EPOLLIN != 0;104 const is_readable = ev.events & linux.EPOLL.IN != 0;
104 const is_writable = ev.events & os.EPOLLOUT != 0;105 const is_writable = ev.events & linux.EPOLL.OUT != 0;
105106
106 try closure.call(Reactor.Event{107 try closure.call(Reactor.Event{
107 .data = ev.data.ptr,108 .data = ev.data.ptr,
lib/std/x/os/net.zig+27-13
...@@ -6,23 +6,28 @@ const mem = std.mem;...@@ -6,23 +6,28 @@ const mem = std.mem;
6const math = std.math;6const math = std.math;
7const testing = std.testing;7const testing = std.testing;
8const native_os = std.Target.current.os;8const native_os = std.Target.current.os;
9const have_ifnamesize = @hasDecl(os.system, "IFNAMESIZE");
910
10/// Resolves a network interface name into a scope/zone ID. It returns11/// Resolves a network interface name into a scope/zone ID. It returns
11/// an error if either resolution fails, or if the interface name is12/// an error if either resolution fails, or if the interface name is
12/// too long.13/// too long.
13pub fn resolveScopeID(name: []const u8) !u32 {14pub fn resolveScopeId(name: []const u8) !u32 {
14 if (@hasDecl(os, "IFNAMESIZE")) {15 if (have_ifnamesize) {
15 if (name.len >= os.IFNAMESIZE - 1) return error.NameTooLong;16 if (name.len >= os.IFNAMESIZE) return error.NameTooLong;
1617
17 if (native_os.tag == .windows) {18 if (native_os.tag == .windows) {
18 var interface_name: [os.IFNAMESIZE]u8 = undefined;19 var interface_name: [os.IFNAMESIZE:0]u8 = undefined;
19 mem.copy(u8, &interface_name, name);20 mem.copy(u8, &interface_name, name);
20 interface_name[name.len] = 0;21 interface_name[name.len] = 0;
2122
22 return os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));23 const rc = os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));
24 if (rc == 0) {
25 return error.InterfaceNotFound;
26 }
27 return rc;
23 }28 }
2429
25 const fd = try os.socket(os.AF_UNIX, os.SOCK_DGRAM, 0);30 const fd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM, 0);
26 defer os.closeSocket(fd);31 defer os.closeSocket(fd);
2732
28 var f: os.ifreq = undefined;33 var f: os.ifreq = undefined;
...@@ -34,7 +39,7 @@ pub fn resolveScopeID(name: []const u8) !u32 {...@@ -34,7 +39,7 @@ pub fn resolveScopeID(name: []const u8) !u32 {
34 return @bitCast(u32, f.ifru.ivalue);39 return @bitCast(u32, f.ifru.ivalue);
35 }40 }
3641
37 return error.Unsupported;42 return error.InterfaceNotFound;
38}43}
3944
40/// An IPv4 address comprised of 4 bytes.45/// An IPv4 address comprised of 4 bytes.
...@@ -402,7 +407,8 @@ pub const IPv6 = extern struct {...@@ -402,7 +407,8 @@ pub const IPv6 = extern struct {
402 /// address.407 /// address.
403 pub const ParseError = error{408 pub const ParseError = error{
404 MalformedV4Mapping,409 MalformedV4Mapping,
405 BadScopeID,410 InterfaceNotFound,
411 UnknownScopeId,
406 } || IPv4.ParseError;412 } || IPv4.ParseError;
407413
408 /// Parses an arbitrary IPv6 address, including link-local addresses.414 /// Parses an arbitrary IPv6 address, including link-local addresses.
...@@ -411,12 +417,15 @@ pub const IPv6 = extern struct {...@@ -411,12 +417,15 @@ pub const IPv6 = extern struct {
411 const ip_slice = buf[0..index];417 const ip_slice = buf[0..index];
412 const scope_id_slice = buf[index + 1 ..];418 const scope_id_slice = buf[index + 1 ..];
413419
414 if (scope_id_slice.len == 0) return error.BadScopeID;420 if (scope_id_slice.len == 0) return error.UnknownScopeId;
415421
416 const scope_id: u32 = switch (scope_id_slice[0]) {422 const scope_id: u32 = switch (scope_id_slice[0]) {
417 '0'...'9' => fmt.parseInt(u32, scope_id_slice, 10),423 '0'...'9' => fmt.parseInt(u32, scope_id_slice, 10),
418 else => resolveScopeID(scope_id_slice),424 else => resolveScopeId(scope_id_slice) catch |err| switch (err) {
419 } catch return error.BadScopeID;425 error.InterfaceNotFound => return error.InterfaceNotFound,
426 else => err,
427 },
428 } catch return error.UnknownScopeId;
420429
421 return parseWithScopeID(ip_slice, scope_id);430 return parseWithScopeID(ip_slice, scope_id);
422 }431 }
...@@ -556,7 +565,7 @@ test "ipv6: parse & format" {...@@ -556,7 +565,7 @@ test "ipv6: parse & format" {
556}565}
557566
558test "ipv6: parse & format addresses with scope ids" {567test "ipv6: parse & format addresses with scope ids" {
559 if (!@hasDecl(os, "IFNAMESIZE")) return error.SkipZigTest;568 if (!have_ifnamesize) return error.SkipZigTest;
560569
561 const inputs = [_][]const u8{570 const inputs = [_][]const u8{
562 "FF01::FB%lo",571 "FF01::FB%lo",
...@@ -567,6 +576,11 @@ test "ipv6: parse & format addresses with scope ids" {...@@ -567,6 +576,11 @@ test "ipv6: parse & format addresses with scope ids" {
567 };576 };
568577
569 for (inputs) |input, i| {578 for (inputs) |input, i| {
570 try testing.expectFmt(outputs[i], "{}", .{try IPv6.parse(input)});579 const parsed = IPv6.parse(input) catch |err| switch (err) {
580 error.InterfaceNotFound => continue,
581 else => return err,
582 };
583
584 try testing.expectFmt(outputs[i], "{}", .{parsed});
571 }585 }
572}586}
lib/std/x/os/socket.zig+9-9
...@@ -35,7 +35,7 @@ pub const Socket = struct {...@@ -35,7 +35,7 @@ pub const Socket = struct {
3535
36 pub const Family = if (requires_prepended_length) u8 else c_ushort;36 pub const Family = if (requires_prepended_length) u8 else c_ushort;
3737
38 /// POSIX `sockaddr_storage`. The expected size and alignment is specified in IETF RFC 2553.38 /// POSIX `sockaddr.storage`. The expected size and alignment is specified in IETF RFC 2553.
39 pub const Storage = extern struct {39 pub const Storage = extern struct {
40 pub const expected_size = 128;40 pub const expected_size = 128;
41 pub const expected_alignment = 8;41 pub const expected_alignment = 8;
...@@ -71,14 +71,14 @@ pub const Socket = struct {...@@ -71,14 +71,14 @@ pub const Socket = struct {
71 /// Parses a `sockaddr` into a generic socket address.71 /// Parses a `sockaddr` into a generic socket address.
72 pub fn fromNative(address: *align(4) const os.sockaddr) Socket.Address {72 pub fn fromNative(address: *align(4) const os.sockaddr) Socket.Address {
73 switch (address.family) {73 switch (address.family) {
74 os.AF_INET => {74 os.AF.INET => {
75 const info = @ptrCast(*const os.sockaddr_in, address);75 const info = @ptrCast(*const os.sockaddr.in, address);
76 const host = net.IPv4{ .octets = @bitCast([4]u8, info.addr) };76 const host = net.IPv4{ .octets = @bitCast([4]u8, info.addr) };
77 const port = mem.bigToNative(u16, info.port);77 const port = mem.bigToNative(u16, info.port);
78 return Socket.Address.initIPv4(host, port);78 return Socket.Address.initIPv4(host, port);
79 },79 },
80 os.AF_INET6 => {80 os.AF.INET6 => {
81 const info = @ptrCast(*const os.sockaddr_in6, address);81 const info = @ptrCast(*const os.sockaddr.in6, address);
82 const host = net.IPv6{ .octets = info.addr, .scope_id = info.scope_id };82 const host = net.IPv6{ .octets = info.addr, .scope_id = info.scope_id };
83 const port = mem.bigToNative(u16, info.port);83 const port = mem.bigToNative(u16, info.port);
84 return Socket.Address.initIPv6(host, port);84 return Socket.Address.initIPv6(host, port);
...@@ -90,8 +90,8 @@ pub const Socket = struct {...@@ -90,8 +90,8 @@ pub const Socket = struct {
90 /// Encodes a generic socket address into an extern union that may be reliably90 /// Encodes a generic socket address into an extern union that may be reliably
91 /// casted into a `sockaddr` which may be passed into socket syscalls.91 /// casted into a `sockaddr` which may be passed into socket syscalls.
92 pub fn toNative(self: Socket.Address) extern union {92 pub fn toNative(self: Socket.Address) extern union {
93 ipv4: os.sockaddr_in,93 ipv4: os.sockaddr.in,
94 ipv6: os.sockaddr_in6,94 ipv6: os.sockaddr.in6,
95 } {95 } {
96 return switch (self) {96 return switch (self) {
97 .ipv4 => |address| .{97 .ipv4 => |address| .{
...@@ -114,8 +114,8 @@ pub const Socket = struct {...@@ -114,8 +114,8 @@ pub const Socket = struct {
114 /// Returns the number of bytes that make up the `sockaddr` equivalent to the address.114 /// Returns the number of bytes that make up the `sockaddr` equivalent to the address.
115 pub fn getNativeSize(self: Socket.Address) u32 {115 pub fn getNativeSize(self: Socket.Address) u32 {
116 return switch (self) {116 return switch (self) {
117 .ipv4 => @sizeOf(os.sockaddr_in),117 .ipv4 => @sizeOf(os.sockaddr.in),
118 .ipv6 => @sizeOf(os.sockaddr_in6),118 .ipv6 => @sizeOf(os.sockaddr.in6),
119 };119 };
120 }120 }
121121
lib/std/x/os/socket_posix.zig+18-18
...@@ -10,8 +10,8 @@ pub fn Mixin(comptime Socket: type) type {...@@ -10,8 +10,8 @@ pub fn Mixin(comptime Socket: type) type {
10 pub fn init(domain: u32, socket_type: u32, protocol: u32, flags: std.enums.EnumFieldStruct(Socket.InitFlags, bool, false)) !Socket {10 pub fn init(domain: u32, socket_type: u32, protocol: u32, flags: std.enums.EnumFieldStruct(Socket.InitFlags, bool, false)) !Socket {
11 var raw_flags: u32 = socket_type;11 var raw_flags: u32 = socket_type;
12 const set = std.EnumSet(Socket.InitFlags).init(flags);12 const set = std.EnumSet(Socket.InitFlags).init(flags);
13 if (set.contains(.close_on_exec)) raw_flags |= os.SOCK_CLOEXEC;13 if (set.contains(.close_on_exec)) raw_flags |= os.SOCK.CLOEXEC;
14 if (set.contains(.nonblocking)) raw_flags |= os.SOCK_NONBLOCK;14 if (set.contains(.nonblocking)) raw_flags |= os.SOCK.NONBLOCK;
15 return Socket{ .fd = try os.socket(domain, raw_flags, protocol) };15 return Socket{ .fd = try os.socket(domain, raw_flags, protocol) };
16 }16 }
1717
...@@ -48,8 +48,8 @@ pub fn Mixin(comptime Socket: type) type {...@@ -48,8 +48,8 @@ pub fn Mixin(comptime Socket: type) type {
4848
49 var raw_flags: u32 = 0;49 var raw_flags: u32 = 0;
50 const set = std.EnumSet(Socket.InitFlags).init(flags);50 const set = std.EnumSet(Socket.InitFlags).init(flags);
51 if (set.contains(.close_on_exec)) raw_flags |= os.SOCK_CLOEXEC;51 if (set.contains(.close_on_exec)) raw_flags |= os.SOCK.CLOEXEC;
52 if (set.contains(.nonblocking)) raw_flags |= os.SOCK_NONBLOCK;52 if (set.contains(.nonblocking)) raw_flags |= os.SOCK.NONBLOCK;
5353
54 const socket = Socket{ .fd = try os.accept(self.fd, @ptrCast(*os.sockaddr, &address), &address_len, raw_flags) };54 const socket = Socket{ .fd = try os.accept(self.fd, @ptrCast(*os.sockaddr, &address), &address_len, raw_flags) };
55 const socket_address = Socket.Address.fromNative(@ptrCast(*os.sockaddr, &address));55 const socket_address = Socket.Address.fromNative(@ptrCast(*os.sockaddr, &address));
...@@ -156,7 +156,7 @@ pub fn Mixin(comptime Socket: type) type {...@@ -156,7 +156,7 @@ pub fn Mixin(comptime Socket: type) type {
156 var value: u32 = undefined;156 var value: u32 = undefined;
157 var value_len: u32 = @sizeOf(u32);157 var value_len: u32 = @sizeOf(u32);
158158
159 const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&value), &value_len);159 const rc = os.system.getsockopt(self.fd, os.SOL.SOCKET, os.SO.RCVBUF, mem.asBytes(&value), &value_len);
160 return switch (os.errno(rc)) {160 return switch (os.errno(rc)) {
161 .SUCCESS => value,161 .SUCCESS => value,
162 .BADF => error.BadFileDescriptor,162 .BADF => error.BadFileDescriptor,
...@@ -173,7 +173,7 @@ pub fn Mixin(comptime Socket: type) type {...@@ -173,7 +173,7 @@ pub fn Mixin(comptime Socket: type) type {
173 var value: u32 = undefined;173 var value: u32 = undefined;
174 var value_len: u32 = @sizeOf(u32);174 var value_len: u32 = @sizeOf(u32);
175175
176 const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&value), &value_len);176 const rc = os.system.getsockopt(self.fd, os.SOL.SOCKET, os.SO.SNDBUF, mem.asBytes(&value), &value_len);
177 return switch (os.errno(rc)) {177 return switch (os.errno(rc)) {
178 .SUCCESS => value,178 .SUCCESS => value,
179 .BADF => error.BadFileDescriptor,179 .BADF => error.BadFileDescriptor,
...@@ -195,9 +195,9 @@ pub fn Mixin(comptime Socket: type) type {...@@ -195,9 +195,9 @@ pub fn Mixin(comptime Socket: type) type {
195 /// if the host does not support the option for a socket to linger around up until a timeout specified in195 /// if the host does not support the option for a socket to linger around up until a timeout specified in
196 /// seconds.196 /// seconds.
197 pub fn setLinger(self: Socket, timeout_seconds: ?u16) !void {197 pub fn setLinger(self: Socket, timeout_seconds: ?u16) !void {
198 if (comptime @hasDecl(os, "SO_LINGER")) {198 if (@hasDecl(os.SO, "LINGER")) {
199 const settings = Socket.Linger.init(timeout_seconds);199 const settings = Socket.Linger.init(timeout_seconds);
200 return self.setOption(os.SOL_SOCKET, os.SO_LINGER, mem.asBytes(&settings));200 return self.setOption(os.SOL.SOCKET, os.SO.LINGER, mem.asBytes(&settings));
201 }201 }
202202
203 return error.UnsupportedSocketOption;203 return error.UnsupportedSocketOption;
...@@ -207,8 +207,8 @@ pub fn Mixin(comptime Socket: type) type {...@@ -207,8 +207,8 @@ pub fn Mixin(comptime Socket: type) type {
207 /// messages are sent are dependant on operating system settings. It returns `error.UnsupportedSocketOption` if207 /// messages are sent are dependant on operating system settings. It returns `error.UnsupportedSocketOption` if
208 /// the host does not support periodically sending keep-alive messages on connection-oriented sockets. 208 /// the host does not support periodically sending keep-alive messages on connection-oriented sockets.
209 pub fn setKeepAlive(self: Socket, enabled: bool) !void {209 pub fn setKeepAlive(self: Socket, enabled: bool) !void {
210 if (comptime @hasDecl(os, "SO_KEEPALIVE")) {210 if (@hasDecl(os.SO, "KEEPALIVE")) {
211 return self.setOption(os.SOL_SOCKET, os.SO_KEEPALIVE, mem.asBytes(&@as(u32, @boolToInt(enabled))));211 return self.setOption(os.SOL.SOCKET, os.SO.KEEPALIVE, mem.asBytes(&@as(u32, @boolToInt(enabled))));
212 }212 }
213 return error.UnsupportedSocketOption;213 return error.UnsupportedSocketOption;
214 }214 }
...@@ -216,8 +216,8 @@ pub fn Mixin(comptime Socket: type) type {...@@ -216,8 +216,8 @@ pub fn Mixin(comptime Socket: type) type {
216 /// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if216 /// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
217 /// the host does not support sockets listening the same address.217 /// the host does not support sockets listening the same address.
218 pub fn setReuseAddress(self: Socket, enabled: bool) !void {218 pub fn setReuseAddress(self: Socket, enabled: bool) !void {
219 if (comptime @hasDecl(os, "SO_REUSEADDR")) {219 if (@hasDecl(os.SO, "REUSEADDR")) {
220 return self.setOption(os.SOL_SOCKET, os.SO_REUSEADDR, mem.asBytes(&@as(u32, @boolToInt(enabled))));220 return self.setOption(os.SOL.SOCKET, os.SO.REUSEADDR, mem.asBytes(&@as(u32, @boolToInt(enabled))));
221 }221 }
222 return error.UnsupportedSocketOption;222 return error.UnsupportedSocketOption;
223 }223 }
...@@ -225,20 +225,20 @@ pub fn Mixin(comptime Socket: type) type {...@@ -225,20 +225,20 @@ pub fn Mixin(comptime Socket: type) type {
225 /// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if225 /// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if
226 /// the host does not supports sockets listening on the same port.226 /// the host does not supports sockets listening on the same port.
227 pub fn setReusePort(self: Socket, enabled: bool) !void {227 pub fn setReusePort(self: Socket, enabled: bool) !void {
228 if (comptime @hasDecl(os, "SO_REUSEPORT")) {228 if (@hasDecl(os.SO, "REUSEPORT")) {
229 return self.setOption(os.SOL_SOCKET, os.SO_REUSEPORT, mem.asBytes(&@as(u32, @boolToInt(enabled))));229 return self.setOption(os.SOL.SOCKET, os.SO.REUSEPORT, mem.asBytes(&@as(u32, @boolToInt(enabled))));
230 }230 }
231 return error.UnsupportedSocketOption;231 return error.UnsupportedSocketOption;
232 }232 }
233233
234 /// Set the write buffer size of the socket.234 /// Set the write buffer size of the socket.
235 pub fn setWriteBufferSize(self: Socket, size: u32) !void {235 pub fn setWriteBufferSize(self: Socket, size: u32) !void {
236 return self.setOption(os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&size));236 return self.setOption(os.SOL.SOCKET, os.SO.SNDBUF, mem.asBytes(&size));
237 }237 }
238238
239 /// Set the read buffer size of the socket.239 /// Set the read buffer size of the socket.
240 pub fn setReadBufferSize(self: Socket, size: u32) !void {240 pub fn setReadBufferSize(self: Socket, size: u32) !void {
241 return self.setOption(os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&size));241 return self.setOption(os.SOL.SOCKET, os.SO.RCVBUF, mem.asBytes(&size));
242 }242 }
243243
244 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is244 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is
...@@ -253,7 +253,7 @@ pub fn Mixin(comptime Socket: type) type {...@@ -253,7 +253,7 @@ pub fn Mixin(comptime Socket: type) type {
253 .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),253 .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
254 };254 };
255255
256 return self.setOption(os.SOL_SOCKET, os.SO_SNDTIMEO, mem.asBytes(&timeout));256 return self.setOption(os.SOL.SOCKET, os.SO.SNDTIMEO, mem.asBytes(&timeout));
257 }257 }
258258
259 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is259 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is
...@@ -269,7 +269,7 @@ pub fn Mixin(comptime Socket: type) type {...@@ -269,7 +269,7 @@ pub fn Mixin(comptime Socket: type) type {
269 .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),269 .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
270 };270 };
271271
272 return self.setOption(os.SOL_SOCKET, os.SO_RCVTIMEO, mem.asBytes(&timeout));272 return self.setOption(os.SOL.SOCKET, os.SO.RCVTIMEO, mem.asBytes(&timeout));
273 }273 }
274 };274 };
275}275}
lib/std/x/os/socket_windows.zig+10-10
...@@ -11,7 +11,7 @@ pub fn Mixin(comptime Socket: type) type {...@@ -11,7 +11,7 @@ pub fn Mixin(comptime Socket: type) type {
11 return struct {11 return struct {
12 /// Open a new socket.12 /// Open a new socket.
13 pub fn init(domain: u32, socket_type: u32, protocol: u32, flags: std.enums.EnumFieldStruct(Socket.InitFlags, bool, false)) !Socket {13 pub fn init(domain: u32, socket_type: u32, protocol: u32, flags: std.enums.EnumFieldStruct(Socket.InitFlags, bool, false)) !Socket {
14 var raw_flags: u32 = 0;14 var raw_flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED;
15 const set = std.EnumSet(Socket.InitFlags).init(flags);15 const set = std.EnumSet(Socket.InitFlags).init(flags);
16 if (set.contains(.close_on_exec)) raw_flags |= ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;16 if (set.contains(.close_on_exec)) raw_flags |= ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;
1717
...@@ -399,39 +399,39 @@ pub fn Mixin(comptime Socket: type) type {...@@ -399,39 +399,39 @@ pub fn Mixin(comptime Socket: type) type {
399 /// seconds.399 /// seconds.
400 pub fn setLinger(self: Socket, timeout_seconds: ?u16) !void {400 pub fn setLinger(self: Socket, timeout_seconds: ?u16) !void {
401 const settings = Socket.Linger.init(timeout_seconds);401 const settings = Socket.Linger.init(timeout_seconds);
402 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_LINGER, mem.asBytes(&settings));402 return self.setOption(ws2_32.SOL.SOCKET, ws2_32.SO.LINGER, mem.asBytes(&settings));
403 }403 }
404404
405 /// On connection-oriented sockets, have keep-alive messages be sent periodically. The timing in which keep-alive405 /// On connection-oriented sockets, have keep-alive messages be sent periodically. The timing in which keep-alive
406 /// messages are sent are dependant on operating system settings. It returns `error.UnsupportedSocketOption` if406 /// messages are sent are dependant on operating system settings. It returns `error.UnsupportedSocketOption` if
407 /// the host does not support periodically sending keep-alive messages on connection-oriented sockets.407 /// the host does not support periodically sending keep-alive messages on connection-oriented sockets.
408 pub fn setKeepAlive(self: Socket, enabled: bool) !void {408 pub fn setKeepAlive(self: Socket, enabled: bool) !void {
409 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_KEEPALIVE, mem.asBytes(&@as(u32, @boolToInt(enabled))));409 return self.setOption(ws2_32.SOL.SOCKET, ws2_32.SO.KEEPALIVE, mem.asBytes(&@as(u32, @boolToInt(enabled))));
410 }410 }
411411
412 /// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if412 /// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
413 /// the host does not support sockets listening the same address.413 /// the host does not support sockets listening the same address.
414 pub fn setReuseAddress(self: Socket, enabled: bool) !void {414 pub fn setReuseAddress(self: Socket, enabled: bool) !void {
415 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_REUSEADDR, mem.asBytes(&@as(u32, @boolToInt(enabled))));415 return self.setOption(ws2_32.SOL.SOCKET, ws2_32.SO.REUSEADDR, mem.asBytes(&@as(u32, @boolToInt(enabled))));
416 }416 }
417417
418 /// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if418 /// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if
419 /// the host does not supports sockets listening on the same port.419 /// the host does not supports sockets listening on the same port.
420 ///420 ///
421 /// TODO: verify if this truly mimicks SO_REUSEPORT behavior, or if SO_REUSE_UNICASTPORT provides the correct behavior421 /// TODO: verify if this truly mimicks SO.REUSEPORT behavior, or if SO.REUSE_UNICASTPORT provides the correct behavior
422 pub fn setReusePort(self: Socket, enabled: bool) !void {422 pub fn setReusePort(self: Socket, enabled: bool) !void {
423 try self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_BROADCAST, mem.asBytes(&@as(u32, @boolToInt(enabled))));423 try self.setOption(ws2_32.SOL.SOCKET, ws2_32.SO.BROADCAST, mem.asBytes(&@as(u32, @boolToInt(enabled))));
424 try self.setReuseAddress(enabled);424 try self.setReuseAddress(enabled);
425 }425 }
426426
427 /// Set the write buffer size of the socket.427 /// Set the write buffer size of the socket.
428 pub fn setWriteBufferSize(self: Socket, size: u32) !void {428 pub fn setWriteBufferSize(self: Socket, size: u32) !void {
429 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_SNDBUF, mem.asBytes(&size));429 return self.setOption(ws2_32.SOL.SOCKET, ws2_32.SO.SNDBUF, mem.asBytes(&size));
430 }430 }
431431
432 /// Set the read buffer size of the socket.432 /// Set the read buffer size of the socket.
433 pub fn setReadBufferSize(self: Socket, size: u32) !void {433 pub fn setReadBufferSize(self: Socket, size: u32) !void {
434 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_RCVBUF, mem.asBytes(&size));434 return self.setOption(ws2_32.SOL.SOCKET, ws2_32.SO.RCVBUF, mem.asBytes(&size));
435 }435 }
436436
437 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is437 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is
...@@ -441,7 +441,7 @@ pub fn Mixin(comptime Socket: type) type {...@@ -441,7 +441,7 @@ pub fn Mixin(comptime Socket: type) type {
441 /// to its bound destination after a specified number of milliseconds. A subsequent write441 /// to its bound destination after a specified number of milliseconds. A subsequent write
442 /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.442 /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
443 pub fn setWriteTimeout(self: Socket, milliseconds: u32) !void {443 pub fn setWriteTimeout(self: Socket, milliseconds: u32) !void {
444 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_SNDTIMEO, mem.asBytes(&milliseconds));444 return self.setOption(ws2_32.SOL.SOCKET, ws2_32.SO.SNDTIMEO, mem.asBytes(&milliseconds));
445 }445 }
446446
447 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is447 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is
...@@ -452,7 +452,7 @@ pub fn Mixin(comptime Socket: type) type {...@@ -452,7 +452,7 @@ pub fn Mixin(comptime Socket: type) type {
452 /// read from the socket will thereafter return `error.WouldBlock` should the timeout be452 /// read from the socket will thereafter return `error.WouldBlock` should the timeout be
453 /// exceeded.453 /// exceeded.
454 pub fn setReadTimeout(self: Socket, milliseconds: u32) !void {454 pub fn setReadTimeout(self: Socket, milliseconds: u32) !void {
455 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_RCVTIMEO, mem.asBytes(&milliseconds));455 return self.setOption(ws2_32.SOL.SOCKET, ws2_32.SO.RCVTIMEO, mem.asBytes(&milliseconds));
456 }456 }
457 };457 };
458}458}
lib/std/zig.zig+6-5
...@@ -10,7 +10,7 @@ pub const fmtEscapes = fmt.fmtEscapes;...@@ -10,7 +10,7 @@ pub const fmtEscapes = fmt.fmtEscapes;
10pub const isValidId = fmt.isValidId;10pub const isValidId = fmt.isValidId;
11pub const parse = @import("zig/parse.zig").parse;11pub const parse = @import("zig/parse.zig").parse;
12pub const string_literal = @import("zig/string_literal.zig");12pub const string_literal = @import("zig/string_literal.zig");
13pub const ast = @import("zig/ast.zig");13pub const Ast = @import("zig/Ast.zig");
14pub const system = @import("zig/system.zig");14pub const system = @import("zig/system.zig");
15pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget;15pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget;
1616
...@@ -157,7 +157,6 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro...@@ -157,7 +157,6 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
157 }157 }
158 },158 },
159 }159 }
160 return std.fmt.allocPrint(allocator, "{s}{s}{s}", .{ target.libPrefix(), root_name, suffix });
161 },160 },
162 .Obj => return std.fmt.allocPrint(allocator, "{s}.o", .{root_name}),161 .Obj => return std.fmt.allocPrint(allocator, "{s}.o", .{root_name}),
163 },162 },
...@@ -177,9 +176,11 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro...@@ -177,9 +176,11 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
177 .spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}),176 .spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}),
178 .hex => return std.fmt.allocPrint(allocator, "{s}.ihex", .{root_name}),177 .hex => return std.fmt.allocPrint(allocator, "{s}.ihex", .{root_name}),
179 .raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}),178 .raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}),
180 .plan9 => return std.fmt.allocPrint(allocator, "{s}{s}", .{179 .plan9 => switch (options.output_mode) {
181 root_name, ofmt.fileExt(target.cpu.arch),180 .Exe => return allocator.dupe(u8, root_name),
182 }),181 .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, ofmt.fileExt(target.cpu.arch) }),
182 .Lib => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ target.libPrefix(), root_name }),
183 },
183 }184 }
184}185}
185186
lib/std/zig/Ast.zig created+2979
...@@ -0,0 +1,2979 @@
1//! Abstract Syntax Tree for Zig source code.
2
3/// Reference to externally-owned data.
4source: [:0]const u8,
5
6tokens: TokenList.Slice,
7/// The root AST node is assumed to be index 0. Since there can be no
8/// references to the root node, this means 0 is available to indicate null.
9nodes: NodeList.Slice,
10extra_data: []Node.Index,
11
12errors: []const Error,
13
14const std = @import("../std.zig");
15const assert = std.debug.assert;
16const testing = std.testing;
17const mem = std.mem;
18const Token = std.zig.Token;
19const Tree = @This();
20
21pub const TokenIndex = u32;
22pub const ByteOffset = u32;
23
24pub const TokenList = std.MultiArrayList(struct {
25 tag: Token.Tag,
26 start: ByteOffset,
27});
28pub const NodeList = std.MultiArrayList(Node);
29
30pub const Location = struct {
31 line: usize,
32 column: usize,
33 line_start: usize,
34 line_end: usize,
35};
36
37pub fn deinit(tree: *Tree, gpa: *mem.Allocator) void {
38 tree.tokens.deinit(gpa);
39 tree.nodes.deinit(gpa);
40 gpa.free(tree.extra_data);
41 gpa.free(tree.errors);
42 tree.* = undefined;
43}
44
45pub const RenderError = error{
46 /// Ran out of memory allocating call stack frames to complete rendering, or
47 /// ran out of memory allocating space in the output buffer.
48 OutOfMemory,
49};
50
51/// `gpa` is used for allocating the resulting formatted source code, as well as
52/// for allocating extra stack memory if needed, because this function utilizes recursion.
53/// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.
54/// Caller owns the returned slice of bytes, allocated with `gpa`.
55pub fn render(tree: Tree, gpa: *mem.Allocator) RenderError![]u8 {
56 var buffer = std.ArrayList(u8).init(gpa);
57 defer buffer.deinit();
58
59 try tree.renderToArrayList(&buffer);
60 return buffer.toOwnedSlice();
61}
62
63pub fn renderToArrayList(tree: Tree, buffer: *std.ArrayList(u8)) RenderError!void {
64 return @import("./render.zig").renderTree(buffer, tree);
65}
66
67pub fn tokenLocation(self: Tree, start_offset: ByteOffset, token_index: TokenIndex) Location {
68 var loc = Location{
69 .line = 0,
70 .column = 0,
71 .line_start = start_offset,
72 .line_end = self.source.len,
73 };
74 const token_start = self.tokens.items(.start)[token_index];
75 for (self.source[start_offset..]) |c, i| {
76 if (i + start_offset == token_start) {
77 loc.line_end = i + start_offset;
78 while (loc.line_end < self.source.len and self.source[loc.line_end] != '\n') {
79 loc.line_end += 1;
80 }
81 return loc;
82 }
83 if (c == '\n') {
84 loc.line += 1;
85 loc.column = 0;
86 loc.line_start = i + 1;
87 } else {
88 loc.column += 1;
89 }
90 }
91 return loc;
92}
93
94pub fn tokenSlice(tree: Tree, token_index: TokenIndex) []const u8 {
95 const token_starts = tree.tokens.items(.start);
96 const token_tags = tree.tokens.items(.tag);
97 const token_tag = token_tags[token_index];
98
99 // Many tokens can be determined entirely by their tag.
100 if (token_tag.lexeme()) |lexeme| {
101 return lexeme;
102 }
103
104 // For some tokens, re-tokenization is needed to find the end.
105 var tokenizer: std.zig.Tokenizer = .{
106 .buffer = tree.source,
107 .index = token_starts[token_index],
108 .pending_invalid_token = null,
109 };
110 const token = tokenizer.next();
111 assert(token.tag == token_tag);
112 return tree.source[token.loc.start..token.loc.end];
113}
114
115pub fn extraData(tree: Tree, index: usize, comptime T: type) T {
116 const fields = std.meta.fields(T);
117 var result: T = undefined;
118 inline for (fields) |field, i| {
119 comptime assert(field.field_type == Node.Index);
120 @field(result, field.name) = tree.extra_data[index + i];
121 }
122 return result;
123}
124
125pub fn rootDecls(tree: Tree) []const Node.Index {
126 // Root is always index 0.
127 const nodes_data = tree.nodes.items(.data);
128 return tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs];
129}
130
131pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {
132 const token_tags = tree.tokens.items(.tag);
133 switch (parse_error.tag) {
134 .asterisk_after_ptr_deref => {
135 // Note that the token will point at the `.*` but ideally the source
136 // location would point to the `*` after the `.*`.
137 return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");
138 },
139 .decl_between_fields => {
140 return stream.writeAll("declarations are not allowed between container fields");
141 },
142 .expected_block => {
143 return stream.print("expected block or field, found '{s}'", .{
144 token_tags[parse_error.token].symbol(),
145 });
146 },
147 .expected_block_or_assignment => {
148 return stream.print("expected block or assignment, found '{s}'", .{
149 token_tags[parse_error.token].symbol(),
150 });
151 },
152 .expected_block_or_expr => {
153 return stream.print("expected block or expression, found '{s}'", .{
154 token_tags[parse_error.token].symbol(),
155 });
156 },
157 .expected_block_or_field => {
158 return stream.print("expected block or field, found '{s}'", .{
159 token_tags[parse_error.token].symbol(),
160 });
161 },
162 .expected_container_members => {
163 return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{
164 token_tags[parse_error.token].symbol(),
165 });
166 },
167 .expected_expr => {
168 return stream.print("expected expression, found '{s}'", .{
169 token_tags[parse_error.token].symbol(),
170 });
171 },
172 .expected_expr_or_assignment => {
173 return stream.print("expected expression or assignment, found '{s}'", .{
174 token_tags[parse_error.token].symbol(),
175 });
176 },
177 .expected_fn => {
178 return stream.print("expected function, found '{s}'", .{
179 token_tags[parse_error.token].symbol(),
180 });
181 },
182 .expected_inlinable => {
183 return stream.print("expected 'while' or 'for', found '{s}'", .{
184 token_tags[parse_error.token].symbol(),
185 });
186 },
187 .expected_labelable => {
188 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{
189 token_tags[parse_error.token].symbol(),
190 });
191 },
192 .expected_param_list => {
193 return stream.print("expected parameter list, found '{s}'", .{
194 token_tags[parse_error.token].symbol(),
195 });
196 },
197 .expected_prefix_expr => {
198 return stream.print("expected prefix expression, found '{s}'", .{
199 token_tags[parse_error.token].symbol(),
200 });
201 },
202 .expected_primary_type_expr => {
203 return stream.print("expected primary type expression, found '{s}'", .{
204 token_tags[parse_error.token].symbol(),
205 });
206 },
207 .expected_pub_item => {
208 return stream.writeAll("expected function or variable declaration after pub");
209 },
210 .expected_return_type => {
211 return stream.print("expected return type expression, found '{s}'", .{
212 token_tags[parse_error.token].symbol(),
213 });
214 },
215 .expected_semi_or_else => {
216 return stream.print("expected ';' or 'else', found '{s}'", .{
217 token_tags[parse_error.token].symbol(),
218 });
219 },
220 .expected_semi_or_lbrace => {
221 return stream.print("expected ';' or '{{', found '{s}'", .{
222 token_tags[parse_error.token].symbol(),
223 });
224 },
225 .expected_statement => {
226 return stream.print("expected statement, found '{s}'", .{
227 token_tags[parse_error.token].symbol(),
228 });
229 },
230 .expected_string_literal => {
231 return stream.print("expected string literal, found '{s}'", .{
232 token_tags[parse_error.token].symbol(),
233 });
234 },
235 .expected_suffix_op => {
236 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
237 token_tags[parse_error.token].symbol(),
238 });
239 },
240 .expected_type_expr => {
241 return stream.print("expected type expression, found '{s}'", .{
242 token_tags[parse_error.token].symbol(),
243 });
244 },
245 .expected_var_decl => {
246 return stream.print("expected variable declaration, found '{s}'", .{
247 token_tags[parse_error.token].symbol(),
248 });
249 },
250 .expected_var_decl_or_fn => {
251 return stream.print("expected variable declaration or function, found '{s}'", .{
252 token_tags[parse_error.token].symbol(),
253 });
254 },
255 .expected_loop_payload => {
256 return stream.print("expected loop payload, found '{s}'", .{
257 token_tags[parse_error.token].symbol(),
258 });
259 },
260 .expected_container => {
261 return stream.print("expected a struct, enum or union, found '{s}'", .{
262 token_tags[parse_error.token].symbol(),
263 });
264 },
265 .extra_align_qualifier => {
266 return stream.writeAll("extra align qualifier");
267 },
268 .extra_allowzero_qualifier => {
269 return stream.writeAll("extra allowzero qualifier");
270 },
271 .extra_const_qualifier => {
272 return stream.writeAll("extra const qualifier");
273 },
274 .extra_volatile_qualifier => {
275 return stream.writeAll("extra volatile qualifier");
276 },
277 .ptr_mod_on_array_child_type => {
278 return stream.print("pointer modifier '{s}' not allowed on array child type", .{
279 token_tags[parse_error.token].symbol(),
280 });
281 },
282 .invalid_bit_range => {
283 return stream.writeAll("bit range not allowed on slices and arrays");
284 },
285 .invalid_token => {
286 return stream.print("invalid token: '{s}'", .{
287 token_tags[parse_error.token].symbol(),
288 });
289 },
290 .same_line_doc_comment => {
291 return stream.writeAll("same line documentation comment");
292 },
293 .unattached_doc_comment => {
294 return stream.writeAll("unattached documentation comment");
295 },
296 .varargs_nonfinal => {
297 return stream.writeAll("function prototype has parameter after varargs");
298 },
299
300 .expected_token => {
301 const found_tag = token_tags[parse_error.token];
302 const expected_symbol = parse_error.extra.expected_tag.symbol();
303 switch (found_tag) {
304 .invalid => return stream.print("expected '{s}', found invalid bytes", .{
305 expected_symbol,
306 }),
307 else => return stream.print("expected '{s}', found '{s}'", .{
308 expected_symbol, found_tag.symbol(),
309 }),
310 }
311 },
312 }
313}
314
315pub fn firstToken(tree: Tree, node: Node.Index) TokenIndex {
316 const tags = tree.nodes.items(.tag);
317 const datas = tree.nodes.items(.data);
318 const main_tokens = tree.nodes.items(.main_token);
319 const token_tags = tree.tokens.items(.tag);
320 var end_offset: TokenIndex = 0;
321 var n = node;
322 while (true) switch (tags[n]) {
323 .root => return 0,
324
325 .test_decl,
326 .@"errdefer",
327 .@"defer",
328 .bool_not,
329 .negation,
330 .bit_not,
331 .negation_wrap,
332 .address_of,
333 .@"try",
334 .@"await",
335 .optional_type,
336 .@"switch",
337 .switch_comma,
338 .if_simple,
339 .@"if",
340 .@"suspend",
341 .@"resume",
342 .@"continue",
343 .@"break",
344 .@"return",
345 .anyframe_type,
346 .identifier,
347 .anyframe_literal,
348 .char_literal,
349 .integer_literal,
350 .float_literal,
351 .unreachable_literal,
352 .string_literal,
353 .multiline_string_literal,
354 .grouped_expression,
355 .builtin_call_two,
356 .builtin_call_two_comma,
357 .builtin_call,
358 .builtin_call_comma,
359 .error_set_decl,
360 .@"anytype",
361 .@"comptime",
362 .@"nosuspend",
363 .asm_simple,
364 .@"asm",
365 .array_type,
366 .array_type_sentinel,
367 .error_value,
368 => return main_tokens[n] - end_offset,
369
370 .array_init_dot,
371 .array_init_dot_comma,
372 .array_init_dot_two,
373 .array_init_dot_two_comma,
374 .struct_init_dot,
375 .struct_init_dot_comma,
376 .struct_init_dot_two,
377 .struct_init_dot_two_comma,
378 .enum_literal,
379 => return main_tokens[n] - 1 - end_offset,
380
381 .@"catch",
382 .field_access,
383 .unwrap_optional,
384 .equal_equal,
385 .bang_equal,
386 .less_than,
387 .greater_than,
388 .less_or_equal,
389 .greater_or_equal,
390 .assign_mul,
391 .assign_div,
392 .assign_mod,
393 .assign_add,
394 .assign_sub,
395 .assign_bit_shift_left,
396 .assign_bit_shift_right,
397 .assign_bit_and,
398 .assign_bit_xor,
399 .assign_bit_or,
400 .assign_mul_wrap,
401 .assign_add_wrap,
402 .assign_sub_wrap,
403 .assign,
404 .merge_error_sets,
405 .mul,
406 .div,
407 .mod,
408 .array_mult,
409 .mul_wrap,
410 .add,
411 .sub,
412 .array_cat,
413 .add_wrap,
414 .sub_wrap,
415 .bit_shift_left,
416 .bit_shift_right,
417 .bit_and,
418 .bit_xor,
419 .bit_or,
420 .@"orelse",
421 .bool_and,
422 .bool_or,
423 .slice_open,
424 .slice,
425 .slice_sentinel,
426 .deref,
427 .array_access,
428 .array_init_one,
429 .array_init_one_comma,
430 .array_init,
431 .array_init_comma,
432 .struct_init_one,
433 .struct_init_one_comma,
434 .struct_init,
435 .struct_init_comma,
436 .call_one,
437 .call_one_comma,
438 .call,
439 .call_comma,
440 .switch_range,
441 .error_union,
442 => n = datas[n].lhs,
443
444 .fn_decl,
445 .fn_proto_simple,
446 .fn_proto_multi,
447 .fn_proto_one,
448 .fn_proto,
449 => {
450 var i = main_tokens[n]; // fn token
451 while (i > 0) {
452 i -= 1;
453 switch (token_tags[i]) {
454 .keyword_extern,
455 .keyword_export,
456 .keyword_pub,
457 .keyword_inline,
458 .keyword_noinline,
459 .string_literal,
460 => continue,
461
462 else => return i + 1 - end_offset,
463 }
464 }
465 return i - end_offset;
466 },
467
468 .@"usingnamespace" => {
469 const main_token = main_tokens[n];
470 if (main_token > 0 and token_tags[main_token - 1] == .keyword_pub) {
471 end_offset += 1;
472 }
473 return main_token - end_offset;
474 },
475
476 .async_call_one,
477 .async_call_one_comma,
478 .async_call,
479 .async_call_comma,
480 => {
481 end_offset += 1; // async token
482 n = datas[n].lhs;
483 },
484
485 .container_field_init,
486 .container_field_align,
487 .container_field,
488 => {
489 const name_token = main_tokens[n];
490 if (name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) {
491 end_offset += 1;
492 }
493 return name_token - end_offset;
494 },
495
496 .global_var_decl,
497 .local_var_decl,
498 .simple_var_decl,
499 .aligned_var_decl,
500 => {
501 var i = main_tokens[n]; // mut token
502 while (i > 0) {
503 i -= 1;
504 switch (token_tags[i]) {
505 .keyword_extern,
506 .keyword_export,
507 .keyword_comptime,
508 .keyword_pub,
509 .keyword_threadlocal,
510 .string_literal,
511 => continue,
512
513 else => return i + 1 - end_offset,
514 }
515 }
516 return i - end_offset;
517 },
518
519 .block,
520 .block_semicolon,
521 .block_two,
522 .block_two_semicolon,
523 => {
524 // Look for a label.
525 const lbrace = main_tokens[n];
526 if (token_tags[lbrace - 1] == .colon and
527 token_tags[lbrace - 2] == .identifier)
528 {
529 end_offset += 2;
530 }
531 return lbrace - end_offset;
532 },
533
534 .container_decl,
535 .container_decl_trailing,
536 .container_decl_two,
537 .container_decl_two_trailing,
538 .container_decl_arg,
539 .container_decl_arg_trailing,
540 .tagged_union,
541 .tagged_union_trailing,
542 .tagged_union_two,
543 .tagged_union_two_trailing,
544 .tagged_union_enum_tag,
545 .tagged_union_enum_tag_trailing,
546 => {
547 const main_token = main_tokens[n];
548 switch (token_tags[main_token - 1]) {
549 .keyword_packed, .keyword_extern => end_offset += 1,
550 else => {},
551 }
552 return main_token - end_offset;
553 },
554
555 .ptr_type_aligned,
556 .ptr_type_sentinel,
557 .ptr_type,
558 .ptr_type_bit_range,
559 => {
560 const main_token = main_tokens[n];
561 return switch (token_tags[main_token]) {
562 .asterisk,
563 .asterisk_asterisk,
564 => switch (token_tags[main_token - 1]) {
565 .l_bracket => main_token - 1,
566 else => main_token,
567 },
568 .l_bracket => main_token,
569 else => unreachable,
570 } - end_offset;
571 },
572
573 .switch_case_one => {
574 if (datas[n].lhs == 0) {
575 return main_tokens[n] - 1 - end_offset; // else token
576 } else {
577 n = datas[n].lhs;
578 }
579 },
580 .switch_case => {
581 const extra = tree.extraData(datas[n].lhs, Node.SubRange);
582 assert(extra.end - extra.start > 0);
583 n = tree.extra_data[extra.start];
584 },
585
586 .asm_output, .asm_input => {
587 assert(token_tags[main_tokens[n] - 1] == .l_bracket);
588 return main_tokens[n] - 1 - end_offset;
589 },
590
591 .while_simple,
592 .while_cont,
593 .@"while",
594 .for_simple,
595 .@"for",
596 => {
597 // Look for a label and inline.
598 const main_token = main_tokens[n];
599 var result = main_token;
600 if (token_tags[result - 1] == .keyword_inline) {
601 result -= 1;
602 }
603 if (token_tags[result - 1] == .colon) {
604 result -= 2;
605 }
606 return result - end_offset;
607 },
608 };
609}
610
611pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex {
612 const tags = tree.nodes.items(.tag);
613 const datas = tree.nodes.items(.data);
614 const main_tokens = tree.nodes.items(.main_token);
615 const token_starts = tree.tokens.items(.start);
616 const token_tags = tree.tokens.items(.tag);
617 var n = node;
618 var end_offset: TokenIndex = 0;
619 while (true) switch (tags[n]) {
620 .root => return @intCast(TokenIndex, tree.tokens.len - 1),
621
622 .@"usingnamespace",
623 .bool_not,
624 .negation,
625 .bit_not,
626 .negation_wrap,
627 .address_of,
628 .@"try",
629 .@"await",
630 .optional_type,
631 .@"resume",
632 .@"nosuspend",
633 .@"comptime",
634 => n = datas[n].lhs,
635
636 .test_decl,
637 .@"errdefer",
638 .@"defer",
639 .@"catch",
640 .equal_equal,
641 .bang_equal,
642 .less_than,
643 .greater_than,
644 .less_or_equal,
645 .greater_or_equal,
646 .assign_mul,
647 .assign_div,
648 .assign_mod,
649 .assign_add,
650 .assign_sub,
651 .assign_bit_shift_left,
652 .assign_bit_shift_right,
653 .assign_bit_and,
654 .assign_bit_xor,
655 .assign_bit_or,
656 .assign_mul_wrap,
657 .assign_add_wrap,
658 .assign_sub_wrap,
659 .assign,
660 .merge_error_sets,
661 .mul,
662 .div,
663 .mod,
664 .array_mult,
665 .mul_wrap,
666 .add,
667 .sub,
668 .array_cat,
669 .add_wrap,
670 .sub_wrap,
671 .bit_shift_left,
672 .bit_shift_right,
673 .bit_and,
674 .bit_xor,
675 .bit_or,
676 .@"orelse",
677 .bool_and,
678 .bool_or,
679 .anyframe_type,
680 .error_union,
681 .if_simple,
682 .while_simple,
683 .for_simple,
684 .fn_proto_simple,
685 .fn_proto_multi,
686 .ptr_type_aligned,
687 .ptr_type_sentinel,
688 .ptr_type,
689 .ptr_type_bit_range,
690 .array_type,
691 .switch_case_one,
692 .switch_case,
693 .switch_range,
694 => n = datas[n].rhs,
695
696 .field_access,
697 .unwrap_optional,
698 .grouped_expression,
699 .multiline_string_literal,
700 .error_set_decl,
701 .asm_simple,
702 .asm_output,
703 .asm_input,
704 .error_value,
705 => return datas[n].rhs + end_offset,
706
707 .@"anytype",
708 .anyframe_literal,
709 .char_literal,
710 .integer_literal,
711 .float_literal,
712 .unreachable_literal,
713 .identifier,
714 .deref,
715 .enum_literal,
716 .string_literal,
717 => return main_tokens[n] + end_offset,
718
719 .@"return" => if (datas[n].lhs != 0) {
720 n = datas[n].lhs;
721 } else {
722 return main_tokens[n] + end_offset;
723 },
724
725 .call, .async_call => {
726 end_offset += 1; // for the rparen
727 const params = tree.extraData(datas[n].rhs, Node.SubRange);
728 if (params.end - params.start == 0) {
729 return main_tokens[n] + end_offset;
730 }
731 n = tree.extra_data[params.end - 1]; // last parameter
732 },
733 .tagged_union_enum_tag => {
734 const members = tree.extraData(datas[n].rhs, Node.SubRange);
735 if (members.end - members.start == 0) {
736 end_offset += 4; // for the rparen + rparen + lbrace + rbrace
737 n = datas[n].lhs;
738 } else {
739 end_offset += 1; // for the rbrace
740 n = tree.extra_data[members.end - 1]; // last parameter
741 }
742 },
743 .call_comma,
744 .async_call_comma,
745 .tagged_union_enum_tag_trailing,
746 => {
747 end_offset += 2; // for the comma/semicolon + rparen/rbrace
748 const params = tree.extraData(datas[n].rhs, Node.SubRange);
749 assert(params.end > params.start);
750 n = tree.extra_data[params.end - 1]; // last parameter
751 },
752 .@"switch" => {
753 const cases = tree.extraData(datas[n].rhs, Node.SubRange);
754 if (cases.end - cases.start == 0) {
755 end_offset += 3; // rparen, lbrace, rbrace
756 n = datas[n].lhs; // condition expression
757 } else {
758 end_offset += 1; // for the rbrace
759 n = tree.extra_data[cases.end - 1]; // last case
760 }
761 },
762 .container_decl_arg => {
763 const members = tree.extraData(datas[n].rhs, Node.SubRange);
764 if (members.end - members.start == 0) {
765 end_offset += 3; // for the rparen + lbrace + rbrace
766 n = datas[n].lhs;
767 } else {
768 end_offset += 1; // for the rbrace
769 n = tree.extra_data[members.end - 1]; // last parameter
770 }
771 },
772 .@"asm" => {
773 const extra = tree.extraData(datas[n].rhs, Node.Asm);
774 return extra.rparen + end_offset;
775 },
776 .array_init,
777 .struct_init,
778 => {
779 const elements = tree.extraData(datas[n].rhs, Node.SubRange);
780 assert(elements.end - elements.start > 0);
781 end_offset += 1; // for the rbrace
782 n = tree.extra_data[elements.end - 1]; // last element
783 },
784 .array_init_comma,
785 .struct_init_comma,
786 .container_decl_arg_trailing,
787 .switch_comma,
788 => {
789 const members = tree.extraData(datas[n].rhs, Node.SubRange);
790 assert(members.end - members.start > 0);
791 end_offset += 2; // for the comma + rbrace
792 n = tree.extra_data[members.end - 1]; // last parameter
793 },
794 .array_init_dot,
795 .struct_init_dot,
796 .block,
797 .container_decl,
798 .tagged_union,
799 .builtin_call,
800 => {
801 assert(datas[n].rhs - datas[n].lhs > 0);
802 end_offset += 1; // for the rbrace
803 n = tree.extra_data[datas[n].rhs - 1]; // last statement
804 },
805 .array_init_dot_comma,
806 .struct_init_dot_comma,
807 .block_semicolon,
808 .container_decl_trailing,
809 .tagged_union_trailing,
810 .builtin_call_comma,
811 => {
812 assert(datas[n].rhs - datas[n].lhs > 0);
813 end_offset += 2; // for the comma/semicolon + rbrace/rparen
814 n = tree.extra_data[datas[n].rhs - 1]; // last member
815 },
816 .call_one,
817 .async_call_one,
818 .array_access,
819 => {
820 end_offset += 1; // for the rparen/rbracket
821 if (datas[n].rhs == 0) {
822 return main_tokens[n] + end_offset;
823 }
824 n = datas[n].rhs;
825 },
826 .array_init_dot_two,
827 .block_two,
828 .builtin_call_two,
829 .struct_init_dot_two,
830 .container_decl_two,
831 .tagged_union_two,
832 => {
833 if (datas[n].rhs != 0) {
834 end_offset += 1; // for the rparen/rbrace
835 n = datas[n].rhs;
836 } else if (datas[n].lhs != 0) {
837 end_offset += 1; // for the rparen/rbrace
838 n = datas[n].lhs;
839 } else {
840 switch (tags[n]) {
841 .array_init_dot_two,
842 .block_two,
843 .struct_init_dot_two,
844 => end_offset += 1, // rbrace
845 .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace
846 .container_decl_two => {
847 var i: u32 = 2; // lbrace + rbrace
848 while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1;
849 end_offset += i;
850 },
851 .tagged_union_two => {
852 var i: u32 = 5; // (enum) {}
853 while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1;
854 end_offset += i;
855 },
856 else => unreachable,
857 }
858 return main_tokens[n] + end_offset;
859 }
860 },
861 .array_init_dot_two_comma,
862 .builtin_call_two_comma,
863 .block_two_semicolon,
864 .struct_init_dot_two_comma,
865 .container_decl_two_trailing,
866 .tagged_union_two_trailing,
867 => {
868 end_offset += 2; // for the comma/semicolon + rbrace/rparen
869 if (datas[n].rhs != 0) {
870 n = datas[n].rhs;
871 } else if (datas[n].lhs != 0) {
872 n = datas[n].lhs;
873 } else {
874 unreachable;
875 }
876 },
877 .simple_var_decl => {
878 if (datas[n].rhs != 0) {
879 n = datas[n].rhs;
880 } else if (datas[n].lhs != 0) {
881 n = datas[n].lhs;
882 } else {
883 end_offset += 1; // from mut token to name
884 return main_tokens[n] + end_offset;
885 }
886 },
887 .aligned_var_decl => {
888 if (datas[n].rhs != 0) {
889 n = datas[n].rhs;
890 } else if (datas[n].lhs != 0) {
891 end_offset += 1; // for the rparen
892 n = datas[n].lhs;
893 } else {
894 end_offset += 1; // from mut token to name
895 return main_tokens[n] + end_offset;
896 }
897 },
898 .global_var_decl => {
899 if (datas[n].rhs != 0) {
900 n = datas[n].rhs;
901 } else {
902 const extra = tree.extraData(datas[n].lhs, Node.GlobalVarDecl);
903 if (extra.section_node != 0) {
904 end_offset += 1; // for the rparen
905 n = extra.section_node;
906 } else if (extra.align_node != 0) {
907 end_offset += 1; // for the rparen
908 n = extra.align_node;
909 } else if (extra.type_node != 0) {
910 n = extra.type_node;
911 } else {
912 end_offset += 1; // from mut token to name
913 return main_tokens[n] + end_offset;
914 }
915 }
916 },
917 .local_var_decl => {
918 if (datas[n].rhs != 0) {
919 n = datas[n].rhs;
920 } else {
921 const extra = tree.extraData(datas[n].lhs, Node.LocalVarDecl);
922 if (extra.align_node != 0) {
923 end_offset += 1; // for the rparen
924 n = extra.align_node;
925 } else if (extra.type_node != 0) {
926 n = extra.type_node;
927 } else {
928 end_offset += 1; // from mut token to name
929 return main_tokens[n] + end_offset;
930 }
931 }
932 },
933 .container_field_init => {
934 if (datas[n].rhs != 0) {
935 n = datas[n].rhs;
936 } else if (datas[n].lhs != 0) {
937 n = datas[n].lhs;
938 } else {
939 return main_tokens[n] + end_offset;
940 }
941 },
942 .container_field_align => {
943 if (datas[n].rhs != 0) {
944 end_offset += 1; // for the rparen
945 n = datas[n].rhs;
946 } else if (datas[n].lhs != 0) {
947 n = datas[n].lhs;
948 } else {
949 return main_tokens[n] + end_offset;
950 }
951 },
952 .container_field => {
953 const extra = tree.extraData(datas[n].rhs, Node.ContainerField);
954 if (extra.value_expr != 0) {
955 n = extra.value_expr;
956 } else if (extra.align_expr != 0) {
957 end_offset += 1; // for the rparen
958 n = extra.align_expr;
959 } else if (datas[n].lhs != 0) {
960 n = datas[n].lhs;
961 } else {
962 return main_tokens[n] + end_offset;
963 }
964 },
965
966 .array_init_one,
967 .struct_init_one,
968 => {
969 end_offset += 1; // rbrace
970 if (datas[n].rhs == 0) {
971 return main_tokens[n] + end_offset;
972 } else {
973 n = datas[n].rhs;
974 }
975 },
976 .slice_open,
977 .call_one_comma,
978 .async_call_one_comma,
979 .array_init_one_comma,
980 .struct_init_one_comma,
981 => {
982 end_offset += 2; // ellipsis2 + rbracket, or comma + rparen
983 n = datas[n].rhs;
984 assert(n != 0);
985 },
986 .slice => {
987 const extra = tree.extraData(datas[n].rhs, Node.Slice);
988 assert(extra.end != 0); // should have used slice_open
989 end_offset += 1; // rbracket
990 n = extra.end;
991 },
992 .slice_sentinel => {
993 const extra = tree.extraData(datas[n].rhs, Node.SliceSentinel);
994 assert(extra.sentinel != 0); // should have used slice
995 end_offset += 1; // rbracket
996 n = extra.sentinel;
997 },
998
999 .@"continue" => {
1000 if (datas[n].lhs != 0) {
1001 return datas[n].lhs + end_offset;
1002 } else {
1003 return main_tokens[n] + end_offset;
1004 }
1005 },
1006 .@"break" => {
1007 if (datas[n].rhs != 0) {
1008 n = datas[n].rhs;
1009 } else if (datas[n].lhs != 0) {
1010 return datas[n].lhs + end_offset;
1011 } else {
1012 return main_tokens[n] + end_offset;
1013 }
1014 },
1015 .fn_decl => {
1016 if (datas[n].rhs != 0) {
1017 n = datas[n].rhs;
1018 } else {
1019 n = datas[n].lhs;
1020 }
1021 },
1022 .fn_proto_one => {
1023 const extra = tree.extraData(datas[n].lhs, Node.FnProtoOne);
1024 // linksection, callconv, align can appear in any order, so we
1025 // find the last one here.
1026 var max_node: Node.Index = datas[n].rhs;
1027 var max_start = token_starts[main_tokens[max_node]];
1028 var max_offset: TokenIndex = 0;
1029 if (extra.align_expr != 0) {
1030 const start = token_starts[main_tokens[extra.align_expr]];
1031 if (start > max_start) {
1032 max_node = extra.align_expr;
1033 max_start = start;
1034 max_offset = 1; // for the rparen
1035 }
1036 }
1037 if (extra.section_expr != 0) {
1038 const start = token_starts[main_tokens[extra.section_expr]];
1039 if (start > max_start) {
1040 max_node = extra.section_expr;
1041 max_start = start;
1042 max_offset = 1; // for the rparen
1043 }
1044 }
1045 if (extra.callconv_expr != 0) {
1046 const start = token_starts[main_tokens[extra.callconv_expr]];
1047 if (start > max_start) {
1048 max_node = extra.callconv_expr;
1049 max_start = start;
1050 max_offset = 1; // for the rparen
1051 }
1052 }
1053 n = max_node;
1054 end_offset += max_offset;
1055 },
1056 .fn_proto => {
1057 const extra = tree.extraData(datas[n].lhs, Node.FnProto);
1058 // linksection, callconv, align can appear in any order, so we
1059 // find the last one here.
1060 var max_node: Node.Index = datas[n].rhs;
1061 var max_start = token_starts[main_tokens[max_node]];
1062 var max_offset: TokenIndex = 0;
1063 if (extra.align_expr != 0) {
1064 const start = token_starts[main_tokens[extra.align_expr]];
1065 if (start > max_start) {
1066 max_node = extra.align_expr;
1067 max_start = start;
1068 max_offset = 1; // for the rparen
1069 }
1070 }
1071 if (extra.section_expr != 0) {
1072 const start = token_starts[main_tokens[extra.section_expr]];
1073 if (start > max_start) {
1074 max_node = extra.section_expr;
1075 max_start = start;
1076 max_offset = 1; // for the rparen
1077 }
1078 }
1079 if (extra.callconv_expr != 0) {
1080 const start = token_starts[main_tokens[extra.callconv_expr]];
1081 if (start > max_start) {
1082 max_node = extra.callconv_expr;
1083 max_start = start;
1084 max_offset = 1; // for the rparen
1085 }
1086 }
1087 n = max_node;
1088 end_offset += max_offset;
1089 },
1090 .while_cont => {
1091 const extra = tree.extraData(datas[n].rhs, Node.WhileCont);
1092 assert(extra.then_expr != 0);
1093 n = extra.then_expr;
1094 },
1095 .@"while" => {
1096 const extra = tree.extraData(datas[n].rhs, Node.While);
1097 assert(extra.else_expr != 0);
1098 n = extra.else_expr;
1099 },
1100 .@"if", .@"for" => {
1101 const extra = tree.extraData(datas[n].rhs, Node.If);
1102 assert(extra.else_expr != 0);
1103 n = extra.else_expr;
1104 },
1105 .@"suspend" => {
1106 if (datas[n].lhs != 0) {
1107 n = datas[n].lhs;
1108 } else {
1109 return main_tokens[n] + end_offset;
1110 }
1111 },
1112 .array_type_sentinel => {
1113 const extra = tree.extraData(datas[n].rhs, Node.ArrayTypeSentinel);
1114 n = extra.elem_type;
1115 },
1116 };
1117}
1118
1119pub fn tokensOnSameLine(tree: Tree, token1: TokenIndex, token2: TokenIndex) bool {
1120 const token_starts = tree.tokens.items(.start);
1121 const source = tree.source[token_starts[token1]..token_starts[token2]];
1122 return mem.indexOfScalar(u8, source, '\n') == null;
1123}
1124
1125pub fn getNodeSource(tree: Tree, node: Node.Index) []const u8 {
1126 const token_starts = tree.tokens.items(.start);
1127 const first_token = tree.firstToken(node);
1128 const last_token = tree.lastToken(node);
1129 const start = token_starts[first_token];
1130 const end = token_starts[last_token] + tree.tokenSlice(last_token).len;
1131 return tree.source[start..end];
1132}
1133
1134pub fn globalVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1135 assert(tree.nodes.items(.tag)[node] == .global_var_decl);
1136 const data = tree.nodes.items(.data)[node];
1137 const extra = tree.extraData(data.lhs, Node.GlobalVarDecl);
1138 return tree.fullVarDecl(.{
1139 .type_node = extra.type_node,
1140 .align_node = extra.align_node,
1141 .section_node = extra.section_node,
1142 .init_node = data.rhs,
1143 .mut_token = tree.nodes.items(.main_token)[node],
1144 });
1145}
1146
1147pub fn localVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1148 assert(tree.nodes.items(.tag)[node] == .local_var_decl);
1149 const data = tree.nodes.items(.data)[node];
1150 const extra = tree.extraData(data.lhs, Node.LocalVarDecl);
1151 return tree.fullVarDecl(.{
1152 .type_node = extra.type_node,
1153 .align_node = extra.align_node,
1154 .section_node = 0,
1155 .init_node = data.rhs,
1156 .mut_token = tree.nodes.items(.main_token)[node],
1157 });
1158}
1159
1160pub fn simpleVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1161 assert(tree.nodes.items(.tag)[node] == .simple_var_decl);
1162 const data = tree.nodes.items(.data)[node];
1163 return tree.fullVarDecl(.{
1164 .type_node = data.lhs,
1165 .align_node = 0,
1166 .section_node = 0,
1167 .init_node = data.rhs,
1168 .mut_token = tree.nodes.items(.main_token)[node],
1169 });
1170}
1171
1172pub fn alignedVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1173 assert(tree.nodes.items(.tag)[node] == .aligned_var_decl);
1174 const data = tree.nodes.items(.data)[node];
1175 return tree.fullVarDecl(.{
1176 .type_node = 0,
1177 .align_node = data.lhs,
1178 .section_node = 0,
1179 .init_node = data.rhs,
1180 .mut_token = tree.nodes.items(.main_token)[node],
1181 });
1182}
1183
1184pub fn ifSimple(tree: Tree, node: Node.Index) full.If {
1185 assert(tree.nodes.items(.tag)[node] == .if_simple);
1186 const data = tree.nodes.items(.data)[node];
1187 return tree.fullIf(.{
1188 .cond_expr = data.lhs,
1189 .then_expr = data.rhs,
1190 .else_expr = 0,
1191 .if_token = tree.nodes.items(.main_token)[node],
1192 });
1193}
1194
1195pub fn ifFull(tree: Tree, node: Node.Index) full.If {
1196 assert(tree.nodes.items(.tag)[node] == .@"if");
1197 const data = tree.nodes.items(.data)[node];
1198 const extra = tree.extraData(data.rhs, Node.If);
1199 return tree.fullIf(.{
1200 .cond_expr = data.lhs,
1201 .then_expr = extra.then_expr,
1202 .else_expr = extra.else_expr,
1203 .if_token = tree.nodes.items(.main_token)[node],
1204 });
1205}
1206
1207pub fn containerField(tree: Tree, node: Node.Index) full.ContainerField {
1208 assert(tree.nodes.items(.tag)[node] == .container_field);
1209 const data = tree.nodes.items(.data)[node];
1210 const extra = tree.extraData(data.rhs, Node.ContainerField);
1211 return tree.fullContainerField(.{
1212 .name_token = tree.nodes.items(.main_token)[node],
1213 .type_expr = data.lhs,
1214 .value_expr = extra.value_expr,
1215 .align_expr = extra.align_expr,
1216 });
1217}
1218
1219pub fn containerFieldInit(tree: Tree, node: Node.Index) full.ContainerField {
1220 assert(tree.nodes.items(.tag)[node] == .container_field_init);
1221 const data = tree.nodes.items(.data)[node];
1222 return tree.fullContainerField(.{
1223 .name_token = tree.nodes.items(.main_token)[node],
1224 .type_expr = data.lhs,
1225 .value_expr = data.rhs,
1226 .align_expr = 0,
1227 });
1228}
1229
1230pub fn containerFieldAlign(tree: Tree, node: Node.Index) full.ContainerField {
1231 assert(tree.nodes.items(.tag)[node] == .container_field_align);
1232 const data = tree.nodes.items(.data)[node];
1233 return tree.fullContainerField(.{
1234 .name_token = tree.nodes.items(.main_token)[node],
1235 .type_expr = data.lhs,
1236 .value_expr = 0,
1237 .align_expr = data.rhs,
1238 });
1239}
1240
1241pub fn fnProtoSimple(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
1242 assert(tree.nodes.items(.tag)[node] == .fn_proto_simple);
1243 const data = tree.nodes.items(.data)[node];
1244 buffer[0] = data.lhs;
1245 const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1];
1246 return tree.fullFnProto(.{
1247 .proto_node = node,
1248 .fn_token = tree.nodes.items(.main_token)[node],
1249 .return_type = data.rhs,
1250 .params = params,
1251 .align_expr = 0,
1252 .section_expr = 0,
1253 .callconv_expr = 0,
1254 });
1255}
1256
1257pub fn fnProtoMulti(tree: Tree, node: Node.Index) full.FnProto {
1258 assert(tree.nodes.items(.tag)[node] == .fn_proto_multi);
1259 const data = tree.nodes.items(.data)[node];
1260 const params_range = tree.extraData(data.lhs, Node.SubRange);
1261 const params = tree.extra_data[params_range.start..params_range.end];
1262 return tree.fullFnProto(.{
1263 .proto_node = node,
1264 .fn_token = tree.nodes.items(.main_token)[node],
1265 .return_type = data.rhs,
1266 .params = params,
1267 .align_expr = 0,
1268 .section_expr = 0,
1269 .callconv_expr = 0,
1270 });
1271}
1272
1273pub fn fnProtoOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
1274 assert(tree.nodes.items(.tag)[node] == .fn_proto_one);
1275 const data = tree.nodes.items(.data)[node];
1276 const extra = tree.extraData(data.lhs, Node.FnProtoOne);
1277 buffer[0] = extra.param;
1278 const params = if (extra.param == 0) buffer[0..0] else buffer[0..1];
1279 return tree.fullFnProto(.{
1280 .proto_node = node,
1281 .fn_token = tree.nodes.items(.main_token)[node],
1282 .return_type = data.rhs,
1283 .params = params,
1284 .align_expr = extra.align_expr,
1285 .section_expr = extra.section_expr,
1286 .callconv_expr = extra.callconv_expr,
1287 });
1288}
1289
1290pub fn fnProto(tree: Tree, node: Node.Index) full.FnProto {
1291 assert(tree.nodes.items(.tag)[node] == .fn_proto);
1292 const data = tree.nodes.items(.data)[node];
1293 const extra = tree.extraData(data.lhs, Node.FnProto);
1294 const params = tree.extra_data[extra.params_start..extra.params_end];
1295 return tree.fullFnProto(.{
1296 .proto_node = node,
1297 .fn_token = tree.nodes.items(.main_token)[node],
1298 .return_type = data.rhs,
1299 .params = params,
1300 .align_expr = extra.align_expr,
1301 .section_expr = extra.section_expr,
1302 .callconv_expr = extra.callconv_expr,
1303 });
1304}
1305
1306pub fn structInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.StructInit {
1307 assert(tree.nodes.items(.tag)[node] == .struct_init_one or
1308 tree.nodes.items(.tag)[node] == .struct_init_one_comma);
1309 const data = tree.nodes.items(.data)[node];
1310 buffer[0] = data.rhs;
1311 const fields = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
1312 return tree.fullStructInit(.{
1313 .lbrace = tree.nodes.items(.main_token)[node],
1314 .fields = fields,
1315 .type_expr = data.lhs,
1316 });
1317}
1318
1319pub fn structInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.StructInit {
1320 assert(tree.nodes.items(.tag)[node] == .struct_init_dot_two or
1321 tree.nodes.items(.tag)[node] == .struct_init_dot_two_comma);
1322 const data = tree.nodes.items(.data)[node];
1323 buffer.* = .{ data.lhs, data.rhs };
1324 const fields = if (data.rhs != 0)
1325 buffer[0..2]
1326 else if (data.lhs != 0)
1327 buffer[0..1]
1328 else
1329 buffer[0..0];
1330 return tree.fullStructInit(.{
1331 .lbrace = tree.nodes.items(.main_token)[node],
1332 .fields = fields,
1333 .type_expr = 0,
1334 });
1335}
1336
1337pub fn structInitDot(tree: Tree, node: Node.Index) full.StructInit {
1338 assert(tree.nodes.items(.tag)[node] == .struct_init_dot or
1339 tree.nodes.items(.tag)[node] == .struct_init_dot_comma);
1340 const data = tree.nodes.items(.data)[node];
1341 return tree.fullStructInit(.{
1342 .lbrace = tree.nodes.items(.main_token)[node],
1343 .fields = tree.extra_data[data.lhs..data.rhs],
1344 .type_expr = 0,
1345 });
1346}
1347
1348pub fn structInit(tree: Tree, node: Node.Index) full.StructInit {
1349 assert(tree.nodes.items(.tag)[node] == .struct_init or
1350 tree.nodes.items(.tag)[node] == .struct_init_comma);
1351 const data = tree.nodes.items(.data)[node];
1352 const fields_range = tree.extraData(data.rhs, Node.SubRange);
1353 return tree.fullStructInit(.{
1354 .lbrace = tree.nodes.items(.main_token)[node],
1355 .fields = tree.extra_data[fields_range.start..fields_range.end],
1356 .type_expr = data.lhs,
1357 });
1358}
1359
1360pub fn arrayInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit {
1361 assert(tree.nodes.items(.tag)[node] == .array_init_one or
1362 tree.nodes.items(.tag)[node] == .array_init_one_comma);
1363 const data = tree.nodes.items(.data)[node];
1364 buffer[0] = data.rhs;
1365 const elements = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
1366 return .{
1367 .ast = .{
1368 .lbrace = tree.nodes.items(.main_token)[node],
1369 .elements = elements,
1370 .type_expr = data.lhs,
1371 },
1372 };
1373}
1374
1375pub fn arrayInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit {
1376 assert(tree.nodes.items(.tag)[node] == .array_init_dot_two or
1377 tree.nodes.items(.tag)[node] == .array_init_dot_two_comma);
1378 const data = tree.nodes.items(.data)[node];
1379 buffer.* = .{ data.lhs, data.rhs };
1380 const elements = if (data.rhs != 0)
1381 buffer[0..2]
1382 else if (data.lhs != 0)
1383 buffer[0..1]
1384 else
1385 buffer[0..0];
1386 return .{
1387 .ast = .{
1388 .lbrace = tree.nodes.items(.main_token)[node],
1389 .elements = elements,
1390 .type_expr = 0,
1391 },
1392 };
1393}
1394
1395pub fn arrayInitDot(tree: Tree, node: Node.Index) full.ArrayInit {
1396 assert(tree.nodes.items(.tag)[node] == .array_init_dot or
1397 tree.nodes.items(.tag)[node] == .array_init_dot_comma);
1398 const data = tree.nodes.items(.data)[node];
1399 return .{
1400 .ast = .{
1401 .lbrace = tree.nodes.items(.main_token)[node],
1402 .elements = tree.extra_data[data.lhs..data.rhs],
1403 .type_expr = 0,
1404 },
1405 };
1406}
1407
1408pub fn arrayInit(tree: Tree, node: Node.Index) full.ArrayInit {
1409 assert(tree.nodes.items(.tag)[node] == .array_init or
1410 tree.nodes.items(.tag)[node] == .array_init_comma);
1411 const data = tree.nodes.items(.data)[node];
1412 const elem_range = tree.extraData(data.rhs, Node.SubRange);
1413 return .{
1414 .ast = .{
1415 .lbrace = tree.nodes.items(.main_token)[node],
1416 .elements = tree.extra_data[elem_range.start..elem_range.end],
1417 .type_expr = data.lhs,
1418 },
1419 };
1420}
1421
1422pub fn arrayType(tree: Tree, node: Node.Index) full.ArrayType {
1423 assert(tree.nodes.items(.tag)[node] == .array_type);
1424 const data = tree.nodes.items(.data)[node];
1425 return .{
1426 .ast = .{
1427 .lbracket = tree.nodes.items(.main_token)[node],
1428 .elem_count = data.lhs,
1429 .sentinel = 0,
1430 .elem_type = data.rhs,
1431 },
1432 };
1433}
1434
1435pub fn arrayTypeSentinel(tree: Tree, node: Node.Index) full.ArrayType {
1436 assert(tree.nodes.items(.tag)[node] == .array_type_sentinel);
1437 const data = tree.nodes.items(.data)[node];
1438 const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);
1439 assert(extra.sentinel != 0);
1440 return .{
1441 .ast = .{
1442 .lbracket = tree.nodes.items(.main_token)[node],
1443 .elem_count = data.lhs,
1444 .sentinel = extra.sentinel,
1445 .elem_type = extra.elem_type,
1446 },
1447 };
1448}
1449
1450pub fn ptrTypeAligned(tree: Tree, node: Node.Index) full.PtrType {
1451 assert(tree.nodes.items(.tag)[node] == .ptr_type_aligned);
1452 const data = tree.nodes.items(.data)[node];
1453 return tree.fullPtrType(.{
1454 .main_token = tree.nodes.items(.main_token)[node],
1455 .align_node = data.lhs,
1456 .sentinel = 0,
1457 .bit_range_start = 0,
1458 .bit_range_end = 0,
1459 .child_type = data.rhs,
1460 });
1461}
1462
1463pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) full.PtrType {
1464 assert(tree.nodes.items(.tag)[node] == .ptr_type_sentinel);
1465 const data = tree.nodes.items(.data)[node];
1466 return tree.fullPtrType(.{
1467 .main_token = tree.nodes.items(.main_token)[node],
1468 .align_node = 0,
1469 .sentinel = data.lhs,
1470 .bit_range_start = 0,
1471 .bit_range_end = 0,
1472 .child_type = data.rhs,
1473 });
1474}
1475
1476pub fn ptrType(tree: Tree, node: Node.Index) full.PtrType {
1477 assert(tree.nodes.items(.tag)[node] == .ptr_type);
1478 const data = tree.nodes.items(.data)[node];
1479 const extra = tree.extraData(data.lhs, Node.PtrType);
1480 return tree.fullPtrType(.{
1481 .main_token = tree.nodes.items(.main_token)[node],
1482 .align_node = extra.align_node,
1483 .sentinel = extra.sentinel,
1484 .bit_range_start = 0,
1485 .bit_range_end = 0,
1486 .child_type = data.rhs,
1487 });
1488}
1489
1490pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) full.PtrType {
1491 assert(tree.nodes.items(.tag)[node] == .ptr_type_bit_range);
1492 const data = tree.nodes.items(.data)[node];
1493 const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange);
1494 return tree.fullPtrType(.{
1495 .main_token = tree.nodes.items(.main_token)[node],
1496 .align_node = extra.align_node,
1497 .sentinel = extra.sentinel,
1498 .bit_range_start = extra.bit_range_start,
1499 .bit_range_end = extra.bit_range_end,
1500 .child_type = data.rhs,
1501 });
1502}
1503
1504pub fn sliceOpen(tree: Tree, node: Node.Index) full.Slice {
1505 assert(tree.nodes.items(.tag)[node] == .slice_open);
1506 const data = tree.nodes.items(.data)[node];
1507 return .{
1508 .ast = .{
1509 .sliced = data.lhs,
1510 .lbracket = tree.nodes.items(.main_token)[node],
1511 .start = data.rhs,
1512 .end = 0,
1513 .sentinel = 0,
1514 },
1515 };
1516}
1517
1518pub fn slice(tree: Tree, node: Node.Index) full.Slice {
1519 assert(tree.nodes.items(.tag)[node] == .slice);
1520 const data = tree.nodes.items(.data)[node];
1521 const extra = tree.extraData(data.rhs, Node.Slice);
1522 return .{
1523 .ast = .{
1524 .sliced = data.lhs,
1525 .lbracket = tree.nodes.items(.main_token)[node],
1526 .start = extra.start,
1527 .end = extra.end,
1528 .sentinel = 0,
1529 },
1530 };
1531}
1532
1533pub fn sliceSentinel(tree: Tree, node: Node.Index) full.Slice {
1534 assert(tree.nodes.items(.tag)[node] == .slice_sentinel);
1535 const data = tree.nodes.items(.data)[node];
1536 const extra = tree.extraData(data.rhs, Node.SliceSentinel);
1537 return .{
1538 .ast = .{
1539 .sliced = data.lhs,
1540 .lbracket = tree.nodes.items(.main_token)[node],
1541 .start = extra.start,
1542 .end = extra.end,
1543 .sentinel = extra.sentinel,
1544 },
1545 };
1546}
1547
1548pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
1549 assert(tree.nodes.items(.tag)[node] == .container_decl_two or
1550 tree.nodes.items(.tag)[node] == .container_decl_two_trailing);
1551 const data = tree.nodes.items(.data)[node];
1552 buffer.* = .{ data.lhs, data.rhs };
1553 const members = if (data.rhs != 0)
1554 buffer[0..2]
1555 else if (data.lhs != 0)
1556 buffer[0..1]
1557 else
1558 buffer[0..0];
1559 return tree.fullContainerDecl(.{
1560 .main_token = tree.nodes.items(.main_token)[node],
1561 .enum_token = null,
1562 .members = members,
1563 .arg = 0,
1564 });
1565}
1566
1567pub fn containerDecl(tree: Tree, node: Node.Index) full.ContainerDecl {
1568 assert(tree.nodes.items(.tag)[node] == .container_decl or
1569 tree.nodes.items(.tag)[node] == .container_decl_trailing);
1570 const data = tree.nodes.items(.data)[node];
1571 return tree.fullContainerDecl(.{
1572 .main_token = tree.nodes.items(.main_token)[node],
1573 .enum_token = null,
1574 .members = tree.extra_data[data.lhs..data.rhs],
1575 .arg = 0,
1576 });
1577}
1578
1579pub fn containerDeclArg(tree: Tree, node: Node.Index) full.ContainerDecl {
1580 assert(tree.nodes.items(.tag)[node] == .container_decl_arg or
1581 tree.nodes.items(.tag)[node] == .container_decl_arg_trailing);
1582 const data = tree.nodes.items(.data)[node];
1583 const members_range = tree.extraData(data.rhs, Node.SubRange);
1584 return tree.fullContainerDecl(.{
1585 .main_token = tree.nodes.items(.main_token)[node],
1586 .enum_token = null,
1587 .members = tree.extra_data[members_range.start..members_range.end],
1588 .arg = data.lhs,
1589 });
1590}
1591
1592pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
1593 assert(tree.nodes.items(.tag)[node] == .tagged_union_two or
1594 tree.nodes.items(.tag)[node] == .tagged_union_two_trailing);
1595 const data = tree.nodes.items(.data)[node];
1596 buffer.* = .{ data.lhs, data.rhs };
1597 const members = if (data.rhs != 0)
1598 buffer[0..2]
1599 else if (data.lhs != 0)
1600 buffer[0..1]
1601 else
1602 buffer[0..0];
1603 const main_token = tree.nodes.items(.main_token)[node];
1604 return tree.fullContainerDecl(.{
1605 .main_token = main_token,
1606 .enum_token = main_token + 2, // union lparen enum
1607 .members = members,
1608 .arg = 0,
1609 });
1610}
1611
1612pub fn taggedUnion(tree: Tree, node: Node.Index) full.ContainerDecl {
1613 assert(tree.nodes.items(.tag)[node] == .tagged_union or
1614 tree.nodes.items(.tag)[node] == .tagged_union_trailing);
1615 const data = tree.nodes.items(.data)[node];
1616 const main_token = tree.nodes.items(.main_token)[node];
1617 return tree.fullContainerDecl(.{
1618 .main_token = main_token,
1619 .enum_token = main_token + 2, // union lparen enum
1620 .members = tree.extra_data[data.lhs..data.rhs],
1621 .arg = 0,
1622 });
1623}
1624
1625pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) full.ContainerDecl {
1626 assert(tree.nodes.items(.tag)[node] == .tagged_union_enum_tag or
1627 tree.nodes.items(.tag)[node] == .tagged_union_enum_tag_trailing);
1628 const data = tree.nodes.items(.data)[node];
1629 const members_range = tree.extraData(data.rhs, Node.SubRange);
1630 const main_token = tree.nodes.items(.main_token)[node];
1631 return tree.fullContainerDecl(.{
1632 .main_token = main_token,
1633 .enum_token = main_token + 2, // union lparen enum
1634 .members = tree.extra_data[members_range.start..members_range.end],
1635 .arg = data.lhs,
1636 });
1637}
1638
1639pub fn switchCaseOne(tree: Tree, node: Node.Index) full.SwitchCase {
1640 const data = &tree.nodes.items(.data)[node];
1641 const values: *[1]Node.Index = &data.lhs;
1642 return tree.fullSwitchCase(.{
1643 .values = if (data.lhs == 0) values[0..0] else values[0..1],
1644 .arrow_token = tree.nodes.items(.main_token)[node],
1645 .target_expr = data.rhs,
1646 });
1647}
1648
1649pub fn switchCase(tree: Tree, node: Node.Index) full.SwitchCase {
1650 const data = tree.nodes.items(.data)[node];
1651 const extra = tree.extraData(data.lhs, Node.SubRange);
1652 return tree.fullSwitchCase(.{
1653 .values = tree.extra_data[extra.start..extra.end],
1654 .arrow_token = tree.nodes.items(.main_token)[node],
1655 .target_expr = data.rhs,
1656 });
1657}
1658
1659pub fn asmSimple(tree: Tree, node: Node.Index) full.Asm {
1660 const data = tree.nodes.items(.data)[node];
1661 return tree.fullAsm(.{
1662 .asm_token = tree.nodes.items(.main_token)[node],
1663 .template = data.lhs,
1664 .items = &.{},
1665 .rparen = data.rhs,
1666 });
1667}
1668
1669pub fn asmFull(tree: Tree, node: Node.Index) full.Asm {
1670 const data = tree.nodes.items(.data)[node];
1671 const extra = tree.extraData(data.rhs, Node.Asm);
1672 return tree.fullAsm(.{
1673 .asm_token = tree.nodes.items(.main_token)[node],
1674 .template = data.lhs,
1675 .items = tree.extra_data[extra.items_start..extra.items_end],
1676 .rparen = extra.rparen,
1677 });
1678}
1679
1680pub fn whileSimple(tree: Tree, node: Node.Index) full.While {
1681 const data = tree.nodes.items(.data)[node];
1682 return tree.fullWhile(.{
1683 .while_token = tree.nodes.items(.main_token)[node],
1684 .cond_expr = data.lhs,
1685 .cont_expr = 0,
1686 .then_expr = data.rhs,
1687 .else_expr = 0,
1688 });
1689}
1690
1691pub fn whileCont(tree: Tree, node: Node.Index) full.While {
1692 const data = tree.nodes.items(.data)[node];
1693 const extra = tree.extraData(data.rhs, Node.WhileCont);
1694 return tree.fullWhile(.{
1695 .while_token = tree.nodes.items(.main_token)[node],
1696 .cond_expr = data.lhs,
1697 .cont_expr = extra.cont_expr,
1698 .then_expr = extra.then_expr,
1699 .else_expr = 0,
1700 });
1701}
1702
1703pub fn whileFull(tree: Tree, node: Node.Index) full.While {
1704 const data = tree.nodes.items(.data)[node];
1705 const extra = tree.extraData(data.rhs, Node.While);
1706 return tree.fullWhile(.{
1707 .while_token = tree.nodes.items(.main_token)[node],
1708 .cond_expr = data.lhs,
1709 .cont_expr = extra.cont_expr,
1710 .then_expr = extra.then_expr,
1711 .else_expr = extra.else_expr,
1712 });
1713}
1714
1715pub fn forSimple(tree: Tree, node: Node.Index) full.While {
1716 const data = tree.nodes.items(.data)[node];
1717 return tree.fullWhile(.{
1718 .while_token = tree.nodes.items(.main_token)[node],
1719 .cond_expr = data.lhs,
1720 .cont_expr = 0,
1721 .then_expr = data.rhs,
1722 .else_expr = 0,
1723 });
1724}
1725
1726pub fn forFull(tree: Tree, node: Node.Index) full.While {
1727 const data = tree.nodes.items(.data)[node];
1728 const extra = tree.extraData(data.rhs, Node.If);
1729 return tree.fullWhile(.{
1730 .while_token = tree.nodes.items(.main_token)[node],
1731 .cond_expr = data.lhs,
1732 .cont_expr = 0,
1733 .then_expr = extra.then_expr,
1734 .else_expr = extra.else_expr,
1735 });
1736}
1737
1738pub fn callOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.Call {
1739 const data = tree.nodes.items(.data)[node];
1740 buffer.* = .{data.rhs};
1741 const params = if (data.rhs != 0) buffer[0..1] else buffer[0..0];
1742 return tree.fullCall(.{
1743 .lparen = tree.nodes.items(.main_token)[node],
1744 .fn_expr = data.lhs,
1745 .params = params,
1746 });
1747}
1748
1749pub fn callFull(tree: Tree, node: Node.Index) full.Call {
1750 const data = tree.nodes.items(.data)[node];
1751 const extra = tree.extraData(data.rhs, Node.SubRange);
1752 return tree.fullCall(.{
1753 .lparen = tree.nodes.items(.main_token)[node],
1754 .fn_expr = data.lhs,
1755 .params = tree.extra_data[extra.start..extra.end],
1756 });
1757}
1758
1759fn fullVarDecl(tree: Tree, info: full.VarDecl.Components) full.VarDecl {
1760 const token_tags = tree.tokens.items(.tag);
1761 var result: full.VarDecl = .{
1762 .ast = info,
1763 .visib_token = null,
1764 .extern_export_token = null,
1765 .lib_name = null,
1766 .threadlocal_token = null,
1767 .comptime_token = null,
1768 };
1769 var i = info.mut_token;
1770 while (i > 0) {
1771 i -= 1;
1772 switch (token_tags[i]) {
1773 .keyword_extern, .keyword_export => result.extern_export_token = i,
1774 .keyword_comptime => result.comptime_token = i,
1775 .keyword_pub => result.visib_token = i,
1776 .keyword_threadlocal => result.threadlocal_token = i,
1777 .string_literal => result.lib_name = i,
1778 else => break,
1779 }
1780 }
1781 return result;
1782}
1783
1784fn fullIf(tree: Tree, info: full.If.Components) full.If {
1785 const token_tags = tree.tokens.items(.tag);
1786 var result: full.If = .{
1787 .ast = info,
1788 .payload_token = null,
1789 .error_token = null,
1790 .else_token = undefined,
1791 };
1792 // if (cond_expr) |x|
1793 // ^ ^
1794 const payload_pipe = tree.lastToken(info.cond_expr) + 2;
1795 if (token_tags[payload_pipe] == .pipe) {
1796 result.payload_token = payload_pipe + 1;
1797 }
1798 if (info.else_expr != 0) {
1799 // then_expr else |x|
1800 // ^ ^
1801 result.else_token = tree.lastToken(info.then_expr) + 1;
1802 if (token_tags[result.else_token + 1] == .pipe) {
1803 result.error_token = result.else_token + 2;
1804 }
1805 }
1806 return result;
1807}
1808
1809fn fullContainerField(tree: Tree, info: full.ContainerField.Components) full.ContainerField {
1810 const token_tags = tree.tokens.items(.tag);
1811 var result: full.ContainerField = .{
1812 .ast = info,
1813 .comptime_token = null,
1814 };
1815 // comptime name: type = init,
1816 // ^
1817 if (info.name_token > 0 and token_tags[info.name_token - 1] == .keyword_comptime) {
1818 result.comptime_token = info.name_token - 1;
1819 }
1820 return result;
1821}
1822
1823fn fullFnProto(tree: Tree, info: full.FnProto.Components) full.FnProto {
1824 const token_tags = tree.tokens.items(.tag);
1825 var result: full.FnProto = .{
1826 .ast = info,
1827 .visib_token = null,
1828 .extern_export_inline_token = null,
1829 .lib_name = null,
1830 .name_token = null,
1831 .lparen = undefined,
1832 };
1833 var i = info.fn_token;
1834 while (i > 0) {
1835 i -= 1;
1836 switch (token_tags[i]) {
1837 .keyword_extern,
1838 .keyword_export,
1839 .keyword_inline,
1840 .keyword_noinline,
1841 => result.extern_export_inline_token = i,
1842 .keyword_pub => result.visib_token = i,
1843 .string_literal => result.lib_name = i,
1844 else => break,
1845 }
1846 }
1847 const after_fn_token = info.fn_token + 1;
1848 if (token_tags[after_fn_token] == .identifier) {
1849 result.name_token = after_fn_token;
1850 result.lparen = after_fn_token + 1;
1851 } else {
1852 result.lparen = after_fn_token;
1853 }
1854 assert(token_tags[result.lparen] == .l_paren);
1855
1856 return result;
1857}
1858
1859fn fullStructInit(tree: Tree, info: full.StructInit.Components) full.StructInit {
1860 _ = tree;
1861 var result: full.StructInit = .{
1862 .ast = info,
1863 };
1864 return result;
1865}
1866
1867fn fullPtrType(tree: Tree, info: full.PtrType.Components) full.PtrType {
1868 const token_tags = tree.tokens.items(.tag);
1869 // TODO: looks like stage1 isn't quite smart enough to handle enum
1870 // literals in some places here
1871 const Size = std.builtin.TypeInfo.Pointer.Size;
1872 const size: Size = switch (token_tags[info.main_token]) {
1873 .asterisk,
1874 .asterisk_asterisk,
1875 => switch (token_tags[info.main_token + 1]) {
1876 .r_bracket, .colon => .Many,
1877 .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One,
1878 else => .One,
1879 },
1880 .l_bracket => Size.Slice,
1881 else => unreachable,
1882 };
1883 var result: full.PtrType = .{
1884 .size = size,
1885 .allowzero_token = null,
1886 .const_token = null,
1887 .volatile_token = null,
1888 .ast = info,
1889 };
1890 // We need to be careful that we don't iterate over any sub-expressions
1891 // here while looking for modifiers as that could result in false
1892 // positives. Therefore, start after a sentinel if there is one and
1893 // skip over any align node and bit range nodes.
1894 var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else info.main_token;
1895 const end = tree.firstToken(info.child_type);
1896 while (i < end) : (i += 1) {
1897 switch (token_tags[i]) {
1898 .keyword_allowzero => result.allowzero_token = i,
1899 .keyword_const => result.const_token = i,
1900 .keyword_volatile => result.volatile_token = i,
1901 .keyword_align => {
1902 assert(info.align_node != 0);
1903 if (info.bit_range_end != 0) {
1904 assert(info.bit_range_start != 0);
1905 i = tree.lastToken(info.bit_range_end) + 1;
1906 } else {
1907 i = tree.lastToken(info.align_node) + 1;
1908 }
1909 },
1910 else => {},
1911 }
1912 }
1913 return result;
1914}
1915
1916fn fullContainerDecl(tree: Tree, info: full.ContainerDecl.Components) full.ContainerDecl {
1917 const token_tags = tree.tokens.items(.tag);
1918 var result: full.ContainerDecl = .{
1919 .ast = info,
1920 .layout_token = null,
1921 };
1922 switch (token_tags[info.main_token - 1]) {
1923 .keyword_extern, .keyword_packed => result.layout_token = info.main_token - 1,
1924 else => {},
1925 }
1926 return result;
1927}
1928
1929fn fullSwitchCase(tree: Tree, info: full.SwitchCase.Components) full.SwitchCase {
1930 const token_tags = tree.tokens.items(.tag);
1931 var result: full.SwitchCase = .{
1932 .ast = info,
1933 .payload_token = null,
1934 };
1935 if (token_tags[info.arrow_token + 1] == .pipe) {
1936 result.payload_token = info.arrow_token + 2;
1937 }
1938 return result;
1939}
1940
1941fn fullAsm(tree: Tree, info: full.Asm.Components) full.Asm {
1942 const token_tags = tree.tokens.items(.tag);
1943 const node_tags = tree.nodes.items(.tag);
1944 var result: full.Asm = .{
1945 .ast = info,
1946 .volatile_token = null,
1947 .inputs = &.{},
1948 .outputs = &.{},
1949 .first_clobber = null,
1950 };
1951 if (token_tags[info.asm_token + 1] == .keyword_volatile) {
1952 result.volatile_token = info.asm_token + 1;
1953 }
1954 const outputs_end: usize = for (info.items) |item, i| {
1955 switch (node_tags[item]) {
1956 .asm_output => continue,
1957 else => break i,
1958 }
1959 } else info.items.len;
1960
1961 result.outputs = info.items[0..outputs_end];
1962 result.inputs = info.items[outputs_end..];
1963
1964 if (info.items.len == 0) {
1965 // asm ("foo" ::: "a", "b");
1966 const template_token = tree.lastToken(info.template);
1967 if (token_tags[template_token + 1] == .colon and
1968 token_tags[template_token + 2] == .colon and
1969 token_tags[template_token + 3] == .colon and
1970 token_tags[template_token + 4] == .string_literal)
1971 {
1972 result.first_clobber = template_token + 4;
1973 }
1974 } else if (result.inputs.len != 0) {
1975 // asm ("foo" :: [_] "" (y) : "a", "b");
1976 const last_input = result.inputs[result.inputs.len - 1];
1977 const rparen = tree.lastToken(last_input);
1978 var i = rparen + 1;
1979 // Allow a (useless) comma right after the closing parenthesis.
1980 if (token_tags[i] == .comma) i += 1;
1981 if (token_tags[i] == .colon and
1982 token_tags[i + 1] == .string_literal)
1983 {
1984 result.first_clobber = i + 1;
1985 }
1986 } else {
1987 // asm ("foo" : [_] "" (x) :: "a", "b");
1988 const last_output = result.outputs[result.outputs.len - 1];
1989 const rparen = tree.lastToken(last_output);
1990 var i = rparen + 1;
1991 // Allow a (useless) comma right after the closing parenthesis.
1992 if (token_tags[i] == .comma) i += 1;
1993 if (token_tags[i] == .colon and
1994 token_tags[i + 1] == .colon and
1995 token_tags[i + 2] == .string_literal)
1996 {
1997 result.first_clobber = i + 2;
1998 }
1999 }
2000
2001 return result;
2002}
2003
2004fn fullWhile(tree: Tree, info: full.While.Components) full.While {
2005 const token_tags = tree.tokens.items(.tag);
2006 var result: full.While = .{
2007 .ast = info,
2008 .inline_token = null,
2009 .label_token = null,
2010 .payload_token = null,
2011 .else_token = undefined,
2012 .error_token = null,
2013 };
2014 var tok_i = info.while_token - 1;
2015 if (token_tags[tok_i] == .keyword_inline) {
2016 result.inline_token = tok_i;
2017 tok_i -= 1;
2018 }
2019 if (token_tags[tok_i] == .colon and
2020 token_tags[tok_i - 1] == .identifier)
2021 {
2022 result.label_token = tok_i - 1;
2023 }
2024 const last_cond_token = tree.lastToken(info.cond_expr);
2025 if (token_tags[last_cond_token + 2] == .pipe) {
2026 result.payload_token = last_cond_token + 3;
2027 }
2028 if (info.else_expr != 0) {
2029 // then_expr else |x|
2030 // ^ ^
2031 result.else_token = tree.lastToken(info.then_expr) + 1;
2032 if (token_tags[result.else_token + 1] == .pipe) {
2033 result.error_token = result.else_token + 2;
2034 }
2035 }
2036 return result;
2037}
2038
2039fn fullCall(tree: Tree, info: full.Call.Components) full.Call {
2040 const token_tags = tree.tokens.items(.tag);
2041 var result: full.Call = .{
2042 .ast = info,
2043 .async_token = null,
2044 };
2045 const maybe_async_token = tree.firstToken(info.fn_expr) - 1;
2046 if (token_tags[maybe_async_token] == .keyword_async) {
2047 result.async_token = maybe_async_token;
2048 }
2049 return result;
2050}
2051
2052/// Fully assembled AST node information.
2053pub const full = struct {
2054 pub const VarDecl = struct {
2055 visib_token: ?TokenIndex,
2056 extern_export_token: ?TokenIndex,
2057 lib_name: ?TokenIndex,
2058 threadlocal_token: ?TokenIndex,
2059 comptime_token: ?TokenIndex,
2060 ast: Components,
2061
2062 pub const Components = struct {
2063 mut_token: TokenIndex,
2064 type_node: Node.Index,
2065 align_node: Node.Index,
2066 section_node: Node.Index,
2067 init_node: Node.Index,
2068 };
2069 };
2070
2071 pub const If = struct {
2072 /// Points to the first token after the `|`. Will either be an identifier or
2073 /// a `*` (with an identifier immediately after it).
2074 payload_token: ?TokenIndex,
2075 /// Points to the identifier after the `|`.
2076 error_token: ?TokenIndex,
2077 /// Populated only if else_expr != 0.
2078 else_token: TokenIndex,
2079 ast: Components,
2080
2081 pub const Components = struct {
2082 if_token: TokenIndex,
2083 cond_expr: Node.Index,
2084 then_expr: Node.Index,
2085 else_expr: Node.Index,
2086 };
2087 };
2088
2089 pub const While = struct {
2090 ast: Components,
2091 inline_token: ?TokenIndex,
2092 label_token: ?TokenIndex,
2093 payload_token: ?TokenIndex,
2094 error_token: ?TokenIndex,
2095 /// Populated only if else_expr != 0.
2096 else_token: TokenIndex,
2097
2098 pub const Components = struct {
2099 while_token: TokenIndex,
2100 cond_expr: Node.Index,
2101 cont_expr: Node.Index,
2102 then_expr: Node.Index,
2103 else_expr: Node.Index,
2104 };
2105 };
2106
2107 pub const ContainerField = struct {
2108 comptime_token: ?TokenIndex,
2109 ast: Components,
2110
2111 pub const Components = struct {
2112 name_token: TokenIndex,
2113 type_expr: Node.Index,
2114 value_expr: Node.Index,
2115 align_expr: Node.Index,
2116 };
2117 };
2118
2119 pub const FnProto = struct {
2120 visib_token: ?TokenIndex,
2121 extern_export_inline_token: ?TokenIndex,
2122 lib_name: ?TokenIndex,
2123 name_token: ?TokenIndex,
2124 lparen: TokenIndex,
2125 ast: Components,
2126
2127 pub const Components = struct {
2128 proto_node: Node.Index,
2129 fn_token: TokenIndex,
2130 return_type: Node.Index,
2131 params: []const Node.Index,
2132 align_expr: Node.Index,
2133 section_expr: Node.Index,
2134 callconv_expr: Node.Index,
2135 };
2136
2137 pub const Param = struct {
2138 first_doc_comment: ?TokenIndex,
2139 name_token: ?TokenIndex,
2140 comptime_noalias: ?TokenIndex,
2141 anytype_ellipsis3: ?TokenIndex,
2142 type_expr: Node.Index,
2143 };
2144
2145 /// Abstracts over the fact that anytype and ... are not included
2146 /// in the params slice, since they are simple identifiers and
2147 /// not sub-expressions.
2148 pub const Iterator = struct {
2149 tree: *const Tree,
2150 fn_proto: *const FnProto,
2151 param_i: usize,
2152 tok_i: TokenIndex,
2153 tok_flag: bool,
2154
2155 pub fn next(it: *Iterator) ?Param {
2156 const token_tags = it.tree.tokens.items(.tag);
2157 while (true) {
2158 var first_doc_comment: ?TokenIndex = null;
2159 var comptime_noalias: ?TokenIndex = null;
2160 var name_token: ?TokenIndex = null;
2161 if (!it.tok_flag) {
2162 if (it.param_i >= it.fn_proto.ast.params.len) {
2163 return null;
2164 }
2165 const param_type = it.fn_proto.ast.params[it.param_i];
2166 var tok_i = it.tree.firstToken(param_type) - 1;
2167 while (true) : (tok_i -= 1) switch (token_tags[tok_i]) {
2168 .colon => continue,
2169 .identifier => name_token = tok_i,
2170 .doc_comment => first_doc_comment = tok_i,
2171 .keyword_comptime, .keyword_noalias => comptime_noalias = tok_i,
2172 else => break,
2173 };
2174 it.param_i += 1;
2175 it.tok_i = it.tree.lastToken(param_type) + 1;
2176 // Look for anytype and ... params afterwards.
2177 if (token_tags[it.tok_i] == .comma) {
2178 it.tok_i += 1;
2179 }
2180 it.tok_flag = true;
2181 return Param{
2182 .first_doc_comment = first_doc_comment,
2183 .comptime_noalias = comptime_noalias,
2184 .name_token = name_token,
2185 .anytype_ellipsis3 = null,
2186 .type_expr = param_type,
2187 };
2188 }
2189 if (token_tags[it.tok_i] == .comma) {
2190 it.tok_i += 1;
2191 }
2192 if (token_tags[it.tok_i] == .r_paren) {
2193 return null;
2194 }
2195 if (token_tags[it.tok_i] == .doc_comment) {
2196 first_doc_comment = it.tok_i;
2197 while (token_tags[it.tok_i] == .doc_comment) {
2198 it.tok_i += 1;
2199 }
2200 }
2201 switch (token_tags[it.tok_i]) {
2202 .ellipsis3 => {
2203 it.tok_flag = false; // Next iteration should return null.
2204 return Param{
2205 .first_doc_comment = first_doc_comment,
2206 .comptime_noalias = null,
2207 .name_token = null,
2208 .anytype_ellipsis3 = it.tok_i,
2209 .type_expr = 0,
2210 };
2211 },
2212 .keyword_noalias, .keyword_comptime => {
2213 comptime_noalias = it.tok_i;
2214 it.tok_i += 1;
2215 },
2216 else => {},
2217 }
2218 if (token_tags[it.tok_i] == .identifier and
2219 token_tags[it.tok_i + 1] == .colon)
2220 {
2221 name_token = it.tok_i;
2222 it.tok_i += 2;
2223 }
2224 if (token_tags[it.tok_i] == .keyword_anytype) {
2225 it.tok_i += 1;
2226 return Param{
2227 .first_doc_comment = first_doc_comment,
2228 .comptime_noalias = comptime_noalias,
2229 .name_token = name_token,
2230 .anytype_ellipsis3 = it.tok_i - 1,
2231 .type_expr = 0,
2232 };
2233 }
2234 it.tok_flag = false;
2235 }
2236 }
2237 };
2238
2239 pub fn iterate(fn_proto: FnProto, tree: Tree) Iterator {
2240 return .{
2241 .tree = &tree,
2242 .fn_proto = &fn_proto,
2243 .param_i = 0,
2244 .tok_i = fn_proto.lparen + 1,
2245 .tok_flag = true,
2246 };
2247 }
2248 };
2249
2250 pub const StructInit = struct {
2251 ast: Components,
2252
2253 pub const Components = struct {
2254 lbrace: TokenIndex,
2255 fields: []const Node.Index,
2256 type_expr: Node.Index,
2257 };
2258 };
2259
2260 pub const ArrayInit = struct {
2261 ast: Components,
2262
2263 pub const Components = struct {
2264 lbrace: TokenIndex,
2265 elements: []const Node.Index,
2266 type_expr: Node.Index,
2267 };
2268 };
2269
2270 pub const ArrayType = struct {
2271 ast: Components,
2272
2273 pub const Components = struct {
2274 lbracket: TokenIndex,
2275 elem_count: Node.Index,
2276 sentinel: Node.Index,
2277 elem_type: Node.Index,
2278 };
2279 };
2280
2281 pub const PtrType = struct {
2282 size: std.builtin.TypeInfo.Pointer.Size,
2283 allowzero_token: ?TokenIndex,
2284 const_token: ?TokenIndex,
2285 volatile_token: ?TokenIndex,
2286 ast: Components,
2287
2288 pub const Components = struct {
2289 main_token: TokenIndex,
2290 align_node: Node.Index,
2291 sentinel: Node.Index,
2292 bit_range_start: Node.Index,
2293 bit_range_end: Node.Index,
2294 child_type: Node.Index,
2295 };
2296 };
2297
2298 pub const Slice = struct {
2299 ast: Components,
2300
2301 pub const Components = struct {
2302 sliced: Node.Index,
2303 lbracket: TokenIndex,
2304 start: Node.Index,
2305 end: Node.Index,
2306 sentinel: Node.Index,
2307 };
2308 };
2309
2310 pub const ContainerDecl = struct {
2311 layout_token: ?TokenIndex,
2312 ast: Components,
2313
2314 pub const Components = struct {
2315 main_token: TokenIndex,
2316 /// Populated when main_token is Keyword_union.
2317 enum_token: ?TokenIndex,
2318 members: []const Node.Index,
2319 arg: Node.Index,
2320 };
2321 };
2322
2323 pub const SwitchCase = struct {
2324 /// Points to the first token after the `|`. Will either be an identifier or
2325 /// a `*` (with an identifier immediately after it).
2326 payload_token: ?TokenIndex,
2327 ast: Components,
2328
2329 pub const Components = struct {
2330 /// If empty, this is an else case
2331 values: []const Node.Index,
2332 arrow_token: TokenIndex,
2333 target_expr: Node.Index,
2334 };
2335 };
2336
2337 pub const Asm = struct {
2338 ast: Components,
2339 volatile_token: ?TokenIndex,
2340 first_clobber: ?TokenIndex,
2341 outputs: []const Node.Index,
2342 inputs: []const Node.Index,
2343
2344 pub const Components = struct {
2345 asm_token: TokenIndex,
2346 template: Node.Index,
2347 items: []const Node.Index,
2348 rparen: TokenIndex,
2349 };
2350 };
2351
2352 pub const Call = struct {
2353 ast: Components,
2354 async_token: ?TokenIndex,
2355
2356 pub const Components = struct {
2357 lparen: TokenIndex,
2358 fn_expr: Node.Index,
2359 params: []const Node.Index,
2360 };
2361 };
2362};
2363
2364pub const Error = struct {
2365 tag: Tag,
2366 token: TokenIndex,
2367 extra: union {
2368 none: void,
2369 expected_tag: Token.Tag,
2370 } = .{ .none = {} },
2371
2372 pub const Tag = enum {
2373 asterisk_after_ptr_deref,
2374 decl_between_fields,
2375 expected_block,
2376 expected_block_or_assignment,
2377 expected_block_or_expr,
2378 expected_block_or_field,
2379 expected_container_members,
2380 expected_expr,
2381 expected_expr_or_assignment,
2382 expected_fn,
2383 expected_inlinable,
2384 expected_labelable,
2385 expected_param_list,
2386 expected_prefix_expr,
2387 expected_primary_type_expr,
2388 expected_pub_item,
2389 expected_return_type,
2390 expected_semi_or_else,
2391 expected_semi_or_lbrace,
2392 expected_statement,
2393 expected_string_literal,
2394 expected_suffix_op,
2395 expected_type_expr,
2396 expected_var_decl,
2397 expected_var_decl_or_fn,
2398 expected_loop_payload,
2399 expected_container,
2400 extra_align_qualifier,
2401 extra_allowzero_qualifier,
2402 extra_const_qualifier,
2403 extra_volatile_qualifier,
2404 ptr_mod_on_array_child_type,
2405 invalid_bit_range,
2406 invalid_token,
2407 same_line_doc_comment,
2408 unattached_doc_comment,
2409 varargs_nonfinal,
2410
2411 /// `expected_tag` is populated.
2412 expected_token,
2413 };
2414};
2415
2416pub const Node = struct {
2417 tag: Tag,
2418 main_token: TokenIndex,
2419 data: Data,
2420
2421 pub const Index = u32;
2422
2423 comptime {
2424 // Goal is to keep this under one byte for efficiency.
2425 assert(@sizeOf(Tag) == 1);
2426 }
2427
2428 /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of
2429 /// Tree.lastToken()
2430 pub const Tag = enum {
2431 /// sub_list[lhs...rhs]
2432 root,
2433 /// `usingnamespace lhs;`. rhs unused. main_token is `usingnamespace`.
2434 @"usingnamespace",
2435 /// lhs is test name token (must be string literal), if any.
2436 /// rhs is the body node.
2437 test_decl,
2438 /// lhs is the index into extra_data.
2439 /// rhs is the initialization expression, if any.
2440 /// main_token is `var` or `const`.
2441 global_var_decl,
2442 /// `var a: x align(y) = rhs`
2443 /// lhs is the index into extra_data.
2444 /// main_token is `var` or `const`.
2445 local_var_decl,
2446 /// `var a: lhs = rhs`. lhs and rhs may be unused.
2447 /// Can be local or global.
2448 /// main_token is `var` or `const`.
2449 simple_var_decl,
2450 /// `var a align(lhs) = rhs`. lhs and rhs may be unused.
2451 /// Can be local or global.
2452 /// main_token is `var` or `const`.
2453 aligned_var_decl,
2454 /// lhs is the identifier token payload if any,
2455 /// rhs is the deferred expression.
2456 @"errdefer",
2457 /// lhs is unused.
2458 /// rhs is the deferred expression.
2459 @"defer",
2460 /// lhs catch rhs
2461 /// lhs catch |err| rhs
2462 /// main_token is the `catch` keyword.
2463 /// payload is determined by looking at the next token after the `catch` keyword.
2464 @"catch",
2465 /// `lhs.a`. main_token is the dot. rhs is the identifier token index.
2466 field_access,
2467 /// `lhs.?`. main_token is the dot. rhs is the `?` token index.
2468 unwrap_optional,
2469 /// `lhs == rhs`. main_token is op.
2470 equal_equal,
2471 /// `lhs != rhs`. main_token is op.
2472 bang_equal,
2473 /// `lhs < rhs`. main_token is op.
2474 less_than,
2475 /// `lhs > rhs`. main_token is op.
2476 greater_than,
2477 /// `lhs <= rhs`. main_token is op.
2478 less_or_equal,
2479 /// `lhs >= rhs`. main_token is op.
2480 greater_or_equal,
2481 /// `lhs *= rhs`. main_token is op.
2482 assign_mul,
2483 /// `lhs /= rhs`. main_token is op.
2484 assign_div,
2485 /// `lhs *= rhs`. main_token is op.
2486 assign_mod,
2487 /// `lhs += rhs`. main_token is op.
2488 assign_add,
2489 /// `lhs -= rhs`. main_token is op.
2490 assign_sub,
2491 /// `lhs <<= rhs`. main_token is op.
2492 assign_bit_shift_left,
2493 /// `lhs >>= rhs`. main_token is op.
2494 assign_bit_shift_right,
2495 /// `lhs &= rhs`. main_token is op.
2496 assign_bit_and,
2497 /// `lhs ^= rhs`. main_token is op.
2498 assign_bit_xor,
2499 /// `lhs |= rhs`. main_token is op.
2500 assign_bit_or,
2501 /// `lhs *%= rhs`. main_token is op.
2502 assign_mul_wrap,
2503 /// `lhs +%= rhs`. main_token is op.
2504 assign_add_wrap,
2505 /// `lhs -%= rhs`. main_token is op.
2506 assign_sub_wrap,
2507 /// `lhs = rhs`. main_token is op.
2508 assign,
2509 /// `lhs || rhs`. main_token is the `||`.
2510 merge_error_sets,
2511 /// `lhs * rhs`. main_token is the `*`.
2512 mul,
2513 /// `lhs / rhs`. main_token is the `/`.
2514 div,
2515 /// `lhs % rhs`. main_token is the `%`.
2516 mod,
2517 /// `lhs ** rhs`. main_token is the `**`.
2518 array_mult,
2519 /// `lhs *% rhs`. main_token is the `*%`.
2520 mul_wrap,
2521 /// `lhs + rhs`. main_token is the `+`.
2522 add,
2523 /// `lhs - rhs`. main_token is the `-`.
2524 sub,
2525 /// `lhs ++ rhs`. main_token is the `++`.
2526 array_cat,
2527 /// `lhs +% rhs`. main_token is the `+%`.
2528 add_wrap,
2529 /// `lhs -% rhs`. main_token is the `-%`.
2530 sub_wrap,
2531 /// `lhs << rhs`. main_token is the `<<`.
2532 bit_shift_left,
2533 /// `lhs >> rhs`. main_token is the `>>`.
2534 bit_shift_right,
2535 /// `lhs & rhs`. main_token is the `&`.
2536 bit_and,
2537 /// `lhs ^ rhs`. main_token is the `^`.
2538 bit_xor,
2539 /// `lhs | rhs`. main_token is the `|`.
2540 bit_or,
2541 /// `lhs orelse rhs`. main_token is the `orelse`.
2542 @"orelse",
2543 /// `lhs and rhs`. main_token is the `and`.
2544 bool_and,
2545 /// `lhs or rhs`. main_token is the `or`.
2546 bool_or,
2547 /// `op lhs`. rhs unused. main_token is op.
2548 bool_not,
2549 /// `op lhs`. rhs unused. main_token is op.
2550 negation,
2551 /// `op lhs`. rhs unused. main_token is op.
2552 bit_not,
2553 /// `op lhs`. rhs unused. main_token is op.
2554 negation_wrap,
2555 /// `op lhs`. rhs unused. main_token is op.
2556 address_of,
2557 /// `op lhs`. rhs unused. main_token is op.
2558 @"try",
2559 /// `op lhs`. rhs unused. main_token is op.
2560 @"await",
2561 /// `?lhs`. rhs unused. main_token is the `?`.
2562 optional_type,
2563 /// `[lhs]rhs`.
2564 array_type,
2565 /// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`.
2566 array_type_sentinel,
2567 /// `[*]align(lhs) rhs`. lhs can be omitted.
2568 /// `*align(lhs) rhs`. lhs can be omitted.
2569 /// `[]rhs`.
2570 /// main_token is the asterisk if a pointer or the lbracket if a slice
2571 /// main_token might be a ** token, which is shared with a parent/child
2572 /// pointer type and may require special handling.
2573 ptr_type_aligned,
2574 /// `[*:lhs]rhs`. lhs can be omitted.
2575 /// `*rhs`.
2576 /// `[:lhs]rhs`.
2577 /// main_token is the asterisk if a pointer or the lbracket if a slice
2578 /// main_token might be a ** token, which is shared with a parent/child
2579 /// pointer type and may require special handling.
2580 ptr_type_sentinel,
2581 /// lhs is index into ptr_type. rhs is the element type expression.
2582 /// main_token is the asterisk if a pointer or the lbracket if a slice
2583 /// main_token might be a ** token, which is shared with a parent/child
2584 /// pointer type and may require special handling.
2585 ptr_type,
2586 /// lhs is index into ptr_type_bit_range. rhs is the element type expression.
2587 /// main_token is the asterisk if a pointer or the lbracket if a slice
2588 /// main_token might be a ** token, which is shared with a parent/child
2589 /// pointer type and may require special handling.
2590 ptr_type_bit_range,
2591 /// `lhs[rhs..]`
2592 /// main_token is the lbracket.
2593 slice_open,
2594 /// `lhs[b..c]`. rhs is index into Slice
2595 /// main_token is the lbracket.
2596 slice,
2597 /// `lhs[b..c :d]`. rhs is index into SliceSentinel
2598 /// main_token is the lbracket.
2599 slice_sentinel,
2600 /// `lhs.*`. rhs is unused.
2601 deref,
2602 /// `lhs[rhs]`.
2603 array_access,
2604 /// `lhs{rhs}`. rhs can be omitted.
2605 array_init_one,
2606 /// `lhs{rhs,}`. rhs can *not* be omitted
2607 array_init_one_comma,
2608 /// `.{lhs, rhs}`. lhs and rhs can be omitted.
2609 array_init_dot_two,
2610 /// Same as `array_init_dot_two` except there is known to be a trailing comma
2611 /// before the final rbrace.
2612 array_init_dot_two_comma,
2613 /// `.{a, b}`. `sub_list[lhs..rhs]`.
2614 array_init_dot,
2615 /// Same as `array_init_dot` except there is known to be a trailing comma
2616 /// before the final rbrace.
2617 array_init_dot_comma,
2618 /// `lhs{a, b}`. `sub_range_list[rhs]`. lhs can be omitted which means `.{a, b}`.
2619 array_init,
2620 /// Same as `array_init` except there is known to be a trailing comma
2621 /// before the final rbrace.
2622 array_init_comma,
2623 /// `lhs{.a = rhs}`. rhs can be omitted making it empty.
2624 /// main_token is the lbrace.
2625 struct_init_one,
2626 /// `lhs{.a = rhs,}`. rhs can *not* be omitted.
2627 /// main_token is the lbrace.
2628 struct_init_one_comma,
2629 /// `.{.a = lhs, .b = rhs}`. lhs and rhs can be omitted.
2630 /// main_token is the lbrace.
2631 /// No trailing comma before the rbrace.
2632 struct_init_dot_two,
2633 /// Same as `struct_init_dot_two` except there is known to be a trailing comma
2634 /// before the final rbrace.
2635 struct_init_dot_two_comma,
2636 /// `.{.a = b, .c = d}`. `sub_list[lhs..rhs]`.
2637 /// main_token is the lbrace.
2638 struct_init_dot,
2639 /// Same as `struct_init_dot` except there is known to be a trailing comma
2640 /// before the final rbrace.
2641 struct_init_dot_comma,
2642 /// `lhs{.a = b, .c = d}`. `sub_range_list[rhs]`.
2643 /// lhs can be omitted which means `.{.a = b, .c = d}`.
2644 /// main_token is the lbrace.
2645 struct_init,
2646 /// Same as `struct_init` except there is known to be a trailing comma
2647 /// before the final rbrace.
2648 struct_init_comma,
2649 /// `lhs(rhs)`. rhs can be omitted.
2650 /// main_token is the lparen.
2651 call_one,
2652 /// `lhs(rhs,)`. rhs can be omitted.
2653 /// main_token is the lparen.
2654 call_one_comma,
2655 /// `async lhs(rhs)`. rhs can be omitted.
2656 async_call_one,
2657 /// `async lhs(rhs,)`.
2658 async_call_one_comma,
2659 /// `lhs(a, b, c)`. `SubRange[rhs]`.
2660 /// main_token is the `(`.
2661 call,
2662 /// `lhs(a, b, c,)`. `SubRange[rhs]`.
2663 /// main_token is the `(`.
2664 call_comma,
2665 /// `async lhs(a, b, c)`. `SubRange[rhs]`.
2666 /// main_token is the `(`.
2667 async_call,
2668 /// `async lhs(a, b, c,)`. `SubRange[rhs]`.
2669 /// main_token is the `(`.
2670 async_call_comma,
2671 /// `switch(lhs) {}`. `SubRange[rhs]`.
2672 @"switch",
2673 /// Same as switch except there is known to be a trailing comma
2674 /// before the final rbrace
2675 switch_comma,
2676 /// `lhs => rhs`. If lhs is omitted it means `else`.
2677 /// main_token is the `=>`
2678 switch_case_one,
2679 /// `a, b, c => rhs`. `SubRange[lhs]`.
2680 /// main_token is the `=>`
2681 switch_case,
2682 /// `lhs...rhs`.
2683 switch_range,
2684 /// `while (lhs) rhs`.
2685 /// `while (lhs) |x| rhs`.
2686 while_simple,
2687 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
2688 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
2689 while_cont,
2690 /// `while (lhs) : (a) b else c`. `While[rhs]`.
2691 /// `while (lhs) |x| : (a) b else c`. `While[rhs]`.
2692 /// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`.
2693 @"while",
2694 /// `for (lhs) rhs`.
2695 for_simple,
2696 /// `for (lhs) a else b`. `if_list[rhs]`.
2697 @"for",
2698 /// `if (lhs) rhs`.
2699 /// `if (lhs) |a| rhs`.
2700 if_simple,
2701 /// `if (lhs) a else b`. `If[rhs]`.
2702 /// `if (lhs) |x| a else b`. `If[rhs]`.
2703 /// `if (lhs) |x| a else |y| b`. `If[rhs]`.
2704 @"if",
2705 /// `suspend lhs`. lhs can be omitted. rhs is unused.
2706 @"suspend",
2707 /// `resume lhs`. rhs is unused.
2708 @"resume",
2709 /// `continue`. lhs is token index of label if any. rhs is unused.
2710 @"continue",
2711 /// `break :lhs rhs`
2712 /// both lhs and rhs may be omitted.
2713 @"break",
2714 /// `return lhs`. lhs can be omitted. rhs is unused.
2715 @"return",
2716 /// `fn(a: lhs) rhs`. lhs can be omitted.
2717 /// anytype and ... parameters are omitted from the AST tree.
2718 /// main_token is the `fn` keyword.
2719 /// extern function declarations use this tag.
2720 fn_proto_simple,
2721 /// `fn(a: b, c: d) rhs`. `sub_range_list[lhs]`.
2722 /// anytype and ... parameters are omitted from the AST tree.
2723 /// main_token is the `fn` keyword.
2724 /// extern function declarations use this tag.
2725 fn_proto_multi,
2726 /// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`.
2727 /// zero or one parameters.
2728 /// anytype and ... parameters are omitted from the AST tree.
2729 /// main_token is the `fn` keyword.
2730 /// extern function declarations use this tag.
2731 fn_proto_one,
2732 /// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.
2733 /// anytype and ... parameters are omitted from the AST tree.
2734 /// main_token is the `fn` keyword.
2735 /// extern function declarations use this tag.
2736 fn_proto,
2737 /// lhs is the fn_proto.
2738 /// rhs is the function body block.
2739 /// Note that extern function declarations use the fn_proto tags rather
2740 /// than this one.
2741 fn_decl,
2742 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
2743 anyframe_type,
2744 /// Both lhs and rhs unused.
2745 anyframe_literal,
2746 /// Both lhs and rhs unused.
2747 char_literal,
2748 /// Both lhs and rhs unused.
2749 integer_literal,
2750 /// Both lhs and rhs unused.
2751 float_literal,
2752 /// Both lhs and rhs unused.
2753 unreachable_literal,
2754 /// Both lhs and rhs unused.
2755 /// Most identifiers will not have explicit AST nodes, however for expressions
2756 /// which could be one of many different kinds of AST nodes, there will be an
2757 /// identifier AST node for it.
2758 identifier,
2759 /// lhs is the dot token index, rhs unused, main_token is the identifier.
2760 enum_literal,
2761 /// main_token is the string literal token
2762 /// Both lhs and rhs unused.
2763 string_literal,
2764 /// main_token is the first token index (redundant with lhs)
2765 /// lhs is the first token index; rhs is the last token index.
2766 /// Could be a series of multiline_string_literal_line tokens, or a single
2767 /// string_literal token.
2768 multiline_string_literal,
2769 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
2770 grouped_expression,
2771 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
2772 /// main_token is the builtin token.
2773 builtin_call_two,
2774 /// Same as builtin_call_two but there is known to be a trailing comma before the rparen.
2775 builtin_call_two_comma,
2776 /// `@a(b, c)`. `sub_list[lhs..rhs]`.
2777 /// main_token is the builtin token.
2778 builtin_call,
2779 /// Same as builtin_call but there is known to be a trailing comma before the rparen.
2780 builtin_call_comma,
2781 /// `error{a, b}`.
2782 /// rhs is the rbrace, lhs is unused.
2783 error_set_decl,
2784 /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. `extra_data[lhs..rhs]`.
2785 /// main_token is `struct`, `union`, `opaque`, `enum` keyword.
2786 container_decl,
2787 /// Same as ContainerDecl but there is known to be a trailing comma
2788 /// or semicolon before the rbrace.
2789 container_decl_trailing,
2790 /// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`.
2791 /// lhs or rhs can be omitted.
2792 /// main_token is `struct`, `union`, `opaque`, `enum` keyword.
2793 container_decl_two,
2794 /// Same as ContainerDeclTwo except there is known to be a trailing comma
2795 /// or semicolon before the rbrace.
2796 container_decl_two_trailing,
2797 /// `union(lhs)` / `enum(lhs)`. `SubRange[rhs]`.
2798 container_decl_arg,
2799 /// Same as container_decl_arg but there is known to be a trailing
2800 /// comma or semicolon before the rbrace.
2801 container_decl_arg_trailing,
2802 /// `union(enum) {}`. `sub_list[lhs..rhs]`.
2803 /// Note that tagged unions with explicitly provided enums are represented
2804 /// by `container_decl_arg`.
2805 tagged_union,
2806 /// Same as tagged_union but there is known to be a trailing comma
2807 /// or semicolon before the rbrace.
2808 tagged_union_trailing,
2809 /// `union(enum) {lhs, rhs}`. lhs or rhs may be omitted.
2810 /// Note that tagged unions with explicitly provided enums are represented
2811 /// by `container_decl_arg`.
2812 tagged_union_two,
2813 /// Same as tagged_union_two but there is known to be a trailing comma
2814 /// or semicolon before the rbrace.
2815 tagged_union_two_trailing,
2816 /// `union(enum(lhs)) {}`. `SubRange[rhs]`.
2817 tagged_union_enum_tag,
2818 /// Same as tagged_union_enum_tag but there is known to be a trailing comma
2819 /// or semicolon before the rbrace.
2820 tagged_union_enum_tag_trailing,
2821 /// `a: lhs = rhs,`. lhs and rhs can be omitted.
2822 /// main_token is the field name identifier.
2823 /// lastToken() does not include the possible trailing comma.
2824 container_field_init,
2825 /// `a: lhs align(rhs),`. rhs can be omitted.
2826 /// main_token is the field name identifier.
2827 /// lastToken() does not include the possible trailing comma.
2828 container_field_align,
2829 /// `a: lhs align(c) = d,`. `container_field_list[rhs]`.
2830 /// main_token is the field name identifier.
2831 /// lastToken() does not include the possible trailing comma.
2832 container_field,
2833 /// `anytype`. both lhs and rhs unused.
2834 /// Used by `ContainerField`.
2835 @"anytype",
2836 /// `comptime lhs`. rhs unused.
2837 @"comptime",
2838 /// `nosuspend lhs`. rhs unused.
2839 @"nosuspend",
2840 /// `{lhs rhs}`. rhs or lhs can be omitted.
2841 /// main_token points at the lbrace.
2842 block_two,
2843 /// Same as block_two but there is known to be a semicolon before the rbrace.
2844 block_two_semicolon,
2845 /// `{}`. `sub_list[lhs..rhs]`.
2846 /// main_token points at the lbrace.
2847 block,
2848 /// Same as block but there is known to be a semicolon before the rbrace.
2849 block_semicolon,
2850 /// `asm(lhs)`. rhs is the token index of the rparen.
2851 asm_simple,
2852 /// `asm(lhs, a)`. `Asm[rhs]`.
2853 @"asm",
2854 /// `[a] "b" (c)`. lhs is 0, rhs is token index of the rparen.
2855 /// `[a] "b" (-> lhs)`. rhs is token index of the rparen.
2856 /// main_token is `a`.
2857 asm_output,
2858 /// `[a] "b" (lhs)`. rhs is token index of the rparen.
2859 /// main_token is `a`.
2860 asm_input,
2861 /// `error.a`. lhs is token index of `.`. rhs is token index of `a`.
2862 error_value,
2863 /// `lhs!rhs`. main_token is the `!`.
2864 error_union,
2865
2866 pub fn isContainerField(tag: Tag) bool {
2867 return switch (tag) {
2868 .container_field_init,
2869 .container_field_align,
2870 .container_field,
2871 => true,
2872
2873 else => false,
2874 };
2875 }
2876 };
2877
2878 pub const Data = struct {
2879 lhs: Index,
2880 rhs: Index,
2881 };
2882
2883 pub const LocalVarDecl = struct {
2884 type_node: Index,
2885 align_node: Index,
2886 };
2887
2888 pub const ArrayTypeSentinel = struct {
2889 elem_type: Index,
2890 sentinel: Index,
2891 };
2892
2893 pub const PtrType = struct {
2894 sentinel: Index,
2895 align_node: Index,
2896 };
2897
2898 pub const PtrTypeBitRange = struct {
2899 sentinel: Index,
2900 align_node: Index,
2901 bit_range_start: Index,
2902 bit_range_end: Index,
2903 };
2904
2905 pub const SubRange = struct {
2906 /// Index into sub_list.
2907 start: Index,
2908 /// Index into sub_list.
2909 end: Index,
2910 };
2911
2912 pub const If = struct {
2913 then_expr: Index,
2914 else_expr: Index,
2915 };
2916
2917 pub const ContainerField = struct {
2918 value_expr: Index,
2919 align_expr: Index,
2920 };
2921
2922 pub const GlobalVarDecl = struct {
2923 type_node: Index,
2924 align_node: Index,
2925 section_node: Index,
2926 };
2927
2928 pub const Slice = struct {
2929 start: Index,
2930 end: Index,
2931 };
2932
2933 pub const SliceSentinel = struct {
2934 start: Index,
2935 /// May be 0 if the slice is "open"
2936 end: Index,
2937 sentinel: Index,
2938 };
2939
2940 pub const While = struct {
2941 cont_expr: Index,
2942 then_expr: Index,
2943 else_expr: Index,
2944 };
2945
2946 pub const WhileCont = struct {
2947 cont_expr: Index,
2948 then_expr: Index,
2949 };
2950
2951 pub const FnProtoOne = struct {
2952 /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters.
2953 param: Index,
2954 /// Populated if align(A) is present.
2955 align_expr: Index,
2956 /// Populated if linksection(A) is present.
2957 section_expr: Index,
2958 /// Populated if callconv(A) is present.
2959 callconv_expr: Index,
2960 };
2961
2962 pub const FnProto = struct {
2963 params_start: Index,
2964 params_end: Index,
2965 /// Populated if align(A) is present.
2966 align_expr: Index,
2967 /// Populated if linksection(A) is present.
2968 section_expr: Index,
2969 /// Populated if callconv(A) is present.
2970 callconv_expr: Index,
2971 };
2972
2973 pub const Asm = struct {
2974 items_start: Index,
2975 items_end: Index,
2976 /// Needed to make lastToken() work.
2977 rparen: TokenIndex,
2978 };
2979};
lib/std/zig/ast.zig deleted-2978
...@@ -1,2978 +0,0 @@
1const std = @import("../std.zig");
2const assert = std.debug.assert;
3const testing = std.testing;
4const mem = std.mem;
5const Token = std.zig.Token;
6
7pub const TokenIndex = u32;
8pub const ByteOffset = u32;
9
10pub const TokenList = std.MultiArrayList(struct {
11 tag: Token.Tag,
12 start: ByteOffset,
13});
14pub const NodeList = std.MultiArrayList(Node);
15
16pub const Tree = struct {
17 /// Reference to externally-owned data.
18 source: [:0]const u8,
19
20 tokens: TokenList.Slice,
21 /// The root AST node is assumed to be index 0. Since there can be no
22 /// references to the root node, this means 0 is available to indicate null.
23 nodes: NodeList.Slice,
24 extra_data: []Node.Index,
25
26 errors: []const Error,
27
28 pub const Location = struct {
29 line: usize,
30 column: usize,
31 line_start: usize,
32 line_end: usize,
33 };
34
35 pub fn deinit(tree: *Tree, gpa: *mem.Allocator) void {
36 tree.tokens.deinit(gpa);
37 tree.nodes.deinit(gpa);
38 gpa.free(tree.extra_data);
39 gpa.free(tree.errors);
40 tree.* = undefined;
41 }
42
43 pub const RenderError = error{
44 /// Ran out of memory allocating call stack frames to complete rendering, or
45 /// ran out of memory allocating space in the output buffer.
46 OutOfMemory,
47 };
48
49 /// `gpa` is used for allocating the resulting formatted source code, as well as
50 /// for allocating extra stack memory if needed, because this function utilizes recursion.
51 /// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.
52 /// Caller owns the returned slice of bytes, allocated with `gpa`.
53 pub fn render(tree: Tree, gpa: *mem.Allocator) RenderError![]u8 {
54 var buffer = std.ArrayList(u8).init(gpa);
55 defer buffer.deinit();
56
57 try tree.renderToArrayList(&buffer);
58 return buffer.toOwnedSlice();
59 }
60
61 pub fn renderToArrayList(tree: Tree, buffer: *std.ArrayList(u8)) RenderError!void {
62 return @import("./render.zig").renderTree(buffer, tree);
63 }
64
65 pub fn tokenLocation(self: Tree, start_offset: ByteOffset, token_index: TokenIndex) Location {
66 var loc = Location{
67 .line = 0,
68 .column = 0,
69 .line_start = start_offset,
70 .line_end = self.source.len,
71 };
72 const token_start = self.tokens.items(.start)[token_index];
73 for (self.source[start_offset..]) |c, i| {
74 if (i + start_offset == token_start) {
75 loc.line_end = i + start_offset;
76 while (loc.line_end < self.source.len and self.source[loc.line_end] != '\n') {
77 loc.line_end += 1;
78 }
79 return loc;
80 }
81 if (c == '\n') {
82 loc.line += 1;
83 loc.column = 0;
84 loc.line_start = i + 1;
85 } else {
86 loc.column += 1;
87 }
88 }
89 return loc;
90 }
91
92 pub fn tokenSlice(tree: Tree, token_index: TokenIndex) []const u8 {
93 const token_starts = tree.tokens.items(.start);
94 const token_tags = tree.tokens.items(.tag);
95 const token_tag = token_tags[token_index];
96
97 // Many tokens can be determined entirely by their tag.
98 if (token_tag.lexeme()) |lexeme| {
99 return lexeme;
100 }
101
102 // For some tokens, re-tokenization is needed to find the end.
103 var tokenizer: std.zig.Tokenizer = .{
104 .buffer = tree.source,
105 .index = token_starts[token_index],
106 .pending_invalid_token = null,
107 };
108 const token = tokenizer.next();
109 assert(token.tag == token_tag);
110 return tree.source[token.loc.start..token.loc.end];
111 }
112
113 pub fn extraData(tree: Tree, index: usize, comptime T: type) T {
114 const fields = std.meta.fields(T);
115 var result: T = undefined;
116 inline for (fields) |field, i| {
117 comptime assert(field.field_type == Node.Index);
118 @field(result, field.name) = tree.extra_data[index + i];
119 }
120 return result;
121 }
122
123 pub fn rootDecls(tree: Tree) []const Node.Index {
124 // Root is always index 0.
125 const nodes_data = tree.nodes.items(.data);
126 return tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs];
127 }
128
129 pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {
130 const token_tags = tree.tokens.items(.tag);
131 switch (parse_error.tag) {
132 .asterisk_after_ptr_deref => {
133 // Note that the token will point at the `.*` but ideally the source
134 // location would point to the `*` after the `.*`.
135 return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");
136 },
137 .decl_between_fields => {
138 return stream.writeAll("declarations are not allowed between container fields");
139 },
140 .expected_block => {
141 return stream.print("expected block or field, found '{s}'", .{
142 token_tags[parse_error.token].symbol(),
143 });
144 },
145 .expected_block_or_assignment => {
146 return stream.print("expected block or assignment, found '{s}'", .{
147 token_tags[parse_error.token].symbol(),
148 });
149 },
150 .expected_block_or_expr => {
151 return stream.print("expected block or expression, found '{s}'", .{
152 token_tags[parse_error.token].symbol(),
153 });
154 },
155 .expected_block_or_field => {
156 return stream.print("expected block or field, found '{s}'", .{
157 token_tags[parse_error.token].symbol(),
158 });
159 },
160 .expected_container_members => {
161 return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{
162 token_tags[parse_error.token].symbol(),
163 });
164 },
165 .expected_expr => {
166 return stream.print("expected expression, found '{s}'", .{
167 token_tags[parse_error.token].symbol(),
168 });
169 },
170 .expected_expr_or_assignment => {
171 return stream.print("expected expression or assignment, found '{s}'", .{
172 token_tags[parse_error.token].symbol(),
173 });
174 },
175 .expected_fn => {
176 return stream.print("expected function, found '{s}'", .{
177 token_tags[parse_error.token].symbol(),
178 });
179 },
180 .expected_inlinable => {
181 return stream.print("expected 'while' or 'for', found '{s}'", .{
182 token_tags[parse_error.token].symbol(),
183 });
184 },
185 .expected_labelable => {
186 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{
187 token_tags[parse_error.token].symbol(),
188 });
189 },
190 .expected_param_list => {
191 return stream.print("expected parameter list, found '{s}'", .{
192 token_tags[parse_error.token].symbol(),
193 });
194 },
195 .expected_prefix_expr => {
196 return stream.print("expected prefix expression, found '{s}'", .{
197 token_tags[parse_error.token].symbol(),
198 });
199 },
200 .expected_primary_type_expr => {
201 return stream.print("expected primary type expression, found '{s}'", .{
202 token_tags[parse_error.token].symbol(),
203 });
204 },
205 .expected_pub_item => {
206 return stream.writeAll("expected function or variable declaration after pub");
207 },
208 .expected_return_type => {
209 return stream.print("expected return type expression, found '{s}'", .{
210 token_tags[parse_error.token].symbol(),
211 });
212 },
213 .expected_semi_or_else => {
214 return stream.print("expected ';' or 'else', found '{s}'", .{
215 token_tags[parse_error.token].symbol(),
216 });
217 },
218 .expected_semi_or_lbrace => {
219 return stream.print("expected ';' or '{{', found '{s}'", .{
220 token_tags[parse_error.token].symbol(),
221 });
222 },
223 .expected_statement => {
224 return stream.print("expected statement, found '{s}'", .{
225 token_tags[parse_error.token].symbol(),
226 });
227 },
228 .expected_string_literal => {
229 return stream.print("expected string literal, found '{s}'", .{
230 token_tags[parse_error.token].symbol(),
231 });
232 },
233 .expected_suffix_op => {
234 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
235 token_tags[parse_error.token].symbol(),
236 });
237 },
238 .expected_type_expr => {
239 return stream.print("expected type expression, found '{s}'", .{
240 token_tags[parse_error.token].symbol(),
241 });
242 },
243 .expected_var_decl => {
244 return stream.print("expected variable declaration, found '{s}'", .{
245 token_tags[parse_error.token].symbol(),
246 });
247 },
248 .expected_var_decl_or_fn => {
249 return stream.print("expected variable declaration or function, found '{s}'", .{
250 token_tags[parse_error.token].symbol(),
251 });
252 },
253 .expected_loop_payload => {
254 return stream.print("expected loop payload, found '{s}'", .{
255 token_tags[parse_error.token].symbol(),
256 });
257 },
258 .expected_container => {
259 return stream.print("expected a struct, enum or union, found '{s}'", .{
260 token_tags[parse_error.token].symbol(),
261 });
262 },
263 .extra_align_qualifier => {
264 return stream.writeAll("extra align qualifier");
265 },
266 .extra_allowzero_qualifier => {
267 return stream.writeAll("extra allowzero qualifier");
268 },
269 .extra_const_qualifier => {
270 return stream.writeAll("extra const qualifier");
271 },
272 .extra_volatile_qualifier => {
273 return stream.writeAll("extra volatile qualifier");
274 },
275 .ptr_mod_on_array_child_type => {
276 return stream.print("pointer modifier '{s}' not allowed on array child type", .{
277 token_tags[parse_error.token].symbol(),
278 });
279 },
280 .invalid_bit_range => {
281 return stream.writeAll("bit range not allowed on slices and arrays");
282 },
283 .invalid_token => {
284 return stream.print("invalid token: '{s}'", .{
285 token_tags[parse_error.token].symbol(),
286 });
287 },
288 .same_line_doc_comment => {
289 return stream.writeAll("same line documentation comment");
290 },
291 .unattached_doc_comment => {
292 return stream.writeAll("unattached documentation comment");
293 },
294 .varargs_nonfinal => {
295 return stream.writeAll("function prototype has parameter after varargs");
296 },
297
298 .expected_token => {
299 const found_tag = token_tags[parse_error.token];
300 const expected_symbol = parse_error.extra.expected_tag.symbol();
301 switch (found_tag) {
302 .invalid => return stream.print("expected '{s}', found invalid bytes", .{
303 expected_symbol,
304 }),
305 else => return stream.print("expected '{s}', found '{s}'", .{
306 expected_symbol, found_tag.symbol(),
307 }),
308 }
309 },
310 }
311 }
312
313 pub fn firstToken(tree: Tree, node: Node.Index) TokenIndex {
314 const tags = tree.nodes.items(.tag);
315 const datas = tree.nodes.items(.data);
316 const main_tokens = tree.nodes.items(.main_token);
317 const token_tags = tree.tokens.items(.tag);
318 var end_offset: TokenIndex = 0;
319 var n = node;
320 while (true) switch (tags[n]) {
321 .root => return 0,
322
323 .test_decl,
324 .@"errdefer",
325 .@"defer",
326 .bool_not,
327 .negation,
328 .bit_not,
329 .negation_wrap,
330 .address_of,
331 .@"try",
332 .@"await",
333 .optional_type,
334 .@"switch",
335 .switch_comma,
336 .if_simple,
337 .@"if",
338 .@"suspend",
339 .@"resume",
340 .@"continue",
341 .@"break",
342 .@"return",
343 .anyframe_type,
344 .identifier,
345 .anyframe_literal,
346 .char_literal,
347 .integer_literal,
348 .float_literal,
349 .unreachable_literal,
350 .string_literal,
351 .multiline_string_literal,
352 .grouped_expression,
353 .builtin_call_two,
354 .builtin_call_two_comma,
355 .builtin_call,
356 .builtin_call_comma,
357 .error_set_decl,
358 .@"anytype",
359 .@"comptime",
360 .@"nosuspend",
361 .asm_simple,
362 .@"asm",
363 .array_type,
364 .array_type_sentinel,
365 .error_value,
366 => return main_tokens[n] - end_offset,
367
368 .array_init_dot,
369 .array_init_dot_comma,
370 .array_init_dot_two,
371 .array_init_dot_two_comma,
372 .struct_init_dot,
373 .struct_init_dot_comma,
374 .struct_init_dot_two,
375 .struct_init_dot_two_comma,
376 .enum_literal,
377 => return main_tokens[n] - 1 - end_offset,
378
379 .@"catch",
380 .field_access,
381 .unwrap_optional,
382 .equal_equal,
383 .bang_equal,
384 .less_than,
385 .greater_than,
386 .less_or_equal,
387 .greater_or_equal,
388 .assign_mul,
389 .assign_div,
390 .assign_mod,
391 .assign_add,
392 .assign_sub,
393 .assign_bit_shift_left,
394 .assign_bit_shift_right,
395 .assign_bit_and,
396 .assign_bit_xor,
397 .assign_bit_or,
398 .assign_mul_wrap,
399 .assign_add_wrap,
400 .assign_sub_wrap,
401 .assign,
402 .merge_error_sets,
403 .mul,
404 .div,
405 .mod,
406 .array_mult,
407 .mul_wrap,
408 .add,
409 .sub,
410 .array_cat,
411 .add_wrap,
412 .sub_wrap,
413 .bit_shift_left,
414 .bit_shift_right,
415 .bit_and,
416 .bit_xor,
417 .bit_or,
418 .@"orelse",
419 .bool_and,
420 .bool_or,
421 .slice_open,
422 .slice,
423 .slice_sentinel,
424 .deref,
425 .array_access,
426 .array_init_one,
427 .array_init_one_comma,
428 .array_init,
429 .array_init_comma,
430 .struct_init_one,
431 .struct_init_one_comma,
432 .struct_init,
433 .struct_init_comma,
434 .call_one,
435 .call_one_comma,
436 .call,
437 .call_comma,
438 .switch_range,
439 .error_union,
440 => n = datas[n].lhs,
441
442 .fn_decl,
443 .fn_proto_simple,
444 .fn_proto_multi,
445 .fn_proto_one,
446 .fn_proto,
447 => {
448 var i = main_tokens[n]; // fn token
449 while (i > 0) {
450 i -= 1;
451 switch (token_tags[i]) {
452 .keyword_extern,
453 .keyword_export,
454 .keyword_pub,
455 .keyword_inline,
456 .keyword_noinline,
457 .string_literal,
458 => continue,
459
460 else => return i + 1 - end_offset,
461 }
462 }
463 return i - end_offset;
464 },
465
466 .@"usingnamespace" => {
467 const main_token = main_tokens[n];
468 if (main_token > 0 and token_tags[main_token - 1] == .keyword_pub) {
469 end_offset += 1;
470 }
471 return main_token - end_offset;
472 },
473
474 .async_call_one,
475 .async_call_one_comma,
476 .async_call,
477 .async_call_comma,
478 => {
479 end_offset += 1; // async token
480 n = datas[n].lhs;
481 },
482
483 .container_field_init,
484 .container_field_align,
485 .container_field,
486 => {
487 const name_token = main_tokens[n];
488 if (name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) {
489 end_offset += 1;
490 }
491 return name_token - end_offset;
492 },
493
494 .global_var_decl,
495 .local_var_decl,
496 .simple_var_decl,
497 .aligned_var_decl,
498 => {
499 var i = main_tokens[n]; // mut token
500 while (i > 0) {
501 i -= 1;
502 switch (token_tags[i]) {
503 .keyword_extern,
504 .keyword_export,
505 .keyword_comptime,
506 .keyword_pub,
507 .keyword_threadlocal,
508 .string_literal,
509 => continue,
510
511 else => return i + 1 - end_offset,
512 }
513 }
514 return i - end_offset;
515 },
516
517 .block,
518 .block_semicolon,
519 .block_two,
520 .block_two_semicolon,
521 => {
522 // Look for a label.
523 const lbrace = main_tokens[n];
524 if (token_tags[lbrace - 1] == .colon and
525 token_tags[lbrace - 2] == .identifier)
526 {
527 end_offset += 2;
528 }
529 return lbrace - end_offset;
530 },
531
532 .container_decl,
533 .container_decl_trailing,
534 .container_decl_two,
535 .container_decl_two_trailing,
536 .container_decl_arg,
537 .container_decl_arg_trailing,
538 .tagged_union,
539 .tagged_union_trailing,
540 .tagged_union_two,
541 .tagged_union_two_trailing,
542 .tagged_union_enum_tag,
543 .tagged_union_enum_tag_trailing,
544 => {
545 const main_token = main_tokens[n];
546 switch (token_tags[main_token - 1]) {
547 .keyword_packed, .keyword_extern => end_offset += 1,
548 else => {},
549 }
550 return main_token - end_offset;
551 },
552
553 .ptr_type_aligned,
554 .ptr_type_sentinel,
555 .ptr_type,
556 .ptr_type_bit_range,
557 => {
558 const main_token = main_tokens[n];
559 return switch (token_tags[main_token]) {
560 .asterisk,
561 .asterisk_asterisk,
562 => switch (token_tags[main_token - 1]) {
563 .l_bracket => main_token - 1,
564 else => main_token,
565 },
566 .l_bracket => main_token,
567 else => unreachable,
568 } - end_offset;
569 },
570
571 .switch_case_one => {
572 if (datas[n].lhs == 0) {
573 return main_tokens[n] - 1 - end_offset; // else token
574 } else {
575 n = datas[n].lhs;
576 }
577 },
578 .switch_case => {
579 const extra = tree.extraData(datas[n].lhs, Node.SubRange);
580 assert(extra.end - extra.start > 0);
581 n = tree.extra_data[extra.start];
582 },
583
584 .asm_output, .asm_input => {
585 assert(token_tags[main_tokens[n] - 1] == .l_bracket);
586 return main_tokens[n] - 1 - end_offset;
587 },
588
589 .while_simple,
590 .while_cont,
591 .@"while",
592 .for_simple,
593 .@"for",
594 => {
595 // Look for a label and inline.
596 const main_token = main_tokens[n];
597 var result = main_token;
598 if (token_tags[result - 1] == .keyword_inline) {
599 result -= 1;
600 }
601 if (token_tags[result - 1] == .colon) {
602 result -= 2;
603 }
604 return result - end_offset;
605 },
606 };
607 }
608
609 pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex {
610 const tags = tree.nodes.items(.tag);
611 const datas = tree.nodes.items(.data);
612 const main_tokens = tree.nodes.items(.main_token);
613 const token_starts = tree.tokens.items(.start);
614 const token_tags = tree.tokens.items(.tag);
615 var n = node;
616 var end_offset: TokenIndex = 0;
617 while (true) switch (tags[n]) {
618 .root => return @intCast(TokenIndex, tree.tokens.len - 1),
619
620 .@"usingnamespace",
621 .bool_not,
622 .negation,
623 .bit_not,
624 .negation_wrap,
625 .address_of,
626 .@"try",
627 .@"await",
628 .optional_type,
629 .@"resume",
630 .@"nosuspend",
631 .@"comptime",
632 => n = datas[n].lhs,
633
634 .test_decl,
635 .@"errdefer",
636 .@"defer",
637 .@"catch",
638 .equal_equal,
639 .bang_equal,
640 .less_than,
641 .greater_than,
642 .less_or_equal,
643 .greater_or_equal,
644 .assign_mul,
645 .assign_div,
646 .assign_mod,
647 .assign_add,
648 .assign_sub,
649 .assign_bit_shift_left,
650 .assign_bit_shift_right,
651 .assign_bit_and,
652 .assign_bit_xor,
653 .assign_bit_or,
654 .assign_mul_wrap,
655 .assign_add_wrap,
656 .assign_sub_wrap,
657 .assign,
658 .merge_error_sets,
659 .mul,
660 .div,
661 .mod,
662 .array_mult,
663 .mul_wrap,
664 .add,
665 .sub,
666 .array_cat,
667 .add_wrap,
668 .sub_wrap,
669 .bit_shift_left,
670 .bit_shift_right,
671 .bit_and,
672 .bit_xor,
673 .bit_or,
674 .@"orelse",
675 .bool_and,
676 .bool_or,
677 .anyframe_type,
678 .error_union,
679 .if_simple,
680 .while_simple,
681 .for_simple,
682 .fn_proto_simple,
683 .fn_proto_multi,
684 .ptr_type_aligned,
685 .ptr_type_sentinel,
686 .ptr_type,
687 .ptr_type_bit_range,
688 .array_type,
689 .switch_case_one,
690 .switch_case,
691 .switch_range,
692 => n = datas[n].rhs,
693
694 .field_access,
695 .unwrap_optional,
696 .grouped_expression,
697 .multiline_string_literal,
698 .error_set_decl,
699 .asm_simple,
700 .asm_output,
701 .asm_input,
702 .error_value,
703 => return datas[n].rhs + end_offset,
704
705 .@"anytype",
706 .anyframe_literal,
707 .char_literal,
708 .integer_literal,
709 .float_literal,
710 .unreachable_literal,
711 .identifier,
712 .deref,
713 .enum_literal,
714 .string_literal,
715 => return main_tokens[n] + end_offset,
716
717 .@"return" => if (datas[n].lhs != 0) {
718 n = datas[n].lhs;
719 } else {
720 return main_tokens[n] + end_offset;
721 },
722
723 .call, .async_call => {
724 end_offset += 1; // for the rparen
725 const params = tree.extraData(datas[n].rhs, Node.SubRange);
726 if (params.end - params.start == 0) {
727 return main_tokens[n] + end_offset;
728 }
729 n = tree.extra_data[params.end - 1]; // last parameter
730 },
731 .tagged_union_enum_tag => {
732 const members = tree.extraData(datas[n].rhs, Node.SubRange);
733 if (members.end - members.start == 0) {
734 end_offset += 4; // for the rparen + rparen + lbrace + rbrace
735 n = datas[n].lhs;
736 } else {
737 end_offset += 1; // for the rbrace
738 n = tree.extra_data[members.end - 1]; // last parameter
739 }
740 },
741 .call_comma,
742 .async_call_comma,
743 .tagged_union_enum_tag_trailing,
744 => {
745 end_offset += 2; // for the comma/semicolon + rparen/rbrace
746 const params = tree.extraData(datas[n].rhs, Node.SubRange);
747 assert(params.end > params.start);
748 n = tree.extra_data[params.end - 1]; // last parameter
749 },
750 .@"switch" => {
751 const cases = tree.extraData(datas[n].rhs, Node.SubRange);
752 if (cases.end - cases.start == 0) {
753 end_offset += 3; // rparen, lbrace, rbrace
754 n = datas[n].lhs; // condition expression
755 } else {
756 end_offset += 1; // for the rbrace
757 n = tree.extra_data[cases.end - 1]; // last case
758 }
759 },
760 .container_decl_arg => {
761 const members = tree.extraData(datas[n].rhs, Node.SubRange);
762 if (members.end - members.start == 0) {
763 end_offset += 3; // for the rparen + lbrace + rbrace
764 n = datas[n].lhs;
765 } else {
766 end_offset += 1; // for the rbrace
767 n = tree.extra_data[members.end - 1]; // last parameter
768 }
769 },
770 .@"asm" => {
771 const extra = tree.extraData(datas[n].rhs, Node.Asm);
772 return extra.rparen + end_offset;
773 },
774 .array_init,
775 .struct_init,
776 => {
777 const elements = tree.extraData(datas[n].rhs, Node.SubRange);
778 assert(elements.end - elements.start > 0);
779 end_offset += 1; // for the rbrace
780 n = tree.extra_data[elements.end - 1]; // last element
781 },
782 .array_init_comma,
783 .struct_init_comma,
784 .container_decl_arg_trailing,
785 .switch_comma,
786 => {
787 const members = tree.extraData(datas[n].rhs, Node.SubRange);
788 assert(members.end - members.start > 0);
789 end_offset += 2; // for the comma + rbrace
790 n = tree.extra_data[members.end - 1]; // last parameter
791 },
792 .array_init_dot,
793 .struct_init_dot,
794 .block,
795 .container_decl,
796 .tagged_union,
797 .builtin_call,
798 => {
799 assert(datas[n].rhs - datas[n].lhs > 0);
800 end_offset += 1; // for the rbrace
801 n = tree.extra_data[datas[n].rhs - 1]; // last statement
802 },
803 .array_init_dot_comma,
804 .struct_init_dot_comma,
805 .block_semicolon,
806 .container_decl_trailing,
807 .tagged_union_trailing,
808 .builtin_call_comma,
809 => {
810 assert(datas[n].rhs - datas[n].lhs > 0);
811 end_offset += 2; // for the comma/semicolon + rbrace/rparen
812 n = tree.extra_data[datas[n].rhs - 1]; // last member
813 },
814 .call_one,
815 .async_call_one,
816 .array_access,
817 => {
818 end_offset += 1; // for the rparen/rbracket
819 if (datas[n].rhs == 0) {
820 return main_tokens[n] + end_offset;
821 }
822 n = datas[n].rhs;
823 },
824 .array_init_dot_two,
825 .block_two,
826 .builtin_call_two,
827 .struct_init_dot_two,
828 .container_decl_two,
829 .tagged_union_two,
830 => {
831 if (datas[n].rhs != 0) {
832 end_offset += 1; // for the rparen/rbrace
833 n = datas[n].rhs;
834 } else if (datas[n].lhs != 0) {
835 end_offset += 1; // for the rparen/rbrace
836 n = datas[n].lhs;
837 } else {
838 switch (tags[n]) {
839 .array_init_dot_two,
840 .block_two,
841 .struct_init_dot_two,
842 => end_offset += 1, // rbrace
843 .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace
844 .container_decl_two => {
845 var i: u32 = 2; // lbrace + rbrace
846 while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1;
847 end_offset += i;
848 },
849 .tagged_union_two => {
850 var i: u32 = 5; // (enum) {}
851 while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1;
852 end_offset += i;
853 },
854 else => unreachable,
855 }
856 return main_tokens[n] + end_offset;
857 }
858 },
859 .array_init_dot_two_comma,
860 .builtin_call_two_comma,
861 .block_two_semicolon,
862 .struct_init_dot_two_comma,
863 .container_decl_two_trailing,
864 .tagged_union_two_trailing,
865 => {
866 end_offset += 2; // for the comma/semicolon + rbrace/rparen
867 if (datas[n].rhs != 0) {
868 n = datas[n].rhs;
869 } else if (datas[n].lhs != 0) {
870 n = datas[n].lhs;
871 } else {
872 unreachable;
873 }
874 },
875 .simple_var_decl => {
876 if (datas[n].rhs != 0) {
877 n = datas[n].rhs;
878 } else if (datas[n].lhs != 0) {
879 n = datas[n].lhs;
880 } else {
881 end_offset += 1; // from mut token to name
882 return main_tokens[n] + end_offset;
883 }
884 },
885 .aligned_var_decl => {
886 if (datas[n].rhs != 0) {
887 n = datas[n].rhs;
888 } else if (datas[n].lhs != 0) {
889 end_offset += 1; // for the rparen
890 n = datas[n].lhs;
891 } else {
892 end_offset += 1; // from mut token to name
893 return main_tokens[n] + end_offset;
894 }
895 },
896 .global_var_decl => {
897 if (datas[n].rhs != 0) {
898 n = datas[n].rhs;
899 } else {
900 const extra = tree.extraData(datas[n].lhs, Node.GlobalVarDecl);
901 if (extra.section_node != 0) {
902 end_offset += 1; // for the rparen
903 n = extra.section_node;
904 } else if (extra.align_node != 0) {
905 end_offset += 1; // for the rparen
906 n = extra.align_node;
907 } else if (extra.type_node != 0) {
908 n = extra.type_node;
909 } else {
910 end_offset += 1; // from mut token to name
911 return main_tokens[n] + end_offset;
912 }
913 }
914 },
915 .local_var_decl => {
916 if (datas[n].rhs != 0) {
917 n = datas[n].rhs;
918 } else {
919 const extra = tree.extraData(datas[n].lhs, Node.LocalVarDecl);
920 if (extra.align_node != 0) {
921 end_offset += 1; // for the rparen
922 n = extra.align_node;
923 } else if (extra.type_node != 0) {
924 n = extra.type_node;
925 } else {
926 end_offset += 1; // from mut token to name
927 return main_tokens[n] + end_offset;
928 }
929 }
930 },
931 .container_field_init => {
932 if (datas[n].rhs != 0) {
933 n = datas[n].rhs;
934 } else if (datas[n].lhs != 0) {
935 n = datas[n].lhs;
936 } else {
937 return main_tokens[n] + end_offset;
938 }
939 },
940 .container_field_align => {
941 if (datas[n].rhs != 0) {
942 end_offset += 1; // for the rparen
943 n = datas[n].rhs;
944 } else if (datas[n].lhs != 0) {
945 n = datas[n].lhs;
946 } else {
947 return main_tokens[n] + end_offset;
948 }
949 },
950 .container_field => {
951 const extra = tree.extraData(datas[n].rhs, Node.ContainerField);
952 if (extra.value_expr != 0) {
953 n = extra.value_expr;
954 } else if (extra.align_expr != 0) {
955 end_offset += 1; // for the rparen
956 n = extra.align_expr;
957 } else if (datas[n].lhs != 0) {
958 n = datas[n].lhs;
959 } else {
960 return main_tokens[n] + end_offset;
961 }
962 },
963
964 .array_init_one,
965 .struct_init_one,
966 => {
967 end_offset += 1; // rbrace
968 if (datas[n].rhs == 0) {
969 return main_tokens[n] + end_offset;
970 } else {
971 n = datas[n].rhs;
972 }
973 },
974 .slice_open,
975 .call_one_comma,
976 .async_call_one_comma,
977 .array_init_one_comma,
978 .struct_init_one_comma,
979 => {
980 end_offset += 2; // ellipsis2 + rbracket, or comma + rparen
981 n = datas[n].rhs;
982 assert(n != 0);
983 },
984 .slice => {
985 const extra = tree.extraData(datas[n].rhs, Node.Slice);
986 assert(extra.end != 0); // should have used slice_open
987 end_offset += 1; // rbracket
988 n = extra.end;
989 },
990 .slice_sentinel => {
991 const extra = tree.extraData(datas[n].rhs, Node.SliceSentinel);
992 assert(extra.sentinel != 0); // should have used slice
993 end_offset += 1; // rbracket
994 n = extra.sentinel;
995 },
996
997 .@"continue" => {
998 if (datas[n].lhs != 0) {
999 return datas[n].lhs + end_offset;
1000 } else {
1001 return main_tokens[n] + end_offset;
1002 }
1003 },
1004 .@"break" => {
1005 if (datas[n].rhs != 0) {
1006 n = datas[n].rhs;
1007 } else if (datas[n].lhs != 0) {
1008 return datas[n].lhs + end_offset;
1009 } else {
1010 return main_tokens[n] + end_offset;
1011 }
1012 },
1013 .fn_decl => {
1014 if (datas[n].rhs != 0) {
1015 n = datas[n].rhs;
1016 } else {
1017 n = datas[n].lhs;
1018 }
1019 },
1020 .fn_proto_one => {
1021 const extra = tree.extraData(datas[n].lhs, Node.FnProtoOne);
1022 // linksection, callconv, align can appear in any order, so we
1023 // find the last one here.
1024 var max_node: Node.Index = datas[n].rhs;
1025 var max_start = token_starts[main_tokens[max_node]];
1026 var max_offset: TokenIndex = 0;
1027 if (extra.align_expr != 0) {
1028 const start = token_starts[main_tokens[extra.align_expr]];
1029 if (start > max_start) {
1030 max_node = extra.align_expr;
1031 max_start = start;
1032 max_offset = 1; // for the rparen
1033 }
1034 }
1035 if (extra.section_expr != 0) {
1036 const start = token_starts[main_tokens[extra.section_expr]];
1037 if (start > max_start) {
1038 max_node = extra.section_expr;
1039 max_start = start;
1040 max_offset = 1; // for the rparen
1041 }
1042 }
1043 if (extra.callconv_expr != 0) {
1044 const start = token_starts[main_tokens[extra.callconv_expr]];
1045 if (start > max_start) {
1046 max_node = extra.callconv_expr;
1047 max_start = start;
1048 max_offset = 1; // for the rparen
1049 }
1050 }
1051 n = max_node;
1052 end_offset += max_offset;
1053 },
1054 .fn_proto => {
1055 const extra = tree.extraData(datas[n].lhs, Node.FnProto);
1056 // linksection, callconv, align can appear in any order, so we
1057 // find the last one here.
1058 var max_node: Node.Index = datas[n].rhs;
1059 var max_start = token_starts[main_tokens[max_node]];
1060 var max_offset: TokenIndex = 0;
1061 if (extra.align_expr != 0) {
1062 const start = token_starts[main_tokens[extra.align_expr]];
1063 if (start > max_start) {
1064 max_node = extra.align_expr;
1065 max_start = start;
1066 max_offset = 1; // for the rparen
1067 }
1068 }
1069 if (extra.section_expr != 0) {
1070 const start = token_starts[main_tokens[extra.section_expr]];
1071 if (start > max_start) {
1072 max_node = extra.section_expr;
1073 max_start = start;
1074 max_offset = 1; // for the rparen
1075 }
1076 }
1077 if (extra.callconv_expr != 0) {
1078 const start = token_starts[main_tokens[extra.callconv_expr]];
1079 if (start > max_start) {
1080 max_node = extra.callconv_expr;
1081 max_start = start;
1082 max_offset = 1; // for the rparen
1083 }
1084 }
1085 n = max_node;
1086 end_offset += max_offset;
1087 },
1088 .while_cont => {
1089 const extra = tree.extraData(datas[n].rhs, Node.WhileCont);
1090 assert(extra.then_expr != 0);
1091 n = extra.then_expr;
1092 },
1093 .@"while" => {
1094 const extra = tree.extraData(datas[n].rhs, Node.While);
1095 assert(extra.else_expr != 0);
1096 n = extra.else_expr;
1097 },
1098 .@"if", .@"for" => {
1099 const extra = tree.extraData(datas[n].rhs, Node.If);
1100 assert(extra.else_expr != 0);
1101 n = extra.else_expr;
1102 },
1103 .@"suspend" => {
1104 if (datas[n].lhs != 0) {
1105 n = datas[n].lhs;
1106 } else {
1107 return main_tokens[n] + end_offset;
1108 }
1109 },
1110 .array_type_sentinel => {
1111 const extra = tree.extraData(datas[n].rhs, Node.ArrayTypeSentinel);
1112 n = extra.elem_type;
1113 },
1114 };
1115 }
1116
1117 pub fn tokensOnSameLine(tree: Tree, token1: TokenIndex, token2: TokenIndex) bool {
1118 const token_starts = tree.tokens.items(.start);
1119 const source = tree.source[token_starts[token1]..token_starts[token2]];
1120 return mem.indexOfScalar(u8, source, '\n') == null;
1121 }
1122
1123 pub fn getNodeSource(tree: Tree, node: Node.Index) []const u8 {
1124 const token_starts = tree.tokens.items(.start);
1125 const first_token = tree.firstToken(node);
1126 const last_token = tree.lastToken(node);
1127 const start = token_starts[first_token];
1128 const end = token_starts[last_token] + tree.tokenSlice(last_token).len;
1129 return tree.source[start..end];
1130 }
1131
1132 pub fn globalVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1133 assert(tree.nodes.items(.tag)[node] == .global_var_decl);
1134 const data = tree.nodes.items(.data)[node];
1135 const extra = tree.extraData(data.lhs, Node.GlobalVarDecl);
1136 return tree.fullVarDecl(.{
1137 .type_node = extra.type_node,
1138 .align_node = extra.align_node,
1139 .section_node = extra.section_node,
1140 .init_node = data.rhs,
1141 .mut_token = tree.nodes.items(.main_token)[node],
1142 });
1143 }
1144
1145 pub fn localVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1146 assert(tree.nodes.items(.tag)[node] == .local_var_decl);
1147 const data = tree.nodes.items(.data)[node];
1148 const extra = tree.extraData(data.lhs, Node.LocalVarDecl);
1149 return tree.fullVarDecl(.{
1150 .type_node = extra.type_node,
1151 .align_node = extra.align_node,
1152 .section_node = 0,
1153 .init_node = data.rhs,
1154 .mut_token = tree.nodes.items(.main_token)[node],
1155 });
1156 }
1157
1158 pub fn simpleVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1159 assert(tree.nodes.items(.tag)[node] == .simple_var_decl);
1160 const data = tree.nodes.items(.data)[node];
1161 return tree.fullVarDecl(.{
1162 .type_node = data.lhs,
1163 .align_node = 0,
1164 .section_node = 0,
1165 .init_node = data.rhs,
1166 .mut_token = tree.nodes.items(.main_token)[node],
1167 });
1168 }
1169
1170 pub fn alignedVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1171 assert(tree.nodes.items(.tag)[node] == .aligned_var_decl);
1172 const data = tree.nodes.items(.data)[node];
1173 return tree.fullVarDecl(.{
1174 .type_node = 0,
1175 .align_node = data.lhs,
1176 .section_node = 0,
1177 .init_node = data.rhs,
1178 .mut_token = tree.nodes.items(.main_token)[node],
1179 });
1180 }
1181
1182 pub fn ifSimple(tree: Tree, node: Node.Index) full.If {
1183 assert(tree.nodes.items(.tag)[node] == .if_simple);
1184 const data = tree.nodes.items(.data)[node];
1185 return tree.fullIf(.{
1186 .cond_expr = data.lhs,
1187 .then_expr = data.rhs,
1188 .else_expr = 0,
1189 .if_token = tree.nodes.items(.main_token)[node],
1190 });
1191 }
1192
1193 pub fn ifFull(tree: Tree, node: Node.Index) full.If {
1194 assert(tree.nodes.items(.tag)[node] == .@"if");
1195 const data = tree.nodes.items(.data)[node];
1196 const extra = tree.extraData(data.rhs, Node.If);
1197 return tree.fullIf(.{
1198 .cond_expr = data.lhs,
1199 .then_expr = extra.then_expr,
1200 .else_expr = extra.else_expr,
1201 .if_token = tree.nodes.items(.main_token)[node],
1202 });
1203 }
1204
1205 pub fn containerField(tree: Tree, node: Node.Index) full.ContainerField {
1206 assert(tree.nodes.items(.tag)[node] == .container_field);
1207 const data = tree.nodes.items(.data)[node];
1208 const extra = tree.extraData(data.rhs, Node.ContainerField);
1209 return tree.fullContainerField(.{
1210 .name_token = tree.nodes.items(.main_token)[node],
1211 .type_expr = data.lhs,
1212 .value_expr = extra.value_expr,
1213 .align_expr = extra.align_expr,
1214 });
1215 }
1216
1217 pub fn containerFieldInit(tree: Tree, node: Node.Index) full.ContainerField {
1218 assert(tree.nodes.items(.tag)[node] == .container_field_init);
1219 const data = tree.nodes.items(.data)[node];
1220 return tree.fullContainerField(.{
1221 .name_token = tree.nodes.items(.main_token)[node],
1222 .type_expr = data.lhs,
1223 .value_expr = data.rhs,
1224 .align_expr = 0,
1225 });
1226 }
1227
1228 pub fn containerFieldAlign(tree: Tree, node: Node.Index) full.ContainerField {
1229 assert(tree.nodes.items(.tag)[node] == .container_field_align);
1230 const data = tree.nodes.items(.data)[node];
1231 return tree.fullContainerField(.{
1232 .name_token = tree.nodes.items(.main_token)[node],
1233 .type_expr = data.lhs,
1234 .value_expr = 0,
1235 .align_expr = data.rhs,
1236 });
1237 }
1238
1239 pub fn fnProtoSimple(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
1240 assert(tree.nodes.items(.tag)[node] == .fn_proto_simple);
1241 const data = tree.nodes.items(.data)[node];
1242 buffer[0] = data.lhs;
1243 const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1];
1244 return tree.fullFnProto(.{
1245 .proto_node = node,
1246 .fn_token = tree.nodes.items(.main_token)[node],
1247 .return_type = data.rhs,
1248 .params = params,
1249 .align_expr = 0,
1250 .section_expr = 0,
1251 .callconv_expr = 0,
1252 });
1253 }
1254
1255 pub fn fnProtoMulti(tree: Tree, node: Node.Index) full.FnProto {
1256 assert(tree.nodes.items(.tag)[node] == .fn_proto_multi);
1257 const data = tree.nodes.items(.data)[node];
1258 const params_range = tree.extraData(data.lhs, Node.SubRange);
1259 const params = tree.extra_data[params_range.start..params_range.end];
1260 return tree.fullFnProto(.{
1261 .proto_node = node,
1262 .fn_token = tree.nodes.items(.main_token)[node],
1263 .return_type = data.rhs,
1264 .params = params,
1265 .align_expr = 0,
1266 .section_expr = 0,
1267 .callconv_expr = 0,
1268 });
1269 }
1270
1271 pub fn fnProtoOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
1272 assert(tree.nodes.items(.tag)[node] == .fn_proto_one);
1273 const data = tree.nodes.items(.data)[node];
1274 const extra = tree.extraData(data.lhs, Node.FnProtoOne);
1275 buffer[0] = extra.param;
1276 const params = if (extra.param == 0) buffer[0..0] else buffer[0..1];
1277 return tree.fullFnProto(.{
1278 .proto_node = node,
1279 .fn_token = tree.nodes.items(.main_token)[node],
1280 .return_type = data.rhs,
1281 .params = params,
1282 .align_expr = extra.align_expr,
1283 .section_expr = extra.section_expr,
1284 .callconv_expr = extra.callconv_expr,
1285 });
1286 }
1287
1288 pub fn fnProto(tree: Tree, node: Node.Index) full.FnProto {
1289 assert(tree.nodes.items(.tag)[node] == .fn_proto);
1290 const data = tree.nodes.items(.data)[node];
1291 const extra = tree.extraData(data.lhs, Node.FnProto);
1292 const params = tree.extra_data[extra.params_start..extra.params_end];
1293 return tree.fullFnProto(.{
1294 .proto_node = node,
1295 .fn_token = tree.nodes.items(.main_token)[node],
1296 .return_type = data.rhs,
1297 .params = params,
1298 .align_expr = extra.align_expr,
1299 .section_expr = extra.section_expr,
1300 .callconv_expr = extra.callconv_expr,
1301 });
1302 }
1303
1304 pub fn structInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.StructInit {
1305 assert(tree.nodes.items(.tag)[node] == .struct_init_one or
1306 tree.nodes.items(.tag)[node] == .struct_init_one_comma);
1307 const data = tree.nodes.items(.data)[node];
1308 buffer[0] = data.rhs;
1309 const fields = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
1310 return tree.fullStructInit(.{
1311 .lbrace = tree.nodes.items(.main_token)[node],
1312 .fields = fields,
1313 .type_expr = data.lhs,
1314 });
1315 }
1316
1317 pub fn structInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.StructInit {
1318 assert(tree.nodes.items(.tag)[node] == .struct_init_dot_two or
1319 tree.nodes.items(.tag)[node] == .struct_init_dot_two_comma);
1320 const data = tree.nodes.items(.data)[node];
1321 buffer.* = .{ data.lhs, data.rhs };
1322 const fields = if (data.rhs != 0)
1323 buffer[0..2]
1324 else if (data.lhs != 0)
1325 buffer[0..1]
1326 else
1327 buffer[0..0];
1328 return tree.fullStructInit(.{
1329 .lbrace = tree.nodes.items(.main_token)[node],
1330 .fields = fields,
1331 .type_expr = 0,
1332 });
1333 }
1334
1335 pub fn structInitDot(tree: Tree, node: Node.Index) full.StructInit {
1336 assert(tree.nodes.items(.tag)[node] == .struct_init_dot or
1337 tree.nodes.items(.tag)[node] == .struct_init_dot_comma);
1338 const data = tree.nodes.items(.data)[node];
1339 return tree.fullStructInit(.{
1340 .lbrace = tree.nodes.items(.main_token)[node],
1341 .fields = tree.extra_data[data.lhs..data.rhs],
1342 .type_expr = 0,
1343 });
1344 }
1345
1346 pub fn structInit(tree: Tree, node: Node.Index) full.StructInit {
1347 assert(tree.nodes.items(.tag)[node] == .struct_init or
1348 tree.nodes.items(.tag)[node] == .struct_init_comma);
1349 const data = tree.nodes.items(.data)[node];
1350 const fields_range = tree.extraData(data.rhs, Node.SubRange);
1351 return tree.fullStructInit(.{
1352 .lbrace = tree.nodes.items(.main_token)[node],
1353 .fields = tree.extra_data[fields_range.start..fields_range.end],
1354 .type_expr = data.lhs,
1355 });
1356 }
1357
1358 pub fn arrayInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit {
1359 assert(tree.nodes.items(.tag)[node] == .array_init_one or
1360 tree.nodes.items(.tag)[node] == .array_init_one_comma);
1361 const data = tree.nodes.items(.data)[node];
1362 buffer[0] = data.rhs;
1363 const elements = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
1364 return .{
1365 .ast = .{
1366 .lbrace = tree.nodes.items(.main_token)[node],
1367 .elements = elements,
1368 .type_expr = data.lhs,
1369 },
1370 };
1371 }
1372
1373 pub fn arrayInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit {
1374 assert(tree.nodes.items(.tag)[node] == .array_init_dot_two or
1375 tree.nodes.items(.tag)[node] == .array_init_dot_two_comma);
1376 const data = tree.nodes.items(.data)[node];
1377 buffer.* = .{ data.lhs, data.rhs };
1378 const elements = if (data.rhs != 0)
1379 buffer[0..2]
1380 else if (data.lhs != 0)
1381 buffer[0..1]
1382 else
1383 buffer[0..0];
1384 return .{
1385 .ast = .{
1386 .lbrace = tree.nodes.items(.main_token)[node],
1387 .elements = elements,
1388 .type_expr = 0,
1389 },
1390 };
1391 }
1392
1393 pub fn arrayInitDot(tree: Tree, node: Node.Index) full.ArrayInit {
1394 assert(tree.nodes.items(.tag)[node] == .array_init_dot or
1395 tree.nodes.items(.tag)[node] == .array_init_dot_comma);
1396 const data = tree.nodes.items(.data)[node];
1397 return .{
1398 .ast = .{
1399 .lbrace = tree.nodes.items(.main_token)[node],
1400 .elements = tree.extra_data[data.lhs..data.rhs],
1401 .type_expr = 0,
1402 },
1403 };
1404 }
1405
1406 pub fn arrayInit(tree: Tree, node: Node.Index) full.ArrayInit {
1407 assert(tree.nodes.items(.tag)[node] == .array_init or
1408 tree.nodes.items(.tag)[node] == .array_init_comma);
1409 const data = tree.nodes.items(.data)[node];
1410 const elem_range = tree.extraData(data.rhs, Node.SubRange);
1411 return .{
1412 .ast = .{
1413 .lbrace = tree.nodes.items(.main_token)[node],
1414 .elements = tree.extra_data[elem_range.start..elem_range.end],
1415 .type_expr = data.lhs,
1416 },
1417 };
1418 }
1419
1420 pub fn arrayType(tree: Tree, node: Node.Index) full.ArrayType {
1421 assert(tree.nodes.items(.tag)[node] == .array_type);
1422 const data = tree.nodes.items(.data)[node];
1423 return .{
1424 .ast = .{
1425 .lbracket = tree.nodes.items(.main_token)[node],
1426 .elem_count = data.lhs,
1427 .sentinel = 0,
1428 .elem_type = data.rhs,
1429 },
1430 };
1431 }
1432
1433 pub fn arrayTypeSentinel(tree: Tree, node: Node.Index) full.ArrayType {
1434 assert(tree.nodes.items(.tag)[node] == .array_type_sentinel);
1435 const data = tree.nodes.items(.data)[node];
1436 const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);
1437 assert(extra.sentinel != 0);
1438 return .{
1439 .ast = .{
1440 .lbracket = tree.nodes.items(.main_token)[node],
1441 .elem_count = data.lhs,
1442 .sentinel = extra.sentinel,
1443 .elem_type = extra.elem_type,
1444 },
1445 };
1446 }
1447
1448 pub fn ptrTypeAligned(tree: Tree, node: Node.Index) full.PtrType {
1449 assert(tree.nodes.items(.tag)[node] == .ptr_type_aligned);
1450 const data = tree.nodes.items(.data)[node];
1451 return tree.fullPtrType(.{
1452 .main_token = tree.nodes.items(.main_token)[node],
1453 .align_node = data.lhs,
1454 .sentinel = 0,
1455 .bit_range_start = 0,
1456 .bit_range_end = 0,
1457 .child_type = data.rhs,
1458 });
1459 }
1460
1461 pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) full.PtrType {
1462 assert(tree.nodes.items(.tag)[node] == .ptr_type_sentinel);
1463 const data = tree.nodes.items(.data)[node];
1464 return tree.fullPtrType(.{
1465 .main_token = tree.nodes.items(.main_token)[node],
1466 .align_node = 0,
1467 .sentinel = data.lhs,
1468 .bit_range_start = 0,
1469 .bit_range_end = 0,
1470 .child_type = data.rhs,
1471 });
1472 }
1473
1474 pub fn ptrType(tree: Tree, node: Node.Index) full.PtrType {
1475 assert(tree.nodes.items(.tag)[node] == .ptr_type);
1476 const data = tree.nodes.items(.data)[node];
1477 const extra = tree.extraData(data.lhs, Node.PtrType);
1478 return tree.fullPtrType(.{
1479 .main_token = tree.nodes.items(.main_token)[node],
1480 .align_node = extra.align_node,
1481 .sentinel = extra.sentinel,
1482 .bit_range_start = 0,
1483 .bit_range_end = 0,
1484 .child_type = data.rhs,
1485 });
1486 }
1487
1488 pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) full.PtrType {
1489 assert(tree.nodes.items(.tag)[node] == .ptr_type_bit_range);
1490 const data = tree.nodes.items(.data)[node];
1491 const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange);
1492 return tree.fullPtrType(.{
1493 .main_token = tree.nodes.items(.main_token)[node],
1494 .align_node = extra.align_node,
1495 .sentinel = extra.sentinel,
1496 .bit_range_start = extra.bit_range_start,
1497 .bit_range_end = extra.bit_range_end,
1498 .child_type = data.rhs,
1499 });
1500 }
1501
1502 pub fn sliceOpen(tree: Tree, node: Node.Index) full.Slice {
1503 assert(tree.nodes.items(.tag)[node] == .slice_open);
1504 const data = tree.nodes.items(.data)[node];
1505 return .{
1506 .ast = .{
1507 .sliced = data.lhs,
1508 .lbracket = tree.nodes.items(.main_token)[node],
1509 .start = data.rhs,
1510 .end = 0,
1511 .sentinel = 0,
1512 },
1513 };
1514 }
1515
1516 pub fn slice(tree: Tree, node: Node.Index) full.Slice {
1517 assert(tree.nodes.items(.tag)[node] == .slice);
1518 const data = tree.nodes.items(.data)[node];
1519 const extra = tree.extraData(data.rhs, Node.Slice);
1520 return .{
1521 .ast = .{
1522 .sliced = data.lhs,
1523 .lbracket = tree.nodes.items(.main_token)[node],
1524 .start = extra.start,
1525 .end = extra.end,
1526 .sentinel = 0,
1527 },
1528 };
1529 }
1530
1531 pub fn sliceSentinel(tree: Tree, node: Node.Index) full.Slice {
1532 assert(tree.nodes.items(.tag)[node] == .slice_sentinel);
1533 const data = tree.nodes.items(.data)[node];
1534 const extra = tree.extraData(data.rhs, Node.SliceSentinel);
1535 return .{
1536 .ast = .{
1537 .sliced = data.lhs,
1538 .lbracket = tree.nodes.items(.main_token)[node],
1539 .start = extra.start,
1540 .end = extra.end,
1541 .sentinel = extra.sentinel,
1542 },
1543 };
1544 }
1545
1546 pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
1547 assert(tree.nodes.items(.tag)[node] == .container_decl_two or
1548 tree.nodes.items(.tag)[node] == .container_decl_two_trailing);
1549 const data = tree.nodes.items(.data)[node];
1550 buffer.* = .{ data.lhs, data.rhs };
1551 const members = if (data.rhs != 0)
1552 buffer[0..2]
1553 else if (data.lhs != 0)
1554 buffer[0..1]
1555 else
1556 buffer[0..0];
1557 return tree.fullContainerDecl(.{
1558 .main_token = tree.nodes.items(.main_token)[node],
1559 .enum_token = null,
1560 .members = members,
1561 .arg = 0,
1562 });
1563 }
1564
1565 pub fn containerDecl(tree: Tree, node: Node.Index) full.ContainerDecl {
1566 assert(tree.nodes.items(.tag)[node] == .container_decl or
1567 tree.nodes.items(.tag)[node] == .container_decl_trailing);
1568 const data = tree.nodes.items(.data)[node];
1569 return tree.fullContainerDecl(.{
1570 .main_token = tree.nodes.items(.main_token)[node],
1571 .enum_token = null,
1572 .members = tree.extra_data[data.lhs..data.rhs],
1573 .arg = 0,
1574 });
1575 }
1576
1577 pub fn containerDeclArg(tree: Tree, node: Node.Index) full.ContainerDecl {
1578 assert(tree.nodes.items(.tag)[node] == .container_decl_arg or
1579 tree.nodes.items(.tag)[node] == .container_decl_arg_trailing);
1580 const data = tree.nodes.items(.data)[node];
1581 const members_range = tree.extraData(data.rhs, Node.SubRange);
1582 return tree.fullContainerDecl(.{
1583 .main_token = tree.nodes.items(.main_token)[node],
1584 .enum_token = null,
1585 .members = tree.extra_data[members_range.start..members_range.end],
1586 .arg = data.lhs,
1587 });
1588 }
1589
1590 pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
1591 assert(tree.nodes.items(.tag)[node] == .tagged_union_two or
1592 tree.nodes.items(.tag)[node] == .tagged_union_two_trailing);
1593 const data = tree.nodes.items(.data)[node];
1594 buffer.* = .{ data.lhs, data.rhs };
1595 const members = if (data.rhs != 0)
1596 buffer[0..2]
1597 else if (data.lhs != 0)
1598 buffer[0..1]
1599 else
1600 buffer[0..0];
1601 const main_token = tree.nodes.items(.main_token)[node];
1602 return tree.fullContainerDecl(.{
1603 .main_token = main_token,
1604 .enum_token = main_token + 2, // union lparen enum
1605 .members = members,
1606 .arg = 0,
1607 });
1608 }
1609
1610 pub fn taggedUnion(tree: Tree, node: Node.Index) full.ContainerDecl {
1611 assert(tree.nodes.items(.tag)[node] == .tagged_union or
1612 tree.nodes.items(.tag)[node] == .tagged_union_trailing);
1613 const data = tree.nodes.items(.data)[node];
1614 const main_token = tree.nodes.items(.main_token)[node];
1615 return tree.fullContainerDecl(.{
1616 .main_token = main_token,
1617 .enum_token = main_token + 2, // union lparen enum
1618 .members = tree.extra_data[data.lhs..data.rhs],
1619 .arg = 0,
1620 });
1621 }
1622
1623 pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) full.ContainerDecl {
1624 assert(tree.nodes.items(.tag)[node] == .tagged_union_enum_tag or
1625 tree.nodes.items(.tag)[node] == .tagged_union_enum_tag_trailing);
1626 const data = tree.nodes.items(.data)[node];
1627 const members_range = tree.extraData(data.rhs, Node.SubRange);
1628 const main_token = tree.nodes.items(.main_token)[node];
1629 return tree.fullContainerDecl(.{
1630 .main_token = main_token,
1631 .enum_token = main_token + 2, // union lparen enum
1632 .members = tree.extra_data[members_range.start..members_range.end],
1633 .arg = data.lhs,
1634 });
1635 }
1636
1637 pub fn switchCaseOne(tree: Tree, node: Node.Index) full.SwitchCase {
1638 const data = &tree.nodes.items(.data)[node];
1639 const values: *[1]Node.Index = &data.lhs;
1640 return tree.fullSwitchCase(.{
1641 .values = if (data.lhs == 0) values[0..0] else values[0..1],
1642 .arrow_token = tree.nodes.items(.main_token)[node],
1643 .target_expr = data.rhs,
1644 });
1645 }
1646
1647 pub fn switchCase(tree: Tree, node: Node.Index) full.SwitchCase {
1648 const data = tree.nodes.items(.data)[node];
1649 const extra = tree.extraData(data.lhs, Node.SubRange);
1650 return tree.fullSwitchCase(.{
1651 .values = tree.extra_data[extra.start..extra.end],
1652 .arrow_token = tree.nodes.items(.main_token)[node],
1653 .target_expr = data.rhs,
1654 });
1655 }
1656
1657 pub fn asmSimple(tree: Tree, node: Node.Index) full.Asm {
1658 const data = tree.nodes.items(.data)[node];
1659 return tree.fullAsm(.{
1660 .asm_token = tree.nodes.items(.main_token)[node],
1661 .template = data.lhs,
1662 .items = &.{},
1663 .rparen = data.rhs,
1664 });
1665 }
1666
1667 pub fn asmFull(tree: Tree, node: Node.Index) full.Asm {
1668 const data = tree.nodes.items(.data)[node];
1669 const extra = tree.extraData(data.rhs, Node.Asm);
1670 return tree.fullAsm(.{
1671 .asm_token = tree.nodes.items(.main_token)[node],
1672 .template = data.lhs,
1673 .items = tree.extra_data[extra.items_start..extra.items_end],
1674 .rparen = extra.rparen,
1675 });
1676 }
1677
1678 pub fn whileSimple(tree: Tree, node: Node.Index) full.While {
1679 const data = tree.nodes.items(.data)[node];
1680 return tree.fullWhile(.{
1681 .while_token = tree.nodes.items(.main_token)[node],
1682 .cond_expr = data.lhs,
1683 .cont_expr = 0,
1684 .then_expr = data.rhs,
1685 .else_expr = 0,
1686 });
1687 }
1688
1689 pub fn whileCont(tree: Tree, node: Node.Index) full.While {
1690 const data = tree.nodes.items(.data)[node];
1691 const extra = tree.extraData(data.rhs, Node.WhileCont);
1692 return tree.fullWhile(.{
1693 .while_token = tree.nodes.items(.main_token)[node],
1694 .cond_expr = data.lhs,
1695 .cont_expr = extra.cont_expr,
1696 .then_expr = extra.then_expr,
1697 .else_expr = 0,
1698 });
1699 }
1700
1701 pub fn whileFull(tree: Tree, node: Node.Index) full.While {
1702 const data = tree.nodes.items(.data)[node];
1703 const extra = tree.extraData(data.rhs, Node.While);
1704 return tree.fullWhile(.{
1705 .while_token = tree.nodes.items(.main_token)[node],
1706 .cond_expr = data.lhs,
1707 .cont_expr = extra.cont_expr,
1708 .then_expr = extra.then_expr,
1709 .else_expr = extra.else_expr,
1710 });
1711 }
1712
1713 pub fn forSimple(tree: Tree, node: Node.Index) full.While {
1714 const data = tree.nodes.items(.data)[node];
1715 return tree.fullWhile(.{
1716 .while_token = tree.nodes.items(.main_token)[node],
1717 .cond_expr = data.lhs,
1718 .cont_expr = 0,
1719 .then_expr = data.rhs,
1720 .else_expr = 0,
1721 });
1722 }
1723
1724 pub fn forFull(tree: Tree, node: Node.Index) full.While {
1725 const data = tree.nodes.items(.data)[node];
1726 const extra = tree.extraData(data.rhs, Node.If);
1727 return tree.fullWhile(.{
1728 .while_token = tree.nodes.items(.main_token)[node],
1729 .cond_expr = data.lhs,
1730 .cont_expr = 0,
1731 .then_expr = extra.then_expr,
1732 .else_expr = extra.else_expr,
1733 });
1734 }
1735
1736 pub fn callOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.Call {
1737 const data = tree.nodes.items(.data)[node];
1738 buffer.* = .{data.rhs};
1739 const params = if (data.rhs != 0) buffer[0..1] else buffer[0..0];
1740 return tree.fullCall(.{
1741 .lparen = tree.nodes.items(.main_token)[node],
1742 .fn_expr = data.lhs,
1743 .params = params,
1744 });
1745 }
1746
1747 pub fn callFull(tree: Tree, node: Node.Index) full.Call {
1748 const data = tree.nodes.items(.data)[node];
1749 const extra = tree.extraData(data.rhs, Node.SubRange);
1750 return tree.fullCall(.{
1751 .lparen = tree.nodes.items(.main_token)[node],
1752 .fn_expr = data.lhs,
1753 .params = tree.extra_data[extra.start..extra.end],
1754 });
1755 }
1756
1757 fn fullVarDecl(tree: Tree, info: full.VarDecl.Ast) full.VarDecl {
1758 const token_tags = tree.tokens.items(.tag);
1759 var result: full.VarDecl = .{
1760 .ast = info,
1761 .visib_token = null,
1762 .extern_export_token = null,
1763 .lib_name = null,
1764 .threadlocal_token = null,
1765 .comptime_token = null,
1766 };
1767 var i = info.mut_token;
1768 while (i > 0) {
1769 i -= 1;
1770 switch (token_tags[i]) {
1771 .keyword_extern, .keyword_export => result.extern_export_token = i,
1772 .keyword_comptime => result.comptime_token = i,
1773 .keyword_pub => result.visib_token = i,
1774 .keyword_threadlocal => result.threadlocal_token = i,
1775 .string_literal => result.lib_name = i,
1776 else => break,
1777 }
1778 }
1779 return result;
1780 }
1781
1782 fn fullIf(tree: Tree, info: full.If.Ast) full.If {
1783 const token_tags = tree.tokens.items(.tag);
1784 var result: full.If = .{
1785 .ast = info,
1786 .payload_token = null,
1787 .error_token = null,
1788 .else_token = undefined,
1789 };
1790 // if (cond_expr) |x|
1791 // ^ ^
1792 const payload_pipe = tree.lastToken(info.cond_expr) + 2;
1793 if (token_tags[payload_pipe] == .pipe) {
1794 result.payload_token = payload_pipe + 1;
1795 }
1796 if (info.else_expr != 0) {
1797 // then_expr else |x|
1798 // ^ ^
1799 result.else_token = tree.lastToken(info.then_expr) + 1;
1800 if (token_tags[result.else_token + 1] == .pipe) {
1801 result.error_token = result.else_token + 2;
1802 }
1803 }
1804 return result;
1805 }
1806
1807 fn fullContainerField(tree: Tree, info: full.ContainerField.Ast) full.ContainerField {
1808 const token_tags = tree.tokens.items(.tag);
1809 var result: full.ContainerField = .{
1810 .ast = info,
1811 .comptime_token = null,
1812 };
1813 // comptime name: type = init,
1814 // ^
1815 if (info.name_token > 0 and token_tags[info.name_token - 1] == .keyword_comptime) {
1816 result.comptime_token = info.name_token - 1;
1817 }
1818 return result;
1819 }
1820
1821 fn fullFnProto(tree: Tree, info: full.FnProto.Ast) full.FnProto {
1822 const token_tags = tree.tokens.items(.tag);
1823 var result: full.FnProto = .{
1824 .ast = info,
1825 .visib_token = null,
1826 .extern_export_inline_token = null,
1827 .lib_name = null,
1828 .name_token = null,
1829 .lparen = undefined,
1830 };
1831 var i = info.fn_token;
1832 while (i > 0) {
1833 i -= 1;
1834 switch (token_tags[i]) {
1835 .keyword_extern,
1836 .keyword_export,
1837 .keyword_inline,
1838 .keyword_noinline,
1839 => result.extern_export_inline_token = i,
1840 .keyword_pub => result.visib_token = i,
1841 .string_literal => result.lib_name = i,
1842 else => break,
1843 }
1844 }
1845 const after_fn_token = info.fn_token + 1;
1846 if (token_tags[after_fn_token] == .identifier) {
1847 result.name_token = after_fn_token;
1848 result.lparen = after_fn_token + 1;
1849 } else {
1850 result.lparen = after_fn_token;
1851 }
1852 assert(token_tags[result.lparen] == .l_paren);
1853
1854 return result;
1855 }
1856
1857 fn fullStructInit(tree: Tree, info: full.StructInit.Ast) full.StructInit {
1858 _ = tree;
1859 var result: full.StructInit = .{
1860 .ast = info,
1861 };
1862 return result;
1863 }
1864
1865 fn fullPtrType(tree: Tree, info: full.PtrType.Ast) full.PtrType {
1866 const token_tags = tree.tokens.items(.tag);
1867 // TODO: looks like stage1 isn't quite smart enough to handle enum
1868 // literals in some places here
1869 const Size = std.builtin.TypeInfo.Pointer.Size;
1870 const size: Size = switch (token_tags[info.main_token]) {
1871 .asterisk,
1872 .asterisk_asterisk,
1873 => switch (token_tags[info.main_token + 1]) {
1874 .r_bracket, .colon => .Many,
1875 .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One,
1876 else => .One,
1877 },
1878 .l_bracket => Size.Slice,
1879 else => unreachable,
1880 };
1881 var result: full.PtrType = .{
1882 .size = size,
1883 .allowzero_token = null,
1884 .const_token = null,
1885 .volatile_token = null,
1886 .ast = info,
1887 };
1888 // We need to be careful that we don't iterate over any sub-expressions
1889 // here while looking for modifiers as that could result in false
1890 // positives. Therefore, start after a sentinel if there is one and
1891 // skip over any align node and bit range nodes.
1892 var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else info.main_token;
1893 const end = tree.firstToken(info.child_type);
1894 while (i < end) : (i += 1) {
1895 switch (token_tags[i]) {
1896 .keyword_allowzero => result.allowzero_token = i,
1897 .keyword_const => result.const_token = i,
1898 .keyword_volatile => result.volatile_token = i,
1899 .keyword_align => {
1900 assert(info.align_node != 0);
1901 if (info.bit_range_end != 0) {
1902 assert(info.bit_range_start != 0);
1903 i = tree.lastToken(info.bit_range_end) + 1;
1904 } else {
1905 i = tree.lastToken(info.align_node) + 1;
1906 }
1907 },
1908 else => {},
1909 }
1910 }
1911 return result;
1912 }
1913
1914 fn fullContainerDecl(tree: Tree, info: full.ContainerDecl.Ast) full.ContainerDecl {
1915 const token_tags = tree.tokens.items(.tag);
1916 var result: full.ContainerDecl = .{
1917 .ast = info,
1918 .layout_token = null,
1919 };
1920 switch (token_tags[info.main_token - 1]) {
1921 .keyword_extern, .keyword_packed => result.layout_token = info.main_token - 1,
1922 else => {},
1923 }
1924 return result;
1925 }
1926
1927 fn fullSwitchCase(tree: Tree, info: full.SwitchCase.Ast) full.SwitchCase {
1928 const token_tags = tree.tokens.items(.tag);
1929 var result: full.SwitchCase = .{
1930 .ast = info,
1931 .payload_token = null,
1932 };
1933 if (token_tags[info.arrow_token + 1] == .pipe) {
1934 result.payload_token = info.arrow_token + 2;
1935 }
1936 return result;
1937 }
1938
1939 fn fullAsm(tree: Tree, info: full.Asm.Ast) full.Asm {
1940 const token_tags = tree.tokens.items(.tag);
1941 const node_tags = tree.nodes.items(.tag);
1942 var result: full.Asm = .{
1943 .ast = info,
1944 .volatile_token = null,
1945 .inputs = &.{},
1946 .outputs = &.{},
1947 .first_clobber = null,
1948 };
1949 if (token_tags[info.asm_token + 1] == .keyword_volatile) {
1950 result.volatile_token = info.asm_token + 1;
1951 }
1952 const outputs_end: usize = for (info.items) |item, i| {
1953 switch (node_tags[item]) {
1954 .asm_output => continue,
1955 else => break i,
1956 }
1957 } else info.items.len;
1958
1959 result.outputs = info.items[0..outputs_end];
1960 result.inputs = info.items[outputs_end..];
1961
1962 if (info.items.len == 0) {
1963 // asm ("foo" ::: "a", "b");
1964 const template_token = tree.lastToken(info.template);
1965 if (token_tags[template_token + 1] == .colon and
1966 token_tags[template_token + 2] == .colon and
1967 token_tags[template_token + 3] == .colon and
1968 token_tags[template_token + 4] == .string_literal)
1969 {
1970 result.first_clobber = template_token + 4;
1971 }
1972 } else if (result.inputs.len != 0) {
1973 // asm ("foo" :: [_] "" (y) : "a", "b");
1974 const last_input = result.inputs[result.inputs.len - 1];
1975 const rparen = tree.lastToken(last_input);
1976 var i = rparen + 1;
1977 // Allow a (useless) comma right after the closing parenthesis.
1978 if (token_tags[i] == .comma) i += 1;
1979 if (token_tags[i] == .colon and
1980 token_tags[i + 1] == .string_literal)
1981 {
1982 result.first_clobber = i + 1;
1983 }
1984 } else {
1985 // asm ("foo" : [_] "" (x) :: "a", "b");
1986 const last_output = result.outputs[result.outputs.len - 1];
1987 const rparen = tree.lastToken(last_output);
1988 var i = rparen + 1;
1989 // Allow a (useless) comma right after the closing parenthesis.
1990 if (token_tags[i] == .comma) i += 1;
1991 if (token_tags[i] == .colon and
1992 token_tags[i + 1] == .colon and
1993 token_tags[i + 2] == .string_literal)
1994 {
1995 result.first_clobber = i + 2;
1996 }
1997 }
1998
1999 return result;
2000 }
2001
2002 fn fullWhile(tree: Tree, info: full.While.Ast) full.While {
2003 const token_tags = tree.tokens.items(.tag);
2004 var result: full.While = .{
2005 .ast = info,
2006 .inline_token = null,
2007 .label_token = null,
2008 .payload_token = null,
2009 .else_token = undefined,
2010 .error_token = null,
2011 };
2012 var tok_i = info.while_token - 1;
2013 if (token_tags[tok_i] == .keyword_inline) {
2014 result.inline_token = tok_i;
2015 tok_i -= 1;
2016 }
2017 if (token_tags[tok_i] == .colon and
2018 token_tags[tok_i - 1] == .identifier)
2019 {
2020 result.label_token = tok_i - 1;
2021 }
2022 const last_cond_token = tree.lastToken(info.cond_expr);
2023 if (token_tags[last_cond_token + 2] == .pipe) {
2024 result.payload_token = last_cond_token + 3;
2025 }
2026 if (info.else_expr != 0) {
2027 // then_expr else |x|
2028 // ^ ^
2029 result.else_token = tree.lastToken(info.then_expr) + 1;
2030 if (token_tags[result.else_token + 1] == .pipe) {
2031 result.error_token = result.else_token + 2;
2032 }
2033 }
2034 return result;
2035 }
2036
2037 fn fullCall(tree: Tree, info: full.Call.Ast) full.Call {
2038 const token_tags = tree.tokens.items(.tag);
2039 var result: full.Call = .{
2040 .ast = info,
2041 .async_token = null,
2042 };
2043 const maybe_async_token = tree.firstToken(info.fn_expr) - 1;
2044 if (token_tags[maybe_async_token] == .keyword_async) {
2045 result.async_token = maybe_async_token;
2046 }
2047 return result;
2048 }
2049};
2050
2051/// Fully assembled AST node information.
2052pub const full = struct {
2053 pub const VarDecl = struct {
2054 visib_token: ?TokenIndex,
2055 extern_export_token: ?TokenIndex,
2056 lib_name: ?TokenIndex,
2057 threadlocal_token: ?TokenIndex,
2058 comptime_token: ?TokenIndex,
2059 ast: Ast,
2060
2061 pub const Ast = struct {
2062 mut_token: TokenIndex,
2063 type_node: Node.Index,
2064 align_node: Node.Index,
2065 section_node: Node.Index,
2066 init_node: Node.Index,
2067 };
2068 };
2069
2070 pub const If = struct {
2071 /// Points to the first token after the `|`. Will either be an identifier or
2072 /// a `*` (with an identifier immediately after it).
2073 payload_token: ?TokenIndex,
2074 /// Points to the identifier after the `|`.
2075 error_token: ?TokenIndex,
2076 /// Populated only if else_expr != 0.
2077 else_token: TokenIndex,
2078 ast: Ast,
2079
2080 pub const Ast = struct {
2081 if_token: TokenIndex,
2082 cond_expr: Node.Index,
2083 then_expr: Node.Index,
2084 else_expr: Node.Index,
2085 };
2086 };
2087
2088 pub const While = struct {
2089 ast: Ast,
2090 inline_token: ?TokenIndex,
2091 label_token: ?TokenIndex,
2092 payload_token: ?TokenIndex,
2093 error_token: ?TokenIndex,
2094 /// Populated only if else_expr != 0.
2095 else_token: TokenIndex,
2096
2097 pub const Ast = struct {
2098 while_token: TokenIndex,
2099 cond_expr: Node.Index,
2100 cont_expr: Node.Index,
2101 then_expr: Node.Index,
2102 else_expr: Node.Index,
2103 };
2104 };
2105
2106 pub const ContainerField = struct {
2107 comptime_token: ?TokenIndex,
2108 ast: Ast,
2109
2110 pub const Ast = struct {
2111 name_token: TokenIndex,
2112 type_expr: Node.Index,
2113 value_expr: Node.Index,
2114 align_expr: Node.Index,
2115 };
2116 };
2117
2118 pub const FnProto = struct {
2119 visib_token: ?TokenIndex,
2120 extern_export_inline_token: ?TokenIndex,
2121 lib_name: ?TokenIndex,
2122 name_token: ?TokenIndex,
2123 lparen: TokenIndex,
2124 ast: Ast,
2125
2126 pub const Ast = struct {
2127 proto_node: Node.Index,
2128 fn_token: TokenIndex,
2129 return_type: Node.Index,
2130 params: []const Node.Index,
2131 align_expr: Node.Index,
2132 section_expr: Node.Index,
2133 callconv_expr: Node.Index,
2134 };
2135
2136 pub const Param = struct {
2137 first_doc_comment: ?TokenIndex,
2138 name_token: ?TokenIndex,
2139 comptime_noalias: ?TokenIndex,
2140 anytype_ellipsis3: ?TokenIndex,
2141 type_expr: Node.Index,
2142 };
2143
2144 /// Abstracts over the fact that anytype and ... are not included
2145 /// in the params slice, since they are simple identifiers and
2146 /// not sub-expressions.
2147 pub const Iterator = struct {
2148 tree: *const Tree,
2149 fn_proto: *const FnProto,
2150 param_i: usize,
2151 tok_i: TokenIndex,
2152 tok_flag: bool,
2153
2154 pub fn next(it: *Iterator) ?Param {
2155 const token_tags = it.tree.tokens.items(.tag);
2156 while (true) {
2157 var first_doc_comment: ?TokenIndex = null;
2158 var comptime_noalias: ?TokenIndex = null;
2159 var name_token: ?TokenIndex = null;
2160 if (!it.tok_flag) {
2161 if (it.param_i >= it.fn_proto.ast.params.len) {
2162 return null;
2163 }
2164 const param_type = it.fn_proto.ast.params[it.param_i];
2165 var tok_i = it.tree.firstToken(param_type) - 1;
2166 while (true) : (tok_i -= 1) switch (token_tags[tok_i]) {
2167 .colon => continue,
2168 .identifier => name_token = tok_i,
2169 .doc_comment => first_doc_comment = tok_i,
2170 .keyword_comptime, .keyword_noalias => comptime_noalias = tok_i,
2171 else => break,
2172 };
2173 it.param_i += 1;
2174 it.tok_i = it.tree.lastToken(param_type) + 1;
2175 // Look for anytype and ... params afterwards.
2176 if (token_tags[it.tok_i] == .comma) {
2177 it.tok_i += 1;
2178 }
2179 it.tok_flag = true;
2180 return Param{
2181 .first_doc_comment = first_doc_comment,
2182 .comptime_noalias = comptime_noalias,
2183 .name_token = name_token,
2184 .anytype_ellipsis3 = null,
2185 .type_expr = param_type,
2186 };
2187 }
2188 if (token_tags[it.tok_i] == .comma) {
2189 it.tok_i += 1;
2190 }
2191 if (token_tags[it.tok_i] == .r_paren) {
2192 return null;
2193 }
2194 if (token_tags[it.tok_i] == .doc_comment) {
2195 first_doc_comment = it.tok_i;
2196 while (token_tags[it.tok_i] == .doc_comment) {
2197 it.tok_i += 1;
2198 }
2199 }
2200 switch (token_tags[it.tok_i]) {
2201 .ellipsis3 => {
2202 it.tok_flag = false; // Next iteration should return null.
2203 return Param{
2204 .first_doc_comment = first_doc_comment,
2205 .comptime_noalias = null,
2206 .name_token = null,
2207 .anytype_ellipsis3 = it.tok_i,
2208 .type_expr = 0,
2209 };
2210 },
2211 .keyword_noalias, .keyword_comptime => {
2212 comptime_noalias = it.tok_i;
2213 it.tok_i += 1;
2214 },
2215 else => {},
2216 }
2217 if (token_tags[it.tok_i] == .identifier and
2218 token_tags[it.tok_i + 1] == .colon)
2219 {
2220 name_token = it.tok_i;
2221 it.tok_i += 2;
2222 }
2223 if (token_tags[it.tok_i] == .keyword_anytype) {
2224 it.tok_i += 1;
2225 return Param{
2226 .first_doc_comment = first_doc_comment,
2227 .comptime_noalias = comptime_noalias,
2228 .name_token = name_token,
2229 .anytype_ellipsis3 = it.tok_i - 1,
2230 .type_expr = 0,
2231 };
2232 }
2233 it.tok_flag = false;
2234 }
2235 }
2236 };
2237
2238 pub fn iterate(fn_proto: FnProto, tree: Tree) Iterator {
2239 return .{
2240 .tree = &tree,
2241 .fn_proto = &fn_proto,
2242 .param_i = 0,
2243 .tok_i = fn_proto.lparen + 1,
2244 .tok_flag = true,
2245 };
2246 }
2247 };
2248
2249 pub const StructInit = struct {
2250 ast: Ast,
2251
2252 pub const Ast = struct {
2253 lbrace: TokenIndex,
2254 fields: []const Node.Index,
2255 type_expr: Node.Index,
2256 };
2257 };
2258
2259 pub const ArrayInit = struct {
2260 ast: Ast,
2261
2262 pub const Ast = struct {
2263 lbrace: TokenIndex,
2264 elements: []const Node.Index,
2265 type_expr: Node.Index,
2266 };
2267 };
2268
2269 pub const ArrayType = struct {
2270 ast: Ast,
2271
2272 pub const Ast = struct {
2273 lbracket: TokenIndex,
2274 elem_count: Node.Index,
2275 sentinel: Node.Index,
2276 elem_type: Node.Index,
2277 };
2278 };
2279
2280 pub const PtrType = struct {
2281 size: std.builtin.TypeInfo.Pointer.Size,
2282 allowzero_token: ?TokenIndex,
2283 const_token: ?TokenIndex,
2284 volatile_token: ?TokenIndex,
2285 ast: Ast,
2286
2287 pub const Ast = struct {
2288 main_token: TokenIndex,
2289 align_node: Node.Index,
2290 sentinel: Node.Index,
2291 bit_range_start: Node.Index,
2292 bit_range_end: Node.Index,
2293 child_type: Node.Index,
2294 };
2295 };
2296
2297 pub const Slice = struct {
2298 ast: Ast,
2299
2300 pub const Ast = struct {
2301 sliced: Node.Index,
2302 lbracket: TokenIndex,
2303 start: Node.Index,
2304 end: Node.Index,
2305 sentinel: Node.Index,
2306 };
2307 };
2308
2309 pub const ContainerDecl = struct {
2310 layout_token: ?TokenIndex,
2311 ast: Ast,
2312
2313 pub const Ast = struct {
2314 main_token: TokenIndex,
2315 /// Populated when main_token is Keyword_union.
2316 enum_token: ?TokenIndex,
2317 members: []const Node.Index,
2318 arg: Node.Index,
2319 };
2320 };
2321
2322 pub const SwitchCase = struct {
2323 /// Points to the first token after the `|`. Will either be an identifier or
2324 /// a `*` (with an identifier immediately after it).
2325 payload_token: ?TokenIndex,
2326 ast: Ast,
2327
2328 pub const Ast = struct {
2329 /// If empty, this is an else case
2330 values: []const Node.Index,
2331 arrow_token: TokenIndex,
2332 target_expr: Node.Index,
2333 };
2334 };
2335
2336 pub const Asm = struct {
2337 ast: Ast,
2338 volatile_token: ?TokenIndex,
2339 first_clobber: ?TokenIndex,
2340 outputs: []const Node.Index,
2341 inputs: []const Node.Index,
2342
2343 pub const Ast = struct {
2344 asm_token: TokenIndex,
2345 template: Node.Index,
2346 items: []const Node.Index,
2347 rparen: TokenIndex,
2348 };
2349 };
2350
2351 pub const Call = struct {
2352 ast: Ast,
2353 async_token: ?TokenIndex,
2354
2355 pub const Ast = struct {
2356 lparen: TokenIndex,
2357 fn_expr: Node.Index,
2358 params: []const Node.Index,
2359 };
2360 };
2361};
2362
2363pub const Error = struct {
2364 tag: Tag,
2365 token: TokenIndex,
2366 extra: union {
2367 none: void,
2368 expected_tag: Token.Tag,
2369 } = .{ .none = {} },
2370
2371 pub const Tag = enum {
2372 asterisk_after_ptr_deref,
2373 decl_between_fields,
2374 expected_block,
2375 expected_block_or_assignment,
2376 expected_block_or_expr,
2377 expected_block_or_field,
2378 expected_container_members,
2379 expected_expr,
2380 expected_expr_or_assignment,
2381 expected_fn,
2382 expected_inlinable,
2383 expected_labelable,
2384 expected_param_list,
2385 expected_prefix_expr,
2386 expected_primary_type_expr,
2387 expected_pub_item,
2388 expected_return_type,
2389 expected_semi_or_else,
2390 expected_semi_or_lbrace,
2391 expected_statement,
2392 expected_string_literal,
2393 expected_suffix_op,
2394 expected_type_expr,
2395 expected_var_decl,
2396 expected_var_decl_or_fn,
2397 expected_loop_payload,
2398 expected_container,
2399 extra_align_qualifier,
2400 extra_allowzero_qualifier,
2401 extra_const_qualifier,
2402 extra_volatile_qualifier,
2403 ptr_mod_on_array_child_type,
2404 invalid_bit_range,
2405 invalid_token,
2406 same_line_doc_comment,
2407 unattached_doc_comment,
2408 varargs_nonfinal,
2409
2410 /// `expected_tag` is populated.
2411 expected_token,
2412 };
2413};
2414
2415pub const Node = struct {
2416 tag: Tag,
2417 main_token: TokenIndex,
2418 data: Data,
2419
2420 pub const Index = u32;
2421
2422 comptime {
2423 // Goal is to keep this under one byte for efficiency.
2424 assert(@sizeOf(Tag) == 1);
2425 }
2426
2427 /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of
2428 /// Tree.lastToken()
2429 pub const Tag = enum {
2430 /// sub_list[lhs...rhs]
2431 root,
2432 /// `usingnamespace lhs;`. rhs unused. main_token is `usingnamespace`.
2433 @"usingnamespace",
2434 /// lhs is test name token (must be string literal), if any.
2435 /// rhs is the body node.
2436 test_decl,
2437 /// lhs is the index into extra_data.
2438 /// rhs is the initialization expression, if any.
2439 /// main_token is `var` or `const`.
2440 global_var_decl,
2441 /// `var a: x align(y) = rhs`
2442 /// lhs is the index into extra_data.
2443 /// main_token is `var` or `const`.
2444 local_var_decl,
2445 /// `var a: lhs = rhs`. lhs and rhs may be unused.
2446 /// Can be local or global.
2447 /// main_token is `var` or `const`.
2448 simple_var_decl,
2449 /// `var a align(lhs) = rhs`. lhs and rhs may be unused.
2450 /// Can be local or global.
2451 /// main_token is `var` or `const`.
2452 aligned_var_decl,
2453 /// lhs is the identifier token payload if any,
2454 /// rhs is the deferred expression.
2455 @"errdefer",
2456 /// lhs is unused.
2457 /// rhs is the deferred expression.
2458 @"defer",
2459 /// lhs catch rhs
2460 /// lhs catch |err| rhs
2461 /// main_token is the `catch` keyword.
2462 /// payload is determined by looking at the next token after the `catch` keyword.
2463 @"catch",
2464 /// `lhs.a`. main_token is the dot. rhs is the identifier token index.
2465 field_access,
2466 /// `lhs.?`. main_token is the dot. rhs is the `?` token index.
2467 unwrap_optional,
2468 /// `lhs == rhs`. main_token is op.
2469 equal_equal,
2470 /// `lhs != rhs`. main_token is op.
2471 bang_equal,
2472 /// `lhs < rhs`. main_token is op.
2473 less_than,
2474 /// `lhs > rhs`. main_token is op.
2475 greater_than,
2476 /// `lhs <= rhs`. main_token is op.
2477 less_or_equal,
2478 /// `lhs >= rhs`. main_token is op.
2479 greater_or_equal,
2480 /// `lhs *= rhs`. main_token is op.
2481 assign_mul,
2482 /// `lhs /= rhs`. main_token is op.
2483 assign_div,
2484 /// `lhs *= rhs`. main_token is op.
2485 assign_mod,
2486 /// `lhs += rhs`. main_token is op.
2487 assign_add,
2488 /// `lhs -= rhs`. main_token is op.
2489 assign_sub,
2490 /// `lhs <<= rhs`. main_token is op.
2491 assign_bit_shift_left,
2492 /// `lhs >>= rhs`. main_token is op.
2493 assign_bit_shift_right,
2494 /// `lhs &= rhs`. main_token is op.
2495 assign_bit_and,
2496 /// `lhs ^= rhs`. main_token is op.
2497 assign_bit_xor,
2498 /// `lhs |= rhs`. main_token is op.
2499 assign_bit_or,
2500 /// `lhs *%= rhs`. main_token is op.
2501 assign_mul_wrap,
2502 /// `lhs +%= rhs`. main_token is op.
2503 assign_add_wrap,
2504 /// `lhs -%= rhs`. main_token is op.
2505 assign_sub_wrap,
2506 /// `lhs = rhs`. main_token is op.
2507 assign,
2508 /// `lhs || rhs`. main_token is the `||`.
2509 merge_error_sets,
2510 /// `lhs * rhs`. main_token is the `*`.
2511 mul,
2512 /// `lhs / rhs`. main_token is the `/`.
2513 div,
2514 /// `lhs % rhs`. main_token is the `%`.
2515 mod,
2516 /// `lhs ** rhs`. main_token is the `**`.
2517 array_mult,
2518 /// `lhs *% rhs`. main_token is the `*%`.
2519 mul_wrap,
2520 /// `lhs + rhs`. main_token is the `+`.
2521 add,
2522 /// `lhs - rhs`. main_token is the `-`.
2523 sub,
2524 /// `lhs ++ rhs`. main_token is the `++`.
2525 array_cat,
2526 /// `lhs +% rhs`. main_token is the `+%`.
2527 add_wrap,
2528 /// `lhs -% rhs`. main_token is the `-%`.
2529 sub_wrap,
2530 /// `lhs << rhs`. main_token is the `<<`.
2531 bit_shift_left,
2532 /// `lhs >> rhs`. main_token is the `>>`.
2533 bit_shift_right,
2534 /// `lhs & rhs`. main_token is the `&`.
2535 bit_and,
2536 /// `lhs ^ rhs`. main_token is the `^`.
2537 bit_xor,
2538 /// `lhs | rhs`. main_token is the `|`.
2539 bit_or,
2540 /// `lhs orelse rhs`. main_token is the `orelse`.
2541 @"orelse",
2542 /// `lhs and rhs`. main_token is the `and`.
2543 bool_and,
2544 /// `lhs or rhs`. main_token is the `or`.
2545 bool_or,
2546 /// `op lhs`. rhs unused. main_token is op.
2547 bool_not,
2548 /// `op lhs`. rhs unused. main_token is op.
2549 negation,
2550 /// `op lhs`. rhs unused. main_token is op.
2551 bit_not,
2552 /// `op lhs`. rhs unused. main_token is op.
2553 negation_wrap,
2554 /// `op lhs`. rhs unused. main_token is op.
2555 address_of,
2556 /// `op lhs`. rhs unused. main_token is op.
2557 @"try",
2558 /// `op lhs`. rhs unused. main_token is op.
2559 @"await",
2560 /// `?lhs`. rhs unused. main_token is the `?`.
2561 optional_type,
2562 /// `[lhs]rhs`.
2563 array_type,
2564 /// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`.
2565 array_type_sentinel,
2566 /// `[*]align(lhs) rhs`. lhs can be omitted.
2567 /// `*align(lhs) rhs`. lhs can be omitted.
2568 /// `[]rhs`.
2569 /// main_token is the asterisk if a pointer or the lbracket if a slice
2570 /// main_token might be a ** token, which is shared with a parent/child
2571 /// pointer type and may require special handling.
2572 ptr_type_aligned,
2573 /// `[*:lhs]rhs`. lhs can be omitted.
2574 /// `*rhs`.
2575 /// `[:lhs]rhs`.
2576 /// main_token is the asterisk if a pointer or the lbracket if a slice
2577 /// main_token might be a ** token, which is shared with a parent/child
2578 /// pointer type and may require special handling.
2579 ptr_type_sentinel,
2580 /// lhs is index into ptr_type. rhs is the element type expression.
2581 /// main_token is the asterisk if a pointer or the lbracket if a slice
2582 /// main_token might be a ** token, which is shared with a parent/child
2583 /// pointer type and may require special handling.
2584 ptr_type,
2585 /// lhs is index into ptr_type_bit_range. rhs is the element type expression.
2586 /// main_token is the asterisk if a pointer or the lbracket if a slice
2587 /// main_token might be a ** token, which is shared with a parent/child
2588 /// pointer type and may require special handling.
2589 ptr_type_bit_range,
2590 /// `lhs[rhs..]`
2591 /// main_token is the lbracket.
2592 slice_open,
2593 /// `lhs[b..c]`. rhs is index into Slice
2594 /// main_token is the lbracket.
2595 slice,
2596 /// `lhs[b..c :d]`. rhs is index into SliceSentinel
2597 /// main_token is the lbracket.
2598 slice_sentinel,
2599 /// `lhs.*`. rhs is unused.
2600 deref,
2601 /// `lhs[rhs]`.
2602 array_access,
2603 /// `lhs{rhs}`. rhs can be omitted.
2604 array_init_one,
2605 /// `lhs{rhs,}`. rhs can *not* be omitted
2606 array_init_one_comma,
2607 /// `.{lhs, rhs}`. lhs and rhs can be omitted.
2608 array_init_dot_two,
2609 /// Same as `array_init_dot_two` except there is known to be a trailing comma
2610 /// before the final rbrace.
2611 array_init_dot_two_comma,
2612 /// `.{a, b}`. `sub_list[lhs..rhs]`.
2613 array_init_dot,
2614 /// Same as `array_init_dot` except there is known to be a trailing comma
2615 /// before the final rbrace.
2616 array_init_dot_comma,
2617 /// `lhs{a, b}`. `sub_range_list[rhs]`. lhs can be omitted which means `.{a, b}`.
2618 array_init,
2619 /// Same as `array_init` except there is known to be a trailing comma
2620 /// before the final rbrace.
2621 array_init_comma,
2622 /// `lhs{.a = rhs}`. rhs can be omitted making it empty.
2623 /// main_token is the lbrace.
2624 struct_init_one,
2625 /// `lhs{.a = rhs,}`. rhs can *not* be omitted.
2626 /// main_token is the lbrace.
2627 struct_init_one_comma,
2628 /// `.{.a = lhs, .b = rhs}`. lhs and rhs can be omitted.
2629 /// main_token is the lbrace.
2630 /// No trailing comma before the rbrace.
2631 struct_init_dot_two,
2632 /// Same as `struct_init_dot_two` except there is known to be a trailing comma
2633 /// before the final rbrace.
2634 struct_init_dot_two_comma,
2635 /// `.{.a = b, .c = d}`. `sub_list[lhs..rhs]`.
2636 /// main_token is the lbrace.
2637 struct_init_dot,
2638 /// Same as `struct_init_dot` except there is known to be a trailing comma
2639 /// before the final rbrace.
2640 struct_init_dot_comma,
2641 /// `lhs{.a = b, .c = d}`. `sub_range_list[rhs]`.
2642 /// lhs can be omitted which means `.{.a = b, .c = d}`.
2643 /// main_token is the lbrace.
2644 struct_init,
2645 /// Same as `struct_init` except there is known to be a trailing comma
2646 /// before the final rbrace.
2647 struct_init_comma,
2648 /// `lhs(rhs)`. rhs can be omitted.
2649 /// main_token is the lparen.
2650 call_one,
2651 /// `lhs(rhs,)`. rhs can be omitted.
2652 /// main_token is the lparen.
2653 call_one_comma,
2654 /// `async lhs(rhs)`. rhs can be omitted.
2655 async_call_one,
2656 /// `async lhs(rhs,)`.
2657 async_call_one_comma,
2658 /// `lhs(a, b, c)`. `SubRange[rhs]`.
2659 /// main_token is the `(`.
2660 call,
2661 /// `lhs(a, b, c,)`. `SubRange[rhs]`.
2662 /// main_token is the `(`.
2663 call_comma,
2664 /// `async lhs(a, b, c)`. `SubRange[rhs]`.
2665 /// main_token is the `(`.
2666 async_call,
2667 /// `async lhs(a, b, c,)`. `SubRange[rhs]`.
2668 /// main_token is the `(`.
2669 async_call_comma,
2670 /// `switch(lhs) {}`. `SubRange[rhs]`.
2671 @"switch",
2672 /// Same as switch except there is known to be a trailing comma
2673 /// before the final rbrace
2674 switch_comma,
2675 /// `lhs => rhs`. If lhs is omitted it means `else`.
2676 /// main_token is the `=>`
2677 switch_case_one,
2678 /// `a, b, c => rhs`. `SubRange[lhs]`.
2679 /// main_token is the `=>`
2680 switch_case,
2681 /// `lhs...rhs`.
2682 switch_range,
2683 /// `while (lhs) rhs`.
2684 /// `while (lhs) |x| rhs`.
2685 while_simple,
2686 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
2687 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
2688 while_cont,
2689 /// `while (lhs) : (a) b else c`. `While[rhs]`.
2690 /// `while (lhs) |x| : (a) b else c`. `While[rhs]`.
2691 /// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`.
2692 @"while",
2693 /// `for (lhs) rhs`.
2694 for_simple,
2695 /// `for (lhs) a else b`. `if_list[rhs]`.
2696 @"for",
2697 /// `if (lhs) rhs`.
2698 /// `if (lhs) |a| rhs`.
2699 if_simple,
2700 /// `if (lhs) a else b`. `If[rhs]`.
2701 /// `if (lhs) |x| a else b`. `If[rhs]`.
2702 /// `if (lhs) |x| a else |y| b`. `If[rhs]`.
2703 @"if",
2704 /// `suspend lhs`. lhs can be omitted. rhs is unused.
2705 @"suspend",
2706 /// `resume lhs`. rhs is unused.
2707 @"resume",
2708 /// `continue`. lhs is token index of label if any. rhs is unused.
2709 @"continue",
2710 /// `break :lhs rhs`
2711 /// both lhs and rhs may be omitted.
2712 @"break",
2713 /// `return lhs`. lhs can be omitted. rhs is unused.
2714 @"return",
2715 /// `fn(a: lhs) rhs`. lhs can be omitted.
2716 /// anytype and ... parameters are omitted from the AST tree.
2717 /// main_token is the `fn` keyword.
2718 /// extern function declarations use this tag.
2719 fn_proto_simple,
2720 /// `fn(a: b, c: d) rhs`. `sub_range_list[lhs]`.
2721 /// anytype and ... parameters are omitted from the AST tree.
2722 /// main_token is the `fn` keyword.
2723 /// extern function declarations use this tag.
2724 fn_proto_multi,
2725 /// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`.
2726 /// zero or one parameters.
2727 /// anytype and ... parameters are omitted from the AST tree.
2728 /// main_token is the `fn` keyword.
2729 /// extern function declarations use this tag.
2730 fn_proto_one,
2731 /// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.
2732 /// anytype and ... parameters are omitted from the AST tree.
2733 /// main_token is the `fn` keyword.
2734 /// extern function declarations use this tag.
2735 fn_proto,
2736 /// lhs is the fn_proto.
2737 /// rhs is the function body block.
2738 /// Note that extern function declarations use the fn_proto tags rather
2739 /// than this one.
2740 fn_decl,
2741 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
2742 anyframe_type,
2743 /// Both lhs and rhs unused.
2744 anyframe_literal,
2745 /// Both lhs and rhs unused.
2746 char_literal,
2747 /// Both lhs and rhs unused.
2748 integer_literal,
2749 /// Both lhs and rhs unused.
2750 float_literal,
2751 /// Both lhs and rhs unused.
2752 unreachable_literal,
2753 /// Both lhs and rhs unused.
2754 /// Most identifiers will not have explicit AST nodes, however for expressions
2755 /// which could be one of many different kinds of AST nodes, there will be an
2756 /// identifier AST node for it.
2757 identifier,
2758 /// lhs is the dot token index, rhs unused, main_token is the identifier.
2759 enum_literal,
2760 /// main_token is the string literal token
2761 /// Both lhs and rhs unused.
2762 string_literal,
2763 /// main_token is the first token index (redundant with lhs)
2764 /// lhs is the first token index; rhs is the last token index.
2765 /// Could be a series of multiline_string_literal_line tokens, or a single
2766 /// string_literal token.
2767 multiline_string_literal,
2768 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
2769 grouped_expression,
2770 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
2771 /// main_token is the builtin token.
2772 builtin_call_two,
2773 /// Same as builtin_call_two but there is known to be a trailing comma before the rparen.
2774 builtin_call_two_comma,
2775 /// `@a(b, c)`. `sub_list[lhs..rhs]`.
2776 /// main_token is the builtin token.
2777 builtin_call,
2778 /// Same as builtin_call but there is known to be a trailing comma before the rparen.
2779 builtin_call_comma,
2780 /// `error{a, b}`.
2781 /// rhs is the rbrace, lhs is unused.
2782 error_set_decl,
2783 /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. `extra_data[lhs..rhs]`.
2784 /// main_token is `struct`, `union`, `opaque`, `enum` keyword.
2785 container_decl,
2786 /// Same as ContainerDecl but there is known to be a trailing comma
2787 /// or semicolon before the rbrace.
2788 container_decl_trailing,
2789 /// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`.
2790 /// lhs or rhs can be omitted.
2791 /// main_token is `struct`, `union`, `opaque`, `enum` keyword.
2792 container_decl_two,
2793 /// Same as ContainerDeclTwo except there is known to be a trailing comma
2794 /// or semicolon before the rbrace.
2795 container_decl_two_trailing,
2796 /// `union(lhs)` / `enum(lhs)`. `SubRange[rhs]`.
2797 container_decl_arg,
2798 /// Same as container_decl_arg but there is known to be a trailing
2799 /// comma or semicolon before the rbrace.
2800 container_decl_arg_trailing,
2801 /// `union(enum) {}`. `sub_list[lhs..rhs]`.
2802 /// Note that tagged unions with explicitly provided enums are represented
2803 /// by `container_decl_arg`.
2804 tagged_union,
2805 /// Same as tagged_union but there is known to be a trailing comma
2806 /// or semicolon before the rbrace.
2807 tagged_union_trailing,
2808 /// `union(enum) {lhs, rhs}`. lhs or rhs may be omitted.
2809 /// Note that tagged unions with explicitly provided enums are represented
2810 /// by `container_decl_arg`.
2811 tagged_union_two,
2812 /// Same as tagged_union_two but there is known to be a trailing comma
2813 /// or semicolon before the rbrace.
2814 tagged_union_two_trailing,
2815 /// `union(enum(lhs)) {}`. `SubRange[rhs]`.
2816 tagged_union_enum_tag,
2817 /// Same as tagged_union_enum_tag but there is known to be a trailing comma
2818 /// or semicolon before the rbrace.
2819 tagged_union_enum_tag_trailing,
2820 /// `a: lhs = rhs,`. lhs and rhs can be omitted.
2821 /// main_token is the field name identifier.
2822 /// lastToken() does not include the possible trailing comma.
2823 container_field_init,
2824 /// `a: lhs align(rhs),`. rhs can be omitted.
2825 /// main_token is the field name identifier.
2826 /// lastToken() does not include the possible trailing comma.
2827 container_field_align,
2828 /// `a: lhs align(c) = d,`. `container_field_list[rhs]`.
2829 /// main_token is the field name identifier.
2830 /// lastToken() does not include the possible trailing comma.
2831 container_field,
2832 /// `anytype`. both lhs and rhs unused.
2833 /// Used by `ContainerField`.
2834 @"anytype",
2835 /// `comptime lhs`. rhs unused.
2836 @"comptime",
2837 /// `nosuspend lhs`. rhs unused.
2838 @"nosuspend",
2839 /// `{lhs rhs}`. rhs or lhs can be omitted.
2840 /// main_token points at the lbrace.
2841 block_two,
2842 /// Same as block_two but there is known to be a semicolon before the rbrace.
2843 block_two_semicolon,
2844 /// `{}`. `sub_list[lhs..rhs]`.
2845 /// main_token points at the lbrace.
2846 block,
2847 /// Same as block but there is known to be a semicolon before the rbrace.
2848 block_semicolon,
2849 /// `asm(lhs)`. rhs is the token index of the rparen.
2850 asm_simple,
2851 /// `asm(lhs, a)`. `Asm[rhs]`.
2852 @"asm",
2853 /// `[a] "b" (c)`. lhs is 0, rhs is token index of the rparen.
2854 /// `[a] "b" (-> lhs)`. rhs is token index of the rparen.
2855 /// main_token is `a`.
2856 asm_output,
2857 /// `[a] "b" (lhs)`. rhs is token index of the rparen.
2858 /// main_token is `a`.
2859 asm_input,
2860 /// `error.a`. lhs is token index of `.`. rhs is token index of `a`.
2861 error_value,
2862 /// `lhs!rhs`. main_token is the `!`.
2863 error_union,
2864
2865 pub fn isContainerField(tag: Tag) bool {
2866 return switch (tag) {
2867 .container_field_init,
2868 .container_field_align,
2869 .container_field,
2870 => true,
2871
2872 else => false,
2873 };
2874 }
2875 };
2876
2877 pub const Data = struct {
2878 lhs: Index,
2879 rhs: Index,
2880 };
2881
2882 pub const LocalVarDecl = struct {
2883 type_node: Index,
2884 align_node: Index,
2885 };
2886
2887 pub const ArrayTypeSentinel = struct {
2888 elem_type: Index,
2889 sentinel: Index,
2890 };
2891
2892 pub const PtrType = struct {
2893 sentinel: Index,
2894 align_node: Index,
2895 };
2896
2897 pub const PtrTypeBitRange = struct {
2898 sentinel: Index,
2899 align_node: Index,
2900 bit_range_start: Index,
2901 bit_range_end: Index,
2902 };
2903
2904 pub const SubRange = struct {
2905 /// Index into sub_list.
2906 start: Index,
2907 /// Index into sub_list.
2908 end: Index,
2909 };
2910
2911 pub const If = struct {
2912 then_expr: Index,
2913 else_expr: Index,
2914 };
2915
2916 pub const ContainerField = struct {
2917 value_expr: Index,
2918 align_expr: Index,
2919 };
2920
2921 pub const GlobalVarDecl = struct {
2922 type_node: Index,
2923 align_node: Index,
2924 section_node: Index,
2925 };
2926
2927 pub const Slice = struct {
2928 start: Index,
2929 end: Index,
2930 };
2931
2932 pub const SliceSentinel = struct {
2933 start: Index,
2934 /// May be 0 if the slice is "open"
2935 end: Index,
2936 sentinel: Index,
2937 };
2938
2939 pub const While = struct {
2940 cont_expr: Index,
2941 then_expr: Index,
2942 else_expr: Index,
2943 };
2944
2945 pub const WhileCont = struct {
2946 cont_expr: Index,
2947 then_expr: Index,
2948 };
2949
2950 pub const FnProtoOne = struct {
2951 /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters.
2952 param: Index,
2953 /// Populated if align(A) is present.
2954 align_expr: Index,
2955 /// Populated if linksection(A) is present.
2956 section_expr: Index,
2957 /// Populated if callconv(A) is present.
2958 callconv_expr: Index,
2959 };
2960
2961 pub const FnProto = struct {
2962 params_start: Index,
2963 params_end: Index,
2964 /// Populated if align(A) is present.
2965 align_expr: Index,
2966 /// Populated if linksection(A) is present.
2967 section_expr: Index,
2968 /// Populated if callconv(A) is present.
2969 callconv_expr: Index,
2970 };
2971
2972 pub const Asm = struct {
2973 items_start: Index,
2974 items_end: Index,
2975 /// Needed to make lastToken() work.
2976 rparen: TokenIndex,
2977 };
2978};
lib/std/zig/parse.zig+16-17
...@@ -1,19 +1,18 @@...@@ -1,19 +1,18 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3const Allocator = std.mem.Allocator;3const Allocator = std.mem.Allocator;
4const ast = std.zig.ast;4const Ast = std.zig.Ast;
5const Node = ast.Node;5const Node = Ast.Node;
6const Tree = ast.Tree;6const AstError = Ast.Error;
7const AstError = ast.Error;7const TokenIndex = Ast.TokenIndex;
8const TokenIndex = ast.TokenIndex;
9const Token = std.zig.Token;8const Token = std.zig.Token;
109
11pub const Error = error{ParseError} || Allocator.Error;10pub const Error = error{ParseError} || Allocator.Error;
1211
13/// Result should be freed with tree.deinit() when there are12/// Result should be freed with tree.deinit() when there are
14/// no more references to any of the tokens or nodes.13/// no more references to any of the tokens or nodes.
15pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {14pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Ast {
16 var tokens = ast.TokenList{};15 var tokens = Ast.TokenList{};
17 defer tokens.deinit(gpa);16 defer tokens.deinit(gpa);
1817
19 // Empirically, the zig std lib has an 8:1 ratio of source bytes to token count.18 // Empirically, the zig std lib has an 8:1 ratio of source bytes to token count.
...@@ -69,7 +68,7 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {...@@ -69,7 +68,7 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {
69 };68 };
7069
71 // TODO experiment with compacting the MultiArrayList slices here70 // TODO experiment with compacting the MultiArrayList slices here
72 return Tree{71 return Ast{
73 .source = source,72 .source = source,
74 .tokens = tokens.toOwnedSlice(),73 .tokens = tokens.toOwnedSlice(),
75 .nodes = parser.nodes.toOwnedSlice(),74 .nodes = parser.nodes.toOwnedSlice(),
...@@ -80,15 +79,15 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {...@@ -80,15 +79,15 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {
8079
81const null_node: Node.Index = 0;80const null_node: Node.Index = 0;
8281
83/// Represents in-progress parsing, will be converted to an ast.Tree after completion.82/// Represents in-progress parsing, will be converted to an Ast after completion.
84const Parser = struct {83const Parser = struct {
85 gpa: *Allocator,84 gpa: *Allocator,
86 source: []const u8,85 source: []const u8,
87 token_tags: []const Token.Tag,86 token_tags: []const Token.Tag,
88 token_starts: []const ast.ByteOffset,87 token_starts: []const Ast.ByteOffset,
89 tok_i: TokenIndex,88 tok_i: TokenIndex,
90 errors: std.ArrayListUnmanaged(AstError),89 errors: std.ArrayListUnmanaged(AstError),
91 nodes: ast.NodeList,90 nodes: Ast.NodeList,
92 extra_data: std.ArrayListUnmanaged(Node.Index),91 extra_data: std.ArrayListUnmanaged(Node.Index),
93 scratch: std.ArrayListUnmanaged(Node.Index),92 scratch: std.ArrayListUnmanaged(Node.Index),
9493
...@@ -121,13 +120,13 @@ const Parser = struct {...@@ -121,13 +120,13 @@ const Parser = struct {
121 };120 };
122 }121 }
123122
124 fn addNode(p: *Parser, elem: ast.NodeList.Elem) Allocator.Error!Node.Index {123 fn addNode(p: *Parser, elem: Ast.NodeList.Elem) Allocator.Error!Node.Index {
125 const result = @intCast(Node.Index, p.nodes.len);124 const result = @intCast(Node.Index, p.nodes.len);
126 try p.nodes.append(p.gpa, elem);125 try p.nodes.append(p.gpa, elem);
127 return result;126 return result;
128 }127 }
129128
130 fn setNode(p: *Parser, i: usize, elem: ast.NodeList.Elem) Node.Index {129 fn setNode(p: *Parser, i: usize, elem: Ast.NodeList.Elem) Node.Index {
131 p.nodes.set(i, elem);130 p.nodes.set(i, elem);
132 return @intCast(Node.Index, i);131 return @intCast(Node.Index, i);
133 }132 }
...@@ -148,7 +147,7 @@ const Parser = struct {...@@ -148,7 +147,7 @@ const Parser = struct {
148 return result;147 return result;
149 }148 }
150149
151 fn warn(p: *Parser, tag: ast.Error.Tag) error{OutOfMemory}!void {150 fn warn(p: *Parser, tag: Ast.Error.Tag) error{OutOfMemory}!void {
152 @setCold(true);151 @setCold(true);
153 try p.warnMsg(.{ .tag = tag, .token = p.tok_i });152 try p.warnMsg(.{ .tag = tag, .token = p.tok_i });
154 }153 }
...@@ -161,12 +160,12 @@ const Parser = struct {...@@ -161,12 +160,12 @@ const Parser = struct {
161 .extra = .{ .expected_tag = expected_token },160 .extra = .{ .expected_tag = expected_token },
162 });161 });
163 }162 }
164 fn warnMsg(p: *Parser, msg: ast.Error) error{OutOfMemory}!void {163 fn warnMsg(p: *Parser, msg: Ast.Error) error{OutOfMemory}!void {
165 @setCold(true);164 @setCold(true);
166 try p.errors.append(p.gpa, msg);165 try p.errors.append(p.gpa, msg);
167 }166 }
168167
169 fn fail(p: *Parser, tag: ast.Error.Tag) error{ ParseError, OutOfMemory } {168 fn fail(p: *Parser, tag: Ast.Error.Tag) error{ ParseError, OutOfMemory } {
170 @setCold(true);169 @setCold(true);
171 return p.failMsg(.{ .tag = tag, .token = p.tok_i });170 return p.failMsg(.{ .tag = tag, .token = p.tok_i });
172 }171 }
...@@ -180,7 +179,7 @@ const Parser = struct {...@@ -180,7 +179,7 @@ const Parser = struct {
180 });179 });
181 }180 }
182181
183 fn failMsg(p: *Parser, msg: ast.Error) error{ ParseError, OutOfMemory } {182 fn failMsg(p: *Parser, msg: Ast.Error) error{ ParseError, OutOfMemory } {
184 @setCold(true);183 @setCold(true);
185 try p.warnMsg(msg);184 try p.warnMsg(msg);
186 return error.ParseError;185 return error.ParseError;
lib/std/zig/parser_test.zig+75-1
...@@ -2879,6 +2879,9 @@ test "zig fmt: functions" {...@@ -2879,6 +2879,9 @@ test "zig fmt: functions" {
2879 \\pub export fn puts(s: *const u8) align(2 + 2) c_int;2879 \\pub export fn puts(s: *const u8) align(2 + 2) c_int;
2880 \\pub inline fn puts(s: *const u8) align(2 + 2) c_int;2880 \\pub inline fn puts(s: *const u8) align(2 + 2) c_int;
2881 \\pub noinline fn puts(s: *const u8) align(2 + 2) c_int;2881 \\pub noinline fn puts(s: *const u8) align(2 + 2) c_int;
2882 \\pub fn callInlineFn(func: fn () callconv(.Inline) void) void {
2883 \\ func();
2884 \\}
2882 \\2885 \\
2883 );2886 );
2884}2887}
...@@ -4837,6 +4840,77 @@ test "zig fmt: make single-line if no trailing comma" {...@@ -4837,6 +4840,77 @@ test "zig fmt: make single-line if no trailing comma" {
4837 );4840 );
4838}4841}
48394842
4843test "zig fmt: make single-line if no trailing comma" {
4844 try testCanonical(
4845 \\// Test trailing comma syntax
4846 \\// zig fmt: off
4847 \\
4848 \\extern var a: c_int;
4849 \\extern "c" var b: c_int;
4850 \\export var c: c_int = 0;
4851 \\threadlocal var d: c_int = 0;
4852 \\extern threadlocal var e: c_int;
4853 \\extern "c" threadlocal var f: c_int;
4854 \\export threadlocal var g: c_int = 0;
4855 \\
4856 \\const struct_trailing_comma = struct { x: i32, y: i32, };
4857 \\const struct_no_comma = struct { x: i32, y: i32 };
4858 \\const struct_fn_no_comma = struct { fn m() void {} y: i32 };
4859 \\
4860 \\const enum_no_comma = enum { A, B };
4861 \\
4862 \\fn container_init() void {
4863 \\ const S = struct { x: i32, y: i32 };
4864 \\ _ = S { .x = 1, .y = 2 };
4865 \\ _ = S { .x = 1, .y = 2, };
4866 \\}
4867 \\
4868 \\fn type_expr_return1() if (true) A {}
4869 \\fn type_expr_return2() for (true) |_| A {}
4870 \\fn type_expr_return3() while (true) A {}
4871 \\
4872 \\fn switch_cases(x: i32) void {
4873 \\ switch (x) {
4874 \\ 1,2,3 => {},
4875 \\ 4,5, => {},
4876 \\ 6...8, => {},
4877 \\ else => {},
4878 \\ }
4879 \\}
4880 \\
4881 \\fn switch_prongs(x: i32) void {
4882 \\ switch (x) {
4883 \\ 0 => {},
4884 \\ else => {},
4885 \\ }
4886 \\ switch (x) {
4887 \\ 0 => {},
4888 \\ else => {}
4889 \\ }
4890 \\}
4891 \\
4892 \\const fn_no_comma = fn(i32, i32)void;
4893 \\const fn_trailing_comma = fn(i32, i32,)void;
4894 \\
4895 \\fn fn_calls() void {
4896 \\ fn add(x: i32, y: i32,) i32 { x + y };
4897 \\ _ = add(1, 2);
4898 \\ _ = add(1, 2,);
4899 \\}
4900 \\
4901 \\fn asm_lists() void {
4902 \\ if (false) { // Build AST but don't analyze
4903 \\ asm ("not real assembly"
4904 \\ :[a] "x" (x),);
4905 \\ asm ("not real assembly"
4906 \\ :[a] "x" (->i32),:[a] "x" (1),);
4907 \\ asm volatile ("still not real assembly"
4908 \\ :::"a","b",);
4909 \\ }
4910 \\}
4911 );
4912}
4913
4840test "zig fmt: error for invalid bit range" {4914test "zig fmt: error for invalid bit range" {
4841 try testError(4915 try testError(
4842 \\var x: []align(0:0:0)u8 = bar;4916 \\var x: []align(0:0:0)u8 = bar;
...@@ -5237,7 +5311,7 @@ fn testCanonical(source: [:0]const u8) !void {...@@ -5237,7 +5311,7 @@ fn testCanonical(source: [:0]const u8) !void {
5237 return testTransform(source, source);5311 return testTransform(source, source);
5238}5312}
52395313
5240const Error = std.zig.ast.Error.Tag;5314const Error = std.zig.Ast.Error.Tag;
52415315
5242fn testError(source: [:0]const u8, expected_errors: []const Error) !void {5316fn testError(source: [:0]const u8, expected_errors: []const Error) !void {
5243 var tree = try std.zig.parse(std.testing.allocator, source);5317 var tree = try std.zig.parse(std.testing.allocator, source);
lib/std/zig/render.zig+79-79
...@@ -3,17 +3,17 @@ const assert = std.debug.assert;...@@ -3,17 +3,17 @@ const assert = std.debug.assert;
3const mem = std.mem;3const mem = std.mem;
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const meta = std.meta;5const meta = std.meta;
6const ast = std.zig.ast;6const Ast = std.zig.Ast;
7const Token = std.zig.Token;7const Token = std.zig.Token;
88
9const indent_delta = 4;9const indent_delta = 4;
10const asm_indent_delta = 2;10const asm_indent_delta = 2;
1111
12pub const Error = ast.Tree.RenderError;12pub const Error = Ast.RenderError;
1313
14const Ais = AutoIndentingStream(std.ArrayList(u8).Writer);14const Ais = AutoIndentingStream(std.ArrayList(u8).Writer);
1515
16pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {16pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast) Error!void {
17 assert(tree.errors.len == 0); // Cannot render an invalid tree.17 assert(tree.errors.len == 0); // Cannot render an invalid tree.
18 var auto_indenting_stream = Ais{18 var auto_indenting_stream = Ais{
19 .indent_delta = indent_delta,19 .indent_delta = indent_delta,
...@@ -37,7 +37,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {...@@ -37,7 +37,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {
37}37}
3838
39/// Render all members in the given slice, keeping empty lines where appropriate39/// Render all members in the given slice, keeping empty lines where appropriate
40fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const ast.Node.Index) Error!void {40fn renderMembers(gpa: *Allocator, ais: *Ais, tree: Ast, members: []const Ast.Node.Index) Error!void {
41 if (members.len == 0) return;41 if (members.len == 0) return;
42 try renderMember(gpa, ais, tree, members[0], .newline);42 try renderMember(gpa, ais, tree, members[0], .newline);
43 for (members[1..]) |member| {43 for (members[1..]) |member| {
...@@ -46,7 +46,7 @@ fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const as...@@ -46,7 +46,7 @@ fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const as
46 }46 }
47}47}
4848
49fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) Error!void {49fn renderMember(gpa: *Allocator, ais: *Ais, tree: Ast, decl: Ast.Node.Index, space: Space) Error!void {
50 const token_tags = tree.tokens.items(.tag);50 const token_tags = tree.tokens.items(.tag);
51 const main_tokens = tree.nodes.items(.main_token);51 const main_tokens = tree.nodes.items(.main_token);
52 const datas = tree.nodes.items(.data);52 const datas = tree.nodes.items(.data);
...@@ -83,9 +83,9 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index...@@ -83,9 +83,9 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index
83 switch (tree.nodes.items(.tag)[fn_proto]) {83 switch (tree.nodes.items(.tag)[fn_proto]) {
84 .fn_proto_one, .fn_proto => {84 .fn_proto_one, .fn_proto => {
85 const callconv_expr = if (tree.nodes.items(.tag)[fn_proto] == .fn_proto_one)85 const callconv_expr = if (tree.nodes.items(.tag)[fn_proto] == .fn_proto_one)
86 tree.extraData(datas[fn_proto].lhs, ast.Node.FnProtoOne).callconv_expr86 tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProtoOne).callconv_expr
87 else87 else
88 tree.extraData(datas[fn_proto].lhs, ast.Node.FnProto).callconv_expr;88 tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProto).callconv_expr;
89 if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) {89 if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) {
90 if (mem.eql(u8, "Inline", tree.tokenSlice(main_tokens[callconv_expr]))) {90 if (mem.eql(u8, "Inline", tree.tokenSlice(main_tokens[callconv_expr]))) {
91 try ais.writer().writeAll("inline ");91 try ais.writer().writeAll("inline ");
...@@ -168,7 +168,7 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index...@@ -168,7 +168,7 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index
168}168}
169169
170/// Render all expressions in the slice, keeping empty lines where appropriate170/// Render all expressions in the slice, keeping empty lines where appropriate
171fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: ast.Tree, expressions: []const ast.Node.Index, space: Space) Error!void {171fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: Ast, expressions: []const Ast.Node.Index, space: Space) Error!void {
172 if (expressions.len == 0) return;172 if (expressions.len == 0) return;
173 try renderExpression(gpa, ais, tree, expressions[0], space);173 try renderExpression(gpa, ais, tree, expressions[0], space);
174 for (expressions[1..]) |expression| {174 for (expressions[1..]) |expression| {
...@@ -177,7 +177,7 @@ fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: ast.Tree, expressions: []...@@ -177,7 +177,7 @@ fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: ast.Tree, expressions: []
177 }177 }
178}178}
179179
180fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {180fn renderExpression(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
181 const token_tags = tree.tokens.items(.tag);181 const token_tags = tree.tokens.items(.tag);
182 const main_tokens = tree.nodes.items(.main_token);182 const main_tokens = tree.nodes.items(.main_token);
183 const node_tags = tree.nodes.items(.tag);183 const node_tags = tree.nodes.items(.tag);
...@@ -220,7 +220,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -220,7 +220,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
220 .block_two,220 .block_two,
221 .block_two_semicolon,221 .block_two_semicolon,
222 => {222 => {
223 const statements = [2]ast.Node.Index{ datas[node].lhs, datas[node].rhs };223 const statements = [2]Ast.Node.Index{ datas[node].lhs, datas[node].rhs };
224 if (datas[node].lhs == 0) {224 if (datas[node].lhs == 0) {
225 return renderBlock(gpa, ais, tree, node, statements[0..0], space);225 return renderBlock(gpa, ais, tree, node, statements[0..0], space);
226 } else if (datas[node].rhs == 0) {226 } else if (datas[node].rhs == 0) {
...@@ -413,11 +413,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -413,11 +413,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
413 .ptr_type_bit_range => return renderPtrType(gpa, ais, tree, tree.ptrTypeBitRange(node), space),413 .ptr_type_bit_range => return renderPtrType(gpa, ais, tree, tree.ptrTypeBitRange(node), space),
414414
415 .array_init_one, .array_init_one_comma => {415 .array_init_one, .array_init_one_comma => {
416 var elements: [1]ast.Node.Index = undefined;416 var elements: [1]Ast.Node.Index = undefined;
417 return renderArrayInit(gpa, ais, tree, tree.arrayInitOne(&elements, node), space);417 return renderArrayInit(gpa, ais, tree, tree.arrayInitOne(&elements, node), space);
418 },418 },
419 .array_init_dot_two, .array_init_dot_two_comma => {419 .array_init_dot_two, .array_init_dot_two_comma => {
420 var elements: [2]ast.Node.Index = undefined;420 var elements: [2]Ast.Node.Index = undefined;
421 return renderArrayInit(gpa, ais, tree, tree.arrayInitDotTwo(&elements, node), space);421 return renderArrayInit(gpa, ais, tree, tree.arrayInitDotTwo(&elements, node), space);
422 },422 },
423 .array_init_dot,423 .array_init_dot,
...@@ -428,11 +428,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -428,11 +428,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
428 => return renderArrayInit(gpa, ais, tree, tree.arrayInit(node), space),428 => return renderArrayInit(gpa, ais, tree, tree.arrayInit(node), space),
429429
430 .struct_init_one, .struct_init_one_comma => {430 .struct_init_one, .struct_init_one_comma => {
431 var fields: [1]ast.Node.Index = undefined;431 var fields: [1]Ast.Node.Index = undefined;
432 return renderStructInit(gpa, ais, tree, node, tree.structInitOne(&fields, node), space);432 return renderStructInit(gpa, ais, tree, node, tree.structInitOne(&fields, node), space);
433 },433 },
434 .struct_init_dot_two, .struct_init_dot_two_comma => {434 .struct_init_dot_two, .struct_init_dot_two_comma => {
435 var fields: [2]ast.Node.Index = undefined;435 var fields: [2]Ast.Node.Index = undefined;
436 return renderStructInit(gpa, ais, tree, node, tree.structInitDotTwo(&fields, node), space);436 return renderStructInit(gpa, ais, tree, node, tree.structInitDotTwo(&fields, node), space);
437 },437 },
438 .struct_init_dot,438 .struct_init_dot,
...@@ -443,7 +443,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -443,7 +443,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
443 => return renderStructInit(gpa, ais, tree, node, tree.structInit(node), space),443 => return renderStructInit(gpa, ais, tree, node, tree.structInit(node), space),
444444
445 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {445 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {
446 var params: [1]ast.Node.Index = undefined;446 var params: [1]Ast.Node.Index = undefined;
447 return renderCall(gpa, ais, tree, tree.callOne(&params, node), space);447 return renderCall(gpa, ais, tree, tree.callOne(&params, node), space);
448 },448 },
449449
...@@ -536,7 +536,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -536,7 +536,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
536 => return renderContainerDecl(gpa, ais, tree, node, tree.containerDecl(node), space),536 => return renderContainerDecl(gpa, ais, tree, node, tree.containerDecl(node), space),
537537
538 .container_decl_two, .container_decl_two_trailing => {538 .container_decl_two, .container_decl_two_trailing => {
539 var buffer: [2]ast.Node.Index = undefined;539 var buffer: [2]Ast.Node.Index = undefined;
540 return renderContainerDecl(gpa, ais, tree, node, tree.containerDeclTwo(&buffer, node), space);540 return renderContainerDecl(gpa, ais, tree, node, tree.containerDeclTwo(&buffer, node), space);
541 },541 },
542 .container_decl_arg,542 .container_decl_arg,
...@@ -548,7 +548,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -548,7 +548,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
548 => return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnion(node), space),548 => return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnion(node), space),
549549
550 .tagged_union_two, .tagged_union_two_trailing => {550 .tagged_union_two, .tagged_union_two_trailing => {
551 var buffer: [2]ast.Node.Index = undefined;551 var buffer: [2]Ast.Node.Index = undefined;
552 return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnionTwo(&buffer, node), space);552 return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnionTwo(&buffer, node), space);
553 },553 },
554 .tagged_union_enum_tag,554 .tagged_union_enum_tag,
...@@ -619,12 +619,12 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -619,12 +619,12 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
619 },619 },
620620
621 .fn_proto_simple => {621 .fn_proto_simple => {
622 var params: [1]ast.Node.Index = undefined;622 var params: [1]Ast.Node.Index = undefined;
623 return renderFnProto(gpa, ais, tree, tree.fnProtoSimple(&params, node), space);623 return renderFnProto(gpa, ais, tree, tree.fnProtoSimple(&params, node), space);
624 },624 },
625 .fn_proto_multi => return renderFnProto(gpa, ais, tree, tree.fnProtoMulti(node), space),625 .fn_proto_multi => return renderFnProto(gpa, ais, tree, tree.fnProtoMulti(node), space),
626 .fn_proto_one => {626 .fn_proto_one => {
627 var params: [1]ast.Node.Index = undefined;627 var params: [1]Ast.Node.Index = undefined;
628 return renderFnProto(gpa, ais, tree, tree.fnProtoOne(&params, node), space);628 return renderFnProto(gpa, ais, tree, tree.fnProtoOne(&params, node), space);
629 },629 },
630 .fn_proto => return renderFnProto(gpa, ais, tree, tree.fnProto(node), space),630 .fn_proto => return renderFnProto(gpa, ais, tree, tree.fnProto(node), space),
...@@ -645,7 +645,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -645,7 +645,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
645 => {645 => {
646 const switch_token = main_tokens[node];646 const switch_token = main_tokens[node];
647 const condition = datas[node].lhs;647 const condition = datas[node].lhs;
648 const extra = tree.extraData(datas[node].rhs, ast.Node.SubRange);648 const extra = tree.extraData(datas[node].rhs, Ast.Node.SubRange);
649 const cases = tree.extra_data[extra.start..extra.end];649 const cases = tree.extra_data[extra.start..extra.end];
650 const rparen = tree.lastToken(condition) + 1;650 const rparen = tree.lastToken(condition) + 1;
651651
...@@ -704,8 +704,8 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -704,8 +704,8 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
704fn renderArrayType(704fn renderArrayType(
705 gpa: *Allocator,705 gpa: *Allocator,
706 ais: *Ais,706 ais: *Ais,
707 tree: ast.Tree,707 tree: Ast,
708 array_type: ast.full.ArrayType,708 array_type: Ast.full.ArrayType,
709 space: Space,709 space: Space,
710) Error!void {710) Error!void {
711 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;711 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;
...@@ -726,8 +726,8 @@ fn renderArrayType(...@@ -726,8 +726,8 @@ fn renderArrayType(
726fn renderPtrType(726fn renderPtrType(
727 gpa: *Allocator,727 gpa: *Allocator,
728 ais: *Ais,728 ais: *Ais,
729 tree: ast.Tree,729 tree: Ast,
730 ptr_type: ast.full.PtrType,730 ptr_type: Ast.full.PtrType,
731 space: Space,731 space: Space,
732) Error!void {732) Error!void {
733 switch (ptr_type.size) {733 switch (ptr_type.size) {
...@@ -811,9 +811,9 @@ fn renderPtrType(...@@ -811,9 +811,9 @@ fn renderPtrType(
811fn renderSlice(811fn renderSlice(
812 gpa: *Allocator,812 gpa: *Allocator,
813 ais: *Ais,813 ais: *Ais,
814 tree: ast.Tree,814 tree: Ast,
815 slice_node: ast.Node.Index,815 slice_node: Ast.Node.Index,
816 slice: ast.full.Slice,816 slice: Ast.full.Slice,
817 space: Space,817 space: Space,
818) Error!void {818) Error!void {
819 const node_tags = tree.nodes.items(.tag);819 const node_tags = tree.nodes.items(.tag);
...@@ -847,8 +847,8 @@ fn renderSlice(...@@ -847,8 +847,8 @@ fn renderSlice(
847fn renderAsmOutput(847fn renderAsmOutput(
848 gpa: *Allocator,848 gpa: *Allocator,
849 ais: *Ais,849 ais: *Ais,
850 tree: ast.Tree,850 tree: Ast,
851 asm_output: ast.Node.Index,851 asm_output: Ast.Node.Index,
852 space: Space,852 space: Space,
853) Error!void {853) Error!void {
854 const token_tags = tree.tokens.items(.tag);854 const token_tags = tree.tokens.items(.tag);
...@@ -877,8 +877,8 @@ fn renderAsmOutput(...@@ -877,8 +877,8 @@ fn renderAsmOutput(
877fn renderAsmInput(877fn renderAsmInput(
878 gpa: *Allocator,878 gpa: *Allocator,
879 ais: *Ais,879 ais: *Ais,
880 tree: ast.Tree,880 tree: Ast,
881 asm_input: ast.Node.Index,881 asm_input: Ast.Node.Index,
882 space: Space,882 space: Space,
883) Error!void {883) Error!void {
884 const node_tags = tree.nodes.items(.tag);884 const node_tags = tree.nodes.items(.tag);
...@@ -896,7 +896,7 @@ fn renderAsmInput(...@@ -896,7 +896,7 @@ fn renderAsmInput(
896 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen896 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen
897}897}
898898
899fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!void {899fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: Ast, var_decl: Ast.full.VarDecl) Error!void {
900 if (var_decl.visib_token) |visib_token| {900 if (var_decl.visib_token) |visib_token| {
901 try renderToken(ais, tree, visib_token, Space.space); // pub901 try renderToken(ais, tree, visib_token, Space.space); // pub
902 }902 }
...@@ -985,7 +985,7 @@ fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: ast.Tree, var_decl: ast.full....@@ -985,7 +985,7 @@ fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: ast.Tree, var_decl: ast.full.
985 return renderToken(ais, tree, var_decl.ast.mut_token + 2, .newline); // ;985 return renderToken(ais, tree, var_decl.ast.mut_token + 2, .newline); // ;
986}986}
987987
988fn renderIf(gpa: *Allocator, ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error!void {988fn renderIf(gpa: *Allocator, ais: *Ais, tree: Ast, if_node: Ast.full.If, space: Space) Error!void {
989 return renderWhile(gpa, ais, tree, .{989 return renderWhile(gpa, ais, tree, .{
990 .ast = .{990 .ast = .{
991 .while_token = if_node.ast.if_token,991 .while_token = if_node.ast.if_token,
...@@ -1004,7 +1004,7 @@ fn renderIf(gpa: *Allocator, ais: *Ais, tree: ast.Tree, if_node: ast.full.If, sp...@@ -1004,7 +1004,7 @@ fn renderIf(gpa: *Allocator, ais: *Ais, tree: ast.Tree, if_node: ast.full.If, sp
10041004
1005/// Note that this function is additionally used to render if and for expressions, with1005/// Note that this function is additionally used to render if and for expressions, with
1006/// respective values set to null.1006/// respective values set to null.
1007fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Space) Error!void {1007fn renderWhile(gpa: *Allocator, ais: *Ais, tree: Ast, while_node: Ast.full.While, space: Space) Error!void {
1008 const node_tags = tree.nodes.items(.tag);1008 const node_tags = tree.nodes.items(.tag);
1009 const token_tags = tree.tokens.items(.tag);1009 const token_tags = tree.tokens.items(.tag);
10101010
...@@ -1109,8 +1109,8 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full....@@ -1109,8 +1109,8 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
1109fn renderContainerField(1109fn renderContainerField(
1110 gpa: *Allocator,1110 gpa: *Allocator,
1111 ais: *Ais,1111 ais: *Ais,
1112 tree: ast.Tree,1112 tree: Ast,
1113 field: ast.full.ContainerField,1113 field: Ast.full.ContainerField,
1114 space: Space,1114 space: Space,
1115) Error!void {1115) Error!void {
1116 if (field.comptime_token) |t| {1116 if (field.comptime_token) |t| {
...@@ -1183,9 +1183,9 @@ fn renderContainerField(...@@ -1183,9 +1183,9 @@ fn renderContainerField(
1183fn renderBuiltinCall(1183fn renderBuiltinCall(
1184 gpa: *Allocator,1184 gpa: *Allocator,
1185 ais: *Ais,1185 ais: *Ais,
1186 tree: ast.Tree,1186 tree: Ast,
1187 builtin_token: ast.TokenIndex,1187 builtin_token: Ast.TokenIndex,
1188 params: []const ast.Node.Index,1188 params: []const Ast.Node.Index,
1189 space: Space,1189 space: Space,
1190) Error!void {1190) Error!void {
1191 const token_tags = tree.tokens.items(.tag);1191 const token_tags = tree.tokens.items(.tag);
...@@ -1238,7 +1238,7 @@ fn renderBuiltinCall(...@@ -1238,7 +1238,7 @@ fn renderBuiltinCall(
1238 }1238 }
1239}1239}
12401240
1241fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: Space) Error!void {1241fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: Ast, fn_proto: Ast.full.FnProto, space: Space) Error!void {
1242 const token_tags = tree.tokens.items(.tag);1242 const token_tags = tree.tokens.items(.tag);
1243 const token_starts = tree.tokens.items(.start);1243 const token_starts = tree.tokens.items(.start);
12441244
...@@ -1417,9 +1417,9 @@ fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full....@@ -1417,9 +1417,9 @@ fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full.
1417 try renderToken(ais, tree, section_rparen, .space); // )1417 try renderToken(ais, tree, section_rparen, .space); // )
1418 }1418 }
14191419
1420 if (fn_proto.ast.callconv_expr != 0 and1420 const is_callconv_inline = mem.eql(u8, "Inline", tree.tokenSlice(tree.nodes.items(.main_token)[fn_proto.ast.callconv_expr]));
1421 !mem.eql(u8, "Inline", tree.tokenSlice(tree.nodes.items(.main_token)[fn_proto.ast.callconv_expr])))1421 const is_declaration = fn_proto.name_token != null;
1422 {1422 if (fn_proto.ast.callconv_expr != 0 and !(is_declaration and is_callconv_inline)) {
1423 const callconv_lparen = tree.firstToken(fn_proto.ast.callconv_expr) - 1;1423 const callconv_lparen = tree.firstToken(fn_proto.ast.callconv_expr) - 1;
1424 const callconv_rparen = tree.lastToken(fn_proto.ast.callconv_expr) + 1;1424 const callconv_rparen = tree.lastToken(fn_proto.ast.callconv_expr) + 1;
14251425
...@@ -1438,8 +1438,8 @@ fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full....@@ -1438,8 +1438,8 @@ fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full.
1438fn renderSwitchCase(1438fn renderSwitchCase(
1439 gpa: *Allocator,1439 gpa: *Allocator,
1440 ais: *Ais,1440 ais: *Ais,
1441 tree: ast.Tree,1441 tree: Ast,
1442 switch_case: ast.full.SwitchCase,1442 switch_case: Ast.full.SwitchCase,
1443 space: Space,1443 space: Space,
1444) Error!void {1444) Error!void {
1445 const node_tags = tree.nodes.items(.tag);1445 const node_tags = tree.nodes.items(.tag);
...@@ -1491,9 +1491,9 @@ fn renderSwitchCase(...@@ -1491,9 +1491,9 @@ fn renderSwitchCase(
1491fn renderBlock(1491fn renderBlock(
1492 gpa: *Allocator,1492 gpa: *Allocator,
1493 ais: *Ais,1493 ais: *Ais,
1494 tree: ast.Tree,1494 tree: Ast,
1495 block_node: ast.Node.Index,1495 block_node: Ast.Node.Index,
1496 statements: []const ast.Node.Index,1496 statements: []const Ast.Node.Index,
1497 space: Space,1497 space: Space,
1498) Error!void {1498) Error!void {
1499 const token_tags = tree.tokens.items(.tag);1499 const token_tags = tree.tokens.items(.tag);
...@@ -1531,9 +1531,9 @@ fn renderBlock(...@@ -1531,9 +1531,9 @@ fn renderBlock(
1531fn renderStructInit(1531fn renderStructInit(
1532 gpa: *Allocator,1532 gpa: *Allocator,
1533 ais: *Ais,1533 ais: *Ais,
1534 tree: ast.Tree,1534 tree: Ast,
1535 struct_node: ast.Node.Index,1535 struct_node: Ast.Node.Index,
1536 struct_init: ast.full.StructInit,1536 struct_init: Ast.full.StructInit,
1537 space: Space,1537 space: Space,
1538) Error!void {1538) Error!void {
1539 const token_tags = tree.tokens.items(.tag);1539 const token_tags = tree.tokens.items(.tag);
...@@ -1590,8 +1590,8 @@ fn renderStructInit(...@@ -1590,8 +1590,8 @@ fn renderStructInit(
1590fn renderArrayInit(1590fn renderArrayInit(
1591 gpa: *Allocator,1591 gpa: *Allocator,
1592 ais: *Ais,1592 ais: *Ais,
1593 tree: ast.Tree,1593 tree: Ast,
1594 array_init: ast.full.ArrayInit,1594 array_init: Ast.full.ArrayInit,
1595 space: Space,1595 space: Space,
1596) Error!void {1596) Error!void {
1597 const token_tags = tree.tokens.items(.tag);1597 const token_tags = tree.tokens.items(.tag);
...@@ -1787,9 +1787,9 @@ fn renderArrayInit(...@@ -1787,9 +1787,9 @@ fn renderArrayInit(
1787fn renderContainerDecl(1787fn renderContainerDecl(
1788 gpa: *Allocator,1788 gpa: *Allocator,
1789 ais: *Ais,1789 ais: *Ais,
1790 tree: ast.Tree,1790 tree: Ast,
1791 container_decl_node: ast.Node.Index,1791 container_decl_node: Ast.Node.Index,
1792 container_decl: ast.full.ContainerDecl,1792 container_decl: Ast.full.ContainerDecl,
1793 space: Space,1793 space: Space,
1794) Error!void {1794) Error!void {
1795 const token_tags = tree.tokens.items(.tag);1795 const token_tags = tree.tokens.items(.tag);
...@@ -1799,7 +1799,7 @@ fn renderContainerDecl(...@@ -1799,7 +1799,7 @@ fn renderContainerDecl(
1799 try renderToken(ais, tree, layout_token, .space);1799 try renderToken(ais, tree, layout_token, .space);
1800 }1800 }
18011801
1802 var lbrace: ast.TokenIndex = undefined;1802 var lbrace: Ast.TokenIndex = undefined;
1803 if (container_decl.ast.enum_token) |enum_token| {1803 if (container_decl.ast.enum_token) |enum_token| {
1804 try renderToken(ais, tree, container_decl.ast.main_token, .none); // union1804 try renderToken(ais, tree, container_decl.ast.main_token, .none); // union
1805 try renderToken(ais, tree, enum_token - 1, .none); // lparen1805 try renderToken(ais, tree, enum_token - 1, .none); // lparen
...@@ -1869,8 +1869,8 @@ fn renderContainerDecl(...@@ -1869,8 +1869,8 @@ fn renderContainerDecl(
1869fn renderAsm(1869fn renderAsm(
1870 gpa: *Allocator,1870 gpa: *Allocator,
1871 ais: *Ais,1871 ais: *Ais,
1872 tree: ast.Tree,1872 tree: Ast,
1873 asm_node: ast.full.Asm,1873 asm_node: Ast.full.Asm,
1874 space: Space,1874 space: Space,
1875) Error!void {1875) Error!void {
1876 const token_tags = tree.tokens.items(.tag);1876 const token_tags = tree.tokens.items(.tag);
...@@ -2018,8 +2018,8 @@ fn renderAsm(...@@ -2018,8 +2018,8 @@ fn renderAsm(
2018fn renderCall(2018fn renderCall(
2019 gpa: *Allocator,2019 gpa: *Allocator,
2020 ais: *Ais,2020 ais: *Ais,
2021 tree: ast.Tree,2021 tree: Ast,
2022 call: ast.full.Call,2022 call: Ast.full.Call,
2023 space: Space,2023 space: Space,
2024) Error!void {2024) Error!void {
2025 const token_tags = tree.tokens.items(.tag);2025 const token_tags = tree.tokens.items(.tag);
...@@ -2091,7 +2091,7 @@ fn renderCall(...@@ -2091,7 +2091,7 @@ fn renderCall(
20912091
2092/// Renders the given expression indented, popping the indent before rendering2092/// Renders the given expression indented, popping the indent before rendering
2093/// any following line comments2093/// any following line comments
2094fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {2094fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
2095 const token_starts = tree.tokens.items(.start);2095 const token_starts = tree.tokens.items(.start);
2096 const token_tags = tree.tokens.items(.tag);2096 const token_tags = tree.tokens.items(.tag);
20972097
...@@ -2148,7 +2148,7 @@ fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: as...@@ -2148,7 +2148,7 @@ fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: as
2148}2148}
21492149
2150/// Render an expression, and the comma that follows it, if it is present in the source.2150/// Render an expression, and the comma that follows it, if it is present in the source.
2151fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {2151fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
2152 const token_tags = tree.tokens.items(.tag);2152 const token_tags = tree.tokens.items(.tag);
2153 const maybe_comma = tree.lastToken(node) + 1;2153 const maybe_comma = tree.lastToken(node) + 1;
2154 if (token_tags[maybe_comma] == .comma) {2154 if (token_tags[maybe_comma] == .comma) {
...@@ -2159,7 +2159,7 @@ fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.N...@@ -2159,7 +2159,7 @@ fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.N
2159 }2159 }
2160}2160}
21612161
2162fn renderTokenComma(ais: *Ais, tree: ast.Tree, token: ast.TokenIndex, space: Space) Error!void {2162fn renderTokenComma(ais: *Ais, tree: Ast, token: Ast.TokenIndex, space: Space) Error!void {
2163 const token_tags = tree.tokens.items(.tag);2163 const token_tags = tree.tokens.items(.tag);
2164 const maybe_comma = token + 1;2164 const maybe_comma = token + 1;
2165 if (token_tags[maybe_comma] == .comma) {2165 if (token_tags[maybe_comma] == .comma) {
...@@ -2191,7 +2191,7 @@ const Space = enum {...@@ -2191,7 +2191,7 @@ const Space = enum {
2191 skip,2191 skip,
2192};2192};
21932193
2194fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void {2194fn renderToken(ais: *Ais, tree: Ast, token_index: Ast.TokenIndex, space: Space) Error!void {
2195 const token_tags = tree.tokens.items(.tag);2195 const token_tags = tree.tokens.items(.tag);
2196 const token_starts = tree.tokens.items(.start);2196 const token_starts = tree.tokens.items(.start);
21972197
...@@ -2238,7 +2238,7 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp...@@ -2238,7 +2238,7 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp
2238/// `start_token` to `end_token`. This is used to determine if e.g. a2238/// `start_token` to `end_token`. This is used to determine if e.g. a
2239/// fn_proto should be wrapped and have a trailing comma inserted even if2239/// fn_proto should be wrapped and have a trailing comma inserted even if
2240/// there is none in the source.2240/// there is none in the source.
2241fn hasComment(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenIndex) bool {2241fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool {
2242 const token_starts = tree.tokens.items(.start);2242 const token_starts = tree.tokens.items(.start);
22432243
2244 var i = start_token;2244 var i = start_token;
...@@ -2253,7 +2253,7 @@ fn hasComment(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenI...@@ -2253,7 +2253,7 @@ fn hasComment(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenI
22532253
2254/// Returns true if there exists a multiline string literal between the start2254/// Returns true if there exists a multiline string literal between the start
2255/// of token `start_token` and the start of token `end_token`.2255/// of token `start_token` and the start of token `end_token`.
2256fn hasMultilineString(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenIndex) bool {2256fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool {
2257 const token_tags = tree.tokens.items(.tag);2257 const token_tags = tree.tokens.items(.tag);
22582258
2259 for (token_tags[start_token..end_token]) |tag| {2259 for (token_tags[start_token..end_token]) |tag| {
...@@ -2268,7 +2268,7 @@ fn hasMultilineString(tree: ast.Tree, start_token: ast.TokenIndex, end_token: as...@@ -2268,7 +2268,7 @@ fn hasMultilineString(tree: ast.Tree, start_token: ast.TokenIndex, end_token: as
22682268
2269/// Assumes that start is the first byte past the previous token and2269/// Assumes that start is the first byte past the previous token and
2270/// that end is the last byte before the next token.2270/// that end is the last byte before the next token.
2271fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!bool {2271fn renderComments(ais: *Ais, tree: Ast, start: usize, end: usize) Error!bool {
2272 var index: usize = start;2272 var index: usize = start;
2273 while (mem.indexOf(u8, tree.source[index..end], "//")) |offset| {2273 while (mem.indexOf(u8, tree.source[index..end], "//")) |offset| {
2274 const comment_start = index + offset;2274 const comment_start = index + offset;
...@@ -2325,12 +2325,12 @@ fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!boo...@@ -2325,12 +2325,12 @@ fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!boo
2325 return index != start;2325 return index != start;
2326}2326}
23272327
2328fn renderExtraNewline(ais: *Ais, tree: ast.Tree, node: ast.Node.Index) Error!void {2328fn renderExtraNewline(ais: *Ais, tree: Ast, node: Ast.Node.Index) Error!void {
2329 return renderExtraNewlineToken(ais, tree, tree.firstToken(node));2329 return renderExtraNewlineToken(ais, tree, tree.firstToken(node));
2330}2330}
23312331
2332/// Check if there is an empty line immediately before the given token. If so, render it.2332/// Check if there is an empty line immediately before the given token. If so, render it.
2333fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex) Error!void {2333fn renderExtraNewlineToken(ais: *Ais, tree: Ast, token_index: Ast.TokenIndex) Error!void {
2334 const token_starts = tree.tokens.items(.start);2334 const token_starts = tree.tokens.items(.start);
2335 const token_start = token_starts[token_index];2335 const token_start = token_starts[token_index];
2336 if (token_start == 0) return;2336 if (token_start == 0) return;
...@@ -2355,7 +2355,7 @@ fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenInde...@@ -2355,7 +2355,7 @@ fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenInde
23552355
2356/// end_token is the token one past the last doc comment token. This function2356/// end_token is the token one past the last doc comment token. This function
2357/// searches backwards from there.2357/// searches backwards from there.
2358fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error!void {2358fn renderDocComments(ais: *Ais, tree: Ast, end_token: Ast.TokenIndex) Error!void {
2359 // Search backwards for the first doc comment.2359 // Search backwards for the first doc comment.
2360 const token_tags = tree.tokens.items(.tag);2360 const token_tags = tree.tokens.items(.tag);
2361 if (end_token == 0) return;2361 if (end_token == 0) return;
...@@ -2376,7 +2376,7 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error...@@ -2376,7 +2376,7 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error
2376}2376}
23772377
2378/// start_token is first container doc comment token.2378/// start_token is first container doc comment token.
2379fn renderContainerDocComments(ais: *Ais, tree: ast.Tree, start_token: ast.TokenIndex) Error!void {2379fn renderContainerDocComments(ais: *Ais, tree: Ast, start_token: Ast.TokenIndex) Error!void {
2380 const token_tags = tree.tokens.items(.tag);2380 const token_tags = tree.tokens.items(.tag);
2381 var tok = start_token;2381 var tok = start_token;
2382 while (token_tags[tok] == .container_doc_comment) : (tok += 1) {2382 while (token_tags[tok] == .container_doc_comment) : (tok += 1) {
...@@ -2390,7 +2390,7 @@ fn renderContainerDocComments(ais: *Ais, tree: ast.Tree, start_token: ast.TokenI...@@ -2390,7 +2390,7 @@ fn renderContainerDocComments(ais: *Ais, tree: ast.Tree, start_token: ast.TokenI
2390 }2390 }
2391}2391}
23922392
2393fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {2393fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 {
2394 var ret = tree.tokenSlice(token_index);2394 var ret = tree.tokenSlice(token_index);
2395 if (tree.tokens.items(.tag)[token_index] == .multiline_string_literal_line) {2395 if (tree.tokens.items(.tag)[token_index] == .multiline_string_literal_line) {
2396 assert(ret[ret.len - 1] == '\n');2396 assert(ret[ret.len - 1] == '\n');
...@@ -2399,7 +2399,7 @@ fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {...@@ -2399,7 +2399,7 @@ fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {
2399 return ret;2399 return ret;
2400}2400}
24012401
2402fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {2402fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool {
2403 const token_starts = tree.tokens.items(.start);2403 const token_starts = tree.tokens.items(.start);
2404 const between_source = tree.source[token_starts[token_index]..token_starts[token_index + 1]];2404 const between_source = tree.source[token_starts[token_index]..token_starts[token_index + 1]];
2405 for (between_source) |byte| switch (byte) {2405 for (between_source) |byte| switch (byte) {
...@@ -2412,7 +2412,7 @@ fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {...@@ -2412,7 +2412,7 @@ fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {
24122412
2413/// Returns `true` if and only if there are any tokens or line comments between2413/// Returns `true` if and only if there are any tokens or line comments between
2414/// start_token and end_token.2414/// start_token and end_token.
2415fn anythingBetween(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenIndex) bool {2415fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool {
2416 if (start_token + 1 != end_token) return true;2416 if (start_token + 1 != end_token) return true;
2417 const token_starts = tree.tokens.items(.start);2417 const token_starts = tree.tokens.items(.start);
2418 const between_source = tree.source[token_starts[start_token]..token_starts[start_token + 1]];2418 const between_source = tree.source[token_starts[start_token]..token_starts[start_token + 1]];
...@@ -2431,7 +2431,7 @@ fn writeFixingWhitespace(writer: std.ArrayList(u8).Writer, slice: []const u8) Er...@@ -2431,7 +2431,7 @@ fn writeFixingWhitespace(writer: std.ArrayList(u8).Writer, slice: []const u8) Er
2431 };2431 };
2432}2432}
24332433
2434fn nodeIsBlock(tag: ast.Node.Tag) bool {2434fn nodeIsBlock(tag: Ast.Node.Tag) bool {
2435 return switch (tag) {2435 return switch (tag) {
2436 .block,2436 .block,
2437 .block_semicolon,2437 .block_semicolon,
...@@ -2450,7 +2450,7 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool {...@@ -2450,7 +2450,7 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool {
2450 };2450 };
2451}2451}
24522452
2453fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool {2453fn nodeIsIfForWhileSwitch(tag: Ast.Node.Tag) bool {
2454 return switch (tag) {2454 return switch (tag) {
2455 .@"if",2455 .@"if",
2456 .if_simple,2456 .if_simple,
...@@ -2466,7 +2466,7 @@ fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool {...@@ -2466,7 +2466,7 @@ fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool {
2466 };2466 };
2467}2467}
24682468
2469fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {2469fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool {
2470 return switch (tag) {2470 return switch (tag) {
2471 .@"catch",2471 .@"catch",
2472 .add,2472 .add,
...@@ -2516,7 +2516,7 @@ fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {...@@ -2516,7 +2516,7 @@ fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {
2516}2516}
25172517
2518// Returns the number of nodes in `expr` that are on the same line as `rtoken`.2518// Returns the number of nodes in `expr` that are on the same line as `rtoken`.
2519fn rowSize(tree: ast.Tree, exprs: []const ast.Node.Index, rtoken: ast.TokenIndex) usize {2519fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usize {
2520 const token_tags = tree.tokens.items(.tag);2520 const token_tags = tree.tokens.items(.tag);
25212521
2522 const first_token = tree.firstToken(exprs[0]);2522 const first_token = tree.firstToken(exprs[0]);
lib/std/zig/system.zig+2-2
...@@ -309,8 +309,8 @@ pub const NativeTargetInfo = struct {...@@ -309,8 +309,8 @@ pub const NativeTargetInfo = struct {
309 },309 },
310 .openbsd => {310 .openbsd => {
311 const mib: [2]c_int = [_]c_int{311 const mib: [2]c_int = [_]c_int{
312 std.os.CTL_KERN,312 std.os.CTL.KERN,
313 std.os.KERN_OSRELEASE,313 std.os.KERN.OSRELEASE,
314 };314 };
315 var buf: [64]u8 = undefined;315 var buf: [64]u8 = undefined;
316 var len: usize = buf.len;316 var len: usize = buf.len;
lib/std/zig/system/darwin/macos.zig+2-2
...@@ -404,8 +404,8 @@ fn testVersionEquality(expected: std.builtin.Version, got: std.builtin.Version)...@@ -404,8 +404,8 @@ fn testVersionEquality(expected: std.builtin.Version, got: std.builtin.Version)
404}404}
405405
406pub fn detectNativeCpuAndFeatures() ?Target.Cpu {406pub fn detectNativeCpuAndFeatures() ?Target.Cpu {
407 var cpu_family: os.CPUFAMILY = undefined;407 var cpu_family: std.c.CPUFAMILY = undefined;
408 var len: usize = @sizeOf(os.CPUFAMILY);408 var len: usize = @sizeOf(std.c.CPUFAMILY);
409 os.sysctlbynameZ("hw.cpufamily", &cpu_family, &len, null, 0) catch |err| switch (err) {409 os.sysctlbynameZ("hw.cpufamily", &cpu_family, &len, null, 0) catch |err| switch (err) {
410 error.NameTooLong => unreachable, // constant, known good value410 error.NameTooLong => unreachable, // constant, known good value
411 error.PermissionDenied => unreachable, // only when setting values,411 error.PermissionDenied => unreachable, // only when setting values,
src/Air.zig+32
...@@ -69,6 +69,10 @@ pub const Inst = struct {...@@ -69,6 +69,10 @@ pub const Inst = struct {
69 /// is the same as both operands.69 /// is the same as both operands.
70 /// Uses the `bin_op` field.70 /// Uses the `bin_op` field.
71 div,71 div,
72 /// Integer or float remainder.
73 /// Both operands are guaranteed to be the same type, and the result type is the same as both operands.
74 /// Uses the `bin_op` field.
75 rem,
72 /// Add an offset to a pointer, returning a new pointer.76 /// Add an offset to a pointer, returning a new pointer.
73 /// The offset is in element type units, not bytes.77 /// The offset is in element type units, not bytes.
74 /// Wrapping is undefined behavior.78 /// Wrapping is undefined behavior.
...@@ -302,6 +306,13 @@ pub const Inst = struct {...@@ -302,6 +306,13 @@ pub const Inst = struct {
302 /// Result type is the element type of the inner pointer operand.306 /// Result type is the element type of the inner pointer operand.
303 /// Uses the `bin_op` field.307 /// Uses the `bin_op` field.
304 ptr_ptr_elem_val,308 ptr_ptr_elem_val,
309 /// Given a pointer to an array, return a slice.
310 /// Uses the `ty_op` field.
311 array_to_slice,
312 /// Uses the `ty_pl` field with payload `Cmpxchg`.
313 cmpxchg_weak,
314 /// Uses the `ty_pl` field with payload `Cmpxchg`.
315 cmpxchg_strong,
305316
306 pub fn fromCmpOp(op: std.math.CompareOperator) Tag {317 pub fn fromCmpOp(op: std.math.CompareOperator) Tag {
307 return switch (op) {318 return switch (op) {
...@@ -436,6 +447,23 @@ pub const Asm = struct {...@@ -436,6 +447,23 @@ pub const Asm = struct {
436 zir_index: u32,447 zir_index: u32,
437};448};
438449
450pub const Cmpxchg = struct {
451 ptr: Inst.Ref,
452 expected_value: Inst.Ref,
453 new_value: Inst.Ref,
454 /// 0b00000000000000000000000000000XXX - success_order
455 /// 0b00000000000000000000000000XXX000 - failure_order
456 flags: u32,
457
458 pub fn successOrder(self: Cmpxchg) std.builtin.AtomicOrder {
459 return @intToEnum(std.builtin.AtomicOrder, @truncate(u3, self.flags));
460 }
461
462 pub fn failureOrder(self: Cmpxchg) std.builtin.AtomicOrder {
463 return @intToEnum(std.builtin.AtomicOrder, @truncate(u3, self.flags >> 3));
464 }
465};
466
439pub fn getMainBody(air: Air) []const Air.Inst.Index {467pub fn getMainBody(air: Air) []const Air.Inst.Index {
440 const body_index = air.extra[@enumToInt(ExtraIndex.main_block)];468 const body_index = air.extra[@enumToInt(ExtraIndex.main_block)];
441 const extra = air.extraData(Block, body_index);469 const extra = air.extraData(Block, body_index);
...@@ -462,6 +490,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -462,6 +490,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
462 .mul,490 .mul,
463 .mulwrap,491 .mulwrap,
464 .div,492 .div,
493 .rem,
465 .bit_and,494 .bit_and,
466 .bit_or,495 .bit_or,
467 .xor,496 .xor,
...@@ -499,6 +528,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -499,6 +528,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
499 .struct_field_ptr,528 .struct_field_ptr,
500 .struct_field_val,529 .struct_field_val,
501 .ptr_elem_ptr,530 .ptr_elem_ptr,
531 .cmpxchg_weak,
532 .cmpxchg_strong,
502 => return air.getRefType(datas[inst].ty_pl.ty),533 => return air.getRefType(datas[inst].ty_pl.ty),
503534
504 .not,535 .not,
...@@ -521,6 +552,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -521,6 +552,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
521 .struct_field_ptr_index_1,552 .struct_field_ptr_index_1,
522 .struct_field_ptr_index_2,553 .struct_field_ptr_index_2,
523 .struct_field_ptr_index_3,554 .struct_field_ptr_index_3,
555 .array_to_slice,
524 => return air.getRefType(datas[inst].ty_op.ty),556 => return air.getRefType(datas[inst].ty_op.ty),
525557
526 .loop,558 .loop,
src/AstGen.zig+305-284
...@@ -2,18 +2,20 @@...@@ -2,18 +2,20 @@
2const AstGen = @This();2const AstGen = @This();
33
4const std = @import("std");4const std = @import("std");
5const ast = std.zig.ast;5const Ast = std.zig.Ast;
6const mem = std.mem;6const mem = std.mem;
7const Allocator = std.mem.Allocator;7const Allocator = std.mem.Allocator;
8const assert = std.debug.assert;8const assert = std.debug.assert;
9const ArrayListUnmanaged = std.ArrayListUnmanaged;9const ArrayListUnmanaged = std.ArrayListUnmanaged;
10const StringIndexAdapter = std.hash_map.StringIndexAdapter;
11const StringIndexContext = std.hash_map.StringIndexContext;
1012
11const Zir = @import("Zir.zig");13const Zir = @import("Zir.zig");
12const trace = @import("tracy.zig").trace;14const trace = @import("tracy.zig").trace;
13const BuiltinFn = @import("BuiltinFn.zig");15const BuiltinFn = @import("BuiltinFn.zig");
1416
15gpa: *Allocator,17gpa: *Allocator,
16tree: *const ast.Tree,18tree: *const Ast,
17instructions: std.MultiArrayList(Zir.Inst) = .{},19instructions: std.MultiArrayList(Zir.Inst) = .{},
18extra: ArrayListUnmanaged(u32) = .{},20extra: ArrayListUnmanaged(u32) = .{},
19string_bytes: ArrayListUnmanaged(u8) = .{},21string_bytes: ArrayListUnmanaged(u8) = .{},
...@@ -30,13 +32,13 @@ source_column: u32 = 0,...@@ -30,13 +32,13 @@ source_column: u32 = 0,
30/// Used for temporary allocations; freed after AstGen is complete.32/// Used for temporary allocations; freed after AstGen is complete.
31/// The resulting ZIR code has no references to anything in this arena.33/// The resulting ZIR code has no references to anything in this arena.
32arena: *Allocator,34arena: *Allocator,
33string_table: std.StringHashMapUnmanaged(u32) = .{},35string_table: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
34compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},36compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},
35/// The topmost block of the current function.37/// The topmost block of the current function.
36fn_block: ?*GenZir = null,38fn_block: ?*GenZir = null,
37/// Maps string table indexes to the first `@import` ZIR instruction39/// Maps string table indexes to the first `@import` ZIR instruction
38/// that uses this string as the operand.40/// that uses this string as the operand.
39imports: std.AutoArrayHashMapUnmanaged(u32, ast.TokenIndex) = .{},41imports: std.AutoArrayHashMapUnmanaged(u32, Ast.TokenIndex) = .{},
4042
41const InnerError = error{ OutOfMemory, AnalysisFail };43const InnerError = error{ OutOfMemory, AnalysisFail };
4244
...@@ -70,7 +72,7 @@ fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {...@@ -70,7 +72,7 @@ fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {
70 astgen.extra.appendSliceAssumeCapacity(coerced);72 astgen.extra.appendSliceAssumeCapacity(coerced);
71}73}
7274
73pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {75pub fn generate(gpa: *Allocator, tree: Ast) Allocator.Error!Zir {
74 var arena = std.heap.ArenaAllocator.init(gpa);76 var arena = std.heap.ArenaAllocator.init(gpa);
75 defer arena.deinit();77 defer arena.deinit();
7678
...@@ -106,7 +108,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {...@@ -106,7 +108,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {
106 };108 };
107 defer gen_scope.instructions.deinit(gpa);109 defer gen_scope.instructions.deinit(gpa);
108110
109 const container_decl: ast.full.ContainerDecl = .{111 const container_decl: Ast.full.ContainerDecl = .{
110 .layout_token = null,112 .layout_token = null,
111 .ast = .{113 .ast = .{
112 .main_token = undefined,114 .main_token = undefined,
...@@ -265,7 +267,7 @@ pub const bool_rl: ResultLoc = .{ .ty = .bool_type };...@@ -265,7 +267,7 @@ pub const bool_rl: ResultLoc = .{ .ty = .bool_type };
265pub const type_rl: ResultLoc = .{ .ty = .type_type };267pub const type_rl: ResultLoc = .{ .ty = .type_type };
266pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type };268pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type };
267269
268fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zir.Inst.Ref {270fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
269 const prev_force_comptime = gz.force_comptime;271 const prev_force_comptime = gz.force_comptime;
270 gz.force_comptime = true;272 gz.force_comptime = true;
271 defer gz.force_comptime = prev_force_comptime;273 defer gz.force_comptime = prev_force_comptime;
...@@ -278,8 +280,8 @@ fn reachableExpr(...@@ -278,8 +280,8 @@ fn reachableExpr(
278 gz: *GenZir,280 gz: *GenZir,
279 scope: *Scope,281 scope: *Scope,
280 rl: ResultLoc,282 rl: ResultLoc,
281 node: ast.Node.Index,283 node: Ast.Node.Index,
282 src_node: ast.Node.Index,284 src_node: Ast.Node.Index,
283) InnerError!Zir.Inst.Ref {285) InnerError!Zir.Inst.Ref {
284 const result_inst = try expr(gz, scope, rl, node);286 const result_inst = try expr(gz, scope, rl, node);
285 if (gz.refIsNoReturn(result_inst)) {287 if (gz.refIsNoReturn(result_inst)) {
...@@ -290,7 +292,7 @@ fn reachableExpr(...@@ -290,7 +292,7 @@ fn reachableExpr(
290 return result_inst;292 return result_inst;
291}293}
292294
293fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {295fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
294 const astgen = gz.astgen;296 const astgen = gz.astgen;
295 const tree = astgen.tree;297 const tree = astgen.tree;
296 const node_tags = tree.nodes.items(.tag);298 const node_tags = tree.nodes.items(.tag);
...@@ -481,7 +483,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Ins...@@ -481,7 +483,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Ins
481/// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the483/// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the
482/// result instruction can be used to inspect whether it is isNoReturn() but that is it,484/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
483/// it must otherwise not be used.485/// it must otherwise not be used.
484fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {486fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
485 const astgen = gz.astgen;487 const astgen = gz.astgen;
486 const tree = astgen.tree;488 const tree = astgen.tree;
487 const main_tokens = tree.nodes.items(.main_token);489 const main_tokens = tree.nodes.items(.main_token);
...@@ -640,13 +642,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -640,13 +642,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
640642
641 .builtin_call_two, .builtin_call_two_comma => {643 .builtin_call_two, .builtin_call_two_comma => {
642 if (node_datas[node].lhs == 0) {644 if (node_datas[node].lhs == 0) {
643 const params = [_]ast.Node.Index{};645 const params = [_]Ast.Node.Index{};
644 return builtinCall(gz, scope, rl, node, &params);646 return builtinCall(gz, scope, rl, node, &params);
645 } else if (node_datas[node].rhs == 0) {647 } else if (node_datas[node].rhs == 0) {
646 const params = [_]ast.Node.Index{node_datas[node].lhs};648 const params = [_]Ast.Node.Index{node_datas[node].lhs};
647 return builtinCall(gz, scope, rl, node, &params);649 return builtinCall(gz, scope, rl, node, &params);
648 } else {650 } else {
649 const params = [_]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };651 const params = [_]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
650 return builtinCall(gz, scope, rl, node, &params);652 return builtinCall(gz, scope, rl, node, &params);
651 }653 }
652 },654 },
...@@ -656,7 +658,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -656,7 +658,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
656 },658 },
657659
658 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {660 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {
659 var params: [1]ast.Node.Index = undefined;661 var params: [1]Ast.Node.Index = undefined;
660 return callExpr(gz, scope, rl, node, tree.callOne(&params, node));662 return callExpr(gz, scope, rl, node, tree.callOne(&params, node));
661 },663 },
662 .call, .call_comma, .async_call, .async_call_comma => {664 .call, .call_comma, .async_call, .async_call_comma => {
...@@ -704,7 +706,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -704,7 +706,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
704 },706 },
705 .slice => {707 .slice => {
706 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);708 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);
707 const extra = tree.extraData(node_datas[node].rhs, ast.Node.Slice);709 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice);
708 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);710 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);
709 const end = try expr(gz, scope, .{ .ty = .usize_type }, extra.end);711 const end = try expr(gz, scope, .{ .ty = .usize_type }, extra.end);
710 const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{712 const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{
...@@ -722,7 +724,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -722,7 +724,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
722 },724 },
723 .slice_sentinel => {725 .slice_sentinel => {
724 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);726 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);
725 const extra = tree.extraData(node_datas[node].rhs, ast.Node.SliceSentinel);727 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel);
726 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);728 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);
727 const end = if (extra.end != 0) try expr(gz, scope, .{ .ty = .usize_type }, extra.end) else .none;729 const end = if (extra.end != 0) try expr(gz, scope, .{ .ty = .usize_type }, extra.end) else .none;
728 const sentinel = try expr(gz, scope, .{ .ty = .usize_type }, extra.sentinel);730 const sentinel = try expr(gz, scope, .{ .ty = .usize_type }, extra.sentinel);
...@@ -773,7 +775,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -773,7 +775,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
773 ), node),775 ), node),
774 },776 },
775 .block_two, .block_two_semicolon => {777 .block_two, .block_two_semicolon => {
776 const statements = [2]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };778 const statements = [2]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
777 if (node_datas[node].lhs == 0) {779 if (node_datas[node].lhs == 0) {
778 return blockExpr(gz, scope, rl, node, statements[0..0]);780 return blockExpr(gz, scope, rl, node, statements[0..0]);
779 } else if (node_datas[node].rhs == 0) {781 } else if (node_datas[node].rhs == 0) {
...@@ -796,7 +798,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -796,7 +798,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
796 },798 },
797 .@"catch" => {799 .@"catch" => {
798 const catch_token = main_tokens[node];800 const catch_token = main_tokens[node];
799 const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)801 const payload_token: ?Ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
800 catch_token + 2802 catch_token + 2
801 else803 else
802 null;804 null;
...@@ -863,7 +865,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -863,7 +865,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
863 .container_decl_trailing,865 .container_decl_trailing,
864 => return containerDecl(gz, scope, rl, node, tree.containerDecl(node)),866 => return containerDecl(gz, scope, rl, node, tree.containerDecl(node)),
865 .container_decl_two, .container_decl_two_trailing => {867 .container_decl_two, .container_decl_two_trailing => {
866 var buffer: [2]ast.Node.Index = undefined;868 var buffer: [2]Ast.Node.Index = undefined;
867 return containerDecl(gz, scope, rl, node, tree.containerDeclTwo(&buffer, node));869 return containerDecl(gz, scope, rl, node, tree.containerDeclTwo(&buffer, node));
868 },870 },
869 .container_decl_arg,871 .container_decl_arg,
...@@ -874,7 +876,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -874,7 +876,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
874 .tagged_union_trailing,876 .tagged_union_trailing,
875 => return containerDecl(gz, scope, rl, node, tree.taggedUnion(node)),877 => return containerDecl(gz, scope, rl, node, tree.taggedUnion(node)),
876 .tagged_union_two, .tagged_union_two_trailing => {878 .tagged_union_two, .tagged_union_two_trailing => {
877 var buffer: [2]ast.Node.Index = undefined;879 var buffer: [2]Ast.Node.Index = undefined;
878 return containerDecl(gz, scope, rl, node, tree.taggedUnionTwo(&buffer, node));880 return containerDecl(gz, scope, rl, node, tree.taggedUnionTwo(&buffer, node));
879 },881 },
880 .tagged_union_enum_tag,882 .tagged_union_enum_tag,
...@@ -900,11 +902,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -900,11 +902,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
900 .@"try" => return tryExpr(gz, scope, rl, node, node_datas[node].lhs),902 .@"try" => return tryExpr(gz, scope, rl, node, node_datas[node].lhs),
901903
902 .array_init_one, .array_init_one_comma => {904 .array_init_one, .array_init_one_comma => {
903 var elements: [1]ast.Node.Index = undefined;905 var elements: [1]Ast.Node.Index = undefined;
904 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node));906 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node));
905 },907 },
906 .array_init_dot_two, .array_init_dot_two_comma => {908 .array_init_dot_two, .array_init_dot_two_comma => {
907 var elements: [2]ast.Node.Index = undefined;909 var elements: [2]Ast.Node.Index = undefined;
908 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node));910 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node));
909 },911 },
910 .array_init_dot,912 .array_init_dot,
...@@ -915,11 +917,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -915,11 +917,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
915 => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)),917 => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)),
916918
917 .struct_init_one, .struct_init_one_comma => {919 .struct_init_one, .struct_init_one_comma => {
918 var fields: [1]ast.Node.Index = undefined;920 var fields: [1]Ast.Node.Index = undefined;
919 return structInitExpr(gz, scope, rl, node, tree.structInitOne(&fields, node));921 return structInitExpr(gz, scope, rl, node, tree.structInitOne(&fields, node));
920 },922 },
921 .struct_init_dot_two, .struct_init_dot_two_comma => {923 .struct_init_dot_two, .struct_init_dot_two_comma => {
922 var fields: [2]ast.Node.Index = undefined;924 var fields: [2]Ast.Node.Index = undefined;
923 return structInitExpr(gz, scope, rl, node, tree.structInitDotTwo(&fields, node));925 return structInitExpr(gz, scope, rl, node, tree.structInitDotTwo(&fields, node));
924 },926 },
925 .struct_init_dot,927 .struct_init_dot,
...@@ -930,14 +932,14 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -930,14 +932,14 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
930 => return structInitExpr(gz, scope, rl, node, tree.structInit(node)),932 => return structInitExpr(gz, scope, rl, node, tree.structInit(node)),
931933
932 .fn_proto_simple => {934 .fn_proto_simple => {
933 var params: [1]ast.Node.Index = undefined;935 var params: [1]Ast.Node.Index = undefined;
934 return fnProtoExpr(gz, scope, rl, tree.fnProtoSimple(&params, node));936 return fnProtoExpr(gz, scope, rl, tree.fnProtoSimple(&params, node));
935 },937 },
936 .fn_proto_multi => {938 .fn_proto_multi => {
937 return fnProtoExpr(gz, scope, rl, tree.fnProtoMulti(node));939 return fnProtoExpr(gz, scope, rl, tree.fnProtoMulti(node));
938 },940 },
939 .fn_proto_one => {941 .fn_proto_one => {
940 var params: [1]ast.Node.Index = undefined;942 var params: [1]Ast.Node.Index = undefined;
941 return fnProtoExpr(gz, scope, rl, tree.fnProtoOne(&params, node));943 return fnProtoExpr(gz, scope, rl, tree.fnProtoOne(&params, node));
942 },944 },
943 .fn_proto => {945 .fn_proto => {
...@@ -950,7 +952,7 @@ fn nosuspendExpr(...@@ -950,7 +952,7 @@ fn nosuspendExpr(
950 gz: *GenZir,952 gz: *GenZir,
951 scope: *Scope,953 scope: *Scope,
952 rl: ResultLoc,954 rl: ResultLoc,
953 node: ast.Node.Index,955 node: Ast.Node.Index,
954) InnerError!Zir.Inst.Ref {956) InnerError!Zir.Inst.Ref {
955 const astgen = gz.astgen;957 const astgen = gz.astgen;
956 const tree = astgen.tree;958 const tree = astgen.tree;
...@@ -971,7 +973,7 @@ fn nosuspendExpr(...@@ -971,7 +973,7 @@ fn nosuspendExpr(
971fn suspendExpr(973fn suspendExpr(
972 gz: *GenZir,974 gz: *GenZir,
973 scope: *Scope,975 scope: *Scope,
974 node: ast.Node.Index,976 node: Ast.Node.Index,
975) InnerError!Zir.Inst.Ref {977) InnerError!Zir.Inst.Ref {
976 const astgen = gz.astgen;978 const astgen = gz.astgen;
977 const gpa = astgen.gpa;979 const gpa = astgen.gpa;
...@@ -1011,7 +1013,7 @@ fn awaitExpr(...@@ -1011,7 +1013,7 @@ fn awaitExpr(
1011 gz: *GenZir,1013 gz: *GenZir,
1012 scope: *Scope,1014 scope: *Scope,
1013 rl: ResultLoc,1015 rl: ResultLoc,
1014 node: ast.Node.Index,1016 node: Ast.Node.Index,
1015) InnerError!Zir.Inst.Ref {1017) InnerError!Zir.Inst.Ref {
1016 const astgen = gz.astgen;1018 const astgen = gz.astgen;
1017 const tree = astgen.tree;1019 const tree = astgen.tree;
...@@ -1033,7 +1035,7 @@ fn resumeExpr(...@@ -1033,7 +1035,7 @@ fn resumeExpr(
1033 gz: *GenZir,1035 gz: *GenZir,
1034 scope: *Scope,1036 scope: *Scope,
1035 rl: ResultLoc,1037 rl: ResultLoc,
1036 node: ast.Node.Index,1038 node: Ast.Node.Index,
1037) InnerError!Zir.Inst.Ref {1039) InnerError!Zir.Inst.Ref {
1038 const astgen = gz.astgen;1040 const astgen = gz.astgen;
1039 const tree = astgen.tree;1041 const tree = astgen.tree;
...@@ -1048,7 +1050,7 @@ fn fnProtoExpr(...@@ -1048,7 +1050,7 @@ fn fnProtoExpr(
1048 gz: *GenZir,1050 gz: *GenZir,
1049 scope: *Scope,1051 scope: *Scope,
1050 rl: ResultLoc,1052 rl: ResultLoc,
1051 fn_proto: ast.full.FnProto,1053 fn_proto: Ast.full.FnProto,
1052) InnerError!Zir.Inst.Ref {1054) InnerError!Zir.Inst.Ref {
1053 const astgen = gz.astgen;1055 const astgen = gz.astgen;
1054 const gpa = astgen.gpa;1056 const gpa = astgen.gpa;
...@@ -1159,8 +1161,8 @@ fn arrayInitExpr(...@@ -1159,8 +1161,8 @@ fn arrayInitExpr(
1159 gz: *GenZir,1161 gz: *GenZir,
1160 scope: *Scope,1162 scope: *Scope,
1161 rl: ResultLoc,1163 rl: ResultLoc,
1162 node: ast.Node.Index,1164 node: Ast.Node.Index,
1163 array_init: ast.full.ArrayInit,1165 array_init: Ast.full.ArrayInit,
1164) InnerError!Zir.Inst.Ref {1166) InnerError!Zir.Inst.Ref {
1165 const astgen = gz.astgen;1167 const astgen = gz.astgen;
1166 const tree = astgen.tree;1168 const tree = astgen.tree;
...@@ -1179,7 +1181,7 @@ fn arrayInitExpr(...@@ -1179,7 +1181,7 @@ fn arrayInitExpr(
1179 };1181 };
11801182
1181 infer: {1183 infer: {
1182 const array_type: ast.full.ArrayType = switch (node_tags[array_init.ast.type_expr]) {1184 const array_type: Ast.full.ArrayType = switch (node_tags[array_init.ast.type_expr]) {
1183 .array_type => tree.arrayType(array_init.ast.type_expr),1185 .array_type => tree.arrayType(array_init.ast.type_expr),
1184 .array_type_sentinel => tree.arrayTypeSentinel(array_init.ast.type_expr),1186 .array_type_sentinel => tree.arrayTypeSentinel(array_init.ast.type_expr),
1185 else => break :infer,1187 else => break :infer,
...@@ -1256,8 +1258,8 @@ fn arrayInitExpr(...@@ -1256,8 +1258,8 @@ fn arrayInitExpr(
1256fn arrayInitExprRlNone(1258fn arrayInitExprRlNone(
1257 gz: *GenZir,1259 gz: *GenZir,
1258 scope: *Scope,1260 scope: *Scope,
1259 node: ast.Node.Index,1261 node: Ast.Node.Index,
1260 elements: []const ast.Node.Index,1262 elements: []const Ast.Node.Index,
1261 tag: Zir.Inst.Tag,1263 tag: Zir.Inst.Tag,
1262) InnerError!Zir.Inst.Ref {1264) InnerError!Zir.Inst.Ref {
1263 const astgen = gz.astgen;1265 const astgen = gz.astgen;
...@@ -1278,8 +1280,8 @@ fn arrayInitExprRlNone(...@@ -1278,8 +1280,8 @@ fn arrayInitExprRlNone(
1278fn arrayInitExprRlTy(1280fn arrayInitExprRlTy(
1279 gz: *GenZir,1281 gz: *GenZir,
1280 scope: *Scope,1282 scope: *Scope,
1281 node: ast.Node.Index,1283 node: Ast.Node.Index,
1282 elements: []const ast.Node.Index,1284 elements: []const Ast.Node.Index,
1283 elem_ty_inst: Zir.Inst.Ref,1285 elem_ty_inst: Zir.Inst.Ref,
1284 tag: Zir.Inst.Tag,1286 tag: Zir.Inst.Tag,
1285) InnerError!Zir.Inst.Ref {1287) InnerError!Zir.Inst.Ref {
...@@ -1304,8 +1306,8 @@ fn arrayInitExprRlTy(...@@ -1304,8 +1306,8 @@ fn arrayInitExprRlTy(
1304fn arrayInitExprRlPtr(1306fn arrayInitExprRlPtr(
1305 gz: *GenZir,1307 gz: *GenZir,
1306 scope: *Scope,1308 scope: *Scope,
1307 node: ast.Node.Index,1309 node: Ast.Node.Index,
1308 elements: []const ast.Node.Index,1310 elements: []const Ast.Node.Index,
1309 result_ptr: Zir.Inst.Ref,1311 result_ptr: Zir.Inst.Ref,
1310) InnerError!Zir.Inst.Ref {1312) InnerError!Zir.Inst.Ref {
1311 const astgen = gz.astgen;1313 const astgen = gz.astgen;
...@@ -1334,8 +1336,8 @@ fn structInitExpr(...@@ -1334,8 +1336,8 @@ fn structInitExpr(
1334 gz: *GenZir,1336 gz: *GenZir,
1335 scope: *Scope,1337 scope: *Scope,
1336 rl: ResultLoc,1338 rl: ResultLoc,
1337 node: ast.Node.Index,1339 node: Ast.Node.Index,
1338 struct_init: ast.full.StructInit,1340 struct_init: Ast.full.StructInit,
1339) InnerError!Zir.Inst.Ref {1341) InnerError!Zir.Inst.Ref {
1340 const astgen = gz.astgen;1342 const astgen = gz.astgen;
1341 const tree = astgen.tree;1343 const tree = astgen.tree;
...@@ -1347,7 +1349,7 @@ fn structInitExpr(...@@ -1347,7 +1349,7 @@ fn structInitExpr(
1347 } else array: {1349 } else array: {
1348 const node_tags = tree.nodes.items(.tag);1350 const node_tags = tree.nodes.items(.tag);
1349 const main_tokens = tree.nodes.items(.main_token);1351 const main_tokens = tree.nodes.items(.main_token);
1350 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {1352 const array_type: Ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
1351 .array_type => tree.arrayType(struct_init.ast.type_expr),1353 .array_type => tree.arrayType(struct_init.ast.type_expr),
1352 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),1354 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
1353 else => break :array,1355 else => break :array,
...@@ -1420,8 +1422,8 @@ fn structInitExpr(...@@ -1420,8 +1422,8 @@ fn structInitExpr(
1420fn structInitExprRlNone(1422fn structInitExprRlNone(
1421 gz: *GenZir,1423 gz: *GenZir,
1422 scope: *Scope,1424 scope: *Scope,
1423 node: ast.Node.Index,1425 node: Ast.Node.Index,
1424 struct_init: ast.full.StructInit,1426 struct_init: Ast.full.StructInit,
1425 tag: Zir.Inst.Tag,1427 tag: Zir.Inst.Tag,
1426) InnerError!Zir.Inst.Ref {1428) InnerError!Zir.Inst.Ref {
1427 const astgen = gz.astgen;1429 const astgen = gz.astgen;
...@@ -1454,8 +1456,8 @@ fn structInitExprRlNone(...@@ -1454,8 +1456,8 @@ fn structInitExprRlNone(
1454fn structInitExprRlPtr(1456fn structInitExprRlPtr(
1455 gz: *GenZir,1457 gz: *GenZir,
1456 scope: *Scope,1458 scope: *Scope,
1457 node: ast.Node.Index,1459 node: Ast.Node.Index,
1458 struct_init: ast.full.StructInit,1460 struct_init: Ast.full.StructInit,
1459 result_ptr: Zir.Inst.Ref,1461 result_ptr: Zir.Inst.Ref,
1460) InnerError!Zir.Inst.Ref {1462) InnerError!Zir.Inst.Ref {
1461 const astgen = gz.astgen;1463 const astgen = gz.astgen;
...@@ -1488,8 +1490,8 @@ fn structInitExprRlPtr(...@@ -1488,8 +1490,8 @@ fn structInitExprRlPtr(
1488fn structInitExprRlTy(1490fn structInitExprRlTy(
1489 gz: *GenZir,1491 gz: *GenZir,
1490 scope: *Scope,1492 scope: *Scope,
1491 node: ast.Node.Index,1493 node: Ast.Node.Index,
1492 struct_init: ast.full.StructInit,1494 struct_init: Ast.full.StructInit,
1493 ty_inst: Zir.Inst.Ref,1495 ty_inst: Zir.Inst.Ref,
1494 tag: Zir.Inst.Tag,1496 tag: Zir.Inst.Tag,
1495) InnerError!Zir.Inst.Ref {1497) InnerError!Zir.Inst.Ref {
...@@ -1530,7 +1532,7 @@ fn comptimeExpr(...@@ -1530,7 +1532,7 @@ fn comptimeExpr(
1530 gz: *GenZir,1532 gz: *GenZir,
1531 scope: *Scope,1533 scope: *Scope,
1532 rl: ResultLoc,1534 rl: ResultLoc,
1533 node: ast.Node.Index,1535 node: Ast.Node.Index,
1534) InnerError!Zir.Inst.Ref {1536) InnerError!Zir.Inst.Ref {
1535 const prev_force_comptime = gz.force_comptime;1537 const prev_force_comptime = gz.force_comptime;
1536 gz.force_comptime = true;1538 gz.force_comptime = true;
...@@ -1546,7 +1548,7 @@ fn comptimeExprAst(...@@ -1546,7 +1548,7 @@ fn comptimeExprAst(
1546 gz: *GenZir,1548 gz: *GenZir,
1547 scope: *Scope,1549 scope: *Scope,
1548 rl: ResultLoc,1550 rl: ResultLoc,
1549 node: ast.Node.Index,1551 node: Ast.Node.Index,
1550) InnerError!Zir.Inst.Ref {1552) InnerError!Zir.Inst.Ref {
1551 const astgen = gz.astgen;1553 const astgen = gz.astgen;
1552 if (gz.force_comptime) {1554 if (gz.force_comptime) {
...@@ -1561,7 +1563,7 @@ fn comptimeExprAst(...@@ -1561,7 +1563,7 @@ fn comptimeExprAst(
1561 return result;1563 return result;
1562}1564}
15631565
1564fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {1566fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
1565 const astgen = parent_gz.astgen;1567 const astgen = parent_gz.astgen;
1566 const tree = astgen.tree;1568 const tree = astgen.tree;
1567 const node_datas = tree.nodes.items(.data);1569 const node_datas = tree.nodes.items(.data);
...@@ -1636,7 +1638,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn...@@ -1636,7 +1638,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
1636 }1638 }
1637}1639}
16381640
1639fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {1641fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
1640 const astgen = parent_gz.astgen;1642 const astgen = parent_gz.astgen;
1641 const tree = astgen.tree;1643 const tree = astgen.tree;
1642 const node_datas = tree.nodes.items(.data);1644 const node_datas = tree.nodes.items(.data);
...@@ -1694,8 +1696,8 @@ fn blockExpr(...@@ -1694,8 +1696,8 @@ fn blockExpr(
1694 gz: *GenZir,1696 gz: *GenZir,
1695 scope: *Scope,1697 scope: *Scope,
1696 rl: ResultLoc,1698 rl: ResultLoc,
1697 block_node: ast.Node.Index,1699 block_node: Ast.Node.Index,
1698 statements: []const ast.Node.Index,1700 statements: []const Ast.Node.Index,
1699) InnerError!Zir.Inst.Ref {1701) InnerError!Zir.Inst.Ref {
1700 const tracy = trace(@src());1702 const tracy = trace(@src());
1701 defer tracy.end();1703 defer tracy.end();
...@@ -1716,7 +1718,7 @@ fn blockExpr(...@@ -1716,7 +1718,7 @@ fn blockExpr(
1716 return rvalue(gz, rl, .void_value, block_node);1718 return rvalue(gz, rl, .void_value, block_node);
1717}1719}
17181720
1719fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.TokenIndex) !void {1721fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.TokenIndex) !void {
1720 // Look for the label in the scope.1722 // Look for the label in the scope.
1721 var scope = parent_scope;1723 var scope = parent_scope;
1722 while (true) {1724 while (true) {
...@@ -1752,8 +1754,8 @@ fn labeledBlockExpr(...@@ -1752,8 +1754,8 @@ fn labeledBlockExpr(
1752 gz: *GenZir,1754 gz: *GenZir,
1753 parent_scope: *Scope,1755 parent_scope: *Scope,
1754 rl: ResultLoc,1756 rl: ResultLoc,
1755 block_node: ast.Node.Index,1757 block_node: Ast.Node.Index,
1756 statements: []const ast.Node.Index,1758 statements: []const Ast.Node.Index,
1757 zir_tag: Zir.Inst.Tag,1759 zir_tag: Zir.Inst.Tag,
1758) InnerError!Zir.Inst.Ref {1760) InnerError!Zir.Inst.Ref {
1759 const tracy = trace(@src());1761 const tracy = trace(@src());
...@@ -1829,7 +1831,7 @@ fn labeledBlockExpr(...@@ -1829,7 +1831,7 @@ fn labeledBlockExpr(
1829 }1831 }
1830}1832}
18311833
1832fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Node.Index) !void {1834fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Node.Index) !void {
1833 const astgen = gz.astgen;1835 const astgen = gz.astgen;
1834 const tree = astgen.tree;1836 const tree = astgen.tree;
1835 const node_tags = tree.nodes.items(.tag);1837 const node_tags = tree.nodes.items(.tag);
...@@ -1837,7 +1839,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1837,7 +1839,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
1837 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);1839 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
1838 defer block_arena.deinit();1840 defer block_arena.deinit();
18391841
1840 var noreturn_src_node: ast.Node.Index = 0;1842 var noreturn_src_node: Ast.Node.Index = 0;
1841 var scope = parent_scope;1843 var scope = parent_scope;
1842 for (statements) |statement| {1844 for (statements) |statement| {
1843 if (noreturn_src_node != 0) {1845 if (noreturn_src_node != 0) {
...@@ -1892,12 +1894,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1892,12 +1894,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
18921894
1893/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.1895/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.
1894/// Otherwise returns 0.1896/// Otherwise returns 0.
1895fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) InnerError!ast.Node.Index {1897fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) InnerError!Ast.Node.Index {
1896 try emitDbgNode(gz, statement);1898 try emitDbgNode(gz, statement);
1897 // We need to emit an error if the result is not `noreturn` or `void`, but1899 // We need to emit an error if the result is not `noreturn` or `void`, but
1898 // we want to avoid adding the ZIR instruction if possible for performance.1900 // we want to avoid adding the ZIR instruction if possible for performance.
1899 const maybe_unused_result = try expr(gz, scope, .none, statement);1901 const maybe_unused_result = try expr(gz, scope, .none, statement);
1900 var noreturn_src_node: ast.Node.Index = 0;1902 var noreturn_src_node: Ast.Node.Index = 0;
1901 const elide_check = if (refToIndex(maybe_unused_result)) |inst| b: {1903 const elide_check = if (refToIndex(maybe_unused_result)) |inst| b: {
1902 // Note that this array becomes invalid after appending more items to it1904 // Note that this array becomes invalid after appending more items to it
1903 // in the above while loop.1905 // in the above while loop.
...@@ -2344,7 +2346,7 @@ fn checkUsed(...@@ -2344,7 +2346,7 @@ fn checkUsed(
23442346
2345fn makeDeferScope(2347fn makeDeferScope(
2346 scope: *Scope,2348 scope: *Scope,
2347 node: ast.Node.Index,2349 node: Ast.Node.Index,
2348 block_arena: *Allocator,2350 block_arena: *Allocator,
2349 scope_tag: Scope.Tag,2351 scope_tag: Scope.Tag,
2350) InnerError!*Scope {2352) InnerError!*Scope {
...@@ -2360,9 +2362,9 @@ fn makeDeferScope(...@@ -2360,9 +2362,9 @@ fn makeDeferScope(
2360fn varDecl(2362fn varDecl(
2361 gz: *GenZir,2363 gz: *GenZir,
2362 scope: *Scope,2364 scope: *Scope,
2363 node: ast.Node.Index,2365 node: Ast.Node.Index,
2364 block_arena: *Allocator,2366 block_arena: *Allocator,
2365 var_decl: ast.full.VarDecl,2367 var_decl: Ast.full.VarDecl,
2366) InnerError!*Scope {2368) InnerError!*Scope {
2367 try emitDbgNode(gz, node);2369 try emitDbgNode(gz, node);
2368 const astgen = gz.astgen;2370 const astgen = gz.astgen;
...@@ -2574,7 +2576,7 @@ fn varDecl(...@@ -2574,7 +2576,7 @@ fn varDecl(
2574 }2576 }
2575}2577}
25762578
2577fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {2579fn emitDbgNode(gz: *GenZir, node: Ast.Node.Index) !void {
2578 // The instruction emitted here is for debugging runtime code.2580 // The instruction emitted here is for debugging runtime code.
2579 // If the current block will be evaluated only during semantic analysis2581 // If the current block will be evaluated only during semantic analysis
2580 // then no dbg_stmt ZIR instruction is needed.2582 // then no dbg_stmt ZIR instruction is needed.
...@@ -2598,7 +2600,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {...@@ -2598,7 +2600,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {
2598 } });2600 } });
2599}2601}
26002602
2601fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!void {2603fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!void {
2602 try emitDbgNode(gz, infix_node);2604 try emitDbgNode(gz, infix_node);
2603 const astgen = gz.astgen;2605 const astgen = gz.astgen;
2604 const tree = astgen.tree;2606 const tree = astgen.tree;
...@@ -2623,7 +2625,7 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!voi...@@ -2623,7 +2625,7 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!voi
2623fn assignOp(2625fn assignOp(
2624 gz: *GenZir,2626 gz: *GenZir,
2625 scope: *Scope,2627 scope: *Scope,
2626 infix_node: ast.Node.Index,2628 infix_node: Ast.Node.Index,
2627 op_inst_tag: Zir.Inst.Tag,2629 op_inst_tag: Zir.Inst.Tag,
2628) InnerError!void {2630) InnerError!void {
2629 try emitDbgNode(gz, infix_node);2631 try emitDbgNode(gz, infix_node);
...@@ -2646,7 +2648,7 @@ fn assignOp(...@@ -2646,7 +2648,7 @@ fn assignOp(
2646fn assignShift(2648fn assignShift(
2647 gz: *GenZir,2649 gz: *GenZir,
2648 scope: *Scope,2650 scope: *Scope,
2649 infix_node: ast.Node.Index,2651 infix_node: Ast.Node.Index,
2650 op_inst_tag: Zir.Inst.Tag,2652 op_inst_tag: Zir.Inst.Tag,
2651) InnerError!void {2653) InnerError!void {
2652 try emitDbgNode(gz, infix_node);2654 try emitDbgNode(gz, infix_node);
...@@ -2666,7 +2668,7 @@ fn assignShift(...@@ -2666,7 +2668,7 @@ fn assignShift(
2666 _ = try gz.addBin(.store, lhs_ptr, result);2668 _ = try gz.addBin(.store, lhs_ptr, result);
2667}2669}
26682670
2669fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {2671fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
2670 const astgen = gz.astgen;2672 const astgen = gz.astgen;
2671 const tree = astgen.tree;2673 const tree = astgen.tree;
2672 const node_datas = tree.nodes.items(.data);2674 const node_datas = tree.nodes.items(.data);
...@@ -2676,7 +2678,7 @@ fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne...@@ -2676,7 +2678,7 @@ fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne
2676 return rvalue(gz, rl, result, node);2678 return rvalue(gz, rl, result, node);
2677}2679}
26782680
2679fn bitNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {2681fn bitNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
2680 const astgen = gz.astgen;2682 const astgen = gz.astgen;
2681 const tree = astgen.tree;2683 const tree = astgen.tree;
2682 const node_datas = tree.nodes.items(.data);2684 const node_datas = tree.nodes.items(.data);
...@@ -2690,7 +2692,7 @@ fn negation(...@@ -2690,7 +2692,7 @@ fn negation(
2690 gz: *GenZir,2692 gz: *GenZir,
2691 scope: *Scope,2693 scope: *Scope,
2692 rl: ResultLoc,2694 rl: ResultLoc,
2693 node: ast.Node.Index,2695 node: Ast.Node.Index,
2694 tag: Zir.Inst.Tag,2696 tag: Zir.Inst.Tag,
2695) InnerError!Zir.Inst.Ref {2697) InnerError!Zir.Inst.Ref {
2696 const astgen = gz.astgen;2698 const astgen = gz.astgen;
...@@ -2706,8 +2708,8 @@ fn ptrType(...@@ -2706,8 +2708,8 @@ fn ptrType(
2706 gz: *GenZir,2708 gz: *GenZir,
2707 scope: *Scope,2709 scope: *Scope,
2708 rl: ResultLoc,2710 rl: ResultLoc,
2709 node: ast.Node.Index,2711 node: Ast.Node.Index,
2710 ptr_info: ast.full.PtrType,2712 ptr_info: Ast.full.PtrType,
2711) InnerError!Zir.Inst.Ref {2713) InnerError!Zir.Inst.Ref {
2712 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);2714 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);
27132715
...@@ -2788,7 +2790,7 @@ fn ptrType(...@@ -2788,7 +2790,7 @@ fn ptrType(
2788 return rvalue(gz, rl, result, node);2790 return rvalue(gz, rl, result, node);
2789}2791}
27902792
2791fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {2793fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref {
2792 const astgen = gz.astgen;2794 const astgen = gz.astgen;
2793 const tree = astgen.tree;2795 const tree = astgen.tree;
2794 const node_datas = tree.nodes.items(.data);2796 const node_datas = tree.nodes.items(.data);
...@@ -2808,13 +2810,13 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Z...@@ -2808,13 +2810,13 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Z
2808 return rvalue(gz, rl, result, node);2810 return rvalue(gz, rl, result, node);
2809}2811}
28102812
2811fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {2813fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref {
2812 const astgen = gz.astgen;2814 const astgen = gz.astgen;
2813 const tree = astgen.tree;2815 const tree = astgen.tree;
2814 const node_datas = tree.nodes.items(.data);2816 const node_datas = tree.nodes.items(.data);
2815 const node_tags = tree.nodes.items(.tag);2817 const node_tags = tree.nodes.items(.tag);
2816 const main_tokens = tree.nodes.items(.main_token);2818 const main_tokens = tree.nodes.items(.main_token);
2817 const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);2819 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel);
28182820
2819 const len_node = node_datas[node].lhs;2821 const len_node = node_datas[node].lhs;
2820 if (node_tags[len_node] == .identifier and2822 if (node_tags[len_node] == .identifier and
...@@ -2870,9 +2872,9 @@ fn fnDecl(...@@ -2870,9 +2872,9 @@ fn fnDecl(
2870 gz: *GenZir,2872 gz: *GenZir,
2871 scope: *Scope,2873 scope: *Scope,
2872 wip_decls: *WipDecls,2874 wip_decls: *WipDecls,
2873 decl_node: ast.Node.Index,2875 decl_node: Ast.Node.Index,
2874 body_node: ast.Node.Index,2876 body_node: Ast.Node.Index,
2875 fn_proto: ast.full.FnProto,2877 fn_proto: Ast.full.FnProto,
2876) InnerError!void {2878) InnerError!void {
2877 const gpa = astgen.gpa;2879 const gpa = astgen.gpa;
2878 const tree = astgen.tree;2880 const tree = astgen.tree;
...@@ -3135,8 +3137,8 @@ fn globalVarDecl(...@@ -3135,8 +3137,8 @@ fn globalVarDecl(
3135 gz: *GenZir,3137 gz: *GenZir,
3136 scope: *Scope,3138 scope: *Scope,
3137 wip_decls: *WipDecls,3139 wip_decls: *WipDecls,
3138 node: ast.Node.Index,3140 node: Ast.Node.Index,
3139 var_decl: ast.full.VarDecl,3141 var_decl: Ast.full.VarDecl,
3140) InnerError!void {3142) InnerError!void {
3141 const gpa = astgen.gpa;3143 const gpa = astgen.gpa;
3142 const tree = astgen.tree;3144 const tree = astgen.tree;
...@@ -3279,7 +3281,7 @@ fn comptimeDecl(...@@ -3279,7 +3281,7 @@ fn comptimeDecl(
3279 gz: *GenZir,3281 gz: *GenZir,
3280 scope: *Scope,3282 scope: *Scope,
3281 wip_decls: *WipDecls,3283 wip_decls: *WipDecls,
3282 node: ast.Node.Index,3284 node: Ast.Node.Index,
3283) InnerError!void {3285) InnerError!void {
3284 const gpa = astgen.gpa;3286 const gpa = astgen.gpa;
3285 const tree = astgen.tree;3287 const tree = astgen.tree;
...@@ -3326,7 +3328,7 @@ fn usingnamespaceDecl(...@@ -3326,7 +3328,7 @@ fn usingnamespaceDecl(
3326 gz: *GenZir,3328 gz: *GenZir,
3327 scope: *Scope,3329 scope: *Scope,
3328 wip_decls: *WipDecls,3330 wip_decls: *WipDecls,
3329 node: ast.Node.Index,3331 node: Ast.Node.Index,
3330) InnerError!void {3332) InnerError!void {
3331 const gpa = astgen.gpa;3333 const gpa = astgen.gpa;
3332 const tree = astgen.tree;3334 const tree = astgen.tree;
...@@ -3377,7 +3379,7 @@ fn testDecl(...@@ -3377,7 +3379,7 @@ fn testDecl(
3377 gz: *GenZir,3379 gz: *GenZir,
3378 scope: *Scope,3380 scope: *Scope,
3379 wip_decls: *WipDecls,3381 wip_decls: *WipDecls,
3380 node: ast.Node.Index,3382 node: Ast.Node.Index,
3381) InnerError!void {3383) InnerError!void {
3382 const gpa = astgen.gpa;3384 const gpa = astgen.gpa;
3383 const tree = astgen.tree;3385 const tree = astgen.tree;
...@@ -3468,8 +3470,8 @@ fn testDecl(...@@ -3468,8 +3470,8 @@ fn testDecl(
3468fn structDeclInner(3470fn structDeclInner(
3469 gz: *GenZir,3471 gz: *GenZir,
3470 scope: *Scope,3472 scope: *Scope,
3471 node: ast.Node.Index,3473 node: Ast.Node.Index,
3472 container_decl: ast.full.ContainerDecl,3474 container_decl: Ast.full.ContainerDecl,
3473 layout: std.builtin.TypeInfo.ContainerLayout,3475 layout: std.builtin.TypeInfo.ContainerLayout,
3474) InnerError!Zir.Inst.Ref {3476) InnerError!Zir.Inst.Ref {
3475 if (container_decl.ast.members.len == 0) {3477 if (container_decl.ast.members.len == 0) {
...@@ -3537,7 +3539,7 @@ fn structDeclInner(...@@ -3537,7 +3539,7 @@ fn structDeclInner(
3537 const body = node_datas[member_node].rhs;3539 const body = node_datas[member_node].rhs;
3538 switch (node_tags[fn_proto]) {3540 switch (node_tags[fn_proto]) {
3539 .fn_proto_simple => {3541 .fn_proto_simple => {
3540 var params: [1]ast.Node.Index = undefined;3542 var params: [1]Ast.Node.Index = undefined;
3541 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {3543 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3542 error.OutOfMemory => return error.OutOfMemory,3544 error.OutOfMemory => return error.OutOfMemory,
3543 error.AnalysisFail => {},3545 error.AnalysisFail => {},
...@@ -3552,7 +3554,7 @@ fn structDeclInner(...@@ -3552,7 +3554,7 @@ fn structDeclInner(
3552 continue;3554 continue;
3553 },3555 },
3554 .fn_proto_one => {3556 .fn_proto_one => {
3555 var params: [1]ast.Node.Index = undefined;3557 var params: [1]Ast.Node.Index = undefined;
3556 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {3558 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3557 error.OutOfMemory => return error.OutOfMemory,3559 error.OutOfMemory => return error.OutOfMemory,
3558 error.AnalysisFail => {},3560 error.AnalysisFail => {},
...@@ -3570,7 +3572,7 @@ fn structDeclInner(...@@ -3570,7 +3572,7 @@ fn structDeclInner(
3570 }3572 }
3571 },3573 },
3572 .fn_proto_simple => {3574 .fn_proto_simple => {
3573 var params: [1]ast.Node.Index = undefined;3575 var params: [1]Ast.Node.Index = undefined;
3574 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {3576 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3575 error.OutOfMemory => return error.OutOfMemory,3577 error.OutOfMemory => return error.OutOfMemory,
3576 error.AnalysisFail => {},3578 error.AnalysisFail => {},
...@@ -3585,7 +3587,7 @@ fn structDeclInner(...@@ -3585,7 +3587,7 @@ fn structDeclInner(
3585 continue;3587 continue;
3586 },3588 },
3587 .fn_proto_one => {3589 .fn_proto_one => {
3588 var params: [1]ast.Node.Index = undefined;3590 var params: [1]Ast.Node.Index = undefined;
3589 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {3591 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3590 error.OutOfMemory => return error.OutOfMemory,3592 error.OutOfMemory => return error.OutOfMemory,
3591 error.AnalysisFail => {},3593 error.AnalysisFail => {},
...@@ -3750,10 +3752,10 @@ fn structDeclInner(...@@ -3750,10 +3752,10 @@ fn structDeclInner(
3750fn unionDeclInner(3752fn unionDeclInner(
3751 gz: *GenZir,3753 gz: *GenZir,
3752 scope: *Scope,3754 scope: *Scope,
3753 node: ast.Node.Index,3755 node: Ast.Node.Index,
3754 members: []const ast.Node.Index,3756 members: []const Ast.Node.Index,
3755 layout: std.builtin.TypeInfo.ContainerLayout,3757 layout: std.builtin.TypeInfo.ContainerLayout,
3756 arg_node: ast.Node.Index,3758 arg_node: Ast.Node.Index,
3757 have_auto_enum: bool,3759 have_auto_enum: bool,
3758) InnerError!Zir.Inst.Ref {3760) InnerError!Zir.Inst.Ref {
3759 const astgen = gz.astgen;3761 const astgen = gz.astgen;
...@@ -3812,7 +3814,7 @@ fn unionDeclInner(...@@ -3812,7 +3814,7 @@ fn unionDeclInner(
3812 const body = node_datas[member_node].rhs;3814 const body = node_datas[member_node].rhs;
3813 switch (node_tags[fn_proto]) {3815 switch (node_tags[fn_proto]) {
3814 .fn_proto_simple => {3816 .fn_proto_simple => {
3815 var params: [1]ast.Node.Index = undefined;3817 var params: [1]Ast.Node.Index = undefined;
3816 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {3818 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3817 error.OutOfMemory => return error.OutOfMemory,3819 error.OutOfMemory => return error.OutOfMemory,
3818 error.AnalysisFail => {},3820 error.AnalysisFail => {},
...@@ -3827,7 +3829,7 @@ fn unionDeclInner(...@@ -3827,7 +3829,7 @@ fn unionDeclInner(
3827 continue;3829 continue;
3828 },3830 },
3829 .fn_proto_one => {3831 .fn_proto_one => {
3830 var params: [1]ast.Node.Index = undefined;3832 var params: [1]Ast.Node.Index = undefined;
3831 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {3833 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3832 error.OutOfMemory => return error.OutOfMemory,3834 error.OutOfMemory => return error.OutOfMemory,
3833 error.AnalysisFail => {},3835 error.AnalysisFail => {},
...@@ -3845,7 +3847,7 @@ fn unionDeclInner(...@@ -3845,7 +3847,7 @@ fn unionDeclInner(
3845 }3847 }
3846 },3848 },
3847 .fn_proto_simple => {3849 .fn_proto_simple => {
3848 var params: [1]ast.Node.Index = undefined;3850 var params: [1]Ast.Node.Index = undefined;
3849 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {3851 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3850 error.OutOfMemory => return error.OutOfMemory,3852 error.OutOfMemory => return error.OutOfMemory,
3851 error.AnalysisFail => {},3853 error.AnalysisFail => {},
...@@ -3860,7 +3862,7 @@ fn unionDeclInner(...@@ -3860,7 +3862,7 @@ fn unionDeclInner(
3860 continue;3862 continue;
3861 },3863 },
3862 .fn_proto_one => {3864 .fn_proto_one => {
3863 var params: [1]ast.Node.Index = undefined;3865 var params: [1]Ast.Node.Index = undefined;
3864 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {3866 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3865 error.OutOfMemory => return error.OutOfMemory,3867 error.OutOfMemory => return error.OutOfMemory,
3866 error.AnalysisFail => {},3868 error.AnalysisFail => {},
...@@ -4033,8 +4035,8 @@ fn containerDecl(...@@ -4033,8 +4035,8 @@ fn containerDecl(
4033 gz: *GenZir,4035 gz: *GenZir,
4034 scope: *Scope,4036 scope: *Scope,
4035 rl: ResultLoc,4037 rl: ResultLoc,
4036 node: ast.Node.Index,4038 node: Ast.Node.Index,
4037 container_decl: ast.full.ContainerDecl,4039 container_decl: Ast.full.ContainerDecl,
4038) InnerError!Zir.Inst.Ref {4040) InnerError!Zir.Inst.Ref {
4039 const astgen = gz.astgen;4041 const astgen = gz.astgen;
4040 const gpa = astgen.gpa;4042 const gpa = astgen.gpa;
...@@ -4084,7 +4086,7 @@ fn containerDecl(...@@ -4084,7 +4086,7 @@ fn containerDecl(
4084 var values: usize = 0;4086 var values: usize = 0;
4085 var total_fields: usize = 0;4087 var total_fields: usize = 0;
4086 var decls: usize = 0;4088 var decls: usize = 0;
4087 var nonexhaustive_node: ast.Node.Index = 0;4089 var nonexhaustive_node: Ast.Node.Index = 0;
4088 for (container_decl.ast.members) |member_node| {4090 for (container_decl.ast.members) |member_node| {
4089 const member = switch (node_tags[member_node]) {4091 const member = switch (node_tags[member_node]) {
4090 .container_field_init => tree.containerFieldInit(member_node),4092 .container_field_init => tree.containerFieldInit(member_node),
...@@ -4225,7 +4227,7 @@ fn containerDecl(...@@ -4225,7 +4227,7 @@ fn containerDecl(
4225 const body = node_datas[member_node].rhs;4227 const body = node_datas[member_node].rhs;
4226 switch (node_tags[fn_proto]) {4228 switch (node_tags[fn_proto]) {
4227 .fn_proto_simple => {4229 .fn_proto_simple => {
4228 var params: [1]ast.Node.Index = undefined;4230 var params: [1]Ast.Node.Index = undefined;
4229 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {4231 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4230 error.OutOfMemory => return error.OutOfMemory,4232 error.OutOfMemory => return error.OutOfMemory,
4231 error.AnalysisFail => {},4233 error.AnalysisFail => {},
...@@ -4240,7 +4242,7 @@ fn containerDecl(...@@ -4240,7 +4242,7 @@ fn containerDecl(
4240 continue;4242 continue;
4241 },4243 },
4242 .fn_proto_one => {4244 .fn_proto_one => {
4243 var params: [1]ast.Node.Index = undefined;4245 var params: [1]Ast.Node.Index = undefined;
4244 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {4246 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4245 error.OutOfMemory => return error.OutOfMemory,4247 error.OutOfMemory => return error.OutOfMemory,
4246 error.AnalysisFail => {},4248 error.AnalysisFail => {},
...@@ -4258,7 +4260,7 @@ fn containerDecl(...@@ -4258,7 +4260,7 @@ fn containerDecl(
4258 }4260 }
4259 },4261 },
4260 .fn_proto_simple => {4262 .fn_proto_simple => {
4261 var params: [1]ast.Node.Index = undefined;4263 var params: [1]Ast.Node.Index = undefined;
4262 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {4264 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4263 error.OutOfMemory => return error.OutOfMemory,4265 error.OutOfMemory => return error.OutOfMemory,
4264 error.AnalysisFail => {},4266 error.AnalysisFail => {},
...@@ -4273,7 +4275,7 @@ fn containerDecl(...@@ -4273,7 +4275,7 @@ fn containerDecl(
4273 continue;4275 continue;
4274 },4276 },
4275 .fn_proto_one => {4277 .fn_proto_one => {
4276 var params: [1]ast.Node.Index = undefined;4278 var params: [1]Ast.Node.Index = undefined;
4277 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {4279 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4278 error.OutOfMemory => return error.OutOfMemory,4280 error.OutOfMemory => return error.OutOfMemory,
4279 error.AnalysisFail => {},4281 error.AnalysisFail => {},
...@@ -4441,7 +4443,7 @@ fn containerDecl(...@@ -4441,7 +4443,7 @@ fn containerDecl(
4441 const body = node_datas[member_node].rhs;4443 const body = node_datas[member_node].rhs;
4442 switch (node_tags[fn_proto]) {4444 switch (node_tags[fn_proto]) {
4443 .fn_proto_simple => {4445 .fn_proto_simple => {
4444 var params: [1]ast.Node.Index = undefined;4446 var params: [1]Ast.Node.Index = undefined;
4445 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {4447 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4446 error.OutOfMemory => return error.OutOfMemory,4448 error.OutOfMemory => return error.OutOfMemory,
4447 error.AnalysisFail => {},4449 error.AnalysisFail => {},
...@@ -4456,7 +4458,7 @@ fn containerDecl(...@@ -4456,7 +4458,7 @@ fn containerDecl(
4456 continue;4458 continue;
4457 },4459 },
4458 .fn_proto_one => {4460 .fn_proto_one => {
4459 var params: [1]ast.Node.Index = undefined;4461 var params: [1]Ast.Node.Index = undefined;
4460 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {4462 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4461 error.OutOfMemory => return error.OutOfMemory,4463 error.OutOfMemory => return error.OutOfMemory,
4462 error.AnalysisFail => {},4464 error.AnalysisFail => {},
...@@ -4474,7 +4476,7 @@ fn containerDecl(...@@ -4474,7 +4476,7 @@ fn containerDecl(
4474 }4476 }
4475 },4477 },
4476 .fn_proto_simple => {4478 .fn_proto_simple => {
4477 var params: [1]ast.Node.Index = undefined;4479 var params: [1]Ast.Node.Index = undefined;
4478 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {4480 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4479 error.OutOfMemory => return error.OutOfMemory,4481 error.OutOfMemory => return error.OutOfMemory,
4480 error.AnalysisFail => {},4482 error.AnalysisFail => {},
...@@ -4489,7 +4491,7 @@ fn containerDecl(...@@ -4489,7 +4491,7 @@ fn containerDecl(
4489 continue;4491 continue;
4490 },4492 },
4491 .fn_proto_one => {4493 .fn_proto_one => {
4492 var params: [1]ast.Node.Index = undefined;4494 var params: [1]Ast.Node.Index = undefined;
4493 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {4495 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4494 error.OutOfMemory => return error.OutOfMemory,4496 error.OutOfMemory => return error.OutOfMemory,
4495 error.AnalysisFail => {},4497 error.AnalysisFail => {},
...@@ -4590,7 +4592,7 @@ fn containerDecl(...@@ -4590,7 +4592,7 @@ fn containerDecl(
4590 }4592 }
4591}4593}
45924594
4593fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {4595fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
4594 const astgen = gz.astgen;4596 const astgen = gz.astgen;
4595 const gpa = astgen.gpa;4597 const gpa = astgen.gpa;
4596 const tree = astgen.tree;4598 const tree = astgen.tree;
...@@ -4629,8 +4631,8 @@ fn tryExpr(...@@ -4629,8 +4631,8 @@ fn tryExpr(
4629 parent_gz: *GenZir,4631 parent_gz: *GenZir,
4630 scope: *Scope,4632 scope: *Scope,
4631 rl: ResultLoc,4633 rl: ResultLoc,
4632 node: ast.Node.Index,4634 node: Ast.Node.Index,
4633 operand_node: ast.Node.Index,4635 operand_node: Ast.Node.Index,
4634) InnerError!Zir.Inst.Ref {4636) InnerError!Zir.Inst.Ref {
4635 const astgen = parent_gz.astgen;4637 const astgen = parent_gz.astgen;
46364638
...@@ -4705,13 +4707,13 @@ fn orelseCatchExpr(...@@ -4705,13 +4707,13 @@ fn orelseCatchExpr(
4705 parent_gz: *GenZir,4707 parent_gz: *GenZir,
4706 scope: *Scope,4708 scope: *Scope,
4707 rl: ResultLoc,4709 rl: ResultLoc,
4708 node: ast.Node.Index,4710 node: Ast.Node.Index,
4709 lhs: ast.Node.Index,4711 lhs: Ast.Node.Index,
4710 cond_op: Zir.Inst.Tag,4712 cond_op: Zir.Inst.Tag,
4711 unwrap_op: Zir.Inst.Tag,4713 unwrap_op: Zir.Inst.Tag,
4712 unwrap_code_op: Zir.Inst.Tag,4714 unwrap_code_op: Zir.Inst.Tag,
4713 rhs: ast.Node.Index,4715 rhs: Ast.Node.Index,
4714 payload_token: ?ast.TokenIndex,4716 payload_token: ?Ast.TokenIndex,
4715) InnerError!Zir.Inst.Ref {4717) InnerError!Zir.Inst.Ref {
4716 const astgen = parent_gz.astgen;4718 const astgen = parent_gz.astgen;
4717 const tree = astgen.tree;4719 const tree = astgen.tree;
...@@ -4796,7 +4798,7 @@ fn orelseCatchExpr(...@@ -4796,7 +4798,7 @@ fn orelseCatchExpr(
4796fn finishThenElseBlock(4798fn finishThenElseBlock(
4797 parent_gz: *GenZir,4799 parent_gz: *GenZir,
4798 rl: ResultLoc,4800 rl: ResultLoc,
4799 node: ast.Node.Index,4801 node: Ast.Node.Index,
4800 block_scope: *GenZir,4802 block_scope: *GenZir,
4801 then_scope: *GenZir,4803 then_scope: *GenZir,
4802 else_scope: *GenZir,4804 else_scope: *GenZir,
...@@ -4852,7 +4854,7 @@ fn finishThenElseBlock(...@@ -4852,7 +4854,7 @@ fn finishThenElseBlock(
4852/// tokens without allocating.4854/// tokens without allocating.
4853/// OK in theory it could do it without allocating. This implementation4855/// OK in theory it could do it without allocating. This implementation
4854/// allocates when the @"" form is used.4856/// allocates when the @"" form is used.
4855fn tokenIdentEql(astgen: *AstGen, token1: ast.TokenIndex, token2: ast.TokenIndex) !bool {4857fn tokenIdentEql(astgen: *AstGen, token1: Ast.TokenIndex, token2: Ast.TokenIndex) !bool {
4856 const ident_name_1 = try astgen.identifierTokenString(token1);4858 const ident_name_1 = try astgen.identifierTokenString(token1);
4857 const ident_name_2 = try astgen.identifierTokenString(token2);4859 const ident_name_2 = try astgen.identifierTokenString(token2);
4858 return mem.eql(u8, ident_name_1, ident_name_2);4860 return mem.eql(u8, ident_name_1, ident_name_2);
...@@ -4862,7 +4864,7 @@ fn fieldAccess(...@@ -4862,7 +4864,7 @@ fn fieldAccess(
4862 gz: *GenZir,4864 gz: *GenZir,
4863 scope: *Scope,4865 scope: *Scope,
4864 rl: ResultLoc,4866 rl: ResultLoc,
4865 node: ast.Node.Index,4867 node: Ast.Node.Index,
4866) InnerError!Zir.Inst.Ref {4868) InnerError!Zir.Inst.Ref {
4867 const astgen = gz.astgen;4869 const astgen = gz.astgen;
4868 const tree = astgen.tree;4870 const tree = astgen.tree;
...@@ -4889,7 +4891,7 @@ fn arrayAccess(...@@ -4889,7 +4891,7 @@ fn arrayAccess(
4889 gz: *GenZir,4891 gz: *GenZir,
4890 scope: *Scope,4892 scope: *Scope,
4891 rl: ResultLoc,4893 rl: ResultLoc,
4892 node: ast.Node.Index,4894 node: Ast.Node.Index,
4893) InnerError!Zir.Inst.Ref {4895) InnerError!Zir.Inst.Ref {
4894 const astgen = gz.astgen;4896 const astgen = gz.astgen;
4895 const tree = astgen.tree;4897 const tree = astgen.tree;
...@@ -4912,7 +4914,7 @@ fn simpleBinOp(...@@ -4912,7 +4914,7 @@ fn simpleBinOp(
4912 gz: *GenZir,4914 gz: *GenZir,
4913 scope: *Scope,4915 scope: *Scope,
4914 rl: ResultLoc,4916 rl: ResultLoc,
4915 node: ast.Node.Index,4917 node: Ast.Node.Index,
4916 op_inst_tag: Zir.Inst.Tag,4918 op_inst_tag: Zir.Inst.Tag,
4917) InnerError!Zir.Inst.Ref {4919) InnerError!Zir.Inst.Ref {
4918 const astgen = gz.astgen;4920 const astgen = gz.astgen;
...@@ -4929,8 +4931,8 @@ fn simpleBinOp(...@@ -4929,8 +4931,8 @@ fn simpleBinOp(
4929fn simpleStrTok(4931fn simpleStrTok(
4930 gz: *GenZir,4932 gz: *GenZir,
4931 rl: ResultLoc,4933 rl: ResultLoc,
4932 ident_token: ast.TokenIndex,4934 ident_token: Ast.TokenIndex,
4933 node: ast.Node.Index,4935 node: Ast.Node.Index,
4934 op_inst_tag: Zir.Inst.Tag,4936 op_inst_tag: Zir.Inst.Tag,
4935) InnerError!Zir.Inst.Ref {4937) InnerError!Zir.Inst.Ref {
4936 const astgen = gz.astgen;4938 const astgen = gz.astgen;
...@@ -4943,7 +4945,7 @@ fn boolBinOp(...@@ -4943,7 +4945,7 @@ fn boolBinOp(
4943 gz: *GenZir,4945 gz: *GenZir,
4944 scope: *Scope,4946 scope: *Scope,
4945 rl: ResultLoc,4947 rl: ResultLoc,
4946 node: ast.Node.Index,4948 node: Ast.Node.Index,
4947 zir_tag: Zir.Inst.Tag,4949 zir_tag: Zir.Inst.Tag,
4948) InnerError!Zir.Inst.Ref {4950) InnerError!Zir.Inst.Ref {
4949 const astgen = gz.astgen;4951 const astgen = gz.astgen;
...@@ -4969,8 +4971,8 @@ fn ifExpr(...@@ -4969,8 +4971,8 @@ fn ifExpr(
4969 parent_gz: *GenZir,4971 parent_gz: *GenZir,
4970 scope: *Scope,4972 scope: *Scope,
4971 rl: ResultLoc,4973 rl: ResultLoc,
4972 node: ast.Node.Index,4974 node: Ast.Node.Index,
4973 if_full: ast.full.If,4975 if_full: Ast.full.If,
4974) InnerError!Zir.Inst.Ref {4976) InnerError!Zir.Inst.Ref {
4975 const astgen = parent_gz.astgen;4977 const astgen = parent_gz.astgen;
4976 const tree = astgen.tree;4978 const tree = astgen.tree;
...@@ -5089,7 +5091,7 @@ fn ifExpr(...@@ -5089,7 +5091,7 @@ fn ifExpr(
50895091
5090 const else_node = if_full.ast.else_expr;5092 const else_node = if_full.ast.else_expr;
5091 const else_info: struct {5093 const else_info: struct {
5092 src: ast.Node.Index,5094 src: Ast.Node.Index,
5093 result: Zir.Inst.Ref,5095 result: Zir.Inst.Ref,
5094 } = if (else_node != 0) blk: {5096 } = if (else_node != 0) blk: {
5095 block_scope.break_count += 1;5097 block_scope.break_count += 1;
...@@ -5215,8 +5217,8 @@ fn whileExpr(...@@ -5215,8 +5217,8 @@ fn whileExpr(
5215 parent_gz: *GenZir,5217 parent_gz: *GenZir,
5216 scope: *Scope,5218 scope: *Scope,
5217 rl: ResultLoc,5219 rl: ResultLoc,
5218 node: ast.Node.Index,5220 node: Ast.Node.Index,
5219 while_full: ast.full.While,5221 while_full: Ast.full.While,
5220) InnerError!Zir.Inst.Ref {5222) InnerError!Zir.Inst.Ref {
5221 const astgen = parent_gz.astgen;5223 const astgen = parent_gz.astgen;
5222 const tree = astgen.tree;5224 const tree = astgen.tree;
...@@ -5368,7 +5370,7 @@ fn whileExpr(...@@ -5368,7 +5370,7 @@ fn whileExpr(
53685370
5369 const else_node = while_full.ast.else_expr;5371 const else_node = while_full.ast.else_expr;
5370 const else_info: struct {5372 const else_info: struct {
5371 src: ast.Node.Index,5373 src: Ast.Node.Index,
5372 result: Zir.Inst.Ref,5374 result: Zir.Inst.Ref,
5373 } = if (else_node != 0) blk: {5375 } = if (else_node != 0) blk: {
5374 loop_scope.break_count += 1;5376 loop_scope.break_count += 1;
...@@ -5435,8 +5437,8 @@ fn forExpr(...@@ -5435,8 +5437,8 @@ fn forExpr(
5435 parent_gz: *GenZir,5437 parent_gz: *GenZir,
5436 scope: *Scope,5438 scope: *Scope,
5437 rl: ResultLoc,5439 rl: ResultLoc,
5438 node: ast.Node.Index,5440 node: Ast.Node.Index,
5439 for_full: ast.full.While,5441 for_full: Ast.full.While,
5440) InnerError!Zir.Inst.Ref {5442) InnerError!Zir.Inst.Ref {
5441 const astgen = parent_gz.astgen;5443 const astgen = parent_gz.astgen;
54425444
...@@ -5577,7 +5579,7 @@ fn forExpr(...@@ -5577,7 +5579,7 @@ fn forExpr(
55775579
5578 const else_node = for_full.ast.else_expr;5580 const else_node = for_full.ast.else_expr;
5579 const else_info: struct {5581 const else_info: struct {
5580 src: ast.Node.Index,5582 src: Ast.Node.Index,
5581 result: Zir.Inst.Ref,5583 result: Zir.Inst.Ref,
5582 } = if (else_node != 0) blk: {5584 } = if (else_node != 0) blk: {
5583 loop_scope.break_count += 1;5585 loop_scope.break_count += 1;
...@@ -5618,7 +5620,7 @@ fn switchExpr(...@@ -5618,7 +5620,7 @@ fn switchExpr(
5618 parent_gz: *GenZir,5620 parent_gz: *GenZir,
5619 scope: *Scope,5621 scope: *Scope,
5620 rl: ResultLoc,5622 rl: ResultLoc,
5621 switch_node: ast.Node.Index,5623 switch_node: Ast.Node.Index,
5622) InnerError!Zir.Inst.Ref {5624) InnerError!Zir.Inst.Ref {
5623 const astgen = parent_gz.astgen;5625 const astgen = parent_gz.astgen;
5624 const gpa = astgen.gpa;5626 const gpa = astgen.gpa;
...@@ -5628,7 +5630,7 @@ fn switchExpr(...@@ -5628,7 +5630,7 @@ fn switchExpr(
5628 const main_tokens = tree.nodes.items(.main_token);5630 const main_tokens = tree.nodes.items(.main_token);
5629 const token_tags = tree.tokens.items(.tag);5631 const token_tags = tree.tokens.items(.tag);
5630 const operand_node = node_datas[switch_node].lhs;5632 const operand_node = node_datas[switch_node].lhs;
5631 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);5633 const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
5632 const case_nodes = tree.extra_data[extra.start..extra.end];5634 const case_nodes = tree.extra_data[extra.start..extra.end];
56335635
5634 // We perform two passes over the AST. This first pass is to collect information5636 // We perform two passes over the AST. This first pass is to collect information
...@@ -5638,9 +5640,9 @@ fn switchExpr(...@@ -5638,9 +5640,9 @@ fn switchExpr(
5638 var scalar_cases_len: u32 = 0;5640 var scalar_cases_len: u32 = 0;
5639 var multi_cases_len: u32 = 0;5641 var multi_cases_len: u32 = 0;
5640 var special_prong: Zir.SpecialProng = .none;5642 var special_prong: Zir.SpecialProng = .none;
5641 var special_node: ast.Node.Index = 0;5643 var special_node: Ast.Node.Index = 0;
5642 var else_src: ?ast.TokenIndex = null;5644 var else_src: ?Ast.TokenIndex = null;
5643 var underscore_src: ?ast.TokenIndex = null;5645 var underscore_src: ?Ast.TokenIndex = null;
5644 for (case_nodes) |case_node| {5646 for (case_nodes) |case_node| {
5645 const case = switch (node_tags[case_node]) {5647 const case = switch (node_tags[case_node]) {
5646 .switch_case_one => tree.switchCaseOne(case_node),5648 .switch_case_one => tree.switchCaseOne(case_node),
...@@ -6212,7 +6214,7 @@ fn switchExpr(...@@ -6212,7 +6214,7 @@ fn switchExpr(
6212 }6214 }
6213}6215}
62146216
6215fn ret(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {6217fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
6216 const astgen = gz.astgen;6218 const astgen = gz.astgen;
6217 const tree = astgen.tree;6219 const tree = astgen.tree;
6218 const node_datas = tree.nodes.items(.data);6220 const node_datas = tree.nodes.items(.data);
...@@ -6311,7 +6313,7 @@ fn identifier(...@@ -6311,7 +6313,7 @@ fn identifier(
6311 gz: *GenZir,6313 gz: *GenZir,
6312 scope: *Scope,6314 scope: *Scope,
6313 rl: ResultLoc,6315 rl: ResultLoc,
6314 ident: ast.Node.Index,6316 ident: Ast.Node.Index,
6315) InnerError!Zir.Inst.Ref {6317) InnerError!Zir.Inst.Ref {
6316 const tracy = trace(@src());6318 const tracy = trace(@src());
6317 defer tracy.end();6319 defer tracy.end();
...@@ -6363,8 +6365,8 @@ fn identifier(...@@ -6363,8 +6365,8 @@ fn identifier(
6363 // Local variables, including function parameters.6365 // Local variables, including function parameters.
6364 const name_str_index = try astgen.identAsString(ident_token);6366 const name_str_index = try astgen.identAsString(ident_token);
6365 var s = scope;6367 var s = scope;
6366 var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already6368 var found_already: ?Ast.Node.Index = null; // we have found a decl with the same name already
6367 var hit_namespace: ast.Node.Index = 0;6369 var hit_namespace: Ast.Node.Index = 0;
6368 while (true) switch (s.tag) {6370 while (true) switch (s.tag) {
6369 .local_val => {6371 .local_val => {
6370 const local_val = s.cast(Scope.LocalVal).?;6372 const local_val = s.cast(Scope.LocalVal).?;
...@@ -6416,6 +6418,9 @@ fn identifier(...@@ -6416,6 +6418,9 @@ fn identifier(
6416 },6418 },
6417 .top => break,6419 .top => break,
6418 };6420 };
6421 if (found_already == null) {
6422 return astgen.failNode(ident, "use of undeclared identifier '{s}'", .{ident_name});
6423 }
64196424
6420 // Decl references happen by name rather than ZIR index so that when unrelated6425 // Decl references happen by name rather than ZIR index so that when unrelated
6421 // decls are modified, ZIR code containing references to them can be unmodified.6426 // decls are modified, ZIR code containing references to them can be unmodified.
...@@ -6431,7 +6436,7 @@ fn identifier(...@@ -6431,7 +6436,7 @@ fn identifier(
6431fn stringLiteral(6436fn stringLiteral(
6432 gz: *GenZir,6437 gz: *GenZir,
6433 rl: ResultLoc,6438 rl: ResultLoc,
6434 node: ast.Node.Index,6439 node: Ast.Node.Index,
6435) InnerError!Zir.Inst.Ref {6440) InnerError!Zir.Inst.Ref {
6436 const astgen = gz.astgen;6441 const astgen = gz.astgen;
6437 const tree = astgen.tree;6442 const tree = astgen.tree;
...@@ -6451,7 +6456,7 @@ fn stringLiteral(...@@ -6451,7 +6456,7 @@ fn stringLiteral(
6451fn multilineStringLiteral(6456fn multilineStringLiteral(
6452 gz: *GenZir,6457 gz: *GenZir,
6453 rl: ResultLoc,6458 rl: ResultLoc,
6454 node: ast.Node.Index,6459 node: Ast.Node.Index,
6455) InnerError!Zir.Inst.Ref {6460) InnerError!Zir.Inst.Ref {
6456 const astgen = gz.astgen;6461 const astgen = gz.astgen;
6457 const str = try astgen.strLitNodeAsString(node);6462 const str = try astgen.strLitNodeAsString(node);
...@@ -6465,7 +6470,7 @@ fn multilineStringLiteral(...@@ -6465,7 +6470,7 @@ fn multilineStringLiteral(
6465 return rvalue(gz, rl, result, node);6470 return rvalue(gz, rl, result, node);
6466}6471}
64676472
6468fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {6473fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref {
6469 const astgen = gz.astgen;6474 const astgen = gz.astgen;
6470 const tree = astgen.tree;6475 const tree = astgen.tree;
6471 const main_tokens = tree.nodes.items(.main_token);6476 const main_tokens = tree.nodes.items(.main_token);
...@@ -6544,7 +6549,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {...@@ -6544,7 +6549,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {
6544 }6549 }
6545}6550}
65466551
6547fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {6552fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
6548 const astgen = gz.astgen;6553 const astgen = gz.astgen;
6549 const tree = astgen.tree;6554 const tree = astgen.tree;
6550 const main_tokens = tree.nodes.items(.main_token);6555 const main_tokens = tree.nodes.items(.main_token);
...@@ -6590,7 +6595,7 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Z...@@ -6590,7 +6595,7 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Z
6590 return rvalue(gz, rl, result, node);6595 return rvalue(gz, rl, result, node);
6591}6596}
65926597
6593fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {6598fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
6594 const astgen = gz.astgen;6599 const astgen = gz.astgen;
6595 const tree = astgen.tree;6600 const tree = astgen.tree;
6596 const main_tokens = tree.nodes.items(.main_token);6601 const main_tokens = tree.nodes.items(.main_token);
...@@ -6630,8 +6635,8 @@ fn asmExpr(...@@ -6630,8 +6635,8 @@ fn asmExpr(
6630 gz: *GenZir,6635 gz: *GenZir,
6631 scope: *Scope,6636 scope: *Scope,
6632 rl: ResultLoc,6637 rl: ResultLoc,
6633 node: ast.Node.Index,6638 node: Ast.Node.Index,
6634 full: ast.full.Asm,6639 full: Ast.full.Asm,
6635) InnerError!Zir.Inst.Ref {6640) InnerError!Zir.Inst.Ref {
6636 const astgen = gz.astgen;6641 const astgen = gz.astgen;
6637 const tree = astgen.tree;6642 const tree = astgen.tree;
...@@ -6788,9 +6793,9 @@ fn as(...@@ -6788,9 +6793,9 @@ fn as(
6788 gz: *GenZir,6793 gz: *GenZir,
6789 scope: *Scope,6794 scope: *Scope,
6790 rl: ResultLoc,6795 rl: ResultLoc,
6791 node: ast.Node.Index,6796 node: Ast.Node.Index,
6792 lhs: ast.Node.Index,6797 lhs: Ast.Node.Index,
6793 rhs: ast.Node.Index,6798 rhs: Ast.Node.Index,
6794) InnerError!Zir.Inst.Ref {6799) InnerError!Zir.Inst.Ref {
6795 const dest_type = try typeExpr(gz, scope, lhs);6800 const dest_type = try typeExpr(gz, scope, lhs);
6796 switch (rl) {6801 switch (rl) {
...@@ -6811,8 +6816,8 @@ fn unionInit(...@@ -6811,8 +6816,8 @@ fn unionInit(
6811 gz: *GenZir,6816 gz: *GenZir,
6812 scope: *Scope,6817 scope: *Scope,
6813 rl: ResultLoc,6818 rl: ResultLoc,
6814 node: ast.Node.Index,6819 node: Ast.Node.Index,
6815 params: []const ast.Node.Index,6820 params: []const Ast.Node.Index,
6816) InnerError!Zir.Inst.Ref {6821) InnerError!Zir.Inst.Ref {
6817 const union_type = try typeExpr(gz, scope, params[0]);6822 const union_type = try typeExpr(gz, scope, params[0]);
6818 const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);6823 const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
...@@ -6837,9 +6842,9 @@ fn unionInit(...@@ -6837,9 +6842,9 @@ fn unionInit(
6837fn unionInitRlPtr(6842fn unionInitRlPtr(
6838 parent_gz: *GenZir,6843 parent_gz: *GenZir,
6839 scope: *Scope,6844 scope: *Scope,
6840 node: ast.Node.Index,6845 node: Ast.Node.Index,
6841 result_ptr: Zir.Inst.Ref,6846 result_ptr: Zir.Inst.Ref,
6842 expr_node: ast.Node.Index,6847 expr_node: Ast.Node.Index,
6843 union_type: Zir.Inst.Ref,6848 union_type: Zir.Inst.Ref,
6844 field_name: Zir.Inst.Ref,6849 field_name: Zir.Inst.Ref,
6845) InnerError!Zir.Inst.Ref {6850) InnerError!Zir.Inst.Ref {
...@@ -6856,9 +6861,9 @@ fn asRlPtr(...@@ -6856,9 +6861,9 @@ fn asRlPtr(
6856 parent_gz: *GenZir,6861 parent_gz: *GenZir,
6857 scope: *Scope,6862 scope: *Scope,
6858 rl: ResultLoc,6863 rl: ResultLoc,
6859 src_node: ast.Node.Index,6864 src_node: Ast.Node.Index,
6860 result_ptr: Zir.Inst.Ref,6865 result_ptr: Zir.Inst.Ref,
6861 operand_node: ast.Node.Index,6866 operand_node: Ast.Node.Index,
6862 dest_type: Zir.Inst.Ref,6867 dest_type: Zir.Inst.Ref,
6863) InnerError!Zir.Inst.Ref {6868) InnerError!Zir.Inst.Ref {
6864 // Detect whether this expr() call goes into rvalue() to store the result into the6869 // Detect whether this expr() call goes into rvalue() to store the result into the
...@@ -6896,9 +6901,9 @@ fn bitCast(...@@ -6896,9 +6901,9 @@ fn bitCast(
6896 gz: *GenZir,6901 gz: *GenZir,
6897 scope: *Scope,6902 scope: *Scope,
6898 rl: ResultLoc,6903 rl: ResultLoc,
6899 node: ast.Node.Index,6904 node: Ast.Node.Index,
6900 lhs: ast.Node.Index,6905 lhs: Ast.Node.Index,
6901 rhs: ast.Node.Index,6906 rhs: Ast.Node.Index,
6902) InnerError!Zir.Inst.Ref {6907) InnerError!Zir.Inst.Ref {
6903 const astgen = gz.astgen;6908 const astgen = gz.astgen;
6904 const dest_type = try typeExpr(gz, scope, lhs);6909 const dest_type = try typeExpr(gz, scope, lhs);
...@@ -6926,10 +6931,10 @@ fn bitCast(...@@ -6926,10 +6931,10 @@ fn bitCast(
6926fn bitCastRlPtr(6931fn bitCastRlPtr(
6927 gz: *GenZir,6932 gz: *GenZir,
6928 scope: *Scope,6933 scope: *Scope,
6929 node: ast.Node.Index,6934 node: Ast.Node.Index,
6930 dest_type: Zir.Inst.Ref,6935 dest_type: Zir.Inst.Ref,
6931 result_ptr: Zir.Inst.Ref,6936 result_ptr: Zir.Inst.Ref,
6932 rhs: ast.Node.Index,6937 rhs: Ast.Node.Index,
6933) InnerError!Zir.Inst.Ref {6938) InnerError!Zir.Inst.Ref {
6934 const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{6939 const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{
6935 .lhs = dest_type,6940 .lhs = dest_type,
...@@ -6942,8 +6947,8 @@ fn typeOf(...@@ -6942,8 +6947,8 @@ fn typeOf(
6942 gz: *GenZir,6947 gz: *GenZir,
6943 scope: *Scope,6948 scope: *Scope,
6944 rl: ResultLoc,6949 rl: ResultLoc,
6945 node: ast.Node.Index,6950 node: Ast.Node.Index,
6946 params: []const ast.Node.Index,6951 params: []const Ast.Node.Index,
6947) InnerError!Zir.Inst.Ref {6952) InnerError!Zir.Inst.Ref {
6948 if (params.len < 1) {6953 if (params.len < 1) {
6949 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});6954 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});
...@@ -6967,8 +6972,8 @@ fn builtinCall(...@@ -6967,8 +6972,8 @@ fn builtinCall(
6967 gz: *GenZir,6972 gz: *GenZir,
6968 scope: *Scope,6973 scope: *Scope,
6969 rl: ResultLoc,6974 rl: ResultLoc,
6970 node: ast.Node.Index,6975 node: Ast.Node.Index,
6971 params: []const ast.Node.Index,6976 params: []const Ast.Node.Index,
6972) InnerError!Zir.Inst.Ref {6977) InnerError!Zir.Inst.Ref {
6973 const astgen = gz.astgen;6978 const astgen = gz.astgen;
6974 const tree = astgen.tree;6979 const tree = astgen.tree;
...@@ -7300,6 +7305,11 @@ fn builtinCall(...@@ -7300,6 +7305,11 @@ fn builtinCall(
7300 return rvalue(gz, rl, result, node);7305 return rvalue(gz, rl, result, node);
7301 },7306 },
73027307
7308 .add_with_saturation => return saturatingArithmetic(gz, scope, rl, node, params, .add_with_saturation),
7309 .sub_with_saturation => return saturatingArithmetic(gz, scope, rl, node, params, .sub_with_saturation),
7310 .mul_with_saturation => return saturatingArithmetic(gz, scope, rl, node, params, .mul_with_saturation),
7311 .shl_with_saturation => return saturatingArithmetic(gz, scope, rl, node, params, .shl_with_saturation),
7312
7303 .atomic_load => {7313 .atomic_load => {
7304 const int_type = try typeExpr(gz, scope, params[0]);7314 const int_type = try typeExpr(gz, scope, params[0]);
7305 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{7315 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
...@@ -7312,7 +7322,7 @@ fn builtinCall(...@@ -7312,7 +7322,7 @@ fn builtinCall(
7312 },7322 },
7313 } });7323 } });
7314 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);7324 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
7315 const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[2]);7325 const ordering = try expr(gz, scope, .{ .ty = .atomic_order_type }, params[2]);
7316 const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.Bin{7326 const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.Bin{
7317 .lhs = ptr,7327 .lhs = ptr,
7318 .rhs = ordering,7328 .rhs = ordering,
...@@ -7333,7 +7343,7 @@ fn builtinCall(...@@ -7333,7 +7343,7 @@ fn builtinCall(
7333 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);7343 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
7334 const operation = try expr(gz, scope, .{ .ty = .atomic_rmw_op_type }, params[2]);7344 const operation = try expr(gz, scope, .{ .ty = .atomic_rmw_op_type }, params[2]);
7335 const operand = try expr(gz, scope, .{ .ty = int_type }, params[3]);7345 const operand = try expr(gz, scope, .{ .ty = int_type }, params[3]);
7336 const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[4]);7346 const ordering = try expr(gz, scope, .{ .ty = .atomic_order_type }, params[4]);
7337 const result = try gz.addPlNode(.atomic_rmw, node, Zir.Inst.AtomicRmw{7347 const result = try gz.addPlNode(.atomic_rmw, node, Zir.Inst.AtomicRmw{
7338 .ptr = ptr,7348 .ptr = ptr,
7339 .operation = operation,7349 .operation = operation,
...@@ -7355,7 +7365,7 @@ fn builtinCall(...@@ -7355,7 +7365,7 @@ fn builtinCall(
7355 } });7365 } });
7356 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);7366 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
7357 const operand = try expr(gz, scope, .{ .ty = int_type }, params[2]);7367 const operand = try expr(gz, scope, .{ .ty = int_type }, params[2]);
7358 const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[3]);7368 const ordering = try expr(gz, scope, .{ .ty = .atomic_order_type }, params[3]);
7359 const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{7369 const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{
7360 .ptr = ptr,7370 .ptr = ptr,
7361 .operand = operand,7371 .operand = operand,
...@@ -7455,7 +7465,7 @@ fn builtinCall(...@@ -7455,7 +7465,7 @@ fn builtinCall(
7455fn simpleNoOpVoid(7465fn simpleNoOpVoid(
7456 gz: *GenZir,7466 gz: *GenZir,
7457 rl: ResultLoc,7467 rl: ResultLoc,
7458 node: ast.Node.Index,7468 node: Ast.Node.Index,
7459 tag: Zir.Inst.Tag,7469 tag: Zir.Inst.Tag,
7460) InnerError!Zir.Inst.Ref {7470) InnerError!Zir.Inst.Ref {
7461 _ = try gz.addNode(tag, node);7471 _ = try gz.addNode(tag, node);
...@@ -7466,9 +7476,9 @@ fn hasDeclOrField(...@@ -7466,9 +7476,9 @@ fn hasDeclOrField(
7466 gz: *GenZir,7476 gz: *GenZir,
7467 scope: *Scope,7477 scope: *Scope,
7468 rl: ResultLoc,7478 rl: ResultLoc,
7469 node: ast.Node.Index,7479 node: Ast.Node.Index,
7470 lhs_node: ast.Node.Index,7480 lhs_node: Ast.Node.Index,
7471 rhs_node: ast.Node.Index,7481 rhs_node: Ast.Node.Index,
7472 tag: Zir.Inst.Tag,7482 tag: Zir.Inst.Tag,
7473) InnerError!Zir.Inst.Ref {7483) InnerError!Zir.Inst.Ref {
7474 const container_type = try typeExpr(gz, scope, lhs_node);7484 const container_type = try typeExpr(gz, scope, lhs_node);
...@@ -7484,9 +7494,9 @@ fn typeCast(...@@ -7484,9 +7494,9 @@ fn typeCast(
7484 gz: *GenZir,7494 gz: *GenZir,
7485 scope: *Scope,7495 scope: *Scope,
7486 rl: ResultLoc,7496 rl: ResultLoc,
7487 node: ast.Node.Index,7497 node: Ast.Node.Index,
7488 lhs_node: ast.Node.Index,7498 lhs_node: Ast.Node.Index,
7489 rhs_node: ast.Node.Index,7499 rhs_node: Ast.Node.Index,
7490 tag: Zir.Inst.Tag,7500 tag: Zir.Inst.Tag,
7491) InnerError!Zir.Inst.Ref {7501) InnerError!Zir.Inst.Ref {
7492 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{7502 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
...@@ -7500,8 +7510,8 @@ fn simpleUnOpType(...@@ -7500,8 +7510,8 @@ fn simpleUnOpType(
7500 gz: *GenZir,7510 gz: *GenZir,
7501 scope: *Scope,7511 scope: *Scope,
7502 rl: ResultLoc,7512 rl: ResultLoc,
7503 node: ast.Node.Index,7513 node: Ast.Node.Index,
7504 operand_node: ast.Node.Index,7514 operand_node: Ast.Node.Index,
7505 tag: Zir.Inst.Tag,7515 tag: Zir.Inst.Tag,
7506) InnerError!Zir.Inst.Ref {7516) InnerError!Zir.Inst.Ref {
7507 const operand = try typeExpr(gz, scope, operand_node);7517 const operand = try typeExpr(gz, scope, operand_node);
...@@ -7513,9 +7523,9 @@ fn simpleUnOp(...@@ -7513,9 +7523,9 @@ fn simpleUnOp(
7513 gz: *GenZir,7523 gz: *GenZir,
7514 scope: *Scope,7524 scope: *Scope,
7515 rl: ResultLoc,7525 rl: ResultLoc,
7516 node: ast.Node.Index,7526 node: Ast.Node.Index,
7517 operand_rl: ResultLoc,7527 operand_rl: ResultLoc,
7518 operand_node: ast.Node.Index,7528 operand_node: Ast.Node.Index,
7519 tag: Zir.Inst.Tag,7529 tag: Zir.Inst.Tag,
7520) InnerError!Zir.Inst.Ref {7530) InnerError!Zir.Inst.Ref {
7521 const operand = try expr(gz, scope, operand_rl, operand_node);7531 const operand = try expr(gz, scope, operand_rl, operand_node);
...@@ -7527,11 +7537,12 @@ fn cmpxchg(...@@ -7527,11 +7537,12 @@ fn cmpxchg(
7527 gz: *GenZir,7537 gz: *GenZir,
7528 scope: *Scope,7538 scope: *Scope,
7529 rl: ResultLoc,7539 rl: ResultLoc,
7530 node: ast.Node.Index,7540 node: Ast.Node.Index,
7531 params: []const ast.Node.Index,7541 params: []const Ast.Node.Index,
7532 tag: Zir.Inst.Tag,7542 tag: Zir.Inst.Tag,
7533) InnerError!Zir.Inst.Ref {7543) InnerError!Zir.Inst.Ref {
7534 const int_type = try typeExpr(gz, scope, params[0]);7544 const int_type = try typeExpr(gz, scope, params[0]);
7545 // TODO: allow this to be volatile
7535 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{7546 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
7536 .ptr_type_simple = .{7547 .ptr_type_simple = .{
7537 .is_allowzero = false,7548 .is_allowzero = false,
...@@ -7543,11 +7554,11 @@ fn cmpxchg(...@@ -7543,11 +7554,11 @@ fn cmpxchg(
7543 } });7554 } });
7544 const result = try gz.addPlNode(tag, node, Zir.Inst.Cmpxchg{7555 const result = try gz.addPlNode(tag, node, Zir.Inst.Cmpxchg{
7545 // zig fmt: off7556 // zig fmt: off
7546 .ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]),7557 .ptr = try expr(gz, scope, .{ .coerced_ty = ptr_type }, params[1]),
7547 .expected_value = try expr(gz, scope, .{ .ty = int_type }, params[2]),7558 .expected_value = try expr(gz, scope, .{ .coerced_ty = int_type }, params[2]),
7548 .new_value = try expr(gz, scope, .{ .ty = int_type }, params[3]),7559 .new_value = try expr(gz, scope, .{ .coerced_ty = int_type }, params[3]),
7549 .success_order = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[4]),7560 .success_order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[4]),
7550 .fail_order = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[5]),7561 .failure_order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[5]),
7551 // zig fmt: on7562 // zig fmt: on
7552 });7563 });
7553 return rvalue(gz, rl, result, node);7564 return rvalue(gz, rl, result, node);
...@@ -7557,9 +7568,9 @@ fn bitBuiltin(...@@ -7557,9 +7568,9 @@ fn bitBuiltin(
7557 gz: *GenZir,7568 gz: *GenZir,
7558 scope: *Scope,7569 scope: *Scope,
7559 rl: ResultLoc,7570 rl: ResultLoc,
7560 node: ast.Node.Index,7571 node: Ast.Node.Index,
7561 int_type_node: ast.Node.Index,7572 int_type_node: Ast.Node.Index,
7562 operand_node: ast.Node.Index,7573 operand_node: Ast.Node.Index,
7563 tag: Zir.Inst.Tag,7574 tag: Zir.Inst.Tag,
7564) InnerError!Zir.Inst.Ref {7575) InnerError!Zir.Inst.Ref {
7565 const int_type = try typeExpr(gz, scope, int_type_node);7576 const int_type = try typeExpr(gz, scope, int_type_node);
...@@ -7572,9 +7583,9 @@ fn divBuiltin(...@@ -7572,9 +7583,9 @@ fn divBuiltin(
7572 gz: *GenZir,7583 gz: *GenZir,
7573 scope: *Scope,7584 scope: *Scope,
7574 rl: ResultLoc,7585 rl: ResultLoc,
7575 node: ast.Node.Index,7586 node: Ast.Node.Index,
7576 lhs_node: ast.Node.Index,7587 lhs_node: Ast.Node.Index,
7577 rhs_node: ast.Node.Index,7588 rhs_node: Ast.Node.Index,
7578 tag: Zir.Inst.Tag,7589 tag: Zir.Inst.Tag,
7579) InnerError!Zir.Inst.Ref {7590) InnerError!Zir.Inst.Ref {
7580 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{7591 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
...@@ -7588,8 +7599,8 @@ fn simpleCBuiltin(...@@ -7588,8 +7599,8 @@ fn simpleCBuiltin(
7588 gz: *GenZir,7599 gz: *GenZir,
7589 scope: *Scope,7600 scope: *Scope,
7590 rl: ResultLoc,7601 rl: ResultLoc,
7591 node: ast.Node.Index,7602 node: Ast.Node.Index,
7592 operand_node: ast.Node.Index,7603 operand_node: Ast.Node.Index,
7593 tag: Zir.Inst.Extended,7604 tag: Zir.Inst.Extended,
7594) InnerError!Zir.Inst.Ref {7605) InnerError!Zir.Inst.Ref {
7595 const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node);7606 const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node);
...@@ -7604,9 +7615,9 @@ fn offsetOf(...@@ -7604,9 +7615,9 @@ fn offsetOf(
7604 gz: *GenZir,7615 gz: *GenZir,
7605 scope: *Scope,7616 scope: *Scope,
7606 rl: ResultLoc,7617 rl: ResultLoc,
7607 node: ast.Node.Index,7618 node: Ast.Node.Index,
7608 lhs_node: ast.Node.Index,7619 lhs_node: Ast.Node.Index,
7609 rhs_node: ast.Node.Index,7620 rhs_node: Ast.Node.Index,
7610 tag: Zir.Inst.Tag,7621 tag: Zir.Inst.Tag,
7611) InnerError!Zir.Inst.Ref {7622) InnerError!Zir.Inst.Ref {
7612 const type_inst = try typeExpr(gz, scope, lhs_node);7623 const type_inst = try typeExpr(gz, scope, lhs_node);
...@@ -7622,9 +7633,9 @@ fn shiftOp(...@@ -7622,9 +7633,9 @@ fn shiftOp(
7622 gz: *GenZir,7633 gz: *GenZir,
7623 scope: *Scope,7634 scope: *Scope,
7624 rl: ResultLoc,7635 rl: ResultLoc,
7625 node: ast.Node.Index,7636 node: Ast.Node.Index,
7626 lhs_node: ast.Node.Index,7637 lhs_node: Ast.Node.Index,
7627 rhs_node: ast.Node.Index,7638 rhs_node: Ast.Node.Index,
7628 tag: Zir.Inst.Tag,7639 tag: Zir.Inst.Tag,
7629) InnerError!Zir.Inst.Ref {7640) InnerError!Zir.Inst.Ref {
7630 const lhs = try expr(gz, scope, .none, lhs_node);7641 const lhs = try expr(gz, scope, .none, lhs_node);
...@@ -7641,8 +7652,8 @@ fn cImport(...@@ -7641,8 +7652,8 @@ fn cImport(
7641 gz: *GenZir,7652 gz: *GenZir,
7642 scope: *Scope,7653 scope: *Scope,
7643 rl: ResultLoc,7654 rl: ResultLoc,
7644 node: ast.Node.Index,7655 node: Ast.Node.Index,
7645 body_node: ast.Node.Index,7656 body_node: Ast.Node.Index,
7646) InnerError!Zir.Inst.Ref {7657) InnerError!Zir.Inst.Ref {
7647 const astgen = gz.astgen;7658 const astgen = gz.astgen;
7648 const gpa = astgen.gpa;7659 const gpa = astgen.gpa;
...@@ -7666,8 +7677,8 @@ fn overflowArithmetic(...@@ -7666,8 +7677,8 @@ fn overflowArithmetic(
7666 gz: *GenZir,7677 gz: *GenZir,
7667 scope: *Scope,7678 scope: *Scope,
7668 rl: ResultLoc,7679 rl: ResultLoc,
7669 node: ast.Node.Index,7680 node: Ast.Node.Index,
7670 params: []const ast.Node.Index,7681 params: []const Ast.Node.Index,
7671 tag: Zir.Inst.Extended,7682 tag: Zir.Inst.Extended,
7672) InnerError!Zir.Inst.Ref {7683) InnerError!Zir.Inst.Ref {
7673 const int_type = try typeExpr(gz, scope, params[0]);7684 const int_type = try typeExpr(gz, scope, params[0]);
...@@ -7692,12 +7703,30 @@ fn overflowArithmetic(...@@ -7692,12 +7703,30 @@ fn overflowArithmetic(
7692 return rvalue(gz, rl, result, node);7703 return rvalue(gz, rl, result, node);
7693}7704}
76947705
7706fn saturatingArithmetic(
7707 gz: *GenZir,
7708 scope: *Scope,
7709 rl: ResultLoc,
7710 node: Ast.Node.Index,
7711 params: []const Ast.Node.Index,
7712 tag: Zir.Inst.Extended,
7713) InnerError!Zir.Inst.Ref {
7714 const lhs = try expr(gz, scope, .none, params[0]);
7715 const rhs = try expr(gz, scope, .none, params[1]);
7716 const result = try gz.addExtendedPayload(tag, Zir.Inst.SaturatingArithmetic{
7717 .node = gz.nodeIndexToRelative(node),
7718 .lhs = lhs,
7719 .rhs = rhs,
7720 });
7721 return rvalue(gz, rl, result, node);
7722}
7723
7695fn callExpr(7724fn callExpr(
7696 gz: *GenZir,7725 gz: *GenZir,
7697 scope: *Scope,7726 scope: *Scope,
7698 rl: ResultLoc,7727 rl: ResultLoc,
7699 node: ast.Node.Index,7728 node: Ast.Node.Index,
7700 call: ast.full.Call,7729 call: Ast.full.Call,
7701) InnerError!Zir.Inst.Ref {7730) InnerError!Zir.Inst.Ref {
7702 const astgen = gz.astgen;7731 const astgen = gz.astgen;
7703 const lhs = try expr(gz, scope, .none, call.ast.fn_expr);7732 const lhs = try expr(gz, scope, .none, call.ast.fn_expr);
...@@ -7786,7 +7815,7 @@ pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{...@@ -7786,7 +7815,7 @@ pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{
7786 .{ "void", .void_type },7815 .{ "void", .void_type },
7787});7816});
77887817
7789fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index) bool {7818fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index) bool {
7790 const node_tags = tree.nodes.items(.tag);7819 const node_tags = tree.nodes.items(.tag);
7791 const node_datas = tree.nodes.items(.data);7820 const node_datas = tree.nodes.items(.data);
7792 const main_tokens = tree.nodes.items(.main_token);7821 const main_tokens = tree.nodes.items(.main_token);
...@@ -7995,7 +8024,7 @@ fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index)...@@ -7995,7 +8024,7 @@ fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index)
7995 }8024 }
7996}8025}
79978026
7998fn nodeMayEvalToError(tree: *const ast.Tree, start_node: ast.Node.Index) enum { never, always, maybe } {8027fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) enum { never, always, maybe } {
7999 const node_tags = tree.nodes.items(.tag);8028 const node_tags = tree.nodes.items(.tag);
8000 const node_datas = tree.nodes.items(.data);8029 const node_datas = tree.nodes.items(.data);
8001 const main_tokens = tree.nodes.items(.main_token);8030 const main_tokens = tree.nodes.items(.main_token);
...@@ -8204,7 +8233,7 @@ fn nodeMayEvalToError(tree: *const ast.Tree, start_node: ast.Node.Index) enum {...@@ -8204,7 +8233,7 @@ fn nodeMayEvalToError(tree: *const ast.Tree, start_node: ast.Node.Index) enum {
8204 }8233 }
8205}8234}
82068235
8207fn nodeImpliesRuntimeBits(tree: *const ast.Tree, start_node: ast.Node.Index) bool {8236fn nodeImpliesRuntimeBits(tree: *const Ast, start_node: Ast.Node.Index) bool {
8208 const node_tags = tree.nodes.items(.tag);8237 const node_tags = tree.nodes.items(.tag);
8209 const node_datas = tree.nodes.items(.data);8238 const node_datas = tree.nodes.items(.data);
82108239
...@@ -8391,7 +8420,7 @@ fn rvalue(...@@ -8391,7 +8420,7 @@ fn rvalue(
8391 gz: *GenZir,8420 gz: *GenZir,
8392 rl: ResultLoc,8421 rl: ResultLoc,
8393 result: Zir.Inst.Ref,8422 result: Zir.Inst.Ref,
8394 src_node: ast.Node.Index,8423 src_node: Ast.Node.Index,
8395) InnerError!Zir.Inst.Ref {8424) InnerError!Zir.Inst.Ref {
8396 if (gz.endsWithNoReturn()) return result;8425 if (gz.endsWithNoReturn()) return result;
8397 switch (rl) {8426 switch (rl) {
...@@ -8496,7 +8525,7 @@ fn rvalue(...@@ -8496,7 +8525,7 @@ fn rvalue(
8496/// and allocates the result within `astgen.arena`.8525/// and allocates the result within `astgen.arena`.
8497/// Otherwise, returns a reference to the source code bytes directly.8526/// Otherwise, returns a reference to the source code bytes directly.
8498/// See also `appendIdentStr` and `parseStrLit`.8527/// See also `appendIdentStr` and `parseStrLit`.
8499fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]const u8 {8528fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]const u8 {
8500 const tree = astgen.tree;8529 const tree = astgen.tree;
8501 const token_tags = tree.tokens.items(.tag);8530 const token_tags = tree.tokens.items(.tag);
8502 assert(token_tags[token] == .identifier);8531 assert(token_tags[token] == .identifier);
...@@ -8516,7 +8545,7 @@ fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]co...@@ -8516,7 +8545,7 @@ fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]co
8516/// See also `identifierTokenString` and `parseStrLit`.8545/// See also `identifierTokenString` and `parseStrLit`.
8517fn appendIdentStr(8546fn appendIdentStr(
8518 astgen: *AstGen,8547 astgen: *AstGen,
8519 token: ast.TokenIndex,8548 token: Ast.TokenIndex,
8520 buf: *ArrayListUnmanaged(u8),8549 buf: *ArrayListUnmanaged(u8),
8521) InnerError!void {8550) InnerError!void {
8522 const tree = astgen.tree;8551 const tree = astgen.tree;
...@@ -8533,7 +8562,7 @@ fn appendIdentStr(...@@ -8533,7 +8562,7 @@ fn appendIdentStr(
8533/// Appends the result to `buf`.8562/// Appends the result to `buf`.
8534fn parseStrLit(8563fn parseStrLit(
8535 astgen: *AstGen,8564 astgen: *AstGen,
8536 token: ast.TokenIndex,8565 token: Ast.TokenIndex,
8537 buf: *ArrayListUnmanaged(u8),8566 buf: *ArrayListUnmanaged(u8),
8538 bytes: []const u8,8567 bytes: []const u8,
8539 offset: u32,8568 offset: u32,
...@@ -8597,7 +8626,7 @@ fn parseStrLit(...@@ -8597,7 +8626,7 @@ fn parseStrLit(
85978626
8598fn failNode(8627fn failNode(
8599 astgen: *AstGen,8628 astgen: *AstGen,
8600 node: ast.Node.Index,8629 node: Ast.Node.Index,
8601 comptime format: []const u8,8630 comptime format: []const u8,
8602 args: anytype,8631 args: anytype,
8603) InnerError {8632) InnerError {
...@@ -8606,7 +8635,7 @@ fn failNode(...@@ -8606,7 +8635,7 @@ fn failNode(
86068635
8607fn failNodeNotes(8636fn failNodeNotes(
8608 astgen: *AstGen,8637 astgen: *AstGen,
8609 node: ast.Node.Index,8638 node: Ast.Node.Index,
8610 comptime format: []const u8,8639 comptime format: []const u8,
8611 args: anytype,8640 args: anytype,
8612 notes: []const u32,8641 notes: []const u32,
...@@ -8638,7 +8667,7 @@ fn failNodeNotes(...@@ -8638,7 +8667,7 @@ fn failNodeNotes(
86388667
8639fn failTok(8668fn failTok(
8640 astgen: *AstGen,8669 astgen: *AstGen,
8641 token: ast.TokenIndex,8670 token: Ast.TokenIndex,
8642 comptime format: []const u8,8671 comptime format: []const u8,
8643 args: anytype,8672 args: anytype,
8644) InnerError {8673) InnerError {
...@@ -8647,7 +8676,7 @@ fn failTok(...@@ -8647,7 +8676,7 @@ fn failTok(
86478676
8648fn failTokNotes(8677fn failTokNotes(
8649 astgen: *AstGen,8678 astgen: *AstGen,
8650 token: ast.TokenIndex,8679 token: Ast.TokenIndex,
8651 comptime format: []const u8,8680 comptime format: []const u8,
8652 args: anytype,8681 args: anytype,
8653 notes: []const u32,8682 notes: []const u32,
...@@ -8680,7 +8709,7 @@ fn failTokNotes(...@@ -8680,7 +8709,7 @@ fn failTokNotes(
8680/// Same as `fail`, except given an absolute byte offset.8709/// Same as `fail`, except given an absolute byte offset.
8681fn failOff(8710fn failOff(
8682 astgen: *AstGen,8711 astgen: *AstGen,
8683 token: ast.TokenIndex,8712 token: Ast.TokenIndex,
8684 byte_offset: u32,8713 byte_offset: u32,
8685 comptime format: []const u8,8714 comptime format: []const u8,
8686 args: anytype,8715 args: anytype,
...@@ -8705,7 +8734,7 @@ fn failOff(...@@ -8705,7 +8734,7 @@ fn failOff(
87058734
8706fn errNoteTok(8735fn errNoteTok(
8707 astgen: *AstGen,8736 astgen: *AstGen,
8708 token: ast.TokenIndex,8737 token: Ast.TokenIndex,
8709 comptime format: []const u8,8738 comptime format: []const u8,
8710 args: anytype,8739 args: anytype,
8711) Allocator.Error!u32 {8740) Allocator.Error!u32 {
...@@ -8728,7 +8757,7 @@ fn errNoteTok(...@@ -8728,7 +8757,7 @@ fn errNoteTok(
87288757
8729fn errNoteNode(8758fn errNoteNode(
8730 astgen: *AstGen,8759 astgen: *AstGen,
8731 node: ast.Node.Index,8760 node: Ast.Node.Index,
8732 comptime format: []const u8,8761 comptime format: []const u8,
8733 args: anytype,8762 args: anytype,
8734) Allocator.Error!u32 {8763) Allocator.Error!u32 {
...@@ -8749,22 +8778,22 @@ fn errNoteNode(...@@ -8749,22 +8778,22 @@ fn errNoteNode(
8749 });8778 });
8750}8779}
87518780
8752fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 {8781fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {
8753 const gpa = astgen.gpa;8782 const gpa = astgen.gpa;
8754 const string_bytes = &astgen.string_bytes;8783 const string_bytes = &astgen.string_bytes;
8755 const str_index = @intCast(u32, string_bytes.items.len);8784 const str_index = @intCast(u32, string_bytes.items.len);
8756 try astgen.appendIdentStr(ident_token, string_bytes);8785 try astgen.appendIdentStr(ident_token, string_bytes);
8757 const key = string_bytes.items[str_index..];8786 const key = string_bytes.items[str_index..];
8758 const gop = try astgen.string_table.getOrPut(gpa, key);8787 const gop = try astgen.string_table.getOrPutContextAdapted(gpa, @as([]const u8, key), StringIndexAdapter{
8788 .bytes = string_bytes,
8789 }, StringIndexContext{
8790 .bytes = string_bytes,
8791 });
8759 if (gop.found_existing) {8792 if (gop.found_existing) {
8760 string_bytes.shrinkRetainingCapacity(str_index);8793 string_bytes.shrinkRetainingCapacity(str_index);
8761 return gop.value_ptr.*;8794 return gop.key_ptr.*;
8762 } else {8795 } else {
8763 // We have to dupe the key into the arena, otherwise the memory8796 gop.key_ptr.* = str_index;
8764 // becomes invalidated when string_bytes gets data appended.
8765 // TODO https://github.com/ziglang/zig/issues/8528
8766 gop.key_ptr.* = try astgen.arena.dupe(u8, key);
8767 gop.value_ptr.* = str_index;
8768 try string_bytes.append(gpa, 0);8797 try string_bytes.append(gpa, 0);
8769 return str_index;8798 return str_index;
8770 }8799 }
...@@ -8772,26 +8801,26 @@ fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 {...@@ -8772,26 +8801,26 @@ fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 {
87728801
8773const IndexSlice = struct { index: u32, len: u32 };8802const IndexSlice = struct { index: u32, len: u32 };
87748803
8775fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice {8804fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
8776 const gpa = astgen.gpa;8805 const gpa = astgen.gpa;
8777 const string_bytes = &astgen.string_bytes;8806 const string_bytes = &astgen.string_bytes;
8778 const str_index = @intCast(u32, string_bytes.items.len);8807 const str_index = @intCast(u32, string_bytes.items.len);
8779 const token_bytes = astgen.tree.tokenSlice(str_lit_token);8808 const token_bytes = astgen.tree.tokenSlice(str_lit_token);
8780 try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0);8809 try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0);
8781 const key = string_bytes.items[str_index..];8810 const key = string_bytes.items[str_index..];
8782 const gop = try astgen.string_table.getOrPut(gpa, key);8811 const gop = try astgen.string_table.getOrPutContextAdapted(gpa, @as([]const u8, key), StringIndexAdapter{
8812 .bytes = string_bytes,
8813 }, StringIndexContext{
8814 .bytes = string_bytes,
8815 });
8783 if (gop.found_existing) {8816 if (gop.found_existing) {
8784 string_bytes.shrinkRetainingCapacity(str_index);8817 string_bytes.shrinkRetainingCapacity(str_index);
8785 return IndexSlice{8818 return IndexSlice{
8786 .index = gop.value_ptr.*,8819 .index = gop.key_ptr.*,
8787 .len = @intCast(u32, key.len),8820 .len = @intCast(u32, key.len),
8788 };8821 };
8789 } else {8822 } else {
8790 // We have to dupe the key into the arena, otherwise the memory8823 gop.key_ptr.* = str_index;
8791 // becomes invalidated when string_bytes gets data appended.
8792 // TODO https://github.com/ziglang/zig/issues/8528
8793 gop.key_ptr.* = try astgen.arena.dupe(u8, key);
8794 gop.value_ptr.* = str_index;
8795 // Still need a null byte because we are using the same table8824 // Still need a null byte because we are using the same table
8796 // to lookup null terminated strings, so if we get a match, it has to8825 // to lookup null terminated strings, so if we get a match, it has to
8797 // be null terminated for that to work.8826 // be null terminated for that to work.
...@@ -8803,7 +8832,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice {...@@ -8803,7 +8832,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice {
8803 }8832 }
8804}8833}
88058834
8806fn strLitNodeAsString(astgen: *AstGen, node: ast.Node.Index) !IndexSlice {8835fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {
8807 const tree = astgen.tree;8836 const tree = astgen.tree;
8808 const node_datas = tree.nodes.items(.data);8837 const node_datas = tree.nodes.items(.data);
88098838
...@@ -8838,7 +8867,7 @@ fn strLitNodeAsString(astgen: *AstGen, node: ast.Node.Index) !IndexSlice {...@@ -8838,7 +8867,7 @@ fn strLitNodeAsString(astgen: *AstGen, node: ast.Node.Index) !IndexSlice {
8838 };8867 };
8839}8868}
88408869
8841fn testNameString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !u32 {8870fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {
8842 const gpa = astgen.gpa;8871 const gpa = astgen.gpa;
8843 const string_bytes = &astgen.string_bytes;8872 const string_bytes = &astgen.string_bytes;
8844 const str_index = @intCast(u32, string_bytes.items.len);8873 const str_index = @intCast(u32, string_bytes.items.len);
...@@ -8895,7 +8924,7 @@ const Scope = struct {...@@ -8895,7 +8924,7 @@ const Scope = struct {
8895 gen_zir: *GenZir,8924 gen_zir: *GenZir,
8896 inst: Zir.Inst.Ref,8925 inst: Zir.Inst.Ref,
8897 /// Source location of the corresponding variable declaration.8926 /// Source location of the corresponding variable declaration.
8898 token_src: ast.TokenIndex,8927 token_src: Ast.TokenIndex,
8899 /// String table index.8928 /// String table index.
8900 name: u32,8929 name: u32,
8901 id_cat: IdCat,8930 id_cat: IdCat,
...@@ -8914,7 +8943,7 @@ const Scope = struct {...@@ -8914,7 +8943,7 @@ const Scope = struct {
8914 gen_zir: *GenZir,8943 gen_zir: *GenZir,
8915 ptr: Zir.Inst.Ref,8944 ptr: Zir.Inst.Ref,
8916 /// Source location of the corresponding variable declaration.8945 /// Source location of the corresponding variable declaration.
8917 token_src: ast.TokenIndex,8946 token_src: Ast.TokenIndex,
8918 /// String table index.8947 /// String table index.
8919 name: u32,8948 name: u32,
8920 id_cat: IdCat,8949 id_cat: IdCat,
...@@ -8929,7 +8958,7 @@ const Scope = struct {...@@ -8929,7 +8958,7 @@ const Scope = struct {
8929 base: Scope,8958 base: Scope,
8930 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`.8959 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`.
8931 parent: *Scope,8960 parent: *Scope,
8932 defer_node: ast.Node.Index,8961 defer_node: Ast.Node.Index,
8933 };8962 };
89348963
8935 /// Represents a global scope that has any number of declarations in it.8964 /// Represents a global scope that has any number of declarations in it.
...@@ -8941,8 +8970,8 @@ const Scope = struct {...@@ -8941,8 +8970,8 @@ const Scope = struct {
8941 parent: *Scope,8970 parent: *Scope,
8942 /// Maps string table index to the source location of declaration,8971 /// Maps string table index to the source location of declaration,
8943 /// for the purposes of reporting name shadowing compile errors.8972 /// for the purposes of reporting name shadowing compile errors.
8944 decls: std.AutoHashMapUnmanaged(u32, ast.Node.Index) = .{},8973 decls: std.AutoHashMapUnmanaged(u32, Ast.Node.Index) = .{},
8945 node: ast.Node.Index,8974 node: Ast.Node.Index,
8946 };8975 };
89478976
8948 const Top = struct {8977 const Top = struct {
...@@ -8961,7 +8990,7 @@ const GenZir = struct {...@@ -8961,7 +8990,7 @@ const GenZir = struct {
8961 /// How decls created in this scope should be named.8990 /// How decls created in this scope should be named.
8962 anon_name_strategy: Zir.Inst.NameStrategy = .anon,8991 anon_name_strategy: Zir.Inst.NameStrategy = .anon,
8963 /// The containing decl AST node.8992 /// The containing decl AST node.
8964 decl_node_index: ast.Node.Index,8993 decl_node_index: Ast.Node.Index,
8965 /// The containing decl line index, absolute.8994 /// The containing decl line index, absolute.
8966 decl_line: u32,8995 decl_line: u32,
8967 parent: *Scope,8996 parent: *Scope,
...@@ -8996,8 +9025,8 @@ const GenZir = struct {...@@ -8996,8 +9025,8 @@ const GenZir = struct {
8996 /// a result location pointer.9025 /// a result location pointer.
8997 labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{},9026 labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{},
89989027
8999 suspend_node: ast.Node.Index = 0,9028 suspend_node: Ast.Node.Index = 0,
9000 nosuspend_node: ast.Node.Index = 0,9029 nosuspend_node: Ast.Node.Index = 0,
90019030
9002 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {9031 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {
9003 return .{9032 return .{
...@@ -9013,7 +9042,7 @@ const GenZir = struct {...@@ -9013,7 +9042,7 @@ const GenZir = struct {
9013 }9042 }
90149043
9015 const Label = struct {9044 const Label = struct {
9016 token: ast.TokenIndex,9045 token: Ast.TokenIndex,
9017 block_inst: Zir.Inst.Index,9046 block_inst: Zir.Inst.Index,
9018 used: bool = false,9047 used: bool = false,
9019 };9048 };
...@@ -9034,7 +9063,7 @@ const GenZir = struct {...@@ -9034,7 +9063,7 @@ const GenZir = struct {
9034 return false;9063 return false;
9035 }9064 }
90369065
9037 fn calcLine(gz: GenZir, node: ast.Node.Index) u32 {9066 fn calcLine(gz: GenZir, node: Ast.Node.Index) u32 {
9038 const astgen = gz.astgen;9067 const astgen = gz.astgen;
9039 const tree = astgen.tree;9068 const tree = astgen.tree;
9040 const source = tree.source;9069 const source = tree.source;
...@@ -9046,23 +9075,15 @@ const GenZir = struct {...@@ -9046,23 +9075,15 @@ const GenZir = struct {
9046 return @intCast(u32, gz.decl_line + astgen.source_line);9075 return @intCast(u32, gz.decl_line + astgen.source_line);
9047 }9076 }
90489077
9049 fn tokSrcLoc(gz: GenZir, token_index: ast.TokenIndex) LazySrcLoc {9078 fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) i32 {
9050 return .{ .token_offset = token_index - gz.srcToken() };
9051 }
9052
9053 fn nodeSrcLoc(gz: GenZir, node_index: ast.Node.Index) LazySrcLoc {
9054 return .{ .node_offset = gz.nodeIndexToRelative(node_index) };
9055 }
9056
9057 fn nodeIndexToRelative(gz: GenZir, node_index: ast.Node.Index) i32 {
9058 return @bitCast(i32, node_index) - @bitCast(i32, gz.decl_node_index);9079 return @bitCast(i32, node_index) - @bitCast(i32, gz.decl_node_index);
9059 }9080 }
90609081
9061 fn tokenIndexToRelative(gz: GenZir, token: ast.TokenIndex) u32 {9082 fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) u32 {
9062 return token - gz.srcToken();9083 return token - gz.srcToken();
9063 }9084 }
90649085
9065 fn srcToken(gz: GenZir) ast.TokenIndex {9086 fn srcToken(gz: GenZir) Ast.TokenIndex {
9066 return gz.astgen.tree.firstToken(gz.decl_node_index);9087 return gz.astgen.tree.firstToken(gz.decl_node_index);
9067 }9088 }
90689089
...@@ -9147,7 +9168,7 @@ const GenZir = struct {...@@ -9147,7 +9168,7 @@ const GenZir = struct {
9147 }9168 }
91489169
9149 fn addFunc(gz: *GenZir, args: struct {9170 fn addFunc(gz: *GenZir, args: struct {
9150 src_node: ast.Node.Index,9171 src_node: Ast.Node.Index,
9151 body: []const Zir.Inst.Index,9172 body: []const Zir.Inst.Index,
9152 param_block: Zir.Inst.Index,9173 param_block: Zir.Inst.Index,
9153 ret_ty: []const Zir.Inst.Index,9174 ret_ty: []const Zir.Inst.Index,
...@@ -9340,7 +9361,7 @@ const GenZir = struct {...@@ -9340,7 +9361,7 @@ const GenZir = struct {
9340 callee: Zir.Inst.Ref,9361 callee: Zir.Inst.Ref,
9341 args: []const Zir.Inst.Ref,9362 args: []const Zir.Inst.Ref,
9342 /// Absolute node index. This function does the conversion to offset from Decl.9363 /// Absolute node index. This function does the conversion to offset from Decl.
9343 src_node: ast.Node.Index,9364 src_node: Ast.Node.Index,
9344 ) !Zir.Inst.Ref {9365 ) !Zir.Inst.Ref {
9345 assert(callee != .none);9366 assert(callee != .none);
9346 assert(src_node != 0);9367 assert(src_node != 0);
...@@ -9431,7 +9452,7 @@ const GenZir = struct {...@@ -9431,7 +9452,7 @@ const GenZir = struct {
9431 tag: Zir.Inst.Tag,9452 tag: Zir.Inst.Tag,
9432 operand: Zir.Inst.Ref,9453 operand: Zir.Inst.Ref,
9433 /// Absolute node index. This function does the conversion to offset from Decl.9454 /// Absolute node index. This function does the conversion to offset from Decl.
9434 src_node: ast.Node.Index,9455 src_node: Ast.Node.Index,
9435 ) !Zir.Inst.Ref {9456 ) !Zir.Inst.Ref {
9436 assert(operand != .none);9457 assert(operand != .none);
9437 return gz.add(.{9458 return gz.add(.{
...@@ -9447,7 +9468,7 @@ const GenZir = struct {...@@ -9447,7 +9468,7 @@ const GenZir = struct {
9447 gz: *GenZir,9468 gz: *GenZir,
9448 tag: Zir.Inst.Tag,9469 tag: Zir.Inst.Tag,
9449 /// Absolute node index. This function does the conversion to offset from Decl.9470 /// Absolute node index. This function does the conversion to offset from Decl.
9450 src_node: ast.Node.Index,9471 src_node: Ast.Node.Index,
9451 extra: anytype,9472 extra: anytype,
9452 ) !Zir.Inst.Ref {9473 ) !Zir.Inst.Ref {
9453 const gpa = gz.astgen.gpa;9474 const gpa = gz.astgen.gpa;
...@@ -9471,7 +9492,7 @@ const GenZir = struct {...@@ -9471,7 +9492,7 @@ const GenZir = struct {
9471 gz: *GenZir,9492 gz: *GenZir,
9472 tag: Zir.Inst.Tag,9493 tag: Zir.Inst.Tag,
9473 /// Absolute token index. This function does the conversion to Decl offset.9494 /// Absolute token index. This function does the conversion to Decl offset.
9474 abs_tok_index: ast.TokenIndex,9495 abs_tok_index: Ast.TokenIndex,
9475 name: u32,9496 name: u32,
9476 body: []const u32,9497 body: []const u32,
9477 ) !Zir.Inst.Index {9498 ) !Zir.Inst.Index {
...@@ -9526,7 +9547,7 @@ const GenZir = struct {...@@ -9526,7 +9547,7 @@ const GenZir = struct {
9526 fn addExtendedMultiOp(9547 fn addExtendedMultiOp(
9527 gz: *GenZir,9548 gz: *GenZir,
9528 opcode: Zir.Inst.Extended,9549 opcode: Zir.Inst.Extended,
9529 node: ast.Node.Index,9550 node: Ast.Node.Index,
9530 operands: []const Zir.Inst.Ref,9551 operands: []const Zir.Inst.Ref,
9531 ) !Zir.Inst.Ref {9552 ) !Zir.Inst.Ref {
9532 const astgen = gz.astgen;9553 const astgen = gz.astgen;
...@@ -9587,7 +9608,7 @@ const GenZir = struct {...@@ -9587,7 +9608,7 @@ const GenZir = struct {
9587 tag: Zir.Inst.Tag,9608 tag: Zir.Inst.Tag,
9588 operand: Zir.Inst.Ref,9609 operand: Zir.Inst.Ref,
9589 /// Absolute token index. This function does the conversion to Decl offset.9610 /// Absolute token index. This function does the conversion to Decl offset.
9590 abs_tok_index: ast.TokenIndex,9611 abs_tok_index: Ast.TokenIndex,
9591 ) !Zir.Inst.Ref {9612 ) !Zir.Inst.Ref {
9592 assert(operand != .none);9613 assert(operand != .none);
9593 return gz.add(.{9614 return gz.add(.{
...@@ -9604,7 +9625,7 @@ const GenZir = struct {...@@ -9604,7 +9625,7 @@ const GenZir = struct {
9604 tag: Zir.Inst.Tag,9625 tag: Zir.Inst.Tag,
9605 str_index: u32,9626 str_index: u32,
9606 /// Absolute token index. This function does the conversion to Decl offset.9627 /// Absolute token index. This function does the conversion to Decl offset.
9607 abs_tok_index: ast.TokenIndex,9628 abs_tok_index: Ast.TokenIndex,
9608 ) !Zir.Inst.Ref {9629 ) !Zir.Inst.Ref {
9609 return gz.add(.{9630 return gz.add(.{
9610 .tag = tag,9631 .tag = tag,
...@@ -9651,7 +9672,7 @@ const GenZir = struct {...@@ -9651,7 +9672,7 @@ const GenZir = struct {
9651 gz: *GenZir,9672 gz: *GenZir,
9652 tag: Zir.Inst.Tag,9673 tag: Zir.Inst.Tag,
9653 decl_index: u32,9674 decl_index: u32,
9654 src_node: ast.Node.Index,9675 src_node: Ast.Node.Index,
9655 ) !Zir.Inst.Ref {9676 ) !Zir.Inst.Ref {
9656 return gz.add(.{9677 return gz.add(.{
9657 .tag = tag,9678 .tag = tag,
...@@ -9666,7 +9687,7 @@ const GenZir = struct {...@@ -9666,7 +9687,7 @@ const GenZir = struct {
9666 gz: *GenZir,9687 gz: *GenZir,
9667 tag: Zir.Inst.Tag,9688 tag: Zir.Inst.Tag,
9668 /// Absolute node index. This function does the conversion to offset from Decl.9689 /// Absolute node index. This function does the conversion to offset from Decl.
9669 src_node: ast.Node.Index,9690 src_node: Ast.Node.Index,
9670 ) !Zir.Inst.Ref {9691 ) !Zir.Inst.Ref {
9671 return gz.add(.{9692 return gz.add(.{
9672 .tag = tag,9693 .tag = tag,
...@@ -9678,7 +9699,7 @@ const GenZir = struct {...@@ -9678,7 +9699,7 @@ const GenZir = struct {
9678 gz: *GenZir,9699 gz: *GenZir,
9679 opcode: Zir.Inst.Extended,9700 opcode: Zir.Inst.Extended,
9680 /// Absolute node index. This function does the conversion to offset from Decl.9701 /// Absolute node index. This function does the conversion to offset from Decl.
9681 src_node: ast.Node.Index,9702 src_node: Ast.Node.Index,
9682 ) !Zir.Inst.Ref {9703 ) !Zir.Inst.Ref {
9683 return gz.add(.{9704 return gz.add(.{
9684 .tag = .extended,9705 .tag = .extended,
...@@ -9694,7 +9715,7 @@ const GenZir = struct {...@@ -9694,7 +9715,7 @@ const GenZir = struct {
9694 gz: *GenZir,9715 gz: *GenZir,
9695 args: struct {9716 args: struct {
9696 /// Absolute node index. This function does the conversion to offset from Decl.9717 /// Absolute node index. This function does the conversion to offset from Decl.
9697 node: ast.Node.Index,9718 node: Ast.Node.Index,
9698 type_inst: Zir.Inst.Ref,9719 type_inst: Zir.Inst.Ref,
9699 align_inst: Zir.Inst.Ref,9720 align_inst: Zir.Inst.Ref,
9700 is_const: bool,9721 is_const: bool,
...@@ -9745,7 +9766,7 @@ const GenZir = struct {...@@ -9745,7 +9766,7 @@ const GenZir = struct {
9745 gz: *GenZir,9766 gz: *GenZir,
9746 args: struct {9767 args: struct {
9747 /// Absolute node index. This function does the conversion to offset from Decl.9768 /// Absolute node index. This function does the conversion to offset from Decl.
9748 node: ast.Node.Index,9769 node: Ast.Node.Index,
9749 asm_source: u32,9770 asm_source: u32,
9750 output_type_bits: u32,9771 output_type_bits: u32,
9751 is_volatile: bool,9772 is_volatile: bool,
...@@ -9802,7 +9823,7 @@ const GenZir = struct {...@@ -9802,7 +9823,7 @@ const GenZir = struct {
9802 /// Note that this returns a `Zir.Inst.Index` not a ref.9823 /// Note that this returns a `Zir.Inst.Index` not a ref.
9803 /// Does *not* append the block instruction to the scope.9824 /// Does *not* append the block instruction to the scope.
9804 /// Leaves the `payload_index` field undefined.9825 /// Leaves the `payload_index` field undefined.
9805 fn addBlock(gz: *GenZir, tag: Zir.Inst.Tag, node: ast.Node.Index) !Zir.Inst.Index {9826 fn addBlock(gz: *GenZir, tag: Zir.Inst.Tag, node: Ast.Node.Index) !Zir.Inst.Index {
9806 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);9827 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
9807 const gpa = gz.astgen.gpa;9828 const gpa = gz.astgen.gpa;
9808 try gz.astgen.instructions.append(gpa, .{9829 try gz.astgen.instructions.append(gpa, .{
...@@ -9817,7 +9838,7 @@ const GenZir = struct {...@@ -9817,7 +9838,7 @@ const GenZir = struct {
98179838
9818 /// Note that this returns a `Zir.Inst.Index` not a ref.9839 /// Note that this returns a `Zir.Inst.Index` not a ref.
9819 /// Leaves the `payload_index` field undefined.9840 /// Leaves the `payload_index` field undefined.
9820 fn addCondBr(gz: *GenZir, tag: Zir.Inst.Tag, node: ast.Node.Index) !Zir.Inst.Index {9841 fn addCondBr(gz: *GenZir, tag: Zir.Inst.Tag, node: Ast.Node.Index) !Zir.Inst.Index {
9821 const gpa = gz.astgen.gpa;9842 const gpa = gz.astgen.gpa;
9822 try gz.instructions.ensureUnusedCapacity(gpa, 1);9843 try gz.instructions.ensureUnusedCapacity(gpa, 1);
9823 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);9844 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
...@@ -9833,7 +9854,7 @@ const GenZir = struct {...@@ -9833,7 +9854,7 @@ const GenZir = struct {
9833 }9854 }
98349855
9835 fn setStruct(gz: *GenZir, inst: Zir.Inst.Index, args: struct {9856 fn setStruct(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9836 src_node: ast.Node.Index,9857 src_node: Ast.Node.Index,
9837 body_len: u32,9858 body_len: u32,
9838 fields_len: u32,9859 fields_len: u32,
9839 decls_len: u32,9860 decls_len: u32,
...@@ -9878,7 +9899,7 @@ const GenZir = struct {...@@ -9878,7 +9899,7 @@ const GenZir = struct {
9878 }9899 }
98799900
9880 fn setUnion(gz: *GenZir, inst: Zir.Inst.Index, args: struct {9901 fn setUnion(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9881 src_node: ast.Node.Index,9902 src_node: Ast.Node.Index,
9882 tag_type: Zir.Inst.Ref,9903 tag_type: Zir.Inst.Ref,
9883 body_len: u32,9904 body_len: u32,
9884 fields_len: u32,9905 fields_len: u32,
...@@ -9928,7 +9949,7 @@ const GenZir = struct {...@@ -9928,7 +9949,7 @@ const GenZir = struct {
9928 }9949 }
99299950
9930 fn setEnum(gz: *GenZir, inst: Zir.Inst.Index, args: struct {9951 fn setEnum(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9931 src_node: ast.Node.Index,9952 src_node: Ast.Node.Index,
9932 tag_type: Zir.Inst.Ref,9953 tag_type: Zir.Inst.Ref,
9933 body_len: u32,9954 body_len: u32,
9934 fields_len: u32,9955 fields_len: u32,
...@@ -10001,7 +10022,7 @@ const GenZir = struct {...@@ -10001,7 +10022,7 @@ const GenZir = struct {
10001 return new_index;10022 return new_index;
10002 }10023 }
1000310024
10004 fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: ast.Node.Index) !void {10025 fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void {
10005 switch (rl) {10026 switch (rl) {
10006 .ptr => |ret_ptr| _ = try gz.addUnNode(.ret_load, ret_ptr, node),10027 .ptr => |ret_ptr| _ = try gz.addUnNode(.ret_load, ret_ptr, node),
10007 .ty => _ = try gz.addUnNode(.ret_node, operand, node),10028 .ty => _ = try gz.addUnNode(.ret_node, operand, node),
...@@ -10029,12 +10050,12 @@ fn isPrimitive(name: []const u8) bool {...@@ -10029,12 +10050,12 @@ fn isPrimitive(name: []const u8) bool {
10029 }10050 }
10030}10051}
1003110052
10032/// Local variables shadowing detection, including function parameters and primitives.10053/// Local variables shadowing detection, including function parameters.
10033fn detectLocalShadowing(10054fn detectLocalShadowing(
10034 astgen: *AstGen,10055 astgen: *AstGen,
10035 scope: *Scope,10056 scope: *Scope,
10036 ident_name: u32,10057 ident_name: u32,
10037 name_token: ast.TokenIndex,10058 name_token: Ast.TokenIndex,
10038 token_bytes: []const u8,10059 token_bytes: []const u8,
10039) !void {10060) !void {
10040 const gpa = astgen.gpa;10061 const gpa = astgen.gpa;
...@@ -10139,7 +10160,7 @@ fn refToIndex(inst: Zir.Inst.Ref) ?Zir.Inst.Index {...@@ -10139,7 +10160,7 @@ fn refToIndex(inst: Zir.Inst.Ref) ?Zir.Inst.Index {
10139 }10160 }
10140}10161}
1014110162
10142fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const ast.Node.Index) !void {10163fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.Node.Index) !void {
10143 const gpa = astgen.gpa;10164 const gpa = astgen.gpa;
10144 const tree = astgen.tree;10165 const tree = astgen.tree;
10145 const node_tags = tree.nodes.items(.tag);10166 const node_tags = tree.nodes.items(.tag);
src/BuiltinFn.zig+32
...@@ -2,6 +2,7 @@ const std = @import("std");...@@ -2,6 +2,7 @@ const std = @import("std");
22
3pub const Tag = enum {3pub const Tag = enum {
4 add_with_overflow,4 add_with_overflow,
5 add_with_saturation,
5 align_cast,6 align_cast,
6 align_of,7 align_of,
7 as,8 as,
...@@ -65,6 +66,7 @@ pub const Tag = enum {...@@ -65,6 +66,7 @@ pub const Tag = enum {
65 wasm_memory_grow,66 wasm_memory_grow,
66 mod,67 mod,
67 mul_with_overflow,68 mul_with_overflow,
69 mul_with_saturation,
68 panic,70 panic,
69 pop_count,71 pop_count,
70 ptr_cast,72 ptr_cast,
...@@ -79,10 +81,12 @@ pub const Tag = enum {...@@ -79,10 +81,12 @@ pub const Tag = enum {
79 set_runtime_safety,81 set_runtime_safety,
80 shl_exact,82 shl_exact,
81 shl_with_overflow,83 shl_with_overflow,
84 shl_with_saturation,
82 shr_exact,85 shr_exact,
83 shuffle,86 shuffle,
84 size_of,87 size_of,
85 splat,88 splat,
89 sub_with_saturation,
86 reduce,90 reduce,
87 src,91 src,
88 sqrt,92 sqrt,
...@@ -527,6 +531,34 @@ pub const list = list: {...@@ -527,6 +531,34 @@ pub const list = list: {
527 .param_count = 2,531 .param_count = 2,
528 },532 },
529 },533 },
534 .{
535 "@addWithSaturation",
536 .{
537 .tag = .add_with_saturation,
538 .param_count = 2,
539 },
540 },
541 .{
542 "@subWithSaturation",
543 .{
544 .tag = .sub_with_saturation,
545 .param_count = 2,
546 },
547 },
548 .{
549 "@mulWithSaturation",
550 .{
551 .tag = .mul_with_saturation,
552 .param_count = 2,
553 },
554 },
555 .{
556 "@shlWithSaturation",
557 .{
558 .tag = .shl_with_saturation,
559 .param_count = 2,
560 },
561 },
530 .{562 .{
531 "@memcpy",563 "@memcpy",
532 .{564 .{
src/Compilation.zig+9-4
...@@ -708,6 +708,10 @@ pub const InitOptions = struct {...@@ -708,6 +708,10 @@ pub const InitOptions = struct {
708 disable_c_depfile: bool = false,708 disable_c_depfile: bool = false,
709 linker_z_nodelete: bool = false,709 linker_z_nodelete: bool = false,
710 linker_z_defs: bool = false,710 linker_z_defs: bool = false,
711 linker_z_origin: bool = false,
712 linker_z_noexecstack: bool = false,
713 linker_z_now: bool = false,
714 linker_z_relro: bool = false,
711 linker_tsaware: bool = false,715 linker_tsaware: bool = false,
712 linker_nxcompat: bool = false,716 linker_nxcompat: bool = false,
713 linker_dynamicbase: bool = false,717 linker_dynamicbase: bool = false,
...@@ -1382,6 +1386,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1382,6 +1386,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1382 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,1386 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
1383 .z_nodelete = options.linker_z_nodelete,1387 .z_nodelete = options.linker_z_nodelete,
1384 .z_defs = options.linker_z_defs,1388 .z_defs = options.linker_z_defs,
1389 .z_origin = options.linker_z_origin,
1390 .z_noexecstack = options.linker_z_noexecstack,
1391 .z_now = options.linker_z_now,
1392 .z_relro = options.linker_z_relro,
1385 .tsaware = options.linker_tsaware,1393 .tsaware = options.linker_tsaware,
1386 .nxcompat = options.linker_nxcompat,1394 .nxcompat = options.linker_nxcompat,
1387 .dynamicbase = options.linker_dynamicbase,1395 .dynamicbase = options.linker_dynamicbase,
...@@ -2408,7 +2416,7 @@ const AstGenSrc = union(enum) {...@@ -2408,7 +2416,7 @@ const AstGenSrc = union(enum) {
2408 root,2416 root,
2409 import: struct {2417 import: struct {
2410 importing_file: *Module.Scope.File,2418 importing_file: *Module.Scope.File,
2411 import_tok: std.zig.ast.TokenIndex,2419 import_tok: std.zig.Ast.TokenIndex,
2412 },2420 },
2413};2421};
24142422
...@@ -3665,8 +3673,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc...@@ -3665,8 +3673,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
3665 \\pub const zig_is_stage2 = {};3673 \\pub const zig_is_stage2 = {};
3666 \\/// Temporary until self-hosted supports the `cpu.arch` value.3674 \\/// Temporary until self-hosted supports the `cpu.arch` value.
3667 \\pub const stage2_arch: std.Target.Cpu.Arch = .{};3675 \\pub const stage2_arch: std.Target.Cpu.Arch = .{};
3668 \\/// Temporary until self-hosted supports the `os.tag` value.
3669 \\pub const stage2_os: std.Target.Os.Tag = .{};
3670 \\3676 \\
3671 \\pub const output_mode = std.builtin.OutputMode.{};3677 \\pub const output_mode = std.builtin.OutputMode.{};
3672 \\pub const link_mode = std.builtin.LinkMode.{};3678 \\pub const link_mode = std.builtin.LinkMode.{};
...@@ -3682,7 +3688,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc...@@ -3682,7 +3688,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
3682 build_options.version,3688 build_options.version,
3683 !use_stage1,3689 !use_stage1,
3684 std.zig.fmtId(@tagName(target.cpu.arch)),3690 std.zig.fmtId(@tagName(target.cpu.arch)),
3685 std.zig.fmtId(@tagName(target.os.tag)),
3686 std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)),3691 std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)),
3687 std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)),3692 std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)),
3688 comp.bin_file.options.is_test,3693 comp.bin_file.options.is_test,
src/Liveness.zig+6
...@@ -231,6 +231,7 @@ fn analyzeInst(...@@ -231,6 +231,7 @@ fn analyzeInst(
231 .mul,231 .mul,
232 .mulwrap,232 .mulwrap,
233 .div,233 .div,
234 .rem,
234 .ptr_add,235 .ptr_add,
235 .ptr_sub,236 .ptr_sub,
236 .bit_and,237 .bit_and,
...@@ -286,6 +287,7 @@ fn analyzeInst(...@@ -286,6 +287,7 @@ fn analyzeInst(
286 .struct_field_ptr_index_1,287 .struct_field_ptr_index_1,
287 .struct_field_ptr_index_2,288 .struct_field_ptr_index_2,
288 .struct_field_ptr_index_3,289 .struct_field_ptr_index_3,
290 .array_to_slice,
289 => {291 => {
290 const o = inst_datas[inst].ty_op;292 const o = inst_datas[inst].ty_op;
291 return trackOperands(a, new_set, inst, main_tomb, .{ o.operand, .none, .none });293 return trackOperands(a, new_set, inst, main_tomb, .{ o.operand, .none, .none });
...@@ -338,6 +340,10 @@ fn analyzeInst(...@@ -338,6 +340,10 @@ fn analyzeInst(
338 const extra = a.air.extraData(Air.Bin, inst_datas[inst].ty_pl.payload).data;340 const extra = a.air.extraData(Air.Bin, inst_datas[inst].ty_pl.payload).data;
339 return trackOperands(a, new_set, inst, main_tomb, .{ extra.lhs, extra.rhs, .none });341 return trackOperands(a, new_set, inst, main_tomb, .{ extra.lhs, extra.rhs, .none });
340 },342 },
343 .cmpxchg_strong, .cmpxchg_weak => {
344 const extra = a.air.extraData(Air.Cmpxchg, inst_datas[inst].ty_pl.payload).data;
345 return trackOperands(a, new_set, inst, main_tomb, .{ extra.ptr, extra.expected_value, extra.new_value });
346 },
341 .br => {347 .br => {
342 const br = inst_datas[inst].br;348 const br = inst_datas[inst].br;
343 return trackOperands(a, new_set, inst, main_tomb, .{ br.operand, .none, .none });349 return trackOperands(a, new_set, inst, main_tomb, .{ br.operand, .none, .none });
src/Module.zig+131-73
...@@ -11,7 +11,7 @@ const log = std.log.scoped(.module);...@@ -11,7 +11,7 @@ const log = std.log.scoped(.module);
11const BigIntConst = std.math.big.int.Const;11const BigIntConst = std.math.big.int.Const;
12const BigIntMutable = std.math.big.int.Mutable;12const BigIntMutable = std.math.big.int.Mutable;
13const Target = std.Target;13const Target = std.Target;
14const ast = std.zig.ast;14const Ast = std.zig.Ast;
1515
16const Module = @This();16const Module = @This();
17const Compilation = @import("Compilation.zig");17const Compilation = @import("Compilation.zig");
...@@ -291,7 +291,7 @@ pub const Decl = struct {...@@ -291,7 +291,7 @@ pub const Decl = struct {
291 generation: u32,291 generation: u32,
292 /// The AST node index of this declaration.292 /// The AST node index of this declaration.
293 /// Must be recomputed when the corresponding source file is modified.293 /// Must be recomputed when the corresponding source file is modified.
294 src_node: ast.Node.Index,294 src_node: Ast.Node.Index,
295 /// Line number corresponding to `src_node`. Stored separately so that source files295 /// Line number corresponding to `src_node`. Stored separately so that source files
296 /// do not need to be loaded into memory in order to compute debug line numbers.296 /// do not need to be loaded into memory in order to compute debug line numbers.
297 src_line: u32,297 src_line: u32,
...@@ -365,6 +365,8 @@ pub const Decl = struct {...@@ -365,6 +365,8 @@ pub const Decl = struct {
365 /// Decl is marked alive, then it sends the Decl to the linker. Otherwise it365 /// Decl is marked alive, then it sends the Decl to the linker. Otherwise it
366 /// deletes the Decl on the spot.366 /// deletes the Decl on the spot.
367 alive: bool,367 alive: bool,
368 /// Whether the Decl is a `usingnamespace` declaration.
369 is_usingnamespace: bool,
368370
369 /// Represents the position of the code in the output file.371 /// Represents the position of the code in the output file.
370 /// This is populated regardless of semantic analysis and code generation.372 /// This is populated regardless of semantic analysis and code generation.
...@@ -497,19 +499,19 @@ pub const Decl = struct {...@@ -497,19 +499,19 @@ pub const Decl = struct {
497 return decl.src_line + offset;499 return decl.src_line + offset;
498 }500 }
499501
500 pub fn relativeToNodeIndex(decl: Decl, offset: i32) ast.Node.Index {502 pub fn relativeToNodeIndex(decl: Decl, offset: i32) Ast.Node.Index {
501 return @bitCast(ast.Node.Index, offset + @bitCast(i32, decl.src_node));503 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, decl.src_node));
502 }504 }
503505
504 pub fn nodeIndexToRelative(decl: Decl, node_index: ast.Node.Index) i32 {506 pub fn nodeIndexToRelative(decl: Decl, node_index: Ast.Node.Index) i32 {
505 return @bitCast(i32, node_index) - @bitCast(i32, decl.src_node);507 return @bitCast(i32, node_index) - @bitCast(i32, decl.src_node);
506 }508 }
507509
508 pub fn tokSrcLoc(decl: Decl, token_index: ast.TokenIndex) LazySrcLoc {510 pub fn tokSrcLoc(decl: Decl, token_index: Ast.TokenIndex) LazySrcLoc {
509 return .{ .token_offset = token_index - decl.srcToken() };511 return .{ .token_offset = token_index - decl.srcToken() };
510 }512 }
511513
512 pub fn nodeSrcLoc(decl: Decl, node_index: ast.Node.Index) LazySrcLoc {514 pub fn nodeSrcLoc(decl: Decl, node_index: Ast.Node.Index) LazySrcLoc {
513 return .{ .node_offset = decl.nodeIndexToRelative(node_index) };515 return .{ .node_offset = decl.nodeIndexToRelative(node_index) };
514 }516 }
515517
...@@ -525,7 +527,7 @@ pub const Decl = struct {...@@ -525,7 +527,7 @@ pub const Decl = struct {
525 };527 };
526 }528 }
527529
528 pub fn srcToken(decl: Decl) ast.TokenIndex {530 pub fn srcToken(decl: Decl) Ast.TokenIndex {
529 const tree = &decl.namespace.file_scope.tree;531 const tree = &decl.namespace.file_scope.tree;
530 return tree.firstToken(decl.src_node);532 return tree.firstToken(decl.src_node);
531 }533 }
...@@ -1008,6 +1010,11 @@ pub const Scope = struct {...@@ -1008,6 +1010,11 @@ pub const Scope = struct {
10081010
1009 anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},1011 anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},
10101012
1013 /// Key is usingnamespace Decl itself. To find the namespace being included,
1014 /// the Decl Value has to be resolved as a Type which has a Namespace.
1015 /// Value is whether the usingnamespace decl is marked `pub`.
1016 usingnamespace_set: std.AutoHashMapUnmanaged(*Decl, bool) = .{},
1017
1011 pub fn deinit(ns: *Namespace, mod: *Module) void {1018 pub fn deinit(ns: *Namespace, mod: *Module) void {
1012 ns.destroyDecls(mod);1019 ns.destroyDecls(mod);
1013 ns.* = undefined;1020 ns.* = undefined;
...@@ -1114,7 +1121,7 @@ pub const Scope = struct {...@@ -1114,7 +1121,7 @@ pub const Scope = struct {
1114 /// Whether this is populated depends on `status`.1121 /// Whether this is populated depends on `status`.
1115 stat_mtime: i128,1122 stat_mtime: i128,
1116 /// Whether this is populated or not depends on `tree_loaded`.1123 /// Whether this is populated or not depends on `tree_loaded`.
1117 tree: ast.Tree,1124 tree: Ast,
1118 /// Whether this is populated or not depends on `zir_loaded`.1125 /// Whether this is populated or not depends on `zir_loaded`.
1119 zir: Zir,1126 zir: Zir,
1120 /// Package that this file is a part of, managed externally.1127 /// Package that this file is a part of, managed externally.
...@@ -1213,7 +1220,7 @@ pub const Scope = struct {...@@ -1213,7 +1220,7 @@ pub const Scope = struct {
1213 return source;1220 return source;
1214 }1221 }
12151222
1216 pub fn getTree(file: *File, gpa: *Allocator) !*const ast.Tree {1223 pub fn getTree(file: *File, gpa: *Allocator) !*const Ast {
1217 if (file.tree_loaded) return &file.tree;1224 if (file.tree_loaded) return &file.tree;
12181225
1219 const source = try file.getSource(gpa);1226 const source = try file.getSource(gpa);
...@@ -1314,6 +1321,7 @@ pub const Scope = struct {...@@ -1314,6 +1321,7 @@ pub const Scope = struct {
1314 /// It is shared among all the blocks in an inline or comptime called1321 /// It is shared among all the blocks in an inline or comptime called
1315 /// function.1322 /// function.
1316 pub const Inlining = struct {1323 pub const Inlining = struct {
1324 comptime_result: Air.Inst.Ref,
1317 merges: Merges,1325 merges: Merges,
1318 };1326 };
13191327
...@@ -1558,17 +1566,17 @@ pub const ErrorMsg = struct {...@@ -1558,17 +1566,17 @@ pub const ErrorMsg = struct {
1558pub const SrcLoc = struct {1566pub const SrcLoc = struct {
1559 file_scope: *Scope.File,1567 file_scope: *Scope.File,
1560 /// Might be 0 depending on tag of `lazy`.1568 /// Might be 0 depending on tag of `lazy`.
1561 parent_decl_node: ast.Node.Index,1569 parent_decl_node: Ast.Node.Index,
1562 /// Relative to `parent_decl_node`.1570 /// Relative to `parent_decl_node`.
1563 lazy: LazySrcLoc,1571 lazy: LazySrcLoc,
15641572
1565 pub fn declSrcToken(src_loc: SrcLoc) ast.TokenIndex {1573 pub fn declSrcToken(src_loc: SrcLoc) Ast.TokenIndex {
1566 const tree = src_loc.file_scope.tree;1574 const tree = src_loc.file_scope.tree;
1567 return tree.firstToken(src_loc.parent_decl_node);1575 return tree.firstToken(src_loc.parent_decl_node);
1568 }1576 }
15691577
1570 pub fn declRelativeToNodeIndex(src_loc: SrcLoc, offset: i32) ast.TokenIndex {1578 pub fn declRelativeToNodeIndex(src_loc: SrcLoc, offset: i32) Ast.TokenIndex {
1571 return @bitCast(ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node));1579 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node));
1572 }1580 }
15731581
1574 pub fn byteOffset(src_loc: SrcLoc, gpa: *Allocator) !u32 {1582 pub fn byteOffset(src_loc: SrcLoc, gpa: *Allocator) !u32 {
...@@ -1636,36 +1644,12 @@ pub const SrcLoc = struct {...@@ -1636,36 +1644,12 @@ pub const SrcLoc = struct {
1636 const token_starts = tree.tokens.items(.start);1644 const token_starts = tree.tokens.items(.start);
1637 return token_starts[tok_index];1645 return token_starts[tok_index];
1638 },1646 },
1639 .node_offset_builtin_call_arg0 => |node_off| {1647 .node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0),
1640 const tree = try src_loc.file_scope.getTree(gpa);1648 .node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1),
1641 const node_datas = tree.nodes.items(.data);1649 .node_offset_builtin_call_arg2 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 2),
1642 const node_tags = tree.nodes.items(.tag);1650 .node_offset_builtin_call_arg3 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 3),
1643 const node = src_loc.declRelativeToNodeIndex(node_off);1651 .node_offset_builtin_call_arg4 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 4),
1644 const param = switch (node_tags[node]) {1652 .node_offset_builtin_call_arg5 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 5),
1645 .builtin_call_two, .builtin_call_two_comma => node_datas[node].lhs,
1646 .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs],
1647 else => unreachable,
1648 };
1649 const main_tokens = tree.nodes.items(.main_token);
1650 const tok_index = main_tokens[param];
1651 const token_starts = tree.tokens.items(.start);
1652 return token_starts[tok_index];
1653 },
1654 .node_offset_builtin_call_arg1 => |node_off| {
1655 const tree = try src_loc.file_scope.getTree(gpa);
1656 const node_datas = tree.nodes.items(.data);
1657 const node_tags = tree.nodes.items(.tag);
1658 const node = src_loc.declRelativeToNodeIndex(node_off);
1659 const param = switch (node_tags[node]) {
1660 .builtin_call_two, .builtin_call_two_comma => node_datas[node].rhs,
1661 .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + 1],
1662 else => unreachable,
1663 };
1664 const main_tokens = tree.nodes.items(.main_token);
1665 const tok_index = main_tokens[param];
1666 const token_starts = tree.tokens.items(.start);
1667 return token_starts[tok_index];
1668 },
1669 .node_offset_array_access_index => |node_off| {1653 .node_offset_array_access_index => |node_off| {
1670 const tree = try src_loc.file_scope.getTree(gpa);1654 const tree = try src_loc.file_scope.getTree(gpa);
1671 const node_datas = tree.nodes.items(.data);1655 const node_datas = tree.nodes.items(.data);
...@@ -1694,7 +1678,7 @@ pub const SrcLoc = struct {...@@ -1694,7 +1678,7 @@ pub const SrcLoc = struct {
1694 const tree = try src_loc.file_scope.getTree(gpa);1678 const tree = try src_loc.file_scope.getTree(gpa);
1695 const node_tags = tree.nodes.items(.tag);1679 const node_tags = tree.nodes.items(.tag);
1696 const node = src_loc.declRelativeToNodeIndex(node_off);1680 const node = src_loc.declRelativeToNodeIndex(node_off);
1697 var params: [1]ast.Node.Index = undefined;1681 var params: [1]Ast.Node.Index = undefined;
1698 const full = switch (node_tags[node]) {1682 const full = switch (node_tags[node]) {
1699 .call_one,1683 .call_one,
1700 .call_one_comma,1684 .call_one_comma,
...@@ -1824,7 +1808,7 @@ pub const SrcLoc = struct {...@@ -1824,7 +1808,7 @@ pub const SrcLoc = struct {
1824 const node_datas = tree.nodes.items(.data);1808 const node_datas = tree.nodes.items(.data);
1825 const node_tags = tree.nodes.items(.tag);1809 const node_tags = tree.nodes.items(.tag);
1826 const main_tokens = tree.nodes.items(.main_token);1810 const main_tokens = tree.nodes.items(.main_token);
1827 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);1811 const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
1828 const case_nodes = tree.extra_data[extra.start..extra.end];1812 const case_nodes = tree.extra_data[extra.start..extra.end];
1829 for (case_nodes) |case_node| {1813 for (case_nodes) |case_node| {
1830 const case = switch (node_tags[case_node]) {1814 const case = switch (node_tags[case_node]) {
...@@ -1850,7 +1834,7 @@ pub const SrcLoc = struct {...@@ -1850,7 +1834,7 @@ pub const SrcLoc = struct {
1850 const node_datas = tree.nodes.items(.data);1834 const node_datas = tree.nodes.items(.data);
1851 const node_tags = tree.nodes.items(.tag);1835 const node_tags = tree.nodes.items(.tag);
1852 const main_tokens = tree.nodes.items(.main_token);1836 const main_tokens = tree.nodes.items(.main_token);
1853 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);1837 const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
1854 const case_nodes = tree.extra_data[extra.start..extra.end];1838 const case_nodes = tree.extra_data[extra.start..extra.end];
1855 for (case_nodes) |case_node| {1839 for (case_nodes) |case_node| {
1856 const case = switch (node_tags[case_node]) {1840 const case = switch (node_tags[case_node]) {
...@@ -1879,7 +1863,7 @@ pub const SrcLoc = struct {...@@ -1879,7 +1863,7 @@ pub const SrcLoc = struct {
1879 const node_datas = tree.nodes.items(.data);1863 const node_datas = tree.nodes.items(.data);
1880 const node_tags = tree.nodes.items(.tag);1864 const node_tags = tree.nodes.items(.tag);
1881 const node = src_loc.declRelativeToNodeIndex(node_off);1865 const node = src_loc.declRelativeToNodeIndex(node_off);
1882 var params: [1]ast.Node.Index = undefined;1866 var params: [1]Ast.Node.Index = undefined;
1883 const full = switch (node_tags[node]) {1867 const full = switch (node_tags[node]) {
1884 .fn_proto_simple => tree.fnProtoSimple(&params, node),1868 .fn_proto_simple => tree.fnProtoSimple(&params, node),
1885 .fn_proto_multi => tree.fnProtoMulti(node),1869 .fn_proto_multi => tree.fnProtoMulti(node),
...@@ -1904,7 +1888,7 @@ pub const SrcLoc = struct {...@@ -1904,7 +1888,7 @@ pub const SrcLoc = struct {
1904 const tree = try src_loc.file_scope.getTree(gpa);1888 const tree = try src_loc.file_scope.getTree(gpa);
1905 const node_tags = tree.nodes.items(.tag);1889 const node_tags = tree.nodes.items(.tag);
1906 const node = src_loc.declRelativeToNodeIndex(node_off);1890 const node = src_loc.declRelativeToNodeIndex(node_off);
1907 var params: [1]ast.Node.Index = undefined;1891 var params: [1]Ast.Node.Index = undefined;
1908 const full = switch (node_tags[node]) {1892 const full = switch (node_tags[node]) {
1909 .fn_proto_simple => tree.fnProtoSimple(&params, node),1893 .fn_proto_simple => tree.fnProtoSimple(&params, node),
1910 .fn_proto_multi => tree.fnProtoMulti(node),1894 .fn_proto_multi => tree.fnProtoMulti(node),
...@@ -1934,7 +1918,7 @@ pub const SrcLoc = struct {...@@ -1934,7 +1918,7 @@ pub const SrcLoc = struct {
1934 const node_datas = tree.nodes.items(.data);1918 const node_datas = tree.nodes.items(.data);
1935 const node_tags = tree.nodes.items(.tag);1919 const node_tags = tree.nodes.items(.tag);
1936 const parent_node = src_loc.declRelativeToNodeIndex(node_off);1920 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
1937 var params: [1]ast.Node.Index = undefined;1921 var params: [1]Ast.Node.Index = undefined;
1938 const full = switch (node_tags[parent_node]) {1922 const full = switch (node_tags[parent_node]) {
1939 .fn_proto_simple => tree.fnProtoSimple(&params, parent_node),1923 .fn_proto_simple => tree.fnProtoSimple(&params, parent_node),
1940 .fn_proto_multi => tree.fnProtoMulti(parent_node),1924 .fn_proto_multi => tree.fnProtoMulti(parent_node),
...@@ -1958,6 +1942,31 @@ pub const SrcLoc = struct {...@@ -1958,6 +1942,31 @@ pub const SrcLoc = struct {
1958 },1942 },
1959 }1943 }
1960 }1944 }
1945
1946 pub fn byteOffsetBuiltinCallArg(
1947 src_loc: SrcLoc,
1948 gpa: *Allocator,
1949 node_off: i32,
1950 arg_index: u32,
1951 ) !u32 {
1952 const tree = try src_loc.file_scope.getTree(gpa);
1953 const node_datas = tree.nodes.items(.data);
1954 const node_tags = tree.nodes.items(.tag);
1955 const node = src_loc.declRelativeToNodeIndex(node_off);
1956 const param = switch (node_tags[node]) {
1957 .builtin_call_two, .builtin_call_two_comma => switch (arg_index) {
1958 0 => node_datas[node].lhs,
1959 1 => node_datas[node].rhs,
1960 else => unreachable,
1961 },
1962 .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + arg_index],
1963 else => unreachable,
1964 };
1965 const main_tokens = tree.nodes.items(.main_token);
1966 const tok_index = main_tokens[param];
1967 const token_starts = tree.tokens.items(.start);
1968 return token_starts[tok_index];
1969 }
1961};1970};
19621971
1963/// Resolving a source location into a byte offset may require doing work1972/// Resolving a source location into a byte offset may require doing work
...@@ -2025,6 +2034,10 @@ pub const LazySrcLoc = union(enum) {...@@ -2025,6 +2034,10 @@ pub const LazySrcLoc = union(enum) {
2025 node_offset_builtin_call_arg0: i32,2034 node_offset_builtin_call_arg0: i32,
2026 /// Same as `node_offset_builtin_call_arg0` except arg index 1.2035 /// Same as `node_offset_builtin_call_arg0` except arg index 1.
2027 node_offset_builtin_call_arg1: i32,2036 node_offset_builtin_call_arg1: i32,
2037 node_offset_builtin_call_arg2: i32,
2038 node_offset_builtin_call_arg3: i32,
2039 node_offset_builtin_call_arg4: i32,
2040 node_offset_builtin_call_arg5: i32,
2028 /// The source location points to the index expression of an array access2041 /// The source location points to the index expression of an array access
2029 /// expression, found by taking this AST node index offset from the containing2042 /// expression, found by taking this AST node index offset from the containing
2030 /// Decl AST node, which points to an array access AST node. Next, navigate2043 /// Decl AST node, which points to an array access AST node. Next, navigate
...@@ -2150,6 +2163,10 @@ pub const LazySrcLoc = union(enum) {...@@ -2150,6 +2163,10 @@ pub const LazySrcLoc = union(enum) {
2150 .node_offset_for_cond,2163 .node_offset_for_cond,
2151 .node_offset_builtin_call_arg0,2164 .node_offset_builtin_call_arg0,
2152 .node_offset_builtin_call_arg1,2165 .node_offset_builtin_call_arg1,
2166 .node_offset_builtin_call_arg2,
2167 .node_offset_builtin_call_arg3,
2168 .node_offset_builtin_call_arg4,
2169 .node_offset_builtin_call_arg5,
2153 .node_offset_array_access_index,2170 .node_offset_array_access_index,
2154 .node_offset_slice_sentinel,2171 .node_offset_slice_sentinel,
2155 .node_offset_call_func,2172 .node_offset_call_func,
...@@ -2198,6 +2215,10 @@ pub const LazySrcLoc = union(enum) {...@@ -2198,6 +2215,10 @@ pub const LazySrcLoc = union(enum) {
2198 .node_offset_for_cond,2215 .node_offset_for_cond,
2199 .node_offset_builtin_call_arg0,2216 .node_offset_builtin_call_arg0,
2200 .node_offset_builtin_call_arg1,2217 .node_offset_builtin_call_arg1,
2218 .node_offset_builtin_call_arg2,
2219 .node_offset_builtin_call_arg3,
2220 .node_offset_builtin_call_arg4,
2221 .node_offset_builtin_call_arg5,
2201 .node_offset_array_access_index,2222 .node_offset_array_access_index,
2202 .node_offset_slice_sentinel,2223 .node_offset_slice_sentinel,
2203 .node_offset_call_func,2224 .node_offset_call_func,
...@@ -2239,6 +2260,9 @@ pub const CompileError = error{...@@ -2239,6 +2260,9 @@ pub const CompileError = error{
2239 /// because the function is generic. This is only seen when analyzing the body of a param2260 /// because the function is generic. This is only seen when analyzing the body of a param
2240 /// instruction.2261 /// instruction.
2241 GenericPoison,2262 GenericPoison,
2263 /// In a comptime scope, a return instruction was encountered. This error is only seen when
2264 /// doing a comptime function call.
2265 ComptimeReturn,
2242};2266};
22432267
2244pub fn deinit(mod: *Module) void {2268pub fn deinit(mod: *Module) void {
...@@ -3174,6 +3198,31 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3174,6 +3198,31 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3174 errdefer decl_arena.deinit();3198 errdefer decl_arena.deinit();
3175 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);3199 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
31763200
3201 if (decl.is_usingnamespace) {
3202 const ty_ty = Type.initTag(.type);
3203 if (!decl_tv.ty.eql(ty_ty)) {
3204 return mod.fail(&block_scope.base, src, "expected type, found {}", .{decl_tv.ty});
3205 }
3206 var buffer: Value.ToTypeBuffer = undefined;
3207 const ty = decl_tv.val.toType(&buffer);
3208 if (ty.getNamespace() == null) {
3209 return mod.fail(&block_scope.base, src, "type {} has no namespace", .{ty});
3210 }
3211
3212 decl.ty = ty_ty;
3213 decl.val = try Value.Tag.ty.create(&decl_arena.allocator, ty);
3214 decl.align_val = Value.initTag(.null_value);
3215 decl.linksection_val = Value.initTag(.null_value);
3216 decl.has_tv = true;
3217 decl.owns_tv = false;
3218 decl_arena_state.* = decl_arena.state;
3219 decl.value_arena = decl_arena_state;
3220 decl.analysis = .complete;
3221 decl.generation = mod.generation;
3222
3223 return true;
3224 }
3225
3177 if (decl_tv.val.castTag(.function)) |fn_payload| {3226 if (decl_tv.val.castTag(.function)) |fn_payload| {
3178 const func = fn_payload.data;3227 const func = fn_payload.data;
3179 const owns_tv = func.owner_decl == decl;3228 const owns_tv = func.owner_decl == decl;
...@@ -3269,16 +3318,13 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3269,16 +3318,13 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3269 if (type_changed and mod.emit_h != null) {3318 if (type_changed and mod.emit_h != null) {
3270 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });3319 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });
3271 }3320 }
3272 } else if (decl_tv.ty.zigTypeTag() == .Type) {
3273 // In case this Decl is a struct or union, we need to resolve the fields
3274 // while we still have the `Sema` in scope, so that the field type expressions
3275 // can use the resolved AIR instructions that they possibly reference.
3276 // We do this after the decl is populated and set to `complete` so that a `Decl`
3277 // may reference itself.
3278 var buffer: Value.ToTypeBuffer = undefined;
3279 const ty = decl.val.toType(&buffer);
3280 try sema.resolveDeclFields(&block_scope, src, ty);
3281 }3321 }
3322 // In case this Decl is a struct or union, we need to resolve the fields
3323 // while we still have the `Sema` in scope, so that the field type expressions
3324 // can use the resolved AIR instructions that they possibly reference.
3325 // We do this after the decl is populated and set to `complete` so that a `Decl`
3326 // may reference itself.
3327 try sema.resolvePendingTypes(&block_scope);
32823328
3283 if (decl.is_exported) {3329 if (decl.is_exported) {
3284 const export_src = src; // TODO point to the export token3330 const export_src = src; // TODO point to the export token
...@@ -3494,7 +3540,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3494,7 +3540,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
34943540
3495 // zig fmt: off3541 // zig fmt: off
3496 const is_pub = (flags & 0b0001) != 0;3542 const is_pub = (flags & 0b0001) != 0;
3497 const is_exported = (flags & 0b0010) != 0;3543 const export_bit = (flags & 0b0010) != 0;
3498 const has_align = (flags & 0b0100) != 0;3544 const has_align = (flags & 0b0100) != 0;
3499 const has_linksection = (flags & 0b1000) != 0;3545 const has_linksection = (flags & 0b1000) != 0;
3500 // zig fmt: on3546 // zig fmt: on
...@@ -3509,7 +3555,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3509,7 +3555,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
3509 var is_named_test = false;3555 var is_named_test = false;
3510 const decl_name: [:0]const u8 = switch (decl_name_index) {3556 const decl_name: [:0]const u8 = switch (decl_name_index) {
3511 0 => name: {3557 0 => name: {
3512 if (is_exported) {3558 if (export_bit) {
3513 const i = iter.usingnamespace_index;3559 const i = iter.usingnamespace_index;
3514 iter.usingnamespace_index += 1;3560 iter.usingnamespace_index += 1;
3515 break :name try std.fmt.allocPrintZ(gpa, "usingnamespace_{d}", .{i});3561 break :name try std.fmt.allocPrintZ(gpa, "usingnamespace_{d}", .{i});
...@@ -3535,11 +3581,17 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3535,11 +3581,17 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
3535 }3581 }
3536 },3582 },
3537 };3583 };
3584 const is_exported = export_bit and decl_name_index != 0;
3585 const is_usingnamespace = export_bit and decl_name_index == 0;
3586 if (is_usingnamespace) try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);
35383587
3539 // We create a Decl for it regardless of analysis status.3588 // We create a Decl for it regardless of analysis status.
3540 const gop = try namespace.decls.getOrPut(gpa, decl_name);3589 const gop = try namespace.decls.getOrPut(gpa, decl_name);
3541 if (!gop.found_existing) {3590 if (!gop.found_existing) {
3542 const new_decl = try mod.allocateNewDecl(namespace, decl_node);3591 const new_decl = try mod.allocateNewDecl(namespace, decl_node);
3592 if (is_usingnamespace) {
3593 namespace.usingnamespace_set.putAssumeCapacity(new_decl, is_pub);
3594 }
3543 log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });3595 log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });
3544 new_decl.src_line = line;3596 new_decl.src_line = line;
3545 new_decl.name = decl_name;3597 new_decl.name = decl_name;
...@@ -3548,7 +3600,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3548,7 +3600,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
3548 // test decls if in test mode, get analyzed.3600 // test decls if in test mode, get analyzed.
3549 const decl_pkg = namespace.file_scope.pkg;3601 const decl_pkg = namespace.file_scope.pkg;
3550 const want_analysis = is_exported or switch (decl_name_index) {3602 const want_analysis = is_exported or switch (decl_name_index) {
3551 0 => true, // comptime decl3603 0 => true, // comptime or usingnamespace decl
3552 1 => blk: {3604 1 => blk: {
3553 // test decl with no name. Skip the part where we check against3605 // test decl with no name. Skip the part where we check against
3554 // the test name filter.3606 // the test name filter.
...@@ -3571,6 +3623,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3571,6 +3623,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
3571 }3623 }
3572 new_decl.is_pub = is_pub;3624 new_decl.is_pub = is_pub;
3573 new_decl.is_exported = is_exported;3625 new_decl.is_exported = is_exported;
3626 new_decl.is_usingnamespace = is_usingnamespace;
3574 new_decl.has_align = has_align;3627 new_decl.has_align = has_align;
3575 new_decl.has_linksection = has_linksection;3628 new_decl.has_linksection = has_linksection;
3576 new_decl.zir_decl_index = @intCast(u32, decl_sub_index);3629 new_decl.zir_decl_index = @intCast(u32, decl_sub_index);
...@@ -3587,6 +3640,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3587,6 +3640,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
35873640
3588 decl.is_pub = is_pub;3641 decl.is_pub = is_pub;
3589 decl.is_exported = is_exported;3642 decl.is_exported = is_exported;
3643 decl.is_usingnamespace = is_usingnamespace;
3590 decl.has_align = has_align;3644 decl.has_align = has_align;
3591 decl.has_linksection = has_linksection;3645 decl.has_linksection = has_linksection;
3592 decl.zir_decl_index = @intCast(u32, decl_sub_index);3646 decl.zir_decl_index = @intCast(u32, decl_sub_index);
...@@ -3891,8 +3945,10 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) SemaError!Air {...@@ -3891,8 +3945,10 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) SemaError!Air {
3891 log.debug("set {s} to in_progress", .{decl.name});3945 log.debug("set {s} to in_progress", .{decl.name});
38923946
3893 _ = sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {3947 _ = sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
3948 // TODO make these unreachable instead of @panic
3894 error.NeededSourceLocation => @panic("zig compiler bug: NeededSourceLocation"),3949 error.NeededSourceLocation => @panic("zig compiler bug: NeededSourceLocation"),
3895 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),3950 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
3951 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
3896 else => |e| return e,3952 else => |e| return e,
3897 };3953 };
38983954
...@@ -3930,7 +3986,7 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {...@@ -3930,7 +3986,7 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {
3930 decl.analysis = .outdated;3986 decl.analysis = .outdated;
3931}3987}
39323988
3933pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.Node.Index) !*Decl {3989pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast.Node.Index) !*Decl {
3934 // If we have emit-h then we must allocate a bigger structure to store the emit-h state.3990 // If we have emit-h then we must allocate a bigger structure to store the emit-h state.
3935 const new_decl: *Decl = if (mod.emit_h != null) blk: {3991 const new_decl: *Decl = if (mod.emit_h != null) blk: {
3936 const parent_struct = try mod.gpa.create(DeclPlusEmitH);3992 const parent_struct = try mod.gpa.create(DeclPlusEmitH);
...@@ -3979,6 +4035,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast....@@ -3979,6 +4035,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.
3979 .has_linksection = false,4035 .has_linksection = false,
3980 .has_align = false,4036 .has_align = false,
3981 .alive = false,4037 .alive = false,
4038 .is_usingnamespace = false,
3982 };4039 };
3983 return new_decl;4040 return new_decl;
3984}4041}
...@@ -4199,7 +4256,7 @@ pub fn fail(...@@ -4199,7 +4256,7 @@ pub fn fail(
4199pub fn failTok(4256pub fn failTok(
4200 mod: *Module,4257 mod: *Module,
4201 scope: *Scope,4258 scope: *Scope,
4202 token_index: ast.TokenIndex,4259 token_index: Ast.TokenIndex,
4203 comptime format: []const u8,4260 comptime format: []const u8,
4204 args: anytype,4261 args: anytype,
4205) CompileError {4262) CompileError {
...@@ -4212,7 +4269,7 @@ pub fn failTok(...@@ -4212,7 +4269,7 @@ pub fn failTok(
4212pub fn failNode(4269pub fn failNode(
4213 mod: *Module,4270 mod: *Module,
4214 scope: *Scope,4271 scope: *Scope,
4215 node_index: ast.Node.Index,4272 node_index: Ast.Node.Index,
4216 comptime format: []const u8,4273 comptime format: []const u8,
4217 args: anytype,4274 args: anytype,
4218) CompileError {4275) CompileError {
...@@ -4417,7 +4474,7 @@ pub const SwitchProngSrc = union(enum) {...@@ -4417,7 +4474,7 @@ pub const SwitchProngSrc = union(enum) {
4417 const main_tokens = tree.nodes.items(.main_token);4474 const main_tokens = tree.nodes.items(.main_token);
4418 const node_datas = tree.nodes.items(.data);4475 const node_datas = tree.nodes.items(.data);
4419 const node_tags = tree.nodes.items(.tag);4476 const node_tags = tree.nodes.items(.tag);
4420 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);4477 const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
4421 const case_nodes = tree.extra_data[extra.start..extra.end];4478 const case_nodes = tree.extra_data[extra.start..extra.end];
44224479
4423 var multi_i: u32 = 0;4480 var multi_i: u32 = 0;
...@@ -4496,7 +4553,6 @@ pub const PeerTypeCandidateSrc = union(enum) {...@@ -4496,7 +4553,6 @@ pub const PeerTypeCandidateSrc = union(enum) {
4496 self: PeerTypeCandidateSrc,4553 self: PeerTypeCandidateSrc,
4497 gpa: *Allocator,4554 gpa: *Allocator,
4498 decl: *Decl,4555 decl: *Decl,
4499 candidates: usize,
4500 candidate_i: usize,4556 candidate_i: usize,
4501 ) ?LazySrcLoc {4557 ) ?LazySrcLoc {
4502 @setCold(true);4558 @setCold(true);
...@@ -4509,12 +4565,14 @@ pub const PeerTypeCandidateSrc = union(enum) {...@@ -4509,12 +4565,14 @@ pub const PeerTypeCandidateSrc = union(enum) {
4509 return candidate_srcs[candidate_i];4565 return candidate_srcs[candidate_i];
4510 },4566 },
4511 .typeof_builtin_call_node_offset => |node_offset| {4567 .typeof_builtin_call_node_offset => |node_offset| {
4512 if (candidates <= 2) {4568 switch (candidate_i) {
4513 switch (candidate_i) {4569 0 => return LazySrcLoc{ .node_offset_builtin_call_arg0 = node_offset },
4514 0 => return LazySrcLoc{ .node_offset_builtin_call_arg0 = node_offset },4570 1 => return LazySrcLoc{ .node_offset_builtin_call_arg1 = node_offset },
4515 1 => return LazySrcLoc{ .node_offset_builtin_call_arg1 = node_offset },4571 2 => return LazySrcLoc{ .node_offset_builtin_call_arg2 = node_offset },
4516 else => unreachable,4572 3 => return LazySrcLoc{ .node_offset_builtin_call_arg3 = node_offset },
4517 }4573 4 => return LazySrcLoc{ .node_offset_builtin_call_arg4 = node_offset },
4574 5 => return LazySrcLoc{ .node_offset_builtin_call_arg5 = node_offset },
4575 else => {},
4518 }4576 }
45194577
4520 const tree = decl.namespace.file_scope.getTree(gpa) catch |err| {4578 const tree = decl.namespace.file_scope.getTree(gpa) catch |err| {
src/Sema.zig+492-63
...@@ -58,6 +58,9 @@ comptime_args_fn_inst: Zir.Inst.Index = 0,...@@ -58,6 +58,9 @@ comptime_args_fn_inst: Zir.Inst.Index = 0,
58/// extra hash table lookup in the `monomorphed_funcs` set.58/// extra hash table lookup in the `monomorphed_funcs` set.
59/// Sema will set this to null when it takes ownership.59/// Sema will set this to null when it takes ownership.
60preallocated_new_func: ?*Module.Fn = null,60preallocated_new_func: ?*Module.Fn = null,
61/// Collects struct, union, enum, and opaque decls which need to have their
62/// fields resolved before this Sema is deinitialized.
63types_pending_resolution: std.ArrayListUnmanaged(Type) = .{},
6164
62const std = @import("std");65const std = @import("std");
63const mem = std.mem;66const mem = std.mem;
...@@ -90,6 +93,7 @@ pub fn deinit(sema: *Sema) void {...@@ -90,6 +93,7 @@ pub fn deinit(sema: *Sema) void {
90 sema.air_values.deinit(gpa);93 sema.air_values.deinit(gpa);
91 sema.inst_map.deinit(gpa);94 sema.inst_map.deinit(gpa);
92 sema.decl_val_table.deinit(gpa);95 sema.decl_val_table.deinit(gpa);
96 sema.types_pending_resolution.deinit(gpa);
93 sema.* = undefined;97 sema.* = undefined;
94}98}
9599
...@@ -155,7 +159,6 @@ pub fn analyzeBody(...@@ -155,7 +159,6 @@ pub fn analyzeBody(
155 .bit_or => try sema.zirBitwise(block, inst, .bit_or),159 .bit_or => try sema.zirBitwise(block, inst, .bit_or),
156 .bitcast => try sema.zirBitcast(block, inst),160 .bitcast => try sema.zirBitcast(block, inst),
157 .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst),161 .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst),
158 .block => try sema.zirBlock(block, inst),
159 .suspend_block => try sema.zirSuspendBlock(block, inst),162 .suspend_block => try sema.zirSuspendBlock(block, inst),
160 .bool_not => try sema.zirBoolNot(block, inst),163 .bool_not => try sema.zirBoolNot(block, inst),
161 .bool_br_and => try sema.zirBoolBr(block, inst, false),164 .bool_br_and => try sema.zirBoolBr(block, inst, false),
...@@ -211,7 +214,6 @@ pub fn analyzeBody(...@@ -211,7 +214,6 @@ pub fn analyzeBody(
211 .is_non_err_ptr => try sema.zirIsNonErrPtr(block, inst),214 .is_non_err_ptr => try sema.zirIsNonErrPtr(block, inst),
212 .is_non_null => try sema.zirIsNonNull(block, inst),215 .is_non_null => try sema.zirIsNonNull(block, inst),
213 .is_non_null_ptr => try sema.zirIsNonNullPtr(block, inst),216 .is_non_null_ptr => try sema.zirIsNonNullPtr(block, inst),
214 .loop => try sema.zirLoop(block, inst),
215 .merge_error_sets => try sema.zirMergeErrorSets(block, inst),217 .merge_error_sets => try sema.zirMergeErrorSets(block, inst),
216 .negate => try sema.zirNegate(block, inst, .sub),218 .negate => try sema.zirNegate(block, inst, .sub),
217 .negate_wrap => try sema.zirNegate(block, inst, .subwrap),219 .negate_wrap => try sema.zirNegate(block, inst, .subwrap),
...@@ -304,8 +306,8 @@ pub fn analyzeBody(...@@ -304,8 +306,8 @@ pub fn analyzeBody(
304 .shr_exact => try sema.zirShrExact(block, inst),306 .shr_exact => try sema.zirShrExact(block, inst),
305 .bit_offset_of => try sema.zirBitOffsetOf(block, inst),307 .bit_offset_of => try sema.zirBitOffsetOf(block, inst),
306 .offset_of => try sema.zirOffsetOf(block, inst),308 .offset_of => try sema.zirOffsetOf(block, inst),
307 .cmpxchg_strong => try sema.zirCmpxchg(block, inst),309 .cmpxchg_strong => try sema.zirCmpxchg(block, inst, .cmpxchg_strong),
308 .cmpxchg_weak => try sema.zirCmpxchg(block, inst),310 .cmpxchg_weak => try sema.zirCmpxchg(block, inst, .cmpxchg_weak),
309 .splat => try sema.zirSplat(block, inst),311 .splat => try sema.zirSplat(block, inst),
310 .reduce => try sema.zirReduce(block, inst),312 .reduce => try sema.zirReduce(block, inst),
311 .shuffle => try sema.zirShuffle(block, inst),313 .shuffle => try sema.zirShuffle(block, inst),
...@@ -360,16 +362,12 @@ pub fn analyzeBody(...@@ -360,16 +362,12 @@ pub fn analyzeBody(
360 // Instructions that we know to *always* be noreturn based solely on their tag.362 // Instructions that we know to *always* be noreturn based solely on their tag.
361 // These functions match the return type of analyzeBody so that we can363 // These functions match the return type of analyzeBody so that we can
362 // tail call them here.364 // tail call them here.
363 .break_inline => return inst,
364 .condbr => return sema.zirCondbr(block, inst),
365 .@"break" => return sema.zirBreak(block, inst),
366 .compile_error => return sema.zirCompileError(block, inst),365 .compile_error => return sema.zirCompileError(block, inst),
367 .ret_coerce => return sema.zirRetCoerce(block, inst),366 .ret_coerce => return sema.zirRetCoerce(block, inst),
368 .ret_node => return sema.zirRetNode(block, inst),367 .ret_node => return sema.zirRetNode(block, inst),
369 .ret_load => return sema.zirRetLoad(block, inst),368 .ret_load => return sema.zirRetLoad(block, inst),
370 .ret_err_value => return sema.zirRetErrValue(block, inst),369 .ret_err_value => return sema.zirRetErrValue(block, inst),
371 .@"unreachable" => return sema.zirUnreachable(block, inst),370 .@"unreachable" => return sema.zirUnreachable(block, inst),
372 .repeat => return sema.zirRepeat(block, inst),
373 .panic => return sema.zirPanic(block, inst),371 .panic => return sema.zirPanic(block, inst),
374 // zig fmt: on372 // zig fmt: on
375373
...@@ -495,6 +493,28 @@ pub fn analyzeBody(...@@ -495,6 +493,28 @@ pub fn analyzeBody(
495 },493 },
496494
497 // Special case instructions to handle comptime control flow.495 // Special case instructions to handle comptime control flow.
496 .@"break" => {
497 if (block.is_comptime) {
498 return inst; // same as break_inline
499 } else {
500 return sema.zirBreak(block, inst);
501 }
502 },
503 .break_inline => return inst,
504 .repeat => {
505 if (block.is_comptime) {
506 // Send comptime control flow back to the beginning of this block.
507 const src: LazySrcLoc = .{ .node_offset = datas[inst].node };
508 try sema.emitBackwardBranch(block, src);
509 i = 0;
510 continue;
511 } else {
512 const src_node = sema.code.instructions.items(.data)[inst].node;
513 const src: LazySrcLoc = .{ .node_offset = src_node };
514 try sema.requireRuntimeBlock(block, src);
515 return always_noreturn;
516 }
517 },
498 .repeat_inline => {518 .repeat_inline => {
499 // Send comptime control flow back to the beginning of this block.519 // Send comptime control flow back to the beginning of this block.
500 const src: LazySrcLoc = .{ .node_offset = datas[inst].node };520 const src: LazySrcLoc = .{ .node_offset = datas[inst].node };
...@@ -502,6 +522,34 @@ pub fn analyzeBody(...@@ -502,6 +522,34 @@ pub fn analyzeBody(
502 i = 0;522 i = 0;
503 continue;523 continue;
504 },524 },
525 .loop => blk: {
526 if (!block.is_comptime) break :blk try sema.zirLoop(block, inst);
527 // Same as `block_inline`. TODO https://github.com/ziglang/zig/issues/8220
528 const inst_data = datas[inst].pl_node;
529 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
530 const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];
531 const break_inst = try sema.analyzeBody(block, inline_body);
532 const break_data = datas[break_inst].@"break";
533 if (inst == break_data.block_inst) {
534 break :blk sema.resolveInst(break_data.operand);
535 } else {
536 return break_inst;
537 }
538 },
539 .block => blk: {
540 if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
541 // Same as `block_inline`. TODO https://github.com/ziglang/zig/issues/8220
542 const inst_data = datas[inst].pl_node;
543 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
544 const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];
545 const break_inst = try sema.analyzeBody(block, inline_body);
546 const break_data = datas[break_inst].@"break";
547 if (inst == break_data.block_inst) {
548 break :blk sema.resolveInst(break_data.operand);
549 } else {
550 return break_inst;
551 }
552 },
505 .block_inline => blk: {553 .block_inline => blk: {
506 // Directly analyze the block body without introducing a new block.554 // Directly analyze the block body without introducing a new block.
507 const inst_data = datas[inst].pl_node;555 const inst_data = datas[inst].pl_node;
...@@ -515,6 +563,24 @@ pub fn analyzeBody(...@@ -515,6 +563,24 @@ pub fn analyzeBody(
515 return break_inst;563 return break_inst;
516 }564 }
517 },565 },
566 .condbr => blk: {
567 if (!block.is_comptime) return sema.zirCondbr(block, inst);
568 // Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/8220
569 const inst_data = datas[inst].pl_node;
570 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
571 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
572 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];
573 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
574 const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition);
575 const inline_body = if (cond.val.toBool()) then_body else else_body;
576 const break_inst = try sema.analyzeBody(block, inline_body);
577 const break_data = datas[break_inst].@"break";
578 if (inst == break_data.block_inst) {
579 break :blk sema.resolveInst(break_data.operand);
580 } else {
581 return break_inst;
582 }
583 },
518 .condbr_inline => blk: {584 .condbr_inline => blk: {
519 const inst_data = datas[inst].pl_node;585 const inst_data = datas[inst].pl_node;
520 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };586 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
...@@ -570,6 +636,10 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr...@@ -570,6 +636,10 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
570 .c_define => return sema.zirCDefine( block, extended),636 .c_define => return sema.zirCDefine( block, extended),
571 .wasm_memory_size => return sema.zirWasmMemorySize( block, extended),637 .wasm_memory_size => return sema.zirWasmMemorySize( block, extended),
572 .wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended),638 .wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended),
639 .add_with_saturation=> return sema.zirSatArithmetic( block, extended),
640 .sub_with_saturation=> return sema.zirSatArithmetic( block, extended),
641 .mul_with_saturation=> return sema.zirSatArithmetic( block, extended),
642 .shl_with_saturation=> return sema.zirSatArithmetic( block, extended),
573 // zig fmt: on643 // zig fmt: on
574 }644 }
575}645}
...@@ -904,7 +974,9 @@ fn zirStructDecl(...@@ -904,7 +974,9 @@ fn zirStructDecl(
904 &struct_obj.namespace, new_decl, new_decl.name,974 &struct_obj.namespace, new_decl, new_decl.name,
905 });975 });
906 try sema.analyzeStructDecl(new_decl, inst, struct_obj);976 try sema.analyzeStructDecl(new_decl, inst, struct_obj);
977 try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1);
907 try new_decl.finalizeNewArena(&new_decl_arena);978 try new_decl.finalizeNewArena(&new_decl_arena);
979 sema.types_pending_resolution.appendAssumeCapacity(struct_ty);
908 return sema.analyzeDeclVal(block, src, new_decl);980 return sema.analyzeDeclVal(block, src, new_decl);
909}981}
910982
...@@ -1194,7 +1266,9 @@ fn zirUnionDecl(...@@ -1194,7 +1266,9 @@ fn zirUnionDecl(
11941266
1195 _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl);1267 _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl);
11961268
1269 try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1);
1197 try new_decl.finalizeNewArena(&new_decl_arena);1270 try new_decl.finalizeNewArena(&new_decl_arena);
1271 sema.types_pending_resolution.appendAssumeCapacity(union_ty);
1198 return sema.analyzeDeclVal(block, src, new_decl);1272 return sema.analyzeDeclVal(block, src, new_decl);
1199}1273}
12001274
...@@ -1921,16 +1995,6 @@ fn zirCompileLog(...@@ -1921,16 +1995,6 @@ fn zirCompileLog(
1921 return Air.Inst.Ref.void_value;1995 return Air.Inst.Ref.void_value;
1922}1996}
19231997
1924fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
1925 const tracy = trace(@src());
1926 defer tracy.end();
1927
1928 const src_node = sema.code.instructions.items(.data)[inst].node;
1929 const src: LazySrcLoc = .{ .node_offset = src_node };
1930 try sema.requireRuntimeBlock(block, src);
1931 return always_noreturn;
1932}
1933
1934fn zirPanic(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {1998fn zirPanic(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
1935 const inst_data = sema.code.instructions.items(.data)[inst].un_node;1999 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1936 const src: LazySrcLoc = inst_data.src();2000 const src: LazySrcLoc = inst_data.src();
...@@ -1991,7 +2055,6 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil...@@ -1991,7 +2055,6 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil
19912055
1992 _ = try sema.analyzeBody(&loop_block, body);2056 _ = try sema.analyzeBody(&loop_block, body);
19932057
1994 // Loop repetition is implied so the last instruction may or may not be a noreturn instruction.
1995 try child_block.instructions.append(gpa, loop_inst);2058 try child_block.instructions.append(gpa, loop_inst);
19962059
1997 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +2060 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
...@@ -2320,42 +2383,105 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr...@@ -2320,42 +2383,105 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
2320}2383}
23212384
2322fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl {2385fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl {
2323 // TODO emit a compile error if more than one decl would be matched.
2324 var namespace = sema.namespace;2386 var namespace = sema.namespace;
2325 while (true) {2387 while (true) {
2326 if (try sema.lookupInNamespace(namespace, name)) |decl| {2388 if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl| {
2327 return decl;2389 return decl;
2328 }2390 }
2329 namespace = namespace.parent orelse break;2391 namespace = namespace.parent orelse break;
2330 }2392 }
2331 return sema.mod.fail(&block.base, src, "use of undeclared identifier '{s}'", .{name});2393 unreachable; // AstGen detects use of undeclared identifier errors.
2332}2394}
23332395
2334/// This looks up a member of a specific namespace. It is affected by `usingnamespace` but2396/// This looks up a member of a specific namespace. It is affected by `usingnamespace` but
2335/// only for ones in the specified namespace.2397/// only for ones in the specified namespace.
2336fn lookupInNamespace(2398fn lookupInNamespace(
2337 sema: *Sema,2399 sema: *Sema,
2400 block: *Scope.Block,
2401 src: LazySrcLoc,
2338 namespace: *Scope.Namespace,2402 namespace: *Scope.Namespace,
2339 ident_name: []const u8,2403 ident_name: []const u8,
2404 observe_usingnamespace: bool,
2340) CompileError!?*Decl {2405) CompileError!?*Decl {
2406 const mod = sema.mod;
2407
2341 const namespace_decl = namespace.getDecl();2408 const namespace_decl = namespace.getDecl();
2342 if (namespace_decl.analysis == .file_failure) {2409 if (namespace_decl.analysis == .file_failure) {
2343 try sema.mod.declareDeclDependency(sema.owner_decl, namespace_decl);2410 try mod.declareDeclDependency(sema.owner_decl, namespace_decl);
2344 return error.AnalysisFail;2411 return error.AnalysisFail;
2345 }2412 }
23462413
2347 // TODO implement usingnamespace2414 if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) {
2348 if (namespace.decls.get(ident_name)) |decl| {2415 const src_file = block.src_decl.namespace.file_scope;
2349 try sema.mod.declareDeclDependency(sema.owner_decl, decl);2416
2417 const gpa = sema.gpa;
2418 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Scope.Namespace, void) = .{};
2419 defer checked_namespaces.deinit(gpa);
2420
2421 // Keep track of name conflicts for error notes.
2422 var candidates: std.ArrayListUnmanaged(*Decl) = .{};
2423 defer candidates.deinit(gpa);
2424
2425 try checked_namespaces.put(gpa, namespace, {});
2426 var check_i: usize = 0;
2427
2428 while (check_i < checked_namespaces.count()) : (check_i += 1) {
2429 const check_ns = checked_namespaces.keys()[check_i];
2430 if (check_ns.decls.get(ident_name)) |decl| {
2431 // Skip decls which are not marked pub, which are in a different
2432 // file than the `a.b`/`@hasDecl` syntax.
2433 if (decl.is_pub or src_file == decl.namespace.file_scope) {
2434 try candidates.append(gpa, decl);
2435 }
2436 }
2437 var it = check_ns.usingnamespace_set.iterator();
2438 while (it.next()) |entry| {
2439 const sub_usingnamespace_decl = entry.key_ptr.*;
2440 const sub_is_pub = entry.value_ptr.*;
2441 if (!sub_is_pub and src_file != sub_usingnamespace_decl.namespace.file_scope) {
2442 // Skip usingnamespace decls which are not marked pub, which are in
2443 // a different file than the `a.b`/`@hasDecl` syntax.
2444 continue;
2445 }
2446 try sema.ensureDeclAnalyzed(sub_usingnamespace_decl);
2447 const ns_ty = sub_usingnamespace_decl.val.castTag(.ty).?.data;
2448 const sub_ns = ns_ty.getNamespace().?;
2449 try checked_namespaces.put(gpa, sub_ns, {});
2450 }
2451 }
2452
2453 switch (candidates.items.len) {
2454 0 => {},
2455 1 => {
2456 const decl = candidates.items[0];
2457 try mod.declareDeclDependency(sema.owner_decl, decl);
2458 return decl;
2459 },
2460 else => {
2461 const msg = msg: {
2462 const msg = try mod.errMsg(&block.base, src, "ambiguous reference", .{});
2463 errdefer msg.destroy(gpa);
2464 for (candidates.items) |candidate| {
2465 const src_loc = candidate.srcLoc();
2466 try mod.errNoteNonLazy(src_loc, msg, "declared here", .{});
2467 }
2468 break :msg msg;
2469 };
2470 return mod.failWithOwnedErrorMsg(&block.base, msg);
2471 },
2472 }
2473 } else if (namespace.decls.get(ident_name)) |decl| {
2474 try mod.declareDeclDependency(sema.owner_decl, decl);
2350 return decl;2475 return decl;
2351 }2476 }
2477
2352 log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{2478 log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{
2353 sema.owner_decl, sema.owner_decl.name, ident_name, namespace_decl, namespace_decl.name,2479 sema.owner_decl, sema.owner_decl.name, ident_name, namespace_decl, namespace_decl.name,
2354 });2480 });
2355 // TODO This dependency is too strong. Really, it should only be a dependency2481 // TODO This dependency is too strong. Really, it should only be a dependency
2356 // on the non-existence of `ident_name` in the namespace. We can lessen the number of2482 // on the non-existence of `ident_name` in the namespace. We can lessen the number of
2357 // outdated declarations by making this dependency more sophisticated.2483 // outdated declarations by making this dependency more sophisticated.
2358 try sema.mod.declareDeclDependency(sema.owner_decl, namespace_decl);2484 try mod.declareDeclDependency(sema.owner_decl, namespace_decl);
2359 return null;2485 return null;
2360}2486}
23612487
...@@ -2540,6 +2666,7 @@ fn analyzeCall(...@@ -2540,6 +2666,7 @@ fn analyzeCall(
2540 // This one is shared among sub-blocks within the same callee, but not2666 // This one is shared among sub-blocks within the same callee, but not
2541 // shared among the entire inline/comptime call stack.2667 // shared among the entire inline/comptime call stack.
2542 var inlining: Scope.Block.Inlining = .{2668 var inlining: Scope.Block.Inlining = .{
2669 .comptime_result = undefined,
2543 .merges = .{2670 .merges = .{
2544 .results = .{},2671 .results = .{},
2545 .br_list = .{},2672 .br_list = .{},
...@@ -2695,8 +2822,13 @@ fn analyzeCall(...@@ -2695,8 +2822,13 @@ fn analyzeCall(
2695 }2822 }
2696 }2823 }
26972824
2698 _ = try sema.analyzeBody(&child_block, fn_info.body);2825 const result = result: {
2699 const result = try sema.analyzeBlockBody(block, call_src, &child_block, merges);2826 _ = sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
2827 error.ComptimeReturn => break :result inlining.comptime_result,
2828 else => |e| return e,
2829 };
2830 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
2831 };
27002832
2701 if (is_comptime_call) {2833 if (is_comptime_call) {
2702 const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);2834 const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);
...@@ -2723,10 +2855,7 @@ fn analyzeCall(...@@ -2723,10 +2855,7 @@ fn analyzeCall(
2723 // we need to resolve the field type expressions right here, right now, while2855 // we need to resolve the field type expressions right here, right now, while
2724 // the child `Sema` is still available, with the AIR instruction map intact,2856 // the child `Sema` is still available, with the AIR instruction map intact,
2725 // because the field type expressions may reference into it.2857 // because the field type expressions may reference into it.
2726 if (sema.typeOf(result).zigTypeTag() == .Type) {2858 try sema.resolvePendingTypes(&child_block);
2727 const ty = try sema.analyzeAsType(&child_block, call_src, result);
2728 try sema.resolveDeclFields(&child_block, call_src, ty);
2729 }
2730 }2859 }
27312860
2732 break :res2 result;2861 break :res2 result;
...@@ -5328,6 +5457,7 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr...@@ -5328,6 +5457,7 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
5328fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5457fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5329 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;5458 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5330 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;5459 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
5460 const src = inst_data.src();
5331 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5461 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5332 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };5462 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
5333 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);5463 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
...@@ -5340,7 +5470,7 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr...@@ -5340,7 +5470,7 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
5340 "expected struct, enum, union, or opaque, found '{}'",5470 "expected struct, enum, union, or opaque, found '{}'",
5341 .{container_type},5471 .{container_type},
5342 );5472 );
5343 if (try sema.lookupInNamespace(namespace, decl_name)) |decl| {5473 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| {
5344 if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) {5474 if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) {
5345 return Air.Inst.Ref.bool_true;5475 return Air.Inst.Ref.bool_true;
5346 }5476 }
...@@ -5512,16 +5642,134 @@ fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr...@@ -5512,16 +5642,134 @@ fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
5512 const tracy = trace(@src());5642 const tracy = trace(@src());
5513 defer tracy.end();5643 defer tracy.end();
55145644
5515 _ = inst;5645 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5516 return sema.mod.fail(&block.base, sema.src, "TODO implement zirArrayCat", .{});5646 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
5647 const lhs = sema.resolveInst(extra.lhs);
5648 const rhs = sema.resolveInst(extra.rhs);
5649 const lhs_ty = sema.typeOf(lhs);
5650 const rhs_ty = sema.typeOf(rhs);
5651 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
5652 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
5653
5654 const lhs_info = getArrayCatInfo(lhs_ty) orelse
5655 return sema.mod.fail(&block.base, lhs_src, "expected array, found '{}'", .{lhs_ty});
5656 const rhs_info = getArrayCatInfo(rhs_ty) orelse
5657 return sema.mod.fail(&block.base, rhs_src, "expected array, found '{}'", .{rhs_ty});
5658 if (!lhs_info.elem_type.eql(rhs_info.elem_type)) {
5659 return sema.mod.fail(&block.base, rhs_src, "expected array of type '{}', found '{}'", .{ lhs_info.elem_type, rhs_ty });
5660 }
5661
5662 // When there is a sentinel mismatch, no sentinel on the result. The type system
5663 // will catch this if it is a problem.
5664 var res_sent: ?Value = null;
5665 if (rhs_info.sentinel != null and lhs_info.sentinel != null) {
5666 if (rhs_info.sentinel.?.eql(lhs_info.sentinel.?, lhs_info.elem_type)) {
5667 res_sent = lhs_info.sentinel.?;
5668 }
5669 }
5670
5671 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
5672 if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| {
5673 const final_len = lhs_info.len + rhs_info.len;
5674 if (lhs_ty.zigTypeTag() == .Pointer) {
5675 var anon_decl = try block.startAnonDecl();
5676 defer anon_decl.deinit();
5677
5678 const lhs_sub_val = (try lhs_val.pointerDeref(anon_decl.arena())).?;
5679 const rhs_sub_val = (try rhs_val.pointerDeref(anon_decl.arena())).?;
5680 const buf = try anon_decl.arena().alloc(Value, final_len);
5681 {
5682 var i: u64 = 0;
5683 while (i < lhs_info.len) : (i += 1) {
5684 const val = try lhs_sub_val.elemValue(sema.arena, i);
5685 buf[i] = try val.copy(anon_decl.arena());
5686 }
5687 }
5688 {
5689 var i: u64 = 0;
5690 while (i < rhs_info.len) : (i += 1) {
5691 const val = try rhs_sub_val.elemValue(sema.arena, i);
5692 buf[lhs_info.len + i] = try val.copy(anon_decl.arena());
5693 }
5694 }
5695 const ty = if (res_sent) |rs|
5696 try Type.Tag.array_sentinel.create(anon_decl.arena(), .{ .len = final_len, .elem_type = lhs_info.elem_type, .sentinel = rs })
5697 else
5698 try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = lhs_info.elem_type });
5699 const val = try Value.Tag.array.create(anon_decl.arena(), buf);
5700 return sema.analyzeDeclRef(try anon_decl.finish(
5701 ty,
5702 val,
5703 ));
5704 }
5705 return sema.mod.fail(&block.base, lhs_src, "TODO array_cat more types of Values", .{});
5706 } else {
5707 return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_cat", .{});
5708 }
5709 } else {
5710 return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_cat", .{});
5711 }
5712}
5713
5714fn getArrayCatInfo(t: Type) ?Type.ArrayInfo {
5715 return switch (t.zigTypeTag()) {
5716 .Array => t.arrayInfo(),
5717 .Pointer => blk: {
5718 const ptrinfo = t.ptrInfo().data;
5719 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;
5720 if (ptrinfo.size != .One) return null;
5721 break :blk ptrinfo.pointee_type.arrayInfo();
5722 },
5723 else => null,
5724 };
5517}5725}
55185726
5519fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5727fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5520 const tracy = trace(@src());5728 const tracy = trace(@src());
5521 defer tracy.end();5729 defer tracy.end();
55225730
5523 _ = inst;5731 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5524 return sema.mod.fail(&block.base, sema.src, "TODO implement zirArrayMul", .{});5732 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
5733 const lhs = sema.resolveInst(extra.lhs);
5734 const lhs_ty = sema.typeOf(lhs);
5735 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
5736 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
5737
5738 // In `**` rhs has to be comptime-known, but lhs can be runtime-known
5739 const tomulby = try sema.resolveInt(block, rhs_src, extra.rhs, Type.initTag(.usize));
5740 const mulinfo = getArrayCatInfo(lhs_ty) orelse
5741 return sema.mod.fail(&block.base, lhs_src, "expected array, found '{}'", .{lhs_ty});
5742
5743 const final_len = std.math.mul(u64, mulinfo.len, tomulby) catch return sema.mod.fail(&block.base, rhs_src, "operation results in overflow", .{});
5744 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
5745 if (lhs_ty.zigTypeTag() == .Pointer) {
5746 var anon_decl = try block.startAnonDecl();
5747 defer anon_decl.deinit();
5748 const lhs_sub_val = (try lhs_val.pointerDeref(anon_decl.arena())).?;
5749
5750 const final_ty = if (mulinfo.sentinel) |sent|
5751 try Type.Tag.array_sentinel.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type, .sentinel = sent })
5752 else
5753 try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type });
5754
5755 const buf = try anon_decl.arena().alloc(Value, final_len);
5756 var i: u64 = 0;
5757 while (i < tomulby) : (i += 1) {
5758 var j: u64 = 0;
5759 while (j < mulinfo.len) : (j += 1) {
5760 const val = try lhs_sub_val.elemValue(sema.arena, j);
5761 buf[mulinfo.len * i + j] = try val.copy(anon_decl.arena());
5762 }
5763 }
5764 const val = try Value.Tag.array.create(anon_decl.arena(), buf);
5765 return sema.analyzeDeclRef(try anon_decl.finish(
5766 final_ty,
5767 val,
5768 ));
5769 }
5770 return sema.mod.fail(&block.base, lhs_src, "TODO array_mul more types of Values", .{});
5771 }
5772 return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_mul", .{});
5525}5773}
55265774
5527fn zirNegate(5775fn zirNegate(
...@@ -5573,6 +5821,19 @@ fn zirOverflowArithmetic(...@@ -5573,6 +5821,19 @@ fn zirOverflowArithmetic(
5573 return sema.mod.fail(&block.base, src, "TODO implement Sema.zirOverflowArithmetic", .{});5821 return sema.mod.fail(&block.base, src, "TODO implement Sema.zirOverflowArithmetic", .{});
5574}5822}
55755823
5824fn zirSatArithmetic(
5825 sema: *Sema,
5826 block: *Scope.Block,
5827 extended: Zir.Inst.Extended.InstData,
5828) CompileError!Air.Inst.Ref {
5829 const tracy = trace(@src());
5830 defer tracy.end();
5831
5832 const extra = sema.code.extraData(Zir.Inst.SaturatingArithmetic, extended.operand).data;
5833 const src: LazySrcLoc = .{ .node_offset = extra.node };
5834 return sema.mod.fail(&block.base, src, "TODO implement Sema.zirSatArithmetic", .{});
5835}
5836
5576fn analyzeArithmetic(5837fn analyzeArithmetic(
5577 sema: *Sema,5838 sema: *Sema,
5578 block: *Scope.Block,5839 block: *Scope.Block,
...@@ -5701,7 +5962,7 @@ fn analyzeArithmetic(...@@ -5701,7 +5962,7 @@ fn analyzeArithmetic(
5701 try lhs_val.floatMul(rhs_val, scalar_type, sema.arena);5962 try lhs_val.floatMul(rhs_val, scalar_type, sema.arena);
5702 break :blk val;5963 break :blk val;
5703 },5964 },
5704 else => return sema.mod.fail(&block.base, src, "TODO Implement arithmetic operand '{s}'", .{@tagName(zir_tag)}),5965 else => return sema.mod.fail(&block.base, src, "TODO implement comptime arithmetic for operand '{s}'", .{@tagName(zir_tag)}),
5705 };5966 };
57065967
5707 log.debug("{s}({}, {}) result: {}", .{ @tagName(zir_tag), lhs_val, rhs_val, value });5968 log.debug("{s}({}, {}) result: {}", .{ @tagName(zir_tag), lhs_val, rhs_val, value });
...@@ -5714,6 +5975,14 @@ fn analyzeArithmetic(...@@ -5714,6 +5975,14 @@ fn analyzeArithmetic(
5714 try sema.requireRuntimeBlock(block, lhs_src);5975 try sema.requireRuntimeBlock(block, lhs_src);
5715 }5976 }
57165977
5978 if (zir_tag == .mod_rem) {
5979 const dirty_lhs = lhs_ty.isSignedInt() or lhs_ty.isFloat();
5980 const dirty_rhs = rhs_ty.isSignedInt() or rhs_ty.isFloat();
5981 if (dirty_lhs or dirty_rhs) {
5982 return sema.mod.fail(&block.base, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{ lhs_ty, rhs_ty });
5983 }
5984 }
5985
5717 const air_tag: Air.Inst.Tag = switch (zir_tag) {5986 const air_tag: Air.Inst.Tag = switch (zir_tag) {
5718 .add => .add,5987 .add => .add,
5719 .addwrap => .addwrap,5988 .addwrap => .addwrap,
...@@ -5722,7 +5991,9 @@ fn analyzeArithmetic(...@@ -5722,7 +5991,9 @@ fn analyzeArithmetic(
5722 .mul => .mul,5991 .mul => .mul,
5723 .mulwrap => .mulwrap,5992 .mulwrap => .mulwrap,
5724 .div => .div,5993 .div => .div,
5725 else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(zir_tag)}),5994 .mod_rem => .rem,
5995 .rem => .rem,
5996 else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}'", .{@tagName(zir_tag)}),
5726 };5997 };
57275998
5728 return block.addBinOp(air_tag, casted_lhs, casted_rhs);5999 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
...@@ -6099,7 +6370,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr...@@ -6099,7 +6370,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
6099 sema.arena,6370 sema.arena,
6100 @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn),6371 @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn),
6101 ),6372 ),
6102 .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr),6373 .val = try Value.Tag.@"struct".create(sema.arena, field_values),
6103 }),6374 }),
6104 );6375 );
6105 },6376 },
...@@ -6121,7 +6392,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr...@@ -6121,7 +6392,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
6121 sema.arena,6392 sema.arena,
6122 @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Int),6393 @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Int),
6123 ),6394 ),
6124 .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr),6395 .val = try Value.Tag.@"struct".create(sema.arena, field_values),
6125 }),6396 }),
6126 );6397 );
6127 },6398 },
...@@ -6448,9 +6719,9 @@ fn zirRetErrValue(...@@ -6448,9 +6719,9 @@ fn zirRetErrValue(
6448 const src = inst_data.src();6719 const src = inst_data.src();
64496720
6450 // Add the error tag to the inferred error set of the in-scope function.6721 // Add the error tag to the inferred error set of the in-scope function.
6451 if (sema.func) |func| {6722 if (sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) {
6452 if (func.getInferredErrorSet()) |map| {6723 if (sema.fn_ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| {
6453 _ = try map.getOrPut(sema.gpa, err_name);6724 _ = try payload.data.map.getOrPut(sema.gpa, err_name);
6454 }6725 }
6455 }6726 }
6456 // Return the error code from the function.6727 // Return the error code from the function.
...@@ -6485,6 +6756,10 @@ fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr...@@ -6485,6 +6756,10 @@ fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
6485 const operand = sema.resolveInst(inst_data.operand);6756 const operand = sema.resolveInst(inst_data.operand);
6486 const src = inst_data.src();6757 const src = inst_data.src();
64876758
6759 // TODO: we pass false here for the `need_coercion` boolean, but I'm pretty sure we need
6760 // to remove this parameter entirely. Observe the problem by looking at the incorrect compile
6761 // error that occurs when a behavior test case being executed at comptime fails, e.g.
6762 // `test { comptime foo(); } fn foo() { try expect(false); }`
6488 return sema.analyzeRet(block, operand, src, false);6763 return sema.analyzeRet(block, operand, src, false);
6489}6764}
64906765
...@@ -6516,6 +6791,10 @@ fn analyzeRet(...@@ -6516,6 +6791,10 @@ fn analyzeRet(
6516 try sema.coerce(block, sema.fn_ret_ty, uncasted_operand, src);6791 try sema.coerce(block, sema.fn_ret_ty, uncasted_operand, src);
65176792
6518 if (block.inlining) |inlining| {6793 if (block.inlining) |inlining| {
6794 if (block.is_comptime) {
6795 inlining.comptime_result = operand;
6796 return error.ComptimeReturn;
6797 }
6519 // We are inlining a function call; rewrite the `ret` as a `break`.6798 // We are inlining a function call; rewrite the `ret` as a `break`.
6520 try inlining.merges.results.append(sema.gpa, operand);6799 try inlining.merges.results.append(sema.gpa, operand);
6521 _ = try block.addBr(inlining.merges.block_inst, operand);6800 _ = try block.addBr(inlining.merges.block_inst, operand);
...@@ -6729,7 +7008,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref:...@@ -6729,7 +7008,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref:
6729 for (field_inits) |field_init, i| {7008 for (field_inits) |field_init, i| {
6730 values[i] = (sema.resolveMaybeUndefVal(block, src, field_init) catch unreachable).?;7009 values[i] = (sema.resolveMaybeUndefVal(block, src, field_init) catch unreachable).?;
6731 }7010 }
6732 return sema.addConstant(resolved_ty, try Value.Tag.@"struct".create(sema.arena, values.ptr));7011 return sema.addConstant(resolved_ty, try Value.Tag.@"struct".create(sema.arena, values));
6733 }7012 }
67347013
6735 return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{});7014 return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{});
...@@ -7184,9 +7463,7 @@ fn zirMod(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A...@@ -7184,9 +7463,7 @@ fn zirMod(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A
7184}7463}
71857464
7186fn zirRem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7465fn zirRem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
7187 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;7466 return sema.zirArithmetic(block, inst);
7188 const src = inst_data.src();
7189 return sema.mod.fail(&block.base, src, "TODO: Sema.zirRem", .{});
7190}7467}
71917468
7192fn zirShlExact(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7469fn zirShlExact(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -7213,10 +7490,149 @@ fn zirOffsetOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr...@@ -7213,10 +7490,149 @@ fn zirOffsetOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
7213 return sema.mod.fail(&block.base, src, "TODO: Sema.zirOffsetOf", .{});7490 return sema.mod.fail(&block.base, src, "TODO: Sema.zirOffsetOf", .{});
7214}7491}
72157492
7216fn zirCmpxchg(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7493fn checkAtomicOperandType(
7494 sema: *Sema,
7495 block: *Scope.Block,
7496 ty_src: LazySrcLoc,
7497 ty: Type,
7498) CompileError!void {
7499 var buffer: Type.Payload.Bits = undefined;
7500 const target = sema.mod.getTarget();
7501 const max_atomic_bits = target_util.largestAtomicBits(target);
7502 const int_ty = switch (ty.zigTypeTag()) {
7503 .Int => ty,
7504 .Enum => ty.enumTagType(&buffer),
7505 .Float => {
7506 const bit_count = ty.floatBits(target);
7507 if (bit_count > max_atomic_bits) {
7508 return sema.mod.fail(
7509 &block.base,
7510 ty_src,
7511 "expected {d}-bit float type or smaller; found {d}-bit float type",
7512 .{ max_atomic_bits, bit_count },
7513 );
7514 }
7515 return;
7516 },
7517 .Bool => return, // Will be treated as `u8`.
7518 else => return sema.mod.fail(
7519 &block.base,
7520 ty_src,
7521 "expected bool, integer, float, enum, or pointer type; found {}",
7522 .{ty},
7523 ),
7524 };
7525 const bit_count = int_ty.intInfo(target).bits;
7526 if (bit_count > max_atomic_bits) {
7527 return sema.mod.fail(
7528 &block.base,
7529 ty_src,
7530 "expected {d}-bit integer type or smaller; found {d}-bit integer type",
7531 .{ max_atomic_bits, bit_count },
7532 );
7533 }
7534}
7535
7536fn resolveAtomicOrder(
7537 sema: *Sema,
7538 block: *Scope.Block,
7539 src: LazySrcLoc,
7540 zir_ref: Zir.Inst.Ref,
7541) CompileError!std.builtin.AtomicOrder {
7542 const atomic_order_ty = try sema.getBuiltinType(block, src, "AtomicOrder");
7543 const air_ref = sema.resolveInst(zir_ref);
7544 const coerced = try sema.coerce(block, atomic_order_ty, air_ref, src);
7545 const val = try sema.resolveConstValue(block, src, coerced);
7546 return val.toEnum(std.builtin.AtomicOrder);
7547}
7548
7549fn zirCmpxchg(
7550 sema: *Sema,
7551 block: *Scope.Block,
7552 inst: Zir.Inst.Index,
7553 air_tag: Air.Inst.Tag,
7554) CompileError!Air.Inst.Ref {
7555 const mod = sema.mod;
7217 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;7556 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
7557 const extra = sema.code.extraData(Zir.Inst.Cmpxchg, inst_data.payload_index).data;
7218 const src = inst_data.src();7558 const src = inst_data.src();
7219 return sema.mod.fail(&block.base, src, "TODO: Sema.zirCmpxchg", .{});7559 // zig fmt: off
7560 const elem_ty_src : LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
7561 const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
7562 const expected_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
7563 const new_value_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node };
7564 const success_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg4 = inst_data.src_node };
7565 const failure_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg5 = inst_data.src_node };
7566 // zig fmt: on
7567 const ptr = sema.resolveInst(extra.ptr);
7568 const elem_ty = sema.typeOf(ptr).elemType();
7569 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);
7570 if (elem_ty.zigTypeTag() == .Float) {
7571 return mod.fail(
7572 &block.base,
7573 elem_ty_src,
7574 "expected bool, integer, enum, or pointer type; found '{}'",
7575 .{elem_ty},
7576 );
7577 }
7578 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);
7579 const new_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.new_value), new_value_src);
7580 const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order);
7581 const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order);
7582
7583 if (@enumToInt(success_order) < @enumToInt(std.builtin.AtomicOrder.Monotonic)) {
7584 return mod.fail(&block.base, success_order_src, "success atomic ordering must be Monotonic or stricter", .{});
7585 }
7586 if (@enumToInt(failure_order) < @enumToInt(std.builtin.AtomicOrder.Monotonic)) {
7587 return mod.fail(&block.base, failure_order_src, "failure atomic ordering must be Monotonic or stricter", .{});
7588 }
7589 if (@enumToInt(failure_order) > @enumToInt(success_order)) {
7590 return mod.fail(&block.base, failure_order_src, "failure atomic ordering must be no stricter than success", .{});
7591 }
7592 if (failure_order == .Release or failure_order == .AcqRel) {
7593 return mod.fail(&block.base, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{});
7594 }
7595
7596 const result_ty = try Module.optionalType(sema.arena, elem_ty);
7597
7598 // special case zero bit types
7599 if ((try sema.typeHasOnePossibleValue(block, elem_ty_src, elem_ty)) != null) {
7600 return sema.addConstant(result_ty, Value.initTag(.null_value));
7601 }
7602
7603 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {
7604 if (try sema.resolveMaybeUndefVal(block, expected_src, expected_value)) |expected_val| {
7605 if (try sema.resolveMaybeUndefVal(block, new_value_src, new_value)) |new_val| {
7606 if (expected_val.isUndef() or new_val.isUndef()) {
7607 return sema.addConstUndef(result_ty);
7608 }
7609 const stored_val = (try ptr_val.pointerDeref(sema.arena)) orelse break :rs ptr_src;
7610 const result_val = if (stored_val.eql(expected_val, elem_ty)) blk: {
7611 try sema.storePtr(block, src, ptr, new_value);
7612 break :blk Value.initTag(.null_value);
7613 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);
7614
7615 return sema.addConstant(result_ty, result_val);
7616 } else break :rs new_value_src;
7617 } else break :rs expected_src;
7618 } else ptr_src;
7619
7620 const flags: u32 = @as(u32, @enumToInt(success_order)) |
7621 (@as(u32, @enumToInt(failure_order)) << 3);
7622
7623 try sema.requireRuntimeBlock(block, runtime_src);
7624 return block.addInst(.{
7625 .tag = air_tag,
7626 .data = .{ .ty_pl = .{
7627 .ty = try sema.addType(result_ty),
7628 .payload = try sema.addExtra(Air.Cmpxchg{
7629 .ptr = ptr,
7630 .expected_value = expected_value,
7631 .new_value = new_value,
7632 .flags = flags,
7633 }),
7634 } },
7635 });
7220}7636}
72217637
7222fn zirSplat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7638fn zirSplat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -8060,7 +8476,7 @@ fn namespaceLookup(...@@ -8060,7 +8476,7 @@ fn namespaceLookup(
8060) CompileError!?*Decl {8476) CompileError!?*Decl {
8061 const mod = sema.mod;8477 const mod = sema.mod;
8062 const gpa = sema.gpa;8478 const gpa = sema.gpa;
8063 if (try sema.lookupInNamespace(namespace, decl_name)) |decl| {8479 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| {
8064 if (!decl.is_pub and decl.namespace.file_scope != block.getFileScope()) {8480 if (!decl.is_pub and decl.namespace.file_scope != block.getFileScope()) {
8065 const msg = msg: {8481 const msg = msg: {
8066 const msg = try mod.errMsg(&block.base, src, "'{s}' is not marked 'pub'", .{8482 const msg = try mod.errMsg(&block.base, src, "'{s}' is not marked 'pub'", .{
...@@ -8740,7 +9156,8 @@ fn coerceArrayPtrToSlice(...@@ -8740,7 +9156,8 @@ fn coerceArrayPtrToSlice(
8740 // The comptime Value representation is compatible with both types.9156 // The comptime Value representation is compatible with both types.
8741 return sema.addConstant(dest_type, val);9157 return sema.addConstant(dest_type, val);
8742 }9158 }
8743 return sema.mod.fail(&block.base, inst_src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});9159 try sema.requireRuntimeBlock(block, inst_src);
9160 return block.addTyOp(.array_to_slice, dest_type, inst);
8744}9161}
87459162
8746fn coerceArrayPtrToMany(9163fn coerceArrayPtrToMany(
...@@ -8776,8 +9193,7 @@ fn analyzeDeclVal(...@@ -8776,8 +9193,7 @@ fn analyzeDeclVal(
8776 return result;9193 return result;
8777}9194}
87789195
8779fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {9196fn ensureDeclAnalyzed(sema: *Sema, decl: *Decl) CompileError!void {
8780 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
8781 sema.mod.ensureDeclAnalyzed(decl) catch |err| {9197 sema.mod.ensureDeclAnalyzed(decl) catch |err| {
8782 if (sema.owner_func) |owner_func| {9198 if (sema.owner_func) |owner_func| {
8783 owner_func.state = .dependency_failure;9199 owner_func.state = .dependency_failure;
...@@ -8786,6 +9202,11 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {...@@ -8786,6 +9202,11 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {
8786 }9202 }
8787 return err;9203 return err;
8788 };9204 };
9205}
9206
9207fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {
9208 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
9209 try sema.ensureDeclAnalyzed(decl);
87899210
8790 const decl_tv = try decl.typedValue();9211 const decl_tv = try decl.typedValue();
8791 if (decl_tv.val.castTag(.variable)) |payload| {9212 if (decl_tv.val.castTag(.variable)) |payload| {
...@@ -9359,13 +9780,11 @@ fn resolvePeerTypes(...@@ -9359,13 +9780,11 @@ fn resolvePeerTypes(
9359 const chosen_src = candidate_srcs.resolve(9780 const chosen_src = candidate_srcs.resolve(
9360 sema.gpa,9781 sema.gpa,
9361 block.src_decl,9782 block.src_decl,
9362 instructions.len,
9363 chosen_i,9783 chosen_i,
9364 );9784 );
9365 const candidate_src = candidate_srcs.resolve(9785 const candidate_src = candidate_srcs.resolve(
9366 sema.gpa,9786 sema.gpa,
9367 block.src_decl,9787 block.src_decl,
9368 instructions.len,
9369 candidate_i + 1,9788 candidate_i + 1,
9370 );9789 );
93719790
...@@ -9417,6 +9836,16 @@ pub fn resolveTypeLayout(...@@ -9417,6 +9836,16 @@ pub fn resolveTypeLayout(
9417 }9836 }
9418}9837}
94199838
9839pub fn resolvePendingTypes(sema: *Sema, block: *Scope.Block) !void {
9840 for (sema.types_pending_resolution.items) |ty| {
9841 // If an error happens resolving the fields of a struct, it will be marked
9842 // invalid and a proper compile error set up. But we should still look at the
9843 // other types pending resolution.
9844 const src: LazySrcLoc = .{ .node_offset = 0 };
9845 sema.resolveDeclFields(block, src, ty) catch continue;
9846 }
9847}
9848
9420/// `sema` and `block` are expected to be the same ones used for the `Decl`.9849/// `sema` and `block` are expected to be the same ones used for the `Decl`.
9421pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void {9850pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void {
9422 switch (ty.tag()) {9851 switch (ty.tag()) {
...@@ -9475,7 +9904,7 @@ fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type...@@ -9475,7 +9904,7 @@ fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type
9475 .type_info => return sema.resolveBuiltinTypeFields(block, src, "TypeInfo"),9904 .type_info => return sema.resolveBuiltinTypeFields(block, src, "TypeInfo"),
9476 .extern_options => return sema.resolveBuiltinTypeFields(block, src, "ExternOptions"),9905 .extern_options => return sema.resolveBuiltinTypeFields(block, src, "ExternOptions"),
9477 .export_options => return sema.resolveBuiltinTypeFields(block, src, "ExportOptions"),9906 .export_options => return sema.resolveBuiltinTypeFields(block, src, "ExportOptions"),
9478 .atomic_ordering => return sema.resolveBuiltinTypeFields(block, src, "AtomicOrdering"),9907 .atomic_order => return sema.resolveBuiltinTypeFields(block, src, "AtomicOrder"),
9479 .atomic_rmw_op => return sema.resolveBuiltinTypeFields(block, src, "AtomicRmwOp"),9908 .atomic_rmw_op => return sema.resolveBuiltinTypeFields(block, src, "AtomicRmwOp"),
9480 .calling_convention => return sema.resolveBuiltinTypeFields(block, src, "CallingConvention"),9909 .calling_convention => return sema.resolveBuiltinTypeFields(block, src, "CallingConvention"),
9481 .float_mode => return sema.resolveBuiltinTypeFields(block, src, "FloatMode"),9910 .float_mode => return sema.resolveBuiltinTypeFields(block, src, "FloatMode"),
...@@ -9869,7 +10298,7 @@ fn typeHasOnePossibleValue(...@@ -9869,7 +10298,7 @@ fn typeHasOnePossibleValue(
9869 .var_args_param,10298 .var_args_param,
9870 .manyptr_u8,10299 .manyptr_u8,
9871 .manyptr_const_u8,10300 .manyptr_const_u8,
9872 .atomic_ordering,10301 .atomic_order,
9873 .atomic_rmw_op,10302 .atomic_rmw_op,
9874 .calling_convention,10303 .calling_convention,
9875 .float_mode,10304 .float_mode,
...@@ -9951,7 +10380,7 @@ fn typeHasOnePossibleValue(...@@ -9951,7 +10380,7 @@ fn typeHasOnePossibleValue(
9951 };10380 };
9952}10381}
995310382
9954fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.ast.Tree {10383fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.Ast {
9955 return block.src_decl.namespace.file_scope.getTree(sema.gpa) catch |err| {10384 return block.src_decl.namespace.file_scope.getTree(sema.gpa) catch |err| {
9956 log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});10385 log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});
9957 return error.AnalysisFail;10386 return error.AnalysisFail;
...@@ -9960,14 +10389,14 @@ fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.ast....@@ -9960,14 +10389,14 @@ fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.ast.
996010389
9961fn enumFieldSrcLoc(10390fn enumFieldSrcLoc(
9962 decl: *Decl,10391 decl: *Decl,
9963 tree: std.zig.ast.Tree,10392 tree: std.zig.Ast,
9964 node_offset: i32,10393 node_offset: i32,
9965 field_index: usize,10394 field_index: usize,
9966) LazySrcLoc {10395) LazySrcLoc {
9967 @setCold(true);10396 @setCold(true);
9968 const enum_node = decl.relativeToNodeIndex(node_offset);10397 const enum_node = decl.relativeToNodeIndex(node_offset);
9969 const node_tags = tree.nodes.items(.tag);10398 const node_tags = tree.nodes.items(.tag);
9970 var buffer: [2]std.zig.ast.Node.Index = undefined;10399 var buffer: [2]std.zig.Ast.Node.Index = undefined;
9971 const container_decl = switch (node_tags[enum_node]) {10400 const container_decl = switch (node_tags[enum_node]) {
9972 .container_decl,10401 .container_decl,
9973 .container_decl_trailing,10402 .container_decl_trailing,
...@@ -10054,7 +10483,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {...@@ -10054,7 +10483,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
10054 .@"null" => return .null_type,10483 .@"null" => return .null_type,
10055 .@"undefined" => return .undefined_type,10484 .@"undefined" => return .undefined_type,
10056 .enum_literal => return .enum_literal_type,10485 .enum_literal => return .enum_literal_type,
10057 .atomic_ordering => return .atomic_ordering_type,10486 .atomic_order => return .atomic_order_type,
10058 .atomic_rmw_op => return .atomic_rmw_op_type,10487 .atomic_rmw_op => return .atomic_rmw_op_type,
10059 .calling_convention => return .calling_convention_type,10488 .calling_convention => return .calling_convention_type,
10060 .float_mode => return .float_mode_type,10489 .float_mode => return .float_mode_type,
src/Zir.zig+74-16
...@@ -16,7 +16,7 @@ const Allocator = std.mem.Allocator;...@@ -16,7 +16,7 @@ const Allocator = std.mem.Allocator;
16const assert = std.debug.assert;16const assert = std.debug.assert;
17const BigIntConst = std.math.big.int.Const;17const BigIntConst = std.math.big.int.Const;
18const BigIntMutable = std.math.big.int.Mutable;18const BigIntMutable = std.math.big.int.Mutable;
19const ast = std.zig.ast;19const Ast = std.zig.Ast;
2020
21const Zir = @This();21const Zir = @This();
22const Type = @import("type.zig").Type;22const Type = @import("type.zig").Type;
...@@ -1629,6 +1629,22 @@ pub const Inst = struct {...@@ -1629,6 +1629,22 @@ pub const Inst = struct {
1629 wasm_memory_size,1629 wasm_memory_size,
1630 /// `operand` is payload index to `BinNode`.1630 /// `operand` is payload index to `BinNode`.
1631 wasm_memory_grow,1631 wasm_memory_grow,
1632 /// Implements the `@addWithSaturation` builtin.
1633 /// `operand` is payload index to `SaturatingArithmetic`.
1634 /// `small` is unused.
1635 add_with_saturation,
1636 /// Implements the `@subWithSaturation` builtin.
1637 /// `operand` is payload index to `SaturatingArithmetic`.
1638 /// `small` is unused.
1639 sub_with_saturation,
1640 /// Implements the `@mulWithSaturation` builtin.
1641 /// `operand` is payload index to `SaturatingArithmetic`.
1642 /// `small` is unused.
1643 mul_with_saturation,
1644 /// Implements the `@shlWithSaturation` builtin.
1645 /// `operand` is payload index to `SaturatingArithmetic`.
1646 /// `small` is unused.
1647 shl_with_saturation,
16321648
1633 pub const InstData = struct {1649 pub const InstData = struct {
1634 opcode: Extended,1650 opcode: Extended,
...@@ -1698,7 +1714,7 @@ pub const Inst = struct {...@@ -1698,7 +1714,7 @@ pub const Inst = struct {
1698 null_type,1714 null_type,
1699 undefined_type,1715 undefined_type,
1700 enum_literal_type,1716 enum_literal_type,
1701 atomic_ordering_type,1717 atomic_order_type,
1702 atomic_rmw_op_type,1718 atomic_rmw_op_type,
1703 calling_convention_type,1719 calling_convention_type,
1704 float_mode_type,1720 float_mode_type,
...@@ -1945,9 +1961,9 @@ pub const Inst = struct {...@@ -1945,9 +1961,9 @@ pub const Inst = struct {
1945 .ty = Type.initTag(.type),1961 .ty = Type.initTag(.type),
1946 .val = Value.initTag(.manyptr_const_u8_type),1962 .val = Value.initTag(.manyptr_const_u8_type),
1947 },1963 },
1948 .atomic_ordering_type = .{1964 .atomic_order_type = .{
1949 .ty = Type.initTag(.type),1965 .ty = Type.initTag(.type),
1950 .val = Value.initTag(.atomic_ordering_type),1966 .val = Value.initTag(.atomic_order_type),
1951 },1967 },
1952 .atomic_rmw_op_type = .{1968 .atomic_rmw_op_type = .{
1953 .ty = Type.initTag(.type),1969 .ty = Type.initTag(.type),
...@@ -2076,7 +2092,7 @@ pub const Inst = struct {...@@ -2076,7 +2092,7 @@ pub const Inst = struct {
2076 /// Used for unary operators, with a token source location.2092 /// Used for unary operators, with a token source location.
2077 un_tok: struct {2093 un_tok: struct {
2078 /// Offset from Decl AST token index.2094 /// Offset from Decl AST token index.
2079 src_tok: ast.TokenIndex,2095 src_tok: Ast.TokenIndex,
2080 /// The meaning of this operand depends on the corresponding `Tag`.2096 /// The meaning of this operand depends on the corresponding `Tag`.
2081 operand: Ref,2097 operand: Ref,
20822098
...@@ -2098,7 +2114,7 @@ pub const Inst = struct {...@@ -2098,7 +2114,7 @@ pub const Inst = struct {
2098 },2114 },
2099 pl_tok: struct {2115 pl_tok: struct {
2100 /// Offset from Decl AST token index.2116 /// Offset from Decl AST token index.
2101 src_tok: ast.TokenIndex,2117 src_tok: Ast.TokenIndex,
2102 /// index into extra.2118 /// index into extra.
2103 /// `Tag` determines what lives there.2119 /// `Tag` determines what lives there.
2104 payload_index: u32,2120 payload_index: u32,
...@@ -2134,7 +2150,7 @@ pub const Inst = struct {...@@ -2134,7 +2150,7 @@ pub const Inst = struct {
2134 }2150 }
2135 },2151 },
2136 /// Offset from Decl AST token index.2152 /// Offset from Decl AST token index.
2137 tok: ast.TokenIndex,2153 tok: Ast.TokenIndex,
2138 /// Offset from Decl AST node index.2154 /// Offset from Decl AST node index.
2139 node: i32,2155 node: i32,
2140 int: u64,2156 int: u64,
...@@ -2751,12 +2767,18 @@ pub const Inst = struct {...@@ -2751,12 +2767,18 @@ pub const Inst = struct {
2751 ptr: Ref,2767 ptr: Ref,
2752 };2768 };
27532769
2770 pub const SaturatingArithmetic = struct {
2771 node: i32,
2772 lhs: Ref,
2773 rhs: Ref,
2774 };
2775
2754 pub const Cmpxchg = struct {2776 pub const Cmpxchg = struct {
2755 ptr: Ref,2777 ptr: Ref,
2756 expected_value: Ref,2778 expected_value: Ref,
2757 new_value: Ref,2779 new_value: Ref,
2758 success_order: Ref,2780 success_order: Ref,
2759 fail_order: Ref,2781 failure_order: Ref,
2760 };2782 };
27612783
2762 pub const AtomicRmw = struct {2784 pub const AtomicRmw = struct {
...@@ -2856,9 +2878,9 @@ pub const Inst = struct {...@@ -2856,9 +2878,9 @@ pub const Inst = struct {
2856 pub const Item = struct {2878 pub const Item = struct {
2857 /// null terminated string index2879 /// null terminated string index
2858 msg: u32,2880 msg: u32,
2859 node: ast.Node.Index,2881 node: Ast.Node.Index,
2860 /// If node is 0 then this will be populated.2882 /// If node is 0 then this will be populated.
2861 token: ast.TokenIndex,2883 token: Ast.TokenIndex,
2862 /// Can be used in combination with `token`.2884 /// Can be used in combination with `token`.
2863 byte_offset: u32,2885 byte_offset: u32,
2864 /// 0 or a payload index of a `Block`, each is a payload2886 /// 0 or a payload index of a `Block`, each is a payload
...@@ -2875,7 +2897,7 @@ pub const Inst = struct {...@@ -2875,7 +2897,7 @@ pub const Inst = struct {
2875 /// null terminated string index2897 /// null terminated string index
2876 name: u32,2898 name: u32,
2877 /// points to the import name2899 /// points to the import name
2878 token: ast.TokenIndex,2900 token: Ast.TokenIndex,
2879 };2901 };
2880 };2902 };
2881};2903};
...@@ -2890,8 +2912,8 @@ const Writer = struct {...@@ -2890,8 +2912,8 @@ const Writer = struct {
2890 indent: u32,2912 indent: u32,
2891 parent_decl_node: u32,2913 parent_decl_node: u32,
28922914
2893 fn relativeToNodeIndex(self: *Writer, offset: i32) ast.Node.Index {2915 fn relativeToNodeIndex(self: *Writer, offset: i32) Ast.Node.Index {
2894 return @bitCast(ast.Node.Index, offset + @bitCast(i32, self.parent_decl_node));2916 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, self.parent_decl_node));
2895 }2917 }
28962918
2897 fn writeInstToStream(2919 fn writeInstToStream(
...@@ -3032,8 +3054,6 @@ const Writer = struct {...@@ -3032,8 +3054,6 @@ const Writer = struct {
3032 .array_init_ref,3054 .array_init_ref,
3033 .array_init_anon_ref,3055 .array_init_anon_ref,
3034 .union_init_ptr,3056 .union_init_ptr,
3035 .cmpxchg_strong,
3036 .cmpxchg_weak,
3037 .shuffle,3057 .shuffle,
3038 .select,3058 .select,
3039 .atomic_rmw,3059 .atomic_rmw,
...@@ -3050,6 +3070,10 @@ const Writer = struct {...@@ -3050,6 +3070,10 @@ const Writer = struct {
3050 .struct_init_ref,3070 .struct_init_ref,
3051 => try self.writeStructInit(stream, inst),3071 => try self.writeStructInit(stream, inst),
30523072
3073 .cmpxchg_strong,
3074 .cmpxchg_weak,
3075 => try self.writeCmpxchg(stream, inst),
3076
3053 .struct_init_anon,3077 .struct_init_anon,
3054 .struct_init_anon_ref,3078 .struct_init_anon_ref,
3055 => try self.writeStructInitAnon(stream, inst),3079 => try self.writeStructInitAnon(stream, inst),
...@@ -3231,6 +3255,11 @@ const Writer = struct {...@@ -3231,6 +3255,11 @@ const Writer = struct {
3231 .shl_with_overflow,3255 .shl_with_overflow,
3232 => try self.writeOverflowArithmetic(stream, extended),3256 => try self.writeOverflowArithmetic(stream, extended),
32333257
3258 .add_with_saturation,
3259 .sub_with_saturation,
3260 .mul_with_saturation,
3261 .shl_with_saturation,
3262 => try self.writeSaturatingArithmetic(stream, extended),
3234 .struct_decl => try self.writeStructDecl(stream, extended),3263 .struct_decl => try self.writeStructDecl(stream, extended),
3235 .union_decl => try self.writeUnionDecl(stream, extended),3264 .union_decl => try self.writeUnionDecl(stream, extended),
3236 .enum_decl => try self.writeEnumDecl(stream, extended),3265 .enum_decl => try self.writeEnumDecl(stream, extended),
...@@ -3397,7 +3426,7 @@ const Writer = struct {...@@ -3397,7 +3426,7 @@ const Writer = struct {
3397 try self.writeBody(stream, body);3426 try self.writeBody(stream, body);
3398 self.indent -= 2;3427 self.indent -= 2;
3399 try stream.writeByteNTimes(' ', self.indent);3428 try stream.writeByteNTimes(' ', self.indent);
3400 try stream.writeAll(") ");3429 try stream.writeAll("}) ");
3401 try self.writeSrc(stream, inst_data.src());3430 try self.writeSrc(stream, inst_data.src());
3402 }3431 }
34033432
...@@ -3447,6 +3476,23 @@ const Writer = struct {...@@ -3447,6 +3476,23 @@ const Writer = struct {
3447 try self.writeSrc(stream, inst_data.src());3476 try self.writeSrc(stream, inst_data.src());
3448 }3477 }
34493478
3479 fn writeCmpxchg(self: *Writer, stream: anytype, inst: Inst.Index) !void {
3480 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
3481 const extra = self.code.extraData(Inst.Cmpxchg, inst_data.payload_index).data;
3482
3483 try self.writeInstRef(stream, extra.ptr);
3484 try stream.writeAll(", ");
3485 try self.writeInstRef(stream, extra.expected_value);
3486 try stream.writeAll(", ");
3487 try self.writeInstRef(stream, extra.new_value);
3488 try stream.writeAll(", ");
3489 try self.writeInstRef(stream, extra.success_order);
3490 try stream.writeAll(", ");
3491 try self.writeInstRef(stream, extra.failure_order);
3492 try stream.writeAll(") ");
3493 try self.writeSrc(stream, inst_data.src());
3494 }
3495
3450 fn writeStructInitAnon(self: *Writer, stream: anytype, inst: Inst.Index) !void {3496 fn writeStructInitAnon(self: *Writer, stream: anytype, inst: Inst.Index) !void {
3451 const inst_data = self.code.instructions.items(.data)[inst].pl_node;3497 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
3452 const extra = self.code.extraData(Inst.StructInitAnon, inst_data.payload_index);3498 const extra = self.code.extraData(Inst.StructInitAnon, inst_data.payload_index);
...@@ -3584,6 +3630,18 @@ const Writer = struct {...@@ -3584,6 +3630,18 @@ const Writer = struct {
3584 try self.writeSrc(stream, src);3630 try self.writeSrc(stream, src);
3585 }3631 }
35863632
3633 fn writeSaturatingArithmetic(self: *Writer, stream: anytype, extended: Inst.Extended.InstData) !void {
3634 const extra = self.code.extraData(Zir.Inst.SaturatingArithmetic, extended.operand).data;
3635 const src: LazySrcLoc = .{ .node_offset = extra.node };
3636
3637 try self.writeInstRef(stream, extra.lhs);
3638 try stream.writeAll(", ");
3639 try self.writeInstRef(stream, extra.rhs);
3640 try stream.writeAll(", ");
3641 try stream.writeAll(") ");
3642 try self.writeSrc(stream, src);
3643 }
3644
3587 fn writePlNodeCall(self: *Writer, stream: anytype, inst: Inst.Index) !void {3645 fn writePlNodeCall(self: *Writer, stream: anytype, inst: Inst.Index) !void {
3588 const inst_data = self.code.instructions.items(.data)[inst].pl_node;3646 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
3589 const extra = self.code.extraData(Inst.Call, inst_data.payload_index);3647 const extra = self.code.extraData(Inst.Call, inst_data.payload_index);
src/clang_options_data.zig+7-1
...@@ -1,6 +1,12 @@...@@ -1,6 +1,12 @@
1// This file is generated by tools/update_clang_options.zig.1// This file is generated by tools/update_clang_options.zig.
2// zig fmt: off2// zig fmt: off
3usingnamespace @import("clang_options.zig");3const clang_options = @import("clang_options.zig");
4const CliArg = clang_options.CliArg;
5const flagpd1 = clang_options.flagpd1;
6const flagpsl = clang_options.flagpsl;
7const joinpd1 = clang_options.joinpd1;
8const jspd1 = clang_options.jspd1;
9const sepd1 = clang_options.sepd1;
4pub const data = blk: { @setEvalBranchQuota(6000); break :blk &[_]CliArg{10pub const data = blk: { @setEvalBranchQuota(6000); break :blk &[_]CliArg{
5flagpd1("C"),11flagpd1("C"),
6flagpd1("CC"),12flagpd1("CC"),
src/codegen.zig+63-58
...@@ -809,6 +809,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -809,6 +809,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
809 .mul => try self.airMul(inst),809 .mul => try self.airMul(inst),
810 .mulwrap => try self.airMulWrap(inst),810 .mulwrap => try self.airMulWrap(inst),
811 .div => try self.airDiv(inst),811 .div => try self.airDiv(inst),
812 .rem => try self.airRem(inst),
812813
813 .cmp_lt => try self.airCmp(inst, .lt),814 .cmp_lt => try self.airCmp(inst, .lt),
814 .cmp_lte => try self.airCmp(inst, .lte),815 .cmp_lte => try self.airCmp(inst, .lte),
...@@ -855,6 +856,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -855,6 +856,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
855 .store => try self.airStore(inst),856 .store => try self.airStore(inst),
856 .struct_field_ptr=> try self.airStructFieldPtr(inst),857 .struct_field_ptr=> try self.airStructFieldPtr(inst),
857 .struct_field_val=> try self.airStructFieldVal(inst),858 .struct_field_val=> try self.airStructFieldVal(inst),
859 .array_to_slice => try self.airArrayToSlice(inst),
860 .cmpxchg_strong => try self.airCmpxchg(inst),
861 .cmpxchg_weak => try self.airCmpxchg(inst),
858862
859 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),863 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),
860 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),864 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),
...@@ -898,7 +902,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -898,7 +902,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
898 fn dbgSetPrologueEnd(self: *Self) InnerError!void {902 fn dbgSetPrologueEnd(self: *Self) InnerError!void {
899 switch (self.debug_output) {903 switch (self.debug_output) {
900 .dwarf => |dbg_out| {904 .dwarf => |dbg_out| {
901 try dbg_out.dbg_line.append(DW.LNS_set_prologue_end);905 try dbg_out.dbg_line.append(DW.LNS.set_prologue_end);
902 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);906 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
903 },907 },
904 .none => {},908 .none => {},
...@@ -908,7 +912,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -908,7 +912,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
908 fn dbgSetEpilogueBegin(self: *Self) InnerError!void {912 fn dbgSetEpilogueBegin(self: *Self) InnerError!void {
909 switch (self.debug_output) {913 switch (self.debug_output) {
910 .dwarf => |dbg_out| {914 .dwarf => |dbg_out| {
911 try dbg_out.dbg_line.append(DW.LNS_set_epilogue_begin);915 try dbg_out.dbg_line.append(DW.LNS.set_epilogue_begin);
912 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);916 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
913 },917 },
914 .none => {},918 .none => {},
...@@ -924,13 +928,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -924,13 +928,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
924 // It lets you emit single-byte opcodes that add different numbers to928 // It lets you emit single-byte opcodes that add different numbers to
925 // both the PC and the line number at the same time.929 // both the PC and the line number at the same time.
926 try dbg_out.dbg_line.ensureUnusedCapacity(11);930 try dbg_out.dbg_line.ensureUnusedCapacity(11);
927 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_advance_pc);931 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_pc);
928 leb128.writeULEB128(dbg_out.dbg_line.writer(), delta_pc) catch unreachable;932 leb128.writeULEB128(dbg_out.dbg_line.writer(), delta_pc) catch unreachable;
929 if (delta_line != 0) {933 if (delta_line != 0) {
930 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_advance_line);934 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
931 leb128.writeILEB128(dbg_out.dbg_line.writer(), delta_line) catch unreachable;935 leb128.writeILEB128(dbg_out.dbg_line.writer(), delta_line) catch unreachable;
932 }936 }
933 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_copy);937 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.copy);
934 },938 },
935 .none => {},939 .none => {},
936 }940 }
...@@ -1009,7 +1013,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1009,7 +1013,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1009 .dwarf => |dbg_out| {1013 .dwarf => |dbg_out| {
1010 assert(ty.hasCodeGenBits());1014 assert(ty.hasCodeGenBits());
1011 const index = dbg_out.dbg_info.items.len;1015 const index = dbg_out.dbg_info.items.len;
1012 try dbg_out.dbg_info.resize(index + 4); // DW.AT_type, DW.FORM_ref41016 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
10131017
1014 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty);1018 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty);
1015 if (!gop.found_existing) {1019 if (!gop.found_existing) {
...@@ -1266,6 +1270,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1266,6 +1270,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1266 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1270 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1267 }1271 }
12681272
1273 fn airRem(self: *Self, inst: Air.Inst.Index) !void {
1274 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1275 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
1276 else => return self.fail("TODO implement rem for {}", .{self.target.cpu.arch}),
1277 };
1278 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1279 }
1280
1269 fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {1281 fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {
1270 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1282 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1271 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {1283 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
...@@ -2429,13 +2441,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2429,13 +2441,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2429 .dwarf => |dbg_out| {2441 .dwarf => |dbg_out| {
2430 try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 3);2442 try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 3);
2431 dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter);2443 dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter);
2432 dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT_location, DW.FORM_exprloc2444 dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
2433 1, // ULEB128 dwarf expression length2445 1, // ULEB128 dwarf expression length
2434 reg.dwarfLocOp(),2446 reg.dwarfLocOp(),
2435 });2447 });
2436 try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len);2448 try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len);
2437 try self.addDbgInfoTypeReloc(ty); // DW.AT_type, DW.FORM_ref42449 try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
2438 dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string2450 dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
2439 },2451 },
2440 .none => {},2452 .none => {},
2441 }2453 }
...@@ -2458,15 +2470,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2458,15 +2470,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2458 var counting_writer = std.io.countingWriter(std.io.null_writer);2470 var counting_writer = std.io.countingWriter(std.io.null_writer);
2459 leb128.writeILEB128(counting_writer.writer(), adjusted_stack_offset) catch unreachable;2471 leb128.writeILEB128(counting_writer.writer(), adjusted_stack_offset) catch unreachable;
24602472
2461 // DW.AT_location, DW.FORM_exprloc2473 // DW.AT.location, DW.FORM.exprloc
2462 // ULEB128 dwarf expression length2474 // ULEB128 dwarf expression length
2463 try leb128.writeULEB128(dbg_out.dbg_info.writer(), counting_writer.bytes_written + 1);2475 try leb128.writeULEB128(dbg_out.dbg_info.writer(), counting_writer.bytes_written + 1);
2464 try dbg_out.dbg_info.append(DW.OP_breg11);2476 try dbg_out.dbg_info.append(DW.OP.breg11);
2465 try leb128.writeILEB128(dbg_out.dbg_info.writer(), adjusted_stack_offset);2477 try leb128.writeILEB128(dbg_out.dbg_info.writer(), adjusted_stack_offset);
24662478
2467 try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len);2479 try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len);
2468 try self.addDbgInfoTypeReloc(ty); // DW.AT_type, DW.FORM_ref42480 try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
2469 dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string2481 dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
2470 },2482 },
2471 else => {},2483 else => {},
2472 }2484 }
...@@ -2806,24 +2818,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2806,24 +2818,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2806 if (self.air.value(callee)) |func_value| {2818 if (self.air.value(callee)) |func_value| {
2807 if (func_value.castTag(.function)) |func_payload| {2819 if (func_value.castTag(.function)) |func_payload| {
2808 const func = func_payload.data;2820 const func = func_payload.data;
2809 const got_addr = blk: {2821 // TODO I'm hacking my way through here by repurposing .memory for storing
2810 const seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;2822 // index to the GOT target symbol index.
2811 const got = seg.sections.items[macho_file.got_section_index.?];
2812 const got_index = macho_file.got_entries_map.get(.{
2813 .where = .local,
2814 .where_index = func.owner_decl.link.macho.local_sym_index,
2815 }) orelse unreachable;
2816 break :blk got.addr + got_index * @sizeOf(u64);
2817 };
2818 switch (arch) {2823 switch (arch) {
2819 .x86_64 => {2824 .x86_64 => {
2820 try self.genSetReg(Type.initTag(.u64), .rax, .{ .memory = got_addr });2825 try self.genSetReg(Type.initTag(.u64), .rax, .{
2826 .memory = func.owner_decl.link.macho.local_sym_index,
2827 });
2821 // callq *%rax2828 // callq *%rax
2822 try self.code.ensureCapacity(self.code.items.len + 2);2829 try self.code.ensureCapacity(self.code.items.len + 2);
2823 self.code.appendSliceAssumeCapacity(&[2]u8{ 0xff, 0xd0 });2830 self.code.appendSliceAssumeCapacity(&[2]u8{ 0xff, 0xd0 });
2824 },2831 },
2825 .aarch64 => {2832 .aarch64 => {
2826 try self.genSetReg(Type.initTag(.u64), .x30, .{ .memory = got_addr });2833 try self.genSetReg(Type.initTag(.u64), .x30, .{
2834 .memory = func.owner_decl.link.macho.local_sym_index,
2835 });
2827 // blr x302836 // blr x30
2828 writeInt(u32, try self.code.addManyAsArray(4), Instruction.blr(.x30).toU32());2837 writeInt(u32, try self.code.addManyAsArray(4), Instruction.blr(.x30).toU32());
2829 },2838 },
...@@ -4335,29 +4344,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -4335,29 +4344,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
4335 }).toU32());4344 }).toU32());
43364345
4337 if (self.bin_file.cast(link.File.MachO)) |macho_file| {4346 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
4338 // TODO this is super awkward. We are reversing the address of the GOT entry here.4347 // TODO I think the reloc might be in the wrong place.
4339 // We should probably have it cached or move the reloc adding somewhere else.
4340 const got_addr = blk: {
4341 const seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;
4342 const got = seg.sections.items[macho_file.got_section_index.?];
4343 break :blk got.addr;
4344 };
4345 const where_index = blk: for (macho_file.got_entries.items) |key, id| {
4346 if (got_addr + id * @sizeOf(u64) == addr) break :blk key.where_index;
4347 } else unreachable;
4348 const decl = macho_file.active_decl.?;4348 const decl = macho_file.active_decl.?;
4349 // Page reloc for adrp instruction.4349 // Page reloc for adrp instruction.
4350 try decl.link.macho.relocs.append(self.bin_file.allocator, .{4350 try decl.link.macho.relocs.append(self.bin_file.allocator, .{
4351 .offset = offset,4351 .offset = offset,
4352 .where = .local,4352 .where = .local,
4353 .where_index = where_index,4353 .where_index = @intCast(u32, addr),
4354 .payload = .{ .page = .{ .kind = .got } },4354 .payload = .{ .page = .{ .kind = .got } },
4355 });4355 });
4356 // Pageoff reloc for adrp instruction.4356 // Pageoff reloc for adrp instruction.
4357 try decl.link.macho.relocs.append(self.bin_file.allocator, .{4357 try decl.link.macho.relocs.append(self.bin_file.allocator, .{
4358 .offset = offset + 4,4358 .offset = offset + 4,
4359 .where = .local,4359 .where = .local,
4360 .where_index = where_index,4360 .where_index = @intCast(u32, addr),
4361 .payload = .{ .page_off = .{ .kind = .got } },4361 .payload = .{ .page_off = .{ .kind = .got } },
4362 });4362 });
4363 } else {4363 } else {
...@@ -4618,22 +4618,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -4618,22 +4618,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
4618 const offset = @intCast(u32, self.code.items.len);4618 const offset = @intCast(u32, self.code.items.len);
46194619
4620 if (self.bin_file.cast(link.File.MachO)) |macho_file| {4620 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
4621 // TODO this is super awkward. We are reversing the address of the GOT entry here.4621 // TODO I think the reloc might be in the wrong place.
4622 // We should probably have it cached or move the reloc adding somewhere else.
4623 const got_addr = blk: {
4624 const seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;
4625 const got = seg.sections.items[macho_file.got_section_index.?];
4626 break :blk got.addr;
4627 };
4628 const where_index = blk: for (macho_file.got_entries.items) |key, id| {
4629 if (got_addr + id * @sizeOf(u64) == x) break :blk key.where_index;
4630 } else unreachable;
4631 const decl = macho_file.active_decl.?;4622 const decl = macho_file.active_decl.?;
4632 // Load reloc for LEA instruction.4623 // Load reloc for LEA instruction.
4633 try decl.link.macho.relocs.append(self.bin_file.allocator, .{4624 try decl.link.macho.relocs.append(self.bin_file.allocator, .{
4634 .offset = offset - 4,4625 .offset = offset - 4,
4635 .where = .local,4626 .where = .local,
4636 .where_index = where_index,4627 .where_index = @intCast(u32, x),
4637 .payload = .{ .load = .{ .kind = .got } },4628 .payload = .{ .load = .{ .kind = .got } },
4638 });4629 });
4639 } else {4630 } else {
...@@ -4752,6 +4743,27 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -4752,6 +4743,27 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
4752 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });4743 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
4753 }4744 }
47544745
4746 fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
4747 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4748 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
4749 else => return self.fail("TODO implement airArrayToSlice for {}", .{
4750 self.target.cpu.arch,
4751 }),
4752 };
4753 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
4754 }
4755
4756 fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
4757 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4758 const extra = self.air.extraData(Air.Block, ty_pl.payload);
4759 const result: MCValue = switch (arch) {
4760 else => return self.fail("TODO implement airCmpxchg for {}", .{
4761 self.target.cpu.arch,
4762 }),
4763 };
4764 return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value });
4765 }
4766
4755 fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {4767 fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
4756 // First section of indexes correspond to a set number of constant values.4768 // First section of indexes correspond to a set number of constant values.
4757 const ref_int = @enumToInt(inst);4769 const ref_int = @enumToInt(inst);
...@@ -4849,17 +4861,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -4849,17 +4861,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
4849 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];4861 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
4850 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;4862 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;
4851 return MCValue{ .memory = got_addr };4863 return MCValue{ .memory = got_addr };
4852 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {4864 } else if (self.bin_file.cast(link.File.MachO)) |_| {
4853 const got_addr = blk: {4865 // TODO I'm hacking my way through here by repurposing .memory for storing
4854 const seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;4866 // index to the GOT target symbol index.
4855 const got = seg.sections.items[macho_file.got_section_index.?];4867 return MCValue{ .memory = decl.link.macho.local_sym_index };
4856 const got_index = macho_file.got_entries_map.get(.{
4857 .where = .local,
4858 .where_index = decl.link.macho.local_sym_index,
4859 }) orelse unreachable;
4860 break :blk got.addr + got_index * ptr_bytes;
4861 };
4862 return MCValue{ .memory = got_addr };
4863 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {4868 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
4864 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;4869 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
4865 return MCValue{ .memory = got_addr };4870 return MCValue{ .memory = got_addr };
src/codegen/aarch64.zig+1-1
...@@ -52,7 +52,7 @@ pub const Register = enum(u6) {...@@ -52,7 +52,7 @@ pub const Register = enum(u6) {
52 }52 }
5353
54 pub fn dwarfLocOp(self: Register) u8 {54 pub fn dwarfLocOp(self: Register) u8 {
55 return @as(u8, self.id()) + DW.OP_reg0;55 return @as(u8, self.id()) + DW.OP.reg0;
56 }56 }
57};57};
5858
src/codegen/arm.zig+1-1
...@@ -170,7 +170,7 @@ pub const Register = enum(u5) {...@@ -170,7 +170,7 @@ pub const Register = enum(u5) {
170 }170 }
171171
172 pub fn dwarfLocOp(self: Register) u8 {172 pub fn dwarfLocOp(self: Register) u8 {
173 return @as(u8, self.id()) + DW.OP_reg0;173 return @as(u8, self.id()) + DW.OP.reg0;
174 }174 }
175};175};
176176
src/codegen/c.zig+58
...@@ -858,6 +858,7 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM...@@ -858,6 +858,7 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM
858 // TODO use a different strategy for div that communicates to the optimizer858 // TODO use a different strategy for div that communicates to the optimizer
859 // that wrapping is UB.859 // that wrapping is UB.
860 .div => try airBinOp( o, inst, " / "),860 .div => try airBinOp( o, inst, " / "),
861 .rem => try airBinOp( o, inst, " % "),
861862
862 .cmp_eq => try airBinOp(o, inst, " == "),863 .cmp_eq => try airBinOp(o, inst, " == "),
863 .cmp_gt => try airBinOp(o, inst, " > "),864 .cmp_gt => try airBinOp(o, inst, " > "),
...@@ -909,6 +910,9 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM...@@ -909,6 +910,9 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM
909 .switch_br => try airSwitchBr(o, inst),910 .switch_br => try airSwitchBr(o, inst),
910 .wrap_optional => try airWrapOptional(o, inst),911 .wrap_optional => try airWrapOptional(o, inst),
911 .struct_field_ptr => try airStructFieldPtr(o, inst),912 .struct_field_ptr => try airStructFieldPtr(o, inst),
913 .array_to_slice => try airArrayToSlice(o, inst),
914 .cmpxchg_weak => try airCmpxchg(o, inst, "weak"),
915 .cmpxchg_strong => try airCmpxchg(o, inst, "strong"),
912916
913 .struct_field_ptr_index_0 => try airStructFieldPtrIndex(o, inst, 0),917 .struct_field_ptr_index_0 => try airStructFieldPtrIndex(o, inst, 0),
914 .struct_field_ptr_index_1 => try airStructFieldPtrIndex(o, inst, 1),918 .struct_field_ptr_index_1 => try airStructFieldPtrIndex(o, inst, 1),
...@@ -1859,6 +1863,60 @@ fn airIsErr(...@@ -1859,6 +1863,60 @@ fn airIsErr(
1859 return local;1863 return local;
1860}1864}
18611865
1866fn airArrayToSlice(o: *Object, inst: Air.Inst.Index) !CValue {
1867 if (o.liveness.isUnused(inst))
1868 return CValue.none;
1869
1870 const inst_ty = o.air.typeOfIndex(inst);
1871 const local = try o.allocLocal(inst_ty, .Const);
1872 const ty_op = o.air.instructions.items(.data)[inst].ty_op;
1873 const writer = o.writer();
1874 const operand = try o.resolveInst(ty_op.operand);
1875 const array_len = o.air.typeOf(ty_op.operand).elemType().arrayLen();
1876
1877 try writer.writeAll(" = { .ptr = ");
1878 try o.writeCValue(writer, operand);
1879 try writer.print(", .len = {d} }};\n", .{array_len});
1880 return local;
1881}
1882
1883fn airCmpxchg(o: *Object, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
1884 const ty_pl = o.air.instructions.items(.data)[inst].ty_pl;
1885 const extra = o.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
1886 const inst_ty = o.air.typeOfIndex(inst);
1887 const ptr = try o.resolveInst(extra.ptr);
1888 const expected_value = try o.resolveInst(extra.expected_value);
1889 const new_value = try o.resolveInst(extra.new_value);
1890 const local = try o.allocLocal(inst_ty, .Const);
1891 const writer = o.writer();
1892
1893 try writer.print(" = zig_cmpxchg_{s}(", .{flavor});
1894 try o.writeCValue(writer, ptr);
1895 try writer.writeAll(", ");
1896 try o.writeCValue(writer, expected_value);
1897 try writer.writeAll(", ");
1898 try o.writeCValue(writer, new_value);
1899 try writer.writeAll(", ");
1900 try writeMemoryOrder(writer, extra.successOrder());
1901 try writer.writeAll(", ");
1902 try writeMemoryOrder(writer, extra.failureOrder());
1903 try writer.writeAll(");\n");
1904
1905 return local;
1906}
1907
1908fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void {
1909 const str = switch (order) {
1910 .Unordered => "memory_order_relaxed",
1911 .Monotonic => "memory_order_consume",
1912 .Acquire => "memory_order_acquire",
1913 .Release => "memory_order_release",
1914 .AcqRel => "memory_order_acq_rel",
1915 .SeqCst => "memory_order_seq_cst",
1916 };
1917 return w.writeAll(str);
1918}
1919
1862fn IndentWriter(comptime UnderlyingWriter: type) type {1920fn IndentWriter(comptime UnderlyingWriter: type) type {
1863 return struct {1921 return struct {
1864 const Self = @This();1922 const Self = @This();
src/codegen/llvm.zig+149-23
...@@ -392,6 +392,7 @@ pub const Object = struct {...@@ -392,6 +392,7 @@ pub const Object = struct {
392 .latest_alloca_inst = null,392 .latest_alloca_inst = null,
393 .llvm_func = llvm_func,393 .llvm_func = llvm_func,
394 .blocks = .{},394 .blocks = .{},
395 .single_threaded = module.comp.bin_file.options.single_threaded,
395 };396 };
396 defer fg.deinit();397 defer fg.deinit();
397398
...@@ -791,11 +792,13 @@ pub const DeclGen = struct {...@@ -791,11 +792,13 @@ pub const DeclGen = struct {
791 const gpa = self.gpa;792 const gpa = self.gpa;
792 const elem_ty = tv.ty.elemType();793 const elem_ty = tv.ty.elemType();
793 const elem_vals = payload.data;794 const elem_vals = payload.data;
794 const llvm_elems = try gpa.alloc(*const llvm.Value, elem_vals.len);795 const sento = tv.ty.sentinel();
796 const llvm_elems = try gpa.alloc(*const llvm.Value, elem_vals.len + @boolToInt(sento != null));
795 defer gpa.free(llvm_elems);797 defer gpa.free(llvm_elems);
796 for (elem_vals) |elem_val, i| {798 for (elem_vals) |elem_val, i| {
797 llvm_elems[i] = try self.genTypedValue(.{ .ty = elem_ty, .val = elem_val });799 llvm_elems[i] = try self.genTypedValue(.{ .ty = elem_ty, .val = elem_val });
798 }800 }
801 if (sento) |sent| llvm_elems[elem_vals.len] = try self.genTypedValue(.{ .ty = elem_ty, .val = sent });
799 const llvm_elem_ty = try self.llvmType(elem_ty);802 const llvm_elem_ty = try self.llvmType(elem_ty);
800 return llvm_elem_ty.constArray(803 return llvm_elem_ty.constArray(
801 llvm_elems.ptr,804 llvm_elems.ptr,
...@@ -907,6 +910,31 @@ pub const DeclGen = struct {...@@ -907,6 +910,31 @@ pub const DeclGen = struct {
907 // TODO: improve this API, `addAttr(-1, attr_name)`910 // TODO: improve this API, `addAttr(-1, attr_name)`
908 self.addAttr(val, std.math.maxInt(llvm.AttributeIndex), attr_name);911 self.addAttr(val, std.math.maxInt(llvm.AttributeIndex), attr_name);
909 }912 }
913
914 /// If the operand type of an atomic operation is not byte sized we need to
915 /// widen it before using it and then truncate the result.
916 /// RMW exchange of floating-point values is bitcasted to same-sized integer
917 /// types to work around a LLVM deficiency when targeting ARM/AArch64.
918 fn getAtomicAbiType(dg: *DeclGen, ty: Type, is_rmw_xchg: bool) ?*const llvm.Type {
919 const target = dg.module.getTarget();
920 var buffer: Type.Payload.Bits = undefined;
921 const int_ty = switch (ty.zigTypeTag()) {
922 .Int => ty,
923 .Enum => ty.enumTagType(&buffer),
924 .Float => {
925 if (!is_rmw_xchg) return null;
926 return dg.context.intType(@intCast(c_uint, ty.abiSize(target) * 8));
927 },
928 .Bool => return dg.context.intType(8),
929 else => return null,
930 };
931 const bit_count = int_ty.intInfo(target).bits;
932 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {
933 return dg.context.intType(@intCast(c_uint, int_ty.abiSize(target) * 8));
934 } else {
935 return null;
936 }
937 }
910};938};
911939
912pub const FuncGen = struct {940pub const FuncGen = struct {
...@@ -941,6 +969,8 @@ pub const FuncGen = struct {...@@ -941,6 +969,8 @@ pub const FuncGen = struct {
941 break_vals: *BreakValues,969 break_vals: *BreakValues,
942 }),970 }),
943971
972 single_threaded: bool,
973
944 const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock);974 const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock);
945 const BreakValues = std.ArrayListUnmanaged(*const llvm.Value);975 const BreakValues = std.ArrayListUnmanaged(*const llvm.Value);
946976
...@@ -980,6 +1010,7 @@ pub const FuncGen = struct {...@@ -980,6 +1010,7 @@ pub const FuncGen = struct {
980 .mul => try self.airMul(inst, false),1010 .mul => try self.airMul(inst, false),
981 .mulwrap => try self.airMul(inst, true),1011 .mulwrap => try self.airMul(inst, true),
982 .div => try self.airDiv(inst),1012 .div => try self.airDiv(inst),
1013 .rem => try self.airRem(inst),
983 .ptr_add => try self.airPtrAdd(inst),1014 .ptr_add => try self.airPtrAdd(inst),
984 .ptr_sub => try self.airPtrSub(inst),1015 .ptr_sub => try self.airPtrSub(inst),
9851016
...@@ -1006,28 +1037,31 @@ pub const FuncGen = struct {...@@ -1006,28 +1037,31 @@ pub const FuncGen = struct {
1006 .is_err => try self.airIsErr(inst, .NE, false),1037 .is_err => try self.airIsErr(inst, .NE, false),
1007 .is_err_ptr => try self.airIsErr(inst, .NE, true),1038 .is_err_ptr => try self.airIsErr(inst, .NE, true),
10081039
1009 .alloc => try self.airAlloc(inst),1040 .alloc => try self.airAlloc(inst),
1010 .arg => try self.airArg(inst),1041 .arg => try self.airArg(inst),
1011 .bitcast => try self.airBitCast(inst),1042 .bitcast => try self.airBitCast(inst),
1012 .bool_to_int=> try self.airBoolToInt(inst),1043 .bool_to_int => try self.airBoolToInt(inst),
1013 .block => try self.airBlock(inst),1044 .block => try self.airBlock(inst),
1014 .br => try self.airBr(inst),1045 .br => try self.airBr(inst),
1015 .switch_br => try self.airSwitchBr(inst),1046 .switch_br => try self.airSwitchBr(inst),
1016 .breakpoint => try self.airBreakpoint(inst),1047 .breakpoint => try self.airBreakpoint(inst),
1017 .call => try self.airCall(inst),1048 .call => try self.airCall(inst),
1018 .cond_br => try self.airCondBr(inst),1049 .cond_br => try self.airCondBr(inst),
1019 .intcast => try self.airIntCast(inst),1050 .intcast => try self.airIntCast(inst),
1020 .trunc => try self.airTrunc(inst),1051 .trunc => try self.airTrunc(inst),
1021 .floatcast => try self.airFloatCast(inst),1052 .floatcast => try self.airFloatCast(inst),
1022 .ptrtoint => try self.airPtrToInt(inst),1053 .ptrtoint => try self.airPtrToInt(inst),
1023 .load => try self.airLoad(inst),1054 .load => try self.airLoad(inst),
1024 .loop => try self.airLoop(inst),1055 .loop => try self.airLoop(inst),
1025 .not => try self.airNot(inst),1056 .not => try self.airNot(inst),
1026 .ret => try self.airRet(inst),1057 .ret => try self.airRet(inst),
1027 .store => try self.airStore(inst),1058 .store => try self.airStore(inst),
1028 .assembly => try self.airAssembly(inst),1059 .assembly => try self.airAssembly(inst),
1029 .slice_ptr => try self.airSliceField(inst, 0),1060 .slice_ptr => try self.airSliceField(inst, 0),
1030 .slice_len => try self.airSliceField(inst, 1),1061 .slice_len => try self.airSliceField(inst, 1),
1062 .array_to_slice => try self.airArrayToSlice(inst),
1063 .cmpxchg_weak => try self.airCmpxchg(inst, true),
1064 .cmpxchg_strong => try self.airCmpxchg(inst, false),
10311065
1032 .struct_field_ptr => try self.airStructFieldPtr(inst),1066 .struct_field_ptr => try self.airStructFieldPtr(inst),
1033 .struct_field_val => try self.airStructFieldVal(inst),1067 .struct_field_val => try self.airStructFieldVal(inst),
...@@ -1246,6 +1280,24 @@ pub const FuncGen = struct {...@@ -1246,6 +1280,24 @@ pub const FuncGen = struct {
1246 return null;1280 return null;
1247 }1281 }
12481282
1283 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
1284 if (self.liveness.isUnused(inst))
1285 return null;
1286
1287 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1288 const operand = try self.resolveInst(ty_op.operand);
1289 const array_len = self.air.typeOf(ty_op.operand).elemType().arrayLen();
1290 const usize_llvm_ty = try self.dg.llvmType(Type.initTag(.usize));
1291 const len = usize_llvm_ty.constInt(array_len, .False);
1292 const slice_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst));
1293 const indices: [2]*const llvm.Value = .{
1294 usize_llvm_ty.constNull(), usize_llvm_ty.constNull(),
1295 };
1296 const ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
1297 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
1298 return self.builder.buildInsertValue(partial, len, 1, "");
1299 }
1300
1249 fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value {1301 fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value {
1250 if (self.liveness.isUnused(inst))1302 if (self.liveness.isUnused(inst))
1251 return null;1303 return null;
...@@ -1723,6 +1775,19 @@ pub const FuncGen = struct {...@@ -1723,6 +1775,19 @@ pub const FuncGen = struct {
1723 return self.builder.buildUDiv(lhs, rhs, "");1775 return self.builder.buildUDiv(lhs, rhs, "");
1724 }1776 }
17251777
1778 fn airRem(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
1779 if (self.liveness.isUnused(inst)) return null;
1780
1781 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1782 const lhs = try self.resolveInst(bin_op.lhs);
1783 const rhs = try self.resolveInst(bin_op.rhs);
1784 const inst_ty = self.air.typeOfIndex(inst);
1785
1786 if (inst_ty.isFloat()) return self.builder.buildFRem(lhs, rhs, "");
1787 if (inst_ty.isSignedInt()) return self.builder.buildSRem(lhs, rhs, "");
1788 return self.builder.buildURem(lhs, rhs, "");
1789 }
1790
1726 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {1791 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
1727 if (self.liveness.isUnused(inst))1792 if (self.liveness.isUnused(inst))
1728 return null;1793 return null;
...@@ -1944,6 +2009,56 @@ pub const FuncGen = struct {...@@ -1944,6 +2009,56 @@ pub const FuncGen = struct {
1944 return null;2009 return null;
1945 }2010 }
19462011
2012 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*const llvm.Value {
2013 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2014 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
2015 var ptr = try self.resolveInst(extra.ptr);
2016 var expected_value = try self.resolveInst(extra.expected_value);
2017 var new_value = try self.resolveInst(extra.new_value);
2018 const operand_ty = self.air.typeOf(extra.ptr).elemType();
2019 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
2020 if (opt_abi_ty) |abi_ty| {
2021 // operand needs widening and truncating
2022 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
2023 if (operand_ty.isSignedInt()) {
2024 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");
2025 new_value = self.builder.buildSExt(new_value, abi_ty, "");
2026 } else {
2027 expected_value = self.builder.buildZExt(expected_value, abi_ty, "");
2028 new_value = self.builder.buildZExt(new_value, abi_ty, "");
2029 }
2030 }
2031 const result = self.builder.buildAtomicCmpXchg(
2032 ptr,
2033 expected_value,
2034 new_value,
2035 toLlvmAtomicOrdering(extra.successOrder()),
2036 toLlvmAtomicOrdering(extra.failureOrder()),
2037 llvm.Bool.fromBool(self.single_threaded),
2038 );
2039 result.setWeak(llvm.Bool.fromBool(is_weak));
2040
2041 const optional_ty = self.air.typeOfIndex(inst);
2042 var buffer: Type.Payload.ElemType = undefined;
2043 const child_ty = optional_ty.optionalChild(&buffer);
2044
2045 var payload = self.builder.buildExtractValue(result, 0, "");
2046 if (opt_abi_ty != null) {
2047 payload = self.builder.buildTrunc(payload, try self.dg.llvmType(operand_ty), "");
2048 }
2049 const success_bit = self.builder.buildExtractValue(result, 1, "");
2050
2051 if (optional_ty.isPtrLikeOptional()) {
2052 const child_llvm_ty = try self.dg.llvmType(child_ty);
2053 return self.builder.buildSelect(success_bit, child_llvm_ty.constNull(), payload, "");
2054 }
2055
2056 const optional_llvm_ty = try self.dg.llvmType(optional_ty);
2057 const non_null_bit = self.builder.buildNot(success_bit, "");
2058 const partial = self.builder.buildInsertValue(optional_llvm_ty.getUndef(), payload, 0, "");
2059 return self.builder.buildInsertValue(partial, non_null_bit, 1, "");
2060 }
2061
1947 fn getIntrinsic(self: *FuncGen, name: []const u8) *const llvm.Value {2062 fn getIntrinsic(self: *FuncGen, name: []const u8) *const llvm.Value {
1948 const id = llvm.lookupIntrinsicID(name.ptr, name.len);2063 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
1949 assert(id != 0);2064 assert(id != 0);
...@@ -2135,3 +2250,14 @@ fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {...@@ -2135,3 +2250,14 @@ fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
2135 .spirv64 => unreachable, // LLVM does not support this backend2250 .spirv64 => unreachable, // LLVM does not support this backend
2136 }2251 }
2137}2252}
2253
2254fn toLlvmAtomicOrdering(atomic_order: std.builtin.AtomicOrder) llvm.AtomicOrdering {
2255 return switch (atomic_order) {
2256 .Unordered => .Unordered,
2257 .Monotonic => .Monotonic,
2258 .Acquire => .Acquire,
2259 .Release => .Release,
2260 .AcqRel => .AcquireRelease,
2261 .SeqCst => .SequentiallyConsistent,
2262 };
2263}
src/codegen/llvm/bindings.zig+59
...@@ -133,6 +133,9 @@ pub const Value = opaque {...@@ -133,6 +133,9 @@ pub const Value = opaque {
133133
134 pub const constIntToPtr = LLVMConstIntToPtr;134 pub const constIntToPtr = LLVMConstIntToPtr;
135 extern fn LLVMConstIntToPtr(ConstantVal: *const Value, ToType: *const Type) *const Value;135 extern fn LLVMConstIntToPtr(ConstantVal: *const Value, ToType: *const Type) *const Value;
136
137 pub const setWeak = LLVMSetWeak;
138 extern fn LLVMSetWeak(CmpXchgInst: *const Value, IsWeak: Bool) void;
136};139};
137140
138pub const Type = opaque {141pub const Type = opaque {
...@@ -299,6 +302,14 @@ pub const Builder = opaque {...@@ -299,6 +302,14 @@ pub const Builder = opaque {
299 Name: [*:0]const u8,302 Name: [*:0]const u8,
300 ) *const Value;303 ) *const Value;
301304
305 pub const buildSExt = LLVMBuildSExt;
306 extern fn LLVMBuildSExt(
307 *const Builder,
308 Val: *const Value,
309 DestTy: *const Type,
310 Name: [*:0]const u8,
311 ) *const Value;
312
302 pub const buildCall = LLVMBuildCall;313 pub const buildCall = LLVMBuildCall;
303 extern fn LLVMBuildCall(314 extern fn LLVMBuildCall(
304 *const Builder,315 *const Builder,
...@@ -387,6 +398,15 @@ pub const Builder = opaque {...@@ -387,6 +398,15 @@ pub const Builder = opaque {
387 pub const buildFDiv = LLVMBuildFDiv;398 pub const buildFDiv = LLVMBuildFDiv;
388 extern fn LLVMBuildFDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;399 extern fn LLVMBuildFDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
389400
401 pub const buildURem = LLVMBuildURem;
402 extern fn LLVMBuildURem(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
403
404 pub const buildSRem = LLVMBuildSRem;
405 extern fn LLVMBuildSRem(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
406
407 pub const buildFRem = LLVMBuildFRem;
408 extern fn LLVMBuildFRem(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
409
390 pub const buildAnd = LLVMBuildAnd;410 pub const buildAnd = LLVMBuildAnd;
391 extern fn LLVMBuildAnd(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;411 extern fn LLVMBuildAnd(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
392412
...@@ -476,6 +496,35 @@ pub const Builder = opaque {...@@ -476,6 +496,35 @@ pub const Builder = opaque {
476 DestTy: *const Type,496 DestTy: *const Type,
477 Name: [*:0]const u8,497 Name: [*:0]const u8,
478 ) *const Value;498 ) *const Value;
499
500 pub const buildInsertValue = LLVMBuildInsertValue;
501 extern fn LLVMBuildInsertValue(
502 *const Builder,
503 AggVal: *const Value,
504 EltVal: *const Value,
505 Index: c_uint,
506 Name: [*:0]const u8,
507 ) *const Value;
508
509 pub const buildAtomicCmpXchg = LLVMBuildAtomicCmpXchg;
510 extern fn LLVMBuildAtomicCmpXchg(
511 builder: *const Builder,
512 ptr: *const Value,
513 cmp: *const Value,
514 new_val: *const Value,
515 success_ordering: AtomicOrdering,
516 failure_ordering: AtomicOrdering,
517 is_single_threaded: Bool,
518 ) *const Value;
519
520 pub const buildSelect = LLVMBuildSelect;
521 extern fn LLVMBuildSelect(
522 *const Builder,
523 If: *const Value,
524 Then: *const Value,
525 Else: *const Value,
526 Name: [*:0]const u8,
527 ) *const Value;
479};528};
480529
481pub const IntPredicate = enum(c_uint) {530pub const IntPredicate = enum(c_uint) {
...@@ -856,3 +905,13 @@ pub const Linkage = enum(c_uint) {...@@ -856,3 +905,13 @@ pub const Linkage = enum(c_uint) {
856 LinkerPrivate,905 LinkerPrivate,
857 LinkerPrivateWeak,906 LinkerPrivateWeak,
858};907};
908
909pub const AtomicOrdering = enum(c_uint) {
910 NotAtomic = 0,
911 Unordered = 1,
912 Monotonic = 2,
913 Acquire = 4,
914 Release = 5,
915 AcquireRelease = 6,
916 SequentiallyConsistent = 7,
917};
src/codegen/riscv64.zig+2-2
...@@ -390,7 +390,7 @@ pub const RawRegister = enum(u5) {...@@ -390,7 +390,7 @@ pub const RawRegister = enum(u5) {
390 x24, x25, x26, x27, x28, x29, x30, x31,390 x24, x25, x26, x27, x28, x29, x30, x31,
391391
392 pub fn dwarfLocOp(reg: RawRegister) u8 {392 pub fn dwarfLocOp(reg: RawRegister) u8 {
393 return @enumToInt(reg) + DW.OP_reg0;393 return @enumToInt(reg) + DW.OP.reg0;
394 }394 }
395};395};
396396
...@@ -424,7 +424,7 @@ pub const Register = enum(u5) {...@@ -424,7 +424,7 @@ pub const Register = enum(u5) {
424 }424 }
425425
426 pub fn dwarfLocOp(reg: Register) u8 {426 pub fn dwarfLocOp(reg: Register) u8 {
427 return @as(u8, @enumToInt(reg)) + DW.OP_reg0;427 return @as(u8, @enumToInt(reg)) + DW.OP.reg0;
428 }428 }
429};429};
430430
src/codegen/spirv/spec.zig+2-2
...@@ -582,8 +582,8 @@ pub const Opcode = enum(u16) {...@@ -582,8 +582,8 @@ pub const Opcode = enum(u16) {
582 OpSpecConstantCompositeContinuedINTEL = 6092,582 OpSpecConstantCompositeContinuedINTEL = 6092,
583 _,583 _,
584584
585 const OpReportIntersectionKHR = OpReportIntersectionNV;585 const OpReportIntersectionKHR: Opcode = .OpReportIntersectionNV;
586 const OpTypeAccelerationStructureKHR = OpTypeAccelerationStructureNV;586 const OpTypeAccelerationStructureKHR: Opcode = .OpTypeAccelerationStructureNV;
587};587};
588pub const ImageOperands = packed struct {588pub const ImageOperands = packed struct {
589 Bias: bool align(@alignOf(u32)) = false,589 Bias: bool align(@alignOf(u32)) = false,
src/codegen/x86.zig+8-8
...@@ -59,14 +59,14 @@ pub const Register = enum(u8) {...@@ -59,14 +59,14 @@ pub const Register = enum(u8) {
5959
60 pub fn dwarfLocOp(reg: Register) u8 {60 pub fn dwarfLocOp(reg: Register) u8 {
61 return switch (reg.to32()) {61 return switch (reg.to32()) {
62 .eax => DW.OP_reg0,62 .eax => DW.OP.reg0,
63 .ecx => DW.OP_reg1,63 .ecx => DW.OP.reg1,
64 .edx => DW.OP_reg2,64 .edx => DW.OP.reg2,
65 .ebx => DW.OP_reg3,65 .ebx => DW.OP.reg3,
66 .esp => DW.OP_reg4,66 .esp => DW.OP.reg4,
67 .ebp => DW.OP_reg5,67 .ebp => DW.OP.reg5,
68 .esi => DW.OP_reg6,68 .esi => DW.OP.reg6,
69 .edi => DW.OP_reg7,69 .edi => DW.OP.reg7,
70 else => unreachable,70 else => unreachable,
71 };71 };
72 }72 }
src/codegen/x86_64.zig+17-17
...@@ -115,23 +115,23 @@ pub const Register = enum(u8) {...@@ -115,23 +115,23 @@ pub const Register = enum(u8) {
115115
116 pub fn dwarfLocOp(self: Register) u8 {116 pub fn dwarfLocOp(self: Register) u8 {
117 return switch (self.to64()) {117 return switch (self.to64()) {
118 .rax => DW.OP_reg0,118 .rax => DW.OP.reg0,
119 .rdx => DW.OP_reg1,119 .rdx => DW.OP.reg1,
120 .rcx => DW.OP_reg2,120 .rcx => DW.OP.reg2,
121 .rbx => DW.OP_reg3,121 .rbx => DW.OP.reg3,
122 .rsi => DW.OP_reg4,122 .rsi => DW.OP.reg4,
123 .rdi => DW.OP_reg5,123 .rdi => DW.OP.reg5,
124 .rbp => DW.OP_reg6,124 .rbp => DW.OP.reg6,
125 .rsp => DW.OP_reg7,125 .rsp => DW.OP.reg7,
126126
127 .r8 => DW.OP_reg8,127 .r8 => DW.OP.reg8,
128 .r9 => DW.OP_reg9,128 .r9 => DW.OP.reg9,
129 .r10 => DW.OP_reg10,129 .r10 => DW.OP.reg10,
130 .r11 => DW.OP_reg11,130 .r11 => DW.OP.reg11,
131 .r12 => DW.OP_reg12,131 .r12 => DW.OP.reg12,
132 .r13 => DW.OP_reg13,132 .r13 => DW.OP.reg13,
133 .r14 => DW.OP_reg14,133 .r14 => DW.OP.reg14,
134 .r15 => DW.OP_reg15,134 .r15 => DW.OP.reg15,
135135
136 else => unreachable,136 else => unreachable,
137 };137 };
src/libc_installation.zig+19-13
...@@ -12,7 +12,7 @@ const is_haiku = Target.current.os.tag == .haiku;...@@ -12,7 +12,7 @@ const is_haiku = Target.current.os.tag == .haiku;
1212
13const log = std.log.scoped(.libc_installation);13const log = std.log.scoped(.libc_installation);
1414
15usingnamespace @import("windows_sdk.zig");15const ZigWindowsSDK = @import("windows_sdk.zig").ZigWindowsSDK;
1616
17/// See the render function implementation for documentation of the fields.17/// See the render function implementation for documentation of the fields.
18pub const LibCInstallation = struct {18pub const LibCInstallation = struct {
...@@ -41,6 +41,7 @@ pub const LibCInstallation = struct {...@@ -41,6 +41,7 @@ pub const LibCInstallation = struct {
41 pub fn parse(41 pub fn parse(
42 allocator: *Allocator,42 allocator: *Allocator,
43 libc_file: []const u8,43 libc_file: []const u8,
44 target: std.zig.CrossTarget,
44 ) !LibCInstallation {45 ) !LibCInstallation {
45 var self: LibCInstallation = .{};46 var self: LibCInstallation = .{};
4647
...@@ -96,26 +97,31 @@ pub const LibCInstallation = struct {...@@ -96,26 +97,31 @@ pub const LibCInstallation = struct {
96 log.err("sys_include_dir may not be empty\n", .{});97 log.err("sys_include_dir may not be empty\n", .{});
97 return error.ParseError;98 return error.ParseError;
98 }99 }
99 if (self.crt_dir == null and !is_darwin) {100
100 log.err("crt_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});101 const os_tag = target.getOsTag();
102 if (self.crt_dir == null and !target.isDarwin()) {
103 log.err("crt_dir may not be empty for {s}\n", .{@tagName(os_tag)});
101 return error.ParseError;104 return error.ParseError;
102 }105 }
103 if (self.msvc_lib_dir == null and is_windows) {106
107 const abi = target.getAbi();
108 if (self.msvc_lib_dir == null and target.isWindows() and abi == .msvc) {
104 log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{109 log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{
105 @tagName(Target.current.os.tag),110 @tagName(os_tag),
106 @tagName(Target.current.abi),111 @tagName(abi),
107 });112 });
108 return error.ParseError;113 return error.ParseError;
109 }114 }
110 if (self.kernel32_lib_dir == null and is_windows) {115 if (self.kernel32_lib_dir == null and target.isWindows() and abi == .msvc) {
111 log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{116 log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{
112 @tagName(Target.current.os.tag),117 @tagName(os_tag),
113 @tagName(Target.current.abi),118 @tagName(abi),
114 });119 });
115 return error.ParseError;120 return error.ParseError;
116 }121 }
117 if (self.gcc_dir == null and is_haiku) {122
118 log.err("gcc_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});123 if (self.gcc_dir == null and os_tag == .haiku) {
124 log.err("gcc_dir may not be empty for {s}\n", .{@tagName(os_tag)});
119 return error.ParseError;125 return error.ParseError;
120 }126 }
121127
...@@ -183,9 +189,9 @@ pub const LibCInstallation = struct {...@@ -183,9 +189,9 @@ pub const LibCInstallation = struct {
183 if (!build_options.have_llvm)189 if (!build_options.have_llvm)
184 return error.WindowsSdkNotFound;190 return error.WindowsSdkNotFound;
185 var sdk: *ZigWindowsSDK = undefined;191 var sdk: *ZigWindowsSDK = undefined;
186 switch (zig_find_windows_sdk(&sdk)) {192 switch (ZigWindowsSDK.find(&sdk)) {
187 .None => {193 .None => {
188 defer zig_free_windows_sdk(sdk);194 defer sdk.free();
189195
190 var batch = Batch(FindError!void, 5, .auto_async).init();196 var batch = Batch(FindError!void, 5, .auto_async).init();
191 batch.add(&async self.findNativeMsvcIncludeDir(args, sdk));197 batch.add(&async self.findNativeMsvcIncludeDir(args, sdk));
src/libunwind.zig+2
...@@ -71,6 +71,8 @@ pub fn buildStaticLib(comp: *Compilation) !void {...@@ -71,6 +71,8 @@ pub fn buildStaticLib(comp: *Compilation) !void {
71 try cflags.append("-Wa,--noexecstack");71 try cflags.append("-Wa,--noexecstack");
72 try cflags.append("-fvisibility=hidden");72 try cflags.append("-fvisibility=hidden");
73 try cflags.append("-fvisibility-inlines-hidden");73 try cflags.append("-fvisibility-inlines-hidden");
74 // necessary so that libunwind can unwind through its own stack frames
75 try cflags.append("-funwind-tables");
7476
75 // This is intentionally always defined because the macro definition means, should it only77 // This is intentionally always defined because the macro definition means, should it only
76 // build for the target specified by compiler defines. Since we pass -target the compiler78 // build for the target specified by compiler defines. Since we pass -target the compiler
src/link.zig+5-1
...@@ -73,6 +73,10 @@ pub const Options = struct {...@@ -73,6 +73,10 @@ pub const Options = struct {
73 rdynamic: bool,73 rdynamic: bool,
74 z_nodelete: bool,74 z_nodelete: bool,
75 z_defs: bool,75 z_defs: bool,
76 z_origin: bool,
77 z_noexecstack: bool,
78 z_now: bool,
79 z_relro: bool,
76 tsaware: bool,80 tsaware: bool,
77 nxcompat: bool,81 nxcompat: bool,
78 dynamicbase: bool,82 dynamicbase: bool,
...@@ -179,7 +183,7 @@ pub const File = struct {...@@ -179,7 +183,7 @@ pub const File = struct {
179 /// This is where the .debug_info tag for the type is.183 /// This is where the .debug_info tag for the type is.
180 off: u32,184 off: u32,
181 /// Offset from `TextBlock.dbg_info_off` (the buffer that is local to a Decl).185 /// Offset from `TextBlock.dbg_info_off` (the buffer that is local to a Decl).
182 /// List of DW.AT_type / DW.FORM_ref4 that points to the type.186 /// List of DW.AT.type / DW.FORM.ref4 that points to the type.
183 relocs: std.ArrayListUnmanaged(u32),187 relocs: std.ArrayListUnmanaged(u32),
184 };188 };
185189
src/link/C/zig.h+12
...@@ -60,6 +60,18 @@...@@ -60,6 +60,18 @@
60#define zig_breakpoint() raise(SIGTRAP)60#define zig_breakpoint() raise(SIGTRAP)
61#endif61#endif
6262
63#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
64#include <stdatomic.h>
65#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail)
66#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail)
67#elif __GNUC__
68#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) __sync_val_compare_and_swap(obj, expected, desired)
69#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) __sync_val_compare_and_swap(obj, expected, desired)
70#else
71#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) zig_unimplemented()
72#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) zig_unimplemented()
73#endif
74
63#include <stdint.h>75#include <stdint.h>
64#include <stddef.h>76#include <stddef.h>
65#include <limits.h>77#include <limits.h>
src/link/Elf.zig+96-76
...@@ -772,48 +772,48 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -772,48 +772,48 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
772 // These are LEB encoded but since the values are all less than 127772 // These are LEB encoded but since the values are all less than 127
773 // we can simply append these bytes.773 // we can simply append these bytes.
774 const abbrev_buf = [_]u8{774 const abbrev_buf = [_]u8{
775 abbrev_compile_unit, DW.TAG_compile_unit, DW.CHILDREN_yes, // header775 abbrev_compile_unit, DW.TAG.compile_unit, DW.CHILDREN.yes, // header
776 DW.AT_stmt_list, DW.FORM_sec_offset, DW.AT_low_pc,776 DW.AT.stmt_list, DW.FORM.sec_offset, DW.AT.low_pc,
777 DW.FORM_addr, DW.AT_high_pc, DW.FORM_addr,777 DW.FORM.addr, DW.AT.high_pc, DW.FORM.addr,
778 DW.AT_name, DW.FORM_strp, DW.AT_comp_dir,778 DW.AT.name, DW.FORM.strp, DW.AT.comp_dir,
779 DW.FORM_strp, DW.AT_producer, DW.FORM_strp,779 DW.FORM.strp, DW.AT.producer, DW.FORM.strp,
780 DW.AT_language, DW.FORM_data2, 0,780 DW.AT.language, DW.FORM.data2, 0,
781 0, // table sentinel781 0, // table sentinel
782 abbrev_subprogram,782 abbrev_subprogram,
783 DW.TAG_subprogram,783 DW.TAG.subprogram,
784 DW.CHILDREN_yes, // header784 DW.CHILDREN.yes, // header
785 DW.AT_low_pc,785 DW.AT.low_pc,
786 DW.FORM_addr,786 DW.FORM.addr,
787 DW.AT_high_pc,787 DW.AT.high_pc,
788 DW.FORM_data4,788 DW.FORM.data4,
789 DW.AT_type,789 DW.AT.type,
790 DW.FORM_ref4,790 DW.FORM.ref4,
791 DW.AT_name,791 DW.AT.name,
792 DW.FORM_string,792 DW.FORM.string,
793 0, 0, // table sentinel793 0, 0, // table sentinel
794 abbrev_subprogram_retvoid,794 abbrev_subprogram_retvoid,
795 DW.TAG_subprogram, DW.CHILDREN_yes, // header795 DW.TAG.subprogram, DW.CHILDREN.yes, // header
796 DW.AT_low_pc, DW.FORM_addr,796 DW.AT.low_pc, DW.FORM.addr,
797 DW.AT_high_pc, DW.FORM_data4,797 DW.AT.high_pc, DW.FORM.data4,
798 DW.AT_name, DW.FORM_string,798 DW.AT.name, DW.FORM.string,
799 0,799 0,
800 0, // table sentinel800 0, // table sentinel
801 abbrev_base_type,801 abbrev_base_type,
802 DW.TAG_base_type,802 DW.TAG.base_type,
803 DW.CHILDREN_no, // header803 DW.CHILDREN.no, // header
804 DW.AT_encoding,804 DW.AT.encoding,
805 DW.FORM_data1,805 DW.FORM.data1,
806 DW.AT_byte_size,806 DW.AT.byte_size,
807 DW.FORM_data1,807 DW.FORM.data1,
808 DW.AT_name,808 DW.AT.name,
809 DW.FORM_string, 0, 0, // table sentinel809 DW.FORM.string, 0, 0, // table sentinel
810 abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header810 abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header
811 0, 0, // table sentinel811 0, 0, // table sentinel
812 abbrev_parameter,812 abbrev_parameter,
813 DW.TAG_formal_parameter, DW.CHILDREN_no, // header813 DW.TAG.formal_parameter, DW.CHILDREN.no, // header
814 DW.AT_location, DW.FORM_exprloc,814 DW.AT.location, DW.FORM.exprloc,
815 DW.AT_type, DW.FORM_ref4,815 DW.AT.type, DW.FORM.ref4,
816 DW.AT_name, DW.FORM_string,816 DW.AT.name, DW.FORM.string,
817 0,817 0,
818 0, // table sentinel818 0, // table sentinel
819 0,819 0,
...@@ -897,7 +897,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -897,7 +897,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
897 const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;897 const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;
898898
899 di_buf.appendAssumeCapacity(abbrev_compile_unit);899 di_buf.appendAssumeCapacity(abbrev_compile_unit);
900 self.writeDwarfAddrAssumeCapacity(&di_buf, 0); // DW.AT_stmt_list, DW.FORM_sec_offset900 self.writeDwarfAddrAssumeCapacity(&di_buf, 0); // DW.AT.stmt_list, DW.FORM.sec_offset
901 self.writeDwarfAddrAssumeCapacity(&di_buf, low_pc);901 self.writeDwarfAddrAssumeCapacity(&di_buf, low_pc);
902 self.writeDwarfAddrAssumeCapacity(&di_buf, high_pc);902 self.writeDwarfAddrAssumeCapacity(&di_buf, high_pc);
903 self.writeDwarfAddrAssumeCapacity(&di_buf, name_strp);903 self.writeDwarfAddrAssumeCapacity(&di_buf, name_strp);
...@@ -906,7 +906,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -906,7 +906,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
906 // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number:906 // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number:
907 // http://dwarfstd.org/ShowIssue.php?issue=171115.1907 // http://dwarfstd.org/ShowIssue.php?issue=171115.1
908 // Until then we say it is C99.908 // Until then we say it is C99.
909 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG_C99, target_endian);909 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG.C99, target_endian);
910910
911 if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) {911 if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) {
912 // Move the first N decls to the end to make more padding for the header.912 // Move the first N decls to the end to make more padding for the header.
...@@ -1030,7 +1030,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -1030,7 +1030,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
1030 di_buf.items.len += ptr_width_bytes; // We will come back and write this.1030 di_buf.items.len += ptr_width_bytes; // We will come back and write this.
1031 const after_header_len = di_buf.items.len;1031 const after_header_len = di_buf.items.len;
10321032
1033 const opcode_base = DW.LNS_set_isa + 1;1033 const opcode_base = DW.LNS.set_isa + 1;
1034 di_buf.appendSliceAssumeCapacity(&[_]u8{1034 di_buf.appendSliceAssumeCapacity(&[_]u8{
1035 1, // minimum_instruction_length1035 1, // minimum_instruction_length
1036 1, // maximum_operations_per_instruction1036 1, // maximum_operations_per_instruction
...@@ -1041,18 +1041,18 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -1041,18 +1041,18 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
10411041
1042 // Standard opcode lengths. The number of items here is based on `opcode_base`.1042 // Standard opcode lengths. The number of items here is based on `opcode_base`.
1043 // The value is the number of LEB128 operands the instruction takes.1043 // The value is the number of LEB128 operands the instruction takes.
1044 0, // `DW.LNS_copy`1044 0, // `DW.LNS.copy`
1045 1, // `DW.LNS_advance_pc`1045 1, // `DW.LNS.advance_pc`
1046 1, // `DW.LNS_advance_line`1046 1, // `DW.LNS.advance_line`
1047 1, // `DW.LNS_set_file`1047 1, // `DW.LNS.set_file`
1048 1, // `DW.LNS_set_column`1048 1, // `DW.LNS.set_column`
1049 0, // `DW.LNS_negate_stmt`1049 0, // `DW.LNS.negate_stmt`
1050 0, // `DW.LNS_set_basic_block`1050 0, // `DW.LNS.set_basic_block`
1051 0, // `DW.LNS_const_add_pc`1051 0, // `DW.LNS.const_add_pc`
1052 1, // `DW.LNS_fixed_advance_pc`1052 1, // `DW.LNS.fixed_advance_pc`
1053 0, // `DW.LNS_set_prologue_end`1053 0, // `DW.LNS.set_prologue_end`
1054 0, // `DW.LNS_set_epilogue_begin`1054 0, // `DW.LNS.set_epilogue_begin`
1055 1, // `DW.LNS_set_isa`1055 1, // `DW.LNS.set_isa`
1056 0, // include_directories (none except the compilation unit cwd)1056 0, // include_directories (none except the compilation unit cwd)
1057 });1057 });
1058 // file_names[0]1058 // file_names[0]
...@@ -1345,6 +1345,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1345,6 +1345,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1345 man.hash.add(self.base.options.skip_linker_dependencies);1345 man.hash.add(self.base.options.skip_linker_dependencies);
1346 man.hash.add(self.base.options.z_nodelete);1346 man.hash.add(self.base.options.z_nodelete);
1347 man.hash.add(self.base.options.z_defs);1347 man.hash.add(self.base.options.z_defs);
1348 man.hash.add(self.base.options.z_origin);
1349 man.hash.add(self.base.options.z_noexecstack);
1350 man.hash.add(self.base.options.z_now);
1351 man.hash.add(self.base.options.z_relro);
1348 if (self.base.options.link_libc) {1352 if (self.base.options.link_libc) {
1349 man.hash.add(self.base.options.libc_installation != null);1353 man.hash.add(self.base.options.libc_installation != null);
1350 if (self.base.options.libc_installation) |libc_installation| {1354 if (self.base.options.libc_installation) |libc_installation| {
...@@ -1482,6 +1486,22 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1482,6 +1486,22 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1482 try argv.append("-z");1486 try argv.append("-z");
1483 try argv.append("defs");1487 try argv.append("defs");
1484 }1488 }
1489 if (self.base.options.z_origin) {
1490 try argv.append("-z");
1491 try argv.append("origin");
1492 }
1493 if (self.base.options.z_noexecstack) {
1494 try argv.append("-z");
1495 try argv.append("noexecstack");
1496 }
1497 if (self.base.options.z_now) {
1498 try argv.append("-z");
1499 try argv.append("now");
1500 }
1501 if (self.base.options.z_relro) {
1502 try argv.append("-z");
1503 try argv.append("relro");
1504 }
14851505
1486 if (getLDMOption(target)) |ldm| {1506 if (getLDMOption(target)) |ldm| {
1487 // Any target ELF will use the freebsd osabi if suffixed with "_fbsd".1507 // Any target ELF will use the freebsd osabi if suffixed with "_fbsd".
...@@ -2053,7 +2073,7 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al...@@ -2053,7 +2073,7 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al
20532073
2054 // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address2074 // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address
2055 // range of the compilation unit. When we expand the text section, this range changes,2075 // range of the compilation unit. When we expand the text section, this range changes,
2056 // so the DW_TAG_compile_unit tag of the .debug_info section becomes dirty.2076 // so the DW_TAG.compile_unit tag of the .debug_info section becomes dirty.
2057 self.debug_info_header_dirty = true;2077 self.debug_info_header_dirty = true;
2058 // This becomes dirty for the same reason. We could potentially make this more2078 // This becomes dirty for the same reason. We could potentially make this more
2059 // fine-grained with the addition of support for more compilation units. It is planned to2079 // fine-grained with the addition of support for more compilation units. It is planned to
...@@ -2303,22 +2323,22 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2303,22 +2323,22 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
23032323
2304 const ptr_width_bytes = self.ptrWidthBytes();2324 const ptr_width_bytes = self.ptrWidthBytes();
2305 dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{2325 dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{
2306 DW.LNS_extended_op,2326 DW.LNS.extended_op,
2307 ptr_width_bytes + 1,2327 ptr_width_bytes + 1,
2308 DW.LNE_set_address,2328 DW.LNE.set_address,
2309 });2329 });
2310 // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`.2330 // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`.
2311 assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len);2331 assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len);
2312 dbg_line_buffer.items.len += ptr_width_bytes;2332 dbg_line_buffer.items.len += ptr_width_bytes;
23132333
2314 dbg_line_buffer.appendAssumeCapacity(DW.LNS_advance_line);2334 dbg_line_buffer.appendAssumeCapacity(DW.LNS.advance_line);
2315 // This is the "relocatable" relative line offset from the previous function's end curly2335 // This is the "relocatable" relative line offset from the previous function's end curly
2316 // to this function's begin curly.2336 // to this function's begin curly.
2317 assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len);2337 assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len);
2318 // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later.2338 // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later.
2319 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off);2339 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off);
23202340
2321 dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file);2341 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_file);
2322 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);2342 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);
2323 // Once we support more than one source file, this will have the ability to be more2343 // Once we support more than one source file, this will have the ability to be more
2324 // than one possible value.2344 // than one possible value.
...@@ -2327,7 +2347,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2327,7 +2347,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
23272347
2328 // Emit a line for the begin curly with prologue_end=false. The codegen will2348 // Emit a line for the begin curly with prologue_end=false. The codegen will
2329 // do the work of setting prologue_end=true and epilogue_begin=true.2349 // do the work of setting prologue_end=true and epilogue_begin=true.
2330 dbg_line_buffer.appendAssumeCapacity(DW.LNS_copy);2350 dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);
23312351
2332 // .debug_info subprogram2352 // .debug_info subprogram
2333 const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];2353 const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];
...@@ -2344,9 +2364,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2344,9 +2364,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
2344 // "relocations" and have to be in this fixed place so that functions can be2364 // "relocations" and have to be in this fixed place so that functions can be
2345 // moved in virtual address space.2365 // moved in virtual address space.
2346 assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len);2366 assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len);
2347 dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT_low_pc, DW.FORM_addr2367 dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT.low_pc, DW.FORM.addr
2348 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);2368 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);
2349 dbg_info_buffer.items.len += 4; // DW.AT_high_pc, DW.FORM_data42369 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4
2350 if (fn_ret_has_bits) {2370 if (fn_ret_has_bits) {
2351 const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, fn_ret_type);2371 const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, fn_ret_type);
2352 if (!gop.found_existing) {2372 if (!gop.found_existing) {
...@@ -2356,9 +2376,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2356,9 +2376,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
2356 };2376 };
2357 }2377 }
2358 try gop.value_ptr.relocs.append(self.base.allocator, @intCast(u32, dbg_info_buffer.items.len));2378 try gop.value_ptr.relocs.append(self.base.allocator, @intCast(u32, dbg_info_buffer.items.len));
2359 dbg_info_buffer.items.len += 4; // DW.AT_type, DW.FORM_ref42379 dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4
2360 }2380 }
2361 dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT_name, DW.FORM_string2381 dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT.name, DW.FORM.string
23622382
2363 const res = try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{2383 const res = try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
2364 .dwarf = .{2384 .dwarf = .{
...@@ -2409,7 +2429,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2409,7 +2429,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
2409 mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_size), target_endian);2429 mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_size), target_endian);
2410 }2430 }
24112431
2412 try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS_extended_op, 1, DW.LNE_end_sequence });2432 try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence });
24132433
2414 // Now we have the full contents and may allocate a region to store it.2434 // Now we have the full contents and may allocate a region to store it.
24152435
...@@ -2493,7 +2513,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2493,7 +2513,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
2493 const file_pos = debug_line_sect.sh_offset + src_fn.off;2513 const file_pos = debug_line_sect.sh_offset + src_fn.off;
2494 try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos);2514 try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos);
24952515
2496 // .debug_info - End the TAG_subprogram children.2516 // .debug_info - End the TAG.subprogram children.
2497 try dbg_info_buffer.append(0);2517 try dbg_info_buffer.append(0);
24982518
2499 return self.finishUpdateDecl(module, decl, &dbg_info_type_relocs, &dbg_info_buffer);2519 return self.finishUpdateDecl(module, decl, &dbg_info_type_relocs, &dbg_info_buffer);
...@@ -2566,34 +2586,34 @@ fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !vo...@@ -2566,34 +2586,34 @@ fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !vo
2566 .Bool => {2586 .Bool => {
2567 try dbg_info_buffer.appendSlice(&[_]u8{2587 try dbg_info_buffer.appendSlice(&[_]u8{
2568 abbrev_base_type,2588 abbrev_base_type,
2569 DW.ATE_boolean, // DW.AT_encoding , DW.FORM_data12589 DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1
2570 1, // DW.AT_byte_size, DW.FORM_data12590 1, // DW.AT.byte_size, DW.FORM.data1
2571 'b', 'o', 'o', 'l', 0, // DW.AT_name, DW.FORM_string2591 'b', 'o', 'o', 'l', 0, // DW.AT.name, DW.FORM.string
2572 });2592 });
2573 },2593 },
2574 .Int => {2594 .Int => {
2575 const info = ty.intInfo(self.base.options.target);2595 const info = ty.intInfo(self.base.options.target);
2576 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);2596 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);
2577 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);2597 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
2578 // DW.AT_encoding, DW.FORM_data12598 // DW.AT.encoding, DW.FORM.data1
2579 dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {2599 dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {
2580 .signed => DW.ATE_signed,2600 .signed => DW.ATE.signed,
2581 .unsigned => DW.ATE_unsigned,2601 .unsigned => DW.ATE.unsigned,
2582 });2602 });
2583 // DW.AT_byte_size, DW.FORM_data12603 // DW.AT.byte_size, DW.FORM.data1
2584 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target)));2604 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target)));
2585 // DW.AT_name, DW.FORM_string2605 // DW.AT.name, DW.FORM.string
2586 try dbg_info_buffer.writer().print("{}\x00", .{ty});2606 try dbg_info_buffer.writer().print("{}\x00", .{ty});
2587 },2607 },
2588 .Optional => {2608 .Optional => {
2589 if (ty.isPtrLikeOptional()) {2609 if (ty.isPtrLikeOptional()) {
2590 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);2610 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);
2591 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);2611 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
2592 // DW.AT_encoding, DW.FORM_data12612 // DW.AT.encoding, DW.FORM.data1
2593 dbg_info_buffer.appendAssumeCapacity(DW.ATE_address);2613 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);
2594 // DW.AT_byte_size, DW.FORM_data12614 // DW.AT.byte_size, DW.FORM.data1
2595 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target)));2615 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target)));
2596 // DW.AT_name, DW.FORM_string2616 // DW.AT.name, DW.FORM.string
2597 try dbg_info_buffer.writer().print("{}\x00", .{ty});2617 try dbg_info_buffer.writer().print("{}\x00", .{ty});
2598 } else {2618 } else {
2599 log.err("TODO implement .debug_info for type '{}'", .{ty});2619 log.err("TODO implement .debug_info for type '{}'", .{ty});
...@@ -3034,7 +3054,7 @@ fn archPtrWidthBytes(self: Elf) u8 {...@@ -3034,7 +3054,7 @@ fn archPtrWidthBytes(self: Elf) u8 {
3034/// The reloc offset for the virtual address of a function in its Line Number Program.3054/// The reloc offset for the virtual address of a function in its Line Number Program.
3035/// Size is a virtual address integer.3055/// Size is a virtual address integer.
3036const dbg_line_vaddr_reloc_index = 3;3056const dbg_line_vaddr_reloc_index = 3;
3037/// The reloc offset for the virtual address of a function in its .debug_info TAG_subprogram.3057/// The reloc offset for the virtual address of a function in its .debug_info TAG.subprogram.
3038/// Size is a virtual address integer.3058/// Size is a virtual address integer.
3039const dbg_info_low_pc_reloc_index = 1;3059const dbg_info_low_pc_reloc_index = 1;
30403060
...@@ -3060,7 +3080,7 @@ fn dbgLineNeededHeaderBytes(self: Elf) u32 {...@@ -3060,7 +3080,7 @@ fn dbgLineNeededHeaderBytes(self: Elf) u32 {
3060 const root_src_dir_path_len = if (self.base.options.module.?.root_pkg.root_src_directory.path) |p| p.len else 1; // "."3080 const root_src_dir_path_len = if (self.base.options.module.?.root_pkg.root_src_directory.path) |p| p.len else 1; // "."
3061 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +3081 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +
3062 directory_count * 8 + file_name_count * 8 +3082 directory_count * 8 + file_name_count * 8 +
3063 // These are encoded as DW.FORM_string rather than DW.FORM_strp as we would like3083 // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like
3064 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.3084 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.
3065 root_src_dir_path_len +3085 root_src_dir_path_len +
3066 self.base.options.module.?.root_pkg.root_src_path.len);3086 self.base.options.module.?.root_pkg.root_src_path.len);
...@@ -3088,8 +3108,8 @@ fn pwriteDbgLineNops(...@@ -3088,8 +3108,8 @@ fn pwriteDbgLineNops(
3088 const tracy = trace(@src());3108 const tracy = trace(@src());
3089 defer tracy.end();3109 defer tracy.end();
30903110
3091 const page_of_nops = [1]u8{DW.LNS_negate_stmt} ** 4096;3111 const page_of_nops = [1]u8{DW.LNS.negate_stmt} ** 4096;
3092 const three_byte_nop = [3]u8{ DW.LNS_advance_pc, 0b1000_0000, 0 };3112 const three_byte_nop = [3]u8{ DW.LNS.advance_pc, 0b1000_0000, 0 };
3093 var vecs: [512]std.os.iovec_const = undefined;3113 var vecs: [512]std.os.iovec_const = undefined;
3094 var vec_index: usize = 0;3114 var vec_index: usize = 0;
3095 {3115 {
src/link/MachO.zig+3222-4156
...@@ -24,6 +24,7 @@ const trace = @import("../tracy.zig").trace;...@@ -24,6 +24,7 @@ const trace = @import("../tracy.zig").trace;
24const Air = @import("../Air.zig");24const Air = @import("../Air.zig");
25const Allocator = mem.Allocator;25const Allocator = mem.Allocator;
26const Archive = @import("MachO/Archive.zig");26const Archive = @import("MachO/Archive.zig");
27const Atom = @import("MachO/Atom.zig");
27const Cache = @import("../Cache.zig");28const Cache = @import("../Cache.zig");
28const CodeSignature = @import("MachO/CodeSignature.zig");29const CodeSignature = @import("MachO/CodeSignature.zig");
29const Compilation = @import("../Compilation.zig");30const Compilation = @import("../Compilation.zig");
...@@ -37,9 +38,12 @@ const LlvmObject = @import("../codegen/llvm.zig").Object;...@@ -37,9 +38,12 @@ const LlvmObject = @import("../codegen/llvm.zig").Object;
37const LoadCommand = commands.LoadCommand;38const LoadCommand = commands.LoadCommand;
38const Module = @import("../Module.zig");39const Module = @import("../Module.zig");
39const SegmentCommand = commands.SegmentCommand;40const SegmentCommand = commands.SegmentCommand;
40pub const TextBlock = @import("MachO/TextBlock.zig");41const StringIndexAdapter = std.hash_map.StringIndexAdapter;
42const StringIndexContext = std.hash_map.StringIndexContext;
41const Trie = @import("MachO/Trie.zig");43const Trie = @import("MachO/Trie.zig");
4244
45pub const TextBlock = Atom;
46
43pub const base_tag: File.Tag = File.Tag.macho;47pub const base_tag: File.Tag = File.Tag.macho;
4448
45base: File,49base: File,
...@@ -93,9 +97,6 @@ source_version_cmd_index: ?u16 = null,...@@ -93,9 +97,6 @@ source_version_cmd_index: ?u16 = null,
93build_version_cmd_index: ?u16 = null,97build_version_cmd_index: ?u16 = null,
94uuid_cmd_index: ?u16 = null,98uuid_cmd_index: ?u16 = null,
95code_signature_cmd_index: ?u16 = null,99code_signature_cmd_index: ?u16 = null,
96/// Path to libSystem
97/// TODO this is obsolete, remove it.
98libsystem_cmd_index: ?u16 = null,
99100
100// __TEXT segment sections101// __TEXT segment sections
101text_section_index: ?u16 = null,102text_section_index: ?u16 = null,
...@@ -130,65 +131,59 @@ tlv_bss_section_index: ?u16 = null,...@@ -130,65 +131,59 @@ tlv_bss_section_index: ?u16 = null,
130la_symbol_ptr_section_index: ?u16 = null,131la_symbol_ptr_section_index: ?u16 = null,
131data_section_index: ?u16 = null,132data_section_index: ?u16 = null,
132bss_section_index: ?u16 = null,133bss_section_index: ?u16 = null,
133common_section_index: ?u16 = null,
134134
135objc_const_section_index: ?u16 = null,135objc_const_section_index: ?u16 = null,
136objc_selrefs_section_index: ?u16 = null,136objc_selrefs_section_index: ?u16 = null,
137objc_classrefs_section_index: ?u16 = null,137objc_classrefs_section_index: ?u16 = null,
138objc_data_section_index: ?u16 = null,138objc_data_section_index: ?u16 = null,
139139
140bss_file_offset: u32 = 0,
141tlv_bss_file_offset: u32 = 0,
142
140locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},143locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
141globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},144globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
142undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},145undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},
143symbol_resolver: std.AutoHashMapUnmanaged(u32, SymbolWithLoc) = .{},146symbol_resolver: std.AutoHashMapUnmanaged(u32, SymbolWithLoc) = .{},
147unresolved: std.AutoArrayHashMapUnmanaged(u32, enum {
148 none,
149 stub,
150 got,
151}) = .{},
152tentatives: std.AutoArrayHashMapUnmanaged(u32, void) = .{},
144153
145locals_free_list: std.ArrayListUnmanaged(u32) = .{},154locals_free_list: std.ArrayListUnmanaged(u32) = .{},
146globals_free_list: std.ArrayListUnmanaged(u32) = .{},155globals_free_list: std.ArrayListUnmanaged(u32) = .{},
147156
148stub_helper_stubs_start_off: ?u64 = null,157dyld_stub_binder_index: ?u32 = null,
158dyld_private_atom: ?*Atom = null,
159stub_helper_preamble_atom: ?*Atom = null,
149160
150strtab: std.ArrayListUnmanaged(u8) = .{},161strtab: std.ArrayListUnmanaged(u8) = .{},
151strtab_dir: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},162strtab_dir: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
152163
153got_entries: std.ArrayListUnmanaged(GotIndirectionKey) = .{},164got_entries_map: std.AutoArrayHashMapUnmanaged(GotIndirectionKey, *Atom) = .{},
154got_entries_map: std.AutoHashMapUnmanaged(GotIndirectionKey, u32) = .{},165stubs_map: std.AutoArrayHashMapUnmanaged(u32, *Atom) = .{},
155
156got_entries_free_list: std.ArrayListUnmanaged(u32) = .{},
157
158stubs: std.ArrayListUnmanaged(u32) = .{},
159stubs_map: std.AutoHashMapUnmanaged(u32, u32) = .{},
160166
161error_flags: File.ErrorFlags = File.ErrorFlags{},167error_flags: File.ErrorFlags = File.ErrorFlags{},
162168
163got_entries_count_dirty: bool = false,
164load_commands_dirty: bool = false,169load_commands_dirty: bool = false,
165rebase_info_dirty: bool = false,170sections_order_dirty: bool = false,
166binding_info_dirty: bool = false,
167lazy_binding_info_dirty: bool = false,
168export_info_dirty: bool = false,
169
170strtab_dirty: bool = false,
171strtab_needs_relocation: bool = false,
172
173has_dices: bool = false,171has_dices: bool = false,
174has_stabs: bool = false,172has_stabs: bool = false,
173/// A helper var to indicate if we are at the start of the incremental updates, or
174/// already somewhere further along the update-and-run chain.
175/// TODO once we add opening a prelinked output binary from file, this will become
176/// obsolete as we will carry on where we left off.
177cold_start: bool = false,
175178
176section_ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{},179section_ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{},
177180
178pending_updates: std.ArrayListUnmanaged(struct {181/// A list of atoms that have surplus capacity. This list can have false
179 kind: enum {
180 got,
181 stub,
182 },
183 index: u32,
184}) = .{},
185
186/// A list of text blocks that have surplus capacity. This list can have false
187/// positives, as functions grow and shrink over time, only sometimes being added182/// positives, as functions grow and shrink over time, only sometimes being added
188/// or removed from the freelist.183/// or removed from the freelist.
189///184///
190/// A text block has surplus capacity when its overcapacity value is greater than185/// An atom has surplus capacity when its overcapacity value is greater than
191/// padToIdeal(minimum_text_block_size). That is, when it has so186/// padToIdeal(minimum_atom_size). That is, when it has so
192/// much extra capacity, that we could fit a small new symbol in it, itself with187/// much extra capacity, that we could fit a small new symbol in it, itself with
193/// ideal_capacity or more.188/// ideal_capacity or more.
194///189///
...@@ -196,25 +191,23 @@ pending_updates: std.ArrayListUnmanaged(struct {...@@ -196,25 +191,23 @@ pending_updates: std.ArrayListUnmanaged(struct {
196///191///
197/// Overcapacity is measured by actual_capacity - ideal_capacity. Note that192/// Overcapacity is measured by actual_capacity - ideal_capacity. Note that
198/// overcapacity can be negative. A simple way to have negative overcapacity is to193/// overcapacity can be negative. A simple way to have negative overcapacity is to
199/// allocate a fresh text block, which will have ideal capacity, and then grow it194/// allocate a fresh atom, which will have ideal capacity, and then grow it
200/// by 1 byte. It will then have -1 overcapacity.195/// by 1 byte. It will then have -1 overcapacity.
201text_block_free_list: std.ArrayListUnmanaged(*TextBlock) = .{},196atom_free_lists: std.AutoHashMapUnmanaged(MatchingSection, std.ArrayListUnmanaged(*Atom)) = .{},
202197
203/// Pointer to the last allocated text block198/// Pointer to the last allocated atom
204last_text_block: ?*TextBlock = null,199atoms: std.AutoHashMapUnmanaged(MatchingSection, *Atom) = .{},
205200
206/// List of TextBlocks that are owned directly by the linker.201/// List of atoms that are owned directly by the linker.
207/// Currently these are only TextBlocks that are the result of linking202/// Currently these are only atoms that are the result of linking
208/// object files. TextBlock which take part in incremental linking are 203/// object files. Atoms which take part in incremental linking are
209/// at present owned by Module.Decl.204/// at present owned by Module.Decl.
210/// TODO consolidate this.205/// TODO consolidate this.
211managed_blocks: std.ArrayListUnmanaged(*TextBlock) = .{},206managed_atoms: std.ArrayListUnmanaged(*Atom) = .{},
212
213blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{},
214207
215/// Table of Decls that are currently alive.208/// Table of Decls that are currently alive.
216/// We store them here so that we can properly dispose of any allocated209/// We store them here so that we can properly dispose of any allocated
217/// memory within the TextBlock in the incremental linker.210/// memory within the atom in the incremental linker.
218/// TODO consolidate this.211/// TODO consolidate this.
219decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},212decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},
220213
...@@ -224,31 +217,10 @@ decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},...@@ -224,31 +217,10 @@ decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},
224/// somewhere else in the codegen.217/// somewhere else in the codegen.
225active_decl: ?*Module.Decl = null,218active_decl: ?*Module.Decl = null,
226219
227const StringIndexContext = struct {220const PendingUpdate = union(enum) {
228 strtab: *std.ArrayListUnmanaged(u8),221 resolve_undef: u32,
229222 add_stub_entry: u32,
230 pub fn eql(_: StringIndexContext, a: u32, b: u32) bool {223 add_got_entry: u32,
231 return a == b;
232 }
233
234 pub fn hash(self: StringIndexContext, x: u32) u64 {
235 const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr) + x);
236 return std.hash_map.hashString(x_slice);
237 }
238};
239
240pub const StringSliceAdapter = struct {
241 strtab: *std.ArrayListUnmanaged(u8),
242
243 pub fn eql(self: StringSliceAdapter, a_slice: []const u8, b: u32) bool {
244 const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr) + b);
245 return mem.eql(u8, a_slice, b_slice);
246 }
247
248 pub fn hash(self: StringSliceAdapter, adapted_key: []const u8) u64 {
249 _ = self;
250 return std.hash_map.hashString(adapted_key);
251 }
252};224};
253225
254const SymbolWithLoc = struct {226const SymbolWithLoc = struct {
...@@ -272,21 +244,10 @@ pub const GotIndirectionKey = struct {...@@ -272,21 +244,10 @@ pub const GotIndirectionKey = struct {
272244
273/// When allocating, the ideal_capacity is calculated by245/// When allocating, the ideal_capacity is calculated by
274/// actual_capacity + (actual_capacity / ideal_factor)246/// actual_capacity + (actual_capacity / ideal_factor)
275const ideal_factor = 2;247const ideal_factor = 4;
276248
277/// Default path to dyld249/// Default path to dyld
278/// TODO instead of hardcoding it, we should probably look through some env vars and search paths250const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld";
279/// instead but this will do for now.
280const DEFAULT_DYLD_PATH: [*:0]const u8 = "/usr/lib/dyld";
281
282/// Default lib search path
283/// TODO instead of hardcoding it, we should probably look through some env vars and search paths
284/// instead but this will do for now.
285const DEFAULT_LIB_SEARCH_PATH: []const u8 = "/usr/lib";
286
287const LIB_SYSTEM_NAME: [*:0]const u8 = "System";
288/// TODO we should search for libSystem and fail if it doesn't exist, instead of hardcoding it
289const LIB_SYSTEM_PATH: [*:0]const u8 = DEFAULT_LIB_SEARCH_PATH ++ "/libSystem.B.dylib";
290251
291/// In order for a slice of bytes to be considered eligible to keep metadata pointing at252/// In order for a slice of bytes to be considered eligible to keep metadata pointing at
292/// it as a possible place to put new symbols, it must have enough room for this many bytes253/// it as a possible place to put new symbols, it must have enough room for this many bytes
...@@ -294,6 +255,10 @@ const LIB_SYSTEM_PATH: [*:0]const u8 = DEFAULT_LIB_SEARCH_PATH ++ "/libSystem.B....@@ -294,6 +255,10 @@ const LIB_SYSTEM_PATH: [*:0]const u8 = DEFAULT_LIB_SEARCH_PATH ++ "/libSystem.B.
294const minimum_text_block_size = 64;255const minimum_text_block_size = 64;
295pub const min_text_capacity = padToIdeal(minimum_text_block_size);256pub const min_text_capacity = padToIdeal(minimum_text_block_size);
296257
258/// Virtual memory offset corresponds to the size of __PAGEZERO segment and start of
259/// __TEXT segment.
260const pagezero_vmsize: u64 = 0x100000000;
261
297pub const Export = struct {262pub const Export = struct {
298 sym_index: ?u32 = null,263 sym_index: ?u32 = null,
299};264};
...@@ -348,31 +313,32 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio...@@ -348,31 +313,32 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
348 return self;313 return self;
349 }314 }
350315
351 if (!options.strip and options.module != null) {316 // TODO Migrate DebugSymbols to the merged linker codepaths
352 // Create dSYM bundle.317 // if (!options.strip and options.module != null) {
353 const dir = options.module.?.zig_cache_artifact_directory;318 // // Create dSYM bundle.
354 log.debug("creating {s}.dSYM bundle in {s}", .{ sub_path, dir.path });319 // const dir = options.module.?.zig_cache_artifact_directory;
320 // log.debug("creating {s}.dSYM bundle in {s}", .{ sub_path, dir.path });
355321
356 const d_sym_path = try fmt.allocPrint(322 // const d_sym_path = try fmt.allocPrint(
357 allocator,323 // allocator,
358 "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF",324 // "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF",
359 .{sub_path},325 // .{sub_path},
360 );326 // );
361 defer allocator.free(d_sym_path);327 // defer allocator.free(d_sym_path);
362328
363 var d_sym_bundle = try dir.handle.makeOpenPath(d_sym_path, .{});329 // var d_sym_bundle = try dir.handle.makeOpenPath(d_sym_path, .{});
364 defer d_sym_bundle.close();330 // defer d_sym_bundle.close();
365331
366 const d_sym_file = try d_sym_bundle.createFile(sub_path, .{332 // const d_sym_file = try d_sym_bundle.createFile(sub_path, .{
367 .truncate = false,333 // .truncate = false,
368 .read = true,334 // .read = true,
369 });335 // });
370336
371 self.d_sym = .{337 // self.d_sym = .{
372 .base = self,338 // .base = self,
373 .file = d_sym_file,339 // .file = d_sym_file,
374 };340 // };
375 }341 // }
376342
377 // Index 0 is always a null symbol.343 // Index 0 is always a null symbol.
378 try self.locals.append(allocator, .{344 try self.locals.append(allocator, .{
...@@ -382,13 +348,12 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio...@@ -382,13 +348,12 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
382 .n_desc = 0,348 .n_desc = 0,
383 .n_value = 0,349 .n_value = 0,
384 });350 });
351 try self.strtab.append(allocator, 0);
385352
386 try self.populateMissingMetadata();353 try self.populateMissingMetadata();
387 try self.writeLocalSymbol(0);
388354
389 if (self.d_sym) |*ds| {355 if (self.d_sym) |*ds| {
390 try ds.populateMissingMetadata(allocator);356 try ds.populateMissingMetadata(allocator);
391 try ds.writeLocalSymbol(0);
392 }357 }
393358
394 return self;359 return self;
...@@ -428,167 +393,6 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {...@@ -428,167 +393,6 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {
428 }393 }
429 }394 }
430395
431 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
432 if (use_stage1) {
433 return self.linkWithZld(comp);
434 } else {
435 switch (self.base.options.effectiveOutputMode()) {
436 .Exe, .Obj => {},
437 .Lib => return error.TODOImplementWritingLibFiles,
438 }
439 return self.flushModule(comp);
440 }
441}
442
443pub fn flushModule(self: *MachO, comp: *Compilation) !void {
444 _ = comp;
445 const tracy = trace(@src());
446 defer tracy.end();
447
448 const output_mode = self.base.options.output_mode;
449
450 switch (output_mode) {
451 .Exe => {
452 if (self.entry_addr) |addr| {
453 // Update LC_MAIN with entry offset.
454 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
455 const main_cmd = &self.load_commands.items[self.main_cmd_index.?].Main;
456 main_cmd.entryoff = addr - text_segment.inner.vmaddr;
457 main_cmd.stacksize = self.base.options.stack_size_override orelse 0;
458 self.load_commands_dirty = true;
459 }
460 try self.writeRebaseInfoTable();
461 try self.writeBindInfoTable();
462 try self.writeLazyBindInfoTable();
463 try self.writeExportInfo();
464 try self.writeAllGlobalAndUndefSymbols();
465 try self.writeIndirectSymbolTable();
466 try self.writeStringTable();
467 try self.updateLinkeditSegmentSizes();
468
469 if (self.d_sym) |*ds| {
470 // Flush debug symbols bundle.
471 try ds.flushModule(self.base.allocator, self.base.options);
472 }
473
474 if (self.requires_adhoc_codesig) {
475 // Preallocate space for the code signature.
476 // We need to do this at this stage so that we have the load commands with proper values
477 // written out to the file.
478 // The most important here is to have the correct vm and filesize of the __LINKEDIT segment
479 // where the code signature goes into.
480 try self.writeCodeSignaturePadding();
481 }
482 },
483 .Obj => {},
484 .Lib => return error.TODOImplementWritingLibFiles,
485 }
486
487 try self.writeLoadCommands();
488 try self.writeHeader();
489
490 if (self.entry_addr == null and self.base.options.output_mode == .Exe) {
491 log.debug("flushing. no_entry_point_found = true", .{});
492 self.error_flags.no_entry_point_found = true;
493 } else {
494 log.debug("flushing. no_entry_point_found = false", .{});
495 self.error_flags.no_entry_point_found = false;
496 }
497
498 assert(!self.got_entries_count_dirty);
499 assert(!self.load_commands_dirty);
500 assert(!self.rebase_info_dirty);
501 assert(!self.binding_info_dirty);
502 assert(!self.lazy_binding_info_dirty);
503 assert(!self.export_info_dirty);
504 assert(!self.strtab_dirty);
505 assert(!self.strtab_needs_relocation);
506
507 if (self.requires_adhoc_codesig) {
508 try self.writeCodeSignature(); // code signing always comes last
509 }
510}
511
512fn resolveSearchDir(
513 arena: *Allocator,
514 dir: []const u8,
515 syslibroot: ?[]const u8,
516) !?[]const u8 {
517 var candidates = std.ArrayList([]const u8).init(arena);
518
519 if (fs.path.isAbsolute(dir)) {
520 if (syslibroot) |root| {
521 const full_path = try fs.path.join(arena, &[_][]const u8{ root, dir });
522 try candidates.append(full_path);
523 }
524 }
525
526 try candidates.append(dir);
527
528 for (candidates.items) |candidate| {
529 // Verify that search path actually exists
530 var tmp = fs.cwd().openDir(candidate, .{}) catch |err| switch (err) {
531 error.FileNotFound => continue,
532 else => |e| return e,
533 };
534 defer tmp.close();
535
536 return candidate;
537 }
538
539 return null;
540}
541
542fn resolveLib(
543 arena: *Allocator,
544 search_dirs: []const []const u8,
545 name: []const u8,
546 ext: []const u8,
547) !?[]const u8 {
548 const search_name = try std.fmt.allocPrint(arena, "lib{s}{s}", .{ name, ext });
549
550 for (search_dirs) |dir| {
551 const full_path = try fs.path.join(arena, &[_][]const u8{ dir, search_name });
552
553 // Check if the file exists.
554 const tmp = fs.cwd().openFile(full_path, .{}) catch |err| switch (err) {
555 error.FileNotFound => continue,
556 else => |e| return e,
557 };
558 defer tmp.close();
559
560 return full_path;
561 }
562
563 return null;
564}
565
566fn resolveFramework(
567 arena: *Allocator,
568 search_dirs: []const []const u8,
569 name: []const u8,
570 ext: []const u8,
571) !?[]const u8 {
572 const search_name = try std.fmt.allocPrint(arena, "{s}{s}", .{ name, ext });
573 const prefix_path = try std.fmt.allocPrint(arena, "{s}.framework", .{name});
574
575 for (search_dirs) |dir| {
576 const full_path = try fs.path.join(arena, &[_][]const u8{ dir, prefix_path, search_name });
577
578 // Check if the file exists.
579 const tmp = fs.cwd().openFile(full_path, .{}) catch |err| switch (err) {
580 error.FileNotFound => continue,
581 else => |e| return e,
582 };
583 defer tmp.close();
584
585 return full_path;
586 }
587
588 return null;
589}
590
591fn linkWithZld(self: *MachO, comp: *Compilation) !void {
592 const tracy = trace(@src());396 const tracy = trace(@src());
593 defer tracy.end();397 defer tracy.end();
594398
...@@ -597,11 +401,11 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -597,11 +401,11 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
597 const arena = &arena_allocator.allocator;401 const arena = &arena_allocator.allocator;
598402
599 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.403 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
404 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
600405
601 // If there is no Zig code to compile, then we should skip flushing the output file because it406 // If there is no Zig code to compile, then we should skip flushing the output file because it
602 // will not be part of the linker line anyway.407 // will not be part of the linker line anyway.
603 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {408 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
604 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
605 if (use_stage1) {409 if (use_stage1) {
606 const obj_basename = try std.zig.binNameAlloc(arena, .{410 const obj_basename = try std.zig.binNameAlloc(arena, .{
607 .root_name = self.base.options.root_name,411 .root_name = self.base.options.root_name,
...@@ -613,8 +417,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -613,8 +417,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
613 break :blk full_obj_path;417 break :blk full_obj_path;
614 }418 }
615419
420 const obj_basename = self.base.intermediary_basename orelse break :blk null;
616 try self.flushModule(comp);421 try self.flushModule(comp);
617 const obj_basename = self.base.intermediary_basename.?;
618 const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});422 const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
619 break :blk full_obj_path;423 break :blk full_obj_path;
620 } else null;424 } else null;
...@@ -630,8 +434,11 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -630,8 +434,11 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
630 defer if (!self.base.options.disable_lld_caching) man.deinit();434 defer if (!self.base.options.disable_lld_caching) man.deinit();
631435
632 var digest: [Cache.hex_digest_len]u8 = undefined;436 var digest: [Cache.hex_digest_len]u8 = undefined;
437 var needs_full_relink = true;
438
439 cache: {
440 if (use_stage1 and self.base.options.disable_lld_caching) break :cache;
633441
634 if (!self.base.options.disable_lld_caching) {
635 man = comp.cache_parent.obtain();442 man = comp.cache_parent.obtain();
636443
637 // We are about to obtain this lock, so here we give other processes a chance first.444 // We are about to obtain this lock, so here we give other processes a chance first.
...@@ -665,17 +472,36 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -665,17 +472,36 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
665 id_symlink_basename,472 id_symlink_basename,
666 &prev_digest_buf,473 &prev_digest_buf,
667 ) catch |err| blk: {474 ) catch |err| blk: {
668 log.debug("MachO Zld new_digest={s} error: {s}", .{ std.fmt.fmtSliceHexLower(&digest), @errorName(err) });475 log.debug("MachO Zld new_digest={s} error: {s}", .{
476 std.fmt.fmtSliceHexLower(&digest),
477 @errorName(err),
478 });
669 // Handle this as a cache miss.479 // Handle this as a cache miss.
670 break :blk prev_digest_buf[0..0];480 break :blk prev_digest_buf[0..0];
671 };481 };
672 if (mem.eql(u8, prev_digest, &digest)) {482 if (mem.eql(u8, prev_digest, &digest)) {
673 log.debug("MachO Zld digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});
674 // Hot diggity dog! The output binary is already there.483 // Hot diggity dog! The output binary is already there.
675 self.base.lock = man.toOwnedLock();484
676 return;485 if (use_stage1) {
486 log.debug("MachO Zld digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});
487 self.base.lock = man.toOwnedLock();
488 return;
489 } else {
490 log.debug("MachO Zld digest={s} match", .{std.fmt.fmtSliceHexLower(&digest)});
491 if (!self.cold_start) {
492 log.debug(" no need to relink objects", .{});
493 needs_full_relink = false;
494 } else {
495 log.debug(" TODO parse prelinked binary and continue linking where we left off", .{});
496 // TODO until such time however, perform a full relink of objects.
497 needs_full_relink = true;
498 }
499 }
677 }500 }
678 log.debug("MachO Zld prev_digest={s} new_digest={s}", .{ std.fmt.fmtSliceHexLower(prev_digest), std.fmt.fmtSliceHexLower(&digest) });501 log.debug("MachO Zld prev_digest={s} new_digest={s}", .{
502 std.fmt.fmtSliceHexLower(prev_digest),
503 std.fmt.fmtSliceHexLower(&digest),
504 });
679505
680 // We are about to change the output file to be different, so we invalidate the build hash now.506 // We are about to change the output file to be different, so we invalidate the build hash now.
681 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {507 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
...@@ -683,7 +509,6 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -683,7 +509,6 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
683 else => |e| return e,509 else => |e| return e,
684 };510 };
685 }511 }
686
687 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});512 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
688513
689 if (self.base.options.output_mode == .Obj) {514 if (self.base.options.output_mode == .Obj) {
...@@ -710,270 +535,456 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -710,270 +535,456 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
710 try fs.cwd().copyFile(the_object_path, fs.cwd(), full_out_path, .{});535 try fs.cwd().copyFile(the_object_path, fs.cwd(), full_out_path, .{});
711 }536 }
712 } else {537 } else {
713 // Positional arguments to the linker such as object files and static archives.538 if (use_stage1) {
714 var positionals = std.ArrayList([]const u8).init(arena);539 const sub_path = self.base.options.emit.?.sub_path;
715540 self.base.file = try directory.handle.createFile(sub_path, .{
716 try positionals.appendSlice(self.base.options.objects);541 .truncate = true,
542 .read = true,
543 .mode = link.determineMode(self.base.options),
544 });
545 try self.populateMissingMetadata();
717546
718 for (comp.c_object_table.keys()) |key| {547 // TODO mimicking insertion of null symbol from incremental linker.
719 try positionals.append(key.status.success.object_path);548 // This will need to moved.
549 try self.locals.append(self.base.allocator, .{
550 .n_strx = 0,
551 .n_type = macho.N_UNDF,
552 .n_sect = 0,
553 .n_desc = 0,
554 .n_value = 0,
555 });
556 try self.strtab.append(self.base.allocator, 0);
720 }557 }
721558
722 if (module_obj_path) |p| {559 if (needs_full_relink) {
723 try positionals.append(p);560 self.objects.clearRetainingCapacity();
724 }561 self.archives.clearRetainingCapacity();
562 self.dylibs.clearRetainingCapacity();
563 self.dylibs_map.clearRetainingCapacity();
564 self.referenced_dylibs.clearRetainingCapacity();
725565
726 try positionals.append(comp.compiler_rt_static_lib.?.full_object_path);566 // TODO figure out how to clear atoms from objects, etc.
727567
728 // libc++ dep568 // Positional arguments to the linker such as object files and static archives.
729 if (self.base.options.link_libcpp) {569 var positionals = std.ArrayList([]const u8).init(arena);
730 try positionals.append(comp.libcxxabi_static_lib.?.full_object_path);
731 try positionals.append(comp.libcxx_static_lib.?.full_object_path);
732 }
733570
734 // Shared and static libraries passed via `-l` flag.571 try positionals.appendSlice(self.base.options.objects);
735 var search_lib_names = std.ArrayList([]const u8).init(arena);
736572
737 const system_libs = self.base.options.system_libs.keys();573 for (comp.c_object_table.keys()) |key| {
738 for (system_libs) |link_lib| {574 try positionals.append(key.status.success.object_path);
739 // By this time, we depend on these libs being dynamically linked libraries and not static libraries
740 // (the check for that needs to be earlier), but they could be full paths to .dylib files, in which
741 // case we want to avoid prepending "-l".
742 if (Compilation.classifyFileExt(link_lib) == .shared_library) {
743 try positionals.append(link_lib);
744 continue;
745 }575 }
746576
747 try search_lib_names.append(link_lib);577 if (module_obj_path) |p| {
748 }578 try positionals.append(p);
579 }
749580
750 var lib_dirs = std.ArrayList([]const u8).init(arena);581 if (comp.compiler_rt_static_lib) |lib| {
751 for (self.base.options.lib_dirs) |dir| {582 try positionals.append(lib.full_object_path);
752 if (try resolveSearchDir(arena, dir, self.base.options.sysroot)) |search_dir| {
753 try lib_dirs.append(search_dir);
754 } else {
755 log.warn("directory not found for '-L{s}'", .{dir});
756 }583 }
757 }
758584
759 var libs = std.ArrayList([]const u8).init(arena);585 // libc++ dep
760 var lib_not_found = false;586 if (self.base.options.link_libcpp) {
761 for (search_lib_names.items) |lib_name| {587 try positionals.append(comp.libcxxabi_static_lib.?.full_object_path);
762 // Assume ld64 default: -search_paths_first588 try positionals.append(comp.libcxx_static_lib.?.full_object_path);
763 // Look in each directory for a dylib (stub first), and then for archive589 }
764 // TODO implement alternative: -search_dylibs_first590
765 for (&[_][]const u8{ ".tbd", ".dylib", ".a" }) |ext| {591 // Shared and static libraries passed via `-l` flag.
766 if (try resolveLib(arena, lib_dirs.items, lib_name, ext)) |full_path| {592 var search_lib_names = std.ArrayList([]const u8).init(arena);
767 try libs.append(full_path);593
768 break;594 const system_libs = self.base.options.system_libs.keys();
595 for (system_libs) |link_lib| {
596 // By this time, we depend on these libs being dynamically linked libraries and not static libraries
597 // (the check for that needs to be earlier), but they could be full paths to .dylib files, in which
598 // case we want to avoid prepending "-l".
599 if (Compilation.classifyFileExt(link_lib) == .shared_library) {
600 try positionals.append(link_lib);
601 continue;
602 }
603
604 try search_lib_names.append(link_lib);
605 }
606
607 var lib_dirs = std.ArrayList([]const u8).init(arena);
608 for (self.base.options.lib_dirs) |dir| {
609 if (try resolveSearchDir(arena, dir, self.base.options.sysroot)) |search_dir| {
610 try lib_dirs.append(search_dir);
611 } else {
612 log.warn("directory not found for '-L{s}'", .{dir});
769 }613 }
770 } else {
771 log.warn("library not found for '-l{s}'", .{lib_name});
772 lib_not_found = true;
773 }614 }
774 }
775615
776 if (lib_not_found) {616 var libs = std.ArrayList([]const u8).init(arena);
777 log.warn("Library search paths:", .{});617 var lib_not_found = false;
778 for (lib_dirs.items) |dir| {618 for (search_lib_names.items) |lib_name| {
779 log.warn(" {s}", .{dir});619 // Assume ld64 default: -search_paths_first
620 // Look in each directory for a dylib (stub first), and then for archive
621 // TODO implement alternative: -search_dylibs_first
622 for (&[_][]const u8{ ".tbd", ".dylib", ".a" }) |ext| {
623 if (try resolveLib(arena, lib_dirs.items, lib_name, ext)) |full_path| {
624 try libs.append(full_path);
625 break;
626 }
627 } else {
628 log.warn("library not found for '-l{s}'", .{lib_name});
629 lib_not_found = true;
630 }
780 }631 }
781 }
782632
783 // If we were given the sysroot, try to look there first for libSystem.B.{dylib, tbd}.633 if (lib_not_found) {
784 var libsystem_available = false;634 log.warn("Library search paths:", .{});
785 if (self.base.options.sysroot != null) blk: {635 for (lib_dirs.items) |dir| {
786 // Try stub file first. If we hit it, then we're done as the stub file636 log.warn(" {s}", .{dir});
787 // re-exports every single symbol definition.637 }
788 if (try resolveLib(arena, lib_dirs.items, "System", ".tbd")) |full_path| {
789 try libs.append(full_path);
790 libsystem_available = true;
791 break :blk;
792 }638 }
793 // If we didn't hit the stub file, try .dylib next. However, libSystem.dylib639
794 // doesn't export libc.dylib which we'll need to resolve subsequently also.640 // If we were given the sysroot, try to look there first for libSystem.B.{dylib, tbd}.
795 if (try resolveLib(arena, lib_dirs.items, "System", ".dylib")) |libsystem_path| {641 var libsystem_available = false;
796 if (try resolveLib(arena, lib_dirs.items, "c", ".dylib")) |libc_path| {642 if (self.base.options.sysroot != null) blk: {
797 try libs.append(libsystem_path);643 // Try stub file first. If we hit it, then we're done as the stub file
798 try libs.append(libc_path);644 // re-exports every single symbol definition.
645 if (try resolveLib(arena, lib_dirs.items, "System", ".tbd")) |full_path| {
646 try libs.append(full_path);
799 libsystem_available = true;647 libsystem_available = true;
800 break :blk;648 break :blk;
801 }649 }
650 // If we didn't hit the stub file, try .dylib next. However, libSystem.dylib
651 // doesn't export libc.dylib which we'll need to resolve subsequently also.
652 if (try resolveLib(arena, lib_dirs.items, "System", ".dylib")) |libsystem_path| {
653 if (try resolveLib(arena, lib_dirs.items, "c", ".dylib")) |libc_path| {
654 try libs.append(libsystem_path);
655 try libs.append(libc_path);
656 libsystem_available = true;
657 break :blk;
658 }
659 }
660 }
661 if (!libsystem_available) {
662 const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
663 "libc", "darwin", "libSystem.B.tbd",
664 });
665 try libs.append(full_path);
802 }666 }
803 }
804 if (!libsystem_available) {
805 const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
806 "libc", "darwin", "libSystem.B.tbd",
807 });
808 try libs.append(full_path);
809 }
810667
811 // frameworks668 // frameworks
812 var framework_dirs = std.ArrayList([]const u8).init(arena);669 var framework_dirs = std.ArrayList([]const u8).init(arena);
813 for (self.base.options.framework_dirs) |dir| {670 for (self.base.options.framework_dirs) |dir| {
814 if (try resolveSearchDir(arena, dir, self.base.options.sysroot)) |search_dir| {671 if (try resolveSearchDir(arena, dir, self.base.options.sysroot)) |search_dir| {
815 try framework_dirs.append(search_dir);672 try framework_dirs.append(search_dir);
816 } else {673 } else {
817 log.warn("directory not found for '-F{s}'", .{dir});674 log.warn("directory not found for '-F{s}'", .{dir});
675 }
818 }676 }
819 }
820677
821 var framework_not_found = false;678 var framework_not_found = false;
822 for (self.base.options.frameworks) |framework| {679 for (self.base.options.frameworks) |framework| {
823 for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {680 for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
824 if (try resolveFramework(arena, framework_dirs.items, framework, ext)) |full_path| {681 if (try resolveFramework(arena, framework_dirs.items, framework, ext)) |full_path| {
825 try libs.append(full_path);682 try libs.append(full_path);
826 break;683 break;
684 }
685 } else {
686 log.warn("framework not found for '-framework {s}'", .{framework});
687 framework_not_found = true;
827 }688 }
828 } else {
829 log.warn("framework not found for '-framework {s}'", .{framework});
830 framework_not_found = true;
831 }689 }
832 }
833690
834 if (framework_not_found) {691 if (framework_not_found) {
835 log.warn("Framework search paths:", .{});692 log.warn("Framework search paths:", .{});
836 for (framework_dirs.items) |dir| {693 for (framework_dirs.items) |dir| {
837 log.warn(" {s}", .{dir});694 log.warn(" {s}", .{dir});
695 }
838 }696 }
839 }
840697
841 // rpaths698 // rpaths
842 var rpath_table = std.StringArrayHashMap(void).init(arena);699 var rpath_table = std.StringArrayHashMap(void).init(arena);
843 for (self.base.options.rpath_list) |rpath| {700 for (self.base.options.rpath_list) |rpath| {
844 if (rpath_table.contains(rpath)) continue;701 if (rpath_table.contains(rpath)) continue;
845 try rpath_table.putNoClobber(rpath, {});702 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
846 }703 u64,
704 @sizeOf(macho.rpath_command) + rpath.len + 1,
705 @sizeOf(u64),
706 ));
707 var rpath_cmd = commands.emptyGenericCommandWithData(macho.rpath_command{
708 .cmd = macho.LC_RPATH,
709 .cmdsize = cmdsize,
710 .path = @sizeOf(macho.rpath_command),
711 });
712 rpath_cmd.data = try self.base.allocator.alloc(u8, cmdsize - rpath_cmd.inner.path);
713 mem.set(u8, rpath_cmd.data, 0);
714 mem.copy(u8, rpath_cmd.data, rpath);
715 try self.load_commands.append(self.base.allocator, .{ .Rpath = rpath_cmd });
716 try rpath_table.putNoClobber(rpath, {});
717 self.load_commands_dirty = true;
718 }
847719
848 var rpaths = std.ArrayList([]const u8).init(arena);720 if (self.base.options.verbose_link) {
849 try rpaths.ensureCapacity(rpath_table.count());721 var argv = std.ArrayList([]const u8).init(arena);
850 for (rpath_table.keys()) |*key| {
851 rpaths.appendAssumeCapacity(key.*);
852 }
853722
854 if (self.base.options.verbose_link) {723 try argv.append("zig");
855 var argv = std.ArrayList([]const u8).init(arena);724 try argv.append("ld");
856725
857 try argv.append("zig");726 if (is_exe_or_dyn_lib) {
858 try argv.append("ld");727 try argv.append("-dynamic");
728 }
859729
860 if (is_exe_or_dyn_lib) {730 if (is_dyn_lib) {
861 try argv.append("-dynamic");731 try argv.append("-dylib");
862 }732
733 const install_name = try std.fmt.allocPrint(arena, "@rpath/{s}", .{
734 self.base.options.emit.?.sub_path,
735 });
736 try argv.append("-install_name");
737 try argv.append(install_name);
738 }
863739
864 if (is_dyn_lib) {740 if (self.base.options.sysroot) |syslibroot| {
865 try argv.append("-dylib");741 try argv.append("-syslibroot");
742 try argv.append(syslibroot);
743 }
866744
867 const install_name = try std.fmt.allocPrint(arena, "@rpath/{s}", .{745 for (rpath_table.keys()) |rpath| {
868 self.base.options.emit.?.sub_path,746 try argv.append("-rpath");
869 });747 try argv.append(rpath);
870 try argv.append("-install_name");748 }
871 try argv.append(install_name);
872 }
873749
874 if (self.base.options.sysroot) |syslibroot| {750 try argv.appendSlice(positionals.items);
875 try argv.append("-syslibroot");
876 try argv.append(syslibroot);
877 }
878751
879 for (rpaths.items) |rpath| {752 try argv.append("-o");
880 try argv.append("-rpath");753 try argv.append(full_out_path);
881 try argv.append(rpath);
882 }
883754
884 try argv.appendSlice(positionals.items);755 try argv.append("-lSystem");
756 try argv.append("-lc");
885757
886 try argv.append("-o");758 for (search_lib_names.items) |l_name| {
887 try argv.append(full_out_path);759 try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{l_name}));
760 }
888761
889 try argv.append("-lSystem");762 for (self.base.options.lib_dirs) |lib_dir| {
890 try argv.append("-lc");763 try argv.append(try std.fmt.allocPrint(arena, "-L{s}", .{lib_dir}));
764 }
891765
892 for (search_lib_names.items) |l_name| {766 for (self.base.options.frameworks) |framework| {
893 try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{l_name}));767 try argv.append(try std.fmt.allocPrint(arena, "-framework {s}", .{framework}));
894 }768 }
895769
896 for (self.base.options.lib_dirs) |lib_dir| {770 for (self.base.options.framework_dirs) |framework_dir| {
897 try argv.append(try std.fmt.allocPrint(arena, "-L{s}", .{lib_dir}));771 try argv.append(try std.fmt.allocPrint(arena, "-F{s}", .{framework_dir}));
898 }772 }
899773
900 for (self.base.options.frameworks) |framework| {774 Compilation.dump_argv(argv.items);
901 try argv.append(try std.fmt.allocPrint(arena, "-framework {s}", .{framework}));
902 }775 }
903776
904 for (self.base.options.framework_dirs) |framework_dir| {777 try self.parseInputFiles(positionals.items, self.base.options.sysroot);
905 try argv.append(try std.fmt.allocPrint(arena, "-F{s}", .{framework_dir}));778 try self.parseLibs(libs.items, self.base.options.sysroot);
906 }779 }
907780
908 Compilation.dump_argv(argv.items);781 if (self.bss_section_index) |idx| {
782 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
783 const sect = &seg.sections.items[idx];
784 sect.offset = self.bss_file_offset;
785 }
786 if (self.tlv_bss_section_index) |idx| {
787 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
788 const sect = &seg.sections.items[idx];
789 sect.offset = self.tlv_bss_file_offset;
909 }790 }
910791
911 const sub_path = self.base.options.emit.?.sub_path;792 for (self.objects.items) |*object, object_id| {
912 self.base.file = try directory.handle.createFile(sub_path, .{793 if (object.analyzed) continue;
913 .truncate = true,794 try self.resolveSymbolsInObject(@intCast(u16, object_id));
914 .read = true,795 }
915 .mode = link.determineMode(self.base.options),
916 });
917796
918 // TODO mimicking insertion of null symbol from incremental linker.797 try self.resolveSymbolsInArchives();
919 // This will need to moved.798 try self.resolveDyldStubBinder();
920 try self.locals.append(self.base.allocator, .{799 try self.createDyldPrivateAtom();
921 .n_strx = 0,800 try self.createStubHelperPreambleAtom();
922 .n_type = macho.N_UNDF,801 try self.resolveSymbolsInDylibs();
923 .n_sect = 0,802 try self.createDsoHandleAtom();
924 .n_desc = 0,
925 .n_value = 0,
926 });
927 try self.strtab.append(self.base.allocator, 0);
928
929 try self.populateMetadata();
930 try self.addRpathLCs(rpaths.items);
931 try self.parseInputFiles(positionals.items, self.base.options.sysroot);
932 try self.parseLibs(libs.items, self.base.options.sysroot);
933 try self.resolveSymbols();
934 try self.parseTextBlocks();
935 try self.addLoadDylibLCs();
936 try self.addDataInCodeLC();
937 try self.addCodeSignatureLC();803 try self.addCodeSignatureLC();
938804
939 {805 for (self.unresolved.keys()) |index| {
940 // Add dyld_stub_binder as the final GOT entry.806 const sym = self.undefs.items[index];
941 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{807 const sym_name = self.getString(sym.n_strx);
942 .strtab = &self.strtab,808 const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;
943 }) orelse unreachable;809
944 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;810 log.err("undefined reference to symbol '{s}'", .{sym_name});
945 const got_index = @intCast(u32, self.got_entries.items.len);811 log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name});
946 const got_entry = GotIndirectionKey{812 }
947 .where = .undef,813 if (self.unresolved.count() > 0) {
948 .where_index = resolv.where_index,814 return error.UndefinedSymbolReference;
949 };
950 try self.got_entries.append(self.base.allocator, got_entry);
951 try self.got_entries_map.putNoClobber(self.base.allocator, got_entry, got_index);
952 }815 }
953816
954 try self.sortSections();817 try self.createTentativeDefAtoms();
955 try self.allocateTextSegment();818 try self.parseObjectsIntoAtoms();
956 try self.allocateDataConstSegment();819 try self.allocateGlobalSymbols();
957 try self.allocateDataSegment();820 try self.writeAtoms();
958 self.allocateLinkeditSegment();
959 try self.allocateTextBlocks();
960 try self.flushZld();
961 }
962821
963 if (!self.base.options.disable_lld_caching) {822 if (self.bss_section_index) |idx| {
964 // Update the file with the digest. If it fails we can continue; it only823 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
965 // means that the next invocation will have an unnecessary cache miss.824 const sect = &seg.sections.items[idx];
825 self.bss_file_offset = sect.offset;
826 sect.offset = 0;
827 }
828 if (self.tlv_bss_section_index) |idx| {
829 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
830 const sect = &seg.sections.items[idx];
831 self.tlv_bss_file_offset = sect.offset;
832 sect.offset = 0;
833 }
834
835 try self.flushModule(comp);
836 }
837
838 cache: {
839 if (use_stage1 and self.base.options.disable_lld_caching) break :cache;
840 // Update the file with the digest. If it fails we can continue; it only
841 // means that the next invocation will have an unnecessary cache miss.
966 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {842 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
967 log.warn("failed to save linking hash digest file: {s}", .{@errorName(err)});843 log.debug("failed to save linking hash digest file: {s}", .{@errorName(err)});
968 };844 };
969 // Again failure here only means an unnecessary cache miss.845 // Again failure here only means an unnecessary cache miss.
970 man.writeManifest() catch |err| {846 man.writeManifest() catch |err| {
971 log.warn("failed to write cache manifest when linking: {s}", .{@errorName(err)});847 log.debug("failed to write cache manifest when linking: {s}", .{@errorName(err)});
972 };848 };
973 // We hang on to this lock so that the output file path can be used without849 // We hang on to this lock so that the output file path can be used without
974 // other processes clobbering it.850 // other processes clobbering it.
975 self.base.lock = man.toOwnedLock();851 self.base.lock = man.toOwnedLock();
976 }852 }
853
854 self.cold_start = false;
855}
856
857pub fn flushModule(self: *MachO, comp: *Compilation) !void {
858 _ = comp;
859
860 const tracy = trace(@src());
861 defer tracy.end();
862
863 try self.setEntryPoint();
864 try self.updateSectionOrdinals();
865 try self.writeLinkeditSegment();
866
867 if (self.d_sym) |*ds| {
868 // Flush debug symbols bundle.
869 try ds.flushModule(self.base.allocator, self.base.options);
870 }
871
872 if (self.requires_adhoc_codesig) {
873 // Preallocate space for the code signature.
874 // We need to do this at this stage so that we have the load commands with proper values
875 // written out to the file.
876 // The most important here is to have the correct vm and filesize of the __LINKEDIT segment
877 // where the code signature goes into.
878 try self.writeCodeSignaturePadding();
879 }
880
881 try self.writeLoadCommands();
882 try self.writeHeader();
883
884 if (self.entry_addr == null and self.base.options.output_mode == .Exe) {
885 log.debug("flushing. no_entry_point_found = true", .{});
886 self.error_flags.no_entry_point_found = true;
887 } else {
888 log.debug("flushing. no_entry_point_found = false", .{});
889 self.error_flags.no_entry_point_found = false;
890 }
891
892 assert(!self.load_commands_dirty);
893
894 if (self.requires_adhoc_codesig) {
895 try self.writeCodeSignature(); // code signing always comes last
896 }
897}
898
899fn resolveSearchDir(
900 arena: *Allocator,
901 dir: []const u8,
902 syslibroot: ?[]const u8,
903) !?[]const u8 {
904 var candidates = std.ArrayList([]const u8).init(arena);
905
906 if (fs.path.isAbsolute(dir)) {
907 if (syslibroot) |root| {
908 const common_dir = if (std.Target.current.os.tag == .windows) blk: {
909 // We need to check for disk designator and strip it out from dir path so
910 // that we can concat dir with syslibroot.
911 // TODO we should backport this mechanism to 'MachO.Dylib.parseDependentLibs()'
912 const disk_designator = fs.path.diskDesignatorWindows(dir);
913
914 if (mem.indexOf(u8, dir, disk_designator)) |where| {
915 break :blk dir[where + disk_designator.len ..];
916 }
917
918 break :blk dir;
919 } else dir;
920 const full_path = try fs.path.join(arena, &[_][]const u8{ root, common_dir });
921 try candidates.append(full_path);
922 }
923 }
924
925 try candidates.append(dir);
926
927 for (candidates.items) |candidate| {
928 // Verify that search path actually exists
929 var tmp = fs.cwd().openDir(candidate, .{}) catch |err| switch (err) {
930 error.FileNotFound => continue,
931 else => |e| return e,
932 };
933 defer tmp.close();
934
935 return candidate;
936 }
937
938 return null;
939}
940
941fn resolveLib(
942 arena: *Allocator,
943 search_dirs: []const []const u8,
944 name: []const u8,
945 ext: []const u8,
946) !?[]const u8 {
947 const search_name = try std.fmt.allocPrint(arena, "lib{s}{s}", .{ name, ext });
948
949 for (search_dirs) |dir| {
950 const full_path = try fs.path.join(arena, &[_][]const u8{ dir, search_name });
951
952 // Check if the file exists.
953 const tmp = fs.cwd().openFile(full_path, .{}) catch |err| switch (err) {
954 error.FileNotFound => continue,
955 else => |e| return e,
956 };
957 defer tmp.close();
958
959 return full_path;
960 }
961
962 return null;
963}
964
965fn resolveFramework(
966 arena: *Allocator,
967 search_dirs: []const []const u8,
968 name: []const u8,
969 ext: []const u8,
970) !?[]const u8 {
971 const search_name = try std.fmt.allocPrint(arena, "{s}{s}", .{ name, ext });
972 const prefix_path = try std.fmt.allocPrint(arena, "{s}.framework", .{name});
973
974 for (search_dirs) |dir| {
975 const full_path = try fs.path.join(arena, &[_][]const u8{ dir, prefix_path, search_name });
976
977 // Check if the file exists.
978 const tmp = fs.cwd().openFile(full_path, .{}) catch |err| switch (err) {
979 error.FileNotFound => continue,
980 else => |e| return e,
981 };
982 defer tmp.close();
983
984 return full_path;
985 }
986
987 return null;
977}988}
978989
979fn parseObject(self: *MachO, path: []const u8) !bool {990fn parseObject(self: *MachO, path: []const u8) !bool {
...@@ -1093,6 +1104,7 @@ pub fn parseDylib(self: *MachO, path: []const u8, opts: DylibCreateOpts) ParseDy...@@ -1093,6 +1104,7 @@ pub fn parseDylib(self: *MachO, path: []const u8, opts: DylibCreateOpts) ParseDy
1093 try self.dylibs_map.putNoClobber(self.base.allocator, dylib.id.?.name, dylib_id);1104 try self.dylibs_map.putNoClobber(self.base.allocator, dylib.id.?.name, dylib_id);
10941105
1095 if (!(opts.is_dependent or self.referenced_dylibs.contains(dylib_id))) {1106 if (!(opts.is_dependent or self.referenced_dylibs.contains(dylib_id))) {
1107 try self.addLoadDylibLC(dylib_id);
1096 try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});1108 try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});
1097 }1109 }
10981110
...@@ -1111,6 +1123,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const...@@ -1111,6 +1123,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const
1111 break :full_path try self.base.allocator.dupe(u8, path);1123 break :full_path try self.base.allocator.dupe(u8, path);
1112 };1124 };
1113 defer self.base.allocator.free(full_path);1125 defer self.base.allocator.free(full_path);
1126 log.debug("parsing input file path '{s}'", .{full_path});
11141127
1115 if (try self.parseObject(full_path)) continue;1128 if (try self.parseObject(full_path)) continue;
1116 if (try self.parseArchive(full_path)) continue;1129 if (try self.parseArchive(full_path)) continue;
...@@ -1124,6 +1137,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const...@@ -1124,6 +1137,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const
11241137
1125fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8) !void {1138fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8) !void {
1126 for (libs) |lib| {1139 for (libs) |lib| {
1140 log.debug("parsing lib path '{s}'", .{lib});
1127 if (try self.parseDylib(lib, .{1141 if (try self.parseDylib(lib, .{
1128 .syslibroot = syslibroot,1142 .syslibroot = syslibroot,
1129 })) continue;1143 })) continue;
...@@ -1139,18 +1153,19 @@ pub const MatchingSection = struct {...@@ -1139,18 +1153,19 @@ pub const MatchingSection = struct {
1139};1153};
11401154
1141pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection {1155pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection {
1142 const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1143 const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
1144 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1145 const segname = commands.segmentName(sect);1156 const segname = commands.segmentName(sect);
1146 const sectname = commands.sectionName(sect);1157 const sectname = commands.sectionName(sect);
1147
1148 const res: ?MatchingSection = blk: {1158 const res: ?MatchingSection = blk: {
1149 switch (commands.sectionType(sect)) {1159 switch (commands.sectionType(sect)) {
1150 macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => {1160 macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => {
1151 if (self.text_const_section_index == null) {1161 if (self.text_const_section_index == null) {
1152 self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);1162 self.text_const_section_index = try self.allocateSection(
1153 try text_seg.addSection(self.base.allocator, "__const", .{});1163 self.text_segment_cmd_index.?,
1164 "__const",
1165 sect.size,
1166 sect.@"align",
1167 .{},
1168 );
1154 }1169 }
11551170
1156 break :blk .{1171 break :blk .{
...@@ -1163,10 +1178,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1163,10 +1178,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1163 // TODO it seems the common values within the sections in objects are deduplicated/merged1178 // TODO it seems the common values within the sections in objects are deduplicated/merged
1164 // on merging the sections' contents.1179 // on merging the sections' contents.
1165 if (self.objc_methname_section_index == null) {1180 if (self.objc_methname_section_index == null) {
1166 self.objc_methname_section_index = @intCast(u16, text_seg.sections.items.len);1181 self.objc_methname_section_index = try self.allocateSection(
1167 try text_seg.addSection(self.base.allocator, "__objc_methname", .{1182 self.text_segment_cmd_index.?,
1168 .flags = macho.S_CSTRING_LITERALS,1183 "__objc_methname",
1169 });1184 sect.size,
1185 sect.@"align",
1186 .{},
1187 );
1170 }1188 }
11711189
1172 break :blk .{1190 break :blk .{
...@@ -1175,10 +1193,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1175,10 +1193,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1175 };1193 };
1176 } else if (mem.eql(u8, sectname, "__objc_methtype")) {1194 } else if (mem.eql(u8, sectname, "__objc_methtype")) {
1177 if (self.objc_methtype_section_index == null) {1195 if (self.objc_methtype_section_index == null) {
1178 self.objc_methtype_section_index = @intCast(u16, text_seg.sections.items.len);1196 self.objc_methtype_section_index = try self.allocateSection(
1179 try text_seg.addSection(self.base.allocator, "__objc_methtype", .{1197 self.text_segment_cmd_index.?,
1180 .flags = macho.S_CSTRING_LITERALS,1198 "__objc_methtype",
1181 });1199 sect.size,
1200 sect.@"align",
1201 .{},
1202 );
1182 }1203 }
11831204
1184 break :blk .{1205 break :blk .{
...@@ -1187,8 +1208,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1187,8 +1208,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1187 };1208 };
1188 } else if (mem.eql(u8, sectname, "__objc_classname")) {1209 } else if (mem.eql(u8, sectname, "__objc_classname")) {
1189 if (self.objc_classname_section_index == null) {1210 if (self.objc_classname_section_index == null) {
1190 self.objc_classname_section_index = @intCast(u16, text_seg.sections.items.len);1211 self.objc_classname_section_index = try self.allocateSection(
1191 try text_seg.addSection(self.base.allocator, "__objc_classname", .{});1212 self.text_segment_cmd_index.?,
1213 "__objc_classname",
1214 sect.size,
1215 sect.@"align",
1216 .{},
1217 );
1192 }1218 }
11931219
1194 break :blk .{1220 break :blk .{
...@@ -1198,10 +1224,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1198,10 +1224,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1198 }1224 }
11991225
1200 if (self.cstring_section_index == null) {1226 if (self.cstring_section_index == null) {
1201 self.cstring_section_index = @intCast(u16, text_seg.sections.items.len);1227 self.cstring_section_index = try self.allocateSection(
1202 try text_seg.addSection(self.base.allocator, "__cstring", .{1228 self.text_segment_cmd_index.?,
1203 .flags = macho.S_CSTRING_LITERALS,1229 "__cstring",
1204 });1230 sect.size,
1231 sect.@"align",
1232 .{
1233 .flags = macho.S_CSTRING_LITERALS,
1234 },
1235 );
1205 }1236 }
12061237
1207 break :blk .{1238 break :blk .{
...@@ -1212,27 +1243,37 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1212,27 +1243,37 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1212 macho.S_LITERAL_POINTERS => {1243 macho.S_LITERAL_POINTERS => {
1213 if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__objc_selrefs")) {1244 if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__objc_selrefs")) {
1214 if (self.objc_selrefs_section_index == null) {1245 if (self.objc_selrefs_section_index == null) {
1215 self.objc_selrefs_section_index = @intCast(u16, data_seg.sections.items.len);1246 self.objc_selrefs_section_index = try self.allocateSection(
1216 try data_seg.addSection(self.base.allocator, "__objc_selrefs", .{1247 self.data_segment_cmd_index.?,
1217 .flags = macho.S_LITERAL_POINTERS,1248 "__objc_selrefs",
1218 });1249 sect.size,
1250 sect.@"align",
1251 .{
1252 .flags = macho.S_LITERAL_POINTERS,
1253 },
1254 );
1219 }1255 }
12201256
1221 break :blk .{1257 break :blk .{
1222 .seg = self.data_segment_cmd_index.?,1258 .seg = self.data_segment_cmd_index.?,
1223 .sect = self.objc_selrefs_section_index.?,1259 .sect = self.objc_selrefs_section_index.?,
1224 };1260 };
1261 } else {
1262 // TODO investigate
1263 break :blk null;
1225 }1264 }
1226
1227 // TODO investigate
1228 break :blk null;
1229 },1265 },
1230 macho.S_MOD_INIT_FUNC_POINTERS => {1266 macho.S_MOD_INIT_FUNC_POINTERS => {
1231 if (self.mod_init_func_section_index == null) {1267 if (self.mod_init_func_section_index == null) {
1232 self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len);1268 self.mod_init_func_section_index = try self.allocateSection(
1233 try data_const_seg.addSection(self.base.allocator, "__mod_init_func", .{1269 self.data_const_segment_cmd_index.?,
1234 .flags = macho.S_MOD_INIT_FUNC_POINTERS,1270 "__mod_init_func",
1235 });1271 sect.size,
1272 sect.@"align",
1273 .{
1274 .flags = macho.S_MOD_INIT_FUNC_POINTERS,
1275 },
1276 );
1236 }1277 }
12371278
1238 break :blk .{1279 break :blk .{
...@@ -1242,10 +1283,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1242,10 +1283,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1242 },1283 },
1243 macho.S_MOD_TERM_FUNC_POINTERS => {1284 macho.S_MOD_TERM_FUNC_POINTERS => {
1244 if (self.mod_term_func_section_index == null) {1285 if (self.mod_term_func_section_index == null) {
1245 self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len);1286 self.mod_term_func_section_index = try self.allocateSection(
1246 try data_const_seg.addSection(self.base.allocator, "__mod_term_func", .{1287 self.data_const_segment_cmd_index.?,
1247 .flags = macho.S_MOD_TERM_FUNC_POINTERS,1288 "__mod_term_func",
1248 });1289 sect.size,
1290 sect.@"align",
1291 .{
1292 .flags = macho.S_MOD_TERM_FUNC_POINTERS,
1293 },
1294 );
1249 }1295 }
12501296
1251 break :blk .{1297 break :blk .{
...@@ -1254,38 +1300,34 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1254,38 +1300,34 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1254 };1300 };
1255 },1301 },
1256 macho.S_ZEROFILL => {1302 macho.S_ZEROFILL => {
1257 if (mem.eql(u8, sectname, "__common")) {1303 if (self.bss_section_index == null) {
1258 if (self.common_section_index == null) {1304 self.bss_section_index = try self.allocateSection(
1259 self.common_section_index = @intCast(u16, data_seg.sections.items.len);1305 self.data_segment_cmd_index.?,
1260 try data_seg.addSection(self.base.allocator, "__common", .{1306 "__bss",
1261 .flags = macho.S_ZEROFILL,1307 sect.size,
1262 });1308 sect.@"align",
1263 }1309 .{
1264
1265 break :blk .{
1266 .seg = self.data_segment_cmd_index.?,
1267 .sect = self.common_section_index.?,
1268 };
1269 } else {
1270 if (self.bss_section_index == null) {
1271 self.bss_section_index = @intCast(u16, data_seg.sections.items.len);
1272 try data_seg.addSection(self.base.allocator, "__bss", .{
1273 .flags = macho.S_ZEROFILL,1310 .flags = macho.S_ZEROFILL,
1274 });1311 },
1275 }1312 );
1276
1277 break :blk .{
1278 .seg = self.data_segment_cmd_index.?,
1279 .sect = self.bss_section_index.?,
1280 };
1281 }1313 }
1314
1315 break :blk .{
1316 .seg = self.data_segment_cmd_index.?,
1317 .sect = self.bss_section_index.?,
1318 };
1282 },1319 },
1283 macho.S_THREAD_LOCAL_VARIABLES => {1320 macho.S_THREAD_LOCAL_VARIABLES => {
1284 if (self.tlv_section_index == null) {1321 if (self.tlv_section_index == null) {
1285 self.tlv_section_index = @intCast(u16, data_seg.sections.items.len);1322 self.tlv_section_index = try self.allocateSection(
1286 try data_seg.addSection(self.base.allocator, "__thread_vars", .{1323 self.data_segment_cmd_index.?,
1287 .flags = macho.S_THREAD_LOCAL_VARIABLES,1324 "__thread_vars",
1288 });1325 sect.size,
1326 sect.@"align",
1327 .{
1328 .flags = macho.S_THREAD_LOCAL_VARIABLES,
1329 },
1330 );
1289 }1331 }
12901332
1291 break :blk .{1333 break :blk .{
...@@ -1295,10 +1337,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1295,10 +1337,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1295 },1337 },
1296 macho.S_THREAD_LOCAL_REGULAR => {1338 macho.S_THREAD_LOCAL_REGULAR => {
1297 if (self.tlv_data_section_index == null) {1339 if (self.tlv_data_section_index == null) {
1298 self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len);1340 self.tlv_data_section_index = try self.allocateSection(
1299 try data_seg.addSection(self.base.allocator, "__thread_data", .{1341 self.data_segment_cmd_index.?,
1300 .flags = macho.S_THREAD_LOCAL_REGULAR,1342 "__thread_data",
1301 });1343 sect.size,
1344 sect.@"align",
1345 .{
1346 .flags = macho.S_THREAD_LOCAL_REGULAR,
1347 },
1348 );
1302 }1349 }
13031350
1304 break :blk .{1351 break :blk .{
...@@ -1308,10 +1355,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1308,10 +1355,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1308 },1355 },
1309 macho.S_THREAD_LOCAL_ZEROFILL => {1356 macho.S_THREAD_LOCAL_ZEROFILL => {
1310 if (self.tlv_bss_section_index == null) {1357 if (self.tlv_bss_section_index == null) {
1311 self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len);1358 self.tlv_bss_section_index = try self.allocateSection(
1312 try data_seg.addSection(self.base.allocator, "__thread_bss", .{1359 self.data_segment_cmd_index.?,
1313 .flags = macho.S_THREAD_LOCAL_ZEROFILL,1360 "__thread_bss",
1314 });1361 sect.size,
1362 sect.@"align",
1363 .{
1364 .flags = macho.S_THREAD_LOCAL_ZEROFILL,
1365 },
1366 );
1315 }1367 }
13161368
1317 break :blk .{1369 break :blk .{
...@@ -1324,8 +1376,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1324,8 +1376,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1324 // TODO I believe __eh_frame is currently part of __unwind_info section1376 // TODO I believe __eh_frame is currently part of __unwind_info section
1325 // in the latest ld64 output.1377 // in the latest ld64 output.
1326 if (self.eh_frame_section_index == null) {1378 if (self.eh_frame_section_index == null) {
1327 self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len);1379 self.eh_frame_section_index = try self.allocateSection(
1328 try text_seg.addSection(self.base.allocator, "__eh_frame", .{});1380 self.text_segment_cmd_index.?,
1381 "__eh_frame",
1382 sect.size,
1383 sect.@"align",
1384 .{},
1385 );
1329 }1386 }
13301387
1331 break :blk .{1388 break :blk .{
...@@ -1336,8 +1393,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1336,8 +1393,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
13361393
1337 // TODO audit this: is this the right mapping?1394 // TODO audit this: is this the right mapping?
1338 if (self.data_const_section_index == null) {1395 if (self.data_const_section_index == null) {
1339 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);1396 self.data_const_section_index = try self.allocateSection(
1340 try data_const_seg.addSection(self.base.allocator, "__const", .{});1397 self.data_const_segment_cmd_index.?,
1398 "__const",
1399 sect.size,
1400 sect.@"align",
1401 .{},
1402 );
1341 }1403 }
13421404
1343 break :blk .{1405 break :blk .{
...@@ -1348,10 +1410,17 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1348,10 +1410,17 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1348 macho.S_REGULAR => {1410 macho.S_REGULAR => {
1349 if (commands.sectionIsCode(sect)) {1411 if (commands.sectionIsCode(sect)) {
1350 if (self.text_section_index == null) {1412 if (self.text_section_index == null) {
1351 self.text_section_index = @intCast(u16, text_seg.sections.items.len);1413 self.text_section_index = try self.allocateSection(
1352 try text_seg.addSection(self.base.allocator, "__text", .{1414 self.text_segment_cmd_index.?,
1353 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,1415 "__text",
1354 });1416 sect.size,
1417 sect.@"align",
1418 .{
1419 .flags = macho.S_REGULAR |
1420 macho.S_ATTR_PURE_INSTRUCTIONS |
1421 macho.S_ATTR_SOME_INSTRUCTIONS,
1422 },
1423 );
1355 }1424 }
13561425
1357 break :blk .{1426 break :blk .{
...@@ -1372,8 +1441,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1372,8 +1441,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1372 if (mem.eql(u8, segname, "__TEXT")) {1441 if (mem.eql(u8, segname, "__TEXT")) {
1373 if (mem.eql(u8, sectname, "__ustring")) {1442 if (mem.eql(u8, sectname, "__ustring")) {
1374 if (self.ustring_section_index == null) {1443 if (self.ustring_section_index == null) {
1375 self.ustring_section_index = @intCast(u16, text_seg.sections.items.len);1444 self.ustring_section_index = try self.allocateSection(
1376 try text_seg.addSection(self.base.allocator, "__ustring", .{});1445 self.text_segment_cmd_index.?,
1446 "__ustring",
1447 sect.size,
1448 sect.@"align",
1449 .{},
1450 );
1377 }1451 }
13781452
1379 break :blk .{1453 break :blk .{
...@@ -1382,8 +1456,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1382,8 +1456,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1382 };1456 };
1383 } else if (mem.eql(u8, sectname, "__gcc_except_tab")) {1457 } else if (mem.eql(u8, sectname, "__gcc_except_tab")) {
1384 if (self.gcc_except_tab_section_index == null) {1458 if (self.gcc_except_tab_section_index == null) {
1385 self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len);1459 self.gcc_except_tab_section_index = try self.allocateSection(
1386 try text_seg.addSection(self.base.allocator, "__gcc_except_tab", .{});1460 self.text_segment_cmd_index.?,
1461 "__gcc_except_tab",
1462 sect.size,
1463 sect.@"align",
1464 .{},
1465 );
1387 }1466 }
13881467
1389 break :blk .{1468 break :blk .{
...@@ -1392,8 +1471,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1392,8 +1471,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1392 };1471 };
1393 } else if (mem.eql(u8, sectname, "__objc_methlist")) {1472 } else if (mem.eql(u8, sectname, "__objc_methlist")) {
1394 if (self.objc_methlist_section_index == null) {1473 if (self.objc_methlist_section_index == null) {
1395 self.objc_methlist_section_index = @intCast(u16, text_seg.sections.items.len);1474 self.objc_methlist_section_index = try self.allocateSection(
1396 try text_seg.addSection(self.base.allocator, "__objc_methlist", .{});1475 self.text_segment_cmd_index.?,
1476 "__objc_methlist",
1477 sect.size,
1478 sect.@"align",
1479 .{},
1480 );
1397 }1481 }
13981482
1399 break :blk .{1483 break :blk .{
...@@ -1407,8 +1491,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1407,8 +1491,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1407 mem.eql(u8, sectname, "__gopclntab"))1491 mem.eql(u8, sectname, "__gopclntab"))
1408 {1492 {
1409 if (self.data_const_section_index == null) {1493 if (self.data_const_section_index == null) {
1410 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);1494 self.data_const_section_index = try self.allocateSection(
1411 try data_const_seg.addSection(self.base.allocator, "__const", .{});1495 self.data_const_segment_cmd_index.?,
1496 "__const",
1497 sect.size,
1498 sect.@"align",
1499 .{},
1500 );
1412 }1501 }
14131502
1414 break :blk .{1503 break :blk .{
...@@ -1417,8 +1506,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1417,8 +1506,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1417 };1506 };
1418 } else {1507 } else {
1419 if (self.text_const_section_index == null) {1508 if (self.text_const_section_index == null) {
1420 self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);1509 self.text_const_section_index = try self.allocateSection(
1421 try text_seg.addSection(self.base.allocator, "__const", .{});1510 self.text_segment_cmd_index.?,
1511 "__const",
1512 sect.size,
1513 sect.@"align",
1514 .{},
1515 );
1422 }1516 }
14231517
1424 break :blk .{1518 break :blk .{
...@@ -1430,8 +1524,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1430,8 +1524,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
14301524
1431 if (mem.eql(u8, segname, "__DATA_CONST")) {1525 if (mem.eql(u8, segname, "__DATA_CONST")) {
1432 if (self.data_const_section_index == null) {1526 if (self.data_const_section_index == null) {
1433 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);1527 self.data_const_section_index = try self.allocateSection(
1434 try data_const_seg.addSection(self.base.allocator, "__const", .{});1528 self.data_const_segment_cmd_index.?,
1529 "__const",
1530 sect.size,
1531 sect.@"align",
1532 .{},
1533 );
1435 }1534 }
14361535
1437 break :blk .{1536 break :blk .{
...@@ -1443,8 +1542,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1443,8 +1542,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1443 if (mem.eql(u8, segname, "__DATA")) {1542 if (mem.eql(u8, segname, "__DATA")) {
1444 if (mem.eql(u8, sectname, "__const")) {1543 if (mem.eql(u8, sectname, "__const")) {
1445 if (self.data_const_section_index == null) {1544 if (self.data_const_section_index == null) {
1446 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);1545 self.data_const_section_index = try self.allocateSection(
1447 try data_const_seg.addSection(self.base.allocator, "__const", .{});1546 self.data_const_segment_cmd_index.?,
1547 "__const",
1548 sect.size,
1549 sect.@"align",
1550 .{},
1551 );
1448 }1552 }
14491553
1450 break :blk .{1554 break :blk .{
...@@ -1453,8 +1557,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1453,8 +1557,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1453 };1557 };
1454 } else if (mem.eql(u8, sectname, "__cfstring")) {1558 } else if (mem.eql(u8, sectname, "__cfstring")) {
1455 if (self.objc_cfstring_section_index == null) {1559 if (self.objc_cfstring_section_index == null) {
1456 self.objc_cfstring_section_index = @intCast(u16, data_const_seg.sections.items.len);1560 self.objc_cfstring_section_index = try self.allocateSection(
1457 try data_const_seg.addSection(self.base.allocator, "__cfstring", .{});1561 self.data_const_segment_cmd_index.?,
1562 "__cfstring",
1563 sect.size,
1564 sect.@"align",
1565 .{},
1566 );
1458 }1567 }
14591568
1460 break :blk .{1569 break :blk .{
...@@ -1463,8 +1572,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1463,8 +1572,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1463 };1572 };
1464 } else if (mem.eql(u8, sectname, "__objc_classlist")) {1573 } else if (mem.eql(u8, sectname, "__objc_classlist")) {
1465 if (self.objc_classlist_section_index == null) {1574 if (self.objc_classlist_section_index == null) {
1466 self.objc_classlist_section_index = @intCast(u16, data_const_seg.sections.items.len);1575 self.objc_classlist_section_index = try self.allocateSection(
1467 try data_const_seg.addSection(self.base.allocator, "__objc_classlist", .{});1576 self.data_const_segment_cmd_index.?,
1577 "__objc_classlist",
1578 sect.size,
1579 sect.@"align",
1580 .{},
1581 );
1468 }1582 }
14691583
1470 break :blk .{1584 break :blk .{
...@@ -1473,8 +1587,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1473,8 +1587,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1473 };1587 };
1474 } else if (mem.eql(u8, sectname, "__objc_imageinfo")) {1588 } else if (mem.eql(u8, sectname, "__objc_imageinfo")) {
1475 if (self.objc_imageinfo_section_index == null) {1589 if (self.objc_imageinfo_section_index == null) {
1476 self.objc_imageinfo_section_index = @intCast(u16, data_const_seg.sections.items.len);1590 self.objc_imageinfo_section_index = try self.allocateSection(
1477 try data_const_seg.addSection(self.base.allocator, "__objc_imageinfo", .{});1591 self.data_const_segment_cmd_index.?,
1592 "__objc_imageinfo",
1593 sect.size,
1594 sect.@"align",
1595 .{},
1596 );
1478 }1597 }
14791598
1480 break :blk .{1599 break :blk .{
...@@ -1483,8 +1602,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1483,8 +1602,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1483 };1602 };
1484 } else if (mem.eql(u8, sectname, "__objc_const")) {1603 } else if (mem.eql(u8, sectname, "__objc_const")) {
1485 if (self.objc_const_section_index == null) {1604 if (self.objc_const_section_index == null) {
1486 self.objc_const_section_index = @intCast(u16, data_seg.sections.items.len);1605 self.objc_const_section_index = try self.allocateSection(
1487 try data_seg.addSection(self.base.allocator, "__objc_const", .{});1606 self.data_segment_cmd_index.?,
1607 "__objc_const",
1608 sect.size,
1609 sect.@"align",
1610 .{},
1611 );
1488 }1612 }
14891613
1490 break :blk .{1614 break :blk .{
...@@ -1493,8 +1617,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1493,8 +1617,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1493 };1617 };
1494 } else if (mem.eql(u8, sectname, "__objc_classrefs")) {1618 } else if (mem.eql(u8, sectname, "__objc_classrefs")) {
1495 if (self.objc_classrefs_section_index == null) {1619 if (self.objc_classrefs_section_index == null) {
1496 self.objc_classrefs_section_index = @intCast(u16, data_seg.sections.items.len);1620 self.objc_classrefs_section_index = try self.allocateSection(
1497 try data_seg.addSection(self.base.allocator, "__objc_classrefs", .{});1621 self.data_segment_cmd_index.?,
1622 "__objc_classrefs",
1623 sect.size,
1624 sect.@"align",
1625 .{},
1626 );
1498 }1627 }
14991628
1500 break :blk .{1629 break :blk .{
...@@ -1503,8 +1632,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1503,8 +1632,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1503 };1632 };
1504 } else if (mem.eql(u8, sectname, "__objc_data")) {1633 } else if (mem.eql(u8, sectname, "__objc_data")) {
1505 if (self.objc_data_section_index == null) {1634 if (self.objc_data_section_index == null) {
1506 self.objc_data_section_index = @intCast(u16, data_seg.sections.items.len);1635 self.objc_data_section_index = try self.allocateSection(
1507 try data_seg.addSection(self.base.allocator, "__objc_data", .{});1636 self.data_segment_cmd_index.?,
1637 "__objc_data",
1638 sect.size,
1639 sect.@"align",
1640 .{},
1641 );
1508 }1642 }
15091643
1510 break :blk .{1644 break :blk .{
...@@ -1513,8 +1647,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1513,8 +1647,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1513 };1647 };
1514 } else {1648 } else {
1515 if (self.data_section_index == null) {1649 if (self.data_section_index == null) {
1516 self.data_section_index = @intCast(u16, data_seg.sections.items.len);1650 self.data_section_index = try self.allocateSection(
1517 try data_seg.addSection(self.base.allocator, "__data", .{});1651 self.data_segment_cmd_index.?,
1652 "__data",
1653 sect.size,
1654 sect.@"align",
1655 .{},
1656 );
1518 }1657 }
15191658
1520 break :blk .{1659 break :blk .{
...@@ -1535,563 +1674,605 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1535,563 +1674,605 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1535 else => break :blk null,1674 else => break :blk null,
1536 }1675 }
1537 };1676 };
1538
1539 if (res) |match| {
1540 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
1541 }
1542
1543 return res;1677 return res;
1544}1678}
15451679
1546fn sortSections(self: *MachO) !void {1680pub fn createEmptyAtom(self: *MachO, local_sym_index: u32, size: u64, alignment: u32) !*Atom {
1547 var text_index_mapping = std.AutoHashMap(u16, u16).init(self.base.allocator);1681 const code = try self.base.allocator.alloc(u8, size);
1548 defer text_index_mapping.deinit();1682 defer self.base.allocator.free(code);
1549 var data_const_index_mapping = std.AutoHashMap(u16, u16).init(self.base.allocator);1683 mem.set(u8, code, 0);
1550 defer data_const_index_mapping.deinit();1684
1551 var data_index_mapping = std.AutoHashMap(u16, u16).init(self.base.allocator);1685 const atom = try self.base.allocator.create(Atom);
1552 defer data_index_mapping.deinit();1686 errdefer self.base.allocator.destroy(atom);
15531687 atom.* = Atom.empty;
1554 {1688 atom.local_sym_index = local_sym_index;
1555 // __TEXT segment1689 atom.size = size;
1556 const seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;1690 atom.alignment = alignment;
1557 var sections = seg.sections.toOwnedSlice(self.base.allocator);1691 try atom.code.appendSlice(self.base.allocator, code);
1558 defer self.base.allocator.free(sections);1692 try self.managed_atoms.append(self.base.allocator, atom);
1559 try seg.sections.ensureCapacity(self.base.allocator, sections.len);1693
15601694 return atom;
1561 const indices = &[_]*?u16{1695}
1562 &self.text_section_index,
1563 &self.stubs_section_index,
1564 &self.stub_helper_section_index,
1565 &self.gcc_except_tab_section_index,
1566 &self.cstring_section_index,
1567 &self.ustring_section_index,
1568 &self.text_const_section_index,
1569 &self.objc_methlist_section_index,
1570 &self.objc_methname_section_index,
1571 &self.objc_methtype_section_index,
1572 &self.objc_classname_section_index,
1573 &self.eh_frame_section_index,
1574 };
1575 for (indices) |maybe_index| {
1576 const new_index: u16 = if (maybe_index.*) |index| blk: {
1577 const idx = @intCast(u16, seg.sections.items.len);
1578 seg.sections.appendAssumeCapacity(sections[index]);
1579 try text_index_mapping.putNoClobber(index, idx);
1580 break :blk idx;
1581 } else continue;
1582 maybe_index.* = new_index;
1583 }
1584 }
15851696
1586 {1697pub fn writeAtom(self: *MachO, atom: *Atom, match: MatchingSection) !void {
1587 // __DATA_CONST segment1698 const seg = self.load_commands.items[match.seg].Segment;
1588 const seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;1699 const sect = seg.sections.items[match.sect];
1589 var sections = seg.sections.toOwnedSlice(self.base.allocator);1700 const sym = self.locals.items[atom.local_sym_index];
1590 defer self.base.allocator.free(sections);1701 const file_offset = sect.offset + sym.n_value - sect.addr;
1591 try seg.sections.ensureCapacity(self.base.allocator, sections.len);1702 try atom.resolveRelocs(self);
15921703 log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ self.getString(sym.n_strx), file_offset });
1593 const indices = &[_]*?u16{1704 try self.base.file.?.pwriteAll(atom.code.items, file_offset);
1594 &self.got_section_index,1705}
1595 &self.mod_init_func_section_index,
1596 &self.mod_term_func_section_index,
1597 &self.data_const_section_index,
1598 &self.objc_cfstring_section_index,
1599 &self.objc_classlist_section_index,
1600 &self.objc_imageinfo_section_index,
1601 };
1602 for (indices) |maybe_index| {
1603 const new_index: u16 = if (maybe_index.*) |index| blk: {
1604 const idx = @intCast(u16, seg.sections.items.len);
1605 seg.sections.appendAssumeCapacity(sections[index]);
1606 try data_const_index_mapping.putNoClobber(index, idx);
1607 break :blk idx;
1608 } else continue;
1609 maybe_index.* = new_index;
1610 }
1611 }
16121706
1613 {1707fn allocateLocalSymbols(self: *MachO, match: MatchingSection, offset: i64) !void {
1614 // __DATA segment1708 var atom = self.atoms.get(match) orelse return;
1615 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1616 var sections = seg.sections.toOwnedSlice(self.base.allocator);
1617 defer self.base.allocator.free(sections);
1618 try seg.sections.ensureCapacity(self.base.allocator, sections.len);
1619
1620 // __DATA segment
1621 const indices = &[_]*?u16{
1622 &self.la_symbol_ptr_section_index,
1623 &self.objc_const_section_index,
1624 &self.objc_selrefs_section_index,
1625 &self.objc_classrefs_section_index,
1626 &self.objc_data_section_index,
1627 &self.data_section_index,
1628 &self.tlv_section_index,
1629 &self.tlv_data_section_index,
1630 &self.tlv_bss_section_index,
1631 &self.bss_section_index,
1632 &self.common_section_index,
1633 };
1634 for (indices) |maybe_index| {
1635 const new_index: u16 = if (maybe_index.*) |index| blk: {
1636 const idx = @intCast(u16, seg.sections.items.len);
1637 seg.sections.appendAssumeCapacity(sections[index]);
1638 try data_index_mapping.putNoClobber(index, idx);
1639 break :blk idx;
1640 } else continue;
1641 maybe_index.* = new_index;
1642 }
1643 }
16441709
1645 {1710 while (true) {
1646 var transient: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{};1711 const atom_sym = &self.locals.items[atom.local_sym_index];
1647 try transient.ensureCapacity(self.base.allocator, self.blocks.count());1712 atom_sym.n_value = @intCast(u64, @intCast(i64, atom_sym.n_value) + offset);
16481713
1649 var it = self.blocks.iterator();1714 for (atom.aliases.items) |index| {
1650 while (it.next()) |entry| {1715 const alias_sym = &self.locals.items[index];
1651 const old = entry.key_ptr.*;1716 alias_sym.n_value = @intCast(u64, @intCast(i64, alias_sym.n_value) + offset);
1652 const sect = if (old.seg == self.text_segment_cmd_index.?)
1653 text_index_mapping.get(old.sect).?
1654 else if (old.seg == self.data_const_segment_cmd_index.?)
1655 data_const_index_mapping.get(old.sect).?
1656 else
1657 data_index_mapping.get(old.sect).?;
1658 transient.putAssumeCapacityNoClobber(.{
1659 .seg = old.seg,
1660 .sect = sect,
1661 }, entry.value_ptr.*);
1662 }1717 }
16631718
1664 self.blocks.clearAndFree(self.base.allocator);1719 for (atom.contained.items) |sym_at_off| {
1665 self.blocks.deinit(self.base.allocator);1720 const contained_sym = &self.locals.items[sym_at_off.local_sym_index];
1666 self.blocks = transient;1721 contained_sym.n_value = @intCast(u64, @intCast(i64, contained_sym.n_value) + offset);
1667 }
1668
1669 {
1670 // Create new section ordinals.
1671 self.section_ordinals.clearRetainingCapacity();
1672 const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1673 for (text_seg.sections.items) |_, sect_id| {
1674 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
1675 .seg = self.text_segment_cmd_index.?,
1676 .sect = @intCast(u16, sect_id),
1677 });
1678 assert(!res.found_existing);
1679 }
1680 const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
1681 for (data_const_seg.sections.items) |_, sect_id| {
1682 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
1683 .seg = self.data_const_segment_cmd_index.?,
1684 .sect = @intCast(u16, sect_id),
1685 });
1686 assert(!res.found_existing);
1687 }
1688 const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1689 for (data_seg.sections.items) |_, sect_id| {
1690 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
1691 .seg = self.data_segment_cmd_index.?,
1692 .sect = @intCast(u16, sect_id),
1693 });
1694 assert(!res.found_existing);
1695 }1722 }
1696 }
1697}
1698
1699fn allocateTextSegment(self: *MachO) !void {
1700 const seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1701 const nstubs = @intCast(u32, self.stubs.items.len);
1702
1703 const base_vmaddr = self.load_commands.items[self.pagezero_segment_cmd_index.?].Segment.inner.vmsize;
1704 seg.inner.fileoff = 0;
1705 seg.inner.vmaddr = base_vmaddr;
1706
1707 // Set stubs and stub_helper sizes
1708 const stubs = &seg.sections.items[self.stubs_section_index.?];
1709 const stub_helper = &seg.sections.items[self.stub_helper_section_index.?];
1710 stubs.size += nstubs * stubs.reserved2;
1711
1712 const stub_size: u4 = switch (self.base.options.target.cpu.arch) {
1713 .x86_64 => 10,
1714 .aarch64 => 3 * @sizeOf(u32),
1715 else => unreachable,
1716 };
1717 stub_helper.size += nstubs * stub_size;
1718
1719 var sizeofcmds: u64 = 0;
1720 for (self.load_commands.items) |lc| {
1721 sizeofcmds += lc.cmdsize();
1722 }
1723
1724 try self.allocateSegment(self.text_segment_cmd_index.?, @sizeOf(macho.mach_header_64) + sizeofcmds);
1725
1726 // Shift all sections to the back to minimize jump size between __TEXT and __DATA segments.
1727 var min_alignment: u32 = 0;
1728 for (seg.sections.items) |sect| {
1729 const alignment = try math.powi(u32, 2, sect.@"align");
1730 min_alignment = math.max(min_alignment, alignment);
1731 }
1732
1733 assert(min_alignment > 0);
1734 const last_sect_idx = seg.sections.items.len - 1;
1735 const last_sect = seg.sections.items[last_sect_idx];
1736 const shift: u32 = blk: {
1737 const diff = seg.inner.filesize - last_sect.offset - last_sect.size;
1738 const factor = @divTrunc(diff, min_alignment);
1739 break :blk @intCast(u32, factor * min_alignment);
1740 };
17411723
1742 if (shift > 0) {1724 if (atom.prev) |prev| {
1743 for (seg.sections.items) |*sect| {1725 atom = prev;
1744 sect.offset += shift;1726 } else break;
1745 sect.addr += shift;
1746 }
1747 }1727 }
1748}1728}
17491729
1750fn allocateDataConstSegment(self: *MachO) !void {1730fn allocateGlobalSymbols(self: *MachO) !void {
1751 const seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;1731 var sym_it = self.symbol_resolver.valueIterator();
1752 const nentries = @intCast(u32, self.got_entries.items.len);1732 while (sym_it.next()) |resolv| {
17531733 if (resolv.where != .global) continue;
1754 const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1755 seg.inner.fileoff = text_seg.inner.fileoff + text_seg.inner.filesize;
1756 seg.inner.vmaddr = text_seg.inner.vmaddr + text_seg.inner.vmsize;
1757
1758 // Set got size
1759 const got = &seg.sections.items[self.got_section_index.?];
1760 got.size += nentries * @sizeOf(u64);
1761
1762 try self.allocateSegment(self.data_const_segment_cmd_index.?, 0);
1763}
1764
1765fn allocateDataSegment(self: *MachO) !void {
1766 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1767 const nstubs = @intCast(u32, self.stubs.items.len);
1768
1769 const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
1770 seg.inner.fileoff = data_const_seg.inner.fileoff + data_const_seg.inner.filesize;
1771 seg.inner.vmaddr = data_const_seg.inner.vmaddr + data_const_seg.inner.vmsize;
1772
1773 // Set la_symbol_ptr and data size
1774 const la_symbol_ptr = &seg.sections.items[self.la_symbol_ptr_section_index.?];
1775 const data = &seg.sections.items[self.data_section_index.?];
1776 la_symbol_ptr.size += nstubs * @sizeOf(u64);
1777 data.size += @sizeOf(u64); // We need at least 8bytes for address of dyld_stub_binder
1778
1779 try self.allocateSegment(self.data_segment_cmd_index.?, 0);
1780}
1781
1782fn allocateLinkeditSegment(self: *MachO) void {
1783 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
1784 const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1785 seg.inner.fileoff = data_seg.inner.fileoff + data_seg.inner.filesize;
1786 seg.inner.vmaddr = data_seg.inner.vmaddr + data_seg.inner.vmsize;
1787}
1788
1789fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
1790 const seg = &self.load_commands.items[index].Segment;
17911734
1792 // Allocate the sections according to their alignment at the beginning of the segment.1735 assert(resolv.local_sym_index != 0);
1793 var start: u64 = offset;1736 const local_sym = self.locals.items[resolv.local_sym_index];
1794 for (seg.sections.items) |*sect| {1737 const sym = &self.globals.items[resolv.where_index];
1795 const alignment = try math.powi(u32, 2, sect.@"align");1738 sym.n_value = local_sym.n_value;
1796 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);1739 sym.n_sect = local_sym.n_sect;
1797 const end_aligned = mem.alignForwardGeneric(u64, start_aligned + sect.size, alignment);1740 log.debug("allocating global symbol {s} at 0x{x}", .{ self.getString(sym.n_strx), local_sym.n_value });
1798 sect.offset = @intCast(u32, seg.inner.fileoff + start_aligned);
1799 sect.addr = seg.inner.vmaddr + start_aligned;
1800 start = end_aligned;
1801 }1741 }
1802
1803 const seg_size_aligned = mem.alignForwardGeneric(u64, start, self.page_size);
1804 seg.inner.filesize = seg_size_aligned;
1805 seg.inner.vmsize = seg_size_aligned;
1806}1742}
18071743
1808fn allocateTextBlocks(self: *MachO) !void {1744fn writeAtoms(self: *MachO) !void {
1809 var it = self.blocks.iterator();1745 var buffer = std.ArrayList(u8).init(self.base.allocator);
1746 defer buffer.deinit();
1747 var file_offset: ?u64 = null;
1748
1749 var it = self.atoms.iterator();
1810 while (it.next()) |entry| {1750 while (it.next()) |entry| {
1811 const match = entry.key_ptr.*;1751 const match = entry.key_ptr.*;
1812 var block: *TextBlock = entry.value_ptr.*;
1813
1814 // Find the first block
1815 while (block.prev) |prev| {
1816 block = prev;
1817 }
1818
1819 const seg = self.load_commands.items[match.seg].Segment;1752 const seg = self.load_commands.items[match.seg].Segment;
1820 const sect = seg.sections.items[match.sect];1753 const sect = seg.sections.items[match.sect];
1754 var atom: *Atom = entry.value_ptr.*;
18211755
1822 var base_addr: u64 = sect.addr;1756 log.debug("writing atoms in {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) });
1823 const n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
18241757
1825 log.debug(" within section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) });1758 while (atom.prev) |prev| {
1826 log.debug(" {}", .{sect});1759 atom = prev;
1760 }
18271761
1828 while (true) {1762 while (true) {
1829 const block_alignment = try math.powi(u32, 2, block.alignment);1763 if (atom.dirty) {
1830 base_addr = mem.alignForwardGeneric(u64, base_addr, block_alignment);1764 const atom_sym = self.locals.items[atom.local_sym_index];
18311765 const padding_size: u64 = if (atom.next) |next| blk: {
1832 const sym = &self.locals.items[block.local_sym_index];1766 const next_sym = self.locals.items[next.local_sym_index];
1833 sym.n_value = base_addr;1767 break :blk next_sym.n_value - (atom_sym.n_value + atom.size);
1834 sym.n_sect = n_sect;1768 } else 0;
18351769
1836 log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{1770 log.debug(" (adding atom {s} to buffer: {})", .{ self.getString(atom_sym.n_strx), atom_sym });
1837 self.getString(sym.n_strx),1771
1838 base_addr,1772 try atom.resolveRelocs(self);
1839 base_addr + block.size,1773 try buffer.appendSlice(atom.code.items);
1840 block.size,1774 try buffer.ensureUnusedCapacity(padding_size);
1841 block.alignment,1775
1842 });1776 var i: usize = 0;
1777 while (i < padding_size) : (i += 1) {
1778 buffer.appendAssumeCapacity(0);
1779 }
18431780
1844 // Update each alias (if any)1781 if (file_offset == null) {
1845 for (block.aliases.items) |index| {1782 file_offset = sect.offset + atom_sym.n_value - sect.addr;
1846 const alias_sym = &self.locals.items[index];1783 }
1847 alias_sym.n_value = base_addr;1784 atom.dirty = false;
1848 alias_sym.n_sect = n_sect;1785 } else {
1786 if (file_offset) |off| {
1787 try self.base.file.?.pwriteAll(buffer.items, off);
1788 }
1789 file_offset = null;
1790 buffer.clearRetainingCapacity();
1849 }1791 }
18501792
1851 // Update each symbol contained within the TextBlock1793 if (atom.next) |next| {
1852 for (block.contained.items) |sym_at_off| {1794 atom = next;
1853 const contained_sym = &self.locals.items[sym_at_off.local_sym_index];1795 } else {
1854 contained_sym.n_value = base_addr + sym_at_off.offset;1796 if (file_offset) |off| {
1855 contained_sym.n_sect = n_sect;1797 try self.base.file.?.pwriteAll(buffer.items, off);
1798 }
1799 file_offset = null;
1800 buffer.clearRetainingCapacity();
1801 break;
1856 }1802 }
1857
1858 base_addr += block.size;
1859
1860 if (block.next) |next| {
1861 block = next;
1862 } else break;
1863 }1803 }
1864 }1804 }
1805}
18651806
1866 // Update globals1807pub fn createGotAtom(self: *MachO, key: GotIndirectionKey) !*Atom {
1867 {1808 const local_sym_index = @intCast(u32, self.locals.items.len);
1868 var sym_it = self.symbol_resolver.valueIterator();1809 try self.locals.append(self.base.allocator, .{
1869 while (sym_it.next()) |resolv| {1810 .n_strx = try self.makeString("l_zld_got_entry"),
1870 if (resolv.where != .global) continue;1811 .n_type = macho.N_SECT,
18711812 .n_sect = 0,
1872 assert(resolv.local_sym_index != 0);1813 .n_desc = 0,
1873 const local_sym = self.locals.items[resolv.local_sym_index];1814 .n_value = 0,
1874 const sym = &self.globals.items[resolv.where_index];1815 });
1875 sym.n_value = local_sym.n_value;1816 const atom = try self.createEmptyAtom(local_sym_index, @sizeOf(u64), 3);
1876 sym.n_sect = local_sym.n_sect;1817 switch (key.where) {
1877 }1818 .local => {
1819 try atom.relocs.append(self.base.allocator, .{
1820 .offset = 0,
1821 .where = .local,
1822 .where_index = key.where_index,
1823 .payload = .{
1824 .unsigned = .{
1825 .subtractor = null,
1826 .addend = 0,
1827 .is_64bit = true,
1828 },
1829 },
1830 });
1831 try atom.rebases.append(self.base.allocator, 0);
1832 },
1833 .undef => {
1834 try atom.bindings.append(self.base.allocator, .{
1835 .local_sym_index = key.where_index,
1836 .offset = 0,
1837 });
1838 },
1878 }1839 }
1840 return atom;
1879}1841}
18801842
1881fn writeTextBlocks(self: *MachO) !void {1843fn createDyldPrivateAtom(self: *MachO) !void {
1882 var it = self.blocks.iterator();1844 if (self.dyld_private_atom != null) return;
1883 while (it.next()) |entry| {1845 const local_sym_index = @intCast(u32, self.locals.items.len);
1884 const match = entry.key_ptr.*;1846 const sym = try self.locals.addOne(self.base.allocator);
1885 var block: *TextBlock = entry.value_ptr.*;1847 sym.* = .{
18861848 .n_strx = try self.makeString("l_zld_dyld_private"),
1887 while (block.prev) |prev| {1849 .n_type = macho.N_SECT,
1888 block = prev;1850 .n_sect = 0,
1889 }1851 .n_desc = 0,
1852 .n_value = 0,
1853 };
1854 const atom = try self.createEmptyAtom(local_sym_index, @sizeOf(u64), 3);
1855 self.dyld_private_atom = atom;
1856 const match = MatchingSection{
1857 .seg = self.data_segment_cmd_index.?,
1858 .sect = self.data_section_index.?,
1859 };
1860 const vaddr = try self.allocateAtom(atom, @sizeOf(u64), 8, match);
1861 sym.n_value = vaddr;
1862 sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
1863 log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr });
1864}
18901865
1891 const seg = self.load_commands.items[match.seg].Segment;1866fn createStubHelperPreambleAtom(self: *MachO) !void {
1892 const sect = seg.sections.items[match.sect];1867 if (self.stub_helper_preamble_atom != null) return;
1893 const sect_type = commands.sectionType(sect);1868 const arch = self.base.options.target.cpu.arch;
1869 const size: u64 = switch (arch) {
1870 .x86_64 => 15,
1871 .aarch64 => 6 * @sizeOf(u32),
1872 else => unreachable,
1873 };
1874 const alignment: u32 = switch (arch) {
1875 .x86_64 => 0,
1876 .aarch64 => 2,
1877 else => unreachable,
1878 };
1879 const local_sym_index = @intCast(u32, self.locals.items.len);
1880 const sym = try self.locals.addOne(self.base.allocator);
1881 sym.* = .{
1882 .n_strx = try self.makeString("l_zld_stub_preamble"),
1883 .n_type = macho.N_SECT,
1884 .n_sect = 0,
1885 .n_desc = 0,
1886 .n_value = 0,
1887 };
1888 const atom = try self.createEmptyAtom(local_sym_index, size, alignment);
1889 const dyld_private_sym_index = self.dyld_private_atom.?.local_sym_index;
1890 switch (arch) {
1891 .x86_64 => {
1892 try atom.relocs.ensureUnusedCapacity(self.base.allocator, 2);
1893 // lea %r11, [rip + disp]
1894 atom.code.items[0] = 0x4c;
1895 atom.code.items[1] = 0x8d;
1896 atom.code.items[2] = 0x1d;
1897 atom.relocs.appendAssumeCapacity(.{
1898 .offset = 3,
1899 .where = .local,
1900 .where_index = dyld_private_sym_index,
1901 .payload = .{
1902 .signed = .{
1903 .addend = 0,
1904 .correction = 0,
1905 },
1906 },
1907 });
1908 // push %r11
1909 atom.code.items[7] = 0x41;
1910 atom.code.items[8] = 0x53;
1911 // jmp [rip + disp]
1912 atom.code.items[9] = 0xff;
1913 atom.code.items[10] = 0x25;
1914 atom.relocs.appendAssumeCapacity(.{
1915 .offset = 11,
1916 .where = .undef,
1917 .where_index = self.dyld_stub_binder_index.?,
1918 .payload = .{
1919 .load = .{
1920 .kind = .got,
1921 .addend = 0,
1922 },
1923 },
1924 });
1925 },
1926 .aarch64 => {
1927 try atom.relocs.ensureUnusedCapacity(self.base.allocator, 4);
1928 // adrp x17, 0
1929 mem.writeIntLittle(u32, atom.code.items[0..][0..4], aarch64.Instruction.adrp(.x17, 0).toU32());
1930 atom.relocs.appendAssumeCapacity(.{
1931 .offset = 0,
1932 .where = .local,
1933 .where_index = dyld_private_sym_index,
1934 .payload = .{
1935 .page = .{
1936 .kind = .page,
1937 .addend = 0,
1938 },
1939 },
1940 });
1941 // add x17, x17, 0
1942 mem.writeIntLittle(u32, atom.code.items[4..][0..4], aarch64.Instruction.add(.x17, .x17, 0, false).toU32());
1943 atom.relocs.appendAssumeCapacity(.{
1944 .offset = 4,
1945 .where = .local,
1946 .where_index = dyld_private_sym_index,
1947 .payload = .{
1948 .page_off = .{
1949 .kind = .page,
1950 .addend = 0,
1951 .op_kind = .arithmetic,
1952 },
1953 },
1954 });
1955 // stp x16, x17, [sp, #-16]!
1956 mem.writeIntLittle(u32, atom.code.items[8..][0..4], aarch64.Instruction.stp(
1957 .x16,
1958 .x17,
1959 aarch64.Register.sp,
1960 aarch64.Instruction.LoadStorePairOffset.pre_index(-16),
1961 ).toU32());
1962 // adrp x16, 0
1963 mem.writeIntLittle(u32, atom.code.items[12..][0..4], aarch64.Instruction.adrp(.x16, 0).toU32());
1964 atom.relocs.appendAssumeCapacity(.{
1965 .offset = 12,
1966 .where = .undef,
1967 .where_index = self.dyld_stub_binder_index.?,
1968 .payload = .{
1969 .page = .{
1970 .kind = .got,
1971 .addend = 0,
1972 },
1973 },
1974 });
1975 // ldr x16, [x16, 0]
1976 mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(.x16, .{
1977 .register = .{
1978 .rn = .x16,
1979 .offset = aarch64.Instruction.LoadStoreOffset.imm(0),
1980 },
1981 }).toU32());
1982 atom.relocs.appendAssumeCapacity(.{
1983 .offset = 16,
1984 .where = .undef,
1985 .where_index = self.dyld_stub_binder_index.?,
1986 .payload = .{
1987 .page_off = .{
1988 .kind = .got,
1989 .addend = 0,
1990 },
1991 },
1992 });
1993 // br x16
1994 mem.writeIntLittle(u32, atom.code.items[20..][0..4], aarch64.Instruction.br(.x16).toU32());
1995 },
1996 else => unreachable,
1997 }
1998 self.stub_helper_preamble_atom = atom;
1999 const match = MatchingSection{
2000 .seg = self.text_segment_cmd_index.?,
2001 .sect = self.stub_helper_section_index.?,
2002 };
2003 const alignment_pow_2 = try math.powi(u32, 2, atom.alignment);
2004 const vaddr = try self.allocateAtom(atom, atom.size, alignment_pow_2, match);
2005 sym.n_value = vaddr;
2006 sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
2007 log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr });
2008}
18942009
1895 log.debug(" for section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) });2010pub fn createStubHelperAtom(self: *MachO) !*Atom {
1896 log.debug(" {}", .{sect});2011 const arch = self.base.options.target.cpu.arch;
2012 const stub_size: u4 = switch (arch) {
2013 .x86_64 => 10,
2014 .aarch64 => 3 * @sizeOf(u32),
2015 else => unreachable,
2016 };
2017 const alignment: u2 = switch (arch) {
2018 .x86_64 => 0,
2019 .aarch64 => 2,
2020 else => unreachable,
2021 };
2022 const local_sym_index = @intCast(u32, self.locals.items.len);
2023 try self.locals.append(self.base.allocator, .{
2024 .n_strx = try self.makeString("l_zld_stub_in_stub_helper"),
2025 .n_type = macho.N_SECT,
2026 .n_sect = 0,
2027 .n_desc = 0,
2028 .n_value = 0,
2029 });
2030 const atom = try self.createEmptyAtom(local_sym_index, stub_size, alignment);
2031 try atom.relocs.ensureTotalCapacity(self.base.allocator, 1);
18972032
1898 var code = try self.base.allocator.alloc(u8, sect.size);2033 switch (arch) {
1899 defer self.base.allocator.free(code);2034 .x86_64 => {
2035 // pushq
2036 atom.code.items[0] = 0x68;
2037 // Next 4 bytes 1..4 are just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
2038 // jmpq
2039 atom.code.items[5] = 0xe9;
2040 atom.relocs.appendAssumeCapacity(.{
2041 .offset = 6,
2042 .where = .local,
2043 .where_index = self.stub_helper_preamble_atom.?.local_sym_index,
2044 .payload = .{
2045 .branch = .{ .arch = arch },
2046 },
2047 });
2048 },
2049 .aarch64 => {
2050 const literal = blk: {
2051 const div_res = try math.divExact(u64, stub_size - @sizeOf(u32), 4);
2052 break :blk try math.cast(u18, div_res);
2053 };
2054 // ldr w16, literal
2055 mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldr(.w16, .{
2056 .literal = literal,
2057 }).toU32());
2058 // b disp
2059 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.b(0).toU32());
2060 atom.relocs.appendAssumeCapacity(.{
2061 .offset = 4,
2062 .where = .local,
2063 .where_index = self.stub_helper_preamble_atom.?.local_sym_index,
2064 .payload = .{
2065 .branch = .{ .arch = arch },
2066 },
2067 });
2068 // Next 4 bytes 8..12 are just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
2069 },
2070 else => unreachable,
2071 }
19002072
1901 if (sect_type == macho.S_ZEROFILL or sect_type == macho.S_THREAD_LOCAL_ZEROFILL) {2073 return atom;
1902 mem.set(u8, code, 0);2074}
1903 } else {
1904 var base_off: u64 = 0;
19052075
1906 while (true) {2076pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, lazy_binding_sym_index: u32) !*Atom {
1907 const block_alignment = try math.powi(u32, 2, block.alignment);2077 const local_sym_index = @intCast(u32, self.locals.items.len);
1908 const aligned_base_off = mem.alignForwardGeneric(u64, base_off, block_alignment);2078 try self.locals.append(self.base.allocator, .{
2079 .n_strx = try self.makeString("l_zld_lazy_ptr"),
2080 .n_type = macho.N_SECT,
2081 .n_sect = 0,
2082 .n_desc = 0,
2083 .n_value = 0,
2084 });
2085 const atom = try self.createEmptyAtom(local_sym_index, @sizeOf(u64), 3);
2086 try atom.relocs.append(self.base.allocator, .{
2087 .offset = 0,
2088 .where = .local,
2089 .where_index = stub_sym_index,
2090 .payload = .{
2091 .unsigned = .{
2092 .subtractor = null,
2093 .addend = 0,
2094 .is_64bit = true,
2095 },
2096 },
2097 });
2098 try atom.rebases.append(self.base.allocator, 0);
2099 try atom.lazy_bindings.append(self.base.allocator, .{
2100 .local_sym_index = lazy_binding_sym_index,
2101 .offset = 0,
2102 });
2103 return atom;
2104}
19092105
1910 const sym = self.locals.items[block.local_sym_index];2106pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom {
1911 log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{2107 const arch = self.base.options.target.cpu.arch;
1912 self.getString(sym.n_strx),2108 const alignment: u2 = switch (arch) {
1913 aligned_base_off,2109 .x86_64 => 0,
1914 aligned_base_off + block.size,2110 .aarch64 => 2,
1915 block.size,2111 else => unreachable, // unhandled architecture type
1916 block.alignment,2112 };
1917 });2113 const stub_size: u4 = switch (arch) {
2114 .x86_64 => 6,
2115 .aarch64 => 3 * @sizeOf(u32),
2116 else => unreachable, // unhandled architecture type
2117 };
2118 const local_sym_index = @intCast(u32, self.locals.items.len);
2119 try self.locals.append(self.base.allocator, .{
2120 .n_strx = try self.makeString("l_zld_stub"),
2121 .n_type = macho.N_SECT,
2122 .n_sect = 0,
2123 .n_desc = 0,
2124 .n_value = 0,
2125 });
2126 const atom = try self.createEmptyAtom(local_sym_index, stub_size, alignment);
2127 switch (arch) {
2128 .x86_64 => {
2129 // jmp
2130 atom.code.items[0] = 0xff;
2131 atom.code.items[1] = 0x25;
2132 try atom.relocs.append(self.base.allocator, .{
2133 .offset = 2,
2134 .where = .local,
2135 .where_index = laptr_sym_index,
2136 .payload = .{
2137 .branch = .{ .arch = arch },
2138 },
2139 });
2140 },
2141 .aarch64 => {
2142 try atom.relocs.ensureTotalCapacity(self.base.allocator, 2);
2143 // adrp x16, pages
2144 mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.adrp(.x16, 0).toU32());
2145 atom.relocs.appendAssumeCapacity(.{
2146 .offset = 0,
2147 .where = .local,
2148 .where_index = laptr_sym_index,
2149 .payload = .{
2150 .page = .{
2151 .kind = .page,
2152 .addend = 0,
2153 },
2154 },
2155 });
2156 // ldr x16, x16, offset
2157 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr(.x16, .{
2158 .register = .{
2159 .rn = .x16,
2160 .offset = aarch64.Instruction.LoadStoreOffset.imm(0),
2161 },
2162 }).toU32());
2163 atom.relocs.appendAssumeCapacity(.{
2164 .offset = 4,
2165 .where = .local,
2166 .where_index = laptr_sym_index,
2167 .payload = .{
2168 .page_off = .{
2169 .kind = .page,
2170 .addend = 0,
2171 .op_kind = .load,
2172 },
2173 },
2174 });
2175 // br x16
2176 mem.writeIntLittle(u32, atom.code.items[8..12], aarch64.Instruction.br(.x16).toU32());
2177 },
2178 else => unreachable,
2179 }
2180 return atom;
2181}
19182182
1919 try block.resolveRelocs(self);2183fn createTentativeDefAtoms(self: *MachO) !void {
1920 mem.copy(u8, code[aligned_base_off..][0..block.size], block.code.items);2184 if (self.tentatives.count() == 0) return;
2185 // Convert any tentative definition into a regular symbol and allocate
2186 // text blocks for each tentative defintion.
2187 while (self.tentatives.popOrNull()) |entry| {
2188 const match = MatchingSection{
2189 .seg = self.data_segment_cmd_index.?,
2190 .sect = self.bss_section_index.?,
2191 };
2192 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
19212193
1922 // TODO NOP for machine code instead of just zeroing out2194 const global_sym = &self.globals.items[entry.key];
1923 const padding_len = aligned_base_off - base_off;2195 const size = global_sym.n_value;
1924 mem.set(u8, code[base_off..][0..padding_len], 0);2196 const alignment = (global_sym.n_desc >> 8) & 0x0f;
19252197
1926 base_off = aligned_base_off + block.size;2198 global_sym.n_value = 0;
2199 global_sym.n_desc = 0;
2200 global_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
19272201
1928 if (block.next) |next| {2202 const local_sym_index = @intCast(u32, self.locals.items.len);
1929 block = next;2203 const local_sym = try self.locals.addOne(self.base.allocator);
1930 } else break;2204 local_sym.* = .{
1931 }2205 .n_strx = global_sym.n_strx,
2206 .n_type = macho.N_SECT,
2207 .n_sect = global_sym.n_sect,
2208 .n_desc = 0,
2209 .n_value = 0,
2210 };
19322211
1933 mem.set(u8, code[base_off..], 0);2212 const resolv = self.symbol_resolver.getPtr(local_sym.n_strx) orelse unreachable;
1934 }2213 resolv.local_sym_index = local_sym_index;
19352214
1936 try self.base.file.?.pwriteAll(code, sect.offset);2215 const atom = try self.createEmptyAtom(local_sym_index, size, alignment);
2216 const alignment_pow_2 = try math.powi(u32, 2, alignment);
2217 const vaddr = try self.allocateAtom(atom, size, alignment_pow_2, match);
2218 local_sym.n_value = vaddr;
2219 global_sym.n_value = vaddr;
1937 }2220 }
1938}2221}
19392222
1940fn writeStubHelperCommon(self: *MachO) !void {2223fn createDsoHandleAtom(self: *MachO) !void {
1941 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;2224 if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringIndexAdapter{
1942 const stub_helper = &text_segment.sections.items[self.stub_helper_section_index.?];2225 .bytes = &self.strtab,
1943 const data_const_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;2226 })) |n_strx| blk: {
1944 const got = &data_const_segment.sections.items[self.got_section_index.?];2227 const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;
1945 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;2228 if (resolv.where != .undef) break :blk;
1946 const data = &data_segment.sections.items[self.data_section_index.?];2229
19472230 const undef = &self.undefs.items[resolv.where_index];
1948 self.stub_helper_stubs_start_off = blk: {2231 const match: MatchingSection = .{
1949 switch (self.base.options.target.cpu.arch) {2232 .seg = self.text_segment_cmd_index.?,
1950 .x86_64 => {2233 .sect = self.text_section_index.?,
1951 const code_size = 15;2234 };
1952 var code: [code_size]u8 = undefined;2235 const local_sym_index = @intCast(u32, self.locals.items.len);
1953 // lea %r11, [rip + disp]2236 var nlist = macho.nlist_64{
1954 code[0] = 0x4c;2237 .n_strx = undef.n_strx,
1955 code[1] = 0x8d;2238 .n_type = macho.N_SECT,
1956 code[2] = 0x1d;2239 .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1),
1957 {2240 .n_desc = 0,
1958 const target_addr = data.addr + data.size - @sizeOf(u64);2241 .n_value = 0,
1959 const displacement = try math.cast(u32, target_addr - stub_helper.addr - 7);2242 };
1960 mem.writeIntLittle(u32, code[3..7], displacement);2243 try self.locals.append(self.base.allocator, nlist);
1961 }2244 const global_sym_index = @intCast(u32, self.globals.items.len);
1962 // push %r112245 nlist.n_type |= macho.N_EXT;
1963 code[7] = 0x41;2246 nlist.n_desc = macho.N_WEAK_DEF;
1964 code[8] = 0x53;2247 try self.globals.append(self.base.allocator, nlist);
1965 // jmp [rip + disp]2248
1966 code[9] = 0xff;2249 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
1967 code[10] = 0x25;2250
1968 {2251 undef.* = .{
1969 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{2252 .n_strx = 0,
1970 .strtab = &self.strtab,2253 .n_type = macho.N_UNDF,
1971 }) orelse unreachable;2254 .n_sect = 0,
1972 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;2255 .n_desc = 0,
1973 const got_index = self.got_entries_map.get(.{2256 .n_value = 0,
1974 .where = .undef,2257 };
1975 .where_index = resolv.where_index,2258 resolv.* = .{
1976 }) orelse unreachable;2259 .where = .global,
1977 const addr = got.addr + got_index * @sizeOf(u64);2260 .where_index = global_sym_index,
1978 const displacement = try math.cast(u32, addr - stub_helper.addr - code_size);2261 .local_sym_index = local_sym_index,
1979 mem.writeIntLittle(u32, code[11..], displacement);2262 };
1980 }
1981 try self.base.file.?.pwriteAll(&code, stub_helper.offset);
1982 break :blk stub_helper.offset + code_size;
1983 },
1984 .aarch64 => {
1985 var code: [6 * @sizeOf(u32)]u8 = undefined;
1986 data_blk_outer: {
1987 const this_addr = stub_helper.addr;
1988 const target_addr = data.addr + data.size - @sizeOf(u64);
1989 data_blk: {
1990 const displacement = math.cast(i21, target_addr - this_addr) catch break :data_blk;
1991 // adr x17, disp
1992 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x17, displacement).toU32());
1993 // nop
1994 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.nop().toU32());
1995 break :data_blk_outer;
1996 }
1997 data_blk: {
1998 const new_this_addr = this_addr + @sizeOf(u32);
1999 const displacement = math.cast(i21, target_addr - new_this_addr) catch break :data_blk;
2000 // nop
2001 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.nop().toU32());
2002 // adr x17, disp
2003 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.adr(.x17, displacement).toU32());
2004 break :data_blk_outer;
2005 }
2006 // Jump is too big, replace adr with adrp and add.
2007 const this_page = @intCast(i32, this_addr >> 12);
2008 const target_page = @intCast(i32, target_addr >> 12);
2009 const pages = @intCast(i21, target_page - this_page);
2010 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adrp(.x17, pages).toU32());
2011 const narrowed = @truncate(u12, target_addr);
2012 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.add(.x17, .x17, narrowed, false).toU32());
2013 }
2014 // stp x16, x17, [sp, #-16]!
2015 code[8] = 0xf0;
2016 code[9] = 0x47;
2017 code[10] = 0xbf;
2018 code[11] = 0xa9;
2019 binder_blk_outer: {
2020 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
2021 .strtab = &self.strtab,
2022 }) orelse unreachable;
2023 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
2024 const got_index = self.got_entries_map.get(.{
2025 .where = .undef,
2026 .where_index = resolv.where_index,
2027 }) orelse unreachable;
2028 const this_addr = stub_helper.addr + 3 * @sizeOf(u32);
2029 const target_addr = got.addr + got_index * @sizeOf(u64);
2030 binder_blk: {
2031 const displacement = math.divExact(u64, target_addr - this_addr, 4) catch break :binder_blk;
2032 const literal = math.cast(u18, displacement) catch break :binder_blk;
2033 // ldr x16, label
2034 mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.ldr(.x16, .{
2035 .literal = literal,
2036 }).toU32());
2037 // nop
2038 mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.nop().toU32());
2039 break :binder_blk_outer;
2040 }
2041 binder_blk: {
2042 const new_this_addr = this_addr + @sizeOf(u32);
2043 const displacement = math.divExact(u64, target_addr - new_this_addr, 4) catch break :binder_blk;
2044 const literal = math.cast(u18, displacement) catch break :binder_blk;
2045 // Pad with nop to please division.
2046 // nop
2047 mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.nop().toU32());
2048 // ldr x16, label
2049 mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.ldr(.x16, .{
2050 .literal = literal,
2051 }).toU32());
2052 break :binder_blk_outer;
2053 }
2054 // Use adrp followed by ldr(immediate).
2055 const this_page = @intCast(i32, this_addr >> 12);
2056 const target_page = @intCast(i32, target_addr >> 12);
2057 const pages = @intCast(i21, target_page - this_page);
2058 mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.adrp(.x16, pages).toU32());
2059 const narrowed = @truncate(u12, target_addr);
2060 const offset = try math.divExact(u12, narrowed, 8);
2061 mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.ldr(.x16, .{
2062 .register = .{
2063 .rn = .x16,
2064 .offset = aarch64.Instruction.LoadStoreOffset.imm(offset),
2065 },
2066 }).toU32());
2067 }
2068 // br x16
2069 code[20] = 0x00;
2070 code[21] = 0x02;
2071 code[22] = 0x1f;
2072 code[23] = 0xd6;
2073 try self.base.file.?.pwriteAll(&code, stub_helper.offset);
2074 break :blk stub_helper.offset + 6 * @sizeOf(u32);
2075 },
2076 else => unreachable,
2077 }
2078 };
20792263
2080 for (self.stubs.items) |_, i| {2264 // We create an empty atom for this symbol.
2081 const index = @intCast(u32, i);2265 // TODO perhaps we should special-case special symbols? Create a separate
2082 // TODO weak bound pointers2266 // linked list of atoms?
2083 try self.writeLazySymbolPointer(index);2267 const atom = try self.createEmptyAtom(local_sym_index, 0, 0);
2084 try self.writeStub(index);2268 const sym = &self.locals.items[local_sym_index];
2085 try self.writeStubInStubHelper(index);2269 const vaddr = try self.allocateAtom(atom, 0, 1, match);
2270 sym.n_value = vaddr;
2271 atom.dirty = false; // We don't really want to write it to file.
2086 }2272 }
2087}2273}
20882274
2089fn resolveSymbolsInObject(2275fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
2090 self: *MachO,
2091 object_id: u16,
2092 tentatives: *std.AutoArrayHashMap(u32, void),
2093 unresolved: *std.AutoArrayHashMap(u32, void),
2094) !void {
2095 const object = &self.objects.items[object_id];2276 const object = &self.objects.items[object_id];
20962277
2097 log.debug("resolving symbols in '{s}'", .{object.name});2278 log.debug("resolving symbols in '{s}'", .{object.name});
...@@ -2163,7 +2344,7 @@ fn resolveSymbolsInObject(...@@ -2163,7 +2344,7 @@ fn resolveSymbolsInObject(
2163 const global = &self.globals.items[resolv.where_index];2344 const global = &self.globals.items[resolv.where_index];
21642345
2165 if (symbolIsTentative(global.*)) {2346 if (symbolIsTentative(global.*)) {
2166 _ = tentatives.fetchSwapRemove(resolv.where_index);2347 _ = self.tentatives.fetchSwapRemove(resolv.where_index);
2167 } else if (!(symbolIsWeakDef(sym) or symbolIsPext(sym)) and2348 } else if (!(symbolIsWeakDef(sym) or symbolIsPext(sym)) and
2168 !(symbolIsWeakDef(global.*) or symbolIsPext(global.*)))2349 !(symbolIsWeakDef(global.*) or symbolIsPext(global.*)))
2169 {2350 {
...@@ -2181,15 +2362,7 @@ fn resolveSymbolsInObject(...@@ -2181,15 +2362,7 @@ fn resolveSymbolsInObject(
2181 continue;2362 continue;
2182 },2363 },
2183 .undef => {2364 .undef => {
2184 const undef = &self.undefs.items[resolv.where_index];2365 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
2185 undef.* = .{
2186 .n_strx = 0,
2187 .n_type = macho.N_UNDF,
2188 .n_sect = 0,
2189 .n_desc = 0,
2190 .n_value = 0,
2191 };
2192 _ = unresolved.fetchSwapRemove(resolv.where_index);
2193 },2366 },
2194 }2367 }
21952368
...@@ -2223,7 +2396,7 @@ fn resolveSymbolsInObject(...@@ -2223,7 +2396,7 @@ fn resolveSymbolsInObject(
2223 .where_index = global_sym_index,2396 .where_index = global_sym_index,
2224 .file = object_id,2397 .file = object_id,
2225 });2398 });
2226 _ = try tentatives.getOrPut(global_sym_index);2399 _ = try self.tentatives.getOrPut(self.base.allocator, global_sym_index);
2227 continue;2400 continue;
2228 };2401 };
22292402
...@@ -2247,7 +2420,7 @@ fn resolveSymbolsInObject(...@@ -2247,7 +2420,7 @@ fn resolveSymbolsInObject(
2247 .n_desc = sym.n_desc,2420 .n_desc = sym.n_desc,
2248 .n_value = sym.n_value,2421 .n_value = sym.n_value,
2249 });2422 });
2250 _ = try tentatives.getOrPut(global_sym_index);2423 _ = try self.tentatives.getOrPut(self.base.allocator, global_sym_index);
2251 resolv.* = .{2424 resolv.* = .{
2252 .where = .global,2425 .where = .global,
2253 .where_index = global_sym_index,2426 .where_index = global_sym_index,
...@@ -2260,7 +2433,7 @@ fn resolveSymbolsInObject(...@@ -2260,7 +2433,7 @@ fn resolveSymbolsInObject(
2260 .n_desc = 0,2433 .n_desc = 0,
2261 .n_value = 0,2434 .n_value = 0,
2262 };2435 };
2263 _ = unresolved.fetchSwapRemove(resolv.where_index);2436 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
2264 },2437 },
2265 }2438 }
2266 } else {2439 } else {
...@@ -2280,27 +2453,17 @@ fn resolveSymbolsInObject(...@@ -2280,27 +2453,17 @@ fn resolveSymbolsInObject(
2280 .where_index = undef_sym_index,2453 .where_index = undef_sym_index,
2281 .file = object_id,2454 .file = object_id,
2282 });2455 });
2283 _ = try unresolved.getOrPut(undef_sym_index);2456 try self.unresolved.putNoClobber(self.base.allocator, undef_sym_index, .none);
2284 }2457 }
2285 }2458 }
2286}2459}
22872460
2288fn resolveSymbols(self: *MachO) !void {2461fn resolveSymbolsInArchives(self: *MachO) !void {
2289 var tentatives = std.AutoArrayHashMap(u32, void).init(self.base.allocator);2462 if (self.archives.items.len == 0) return;
2290 defer tentatives.deinit();
2291
2292 var unresolved = std.AutoArrayHashMap(u32, void).init(self.base.allocator);
2293 defer unresolved.deinit();
2294
2295 // First pass, resolve symbols in provided objects.
2296 for (self.objects.items) |_, object_id| {
2297 try self.resolveSymbolsInObject(@intCast(u16, object_id), &tentatives, &unresolved);
2298 }
22992463
2300 // Second pass, resolve symbols in static libraries.
2301 var next_sym: usize = 0;2464 var next_sym: usize = 0;
2302 loop: while (next_sym < unresolved.count()) {2465 loop: while (next_sym < self.unresolved.count()) {
2303 const sym = self.undefs.items[unresolved.keys()[next_sym]];2466 const sym = self.undefs.items[self.unresolved.keys()[next_sym]];
2304 const sym_name = self.getString(sym.n_strx);2467 const sym_name = self.getString(sym.n_strx);
23052468
2306 for (self.archives.items) |archive| {2469 for (self.archives.items) |archive| {
...@@ -2314,111 +2477,31 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2314,111 +2477,31 @@ fn resolveSymbols(self: *MachO) !void {
2314 const object_id = @intCast(u16, self.objects.items.len);2477 const object_id = @intCast(u16, self.objects.items.len);
2315 const object = try self.objects.addOne(self.base.allocator);2478 const object = try self.objects.addOne(self.base.allocator);
2316 object.* = try archive.parseObject(self.base.allocator, self.base.options.target, offsets.items[0]);2479 object.* = try archive.parseObject(self.base.allocator, self.base.options.target, offsets.items[0]);
2317 try self.resolveSymbolsInObject(object_id, &tentatives, &unresolved);2480 try self.resolveSymbolsInObject(object_id);
23182481
2319 continue :loop;2482 continue :loop;
2320 }2483 }
23212484
2322 next_sym += 1;2485 next_sym += 1;
2323 }2486 }
2487}
23242488
2325 // Convert any tentative definition into a regular symbol and allocate2489fn resolveSymbolsInDylibs(self: *MachO) !void {
2326 // text blocks for each tentative defintion.2490 if (self.dylibs.items.len == 0) return;
2327 while (tentatives.popOrNull()) |entry| {
2328 const sym = &self.globals.items[entry.key];
2329 const match: MatchingSection = blk: {
2330 if (self.common_section_index == null) {
2331 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2332 self.common_section_index = @intCast(u16, data_seg.sections.items.len);
2333 try data_seg.addSection(self.base.allocator, "__common", .{
2334 .flags = macho.S_ZEROFILL,
2335 });
2336 }
2337 break :blk .{
2338 .seg = self.data_segment_cmd_index.?,
2339 .sect = self.common_section_index.?,
2340 };
2341 };
2342 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
2343
2344 const size = sym.n_value;
2345 const code = try self.base.allocator.alloc(u8, size);
2346 defer self.base.allocator.free(code);
2347 mem.set(u8, code, 0);
2348 const alignment = (sym.n_desc >> 8) & 0x0f;
23492491
2350 sym.n_value = 0;2492 var next_sym: usize = 0;
2351 sym.n_desc = 0;2493 loop: while (next_sym < self.unresolved.count()) {
2352 sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);2494 const sym = self.undefs.items[self.unresolved.keys()[next_sym]];
2353 var local_sym = sym.*;2495 const sym_name = self.getString(sym.n_strx);
2354 local_sym.n_type = macho.N_SECT;
23552496
2356 const local_sym_index = @intCast(u32, self.locals.items.len);2497 for (self.dylibs.items) |dylib, id| {
2357 try self.locals.append(self.base.allocator, local_sym);2498 if (!dylib.symbols.contains(sym_name)) continue;
23582499
2359 const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable;2500 const dylib_id = @intCast(u16, id);
2360 resolv.local_sym_index = local_sym_index;2501 if (!self.referenced_dylibs.contains(dylib_id)) {
23612502 try self.addLoadDylibLC(dylib_id);
2362 const block = try self.base.allocator.create(TextBlock);2503 try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});
2363 block.* = TextBlock.empty;2504 }
2364 block.local_sym_index = local_sym_index;
2365 block.size = size;
2366 block.alignment = alignment;
2367 try self.managed_blocks.append(self.base.allocator, block);
2368
2369 try block.code.appendSlice(self.base.allocator, code);
2370
2371 // Update target section's metadata
2372 // TODO should we update segment's size here too?
2373 // How does it tie with incremental space allocs?
2374 const tseg = &self.load_commands.items[match.seg].Segment;
2375 const tsect = &tseg.sections.items[match.sect];
2376 const new_alignment = math.max(tsect.@"align", block.alignment);
2377 const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment);
2378 const new_size = mem.alignForwardGeneric(u64, tsect.size, new_alignment_pow_2) + block.size;
2379 tsect.size = new_size;
2380 tsect.@"align" = new_alignment;
2381
2382 if (self.blocks.getPtr(match)) |last| {
2383 last.*.next = block;
2384 block.prev = last.*;
2385 last.* = block;
2386 } else {
2387 try self.blocks.putNoClobber(self.base.allocator, match, block);
2388 }
2389 }
2390
2391 // Third pass, resolve symbols in dynamic libraries.
2392 {
2393 // Put dyld_stub_binder as an undefined special symbol.
2394 const n_strx = try self.makeString("dyld_stub_binder");
2395 const undef_sym_index = @intCast(u32, self.undefs.items.len);
2396 try self.undefs.append(self.base.allocator, .{
2397 .n_strx = n_strx,
2398 .n_type = macho.N_UNDF,
2399 .n_sect = 0,
2400 .n_desc = 0,
2401 .n_value = 0,
2402 });
2403 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
2404 .where = .undef,
2405 .where_index = undef_sym_index,
2406 });
2407 _ = try unresolved.getOrPut(undef_sym_index);
2408 }
2409
2410 next_sym = 0;
2411 loop: while (next_sym < unresolved.count()) {
2412 const sym = self.undefs.items[unresolved.keys()[next_sym]];
2413 const sym_name = self.getString(sym.n_strx);
2414
2415 for (self.dylibs.items) |dylib, id| {
2416 if (!dylib.symbols.contains(sym_name)) continue;
2417
2418 const dylib_id = @intCast(u16, id);
2419 if (!self.referenced_dylibs.contains(dylib_id)) {
2420 try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});
2421 }
24222505
2423 const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable;2506 const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable;
2424 const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable;2507 const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable;
...@@ -2426,557 +2509,298 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2426,557 +2509,298 @@ fn resolveSymbols(self: *MachO) !void {
2426 undef.n_type |= macho.N_EXT;2509 undef.n_type |= macho.N_EXT;
2427 undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;2510 undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;
24282511
2429 _ = unresolved.fetchSwapRemove(resolv.where_index);2512 if (self.unresolved.fetchSwapRemove(resolv.where_index)) |entry| outer_blk: {
2513 switch (entry.value) {
2514 .none => {},
2515 .got => return error.TODOGotHint,
2516 .stub => {
2517 if (self.stubs_map.contains(resolv.where_index)) break :outer_blk;
2518 const stub_helper_atom = blk: {
2519 const match = MatchingSection{
2520 .seg = self.text_segment_cmd_index.?,
2521 .sect = self.stub_helper_section_index.?,
2522 };
2523 const atom = try self.createStubHelperAtom();
2524 const atom_sym = &self.locals.items[atom.local_sym_index];
2525 const alignment = try math.powi(u32, 2, atom.alignment);
2526 const vaddr = try self.allocateAtom(atom, atom.size, alignment, match);
2527 atom_sym.n_value = vaddr;
2528 atom_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
2529 break :blk atom;
2530 };
2531 const laptr_atom = blk: {
2532 const match = MatchingSection{
2533 .seg = self.data_segment_cmd_index.?,
2534 .sect = self.la_symbol_ptr_section_index.?,
2535 };
2536 const atom = try self.createLazyPointerAtom(
2537 stub_helper_atom.local_sym_index,
2538 resolv.where_index,
2539 );
2540 const atom_sym = &self.locals.items[atom.local_sym_index];
2541 const alignment = try math.powi(u32, 2, atom.alignment);
2542 const vaddr = try self.allocateAtom(atom, atom.size, alignment, match);
2543 atom_sym.n_value = vaddr;
2544 atom_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
2545 break :blk atom;
2546 };
2547 const stub_atom = blk: {
2548 const match = MatchingSection{
2549 .seg = self.text_segment_cmd_index.?,
2550 .sect = self.stubs_section_index.?,
2551 };
2552 const atom = try self.createStubAtom(laptr_atom.local_sym_index);
2553 const atom_sym = &self.locals.items[atom.local_sym_index];
2554 const alignment = try math.powi(u32, 2, atom.alignment);
2555 const vaddr = try self.allocateAtom(atom, atom.size, alignment, match);
2556 atom_sym.n_value = vaddr;
2557 atom_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
2558 break :blk atom;
2559 };
2560 try self.stubs_map.putNoClobber(self.base.allocator, resolv.where_index, stub_atom);
2561 },
2562 }
2563 }
24302564
2431 continue :loop;2565 continue :loop;
2432 }2566 }
24332567
2434 next_sym += 1;2568 next_sym += 1;
2435 }2569 }
2570}
24362571
2437 // Fourth pass, handle synthetic symbols and flag any undefined references.2572fn resolveDyldStubBinder(self: *MachO) !void {
2438 if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{2573 if (self.dyld_stub_binder_index != null) return;
2439 .strtab = &self.strtab,
2440 })) |n_strx| blk: {
2441 const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;
2442 if (resolv.where != .undef) break :blk;
2443
2444 const undef = &self.undefs.items[resolv.where_index];
2445 const match: MatchingSection = .{
2446 .seg = self.text_segment_cmd_index.?,
2447 .sect = self.text_section_index.?,
2448 };
2449 const local_sym_index = @intCast(u32, self.locals.items.len);
2450 var nlist = macho.nlist_64{
2451 .n_strx = undef.n_strx,
2452 .n_type = macho.N_SECT,
2453 .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1),
2454 .n_desc = 0,
2455 .n_value = 0,
2456 };
2457 try self.locals.append(self.base.allocator, nlist);
2458 const global_sym_index = @intCast(u32, self.globals.items.len);
2459 nlist.n_type |= macho.N_EXT;
2460 nlist.n_desc = macho.N_WEAK_DEF;
2461 try self.globals.append(self.base.allocator, nlist);
24622574
2463 _ = unresolved.fetchSwapRemove(resolv.where_index);2575 const n_strx = try self.makeString("dyld_stub_binder");
2576 const sym_index = @intCast(u32, self.undefs.items.len);
2577 try self.undefs.append(self.base.allocator, .{
2578 .n_strx = n_strx,
2579 .n_type = macho.N_UNDF,
2580 .n_sect = 0,
2581 .n_desc = 0,
2582 .n_value = 0,
2583 });
2584 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
2585 .where = .undef,
2586 .where_index = sym_index,
2587 });
2588 const sym = &self.undefs.items[sym_index];
2589 const sym_name = self.getString(n_strx);
24642590
2465 undef.* = .{2591 for (self.dylibs.items) |dylib, id| {
2466 .n_strx = 0,2592 if (!dylib.symbols.contains(sym_name)) continue;
2467 .n_type = macho.N_UNDF,
2468 .n_sect = 0,
2469 .n_desc = 0,
2470 .n_value = 0,
2471 };
2472 resolv.* = .{
2473 .where = .global,
2474 .where_index = global_sym_index,
2475 .local_sym_index = local_sym_index,
2476 };
24772593
2478 // We create an empty atom for this symbol.2594 const dylib_id = @intCast(u16, id);
2479 // TODO perhaps we should special-case special symbols? Create a separate2595 if (!self.referenced_dylibs.contains(dylib_id)) {
2480 // linked list of atoms?2596 try self.addLoadDylibLC(dylib_id);
2481 const block = try self.base.allocator.create(TextBlock);2597 try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});
2482 block.* = TextBlock.empty;
2483 block.local_sym_index = local_sym_index;
2484 block.size = 0;
2485 block.alignment = 0;
2486 try self.managed_blocks.append(self.base.allocator, block);
2487
2488 if (self.blocks.getPtr(match)) |last| {
2489 last.*.next = block;
2490 block.prev = last.*;
2491 last.* = block;
2492 } else {
2493 try self.blocks.putNoClobber(self.base.allocator, match, block);
2494 }2598 }
2495 }
24962599
2497 for (unresolved.keys()) |index| {2600 const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable;
2498 const sym = self.undefs.items[index];2601 sym.n_type |= macho.N_EXT;
2499 const sym_name = self.getString(sym.n_strx);2602 sym.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;
2500 const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;2603 self.dyld_stub_binder_index = sym_index;
25012604
2502 log.err("undefined reference to symbol '{s}'", .{sym_name});2605 break;
2503 log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name});
2504 }2606 }
25052607
2506 if (unresolved.count() > 0)2608 if (self.dyld_stub_binder_index == null) {
2609 log.err("undefined reference to symbol '{s}'", .{sym_name});
2507 return error.UndefinedSymbolReference;2610 return error.UndefinedSymbolReference;
2611 }
2612
2613 // Add dyld_stub_binder as the final GOT entry.
2614 const got_entry = GotIndirectionKey{
2615 .where = .undef,
2616 .where_index = self.dyld_stub_binder_index.?,
2617 };
2618 const atom = try self.createGotAtom(got_entry);
2619 try self.got_entries_map.putNoClobber(self.base.allocator, got_entry, atom);
2620 const match = MatchingSection{
2621 .seg = self.data_const_segment_cmd_index.?,
2622 .sect = self.got_section_index.?,
2623 };
2624 const atom_sym = &self.locals.items[atom.local_sym_index];
2625 const vaddr = try self.allocateAtom(atom, @sizeOf(u64), 8, match);
2626 atom_sym.n_value = vaddr;
2627 atom_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
2628 log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr });
2508}2629}
25092630
2510fn parseTextBlocks(self: *MachO) !void {2631fn parseObjectsIntoAtoms(self: *MachO) !void {
2632 const tracy = trace(@src());
2633 defer tracy.end();
2634
2635 var parsed_atoms = Object.ParsedAtoms.init(self.base.allocator);
2636 defer parsed_atoms.deinit();
2637
2638 var first_atoms = Object.ParsedAtoms.init(self.base.allocator);
2639 defer first_atoms.deinit();
2640
2641 var section_metadata = std.AutoHashMap(MatchingSection, struct {
2642 size: u64,
2643 alignment: u32,
2644 }).init(self.base.allocator);
2645 defer section_metadata.deinit();
2646
2511 for (self.objects.items) |*object, object_id| {2647 for (self.objects.items) |*object, object_id| {
2512 try object.parseTextBlocks(self.base.allocator, @intCast(u16, object_id), self);2648 if (object.analyzed) continue;
2513 }
2514}
25152649
2516fn populateMetadata(self: *MachO) !void {2650 var atoms_in_objects = try object.parseIntoAtoms(self.base.allocator, @intCast(u16, object_id), self);
2517 if (self.pagezero_segment_cmd_index == null) {2651 defer atoms_in_objects.deinit();
2518 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
2519 try self.load_commands.append(self.base.allocator, .{
2520 .Segment = SegmentCommand.empty("__PAGEZERO", .{
2521 .vmsize = 0x100000000, // size always set to 4GB
2522 }),
2523 });
2524 }
25252652
2526 if (self.text_segment_cmd_index == null) {2653 var it = atoms_in_objects.iterator();
2527 self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);2654 while (it.next()) |entry| {
2528 try self.load_commands.append(self.base.allocator, .{2655 const match = entry.key_ptr.*;
2529 .Segment = SegmentCommand.empty("__TEXT", .{2656 const last_atom = entry.value_ptr.*;
2530 .vmaddr = 0x100000000, // always starts at 4GB2657 var atom = last_atom;
2531 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,2658
2532 .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,2659 const metadata = try section_metadata.getOrPut(match);
2533 }),2660 if (!metadata.found_existing) {
2534 });2661 metadata.value_ptr.* = .{
2535 }2662 .size = 0,
2663 .alignment = 0,
2664 };
2665 }
25362666
2537 if (self.text_section_index == null) {2667 while (true) {
2538 const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;2668 const alignment = try math.powi(u32, 2, atom.alignment);
2539 self.text_section_index = @intCast(u16, text_seg.sections.items.len);2669 metadata.value_ptr.size += mem.alignForwardGeneric(u64, atom.size, alignment);
2540 const alignment: u2 = switch (self.base.options.target.cpu.arch) {2670 metadata.value_ptr.alignment = math.max(metadata.value_ptr.alignment, atom.alignment);
2541 .x86_64 => 0,
2542 .aarch64 => 2,
2543 else => unreachable, // unhandled architecture type
2544 };
2545 try text_seg.addSection(self.base.allocator, "__text", .{
2546 .@"align" = alignment,
2547 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2548 });
2549 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2550 .seg = self.text_segment_cmd_index.?,
2551 .sect = self.text_section_index.?,
2552 });
2553 }
25542671
2555 if (self.stubs_section_index == null) {2672 const sym = self.locals.items[atom.local_sym_index];
2556 const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;2673 log.debug(" {s}: n_value=0x{x}, size=0x{x}, alignment=0x{x}", .{
2557 self.stubs_section_index = @intCast(u16, text_seg.sections.items.len);2674 self.getString(sym.n_strx),
2558 const alignment: u2 = switch (self.base.options.target.cpu.arch) {2675 sym.n_value,
2559 .x86_64 => 0,2676 atom.size,
2560 .aarch64 => 2,2677 atom.alignment,
2561 else => unreachable, // unhandled architecture type2678 });
2562 };
2563 const stub_size: u4 = switch (self.base.options.target.cpu.arch) {
2564 .x86_64 => 6,
2565 .aarch64 => 3 * @sizeOf(u32),
2566 else => unreachable, // unhandled architecture type
2567 };
2568 try text_seg.addSection(self.base.allocator, "__stubs", .{
2569 .@"align" = alignment,
2570 .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2571 .reserved2 = stub_size,
2572 });
2573 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2574 .seg = self.text_segment_cmd_index.?,
2575 .sect = self.stubs_section_index.?,
2576 });
2577 }
25782679
2579 if (self.stub_helper_section_index == null) {2680 if (atom.prev) |prev| {
2580 const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;2681 atom = prev;
2581 self.stub_helper_section_index = @intCast(u16, text_seg.sections.items.len);2682 } else break;
2582 const alignment: u2 = switch (self.base.options.target.cpu.arch) {2683 }
2583 .x86_64 => 0,
2584 .aarch64 => 2,
2585 else => unreachable, // unhandled architecture type
2586 };
2587 const stub_helper_size: u6 = switch (self.base.options.target.cpu.arch) {
2588 .x86_64 => 15,
2589 .aarch64 => 6 * @sizeOf(u32),
2590 else => unreachable,
2591 };
2592 try text_seg.addSection(self.base.allocator, "__stub_helper", .{
2593 .size = stub_helper_size,
2594 .@"align" = alignment,
2595 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2596 });
2597 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2598 .seg = self.text_segment_cmd_index.?,
2599 .sect = self.stub_helper_section_index.?,
2600 });
2601 }
26022684
2603 if (self.data_const_segment_cmd_index == null) {2685 if (parsed_atoms.getPtr(match)) |last| {
2604 self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len);2686 last.*.next = atom;
2605 try self.load_commands.append(self.base.allocator, .{2687 atom.prev = last.*;
2606 .Segment = SegmentCommand.empty("__DATA_CONST", .{2688 last.* = atom;
2607 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,2689 }
2608 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,2690 _ = try parsed_atoms.put(match, last_atom);
2609 }),
2610 });
2611 }
26122691
2613 if (self.got_section_index == null) {2692 if (!first_atoms.contains(match)) {
2614 const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;2693 try first_atoms.putNoClobber(match, atom);
2615 self.got_section_index = @intCast(u16, data_const_seg.sections.items.len);2694 }
2616 try data_const_seg.addSection(self.base.allocator, "__got", .{2695 }
2617 .@"align" = 3, // 2^3 = @sizeOf(u64)
2618 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
2619 });
2620 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2621 .seg = self.data_const_segment_cmd_index.?,
2622 .sect = self.got_section_index.?,
2623 });
2624 }
26252696
2626 if (self.data_segment_cmd_index == null) {2697 object.analyzed = true;
2627 self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
2628 try self.load_commands.append(self.base.allocator, .{
2629 .Segment = SegmentCommand.empty("__DATA", .{
2630 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
2631 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
2632 }),
2633 });
2634 }2698 }
26352699
2636 if (self.la_symbol_ptr_section_index == null) {2700 var it = section_metadata.iterator();
2637 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;2701 while (it.next()) |entry| {
2638 self.la_symbol_ptr_section_index = @intCast(u16, data_seg.sections.items.len);2702 const match = entry.key_ptr.*;
2639 try data_seg.addSection(self.base.allocator, "__la_symbol_ptr", .{2703 const metadata = entry.value_ptr.*;
2640 .@"align" = 3, // 2^3 = @sizeOf(u64)2704 const seg = &self.load_commands.items[match.seg].Segment;
2641 .flags = macho.S_LAZY_SYMBOL_POINTERS,2705 const sect = &seg.sections.items[match.sect];
2642 });2706 log.debug("{s},{s} => size: 0x{x}, alignment: 0x{x}", .{
2643 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{2707 commands.segmentName(sect.*),
2644 .seg = self.data_segment_cmd_index.?,2708 commands.sectionName(sect.*),
2645 .sect = self.la_symbol_ptr_section_index.?,2709 metadata.size,
2710 metadata.alignment,
2646 });2711 });
2647 }
26482712
2649 if (self.data_section_index == null) {2713 const sect_size = if (self.atoms.get(match)) |last| blk: {
2650 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;2714 const last_atom_sym = self.locals.items[last.local_sym_index];
2651 self.data_section_index = @intCast(u16, data_seg.sections.items.len);2715 break :blk last_atom_sym.n_value + last.size - sect.addr;
2652 try data_seg.addSection(self.base.allocator, "__data", .{2716 } else 0;
2653 .@"align" = 3, // 2^3 = @sizeOf(u64)
2654 });
2655 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2656 .seg = self.data_segment_cmd_index.?,
2657 .sect = self.data_section_index.?,
2658 });
2659 }
26602717
2661 if (self.linkedit_segment_cmd_index == null) {2718 sect.@"align" = math.max(sect.@"align", metadata.alignment);
2662 self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);2719 const needed_size = @intCast(u32, metadata.size + sect_size);
2663 try self.load_commands.append(self.base.allocator, .{2720 try self.growSection(match, needed_size);
2664 .Segment = SegmentCommand.empty("__LINKEDIT", .{2721 sect.size = needed_size;
2665 .maxprot = macho.VM_PROT_READ,
2666 .initprot = macho.VM_PROT_READ,
2667 }),
2668 });
2669 }
26702722
2671 if (self.dyld_info_cmd_index == null) {2723 var base_vaddr = if (self.atoms.get(match)) |last| blk: {
2672 self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len);2724 const last_atom_sym = self.locals.items[last.local_sym_index];
2673 try self.load_commands.append(self.base.allocator, .{2725 break :blk last_atom_sym.n_value + last.size;
2674 .DyldInfoOnly = .{2726 } else sect.addr;
2675 .cmd = macho.LC_DYLD_INFO_ONLY,2727 const n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
2676 .cmdsize = @sizeOf(macho.dyld_info_command),
2677 .rebase_off = 0,
2678 .rebase_size = 0,
2679 .bind_off = 0,
2680 .bind_size = 0,
2681 .weak_bind_off = 0,
2682 .weak_bind_size = 0,
2683 .lazy_bind_off = 0,
2684 .lazy_bind_size = 0,
2685 .export_off = 0,
2686 .export_size = 0,
2687 },
2688 });
2689 }
26902728
2691 if (self.symtab_cmd_index == null) {2729 var atom = first_atoms.get(match).?;
2692 self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len);2730 while (true) {
2693 try self.load_commands.append(self.base.allocator, .{2731 const alignment = try math.powi(u32, 2, atom.alignment);
2694 .Symtab = .{2732 base_vaddr = mem.alignForwardGeneric(u64, base_vaddr, alignment);
2695 .cmd = macho.LC_SYMTAB,
2696 .cmdsize = @sizeOf(macho.symtab_command),
2697 .symoff = 0,
2698 .nsyms = 0,
2699 .stroff = 0,
2700 .strsize = 0,
2701 },
2702 });
2703 }
27042733
2705 if (self.dysymtab_cmd_index == null) {2734 const sym = &self.locals.items[atom.local_sym_index];
2706 self.dysymtab_cmd_index = @intCast(u16, self.load_commands.items.len);2735 sym.n_value = base_vaddr;
2707 try self.load_commands.append(self.base.allocator, .{2736 sym.n_sect = n_sect;
2708 .Dysymtab = .{
2709 .cmd = macho.LC_DYSYMTAB,
2710 .cmdsize = @sizeOf(macho.dysymtab_command),
2711 .ilocalsym = 0,
2712 .nlocalsym = 0,
2713 .iextdefsym = 0,
2714 .nextdefsym = 0,
2715 .iundefsym = 0,
2716 .nundefsym = 0,
2717 .tocoff = 0,
2718 .ntoc = 0,
2719 .modtaboff = 0,
2720 .nmodtab = 0,
2721 .extrefsymoff = 0,
2722 .nextrefsyms = 0,
2723 .indirectsymoff = 0,
2724 .nindirectsyms = 0,
2725 .extreloff = 0,
2726 .nextrel = 0,
2727 .locreloff = 0,
2728 .nlocrel = 0,
2729 },
2730 });
2731 }
27322737
2733 if (self.dylinker_cmd_index == null) {2738 log.debug(" {s}: start=0x{x}, end=0x{x}, size=0x{x}, alignment=0x{x}", .{
2734 self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len);2739 self.getString(sym.n_strx),
2735 const cmdsize = @intCast(u32, mem.alignForwardGeneric(2740 base_vaddr,
2736 u64,2741 base_vaddr + atom.size,
2737 @sizeOf(macho.dylinker_command) + mem.lenZ(DEFAULT_DYLD_PATH),2742 atom.size,
2738 @sizeOf(u64),2743 atom.alignment,
2739 ));2744 });
2740 var dylinker_cmd = commands.emptyGenericCommandWithData(macho.dylinker_command{
2741 .cmd = macho.LC_LOAD_DYLINKER,
2742 .cmdsize = cmdsize,
2743 .name = @sizeOf(macho.dylinker_command),
2744 });
2745 dylinker_cmd.data = try self.base.allocator.alloc(u8, cmdsize - dylinker_cmd.inner.name);
2746 mem.set(u8, dylinker_cmd.data, 0);
2747 mem.copy(u8, dylinker_cmd.data, mem.spanZ(DEFAULT_DYLD_PATH));
2748 try self.load_commands.append(self.base.allocator, .{ .Dylinker = dylinker_cmd });
2749 }
27502745
2751 if (self.main_cmd_index == null and self.base.options.output_mode == .Exe) {2746 // Update each alias (if any)
2752 self.main_cmd_index = @intCast(u16, self.load_commands.items.len);2747 for (atom.aliases.items) |index| {
2753 try self.load_commands.append(self.base.allocator, .{2748 const alias_sym = &self.locals.items[index];
2754 .Main = .{2749 alias_sym.n_value = base_vaddr;
2755 .cmd = macho.LC_MAIN,2750 alias_sym.n_sect = n_sect;
2756 .cmdsize = @sizeOf(macho.entry_point_command),2751 }
2757 .entryoff = 0x0,
2758 .stacksize = 0,
2759 },
2760 });
2761 }
27622752
2763 if (self.dylib_id_cmd_index == null and self.base.options.output_mode == .Lib) {2753 // Update each symbol contained within the atom
2764 self.dylib_id_cmd_index = @intCast(u16, self.load_commands.items.len);2754 for (atom.contained.items) |sym_at_off| {
2765 const install_name = try std.fmt.allocPrint(self.base.allocator, "@rpath/{s}", .{2755 const contained_sym = &self.locals.items[sym_at_off.local_sym_index];
2766 self.base.options.emit.?.sub_path,2756 contained_sym.n_value = base_vaddr + sym_at_off.offset;
2767 });2757 contained_sym.n_sect = n_sect;
2768 defer self.base.allocator.free(install_name);2758 }
2769 var dylib_cmd = try commands.createLoadDylibCommand(
2770 self.base.allocator,
2771 install_name,
2772 2,
2773 0x10000, // TODO forward user-provided versions
2774 0x10000,
2775 );
2776 errdefer dylib_cmd.deinit(self.base.allocator);
2777 dylib_cmd.inner.cmd = macho.LC_ID_DYLIB;
2778 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
2779 }
27802759
2781 if (self.source_version_cmd_index == null) {2760 base_vaddr += atom.size;
2782 self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len);
2783 try self.load_commands.append(self.base.allocator, .{
2784 .SourceVersion = .{
2785 .cmd = macho.LC_SOURCE_VERSION,
2786 .cmdsize = @sizeOf(macho.source_version_command),
2787 .version = 0x0,
2788 },
2789 });
2790 }
27912761
2792 if (self.build_version_cmd_index == null) {2762 if (atom.next) |next| {
2793 self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len);2763 atom = next;
2794 const cmdsize = @intCast(u32, mem.alignForwardGeneric(2764 } else break;
2795 u64,2765 }
2796 @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version),
2797 @sizeOf(u64),
2798 ));
2799 const ver = self.base.options.target.os.version_range.semver.min;
2800 const version = ver.major << 16 | ver.minor << 8 | ver.patch;
2801 const is_simulator_abi = self.base.options.target.abi == .simulator;
2802 var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{
2803 .cmd = macho.LC_BUILD_VERSION,
2804 .cmdsize = cmdsize,
2805 .platform = switch (self.base.options.target.os.tag) {
2806 .macos => macho.PLATFORM_MACOS,
2807 .ios => if (is_simulator_abi) macho.PLATFORM_IOSSIMULATOR else macho.PLATFORM_IOS,
2808 .watchos => if (is_simulator_abi) macho.PLATFORM_WATCHOSSIMULATOR else macho.PLATFORM_WATCHOS,
2809 .tvos => if (is_simulator_abi) macho.PLATFORM_TVOSSIMULATOR else macho.PLATFORM_TVOS,
2810 else => unreachable,
2811 },
2812 .minos = version,
2813 .sdk = version,
2814 .ntools = 1,
2815 });
2816 const ld_ver = macho.build_tool_version{
2817 .tool = macho.TOOL_LD,
2818 .version = 0x0,
2819 };
2820 cmd.data = try self.base.allocator.alloc(u8, cmdsize - @sizeOf(macho.build_version_command));
2821 mem.set(u8, cmd.data, 0);
2822 mem.copy(u8, cmd.data, mem.asBytes(&ld_ver));
2823 try self.load_commands.append(self.base.allocator, .{ .BuildVersion = cmd });
2824 }
28252766
2826 if (self.uuid_cmd_index == null) {2767 if (self.atoms.getPtr(match)) |last| {
2827 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);2768 const first_atom = first_atoms.get(match).?;
2828 var uuid_cmd: macho.uuid_command = .{2769 last.*.next = first_atom;
2829 .cmd = macho.LC_UUID,2770 first_atom.prev = last.*;
2830 .cmdsize = @sizeOf(macho.uuid_command),2771 last.* = first_atom;
2831 .uuid = undefined,2772 }
2832 };2773 _ = try self.atoms.put(self.base.allocator, match, parsed_atoms.get(match).?);
2833 std.crypto.random.bytes(&uuid_cmd.uuid);
2834 try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd });
2835 }2774 }
2836}2775}
28372776
2838fn addDataInCodeLC(self: *MachO) !void {2777fn addLoadDylibLC(self: *MachO, id: u16) !void {
2839 if (self.data_in_code_cmd_index == null) {2778 const dylib = self.dylibs.items[id];
2840 self.data_in_code_cmd_index = @intCast(u16, self.load_commands.items.len);2779 const dylib_id = dylib.id orelse unreachable;
2841 try self.load_commands.append(self.base.allocator, .{2780 var dylib_cmd = try commands.createLoadDylibCommand(
2842 .LinkeditData = .{2781 self.base.allocator,
2843 .cmd = macho.LC_DATA_IN_CODE,2782 dylib_id.name,
2844 .cmdsize = @sizeOf(macho.linkedit_data_command),2783 dylib_id.timestamp,
2845 .dataoff = 0,2784 dylib_id.current_version,
2846 .datasize = 0,2785 dylib_id.compatibility_version,
2847 },2786 );
2848 });2787 errdefer dylib_cmd.deinit(self.base.allocator);
2849 }2788 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
2789 self.load_commands_dirty = true;
2850}2790}
28512791
2852fn addCodeSignatureLC(self: *MachO) !void {2792fn addCodeSignatureLC(self: *MachO) !void {
2853 if (self.code_signature_cmd_index == null and self.requires_adhoc_codesig) {2793 if (self.code_signature_cmd_index != null or !self.requires_adhoc_codesig) return;
2854 self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len);2794 self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len);
2855 try self.load_commands.append(self.base.allocator, .{2795 try self.load_commands.append(self.base.allocator, .{
2856 .LinkeditData = .{2796 .LinkeditData = .{
2857 .cmd = macho.LC_CODE_SIGNATURE,2797 .cmd = macho.LC_CODE_SIGNATURE,
2858 .cmdsize = @sizeOf(macho.linkedit_data_command),2798 .cmdsize = @sizeOf(macho.linkedit_data_command),
2859 .dataoff = 0,2799 .dataoff = 0,
2860 .datasize = 0,2800 .datasize = 0,
2861 },2801 },
2862 });2802 });
2863 }
2864}
2865
2866fn addRpathLCs(self: *MachO, rpaths: []const []const u8) !void {
2867 for (rpaths) |rpath| {
2868 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
2869 u64,
2870 @sizeOf(macho.rpath_command) + rpath.len + 1,
2871 @sizeOf(u64),
2872 ));
2873 var rpath_cmd = commands.emptyGenericCommandWithData(macho.rpath_command{
2874 .cmd = macho.LC_RPATH,
2875 .cmdsize = cmdsize,
2876 .path = @sizeOf(macho.rpath_command),
2877 });
2878 rpath_cmd.data = try self.base.allocator.alloc(u8, cmdsize - rpath_cmd.inner.path);
2879 mem.set(u8, rpath_cmd.data, 0);
2880 mem.copy(u8, rpath_cmd.data, rpath);
2881 try self.load_commands.append(self.base.allocator, .{ .Rpath = rpath_cmd });
2882 }
2883}
2884
2885fn addLoadDylibLCs(self: *MachO) !void {
2886 for (self.referenced_dylibs.keys()) |id| {
2887 const dylib = self.dylibs.items[id];
2888 const dylib_id = dylib.id orelse unreachable;
2889 var dylib_cmd = try commands.createLoadDylibCommand(
2890 self.base.allocator,
2891 dylib_id.name,
2892 dylib_id.timestamp,
2893 dylib_id.current_version,
2894 dylib_id.compatibility_version,
2895 );
2896 errdefer dylib_cmd.deinit(self.base.allocator);
2897 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
2898 }
2899}
2900
2901fn flushZld(self: *MachO) !void {
2902 self.load_commands_dirty = true;2803 self.load_commands_dirty = true;
2903 try self.writeTextBlocks();
2904 try self.writeStubHelperCommon();
2905
2906 if (self.common_section_index) |index| {
2907 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2908 const sect = &seg.sections.items[index];
2909 sect.offset = 0;
2910 }
2911
2912 if (self.bss_section_index) |index| {
2913 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2914 const sect = &seg.sections.items[index];
2915 sect.offset = 0;
2916 }
2917
2918 if (self.tlv_bss_section_index) |index| {
2919 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2920 const sect = &seg.sections.items[index];
2921 sect.offset = 0;
2922 }
2923
2924 try self.writeGotEntries();
2925 try self.setEntryPoint();
2926 try self.writeRebaseInfoTableZld();
2927 try self.writeBindInfoTableZld();
2928 try self.writeLazyBindInfoTableZld();
2929 try self.writeExportInfoZld();
2930 try self.writeDices();
2931
2932 {
2933 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
2934 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
2935 symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
2936 }
2937
2938 try self.writeSymbolTable();
2939 try self.writeStringTableZld();
2940
2941 {
2942 // Seal __LINKEDIT size
2943 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
2944 seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size);
2945 }
2946
2947 if (self.requires_adhoc_codesig) {
2948 try self.writeCodeSignaturePadding();
2949 }
2950
2951 try self.writeLoadCommands();
2952 try self.writeHeader();
2953
2954 if (self.requires_adhoc_codesig) {
2955 try self.writeCodeSignature();
2956 }
2957}
2958
2959fn writeGotEntries(self: *MachO) !void {
2960 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
2961 const sect = seg.sections.items[self.got_section_index.?];
2962
2963 var buffer = try self.base.allocator.alloc(u8, self.got_entries.items.len * @sizeOf(u64));
2964 defer self.base.allocator.free(buffer);
2965
2966 var stream = std.io.fixedBufferStream(buffer);
2967 var writer = stream.writer();
2968
2969 for (self.got_entries.items) |key| {
2970 const address: u64 = switch (key.where) {
2971 .local => self.locals.items[key.where_index].n_value,
2972 .undef => 0,
2973 };
2974 try writer.writeIntLittle(u64, address);
2975 }
2976
2977 log.debug("writing GOT pointers at 0x{x} to 0x{x}", .{ sect.offset, sect.offset + buffer.len });
2978
2979 try self.base.file.?.pwriteAll(buffer, sect.offset);
2980}2804}
29812805
2982fn setEntryPoint(self: *MachO) !void {2806fn setEntryPoint(self: *MachO) !void {
...@@ -2985,8 +2809,8 @@ fn setEntryPoint(self: *MachO) !void {...@@ -2985,8 +2809,8 @@ fn setEntryPoint(self: *MachO) !void {
2985 // TODO we should respect the -entry flag passed in by the user to set a custom2809 // TODO we should respect the -entry flag passed in by the user to set a custom
2986 // entrypoint. For now, assume default of `_main`.2810 // entrypoint. For now, assume default of `_main`.
2987 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;2811 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
2988 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringSliceAdapter{2812 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringIndexAdapter{
2989 .strtab = &self.strtab,2813 .bytes = &self.strtab,
2990 }) orelse {2814 }) orelse {
2991 log.err("'_main' export not found", .{});2815 log.err("'_main' export not found", .{});
2992 return error.MissingMainEntrypoint;2816 return error.MissingMainEntrypoint;
...@@ -2997,2544 +2821,1547 @@ fn setEntryPoint(self: *MachO) !void {...@@ -2997,2544 +2821,1547 @@ fn setEntryPoint(self: *MachO) !void {
2997 const ec = &self.load_commands.items[self.main_cmd_index.?].Main;2821 const ec = &self.load_commands.items[self.main_cmd_index.?].Main;
2998 ec.entryoff = @intCast(u32, sym.n_value - seg.inner.vmaddr);2822 ec.entryoff = @intCast(u32, sym.n_value - seg.inner.vmaddr);
2999 ec.stacksize = self.base.options.stack_size_override orelse 0;2823 ec.stacksize = self.base.options.stack_size_override orelse 0;
2824 self.entry_addr = sym.n_value;
2825 self.load_commands_dirty = true;
3000}2826}
30012827
3002fn writeRebaseInfoTableZld(self: *MachO) !void {2828pub fn deinit(self: *MachO) void {
3003 var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);2829 if (build_options.have_llvm) {
3004 defer pointers.deinit();2830 if (self.llvm_object) |llvm_object| llvm_object.destroy(self.base.allocator);
30052831 }
3006 {
3007 var it = self.blocks.iterator();
3008 while (it.next()) |entry| {
3009 const match = entry.key_ptr.*;
3010 var block: *TextBlock = entry.value_ptr.*;
3011
3012 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable
30132832
3014 const seg = self.load_commands.items[match.seg].Segment;2833 if (self.d_sym) |*ds| {
2834 ds.deinit(self.base.allocator);
2835 }
30152836
3016 while (true) {2837 self.section_ordinals.deinit(self.base.allocator);
3017 const sym = self.locals.items[block.local_sym_index];2838 self.got_entries_map.deinit(self.base.allocator);
3018 const base_offset = sym.n_value - seg.inner.vmaddr;2839 self.stubs_map.deinit(self.base.allocator);
2840 self.strtab_dir.deinit(self.base.allocator);
2841 self.strtab.deinit(self.base.allocator);
2842 self.undefs.deinit(self.base.allocator);
2843 self.globals.deinit(self.base.allocator);
2844 self.globals_free_list.deinit(self.base.allocator);
2845 self.locals.deinit(self.base.allocator);
2846 self.locals_free_list.deinit(self.base.allocator);
2847 self.symbol_resolver.deinit(self.base.allocator);
2848 self.unresolved.deinit(self.base.allocator);
2849 self.tentatives.deinit(self.base.allocator);
30192850
3020 for (block.rebases.items) |offset| {2851 for (self.objects.items) |*object| {
3021 try pointers.append(.{2852 object.deinit(self.base.allocator);
3022 .offset = base_offset + offset,2853 }
3023 .segment_id = match.seg,2854 self.objects.deinit(self.base.allocator);
3024 });
3025 }
30262855
3027 if (block.prev) |prev| {2856 for (self.archives.items) |*archive| {
3028 block = prev;2857 archive.deinit(self.base.allocator);
3029 } else break;
3030 }
3031 }
3032 }2858 }
2859 self.archives.deinit(self.base.allocator);
30332860
3034 if (self.got_section_index) |idx| {2861 for (self.dylibs.items) |*dylib| {
3035 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;2862 dylib.deinit(self.base.allocator);
3036 const sect = seg.sections.items[idx];2863 }
3037 const base_offset = sect.addr - seg.inner.vmaddr;2864 self.dylibs.deinit(self.base.allocator);
3038 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);2865 self.dylibs_map.deinit(self.base.allocator);
2866 self.referenced_dylibs.deinit(self.base.allocator);
30392867
3040 for (self.got_entries.items) |entry, i| {2868 for (self.load_commands.items) |*lc| {
3041 if (entry.where == .undef) continue;2869 lc.deinit(self.base.allocator);
2870 }
2871 self.load_commands.deinit(self.base.allocator);
30422872
3043 try pointers.append(.{2873 for (self.managed_atoms.items) |atom| {
3044 .offset = base_offset + i * @sizeOf(u64),2874 atom.deinit(self.base.allocator);
3045 .segment_id = segment_id,2875 self.base.allocator.destroy(atom);
3046 });2876 }
2877 self.managed_atoms.deinit(self.base.allocator);
2878 self.atoms.deinit(self.base.allocator);
2879 {
2880 var it = self.atom_free_lists.valueIterator();
2881 while (it.next()) |free_list| {
2882 free_list.deinit(self.base.allocator);
3047 }2883 }
2884 self.atom_free_lists.deinit(self.base.allocator);
2885 }
2886 for (self.decls.keys()) |decl| {
2887 decl.link.macho.deinit(self.base.allocator);
3048 }2888 }
2889 self.decls.deinit(self.base.allocator);
2890}
30492891
3050 if (self.la_symbol_ptr_section_index) |idx| {2892pub fn closeFiles(self: MachO) void {
3051 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;2893 for (self.objects.items) |object| {
3052 const sect = seg.sections.items[idx];2894 object.file.close();
3053 const base_offset = sect.addr - seg.inner.vmaddr;
3054 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);
3055
3056 try pointers.ensureUnusedCapacity(self.stubs.items.len);
3057 for (self.stubs.items) |_, i| {
3058 pointers.appendAssumeCapacity(.{
3059 .offset = base_offset + i * @sizeOf(u64),
3060 .segment_id = segment_id,
3061 });
3062 }
3063 }2895 }
2896 for (self.archives.items) |archive| {
2897 archive.file.close();
2898 }
2899 for (self.dylibs.items) |dylib| {
2900 dylib.file.close();
2901 }
2902}
30642903
3065 std.sort.sort(bind.Pointer, pointers.items, {}, bind.pointerCmp);2904fn freeAtom(self: *MachO, atom: *Atom, match: MatchingSection) void {
2905 log.debug("freeAtom {*}", .{atom});
2906 atom.deinit(self.base.allocator);
30662907
3067 const size = try bind.rebaseInfoSize(pointers.items);2908 const free_list = self.atom_free_lists.getPtr(match).?;
3068 var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size));2909 var already_have_free_list_node = false;
3069 defer self.base.allocator.free(buffer);2910 {
30702911 var i: usize = 0;
3071 var stream = std.io.fixedBufferStream(buffer);2912 // TODO turn free_list into a hash map
3072 try bind.writeRebaseInfo(pointers.items, stream.writer());2913 while (i < free_list.items.len) {
30732914 if (free_list.items[i] == atom) {
3074 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;2915 _ = free_list.swapRemove(i);
3075 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;2916 continue;
3076 dyld_info.rebase_off = @intCast(u32, seg.inner.fileoff);2917 }
3077 dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64)));2918 if (free_list.items[i] == atom.prev) {
3078 seg.inner.filesize += dyld_info.rebase_size;2919 already_have_free_list_node = true;
30792920 }
3080 log.debug("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size });2921 i += 1;
3081
3082 try self.base.file.?.pwriteAll(buffer, dyld_info.rebase_off);
3083}
3084
3085fn writeBindInfoTableZld(self: *MachO) !void {
3086 var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);
3087 defer pointers.deinit();
3088
3089 if (self.got_section_index) |idx| {
3090 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
3091 const sect = seg.sections.items[idx];
3092 const base_offset = sect.addr - seg.inner.vmaddr;
3093 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);
3094
3095 for (self.got_entries.items) |entry, i| {
3096 if (entry.where == .local) continue;
3097
3098 const sym = self.undefs.items[entry.where_index];
3099 try pointers.append(.{
3100 .offset = base_offset + i * @sizeOf(u64),
3101 .segment_id = segment_id,
3102 .dylib_ordinal = @divExact(sym.n_desc, macho.N_SYMBOL_RESOLVER),
3103 .name = self.getString(sym.n_strx),
3104 });
3105 }2922 }
3106 }2923 }
2924 // TODO process free list for dbg info just like we do above for vaddrs
31072925
3108 {2926 if (self.atoms.getPtr(match)) |last_atom| {
3109 var it = self.blocks.iterator();2927 if (last_atom.* == atom) {
3110 while (it.next()) |entry| {2928 if (atom.prev) |prev| {
3111 const match = entry.key_ptr.*;2929 // TODO shrink the section size here
3112 var block: *TextBlock = entry.value_ptr.*;2930 last_atom.* = prev;
31132931 } else {
3114 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable2932 _ = self.atoms.fetchRemove(match);
31152933 }
3116 const seg = self.load_commands.items[match.seg].Segment;2934 }
2935 }
31172936
3118 while (true) {2937 if (self.d_sym) |*ds| {
3119 const sym = self.locals.items[block.local_sym_index];2938 if (ds.dbg_info_decl_first == atom) {
3120 const base_offset = sym.n_value - seg.inner.vmaddr;2939 ds.dbg_info_decl_first = atom.dbg_info_next;
2940 }
2941 if (ds.dbg_info_decl_last == atom) {
2942 // TODO shrink the .debug_info section size here
2943 ds.dbg_info_decl_last = atom.dbg_info_prev;
2944 }
2945 }
31212946
3122 for (block.bindings.items) |binding| {2947 if (atom.prev) |prev| {
3123 const bind_sym = self.undefs.items[binding.local_sym_index];2948 prev.next = atom.next;
3124 try pointers.append(.{
3125 .offset = binding.offset + base_offset,
3126 .segment_id = match.seg,
3127 .dylib_ordinal = @divExact(bind_sym.n_desc, macho.N_SYMBOL_RESOLVER),
3128 .name = self.getString(bind_sym.n_strx),
3129 });
3130 }
31312949
3132 if (block.prev) |prev| {2950 if (!already_have_free_list_node and prev.freeListEligible(self.*)) {
3133 block = prev;2951 // The free list is heuristics, it doesn't have to be perfect, so we can ignore
3134 } else break;2952 // the OOM here.
3135 }2953 free_list.append(self.base.allocator, prev) catch {};
3136 }2954 }
2955 } else {
2956 atom.prev = null;
3137 }2957 }
31382958
3139 const size = try bind.bindInfoSize(pointers.items);2959 if (atom.next) |next| {
3140 var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size));2960 next.prev = atom.prev;
3141 defer self.base.allocator.free(buffer);2961 } else {
31422962 atom.next = null;
3143 var stream = std.io.fixedBufferStream(buffer);2963 }
3144 try bind.writeBindInfo(pointers.items, stream.writer());
31452964
3146 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;2965 if (atom.dbg_info_prev) |prev| {
3147 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;2966 prev.dbg_info_next = atom.dbg_info_next;
3148 dyld_info.bind_off = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
3149 dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));
3150 seg.inner.filesize += dyld_info.bind_size;
31512967
3152 log.debug("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size });2968 // TODO the free list logic like we do for atoms above
2969 } else {
2970 atom.dbg_info_prev = null;
2971 }
31532972
3154 try self.base.file.?.pwriteAll(buffer, dyld_info.bind_off);2973 if (atom.dbg_info_next) |next| {
2974 next.dbg_info_prev = atom.dbg_info_prev;
2975 } else {
2976 atom.dbg_info_next = null;
2977 }
3155}2978}
31562979
3157fn writeLazyBindInfoTableZld(self: *MachO) !void {2980fn shrinkAtom(self: *MachO, atom: *Atom, new_block_size: u64, match: MatchingSection) void {
3158 var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);2981 _ = self;
3159 defer pointers.deinit();2982 _ = atom;
2983 _ = new_block_size;
2984 _ = match;
2985 // TODO check the new capacity, and if it crosses the size threshold into a big enough
2986 // capacity, insert a free list node for it.
2987}
31602988
3161 if (self.la_symbol_ptr_section_index) |idx| {2989fn growAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, match: MatchingSection) !u64 {
3162 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;2990 const sym = self.locals.items[atom.local_sym_index];
3163 const sect = seg.sections.items[idx];2991 const align_ok = mem.alignBackwardGeneric(u64, sym.n_value, alignment) == sym.n_value;
3164 const base_offset = sect.addr - seg.inner.vmaddr;2992 const need_realloc = !align_ok or new_atom_size > atom.capacity(self.*);
3165 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);2993 if (!need_realloc) return sym.n_value;
31662994 return self.allocateAtom(atom, new_atom_size, alignment, match);
3167 try pointers.ensureUnusedCapacity(self.stubs.items.len);2995}
3168
3169 for (self.stubs.items) |import_id, i| {
3170 const sym = self.undefs.items[import_id];
3171 pointers.appendAssumeCapacity(.{
3172 .offset = base_offset + i * @sizeOf(u64),
3173 .segment_id = segment_id,
3174 .dylib_ordinal = @divExact(sym.n_desc, macho.N_SYMBOL_RESOLVER),
3175 .name = self.getString(sym.n_strx),
3176 });
3177 }
3178 }
31792996
3180 const size = try bind.lazyBindInfoSize(pointers.items);2997pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {
3181 var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size));2998 if (decl.link.macho.local_sym_index != 0) return;
3182 defer self.base.allocator.free(buffer);
31832999
3184 var stream = std.io.fixedBufferStream(buffer);3000 try self.locals.ensureUnusedCapacity(self.base.allocator, 1);
3185 try bind.writeLazyBindInfo(pointers.items, stream.writer());3001 try self.decls.putNoClobber(self.base.allocator, decl, {});
31863002
3187 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;3003 if (self.locals_free_list.popOrNull()) |i| {
3188 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;3004 log.debug("reusing symbol index {d} for {s}", .{ i, decl.name });
3189 dyld_info.lazy_bind_off = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);3005 decl.link.macho.local_sym_index = i;
3190 dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));3006 } else {
3191 seg.inner.filesize += dyld_info.lazy_bind_size;3007 log.debug("allocating symbol index {d} for {s}", .{ self.locals.items.len, decl.name });
3008 decl.link.macho.local_sym_index = @intCast(u32, self.locals.items.len);
3009 _ = self.locals.addOneAssumeCapacity();
3010 }
31923011
3193 log.debug("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size });3012 self.locals.items[decl.link.macho.local_sym_index] = .{
3013 .n_strx = 0,
3014 .n_type = 0,
3015 .n_sect = 0,
3016 .n_desc = 0,
3017 .n_value = 0,
3018 };
31943019
3195 try self.base.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off);3020 // TODO try popping from free list first before allocating a new GOT atom.
3196 try self.populateLazyBindOffsetsInStubHelper(buffer);3021 const key = GotIndirectionKey{
3022 .where = .local,
3023 .where_index = decl.link.macho.local_sym_index,
3024 };
3025 const got_atom = try self.createGotAtom(key);
3026 try self.got_entries_map.put(self.base.allocator, key, got_atom);
3197}3027}
31983028
3199fn writeExportInfoZld(self: *MachO) !void {3029pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
3200 var trie: Trie = .{};3030 if (build_options.skip_non_native and builtin.object_format != .macho) {
3201 defer trie.deinit(self.base.allocator);3031 @panic("Attempted to compile for object format that was disabled by build configuration");
32023032 }
3203 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;3033 if (build_options.have_llvm) {
3204 const base_address = text_segment.inner.vmaddr;3034 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(module, func, air, liveness);
3035 }
3036 const tracy = trace(@src());
3037 defer tracy.end();
32053038
3206 // TODO handle macho.EXPORT_SYMBOL_FLAGS_REEXPORT and macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER.3039 const decl = func.owner_decl;
3207 log.debug("writing export trie", .{});3040 // TODO clearing the code and relocs buffer should probably be orchestrated
3041 // in a different, smarter, more automatic way somewhere else, in a more centralised
3042 // way than this.
3043 // If we don't clear the buffers here, we are up for some nasty surprises when
3044 // this atom is reused later on and was not freed by freeAtom().
3045 decl.link.macho.clearRetainingCapacity();
32083046
3209 for (self.globals.items) |sym| {3047 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
3210 const sym_name = self.getString(sym.n_strx);3048 defer code_buffer.deinit();
3211 log.debug(" | putting '{s}' defined at 0x{x}", .{ sym_name, sym.n_value });
32123049
3213 try trie.put(self.base.allocator, .{3050 var debug_buffers_buf: DebugSymbols.DeclDebugBuffers = undefined;
3214 .name = sym_name,3051 const debug_buffers = if (self.d_sym) |*ds| blk: {
3215 .vmaddr_offset = sym.n_value - base_address,3052 debug_buffers_buf = try ds.initDeclDebugBuffers(self.base.allocator, module, decl);
3216 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,3053 break :blk &debug_buffers_buf;
3217 });3054 } else null;
3055 defer {
3056 if (debug_buffers) |dbg| {
3057 dbg.dbg_line_buffer.deinit();
3058 dbg.dbg_info_buffer.deinit();
3059 var it = dbg.dbg_info_type_relocs.valueIterator();
3060 while (it.next()) |value| {
3061 value.relocs.deinit(self.base.allocator);
3062 }
3063 dbg.dbg_info_type_relocs.deinit(self.base.allocator);
3064 }
3218 }3065 }
32193066
3220 try trie.finalize(self.base.allocator);3067 self.active_decl = decl;
3221
3222 var buffer = try self.base.allocator.alloc(u8, @intCast(usize, trie.size));
3223 defer self.base.allocator.free(buffer);
32243068
3225 var stream = std.io.fixedBufferStream(buffer);3069 const res = if (debug_buffers) |dbg|
3226 const nwritten = try trie.write(stream.writer());3070 try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
3227 assert(nwritten == trie.size);3071 .dwarf = .{
3072 .dbg_line = &dbg.dbg_line_buffer,
3073 .dbg_info = &dbg.dbg_info_buffer,
3074 .dbg_info_type_relocs = &dbg.dbg_info_type_relocs,
3075 },
3076 })
3077 else
3078 try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none);
3079 switch (res) {
3080 .appended => {
3081 try decl.link.macho.code.appendSlice(self.base.allocator, code_buffer.items);
3082 },
3083 .fail => |em| {
3084 decl.analysis = .codegen_failure;
3085 try module.failed_decls.put(module.gpa, decl, em);
3086 return;
3087 },
3088 }
32283089
3229 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;3090 _ = try self.placeDecl(decl, decl.link.macho.code.items.len);
3230 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;
3231 dyld_info.export_off = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
3232 dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));
3233 seg.inner.filesize += dyld_info.export_size;
32343091
3235 log.debug("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size });3092 if (debug_buffers) |db| {
3093 try self.d_sym.?.commitDeclDebugInfo(
3094 self.base.allocator,
3095 module,
3096 decl,
3097 db,
3098 self.base.options.target,
3099 );
3100 }
32363101
3237 try self.base.file.?.pwriteAll(buffer, dyld_info.export_off);3102 // Since we updated the vaddr and the size, each corresponding export symbol also
3103 // needs to be updated.
3104 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};
3105 try self.updateDeclExports(module, decl, decl_exports);
3238}3106}
32393107
3240fn writeSymbolTable(self: *MachO) !void {3108pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
3241 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;3109 if (build_options.skip_non_native and builtin.object_format != .macho) {
3242 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;3110 @panic("Attempted to compile for object format that was disabled by build configuration");
32433111 }
3244 var locals = std.ArrayList(macho.nlist_64).init(self.base.allocator);3112 if (build_options.have_llvm) {
3245 defer locals.deinit();3113 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl);
3246 try locals.appendSlice(self.locals.items);3114 }
3115 const tracy = trace(@src());
3116 defer tracy.end();
32473117
3248 if (self.has_stabs) {3118 if (decl.val.tag() == .extern_fn) {
3249 for (self.objects.items) |object| {3119 return; // TODO Should we do more when front-end analyzed extern decl?
3250 if (object.debug_info == null) continue;3120 }
32513121
3252 // Open scope3122 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
3253 try locals.ensureUnusedCapacity(3);3123 defer code_buffer.deinit();
3254 locals.appendAssumeCapacity(.{
3255 .n_strx = try self.makeString(object.tu_comp_dir.?),
3256 .n_type = macho.N_SO,
3257 .n_sect = 0,
3258 .n_desc = 0,
3259 .n_value = 0,
3260 });
3261 locals.appendAssumeCapacity(.{
3262 .n_strx = try self.makeString(object.tu_name.?),
3263 .n_type = macho.N_SO,
3264 .n_sect = 0,
3265 .n_desc = 0,
3266 .n_value = 0,
3267 });
3268 locals.appendAssumeCapacity(.{
3269 .n_strx = try self.makeString(object.name),
3270 .n_type = macho.N_OSO,
3271 .n_sect = 0,
3272 .n_desc = 1,
3273 .n_value = object.mtime orelse 0,
3274 });
32753124
3276 for (object.text_blocks.items) |block| {3125 var debug_buffers_buf: DebugSymbols.DeclDebugBuffers = undefined;
3277 if (block.stab) |stab| {3126 const debug_buffers = if (self.d_sym) |*ds| blk: {
3278 const nlists = try stab.asNlists(block.local_sym_index, self);3127 debug_buffers_buf = try ds.initDeclDebugBuffers(self.base.allocator, module, decl);
3279 defer self.base.allocator.free(nlists);3128 break :blk &debug_buffers_buf;
3280 try locals.appendSlice(nlists);3129 } else null;
3281 } else {3130 defer {
3282 for (block.contained.items) |sym_at_off| {3131 if (debug_buffers) |dbg| {
3283 const stab = sym_at_off.stab orelse continue;3132 dbg.dbg_line_buffer.deinit();
3284 const nlists = try stab.asNlists(sym_at_off.local_sym_index, self);3133 dbg.dbg_info_buffer.deinit();
3285 defer self.base.allocator.free(nlists);3134 var it = dbg.dbg_info_type_relocs.valueIterator();
3286 try locals.appendSlice(nlists);3135 while (it.next()) |value| {
3287 }3136 value.relocs.deinit(self.base.allocator);
3288 }
3289 }3137 }
32903138 dbg.dbg_info_type_relocs.deinit(self.base.allocator);
3291 // Close scope
3292 try locals.append(.{
3293 .n_strx = 0,
3294 .n_type = macho.N_SO,
3295 .n_sect = 0,
3296 .n_desc = 0,
3297 .n_value = 0,
3298 });
3299 }3139 }
3300 }3140 }
33013141
3302 const nlocals = locals.items.len;3142 self.active_decl = decl;
3303 const nexports = self.globals.items.len;
3304 const nundefs = self.undefs.items.len;
33053143
3306 const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64);3144 const res = if (debug_buffers) |dbg|
3307 const locals_size = nlocals * @sizeOf(macho.nlist_64);3145 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
3308 log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off });3146 .ty = decl.ty,
3309 try self.base.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off);3147 .val = decl.val,
3148 }, &code_buffer, .{
3149 .dwarf = .{
3150 .dbg_line = &dbg.dbg_line_buffer,
3151 .dbg_info = &dbg.dbg_info_buffer,
3152 .dbg_info_type_relocs = &dbg.dbg_info_type_relocs,
3153 },
3154 })
3155 else
3156 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
3157 .ty = decl.ty,
3158 .val = decl.val,
3159 }, &code_buffer, .none);
33103160
3311 const exports_off = locals_off + locals_size;3161 const code = blk: {
3312 const exports_size = nexports * @sizeOf(macho.nlist_64);3162 switch (res) {
3313 log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off });3163 .externally_managed => |x| break :blk x,
3314 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.globals.items), exports_off);3164 .appended => {
3165 // TODO clearing the code and relocs buffer should probably be orchestrated
3166 // in a different, smarter, more automatic way somewhere else, in a more centralised
3167 // way than this.
3168 // If we don't clear the buffers here, we are up for some nasty surprises when
3169 // this atom is reused later on and was not freed by freeAtom().
3170 decl.link.macho.code.clearAndFree(self.base.allocator);
3171 try decl.link.macho.code.appendSlice(self.base.allocator, code_buffer.items);
3172 break :blk decl.link.macho.code.items;
3173 },
3174 .fail => |em| {
3175 decl.analysis = .codegen_failure;
3176 try module.failed_decls.put(module.gpa, decl, em);
3177 return;
3178 },
3179 }
3180 };
3181 _ = try self.placeDecl(decl, code.len);
33153182
3316 const undefs_off = exports_off + exports_size;3183 // Since we updated the vaddr and the size, each corresponding export symbol also
3317 const undefs_size = nundefs * @sizeOf(macho.nlist_64);3184 // needs to be updated.
3318 log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off });3185 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};
3319 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off);3186 try self.updateDeclExports(module, decl, decl_exports);
3187}
33203188
3321 symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs);3189fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 {
3322 seg.inner.filesize += locals_size + exports_size + undefs_size;3190 const required_alignment = decl.ty.abiAlignment(self.base.options.target);
3191 assert(decl.link.macho.local_sym_index != 0); // Caller forgot to call allocateDeclIndexes()
3192 const symbol = &self.locals.items[decl.link.macho.local_sym_index];
33233193
3324 // Update dynamic symbol table.3194 if (decl.link.macho.size != 0) {
3325 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;3195 const capacity = decl.link.macho.capacity(self.*);
3326 dysymtab.nlocalsym += @intCast(u32, nlocals);3196 const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);
3327 dysymtab.iextdefsym = dysymtab.nlocalsym;3197 if (need_realloc) {
3328 dysymtab.nextdefsym = @intCast(u32, nexports);3198 const vaddr = try self.growAtom(&decl.link.macho, code_len, required_alignment, .{
3329 dysymtab.iundefsym = dysymtab.nlocalsym + dysymtab.nextdefsym;3199 .seg = self.text_segment_cmd_index.?,
3330 dysymtab.nundefsym = @intCast(u32, nundefs);3200 .sect = self.text_section_index.?,
3201 });
33313202
3332 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;3203 log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr });
3333 const stubs = &text_segment.sections.items[self.stubs_section_index.?];
3334 const data_const_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
3335 const got = &data_const_segment.sections.items[self.got_section_index.?];
3336 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
3337 const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?];
33383204
3339 const nstubs = @intCast(u32, self.stubs.items.len);3205 if (vaddr != symbol.n_value) {
3340 const ngot_entries = @intCast(u32, self.got_entries.items.len);3206 log.debug(" (writing new GOT entry)", .{});
3207 const got_atom = self.got_entries_map.get(.{
3208 .where = .local,
3209 .where_index = decl.link.macho.local_sym_index,
3210 }) orelse unreachable;
3211 const got_sym = &self.locals.items[got_atom.local_sym_index];
3212 const got_vaddr = try self.allocateAtom(got_atom, @sizeOf(u64), 8, .{
3213 .seg = self.data_const_segment_cmd_index.?,
3214 .sect = self.got_section_index.?,
3215 });
3216 got_sym.n_value = got_vaddr;
3217 got_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(.{
3218 .seg = self.data_const_segment_cmd_index.?,
3219 .sect = self.got_section_index.?,
3220 }).? + 1);
3221 }
33413222
3342 dysymtab.indirectsymoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);3223 symbol.n_value = vaddr;
3343 dysymtab.nindirectsyms = nstubs * 2 + ngot_entries;3224 } else if (code_len < decl.link.macho.size) {
3225 self.shrinkAtom(&decl.link.macho, code_len, .{
3226 .seg = self.text_segment_cmd_index.?,
3227 .sect = self.text_section_index.?,
3228 });
3229 }
3230 decl.link.macho.size = code_len;
3231 decl.link.macho.dirty = true;
33443232
3345 const needed_size = dysymtab.nindirectsyms * @sizeOf(u32);3233 const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)});
3346 seg.inner.filesize += needed_size;3234 defer self.base.allocator.free(new_name);
33473235
3348 log.debug("writing indirect symbol table from 0x{x} to 0x{x}", .{3236 symbol.n_strx = try self.makeString(new_name);
3349 dysymtab.indirectsymoff,3237 symbol.n_type = macho.N_SECT;
3350 dysymtab.indirectsymoff + needed_size,3238 symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;
3351 });3239 symbol.n_desc = 0;
3240 } else {
3241 const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)});
3242 defer self.base.allocator.free(decl_name);
33523243
3353 var buf = try self.base.allocator.alloc(u8, needed_size);3244 const name_str_index = try self.makeString(decl_name);
3354 defer self.base.allocator.free(buf);3245 const addr = try self.allocateAtom(&decl.link.macho, code_len, required_alignment, .{
3246 .seg = self.text_segment_cmd_index.?,
3247 .sect = self.text_section_index.?,
3248 });
33553249
3356 var stream = std.io.fixedBufferStream(buf);3250 log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, addr });
3357 var writer = stream.writer();
33583251
3359 stubs.reserved1 = 0;3252 errdefer self.freeAtom(&decl.link.macho, .{
3360 for (self.stubs.items) |id| {3253 .seg = self.text_segment_cmd_index.?,
3361 try writer.writeIntLittle(u32, dysymtab.iundefsym + id);3254 .sect = self.text_section_index.?,
3362 }3255 });
33633256
3364 got.reserved1 = nstubs;3257 symbol.* = .{
3365 for (self.got_entries.items) |entry| {3258 .n_strx = name_str_index,
3366 switch (entry.where) {3259 .n_type = macho.N_SECT,
3367 .undef => {3260 .n_sect = @intCast(u8, self.text_section_index.?) + 1,
3368 try writer.writeIntLittle(u32, dysymtab.iundefsym + entry.where_index);3261 .n_desc = 0,
3369 },3262 .n_value = addr,
3370 .local => {3263 };
3371 try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL);3264 const got_atom = self.got_entries_map.get(.{
3372 },3265 .where = .local,
3373 }3266 .where_index = decl.link.macho.local_sym_index,
3267 }) orelse unreachable;
3268 const got_sym = &self.locals.items[got_atom.local_sym_index];
3269 const vaddr = try self.allocateAtom(got_atom, @sizeOf(u64), 8, .{
3270 .seg = self.data_const_segment_cmd_index.?,
3271 .sect = self.got_section_index.?,
3272 });
3273 got_sym.n_value = vaddr;
3274 got_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(.{
3275 .seg = self.data_const_segment_cmd_index.?,
3276 .sect = self.got_section_index.?,
3277 }).? + 1);
3374 }3278 }
33753279
3376 la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries;3280 return symbol;
3377 for (self.stubs.items) |id| {3281}
3378 try writer.writeIntLittle(u32, dysymtab.iundefsym + id);
3379 }
33803282
3381 try self.base.file.?.pwriteAll(buf, dysymtab.indirectsymoff);3283pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void {
3284 if (self.d_sym) |*ds| {
3285 try ds.updateDeclLineNumber(module, decl);
3286 }
3382}3287}
33833288
3384pub fn deinit(self: *MachO) void {3289pub fn updateDeclExports(
3290 self: *MachO,
3291 module: *Module,
3292 decl: *Module.Decl,
3293 exports: []const *Module.Export,
3294) !void {
3295 // TODO If we are exporting with global linkage, check for already defined globals and flag
3296 // symbol duplicate/collision!
3297 if (build_options.skip_non_native and builtin.object_format != .macho) {
3298 @panic("Attempted to compile for object format that was disabled by build configuration");
3299 }
3385 if (build_options.have_llvm) {3300 if (build_options.have_llvm) {
3386 if (self.llvm_object) |llvm_object| llvm_object.destroy(self.base.allocator);3301 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl, exports);
3387 }3302 }
3303 const tracy = trace(@src());
3304 defer tracy.end();
33883305
3389 if (self.d_sym) |*ds| {3306 try self.globals.ensureCapacity(self.base.allocator, self.globals.items.len + exports.len);
3390 ds.deinit(self.base.allocator);3307 if (decl.link.macho.local_sym_index == 0) return;
3391 }3308 const decl_sym = &self.locals.items[decl.link.macho.local_sym_index];
33923309
3393 self.section_ordinals.deinit(self.base.allocator);3310 for (exports) |exp| {
3394 self.pending_updates.deinit(self.base.allocator);3311 const exp_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{exp.options.name});
3395 self.got_entries.deinit(self.base.allocator);3312 defer self.base.allocator.free(exp_name);
3396 self.got_entries_map.deinit(self.base.allocator);
3397 self.got_entries_free_list.deinit(self.base.allocator);
3398 self.stubs.deinit(self.base.allocator);
3399 self.stubs_map.deinit(self.base.allocator);
3400 self.strtab_dir.deinit(self.base.allocator);
3401 self.strtab.deinit(self.base.allocator);
3402 self.undefs.deinit(self.base.allocator);
3403 self.globals.deinit(self.base.allocator);
3404 self.globals_free_list.deinit(self.base.allocator);
3405 self.locals.deinit(self.base.allocator);
3406 self.locals_free_list.deinit(self.base.allocator);
3407 self.symbol_resolver.deinit(self.base.allocator);
34083313
3409 for (self.objects.items) |*object| {3314 if (exp.options.section) |section_name| {
3410 object.deinit(self.base.allocator);3315 if (!mem.eql(u8, section_name, "__text")) {
3411 }3316 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.count() + 1);
3412 self.objects.deinit(self.base.allocator);3317 module.failed_exports.putAssumeCapacityNoClobber(
3318 exp,
3319 try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "Unimplemented: ExportOptions.section", .{}),
3320 );
3321 continue;
3322 }
3323 }
34133324
3414 for (self.archives.items) |*archive| {3325 var n_type: u8 = macho.N_SECT | macho.N_EXT;
3415 archive.deinit(self.base.allocator);3326 var n_desc: u16 = 0;
3416 }
3417 self.archives.deinit(self.base.allocator);
34183327
3419 for (self.dylibs.items) |*dylib| {3328 switch (exp.options.linkage) {
3420 dylib.deinit(self.base.allocator);3329 .Internal => {
3421 }3330 // Symbol should be hidden, or in MachO lingo, private extern.
3422 self.dylibs.deinit(self.base.allocator);3331 // We should also mark the symbol as Weak: n_desc == N_WEAK_DEF.
3423 self.dylibs_map.deinit(self.base.allocator);3332 // TODO work out when to add N_WEAK_REF.
3424 self.referenced_dylibs.deinit(self.base.allocator);3333 n_type |= macho.N_PEXT;
3334 n_desc |= macho.N_WEAK_DEF;
3335 },
3336 .Strong => {},
3337 .Weak => {
3338 // Weak linkage is specified as part of n_desc field.
3339 // Symbol's n_type is like for a symbol with strong linkage.
3340 n_desc |= macho.N_WEAK_DEF;
3341 },
3342 .LinkOnce => {
3343 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.count() + 1);
3344 module.failed_exports.putAssumeCapacityNoClobber(
3345 exp,
3346 try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "Unimplemented: GlobalLinkage.LinkOnce", .{}),
3347 );
3348 continue;
3349 },
3350 }
34253351
3426 for (self.load_commands.items) |*lc| {3352 const global_sym_index = if (exp.link.macho.sym_index) |i| i else blk: {
3427 lc.deinit(self.base.allocator);3353 const i = if (self.globals_free_list.popOrNull()) |i| i else inner: {
3428 }3354 _ = self.globals.addOneAssumeCapacity();
3429 self.load_commands.deinit(self.base.allocator);3355 break :inner @intCast(u32, self.globals.items.len - 1);
3356 };
3357 break :blk i;
3358 };
34303359
3431 for (self.managed_blocks.items) |block| {3360 const n_strx = try self.makeString(exp_name);
3432 block.deinit(self.base.allocator);3361 const sym = &self.globals.items[global_sym_index];
3433 self.base.allocator.destroy(block);3362 sym.* = .{
3434 }3363 .n_strx = try self.makeString(exp_name),
3435 self.managed_blocks.deinit(self.base.allocator);3364 .n_type = n_type,
3436 self.blocks.deinit(self.base.allocator);3365 .n_sect = @intCast(u8, self.text_section_index.?) + 1,
3437 self.text_block_free_list.deinit(self.base.allocator);3366 .n_desc = n_desc,
3367 .n_value = decl_sym.n_value,
3368 };
3369 exp.link.macho.sym_index = global_sym_index;
34383370
3439 for (self.decls.keys()) |decl| {3371 const resolv = try self.symbol_resolver.getOrPut(self.base.allocator, n_strx);
3440 decl.link.macho.deinit(self.base.allocator);3372 resolv.value_ptr.* = .{
3373 .where = .global,
3374 .where_index = global_sym_index,
3375 .local_sym_index = decl.link.macho.local_sym_index,
3376 };
3441 }3377 }
3442 self.decls.deinit(self.base.allocator);
3443}3378}
34443379
3445pub fn closeFiles(self: MachO) void {3380pub fn deleteExport(self: *MachO, exp: Export) void {
3446 for (self.objects.items) |object| {3381 const sym_index = exp.sym_index orelse return;
3447 object.file.close();3382 self.globals_free_list.append(self.base.allocator, sym_index) catch {};
3448 }3383 const global = &self.globals.items[sym_index];
3449 for (self.archives.items) |archive| {3384 global.n_type = 0;
3450 archive.file.close();3385 assert(self.symbol_resolver.remove(global.n_strx));
3451 }
3452 for (self.dylibs.items) |dylib| {
3453 dylib.file.close();
3454 }
3455}3386}
34563387
3457fn freeTextBlock(self: *MachO, text_block: *TextBlock) void {3388pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {
3458 log.debug("freeTextBlock {*}", .{text_block});3389 log.debug("freeDecl {*}", .{decl});
3459 text_block.deinit(self.base.allocator);3390 _ = self.decls.swapRemove(decl);
3391 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
3392 self.freeAtom(&decl.link.macho, .{
3393 .seg = self.text_segment_cmd_index.?,
3394 .sect = self.text_section_index.?,
3395 });
3396 if (decl.link.macho.local_sym_index != 0) {
3397 self.locals_free_list.append(self.base.allocator, decl.link.macho.local_sym_index) catch {};
34603398
3461 var already_have_free_list_node = false;3399 // TODO free GOT atom here.
3462 {
3463 var i: usize = 0;
3464 // TODO turn text_block_free_list into a hash map
3465 while (i < self.text_block_free_list.items.len) {
3466 if (self.text_block_free_list.items[i] == text_block) {
3467 _ = self.text_block_free_list.swapRemove(i);
3468 continue;
3469 }
3470 if (self.text_block_free_list.items[i] == text_block.prev) {
3471 already_have_free_list_node = true;
3472 }
3473 i += 1;
3474 }
3475 }
3476 // TODO process free list for dbg info just like we do above for vaddrs
34773400
3478 if (self.last_text_block == text_block) {3401 self.locals.items[decl.link.macho.local_sym_index].n_type = 0;
3479 // TODO shrink the __text section size here3402 decl.link.macho.local_sym_index = 0;
3480 self.last_text_block = text_block.prev;
3481 }3403 }
3482 if (self.d_sym) |*ds| {3404 if (self.d_sym) |*ds| {
3483 if (ds.dbg_info_decl_first == text_block) {3405 // TODO make this logic match freeAtom. Maybe abstract the logic
3484 ds.dbg_info_decl_first = text_block.dbg_info_next;3406 // out since the same thing is desired for both.
3407 _ = ds.dbg_line_fn_free_list.remove(&decl.fn_link.macho);
3408 if (decl.fn_link.macho.prev) |prev| {
3409 ds.dbg_line_fn_free_list.put(self.base.allocator, prev, {}) catch {};
3410 prev.next = decl.fn_link.macho.next;
3411 if (decl.fn_link.macho.next) |next| {
3412 next.prev = prev;
3413 } else {
3414 ds.dbg_line_fn_last = prev;
3415 }
3416 } else if (decl.fn_link.macho.next) |next| {
3417 ds.dbg_line_fn_first = next;
3418 next.prev = null;
3485 }3419 }
3486 if (ds.dbg_info_decl_last == text_block) {3420 if (ds.dbg_line_fn_first == &decl.fn_link.macho) {
3487 // TODO shrink the .debug_info section size here3421 ds.dbg_line_fn_first = decl.fn_link.macho.next;
3488 ds.dbg_info_decl_last = text_block.dbg_info_prev;3422 }
3423 if (ds.dbg_line_fn_last == &decl.fn_link.macho) {
3424 ds.dbg_line_fn_last = decl.fn_link.macho.prev;
3489 }3425 }
3490 }3426 }
3427}
34913428
3492 if (text_block.prev) |prev| {3429pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl) u64 {
3493 prev.next = text_block.next;3430 assert(decl.link.macho.local_sym_index != 0);
3431 return self.locals.items[decl.link.macho.local_sym_index].n_value;
3432}
34943433
3495 if (!already_have_free_list_node and prev.freeListEligible(self.*)) {3434pub fn populateMissingMetadata(self: *MachO) !void {
3496 // The free list is heuristics, it doesn't have to be perfect, so we can ignore3435 if (self.pagezero_segment_cmd_index == null) {
3497 // the OOM here.3436 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
3498 self.text_block_free_list.append(self.base.allocator, prev) catch {};3437 try self.load_commands.append(self.base.allocator, .{
3499 }3438 .Segment = .{
3500 } else {3439 .inner = .{
3501 text_block.prev = null;3440 .segname = makeStaticString("__PAGEZERO"),
3441 .vmsize = pagezero_vmsize,
3442 },
3443 },
3444 });
3445 self.load_commands_dirty = true;
3502 }3446 }
35033447
3504 if (text_block.next) |next| {3448 if (self.text_segment_cmd_index == null) {
3505 next.prev = text_block.prev;3449 self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
3506 } else {3450 const program_code_size_hint = self.base.options.program_code_size_hint;
3507 text_block.next = null;3451 const got_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint;
3508 }3452 const ideal_size = self.header_pad + program_code_size_hint + got_size_hint;
3453 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
35093454
3510 if (text_block.dbg_info_prev) |prev| {3455 log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });
3511 prev.dbg_info_next = text_block.dbg_info_next;
35123456
3513 // TODO the free list logic like we do for text blocks above3457 try self.load_commands.append(self.base.allocator, .{
3514 } else {3458 .Segment = .{
3515 text_block.dbg_info_prev = null;3459 .inner = .{
3460 .segname = makeStaticString("__TEXT"),
3461 .vmaddr = pagezero_vmsize,
3462 .vmsize = needed_size,
3463 .filesize = needed_size,
3464 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
3465 .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
3466 },
3467 },
3468 });
3469 self.load_commands_dirty = true;
3516 }3470 }
35173471
3518 if (text_block.dbg_info_next) |next| {3472 if (self.text_section_index == null) {
3519 next.dbg_info_prev = text_block.dbg_info_prev;3473 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
3520 } else {3474 .x86_64 => 0,
3521 text_block.dbg_info_next = null;3475 .aarch64 => 2,
3476 else => unreachable, // unhandled architecture type
3477 };
3478 const needed_size = self.base.options.program_code_size_hint;
3479 self.text_section_index = try self.allocateSection(
3480 self.text_segment_cmd_index.?,
3481 "__text",
3482 needed_size,
3483 alignment,
3484 .{
3485 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
3486 },
3487 );
3522 }3488 }
3523}
35243489
3525fn shrinkTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64) void {3490 if (self.stubs_section_index == null) {
3526 _ = self;3491 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
3527 _ = text_block;3492 .x86_64 => 0,
3528 _ = new_block_size;3493 .aarch64 => 2,
3529 // TODO check the new capacity, and if it crosses the size threshold into a big enough3494 else => unreachable, // unhandled architecture type
3530 // capacity, insert a free list node for it.3495 };
3531}3496 const stub_size: u4 = switch (self.base.options.target.cpu.arch) {
3497 .x86_64 => 6,
3498 .aarch64 => 3 * @sizeOf(u32),
3499 else => unreachable, // unhandled architecture type
3500 };
3501 const needed_size = stub_size * self.base.options.symbol_count_hint;
3502 self.stubs_section_index = try self.allocateSection(
3503 self.text_segment_cmd_index.?,
3504 "__stubs",
3505 needed_size,
3506 alignment,
3507 .{
3508 .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
3509 .reserved2 = stub_size,
3510 },
3511 );
3512 }
35323513
3533fn growTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {3514 if (self.stub_helper_section_index == null) {
3534 const sym = self.locals.items[text_block.local_sym_index];3515 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
3535 const align_ok = mem.alignBackwardGeneric(u64, sym.n_value, alignment) == sym.n_value;3516 .x86_64 => 0,
3536 const need_realloc = !align_ok or new_block_size > text_block.capacity(self.*);3517 .aarch64 => 2,
3537 if (!need_realloc) return sym.n_value;3518 else => unreachable, // unhandled architecture type
3538 return self.allocateTextBlock(text_block, new_block_size, alignment);3519 };
3539}3520 const preamble_size: u6 = switch (self.base.options.target.cpu.arch) {
3521 .x86_64 => 15,
3522 .aarch64 => 6 * @sizeOf(u32),
3523 else => unreachable,
3524 };
3525 const stub_size: u4 = switch (self.base.options.target.cpu.arch) {
3526 .x86_64 => 10,
3527 .aarch64 => 3 * @sizeOf(u32),
3528 else => unreachable,
3529 };
3530 const needed_size = stub_size * self.base.options.symbol_count_hint + preamble_size;
3531 self.stub_helper_section_index = try self.allocateSection(
3532 self.text_segment_cmd_index.?,
3533 "__stub_helper",
3534 needed_size,
3535 alignment,
3536 .{
3537 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
3538 },
3539 );
3540 }
35403541
3541pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {3542 if (self.data_const_segment_cmd_index == null) {
3542 if (decl.link.macho.local_sym_index != 0) return;3543 self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
3544 const address_and_offset = self.nextSegmentAddressAndOffset();
3545 const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
3546 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
35433547
3544 try self.locals.ensureUnusedCapacity(self.base.allocator, 1);3548 log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{
3545 try self.got_entries.ensureUnusedCapacity(self.base.allocator, 1);3549 address_and_offset.offset,
3550 address_and_offset.offset + needed_size,
3551 });
35463552
3547 try self.decls.putNoClobber(self.base.allocator, decl, {});3553 try self.load_commands.append(self.base.allocator, .{
3554 .Segment = .{
3555 .inner = .{
3556 .segname = makeStaticString("__DATA_CONST"),
3557 .vmaddr = address_and_offset.address,
3558 .vmsize = needed_size,
3559 .fileoff = address_and_offset.offset,
3560 .filesize = needed_size,
3561 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
3562 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
3563 },
3564 },
3565 });
3566 self.load_commands_dirty = true;
3567 }
35483568
3549 if (self.locals_free_list.popOrNull()) |i| {3569 if (self.got_section_index == null) {
3550 log.debug("reusing symbol index {d} for {s}", .{ i, decl.name });3570 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
3551 decl.link.macho.local_sym_index = i;3571 const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
3552 } else {3572 self.got_section_index = try self.allocateSection(
3553 log.debug("allocating symbol index {d} for {s}", .{ self.locals.items.len, decl.name });3573 self.data_const_segment_cmd_index.?,
3554 decl.link.macho.local_sym_index = @intCast(u32, self.locals.items.len);3574 "__got",
3555 _ = self.locals.addOneAssumeCapacity();3575 needed_size,
3576 alignment,
3577 .{
3578 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
3579 },
3580 );
3556 }3581 }
35573582
3558 const got_index: u32 = blk: {3583 if (self.data_segment_cmd_index == null) {
3559 if (self.got_entries_free_list.popOrNull()) |i| {3584 self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
3560 log.debug("reusing GOT entry index {d} for {s}", .{ i, decl.name });3585 const address_and_offset = self.nextSegmentAddressAndOffset();
3561 break :blk i;3586 const ideal_size = 2 * @sizeOf(u64) * self.base.options.symbol_count_hint;
3562 } else {3587 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
3563 const got_index = @intCast(u32, self.got_entries.items.len);
3564 log.debug("allocating GOT entry index {d} for {s}", .{ got_index, decl.name });
3565 _ = self.got_entries.addOneAssumeCapacity();
3566 self.got_entries_count_dirty = true;
3567 self.rebase_info_dirty = true;
3568 break :blk got_index;
3569 }
3570 };
35713588
3572 self.locals.items[decl.link.macho.local_sym_index] = .{3589 log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
3573 .n_strx = 0,
3574 .n_type = 0,
3575 .n_sect = 0,
3576 .n_desc = 0,
3577 .n_value = 0,
3578 };
3579 const got_entry = GotIndirectionKey{
3580 .where = .local,
3581 .where_index = decl.link.macho.local_sym_index,
3582 };
3583 self.got_entries.items[got_index] = got_entry;
3584 try self.got_entries_map.putNoClobber(self.base.allocator, got_entry, got_index);
3585}
35863590
3587pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {3591 try self.load_commands.append(self.base.allocator, .{
3588 if (build_options.skip_non_native and builtin.object_format != .macho) {3592 .Segment = .{
3589 @panic("Attempted to compile for object format that was disabled by build configuration");3593 .inner = .{
3594 .segname = makeStaticString("__DATA"),
3595 .vmaddr = address_and_offset.address,
3596 .vmsize = needed_size,
3597 .fileoff = address_and_offset.offset,
3598 .filesize = needed_size,
3599 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
3600 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
3601 },
3602 },
3603 });
3604 self.load_commands_dirty = true;
3590 }3605 }
3591 if (build_options.have_llvm) {3606
3592 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(module, func, air, liveness);3607 if (self.la_symbol_ptr_section_index == null) {
3608 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
3609 const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
3610 self.la_symbol_ptr_section_index = try self.allocateSection(
3611 self.data_segment_cmd_index.?,
3612 "__la_symbol_ptr",
3613 needed_size,
3614 alignment,
3615 .{
3616 .flags = macho.S_LAZY_SYMBOL_POINTERS,
3617 },
3618 );
3593 }3619 }
3594 const tracy = trace(@src());
3595 defer tracy.end();
35963620
3597 const decl = func.owner_decl;3621 if (self.data_section_index == null) {
3622 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
3623 const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
3624 self.data_section_index = try self.allocateSection(
3625 self.data_segment_cmd_index.?,
3626 "__data",
3627 needed_size,
3628 alignment,
3629 .{},
3630 );
3631 }
35983632
3599 var code_buffer = std.ArrayList(u8).init(self.base.allocator);3633 if (self.tlv_section_index == null) {
3600 defer code_buffer.deinit();3634 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
3635 const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
3636 self.tlv_section_index = try self.allocateSection(
3637 self.data_segment_cmd_index.?,
3638 "__thread_vars",
3639 needed_size,
3640 alignment,
3641 .{
3642 .flags = macho.S_THREAD_LOCAL_VARIABLES,
3643 },
3644 );
3645 }
36013646
3602 var debug_buffers_buf: DebugSymbols.DeclDebugBuffers = undefined;3647 if (self.tlv_data_section_index == null) {
3603 const debug_buffers = if (self.d_sym) |*ds| blk: {3648 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
3604 debug_buffers_buf = try ds.initDeclDebugBuffers(self.base.allocator, module, decl);3649 const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
3605 break :blk &debug_buffers_buf;3650 self.tlv_data_section_index = try self.allocateSection(
3606 } else null;3651 self.data_segment_cmd_index.?,
3607 defer {3652 "__thread_data",
3608 if (debug_buffers) |dbg| {3653 needed_size,
3609 dbg.dbg_line_buffer.deinit();3654 alignment,
3610 dbg.dbg_info_buffer.deinit();3655 .{
3611 var it = dbg.dbg_info_type_relocs.valueIterator();3656 .flags = macho.S_THREAD_LOCAL_REGULAR,
3612 while (it.next()) |value| {3657 },
3613 value.relocs.deinit(self.base.allocator);3658 );
3614 }
3615 dbg.dbg_info_type_relocs.deinit(self.base.allocator);
3616 }
3617 }3659 }
36183660
3619 self.active_decl = decl;3661 if (self.tlv_bss_section_index == null) {
3662 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
3663 const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
3664 self.tlv_bss_section_index = try self.allocateSection(
3665 self.data_segment_cmd_index.?,
3666 "__thread_bss",
3667 needed_size,
3668 alignment,
3669 .{
3670 .flags = macho.S_THREAD_LOCAL_ZEROFILL,
3671 },
3672 );
3673 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
3674 const sect = seg.sections.items[self.tlv_bss_section_index.?];
3675 self.tlv_bss_file_offset = sect.offset;
3676 }
36203677
3621 const res = if (debug_buffers) |dbg|3678 if (self.bss_section_index == null) {
3622 try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{3679 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
3623 .dwarf = .{3680 const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
3624 .dbg_line = &dbg.dbg_line_buffer,3681 self.bss_section_index = try self.allocateSection(
3625 .dbg_info = &dbg.dbg_info_buffer,3682 self.data_segment_cmd_index.?,
3626 .dbg_info_type_relocs = &dbg.dbg_info_type_relocs,3683 "__bss",
3684 needed_size,
3685 alignment,
3686 .{
3687 .flags = macho.S_ZEROFILL,
3627 },3688 },
3628 })3689 );
3629 else3690 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
3630 try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none);3691 const sect = seg.sections.items[self.bss_section_index.?];
3631 switch (res) {3692 self.bss_file_offset = sect.offset;
3632 .appended => {
3633 // TODO clearing the code and relocs buffer should probably be orchestrated
3634 // in a different, smarter, more automatic way somewhere else, in a more centralised
3635 // way than this.
3636 // If we don't clear the buffers here, we are up for some nasty surprises when
3637 // this TextBlock is reused later on and was not freed by freeTextBlock().
3638 decl.link.macho.code.clearAndFree(self.base.allocator);
3639 try decl.link.macho.code.appendSlice(self.base.allocator, code_buffer.items);
3640 },
3641 .fail => |em| {
3642 decl.analysis = .codegen_failure;
3643 try module.failed_decls.put(module.gpa, decl, em);
3644 return;
3645 },
3646 }3693 }
36473694
3648 const symbol = try self.placeDecl(decl, decl.link.macho.code.items.len);3695 if (self.linkedit_segment_cmd_index == null) {
3696 self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
3697 const address_and_offset = self.nextSegmentAddressAndOffset();
36493698
3650 try self.writeCode(symbol, decl.link.macho.code.items);3699 log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset});
3651
3652 if (debug_buffers) |db| {
3653 try self.d_sym.?.commitDeclDebugInfo(
3654 self.base.allocator,
3655 module,
3656 decl,
3657 db,
3658 self.base.options.target,
3659 );
3660 }
3661
3662 // Since we updated the vaddr and the size, each corresponding export symbol also
3663 // needs to be updated.
3664 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};
3665 try self.updateDeclExports(module, decl, decl_exports);
3666}
3667
3668pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
3669 if (build_options.skip_non_native and builtin.object_format != .macho) {
3670 @panic("Attempted to compile for object format that was disabled by build configuration");
3671 }
3672 if (build_options.have_llvm) {
3673 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl);
3674 }
3675 const tracy = trace(@src());
3676 defer tracy.end();
3677
3678 if (decl.val.tag() == .extern_fn) {
3679 return; // TODO Should we do more when front-end analyzed extern decl?
3680 }
3681
3682 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
3683 defer code_buffer.deinit();
3684
3685 var debug_buffers_buf: DebugSymbols.DeclDebugBuffers = undefined;
3686 const debug_buffers = if (self.d_sym) |*ds| blk: {
3687 debug_buffers_buf = try ds.initDeclDebugBuffers(self.base.allocator, module, decl);
3688 break :blk &debug_buffers_buf;
3689 } else null;
3690 defer {
3691 if (debug_buffers) |dbg| {
3692 dbg.dbg_line_buffer.deinit();
3693 dbg.dbg_info_buffer.deinit();
3694 var it = dbg.dbg_info_type_relocs.valueIterator();
3695 while (it.next()) |value| {
3696 value.relocs.deinit(self.base.allocator);
3697 }
3698 dbg.dbg_info_type_relocs.deinit(self.base.allocator);
3699 }
3700 }
3701
3702 self.active_decl = decl;
3703
3704 const res = if (debug_buffers) |dbg|
3705 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
3706 .ty = decl.ty,
3707 .val = decl.val,
3708 }, &code_buffer, .{
3709 .dwarf = .{
3710 .dbg_line = &dbg.dbg_line_buffer,
3711 .dbg_info = &dbg.dbg_info_buffer,
3712 .dbg_info_type_relocs = &dbg.dbg_info_type_relocs,
3713 },
3714 })
3715 else
3716 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
3717 .ty = decl.ty,
3718 .val = decl.val,
3719 }, &code_buffer, .none);
3720
3721 const code = blk: {
3722 switch (res) {
3723 .externally_managed => |x| break :blk x,
3724 .appended => {
3725 // TODO clearing the code and relocs buffer should probably be orchestrated
3726 // in a different, smarter, more automatic way somewhere else, in a more centralised
3727 // way than this.
3728 // If we don't clear the buffers here, we are up for some nasty surprises when
3729 // this TextBlock is reused later on and was not freed by freeTextBlock().
3730 decl.link.macho.code.clearAndFree(self.base.allocator);
3731 try decl.link.macho.code.appendSlice(self.base.allocator, code_buffer.items);
3732 break :blk decl.link.macho.code.items;
3733 },
3734 .fail => |em| {
3735 decl.analysis = .codegen_failure;
3736 try module.failed_decls.put(module.gpa, decl, em);
3737 return;
3738 },
3739 }
3740 };
3741 const symbol = try self.placeDecl(decl, code.len);
3742
3743 try self.writeCode(symbol, code);
3744
3745 // Since we updated the vaddr and the size, each corresponding export symbol also
3746 // needs to be updated.
3747 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};
3748 try self.updateDeclExports(module, decl, decl_exports);
3749}
3750
3751fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 {
3752 const required_alignment = decl.ty.abiAlignment(self.base.options.target);
3753 assert(decl.link.macho.local_sym_index != 0); // Caller forgot to call allocateDeclIndexes()
3754 const symbol = &self.locals.items[decl.link.macho.local_sym_index];
3755
3756 if (decl.link.macho.size != 0) {
3757 const capacity = decl.link.macho.capacity(self.*);
3758 const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);
3759 if (need_realloc) {
3760 const vaddr = try self.growTextBlock(&decl.link.macho, code_len, required_alignment);
3761
3762 log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr });
3763
3764 if (vaddr != symbol.n_value) {
3765 log.debug(" (writing new GOT entry)", .{});
3766 const got_index = self.got_entries_map.get(.{
3767 .where = .local,
3768 .where_index = decl.link.macho.local_sym_index,
3769 }) orelse unreachable;
3770 try self.writeGotEntry(got_index);
3771 }
3772
3773 symbol.n_value = vaddr;
3774 } else if (code_len < decl.link.macho.size) {
3775 self.shrinkTextBlock(&decl.link.macho, code_len);
3776 }
3777 decl.link.macho.size = code_len;
3778
3779 const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)});
3780 defer self.base.allocator.free(new_name);
3781
3782 symbol.n_strx = try self.makeString(new_name);
3783 symbol.n_type = macho.N_SECT;
3784 symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;
3785 symbol.n_desc = 0;
3786
3787 try self.writeLocalSymbol(decl.link.macho.local_sym_index);
3788 if (self.d_sym) |*ds|
3789 try ds.writeLocalSymbol(decl.link.macho.local_sym_index);
3790 } else {
3791 const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)});
3792 defer self.base.allocator.free(decl_name);
3793
3794 const name_str_index = try self.makeString(decl_name);
3795 const addr = try self.allocateTextBlock(&decl.link.macho, code_len, required_alignment);
3796
3797 log.debug("allocated text block for {s} at 0x{x}", .{ decl_name, addr });
3798
3799 errdefer self.freeTextBlock(&decl.link.macho);
3800
3801 symbol.* = .{
3802 .n_strx = name_str_index,
3803 .n_type = macho.N_SECT,
3804 .n_sect = @intCast(u8, self.text_section_index.?) + 1,
3805 .n_desc = 0,
3806 .n_value = addr,
3807 };
3808 const got_index = self.got_entries_map.get(.{
3809 .where = .local,
3810 .where_index = decl.link.macho.local_sym_index,
3811 }) orelse unreachable;
3812 try self.writeGotEntry(got_index);
3813
3814 try self.writeLocalSymbol(decl.link.macho.local_sym_index);
3815 if (self.d_sym) |*ds|
3816 try ds.writeLocalSymbol(decl.link.macho.local_sym_index);
3817 }
3818
3819 // Resolve relocations
3820 try decl.link.macho.resolveRelocs(self);
3821 // TODO this requires further investigation: should we dispose of resolved relocs, or keep them
3822 // so that we can reapply them when moving/growing sections?
3823 decl.link.macho.relocs.clearAndFree(self.base.allocator);
3824
3825 // Apply pending updates
3826 while (self.pending_updates.popOrNull()) |update| {
3827 switch (update.kind) {
3828 .got => unreachable,
3829 .stub => {
3830 try self.writeStub(update.index);
3831 try self.writeStubInStubHelper(update.index);
3832 try self.writeLazySymbolPointer(update.index);
3833 self.rebase_info_dirty = true;
3834 self.lazy_binding_info_dirty = true;
3835 },
3836 }
3837 }
3838
3839 return symbol;
3840}
3841
3842fn writeCode(self: *MachO, symbol: *macho.nlist_64, code: []const u8) !void {
3843 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
3844 const text_section = text_segment.sections.items[self.text_section_index.?];
3845 const section_offset = symbol.n_value - text_section.addr;
3846 const file_offset = text_section.offset + section_offset;
3847 log.debug("writing code for symbol {s} at file offset 0x{x}", .{ self.getString(symbol.n_strx), file_offset });
3848 try self.base.file.?.pwriteAll(code, file_offset);
3849}
3850
3851pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void {
3852 if (self.d_sym) |*ds| {
3853 try ds.updateDeclLineNumber(module, decl);
3854 }
3855}
3856
3857pub fn updateDeclExports(
3858 self: *MachO,
3859 module: *Module,
3860 decl: *Module.Decl,
3861 exports: []const *Module.Export,
3862) !void {
3863 if (build_options.skip_non_native and builtin.object_format != .macho) {
3864 @panic("Attempted to compile for object format that was disabled by build configuration");
3865 }
3866 if (build_options.have_llvm) {
3867 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl, exports);
3868 }
3869 const tracy = trace(@src());
3870 defer tracy.end();
3871
3872 try self.globals.ensureCapacity(self.base.allocator, self.globals.items.len + exports.len);
3873 if (decl.link.macho.local_sym_index == 0) return;
3874 const decl_sym = &self.locals.items[decl.link.macho.local_sym_index];
3875
3876 for (exports) |exp| {
3877 const exp_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{exp.options.name});
3878 defer self.base.allocator.free(exp_name);
3879
3880 if (exp.options.section) |section_name| {
3881 if (!mem.eql(u8, section_name, "__text")) {
3882 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.count() + 1);
3883 module.failed_exports.putAssumeCapacityNoClobber(
3884 exp,
3885 try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "Unimplemented: ExportOptions.section", .{}),
3886 );
3887 continue;
3888 }
3889 }
3890
3891 var n_type: u8 = macho.N_SECT | macho.N_EXT;
3892 var n_desc: u16 = 0;
3893
3894 switch (exp.options.linkage) {
3895 .Internal => {
3896 // Symbol should be hidden, or in MachO lingo, private extern.
3897 // We should also mark the symbol as Weak: n_desc == N_WEAK_DEF.
3898 // TODO work out when to add N_WEAK_REF.
3899 n_type |= macho.N_PEXT;
3900 n_desc |= macho.N_WEAK_DEF;
3901 },
3902 .Strong => {
3903 // Check if the export is _main, and note if os.
3904 // Otherwise, don't do anything since we already have all the flags
3905 // set that we need for global (strong) linkage.
3906 // n_type == N_SECT | N_EXT
3907 if (mem.eql(u8, exp_name, "_main")) {
3908 self.entry_addr = decl_sym.n_value;
3909 }
3910 },
3911 .Weak => {
3912 // Weak linkage is specified as part of n_desc field.
3913 // Symbol's n_type is like for a symbol with strong linkage.
3914 n_desc |= macho.N_WEAK_DEF;
3915 },
3916 .LinkOnce => {
3917 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.count() + 1);
3918 module.failed_exports.putAssumeCapacityNoClobber(
3919 exp,
3920 try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "Unimplemented: GlobalLinkage.LinkOnce", .{}),
3921 );
3922 continue;
3923 },
3924 }
3925
3926 if (exp.link.macho.sym_index) |i| {
3927 const sym = &self.globals.items[i];
3928 sym.* = .{
3929 .n_strx = sym.n_strx,
3930 .n_type = n_type,
3931 .n_sect = @intCast(u8, self.text_section_index.?) + 1,
3932 .n_desc = n_desc,
3933 .n_value = decl_sym.n_value,
3934 };
3935 } else {
3936 const name_str_index = try self.makeString(exp_name);
3937 const i = if (self.globals_free_list.popOrNull()) |i| i else blk: {
3938 _ = self.globals.addOneAssumeCapacity();
3939 self.export_info_dirty = true;
3940 break :blk @intCast(u32, self.globals.items.len - 1);
3941 };
3942 self.globals.items[i] = .{
3943 .n_strx = name_str_index,
3944 .n_type = n_type,
3945 .n_sect = @intCast(u8, self.text_section_index.?) + 1,
3946 .n_desc = n_desc,
3947 .n_value = decl_sym.n_value,
3948 };
3949 const resolv = try self.symbol_resolver.getOrPut(self.base.allocator, name_str_index);
3950 resolv.value_ptr.* = .{
3951 .where = .global,
3952 .where_index = i,
3953 .local_sym_index = decl.link.macho.local_sym_index,
3954 };
3955
3956 exp.link.macho.sym_index = @intCast(u32, i);
3957 }
3958 }
3959}
3960
3961pub fn deleteExport(self: *MachO, exp: Export) void {
3962 const sym_index = exp.sym_index orelse return;
3963 self.globals_free_list.append(self.base.allocator, sym_index) catch {};
3964 self.globals.items[sym_index].n_type = 0;
3965}
3966
3967pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {
3968 log.debug("freeDecl {*}", .{decl});
3969 _ = self.decls.swapRemove(decl);
3970 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
3971 self.freeTextBlock(&decl.link.macho);
3972 if (decl.link.macho.local_sym_index != 0) {
3973 self.locals_free_list.append(self.base.allocator, decl.link.macho.local_sym_index) catch {};
3974
3975 const got_key = GotIndirectionKey{
3976 .where = .local,
3977 .where_index = decl.link.macho.local_sym_index,
3978 };
3979 const got_index = self.got_entries_map.get(got_key) orelse unreachable;
3980 _ = self.got_entries_map.remove(got_key);
3981 self.got_entries_free_list.append(self.base.allocator, got_index) catch {};
3982
3983 self.locals.items[decl.link.macho.local_sym_index].n_type = 0;
3984 decl.link.macho.local_sym_index = 0;
3985 }
3986 if (self.d_sym) |*ds| {
3987 // TODO make this logic match freeTextBlock. Maybe abstract the logic
3988 // out since the same thing is desired for both.
3989 _ = ds.dbg_line_fn_free_list.remove(&decl.fn_link.macho);
3990 if (decl.fn_link.macho.prev) |prev| {
3991 ds.dbg_line_fn_free_list.put(self.base.allocator, prev, {}) catch {};
3992 prev.next = decl.fn_link.macho.next;
3993 if (decl.fn_link.macho.next) |next| {
3994 next.prev = prev;
3995 } else {
3996 ds.dbg_line_fn_last = prev;
3997 }
3998 } else if (decl.fn_link.macho.next) |next| {
3999 ds.dbg_line_fn_first = next;
4000 next.prev = null;
4001 }
4002 if (ds.dbg_line_fn_first == &decl.fn_link.macho) {
4003 ds.dbg_line_fn_first = decl.fn_link.macho.next;
4004 }
4005 if (ds.dbg_line_fn_last == &decl.fn_link.macho) {
4006 ds.dbg_line_fn_last = decl.fn_link.macho.prev;
4007 }
4008 }
4009}
4010
4011pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl) u64 {
4012 assert(decl.link.macho.local_sym_index != 0);
4013 return self.locals.items[decl.link.macho.local_sym_index].n_value;
4014}
4015
4016pub fn populateMissingMetadata(self: *MachO) !void {
4017 switch (self.base.options.output_mode) {
4018 .Exe => {},
4019 .Obj => return error.TODOImplementWritingObjFiles,
4020 .Lib => return error.TODOImplementWritingLibFiles,
4021 }
4022
4023 if (self.pagezero_segment_cmd_index == null) {
4024 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
4025 try self.load_commands.append(self.base.allocator, .{
4026 .Segment = SegmentCommand.empty("__PAGEZERO", .{
4027 .vmsize = 0x100000000, // size always set to 4GB
4028 }),
4029 });
4030 self.load_commands_dirty = true;
4031 }
4032 if (self.text_segment_cmd_index == null) {
4033 self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
4034 const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE;
4035 const initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE;
4036
4037 const program_code_size_hint = self.base.options.program_code_size_hint;
4038 const got_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint;
4039 const ideal_size = self.header_pad + program_code_size_hint + 3 * got_size_hint;
4040 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
4041
4042 log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });
4043
4044 try self.load_commands.append(self.base.allocator, .{
4045 .Segment = SegmentCommand.empty("__TEXT", .{
4046 .vmaddr = 0x100000000, // always starts at 4GB
4047 .vmsize = needed_size,
4048 .filesize = needed_size,
4049 .maxprot = maxprot,
4050 .initprot = initprot,
4051 }),
4052 });
4053 self.load_commands_dirty = true;
4054 }
4055 if (self.text_section_index == null) {
4056 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4057 self.text_section_index = @intCast(u16, text_segment.sections.items.len);
4058
4059 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
4060 .x86_64 => 0,
4061 .aarch64 => 2,
4062 else => unreachable, // unhandled architecture type
4063 };
4064 const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS;
4065 const needed_size = self.base.options.program_code_size_hint;
4066 const off = text_segment.findFreeSpace(needed_size, @as(u16, 1) << alignment, self.header_pad);
4067
4068 log.debug("found __text section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4069
4070 try text_segment.addSection(self.base.allocator, "__text", .{
4071 .addr = text_segment.inner.vmaddr + off,
4072 .size = @intCast(u32, needed_size),
4073 .offset = @intCast(u32, off),
4074 .@"align" = alignment,
4075 .flags = flags,
4076 });
4077 self.load_commands_dirty = true;
4078 }
4079 if (self.stubs_section_index == null) {
4080 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4081 self.stubs_section_index = @intCast(u16, text_segment.sections.items.len);
4082
4083 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
4084 .x86_64 => 0,
4085 .aarch64 => 2,
4086 else => unreachable, // unhandled architecture type
4087 };
4088 const stub_size: u4 = switch (self.base.options.target.cpu.arch) {
4089 .x86_64 => 6,
4090 .aarch64 => 3 * @sizeOf(u32),
4091 else => unreachable, // unhandled architecture type
4092 };
4093 const flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS;
4094 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4095 const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad);
4096 assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment.
4097
4098 log.debug("found __stubs section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4099
4100 try text_segment.addSection(self.base.allocator, "__stubs", .{
4101 .addr = text_segment.inner.vmaddr + off,
4102 .size = needed_size,
4103 .offset = @intCast(u32, off),
4104 .@"align" = alignment,
4105 .flags = flags,
4106 .reserved2 = stub_size,
4107 });
4108 self.load_commands_dirty = true;
4109 }
4110 if (self.stub_helper_section_index == null) {
4111 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4112 self.stub_helper_section_index = @intCast(u16, text_segment.sections.items.len);
4113
4114 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
4115 .x86_64 => 0,
4116 .aarch64 => 2,
4117 else => unreachable, // unhandled architecture type
4118 };
4119 const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS;
4120 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4121 const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad);
4122 assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment.
4123
4124 log.debug("found __stub_helper section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4125
4126 try text_segment.addSection(self.base.allocator, "__stub_helper", .{
4127 .addr = text_segment.inner.vmaddr + off,
4128 .size = needed_size,
4129 .offset = @intCast(u32, off),
4130 .@"align" = alignment,
4131 .flags = flags,
4132 });
4133 self.load_commands_dirty = true;
4134 }
4135 if (self.data_const_segment_cmd_index == null) {
4136 self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
4137 const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE;
4138 const initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE;
4139 const address_and_offset = self.nextSegmentAddressAndOffset();
4140
4141 const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4142 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
4143
4144 log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
4145
4146 try self.load_commands.append(self.base.allocator, .{
4147 .Segment = SegmentCommand.empty("__DATA_CONST", .{
4148 .vmaddr = address_and_offset.address,
4149 .vmsize = needed_size,
4150 .fileoff = address_and_offset.offset,
4151 .filesize = needed_size,
4152 .maxprot = maxprot,
4153 .initprot = initprot,
4154 }),
4155 });
4156 self.load_commands_dirty = true;
4157 }
4158 if (self.got_section_index == null) {
4159 const dc_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
4160 self.got_section_index = @intCast(u16, dc_segment.sections.items.len);
4161
4162 const flags = macho.S_NON_LAZY_SYMBOL_POINTERS;
4163 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4164 const off = dc_segment.findFreeSpace(needed_size, @alignOf(u64), null);
4165 assert(off + needed_size <= dc_segment.inner.fileoff + dc_segment.inner.filesize); // TODO Must expand __DATA_CONST segment.
4166
4167 log.debug("found __got section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4168
4169 try dc_segment.addSection(self.base.allocator, "__got", .{
4170 .addr = dc_segment.inner.vmaddr + off - dc_segment.inner.fileoff,
4171 .size = needed_size,
4172 .offset = @intCast(u32, off),
4173 .@"align" = 3, // 2^3 = @sizeOf(u64)
4174 .flags = flags,
4175 });
4176 self.load_commands_dirty = true;
4177 }
4178 if (self.data_segment_cmd_index == null) {
4179 self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
4180 const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE;
4181 const initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE;
4182 const address_and_offset = self.nextSegmentAddressAndOffset();
4183
4184 const ideal_size = 2 * @sizeOf(u64) * self.base.options.symbol_count_hint;
4185 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
4186
4187 log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
4188
4189 try self.load_commands.append(self.base.allocator, .{
4190 .Segment = SegmentCommand.empty("__DATA", .{
4191 .vmaddr = address_and_offset.address,
4192 .vmsize = needed_size,
4193 .fileoff = address_and_offset.offset,
4194 .filesize = needed_size,
4195 .maxprot = maxprot,
4196 .initprot = initprot,
4197 }),
4198 });
4199 self.load_commands_dirty = true;
4200 }
4201 if (self.la_symbol_ptr_section_index == null) {
4202 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4203 self.la_symbol_ptr_section_index = @intCast(u16, data_segment.sections.items.len);
4204
4205 const flags = macho.S_LAZY_SYMBOL_POINTERS;
4206 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4207 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
4208 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
4209
4210 log.debug("found __la_symbol_ptr section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4211
4212 try data_segment.addSection(self.base.allocator, "__la_symbol_ptr", .{
4213 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
4214 .size = needed_size,
4215 .offset = @intCast(u32, off),
4216 .@"align" = 3, // 2^3 = @sizeOf(u64)
4217 .flags = flags,
4218 });
4219 self.load_commands_dirty = true;
4220 }
4221 if (self.data_section_index == null) {
4222 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4223 self.data_section_index = @intCast(u16, data_segment.sections.items.len);
4224
4225 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4226 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
4227 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
4228
4229 log.debug("found __data section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4230
4231 try data_segment.addSection(self.base.allocator, "__data", .{
4232 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
4233 .size = needed_size,
4234 .offset = @intCast(u32, off),
4235 .@"align" = 3, // 2^3 = @sizeOf(u64)
4236 });
4237 self.load_commands_dirty = true;
4238 }
4239 if (self.linkedit_segment_cmd_index == null) {
4240 self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
4241
4242 const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE;
4243 const initprot = macho.VM_PROT_READ;
4244 const address_and_offset = self.nextSegmentAddressAndOffset();
4245
4246 log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset});
4247
4248 try self.load_commands.append(self.base.allocator, .{
4249 .Segment = SegmentCommand.empty("__LINKEDIT", .{
4250 .vmaddr = address_and_offset.address,
4251 .fileoff = address_and_offset.offset,
4252 .maxprot = maxprot,
4253 .initprot = initprot,
4254 }),
4255 });
4256 self.load_commands_dirty = true;
4257 }
4258 if (self.dyld_info_cmd_index == null) {
4259 self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len);
4260
4261 try self.load_commands.append(self.base.allocator, .{
4262 .DyldInfoOnly = .{
4263 .cmd = macho.LC_DYLD_INFO_ONLY,
4264 .cmdsize = @sizeOf(macho.dyld_info_command),
4265 .rebase_off = 0,
4266 .rebase_size = 0,
4267 .bind_off = 0,
4268 .bind_size = 0,
4269 .weak_bind_off = 0,
4270 .weak_bind_size = 0,
4271 .lazy_bind_off = 0,
4272 .lazy_bind_size = 0,
4273 .export_off = 0,
4274 .export_size = 0,
4275 },
4276 });
4277
4278 const dyld = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;
4279
4280 // Preallocate rebase, binding, lazy binding info, and export info.
4281 const expected_size = 48; // TODO This is totally random.
4282 const rebase_off = self.findFreeSpaceLinkedit(expected_size, 1, null);
4283 log.debug("found rebase info free space 0x{x} to 0x{x}", .{ rebase_off, rebase_off + expected_size });
4284 dyld.rebase_off = @intCast(u32, rebase_off);
4285 dyld.rebase_size = expected_size;
4286
4287 const bind_off = self.findFreeSpaceLinkedit(expected_size, 1, null);
4288 log.debug("found binding info free space 0x{x} to 0x{x}", .{ bind_off, bind_off + expected_size });
4289 dyld.bind_off = @intCast(u32, bind_off);
4290 dyld.bind_size = expected_size;
4291
4292 const lazy_bind_off = self.findFreeSpaceLinkedit(expected_size, 1, null);
4293 log.debug("found lazy binding info free space 0x{x} to 0x{x}", .{ lazy_bind_off, lazy_bind_off + expected_size });
4294 dyld.lazy_bind_off = @intCast(u32, lazy_bind_off);
4295 dyld.lazy_bind_size = expected_size;
4296
4297 const export_off = self.findFreeSpaceLinkedit(expected_size, 1, null);
4298 log.debug("found export info free space 0x{x} to 0x{x}", .{ export_off, export_off + expected_size });
4299 dyld.export_off = @intCast(u32, export_off);
4300 dyld.export_size = expected_size;
4301
4302 self.load_commands_dirty = true;
4303 }
4304 if (self.symtab_cmd_index == null) {
4305 self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len);
4306
4307 try self.load_commands.append(self.base.allocator, .{
4308 .Symtab = .{
4309 .cmd = macho.LC_SYMTAB,
4310 .cmdsize = @sizeOf(macho.symtab_command),
4311 .symoff = 0,
4312 .nsyms = 0,
4313 .stroff = 0,
4314 .strsize = 0,
4315 },
4316 });
4317
4318 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
4319
4320 const symtab_size = self.base.options.symbol_count_hint * @sizeOf(macho.nlist_64);
4321 const symtab_off = self.findFreeSpaceLinkedit(symtab_size, @sizeOf(macho.nlist_64), null);
4322 log.debug("found symbol table free space 0x{x} to 0x{x}", .{ symtab_off, symtab_off + symtab_size });
4323 symtab.symoff = @intCast(u32, symtab_off);
4324 symtab.nsyms = @intCast(u32, self.base.options.symbol_count_hint);
4325
4326 try self.strtab.append(self.base.allocator, 0);
4327 const strtab_size = self.strtab.items.len;
4328 const strtab_off = self.findFreeSpaceLinkedit(strtab_size, 1, symtab_off);
4329 log.debug("found string table free space 0x{x} to 0x{x}", .{ strtab_off, strtab_off + strtab_size });
4330 symtab.stroff = @intCast(u32, strtab_off);
4331 symtab.strsize = @intCast(u32, strtab_size);
4332
4333 self.load_commands_dirty = true;
4334 self.strtab_dirty = true;
4335 }
4336 if (self.dysymtab_cmd_index == null) {
4337 self.dysymtab_cmd_index = @intCast(u16, self.load_commands.items.len);
4338
4339 // Preallocate space for indirect symbol table.
4340 const indsymtab_size = self.base.options.symbol_count_hint * @sizeOf(u64); // Each entry is just a u64.
4341 const indsymtab_off = self.findFreeSpaceLinkedit(indsymtab_size, @sizeOf(u64), null);
4342
4343 log.debug("found indirect symbol table free space 0x{x} to 0x{x}", .{ indsymtab_off, indsymtab_off + indsymtab_size });
4344
4345 try self.load_commands.append(self.base.allocator, .{
4346 .Dysymtab = .{
4347 .cmd = macho.LC_DYSYMTAB,
4348 .cmdsize = @sizeOf(macho.dysymtab_command),
4349 .ilocalsym = 0,
4350 .nlocalsym = 0,
4351 .iextdefsym = 0,
4352 .nextdefsym = 0,
4353 .iundefsym = 0,
4354 .nundefsym = 0,
4355 .tocoff = 0,
4356 .ntoc = 0,
4357 .modtaboff = 0,
4358 .nmodtab = 0,
4359 .extrefsymoff = 0,
4360 .nextrefsyms = 0,
4361 .indirectsymoff = @intCast(u32, indsymtab_off),
4362 .nindirectsyms = @intCast(u32, self.base.options.symbol_count_hint),
4363 .extreloff = 0,
4364 .nextrel = 0,
4365 .locreloff = 0,
4366 .nlocrel = 0,
4367 },
4368 });
4369 self.load_commands_dirty = true;
4370 }
4371 if (self.dylinker_cmd_index == null) {
4372 self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len);
4373 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
4374 u64,
4375 @sizeOf(macho.dylinker_command) + mem.lenZ(DEFAULT_DYLD_PATH),
4376 @sizeOf(u64),
4377 ));
4378 var dylinker_cmd = commands.emptyGenericCommandWithData(macho.dylinker_command{
4379 .cmd = macho.LC_LOAD_DYLINKER,
4380 .cmdsize = cmdsize,
4381 .name = @sizeOf(macho.dylinker_command),
4382 });
4383 dylinker_cmd.data = try self.base.allocator.alloc(u8, cmdsize - dylinker_cmd.inner.name);
4384 mem.set(u8, dylinker_cmd.data, 0);
4385 mem.copy(u8, dylinker_cmd.data, mem.spanZ(DEFAULT_DYLD_PATH));
4386 try self.load_commands.append(self.base.allocator, .{ .Dylinker = dylinker_cmd });
4387 self.load_commands_dirty = true;
4388 }
4389 if (self.libsystem_cmd_index == null) {
4390 self.libsystem_cmd_index = @intCast(u16, self.load_commands.items.len);
4391
4392 var dylib_cmd = try commands.createLoadDylibCommand(self.base.allocator, mem.spanZ(LIB_SYSTEM_PATH), 2, 0, 0);
4393 errdefer dylib_cmd.deinit(self.base.allocator);
4394
4395 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
4396
4397 self.load_commands_dirty = true;
4398 }
4399 if (self.main_cmd_index == null) {
4400 self.main_cmd_index = @intCast(u16, self.load_commands.items.len);
4401 try self.load_commands.append(self.base.allocator, .{
4402 .Main = .{
4403 .cmd = macho.LC_MAIN,
4404 .cmdsize = @sizeOf(macho.entry_point_command),
4405 .entryoff = 0x0,
4406 .stacksize = 0,
4407 },
4408 });
4409 self.load_commands_dirty = true;
4410 }
4411 if (self.build_version_cmd_index == null) {
4412 self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len);
4413 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
4414 u64,
4415 @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version),
4416 @sizeOf(u64),
4417 ));
4418 const ver = self.base.options.target.os.version_range.semver.min;
4419 const version = ver.major << 16 | ver.minor << 8 | ver.patch;
4420 const is_simulator_abi = self.base.options.target.abi == .simulator;
4421 var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{
4422 .cmd = macho.LC_BUILD_VERSION,
4423 .cmdsize = cmdsize,
4424 .platform = switch (self.base.options.target.os.tag) {
4425 .macos => macho.PLATFORM_MACOS,
4426 .ios => if (is_simulator_abi) macho.PLATFORM_IOSSIMULATOR else macho.PLATFORM_IOS,
4427 .watchos => if (is_simulator_abi) macho.PLATFORM_WATCHOSSIMULATOR else macho.PLATFORM_WATCHOS,
4428 .tvos => if (is_simulator_abi) macho.PLATFORM_TVOSSIMULATOR else macho.PLATFORM_TVOS,
4429 else => unreachable,
4430 },
4431 .minos = version,
4432 .sdk = version,
4433 .ntools = 1,
4434 });
4435 const ld_ver = macho.build_tool_version{
4436 .tool = macho.TOOL_LD,
4437 .version = 0x0,
4438 };
4439 cmd.data = try self.base.allocator.alloc(u8, cmdsize - @sizeOf(macho.build_version_command));
4440 mem.set(u8, cmd.data, 0);
4441 mem.copy(u8, cmd.data, mem.asBytes(&ld_ver));
4442 try self.load_commands.append(self.base.allocator, .{ .BuildVersion = cmd });
4443 }
4444 if (self.source_version_cmd_index == null) {
4445 self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len);
4446 try self.load_commands.append(self.base.allocator, .{
4447 .SourceVersion = .{
4448 .cmd = macho.LC_SOURCE_VERSION,
4449 .cmdsize = @sizeOf(macho.source_version_command),
4450 .version = 0x0,
4451 },
4452 });
4453 self.load_commands_dirty = true;
4454 }
4455 if (self.uuid_cmd_index == null) {
4456 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
4457 var uuid_cmd: macho.uuid_command = .{
4458 .cmd = macho.LC_UUID,
4459 .cmdsize = @sizeOf(macho.uuid_command),
4460 .uuid = undefined,
4461 };
4462 std.crypto.random.bytes(&uuid_cmd.uuid);
4463 try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd });
4464 self.load_commands_dirty = true;
4465 }
4466 if (self.code_signature_cmd_index == null and self.requires_adhoc_codesig) {
4467 self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len);
4468 try self.load_commands.append(self.base.allocator, .{
4469 .LinkeditData = .{
4470 .cmd = macho.LC_CODE_SIGNATURE,
4471 .cmdsize = @sizeOf(macho.linkedit_data_command),
4472 .dataoff = 0,
4473 .datasize = 0,
4474 },
4475 });
4476 self.load_commands_dirty = true;
4477 }
4478 if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
4479 .strtab = &self.strtab,
4480 })) {
4481 const import_sym_index = @intCast(u32, self.undefs.items.len);
4482 const n_strx = try self.makeString("dyld_stub_binder");
4483 try self.undefs.append(self.base.allocator, .{
4484 .n_strx = n_strx,
4485 .n_type = macho.N_UNDF | macho.N_EXT,
4486 .n_sect = 0,
4487 .n_desc = @intCast(u8, 1) * macho.N_SYMBOL_RESOLVER,
4488 .n_value = 0,
4489 });
4490 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
4491 .where = .undef,
4492 .where_index = import_sym_index,
4493 });
4494 const got_key = GotIndirectionKey{
4495 .where = .undef,
4496 .where_index = import_sym_index,
4497 };
4498 const got_index = @intCast(u32, self.got_entries.items.len);
4499 try self.got_entries.append(self.base.allocator, got_key);
4500 try self.got_entries_map.putNoClobber(self.base.allocator, got_key, got_index);
4501 try self.writeGotEntry(got_index);
4502 self.binding_info_dirty = true;
4503 }
4504 if (self.stub_helper_stubs_start_off == null) {
4505 try self.writeStubHelperPreamble();
4506 }
4507}
4508
4509fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
4510 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4511 const text_section = &text_segment.sections.items[self.text_section_index.?];
4512 const new_block_ideal_capacity = padToIdeal(new_block_size);
4513
4514 // We use these to indicate our intention to update metadata, placing the new block,
4515 // and possibly removing a free list node.
4516 // It would be simpler to do it inside the for loop below, but that would cause a
4517 // problem if an error was returned later in the function. So this action
4518 // is actually carried out at the end of the function, when errors are no longer possible.
4519 var block_placement: ?*TextBlock = null;
4520 var free_list_removal: ?usize = null;
4521
4522 // First we look for an appropriately sized free list node.
4523 // The list is unordered. We'll just take the first thing that works.
4524 const vaddr = blk: {
4525 var i: usize = 0;
4526 while (i < self.text_block_free_list.items.len) {
4527 const big_block = self.text_block_free_list.items[i];
4528 // We now have a pointer to a live text block that has too much capacity.
4529 // Is it enough that we could fit this new text block?
4530 const sym = self.locals.items[big_block.local_sym_index];
4531 const capacity = big_block.capacity(self.*);
4532 const ideal_capacity = padToIdeal(capacity);
4533 const ideal_capacity_end_vaddr = sym.n_value + ideal_capacity;
4534 const capacity_end_vaddr = sym.n_value + capacity;
4535 const new_start_vaddr_unaligned = capacity_end_vaddr - new_block_ideal_capacity;
4536 const new_start_vaddr = mem.alignBackwardGeneric(u64, new_start_vaddr_unaligned, alignment);
4537 if (new_start_vaddr < ideal_capacity_end_vaddr) {
4538 // Additional bookkeeping here to notice if this free list node
4539 // should be deleted because the block that it points to has grown to take up
4540 // more of the extra capacity.
4541 if (!big_block.freeListEligible(self.*)) {
4542 const bl = self.text_block_free_list.swapRemove(i);
4543 bl.deinit(self.base.allocator);
4544 } else {
4545 i += 1;
4546 }
4547 continue;
4548 }
4549 // At this point we know that we will place the new block here. But the
4550 // remaining question is whether there is still yet enough capacity left
4551 // over for there to still be a free list node.
4552 const remaining_capacity = new_start_vaddr - ideal_capacity_end_vaddr;
4553 const keep_free_list_node = remaining_capacity >= min_text_capacity;
4554
4555 // Set up the metadata to be updated, after errors are no longer possible.
4556 block_placement = big_block;
4557 if (!keep_free_list_node) {
4558 free_list_removal = i;
4559 }
4560 break :blk new_start_vaddr;
4561 } else if (self.last_text_block) |last| {
4562 const last_symbol = self.locals.items[last.local_sym_index];
4563 // TODO We should pad out the excess capacity with NOPs. For executables,
4564 // no padding seems to be OK, but it will probably not be for objects.
4565 const ideal_capacity = padToIdeal(last.size);
4566 const ideal_capacity_end_vaddr = last_symbol.n_value + ideal_capacity;
4567 const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment);
4568 block_placement = last;
4569 break :blk new_start_vaddr;
4570 } else {
4571 break :blk text_section.addr;
4572 }
4573 };
4574
4575 const expand_text_section = block_placement == null or block_placement.?.next == null;
4576 if (expand_text_section) {
4577 const needed_size = (vaddr + new_block_size) - text_section.addr;
4578 assert(needed_size <= text_segment.inner.filesize); // TODO must move the entire text section.
4579
4580 self.last_text_block = text_block;
4581 text_section.size = needed_size;
4582 self.load_commands_dirty = true; // TODO Make more granular.
4583
4584 if (self.d_sym) |*ds| {
4585 const debug_text_seg = &ds.load_commands.items[ds.text_segment_cmd_index.?].Segment;
4586 const debug_text_sect = &debug_text_seg.sections.items[ds.text_section_index.?];
4587 debug_text_sect.size = needed_size;
4588 ds.load_commands_dirty = true;
4589 }
4590 }
4591 text_block.size = new_block_size;
4592
4593 if (text_block.prev) |prev| {
4594 prev.next = text_block.next;
4595 }
4596 if (text_block.next) |next| {
4597 next.prev = text_block.prev;
4598 }
4599
4600 if (block_placement) |big_block| {
4601 text_block.prev = big_block;
4602 text_block.next = big_block.next;
4603 big_block.next = text_block;
4604 } else {
4605 text_block.prev = null;
4606 text_block.next = null;
4607 }
4608 if (free_list_removal) |i| {
4609 _ = self.text_block_free_list.swapRemove(i);
4610 }
4611
4612 return vaddr;
4613}
4614
4615pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
4616 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
4617 defer self.base.allocator.free(sym_name);
4618
4619 if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringSliceAdapter{
4620 .strtab = &self.strtab,
4621 })) |n_strx| {
4622 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
4623 return resolv.where_index;
4624 }
4625
4626 log.debug("adding new extern function '{s}' with dylib ordinal 1", .{sym_name});
4627 const import_sym_index = @intCast(u32, self.undefs.items.len);
4628 const n_strx = try self.makeString(sym_name);
4629 try self.undefs.append(self.base.allocator, .{
4630 .n_strx = n_strx,
4631 .n_type = macho.N_UNDF | macho.N_EXT,
4632 .n_sect = 0,
4633 .n_desc = @intCast(u8, 1) * macho.N_SYMBOL_RESOLVER,
4634 .n_value = 0,
4635 });
4636 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
4637 .where = .undef,
4638 .where_index = import_sym_index,
4639 });
4640
4641 const stubs_index = @intCast(u32, self.stubs.items.len);
4642 try self.stubs.append(self.base.allocator, import_sym_index);
4643 try self.stubs_map.putNoClobber(self.base.allocator, import_sym_index, stubs_index);
4644
4645 // TODO discuss this. The caller context expects codegen.InnerError{ OutOfMemory, CodegenFail },
4646 // which obviously doesn't include file writing op errors. So instead of trying to write the stub
4647 // entry right here and now, queue it up and dispose of when updating decl.
4648 try self.pending_updates.append(self.base.allocator, .{
4649 .kind = .stub,
4650 .index = stubs_index,
4651 });
4652
4653 return import_sym_index;
4654}
4655
4656const NextSegmentAddressAndOffset = struct {
4657 address: u64,
4658 offset: u64,
4659};
4660
4661fn nextSegmentAddressAndOffset(self: *MachO) NextSegmentAddressAndOffset {
4662 var prev_segment_idx: ?usize = null; // We use optional here for safety.
4663 for (self.load_commands.items) |cmd, i| {
4664 if (cmd == .Segment) {
4665 prev_segment_idx = i;
4666 }
4667 }
4668 const prev_segment = self.load_commands.items[prev_segment_idx.?].Segment;
4669 const address = prev_segment.inner.vmaddr + prev_segment.inner.vmsize;
4670 const offset = prev_segment.inner.fileoff + prev_segment.inner.filesize;
4671 return .{
4672 .address = address,
4673 .offset = offset,
4674 };
4675}
4676
4677fn allocatedSizeLinkedit(self: *MachO, start: u64) u64 {
4678 assert(start > 0);
4679 var min_pos: u64 = std.math.maxInt(u64);
4680
4681 // __LINKEDIT is a weird segment where sections get their own load commands so we
4682 // special-case it.
4683 if (self.dyld_info_cmd_index) |idx| {
4684 const dyld_info = self.load_commands.items[idx].DyldInfoOnly;
4685 if (dyld_info.rebase_off > start and dyld_info.rebase_off < min_pos) min_pos = dyld_info.rebase_off;
4686 if (dyld_info.bind_off > start and dyld_info.bind_off < min_pos) min_pos = dyld_info.bind_off;
4687 if (dyld_info.weak_bind_off > start and dyld_info.weak_bind_off < min_pos) min_pos = dyld_info.weak_bind_off;
4688 if (dyld_info.lazy_bind_off > start and dyld_info.lazy_bind_off < min_pos) min_pos = dyld_info.lazy_bind_off;
4689 if (dyld_info.export_off > start and dyld_info.export_off < min_pos) min_pos = dyld_info.export_off;
4690 }
4691
4692 if (self.function_starts_cmd_index) |idx| {
4693 const fstart = self.load_commands.items[idx].LinkeditData;
4694 if (fstart.dataoff > start and fstart.dataoff < min_pos) min_pos = fstart.dataoff;
4695 }
4696
4697 if (self.data_in_code_cmd_index) |idx| {
4698 const dic = self.load_commands.items[idx].LinkeditData;
4699 if (dic.dataoff > start and dic.dataoff < min_pos) min_pos = dic.dataoff;
4700 }
4701
4702 if (self.dysymtab_cmd_index) |idx| {
4703 const dysymtab = self.load_commands.items[idx].Dysymtab;
4704 if (dysymtab.indirectsymoff > start and dysymtab.indirectsymoff < min_pos) min_pos = dysymtab.indirectsymoff;
4705 // TODO Handle more dynamic symbol table sections.
4706 }
4707
4708 if (self.symtab_cmd_index) |idx| {
4709 const symtab = self.load_commands.items[idx].Symtab;
4710 if (symtab.symoff > start and symtab.symoff < min_pos) min_pos = symtab.symoff;
4711 if (symtab.stroff > start and symtab.stroff < min_pos) min_pos = symtab.stroff;
4712 }
4713
4714 return min_pos - start;
4715}
4716inline fn checkForCollision(start: u64, end: u64, off: u64, size: u64) ?u64 {
4717 const increased_size = padToIdeal(size);
4718 const test_end = off + increased_size;
4719 if (end > off and start < test_end) {
4720 return test_end;
4721 }
4722 return null;
4723}
4724
4725fn detectAllocCollisionLinkedit(self: *MachO, start: u64, size: u64) ?u64 {
4726 const end = start + padToIdeal(size);
4727
4728 // __LINKEDIT is a weird segment where sections get their own load commands so we
4729 // special-case it.
4730 if (self.dyld_info_cmd_index) |idx| outer: {
4731 if (self.load_commands.items.len == idx) break :outer;
4732 const dyld_info = self.load_commands.items[idx].DyldInfoOnly;
4733 if (checkForCollision(start, end, dyld_info.rebase_off, dyld_info.rebase_size)) |pos| {
4734 return pos;
4735 }
4736 // Binding info
4737 if (checkForCollision(start, end, dyld_info.bind_off, dyld_info.bind_size)) |pos| {
4738 return pos;
4739 }
4740 // Weak binding info
4741 if (checkForCollision(start, end, dyld_info.weak_bind_off, dyld_info.weak_bind_size)) |pos| {
4742 return pos;
4743 }
4744 // Lazy binding info
4745 if (checkForCollision(start, end, dyld_info.lazy_bind_off, dyld_info.lazy_bind_size)) |pos| {
4746 return pos;
4747 }
4748 // Export info
4749 if (checkForCollision(start, end, dyld_info.export_off, dyld_info.export_size)) |pos| {
4750 return pos;
4751 }
4752 }
4753
4754 if (self.function_starts_cmd_index) |idx| outer: {
4755 if (self.load_commands.items.len == idx) break :outer;
4756 const fstart = self.load_commands.items[idx].LinkeditData;
4757 if (checkForCollision(start, end, fstart.dataoff, fstart.datasize)) |pos| {
4758 return pos;
4759 }
4760 }
4761
4762 if (self.data_in_code_cmd_index) |idx| outer: {
4763 if (self.load_commands.items.len == idx) break :outer;
4764 const dic = self.load_commands.items[idx].LinkeditData;
4765 if (checkForCollision(start, end, dic.dataoff, dic.datasize)) |pos| {
4766 return pos;
4767 }
4768 }
4769
4770 if (self.dysymtab_cmd_index) |idx| outer: {
4771 if (self.load_commands.items.len == idx) break :outer;
4772 const dysymtab = self.load_commands.items[idx].Dysymtab;
4773 // Indirect symbol table
4774 const nindirectsize = dysymtab.nindirectsyms * @sizeOf(u32);
4775 if (checkForCollision(start, end, dysymtab.indirectsymoff, nindirectsize)) |pos| {
4776 return pos;
4777 }
4778 // TODO Handle more dynamic symbol table sections.
4779 }
4780
4781 if (self.symtab_cmd_index) |idx| outer: {
4782 if (self.load_commands.items.len == idx) break :outer;
4783 const symtab = self.load_commands.items[idx].Symtab;
4784 // Symbol table
4785 const symsize = symtab.nsyms * @sizeOf(macho.nlist_64);
4786 if (checkForCollision(start, end, symtab.symoff, symsize)) |pos| {
4787 return pos;
4788 }
4789 // String table
4790 if (checkForCollision(start, end, symtab.stroff, symtab.strsize)) |pos| {
4791 return pos;
4792 }
4793 }
4794
4795 return null;
4796}
4797
4798fn findFreeSpaceLinkedit(self: *MachO, object_size: u64, min_alignment: u16, start: ?u64) u64 {
4799 const linkedit = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
4800 var st: u64 = start orelse linkedit.inner.fileoff;
4801 while (self.detectAllocCollisionLinkedit(st, object_size)) |item_end| {
4802 st = mem.alignForwardGeneric(u64, item_end, min_alignment);
4803 }
4804 return st;
4805}
4806
4807fn writeGotEntry(self: *MachO, index: usize) !void {
4808 const seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
4809 const sect = &seg.sections.items[self.got_section_index.?];
4810 const off = sect.offset + @sizeOf(u64) * index;
4811
4812 if (self.got_entries_count_dirty) {
4813 // TODO relocate.
4814 self.got_entries_count_dirty = false;
4815 }
4816
4817 const got_entry = self.got_entries.items[index];
4818 const sym = switch (got_entry.where) {
4819 .local => self.locals.items[got_entry.where_index],
4820 .undef => self.undefs.items[got_entry.where_index],
4821 };
4822 log.debug("writing offset table entry [ 0x{x} => 0x{x} ({s}) ]", .{
4823 off,
4824 sym.n_value,
4825 self.getString(sym.n_strx),
4826 });
4827 try self.base.file.?.pwriteAll(mem.asBytes(&sym.n_value), off);
4828}
4829
4830fn writeLazySymbolPointer(self: *MachO, index: u32) !void {
4831 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4832 const stub_helper = text_segment.sections.items[self.stub_helper_section_index.?];
4833 const data_segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4834 const la_symbol_ptr = data_segment.sections.items[self.la_symbol_ptr_section_index.?];
4835
4836 const stub_size: u4 = switch (self.base.options.target.cpu.arch) {
4837 .x86_64 => 10,
4838 .aarch64 => 3 * @sizeOf(u32),
4839 else => unreachable,
4840 };
4841 const stub_off = self.stub_helper_stubs_start_off.? + index * stub_size;
4842 const end = stub_helper.addr + stub_off - stub_helper.offset;
4843 var buf: [@sizeOf(u64)]u8 = undefined;
4844 mem.writeIntLittle(u64, &buf, end);
4845 const off = la_symbol_ptr.offset + index * @sizeOf(u64);
4846 log.debug("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off });
4847 try self.base.file.?.pwriteAll(&buf, off);
4848}
4849
4850fn writeStubHelperPreamble(self: *MachO) !void {
4851 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4852 const stub_helper = &text_segment.sections.items[self.stub_helper_section_index.?];
4853 const data_const_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
4854 const got = &data_const_segment.sections.items[self.got_section_index.?];
4855 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4856 const data = &data_segment.sections.items[self.data_section_index.?];
4857
4858 switch (self.base.options.target.cpu.arch) {
4859 .x86_64 => {
4860 const code_size = 15;
4861 var code: [code_size]u8 = undefined;
4862 // lea %r11, [rip + disp]
4863 code[0] = 0x4c;
4864 code[1] = 0x8d;
4865 code[2] = 0x1d;
4866 {
4867 const target_addr = data.addr;
4868 const displacement = try math.cast(u32, target_addr - stub_helper.addr - 7);
4869 mem.writeIntLittle(u32, code[3..7], displacement);
4870 }
4871 // push %r11
4872 code[7] = 0x41;
4873 code[8] = 0x53;
4874 // jmp [rip + disp]
4875 code[9] = 0xff;
4876 code[10] = 0x25;
4877 {
4878 const displacement = try math.cast(u32, got.addr - stub_helper.addr - code_size);
4879 mem.writeIntLittle(u32, code[11..], displacement);
4880 }
4881 try self.base.file.?.pwriteAll(&code, stub_helper.offset);
4882 self.stub_helper_stubs_start_off = stub_helper.offset + code_size;
4883 },
4884 .aarch64 => {
4885 var code: [6 * @sizeOf(u32)]u8 = undefined;
4886
4887 data_blk_outer: {
4888 const this_addr = stub_helper.addr;
4889 const target_addr = data.addr;
4890 data_blk: {
4891 const displacement = math.cast(i21, target_addr - this_addr) catch break :data_blk;
4892 // adr x17, disp
4893 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x17, displacement).toU32());
4894 // nop
4895 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.nop().toU32());
4896 break :data_blk_outer;
4897 }
4898 data_blk: {
4899 const new_this_addr = this_addr + @sizeOf(u32);
4900 const displacement = math.cast(i21, target_addr - new_this_addr) catch break :data_blk;
4901 // nop
4902 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.nop().toU32());
4903 // adr x17, disp
4904 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.adr(.x17, displacement).toU32());
4905 break :data_blk_outer;
4906 }
4907 // Jump is too big, replace adr with adrp and add.
4908 const this_page = @intCast(i32, this_addr >> 12);
4909 const target_page = @intCast(i32, target_addr >> 12);
4910 const pages = @intCast(i21, target_page - this_page);
4911 // adrp x17, pages
4912 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adrp(.x17, pages).toU32());
4913 const narrowed = @truncate(u12, target_addr);
4914 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.add(.x17, .x17, narrowed, false).toU32());
4915 }
4916
4917 // stp x16, x17, [sp, #-16]!
4918 mem.writeIntLittle(u32, code[8..12], aarch64.Instruction.stp(
4919 .x16,
4920 .x17,
4921 aarch64.Register.sp,
4922 aarch64.Instruction.LoadStorePairOffset.pre_index(-16),
4923 ).toU32());
4924
4925 binder_blk_outer: {
4926 const this_addr = stub_helper.addr + 3 * @sizeOf(u32);
4927 const target_addr = got.addr;
4928 binder_blk: {
4929 const displacement = math.divExact(u64, target_addr - this_addr, 4) catch break :binder_blk;
4930 const literal = math.cast(u18, displacement) catch break :binder_blk;
4931 // ldr x16, label
4932 mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.ldr(.x16, .{
4933 .literal = literal,
4934 }).toU32());
4935 // nop
4936 mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.nop().toU32());
4937 break :binder_blk_outer;
4938 }
4939 binder_blk: {
4940 const new_this_addr = this_addr + @sizeOf(u32);
4941 const displacement = math.divExact(u64, target_addr - new_this_addr, 4) catch break :binder_blk;
4942 const literal = math.cast(u18, displacement) catch break :binder_blk;
4943 // nop
4944 mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.nop().toU32());
4945 // ldr x16, label
4946 mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.ldr(.x16, .{
4947 .literal = literal,
4948 }).toU32());
4949 break :binder_blk_outer;
4950 }
4951 // Jump is too big, replace ldr with adrp and ldr(register).
4952 const this_page = @intCast(i32, this_addr >> 12);
4953 const target_page = @intCast(i32, target_addr >> 12);
4954 const pages = @intCast(i21, target_page - this_page);
4955 // adrp x16, pages
4956 mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.adrp(.x16, pages).toU32());
4957 const narrowed = @truncate(u12, target_addr);
4958 const offset = try math.divExact(u12, narrowed, 8);
4959 // ldr x16, x16, offset
4960 mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.ldr(.x16, .{
4961 .register = .{
4962 .rn = .x16,
4963 .offset = aarch64.Instruction.LoadStoreOffset.imm(offset),
4964 },
4965 }).toU32());
4966 }
4967
4968 // br x16
4969 mem.writeIntLittle(u32, code[20..24], aarch64.Instruction.br(.x16).toU32());
4970 try self.base.file.?.pwriteAll(&code, stub_helper.offset);
4971 self.stub_helper_stubs_start_off = stub_helper.offset + code.len;
4972 },
4973 else => unreachable,
4974 }
4975}
4976
4977fn writeStub(self: *MachO, index: u32) !void {
4978 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4979 const stubs = text_segment.sections.items[self.stubs_section_index.?];
4980 const data_segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4981 const la_symbol_ptr = data_segment.sections.items[self.la_symbol_ptr_section_index.?];
4982
4983 const stub_off = stubs.offset + index * stubs.reserved2;
4984 const stub_addr = stubs.addr + index * stubs.reserved2;
4985 const la_ptr_addr = la_symbol_ptr.addr + index * @sizeOf(u64);
4986
4987 log.debug("writing stub at 0x{x}", .{stub_off});
4988
4989 var code = try self.base.allocator.alloc(u8, stubs.reserved2);
4990 defer self.base.allocator.free(code);
4991
4992 switch (self.base.options.target.cpu.arch) {
4993 .x86_64 => {
4994 assert(la_ptr_addr >= stub_addr + stubs.reserved2);
4995 const displacement = try math.cast(u32, la_ptr_addr - stub_addr - stubs.reserved2);
4996 // jmp
4997 code[0] = 0xff;
4998 code[1] = 0x25;
4999 mem.writeIntLittle(u32, code[2..][0..4], displacement);
5000 },
5001 .aarch64 => {
5002 assert(la_ptr_addr >= stub_addr);
5003 outer: {
5004 const this_addr = stub_addr;
5005 const target_addr = la_ptr_addr;
5006 inner: {
5007 const displacement = math.divExact(u64, target_addr - this_addr, 4) catch break :inner;
5008 const literal = math.cast(u18, displacement) catch break :inner;
5009 // ldr x16, literal
5010 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.ldr(.x16, .{
5011 .literal = literal,
5012 }).toU32());
5013 // nop
5014 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.nop().toU32());
5015 break :outer;
5016 }
5017 inner: {
5018 const new_this_addr = this_addr + @sizeOf(u32);
5019 const displacement = math.divExact(u64, target_addr - new_this_addr, 4) catch break :inner;
5020 const literal = math.cast(u18, displacement) catch break :inner;
5021 // nop
5022 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.nop().toU32());
5023 // ldr x16, literal
5024 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ldr(.x16, .{
5025 .literal = literal,
5026 }).toU32());
5027 break :outer;
5028 }
5029 // Use adrp followed by ldr(register).
5030 const this_page = @intCast(i32, this_addr >> 12);
5031 const target_page = @intCast(i32, target_addr >> 12);
5032 const pages = @intCast(i21, target_page - this_page);
5033 // adrp x16, pages
5034 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adrp(.x16, pages).toU32());
5035 const narrowed = @truncate(u12, target_addr);
5036 const offset = try math.divExact(u12, narrowed, 8);
5037 // ldr x16, x16, offset
5038 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ldr(.x16, .{
5039 .register = .{
5040 .rn = .x16,
5041 .offset = aarch64.Instruction.LoadStoreOffset.imm(offset),
5042 },
5043 }).toU32());
5044 }
5045 // br x16
5046 mem.writeIntLittle(u32, code[8..12], aarch64.Instruction.br(.x16).toU32());
5047 },
5048 else => unreachable,
5049 }
5050 try self.base.file.?.pwriteAll(code, stub_off);
5051}
5052
5053fn writeStubInStubHelper(self: *MachO, index: u32) !void {
5054 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
5055 const stub_helper = text_segment.sections.items[self.stub_helper_section_index.?];
5056
5057 const stub_size: u4 = switch (self.base.options.target.cpu.arch) {
5058 .x86_64 => 10,
5059 .aarch64 => 3 * @sizeOf(u32),
5060 else => unreachable,
5061 };
5062 const stub_off = self.stub_helper_stubs_start_off.? + index * stub_size;
5063
5064 var code = try self.base.allocator.alloc(u8, stub_size);
5065 defer self.base.allocator.free(code);
5066
5067 switch (self.base.options.target.cpu.arch) {
5068 .x86_64 => {
5069 const displacement = try math.cast(
5070 i32,
5071 @intCast(i64, stub_helper.offset) - @intCast(i64, stub_off) - stub_size,
5072 );
5073 // pushq
5074 code[0] = 0x68;
5075 mem.writeIntLittle(u32, code[1..][0..4], 0x0); // Just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
5076 // jmpq
5077 code[5] = 0xe9;
5078 mem.writeIntLittle(u32, code[6..][0..4], @bitCast(u32, displacement));
5079 },
5080 .aarch64 => {
5081 const literal = blk: {
5082 const div_res = try math.divExact(u64, stub_size - @sizeOf(u32), 4);
5083 break :blk try math.cast(u18, div_res);
5084 };
5085 // ldr w16, literal
5086 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.ldr(.w16, .{
5087 .literal = literal,
5088 }).toU32());
5089 const displacement = try math.cast(i28, @intCast(i64, stub_helper.offset) - @intCast(i64, stub_off) - 4);
5090 // b disp
5091 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.b(displacement).toU32());
5092 // Just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
5093 mem.writeIntLittle(u32, code[8..12], 0x0);
5094 },
5095 else => unreachable,
5096 }
5097 try self.base.file.?.pwriteAll(code, stub_off);
5098}
5099
5100fn relocateSymbolTable(self: *MachO) !void {
5101 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
5102 const nlocals = self.locals.items.len;
5103 const nglobals = self.globals.items.len;
5104 const nundefs = self.undefs.items.len;
5105 const nsyms = nlocals + nglobals + nundefs;
5106
5107 if (symtab.nsyms < nsyms) {
5108 const needed_size = nsyms * @sizeOf(macho.nlist_64);
5109 if (needed_size > self.allocatedSizeLinkedit(symtab.symoff)) {
5110 // Move the entire symbol table to a new location
5111 const new_symoff = self.findFreeSpaceLinkedit(needed_size, @alignOf(macho.nlist_64), null);
5112 const existing_size = symtab.nsyms * @sizeOf(macho.nlist_64);
5113
5114 log.debug("relocating symbol table from 0x{x}-0x{x} to 0x{x}-0x{x}", .{
5115 symtab.symoff,
5116 symtab.symoff + existing_size,
5117 new_symoff,
5118 new_symoff + existing_size,
5119 });
51203700
5121 const amt = try self.base.file.?.copyRangeAll(symtab.symoff, self.base.file.?, new_symoff, existing_size);3701 try self.load_commands.append(self.base.allocator, .{
5122 if (amt != existing_size) return error.InputOutput;3702 .Segment = .{
5123 symtab.symoff = @intCast(u32, new_symoff);3703 .inner = .{
5124 self.strtab_needs_relocation = true;3704 .segname = makeStaticString("__LINKEDIT"),
5125 }3705 .vmaddr = address_and_offset.address,
5126 symtab.nsyms = @intCast(u32, nsyms);3706 .fileoff = address_and_offset.offset,
3707 .maxprot = macho.VM_PROT_READ,
3708 .initprot = macho.VM_PROT_READ,
3709 },
3710 },
3711 });
5127 self.load_commands_dirty = true;3712 self.load_commands_dirty = true;
5128 }3713 }
5129}
5130
5131fn writeLocalSymbol(self: *MachO, index: usize) !void {
5132 const tracy = trace(@src());
5133 defer tracy.end();
5134 try self.relocateSymbolTable();
5135 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
5136 const off = symtab.symoff + @sizeOf(macho.nlist_64) * index;
5137 log.debug("writing local symbol {} at 0x{x}", .{ index, off });
5138 try self.base.file.?.pwriteAll(mem.asBytes(&self.locals.items[index]), off);
5139}
5140
5141fn writeAllGlobalAndUndefSymbols(self: *MachO) !void {
5142 const tracy = trace(@src());
5143 defer tracy.end();
5144
5145 try self.relocateSymbolTable();
5146 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
5147 const nlocals = self.locals.items.len;
5148 const nglobals = self.globals.items.len;
5149 const nundefs = self.undefs.items.len;
5150
5151 const locals_off = symtab.symoff;
5152 const locals_size = nlocals * @sizeOf(macho.nlist_64);
5153
5154 const globals_off = locals_off + locals_size;
5155 const globals_size = nglobals * @sizeOf(macho.nlist_64);
5156 log.debug("writing global symbols from 0x{x} to 0x{x}", .{ globals_off, globals_size + globals_off });
5157 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.globals.items), globals_off);
5158
5159 const undefs_off = globals_off + globals_size;
5160 const undefs_size = nundefs * @sizeOf(macho.nlist_64);
5161 log.debug("writing extern symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off });
5162 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off);
5163
5164 // Update dynamic symbol table.
5165 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
5166 dysymtab.nlocalsym = @intCast(u32, nlocals);
5167 dysymtab.iextdefsym = @intCast(u32, nlocals);
5168 dysymtab.nextdefsym = @intCast(u32, nglobals);
5169 dysymtab.iundefsym = @intCast(u32, nlocals + nglobals);
5170 dysymtab.nundefsym = @intCast(u32, nundefs);
5171 self.load_commands_dirty = true;
5172}
5173
5174fn writeIndirectSymbolTable(self: *MachO) !void {
5175 // TODO figure out a way not to rewrite the table every time if
5176 // no new undefs are not added.
5177 const tracy = trace(@src());
5178 defer tracy.end();
51793714
5180 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;3715 if (self.dyld_info_cmd_index == null) {
5181 const stubs = &text_segment.sections.items[self.stubs_section_index.?];3716 self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len);
5182 const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;3717 try self.load_commands.append(self.base.allocator, .{
5183 const got = &data_const_seg.sections.items[self.got_section_index.?];3718 .DyldInfoOnly = .{
5184 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;3719 .cmd = macho.LC_DYLD_INFO_ONLY,
5185 const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?];3720 .cmdsize = @sizeOf(macho.dyld_info_command),
5186 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;3721 .rebase_off = 0,
51873722 .rebase_size = 0,
5188 const nstubs = @intCast(u32, self.stubs.items.len);3723 .bind_off = 0,
5189 const ngot_entries = @intCast(u32, self.got_entries.items.len);3724 .bind_size = 0,
5190 const allocated_size = self.allocatedSizeLinkedit(dysymtab.indirectsymoff);3725 .weak_bind_off = 0,
5191 const nindirectsyms = nstubs * 2 + ngot_entries;3726 .weak_bind_size = 0,
5192 const needed_size = @intCast(u32, nindirectsyms * @sizeOf(u32));3727 .lazy_bind_off = 0,
51933728 .lazy_bind_size = 0,
5194 if (needed_size > allocated_size) {3729 .export_off = 0,
5195 dysymtab.nindirectsyms = 0;3730 .export_size = 0,
5196 dysymtab.indirectsymoff = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, @sizeOf(u32), null));3731 },
3732 });
3733 self.load_commands_dirty = true;
5197 }3734 }
5198 dysymtab.nindirectsyms = nindirectsyms;
5199 log.debug("writing indirect symbol table from 0x{x} to 0x{x}", .{
5200 dysymtab.indirectsymoff,
5201 dysymtab.indirectsymoff + needed_size,
5202 });
5203
5204 var buf = try self.base.allocator.alloc(u8, needed_size);
5205 defer self.base.allocator.free(buf);
5206 var stream = std.io.fixedBufferStream(buf);
5207 var writer = stream.writer();
52083735
5209 stubs.reserved1 = 0;3736 if (self.symtab_cmd_index == null) {
5210 for (self.stubs.items) |id| {3737 self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len);
5211 try writer.writeIntLittle(u32, dysymtab.iundefsym + id);3738 try self.load_commands.append(self.base.allocator, .{
3739 .Symtab = .{
3740 .cmd = macho.LC_SYMTAB,
3741 .cmdsize = @sizeOf(macho.symtab_command),
3742 .symoff = 0,
3743 .nsyms = 0,
3744 .stroff = 0,
3745 .strsize = 0,
3746 },
3747 });
3748 self.load_commands_dirty = true;
5212 }3749 }
52133750
5214 got.reserved1 = nstubs;3751 if (self.dysymtab_cmd_index == null) {
5215 for (self.got_entries.items) |entry| {3752 self.dysymtab_cmd_index = @intCast(u16, self.load_commands.items.len);
5216 switch (entry.where) {3753 try self.load_commands.append(self.base.allocator, .{
5217 .undef => {3754 .Dysymtab = .{
5218 try writer.writeIntLittle(u32, dysymtab.iundefsym + entry.where_index);3755 .cmd = macho.LC_DYSYMTAB,
5219 },3756 .cmdsize = @sizeOf(macho.dysymtab_command),
5220 .local => {3757 .ilocalsym = 0,
5221 try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL);3758 .nlocalsym = 0,
3759 .iextdefsym = 0,
3760 .nextdefsym = 0,
3761 .iundefsym = 0,
3762 .nundefsym = 0,
3763 .tocoff = 0,
3764 .ntoc = 0,
3765 .modtaboff = 0,
3766 .nmodtab = 0,
3767 .extrefsymoff = 0,
3768 .nextrefsyms = 0,
3769 .indirectsymoff = 0,
3770 .nindirectsyms = 0,
3771 .extreloff = 0,
3772 .nextrel = 0,
3773 .locreloff = 0,
3774 .nlocrel = 0,
5222 },3775 },
5223 }3776 });
3777 self.load_commands_dirty = true;
5224 }3778 }
52253779
5226 la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries;3780 if (self.dylinker_cmd_index == null) {
5227 for (self.stubs.items) |id| {3781 self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len);
5228 try writer.writeIntLittle(u32, dysymtab.iundefsym + id);3782 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
3783 u64,
3784 @sizeOf(macho.dylinker_command) + mem.lenZ(default_dyld_path),
3785 @sizeOf(u64),
3786 ));
3787 var dylinker_cmd = commands.emptyGenericCommandWithData(macho.dylinker_command{
3788 .cmd = macho.LC_LOAD_DYLINKER,
3789 .cmdsize = cmdsize,
3790 .name = @sizeOf(macho.dylinker_command),
3791 });
3792 dylinker_cmd.data = try self.base.allocator.alloc(u8, cmdsize - dylinker_cmd.inner.name);
3793 mem.set(u8, dylinker_cmd.data, 0);
3794 mem.copy(u8, dylinker_cmd.data, mem.spanZ(default_dyld_path));
3795 try self.load_commands.append(self.base.allocator, .{ .Dylinker = dylinker_cmd });
3796 self.load_commands_dirty = true;
5229 }3797 }
52303798
5231 try self.base.file.?.pwriteAll(buf, dysymtab.indirectsymoff);3799 if (self.main_cmd_index == null and self.base.options.output_mode == .Exe) {
5232 self.load_commands_dirty = true;3800 self.main_cmd_index = @intCast(u16, self.load_commands.items.len);
5233}3801 try self.load_commands.append(self.base.allocator, .{
3802 .Main = .{
3803 .cmd = macho.LC_MAIN,
3804 .cmdsize = @sizeOf(macho.entry_point_command),
3805 .entryoff = 0x0,
3806 .stacksize = 0,
3807 },
3808 });
3809 self.load_commands_dirty = true;
3810 }
52343811
5235fn writeDices(self: *MachO) !void {3812 if (self.dylib_id_cmd_index == null and self.base.options.output_mode == .Lib) {
5236 if (!self.has_dices) return;3813 self.dylib_id_cmd_index = @intCast(u16, self.load_commands.items.len);
3814 const install_name = try std.fmt.allocPrint(self.base.allocator, "@rpath/{s}", .{
3815 self.base.options.emit.?.sub_path,
3816 });
3817 defer self.base.allocator.free(install_name);
3818 var dylib_cmd = try commands.createLoadDylibCommand(
3819 self.base.allocator,
3820 install_name,
3821 2,
3822 0x10000, // TODO forward user-provided versions
3823 0x10000,
3824 );
3825 errdefer dylib_cmd.deinit(self.base.allocator);
3826 dylib_cmd.inner.cmd = macho.LC_ID_DYLIB;
3827 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
3828 self.load_commands_dirty = true;
3829 }
52373830
5238 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;3831 if (self.source_version_cmd_index == null) {
5239 const dice_cmd = &self.load_commands.items[self.data_in_code_cmd_index.?].LinkeditData;3832 self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len);
5240 const fileoff = seg.inner.fileoff + seg.inner.filesize;3833 try self.load_commands.append(self.base.allocator, .{
3834 .SourceVersion = .{
3835 .cmd = macho.LC_SOURCE_VERSION,
3836 .cmdsize = @sizeOf(macho.source_version_command),
3837 .version = 0x0,
3838 },
3839 });
3840 self.load_commands_dirty = true;
3841 }
52413842
5242 var buf = std.ArrayList(u8).init(self.base.allocator);3843 if (self.build_version_cmd_index == null) {
5243 defer buf.deinit();3844 self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len);
3845 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
3846 u64,
3847 @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version),
3848 @sizeOf(u64),
3849 ));
3850 const ver = self.base.options.target.os.version_range.semver.min;
3851 const version = ver.major << 16 | ver.minor << 8 | ver.patch;
3852 const is_simulator_abi = self.base.options.target.abi == .simulator;
3853 var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{
3854 .cmd = macho.LC_BUILD_VERSION,
3855 .cmdsize = cmdsize,
3856 .platform = switch (self.base.options.target.os.tag) {
3857 .macos => macho.PLATFORM_MACOS,
3858 .ios => if (is_simulator_abi) macho.PLATFORM_IOSSIMULATOR else macho.PLATFORM_IOS,
3859 .watchos => if (is_simulator_abi) macho.PLATFORM_WATCHOSSIMULATOR else macho.PLATFORM_WATCHOS,
3860 .tvos => if (is_simulator_abi) macho.PLATFORM_TVOSSIMULATOR else macho.PLATFORM_TVOS,
3861 else => unreachable,
3862 },
3863 .minos = version,
3864 .sdk = version,
3865 .ntools = 1,
3866 });
3867 const ld_ver = macho.build_tool_version{
3868 .tool = macho.TOOL_LD,
3869 .version = 0x0,
3870 };
3871 cmd.data = try self.base.allocator.alloc(u8, cmdsize - @sizeOf(macho.build_version_command));
3872 mem.set(u8, cmd.data, 0);
3873 mem.copy(u8, cmd.data, mem.asBytes(&ld_ver));
3874 try self.load_commands.append(self.base.allocator, .{ .BuildVersion = cmd });
3875 self.load_commands_dirty = true;
3876 }
52443877
5245 var block: *TextBlock = self.blocks.get(.{3878 if (self.uuid_cmd_index == null) {
5246 .seg = self.text_segment_cmd_index orelse return,3879 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
5247 .sect = self.text_section_index orelse return,3880 var uuid_cmd: macho.uuid_command = .{
5248 }) orelse return;3881 .cmd = macho.LC_UUID,
3882 .cmdsize = @sizeOf(macho.uuid_command),
3883 .uuid = undefined,
3884 };
3885 std.crypto.random.bytes(&uuid_cmd.uuid);
3886 try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd });
3887 self.load_commands_dirty = true;
3888 }
52493889
5250 while (block.prev) |prev| {3890 if (self.data_in_code_cmd_index == null) {
5251 block = prev;3891 self.data_in_code_cmd_index = @intCast(u16, self.load_commands.items.len);
3892 try self.load_commands.append(self.base.allocator, .{
3893 .LinkeditData = .{
3894 .cmd = macho.LC_DATA_IN_CODE,
3895 .cmdsize = @sizeOf(macho.linkedit_data_command),
3896 .dataoff = 0,
3897 .datasize = 0,
3898 },
3899 });
3900 self.load_commands_dirty = true;
5252 }3901 }
52533902
5254 const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;3903 self.cold_start = true;
5255 const text_sect = text_seg.sections.items[self.text_section_index.?];3904}
52563905
5257 while (true) {3906const AllocateSectionOpts = struct {
5258 if (block.dices.items.len > 0) {3907 flags: u32 = macho.S_REGULAR,
5259 const sym = self.locals.items[block.local_sym_index];3908 reserved1: u32 = 0,
5260 const base_off = try math.cast(u32, sym.n_value - text_sect.addr + text_sect.offset);3909 reserved2: u32 = 0,
3910};
52613911
5262 try buf.ensureUnusedCapacity(block.dices.items.len * @sizeOf(macho.data_in_code_entry));3912fn allocateSection(
5263 for (block.dices.items) |dice| {3913 self: *MachO,
5264 const rebased_dice = macho.data_in_code_entry{3914 segment_id: u16,
5265 .offset = base_off + dice.offset,3915 sectname: []const u8,
5266 .length = dice.length,3916 size: u64,
5267 .kind = dice.kind,3917 alignment: u32,
5268 };3918 opts: AllocateSectionOpts,
5269 buf.appendSliceAssumeCapacity(mem.asBytes(&rebased_dice));3919) !u16 {
5270 }3920 const seg = &self.load_commands.items[segment_id].Segment;
5271 }3921 var sect = macho.section_64{
3922 .sectname = makeStaticString(sectname),
3923 .segname = seg.inner.segname,
3924 .size = @intCast(u32, size),
3925 .@"align" = alignment,
3926 .flags = opts.flags,
3927 .reserved1 = opts.reserved1,
3928 .reserved2 = opts.reserved2,
3929 };
52723930
5273 if (block.next) |next| {3931 const alignment_pow_2 = try math.powi(u32, 2, alignment);
5274 block = next;3932 const padding: ?u64 = if (segment_id == self.text_segment_cmd_index.?) self.header_pad else null;
5275 } else break;3933 const off = self.findFreeSpace(segment_id, alignment_pow_2, padding);
5276 }
52773934
5278 const datasize = @intCast(u32, buf.items.len);3935 log.debug("allocating {s},{s} section from 0x{x} to 0x{x}", .{
3936 commands.segmentName(sect),
3937 commands.sectionName(sect),
3938 off,
3939 off + size,
3940 });
52793941
5280 dice_cmd.dataoff = @intCast(u32, fileoff);3942 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;
5281 dice_cmd.datasize = datasize;3943 sect.offset = @intCast(u32, off);
5282 seg.inner.filesize += datasize;
52833944
5284 log.debug("writing data-in-code from 0x{x} to 0x{x}", .{ fileoff, fileoff + datasize });3945 const index = @intCast(u16, seg.sections.items.len);
3946 try seg.sections.append(self.base.allocator, sect);
3947 seg.inner.cmdsize += @sizeOf(macho.section_64);
3948 seg.inner.nsects += 1;
52853949
5286 try self.base.file.?.pwriteAll(buf.items, fileoff);3950 const match = MatchingSection{
5287}3951 .seg = segment_id,
3952 .sect = index,
3953 };
3954 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
3955 try self.atom_free_lists.putNoClobber(self.base.allocator, match, .{});
52883956
5289fn writeCodeSignaturePadding(self: *MachO) !void {3957 self.load_commands_dirty = true;
5290 // TODO figure out how not to rewrite padding every single time.3958 self.sections_order_dirty = true;
5291 const tracy = trace(@src());
5292 defer tracy.end();
52933959
5294 const linkedit_segment = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;3960 return index;
5295 const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData;3961}
5296 const fileoff = linkedit_segment.inner.fileoff + linkedit_segment.inner.filesize;
5297 const needed_size = CodeSignature.calcCodeSignaturePaddingSize(
5298 self.base.options.emit.?.sub_path,
5299 fileoff,
5300 self.page_size,
5301 );
5302 code_sig_cmd.dataoff = @intCast(u32, fileoff);
5303 code_sig_cmd.datasize = needed_size;
53043962
5305 // Advance size of __LINKEDIT segment3963fn findFreeSpace(self: MachO, segment_id: u16, alignment: u64, start: ?u64) u64 {
5306 linkedit_segment.inner.filesize += needed_size;3964 const seg = self.load_commands.items[segment_id].Segment;
5307 if (linkedit_segment.inner.vmsize < linkedit_segment.inner.filesize) {3965 if (seg.sections.items.len == 0) {
5308 linkedit_segment.inner.vmsize = mem.alignForwardGeneric(u64, linkedit_segment.inner.filesize, self.page_size);3966 return if (start) |v| v else seg.inner.fileoff;
5309 }3967 }
5310 log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size });3968 const last_sect = seg.sections.items[seg.sections.items.len - 1];
5311 // Pad out the space. We need to do this to calculate valid hashes for everything in the file3969 const final_off = last_sect.offset + padToIdeal(last_sect.size);
5312 // except for code signature data.3970 return mem.alignForwardGeneric(u64, final_off, alignment);
5313 try self.base.file.?.pwriteAll(&[_]u8{0}, fileoff + needed_size - 1);
5314 self.load_commands_dirty = true;
5315}3971}
53163972
5317fn writeCodeSignature(self: *MachO) !void {3973fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void {
5318 const tracy = trace(@src());3974 const tracy = trace(@src());
5319 defer tracy.end();3975 defer tracy.end();
53203976
5321 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;3977 const seg = &self.load_commands.items[match.seg].Segment;
5322 const code_sig_cmd = self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData;3978 const sect = &seg.sections.items[match.sect];
5323
5324 var code_sig: CodeSignature = .{};
5325 defer code_sig.deinit(self.base.allocator);
5326
5327 try code_sig.calcAdhocSignature(
5328 self.base.allocator,
5329 self.base.file.?,
5330 self.base.options.emit.?.sub_path,
5331 text_segment.inner,
5332 code_sig_cmd,
5333 self.base.options.output_mode,
5334 self.page_size,
5335 );
5336
5337 var buffer = try self.base.allocator.alloc(u8, code_sig.size());
5338 defer self.base.allocator.free(buffer);
5339 var stream = std.io.fixedBufferStream(buffer);
5340 try code_sig.write(stream.writer());
53413979
5342 log.debug("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len });3980 const alignment = try math.powi(u32, 2, sect.@"align");
3981 const max_size = self.allocatedSize(match.seg, sect.offset);
3982 const ideal_size = padToIdeal(new_size);
3983 const needed_size = mem.alignForwardGeneric(u32, ideal_size, alignment);
53433984
5344 try self.base.file.?.pwriteAll(buffer, code_sig_cmd.dataoff);3985 if (needed_size > max_size) blk: {
5345}3986 log.debug(" (need to grow!)", .{});
3987 // Need to move all sections below in file and address spaces.
3988 const offset_amt = offset: {
3989 const max_alignment = try self.getSectionMaxAlignment(match.seg, match.sect + 1);
3990 break :offset mem.alignForwardGeneric(u64, needed_size - max_size, max_alignment);
3991 };
53463992
5347fn writeExportInfo(self: *MachO) !void {3993 // Before we commit to this, check if the segment needs to grow too.
5348 if (!self.export_info_dirty) return;3994 // We assume that each section header is growing linearly with the increasing
5349 if (self.globals.items.len == 0) return;3995 // file offset / virtual memory address space.
3996 const last_sect = seg.sections.items[seg.sections.items.len - 1];
3997 const last_sect_off = last_sect.offset + last_sect.size;
3998 const seg_off = seg.inner.fileoff + seg.inner.filesize;
3999
4000 if (last_sect_off + offset_amt > seg_off) {
4001 // Need to grow segment first.
4002 log.debug(" (need to grow segment first)", .{});
4003 const spill_size = (last_sect_off + offset_amt) - seg_off;
4004 const seg_offset_amt = mem.alignForwardGeneric(u64, spill_size, self.page_size);
4005 seg.inner.filesize += seg_offset_amt;
4006 seg.inner.vmsize += seg_offset_amt;
4007
4008 log.debug(" (new {s} segment file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{
4009 seg.inner.segname,
4010 seg.inner.fileoff,
4011 seg.inner.fileoff + seg.inner.filesize,
4012 seg.inner.vmaddr,
4013 seg.inner.vmaddr + seg.inner.vmsize,
4014 });
53504015
5351 const tracy = trace(@src());4016 // TODO We should probably nop the expanded by distance, or put 0s.
5352 defer tracy.end();4017
4018 // TODO copyRangeAll doesn't automatically extend the file on macOS.
4019 const ledit_seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
4020 const new_filesize = seg_offset_amt + ledit_seg.inner.fileoff + ledit_seg.inner.filesize;
4021 try self.base.file.?.pwriteAll(&[_]u8{0}, new_filesize - 1);
4022
4023 var next: usize = match.seg + 1;
4024 while (next < self.linkedit_segment_cmd_index.? + 1) : (next += 1) {
4025 const next_seg = &self.load_commands.items[next].Segment;
4026 _ = try self.base.file.?.copyRangeAll(
4027 next_seg.inner.fileoff,
4028 self.base.file.?,
4029 next_seg.inner.fileoff + seg_offset_amt,
4030 next_seg.inner.filesize,
4031 );
4032 next_seg.inner.fileoff += seg_offset_amt;
4033 next_seg.inner.vmaddr += seg_offset_amt;
4034
4035 log.debug(" (new {s} segment file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{
4036 next_seg.inner.segname,
4037 next_seg.inner.fileoff,
4038 next_seg.inner.fileoff + next_seg.inner.filesize,
4039 next_seg.inner.vmaddr,
4040 next_seg.inner.vmaddr + next_seg.inner.vmsize,
4041 });
53534042
5354 var trie: Trie = .{};4043 for (next_seg.sections.items) |*moved_sect, moved_sect_id| {
5355 defer trie.deinit(self.base.allocator);4044 moved_sect.offset += @intCast(u32, seg_offset_amt);
4045 moved_sect.addr += seg_offset_amt;
4046
4047 log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{
4048 commands.segmentName(moved_sect.*),
4049 commands.sectionName(moved_sect.*),
4050 moved_sect.offset,
4051 moved_sect.offset + moved_sect.size,
4052 moved_sect.addr,
4053 moved_sect.addr + moved_sect.size,
4054 });
53564055
5357 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;4056 try self.allocateLocalSymbols(.{
5358 const base_address = text_segment.inner.vmaddr;4057 .seg = @intCast(u16, next),
4058 .sect = @intCast(u16, moved_sect_id),
4059 }, @intCast(i64, seg_offset_amt));
4060 }
4061 }
4062 }
53594063
5360 // TODO handle macho.EXPORT_SYMBOL_FLAGS_REEXPORT and macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER.4064 if (match.sect + 1 >= seg.sections.items.len) break :blk;
5361 log.debug("writing export trie", .{});4065
4066 // We have enough space to expand within the segment, so move all sections by
4067 // the required amount and update their header offsets.
4068 const next_sect = seg.sections.items[match.sect + 1];
4069 const total_size = last_sect_off - next_sect.offset;
4070 _ = try self.base.file.?.copyRangeAll(
4071 next_sect.offset,
4072 self.base.file.?,
4073 next_sect.offset + offset_amt,
4074 total_size,
4075 );
53624076
5363 for (self.globals.items) |sym| {4077 var next = match.sect + 1;
5364 const sym_name = self.getString(sym.n_strx);4078 while (next < seg.sections.items.len) : (next += 1) {
5365 log.debug(" | putting '{s}' defined at 0x{x}", .{ sym_name, sym.n_value });4079 const moved_sect = &seg.sections.items[next];
4080 moved_sect.offset += @intCast(u32, offset_amt);
4081 moved_sect.addr += offset_amt;
4082
4083 log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{
4084 commands.segmentName(moved_sect.*),
4085 commands.sectionName(moved_sect.*),
4086 moved_sect.offset,
4087 moved_sect.offset + moved_sect.size,
4088 moved_sect.addr,
4089 moved_sect.addr + moved_sect.size,
4090 });
53664091
5367 try trie.put(self.base.allocator, .{4092 try self.allocateLocalSymbols(.{
5368 .name = sym_name,4093 .seg = match.seg,
5369 .vmaddr_offset = sym.n_value - base_address,4094 .sect = next,
5370 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,4095 }, @intCast(i64, offset_amt));
5371 });4096 }
5372 }4097 }
5373 try trie.finalize(self.base.allocator);4098}
5374
5375 var buffer = try self.base.allocator.alloc(u8, @intCast(usize, trie.size));
5376 defer self.base.allocator.free(buffer);
5377 var stream = std.io.fixedBufferStream(buffer);
5378 const nwritten = try trie.write(stream.writer());
5379 assert(nwritten == trie.size);
5380
5381 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;
5382 const allocated_size = self.allocatedSizeLinkedit(dyld_info.export_off);
5383 const needed_size = mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64));
53844099
5385 if (needed_size > allocated_size) {4100fn allocatedSize(self: MachO, segment_id: u16, start: u64) u64 {
5386 dyld_info.export_off = 0;4101 const seg = self.load_commands.items[segment_id].Segment;
5387 dyld_info.export_off = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1, null));4102 assert(start >= seg.inner.fileoff);
5388 // TODO this might require relocating all following LC_DYLD_INFO_ONLY sections too.4103 var min_pos: u64 = seg.inner.fileoff + seg.inner.filesize;
4104 if (start > min_pos) return 0;
4105 for (seg.sections.items) |section| {
4106 if (section.offset <= start) continue;
4107 if (section.offset < min_pos) min_pos = section.offset;
5389 }4108 }
5390 dyld_info.export_size = @intCast(u32, needed_size);4109 return min_pos - start;
5391 log.debug("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size });
5392
5393 try self.base.file.?.pwriteAll(buffer, dyld_info.export_off);
5394 self.load_commands_dirty = true;
5395 self.export_info_dirty = false;
5396}4110}
53974111
5398fn writeRebaseInfoTable(self: *MachO) !void {4112fn getSectionMaxAlignment(self: *MachO, segment_id: u16, start_sect_id: u16) !u32 {
5399 if (!self.rebase_info_dirty) return;4113 const seg = self.load_commands.items[segment_id].Segment;
4114 var max_alignment: u32 = 1;
4115 var next = start_sect_id;
4116 while (next < seg.sections.items.len) : (next += 1) {
4117 const sect = seg.sections.items[next];
4118 const alignment = try math.powi(u32, 2, sect.@"align");
4119 max_alignment = math.max(max_alignment, alignment);
4120 }
4121 return max_alignment;
4122}
54004123
4124fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, match: MatchingSection) !u64 {
5401 const tracy = trace(@src());4125 const tracy = trace(@src());
5402 defer tracy.end();4126 defer tracy.end();
54034127
5404 var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);4128 const seg = &self.load_commands.items[match.seg].Segment;
5405 defer pointers.deinit();4129 const sect = &seg.sections.items[match.sect];
54064130 var free_list = self.atom_free_lists.get(match).?;
5407 {4131 const needs_padding = match.seg == self.text_segment_cmd_index.? and match.sect == self.text_section_index.?;
5408 var it = self.blocks.iterator();4132 const new_atom_ideal_capacity = if (needs_padding) padToIdeal(new_atom_size) else new_atom_size;
5409 while (it.next()) |entry| {
5410 const match = entry.key_ptr.*;
5411 var block: *TextBlock = entry.value_ptr.*;
5412
5413 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable
5414
5415 const seg = self.load_commands.items[match.seg].Segment;
54164133
5417 while (true) {4134 // We use these to indicate our intention to update metadata, placing the new atom,
5418 const sym = self.locals.items[block.local_sym_index];4135 // and possibly removing a free list node.
5419 const base_offset = sym.n_value - seg.inner.vmaddr;4136 // It would be simpler to do it inside the for loop below, but that would cause a
4137 // problem if an error was returned later in the function. So this action
4138 // is actually carried out at the end of the function, when errors are no longer possible.
4139 var atom_placement: ?*Atom = null;
4140 var free_list_removal: ?usize = null;
54204141
5421 for (block.rebases.items) |offset| {4142 // First we look for an appropriately sized free list node.
5422 try pointers.append(.{4143 // The list is unordered. We'll just take the first thing that works.
5423 .offset = base_offset + offset,4144 var vaddr = blk: {
5424 .segment_id = match.seg,4145 var i: usize = 0;
5425 });4146 while (i < free_list.items.len) {
4147 const big_atom = free_list.items[i];
4148 // We now have a pointer to a live atom that has too much capacity.
4149 // Is it enough that we could fit this new atom?
4150 const sym = self.locals.items[big_atom.local_sym_index];
4151 const capacity = big_atom.capacity(self.*);
4152 const ideal_capacity = if (needs_padding) padToIdeal(capacity) else capacity;
4153 const ideal_capacity_end_vaddr = sym.n_value + ideal_capacity;
4154 const capacity_end_vaddr = sym.n_value + capacity;
4155 const new_start_vaddr_unaligned = capacity_end_vaddr - new_atom_ideal_capacity;
4156 const new_start_vaddr = mem.alignBackwardGeneric(u64, new_start_vaddr_unaligned, alignment);
4157 if (new_start_vaddr < ideal_capacity_end_vaddr) {
4158 // Additional bookkeeping here to notice if this free list node
4159 // should be deleted because the atom that it points to has grown to take up
4160 // more of the extra capacity.
4161 if (!big_atom.freeListEligible(self.*)) {
4162 const bl = free_list.swapRemove(i);
4163 bl.deinit(self.base.allocator);
4164 } else {
4165 i += 1;
5426 }4166 }
4167 continue;
4168 }
4169 // At this point we know that we will place the new atom here. But the
4170 // remaining question is whether there is still yet enough capacity left
4171 // over for there to still be a free list node.
4172 const remaining_capacity = new_start_vaddr - ideal_capacity_end_vaddr;
4173 const keep_free_list_node = remaining_capacity >= min_text_capacity;
54274174
5428 if (block.prev) |prev| {4175 // Set up the metadata to be updated, after errors are no longer possible.
5429 block = prev;4176 atom_placement = big_atom;
5430 } else break;4177 if (!keep_free_list_node) {
4178 free_list_removal = i;
5431 }4179 }
4180 break :blk new_start_vaddr;
4181 } else if (self.atoms.get(match)) |last| {
4182 const last_symbol = self.locals.items[last.local_sym_index];
4183 const ideal_capacity = if (needs_padding) padToIdeal(last.size) else last.size;
4184 const ideal_capacity_end_vaddr = last_symbol.n_value + ideal_capacity;
4185 const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment);
4186 atom_placement = last;
4187 break :blk new_start_vaddr;
4188 } else {
4189 break :blk mem.alignForwardGeneric(u64, sect.addr, alignment);
5432 }4190 }
5433 }4191 };
5434
5435 if (self.got_section_index) |idx| {
5436 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
5437 const sect = seg.sections.items[idx];
5438 const base_offset = sect.addr - seg.inner.vmaddr;
5439 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);
54404192
5441 for (self.got_entries.items) |entry, i| {4193 const expand_section = atom_placement == null or atom_placement.?.next == null;
5442 if (entry.where == .undef) continue;4194 if (expand_section) {
4195 const needed_size = @intCast(u32, (vaddr + new_atom_size) - sect.addr);
4196 try self.growSection(match, needed_size);
4197 _ = try self.atoms.put(self.base.allocator, match, atom);
4198 sect.size = needed_size;
4199 self.load_commands_dirty = true;
4200 }
4201 const align_pow = @intCast(u32, math.log2(alignment));
4202 if (sect.@"align" < align_pow) {
4203 sect.@"align" = align_pow;
4204 self.load_commands_dirty = true;
4205 }
4206 atom.size = new_atom_size;
4207 atom.alignment = align_pow;
54434208
5444 try pointers.append(.{4209 if (atom.prev) |prev| {
5445 .offset = base_offset + i * @sizeOf(u64),4210 prev.next = atom.next;
5446 .segment_id = segment_id,4211 }
5447 });4212 if (atom.next) |next| {
5448 }4213 next.prev = atom.prev;
5449 }4214 }
54504215
5451 if (self.la_symbol_ptr_section_index) |idx| {4216 if (atom_placement) |big_atom| {
5452 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;4217 atom.prev = big_atom;
5453 const sect = seg.sections.items[idx];4218 atom.next = big_atom.next;
5454 const base_offset = sect.addr - seg.inner.vmaddr;4219 big_atom.next = atom;
5455 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);4220 } else {
54564221 atom.prev = null;
5457 try pointers.ensureUnusedCapacity(self.stubs.items.len);4222 atom.next = null;
5458 for (self.stubs.items) |_, i| {4223 }
5459 pointers.appendAssumeCapacity(.{4224 if (free_list_removal) |i| {
5460 .offset = base_offset + i * @sizeOf(u64),4225 _ = free_list.swapRemove(i);
5461 .segment_id = segment_id,
5462 });
5463 }
5464 }4226 }
54654227
5466 std.sort.sort(bind.Pointer, pointers.items, {}, bind.pointerCmp);4228 return vaddr;
4229}
54674230
5468 const size = try bind.rebaseInfoSize(pointers.items);4231pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
5469 var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size));4232 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
5470 defer self.base.allocator.free(buffer);4233 defer self.base.allocator.free(sym_name);
54714234
5472 var stream = std.io.fixedBufferStream(buffer);4235 if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{
5473 try bind.writeRebaseInfo(pointers.items, stream.writer());4236 .bytes = &self.strtab,
4237 })) |n_strx| {
4238 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
4239 return resolv.where_index;
4240 }
54744241
5475 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;4242 log.debug("adding new extern function '{s}'", .{sym_name});
5476 const allocated_size = self.allocatedSizeLinkedit(dyld_info.rebase_off);4243 const sym_index = @intCast(u32, self.undefs.items.len);
5477 const needed_size = mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64));4244 const n_strx = try self.makeString(sym_name);
4245 try self.undefs.append(self.base.allocator, .{
4246 .n_strx = n_strx,
4247 .n_type = macho.N_UNDF,
4248 .n_sect = 0,
4249 .n_desc = 0,
4250 .n_value = 0,
4251 });
4252 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
4253 .where = .undef,
4254 .where_index = sym_index,
4255 });
4256 try self.unresolved.putNoClobber(self.base.allocator, sym_index, .stub);
54784257
5479 if (needed_size > allocated_size) {4258 return sym_index;
5480 dyld_info.rebase_off = 0;4259}
5481 dyld_info.rebase_off = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1, null));
5482 // TODO this might require relocating all following LC_DYLD_INFO_ONLY sections too.
5483 }
54844260
5485 dyld_info.rebase_size = @intCast(u32, needed_size);4261const NextSegmentAddressAndOffset = struct {
5486 log.debug("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size });4262 address: u64,
4263 offset: u64,
4264};
54874265
5488 try self.base.file.?.pwriteAll(buffer, dyld_info.rebase_off);4266fn nextSegmentAddressAndOffset(self: *MachO) NextSegmentAddressAndOffset {
5489 self.load_commands_dirty = true;4267 var prev_segment_idx: ?usize = null; // We use optional here for safety.
5490 self.rebase_info_dirty = false;4268 for (self.load_commands.items) |cmd, i| {
4269 if (cmd == .Segment) {
4270 prev_segment_idx = i;
4271 }
4272 }
4273 const prev_segment = self.load_commands.items[prev_segment_idx.?].Segment;
4274 const address = prev_segment.inner.vmaddr + prev_segment.inner.vmsize;
4275 const offset = prev_segment.inner.fileoff + prev_segment.inner.filesize;
4276 return .{
4277 .address = address,
4278 .offset = offset,
4279 };
5491}4280}
54924281
5493fn writeBindInfoTable(self: *MachO) !void {4282fn updateSectionOrdinals(self: *MachO) !void {
5494 if (!self.binding_info_dirty) return;4283 if (!self.sections_order_dirty) return;
54954284
5496 const tracy = trace(@src());4285 const tracy = trace(@src());
5497 defer tracy.end();4286 defer tracy.end();
54984287
5499 var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);4288 var ordinal_remap = std.AutoHashMap(u8, u8).init(self.base.allocator);
5500 defer pointers.deinit();4289 defer ordinal_remap.deinit();
4290 var ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{};
55014291
5502 if (self.got_section_index) |idx| {4292 var new_ordinal: u8 = 0;
5503 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;4293 for (self.load_commands.items) |lc, lc_id| {
5504 const sect = seg.sections.items[idx];4294 if (lc != .Segment) break;
5505 const base_offset = sect.addr - seg.inner.vmaddr;
5506 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);
55074295
5508 for (self.got_entries.items) |entry, i| {4296 for (lc.Segment.sections.items) |_, sect_id| {
5509 if (entry.where == .local) continue;4297 const match = MatchingSection{
55104298 .seg = @intCast(u16, lc_id),
5511 const sym = self.undefs.items[entry.where_index];4299 .sect = @intCast(u16, sect_id),
5512 try pointers.append(.{4300 };
5513 .offset = base_offset + i * @sizeOf(u64),4301 const old_ordinal = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
5514 .segment_id = segment_id,4302 new_ordinal += 1;
5515 .dylib_ordinal = @divExact(sym.n_desc, macho.N_SYMBOL_RESOLVER),4303 try ordinal_remap.putNoClobber(old_ordinal, new_ordinal);
5516 .name = self.getString(sym.n_strx),4304 try ordinals.putNoClobber(self.base.allocator, match, {});
5517 });
5518 }4305 }
5519 }4306 }
55204307
4308 for (self.locals.items) |*sym| {
4309 if (sym.n_sect == 0) continue;
4310 sym.n_sect = ordinal_remap.get(sym.n_sect).?;
4311 }
4312 for (self.globals.items) |*sym| {
4313 sym.n_sect = ordinal_remap.get(sym.n_sect).?;
4314 }
4315
4316 self.section_ordinals.deinit(self.base.allocator);
4317 self.section_ordinals = ordinals;
4318}
4319
4320fn writeDyldInfoData(self: *MachO) !void {
4321 const tracy = trace(@src());
4322 defer tracy.end();
4323
4324 var rebase_pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);
4325 defer rebase_pointers.deinit();
4326 var bind_pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);
4327 defer bind_pointers.deinit();
4328 var lazy_bind_pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);
4329 defer lazy_bind_pointers.deinit();
4330
5521 {4331 {
5522 var it = self.blocks.iterator();4332 var it = self.atoms.iterator();
5523 while (it.next()) |entry| {4333 while (it.next()) |entry| {
5524 const match = entry.key_ptr.*;4334 const match = entry.key_ptr.*;
5525 var block: *TextBlock = entry.value_ptr.*;4335 var atom: *Atom = entry.value_ptr.*;
55264336
5527 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable4337 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable
55284338
5529 const seg = self.load_commands.items[match.seg].Segment;4339 const seg = self.load_commands.items[match.seg].Segment;
55304340
5531 while (true) {4341 while (true) {
5532 const sym = self.locals.items[block.local_sym_index];4342 const sym = self.locals.items[atom.local_sym_index];
5533 const base_offset = sym.n_value - seg.inner.vmaddr;4343 const base_offset = sym.n_value - seg.inner.vmaddr;
55344344
5535 for (block.bindings.items) |binding| {4345 for (atom.rebases.items) |offset| {
4346 try rebase_pointers.append(.{
4347 .offset = base_offset + offset,
4348 .segment_id = match.seg,
4349 });
4350 }
4351
4352 for (atom.bindings.items) |binding| {
4353 const bind_sym = self.undefs.items[binding.local_sym_index];
4354 try bind_pointers.append(.{
4355 .offset = binding.offset + base_offset,
4356 .segment_id = match.seg,
4357 .dylib_ordinal = @divExact(bind_sym.n_desc, macho.N_SYMBOL_RESOLVER),
4358 .name = self.getString(bind_sym.n_strx),
4359 });
4360 }
4361
4362 for (atom.lazy_bindings.items) |binding| {
5536 const bind_sym = self.undefs.items[binding.local_sym_index];4363 const bind_sym = self.undefs.items[binding.local_sym_index];
5537 try pointers.append(.{4364 try lazy_bind_pointers.append(.{
5538 .offset = binding.offset + base_offset,4365 .offset = binding.offset + base_offset,
5539 .segment_id = match.seg,4366 .segment_id = match.seg,
5540 .dylib_ordinal = @divExact(bind_sym.n_desc, macho.N_SYMBOL_RESOLVER),4367 .dylib_ordinal = @divExact(bind_sym.n_desc, macho.N_SYMBOL_RESOLVER),
...@@ -5542,94 +4369,105 @@ fn writeBindInfoTable(self: *MachO) !void {...@@ -5542,94 +4369,105 @@ fn writeBindInfoTable(self: *MachO) !void {
5542 });4369 });
5543 }4370 }
55444371
5545 if (block.prev) |prev| {4372 if (atom.prev) |prev| {
5546 block = prev;4373 atom = prev;
5547 } else break;4374 } else break;
5548 }4375 }
5549 }4376 }
5550 }4377 }
55514378
5552 const size = try bind.bindInfoSize(pointers.items);4379 var trie: Trie = .{};
5553 var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size));4380 defer trie.deinit(self.base.allocator);
5554 defer self.base.allocator.free(buffer);
5555
5556 var stream = std.io.fixedBufferStream(buffer);
5557 try bind.writeBindInfo(pointers.items, stream.writer());
55584381
5559 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;4382 {
5560 const allocated_size = self.allocatedSizeLinkedit(dyld_info.bind_off);4383 // TODO handle macho.EXPORT_SYMBOL_FLAGS_REEXPORT and macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER.
5561 const needed_size = mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64));4384 log.debug("generating export trie", .{});
4385 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4386 const base_address = text_segment.inner.vmaddr;
4387
4388 for (self.globals.items) |sym| {
4389 const sym_name = self.getString(sym.n_strx);
4390 log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });
4391
4392 try trie.put(self.base.allocator, .{
4393 .name = sym_name,
4394 .vmaddr_offset = sym.n_value - base_address,
4395 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
4396 });
4397 }
55624398
5563 if (needed_size > allocated_size) {4399 try trie.finalize(self.base.allocator);
5564 dyld_info.bind_off = 0;
5565 dyld_info.bind_off = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1, null));
5566 // TODO this might require relocating all following LC_DYLD_INFO_ONLY sections too.
5567 }4400 }
55684401
5569 dyld_info.bind_size = @intCast(u32, needed_size);4402 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
5570 log.debug("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size });4403 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;
55714404 const rebase_size = try bind.rebaseInfoSize(rebase_pointers.items);
5572 try self.base.file.?.pwriteAll(buffer, dyld_info.bind_off);4405 const bind_size = try bind.bindInfoSize(bind_pointers.items);
5573 self.load_commands_dirty = true;4406 const lazy_bind_size = try bind.lazyBindInfoSize(lazy_bind_pointers.items);
5574 self.binding_info_dirty = false;4407 const export_size = trie.size;
5575}
5576
5577fn writeLazyBindInfoTable(self: *MachO) !void {
5578 if (!self.lazy_binding_info_dirty) return;
55794408
5580 const tracy = trace(@src());4409 dyld_info.rebase_off = @intCast(u32, seg.inner.fileoff);
5581 defer tracy.end();4410 dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, rebase_size, @alignOf(u64)));
4411 seg.inner.filesize += dyld_info.rebase_size;
55824412
5583 var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator);4413 dyld_info.bind_off = dyld_info.rebase_off + dyld_info.rebase_size;
5584 defer pointers.deinit();4414 dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, bind_size, @alignOf(u64)));
4415 seg.inner.filesize += dyld_info.bind_size;
55854416
5586 if (self.la_symbol_ptr_section_index) |idx| {4417 dyld_info.lazy_bind_off = dyld_info.bind_off + dyld_info.bind_size;
5587 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;4418 dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, lazy_bind_size, @alignOf(u64)));
5588 const sect = seg.sections.items[idx];4419 seg.inner.filesize += dyld_info.lazy_bind_size;
5589 const base_offset = sect.addr - seg.inner.vmaddr;
5590 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);
5591
5592 try pointers.ensureUnusedCapacity(self.stubs.items.len);
5593
5594 for (self.stubs.items) |import_id, i| {
5595 const sym = self.undefs.items[import_id];
5596 pointers.appendAssumeCapacity(.{
5597 .offset = base_offset + i * @sizeOf(u64),
5598 .segment_id = segment_id,
5599 .dylib_ordinal = @divExact(sym.n_desc, macho.N_SYMBOL_RESOLVER),
5600 .name = self.getString(sym.n_strx),
5601 });
5602 }
5603 }
56044420
5605 const size = try bind.lazyBindInfoSize(pointers.items);4421 dyld_info.export_off = dyld_info.lazy_bind_off + dyld_info.lazy_bind_size;
5606 var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size));4422 dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, export_size, @alignOf(u64)));
4423 seg.inner.filesize += dyld_info.export_size;
4424
4425 const needed_size = dyld_info.rebase_size + dyld_info.bind_size + dyld_info.lazy_bind_size + dyld_info.export_size;
4426 var buffer = try self.base.allocator.alloc(u8, needed_size);
5607 defer self.base.allocator.free(buffer);4427 defer self.base.allocator.free(buffer);
4428 mem.set(u8, buffer, 0);
56084429
5609 var stream = std.io.fixedBufferStream(buffer);4430 var stream = std.io.fixedBufferStream(buffer);
5610 try bind.writeLazyBindInfo(pointers.items, stream.writer());4431 const writer = stream.writer();
56114432
5612 const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly;4433 try bind.writeRebaseInfo(rebase_pointers.items, writer);
5613 const allocated_size = self.allocatedSizeLinkedit(dyld_info.lazy_bind_off);4434 try stream.seekBy(@intCast(i64, dyld_info.rebase_size) - @intCast(i64, rebase_size));
5614 const needed_size = mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64));
56154435
5616 if (needed_size > allocated_size) {4436 try bind.writeBindInfo(bind_pointers.items, writer);
5617 dyld_info.lazy_bind_off = 0;4437 try stream.seekBy(@intCast(i64, dyld_info.bind_size) - @intCast(i64, bind_size));
5618 dyld_info.lazy_bind_off = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1, null));
5619 // TODO this might require relocating all following LC_DYLD_INFO_ONLY sections too.
5620 }
56214438
5622 dyld_info.lazy_bind_size = @intCast(u32, needed_size);4439 try bind.writeLazyBindInfo(lazy_bind_pointers.items, writer);
5623 log.debug("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size });4440 try stream.seekBy(@intCast(i64, dyld_info.lazy_bind_size) - @intCast(i64, lazy_bind_size));
56244441
5625 try self.base.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off);4442 _ = try trie.write(writer);
5626 try self.populateLazyBindOffsetsInStubHelper(buffer);4443
4444 log.debug("writing dyld info from 0x{x} to 0x{x}", .{
4445 dyld_info.rebase_off,
4446 dyld_info.rebase_off + needed_size,
4447 });
4448
4449 try self.base.file.?.pwriteAll(buffer, dyld_info.rebase_off);
4450 try self.populateLazyBindOffsetsInStubHelper(
4451 buffer[dyld_info.rebase_size + dyld_info.bind_size ..][0..dyld_info.lazy_bind_size],
4452 );
5627 self.load_commands_dirty = true;4453 self.load_commands_dirty = true;
5628 self.lazy_binding_info_dirty = false;
5629}4454}
56304455
5631fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void {4456fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void {
5632 if (self.stubs.items.len == 0) return;4457 const last_atom = self.atoms.get(.{
4458 .seg = self.text_segment_cmd_index.?,
4459 .sect = self.stub_helper_section_index.?,
4460 }) orelse return;
4461 if (last_atom == self.stub_helper_preamble_atom.?) return;
4462
4463 // Because we insert lazy binding opcodes in reverse order (from last to the first atom),
4464 // we need reverse the order of atom traversal here as well.
4465 // TODO figure out a less error prone mechanims for this!
4466 var atom = last_atom;
4467 while (atom.prev) |prev| {
4468 atom = prev;
4469 }
4470 atom = atom.next.?;
56334471
5634 var stream = std.io.fixedBufferStream(buffer);4472 var stream = std.io.fixedBufferStream(buffer);
5635 var reader = stream.reader();4473 var reader = stream.reader();
...@@ -5674,50 +4512,245 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void {...@@ -5674,50 +4512,245 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void {
5674 else => {},4512 else => {},
5675 }4513 }
5676 }4514 }
5677 assert(self.stubs.items.len <= offsets.items.len);
56784515
5679 const stub_size: u4 = switch (self.base.options.target.cpu.arch) {4516 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
5680 .x86_64 => 10,4517 const sect = seg.sections.items[self.stub_helper_section_index.?];
5681 .aarch64 => 3 * @sizeOf(u32),4518 const stub_offset: u4 = switch (self.base.options.target.cpu.arch) {
5682 else => unreachable,
5683 };
5684 const off: u4 = switch (self.base.options.target.cpu.arch) {
5685 .x86_64 => 1,4519 .x86_64 => 1,
5686 .aarch64 => 2 * @sizeOf(u32),4520 .aarch64 => 2 * @sizeOf(u32),
5687 else => unreachable,4521 else => unreachable,
5688 };4522 };
5689 var buf: [@sizeOf(u32)]u8 = undefined;4523 var buf: [@sizeOf(u32)]u8 = undefined;
5690 for (self.stubs.items) |_, index| {4524 _ = offsets.pop();
5691 const placeholder_off = self.stub_helper_stubs_start_off.? + index * stub_size + off;4525 while (offsets.popOrNull()) |bind_offset| {
5692 mem.writeIntLittle(u32, &buf, offsets.items[index]);4526 const sym = self.locals.items[atom.local_sym_index];
5693 try self.base.file.?.pwriteAll(&buf, placeholder_off);4527 const file_offset = sect.offset + sym.n_value - sect.addr + stub_offset;
4528 mem.writeIntLittle(u32, &buf, bind_offset);
4529 log.debug("writing lazy bind offset in stub helper of 0x{x} for symbol {s} at offset 0x{x}", .{
4530 bind_offset,
4531 self.getString(sym.n_strx),
4532 file_offset,
4533 });
4534 try self.base.file.?.pwriteAll(&buf, file_offset);
4535
4536 if (atom.next) |next| {
4537 atom = next;
4538 } else break;
5694 }4539 }
5695}4540}
56964541
5697fn writeStringTable(self: *MachO) !void {4542fn writeDices(self: *MachO) !void {
5698 if (!self.strtab_dirty) return;4543 if (!self.has_dices) return;
4544
4545 const tracy = trace(@src());
4546 defer tracy.end();
4547
4548 var buf = std.ArrayList(u8).init(self.base.allocator);
4549 defer buf.deinit();
4550
4551 var atom: *Atom = self.atoms.get(.{
4552 .seg = self.text_segment_cmd_index orelse return,
4553 .sect = self.text_section_index orelse return,
4554 }) orelse return;
4555
4556 while (atom.prev) |prev| {
4557 atom = prev;
4558 }
4559
4560 const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4561 const text_sect = text_seg.sections.items[self.text_section_index.?];
4562
4563 while (true) {
4564 if (atom.dices.items.len > 0) {
4565 const sym = self.locals.items[atom.local_sym_index];
4566 const base_off = try math.cast(u32, sym.n_value - text_sect.addr + text_sect.offset);
4567
4568 try buf.ensureUnusedCapacity(atom.dices.items.len * @sizeOf(macho.data_in_code_entry));
4569 for (atom.dices.items) |dice| {
4570 const rebased_dice = macho.data_in_code_entry{
4571 .offset = base_off + dice.offset,
4572 .length = dice.length,
4573 .kind = dice.kind,
4574 };
4575 buf.appendSliceAssumeCapacity(mem.asBytes(&rebased_dice));
4576 }
4577 }
4578
4579 if (atom.next) |next| {
4580 atom = next;
4581 } else break;
4582 }
4583
4584 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
4585 const dice_cmd = &self.load_commands.items[self.data_in_code_cmd_index.?].LinkeditData;
4586 const needed_size = @intCast(u32, buf.items.len);
56994587
4588 dice_cmd.dataoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
4589 dice_cmd.datasize = needed_size;
4590 seg.inner.filesize += needed_size;
4591
4592 log.debug("writing data-in-code from 0x{x} to 0x{x}", .{
4593 dice_cmd.dataoff,
4594 dice_cmd.dataoff + dice_cmd.datasize,
4595 });
4596
4597 try self.base.file.?.pwriteAll(buf.items, dice_cmd.dataoff);
4598 self.load_commands_dirty = true;
4599}
4600
4601fn writeSymbolTable(self: *MachO) !void {
5700 const tracy = trace(@src());4602 const tracy = trace(@src());
5701 defer tracy.end();4603 defer tracy.end();
57024604
4605 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
5703 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;4606 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
5704 const allocated_size = self.allocatedSizeLinkedit(symtab.stroff);4607 symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
5705 const needed_size = mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64));4608
4609 var locals = std.ArrayList(macho.nlist_64).init(self.base.allocator);
4610 defer locals.deinit();
4611 try locals.appendSlice(self.locals.items);
4612
4613 if (self.has_stabs) {
4614 for (self.objects.items) |object| {
4615 if (object.debug_info == null) continue;
4616
4617 // Open scope
4618 try locals.ensureUnusedCapacity(3);
4619 locals.appendAssumeCapacity(.{
4620 .n_strx = try self.makeString(object.tu_comp_dir.?),
4621 .n_type = macho.N_SO,
4622 .n_sect = 0,
4623 .n_desc = 0,
4624 .n_value = 0,
4625 });
4626 locals.appendAssumeCapacity(.{
4627 .n_strx = try self.makeString(object.tu_name.?),
4628 .n_type = macho.N_SO,
4629 .n_sect = 0,
4630 .n_desc = 0,
4631 .n_value = 0,
4632 });
4633 locals.appendAssumeCapacity(.{
4634 .n_strx = try self.makeString(object.name),
4635 .n_type = macho.N_OSO,
4636 .n_sect = 0,
4637 .n_desc = 1,
4638 .n_value = object.mtime orelse 0,
4639 });
4640
4641 for (object.atoms.items) |atom| {
4642 if (atom.stab) |stab| {
4643 const nlists = try stab.asNlists(atom.local_sym_index, self);
4644 defer self.base.allocator.free(nlists);
4645 try locals.appendSlice(nlists);
4646 } else {
4647 for (atom.contained.items) |sym_at_off| {
4648 const stab = sym_at_off.stab orelse continue;
4649 const nlists = try stab.asNlists(sym_at_off.local_sym_index, self);
4650 defer self.base.allocator.free(nlists);
4651 try locals.appendSlice(nlists);
4652 }
4653 }
4654 }
57064655
5707 if (needed_size > allocated_size or self.strtab_needs_relocation) {4656 // Close scope
5708 symtab.strsize = 0;4657 try locals.append(.{
5709 symtab.stroff = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1, symtab.symoff));4658 .n_strx = 0,
5710 self.strtab_needs_relocation = false;4659 .n_type = macho.N_SO,
4660 .n_sect = 0,
4661 .n_desc = 0,
4662 .n_value = 0,
4663 });
4664 }
5711 }4665 }
5712 symtab.strsize = @intCast(u32, needed_size);
5713 log.debug("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize });
57144666
5715 try self.base.file.?.pwriteAll(self.strtab.items, symtab.stroff);4667 const nlocals = locals.items.len;
4668 const nexports = self.globals.items.len;
4669 const nundefs = self.undefs.items.len;
4670
4671 const locals_off = symtab.symoff;
4672 const locals_size = nlocals * @sizeOf(macho.nlist_64);
4673 log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off });
4674 try self.base.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off);
4675
4676 const exports_off = locals_off + locals_size;
4677 const exports_size = nexports * @sizeOf(macho.nlist_64);
4678 log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off });
4679 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.globals.items), exports_off);
4680
4681 const undefs_off = exports_off + exports_size;
4682 const undefs_size = nundefs * @sizeOf(macho.nlist_64);
4683 log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off });
4684 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off);
4685
4686 symtab.nsyms = @intCast(u32, nlocals + nexports + nundefs);
4687 seg.inner.filesize += locals_size + exports_size + undefs_size;
4688
4689 // Update dynamic symbol table.
4690 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
4691 dysymtab.nlocalsym = @intCast(u32, nlocals);
4692 dysymtab.iextdefsym = dysymtab.nlocalsym;
4693 dysymtab.nextdefsym = @intCast(u32, nexports);
4694 dysymtab.iundefsym = dysymtab.nlocalsym + dysymtab.nextdefsym;
4695 dysymtab.nundefsym = @intCast(u32, nundefs);
4696
4697 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4698 const stubs = &text_segment.sections.items[self.stubs_section_index.?];
4699 const data_const_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
4700 const got = &data_const_segment.sections.items[self.got_section_index.?];
4701 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4702 const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?];
4703
4704 const nstubs = @intCast(u32, self.stubs_map.keys().len);
4705 const ngot_entries = @intCast(u32, self.got_entries_map.keys().len);
4706
4707 dysymtab.indirectsymoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
4708 dysymtab.nindirectsyms = nstubs * 2 + ngot_entries;
4709
4710 const needed_size = dysymtab.nindirectsyms * @sizeOf(u32);
4711 seg.inner.filesize += needed_size;
4712
4713 log.debug("writing indirect symbol table from 0x{x} to 0x{x}", .{
4714 dysymtab.indirectsymoff,
4715 dysymtab.indirectsymoff + needed_size,
4716 });
4717
4718 var buf = try self.base.allocator.alloc(u8, needed_size);
4719 defer self.base.allocator.free(buf);
4720
4721 var stream = std.io.fixedBufferStream(buf);
4722 var writer = stream.writer();
4723
4724 stubs.reserved1 = 0;
4725 for (self.stubs_map.keys()) |key| {
4726 try writer.writeIntLittle(u32, dysymtab.iundefsym + key);
4727 }
4728
4729 got.reserved1 = nstubs;
4730 for (self.got_entries_map.keys()) |key| {
4731 switch (key.where) {
4732 .undef => {
4733 try writer.writeIntLittle(u32, dysymtab.iundefsym + key.where_index);
4734 },
4735 .local => {
4736 try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL);
4737 },
4738 }
4739 }
4740
4741 la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries;
4742 for (self.stubs_map.keys()) |key| {
4743 try writer.writeIntLittle(u32, dysymtab.iundefsym + key);
4744 }
4745
4746 try self.base.file.?.pwriteAll(buf, dysymtab.indirectsymoff);
5716 self.load_commands_dirty = true;4747 self.load_commands_dirty = true;
5717 self.strtab_dirty = false;
5718}4748}
57194749
5720fn writeStringTableZld(self: *MachO) !void {4750fn writeStringTable(self: *MachO) !void {
4751 const tracy = trace(@src());
4752 defer tracy.end();
4753
5721 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;4754 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
5722 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;4755 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
5723 symtab.stroff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);4756 symtab.stroff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
...@@ -5732,55 +4765,81 @@ fn writeStringTableZld(self: *MachO) !void {...@@ -5732,55 +4765,81 @@ fn writeStringTableZld(self: *MachO) !void {
5732 // This is potentially the last section, so we need to pad it out.4765 // This is potentially the last section, so we need to pad it out.
5733 try self.base.file.?.pwriteAll(&[_]u8{0}, seg.inner.fileoff + seg.inner.filesize - 1);4766 try self.base.file.?.pwriteAll(&[_]u8{0}, seg.inner.fileoff + seg.inner.filesize - 1);
5734 }4767 }
4768 self.load_commands_dirty = true;
5735}4769}
57364770
5737fn updateLinkeditSegmentSizes(self: *MachO) !void {4771fn writeLinkeditSegment(self: *MachO) !void {
5738 if (!self.load_commands_dirty) return;4772 const tracy = trace(@src());
4773 defer tracy.end();
4774
4775 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
4776 seg.inner.filesize = 0;
4777
4778 try self.writeDyldInfoData();
4779 try self.writeDices();
4780 try self.writeSymbolTable();
4781 try self.writeStringTable();
4782
4783 seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size);
4784}
57394785
4786fn writeCodeSignaturePadding(self: *MachO) !void {
5740 const tracy = trace(@src());4787 const tracy = trace(@src());
5741 defer tracy.end();4788 defer tracy.end();
57424789
5743 // Now, we are in position to update __LINKEDIT segment sizes.
5744 // TODO Add checkpointing so that we don't have to do this every single time.
5745 const linkedit_segment = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;4790 const linkedit_segment = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
5746 var final_offset = linkedit_segment.inner.fileoff;4791 const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData;
57474792 const fileoff = linkedit_segment.inner.fileoff + linkedit_segment.inner.filesize;
5748 if (self.dyld_info_cmd_index) |idx| {4793 const needed_size = CodeSignature.calcCodeSignaturePaddingSize(
5749 const dyld_info = self.load_commands.items[idx].DyldInfoOnly;4794 self.base.options.emit.?.sub_path,
5750 final_offset = std.math.max(final_offset, dyld_info.rebase_off + dyld_info.rebase_size);4795 fileoff,
5751 final_offset = std.math.max(final_offset, dyld_info.bind_off + dyld_info.bind_size);4796 self.page_size,
5752 final_offset = std.math.max(final_offset, dyld_info.weak_bind_off + dyld_info.weak_bind_size);4797 );
5753 final_offset = std.math.max(final_offset, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size);4798 code_sig_cmd.dataoff = @intCast(u32, fileoff);
5754 final_offset = std.math.max(final_offset, dyld_info.export_off + dyld_info.export_size);4799 code_sig_cmd.datasize = needed_size;
5755 }4800
5756 if (self.function_starts_cmd_index) |idx| {4801 // Advance size of __LINKEDIT segment
5757 const fstart = self.load_commands.items[idx].LinkeditData;4802 linkedit_segment.inner.filesize += needed_size;
5758 final_offset = std.math.max(final_offset, fstart.dataoff + fstart.datasize);4803 if (linkedit_segment.inner.vmsize < linkedit_segment.inner.filesize) {
5759 }4804 linkedit_segment.inner.vmsize = mem.alignForwardGeneric(u64, linkedit_segment.inner.filesize, self.page_size);
5760 if (self.data_in_code_cmd_index) |idx| {4805 }
5761 const dic = self.load_commands.items[idx].LinkeditData;4806 log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size });
5762 final_offset = std.math.max(final_offset, dic.dataoff + dic.datasize);4807 // Pad out the space. We need to do this to calculate valid hashes for everything in the file
5763 }4808 // except for code signature data.
5764 if (self.dysymtab_cmd_index) |idx| {4809 try self.base.file.?.pwriteAll(&[_]u8{0}, fileoff + needed_size - 1);
5765 const dysymtab = self.load_commands.items[idx].Dysymtab;
5766 const nindirectsize = dysymtab.nindirectsyms * @sizeOf(u32);
5767 final_offset = std.math.max(final_offset, dysymtab.indirectsymoff + nindirectsize);
5768 // TODO Handle more dynamic symbol table sections.
5769 }
5770 if (self.symtab_cmd_index) |idx| {
5771 const symtab = self.load_commands.items[idx].Symtab;
5772 const symsize = symtab.nsyms * @sizeOf(macho.nlist_64);
5773 final_offset = std.math.max(final_offset, symtab.symoff + symsize);
5774 final_offset = std.math.max(final_offset, symtab.stroff + symtab.strsize);
5775 }
5776
5777 const filesize = final_offset - linkedit_segment.inner.fileoff;
5778 linkedit_segment.inner.filesize = filesize;
5779 linkedit_segment.inner.vmsize = mem.alignForwardGeneric(u64, filesize, self.page_size);
5780 try self.base.file.?.pwriteAll(&[_]u8{0}, final_offset);
5781 self.load_commands_dirty = true;4810 self.load_commands_dirty = true;
5782}4811}
57834812
4813fn writeCodeSignature(self: *MachO) !void {
4814 const tracy = trace(@src());
4815 defer tracy.end();
4816
4817 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4818 const code_sig_cmd = self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData;
4819
4820 var code_sig: CodeSignature = .{};
4821 defer code_sig.deinit(self.base.allocator);
4822
4823 try code_sig.calcAdhocSignature(
4824 self.base.allocator,
4825 self.base.file.?,
4826 self.base.options.emit.?.sub_path,
4827 text_segment.inner,
4828 code_sig_cmd,
4829 self.base.options.output_mode,
4830 self.page_size,
4831 );
4832
4833 var buffer = try self.base.allocator.alloc(u8, code_sig.size());
4834 defer self.base.allocator.free(buffer);
4835 var stream = std.io.fixedBufferStream(buffer);
4836 try code_sig.write(stream.writer());
4837
4838 log.debug("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len });
4839
4840 try self.base.file.?.pwriteAll(buffer, code_sig_cmd.dataoff);
4841}
4842
5784/// Writes all load commands and section headers.4843/// Writes all load commands and section headers.
5785fn writeLoadCommands(self: *MachO) !void {4844fn writeLoadCommands(self: *MachO) !void {
5786 if (!self.load_commands_dirty) return;4845 if (!self.load_commands_dirty) return;
...@@ -5857,11 +4916,18 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {...@@ -5857,11 +4916,18 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
5857 std.math.maxInt(@TypeOf(actual_size));4916 std.math.maxInt(@TypeOf(actual_size));
5858}4917}
58594918
4919pub fn makeStaticString(bytes: []const u8) [16]u8 {
4920 var buf = [_]u8{0} ** 16;
4921 assert(bytes.len <= buf.len);
4922 mem.copy(u8, &buf, bytes);
4923 return buf;
4924}
4925
5860pub fn makeString(self: *MachO, string: []const u8) !u32 {4926pub fn makeString(self: *MachO, string: []const u8) !u32 {
5861 const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringSliceAdapter{4927 const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringIndexAdapter{
5862 .strtab = &self.strtab,4928 .bytes = &self.strtab,
5863 }, StringIndexContext{4929 }, StringIndexContext{
5864 .strtab = &self.strtab,4930 .bytes = &self.strtab,
5865 });4931 });
5866 if (gop.found_existing) {4932 if (gop.found_existing) {
5867 const off = gop.key_ptr.*;4933 const off = gop.key_ptr.*;
src/link/MachO/Atom.zig created+1324
...@@ -0,0 +1,1324 @@
1const Atom = @This();
2
3const std = @import("std");
4const build_options = @import("build_options");
5const aarch64 = @import("../../codegen/aarch64.zig");
6const assert = std.debug.assert;
7const commands = @import("commands.zig");
8const log = std.log.scoped(.text_block);
9const macho = std.macho;
10const math = std.math;
11const mem = std.mem;
12const meta = std.meta;
13const trace = @import("../../tracy.zig").trace;
14
15const Allocator = mem.Allocator;
16const Arch = std.Target.Cpu.Arch;
17const MachO = @import("../MachO.zig");
18const Object = @import("Object.zig");
19const StringIndexAdapter = std.hash_map.StringIndexAdapter;
20
21/// Each decl always gets a local symbol with the fully qualified name.
22/// The vaddr and size are found here directly.
23/// The file offset is found by computing the vaddr offset from the section vaddr
24/// the symbol references, and adding that to the file offset of the section.
25/// If this field is 0, it means the codegen size = 0 and there is no symbol or
26/// offset table entry.
27local_sym_index: u32,
28
29/// List of symbol aliases pointing to the same atom via different nlists
30aliases: std.ArrayListUnmanaged(u32) = .{},
31
32/// List of symbols contained within this atom
33contained: std.ArrayListUnmanaged(SymbolAtOffset) = .{},
34
35/// Code (may be non-relocated) this atom represents
36code: std.ArrayListUnmanaged(u8) = .{},
37
38/// Size and alignment of this atom
39/// Unlike in Elf, we need to store the size of this symbol as part of
40/// the atom since macho.nlist_64 lacks this information.
41size: u64,
42
43/// Alignment of this atom as a power of 2.
44/// For instance, aligmment of 0 should be read as 2^0 = 1 byte aligned.
45alignment: u32,
46
47/// List of relocations belonging to this atom.
48relocs: std.ArrayListUnmanaged(Relocation) = .{},
49
50/// List of offsets contained within this atom that need rebasing by the dynamic
51/// loader in presence of ASLR.
52rebases: std.ArrayListUnmanaged(u64) = .{},
53
54/// List of offsets contained within this atom that will be dynamically bound
55/// by the dynamic loader and contain pointers to resolved (at load time) extern
56/// symbols (aka proxies aka imports)
57bindings: std.ArrayListUnmanaged(SymbolAtOffset) = .{},
58
59/// List of lazy bindings
60lazy_bindings: std.ArrayListUnmanaged(SymbolAtOffset) = .{},
61
62/// List of data-in-code entries. This is currently specific to x86_64 only.
63dices: std.ArrayListUnmanaged(macho.data_in_code_entry) = .{},
64
65/// Stab entry for this atom. This is currently specific to a binary created
66/// by linking object files in a traditional sense - in incremental sense, we
67/// bypass stabs altogether to produce dSYM bundle directly with fully relocated
68/// DWARF sections.
69stab: ?Stab = null,
70
71/// Points to the previous and next neighbours
72next: ?*Atom,
73prev: ?*Atom,
74
75/// Previous/next linked list pointers.
76/// This is the linked list node for this Decl's corresponding .debug_info tag.
77dbg_info_prev: ?*Atom,
78dbg_info_next: ?*Atom,
79/// Offset into .debug_info pointing to the tag for this Decl.
80dbg_info_off: u32,
81/// Size of the .debug_info tag for this Decl, not including padding.
82dbg_info_len: u32,
83
84dirty: bool = true,
85
86pub const SymbolAtOffset = struct {
87 local_sym_index: u32,
88 offset: u64,
89 stab: ?Stab = null,
90
91 pub fn format(
92 self: SymbolAtOffset,
93 comptime fmt: []const u8,
94 options: std.fmt.FormatOptions,
95 writer: anytype,
96 ) !void {
97 _ = fmt;
98 _ = options;
99 try std.fmt.format(writer, "{{ {d}: .offset = {d}", .{ self.local_sym_index, self.offset });
100 if (self.stab) |stab| {
101 try std.fmt.format(writer, ", .stab = {any}", .{stab});
102 }
103 try std.fmt.format(writer, " }}", .{});
104 }
105};
106
107pub const Stab = union(enum) {
108 function: u64,
109 static,
110 global,
111
112 pub fn asNlists(stab: Stab, local_sym_index: u32, macho_file: anytype) ![]macho.nlist_64 {
113 var nlists = std.ArrayList(macho.nlist_64).init(macho_file.base.allocator);
114 defer nlists.deinit();
115
116 const sym = macho_file.locals.items[local_sym_index];
117 switch (stab) {
118 .function => |size| {
119 try nlists.ensureUnusedCapacity(4);
120 nlists.appendAssumeCapacity(.{
121 .n_strx = 0,
122 .n_type = macho.N_BNSYM,
123 .n_sect = sym.n_sect,
124 .n_desc = 0,
125 .n_value = sym.n_value,
126 });
127 nlists.appendAssumeCapacity(.{
128 .n_strx = sym.n_strx,
129 .n_type = macho.N_FUN,
130 .n_sect = sym.n_sect,
131 .n_desc = 0,
132 .n_value = sym.n_value,
133 });
134 nlists.appendAssumeCapacity(.{
135 .n_strx = 0,
136 .n_type = macho.N_FUN,
137 .n_sect = 0,
138 .n_desc = 0,
139 .n_value = size,
140 });
141 nlists.appendAssumeCapacity(.{
142 .n_strx = 0,
143 .n_type = macho.N_ENSYM,
144 .n_sect = sym.n_sect,
145 .n_desc = 0,
146 .n_value = size,
147 });
148 },
149 .global => {
150 try nlists.append(.{
151 .n_strx = sym.n_strx,
152 .n_type = macho.N_GSYM,
153 .n_sect = 0,
154 .n_desc = 0,
155 .n_value = 0,
156 });
157 },
158 .static => {
159 try nlists.append(.{
160 .n_strx = sym.n_strx,
161 .n_type = macho.N_STSYM,
162 .n_sect = sym.n_sect,
163 .n_desc = 0,
164 .n_value = sym.n_value,
165 });
166 },
167 }
168
169 return nlists.toOwnedSlice();
170 }
171};
172
173pub const Relocation = struct {
174 /// Offset within the atom's code buffer.
175 /// Note relocation size can be inferred by relocation's kind.
176 offset: u32,
177
178 where: enum {
179 local,
180 undef,
181 },
182
183 where_index: u32,
184
185 payload: union(enum) {
186 unsigned: Unsigned,
187 branch: Branch,
188 page: Page,
189 page_off: PageOff,
190 pointer_to_got: PointerToGot,
191 signed: Signed,
192 load: Load,
193 },
194
195 const ResolveArgs = struct {
196 block: *Atom,
197 offset: u32,
198 source_addr: u64,
199 target_addr: u64,
200 macho_file: *MachO,
201 };
202
203 pub const Unsigned = struct {
204 subtractor: ?u32,
205
206 /// Addend embedded directly in the relocation slot
207 addend: i64,
208
209 /// Extracted from r_length:
210 /// => 3 implies true
211 /// => 2 implies false
212 /// => * is unreachable
213 is_64bit: bool,
214
215 pub fn resolve(self: Unsigned, args: ResolveArgs) !void {
216 const result = blk: {
217 if (self.subtractor) |subtractor| {
218 const sym = args.macho_file.locals.items[subtractor];
219 break :blk @intCast(i64, args.target_addr) - @intCast(i64, sym.n_value) + self.addend;
220 } else {
221 break :blk @intCast(i64, args.target_addr) + self.addend;
222 }
223 };
224
225 if (self.is_64bit) {
226 mem.writeIntLittle(u64, args.block.code.items[args.offset..][0..8], @bitCast(u64, result));
227 } else {
228 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @truncate(u32, @bitCast(u64, result)));
229 }
230 }
231
232 pub fn format(self: Unsigned, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
233 _ = fmt;
234 _ = options;
235 try std.fmt.format(writer, "Unsigned {{ ", .{});
236 if (self.subtractor) |sub| {
237 try std.fmt.format(writer, ".subtractor = {}, ", .{sub});
238 }
239 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
240 const length: usize = if (self.is_64bit) 8 else 4;
241 try std.fmt.format(writer, ".length = {}, ", .{length});
242 try std.fmt.format(writer, "}}", .{});
243 }
244 };
245
246 pub const Branch = struct {
247 arch: Arch,
248
249 pub fn resolve(self: Branch, args: ResolveArgs) !void {
250 switch (self.arch) {
251 .aarch64 => {
252 const displacement = math.cast(
253 i28,
254 @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr),
255 ) catch |err| switch (err) {
256 error.Overflow => {
257 log.err("jump too big to encode as i28 displacement value", .{});
258 log.err(" (target - source) = displacement => 0x{x} - 0x{x} = 0x{x}", .{
259 args.target_addr,
260 args.source_addr,
261 @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr),
262 });
263 log.err(" TODO implement branch islands to extend jump distance for arm64", .{});
264 return error.TODOImplementBranchIslands;
265 },
266 };
267 const code = args.block.code.items[args.offset..][0..4];
268 var inst = aarch64.Instruction{
269 .unconditional_branch_immediate = mem.bytesToValue(meta.TagPayload(
270 aarch64.Instruction,
271 aarch64.Instruction.unconditional_branch_immediate,
272 ), code),
273 };
274 inst.unconditional_branch_immediate.imm26 = @truncate(u26, @bitCast(u28, displacement >> 2));
275 mem.writeIntLittle(u32, code, inst.toU32());
276 },
277 .x86_64 => {
278 const displacement = try math.cast(
279 i32,
280 @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr) - 4,
281 );
282 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @bitCast(u32, displacement));
283 },
284 else => return error.UnsupportedCpuArchitecture,
285 }
286 }
287
288 pub fn format(self: Branch, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
289 _ = self;
290 _ = fmt;
291 _ = options;
292 try std.fmt.format(writer, "Branch {{}}", .{});
293 }
294 };
295
296 pub const Page = struct {
297 kind: enum {
298 page,
299 got,
300 tlvp,
301 },
302 addend: u32 = 0,
303
304 pub fn resolve(self: Page, args: ResolveArgs) !void {
305 const target_addr = args.target_addr + self.addend;
306 const source_page = @intCast(i32, args.source_addr >> 12);
307 const target_page = @intCast(i32, target_addr >> 12);
308 const pages = @bitCast(u21, @intCast(i21, target_page - source_page));
309
310 const code = args.block.code.items[args.offset..][0..4];
311 var inst = aarch64.Instruction{
312 .pc_relative_address = mem.bytesToValue(meta.TagPayload(
313 aarch64.Instruction,
314 aarch64.Instruction.pc_relative_address,
315 ), code),
316 };
317 inst.pc_relative_address.immhi = @truncate(u19, pages >> 2);
318 inst.pc_relative_address.immlo = @truncate(u2, pages);
319
320 mem.writeIntLittle(u32, code, inst.toU32());
321 }
322
323 pub fn format(self: Page, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
324 _ = fmt;
325 _ = options;
326 try std.fmt.format(writer, "Page {{ ", .{});
327 switch (self.kind) {
328 .page => {},
329 .got => {
330 try std.fmt.format(writer, ".got, ", .{});
331 },
332 .tlvp => {
333 try std.fmt.format(writer, ".tlvp", .{});
334 },
335 }
336 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
337 try std.fmt.format(writer, "}}", .{});
338 }
339 };
340
341 pub const PageOff = struct {
342 kind: enum {
343 page,
344 got,
345 tlvp,
346 },
347 addend: u32 = 0,
348 op_kind: ?OpKind = null,
349
350 pub const OpKind = enum {
351 arithmetic,
352 load,
353 };
354
355 pub fn resolve(self: PageOff, args: ResolveArgs) !void {
356 const code = args.block.code.items[args.offset..][0..4];
357
358 switch (self.kind) {
359 .page => {
360 const target_addr = args.target_addr + self.addend;
361 const narrowed = @truncate(u12, target_addr);
362
363 const op_kind = self.op_kind orelse unreachable;
364 var inst: aarch64.Instruction = blk: {
365 switch (op_kind) {
366 .arithmetic => {
367 break :blk .{
368 .add_subtract_immediate = mem.bytesToValue(meta.TagPayload(
369 aarch64.Instruction,
370 aarch64.Instruction.add_subtract_immediate,
371 ), code),
372 };
373 },
374 .load => {
375 break :blk .{
376 .load_store_register = mem.bytesToValue(meta.TagPayload(
377 aarch64.Instruction,
378 aarch64.Instruction.load_store_register,
379 ), code),
380 };
381 },
382 }
383 };
384
385 if (op_kind == .arithmetic) {
386 inst.add_subtract_immediate.imm12 = narrowed;
387 } else {
388 const offset: u12 = blk: {
389 if (inst.load_store_register.size == 0) {
390 if (inst.load_store_register.v == 1) {
391 // 128-bit SIMD is scaled by 16.
392 break :blk try math.divExact(u12, narrowed, 16);
393 }
394 // Otherwise, 8-bit SIMD or ldrb.
395 break :blk narrowed;
396 } else {
397 const denom: u4 = try math.powi(u4, 2, inst.load_store_register.size);
398 break :blk try math.divExact(u12, narrowed, denom);
399 }
400 };
401 inst.load_store_register.offset = offset;
402 }
403
404 mem.writeIntLittle(u32, code, inst.toU32());
405 },
406 .got => {
407 const narrowed = @truncate(u12, args.target_addr);
408 var inst: aarch64.Instruction = .{
409 .load_store_register = mem.bytesToValue(meta.TagPayload(
410 aarch64.Instruction,
411 aarch64.Instruction.load_store_register,
412 ), code),
413 };
414 const offset = try math.divExact(u12, narrowed, 8);
415 inst.load_store_register.offset = offset;
416 mem.writeIntLittle(u32, code, inst.toU32());
417 },
418 .tlvp => {
419 const RegInfo = struct {
420 rd: u5,
421 rn: u5,
422 size: u1,
423 };
424 const reg_info: RegInfo = blk: {
425 if (isArithmeticOp(code)) {
426 const inst = mem.bytesToValue(meta.TagPayload(
427 aarch64.Instruction,
428 aarch64.Instruction.add_subtract_immediate,
429 ), code);
430 break :blk .{
431 .rd = inst.rd,
432 .rn = inst.rn,
433 .size = inst.sf,
434 };
435 } else {
436 const inst = mem.bytesToValue(meta.TagPayload(
437 aarch64.Instruction,
438 aarch64.Instruction.load_store_register,
439 ), code);
440 break :blk .{
441 .rd = inst.rt,
442 .rn = inst.rn,
443 .size = @truncate(u1, inst.size),
444 };
445 }
446 };
447 const narrowed = @truncate(u12, args.target_addr);
448 var inst = aarch64.Instruction{
449 .add_subtract_immediate = .{
450 .rd = reg_info.rd,
451 .rn = reg_info.rn,
452 .imm12 = narrowed,
453 .sh = 0,
454 .s = 0,
455 .op = 0,
456 .sf = reg_info.size,
457 },
458 };
459 mem.writeIntLittle(u32, code, inst.toU32());
460 },
461 }
462 }
463
464 pub fn format(self: PageOff, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
465 _ = fmt;
466 _ = options;
467 try std.fmt.format(writer, "PageOff {{ ", .{});
468 switch (self.kind) {
469 .page => {},
470 .got => {
471 try std.fmt.format(writer, ".got, ", .{});
472 },
473 .tlvp => {
474 try std.fmt.format(writer, ".tlvp, ", .{});
475 },
476 }
477 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
478 try std.fmt.format(writer, ".op_kind = {s}, ", .{self.op_kind});
479 try std.fmt.format(writer, "}}", .{});
480 }
481 };
482
483 pub const PointerToGot = struct {
484 pub fn resolve(_: PointerToGot, args: ResolveArgs) !void {
485 const result = try math.cast(i32, @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr));
486 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @bitCast(u32, result));
487 }
488
489 pub fn format(self: PointerToGot, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
490 _ = self;
491 _ = fmt;
492 _ = options;
493 try std.fmt.format(writer, "PointerToGot {{}}", .{});
494 }
495 };
496
497 pub const Signed = struct {
498 addend: i64,
499 correction: u3,
500
501 pub fn resolve(self: Signed, args: ResolveArgs) !void {
502 const target_addr = @intCast(i64, args.target_addr) + self.addend;
503 const displacement = try math.cast(
504 i32,
505 target_addr - @intCast(i64, args.source_addr + self.correction + 4),
506 );
507 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @bitCast(u32, displacement));
508 }
509
510 pub fn format(self: Signed, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
511 _ = fmt;
512 _ = options;
513 try std.fmt.format(writer, "Signed {{ ", .{});
514 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
515 try std.fmt.format(writer, ".correction = {}, ", .{self.correction});
516 try std.fmt.format(writer, "}}", .{});
517 }
518 };
519
520 pub const Load = struct {
521 kind: enum {
522 got,
523 tlvp,
524 },
525 addend: i32 = 0,
526
527 pub fn resolve(self: Load, args: ResolveArgs) !void {
528 if (self.kind == .tlvp) {
529 // We need to rewrite the opcode from movq to leaq.
530 args.block.code.items[args.offset - 2] = 0x8d;
531 }
532 const displacement = try math.cast(
533 i32,
534 @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr) - 4 + self.addend,
535 );
536 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @bitCast(u32, displacement));
537 }
538
539 pub fn format(self: Load, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
540 _ = fmt;
541 _ = options;
542 try std.fmt.format(writer, "Load {{ ", .{});
543 try std.fmt.format(writer, "{s}, ", .{self.kind});
544 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
545 try std.fmt.format(writer, "}}", .{});
546 }
547 };
548
549 pub fn resolve(self: Relocation, args: ResolveArgs) !void {
550 switch (self.payload) {
551 .unsigned => |unsigned| try unsigned.resolve(args),
552 .branch => |branch| try branch.resolve(args),
553 .page => |page| try page.resolve(args),
554 .page_off => |page_off| try page_off.resolve(args),
555 .pointer_to_got => |pointer_to_got| try pointer_to_got.resolve(args),
556 .signed => |signed| try signed.resolve(args),
557 .load => |load| try load.resolve(args),
558 }
559 }
560
561 pub fn format(self: Relocation, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
562 try std.fmt.format(writer, "Relocation {{ ", .{});
563 try std.fmt.format(writer, ".offset = {}, ", .{self.offset});
564 try std.fmt.format(writer, ".where = {}, ", .{self.where});
565 try std.fmt.format(writer, ".where_index = {d}, ", .{self.where_index});
566
567 switch (self.payload) {
568 .unsigned => |unsigned| try unsigned.format(fmt, options, writer),
569 .branch => |branch| try branch.format(fmt, options, writer),
570 .page => |page| try page.format(fmt, options, writer),
571 .page_off => |page_off| try page_off.format(fmt, options, writer),
572 .pointer_to_got => |pointer_to_got| try pointer_to_got.format(fmt, options, writer),
573 .signed => |signed| try signed.format(fmt, options, writer),
574 .load => |load| try load.format(fmt, options, writer),
575 }
576
577 try std.fmt.format(writer, "}}", .{});
578 }
579};
580
581pub const empty = Atom{
582 .local_sym_index = 0,
583 .size = 0,
584 .alignment = 0,
585 .prev = null,
586 .next = null,
587 .dbg_info_prev = null,
588 .dbg_info_next = null,
589 .dbg_info_off = undefined,
590 .dbg_info_len = undefined,
591};
592
593pub fn deinit(self: *Atom, allocator: *Allocator) void {
594 self.dices.deinit(allocator);
595 self.lazy_bindings.deinit(allocator);
596 self.bindings.deinit(allocator);
597 self.rebases.deinit(allocator);
598 self.relocs.deinit(allocator);
599 self.contained.deinit(allocator);
600 self.aliases.deinit(allocator);
601 self.code.deinit(allocator);
602}
603
604pub fn clearRetainingCapacity(self: *Atom) void {
605 self.dices.clearRetainingCapacity();
606 self.lazy_bindings.clearRetainingCapacity();
607 self.bindings.clearRetainingCapacity();
608 self.rebases.clearRetainingCapacity();
609 self.relocs.clearRetainingCapacity();
610 self.contained.clearRetainingCapacity();
611 self.aliases.clearRetainingCapacity();
612 self.code.clearRetainingCapacity();
613}
614
615/// Returns how much room there is to grow in virtual address space.
616/// File offset relocation happens transparently, so it is not included in
617/// this calculation.
618pub fn capacity(self: Atom, macho_file: MachO) u64 {
619 const self_sym = macho_file.locals.items[self.local_sym_index];
620 if (self.next) |next| {
621 const next_sym = macho_file.locals.items[next.local_sym_index];
622 return next_sym.n_value - self_sym.n_value;
623 } else {
624 // We are the last atom.
625 // The capacity is limited only by virtual address space.
626 return std.math.maxInt(u64) - self_sym.n_value;
627 }
628}
629
630pub fn freeListEligible(self: Atom, macho_file: MachO) bool {
631 // No need to keep a free list node for the last atom.
632 const next = self.next orelse return false;
633 const self_sym = macho_file.locals.items[self.local_sym_index];
634 const next_sym = macho_file.locals.items[next.local_sym_index];
635 const cap = next_sym.n_value - self_sym.n_value;
636 const ideal_cap = MachO.padToIdeal(self.size);
637 if (cap <= ideal_cap) return false;
638 const surplus = cap - ideal_cap;
639 return surplus >= MachO.min_text_capacity;
640}
641
642const RelocContext = struct {
643 base_addr: u64 = 0,
644 base_offset: u64 = 0,
645 allocator: *Allocator,
646 object: *Object,
647 macho_file: *MachO,
648 parsed_atoms: *Object.ParsedAtoms,
649};
650
651fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Relocation {
652 var parsed_rel = Relocation{
653 .offset = @intCast(u32, @intCast(u64, rel.r_address) - context.base_offset),
654 .where = undefined,
655 .where_index = undefined,
656 .payload = undefined,
657 };
658
659 if (rel.r_extern == 0) {
660 const sect_id = @intCast(u16, rel.r_symbolnum - 1);
661
662 const local_sym_index = context.object.sections_as_symbols.get(sect_id) orelse blk: {
663 const seg = context.object.load_commands.items[context.object.segment_cmd_index.?].Segment;
664 const sect = seg.sections.items[sect_id];
665 const match = (try context.macho_file.getMatchingSection(sect)) orelse unreachable;
666 const local_sym_index = @intCast(u32, context.macho_file.locals.items.len);
667 const sym_name = try std.fmt.allocPrint(context.allocator, "l_{s}_{s}_{s}", .{
668 context.object.name,
669 commands.segmentName(sect),
670 commands.sectionName(sect),
671 });
672 defer context.allocator.free(sym_name);
673
674 try context.macho_file.locals.append(context.allocator, .{
675 .n_strx = try context.macho_file.makeString(sym_name),
676 .n_type = macho.N_SECT,
677 .n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(match).? + 1),
678 .n_desc = 0,
679 .n_value = 0,
680 });
681 try context.object.sections_as_symbols.putNoClobber(context.allocator, sect_id, local_sym_index);
682 break :blk local_sym_index;
683 };
684
685 parsed_rel.where = .local;
686 parsed_rel.where_index = local_sym_index;
687 } else {
688 const sym = context.object.symtab.items[rel.r_symbolnum];
689 const sym_name = context.object.getString(sym.n_strx);
690
691 if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
692 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
693 parsed_rel.where = .local;
694 parsed_rel.where_index = where_index;
695 } else {
696 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{
697 .bytes = &context.macho_file.strtab,
698 }) orelse unreachable;
699 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
700 switch (resolv.where) {
701 .global => {
702 parsed_rel.where = .local;
703 parsed_rel.where_index = resolv.local_sym_index;
704 },
705 .undef => {
706 parsed_rel.where = .undef;
707 parsed_rel.where_index = resolv.where_index;
708 },
709 }
710 }
711 }
712
713 return parsed_rel;
714}
715
716pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocContext) !void {
717 const tracy = trace(@src());
718 defer tracy.end();
719
720 const filtered_relocs = filterRelocs(relocs, context.base_offset, context.base_offset + self.size);
721 var it = RelocIterator{
722 .buffer = filtered_relocs,
723 };
724
725 var addend: u32 = 0;
726 var subtractor: ?u32 = null;
727 const arch = context.macho_file.base.options.target.cpu.arch;
728
729 while (it.next()) |rel| {
730 if (isAddend(rel, arch)) {
731 // Addend is not a relocation with effect on the TextBlock, so
732 // parse it and carry on.
733 assert(addend == 0); // Oh no, addend was not reset!
734 addend = rel.r_symbolnum;
735
736 // Verify ADDEND is followed by a PAGE21 or PAGEOFF12.
737 const next = @intToEnum(macho.reloc_type_arm64, it.peek().r_type);
738 switch (next) {
739 .ARM64_RELOC_PAGE21, .ARM64_RELOC_PAGEOFF12 => {},
740 else => {
741 log.err("unexpected relocation type: expected PAGE21 or PAGEOFF12, found {s}", .{next});
742 return error.UnexpectedRelocationType;
743 },
744 }
745 continue;
746 }
747
748 if (isSubtractor(rel, arch)) {
749 // Subtractor is not a relocation with effect on the TextBlock, so
750 // parse it and carry on.
751 assert(subtractor == null); // Oh no, subtractor was not reset!
752 assert(rel.r_extern == 1);
753 const sym = context.object.symtab.items[rel.r_symbolnum];
754 const sym_name = context.object.getString(sym.n_strx);
755
756 if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
757 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
758 subtractor = where_index;
759 } else {
760 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{
761 .bytes = &context.macho_file.strtab,
762 }) orelse unreachable;
763 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
764 assert(resolv.where == .global);
765 subtractor = resolv.local_sym_index;
766 }
767
768 // Verify SUBTRACTOR is followed by UNSIGNED.
769 switch (arch) {
770 .aarch64 => {
771 const next = @intToEnum(macho.reloc_type_arm64, it.peek().r_type);
772 if (next != .ARM64_RELOC_UNSIGNED) {
773 log.err("unexpected relocation type: expected UNSIGNED, found {s}", .{next});
774 return error.UnexpectedRelocationType;
775 }
776 },
777 .x86_64 => {
778 const next = @intToEnum(macho.reloc_type_x86_64, it.peek().r_type);
779 if (next != .X86_64_RELOC_UNSIGNED) {
780 log.err("unexpected relocation type: expected UNSIGNED, found {s}", .{next});
781 return error.UnexpectedRelocationType;
782 }
783 },
784 else => unreachable,
785 }
786 continue;
787 }
788
789 var parsed_rel = try initRelocFromObject(rel, context);
790
791 switch (arch) {
792 .aarch64 => {
793 const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type);
794 switch (rel_type) {
795 .ARM64_RELOC_ADDEND => unreachable,
796 .ARM64_RELOC_SUBTRACTOR => unreachable,
797 .ARM64_RELOC_BRANCH26 => {
798 self.parseBranch(rel, &parsed_rel, context);
799 },
800 .ARM64_RELOC_UNSIGNED => {
801 self.parseUnsigned(rel, &parsed_rel, subtractor, context);
802 subtractor = null;
803 },
804 .ARM64_RELOC_PAGE21,
805 .ARM64_RELOC_GOT_LOAD_PAGE21,
806 .ARM64_RELOC_TLVP_LOAD_PAGE21,
807 => {
808 self.parsePage(rel, &parsed_rel, addend);
809 if (rel_type == .ARM64_RELOC_PAGE21)
810 addend = 0;
811 },
812 .ARM64_RELOC_PAGEOFF12,
813 .ARM64_RELOC_GOT_LOAD_PAGEOFF12,
814 .ARM64_RELOC_TLVP_LOAD_PAGEOFF12,
815 => {
816 self.parsePageOff(rel, &parsed_rel, addend);
817 if (rel_type == .ARM64_RELOC_PAGEOFF12)
818 addend = 0;
819 },
820 .ARM64_RELOC_POINTER_TO_GOT => {
821 self.parsePointerToGot(rel, &parsed_rel);
822 },
823 }
824 },
825 .x86_64 => {
826 switch (@intToEnum(macho.reloc_type_x86_64, rel.r_type)) {
827 .X86_64_RELOC_SUBTRACTOR => unreachable,
828 .X86_64_RELOC_BRANCH => {
829 self.parseBranch(rel, &parsed_rel, context);
830 },
831 .X86_64_RELOC_UNSIGNED => {
832 self.parseUnsigned(rel, &parsed_rel, subtractor, context);
833 subtractor = null;
834 },
835 .X86_64_RELOC_SIGNED,
836 .X86_64_RELOC_SIGNED_1,
837 .X86_64_RELOC_SIGNED_2,
838 .X86_64_RELOC_SIGNED_4,
839 => {
840 self.parseSigned(rel, &parsed_rel, context);
841 },
842 .X86_64_RELOC_GOT_LOAD,
843 .X86_64_RELOC_GOT,
844 .X86_64_RELOC_TLV,
845 => {
846 self.parseLoad(rel, &parsed_rel);
847 },
848 }
849 },
850 else => unreachable,
851 }
852
853 try self.relocs.append(context.allocator, parsed_rel);
854
855 const is_via_got = switch (parsed_rel.payload) {
856 .pointer_to_got => true,
857 .load => |load| load.kind == .got,
858 .page => |page| page.kind == .got,
859 .page_off => |page_off| page_off.kind == .got,
860 else => false,
861 };
862
863 if (is_via_got) blk: {
864 const key = MachO.GotIndirectionKey{
865 .where = switch (parsed_rel.where) {
866 .local => .local,
867 .undef => .undef,
868 },
869 .where_index = parsed_rel.where_index,
870 };
871 if (context.macho_file.got_entries_map.contains(key)) break :blk;
872
873 const atom = try context.macho_file.createGotAtom(key);
874 try context.macho_file.got_entries_map.putNoClobber(context.macho_file.base.allocator, key, atom);
875 const match = MachO.MatchingSection{
876 .seg = context.macho_file.data_const_segment_cmd_index.?,
877 .sect = context.macho_file.got_section_index.?,
878 };
879
880 if (context.parsed_atoms.getPtr(match)) |last| {
881 last.*.next = atom;
882 atom.prev = last.*;
883 last.* = atom;
884 } else {
885 try context.parsed_atoms.putNoClobber(match, atom);
886 }
887 } else if (parsed_rel.payload == .unsigned) {
888 switch (parsed_rel.where) {
889 .undef => {
890 try self.bindings.append(context.allocator, .{
891 .local_sym_index = parsed_rel.where_index,
892 .offset = parsed_rel.offset,
893 });
894 },
895 .local => {
896 const source_sym = context.macho_file.locals.items[self.local_sym_index];
897 const match = context.macho_file.section_ordinals.keys()[source_sym.n_sect - 1];
898 const seg = context.macho_file.load_commands.items[match.seg].Segment;
899 const sect = seg.sections.items[match.sect];
900 const sect_type = commands.sectionType(sect);
901
902 const should_rebase = rebase: {
903 if (!parsed_rel.payload.unsigned.is_64bit) break :rebase false;
904
905 // TODO actually, a check similar to what dyld is doing, that is, verifying
906 // that the segment is writable should be enough here.
907 const is_right_segment = blk: {
908 if (context.macho_file.data_segment_cmd_index) |idx| {
909 if (match.seg == idx) {
910 break :blk true;
911 }
912 }
913 if (context.macho_file.data_const_segment_cmd_index) |idx| {
914 if (match.seg == idx) {
915 break :blk true;
916 }
917 }
918 break :blk false;
919 };
920
921 if (!is_right_segment) break :rebase false;
922 if (sect_type != macho.S_LITERAL_POINTERS and
923 sect_type != macho.S_REGULAR and
924 sect_type != macho.S_MOD_INIT_FUNC_POINTERS and
925 sect_type != macho.S_MOD_TERM_FUNC_POINTERS)
926 {
927 break :rebase false;
928 }
929
930 break :rebase true;
931 };
932
933 if (should_rebase) {
934 try self.rebases.append(context.allocator, parsed_rel.offset);
935 }
936 },
937 }
938 } else if (parsed_rel.payload == .branch) blk: {
939 if (parsed_rel.where != .undef) break :blk;
940 if (context.macho_file.stubs_map.contains(parsed_rel.where_index)) break :blk;
941
942 const stub_helper_atom = try context.macho_file.createStubHelperAtom();
943 const laptr_atom = try context.macho_file.createLazyPointerAtom(
944 stub_helper_atom.local_sym_index,
945 parsed_rel.where_index,
946 );
947 const stub_atom = try context.macho_file.createStubAtom(laptr_atom.local_sym_index);
948 try context.macho_file.stubs_map.putNoClobber(context.allocator, parsed_rel.where_index, stub_atom);
949 // TODO clean this up!
950 if (context.parsed_atoms.getPtr(.{
951 .seg = context.macho_file.text_segment_cmd_index.?,
952 .sect = context.macho_file.stub_helper_section_index.?,
953 })) |last| {
954 last.*.next = stub_helper_atom;
955 stub_helper_atom.prev = last.*;
956 last.* = stub_helper_atom;
957 } else {
958 try context.parsed_atoms.putNoClobber(.{
959 .seg = context.macho_file.text_segment_cmd_index.?,
960 .sect = context.macho_file.stub_helper_section_index.?,
961 }, stub_helper_atom);
962 }
963 if (context.parsed_atoms.getPtr(.{
964 .seg = context.macho_file.text_segment_cmd_index.?,
965 .sect = context.macho_file.stubs_section_index.?,
966 })) |last| {
967 last.*.next = stub_atom;
968 stub_atom.prev = last.*;
969 last.* = stub_atom;
970 } else {
971 try context.parsed_atoms.putNoClobber(.{
972 .seg = context.macho_file.text_segment_cmd_index.?,
973 .sect = context.macho_file.stubs_section_index.?,
974 }, stub_atom);
975 }
976 if (context.parsed_atoms.getPtr(.{
977 .seg = context.macho_file.data_segment_cmd_index.?,
978 .sect = context.macho_file.la_symbol_ptr_section_index.?,
979 })) |last| {
980 last.*.next = laptr_atom;
981 laptr_atom.prev = last.*;
982 last.* = laptr_atom;
983 } else {
984 try context.parsed_atoms.putNoClobber(.{
985 .seg = context.macho_file.data_segment_cmd_index.?,
986 .sect = context.macho_file.la_symbol_ptr_section_index.?,
987 }, laptr_atom);
988 }
989 }
990 }
991}
992
993fn isAddend(rel: macho.relocation_info, arch: Arch) bool {
994 if (arch != .aarch64) return false;
995 return @intToEnum(macho.reloc_type_arm64, rel.r_type) == .ARM64_RELOC_ADDEND;
996}
997
998fn isSubtractor(rel: macho.relocation_info, arch: Arch) bool {
999 return switch (arch) {
1000 .aarch64 => @intToEnum(macho.reloc_type_arm64, rel.r_type) == .ARM64_RELOC_SUBTRACTOR,
1001 .x86_64 => @intToEnum(macho.reloc_type_x86_64, rel.r_type) == .X86_64_RELOC_SUBTRACTOR,
1002 else => unreachable,
1003 };
1004}
1005
1006fn parseUnsigned(
1007 self: Atom,
1008 rel: macho.relocation_info,
1009 out: *Relocation,
1010 subtractor: ?u32,
1011 context: RelocContext,
1012) void {
1013 assert(rel.r_pcrel == 0);
1014
1015 const is_64bit: bool = switch (rel.r_length) {
1016 3 => true,
1017 2 => false,
1018 else => unreachable,
1019 };
1020
1021 var addend: i64 = if (is_64bit)
1022 mem.readIntLittle(i64, self.code.items[out.offset..][0..8])
1023 else
1024 mem.readIntLittle(i32, self.code.items[out.offset..][0..4]);
1025
1026 if (rel.r_extern == 0) {
1027 const seg = context.object.load_commands.items[context.object.segment_cmd_index.?].Segment;
1028 const target_sect_base_addr = seg.sections.items[rel.r_symbolnum - 1].addr;
1029 addend -= @intCast(i64, target_sect_base_addr);
1030 }
1031
1032 out.payload = .{
1033 .unsigned = .{
1034 .subtractor = subtractor,
1035 .is_64bit = is_64bit,
1036 .addend = addend,
1037 },
1038 };
1039}
1040
1041fn parseBranch(self: Atom, rel: macho.relocation_info, out: *Relocation, context: RelocContext) void {
1042 _ = self;
1043 assert(rel.r_pcrel == 1);
1044 assert(rel.r_length == 2);
1045
1046 out.payload = .{
1047 .branch = .{
1048 .arch = context.macho_file.base.options.target.cpu.arch,
1049 },
1050 };
1051}
1052
1053fn parsePage(self: Atom, rel: macho.relocation_info, out: *Relocation, addend: u32) void {
1054 _ = self;
1055 assert(rel.r_pcrel == 1);
1056 assert(rel.r_length == 2);
1057
1058 out.payload = .{
1059 .page = .{
1060 .kind = switch (@intToEnum(macho.reloc_type_arm64, rel.r_type)) {
1061 .ARM64_RELOC_PAGE21 => .page,
1062 .ARM64_RELOC_GOT_LOAD_PAGE21 => .got,
1063 .ARM64_RELOC_TLVP_LOAD_PAGE21 => .tlvp,
1064 else => unreachable,
1065 },
1066 .addend = addend,
1067 },
1068 };
1069}
1070
1071fn parsePageOff(self: Atom, rel: macho.relocation_info, out: *Relocation, addend: u32) void {
1072 assert(rel.r_pcrel == 0);
1073 assert(rel.r_length == 2);
1074
1075 const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type);
1076 const op_kind: ?Relocation.PageOff.OpKind = blk: {
1077 if (rel_type != .ARM64_RELOC_PAGEOFF12) break :blk null;
1078 const op_kind: Relocation.PageOff.OpKind = if (isArithmeticOp(self.code.items[out.offset..][0..4]))
1079 .arithmetic
1080 else
1081 .load;
1082 break :blk op_kind;
1083 };
1084
1085 out.payload = .{
1086 .page_off = .{
1087 .kind = switch (rel_type) {
1088 .ARM64_RELOC_PAGEOFF12 => .page,
1089 .ARM64_RELOC_GOT_LOAD_PAGEOFF12 => .got,
1090 .ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => .tlvp,
1091 else => unreachable,
1092 },
1093 .addend = addend,
1094 .op_kind = op_kind,
1095 },
1096 };
1097}
1098
1099fn parsePointerToGot(self: Atom, rel: macho.relocation_info, out: *Relocation) void {
1100 _ = self;
1101 assert(rel.r_pcrel == 1);
1102 assert(rel.r_length == 2);
1103
1104 out.payload = .{
1105 .pointer_to_got = .{},
1106 };
1107}
1108
1109fn parseSigned(self: Atom, rel: macho.relocation_info, out: *Relocation, context: RelocContext) void {
1110 assert(rel.r_pcrel == 1);
1111 assert(rel.r_length == 2);
1112
1113 const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type);
1114 const correction: u3 = switch (rel_type) {
1115 .X86_64_RELOC_SIGNED => 0,
1116 .X86_64_RELOC_SIGNED_1 => 1,
1117 .X86_64_RELOC_SIGNED_2 => 2,
1118 .X86_64_RELOC_SIGNED_4 => 4,
1119 else => unreachable,
1120 };
1121 var addend: i64 = mem.readIntLittle(i32, self.code.items[out.offset..][0..4]) + correction;
1122
1123 if (rel.r_extern == 0) {
1124 const seg = context.object.load_commands.items[context.object.segment_cmd_index.?].Segment;
1125 const target_sect_base_addr = seg.sections.items[rel.r_symbolnum - 1].addr;
1126 addend += @intCast(i64, context.base_addr + out.offset + correction + 4) - @intCast(i64, target_sect_base_addr);
1127 }
1128
1129 out.payload = .{
1130 .signed = .{
1131 .correction = correction,
1132 .addend = addend,
1133 },
1134 };
1135}
1136
1137fn parseLoad(self: Atom, rel: macho.relocation_info, out: *Relocation) void {
1138 assert(rel.r_pcrel == 1);
1139 assert(rel.r_length == 2);
1140
1141 const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type);
1142 const addend: i32 = if (rel_type == .X86_64_RELOC_GOT)
1143 mem.readIntLittle(i32, self.code.items[out.offset..][0..4])
1144 else
1145 0;
1146
1147 out.payload = .{
1148 .load = .{
1149 .kind = switch (rel_type) {
1150 .X86_64_RELOC_GOT_LOAD, .X86_64_RELOC_GOT => .got,
1151 .X86_64_RELOC_TLV => .tlvp,
1152 else => unreachable,
1153 },
1154 .addend = addend,
1155 },
1156 };
1157}
1158
1159pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
1160 const tracy = trace(@src());
1161 defer tracy.end();
1162
1163 for (self.relocs.items) |rel| {
1164 log.debug("relocating {}", .{rel});
1165
1166 const source_addr = blk: {
1167 const sym = macho_file.locals.items[self.local_sym_index];
1168 break :blk sym.n_value + rel.offset;
1169 };
1170 const target_addr = blk: {
1171 const is_via_got = switch (rel.payload) {
1172 .pointer_to_got => true,
1173 .page => |page| page.kind == .got,
1174 .page_off => |page_off| page_off.kind == .got,
1175 .load => |load| load.kind == .got,
1176 else => false,
1177 };
1178
1179 if (is_via_got) {
1180 const atom = macho_file.got_entries_map.get(.{
1181 .where = switch (rel.where) {
1182 .local => .local,
1183 .undef => .undef,
1184 },
1185 .where_index = rel.where_index,
1186 }) orelse {
1187 const sym = switch (rel.where) {
1188 .local => macho_file.locals.items[rel.where_index],
1189 .undef => macho_file.undefs.items[rel.where_index],
1190 };
1191 log.err("expected GOT entry for symbol '{s}'", .{macho_file.getString(sym.n_strx)});
1192 log.err(" this is an internal linker error", .{});
1193 return error.FailedToResolveRelocationTarget;
1194 };
1195 break :blk macho_file.locals.items[atom.local_sym_index].n_value;
1196 }
1197
1198 switch (rel.where) {
1199 .local => {
1200 const sym = macho_file.locals.items[rel.where_index];
1201 const is_tlv = is_tlv: {
1202 const source_sym = macho_file.locals.items[self.local_sym_index];
1203 const match = macho_file.section_ordinals.keys()[source_sym.n_sect - 1];
1204 const seg = macho_file.load_commands.items[match.seg].Segment;
1205 const sect = seg.sections.items[match.sect];
1206 break :is_tlv commands.sectionType(sect) == macho.S_THREAD_LOCAL_VARIABLES;
1207 };
1208 if (is_tlv) {
1209 // For TLV relocations, the value specified as a relocation is the displacement from the
1210 // TLV initializer (either value in __thread_data or zero-init in __thread_bss) to the first
1211 // defined TLV template init section in the following order:
1212 // * wrt to __thread_data if defined, then
1213 // * wrt to __thread_bss
1214 const seg = macho_file.load_commands.items[macho_file.data_segment_cmd_index.?].Segment;
1215 const base_address = inner: {
1216 if (macho_file.tlv_data_section_index) |i| {
1217 break :inner seg.sections.items[i].addr;
1218 } else if (macho_file.tlv_bss_section_index) |i| {
1219 break :inner seg.sections.items[i].addr;
1220 } else {
1221 log.err("threadlocal variables present but no initializer sections found", .{});
1222 log.err(" __thread_data not found", .{});
1223 log.err(" __thread_bss not found", .{});
1224 return error.FailedToResolveRelocationTarget;
1225 }
1226 };
1227 break :blk sym.n_value - base_address;
1228 }
1229
1230 break :blk sym.n_value;
1231 },
1232 .undef => {
1233 const atom = macho_file.stubs_map.get(rel.where_index) orelse {
1234 // TODO this is required for incremental when we don't have every symbol
1235 // resolved when creating relocations. In this case, we will insert a branch
1236 // reloc to an undef symbol which may happen to be defined within the binary.
1237 // Then, the undef we point at will be a null symbol (free symbol) which we
1238 // should remove/repurpose. To circumvent this (for now), we check if the symbol
1239 // we point to is garbage, and if so we fall back to symbol resolver to find by name.
1240 const n_strx = macho_file.undefs.items[rel.where_index].n_strx;
1241 if (macho_file.symbol_resolver.get(n_strx)) |resolv| inner: {
1242 if (resolv.where != .global) break :inner;
1243 break :blk macho_file.globals.items[resolv.where_index].n_value;
1244 }
1245
1246 // TODO verify in TextBlock that the symbol is indeed dynamically bound.
1247 break :blk 0; // Dynamically bound by dyld.
1248 };
1249
1250 break :blk macho_file.locals.items[atom.local_sym_index].n_value;
1251 },
1252 }
1253 };
1254
1255 log.debug(" | source_addr = 0x{x}", .{source_addr});
1256 log.debug(" | target_addr = 0x{x}", .{target_addr});
1257
1258 try rel.resolve(.{
1259 .block = self,
1260 .offset = rel.offset,
1261 .source_addr = source_addr,
1262 .target_addr = target_addr,
1263 .macho_file = macho_file,
1264 });
1265 }
1266}
1267
1268pub fn format(self: Atom, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
1269 _ = fmt;
1270 _ = options;
1271 try std.fmt.format(writer, "TextBlock {{ ", .{});
1272 try std.fmt.format(writer, ".local_sym_index = {d}, ", .{self.local_sym_index});
1273 try std.fmt.format(writer, ".aliases = {any}, ", .{self.aliases.items});
1274 try std.fmt.format(writer, ".contained = {any}, ", .{self.contained.items});
1275 try std.fmt.format(writer, ".code = {*}, ", .{self.code.items});
1276 try std.fmt.format(writer, ".size = {d}, ", .{self.size});
1277 try std.fmt.format(writer, ".alignment = {d}, ", .{self.alignment});
1278 try std.fmt.format(writer, ".relocs = {any}, ", .{self.relocs.items});
1279 try std.fmt.format(writer, ".rebases = {any}, ", .{self.rebases.items});
1280 try std.fmt.format(writer, ".bindings = {any}, ", .{self.bindings.items});
1281 try std.fmt.format(writer, ".dices = {any}, ", .{self.dices.items});
1282 if (self.stab) |stab| {
1283 try std.fmt.format(writer, ".stab = {any}, ", .{stab});
1284 }
1285 try std.fmt.format(writer, "}}", .{});
1286}
1287
1288const RelocIterator = struct {
1289 buffer: []const macho.relocation_info,
1290 index: i32 = -1,
1291
1292 pub fn next(self: *RelocIterator) ?macho.relocation_info {
1293 self.index += 1;
1294 if (self.index < self.buffer.len) {
1295 return self.buffer[@intCast(u32, self.index)];
1296 }
1297 return null;
1298 }
1299
1300 pub fn peek(self: RelocIterator) macho.relocation_info {
1301 assert(self.index + 1 < self.buffer.len);
1302 return self.buffer[@intCast(u32, self.index + 1)];
1303 }
1304};
1305
1306fn filterRelocs(relocs: []macho.relocation_info, start_addr: u64, end_addr: u64) []macho.relocation_info {
1307 const Predicate = struct {
1308 addr: u64,
1309
1310 pub fn predicate(self: @This(), rel: macho.relocation_info) bool {
1311 return rel.r_address < self.addr;
1312 }
1313 };
1314
1315 const start = MachO.findFirst(macho.relocation_info, relocs, 0, Predicate{ .addr = end_addr });
1316 const end = MachO.findFirst(macho.relocation_info, relocs, start, Predicate{ .addr = start_addr });
1317
1318 return relocs[start..end];
1319}
1320
1321inline fn isArithmeticOp(inst: *const [4]u8) bool {
1322 const group_decode = @truncate(u5, inst[3]);
1323 return ((group_decode >> 2) == 4);
1324}
src/link/MachO/DebugSymbols.zig+147-162
...@@ -5,23 +5,26 @@ const assert = std.debug.assert;...@@ -5,23 +5,26 @@ const assert = std.debug.assert;
5const fs = std.fs;5const fs = std.fs;
6const log = std.log.scoped(.dsym);6const log = std.log.scoped(.dsym);
7const macho = std.macho;7const macho = std.macho;
8const math = std.math;
8const mem = std.mem;9const mem = std.mem;
9const DW = std.dwarf;10const DW = std.dwarf;
10const leb = std.leb;11const leb = std.leb;
11const Allocator = mem.Allocator;12const Allocator = mem.Allocator;
1213
13const build_options = @import("build_options");14const build_options = @import("build_options");
15const commands = @import("commands.zig");
14const trace = @import("../../tracy.zig").trace;16const trace = @import("../../tracy.zig").trace;
17const LoadCommand = commands.LoadCommand;
15const Module = @import("../../Module.zig");18const Module = @import("../../Module.zig");
16const Type = @import("../../type.zig").Type;19const Type = @import("../../type.zig").Type;
17const link = @import("../../link.zig");20const link = @import("../../link.zig");
18const MachO = @import("../MachO.zig");21const MachO = @import("../MachO.zig");
19const SrcFn = MachO.SrcFn;
20const TextBlock = MachO.TextBlock;22const TextBlock = MachO.TextBlock;
23const SegmentCommand = commands.SegmentCommand;
24const SrcFn = MachO.SrcFn;
25const makeStaticString = MachO.makeStaticString;
21const padToIdeal = MachO.padToIdeal;26const padToIdeal = MachO.padToIdeal;
2227
23usingnamespace @import("commands.zig");
24
25const page_size: u16 = 0x1000;28const page_size: u16 = 0x1000;
2629
27base: *MachO,30base: *MachO,
...@@ -93,7 +96,7 @@ const abbrev_parameter = 6;...@@ -93,7 +96,7 @@ const abbrev_parameter = 6;
93/// The reloc offset for the virtual address of a function in its Line Number Program.96/// The reloc offset for the virtual address of a function in its Line Number Program.
94/// Size is a virtual address integer.97/// Size is a virtual address integer.
95const dbg_line_vaddr_reloc_index = 3;98const dbg_line_vaddr_reloc_index = 3;
96/// The reloc offset for the virtual address of a function in its .debug_info TAG_subprogram.99/// The reloc offset for the virtual address of a function in its .debug_info TAG.subprogram.
97/// Size is a virtual address integer.100/// Size is a virtual address integer.
98const dbg_info_low_pc_reloc_index = 1;101const dbg_info_low_pc_reloc_index = 1;
99102
...@@ -185,105 +188,84 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -185,105 +188,84 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
185 log.debug("found __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });188 log.debug("found __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });
186189
187 try self.load_commands.append(allocator, .{190 try self.load_commands.append(allocator, .{
188 .Segment = SegmentCommand.empty("__DWARF", .{191 .Segment = .{
189 .vmaddr = vmaddr,192 .inner = .{
190 .vmsize = needed_size,193 .segname = makeStaticString("__DWARF"),
191 .fileoff = off,194 .vmaddr = vmaddr,
192 .filesize = needed_size,195 .vmsize = needed_size,
193 }),196 .fileoff = off,
197 .filesize = needed_size,
198 },
199 },
194 });200 });
195 self.load_commands_dirty = true;201 self.load_commands_dirty = true;
196 }202 }
197 if (self.debug_str_section_index == null) {203 if (self.debug_str_section_index == null) {
198 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
199 self.debug_str_section_index = @intCast(u16, dwarf_segment.sections.items.len);
200 assert(self.debug_string_table.items.len == 0);204 assert(self.debug_string_table.items.len == 0);
201205 self.debug_str_section_index = try self.allocateSection(
202 try dwarf_segment.addSection(allocator, "__debug_str", .{206 "__debug_str",
203 .addr = dwarf_segment.inner.vmaddr,207 @intCast(u32, self.debug_string_table.items.len),
204 .size = @intCast(u32, self.debug_string_table.items.len),208 0,
205 .offset = @intCast(u32, dwarf_segment.inner.fileoff),209 );
206 .@"align" = 1,
207 });
208 self.load_commands_dirty = true;
209 self.debug_string_table_dirty = true;210 self.debug_string_table_dirty = true;
210 }211 }
211 if (self.debug_info_section_index == null) {212 if (self.debug_info_section_index == null) {
212 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;213 self.debug_info_section_index = try self.allocateSection("__debug_info", 200, 0);
213 self.debug_info_section_index = @intCast(u16, dwarf_segment.sections.items.len);
214
215 const file_size_hint = 200;
216 const p_align = 1;
217 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);
218
219 log.debug("found __debug_info free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
220
221 try dwarf_segment.addSection(allocator, "__debug_info", .{
222 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
223 .size = file_size_hint,
224 .offset = @intCast(u32, off),
225 .@"align" = p_align,
226 });
227 self.load_commands_dirty = true;
228 self.debug_info_header_dirty = true;214 self.debug_info_header_dirty = true;
229 }215 }
230 if (self.debug_abbrev_section_index == null) {216 if (self.debug_abbrev_section_index == null) {
231 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;217 self.debug_abbrev_section_index = try self.allocateSection("__debug_abbrev", 128, 0);
232 self.debug_abbrev_section_index = @intCast(u16, dwarf_segment.sections.items.len);
233
234 const file_size_hint = 128;
235 const p_align = 1;
236 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);
237
238 log.debug("found __debug_abbrev free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
239
240 try dwarf_segment.addSection(allocator, "__debug_abbrev", .{
241 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
242 .size = file_size_hint,
243 .offset = @intCast(u32, off),
244 .@"align" = p_align,
245 });
246 self.load_commands_dirty = true;
247 self.debug_abbrev_section_dirty = true;218 self.debug_abbrev_section_dirty = true;
248 }219 }
249 if (self.debug_aranges_section_index == null) {220 if (self.debug_aranges_section_index == null) {
250 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;221 self.debug_aranges_section_index = try self.allocateSection("__debug_aranges", 160, 4);
251 self.debug_aranges_section_index = @intCast(u16, dwarf_segment.sections.items.len);
252
253 const file_size_hint = 160;
254 const p_align = 16;
255 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);
256
257 log.debug("found __debug_aranges free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
258
259 try dwarf_segment.addSection(allocator, "__debug_aranges", .{
260 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
261 .size = file_size_hint,
262 .offset = @intCast(u32, off),
263 .@"align" = p_align,
264 });
265 self.load_commands_dirty = true;
266 self.debug_aranges_section_dirty = true;222 self.debug_aranges_section_dirty = true;
267 }223 }
268 if (self.debug_line_section_index == null) {224 if (self.debug_line_section_index == null) {
269 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;225 self.debug_line_section_index = try self.allocateSection("__debug_line", 250, 0);
270 self.debug_line_section_index = @intCast(u16, dwarf_segment.sections.items.len);226 self.debug_line_header_dirty = true;
227 }
228}
271229
272 const file_size_hint = 250;230fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignment: u16) !u16 {
273 const p_align = 1;231 const seg = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
274 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);232 var sect = macho.section_64{
233 .sectname = makeStaticString(sectname),
234 .segname = seg.inner.segname,
235 .size = @intCast(u32, size),
236 .@"align" = alignment,
237 };
238 const alignment_pow_2 = try math.powi(u32, 2, alignment);
239 const off = seg.findFreeSpace(size, alignment_pow_2, null);
275240
276 log.debug("found __debug_line free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });241 assert(off + size <= seg.inner.fileoff + seg.inner.filesize); // TODO expand
277242
278 try dwarf_segment.addSection(allocator, "__debug_line", .{243 log.debug("found {s},{s} section free space 0x{x} to 0x{x}", .{
279 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,244 commands.segmentName(sect),
280 .size = file_size_hint,245 commands.sectionName(sect),
281 .offset = @intCast(u32, off),246 off,
282 .@"align" = p_align,247 off + size,
283 });248 });
284 self.load_commands_dirty = true;249
285 self.debug_line_header_dirty = true;250 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;
286 }251 sect.offset = @intCast(u32, off);
252
253 const index = @intCast(u16, seg.sections.items.len);
254 try seg.sections.append(self.base.base.allocator, sect);
255 seg.inner.cmdsize += @sizeOf(macho.section_64);
256 seg.inner.nsects += 1;
257
258 // TODO
259 // const match = MatchingSection{
260 // .seg = segment_id,
261 // .sect = index,
262 // };
263 // _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
264 // try self.block_free_lists.putNoClobber(self.base.allocator, match, .{});
265
266 self.load_commands_dirty = true;
267
268 return index;
287}269}
288270
289pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Options) !void {271pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Options) !void {
...@@ -299,40 +281,40 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt...@@ -299,40 +281,40 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
299 // These are LEB encoded but since the values are all less than 127281 // These are LEB encoded but since the values are all less than 127
300 // we can simply append these bytes.282 // we can simply append these bytes.
301 const abbrev_buf = [_]u8{283 const abbrev_buf = [_]u8{
302 abbrev_compile_unit, DW.TAG_compile_unit, DW.CHILDREN_yes, // header284 abbrev_compile_unit, DW.TAG.compile_unit, DW.CHILDREN.yes, // header
303 DW.AT_stmt_list, DW.FORM_sec_offset, // offset285 DW.AT.stmt_list, DW.FORM.sec_offset, // offset
304 DW.AT_low_pc, DW.FORM_addr,286 DW.AT.low_pc, DW.FORM.addr,
305 DW.AT_high_pc, DW.FORM_addr,287 DW.AT.high_pc, DW.FORM.addr,
306 DW.AT_name, DW.FORM_strp,288 DW.AT.name, DW.FORM.strp,
307 DW.AT_comp_dir, DW.FORM_strp,289 DW.AT.comp_dir, DW.FORM.strp,
308 DW.AT_producer, DW.FORM_strp,290 DW.AT.producer, DW.FORM.strp,
309 DW.AT_language, DW.FORM_data2,291 DW.AT.language, DW.FORM.data2,
310 0, 0, // table sentinel292 0, 0, // table sentinel
311 abbrev_subprogram, DW.TAG_subprogram, DW.CHILDREN_yes, // header293 abbrev_subprogram, DW.TAG.subprogram, DW.CHILDREN.yes, // header
312 DW.AT_low_pc, DW.FORM_addr, // start VM address294 DW.AT.low_pc, DW.FORM.addr, // start VM address
313 DW.AT_high_pc, DW.FORM_data4,295 DW.AT.high_pc, DW.FORM.data4,
314 DW.AT_type, DW.FORM_ref4,296 DW.AT.type, DW.FORM.ref4,
315 DW.AT_name, DW.FORM_string,297 DW.AT.name, DW.FORM.string,
316 DW.AT_decl_line, DW.FORM_data4,298 DW.AT.decl_line, DW.FORM.data4,
317 DW.AT_decl_file, DW.FORM_data1,299 DW.AT.decl_file, DW.FORM.data1,
318 0, 0, // table sentinel300 0, 0, // table sentinel
319 abbrev_subprogram_retvoid,301 abbrev_subprogram_retvoid,
320 DW.TAG_subprogram, DW.CHILDREN_yes, // header302 DW.TAG.subprogram, DW.CHILDREN.yes, // header
321 DW.AT_low_pc, DW.FORM_addr,303 DW.AT.low_pc, DW.FORM.addr,
322 DW.AT_high_pc, DW.FORM_data4,304 DW.AT.high_pc, DW.FORM.data4,
323 DW.AT_name, DW.FORM_string,305 DW.AT.name, DW.FORM.string,
324 DW.AT_decl_line, DW.FORM_data4,306 DW.AT.decl_line, DW.FORM.data4,
325 DW.AT_decl_file, DW.FORM_data1,307 DW.AT.decl_file, DW.FORM.data1,
326 0, 0, // table sentinel308 0, 0, // table sentinel
327 abbrev_base_type, DW.TAG_base_type, DW.CHILDREN_no, // header309 abbrev_base_type, DW.TAG.base_type, DW.CHILDREN.no, // header
328 DW.AT_encoding, DW.FORM_data1, DW.AT_byte_size,310 DW.AT.encoding, DW.FORM.data1, DW.AT.byte_size,
329 DW.FORM_data1, DW.AT_name, DW.FORM_string,311 DW.FORM.data1, DW.AT.name, DW.FORM.string,
330 0, 0, // table sentinel312 0, 0, // table sentinel
331 abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header313 abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header
332 0, 0, // table sentinel314 0, 0, // table sentinel
333 abbrev_parameter, DW.TAG_formal_parameter, DW.CHILDREN_no, // header315 abbrev_parameter, DW.TAG.formal_parameter, DW.CHILDREN.no, // header
334 DW.AT_location, DW.FORM_exprloc, DW.AT_type,316 DW.AT.location, DW.FORM.exprloc, DW.AT.type,
335 DW.FORM_ref4, DW.AT_name, DW.FORM_string,317 DW.FORM.ref4, DW.AT.name, DW.FORM.string,
336 0, 0, // table sentinel318 0, 0, // table sentinel
337 0, 0, 0, // section sentinel319 0, 0, 0, // section sentinel
338 };320 };
...@@ -397,7 +379,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt...@@ -397,7 +379,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
397 const high_pc = text_section.addr + text_section.size;379 const high_pc = text_section.addr + text_section.size;
398380
399 di_buf.appendAssumeCapacity(abbrev_compile_unit);381 di_buf.appendAssumeCapacity(abbrev_compile_unit);
400 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT_stmt_list, DW.FORM_sec_offset382 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT.stmt_list, DW.FORM.sec_offset
401 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);383 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);
402 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), high_pc);384 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), high_pc);
403 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, name_strp));385 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, name_strp));
...@@ -406,7 +388,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt...@@ -406,7 +388,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
406 // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number:388 // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number:
407 // http://dwarfstd.org/ShowIssue.php?issue=171115.1389 // http://dwarfstd.org/ShowIssue.php?issue=171115.1
408 // Until then we say it is C99.390 // Until then we say it is C99.
409 mem.writeIntLittle(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG_C99);391 mem.writeIntLittle(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG.C99);
410392
411 if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) {393 if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) {
412 // Move the first N decls to the end to make more padding for the header.394 // Move the first N decls to the end to make more padding for the header.
...@@ -514,7 +496,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt...@@ -514,7 +496,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
514 di_buf.items.len += @sizeOf(u32); // We will come back and write this.496 di_buf.items.len += @sizeOf(u32); // We will come back and write this.
515 const after_header_len = di_buf.items.len;497 const after_header_len = di_buf.items.len;
516498
517 const opcode_base = DW.LNS_set_isa + 1;499 const opcode_base = DW.LNS.set_isa + 1;
518 di_buf.appendSliceAssumeCapacity(&[_]u8{500 di_buf.appendSliceAssumeCapacity(&[_]u8{
519 1, // minimum_instruction_length501 1, // minimum_instruction_length
520 1, // maximum_operations_per_instruction502 1, // maximum_operations_per_instruction
...@@ -525,18 +507,18 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt...@@ -525,18 +507,18 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
525507
526 // Standard opcode lengths. The number of items here is based on `opcode_base`.508 // Standard opcode lengths. The number of items here is based on `opcode_base`.
527 // The value is the number of LEB128 operands the instruction takes.509 // The value is the number of LEB128 operands the instruction takes.
528 0, // `DW.LNS_copy`510 0, // `DW.LNS.copy`
529 1, // `DW.LNS_advance_pc`511 1, // `DW.LNS.advance_pc`
530 1, // `DW.LNS_advance_line`512 1, // `DW.LNS.advance_line`
531 1, // `DW.LNS_set_file`513 1, // `DW.LNS.set_file`
532 1, // `DW.LNS_set_column`514 1, // `DW.LNS.set_column`
533 0, // `DW.LNS_negate_stmt`515 0, // `DW.LNS.negate_stmt`
534 0, // `DW.LNS_set_basic_block`516 0, // `DW.LNS.set_basic_block`
535 0, // `DW.LNS_const_add_pc`517 0, // `DW.LNS.const_add_pc`
536 1, // `DW.LNS_fixed_advance_pc`518 1, // `DW.LNS.fixed_advance_pc`
537 0, // `DW.LNS_set_prologue_end`519 0, // `DW.LNS.set_prologue_end`
538 0, // `DW.LNS_set_epilogue_begin`520 0, // `DW.LNS.set_epilogue_begin`
539 1, // `DW.LNS_set_isa`521 1, // `DW.LNS.set_isa`
540 0, // include_directories (none except the compilation unit cwd)522 0, // include_directories (none except the compilation unit cwd)
541 });523 });
542 // file_names[0]524 // file_names[0]
...@@ -611,15 +593,18 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {...@@ -611,15 +593,18 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {
611}593}
612594
613fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !SegmentCommand {595fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !SegmentCommand {
614 var cmd = SegmentCommand.empty("", .{596 var cmd = SegmentCommand{
615 .cmdsize = base_cmd.inner.cmdsize,597 .inner = .{
616 .vmaddr = base_cmd.inner.vmaddr,598 .segname = undefined,
617 .vmsize = base_cmd.inner.vmsize,599 .cmdsize = base_cmd.inner.cmdsize,
618 .maxprot = base_cmd.inner.maxprot,600 .vmaddr = base_cmd.inner.vmaddr,
619 .initprot = base_cmd.inner.initprot,601 .vmsize = base_cmd.inner.vmsize,
620 .nsects = base_cmd.inner.nsects,602 .maxprot = base_cmd.inner.maxprot,
621 .flags = base_cmd.inner.flags,603 .initprot = base_cmd.inner.initprot,
622 });604 .nsects = base_cmd.inner.nsects,
605 .flags = base_cmd.inner.flags,
606 },
607 };
623 mem.copy(u8, &cmd.inner.segname, &base_cmd.inner.segname);608 mem.copy(u8, &cmd.inner.segname, &base_cmd.inner.segname);
624609
625 try cmd.sections.ensureCapacity(allocator, cmd.inner.nsects);610 try cmd.sections.ensureCapacity(allocator, cmd.inner.nsects);
...@@ -689,7 +674,7 @@ fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void {...@@ -689,7 +674,7 @@ fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void {
689}674}
690675
691fn writeHeader(self: *DebugSymbols) !void {676fn writeHeader(self: *DebugSymbols) !void {
692 var header = emptyHeader(.{677 var header = commands.emptyHeader(.{
693 .filetype = macho.MH_DSYM,678 .filetype = macho.MH_DSYM,
694 });679 });
695680
...@@ -876,22 +861,22 @@ pub fn initDeclDebugBuffers(...@@ -876,22 +861,22 @@ pub fn initDeclDebugBuffers(
876 const line_off = @intCast(u28, decl.src_line + func.lbrace_line);861 const line_off = @intCast(u28, decl.src_line + func.lbrace_line);
877862
878 dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{863 dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{
879 DW.LNS_extended_op,864 DW.LNS.extended_op,
880 @sizeOf(u64) + 1,865 @sizeOf(u64) + 1,
881 DW.LNE_set_address,866 DW.LNE.set_address,
882 });867 });
883 // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`.868 // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`.
884 assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len);869 assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len);
885 dbg_line_buffer.items.len += @sizeOf(u64);870 dbg_line_buffer.items.len += @sizeOf(u64);
886871
887 dbg_line_buffer.appendAssumeCapacity(DW.LNS_advance_line);872 dbg_line_buffer.appendAssumeCapacity(DW.LNS.advance_line);
888 // This is the "relocatable" relative line offset from the previous function's end curly873 // This is the "relocatable" relative line offset from the previous function's end curly
889 // to this function's begin curly.874 // to this function's begin curly.
890 assert(getRelocDbgLineOff() == dbg_line_buffer.items.len);875 assert(getRelocDbgLineOff() == dbg_line_buffer.items.len);
891 // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later.876 // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later.
892 leb.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off);877 leb.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off);
893878
894 dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file);879 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_file);
895 assert(getRelocDbgFileIndex() == dbg_line_buffer.items.len);880 assert(getRelocDbgFileIndex() == dbg_line_buffer.items.len);
896 // Once we support more than one source file, this will have the ability to be more881 // Once we support more than one source file, this will have the ability to be more
897 // than one possible value.882 // than one possible value.
...@@ -900,7 +885,7 @@ pub fn initDeclDebugBuffers(...@@ -900,7 +885,7 @@ pub fn initDeclDebugBuffers(
900885
901 // Emit a line for the begin curly with prologue_end=false. The codegen will886 // Emit a line for the begin curly with prologue_end=false. The codegen will
902 // do the work of setting prologue_end=true and epilogue_begin=true.887 // do the work of setting prologue_end=true and epilogue_begin=true.
903 dbg_line_buffer.appendAssumeCapacity(DW.LNS_copy);888 dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);
904889
905 // .debug_info subprogram890 // .debug_info subprogram
906 const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];891 const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];
...@@ -917,9 +902,9 @@ pub fn initDeclDebugBuffers(...@@ -917,9 +902,9 @@ pub fn initDeclDebugBuffers(
917 // "relocations" and have to be in this fixed place so that functions can be902 // "relocations" and have to be in this fixed place so that functions can be
918 // moved in virtual address space.903 // moved in virtual address space.
919 assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len);904 assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len);
920 dbg_info_buffer.items.len += @sizeOf(u64); // DW.AT_low_pc, DW.FORM_addr905 dbg_info_buffer.items.len += @sizeOf(u64); // DW.AT.low_pc, DW.FORM.addr
921 assert(getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);906 assert(getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);
922 dbg_info_buffer.items.len += 4; // DW.AT_high_pc, DW.FORM_data4907 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4
923 if (fn_ret_has_bits) {908 if (fn_ret_has_bits) {
924 const gop = try dbg_info_type_relocs.getOrPut(allocator, fn_ret_type);909 const gop = try dbg_info_type_relocs.getOrPut(allocator, fn_ret_type);
925 if (!gop.found_existing) {910 if (!gop.found_existing) {
...@@ -929,11 +914,11 @@ pub fn initDeclDebugBuffers(...@@ -929,11 +914,11 @@ pub fn initDeclDebugBuffers(
929 };914 };
930 }915 }
931 try gop.value_ptr.relocs.append(allocator, @intCast(u32, dbg_info_buffer.items.len));916 try gop.value_ptr.relocs.append(allocator, @intCast(u32, dbg_info_buffer.items.len));
932 dbg_info_buffer.items.len += 4; // DW.AT_type, DW.FORM_ref4917 dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4
933 }918 }
934 dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT_name, DW.FORM_string919 dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT.name, DW.FORM.string
935 mem.writeIntLittle(u32, dbg_info_buffer.addManyAsArrayAssumeCapacity(4), line_off + 1); // DW.AT_decl_line, DW.FORM_data4920 mem.writeIntLittle(u32, dbg_info_buffer.addManyAsArrayAssumeCapacity(4), line_off + 1); // DW.AT.decl_line, DW.FORM.data4
936 dbg_info_buffer.appendAssumeCapacity(file_index); // DW.AT_decl_file, DW.FORM_data1921 dbg_info_buffer.appendAssumeCapacity(file_index); // DW.AT.decl_file, DW.FORM.data1
937 },922 },
938 else => {923 else => {
939 // TODO implement .debug_info for global variables924 // TODO implement .debug_info for global variables
...@@ -985,16 +970,16 @@ pub fn commitDeclDebugInfo(...@@ -985,16 +970,16 @@ pub fn commitDeclDebugInfo(
985 {970 {
986 // Advance line and PC.971 // Advance line and PC.
987 // TODO encapsulate logic in a helper function.972 // TODO encapsulate logic in a helper function.
988 try dbg_line_buffer.append(DW.LNS_advance_pc);973 try dbg_line_buffer.append(DW.LNS.advance_pc);
989 try leb.writeULEB128(dbg_line_buffer.writer(), text_block.size);974 try leb.writeULEB128(dbg_line_buffer.writer(), text_block.size);
990975
991 try dbg_line_buffer.append(DW.LNS_advance_line);976 try dbg_line_buffer.append(DW.LNS.advance_line);
992 const func = decl.val.castTag(.function).?.data;977 const func = decl.val.castTag(.function).?.data;
993 const line_off = @intCast(u28, func.rbrace_line - func.lbrace_line);978 const line_off = @intCast(u28, func.rbrace_line - func.lbrace_line);
994 try leb.writeULEB128(dbg_line_buffer.writer(), line_off);979 try leb.writeULEB128(dbg_line_buffer.writer(), line_off);
995 }980 }
996981
997 try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS_extended_op, 1, DW.LNE_end_sequence });982 try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence });
998983
999 // Now we have the full contents and may allocate a region to store it.984 // Now we have the full contents and may allocate a region to store it.
1000985
...@@ -1075,7 +1060,7 @@ pub fn commitDeclDebugInfo(...@@ -1075,7 +1060,7 @@ pub fn commitDeclDebugInfo(
1075 const file_pos = debug_line_sect.offset + src_fn.off;1060 const file_pos = debug_line_sect.offset + src_fn.off;
1076 try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos);1061 try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos);
10771062
1078 // .debug_info - End the TAG_subprogram children.1063 // .debug_info - End the TAG.subprogram children.
1079 try dbg_info_buffer.append(0);1064 try dbg_info_buffer.append(0);
1080 },1065 },
1081 else => {},1066 else => {},
...@@ -1128,27 +1113,27 @@ fn addDbgInfoType(...@@ -1128,27 +1113,27 @@ fn addDbgInfoType(
1128 .Bool => {1113 .Bool => {
1129 try dbg_info_buffer.appendSlice(&[_]u8{1114 try dbg_info_buffer.appendSlice(&[_]u8{
1130 abbrev_base_type,1115 abbrev_base_type,
1131 DW.ATE_boolean, // DW.AT_encoding , DW.FORM_data11116 DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1
1132 1, // DW.AT_byte_size, DW.FORM_data11117 1, // DW.AT.byte_size, DW.FORM.data1
1133 'b',1118 'b',
1134 'o',1119 'o',
1135 'o',1120 'o',
1136 'l',1121 'l',
1137 0, // DW.AT_name, DW.FORM_string1122 0, // DW.AT.name, DW.FORM.string
1138 });1123 });
1139 },1124 },
1140 .Int => {1125 .Int => {
1141 const info = ty.intInfo(target);1126 const info = ty.intInfo(target);
1142 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);1127 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);
1143 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);1128 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
1144 // DW.AT_encoding, DW.FORM_data11129 // DW.AT.encoding, DW.FORM.data1
1145 dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {1130 dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {
1146 .signed => DW.ATE_signed,1131 .signed => DW.ATE.signed,
1147 .unsigned => DW.ATE_unsigned,1132 .unsigned => DW.ATE.unsigned,
1148 });1133 });
1149 // DW.AT_byte_size, DW.FORM_data11134 // DW.AT.byte_size, DW.FORM.data1
1150 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));1135 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
1151 // DW.AT_name, DW.FORM_string1136 // DW.AT.name, DW.FORM.string
1152 try dbg_info_buffer.writer().print("{}\x00", .{ty});1137 try dbg_info_buffer.writer().print("{}\x00", .{ty});
1153 },1138 },
1154 else => {1139 else => {
...@@ -1306,7 +1291,7 @@ fn dbgLineNeededHeaderBytes(self: DebugSymbols, module: *Module) u32 {...@@ -1306,7 +1291,7 @@ fn dbgLineNeededHeaderBytes(self: DebugSymbols, module: *Module) u32 {
1306 const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "."1291 const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "."
1307 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +1292 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +
1308 directory_count * 8 + file_name_count * 8 +1293 directory_count * 8 + file_name_count * 8 +
1309 // These are encoded as DW.FORM_string rather than DW.FORM_strp as we would like1294 // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like
1310 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.1295 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.
1311 root_src_dir_path_len +1296 root_src_dir_path_len +
1312 module.root_pkg.root_src_path.len);1297 module.root_pkg.root_src_path.len);
...@@ -1332,8 +1317,8 @@ fn pwriteDbgLineNops(...@@ -1332,8 +1317,8 @@ fn pwriteDbgLineNops(
1332 const tracy = trace(@src());1317 const tracy = trace(@src());
1333 defer tracy.end();1318 defer tracy.end();
13341319
1335 const page_of_nops = [1]u8{DW.LNS_negate_stmt} ** 4096;1320 const page_of_nops = [1]u8{DW.LNS.negate_stmt} ** 4096;
1336 const three_byte_nop = [3]u8{ DW.LNS_advance_pc, 0b1000_0000, 0 };1321 const three_byte_nop = [3]u8{ DW.LNS.advance_pc, 0b1000_0000, 0 };
1337 var vecs: [32]std.os.iovec_const = undefined;1322 var vecs: [32]std.os.iovec_const = undefined;
1338 var vec_index: usize = 0;1323 var vec_index: usize = 0;
1339 {1324 {
src/link/MachO/Object.zig+132-142
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const Object = @This();1const Object = @This();
22
3const std = @import("std");3const std = @import("std");
4const build_options = @import("build_options");
4const assert = std.debug.assert;5const assert = std.debug.assert;
5const dwarf = std.dwarf;6const dwarf = std.dwarf;
6const fs = std.fs;7const fs = std.fs;
...@@ -13,11 +14,12 @@ const sort = std.sort;...@@ -13,11 +14,12 @@ const sort = std.sort;
13const commands = @import("commands.zig");14const commands = @import("commands.zig");
14const segmentName = commands.segmentName;15const segmentName = commands.segmentName;
15const sectionName = commands.sectionName;16const sectionName = commands.sectionName;
17const trace = @import("../../tracy.zig").trace;
1618
17const Allocator = mem.Allocator;19const Allocator = mem.Allocator;
20const Atom = @import("Atom.zig");
18const LoadCommand = commands.LoadCommand;21const LoadCommand = commands.LoadCommand;
19const MachO = @import("../MachO.zig");22const MachO = @import("../MachO.zig");
20const TextBlock = @import("TextBlock.zig");
2123
22file: fs.File,24file: fs.File,
23name: []const u8,25name: []const u8,
...@@ -54,7 +56,7 @@ tu_name: ?[]const u8 = null,...@@ -54,7 +56,7 @@ tu_name: ?[]const u8 = null,
54tu_comp_dir: ?[]const u8 = null,56tu_comp_dir: ?[]const u8 = null,
55mtime: ?u64 = null,57mtime: ?u64 = null,
5658
57text_blocks: std.ArrayListUnmanaged(*TextBlock) = .{},59atoms: std.ArrayListUnmanaged(*Atom) = .{},
58sections_as_symbols: std.AutoHashMapUnmanaged(u16, u32) = .{},60sections_as_symbols: std.AutoHashMapUnmanaged(u16, u32) = .{},
5961
60// TODO symbol mapping and its inverse can probably be simple arrays62// TODO symbol mapping and its inverse can probably be simple arrays
...@@ -62,6 +64,8 @@ sections_as_symbols: std.AutoHashMapUnmanaged(u16, u32) = .{},...@@ -62,6 +64,8 @@ sections_as_symbols: std.AutoHashMapUnmanaged(u16, u32) = .{},
62symbol_mapping: std.AutoHashMapUnmanaged(u32, u32) = .{},64symbol_mapping: std.AutoHashMapUnmanaged(u32, u32) = .{},
63reverse_symbol_mapping: std.AutoHashMapUnmanaged(u32, u32) = .{},65reverse_symbol_mapping: std.AutoHashMapUnmanaged(u32, u32) = .{},
6466
67analyzed: bool = false,
68
65const DebugInfo = struct {69const DebugInfo = struct {
66 inner: dwarf.DwarfInfo,70 inner: dwarf.DwarfInfo,
67 debug_info: []u8,71 debug_info: []u8,
...@@ -134,7 +138,7 @@ pub fn deinit(self: *Object, allocator: *Allocator) void {...@@ -134,7 +138,7 @@ pub fn deinit(self: *Object, allocator: *Allocator) void {
134 self.data_in_code_entries.deinit(allocator);138 self.data_in_code_entries.deinit(allocator);
135 self.symtab.deinit(allocator);139 self.symtab.deinit(allocator);
136 self.strtab.deinit(allocator);140 self.strtab.deinit(allocator);
137 self.text_blocks.deinit(allocator);141 self.atoms.deinit(allocator);
138 self.sections_as_symbols.deinit(allocator);142 self.sections_as_symbols.deinit(allocator);
139 self.symbol_mapping.deinit(allocator);143 self.symbol_mapping.deinit(allocator);
140 self.reverse_symbol_mapping.deinit(allocator);144 self.reverse_symbol_mapping.deinit(allocator);
...@@ -316,16 +320,17 @@ const Context = struct {...@@ -316,16 +320,17 @@ const Context = struct {
316 object: *Object,320 object: *Object,
317 macho_file: *MachO,321 macho_file: *MachO,
318 match: MachO.MatchingSection,322 match: MachO.MatchingSection,
323 parsed_atoms: *ParsedAtoms,
319};324};
320325
321const TextBlockParser = struct {326const AtomParser = struct {
322 section: macho.section_64,327 section: macho.section_64,
323 code: []u8,328 code: []u8,
324 relocs: []macho.relocation_info,329 relocs: []macho.relocation_info,
325 nlists: []NlistWithIndex,330 nlists: []NlistWithIndex,
326 index: u32 = 0,331 index: u32 = 0,
327332
328 fn peek(self: TextBlockParser) ?NlistWithIndex {333 fn peek(self: AtomParser) ?NlistWithIndex {
329 return if (self.index + 1 < self.nlists.len) self.nlists[self.index + 1] else null;334 return if (self.index + 1 < self.nlists.len) self.nlists[self.index + 1] else null;
330 }335 }
331336
...@@ -339,9 +344,12 @@ const TextBlockParser = struct {...@@ -339,9 +344,12 @@ const TextBlockParser = struct {
339 }344 }
340 }345 }
341346
342 pub fn next(self: *TextBlockParser, context: Context) !?*TextBlock {347 pub fn next(self: *AtomParser, context: Context) !?*Atom {
343 if (self.index == self.nlists.len) return null;348 if (self.index == self.nlists.len) return null;
344349
350 const tracy = trace(@src());
351 defer tracy.end();
352
345 var aliases = std.ArrayList(NlistWithIndex).init(context.allocator);353 var aliases = std.ArrayList(NlistWithIndex).init(context.allocator);
346 defer aliases.deinit();354 defer aliases.deinit();
347355
...@@ -364,12 +372,12 @@ const TextBlockParser = struct {...@@ -364,12 +372,12 @@ const TextBlockParser = struct {
364 }372 }
365373
366 if (aliases.items.len > 1) {374 if (aliases.items.len > 1) {
367 // Bubble-up senior symbol as the main link to the text block.375 // Bubble-up senior symbol as the main link to the atom.
368 sort.sort(376 sort.sort(
369 NlistWithIndex,377 NlistWithIndex,
370 aliases.items,378 aliases.items,
371 context,379 context,
372 TextBlockParser.lessThanBySeniority,380 AtomParser.lessThanBySeniority,
373 );381 );
374 }382 }
375383
...@@ -389,12 +397,12 @@ const TextBlockParser = struct {...@@ -389,12 +397,12 @@ const TextBlockParser = struct {
389 else397 else
390 max_align;398 max_align;
391399
392 const stab: ?TextBlock.Stab = if (context.object.debug_info) |di| blk: {400 const stab: ?Atom.Stab = if (context.object.debug_info) |di| blk: {
393 // TODO there has to be a better to handle this.401 // TODO there has to be a better to handle this.
394 for (di.inner.func_list.items) |func| {402 for (di.inner.func_list.items) |func| {
395 if (func.pc_range) |range| {403 if (func.pc_range) |range| {
396 if (senior_nlist.nlist.n_value >= range.start and senior_nlist.nlist.n_value < range.end) {404 if (senior_nlist.nlist.n_value >= range.start and senior_nlist.nlist.n_value < range.end) {
397 break :blk TextBlock.Stab{405 break :blk Atom.Stab{
398 .function = range.end - range.start,406 .function = range.end - range.start,
399 };407 };
400 }408 }
...@@ -405,28 +413,31 @@ const TextBlockParser = struct {...@@ -405,28 +413,31 @@ const TextBlockParser = struct {
405 break :blk .static;413 break :blk .static;
406 } else null;414 } else null;
407415
408 const block = try context.allocator.create(TextBlock);416 const atom = try context.macho_file.createEmptyAtom(senior_nlist.index, size, actual_align);
409 block.* = TextBlock.empty;417 atom.stab = stab;
410 block.local_sym_index = senior_nlist.index;
411 block.stab = stab;
412 block.size = size;
413 block.alignment = actual_align;
414 try context.macho_file.managed_blocks.append(context.allocator, block);
415418
416 try block.code.appendSlice(context.allocator, code);419 const is_zerofill = blk: {
420 const section_type = commands.sectionType(self.section);
421 break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL;
422 };
423 if (!is_zerofill) {
424 mem.copy(u8, atom.code.items, code);
425 }
417426
418 try block.aliases.ensureTotalCapacity(context.allocator, aliases.items.len);427 try atom.aliases.ensureTotalCapacity(context.allocator, aliases.items.len);
419 for (aliases.items) |alias| {428 for (aliases.items) |alias| {
420 block.aliases.appendAssumeCapacity(alias.index);429 atom.aliases.appendAssumeCapacity(alias.index);
421 const sym = &context.macho_file.locals.items[alias.index];430 const sym = &context.macho_file.locals.items[alias.index];
422 sym.n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(context.match).? + 1);431 sym.n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(context.match).? + 1);
423 }432 }
424433
425 try block.parseRelocs(self.relocs, .{434 try atom.parseRelocs(self.relocs, .{
426 .base_addr = start_addr,435 .base_addr = self.section.addr,
436 .base_offset = start_addr,
427 .allocator = context.allocator,437 .allocator = context.allocator,
428 .object = context.object,438 .object = context.object,
429 .macho_file = context.macho_file,439 .macho_file = context.macho_file,
440 .parsed_atoms = context.parsed_atoms,
430 });441 });
431442
432 if (context.macho_file.has_dices) {443 if (context.macho_file.has_dices) {
...@@ -435,10 +446,10 @@ const TextBlockParser = struct {...@@ -435,10 +446,10 @@ const TextBlockParser = struct {
435 senior_nlist.nlist.n_value,446 senior_nlist.nlist.n_value,
436 senior_nlist.nlist.n_value + size,447 senior_nlist.nlist.n_value + size,
437 );448 );
438 try block.dices.ensureTotalCapacity(context.allocator, dices.len);449 try atom.dices.ensureTotalCapacity(context.allocator, dices.len);
439450
440 for (dices) |dice| {451 for (dices) |dice| {
441 block.dices.appendAssumeCapacity(.{452 atom.dices.appendAssumeCapacity(.{
442 .offset = dice.offset - try math.cast(u32, senior_nlist.nlist.n_value),453 .offset = dice.offset - try math.cast(u32, senior_nlist.nlist.n_value),
443 .length = dice.length,454 .length = dice.length,
444 .kind = dice.kind,455 .kind = dice.kind,
...@@ -448,16 +459,22 @@ const TextBlockParser = struct {...@@ -448,16 +459,22 @@ const TextBlockParser = struct {
448459
449 self.index += 1;460 self.index += 1;
450461
451 return block;462 return atom;
452 }463 }
453};464};
454465
455pub fn parseTextBlocks(466pub const ParsedAtoms = std.AutoHashMap(MachO.MatchingSection, *Atom);
467
468pub fn parseIntoAtoms(
456 self: *Object,469 self: *Object,
457 allocator: *Allocator,470 allocator: *Allocator,
458 object_id: u16,471 object_id: u16,
459 macho_file: *MachO,472 macho_file: *MachO,
460) !void {473) !ParsedAtoms {
474 const tracy = trace(@src());
475 defer tracy.end();
476
477 var parsed_atoms = ParsedAtoms.init(allocator);
461 const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;478 const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;
462479
463 log.debug("analysing {s}", .{self.name});480 log.debug("analysing {s}", .{self.name});
...@@ -498,7 +515,7 @@ pub fn parseTextBlocks(...@@ -498,7 +515,7 @@ pub fn parseTextBlocks(
498515
499 for (seg.sections.items) |sect, id| {516 for (seg.sections.items) |sect, id| {
500 const sect_id = @intCast(u8, id);517 const sect_id = @intCast(u8, id);
501 log.debug("putting section '{s},{s}' as a TextBlock", .{518 log.debug("putting section '{s},{s}' as an Atom", .{
502 segmentName(sect),519 segmentName(sect),
503 sectionName(sect),520 sectionName(sect),
504 });521 });
...@@ -523,14 +540,17 @@ pub fn parseTextBlocks(...@@ -523,14 +540,17 @@ pub fn parseTextBlocks(
523 // Symbols within this section only.540 // Symbols within this section only.
524 const filtered_nlists = NlistWithIndex.filterInSection(sorted_nlists, sect);541 const filtered_nlists = NlistWithIndex.filterInSection(sorted_nlists, sect);
525542
543 // TODO rewrite and re-enable dead-code stripping optimisation. I think it might make sense
544 // to do this in a standalone pass after we parse the sections as atoms.
526 // In release mode, if the object file was generated with dead code stripping optimisations,545 // In release mode, if the object file was generated with dead code stripping optimisations,
527 // note it now and parse sections as atoms.546 // note it now and parse sections as atoms.
528 const is_splittable = blk: {547 // const is_splittable = blk: {
529 if (macho_file.base.options.optimize_mode == .Debug) break :blk false;548 // if (macho_file.base.options.optimize_mode == .Debug) break :blk false;
530 break :blk self.header.?.flags & macho.MH_SUBSECTIONS_VIA_SYMBOLS != 0;549 // break :blk self.header.?.flags & macho.MH_SUBSECTIONS_VIA_SYMBOLS != 0;
531 };550 // };
551 const is_splittable = false;
532552
533 macho_file.has_dices = blk: {553 macho_file.has_dices = macho_file.has_dices or blk: {
534 if (self.text_section_index) |index| {554 if (self.text_section_index) |index| {
535 if (index != id) break :blk false;555 if (index != id) break :blk false;
536 if (self.data_in_code_entries.items.len == 0) break :blk false;556 if (self.data_in_code_entries.items.len == 0) break :blk false;
...@@ -541,12 +561,12 @@ pub fn parseTextBlocks(...@@ -541,12 +561,12 @@ pub fn parseTextBlocks(
541 macho_file.has_stabs = macho_file.has_stabs or self.debug_info != null;561 macho_file.has_stabs = macho_file.has_stabs or self.debug_info != null;
542562
543 next: {563 next: {
544 if (is_splittable) blocks: {564 if (is_splittable) atoms: {
545 if (filtered_nlists.len == 0) break :blocks;565 if (filtered_nlists.len == 0) break :atoms;
546566
547 // If the first nlist does not match the start of the section,567 // If the first nlist does not match the start of the section,
548 // then we need to encapsulate the memory range [section start, first symbol)568 // then we need to encapsulate the memory range [section start, first symbol)
549 // as a temporary symbol and insert the matching TextBlock.569 // as a temporary symbol and insert the matching Atom.
550 const first_nlist = filtered_nlists[0].nlist;570 const first_nlist = filtered_nlists[0].nlist;
551 if (first_nlist.n_value > sect.addr) {571 if (first_nlist.n_value > sect.addr) {
552 const sym_name = try std.fmt.allocPrint(allocator, "l_{s}_{s}_{s}", .{572 const sym_name = try std.fmt.allocPrint(allocator, "l_{s}_{s}_{s}", .{
...@@ -556,44 +576,45 @@ pub fn parseTextBlocks(...@@ -556,44 +576,45 @@ pub fn parseTextBlocks(
556 });576 });
557 defer allocator.free(sym_name);577 defer allocator.free(sym_name);
558578
559 const block_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {579 const atom_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {
560 const block_local_sym_index = @intCast(u32, macho_file.locals.items.len);580 const atom_local_sym_index = @intCast(u32, macho_file.locals.items.len);
561 try macho_file.locals.append(allocator, .{581 try macho_file.locals.append(allocator, .{
562 .n_strx = try macho_file.makeString(sym_name),582 .n_strx = try macho_file.makeString(sym_name),
563 .n_type = macho.N_SECT,583 .n_type = macho.N_SECT,
564 .n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1),584 .n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1),
565 .n_desc = 0,585 .n_desc = 0,
566 .n_value = sect.addr,586 .n_value = 0,
567 });587 });
568 try self.sections_as_symbols.putNoClobber(allocator, sect_id, block_local_sym_index);588 try self.sections_as_symbols.putNoClobber(allocator, sect_id, atom_local_sym_index);
569 break :blk block_local_sym_index;589 break :blk atom_local_sym_index;
570 };590 };
591 const atom_code = code[0 .. first_nlist.n_value - sect.addr];
592 const atom_size = atom_code.len;
593 const atom = try macho_file.createEmptyAtom(atom_local_sym_index, atom_size, sect.@"align");
571594
572 const block_code = code[0 .. first_nlist.n_value - sect.addr];595 const is_zerofill = blk: {
573 const block_size = block_code.len;596 const section_type = commands.sectionType(sect);
574597 break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL;
575 const block = try allocator.create(TextBlock);598 };
576 block.* = TextBlock.empty;599 if (!is_zerofill) {
577 block.local_sym_index = block_local_sym_index;600 mem.copy(u8, atom.code.items, atom_code);
578 block.size = block_size;601 }
579 block.alignment = sect.@"align";
580 try macho_file.managed_blocks.append(allocator, block);
581
582 try block.code.appendSlice(allocator, block_code);
583602
584 try block.parseRelocs(relocs, .{603 try atom.parseRelocs(relocs, .{
585 .base_addr = 0,604 .base_addr = sect.addr,
605 .base_offset = 0,
586 .allocator = allocator,606 .allocator = allocator,
587 .object = self,607 .object = self,
588 .macho_file = macho_file,608 .macho_file = macho_file,
609 .parsed_atoms = &parsed_atoms,
589 });610 });
590611
591 if (macho_file.has_dices) {612 if (macho_file.has_dices) {
592 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + block_size);613 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + atom_size);
593 try block.dices.ensureTotalCapacity(allocator, dices.len);614 try atom.dices.ensureTotalCapacity(allocator, dices.len);
594615
595 for (dices) |dice| {616 for (dices) |dice| {
596 block.dices.appendAssumeCapacity(.{617 atom.dices.appendAssumeCapacity(.{
597 .offset = dice.offset - try math.cast(u32, sect.addr),618 .offset = dice.offset - try math.cast(u32, sect.addr),
598 .length = dice.length,619 .length = dice.length,
599 .kind = dice.kind,620 .kind = dice.kind,
...@@ -601,29 +622,17 @@ pub fn parseTextBlocks(...@@ -601,29 +622,17 @@ pub fn parseTextBlocks(
601 }622 }
602 }623 }
603624
604 // Update target section's metadata625 if (parsed_atoms.getPtr(match)) |last| {
605 // TODO should we update segment's size here too?626 last.*.next = atom;
606 // How does it tie with incremental space allocs?627 atom.prev = last.*;
607 const tseg = &macho_file.load_commands.items[match.seg].Segment;628 last.* = atom;
608 const tsect = &tseg.sections.items[match.sect];
609 const new_alignment = math.max(tsect.@"align", block.alignment);
610 const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment);
611 const new_size = mem.alignForwardGeneric(u64, tsect.size, new_alignment_pow_2) + block.size;
612 tsect.size = new_size;
613 tsect.@"align" = new_alignment;
614
615 if (macho_file.blocks.getPtr(match)) |last| {
616 last.*.next = block;
617 block.prev = last.*;
618 last.* = block;
619 } else {629 } else {
620 try macho_file.blocks.putNoClobber(allocator, match, block);630 try parsed_atoms.putNoClobber(match, atom);
621 }631 }
622632 try self.atoms.append(allocator, atom);
623 try self.text_blocks.append(allocator, block);
624 }633 }
625634
626 var parser = TextBlockParser{635 var parser = AtomParser{
627 .section = sect,636 .section = sect,
628 .code = code,637 .code = code,
629 .relocs = relocs,638 .relocs = relocs,
...@@ -635,10 +644,11 @@ pub fn parseTextBlocks(...@@ -635,10 +644,11 @@ pub fn parseTextBlocks(
635 .object = self,644 .object = self,
636 .macho_file = macho_file,645 .macho_file = macho_file,
637 .match = match,646 .match = match,
638 })) |block| {647 .parsed_atoms = &parsed_atoms,
639 const sym = macho_file.locals.items[block.local_sym_index];648 })) |atom| {
649 const sym = macho_file.locals.items[atom.local_sym_index];
640 const is_ext = blk: {650 const is_ext = blk: {
641 const orig_sym_id = self.reverse_symbol_mapping.get(block.local_sym_index) orelse unreachable;651 const orig_sym_id = self.reverse_symbol_mapping.get(atom.local_sym_index) orelse unreachable;
642 break :blk MachO.symbolIsExt(self.symtab.items[orig_sym_id]);652 break :blk MachO.symbolIsExt(self.symtab.items[orig_sym_id]);
643 };653 };
644 if (is_ext) {654 if (is_ext) {
...@@ -662,38 +672,26 @@ pub fn parseTextBlocks(...@@ -662,38 +672,26 @@ pub fn parseTextBlocks(
662 // In x86_64 relocs, it can so happen that the compiler refers to the same672 // In x86_64 relocs, it can so happen that the compiler refers to the same
663 // atom by both the actual assigned symbol and the start of the section. In this673 // atom by both the actual assigned symbol and the start of the section. In this
664 // case, we need to link the two together so add an alias.674 // case, we need to link the two together so add an alias.
665 try block.aliases.append(allocator, alias);675 try atom.aliases.append(allocator, alias);
666 }676 }
667 }677 }
668678
669 // Update target section's metadata679 if (parsed_atoms.getPtr(match)) |last| {
670 // TODO should we update segment's size here too?680 last.*.next = atom;
671 // How does it tie with incremental space allocs?681 atom.prev = last.*;
672 const tseg = &macho_file.load_commands.items[match.seg].Segment;682 last.* = atom;
673 const tsect = &tseg.sections.items[match.sect];
674 const new_alignment = math.max(tsect.@"align", block.alignment);
675 const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment);
676 const new_size = mem.alignForwardGeneric(u64, tsect.size, new_alignment_pow_2) + block.size;
677 tsect.size = new_size;
678 tsect.@"align" = new_alignment;
679
680 if (macho_file.blocks.getPtr(match)) |last| {
681 last.*.next = block;
682 block.prev = last.*;
683 last.* = block;
684 } else {683 } else {
685 try macho_file.blocks.putNoClobber(allocator, match, block);684 try parsed_atoms.putNoClobber(match, atom);
686 }685 }
687686 try self.atoms.append(allocator, atom);
688 try self.text_blocks.append(allocator, block);
689 }687 }
690688
691 break :next;689 break :next;
692 }690 }
693691
694 // Since there is no symbol to refer to this block, we create692 // Since there is no symbol to refer to this atom, we create
695 // a temp one, unless we already did that when working out the relocations693 // a temp one, unless we already did that when working out the relocations
696 // of other text blocks.694 // of other atoms.
697 const sym_name = try std.fmt.allocPrint(allocator, "l_{s}_{s}_{s}", .{695 const sym_name = try std.fmt.allocPrint(allocator, "l_{s}_{s}_{s}", .{
698 self.name,696 self.name,
699 segmentName(sect),697 segmentName(sect),
...@@ -701,41 +699,43 @@ pub fn parseTextBlocks(...@@ -701,41 +699,43 @@ pub fn parseTextBlocks(
701 });699 });
702 defer allocator.free(sym_name);700 defer allocator.free(sym_name);
703701
704 const block_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {702 const atom_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {
705 const block_local_sym_index = @intCast(u32, macho_file.locals.items.len);703 const atom_local_sym_index = @intCast(u32, macho_file.locals.items.len);
706 try macho_file.locals.append(allocator, .{704 try macho_file.locals.append(allocator, .{
707 .n_strx = try macho_file.makeString(sym_name),705 .n_strx = try macho_file.makeString(sym_name),
708 .n_type = macho.N_SECT,706 .n_type = macho.N_SECT,
709 .n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1),707 .n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1),
710 .n_desc = 0,708 .n_desc = 0,
711 .n_value = sect.addr,709 .n_value = 0,
712 });710 });
713 try self.sections_as_symbols.putNoClobber(allocator, sect_id, block_local_sym_index);711 try self.sections_as_symbols.putNoClobber(allocator, sect_id, atom_local_sym_index);
714 break :blk block_local_sym_index;712 break :blk atom_local_sym_index;
715 };713 };
714 const atom = try macho_file.createEmptyAtom(atom_local_sym_index, sect.size, sect.@"align");
716715
717 const block = try allocator.create(TextBlock);716 const is_zerofill = blk: {
718 block.* = TextBlock.empty;717 const section_type = commands.sectionType(sect);
719 block.local_sym_index = block_local_sym_index;718 break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL;
720 block.size = sect.size;719 };
721 block.alignment = sect.@"align";720 if (!is_zerofill) {
722 try macho_file.managed_blocks.append(allocator, block);721 mem.copy(u8, atom.code.items, code);
723722 }
724 try block.code.appendSlice(allocator, code);
725723
726 try block.parseRelocs(relocs, .{724 try atom.parseRelocs(relocs, .{
727 .base_addr = 0,725 .base_addr = sect.addr,
726 .base_offset = 0,
728 .allocator = allocator,727 .allocator = allocator,
729 .object = self,728 .object = self,
730 .macho_file = macho_file,729 .macho_file = macho_file,
730 .parsed_atoms = &parsed_atoms,
731 });731 });
732732
733 if (macho_file.has_dices) {733 if (macho_file.has_dices) {
734 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + sect.size);734 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + sect.size);
735 try block.dices.ensureTotalCapacity(allocator, dices.len);735 try atom.dices.ensureTotalCapacity(allocator, dices.len);
736736
737 for (dices) |dice| {737 for (dices) |dice| {
738 block.dices.appendAssumeCapacity(.{738 atom.dices.appendAssumeCapacity(.{
739 .offset = dice.offset - try math.cast(u32, sect.addr),739 .offset = dice.offset - try math.cast(u32, sect.addr),
740 .length = dice.length,740 .length = dice.length,
741 .kind = dice.kind,741 .kind = dice.kind,
...@@ -743,12 +743,12 @@ pub fn parseTextBlocks(...@@ -743,12 +743,12 @@ pub fn parseTextBlocks(
743 }743 }
744 }744 }
745745
746 // Since this is block gets a helper local temporary symbol that didn't exist746 // Since this is atom gets a helper local temporary symbol that didn't exist
747 // in the object file which encompasses the entire section, we need traverse747 // in the object file which encompasses the entire section, we need traverse
748 // the filtered symbols and note which symbol is contained within so that748 // the filtered symbols and note which symbol is contained within so that
749 // we can properly allocate addresses down the line.749 // we can properly allocate addresses down the line.
750 // While we're at it, we need to update segment,section mapping of each symbol too.750 // While we're at it, we need to update segment,section mapping of each symbol too.
751 try block.contained.ensureTotalCapacity(allocator, filtered_nlists.len);751 try atom.contained.ensureTotalCapacity(allocator, filtered_nlists.len);
752752
753 for (filtered_nlists) |nlist_with_index| {753 for (filtered_nlists) |nlist_with_index| {
754 const nlist = nlist_with_index.nlist;754 const nlist = nlist_with_index.nlist;
...@@ -756,12 +756,12 @@ pub fn parseTextBlocks(...@@ -756,12 +756,12 @@ pub fn parseTextBlocks(
756 const local = &macho_file.locals.items[local_sym_index];756 const local = &macho_file.locals.items[local_sym_index];
757 local.n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1);757 local.n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1);
758758
759 const stab: ?TextBlock.Stab = if (self.debug_info) |di| blk: {759 const stab: ?Atom.Stab = if (self.debug_info) |di| blk: {
760 // TODO there has to be a better to handle this.760 // TODO there has to be a better to handle this.
761 for (di.inner.func_list.items) |func| {761 for (di.inner.func_list.items) |func| {
762 if (func.pc_range) |range| {762 if (func.pc_range) |range| {
763 if (nlist.n_value >= range.start and nlist.n_value < range.end) {763 if (nlist.n_value >= range.start and nlist.n_value < range.end) {
764 break :blk TextBlock.Stab{764 break :blk Atom.Stab{
765 .function = range.end - range.start,765 .function = range.end - range.start,
766 };766 };
767 }767 }
...@@ -772,35 +772,25 @@ pub fn parseTextBlocks(...@@ -772,35 +772,25 @@ pub fn parseTextBlocks(
772 break :blk .static;772 break :blk .static;
773 } else null;773 } else null;
774774
775 block.contained.appendAssumeCapacity(.{775 atom.contained.appendAssumeCapacity(.{
776 .local_sym_index = local_sym_index,776 .local_sym_index = local_sym_index,
777 .offset = nlist.n_value - sect.addr,777 .offset = nlist.n_value - sect.addr,
778 .stab = stab,778 .stab = stab,
779 });779 });
780 }780 }
781781
782 // Update target section's metadata782 if (parsed_atoms.getPtr(match)) |last| {
783 // TODO should we update segment's size here too?783 last.*.next = atom;
784 // How does it tie with incremental space allocs?784 atom.prev = last.*;
785 const tseg = &macho_file.load_commands.items[match.seg].Segment;785 last.* = atom;
786 const tsect = &tseg.sections.items[match.sect];
787 const new_alignment = math.max(tsect.@"align", block.alignment);
788 const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment);
789 const new_size = mem.alignForwardGeneric(u64, tsect.size, new_alignment_pow_2) + block.size;
790 tsect.size = new_size;
791 tsect.@"align" = new_alignment;
792
793 if (macho_file.blocks.getPtr(match)) |last| {
794 last.*.next = block;
795 block.prev = last.*;
796 last.* = block;
797 } else {786 } else {
798 try macho_file.blocks.putNoClobber(allocator, match, block);787 try parsed_atoms.putNoClobber(match, atom);
799 }788 }
800789 try self.atoms.append(allocator, atom);
801 try self.text_blocks.append(allocator, block);
802 }790 }
803 }791 }
792
793 return parsed_atoms;
804}794}
805795
806fn parseSymtab(self: *Object, allocator: *Allocator) !void {796fn parseSymtab(self: *Object, allocator: *Allocator) !void {
...@@ -836,8 +826,8 @@ pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void {...@@ -836,8 +826,8 @@ pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void {
836 },826 },
837 else => |e| return e,827 else => |e| return e,
838 };828 };
839 const name = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT_name);829 const name = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT.name);
840 const comp_dir = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT_comp_dir);830 const comp_dir = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT.comp_dir);
841831
842 self.debug_info = debug_info;832 self.debug_info = debug_info;
843 self.tu_name = try allocator.dupe(u8, name);833 self.tu_name = try allocator.dupe(u8, name);
src/link/MachO/TextBlock.zig deleted-1220
...@@ -1,1220 +0,0 @@
1const TextBlock = @This();
2
3const std = @import("std");
4const aarch64 = @import("../../codegen/aarch64.zig");
5const assert = std.debug.assert;
6const commands = @import("commands.zig");
7const log = std.log.scoped(.text_block);
8const macho = std.macho;
9const math = std.math;
10const mem = std.mem;
11const meta = std.meta;
12
13const Allocator = mem.Allocator;
14const Arch = std.Target.Cpu.Arch;
15const MachO = @import("../MachO.zig");
16const Object = @import("Object.zig");
17
18/// Each decl always gets a local symbol with the fully qualified name.
19/// The vaddr and size are found here directly.
20/// The file offset is found by computing the vaddr offset from the section vaddr
21/// the symbol references, and adding that to the file offset of the section.
22/// If this field is 0, it means the codegen size = 0 and there is no symbol or
23/// offset table entry.
24local_sym_index: u32,
25
26/// List of symbol aliases pointing to the same block via different nlists
27aliases: std.ArrayListUnmanaged(u32) = .{},
28
29/// List of symbols contained within this block
30contained: std.ArrayListUnmanaged(SymbolAtOffset) = .{},
31
32/// Code (may be non-relocated) this block represents
33code: std.ArrayListUnmanaged(u8) = .{},
34
35/// Size and alignment of this text block
36/// Unlike in Elf, we need to store the size of this symbol as part of
37/// the TextBlock since macho.nlist_64 lacks this information.
38size: u64,
39alignment: u32,
40
41relocs: std.ArrayListUnmanaged(Relocation) = .{},
42
43/// List of offsets contained within this block that need rebasing by the dynamic
44/// loader in presence of ASLR
45rebases: std.ArrayListUnmanaged(u64) = .{},
46
47/// List of offsets contained within this block that will be dynamically bound
48/// by the dynamic loader and contain pointers to resolved (at load time) extern
49/// symbols (aka proxies aka imports)
50bindings: std.ArrayListUnmanaged(SymbolAtOffset) = .{},
51
52/// List of data-in-code entries. This is currently specific to x86_64 only.
53dices: std.ArrayListUnmanaged(macho.data_in_code_entry) = .{},
54
55/// Stab entry for this block. This is currently specific to a binary created
56/// by linking object files in a traditional sense - in incremental sense, we
57/// bypass stabs altogether to produce dSYM bundle directly with fully relocated
58/// DWARF sections.
59stab: ?Stab = null,
60
61/// Points to the previous and next neighbours
62next: ?*TextBlock,
63prev: ?*TextBlock,
64
65/// Previous/next linked list pointers.
66/// This is the linked list node for this Decl's corresponding .debug_info tag.
67dbg_info_prev: ?*TextBlock,
68dbg_info_next: ?*TextBlock,
69/// Offset into .debug_info pointing to the tag for this Decl.
70dbg_info_off: u32,
71/// Size of the .debug_info tag for this Decl, not including padding.
72dbg_info_len: u32,
73
74pub const SymbolAtOffset = struct {
75 local_sym_index: u32,
76 offset: u64,
77 stab: ?Stab = null,
78
79 pub fn format(
80 self: SymbolAtOffset,
81 comptime fmt: []const u8,
82 options: std.fmt.FormatOptions,
83 writer: anytype,
84 ) !void {
85 _ = fmt;
86 _ = options;
87 try std.fmt.format(writer, "{{ {d}: .offset = {d}", .{ self.local_sym_index, self.offset });
88 if (self.stab) |stab| {
89 try std.fmt.format(writer, ", .stab = {any}", .{stab});
90 }
91 try std.fmt.format(writer, " }}", .{});
92 }
93};
94
95pub const Stab = union(enum) {
96 function: u64,
97 static,
98 global,
99
100 pub fn asNlists(stab: Stab, local_sym_index: u32, macho_file: anytype) ![]macho.nlist_64 {
101 var nlists = std.ArrayList(macho.nlist_64).init(macho_file.base.allocator);
102 defer nlists.deinit();
103
104 const sym = macho_file.locals.items[local_sym_index];
105 switch (stab) {
106 .function => |size| {
107 try nlists.ensureUnusedCapacity(4);
108 nlists.appendAssumeCapacity(.{
109 .n_strx = 0,
110 .n_type = macho.N_BNSYM,
111 .n_sect = sym.n_sect,
112 .n_desc = 0,
113 .n_value = sym.n_value,
114 });
115 nlists.appendAssumeCapacity(.{
116 .n_strx = sym.n_strx,
117 .n_type = macho.N_FUN,
118 .n_sect = sym.n_sect,
119 .n_desc = 0,
120 .n_value = sym.n_value,
121 });
122 nlists.appendAssumeCapacity(.{
123 .n_strx = 0,
124 .n_type = macho.N_FUN,
125 .n_sect = 0,
126 .n_desc = 0,
127 .n_value = size,
128 });
129 nlists.appendAssumeCapacity(.{
130 .n_strx = 0,
131 .n_type = macho.N_ENSYM,
132 .n_sect = sym.n_sect,
133 .n_desc = 0,
134 .n_value = size,
135 });
136 },
137 .global => {
138 try nlists.append(.{
139 .n_strx = sym.n_strx,
140 .n_type = macho.N_GSYM,
141 .n_sect = 0,
142 .n_desc = 0,
143 .n_value = 0,
144 });
145 },
146 .static => {
147 try nlists.append(.{
148 .n_strx = sym.n_strx,
149 .n_type = macho.N_STSYM,
150 .n_sect = sym.n_sect,
151 .n_desc = 0,
152 .n_value = sym.n_value,
153 });
154 },
155 }
156
157 return nlists.toOwnedSlice();
158 }
159};
160
161pub const Relocation = struct {
162 /// Offset within the `block`s code buffer.
163 /// Note relocation size can be inferred by relocation's kind.
164 offset: u32,
165
166 where: enum {
167 local,
168 undef,
169 },
170
171 where_index: u32,
172
173 payload: union(enum) {
174 unsigned: Unsigned,
175 branch: Branch,
176 page: Page,
177 page_off: PageOff,
178 pointer_to_got: PointerToGot,
179 signed: Signed,
180 load: Load,
181 },
182
183 const ResolveArgs = struct {
184 block: *TextBlock,
185 offset: u32,
186 source_addr: u64,
187 target_addr: u64,
188 macho_file: *MachO,
189 };
190
191 pub const Unsigned = struct {
192 subtractor: ?u32,
193
194 /// Addend embedded directly in the relocation slot
195 addend: i64,
196
197 /// Extracted from r_length:
198 /// => 3 implies true
199 /// => 2 implies false
200 /// => * is unreachable
201 is_64bit: bool,
202
203 pub fn resolve(self: Unsigned, args: ResolveArgs) !void {
204 const result = blk: {
205 if (self.subtractor) |subtractor| {
206 const sym = args.macho_file.locals.items[subtractor];
207 break :blk @intCast(i64, args.target_addr) - @intCast(i64, sym.n_value) + self.addend;
208 } else {
209 break :blk @intCast(i64, args.target_addr) + self.addend;
210 }
211 };
212
213 if (self.is_64bit) {
214 mem.writeIntLittle(u64, args.block.code.items[args.offset..][0..8], @bitCast(u64, result));
215 } else {
216 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @truncate(u32, @bitCast(u64, result)));
217 }
218 }
219
220 pub fn format(self: Unsigned, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
221 _ = fmt;
222 _ = options;
223 try std.fmt.format(writer, "Unsigned {{ ", .{});
224 if (self.subtractor) |sub| {
225 try std.fmt.format(writer, ".subtractor = {}, ", .{sub});
226 }
227 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
228 const length: usize = if (self.is_64bit) 8 else 4;
229 try std.fmt.format(writer, ".length = {}, ", .{length});
230 try std.fmt.format(writer, "}}", .{});
231 }
232 };
233
234 pub const Branch = struct {
235 arch: Arch,
236
237 pub fn resolve(self: Branch, args: ResolveArgs) !void {
238 switch (self.arch) {
239 .aarch64 => {
240 const displacement = try math.cast(
241 i28,
242 @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr),
243 );
244 const code = args.block.code.items[args.offset..][0..4];
245 var inst = aarch64.Instruction{
246 .unconditional_branch_immediate = mem.bytesToValue(meta.TagPayload(
247 aarch64.Instruction,
248 aarch64.Instruction.unconditional_branch_immediate,
249 ), code),
250 };
251 inst.unconditional_branch_immediate.imm26 = @truncate(u26, @bitCast(u28, displacement >> 2));
252 mem.writeIntLittle(u32, code, inst.toU32());
253 },
254 .x86_64 => {
255 const displacement = try math.cast(
256 i32,
257 @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr) - 4,
258 );
259 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @bitCast(u32, displacement));
260 },
261 else => return error.UnsupportedCpuArchitecture,
262 }
263 }
264
265 pub fn format(self: Branch, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
266 _ = self;
267 _ = fmt;
268 _ = options;
269 try std.fmt.format(writer, "Branch {{}}", .{});
270 }
271 };
272
273 pub const Page = struct {
274 kind: enum {
275 page,
276 got,
277 tlvp,
278 },
279 addend: u32 = 0,
280
281 pub fn resolve(self: Page, args: ResolveArgs) !void {
282 const target_addr = args.target_addr + self.addend;
283 const source_page = @intCast(i32, args.source_addr >> 12);
284 const target_page = @intCast(i32, target_addr >> 12);
285 const pages = @bitCast(u21, @intCast(i21, target_page - source_page));
286
287 const code = args.block.code.items[args.offset..][0..4];
288 var inst = aarch64.Instruction{
289 .pc_relative_address = mem.bytesToValue(meta.TagPayload(
290 aarch64.Instruction,
291 aarch64.Instruction.pc_relative_address,
292 ), code),
293 };
294 inst.pc_relative_address.immhi = @truncate(u19, pages >> 2);
295 inst.pc_relative_address.immlo = @truncate(u2, pages);
296
297 mem.writeIntLittle(u32, code, inst.toU32());
298 }
299
300 pub fn format(self: Page, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
301 _ = fmt;
302 _ = options;
303 try std.fmt.format(writer, "Page {{ ", .{});
304 switch (self.kind) {
305 .page => {},
306 .got => {
307 try std.fmt.format(writer, ".got, ", .{});
308 },
309 .tlvp => {
310 try std.fmt.format(writer, ".tlvp", .{});
311 },
312 }
313 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
314 try std.fmt.format(writer, "}}", .{});
315 }
316 };
317
318 pub const PageOff = struct {
319 kind: enum {
320 page,
321 got,
322 tlvp,
323 },
324 addend: u32 = 0,
325 op_kind: ?OpKind = null,
326
327 pub const OpKind = enum {
328 arithmetic,
329 load,
330 };
331
332 pub fn resolve(self: PageOff, args: ResolveArgs) !void {
333 const code = args.block.code.items[args.offset..][0..4];
334
335 switch (self.kind) {
336 .page => {
337 const target_addr = args.target_addr + self.addend;
338 const narrowed = @truncate(u12, target_addr);
339
340 const op_kind = self.op_kind orelse unreachable;
341 var inst: aarch64.Instruction = blk: {
342 switch (op_kind) {
343 .arithmetic => {
344 break :blk .{
345 .add_subtract_immediate = mem.bytesToValue(meta.TagPayload(
346 aarch64.Instruction,
347 aarch64.Instruction.add_subtract_immediate,
348 ), code),
349 };
350 },
351 .load => {
352 break :blk .{
353 .load_store_register = mem.bytesToValue(meta.TagPayload(
354 aarch64.Instruction,
355 aarch64.Instruction.load_store_register,
356 ), code),
357 };
358 },
359 }
360 };
361
362 if (op_kind == .arithmetic) {
363 inst.add_subtract_immediate.imm12 = narrowed;
364 } else {
365 const offset: u12 = blk: {
366 if (inst.load_store_register.size == 0) {
367 if (inst.load_store_register.v == 1) {
368 // 128-bit SIMD is scaled by 16.
369 break :blk try math.divExact(u12, narrowed, 16);
370 }
371 // Otherwise, 8-bit SIMD or ldrb.
372 break :blk narrowed;
373 } else {
374 const denom: u4 = try math.powi(u4, 2, inst.load_store_register.size);
375 break :blk try math.divExact(u12, narrowed, denom);
376 }
377 };
378 inst.load_store_register.offset = offset;
379 }
380
381 mem.writeIntLittle(u32, code, inst.toU32());
382 },
383 .got => {
384 const narrowed = @truncate(u12, args.target_addr);
385 var inst: aarch64.Instruction = .{
386 .load_store_register = mem.bytesToValue(meta.TagPayload(
387 aarch64.Instruction,
388 aarch64.Instruction.load_store_register,
389 ), code),
390 };
391 const offset = try math.divExact(u12, narrowed, 8);
392 inst.load_store_register.offset = offset;
393 mem.writeIntLittle(u32, code, inst.toU32());
394 },
395 .tlvp => {
396 const RegInfo = struct {
397 rd: u5,
398 rn: u5,
399 size: u1,
400 };
401 const reg_info: RegInfo = blk: {
402 if (isArithmeticOp(code)) {
403 const inst = mem.bytesToValue(meta.TagPayload(
404 aarch64.Instruction,
405 aarch64.Instruction.add_subtract_immediate,
406 ), code);
407 break :blk .{
408 .rd = inst.rd,
409 .rn = inst.rn,
410 .size = inst.sf,
411 };
412 } else {
413 const inst = mem.bytesToValue(meta.TagPayload(
414 aarch64.Instruction,
415 aarch64.Instruction.load_store_register,
416 ), code);
417 break :blk .{
418 .rd = inst.rt,
419 .rn = inst.rn,
420 .size = @truncate(u1, inst.size),
421 };
422 }
423 };
424 const narrowed = @truncate(u12, args.target_addr);
425 var inst = aarch64.Instruction{
426 .add_subtract_immediate = .{
427 .rd = reg_info.rd,
428 .rn = reg_info.rn,
429 .imm12 = narrowed,
430 .sh = 0,
431 .s = 0,
432 .op = 0,
433 .sf = reg_info.size,
434 },
435 };
436 mem.writeIntLittle(u32, code, inst.toU32());
437 },
438 }
439 }
440
441 pub fn format(self: PageOff, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
442 _ = fmt;
443 _ = options;
444 try std.fmt.format(writer, "PageOff {{ ", .{});
445 switch (self.kind) {
446 .page => {},
447 .got => {
448 try std.fmt.format(writer, ".got, ", .{});
449 },
450 .tlvp => {
451 try std.fmt.format(writer, ".tlvp, ", .{});
452 },
453 }
454 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
455 try std.fmt.format(writer, ".op_kind = {s}, ", .{self.op_kind});
456 try std.fmt.format(writer, "}}", .{});
457 }
458 };
459
460 pub const PointerToGot = struct {
461 pub fn resolve(_: PointerToGot, args: ResolveArgs) !void {
462 const result = try math.cast(i32, @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr));
463 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @bitCast(u32, result));
464 }
465
466 pub fn format(self: PointerToGot, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
467 _ = self;
468 _ = fmt;
469 _ = options;
470 try std.fmt.format(writer, "PointerToGot {{}}", .{});
471 }
472 };
473
474 pub const Signed = struct {
475 addend: i64,
476 correction: i4,
477
478 pub fn resolve(self: Signed, args: ResolveArgs) !void {
479 const target_addr = @intCast(i64, args.target_addr) + self.addend;
480 const displacement = try math.cast(
481 i32,
482 target_addr - @intCast(i64, args.source_addr) - self.correction - 4,
483 );
484 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @bitCast(u32, displacement));
485 }
486
487 pub fn format(self: Signed, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
488 _ = fmt;
489 _ = options;
490 try std.fmt.format(writer, "Signed {{ ", .{});
491 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
492 try std.fmt.format(writer, ".correction = {}, ", .{self.correction});
493 try std.fmt.format(writer, "}}", .{});
494 }
495 };
496
497 pub const Load = struct {
498 kind: enum {
499 got,
500 tlvp,
501 },
502 addend: i32 = 0,
503
504 pub fn resolve(self: Load, args: ResolveArgs) !void {
505 if (self.kind == .tlvp) {
506 // We need to rewrite the opcode from movq to leaq.
507 args.block.code.items[args.offset - 2] = 0x8d;
508 }
509 const displacement = try math.cast(
510 i32,
511 @intCast(i64, args.target_addr) - @intCast(i64, args.source_addr) - 4 + self.addend,
512 );
513 mem.writeIntLittle(u32, args.block.code.items[args.offset..][0..4], @bitCast(u32, displacement));
514 }
515
516 pub fn format(self: Load, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
517 _ = fmt;
518 _ = options;
519 try std.fmt.format(writer, "Load {{ ", .{});
520 try std.fmt.format(writer, "{s}, ", .{self.kind});
521 try std.fmt.format(writer, ".addend = {}, ", .{self.addend});
522 try std.fmt.format(writer, "}}", .{});
523 }
524 };
525
526 pub fn resolve(self: Relocation, args: ResolveArgs) !void {
527 switch (self.payload) {
528 .unsigned => |unsigned| try unsigned.resolve(args),
529 .branch => |branch| try branch.resolve(args),
530 .page => |page| try page.resolve(args),
531 .page_off => |page_off| try page_off.resolve(args),
532 .pointer_to_got => |pointer_to_got| try pointer_to_got.resolve(args),
533 .signed => |signed| try signed.resolve(args),
534 .load => |load| try load.resolve(args),
535 }
536 }
537
538 pub fn format(self: Relocation, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
539 try std.fmt.format(writer, "Relocation {{ ", .{});
540 try std.fmt.format(writer, ".offset = {}, ", .{self.offset});
541 try std.fmt.format(writer, ".where = {}, ", .{self.where});
542 try std.fmt.format(writer, ".where_index = {d}, ", .{self.where_index});
543
544 switch (self.payload) {
545 .unsigned => |unsigned| try unsigned.format(fmt, options, writer),
546 .branch => |branch| try branch.format(fmt, options, writer),
547 .page => |page| try page.format(fmt, options, writer),
548 .page_off => |page_off| try page_off.format(fmt, options, writer),
549 .pointer_to_got => |pointer_to_got| try pointer_to_got.format(fmt, options, writer),
550 .signed => |signed| try signed.format(fmt, options, writer),
551 .load => |load| try load.format(fmt, options, writer),
552 }
553
554 try std.fmt.format(writer, "}}", .{});
555 }
556};
557
558pub const empty = TextBlock{
559 .local_sym_index = 0,
560 .size = 0,
561 .alignment = 0,
562 .prev = null,
563 .next = null,
564 .dbg_info_prev = null,
565 .dbg_info_next = null,
566 .dbg_info_off = undefined,
567 .dbg_info_len = undefined,
568};
569
570pub fn deinit(self: *TextBlock, allocator: *Allocator) void {
571 self.dices.deinit(allocator);
572 self.bindings.deinit(allocator);
573 self.rebases.deinit(allocator);
574 self.relocs.deinit(allocator);
575 self.contained.deinit(allocator);
576 self.aliases.deinit(allocator);
577 self.code.deinit(allocator);
578}
579
580/// Returns how much room there is to grow in virtual address space.
581/// File offset relocation happens transparently, so it is not included in
582/// this calculation.
583pub fn capacity(self: TextBlock, macho_file: MachO) u64 {
584 const self_sym = macho_file.locals.items[self.local_sym_index];
585 if (self.next) |next| {
586 const next_sym = macho_file.locals.items[next.local_sym_index];
587 return next_sym.n_value - self_sym.n_value;
588 } else {
589 // We are the last block.
590 // The capacity is limited only by virtual address space.
591 return std.math.maxInt(u64) - self_sym.n_value;
592 }
593}
594
595pub fn freeListEligible(self: TextBlock, macho_file: MachO) bool {
596 // No need to keep a free list node for the last block.
597 const next = self.next orelse return false;
598 const self_sym = macho_file.locals.items[self.local_sym_index];
599 const next_sym = macho_file.locals.items[next.local_sym_index];
600 const cap = next_sym.n_value - self_sym.n_value;
601 const ideal_cap = MachO.padToIdeal(self.size);
602 if (cap <= ideal_cap) return false;
603 const surplus = cap - ideal_cap;
604 return surplus >= MachO.min_text_capacity;
605}
606
607const RelocContext = struct {
608 base_addr: u64 = 0,
609 allocator: *Allocator,
610 object: *Object,
611 macho_file: *MachO,
612};
613
614fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Relocation {
615 var parsed_rel = Relocation{
616 .offset = @intCast(u32, @intCast(u64, rel.r_address) - context.base_addr),
617 .where = undefined,
618 .where_index = undefined,
619 .payload = undefined,
620 };
621
622 if (rel.r_extern == 0) {
623 const sect_id = @intCast(u16, rel.r_symbolnum - 1);
624
625 const local_sym_index = context.object.sections_as_symbols.get(sect_id) orelse blk: {
626 const seg = context.object.load_commands.items[context.object.segment_cmd_index.?].Segment;
627 const sect = seg.sections.items[sect_id];
628 const match = (try context.macho_file.getMatchingSection(sect)) orelse unreachable;
629 const local_sym_index = @intCast(u32, context.macho_file.locals.items.len);
630 const sym_name = try std.fmt.allocPrint(context.allocator, "l_{s}_{s}_{s}", .{
631 context.object.name,
632 commands.segmentName(sect),
633 commands.sectionName(sect),
634 });
635 defer context.allocator.free(sym_name);
636
637 try context.macho_file.locals.append(context.allocator, .{
638 .n_strx = try context.macho_file.makeString(sym_name),
639 .n_type = macho.N_SECT,
640 .n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(match).? + 1),
641 .n_desc = 0,
642 .n_value = sect.addr,
643 });
644 try context.object.sections_as_symbols.putNoClobber(context.allocator, sect_id, local_sym_index);
645 break :blk local_sym_index;
646 };
647
648 parsed_rel.where = .local;
649 parsed_rel.where_index = local_sym_index;
650 } else {
651 const sym = context.object.symtab.items[rel.r_symbolnum];
652 const sym_name = context.object.getString(sym.n_strx);
653
654 if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
655 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
656 parsed_rel.where = .local;
657 parsed_rel.where_index = where_index;
658 } else {
659 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
660 .strtab = &context.macho_file.strtab,
661 }) orelse unreachable;
662 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
663 switch (resolv.where) {
664 .global => {
665 parsed_rel.where = .local;
666 parsed_rel.where_index = resolv.local_sym_index;
667 },
668 .undef => {
669 parsed_rel.where = .undef;
670 parsed_rel.where_index = resolv.where_index;
671 },
672 }
673 }
674 }
675
676 return parsed_rel;
677}
678
679pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: RelocContext) !void {
680 const filtered_relocs = filterRelocs(relocs, context.base_addr, context.base_addr + self.size);
681 var it = RelocIterator{
682 .buffer = filtered_relocs,
683 };
684
685 var addend: u32 = 0;
686 var subtractor: ?u32 = null;
687 const arch = context.macho_file.base.options.target.cpu.arch;
688
689 while (it.next()) |rel| {
690 if (isAddend(rel, arch)) {
691 // Addend is not a relocation with effect on the TextBlock, so
692 // parse it and carry on.
693 assert(addend == 0); // Oh no, addend was not reset!
694 addend = rel.r_symbolnum;
695
696 // Verify ADDEND is followed by a PAGE21 or PAGEOFF12.
697 const next = @intToEnum(macho.reloc_type_arm64, it.peek().r_type);
698 switch (next) {
699 .ARM64_RELOC_PAGE21, .ARM64_RELOC_PAGEOFF12 => {},
700 else => {
701 log.err("unexpected relocation type: expected PAGE21 or PAGEOFF12, found {s}", .{next});
702 return error.UnexpectedRelocationType;
703 },
704 }
705 continue;
706 }
707
708 if (isSubtractor(rel, arch)) {
709 // Subtractor is not a relocation with effect on the TextBlock, so
710 // parse it and carry on.
711 assert(subtractor == null); // Oh no, subtractor was not reset!
712 assert(rel.r_extern == 1);
713 const sym = context.object.symtab.items[rel.r_symbolnum];
714 const sym_name = context.object.getString(sym.n_strx);
715
716 if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
717 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
718 subtractor = where_index;
719 } else {
720 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
721 .strtab = &context.macho_file.strtab,
722 }) orelse unreachable;
723 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
724 assert(resolv.where == .global);
725 subtractor = resolv.local_sym_index;
726 }
727
728 // Verify SUBTRACTOR is followed by UNSIGNED.
729 switch (arch) {
730 .aarch64 => {
731 const next = @intToEnum(macho.reloc_type_arm64, it.peek().r_type);
732 if (next != .ARM64_RELOC_UNSIGNED) {
733 log.err("unexpected relocation type: expected UNSIGNED, found {s}", .{next});
734 return error.UnexpectedRelocationType;
735 }
736 },
737 .x86_64 => {
738 const next = @intToEnum(macho.reloc_type_x86_64, it.peek().r_type);
739 if (next != .X86_64_RELOC_UNSIGNED) {
740 log.err("unexpected relocation type: expected UNSIGNED, found {s}", .{next});
741 return error.UnexpectedRelocationType;
742 }
743 },
744 else => unreachable,
745 }
746 continue;
747 }
748
749 var parsed_rel = try initRelocFromObject(rel, context);
750
751 switch (arch) {
752 .aarch64 => {
753 const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type);
754 switch (rel_type) {
755 .ARM64_RELOC_ADDEND => unreachable,
756 .ARM64_RELOC_SUBTRACTOR => unreachable,
757 .ARM64_RELOC_BRANCH26 => {
758 self.parseBranch(rel, &parsed_rel, context);
759 },
760 .ARM64_RELOC_UNSIGNED => {
761 self.parseUnsigned(rel, &parsed_rel, subtractor, context);
762 subtractor = null;
763 },
764 .ARM64_RELOC_PAGE21,
765 .ARM64_RELOC_GOT_LOAD_PAGE21,
766 .ARM64_RELOC_TLVP_LOAD_PAGE21,
767 => {
768 self.parsePage(rel, &parsed_rel, addend);
769 if (rel_type == .ARM64_RELOC_PAGE21)
770 addend = 0;
771 },
772 .ARM64_RELOC_PAGEOFF12,
773 .ARM64_RELOC_GOT_LOAD_PAGEOFF12,
774 .ARM64_RELOC_TLVP_LOAD_PAGEOFF12,
775 => {
776 self.parsePageOff(rel, &parsed_rel, addend);
777 if (rel_type == .ARM64_RELOC_PAGEOFF12)
778 addend = 0;
779 },
780 .ARM64_RELOC_POINTER_TO_GOT => {
781 self.parsePointerToGot(rel, &parsed_rel);
782 },
783 }
784 },
785 .x86_64 => {
786 switch (@intToEnum(macho.reloc_type_x86_64, rel.r_type)) {
787 .X86_64_RELOC_SUBTRACTOR => unreachable,
788 .X86_64_RELOC_BRANCH => {
789 self.parseBranch(rel, &parsed_rel, context);
790 },
791 .X86_64_RELOC_UNSIGNED => {
792 self.parseUnsigned(rel, &parsed_rel, subtractor, context);
793 subtractor = null;
794 },
795 .X86_64_RELOC_SIGNED,
796 .X86_64_RELOC_SIGNED_1,
797 .X86_64_RELOC_SIGNED_2,
798 .X86_64_RELOC_SIGNED_4,
799 => {
800 self.parseSigned(rel, &parsed_rel, context);
801 },
802 .X86_64_RELOC_GOT_LOAD,
803 .X86_64_RELOC_GOT,
804 .X86_64_RELOC_TLV,
805 => {
806 self.parseLoad(rel, &parsed_rel);
807 },
808 }
809 },
810 else => unreachable,
811 }
812
813 try self.relocs.append(context.allocator, parsed_rel);
814
815 const is_via_got = switch (parsed_rel.payload) {
816 .pointer_to_got => true,
817 .load => |load| load.kind == .got,
818 .page => |page| page.kind == .got,
819 .page_off => |page_off| page_off.kind == .got,
820 else => false,
821 };
822
823 if (is_via_got) blk: {
824 const key = MachO.GotIndirectionKey{
825 .where = switch (parsed_rel.where) {
826 .local => .local,
827 .undef => .undef,
828 },
829 .where_index = parsed_rel.where_index,
830 };
831 if (context.macho_file.got_entries_map.contains(key)) break :blk;
832
833 const got_index = @intCast(u32, context.macho_file.got_entries.items.len);
834 try context.macho_file.got_entries.append(context.allocator, key);
835 try context.macho_file.got_entries_map.putNoClobber(context.allocator, key, got_index);
836 } else if (parsed_rel.payload == .unsigned) {
837 switch (parsed_rel.where) {
838 .undef => {
839 try self.bindings.append(context.allocator, .{
840 .local_sym_index = parsed_rel.where_index,
841 .offset = parsed_rel.offset,
842 });
843 },
844 .local => {
845 const source_sym = context.macho_file.locals.items[self.local_sym_index];
846 const match = context.macho_file.section_ordinals.keys()[source_sym.n_sect - 1];
847 const seg = context.macho_file.load_commands.items[match.seg].Segment;
848 const sect = seg.sections.items[match.sect];
849 const sect_type = commands.sectionType(sect);
850
851 const should_rebase = rebase: {
852 if (!parsed_rel.payload.unsigned.is_64bit) break :rebase false;
853
854 // TODO actually, a check similar to what dyld is doing, that is, verifying
855 // that the segment is writable should be enough here.
856 const is_right_segment = blk: {
857 if (context.macho_file.data_segment_cmd_index) |idx| {
858 if (match.seg == idx) {
859 break :blk true;
860 }
861 }
862 if (context.macho_file.data_const_segment_cmd_index) |idx| {
863 if (match.seg == idx) {
864 break :blk true;
865 }
866 }
867 break :blk false;
868 };
869
870 if (!is_right_segment) break :rebase false;
871 if (sect_type != macho.S_LITERAL_POINTERS and
872 sect_type != macho.S_REGULAR and
873 sect_type != macho.S_MOD_INIT_FUNC_POINTERS and
874 sect_type != macho.S_MOD_TERM_FUNC_POINTERS)
875 {
876 break :rebase false;
877 }
878
879 break :rebase true;
880 };
881
882 if (should_rebase) {
883 try self.rebases.append(context.allocator, parsed_rel.offset);
884 }
885 },
886 }
887 } else if (parsed_rel.payload == .branch) blk: {
888 if (parsed_rel.where != .undef) break :blk;
889 if (context.macho_file.stubs_map.contains(parsed_rel.where_index)) break :blk;
890
891 const stubs_index = @intCast(u32, context.macho_file.stubs.items.len);
892 try context.macho_file.stubs.append(context.allocator, parsed_rel.where_index);
893 try context.macho_file.stubs_map.putNoClobber(context.allocator, parsed_rel.where_index, stubs_index);
894 }
895 }
896}
897
898fn isAddend(rel: macho.relocation_info, arch: Arch) bool {
899 if (arch != .aarch64) return false;
900 return @intToEnum(macho.reloc_type_arm64, rel.r_type) == .ARM64_RELOC_ADDEND;
901}
902
903fn isSubtractor(rel: macho.relocation_info, arch: Arch) bool {
904 return switch (arch) {
905 .aarch64 => @intToEnum(macho.reloc_type_arm64, rel.r_type) == .ARM64_RELOC_SUBTRACTOR,
906 .x86_64 => @intToEnum(macho.reloc_type_x86_64, rel.r_type) == .X86_64_RELOC_SUBTRACTOR,
907 else => unreachable,
908 };
909}
910
911fn parseUnsigned(
912 self: TextBlock,
913 rel: macho.relocation_info,
914 out: *Relocation,
915 subtractor: ?u32,
916 context: RelocContext,
917) void {
918 assert(rel.r_pcrel == 0);
919
920 const is_64bit: bool = switch (rel.r_length) {
921 3 => true,
922 2 => false,
923 else => unreachable,
924 };
925
926 var addend: i64 = if (is_64bit)
927 mem.readIntLittle(i64, self.code.items[out.offset..][0..8])
928 else
929 mem.readIntLittle(i32, self.code.items[out.offset..][0..4]);
930
931 if (rel.r_extern == 0) {
932 assert(out.where == .local);
933 const target_sym = context.macho_file.locals.items[out.where_index];
934 addend -= @intCast(i64, target_sym.n_value);
935 }
936
937 out.payload = .{
938 .unsigned = .{
939 .subtractor = subtractor,
940 .is_64bit = is_64bit,
941 .addend = addend,
942 },
943 };
944}
945
946fn parseBranch(self: TextBlock, rel: macho.relocation_info, out: *Relocation, context: RelocContext) void {
947 _ = self;
948 assert(rel.r_pcrel == 1);
949 assert(rel.r_length == 2);
950
951 out.payload = .{
952 .branch = .{
953 .arch = context.macho_file.base.options.target.cpu.arch,
954 },
955 };
956}
957
958fn parsePage(self: TextBlock, rel: macho.relocation_info, out: *Relocation, addend: u32) void {
959 _ = self;
960 assert(rel.r_pcrel == 1);
961 assert(rel.r_length == 2);
962
963 out.payload = .{
964 .page = .{
965 .kind = switch (@intToEnum(macho.reloc_type_arm64, rel.r_type)) {
966 .ARM64_RELOC_PAGE21 => .page,
967 .ARM64_RELOC_GOT_LOAD_PAGE21 => .got,
968 .ARM64_RELOC_TLVP_LOAD_PAGE21 => .tlvp,
969 else => unreachable,
970 },
971 .addend = addend,
972 },
973 };
974}
975
976fn parsePageOff(self: TextBlock, rel: macho.relocation_info, out: *Relocation, addend: u32) void {
977 assert(rel.r_pcrel == 0);
978 assert(rel.r_length == 2);
979
980 const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type);
981 const op_kind: ?Relocation.PageOff.OpKind = blk: {
982 if (rel_type != .ARM64_RELOC_PAGEOFF12) break :blk null;
983 const op_kind: Relocation.PageOff.OpKind = if (isArithmeticOp(self.code.items[out.offset..][0..4]))
984 .arithmetic
985 else
986 .load;
987 break :blk op_kind;
988 };
989
990 out.payload = .{
991 .page_off = .{
992 .kind = switch (rel_type) {
993 .ARM64_RELOC_PAGEOFF12 => .page,
994 .ARM64_RELOC_GOT_LOAD_PAGEOFF12 => .got,
995 .ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => .tlvp,
996 else => unreachable,
997 },
998 .addend = addend,
999 .op_kind = op_kind,
1000 },
1001 };
1002}
1003
1004fn parsePointerToGot(self: TextBlock, rel: macho.relocation_info, out: *Relocation) void {
1005 _ = self;
1006 assert(rel.r_pcrel == 1);
1007 assert(rel.r_length == 2);
1008
1009 out.payload = .{
1010 .pointer_to_got = .{},
1011 };
1012}
1013
1014fn parseSigned(self: TextBlock, rel: macho.relocation_info, out: *Relocation, context: RelocContext) void {
1015 assert(rel.r_pcrel == 1);
1016 assert(rel.r_length == 2);
1017
1018 const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type);
1019 const correction: i4 = switch (rel_type) {
1020 .X86_64_RELOC_SIGNED => 0,
1021 .X86_64_RELOC_SIGNED_1 => 1,
1022 .X86_64_RELOC_SIGNED_2 => 2,
1023 .X86_64_RELOC_SIGNED_4 => 4,
1024 else => unreachable,
1025 };
1026 var addend: i64 = mem.readIntLittle(i32, self.code.items[out.offset..][0..4]) + correction;
1027
1028 if (rel.r_extern == 0) {
1029 const source_sym = context.macho_file.locals.items[self.local_sym_index];
1030 const target_sym = switch (out.where) {
1031 .local => context.macho_file.locals.items[out.where_index],
1032 .undef => context.macho_file.undefs.items[out.where_index],
1033 };
1034 addend = @intCast(i64, source_sym.n_value + out.offset + 4) + addend - @intCast(i64, target_sym.n_value);
1035 }
1036
1037 out.payload = .{
1038 .signed = .{
1039 .correction = correction,
1040 .addend = addend,
1041 },
1042 };
1043}
1044
1045fn parseLoad(self: TextBlock, rel: macho.relocation_info, out: *Relocation) void {
1046 assert(rel.r_pcrel == 1);
1047 assert(rel.r_length == 2);
1048
1049 const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type);
1050 const addend: i32 = if (rel_type == .X86_64_RELOC_GOT)
1051 mem.readIntLittle(i32, self.code.items[out.offset..][0..4])
1052 else
1053 0;
1054
1055 out.payload = .{
1056 .load = .{
1057 .kind = switch (rel_type) {
1058 .X86_64_RELOC_GOT_LOAD, .X86_64_RELOC_GOT => .got,
1059 .X86_64_RELOC_TLV => .tlvp,
1060 else => unreachable,
1061 },
1062 .addend = addend,
1063 },
1064 };
1065}
1066
1067pub fn resolveRelocs(self: *TextBlock, macho_file: *MachO) !void {
1068 for (self.relocs.items) |rel| {
1069 log.debug("relocating {}", .{rel});
1070
1071 const source_addr = blk: {
1072 const sym = macho_file.locals.items[self.local_sym_index];
1073 break :blk sym.n_value + rel.offset;
1074 };
1075 const target_addr = blk: {
1076 const is_via_got = switch (rel.payload) {
1077 .pointer_to_got => true,
1078 .page => |page| page.kind == .got,
1079 .page_off => |page_off| page_off.kind == .got,
1080 .load => |load| load.kind == .got,
1081 else => false,
1082 };
1083
1084 if (is_via_got) {
1085 const dc_seg = macho_file.load_commands.items[macho_file.data_const_segment_cmd_index.?].Segment;
1086 const got = dc_seg.sections.items[macho_file.got_section_index.?];
1087 const got_index = macho_file.got_entries_map.get(.{
1088 .where = switch (rel.where) {
1089 .local => .local,
1090 .undef => .undef,
1091 },
1092 .where_index = rel.where_index,
1093 }) orelse {
1094 const sym = switch (rel.where) {
1095 .local => macho_file.locals.items[rel.where_index],
1096 .undef => macho_file.undefs.items[rel.where_index],
1097 };
1098 log.err("expected GOT entry for symbol '{s}'", .{macho_file.getString(sym.n_strx)});
1099 log.err(" this is an internal linker error", .{});
1100 return error.FailedToResolveRelocationTarget;
1101 };
1102 break :blk got.addr + got_index * @sizeOf(u64);
1103 }
1104
1105 switch (rel.where) {
1106 .local => {
1107 const sym = macho_file.locals.items[rel.where_index];
1108 const is_tlv = is_tlv: {
1109 const source_sym = macho_file.locals.items[self.local_sym_index];
1110 const match = macho_file.section_ordinals.keys()[source_sym.n_sect - 1];
1111 const seg = macho_file.load_commands.items[match.seg].Segment;
1112 const sect = seg.sections.items[match.sect];
1113 break :is_tlv commands.sectionType(sect) == macho.S_THREAD_LOCAL_VARIABLES;
1114 };
1115 if (is_tlv) {
1116 // For TLV relocations, the value specified as a relocation is the displacement from the
1117 // TLV initializer (either value in __thread_data or zero-init in __thread_bss) to the first
1118 // defined TLV template init section in the following order:
1119 // * wrt to __thread_data if defined, then
1120 // * wrt to __thread_bss
1121 const seg = macho_file.load_commands.items[macho_file.data_segment_cmd_index.?].Segment;
1122 const base_address = inner: {
1123 if (macho_file.tlv_data_section_index) |i| {
1124 break :inner seg.sections.items[i].addr;
1125 } else if (macho_file.tlv_bss_section_index) |i| {
1126 break :inner seg.sections.items[i].addr;
1127 } else {
1128 log.err("threadlocal variables present but no initializer sections found", .{});
1129 log.err(" __thread_data not found", .{});
1130 log.err(" __thread_bss not found", .{});
1131 return error.FailedToResolveRelocationTarget;
1132 }
1133 };
1134 break :blk sym.n_value - base_address;
1135 }
1136
1137 break :blk sym.n_value;
1138 },
1139 .undef => {
1140 const stubs_index = macho_file.stubs_map.get(rel.where_index) orelse {
1141 // TODO verify in TextBlock that the symbol is indeed dynamically bound.
1142 break :blk 0; // Dynamically bound by dyld.
1143 };
1144 const segment = macho_file.load_commands.items[macho_file.text_segment_cmd_index.?].Segment;
1145 const stubs = segment.sections.items[macho_file.stubs_section_index.?];
1146 break :blk stubs.addr + stubs_index * stubs.reserved2;
1147 },
1148 }
1149 };
1150
1151 log.debug(" | source_addr = 0x{x}", .{source_addr});
1152 log.debug(" | target_addr = 0x{x}", .{target_addr});
1153
1154 try rel.resolve(.{
1155 .block = self,
1156 .offset = rel.offset,
1157 .source_addr = source_addr,
1158 .target_addr = target_addr,
1159 .macho_file = macho_file,
1160 });
1161 }
1162}
1163
1164pub fn format(self: TextBlock, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
1165 _ = fmt;
1166 _ = options;
1167 try std.fmt.format(writer, "TextBlock {{ ", .{});
1168 try std.fmt.format(writer, ".local_sym_index = {d}, ", .{self.local_sym_index});
1169 try std.fmt.format(writer, ".aliases = {any}, ", .{self.aliases.items});
1170 try std.fmt.format(writer, ".contained = {any}, ", .{self.contained.items});
1171 try std.fmt.format(writer, ".code = {*}, ", .{self.code.items});
1172 try std.fmt.format(writer, ".size = {d}, ", .{self.size});
1173 try std.fmt.format(writer, ".alignment = {d}, ", .{self.alignment});
1174 try std.fmt.format(writer, ".relocs = {any}, ", .{self.relocs.items});
1175 try std.fmt.format(writer, ".rebases = {any}, ", .{self.rebases.items});
1176 try std.fmt.format(writer, ".bindings = {any}, ", .{self.bindings.items});
1177 try std.fmt.format(writer, ".dices = {any}, ", .{self.dices.items});
1178 if (self.stab) |stab| {
1179 try std.fmt.format(writer, ".stab = {any}, ", .{stab});
1180 }
1181 try std.fmt.format(writer, "}}", .{});
1182}
1183
1184const RelocIterator = struct {
1185 buffer: []const macho.relocation_info,
1186 index: i32 = -1,
1187
1188 pub fn next(self: *RelocIterator) ?macho.relocation_info {
1189 self.index += 1;
1190 if (self.index < self.buffer.len) {
1191 return self.buffer[@intCast(u32, self.index)];
1192 }
1193 return null;
1194 }
1195
1196 pub fn peek(self: RelocIterator) macho.relocation_info {
1197 assert(self.index + 1 < self.buffer.len);
1198 return self.buffer[@intCast(u32, self.index + 1)];
1199 }
1200};
1201
1202fn filterRelocs(relocs: []macho.relocation_info, start_addr: u64, end_addr: u64) []macho.relocation_info {
1203 const Predicate = struct {
1204 addr: u64,
1205
1206 pub fn predicate(self: @This(), rel: macho.relocation_info) bool {
1207 return rel.r_address < self.addr;
1208 }
1209 };
1210
1211 const start = MachO.findFirst(macho.relocation_info, relocs, 0, Predicate{ .addr = end_addr });
1212 const end = MachO.findFirst(macho.relocation_info, relocs, start, Predicate{ .addr = start_addr });
1213
1214 return relocs[start..end];
1215}
1216
1217inline fn isArithmeticOp(inst: *const [4]u8) bool {
1218 const group_decode = @truncate(u5, inst[3]);
1219 return ((group_decode >> 2) == 4);
1220}
src/link/MachO/bind.zig-9
...@@ -9,15 +9,6 @@ pub const Pointer = struct {...@@ -9,15 +9,6 @@ pub const Pointer = struct {
9 name: ?[]const u8 = null,9 name: ?[]const u8 = null,
10};10};
1111
12pub fn pointerCmp(context: void, a: Pointer, b: Pointer) bool {
13 _ = context;
14 if (a.segment_id < b.segment_id) return true;
15 if (a.segment_id == b.segment_id) {
16 return a.offset < b.offset;
17 }
18 return false;
19}
20
21pub fn rebaseInfoSize(pointers: []const Pointer) !u64 {12pub fn rebaseInfoSize(pointers: []const Pointer) !u64 {
22 var stream = std.io.countingWriter(std.io.null_writer);13 var stream = std.io.countingWriter(std.io.null_writer);
23 var writer = stream.writer();14 var writer = stream.writer();
src/link/MachO/commands.zig+8-93
...@@ -9,6 +9,7 @@ const assert = std.debug.assert;...@@ -9,6 +9,7 @@ const assert = std.debug.assert;
99
10const Allocator = std.mem.Allocator;10const Allocator = std.mem.Allocator;
11const MachO = @import("../MachO.zig");11const MachO = @import("../MachO.zig");
12const makeStaticString = MachO.makeStaticString;
12const padToIdeal = MachO.padToIdeal;13const padToIdeal = MachO.padToIdeal;
1314
14pub const HeaderArgs = struct {15pub const HeaderArgs = struct {
...@@ -217,75 +218,6 @@ pub const SegmentCommand = struct {...@@ -217,75 +218,6 @@ pub const SegmentCommand = struct {
217 inner: macho.segment_command_64,218 inner: macho.segment_command_64,
218 sections: std.ArrayListUnmanaged(macho.section_64) = .{},219 sections: std.ArrayListUnmanaged(macho.section_64) = .{},
219220
220 const SegmentOptions = struct {
221 cmdsize: u32 = @sizeOf(macho.segment_command_64),
222 vmaddr: u64 = 0,
223 vmsize: u64 = 0,
224 fileoff: u64 = 0,
225 filesize: u64 = 0,
226 maxprot: macho.vm_prot_t = macho.VM_PROT_NONE,
227 initprot: macho.vm_prot_t = macho.VM_PROT_NONE,
228 nsects: u32 = 0,
229 flags: u32 = 0,
230 };
231
232 pub fn empty(comptime segname: []const u8, opts: SegmentOptions) SegmentCommand {
233 return .{
234 .inner = .{
235 .cmd = macho.LC_SEGMENT_64,
236 .cmdsize = opts.cmdsize,
237 .segname = makeStaticString(segname),
238 .vmaddr = opts.vmaddr,
239 .vmsize = opts.vmsize,
240 .fileoff = opts.fileoff,
241 .filesize = opts.filesize,
242 .maxprot = opts.maxprot,
243 .initprot = opts.initprot,
244 .nsects = opts.nsects,
245 .flags = opts.flags,
246 },
247 };
248 }
249
250 const SectionOptions = struct {
251 addr: u64 = 0,
252 size: u64 = 0,
253 offset: u32 = 0,
254 @"align": u32 = 0,
255 reloff: u32 = 0,
256 nreloc: u32 = 0,
257 flags: u32 = macho.S_REGULAR,
258 reserved1: u32 = 0,
259 reserved2: u32 = 0,
260 reserved3: u32 = 0,
261 };
262
263 pub fn addSection(
264 self: *SegmentCommand,
265 alloc: *Allocator,
266 comptime sectname: []const u8,
267 opts: SectionOptions,
268 ) !void {
269 var section = macho.section_64{
270 .sectname = makeStaticString(sectname),
271 .segname = undefined,
272 .addr = opts.addr,
273 .size = opts.size,
274 .offset = opts.offset,
275 .@"align" = opts.@"align",
276 .reloff = opts.reloff,
277 .nreloc = opts.nreloc,
278 .flags = opts.flags,
279 .reserved1 = opts.reserved1,
280 .reserved2 = opts.reserved2,
281 .reserved3 = opts.reserved3,
282 };
283 mem.copy(u8, &section.segname, &self.inner.segname);
284 try self.sections.append(alloc, section);
285 self.inner.cmdsize += @sizeOf(macho.section_64);
286 self.inner.nsects += 1;
287 }
288
289 pub fn read(alloc: *Allocator, reader: anytype) !SegmentCommand {221 pub fn read(alloc: *Allocator, reader: anytype) !SegmentCommand {
290 const inner = try reader.readStruct(macho.segment_command_64);222 const inner = try reader.readStruct(macho.segment_command_64);
291 var segment = SegmentCommand{223 var segment = SegmentCommand{
...@@ -314,10 +246,8 @@ pub const SegmentCommand = struct {...@@ -314,10 +246,8 @@ pub const SegmentCommand = struct {
314 }246 }
315247
316 pub fn allocatedSize(self: SegmentCommand, start: u64) u64 {248 pub fn allocatedSize(self: SegmentCommand, start: u64) u64 {
317 assert(start > 0);249 assert(start >= self.inner.fileoff);
318 if (start == self.inner.fileoff)250 var min_pos: u64 = self.inner.fileoff + self.inner.filesize;
319 return 0;
320 var min_pos: u64 = std.math.maxInt(u64);
321 for (self.sections.items) |section| {251 for (self.sections.items) |section| {
322 if (section.offset <= start) continue;252 if (section.offset <= start) continue;
323 if (section.offset < min_pos) min_pos = section.offset;253 if (section.offset < min_pos) min_pos = section.offset;
...@@ -337,12 +267,12 @@ pub const SegmentCommand = struct {...@@ -337,12 +267,12 @@ pub const SegmentCommand = struct {
337 return null;267 return null;
338 }268 }
339269
340 pub fn findFreeSpace(self: SegmentCommand, object_size: u64, min_alignment: u16, start: ?u64) u64 {270 pub fn findFreeSpace(self: SegmentCommand, object_size: u64, min_alignment: u64, start: ?u64) u64 {
341 var st: u64 = if (start) |v| v else self.inner.fileoff;271 var offset: u64 = if (start) |v| v else self.inner.fileoff;
342 while (self.detectAllocCollision(st, object_size)) |item_end| {272 while (self.detectAllocCollision(offset, object_size)) |item_end| {
343 st = mem.alignForwardGeneric(u64, item_end, min_alignment);273 offset = mem.alignForwardGeneric(u64, item_end, min_alignment);
344 }274 }
345 return st;275 return offset;
346 }276 }
347277
348 fn eql(self: SegmentCommand, other: SegmentCommand) bool {278 fn eql(self: SegmentCommand, other: SegmentCommand) bool {
...@@ -427,13 +357,6 @@ pub fn createLoadDylibCommand(...@@ -427,13 +357,6 @@ pub fn createLoadDylibCommand(
427 return dylib_cmd;357 return dylib_cmd;
428}358}
429359
430fn makeStaticString(bytes: []const u8) [16]u8 {
431 var buf = [_]u8{0} ** 16;
432 assert(bytes.len <= buf.len);
433 mem.copy(u8, &buf, bytes);
434 return buf;
435}
436
437fn parseName(name: *const [16]u8) []const u8 {360fn parseName(name: *const [16]u8) []const u8 {
438 const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len;361 const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len;
439 return name[0..len];362 return name[0..len];
...@@ -514,17 +437,14 @@ test "read-write segment command" {...@@ -514,17 +437,14 @@ test "read-write segment command" {
514 };437 };
515 var cmd = SegmentCommand{438 var cmd = SegmentCommand{
516 .inner = .{439 .inner = .{
517 .cmd = macho.LC_SEGMENT_64,
518 .cmdsize = 152,440 .cmdsize = 152,
519 .segname = makeStaticString("__TEXT"),441 .segname = makeStaticString("__TEXT"),
520 .vmaddr = 4294967296,442 .vmaddr = 4294967296,
521 .vmsize = 294912,443 .vmsize = 294912,
522 .fileoff = 0,
523 .filesize = 294912,444 .filesize = 294912,
524 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE,445 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE,
525 .initprot = macho.VM_PROT_EXECUTE | macho.VM_PROT_READ,446 .initprot = macho.VM_PROT_EXECUTE | macho.VM_PROT_READ,
526 .nsects = 1,447 .nsects = 1,
527 .flags = 0,
528 },448 },
529 };449 };
530 try cmd.sections.append(gpa, .{450 try cmd.sections.append(gpa, .{
...@@ -534,12 +454,7 @@ test "read-write segment command" {...@@ -534,12 +454,7 @@ test "read-write segment command" {
534 .size = 448,454 .size = 448,
535 .offset = 16384,455 .offset = 16384,
536 .@"align" = 2,456 .@"align" = 2,
537 .reloff = 0,
538 .nreloc = 0,
539 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,457 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
540 .reserved1 = 0,
541 .reserved2 = 0,
542 .reserved3 = 0,
543 });458 });
544 defer cmd.deinit(gpa);459 defer cmd.deinit(gpa);
545 try testRead(gpa, in_buffer, LoadCommand{ .Segment = cmd });460 try testRead(gpa, in_buffer, LoadCommand{ .Segment = cmd });
src/link/Plan9.zig+2-2
...@@ -36,7 +36,7 @@ hdr: aout.ExecHdr = undefined,...@@ -36,7 +36,7 @@ hdr: aout.ExecHdr = undefined,
3636
37entry_val: ?u64 = null,37entry_val: ?u64 = null,
3838
39got_len: u64 = 0,39got_len: usize = 0,
4040
41const Bases = struct {41const Bases = struct {
42 text: u64,42 text: u64,
...@@ -243,7 +243,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {...@@ -243,7 +243,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
243 const hdr_slice: []u8 = hdr_buf[0..hdr_size];243 const hdr_slice: []u8 = hdr_buf[0..hdr_size];
244 var foff = hdr_size;244 var foff = hdr_size;
245 iovecs[0] = .{ .iov_base = hdr_slice.ptr, .iov_len = hdr_slice.len };245 iovecs[0] = .{ .iov_base = hdr_slice.ptr, .iov_len = hdr_slice.len };
246 var iovecs_i: u64 = 1;246 var iovecs_i: usize = 1;
247 var text_i: u64 = 0;247 var text_i: u64 = 0;
248 // text248 // text
249 {249 {
src/link/tapi/parse/test.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const std = @import("std");1const std = @import("std");
2const mem = std.mem;2const mem = std.mem;
3const testing = std.testing;3const testing = std.testing;
44const Tree = @import("../parse.zig").Tree;
5usingnamespace @import("../parse.zig");5const Node = @import("../parse.zig").Node;
66
7test "explicit doc" {7test "explicit doc" {
8 const source =8 const source =
src/main.zig+87-44
...@@ -6,7 +6,7 @@ const mem = std.mem;...@@ -6,7 +6,7 @@ const mem = std.mem;
6const process = std.process;6const process = std.process;
7const Allocator = mem.Allocator;7const Allocator = mem.Allocator;
8const ArrayList = std.ArrayList;8const ArrayList = std.ArrayList;
9const ast = std.zig.ast;9const Ast = std.zig.Ast;
10const warn = std.log.warn;10const warn = std.log.warn;
1111
12const Compilation = @import("Compilation.zig");12const Compilation = @import("Compilation.zig");
...@@ -589,6 +589,10 @@ fn buildOutputType(...@@ -589,6 +589,10 @@ fn buildOutputType(
589 var linker_bind_global_refs_locally: ?bool = null;589 var linker_bind_global_refs_locally: ?bool = null;
590 var linker_z_nodelete = false;590 var linker_z_nodelete = false;
591 var linker_z_defs = false;591 var linker_z_defs = false;
592 var linker_z_origin = false;
593 var linker_z_noexecstack = false;
594 var linker_z_now = false;
595 var linker_z_relro = false;
592 var linker_tsaware = false;596 var linker_tsaware = false;
593 var linker_nxcompat = false;597 var linker_nxcompat = false;
594 var linker_dynamicbase = false;598 var linker_dynamicbase = false;
...@@ -1393,6 +1397,14 @@ fn buildOutputType(...@@ -1393,6 +1397,14 @@ fn buildOutputType(
1393 linker_z_nodelete = true;1397 linker_z_nodelete = true;
1394 } else if (mem.eql(u8, z_arg, "defs")) {1398 } else if (mem.eql(u8, z_arg, "defs")) {
1395 linker_z_defs = true;1399 linker_z_defs = true;
1400 } else if (mem.eql(u8, z_arg, "origin")) {
1401 linker_z_origin = true;
1402 } else if (mem.eql(u8, z_arg, "noexecstack")) {
1403 linker_z_noexecstack = true;
1404 } else if (mem.eql(u8, z_arg, "now")) {
1405 linker_z_now = true;
1406 } else if (mem.eql(u8, z_arg, "relro")) {
1407 linker_z_relro = true;
1396 } else {1408 } else {
1397 warn("unsupported linker arg: -z {s}", .{z_arg});1409 warn("unsupported linker arg: -z {s}", .{z_arg});
1398 }1410 }
...@@ -1581,39 +1593,11 @@ fn buildOutputType(...@@ -1581,39 +1593,11 @@ fn buildOutputType(
1581 }1593 }
1582 };1594 };
15831595
1584 var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};1596 const cross_target = try parseCrossTargetOrReportFatalError(arena, .{
1585 const cross_target = std.zig.CrossTarget.parse(.{
1586 .arch_os_abi = target_arch_os_abi,1597 .arch_os_abi = target_arch_os_abi,
1587 .cpu_features = target_mcpu,1598 .cpu_features = target_mcpu,
1588 .dynamic_linker = target_dynamic_linker,1599 .dynamic_linker = target_dynamic_linker,
1589 .diagnostics = &diags,1600 });
1590 }) catch |err| switch (err) {
1591 error.UnknownCpuModel => {
1592 help: {
1593 var help_text = std.ArrayList(u8).init(arena);
1594 for (diags.arch.?.allCpuModels()) |cpu| {
1595 help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;
1596 }
1597 std.log.info("Available CPUs for architecture '{s}':\n{s}", .{
1598 @tagName(diags.arch.?), help_text.items,
1599 });
1600 }
1601 fatal("Unknown CPU: '{s}'", .{diags.cpu_name.?});
1602 },
1603 error.UnknownCpuFeature => {
1604 help: {
1605 var help_text = std.ArrayList(u8).init(arena);
1606 for (diags.arch.?.allFeaturesList()) |feature| {
1607 help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;
1608 }
1609 std.log.info("Available CPU features for architecture '{s}':\n{s}", .{
1610 @tagName(diags.arch.?), help_text.items,
1611 });
1612 }
1613 fatal("Unknown CPU feature: '{s}'", .{diags.unknown_feature_name});
1614 },
1615 else => |e| return e,
1616 };
16171601
1618 const target_info = try detectNativeTargetInfo(gpa, cross_target);1602 const target_info = try detectNativeTargetInfo(gpa, cross_target);
16191603
...@@ -1960,7 +1944,7 @@ fn buildOutputType(...@@ -1960,7 +1944,7 @@ fn buildOutputType(
1960 defer if (libc_installation) |*l| l.deinit(gpa);1944 defer if (libc_installation) |*l| l.deinit(gpa);
19611945
1962 if (libc_paths_file) |paths_file| {1946 if (libc_paths_file) |paths_file| {
1963 libc_installation = LibCInstallation.parse(gpa, paths_file) catch |err| {1947 libc_installation = LibCInstallation.parse(gpa, paths_file, cross_target) catch |err| {
1964 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });1948 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });
1965 };1949 };
1966 }1950 }
...@@ -2077,6 +2061,10 @@ fn buildOutputType(...@@ -2077,6 +2061,10 @@ fn buildOutputType(
2077 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,2061 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,
2078 .linker_z_nodelete = linker_z_nodelete,2062 .linker_z_nodelete = linker_z_nodelete,
2079 .linker_z_defs = linker_z_defs,2063 .linker_z_defs = linker_z_defs,
2064 .linker_z_origin = linker_z_origin,
2065 .linker_z_noexecstack = linker_z_noexecstack,
2066 .linker_z_now = linker_z_now,
2067 .linker_z_relro = linker_z_relro,
2080 .linker_tsaware = linker_tsaware,2068 .linker_tsaware = linker_tsaware,
2081 .linker_nxcompat = linker_nxcompat,2069 .linker_nxcompat = linker_nxcompat,
2082 .linker_dynamicbase = linker_dynamicbase,2070 .linker_dynamicbase = linker_dynamicbase,
...@@ -2273,6 +2261,43 @@ fn buildOutputType(...@@ -2273,6 +2261,43 @@ fn buildOutputType(
2273 return cleanExit();2261 return cleanExit();
2274}2262}
22752263
2264fn parseCrossTargetOrReportFatalError(allocator: *Allocator, opts: std.zig.CrossTarget.ParseOptions) !std.zig.CrossTarget {
2265 var opts_with_diags = opts;
2266 var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};
2267 if (opts_with_diags.diagnostics == null) {
2268 opts_with_diags.diagnostics = &diags;
2269 }
2270 return std.zig.CrossTarget.parse(opts_with_diags) catch |err| switch (err) {
2271 error.UnknownCpuModel => {
2272 help: {
2273 var help_text = std.ArrayList(u8).init(allocator);
2274 defer help_text.deinit();
2275 for (diags.arch.?.allCpuModels()) |cpu| {
2276 help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;
2277 }
2278 std.log.info("Available CPUs for architecture '{s}':\n{s}", .{
2279 @tagName(diags.arch.?), help_text.items,
2280 });
2281 }
2282 fatal("Unknown CPU: '{s}'", .{diags.cpu_name.?});
2283 },
2284 error.UnknownCpuFeature => {
2285 help: {
2286 var help_text = std.ArrayList(u8).init(allocator);
2287 defer help_text.deinit();
2288 for (diags.arch.?.allFeaturesList()) |feature| {
2289 help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;
2290 }
2291 std.log.info("Available CPU features for architecture '{s}':\n{s}", .{
2292 @tagName(diags.arch.?), help_text.items,
2293 });
2294 }
2295 fatal("Unknown CPU feature: '{s}'", .{diags.unknown_feature_name});
2296 },
2297 else => |e| return e,
2298 };
2299}
2300
2276fn runOrTest(2301fn runOrTest(
2277 comp: *Compilation,2302 comp: *Compilation,
2278 gpa: *Allocator,2303 gpa: *Allocator,
...@@ -2614,10 +2639,15 @@ pub const usage_libc =...@@ -2614,10 +2639,15 @@ pub const usage_libc =
2614 \\2639 \\
2615 \\ Parse a libc installation text file and validate it.2640 \\ Parse a libc installation text file and validate it.
2616 \\2641 \\
2642 \\Options:
2643 \\ -h, --help Print this help and exit
2644 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command
2645 \\
2617;2646;
26182647
2619pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {2648pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
2620 var input_file: ?[]const u8 = null;2649 var input_file: ?[]const u8 = null;
2650 var target_arch_os_abi: []const u8 = "native";
2621 {2651 {
2622 var i: usize = 0;2652 var i: usize = 0;
2623 while (i < args.len) : (i += 1) {2653 while (i < args.len) : (i += 1) {
...@@ -2627,6 +2657,10 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {...@@ -2627,6 +2657,10 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
2627 const stdout = io.getStdOut().writer();2657 const stdout = io.getStdOut().writer();
2628 try stdout.writeAll(usage_libc);2658 try stdout.writeAll(usage_libc);
2629 return cleanExit();2659 return cleanExit();
2660 } else if (mem.eql(u8, arg, "-target")) {
2661 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});
2662 i += 1;
2663 target_arch_os_abi = args[i];
2630 } else {2664 } else {
2631 fatal("unrecognized parameter: '{s}'", .{arg});2665 fatal("unrecognized parameter: '{s}'", .{arg});
2632 }2666 }
...@@ -2637,12 +2671,21 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {...@@ -2637,12 +2671,21 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
2637 }2671 }
2638 }2672 }
2639 }2673 }
2674
2675 const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{
2676 .arch_os_abi = target_arch_os_abi,
2677 });
2678
2640 if (input_file) |libc_file| {2679 if (input_file) |libc_file| {
2641 var libc = LibCInstallation.parse(gpa, libc_file) catch |err| {2680 var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| {
2642 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });2681 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });
2643 };2682 };
2644 defer libc.deinit(gpa);2683 defer libc.deinit(gpa);
2645 } else {2684 } else {
2685 if (!cross_target.isNative()) {
2686 fatal("unable to detect libc for non-native target", .{});
2687 }
2688
2646 var libc = LibCInstallation.findNative(.{2689 var libc = LibCInstallation.findNative(.{
2647 .allocator = gpa,2690 .allocator = gpa,
2648 .verbose = true,2691 .verbose = true,
...@@ -3423,8 +3466,8 @@ fn fmtPathFile(...@@ -3423,8 +3466,8 @@ fn fmtPathFile(
3423fn printErrMsgToStdErr(3466fn printErrMsgToStdErr(
3424 gpa: *mem.Allocator,3467 gpa: *mem.Allocator,
3425 arena: *mem.Allocator,3468 arena: *mem.Allocator,
3426 parse_error: ast.Error,3469 parse_error: Ast.Error,
3427 tree: ast.Tree,3470 tree: Ast,
3428 path: []const u8,3471 path: []const u8,
3429 color: Color,3472 color: Color,
3430) !void {3473) !void {
...@@ -3828,7 +3871,7 @@ fn parseCodeModel(arg: []const u8) std.builtin.CodeModel {...@@ -3828,7 +3871,7 @@ fn parseCodeModel(arg: []const u8) std.builtin.CodeModel {
3828/// garbage collector to run concurrently to zig processes, and to allow multiple3871/// garbage collector to run concurrently to zig processes, and to allow multiple
3829/// zig processes to run concurrently with each other, without clobbering each other.3872/// zig processes to run concurrently with each other, without clobbering each other.
3830fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {3873fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {
3831 if (!@hasDecl(std.os, "rlimit")) return;3874 if (!@hasDecl(std.os.system, "rlimit")) return;
3832 const posix = std.os;3875 const posix = std.os;
38333876
3834 var lim = posix.getrlimit(.NOFILE) catch return; // Oh well; we tried.3877 var lim = posix.getrlimit(.NOFILE) catch return; // Oh well; we tried.
...@@ -3836,7 +3879,7 @@ fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {...@@ -3836,7 +3879,7 @@ fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {
3836 // On Darwin, `NOFILE` is bounded by a hardcoded value `OPEN_MAX`.3879 // On Darwin, `NOFILE` is bounded by a hardcoded value `OPEN_MAX`.
3837 // According to the man pages for setrlimit():3880 // According to the man pages for setrlimit():
3838 // setrlimit() now returns with errno set to EINVAL in places that historically succeeded.3881 // setrlimit() now returns with errno set to EINVAL in places that historically succeeded.
3839 // It no longer accepts "rlim_cur = RLIM_INFINITY" for RLIM_NOFILE.3882 // It no longer accepts "rlim_cur = RLIM.INFINITY" for RLIM.NOFILE.
3840 // Use "rlim_cur = min(OPEN_MAX, rlim_max)".3883 // Use "rlim_cur = min(OPEN_MAX, rlim_max)".
3841 lim.max = std.math.min(std.os.darwin.OPEN_MAX, lim.max);3884 lim.max = std.math.min(std.os.darwin.OPEN_MAX, lim.max);
3842 }3885 }
...@@ -3846,7 +3889,7 @@ fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {...@@ -3846,7 +3889,7 @@ fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {
3846 var min: posix.rlim_t = lim.cur;3889 var min: posix.rlim_t = lim.cur;
3847 var max: posix.rlim_t = 1 << 20;3890 var max: posix.rlim_t = 1 << 20;
3848 // But if there's a defined upper bound, don't search, just set it.3891 // But if there's a defined upper bound, don't search, just set it.
3849 if (lim.max != posix.RLIM_INFINITY) {3892 if (lim.max != posix.RLIM.INFINITY) {
3850 min = lim.max;3893 min = lim.max;
3851 max = lim.max;3894 max = lim.max;
3852 }3895 }
...@@ -4029,12 +4072,12 @@ pub fn cmdAstCheck(...@@ -4029,12 +4072,12 @@ pub fn cmdAstCheck(
4029 }4072 }
40304073
4031 {4074 {
4032 const token_bytes = @sizeOf(std.zig.ast.TokenList) +4075 const token_bytes = @sizeOf(Ast.TokenList) +
4033 file.tree.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(std.zig.ast.ByteOffset));4076 file.tree.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset));
4034 const tree_bytes = @sizeOf(std.zig.ast.Tree) + file.tree.nodes.len *4077 const tree_bytes = @sizeOf(Ast) + file.tree.nodes.len *
4035 (@sizeOf(std.zig.ast.Node.Tag) +4078 (@sizeOf(Ast.Node.Tag) +
4036 @sizeOf(std.zig.ast.Node.Data) +4079 @sizeOf(Ast.Node.Data) +
4037 @sizeOf(std.zig.ast.TokenIndex));4080 @sizeOf(Ast.TokenIndex));
4038 const instruction_bytes = file.zir.instructions.len *4081 const instruction_bytes = file.zir.instructions.len *
4039 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include4082 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include
4040 // the debug safety tag but we want to measure release size.4083 // the debug safety tag but we want to measure release size.
src/mingw.zig+4
...@@ -1022,6 +1022,10 @@ const mingwex_arm32_src = [_][]const u8{...@@ -1022,6 +1022,10 @@ const mingwex_arm32_src = [_][]const u8{
1022};1022};
10231023
1024const mingwex_arm64_src = [_][]const u8{1024const mingwex_arm64_src = [_][]const u8{
1025 "misc" ++ path.sep_str ++ "initenv.c",
1026 "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "log2.c",
1027 "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "pow.c",
1028 "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "scalbn.c",
1025 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "_chgsignl.S",1029 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "_chgsignl.S",
1026 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rint.c",1030 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rint.c",
1027 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rintf.c",1031 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rintf.c",
src/print_air.zig+18-1
...@@ -109,6 +109,7 @@ const Writer = struct {...@@ -109,6 +109,7 @@ const Writer = struct {
109 .mul,109 .mul,
110 .mulwrap,110 .mulwrap,
111 .div,111 .div,
112 .rem,
112 .ptr_add,113 .ptr_add,
113 .ptr_sub,114 .ptr_sub,
114 .bit_and,115 .bit_and,
...@@ -173,6 +174,7 @@ const Writer = struct {...@@ -173,6 +174,7 @@ const Writer = struct {
173 .struct_field_ptr_index_1,174 .struct_field_ptr_index_1,
174 .struct_field_ptr_index_2,175 .struct_field_ptr_index_2,
175 .struct_field_ptr_index_3,176 .struct_field_ptr_index_3,
177 .array_to_slice,
176 => try w.writeTyOp(s, inst),178 => try w.writeTyOp(s, inst),
177179
178 .block,180 .block,
...@@ -189,6 +191,7 @@ const Writer = struct {...@@ -189,6 +191,7 @@ const Writer = struct {
189 .br => try w.writeBr(s, inst),191 .br => try w.writeBr(s, inst),
190 .cond_br => try w.writeCondBr(s, inst),192 .cond_br => try w.writeCondBr(s, inst),
191 .switch_br => try w.writeSwitchBr(s, inst),193 .switch_br => try w.writeSwitchBr(s, inst),
194 .cmpxchg_weak, .cmpxchg_strong => try w.writeCmpxchg(s, inst),
192 }195 }
193 }196 }
194197
...@@ -256,7 +259,21 @@ const Writer = struct {...@@ -256,7 +259,21 @@ const Writer = struct {
256259
257 try w.writeOperand(s, inst, 0, extra.lhs);260 try w.writeOperand(s, inst, 0, extra.lhs);
258 try s.writeAll(", ");261 try s.writeAll(", ");
259 try w.writeOperand(s, inst, 0, extra.rhs);262 try w.writeOperand(s, inst, 1, extra.rhs);
263 }
264
265 fn writeCmpxchg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
266 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
267 const extra = w.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
268
269 try w.writeOperand(s, inst, 0, extra.ptr);
270 try s.writeAll(", ");
271 try w.writeOperand(s, inst, 1, extra.expected_value);
272 try s.writeAll(", ");
273 try w.writeOperand(s, inst, 2, extra.new_value);
274 try s.print(", {s}, {s}", .{
275 @tagName(extra.successOrder()), @tagName(extra.failureOrder()),
276 });
260 }277 }
261278
262 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {279 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/stage1/all_types.hpp+8
...@@ -1802,6 +1802,10 @@ enum BuiltinFnId {...@@ -1802,6 +1802,10 @@ enum BuiltinFnId {
1802 BuiltinFnIdReduce,1802 BuiltinFnIdReduce,
1803 BuiltinFnIdMaximum,1803 BuiltinFnIdMaximum,
1804 BuiltinFnIdMinimum,1804 BuiltinFnIdMinimum,
1805 BuiltinFnIdSatAdd,
1806 BuiltinFnIdSatSub,
1807 BuiltinFnIdSatMul,
1808 BuiltinFnIdSatShl,
1805};1809};
18061810
1807struct BuiltinFnEntry {1811struct BuiltinFnEntry {
...@@ -2946,6 +2950,10 @@ enum IrBinOp {...@@ -2946,6 +2950,10 @@ enum IrBinOp {
2946 IrBinOpArrayMult,2950 IrBinOpArrayMult,
2947 IrBinOpMaximum,2951 IrBinOpMaximum,
2948 IrBinOpMinimum,2952 IrBinOpMinimum,
2953 IrBinOpSatAdd,
2954 IrBinOpSatSub,
2955 IrBinOpSatMul,
2956 IrBinOpSatShl,
2949};2957};
29502958
2951struct Stage1ZirInstBinOp {2959struct Stage1ZirInstBinOp {
src/stage1/astgen.cpp+60
...@@ -4704,6 +4704,66 @@ static Stage1ZirInst *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, Ast...@@ -4704,6 +4704,66 @@ static Stage1ZirInst *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, Ast
4704 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpMaximum, arg0_value, arg1_value, true);4704 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpMaximum, arg0_value, arg1_value, true);
4705 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);4705 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4706 }4706 }
4707 case BuiltinFnIdSatAdd:
4708 {
4709 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4710 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4711 if (arg0_value == ag->codegen->invalid_inst_src)
4712 return arg0_value;
4713
4714 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4715 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4716 if (arg1_value == ag->codegen->invalid_inst_src)
4717 return arg1_value;
4718
4719 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpSatAdd, arg0_value, arg1_value, true);
4720 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4721 }
4722 case BuiltinFnIdSatSub:
4723 {
4724 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4725 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4726 if (arg0_value == ag->codegen->invalid_inst_src)
4727 return arg0_value;
4728
4729 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4730 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4731 if (arg1_value == ag->codegen->invalid_inst_src)
4732 return arg1_value;
4733
4734 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpSatSub, arg0_value, arg1_value, true);
4735 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4736 }
4737 case BuiltinFnIdSatMul:
4738 {
4739 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4740 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4741 if (arg0_value == ag->codegen->invalid_inst_src)
4742 return arg0_value;
4743
4744 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4745 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4746 if (arg1_value == ag->codegen->invalid_inst_src)
4747 return arg1_value;
4748
4749 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpSatMul, arg0_value, arg1_value, true);
4750 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4751 }
4752 case BuiltinFnIdSatShl:
4753 {
4754 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4755 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4756 if (arg0_value == ag->codegen->invalid_inst_src)
4757 return arg0_value;
4758
4759 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4760 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4761 if (arg1_value == ag->codegen->invalid_inst_src)
4762 return arg1_value;
4763
4764 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpSatShl, arg0_value, arg1_value, true);
4765 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4766 }
4707 case BuiltinFnIdMemcpy:4767 case BuiltinFnIdMemcpy:
4708 {4768 {
4709 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);4769 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
src/stage1/bigint.cpp+78
...@@ -468,6 +468,84 @@ void bigint_min(BigInt* dest, const BigInt *op1, const BigInt *op2) {...@@ -468,6 +468,84 @@ void bigint_min(BigInt* dest, const BigInt *op1, const BigInt *op2) {
468 }468 }
469}469}
470470
471/// clamps op within bit_count/signedness boundaries
472/// signed bounds are [-2^(bit_count-1)..2^(bit_count-1)-1]
473/// unsigned bounds are [0..2^bit_count-1]
474void bigint_clamp_by_bitcount(BigInt* dest, uint32_t bit_count, bool is_signed) {
475 // compute the number of bits required to store the value, and use that
476 // to decide whether to clamp the result
477 bool is_negative = dest->is_negative;
478 // to workaround the fact this bits_needed calculation would yield 65 or more for
479 // all negative numbers, set is_negative to false. this is a cheap way to find
480 // bits_needed(abs(dest)).
481 dest->is_negative = false;
482 // because we've set is_negative to false, we have to account for the extra bit here
483 // by adding 1 additional bit_needed when (is_negative && !is_signed).
484 size_t full_bits = dest->digit_count * 64;
485 size_t leading_zero_count = bigint_clz(dest, full_bits);
486 size_t bits_needed = full_bits - leading_zero_count + (is_negative && !is_signed);
487
488 bit_count -= is_signed;
489 if(bits_needed > bit_count) {
490 BigInt one;
491 bigint_init_unsigned(&one, 1);
492 BigInt bit_count_big;
493 bigint_init_unsigned(&bit_count_big, bit_count);
494
495 if(is_signed) {
496 if(is_negative) {
497 BigInt bound;
498 bigint_shl(&bound, &one, &bit_count_big);
499 bigint_deinit(dest);
500 *dest = bound;
501 } else {
502 BigInt bound;
503 bigint_shl(&bound, &one, &bit_count_big);
504 BigInt bound_sub_one;
505 bigint_sub(&bound_sub_one, &bound, &one);
506 bigint_deinit(&bound);
507 bigint_deinit(dest);
508 *dest = bound_sub_one;
509 }
510 } else {
511 if(is_negative) {
512 bigint_deinit(dest);
513 bigint_init_unsigned(dest, 0);
514 return; // skips setting is_negative which would be invalid
515 } else {
516 BigInt bound;
517 bigint_shl(&bound, &one, &bit_count_big);
518 BigInt bound_sub_one;
519 bigint_sub(&bound_sub_one, &bound, &one);
520 bigint_deinit(&bound);
521 bigint_deinit(dest);
522 *dest = bound_sub_one;
523 }
524 }
525 }
526 dest->is_negative = is_negative;
527}
528
529void bigint_add_sat(BigInt* dest, const BigInt *op1, const BigInt *op2, uint32_t bit_count, bool is_signed) {
530 bigint_add(dest, op1, op2);
531 bigint_clamp_by_bitcount(dest, bit_count, is_signed);
532}
533
534void bigint_sub_sat(BigInt* dest, const BigInt *op1, const BigInt *op2, uint32_t bit_count, bool is_signed) {
535 bigint_sub(dest, op1, op2);
536 bigint_clamp_by_bitcount(dest, bit_count, is_signed);
537}
538
539void bigint_mul_sat(BigInt* dest, const BigInt *op1, const BigInt *op2, uint32_t bit_count, bool is_signed) {
540 bigint_mul(dest, op1, op2);
541 bigint_clamp_by_bitcount(dest, bit_count, is_signed);
542}
543
544void bigint_shl_sat(BigInt* dest, const BigInt *op1, const BigInt *op2, uint32_t bit_count, bool is_signed) {
545 bigint_shl(dest, op1, op2);
546 bigint_clamp_by_bitcount(dest, bit_count, is_signed);
547}
548
471void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {549void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {
472 if (op1->digit_count == 0) {550 if (op1->digit_count == 0) {
473 return bigint_init_bigint(dest, op2);551 return bigint_init_bigint(dest, op2);
src/stage1/bigint.hpp+4
...@@ -105,4 +105,8 @@ bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result);...@@ -105,4 +105,8 @@ bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result);
105uint32_t bigint_hash(BigInt const *x);105uint32_t bigint_hash(BigInt const *x);
106bool bigint_eql(BigInt const *a, BigInt const *b);106bool bigint_eql(BigInt const *a, BigInt const *b);
107107
108void bigint_add_sat(BigInt* dest, const BigInt *op1, const BigInt *op2, uint32_t bit_count, bool is_signed);
109void bigint_sub_sat(BigInt* dest, const BigInt *op1, const BigInt *op2, uint32_t bit_count, bool is_signed);
110void bigint_mul_sat(BigInt* dest, const BigInt *op1, const BigInt *op2, uint32_t bit_count, bool is_signed);
111void bigint_shl_sat(BigInt* dest, const BigInt *op1, const BigInt *op2, uint32_t bit_count, bool is_signed);
108#endif112#endif
src/stage1/codegen.cpp+44
...@@ -3335,6 +3335,46 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, Stage1Air *executable,...@@ -3335,6 +3335,46 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, Stage1Air *executable,
3335 } else {3335 } else {
3336 zig_unreachable();3336 zig_unreachable();
3337 }3337 }
3338 case IrBinOpSatAdd:
3339 if (scalar_type->id == ZigTypeIdInt) {
3340 if (scalar_type->data.integral.is_signed) {
3341 return ZigLLVMBuildSAddSat(g->builder, op1_value, op2_value, "");
3342 } else {
3343 return ZigLLVMBuildUAddSat(g->builder, op1_value, op2_value, "");
3344 }
3345 } else {
3346 zig_unreachable();
3347 }
3348 case IrBinOpSatSub:
3349 if (scalar_type->id == ZigTypeIdInt) {
3350 if (scalar_type->data.integral.is_signed) {
3351 return ZigLLVMBuildSSubSat(g->builder, op1_value, op2_value, "");
3352 } else {
3353 return ZigLLVMBuildUSubSat(g->builder, op1_value, op2_value, "");
3354 }
3355 } else {
3356 zig_unreachable();
3357 }
3358 case IrBinOpSatMul:
3359 if (scalar_type->id == ZigTypeIdInt) {
3360 if (scalar_type->data.integral.is_signed) {
3361 return ZigLLVMBuildSMulFixSat(g->builder, op1_value, op2_value, "");
3362 } else {
3363 return ZigLLVMBuildUMulFixSat(g->builder, op1_value, op2_value, "");
3364 }
3365 } else {
3366 zig_unreachable();
3367 }
3368 case IrBinOpSatShl:
3369 if (scalar_type->id == ZigTypeIdInt) {
3370 if (scalar_type->data.integral.is_signed) {
3371 return ZigLLVMBuildSShlSat(g->builder, op1_value, op2_value, "");
3372 } else {
3373 return ZigLLVMBuildUShlSat(g->builder, op1_value, op2_value, "");
3374 }
3375 } else {
3376 zig_unreachable();
3377 }
3338 }3378 }
3339 zig_unreachable();3379 zig_unreachable();
3340}3380}
...@@ -9094,6 +9134,10 @@ static void define_builtin_fns(CodeGen *g) {...@@ -9094,6 +9134,10 @@ static void define_builtin_fns(CodeGen *g) {
9094 create_builtin_fn(g, BuiltinFnIdReduce, "reduce", 2);9134 create_builtin_fn(g, BuiltinFnIdReduce, "reduce", 2);
9095 create_builtin_fn(g, BuiltinFnIdMaximum, "maximum", 2);9135 create_builtin_fn(g, BuiltinFnIdMaximum, "maximum", 2);
9096 create_builtin_fn(g, BuiltinFnIdMinimum, "minimum", 2);9136 create_builtin_fn(g, BuiltinFnIdMinimum, "minimum", 2);
9137 create_builtin_fn(g, BuiltinFnIdSatAdd, "addWithSaturation", 2);
9138 create_builtin_fn(g, BuiltinFnIdSatSub, "subWithSaturation", 2);
9139 create_builtin_fn(g, BuiltinFnIdSatMul, "mulWithSaturation", 2);
9140 create_builtin_fn(g, BuiltinFnIdSatShl, "shlWithSaturation", 2);
9097}9141}
90989142
9099static const char *bool_to_str(bool b) {9143static const char *bool_to_str(bool b) {
src/stage1/ir.cpp+36
...@@ -9820,6 +9820,34 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, Scope *scope, AstNode *s...@@ -9820,6 +9820,34 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, Scope *scope, AstNode *s
9820 float_min(out_val, op1_val, op2_val);9820 float_min(out_val, op1_val, op2_val);
9821 }9821 }
9822 break;9822 break;
9823 case IrBinOpSatAdd:
9824 if (is_int) {
9825 bigint_add_sat(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, type_entry->data.integral.bit_count, type_entry->data.integral.is_signed);
9826 } else {
9827 zig_unreachable();
9828 }
9829 break;
9830 case IrBinOpSatSub:
9831 if (is_int) {
9832 bigint_sub_sat(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, type_entry->data.integral.bit_count, type_entry->data.integral.is_signed);
9833 } else {
9834 zig_unreachable();
9835 }
9836 break;
9837 case IrBinOpSatMul:
9838 if (is_int) {
9839 bigint_mul_sat(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, type_entry->data.integral.bit_count, type_entry->data.integral.is_signed);
9840 } else {
9841 zig_unreachable();
9842 }
9843 break;
9844 case IrBinOpSatShl:
9845 if (is_int) {
9846 bigint_shl_sat(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, type_entry->data.integral.bit_count, type_entry->data.integral.is_signed);
9847 } else {
9848 zig_unreachable();
9849 }
9850 break;
9823 }9851 }
98249852
9825 if (type_entry->id == ZigTypeIdInt) {9853 if (type_entry->id == ZigTypeIdInt) {
...@@ -10041,6 +10069,10 @@ static bool ok_float_op(IrBinOp op) {...@@ -10041,6 +10069,10 @@ static bool ok_float_op(IrBinOp op) {
10041 case IrBinOpBitShiftRightExact:10069 case IrBinOpBitShiftRightExact:
10042 case IrBinOpAddWrap:10070 case IrBinOpAddWrap:
10043 case IrBinOpSubWrap:10071 case IrBinOpSubWrap:
10072 case IrBinOpSatAdd:
10073 case IrBinOpSatSub:
10074 case IrBinOpSatMul:
10075 case IrBinOpSatShl:
10044 case IrBinOpMultWrap:10076 case IrBinOpMultWrap:
10045 case IrBinOpArrayCat:10077 case IrBinOpArrayCat:
10046 case IrBinOpArrayMult:10078 case IrBinOpArrayMult:
...@@ -11014,6 +11046,10 @@ static Stage1AirInst *ir_analyze_instruction_bin_op(IrAnalyze *ira, Stage1ZirIns...@@ -11014,6 +11046,10 @@ static Stage1AirInst *ir_analyze_instruction_bin_op(IrAnalyze *ira, Stage1ZirIns
11014 case IrBinOpRemMod:11046 case IrBinOpRemMod:
11015 case IrBinOpMaximum:11047 case IrBinOpMaximum:
11016 case IrBinOpMinimum:11048 case IrBinOpMinimum:
11049 case IrBinOpSatAdd:
11050 case IrBinOpSatSub:
11051 case IrBinOpSatMul:
11052 case IrBinOpSatShl:
11017 return ir_analyze_bin_op_math(ira, bin_op_instruction);11053 return ir_analyze_bin_op_math(ira, bin_op_instruction);
11018 case IrBinOpArrayCat:11054 case IrBinOpArrayCat:
11019 return ir_analyze_array_cat(ira, bin_op_instruction);11055 return ir_analyze_array_cat(ira, bin_op_instruction);
src/stage1/ir_print.cpp+8
...@@ -737,6 +737,14 @@ static const char *ir_bin_op_id_str(IrBinOp op_id) {...@@ -737,6 +737,14 @@ static const char *ir_bin_op_id_str(IrBinOp op_id) {
737 return "@maximum";737 return "@maximum";
738 case IrBinOpMinimum:738 case IrBinOpMinimum:
739 return "@minimum";739 return "@minimum";
740 case IrBinOpSatAdd:
741 return "@addWithSaturation";
742 case IrBinOpSatSub:
743 return "@subWithSaturation";
744 case IrBinOpSatMul:
745 return "@mulWithSaturation";
746 case IrBinOpSatShl:
747 return "@shlWithSaturation";
740 }748 }
741 zig_unreachable();749 zig_unreachable();
742}750}
src/target.zig+70
...@@ -480,3 +480,73 @@ pub fn clangAssemblerSupportsMcpuArg(target: std.Target) bool {...@@ -480,3 +480,73 @@ pub fn clangAssemblerSupportsMcpuArg(target: std.Target) bool {
480pub fn needUnwindTables(target: std.Target) bool {480pub fn needUnwindTables(target: std.Target) bool {
481 return target.os.tag == .windows;481 return target.os.tag == .windows;
482}482}
483
484/// TODO this was ported from stage1 but it does not take into account CPU features,
485/// which can affect this value. Audit this!
486pub fn largestAtomicBits(target: std.Target) u32 {
487 return switch (target.cpu.arch) {
488 .avr,
489 .msp430,
490 .spu_2,
491 => 16,
492
493 .arc,
494 .arm,
495 .armeb,
496 .hexagon,
497 .m68k,
498 .le32,
499 .mips,
500 .mipsel,
501 .nvptx,
502 .powerpc,
503 .powerpcle,
504 .r600,
505 .riscv32,
506 .sparc,
507 .sparcel,
508 .tce,
509 .tcele,
510 .thumb,
511 .thumbeb,
512 .i386,
513 .xcore,
514 .amdil,
515 .hsail,
516 .spir,
517 .kalimba,
518 .lanai,
519 .shave,
520 .wasm32,
521 .renderscript32,
522 .csky,
523 .spirv32,
524 => 32,
525
526 .aarch64,
527 .aarch64_be,
528 .aarch64_32,
529 .amdgcn,
530 .bpfel,
531 .bpfeb,
532 .le64,
533 .mips64,
534 .mips64el,
535 .nvptx64,
536 .powerpc64,
537 .powerpc64le,
538 .riscv64,
539 .sparcv9,
540 .s390x,
541 .amdil64,
542 .hsail64,
543 .spir64,
544 .wasm64,
545 .renderscript64,
546 .ve,
547 .spirv64,
548 => 64,
549
550 .x86_64 => 128,
551 };
552}
src/translate_c.zig+42-8
...@@ -356,7 +356,7 @@ pub fn translate(...@@ -356,7 +356,7 @@ pub fn translate(
356 args_end: [*]?[*]const u8,356 args_end: [*]?[*]const u8,
357 errors: *[]ClangErrMsg,357 errors: *[]ClangErrMsg,
358 resources_path: [*:0]const u8,358 resources_path: [*:0]const u8,
359) !std.zig.ast.Tree {359) !std.zig.Ast {
360 const ast_unit = clang.LoadFromCommandLine(360 const ast_unit = clang.LoadFromCommandLine(
361 args_begin,361 args_begin,
362 args_end,362 args_end,
...@@ -369,7 +369,7 @@ pub fn translate(...@@ -369,7 +369,7 @@ pub fn translate(
369 };369 };
370 defer ast_unit.delete();370 defer ast_unit.delete();
371371
372 // For memory that has the same lifetime as the Tree that we return372 // For memory that has the same lifetime as the Ast that we return
373 // from this function.373 // from this function.
374 var arena = std.heap.ArenaAllocator.init(gpa);374 var arena = std.heap.ArenaAllocator.init(gpa);
375 errdefer arena.deinit();375 errdefer arena.deinit();
...@@ -395,7 +395,15 @@ pub fn translate(...@@ -395,7 +395,15 @@ pub fn translate(
395 context.pattern_list.deinit(gpa);395 context.pattern_list.deinit(gpa);
396 }396 }
397397
398 try context.global_scope.nodes.append(Tag.usingnamespace_builtins.init());398 inline for (meta.declarations(std.zig.c_builtins)) |decl| {
399 if (decl.is_pub) {
400 const builtin = try Tag.pub_var_simple.create(context.arena, .{
401 .name = decl.name,
402 .init = try Tag.import_c_builtin.create(context.arena, decl.name),
403 });
404 try addTopLevelDecl(&context, decl.name, builtin);
405 }
406 }
399407
400 try prepopulateGlobalNameTable(ast_unit, &context);408 try prepopulateGlobalNameTable(ast_unit, &context);
401409
...@@ -1982,6 +1990,7 @@ fn transImplicitCastExpr(...@@ -1982,6 +1990,7 @@ fn transImplicitCastExpr(
19821990
1983fn isBuiltinDefined(name: []const u8) bool {1991fn isBuiltinDefined(name: []const u8) bool {
1984 inline for (meta.declarations(std.zig.c_builtins)) |decl| {1992 inline for (meta.declarations(std.zig.c_builtins)) |decl| {
1993 if (!decl.is_pub) continue;
1985 if (std.mem.eql(u8, name, decl.name)) return true;1994 if (std.mem.eql(u8, name, decl.name)) return true;
1986 }1995 }
1987 return false;1996 return false;
...@@ -5248,6 +5257,26 @@ const MacroCtx = struct {...@@ -5248,6 +5257,26 @@ const MacroCtx = struct {
5248 fn makeSlicer(self: *const MacroCtx) MacroSlicer {5257 fn makeSlicer(self: *const MacroCtx) MacroSlicer {
5249 return MacroSlicer{ .source = self.source, .tokens = self.list };5258 return MacroSlicer{ .source = self.source, .tokens = self.list };
5250 }5259 }
5260
5261 fn containsUndefinedIdentifier(self: *MacroCtx, scope: *Scope, params: []const ast.Payload.Param) ?[]const u8 {
5262 const slicer = self.makeSlicer();
5263 var i: usize = 1; // index 0 is the macro name
5264 while (i < self.list.len) : (i += 1) {
5265 const token = self.list[i];
5266 switch (token.id) {
5267 .Period, .Arrow => i += 1, // skip next token since field identifiers can be unknown
5268 .Identifier => {
5269 const identifier = slicer.slice(token);
5270 const is_param = for (params) |param| {
5271 if (param.name != null and mem.eql(u8, identifier, param.name.?)) break true;
5272 } else false;
5273 if (!scope.contains(identifier) and !isBuiltinDefined(identifier) and !is_param) return identifier;
5274 },
5275 else => {},
5276 }
5277 }
5278 return null;
5279 }
5251};5280};
52525281
5253fn tokenizeMacro(source: []const u8, tok_list: *std.ArrayList(CToken)) Error!void {5282fn tokenizeMacro(source: []const u8, tok_list: *std.ArrayList(CToken)) Error!void {
...@@ -5318,7 +5347,10 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {...@@ -5318,7 +5347,10 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
5318 },5347 },
5319 .Nl, .Eof => {5348 .Nl, .Eof => {
5320 // this means it is a macro without a value5349 // this means it is a macro without a value
5321 // we don't care about such things5350 // We define it as an empty string so that it can still be used with ++
5351 const str_node = try Tag.string_literal.create(c.arena, "\"\"");
5352 const var_decl = try Tag.pub_var_simple.create(c.arena, .{ .name = name, .init = str_node });
5353 try c.global_scope.macro_table.put(name, var_decl);
5322 continue;5354 continue;
5323 },5355 },
5324 .LParen => {5356 .LParen => {
...@@ -5344,6 +5376,9 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {...@@ -5344,6 +5376,9 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
5344fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void {5376fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void {
5345 const scope = &c.global_scope.base;5377 const scope = &c.global_scope.base;
53465378
5379 if (m.containsUndefinedIdentifier(scope, &.{})) |ident|
5380 return m.fail(c, "unable to translate macro: undefined identifier `{s}`", .{ident});
5381
5347 const init_node = try parseCExpr(c, m, scope);5382 const init_node = try parseCExpr(c, m, scope);
5348 const last = m.next().?;5383 const last = m.next().?;
5349 if (last != .Eof and last != .Nl)5384 if (last != .Eof and last != .Nl)
...@@ -5394,6 +5429,9 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {...@@ -5394,6 +5429,9 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
5394 return m.fail(c, "unable to translate C expr: expected ')'", .{});5429 return m.fail(c, "unable to translate C expr: expected ')'", .{});
5395 }5430 }
53965431
5432 if (m.containsUndefinedIdentifier(scope, fn_params.items)) |ident|
5433 return m.fail(c, "unable to translate macro: undefined identifier `{s}`", .{ident});
5434
5397 const expr = try parseCExpr(c, m, scope);5435 const expr = try parseCExpr(c, m, scope);
5398 const last = m.next().?;5436 const last = m.next().?;
5399 if (last != .Eof and last != .Nl)5437 if (last != .Eof and last != .Nl)
...@@ -5735,10 +5773,6 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N...@@ -5735,10 +5773,6 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
5735 },5773 },
5736 .Identifier => {5774 .Identifier => {
5737 const mangled_name = scope.getAlias(slice);5775 const mangled_name = scope.getAlias(slice);
5738 if (mem.startsWith(u8, mangled_name, "__builtin_") and !isBuiltinDefined(mangled_name)) {
5739 try m.fail(c, "TODO implement function '{s}' in std.zig.c_builtins", .{mangled_name});
5740 return error.ParseError;
5741 }
5742 if (builtin_typedef_map.get(mangled_name)) |ty| return Tag.type.create(c.arena, ty);5776 if (builtin_typedef_map.get(mangled_name)) |ty| return Tag.type.create(c.arena, ty);
5743 const identifier = try Tag.identifier.create(c.arena, mangled_name);5777 const identifier = try Tag.identifier.create(c.arena, mangled_name);
5744 scope.skipVariableDiscard(identifier.castTag(.identifier).?.data);5778 scope.skipVariableDiscard(identifier.castTag(.identifier).?.data);
src/translate_c/ast.zig+36-43
...@@ -31,8 +31,6 @@ pub const Node = extern union {...@@ -31,8 +31,6 @@ pub const Node = extern union {
31 @"anytype",31 @"anytype",
32 @"continue",32 @"continue",
33 @"break",33 @"break",
34 /// pub usingnamespace @import("std").zig.c_builtins
35 usingnamespace_builtins,
36 // After this, the tag requires a payload.34 // After this, the tag requires a payload.
3735
38 integer_literal,36 integer_literal,
...@@ -119,6 +117,8 @@ pub const Node = extern union {...@@ -119,6 +117,8 @@ pub const Node = extern union {
119 ellipsis3,117 ellipsis3,
120 assign,118 assign,
121119
120 /// @import("std").zig.c_builtins.<name>
121 import_c_builtin,
122 log2_int_type,122 log2_int_type,
123 /// @import("std").math.Log2Int(operand)123 /// @import("std").math.Log2Int(operand)
124 std_math_Log2Int,124 std_math_Log2Int,
...@@ -224,7 +224,7 @@ pub const Node = extern union {...@@ -224,7 +224,7 @@ pub const Node = extern union {
224 /// [1]type{val} ** count224 /// [1]type{val} ** count
225 array_filler,225 array_filler,
226226
227 pub const last_no_payload_tag = Tag.usingnamespace_builtins;227 pub const last_no_payload_tag = Tag.@"break";
228 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;228 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
229229
230 pub fn Type(comptime t: Tag) type {230 pub fn Type(comptime t: Tag) type {
...@@ -236,7 +236,6 @@ pub const Node = extern union {...@@ -236,7 +236,6 @@ pub const Node = extern union {
236 .true_literal,236 .true_literal,
237 .false_literal,237 .false_literal,
238 .empty_block,238 .empty_block,
239 .usingnamespace_builtins,
240 .return_void,239 .return_void,
241 .zero_literal,240 .zero_literal,
242 .one_literal,241 .one_literal,
...@@ -344,6 +343,7 @@ pub const Node = extern union {...@@ -344,6 +343,7 @@ pub const Node = extern union {
344 .warning,343 .warning,
345 .type,344 .type,
346 .helpers_macro,345 .helpers_macro,
346 .import_c_builtin,
347 => Payload.Value,347 => Payload.Value,
348 .discard => Payload.Discard,348 .discard => Payload.Discard,
349 .@"if" => Payload.If,349 .@"if" => Payload.If,
...@@ -714,9 +714,9 @@ pub const Payload = struct {...@@ -714,9 +714,9 @@ pub const Payload = struct {
714 };714 };
715};715};
716716
717/// Converts the nodes into a Zig ast.717/// Converts the nodes into a Zig Ast.
718/// Caller must free the source slice.718/// Caller must free the source slice.
719pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {719pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.Ast {
720 var ctx = Context{720 var ctx = Context{
721 .gpa = gpa,721 .gpa = gpa,
722 .buf = std.ArrayList(u8).init(gpa),722 .buf = std.ArrayList(u8).init(gpa),
...@@ -767,7 +767,7 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {...@@ -767,7 +767,7 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
767 .start = @intCast(u32, ctx.buf.items.len),767 .start = @intCast(u32, ctx.buf.items.len),
768 });768 });
769769
770 return std.zig.ast.Tree{770 return std.zig.Ast{
771 .source = try ctx.buf.toOwnedSliceSentinel(0),771 .source = try ctx.buf.toOwnedSliceSentinel(0),
772 .tokens = ctx.tokens.toOwnedSlice(),772 .tokens = ctx.tokens.toOwnedSlice(),
773 .nodes = ctx.nodes.toOwnedSlice(),773 .nodes = ctx.nodes.toOwnedSlice(),
...@@ -776,17 +776,17 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {...@@ -776,17 +776,17 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
776 };776 };
777}777}
778778
779const NodeIndex = std.zig.ast.Node.Index;779const NodeIndex = std.zig.Ast.Node.Index;
780const NodeSubRange = std.zig.ast.Node.SubRange;780const NodeSubRange = std.zig.Ast.Node.SubRange;
781const TokenIndex = std.zig.ast.TokenIndex;781const TokenIndex = std.zig.Ast.TokenIndex;
782const TokenTag = std.zig.Token.Tag;782const TokenTag = std.zig.Token.Tag;
783783
784const Context = struct {784const Context = struct {
785 gpa: *Allocator,785 gpa: *Allocator,
786 buf: std.ArrayList(u8) = .{},786 buf: std.ArrayList(u8) = .{},
787 nodes: std.zig.ast.NodeList = .{},787 nodes: std.zig.Ast.NodeList = .{},
788 extra_data: std.ArrayListUnmanaged(std.zig.ast.Node.Index) = .{},788 extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},
789 tokens: std.zig.ast.TokenList = .{},789 tokens: std.zig.Ast.TokenList = .{},
790790
791 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {791 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
792 const start_index = c.buf.items.len;792 const start_index = c.buf.items.len;
...@@ -831,7 +831,7 @@ const Context = struct {...@@ -831,7 +831,7 @@ const Context = struct {
831 };831 };
832 }832 }
833833
834 fn addNode(c: *Context, elem: std.zig.ast.NodeList.Elem) Allocator.Error!NodeIndex {834 fn addNode(c: *Context, elem: std.zig.Ast.NodeList.Elem) Allocator.Error!NodeIndex {
835 const result = @intCast(NodeIndex, c.nodes.len);835 const result = @intCast(NodeIndex, c.nodes.len);
836 try c.nodes.append(c.gpa, elem);836 try c.nodes.append(c.gpa, elem);
837 return result;837 return result;
...@@ -871,22 +871,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -871,22 +871,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
871 try c.buf.append('\n');871 try c.buf.append('\n');
872 return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'872 return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
873 },873 },
874 .usingnamespace_builtins => {
875 // pub usingnamespace @import("std").c.builtins;
876 _ = try c.addToken(.keyword_pub, "pub");
877 const usingnamespace_token = try c.addToken(.keyword_usingnamespace, "usingnamespace");
878 const import_node = try renderStdImport(c, &.{ "zig", "c_builtins" });
879 _ = try c.addToken(.semicolon, ";");
880
881 return c.addNode(.{
882 .tag = .@"usingnamespace",
883 .main_token = usingnamespace_token,
884 .data = .{
885 .lhs = import_node,
886 .rhs = undefined,
887 },
888 });
889 },
890 .std_math_Log2Int => {874 .std_math_Log2Int => {
891 const payload = node.castTag(.std_math_Log2Int).?.data;875 const payload = node.castTag(.std_math_Log2Int).?.data;
892 const import_node = try renderStdImport(c, &.{ "math", "Log2Int" });876 const import_node = try renderStdImport(c, &.{ "math", "Log2Int" });
...@@ -1143,6 +1127,15 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1143,6 +1127,15 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1143 };1127 };
1144 return renderStdImport(c, &chain);1128 return renderStdImport(c, &chain);
1145 },1129 },
1130 .import_c_builtin => {
1131 const payload = node.castTag(.import_c_builtin).?.data;
1132 const chain = [_][]const u8{
1133 "zig",
1134 "c_builtins",
1135 payload,
1136 };
1137 return renderStdImport(c, &chain);
1138 },
1146 .string_slice => {1139 .string_slice => {
1147 const payload = node.castTag(.string_slice).?.data;1140 const payload = node.castTag(.string_slice).?.data;
11481141
...@@ -1166,7 +1159,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1166,7 +1159,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1166 .main_token = l_bracket,1159 .main_token = l_bracket,
1167 .data = .{1160 .data = .{
1168 .lhs = string,1161 .lhs = string,
1169 .rhs = try c.addExtra(std.zig.ast.Node.Slice{1162 .rhs = try c.addExtra(std.zig.Ast.Node.Slice{
1170 .start = start,1163 .start = start,
1171 .end = end,1164 .end = end,
1172 }),1165 }),
...@@ -1601,7 +1594,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1601,7 +1594,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1601 .main_token = while_tok,1594 .main_token = while_tok,
1602 .data = .{1595 .data = .{
1603 .lhs = cond,1596 .lhs = cond,
1604 .rhs = try c.addExtra(std.zig.ast.Node.WhileCont{1597 .rhs = try c.addExtra(std.zig.Ast.Node.WhileCont{
1605 .cont_expr = cont_expr,1598 .cont_expr = cont_expr,
1606 .then_expr = body,1599 .then_expr = body,
1607 }),1600 }),
...@@ -1654,7 +1647,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1654,7 +1647,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1654 .main_token = if_tok,1647 .main_token = if_tok,
1655 .data = .{1648 .data = .{
1656 .lhs = cond,1649 .lhs = cond,
1657 .rhs = try c.addExtra(std.zig.ast.Node.If{1650 .rhs = try c.addExtra(std.zig.Ast.Node.If{
1658 .then_expr = then_expr,1651 .then_expr = then_expr,
1659 .else_expr = else_expr,1652 .else_expr = else_expr,
1660 }),1653 }),
...@@ -2175,7 +2168,7 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn...@@ -2175,7 +2168,7 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn
2175 .main_token = l_bracket,2168 .main_token = l_bracket,
2176 .data = .{2169 .data = .{
2177 .lhs = len_expr,2170 .lhs = len_expr,
2178 .rhs = try c.addExtra(std.zig.ast.Node.ArrayTypeSentinel{2171 .rhs = try c.addExtra(std.zig.Ast.Node.ArrayTypeSentinel{
2179 .sentinel = sentinel_expr,2172 .sentinel = sentinel_expr,
2180 .elem_type = elem_type_expr,2173 .elem_type = elem_type_expr,
2181 }),2174 }),
...@@ -2352,7 +2345,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2352,7 +2345,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2352 .@"comptime",2345 .@"comptime",
2353 .@"defer",2346 .@"defer",
2354 .asm_simple,2347 .asm_simple,
2355 .usingnamespace_builtins,
2356 .while_true,2348 .while_true,
2357 .if_not_break,2349 .if_not_break,
2358 .switch_else,2350 .switch_else,
...@@ -2371,6 +2363,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2371,6 +2363,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2371 .bit_xor_assign,2363 .bit_xor_assign,
2372 .assign,2364 .assign,
2373 .helpers_macro,2365 .helpers_macro,
2366 .import_c_builtin,
2374 => {2367 => {
2375 // these should never appear in places where grouping might be needed.2368 // these should never appear in places where grouping might be needed.
2376 unreachable;2369 unreachable;
...@@ -2378,7 +2371,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2378,7 +2371,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2378 }2371 }
2379}2372}
23802373
2381fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {2374fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2382 const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;2375 const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;
2383 return c.addNode(.{2376 return c.addNode(.{
2384 .tag = tag,2377 .tag = tag,
...@@ -2390,7 +2383,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: T...@@ -2390,7 +2383,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: T
2390 });2383 });
2391}2384}
23922385
2393fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {2386fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2394 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;2387 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2395 const lhs = try renderNodeGrouped(c, payload.lhs);2388 const lhs = try renderNodeGrouped(c, payload.lhs);
2396 return c.addNode(.{2389 return c.addNode(.{
...@@ -2403,7 +2396,7 @@ fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_ta...@@ -2403,7 +2396,7 @@ fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_ta
2403 });2396 });
2404}2397}
24052398
2406fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {2399fn renderBinOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2407 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;2400 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2408 const lhs = try renderNode(c, payload.lhs);2401 const lhs = try renderNode(c, payload.lhs);
2409 return c.addNode(.{2402 return c.addNode(.{
...@@ -2604,7 +2597,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {...@@ -2604,7 +2597,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
2604 .tag = .local_var_decl,2597 .tag = .local_var_decl,
2605 .main_token = mut_tok,2598 .main_token = mut_tok,
2606 .data = .{2599 .data = .{
2607 .lhs = try c.addExtra(std.zig.ast.Node.LocalVarDecl{2600 .lhs = try c.addExtra(std.zig.Ast.Node.LocalVarDecl{
2608 .type_node = type_node,2601 .type_node = type_node,
2609 .align_node = align_node,2602 .align_node = align_node,
2610 }),2603 }),
...@@ -2617,7 +2610,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {...@@ -2617,7 +2610,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
2617 .tag = .global_var_decl,2610 .tag = .global_var_decl,
2618 .main_token = mut_tok,2611 .main_token = mut_tok,
2619 .data = .{2612 .data = .{
2620 .lhs = try c.addExtra(std.zig.ast.Node.GlobalVarDecl{2613 .lhs = try c.addExtra(std.zig.Ast.Node.GlobalVarDecl{
2621 .type_node = type_node,2614 .type_node = type_node,
2622 .align_node = align_node,2615 .align_node = align_node,
2623 .section_node = section_node,2616 .section_node = section_node,
...@@ -2709,7 +2702,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2709,7 +2702,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2709 .tag = .fn_proto_one,2702 .tag = .fn_proto_one,
2710 .main_token = fn_token,2703 .main_token = fn_token,
2711 .data = .{2704 .data = .{
2712 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{2705 .lhs = try c.addExtra(std.zig.Ast.Node.FnProtoOne{
2713 .param = params.items[0],2706 .param = params.items[0],
2714 .align_expr = align_expr,2707 .align_expr = align_expr,
2715 .section_expr = section_expr,2708 .section_expr = section_expr,
...@@ -2723,7 +2716,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2723,7 +2716,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2723 .tag = .fn_proto,2716 .tag = .fn_proto,
2724 .main_token = fn_token,2717 .main_token = fn_token,
2725 .data = .{2718 .data = .{
2726 .lhs = try c.addExtra(std.zig.ast.Node.FnProto{2719 .lhs = try c.addExtra(std.zig.Ast.Node.FnProto{
2727 .params_start = span.start,2720 .params_start = span.start,
2728 .params_end = span.end,2721 .params_end = span.end,
2729 .align_expr = align_expr,2722 .align_expr = align_expr,
...@@ -2781,7 +2774,7 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {...@@ -2781,7 +2774,7 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2781 .tag = .fn_proto_multi,2774 .tag = .fn_proto_multi,
2782 .main_token = fn_token,2775 .main_token = fn_token,
2783 .data = .{2776 .data = .{
2784 .lhs = try c.addExtra(std.zig.ast.Node.SubRange{2777 .lhs = try c.addExtra(std.zig.Ast.Node.SubRange{
2785 .start = span.start,2778 .start = span.start,
2786 .end = span.end,2779 .end = span.end,
2787 }),2780 }),
src/type.zig+68-30
...@@ -18,7 +18,7 @@ const file_struct = @This();...@@ -18,7 +18,7 @@ const file_struct = @This();
18pub const Type = extern union {18pub const Type = extern union {
19 /// If the tag value is less than Tag.no_payload_count, then no pointer19 /// If the tag value is less than Tag.no_payload_count, then no pointer
20 /// dereference is needed.20 /// dereference is needed.
21 tag_if_small_enough: usize,21 tag_if_small_enough: Tag,
22 ptr_otherwise: *Payload,22 ptr_otherwise: *Payload,
2323
24 pub fn zigTypeTag(ty: Type) std.builtin.TypeId {24 pub fn zigTypeTag(ty: Type) std.builtin.TypeId {
...@@ -124,7 +124,7 @@ pub const Type = extern union {...@@ -124,7 +124,7 @@ pub const Type = extern union {
124 .enum_full,124 .enum_full,
125 .enum_nonexhaustive,125 .enum_nonexhaustive,
126 .enum_simple,126 .enum_simple,
127 .atomic_ordering,127 .atomic_order,
128 .atomic_rmw_op,128 .atomic_rmw_op,
129 .calling_convention,129 .calling_convention,
130 .float_mode,130 .float_mode,
...@@ -178,7 +178,7 @@ pub const Type = extern union {...@@ -178,7 +178,7 @@ pub const Type = extern union {
178178
179 pub fn initTag(comptime small_tag: Tag) Type {179 pub fn initTag(comptime small_tag: Tag) Type {
180 comptime assert(@enumToInt(small_tag) < Tag.no_payload_count);180 comptime assert(@enumToInt(small_tag) < Tag.no_payload_count);
181 return .{ .tag_if_small_enough = @enumToInt(small_tag) };181 return .{ .tag_if_small_enough = small_tag };
182 }182 }
183183
184 pub fn initPayload(payload: *Payload) Type {184 pub fn initPayload(payload: *Payload) Type {
...@@ -187,8 +187,8 @@ pub const Type = extern union {...@@ -187,8 +187,8 @@ pub const Type = extern union {
187 }187 }
188188
189 pub fn tag(self: Type) Tag {189 pub fn tag(self: Type) Tag {
190 if (self.tag_if_small_enough < Tag.no_payload_count) {190 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
191 return @intToEnum(Tag, @intCast(std.meta.Tag(Tag), self.tag_if_small_enough));191 return self.tag_if_small_enough;
192 } else {192 } else {
193 return self.ptr_otherwise.tag;193 return self.ptr_otherwise.tag;
194 }194 }
...@@ -197,9 +197,9 @@ pub const Type = extern union {...@@ -197,9 +197,9 @@ pub const Type = extern union {
197 /// Prefer `castTag` to this.197 /// Prefer `castTag` to this.
198 pub fn cast(self: Type, comptime T: type) ?*T {198 pub fn cast(self: Type, comptime T: type) ?*T {
199 if (@hasField(T, "base_tag")) {199 if (@hasField(T, "base_tag")) {
200 return base.castTag(T.base_tag);200 return self.castTag(T.base_tag);
201 }201 }
202 if (self.tag_if_small_enough < Tag.no_payload_count) {202 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
203 return null;203 return null;
204 }204 }
205 inline for (@typeInfo(Tag).Enum.fields) |field| {205 inline for (@typeInfo(Tag).Enum.fields) |field| {
...@@ -217,7 +217,7 @@ pub const Type = extern union {...@@ -217,7 +217,7 @@ pub const Type = extern union {
217 }217 }
218218
219 pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() {219 pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() {
220 if (self.tag_if_small_enough < Tag.no_payload_count)220 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count)
221 return null;221 return null;
222222
223 if (self.ptr_otherwise.tag == t)223 if (self.ptr_otherwise.tag == t)
...@@ -273,6 +273,15 @@ pub const Type = extern union {...@@ -273,6 +273,15 @@ pub const Type = extern union {
273 };273 };
274 }274 }
275275
276 pub const ArrayInfo = struct { elem_type: Type, sentinel: ?Value = null, len: u64 };
277 pub fn arrayInfo(self: Type) ArrayInfo {
278 return .{
279 .len = self.arrayLen(),
280 .sentinel = self.sentinel(),
281 .elem_type = self.elemType(),
282 };
283 }
284
276 pub fn ptrInfo(self: Type) Payload.Pointer {285 pub fn ptrInfo(self: Type) Payload.Pointer {
277 switch (self.tag()) {286 switch (self.tag()) {
278 .single_const_pointer_to_comptime_int => return .{ .data = .{287 .single_const_pointer_to_comptime_int => return .{ .data = .{
...@@ -681,7 +690,7 @@ pub const Type = extern union {...@@ -681,7 +690,7 @@ pub const Type = extern union {
681 };690 };
682691
683 pub fn copy(self: Type, allocator: *Allocator) error{OutOfMemory}!Type {692 pub fn copy(self: Type, allocator: *Allocator) error{OutOfMemory}!Type {
684 if (self.tag_if_small_enough < Tag.no_payload_count) {693 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
685 return Type{ .tag_if_small_enough = self.tag_if_small_enough };694 return Type{ .tag_if_small_enough = self.tag_if_small_enough };
686 } else switch (self.ptr_otherwise.tag) {695 } else switch (self.ptr_otherwise.tag) {
687 .u1,696 .u1,
...@@ -734,7 +743,7 @@ pub const Type = extern union {...@@ -734,7 +743,7 @@ pub const Type = extern union {
734 .empty_struct_literal,743 .empty_struct_literal,
735 .manyptr_u8,744 .manyptr_u8,
736 .manyptr_const_u8,745 .manyptr_const_u8,
737 .atomic_ordering,746 .atomic_order,
738 .atomic_rmw_op,747 .atomic_rmw_op,
739 .calling_convention,748 .calling_convention,
740 .float_mode,749 .float_mode,
...@@ -946,7 +955,7 @@ pub const Type = extern union {...@@ -946,7 +955,7 @@ pub const Type = extern union {
946 .single_const_pointer_to_comptime_int => return writer.writeAll("*const comptime_int"),955 .single_const_pointer_to_comptime_int => return writer.writeAll("*const comptime_int"),
947 .manyptr_u8 => return writer.writeAll("[*]u8"),956 .manyptr_u8 => return writer.writeAll("[*]u8"),
948 .manyptr_const_u8 => return writer.writeAll("[*]const u8"),957 .manyptr_const_u8 => return writer.writeAll("[*]const u8"),
949 .atomic_ordering => return writer.writeAll("std.builtin.AtomicOrdering"),958 .atomic_order => return writer.writeAll("std.builtin.AtomicOrder"),
950 .atomic_rmw_op => return writer.writeAll("std.builtin.AtomicRmwOp"),959 .atomic_rmw_op => return writer.writeAll("std.builtin.AtomicRmwOp"),
951 .calling_convention => return writer.writeAll("std.builtin.CallingConvention"),960 .calling_convention => return writer.writeAll("std.builtin.CallingConvention"),
952 .float_mode => return writer.writeAll("std.builtin.FloatMode"),961 .float_mode => return writer.writeAll("std.builtin.FloatMode"),
...@@ -1174,7 +1183,7 @@ pub const Type = extern union {...@@ -1174,7 +1183,7 @@ pub const Type = extern union {
1174 .@"anyframe",1183 .@"anyframe",
1175 .@"null",1184 .@"null",
1176 .@"undefined",1185 .@"undefined",
1177 .atomic_ordering,1186 .atomic_order,
1178 .atomic_rmw_op,1187 .atomic_rmw_op,
1179 .calling_convention,1188 .calling_convention,
1180 .float_mode,1189 .float_mode,
...@@ -1289,7 +1298,7 @@ pub const Type = extern union {...@@ -1289,7 +1298,7 @@ pub const Type = extern union {
1289 .enum_literal => return Value.initTag(.enum_literal_type),1298 .enum_literal => return Value.initTag(.enum_literal_type),
1290 .manyptr_u8 => return Value.initTag(.manyptr_u8_type),1299 .manyptr_u8 => return Value.initTag(.manyptr_u8_type),
1291 .manyptr_const_u8 => return Value.initTag(.manyptr_const_u8_type),1300 .manyptr_const_u8 => return Value.initTag(.manyptr_const_u8_type),
1292 .atomic_ordering => return Value.initTag(.atomic_ordering_type),1301 .atomic_order => return Value.initTag(.atomic_order_type),
1293 .atomic_rmw_op => return Value.initTag(.atomic_rmw_op_type),1302 .atomic_rmw_op => return Value.initTag(.atomic_rmw_op_type),
1294 .calling_convention => return Value.initTag(.calling_convention_type),1303 .calling_convention => return Value.initTag(.calling_convention_type),
1295 .float_mode => return Value.initTag(.float_mode_type),1304 .float_mode => return Value.initTag(.float_mode_type),
...@@ -1350,7 +1359,7 @@ pub const Type = extern union {...@@ -1350,7 +1359,7 @@ pub const Type = extern union {
1350 .error_set_inferred,1359 .error_set_inferred,
1351 .manyptr_u8,1360 .manyptr_u8,
1352 .manyptr_const_u8,1361 .manyptr_const_u8,
1353 .atomic_ordering,1362 .atomic_order,
1354 .atomic_rmw_op,1363 .atomic_rmw_op,
1355 .calling_convention,1364 .calling_convention,
1356 .float_mode,1365 .float_mode,
...@@ -1450,7 +1459,7 @@ pub const Type = extern union {...@@ -1450,7 +1459,7 @@ pub const Type = extern union {
14501459
1451 pub fn isNoReturn(self: Type) bool {1460 pub fn isNoReturn(self: Type) bool {
1452 const definitely_correct_result = self.zigTypeTag() == .NoReturn;1461 const definitely_correct_result = self.zigTypeTag() == .NoReturn;
1453 const fast_result = self.tag_if_small_enough == @enumToInt(Tag.noreturn);1462 const fast_result = self.tag_if_small_enough == Tag.noreturn;
1454 assert(fast_result == definitely_correct_result);1463 assert(fast_result == definitely_correct_result);
1455 return fast_result;1464 return fast_result;
1456 }1465 }
...@@ -1496,7 +1505,7 @@ pub const Type = extern union {...@@ -1496,7 +1505,7 @@ pub const Type = extern union {
1496 .bool,1505 .bool,
1497 .array_u8_sentinel_0,1506 .array_u8_sentinel_0,
1498 .array_u8,1507 .array_u8,
1499 .atomic_ordering,1508 .atomic_order,
1500 .atomic_rmw_op,1509 .atomic_rmw_op,
1501 .calling_convention,1510 .calling_convention,
1502 .float_mode,1511 .float_mode,
...@@ -1718,7 +1727,7 @@ pub const Type = extern union {...@@ -1718,7 +1727,7 @@ pub const Type = extern union {
1718 .u8,1727 .u8,
1719 .i8,1728 .i8,
1720 .bool,1729 .bool,
1721 .atomic_ordering,1730 .atomic_order,
1722 .atomic_rmw_op,1731 .atomic_rmw_op,
1723 .calling_convention,1732 .calling_convention,
1724 .float_mode,1733 .float_mode,
...@@ -2002,7 +2011,7 @@ pub const Type = extern union {...@@ -2002,7 +2011,7 @@ pub const Type = extern union {
2002 @panic("TODO bitSize error union");2011 @panic("TODO bitSize error union");
2003 },2012 },
20042013
2005 .atomic_ordering,2014 .atomic_order,
2006 .atomic_rmw_op,2015 .atomic_rmw_op,
2007 .calling_convention,2016 .calling_convention,
2008 .float_mode,2017 .float_mode,
...@@ -2716,7 +2725,7 @@ pub const Type = extern union {...@@ -2716,7 +2725,7 @@ pub const Type = extern union {
2716 .var_args_param,2725 .var_args_param,
2717 .manyptr_u8,2726 .manyptr_u8,
2718 .manyptr_const_u8,2727 .manyptr_const_u8,
2719 .atomic_ordering,2728 .atomic_order,
2720 .atomic_rmw_op,2729 .atomic_rmw_op,
2721 .calling_convention,2730 .calling_convention,
2722 .float_mode,2731 .float_mode,
...@@ -2877,6 +2886,35 @@ pub const Type = extern union {...@@ -2877,6 +2886,35 @@ pub const Type = extern union {
2877 }2886 }
2878 }2887 }
28792888
2889 /// Returns the integer tag type of the enum.
2890 pub fn enumTagType(ty: Type, buffer: *Payload.Bits) Type {
2891 switch (ty.tag()) {
2892 .enum_full, .enum_nonexhaustive => {
2893 const enum_full = ty.cast(Payload.EnumFull).?.data;
2894 return enum_full.tag_ty;
2895 },
2896 .enum_simple => {
2897 const enum_simple = ty.castTag(.enum_simple).?.data;
2898 buffer.* = .{
2899 .base = .{ .tag = .int_unsigned },
2900 .data = std.math.log2_int_ceil(usize, enum_simple.fields.count()),
2901 };
2902 return Type.initPayload(&buffer.base);
2903 },
2904 .atomic_order,
2905 .atomic_rmw_op,
2906 .calling_convention,
2907 .float_mode,
2908 .reduce_op,
2909 .call_options,
2910 .export_options,
2911 .extern_options,
2912 => @panic("TODO resolve std.builtin types"),
2913
2914 else => unreachable,
2915 }
2916 }
2917
2880 pub fn isNonexhaustiveEnum(ty: Type) bool {2918 pub fn isNonexhaustiveEnum(ty: Type) bool {
2881 return switch (ty.tag()) {2919 return switch (ty.tag()) {
2882 .enum_nonexhaustive => true,2920 .enum_nonexhaustive => true,
...@@ -2894,7 +2932,7 @@ pub const Type = extern union {...@@ -2894,7 +2932,7 @@ pub const Type = extern union {
2894 const enum_simple = ty.castTag(.enum_simple).?.data;2932 const enum_simple = ty.castTag(.enum_simple).?.data;
2895 return enum_simple.fields.count();2933 return enum_simple.fields.count();
2896 },2934 },
2897 .atomic_ordering,2935 .atomic_order,
2898 .atomic_rmw_op,2936 .atomic_rmw_op,
2899 .calling_convention,2937 .calling_convention,
2900 .float_mode,2938 .float_mode,
...@@ -2918,7 +2956,7 @@ pub const Type = extern union {...@@ -2918,7 +2956,7 @@ pub const Type = extern union {
2918 const enum_simple = ty.castTag(.enum_simple).?.data;2956 const enum_simple = ty.castTag(.enum_simple).?.data;
2919 return enum_simple.fields.keys()[field_index];2957 return enum_simple.fields.keys()[field_index];
2920 },2958 },
2921 .atomic_ordering,2959 .atomic_order,
2922 .atomic_rmw_op,2960 .atomic_rmw_op,
2923 .calling_convention,2961 .calling_convention,
2924 .float_mode,2962 .float_mode,
...@@ -2941,7 +2979,7 @@ pub const Type = extern union {...@@ -2941,7 +2979,7 @@ pub const Type = extern union {
2941 const enum_simple = ty.castTag(.enum_simple).?.data;2979 const enum_simple = ty.castTag(.enum_simple).?.data;
2942 return enum_simple.fields.getIndex(field_name);2980 return enum_simple.fields.getIndex(field_name);
2943 },2981 },
2944 .atomic_ordering,2982 .atomic_order,
2945 .atomic_rmw_op,2983 .atomic_rmw_op,
2946 .calling_convention,2984 .calling_convention,
2947 .float_mode,2985 .float_mode,
...@@ -2994,7 +3032,7 @@ pub const Type = extern union {...@@ -2994,7 +3032,7 @@ pub const Type = extern union {
2994 const tag_ty = Type.initPayload(&buffer.base);3032 const tag_ty = Type.initPayload(&buffer.base);
2995 return S.fieldWithRange(tag_ty, enum_tag, fields_len);3033 return S.fieldWithRange(tag_ty, enum_tag, fields_len);
2996 },3034 },
2997 .atomic_ordering,3035 .atomic_order,
2998 .atomic_rmw_op,3036 .atomic_rmw_op,
2999 .calling_convention,3037 .calling_convention,
3000 .float_mode,3038 .float_mode,
...@@ -3049,7 +3087,7 @@ pub const Type = extern union {...@@ -3049,7 +3087,7 @@ pub const Type = extern union {
3049 const union_obj = ty.cast(Payload.Union).?.data;3087 const union_obj = ty.cast(Payload.Union).?.data;
3050 return union_obj.srcLoc();3088 return union_obj.srcLoc();
3051 },3089 },
3052 .atomic_ordering,3090 .atomic_order,
3053 .atomic_rmw_op,3091 .atomic_rmw_op,
3054 .calling_convention,3092 .calling_convention,
3055 .float_mode,3093 .float_mode,
...@@ -3086,7 +3124,7 @@ pub const Type = extern union {...@@ -3086,7 +3124,7 @@ pub const Type = extern union {
3086 return union_obj.owner_decl;3124 return union_obj.owner_decl;
3087 },3125 },
3088 .@"opaque" => @panic("TODO"),3126 .@"opaque" => @panic("TODO"),
3089 .atomic_ordering,3127 .atomic_order,
3090 .atomic_rmw_op,3128 .atomic_rmw_op,
3091 .calling_convention,3129 .calling_convention,
3092 .float_mode,3130 .float_mode,
...@@ -3136,7 +3174,7 @@ pub const Type = extern union {...@@ -3136,7 +3174,7 @@ pub const Type = extern union {
3136 const tag_ty = Type.initPayload(&buffer.base);3174 const tag_ty = Type.initPayload(&buffer.base);
3137 return S.intInRange(tag_ty, int, fields_len);3175 return S.intInRange(tag_ty, int, fields_len);
3138 },3176 },
3139 .atomic_ordering,3177 .atomic_order,
3140 .atomic_rmw_op,3178 .atomic_rmw_op,
3141 .calling_convention,3179 .calling_convention,
3142 .float_mode,3180 .float_mode,
...@@ -3156,7 +3194,7 @@ pub const Type = extern union {...@@ -3156,7 +3194,7 @@ pub const Type = extern union {
3156 /// but with different alignment values, in this data structure they are represented3194 /// but with different alignment values, in this data structure they are represented
3157 /// with different enum tags, because the the former requires more payload data than the latter.3195 /// with different enum tags, because the the former requires more payload data than the latter.
3158 /// See `zigTypeTag` for the function that corresponds to `std.builtin.TypeId`.3196 /// See `zigTypeTag` for the function that corresponds to `std.builtin.TypeId`.
3159 pub const Tag = enum {3197 pub const Tag = enum(usize) {
3160 // The first section of this enum are tags that require no payload.3198 // The first section of this enum are tags that require no payload.
3161 u1,3199 u1,
3162 u8,3200 u8,
...@@ -3196,7 +3234,7 @@ pub const Type = extern union {...@@ -3196,7 +3234,7 @@ pub const Type = extern union {
3196 @"null",3234 @"null",
3197 @"undefined",3235 @"undefined",
3198 enum_literal,3236 enum_literal,
3199 atomic_ordering,3237 atomic_order,
3200 atomic_rmw_op,3238 atomic_rmw_op,
3201 calling_convention,3239 calling_convention,
3202 float_mode,3240 float_mode,
...@@ -3319,7 +3357,7 @@ pub const Type = extern union {...@@ -3319,7 +3357,7 @@ pub const Type = extern union {
3319 .empty_struct_literal,3357 .empty_struct_literal,
3320 .manyptr_u8,3358 .manyptr_u8,
3321 .manyptr_const_u8,3359 .manyptr_const_u8,
3322 .atomic_ordering,3360 .atomic_order,
3323 .atomic_rmw_op,3361 .atomic_rmw_op,
3324 .calling_convention,3362 .calling_convention,
3325 .float_mode,3363 .float_mode,
...@@ -3373,7 +3411,7 @@ pub const Type = extern union {...@@ -3373,7 +3411,7 @@ pub const Type = extern union {
33733411
3374 pub fn init(comptime t: Tag) file_struct.Type {3412 pub fn init(comptime t: Tag) file_struct.Type {
3375 comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);3413 comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
3376 return .{ .tag_if_small_enough = @enumToInt(t) };3414 return .{ .tag_if_small_enough = t };
3377 }3415 }
33783416
3379 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {3417 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {
src/value.zig+80-53
...@@ -17,10 +17,10 @@ const Air = @import("Air.zig");...@@ -17,10 +17,10 @@ const Air = @import("Air.zig");
17pub const Value = extern union {17pub const Value = extern union {
18 /// If the tag value is less than Tag.no_payload_count, then no pointer18 /// If the tag value is less than Tag.no_payload_count, then no pointer
19 /// dereference is needed.19 /// dereference is needed.
20 tag_if_small_enough: usize,20 tag_if_small_enough: Tag,
21 ptr_otherwise: *Payload,21 ptr_otherwise: *Payload,
2222
23 pub const Tag = enum {23 pub const Tag = enum(usize) {
24 // The first section of this enum are tags that require no payload.24 // The first section of this enum are tags that require no payload.
25 u1_type,25 u1_type,
26 u8_type,26 u8_type,
...@@ -60,7 +60,7 @@ pub const Value = extern union {...@@ -60,7 +60,7 @@ pub const Value = extern union {
60 null_type,60 null_type,
61 undefined_type,61 undefined_type,
62 enum_literal_type,62 enum_literal_type,
63 atomic_ordering_type,63 atomic_order_type,
64 atomic_rmw_op_type,64 atomic_rmw_op_type,
65 calling_convention_type,65 calling_convention_type,
66 float_mode_type,66 float_mode_type,
...@@ -223,7 +223,7 @@ pub const Value = extern union {...@@ -223,7 +223,7 @@ pub const Value = extern union {
223 .abi_align_default,223 .abi_align_default,
224 .manyptr_u8_type,224 .manyptr_u8_type,
225 .manyptr_const_u8_type,225 .manyptr_const_u8_type,
226 .atomic_ordering_type,226 .atomic_order_type,
227 .atomic_rmw_op_type,227 .atomic_rmw_op_type,
228 .calling_convention_type,228 .calling_convention_type,
229 .float_mode_type,229 .float_mode_type,
...@@ -296,7 +296,7 @@ pub const Value = extern union {...@@ -296,7 +296,7 @@ pub const Value = extern union {
296296
297 pub fn initTag(small_tag: Tag) Value {297 pub fn initTag(small_tag: Tag) Value {
298 assert(@enumToInt(small_tag) < Tag.no_payload_count);298 assert(@enumToInt(small_tag) < Tag.no_payload_count);
299 return .{ .tag_if_small_enough = @enumToInt(small_tag) };299 return .{ .tag_if_small_enough = small_tag };
300 }300 }
301301
302 pub fn initPayload(payload: *Payload) Value {302 pub fn initPayload(payload: *Payload) Value {
...@@ -305,8 +305,8 @@ pub const Value = extern union {...@@ -305,8 +305,8 @@ pub const Value = extern union {
305 }305 }
306306
307 pub fn tag(self: Value) Tag {307 pub fn tag(self: Value) Tag {
308 if (self.tag_if_small_enough < Tag.no_payload_count) {308 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
309 return @intToEnum(Tag, @intCast(std.meta.Tag(Tag), self.tag_if_small_enough));309 return self.tag_if_small_enough;
310 } else {310 } else {
311 return self.ptr_otherwise.tag;311 return self.ptr_otherwise.tag;
312 }312 }
...@@ -315,9 +315,9 @@ pub const Value = extern union {...@@ -315,9 +315,9 @@ pub const Value = extern union {
315 /// Prefer `castTag` to this.315 /// Prefer `castTag` to this.
316 pub fn cast(self: Value, comptime T: type) ?*T {316 pub fn cast(self: Value, comptime T: type) ?*T {
317 if (@hasField(T, "base_tag")) {317 if (@hasField(T, "base_tag")) {
318 return base.castTag(T.base_tag);318 return self.castTag(T.base_tag);
319 }319 }
320 if (self.tag_if_small_enough < Tag.no_payload_count) {320 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
321 return null;321 return null;
322 }322 }
323 inline for (@typeInfo(Tag).Enum.fields) |field| {323 inline for (@typeInfo(Tag).Enum.fields) |field| {
...@@ -335,7 +335,7 @@ pub const Value = extern union {...@@ -335,7 +335,7 @@ pub const Value = extern union {
335 }335 }
336336
337 pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {337 pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {
338 if (self.tag_if_small_enough < Tag.no_payload_count)338 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count)
339 return null;339 return null;
340340
341 if (self.ptr_otherwise.tag == t)341 if (self.ptr_otherwise.tag == t)
...@@ -344,8 +344,10 @@ pub const Value = extern union {...@@ -344,8 +344,10 @@ pub const Value = extern union {
344 return null;344 return null;
345 }345 }
346346
347 pub fn copy(self: Value, allocator: *Allocator) error{OutOfMemory}!Value {347 /// It's intentional that this function is not passed a corresponding Type, so that
348 if (self.tag_if_small_enough < Tag.no_payload_count) {348 /// a Value can be copied from a Sema to a Decl prior to resolving struct/union field types.
349 pub fn copy(self: Value, arena: *Allocator) error{OutOfMemory}!Value {
350 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
349 return Value{ .tag_if_small_enough = self.tag_if_small_enough };351 return Value{ .tag_if_small_enough = self.tag_if_small_enough };
350 } else switch (self.ptr_otherwise.tag) {352 } else switch (self.ptr_otherwise.tag) {
351 .u1_type,353 .u1_type,
...@@ -407,7 +409,7 @@ pub const Value = extern union {...@@ -407,7 +409,7 @@ pub const Value = extern union {
407 .abi_align_default,409 .abi_align_default,
408 .manyptr_u8_type,410 .manyptr_u8_type,
409 .manyptr_const_u8_type,411 .manyptr_const_u8_type,
410 .atomic_ordering_type,412 .atomic_order_type,
411 .atomic_rmw_op_type,413 .atomic_rmw_op_type,
412 .calling_convention_type,414 .calling_convention_type,
413 .float_mode_type,415 .float_mode_type,
...@@ -421,37 +423,37 @@ pub const Value = extern union {...@@ -421,37 +423,37 @@ pub const Value = extern union {
421423
422 .ty => {424 .ty => {
423 const payload = self.castTag(.ty).?;425 const payload = self.castTag(.ty).?;
424 const new_payload = try allocator.create(Payload.Ty);426 const new_payload = try arena.create(Payload.Ty);
425 new_payload.* = .{427 new_payload.* = .{
426 .base = payload.base,428 .base = payload.base,
427 .data = try payload.data.copy(allocator),429 .data = try payload.data.copy(arena),
428 };430 };
429 return Value{ .ptr_otherwise = &new_payload.base };431 return Value{ .ptr_otherwise = &new_payload.base };
430 },432 },
431 .int_type => return self.copyPayloadShallow(allocator, Payload.IntType),433 .int_type => return self.copyPayloadShallow(arena, Payload.IntType),
432 .int_u64 => return self.copyPayloadShallow(allocator, Payload.U64),434 .int_u64 => return self.copyPayloadShallow(arena, Payload.U64),
433 .int_i64 => return self.copyPayloadShallow(allocator, Payload.I64),435 .int_i64 => return self.copyPayloadShallow(arena, Payload.I64),
434 .int_big_positive, .int_big_negative => {436 .int_big_positive, .int_big_negative => {
435 const old_payload = self.cast(Payload.BigInt).?;437 const old_payload = self.cast(Payload.BigInt).?;
436 const new_payload = try allocator.create(Payload.BigInt);438 const new_payload = try arena.create(Payload.BigInt);
437 new_payload.* = .{439 new_payload.* = .{
438 .base = .{ .tag = self.ptr_otherwise.tag },440 .base = .{ .tag = self.ptr_otherwise.tag },
439 .data = try allocator.dupe(std.math.big.Limb, old_payload.data),441 .data = try arena.dupe(std.math.big.Limb, old_payload.data),
440 };442 };
441 return Value{ .ptr_otherwise = &new_payload.base };443 return Value{ .ptr_otherwise = &new_payload.base };
442 },444 },
443 .function => return self.copyPayloadShallow(allocator, Payload.Function),445 .function => return self.copyPayloadShallow(arena, Payload.Function),
444 .extern_fn => return self.copyPayloadShallow(allocator, Payload.Decl),446 .extern_fn => return self.copyPayloadShallow(arena, Payload.Decl),
445 .variable => return self.copyPayloadShallow(allocator, Payload.Variable),447 .variable => return self.copyPayloadShallow(arena, Payload.Variable),
446 .decl_ref => return self.copyPayloadShallow(allocator, Payload.Decl),448 .decl_ref => return self.copyPayloadShallow(arena, Payload.Decl),
447 .decl_ref_mut => return self.copyPayloadShallow(allocator, Payload.DeclRefMut),449 .decl_ref_mut => return self.copyPayloadShallow(arena, Payload.DeclRefMut),
448 .elem_ptr => {450 .elem_ptr => {
449 const payload = self.castTag(.elem_ptr).?;451 const payload = self.castTag(.elem_ptr).?;
450 const new_payload = try allocator.create(Payload.ElemPtr);452 const new_payload = try arena.create(Payload.ElemPtr);
451 new_payload.* = .{453 new_payload.* = .{
452 .base = payload.base,454 .base = payload.base,
453 .data = .{455 .data = .{
454 .array_ptr = try payload.data.array_ptr.copy(allocator),456 .array_ptr = try payload.data.array_ptr.copy(arena),
455 .index = payload.data.index,457 .index = payload.data.index,
456 },458 },
457 };459 };
...@@ -459,17 +461,17 @@ pub const Value = extern union {...@@ -459,17 +461,17 @@ pub const Value = extern union {
459 },461 },
460 .field_ptr => {462 .field_ptr => {
461 const payload = self.castTag(.field_ptr).?;463 const payload = self.castTag(.field_ptr).?;
462 const new_payload = try allocator.create(Payload.FieldPtr);464 const new_payload = try arena.create(Payload.FieldPtr);
463 new_payload.* = .{465 new_payload.* = .{
464 .base = payload.base,466 .base = payload.base,
465 .data = .{467 .data = .{
466 .container_ptr = try payload.data.container_ptr.copy(allocator),468 .container_ptr = try payload.data.container_ptr.copy(arena),
467 .field_index = payload.data.field_index,469 .field_index = payload.data.field_index,
468 },470 },
469 };471 };
470 return Value{ .ptr_otherwise = &new_payload.base };472 return Value{ .ptr_otherwise = &new_payload.base };
471 },473 },
472 .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes),474 .bytes => return self.copyPayloadShallow(arena, Payload.Bytes),
473 .repeated,475 .repeated,
474 .eu_payload,476 .eu_payload,
475 .eu_payload_ptr,477 .eu_payload_ptr,
...@@ -477,61 +479,85 @@ pub const Value = extern union {...@@ -477,61 +479,85 @@ pub const Value = extern union {
477 .opt_payload_ptr,479 .opt_payload_ptr,
478 => {480 => {
479 const payload = self.cast(Payload.SubValue).?;481 const payload = self.cast(Payload.SubValue).?;
480 const new_payload = try allocator.create(Payload.SubValue);482 const new_payload = try arena.create(Payload.SubValue);
481 new_payload.* = .{483 new_payload.* = .{
482 .base = payload.base,484 .base = payload.base,
483 .data = try payload.data.copy(allocator),485 .data = try payload.data.copy(arena),
484 };486 };
485 return Value{ .ptr_otherwise = &new_payload.base };487 return Value{ .ptr_otherwise = &new_payload.base };
486 },488 },
487 .array => {489 .array => {
488 const payload = self.castTag(.array).?;490 const payload = self.castTag(.array).?;
489 const new_payload = try allocator.create(Payload.Array);491 const new_payload = try arena.create(Payload.Array);
490 new_payload.* = .{492 new_payload.* = .{
491 .base = payload.base,493 .base = payload.base,
492 .data = try allocator.alloc(Value, payload.data.len),494 .data = try arena.alloc(Value, payload.data.len),
493 };495 };
494 std.mem.copy(Value, new_payload.data, payload.data);496 std.mem.copy(Value, new_payload.data, payload.data);
495 return Value{ .ptr_otherwise = &new_payload.base };497 return Value{ .ptr_otherwise = &new_payload.base };
496 },498 },
497 .slice => {499 .slice => {
498 const payload = self.castTag(.slice).?;500 const payload = self.castTag(.slice).?;
499 const new_payload = try allocator.create(Payload.Slice);501 const new_payload = try arena.create(Payload.Slice);
500 new_payload.* = .{502 new_payload.* = .{
501 .base = payload.base,503 .base = payload.base,
502 .data = .{504 .data = .{
503 .ptr = try payload.data.ptr.copy(allocator),505 .ptr = try payload.data.ptr.copy(arena),
504 .len = try payload.data.len.copy(allocator),506 .len = try payload.data.len.copy(arena),
505 },507 },
506 };508 };
507 return Value{ .ptr_otherwise = &new_payload.base };509 return Value{ .ptr_otherwise = &new_payload.base };
508 },510 },
509 .float_16 => return self.copyPayloadShallow(allocator, Payload.Float_16),511 .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16),
510 .float_32 => return self.copyPayloadShallow(allocator, Payload.Float_32),512 .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32),
511 .float_64 => return self.copyPayloadShallow(allocator, Payload.Float_64),513 .float_64 => return self.copyPayloadShallow(arena, Payload.Float_64),
512 .float_128 => return self.copyPayloadShallow(allocator, Payload.Float_128),514 .float_128 => return self.copyPayloadShallow(arena, Payload.Float_128),
513 .enum_literal => {515 .enum_literal => {
514 const payload = self.castTag(.enum_literal).?;516 const payload = self.castTag(.enum_literal).?;
515 const new_payload = try allocator.create(Payload.Bytes);517 const new_payload = try arena.create(Payload.Bytes);
516 new_payload.* = .{518 new_payload.* = .{
517 .base = payload.base,519 .base = payload.base,
518 .data = try allocator.dupe(u8, payload.data),520 .data = try arena.dupe(u8, payload.data),
521 };
522 return Value{ .ptr_otherwise = &new_payload.base };
523 },
524 .enum_field_index => return self.copyPayloadShallow(arena, Payload.U32),
525 .@"error" => return self.copyPayloadShallow(arena, Payload.Error),
526
527 .@"struct" => {
528 const old_field_values = self.castTag(.@"struct").?.data;
529 const new_payload = try arena.create(Payload.Struct);
530 new_payload.* = .{
531 .base = .{ .tag = .@"struct" },
532 .data = try arena.alloc(Value, old_field_values.len),
533 };
534 for (old_field_values) |old_field_val, i| {
535 new_payload.data[i] = try old_field_val.copy(arena);
536 }
537 return Value{ .ptr_otherwise = &new_payload.base };
538 },
539
540 .@"union" => {
541 const tag_and_val = self.castTag(.@"union").?.data;
542 const new_payload = try arena.create(Payload.Union);
543 new_payload.* = .{
544 .base = .{ .tag = .@"union" },
545 .data = .{
546 .tag = try tag_and_val.tag.copy(arena),
547 .val = try tag_and_val.val.copy(arena),
548 },
519 };549 };
520 return Value{ .ptr_otherwise = &new_payload.base };550 return Value{ .ptr_otherwise = &new_payload.base };
521 },551 },
522 .enum_field_index => return self.copyPayloadShallow(allocator, Payload.U32),
523 .@"error" => return self.copyPayloadShallow(allocator, Payload.Error),
524 .@"struct" => @panic("TODO can't copy struct value without knowing the type"),
525 .@"union" => @panic("TODO can't copy union value without knowing the type"),
526552
527 .inferred_alloc => unreachable,553 .inferred_alloc => unreachable,
528 .inferred_alloc_comptime => unreachable,554 .inferred_alloc_comptime => unreachable,
529 }555 }
530 }556 }
531557
532 fn copyPayloadShallow(self: Value, allocator: *Allocator, comptime T: type) error{OutOfMemory}!Value {558 fn copyPayloadShallow(self: Value, arena: *Allocator, comptime T: type) error{OutOfMemory}!Value {
533 const payload = self.cast(T).?;559 const payload = self.cast(T).?;
534 const new_payload = try allocator.create(T);560 const new_payload = try arena.create(T);
535 new_payload.* = payload.*;561 new_payload.* = payload.*;
536 return Value{ .ptr_otherwise = &new_payload.base };562 return Value{ .ptr_otherwise = &new_payload.base };
537 }563 }
...@@ -596,7 +622,7 @@ pub const Value = extern union {...@@ -596,7 +622,7 @@ pub const Value = extern union {
596 .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),622 .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),
597 .manyptr_u8_type => return out_stream.writeAll("[*]u8"),623 .manyptr_u8_type => return out_stream.writeAll("[*]u8"),
598 .manyptr_const_u8_type => return out_stream.writeAll("[*]const u8"),624 .manyptr_const_u8_type => return out_stream.writeAll("[*]const u8"),
599 .atomic_ordering_type => return out_stream.writeAll("std.builtin.AtomicOrdering"),625 .atomic_order_type => return out_stream.writeAll("std.builtin.AtomicOrder"),
600 .atomic_rmw_op_type => return out_stream.writeAll("std.builtin.AtomicRmwOp"),626 .atomic_rmw_op_type => return out_stream.writeAll("std.builtin.AtomicRmwOp"),
601 .calling_convention_type => return out_stream.writeAll("std.builtin.CallingConvention"),627 .calling_convention_type => return out_stream.writeAll("std.builtin.CallingConvention"),
602 .float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"),628 .float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"),
...@@ -763,7 +789,7 @@ pub const Value = extern union {...@@ -763,7 +789,7 @@ pub const Value = extern union {
763 .enum_literal_type => Type.initTag(.enum_literal),789 .enum_literal_type => Type.initTag(.enum_literal),
764 .manyptr_u8_type => Type.initTag(.manyptr_u8),790 .manyptr_u8_type => Type.initTag(.manyptr_u8),
765 .manyptr_const_u8_type => Type.initTag(.manyptr_const_u8),791 .manyptr_const_u8_type => Type.initTag(.manyptr_const_u8),
766 .atomic_ordering_type => Type.initTag(.atomic_ordering),792 .atomic_order_type => Type.initTag(.atomic_order),
767 .atomic_rmw_op_type => Type.initTag(.atomic_rmw_op),793 .atomic_rmw_op_type => Type.initTag(.atomic_rmw_op),
768 .calling_convention_type => Type.initTag(.calling_convention),794 .calling_convention_type => Type.initTag(.calling_convention),
769 .float_mode_type => Type.initTag(.float_mode),795 .float_mode_type => Type.initTag(.float_mode),
...@@ -1932,8 +1958,9 @@ pub const Value = extern union {...@@ -1932,8 +1958,9 @@ pub const Value = extern union {
1932 pub const base_tag = Tag.@"struct";1958 pub const base_tag = Tag.@"struct";
19331959
1934 base: Payload = .{ .tag = base_tag },1960 base: Payload = .{ .tag = base_tag },
1935 /// Field values. The number and type are according to the struct type.1961 /// Field values. The types are according to the struct type.
1936 data: [*]Value,1962 /// The length is provided here so that copying a Value does not depend on the Type.
1963 data: []Value,
1937 };1964 };
19381965
1939 pub const Union = struct {1966 pub const Union = struct {
src/windows_sdk.cpp+16-4
...@@ -23,16 +23,19 @@ enum NativeArch {...@@ -23,16 +23,19 @@ enum NativeArch {
23 NativeArchArm,23 NativeArchArm,
24 NativeArchi386,24 NativeArchi386,
25 NativeArchx86_64,25 NativeArchx86_64,
26 NativeArchAarch64,
26};27};
2728
28#if defined(_M_ARM) || defined(__arm_)29#if defined(_M_ARM) || defined(__arm_)
29static const NativeArch native_arch = NativeArchArm;30static const NativeArch native_arch = NativeArchArm;
30#endif31#elif defined(_M_IX86) || defined(__i386__)
31#if defined(_M_IX86) || defined(__i386__)
32static const NativeArch native_arch = NativeArchi386;32static const NativeArch native_arch = NativeArchi386;
33#endif33#elif defined(_M_X64) || defined(__x86_64__)
34#if defined(_M_X64) || defined(__x86_64__)
35static const NativeArch native_arch = NativeArchx86_64;34static const NativeArch native_arch = NativeArchx86_64;
35#elif defined(_M_ARM64) || defined(__aarch64__)
36static const NativeArch native_arch = NativeArchAarch64;
37#else
38#error unsupported architecture
36#endif39#endif
3740
38void zig_free_windows_sdk(struct ZigWindowsSDK *sdk) {41void zig_free_windows_sdk(struct ZigWindowsSDK *sdk) {
...@@ -116,6 +119,9 @@ static ZigFindWindowsSdkError find_msvc_lib_dir(ZigWindowsSDKPrivate *priv) {...@@ -116,6 +119,9 @@ static ZigFindWindowsSdkError find_msvc_lib_dir(ZigWindowsSDKPrivate *priv) {
116 case NativeArchArm:119 case NativeArchArm:
117 out_append_ptr += sprintf(out_append_ptr, "arm\\");120 out_append_ptr += sprintf(out_append_ptr, "arm\\");
118 break;121 break;
122 case NativeArchAarch64:
123 out_append_ptr += sprintf(out_append_ptr, "arm64\\");
124 break;
119 }125 }
120 sprintf(tmp_buf, "%s%s", output_path, "vcruntime.lib");126 sprintf(tmp_buf, "%s%s", output_path, "vcruntime.lib");
121127
...@@ -161,6 +167,9 @@ com_done:;...@@ -161,6 +167,9 @@ com_done:;
161 case NativeArchArm:167 case NativeArchArm:
162 tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "arm\\");168 tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "arm\\");
163 break;169 break;
170 case NativeArchAarch64:
171 tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "arm64\\");
172 break;
164 }173 }
165174
166 char *output_path = strdup(tmp_buf);175 char *output_path = strdup(tmp_buf);
...@@ -204,6 +213,9 @@ static ZigFindWindowsSdkError find_10_version(ZigWindowsSDKPrivate *priv) {...@@ -204,6 +213,9 @@ static ZigFindWindowsSdkError find_10_version(ZigWindowsSDKPrivate *priv) {
204 case NativeArchArm:213 case NativeArchArm:
205 option_name = "OptionId.DesktopCPParm";214 option_name = "OptionId.DesktopCPParm";
206 break;215 break;
216 case NativeArchAarch64:
217 option_name = "OptionId.DesktopCPParm64";
218 break;
207 case NativeArchx86_64:219 case NativeArchx86_64:
208 option_name = "OptionId.DesktopCPPx64";220 option_name = "OptionId.DesktopCPPx64";
209 break;221 break;
src/windows_sdk.zig+13-8
...@@ -11,12 +11,17 @@ pub const ZigWindowsSDK = extern struct {...@@ -11,12 +11,17 @@ pub const ZigWindowsSDK = extern struct {
11 version81_len: usize,11 version81_len: usize,
12 msvc_lib_dir_ptr: ?[*]const u8,12 msvc_lib_dir_ptr: ?[*]const u8,
13 msvc_lib_dir_len: usize,13 msvc_lib_dir_len: usize,
14
15 pub const find = zig_find_windows_sdk;
16 pub const free = zig_free_windows_sdk;
17
18 pub const FindError = enum(c_int) {
19 None,
20 OutOfMemory,
21 NotFound,
22 PathTooLong,
23 };
24
25 extern fn zig_find_windows_sdk(out_sdk: **ZigWindowsSDK) FindError;
26 extern fn zig_free_windows_sdk(sdk: *ZigWindowsSDK) void;
14};27};
15pub const ZigFindWindowsSdkError = enum(c_int) {
16 None,
17 OutOfMemory,
18 NotFound,
19 PathTooLong,
20};
21pub extern fn zig_find_windows_sdk(out_sdk: **ZigWindowsSDK) ZigFindWindowsSdkError;
22pub extern fn zig_free_windows_sdk(sdk: *ZigWindowsSDK) void;
src/zig_llvm.cpp+52
...@@ -484,6 +484,58 @@ LLVMValueRef ZigLLVMBuildSMin(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef R...@@ -484,6 +484,58 @@ LLVMValueRef ZigLLVMBuildSMin(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef R
484 return wrap(call_inst);484 return wrap(call_inst);
485}485}
486486
487LLVMValueRef ZigLLVMBuildSAddSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
488 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::sadd_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
489 return wrap(call_inst);
490}
491
492LLVMValueRef ZigLLVMBuildUAddSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
493 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::uadd_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
494 return wrap(call_inst);
495}
496
497LLVMValueRef ZigLLVMBuildSSubSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
498 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::ssub_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
499 return wrap(call_inst);
500}
501
502LLVMValueRef ZigLLVMBuildUSubSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
503 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::usub_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
504 return wrap(call_inst);
505}
506
507LLVMValueRef ZigLLVMBuildSMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
508 llvm::Type* types[1] = {
509 unwrap(LHS)->getType(),
510 };
511 // pass scale = 0 as third argument
512 llvm::Value* values[3] = {unwrap(LHS), unwrap(RHS), unwrap(B)->getInt32(0)};
513
514 CallInst *call_inst = unwrap(B)->CreateIntrinsic(Intrinsic::smul_fix_sat, types, values, nullptr, name);
515 return wrap(call_inst);
516}
517
518LLVMValueRef ZigLLVMBuildUMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
519 llvm::Type* types[1] = {
520 unwrap(LHS)->getType(),
521 };
522 // pass scale = 0 as third argument
523 llvm::Value* values[3] = {unwrap(LHS), unwrap(RHS), unwrap(B)->getInt32(0)};
524
525 CallInst *call_inst = unwrap(B)->CreateIntrinsic(Intrinsic::umul_fix_sat, types, values, nullptr, name);
526 return wrap(call_inst);
527}
528
529LLVMValueRef ZigLLVMBuildSShlSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
530 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::sshl_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
531 return wrap(call_inst);
532}
533
534LLVMValueRef ZigLLVMBuildUShlSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
535 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::ushl_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
536 return wrap(call_inst);
537}
538
487void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) {539void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) {
488 assert( isa<Function>(unwrap(fn)) );540 assert( isa<Function>(unwrap(fn)) );
489 Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn));541 Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn));
src/zig_llvm.h+9
...@@ -136,6 +136,15 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMax(LLVMBuilderRef builder, LLVMValueRef...@@ -136,6 +136,15 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMax(LLVMBuilderRef builder, LLVMValueRef
136ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMin(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);136ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMin(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
137ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMax(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);137ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMax(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
138ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMin(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);138ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMin(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
139ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUAddSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
140ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSAddSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
141ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUSubSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
142ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSSubSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
143ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name);
144ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name);
145ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUShlSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
146ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSShlSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
147
139148
140ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,149ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
141 const char *name);150 const char *name);
test/behavior.zig+5-3
...@@ -10,6 +10,8 @@ test {...@@ -10,6 +10,8 @@ test {
10 _ = @import("behavior/if.zig");10 _ = @import("behavior/if.zig");
11 _ = @import("behavior/cast.zig");11 _ = @import("behavior/cast.zig");
12 _ = @import("behavior/array.zig");12 _ = @import("behavior/array.zig");
13 _ = @import("behavior/usingnamespace.zig");
14 _ = @import("behavior/atomics.zig");
1315
14 if (!builtin.zig_is_stage2) {16 if (!builtin.zig_is_stage2) {
15 // Tests that only pass for stage1.17 // Tests that only pass for stage1.
...@@ -20,7 +22,7 @@ test {...@@ -20,7 +22,7 @@ test {
20 _ = @import("behavior/asm.zig");22 _ = @import("behavior/asm.zig");
21 _ = @import("behavior/async_fn.zig");23 _ = @import("behavior/async_fn.zig");
22 }24 }
23 _ = @import("behavior/atomics.zig");25 _ = @import("behavior/atomics_stage1.zig");
24 _ = @import("behavior/await_struct.zig");26 _ = @import("behavior/await_struct.zig");
25 _ = @import("behavior/bit_shifting.zig");27 _ = @import("behavior/bit_shifting.zig");
26 _ = @import("behavior/bitcast.zig");28 _ = @import("behavior/bitcast.zig");
...@@ -125,6 +127,7 @@ test {...@@ -125,6 +127,7 @@ test {
125 _ = @import("behavior/pub_enum.zig");127 _ = @import("behavior/pub_enum.zig");
126 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");128 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
127 _ = @import("behavior/reflection.zig");129 _ = @import("behavior/reflection.zig");
130 _ = @import("behavior/saturating_arithmetic.zig");
128 _ = @import("behavior/shuffle.zig");131 _ = @import("behavior/shuffle.zig");
129 _ = @import("behavior/select.zig");132 _ = @import("behavior/select.zig");
130 _ = @import("behavior/sizeof_and_typeof.zig");133 _ = @import("behavior/sizeof_and_typeof.zig");
...@@ -136,7 +139,6 @@ test {...@@ -136,7 +139,6 @@ test {
136 _ = @import("behavior/switch.zig");139 _ = @import("behavior/switch.zig");
137 _ = @import("behavior/switch_prong_err_enum.zig");140 _ = @import("behavior/switch_prong_err_enum.zig");
138 _ = @import("behavior/switch_prong_implicit_cast.zig");141 _ = @import("behavior/switch_prong_implicit_cast.zig");
139 _ = @import("behavior/syntax.zig");
140 _ = @import("behavior/this.zig");142 _ = @import("behavior/this.zig");
141 _ = @import("behavior/truncate.zig");143 _ = @import("behavior/truncate.zig");
142 _ = @import("behavior/try.zig");144 _ = @import("behavior/try.zig");
...@@ -147,7 +149,7 @@ test {...@@ -147,7 +149,7 @@ test {
147 _ = @import("behavior/undefined.zig");149 _ = @import("behavior/undefined.zig");
148 _ = @import("behavior/underscore.zig");150 _ = @import("behavior/underscore.zig");
149 _ = @import("behavior/union.zig");151 _ = @import("behavior/union.zig");
150 _ = @import("behavior/usingnamespace.zig");152 _ = @import("behavior/usingnamespace_stage1.zig");
151 _ = @import("behavior/var_args.zig");153 _ = @import("behavior/var_args.zig");
152 _ = @import("behavior/vector.zig");154 _ = @import("behavior/vector.zig");
153 _ = @import("behavior/void.zig");155 _ = @import("behavior/void.zig");
test/behavior/array.zig+24
...@@ -3,3 +3,27 @@ const testing = std.testing;...@@ -3,3 +3,27 @@ const testing = std.testing;
3const mem = std.mem;3const mem = std.mem;
4const expect = testing.expect;4const expect = testing.expect;
5const expectEqual = testing.expectEqual;5const expectEqual = testing.expectEqual;
6
7test "arrays" {
8 var array: [5]u32 = undefined;
9
10 var i: u32 = 0;
11 while (i < 5) {
12 array[i] = i + 1;
13 i = array[i];
14 }
15
16 i = 0;
17 var accumulator = @as(u32, 0);
18 while (i < 5) {
19 accumulator += array[i];
20
21 i += 1;
22 }
23
24 try expect(accumulator == 15);
25 try expect(getArrayLen(&array) == 5);
26}
27fn getArrayLen(a: []const u32) usize {
28 return a.len;
29}
test/behavior/array_stage1.zig+9-69
...@@ -4,30 +4,6 @@ const mem = std.mem;...@@ -4,30 +4,6 @@ const mem = std.mem;
4const expect = testing.expect;4const expect = testing.expect;
5const expectEqual = testing.expectEqual;5const expectEqual = testing.expectEqual;
66
7test "arrays" {
8 var array: [5]u32 = undefined;
9
10 var i: u32 = 0;
11 while (i < 5) {
12 array[i] = i + 1;
13 i = array[i];
14 }
15
16 i = 0;
17 var accumulator = @as(u32, 0);
18 while (i < 5) {
19 accumulator += array[i];
20
21 i += 1;
22 }
23
24 try expect(accumulator == 15);
25 try expect(getArrayLen(&array) == 5);
26}
27fn getArrayLen(a: []const u32) usize {
28 return a.len;
29}
30
31test "array with sentinels" {7test "array with sentinels" {
32 const S = struct {8 const S = struct {
33 fn doTheTest(is_ct: bool) !void {9 fn doTheTest(is_ct: bool) !void {
...@@ -64,12 +40,7 @@ test "void arrays" {...@@ -64,12 +40,7 @@ test "void arrays" {
64}40}
6541
66test "array literal" {42test "array literal" {
67 const hex_mult = [_]u16{43 const hex_mult = [_]u16{ 4096, 256, 16, 1 };
68 4096,
69 256,
70 16,
71 1,
72 };
7344
74 try expect(hex_mult.len == 4);45 try expect(hex_mult.len == 4);
75 try expect(hex_mult[1] == 256);46 try expect(hex_mult[1] == 256);
...@@ -84,21 +55,10 @@ test "array dot len const expr" {...@@ -84,21 +55,10 @@ test "array dot len const expr" {
84const ArrayDotLenConstExpr = struct {55const ArrayDotLenConstExpr = struct {
85 y: [some_array.len]u8,56 y: [some_array.len]u8,
86};57};
87const some_array = [_]u8{58const some_array = [_]u8{ 0, 1, 2, 3 };
88 0,
89 1,
90 2,
91 3,
92};
9359
94test "nested arrays" {60test "nested arrays" {
95 const array_of_strings = [_][]const u8{61 const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" };
96 "hello",
97 "this",
98 "is",
99 "my",
100 "thing",
101 };
102 for (array_of_strings) |s, i| {62 for (array_of_strings) |s, i| {
103 if (i == 0) try expect(mem.eql(u8, s, "hello"));63 if (i == 0) try expect(mem.eql(u8, s, "hello"));
104 if (i == 1) try expect(mem.eql(u8, s, "this"));64 if (i == 1) try expect(mem.eql(u8, s, "this"));
...@@ -109,12 +69,8 @@ test "nested arrays" {...@@ -109,12 +69,8 @@ test "nested arrays" {
109}69}
11070
111var s_array: [8]Sub = undefined;71var s_array: [8]Sub = undefined;
112const Sub = struct {72const Sub = struct { b: u8 };
113 b: u8,73const Str = struct { a: []Sub };
114};
115const Str = struct {
116 a: []Sub,
117};
118test "set global var array via slice embedded in struct" {74test "set global var array via slice embedded in struct" {
119 var s = Str{ .a = s_array[0..] };75 var s = Str{ .a = s_array[0..] };
12076
...@@ -208,26 +164,10 @@ test "runtime initialize array elem and then implicit cast to slice" {...@@ -208,26 +164,10 @@ test "runtime initialize array elem and then implicit cast to slice" {
208test "array literal as argument to function" {164test "array literal as argument to function" {
209 const S = struct {165 const S = struct {
210 fn entry(two: i32) !void {166 fn entry(two: i32) !void {
211 try foo(&[_]i32{167 try foo(&[_]i32{ 1, 2, 3 });
212 1,168 try foo(&[_]i32{ 1, two, 3 });
213 2,169 try foo2(true, &[_]i32{ 1, 2, 3 });
214 3,170 try foo2(true, &[_]i32{ 1, two, 3 });
215 });
216 try foo(&[_]i32{
217 1,
218 two,
219 3,
220 });
221 try foo2(true, &[_]i32{
222 1,
223 2,
224 3,
225 });
226 try foo2(true, &[_]i32{
227 1,
228 two,
229 3,
230 });
231 }171 }
232 fn foo(x: []const i32) !void {172 fn foo(x: []const i32) !void {
233 try expect(x[0] == 1);173 try expect(x[0] == 1);
test/behavior/atomics.zig-190
...@@ -24,193 +24,3 @@ fn testCmpxchg() !void {...@@ -24,193 +24,3 @@ fn testCmpxchg() !void {
24 try expect(@cmpxchgStrong(i32, &x, 5678, 42, .SeqCst, .SeqCst) == null);24 try expect(@cmpxchgStrong(i32, &x, 5678, 42, .SeqCst, .SeqCst) == null);
25 try expect(x == 42);25 try expect(x == 42);
26}26}
27
28test "fence" {
29 var x: i32 = 1234;
30 @fence(.SeqCst);
31 x = 5678;
32}
33
34test "atomicrmw and atomicload" {
35 var data: u8 = 200;
36 try testAtomicRmw(&data);
37 try expect(data == 42);
38 try testAtomicLoad(&data);
39}
40
41fn testAtomicRmw(ptr: *u8) !void {
42 const prev_value = @atomicRmw(u8, ptr, .Xchg, 42, .SeqCst);
43 try expect(prev_value == 200);
44 comptime {
45 var x: i32 = 1234;
46 const y: i32 = 12345;
47 try expect(@atomicLoad(i32, &x, .SeqCst) == 1234);
48 try expect(@atomicLoad(i32, &y, .SeqCst) == 12345);
49 }
50}
51
52fn testAtomicLoad(ptr: *u8) !void {
53 const x = @atomicLoad(u8, ptr, .SeqCst);
54 try expect(x == 42);
55}
56
57test "cmpxchg with ptr" {
58 var data1: i32 = 1234;
59 var data2: i32 = 5678;
60 var data3: i32 = 9101;
61 var x: *i32 = &data1;
62 if (@cmpxchgWeak(*i32, &x, &data2, &data3, .SeqCst, .SeqCst)) |x1| {
63 try expect(x1 == &data1);
64 } else {
65 @panic("cmpxchg should have failed");
66 }
67
68 while (@cmpxchgWeak(*i32, &x, &data1, &data3, .SeqCst, .SeqCst)) |x1| {
69 try expect(x1 == &data1);
70 }
71 try expect(x == &data3);
72
73 try expect(@cmpxchgStrong(*i32, &x, &data3, &data2, .SeqCst, .SeqCst) == null);
74 try expect(x == &data2);
75}
76
77test "128-bit cmpxchg" {
78 try test_u128_cmpxchg();
79 comptime try test_u128_cmpxchg();
80}
81
82fn test_u128_cmpxchg() !void {
83 if (std.Target.current.cpu.arch != .x86_64) return error.SkipZigTest;
84 if (comptime !std.Target.x86.featureSetHas(std.Target.current.cpu.features, .cx16)) return error.SkipZigTest;
85
86 var x: u128 = 1234;
87 if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
88 try expect(x1 == 1234);
89 } else {
90 @panic("cmpxchg should have failed");
91 }
92
93 while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {
94 try expect(x1 == 1234);
95 }
96 try expect(x == 5678);
97
98 try expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
99 try expect(x == 42);
100}
101
102test "cmpxchg with ignored result" {
103 var x: i32 = 1234;
104
105 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
106
107 try expectEqual(@as(i32, 5678), x);
108}
109
110var a_global_variable = @as(u32, 1234);
111
112test "cmpxchg on a global variable" {
113 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
114 try expectEqual(@as(u32, 42), a_global_variable);
115}
116
117test "atomic load and rmw with enum" {
118 const Value = enum(u8) {
119 a,
120 b,
121 c,
122 };
123 var x = Value.a;
124
125 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);
126
127 _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst);
128 try expect(@atomicLoad(Value, &x, .SeqCst) == .c);
129 try expect(@atomicLoad(Value, &x, .SeqCst) != .a);
130 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);
131}
132
133test "atomic store" {
134 var x: u32 = 0;
135 @atomicStore(u32, &x, 1, .SeqCst);
136 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
137 @atomicStore(u32, &x, 12345678, .SeqCst);
138 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
139}
140
141test "atomic store comptime" {
142 comptime try testAtomicStore();
143 try testAtomicStore();
144}
145
146fn testAtomicStore() !void {
147 var x: u32 = 0;
148 @atomicStore(u32, &x, 1, .SeqCst);
149 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
150 @atomicStore(u32, &x, 12345678, .SeqCst);
151 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
152}
153
154test "atomicrmw with floats" {
155 try testAtomicRmwFloat();
156 comptime try testAtomicRmwFloat();
157}
158
159fn testAtomicRmwFloat() !void {
160 var x: f32 = 0;
161 try expect(x == 0);
162 _ = @atomicRmw(f32, &x, .Xchg, 1, .SeqCst);
163 try expect(x == 1);
164 _ = @atomicRmw(f32, &x, .Add, 5, .SeqCst);
165 try expect(x == 6);
166 _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst);
167 try expect(x == 4);
168}
169
170test "atomicrmw with ints" {
171 try testAtomicRmwInt();
172 comptime try testAtomicRmwInt();
173}
174
175fn testAtomicRmwInt() !void {
176 var x: u8 = 1;
177 var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst);
178 try expect(x == 3 and res == 1);
179 _ = @atomicRmw(u8, &x, .Add, 3, .SeqCst);
180 try expect(x == 6);
181 _ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst);
182 try expect(x == 5);
183 _ = @atomicRmw(u8, &x, .And, 4, .SeqCst);
184 try expect(x == 4);
185 _ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst);
186 try expect(x == 0xfb);
187 _ = @atomicRmw(u8, &x, .Or, 6, .SeqCst);
188 try expect(x == 0xff);
189 _ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst);
190 try expect(x == 0xfd);
191
192 _ = @atomicRmw(u8, &x, .Max, 1, .SeqCst);
193 try expect(x == 0xfd);
194 _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst);
195 try expect(x == 1);
196}
197
198test "atomics with different types" {
199 try testAtomicsWithType(bool, true, false);
200 inline for (.{ u1, i4, u5, i15, u24 }) |T| {
201 try testAtomicsWithType(T, 0, 1);
202 }
203 try testAtomicsWithType(u0, 0, 0);
204 try testAtomicsWithType(i0, 0, 0);
205}
206
207fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {
208 var x: T = b;
209 @atomicStore(T, &x, a, .SeqCst);
210 try expect(x == a);
211 try expect(@atomicLoad(T, &x, .SeqCst) == a);
212 try expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a);
213 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null);
214 if (@sizeOf(T) != 0)
215 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a);
216}
test/behavior/atomics_stage1.zig created+194
...@@ -0,0 +1,194 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4const builtin = @import("builtin");
5
6test "fence" {
7 var x: i32 = 1234;
8 @fence(.SeqCst);
9 x = 5678;
10}
11
12test "atomicrmw and atomicload" {
13 var data: u8 = 200;
14 try testAtomicRmw(&data);
15 try expect(data == 42);
16 try testAtomicLoad(&data);
17}
18
19fn testAtomicRmw(ptr: *u8) !void {
20 const prev_value = @atomicRmw(u8, ptr, .Xchg, 42, .SeqCst);
21 try expect(prev_value == 200);
22 comptime {
23 var x: i32 = 1234;
24 const y: i32 = 12345;
25 try expect(@atomicLoad(i32, &x, .SeqCst) == 1234);
26 try expect(@atomicLoad(i32, &y, .SeqCst) == 12345);
27 }
28}
29
30fn testAtomicLoad(ptr: *u8) !void {
31 const x = @atomicLoad(u8, ptr, .SeqCst);
32 try expect(x == 42);
33}
34
35test "cmpxchg with ptr" {
36 var data1: i32 = 1234;
37 var data2: i32 = 5678;
38 var data3: i32 = 9101;
39 var x: *i32 = &data1;
40 if (@cmpxchgWeak(*i32, &x, &data2, &data3, .SeqCst, .SeqCst)) |x1| {
41 try expect(x1 == &data1);
42 } else {
43 @panic("cmpxchg should have failed");
44 }
45
46 while (@cmpxchgWeak(*i32, &x, &data1, &data3, .SeqCst, .SeqCst)) |x1| {
47 try expect(x1 == &data1);
48 }
49 try expect(x == &data3);
50
51 try expect(@cmpxchgStrong(*i32, &x, &data3, &data2, .SeqCst, .SeqCst) == null);
52 try expect(x == &data2);
53}
54
55test "128-bit cmpxchg" {
56 try test_u128_cmpxchg();
57 comptime try test_u128_cmpxchg();
58}
59
60fn test_u128_cmpxchg() !void {
61 if (std.Target.current.cpu.arch != .x86_64) return error.SkipZigTest;
62 if (comptime !std.Target.x86.featureSetHas(std.Target.current.cpu.features, .cx16)) return error.SkipZigTest;
63
64 var x: u128 = 1234;
65 if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
66 try expect(x1 == 1234);
67 } else {
68 @panic("cmpxchg should have failed");
69 }
70
71 while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {
72 try expect(x1 == 1234);
73 }
74 try expect(x == 5678);
75
76 try expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
77 try expect(x == 42);
78}
79
80test "cmpxchg with ignored result" {
81 var x: i32 = 1234;
82
83 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
84
85 try expectEqual(@as(i32, 5678), x);
86}
87
88var a_global_variable = @as(u32, 1234);
89
90test "cmpxchg on a global variable" {
91 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
92 try expectEqual(@as(u32, 42), a_global_variable);
93}
94
95test "atomic load and rmw with enum" {
96 const Value = enum(u8) {
97 a,
98 b,
99 c,
100 };
101 var x = Value.a;
102
103 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);
104
105 _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst);
106 try expect(@atomicLoad(Value, &x, .SeqCst) == .c);
107 try expect(@atomicLoad(Value, &x, .SeqCst) != .a);
108 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);
109}
110
111test "atomic store" {
112 var x: u32 = 0;
113 @atomicStore(u32, &x, 1, .SeqCst);
114 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
115 @atomicStore(u32, &x, 12345678, .SeqCst);
116 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
117}
118
119test "atomic store comptime" {
120 comptime try testAtomicStore();
121 try testAtomicStore();
122}
123
124fn testAtomicStore() !void {
125 var x: u32 = 0;
126 @atomicStore(u32, &x, 1, .SeqCst);
127 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
128 @atomicStore(u32, &x, 12345678, .SeqCst);
129 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
130}
131
132test "atomicrmw with floats" {
133 try testAtomicRmwFloat();
134 comptime try testAtomicRmwFloat();
135}
136
137fn testAtomicRmwFloat() !void {
138 var x: f32 = 0;
139 try expect(x == 0);
140 _ = @atomicRmw(f32, &x, .Xchg, 1, .SeqCst);
141 try expect(x == 1);
142 _ = @atomicRmw(f32, &x, .Add, 5, .SeqCst);
143 try expect(x == 6);
144 _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst);
145 try expect(x == 4);
146}
147
148test "atomicrmw with ints" {
149 try testAtomicRmwInt();
150 comptime try testAtomicRmwInt();
151}
152
153fn testAtomicRmwInt() !void {
154 var x: u8 = 1;
155 var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst);
156 try expect(x == 3 and res == 1);
157 _ = @atomicRmw(u8, &x, .Add, 3, .SeqCst);
158 try expect(x == 6);
159 _ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst);
160 try expect(x == 5);
161 _ = @atomicRmw(u8, &x, .And, 4, .SeqCst);
162 try expect(x == 4);
163 _ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst);
164 try expect(x == 0xfb);
165 _ = @atomicRmw(u8, &x, .Or, 6, .SeqCst);
166 try expect(x == 0xff);
167 _ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst);
168 try expect(x == 0xfd);
169
170 _ = @atomicRmw(u8, &x, .Max, 1, .SeqCst);
171 try expect(x == 0xfd);
172 _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst);
173 try expect(x == 1);
174}
175
176test "atomics with different types" {
177 try testAtomicsWithType(bool, true, false);
178 inline for (.{ u1, i4, u5, i15, u24 }) |T| {
179 try testAtomicsWithType(T, 0, 1);
180 }
181 try testAtomicsWithType(u0, 0, 0);
182 try testAtomicsWithType(i0, 0, 0);
183}
184
185fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {
186 var x: T = b;
187 @atomicStore(T, &x, a, .SeqCst);
188 try expect(x == a);
189 try expect(@atomicLoad(T, &x, .SeqCst) == a);
190 try expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a);
191 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null);
192 if (@sizeOf(T) != 0)
193 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a);
194}
test/behavior/basic.zig+8
...@@ -162,3 +162,11 @@ fn fA() []const u8 {...@@ -162,3 +162,11 @@ fn fA() []const u8 {
162fn fB() []const u8 {162fn fB() []const u8 {
163 return "b";163 return "b";
164}164}
165
166test "string concatenation" {
167 try expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
168}
169
170test "array mult operator" {
171 try expect(mem.eql(u8, "ab" ** 5, "ababababab"));
172}
test/behavior/eval.zig-6
...@@ -125,12 +125,6 @@ test "pointer to type" {...@@ -125,12 +125,6 @@ test "pointer to type" {
125 }125 }
126}126}
127127
128test "no undeclared identifier error in unanalyzed branches" {
129 if (false) {
130 lol_this_doesnt_exist = nonsense;
131 }
132}
133
134test "a type constructed in a global expression" {128test "a type constructed in a global expression" {
135 var l: List = undefined;129 var l: List = undefined;
136 l.array[0] = 10;130 l.array[0] = 10;
test/behavior/misc.zig-8
...@@ -40,14 +40,6 @@ test "constant equal function pointers" {...@@ -40,14 +40,6 @@ test "constant equal function pointers" {
4040
41fn emptyFn() void {}41fn emptyFn() void {}
4242
43test "string concatenation" {
44 try expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
45}
46
47test "array mult operator" {
48 try expect(mem.eql(u8, "ab" ** 5, "ababababab"));
49}
50
51test "string escapes" {43test "string escapes" {
52 try expectEqualStrings("\"", "\x22");44 try expectEqualStrings("\"", "\x22");
53 try expectEqualStrings("\'", "\x27");45 try expectEqualStrings("\'", "\x27");
test/behavior/saturating_arithmetic.zig created+139
...@@ -0,0 +1,139 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const mem = std.mem;
4const expectEqual = std.testing.expectEqual;
5const Vector = std.meta.Vector;
6const minInt = std.math.minInt;
7const maxInt = std.math.maxInt;
8
9const Op = enum { add, sub, mul, shl };
10fn testSaturatingOp(comptime op: Op, comptime T: type, test_data: [3]T) !void {
11 const a = test_data[0];
12 const b = test_data[1];
13 const expected = test_data[2];
14 const actual = switch (op) {
15 .add => @addWithSaturation(a, b),
16 .sub => @subWithSaturation(a, b),
17 .mul => @mulWithSaturation(a, b),
18 .shl => @shlWithSaturation(a, b),
19 };
20 try expectEqual(expected, actual);
21}
22
23test "@addWithSaturation" {
24 const S = struct {
25 fn doTheTest() !void {
26 // .{a, b, expected a+b}
27 try testSaturatingOp(.add, i8, .{ -3, 10, 7 });
28 try testSaturatingOp(.add, i8, .{ -128, -128, -128 });
29 try testSaturatingOp(.add, i2, .{ 1, 1, 1 });
30 try testSaturatingOp(.add, i64, .{ maxInt(i64), 1, maxInt(i64) });
31 try testSaturatingOp(.add, i128, .{ maxInt(i128), -maxInt(i128), 0 });
32 try testSaturatingOp(.add, i128, .{ minInt(i128), maxInt(i128), -1 });
33 try testSaturatingOp(.add, i8, .{ 127, 127, 127 });
34 try testSaturatingOp(.add, u8, .{ 3, 10, 13 });
35 try testSaturatingOp(.add, u8, .{ 255, 255, 255 });
36 try testSaturatingOp(.add, u2, .{ 3, 2, 3 });
37 try testSaturatingOp(.add, u3, .{ 7, 1, 7 });
38 try testSaturatingOp(.add, u128, .{ maxInt(u128), 1, maxInt(u128) });
39
40 const u8x3 = std.meta.Vector(3, u8);
41 try expectEqual(u8x3{ 255, 255, 255 }, @addWithSaturation(
42 u8x3{ 255, 254, 1 },
43 u8x3{ 1, 2, 255 },
44 ));
45 const i8x3 = std.meta.Vector(3, i8);
46 try expectEqual(i8x3{ 127, 127, 127 }, @addWithSaturation(
47 i8x3{ 127, 126, 1 },
48 i8x3{ 1, 2, 127 },
49 ));
50 }
51 };
52 try S.doTheTest();
53 comptime try S.doTheTest();
54}
55
56test "@subWithSaturation" {
57 const S = struct {
58 fn doTheTest() !void {
59 // .{a, b, expected a-b}
60 try testSaturatingOp(.sub, i8, .{ -3, 10, -13 });
61 try testSaturatingOp(.sub, i8, .{ -128, -128, 0 });
62 try testSaturatingOp(.sub, i8, .{ -1, 127, -128 });
63 try testSaturatingOp(.sub, i64, .{ minInt(i64), 1, minInt(i64) });
64 try testSaturatingOp(.sub, i128, .{ maxInt(i128), -1, maxInt(i128) });
65 try testSaturatingOp(.sub, i128, .{ minInt(i128), -maxInt(i128), -1 });
66 try testSaturatingOp(.sub, u8, .{ 10, 3, 7 });
67 try testSaturatingOp(.sub, u8, .{ 0, 255, 0 });
68 try testSaturatingOp(.sub, u5, .{ 0, 31, 0 });
69 try testSaturatingOp(.sub, u128, .{ 0, maxInt(u128), 0 });
70
71 const u8x3 = std.meta.Vector(3, u8);
72 try expectEqual(u8x3{ 0, 0, 0 }, @subWithSaturation(
73 u8x3{ 0, 0, 0 },
74 u8x3{ 255, 255, 255 },
75 ));
76 }
77 };
78 try S.doTheTest();
79 comptime try S.doTheTest();
80}
81
82test "@mulWithSaturation" {
83 // TODO: once #9660 has been solved, remove this line
84 if (std.builtin.target.cpu.arch == .wasm32) return error.SkipZigTest;
85
86 const S = struct {
87 fn doTheTest() !void {
88 // .{a, b, expected a*b}
89 try testSaturatingOp(.mul, i8, .{ -3, 10, -30 });
90 try testSaturatingOp(.mul, i4, .{ 2, 4, 7 });
91 try testSaturatingOp(.mul, i8, .{ 2, 127, 127 });
92 // TODO: uncomment these after #9643 has been solved - this should happen at 0.9.0/llvm-13 release
93 // try testSaturatingOp(.mul, i8, .{ -128, -128, 127 });
94 // try testSaturatingOp(.mul, i8, .{ maxInt(i8), maxInt(i8), maxInt(i8) });
95 try testSaturatingOp(.mul, i16, .{ maxInt(i16), -1, minInt(i16) + 1 });
96 try testSaturatingOp(.mul, i128, .{ maxInt(i128), -1, minInt(i128) + 1 });
97 try testSaturatingOp(.mul, i128, .{ minInt(i128), -1, maxInt(i128) });
98 try testSaturatingOp(.mul, u8, .{ 10, 3, 30 });
99 try testSaturatingOp(.mul, u8, .{ 2, 255, 255 });
100 try testSaturatingOp(.mul, u128, .{ maxInt(u128), maxInt(u128), maxInt(u128) });
101
102 const u8x3 = std.meta.Vector(3, u8);
103 try expectEqual(u8x3{ 255, 255, 255 }, @mulWithSaturation(
104 u8x3{ 2, 2, 2 },
105 u8x3{ 255, 255, 255 },
106 ));
107 }
108 };
109
110 try S.doTheTest();
111 comptime try S.doTheTest();
112}
113
114test "@shlWithSaturation" {
115 const S = struct {
116 fn doTheTest() !void {
117 // .{a, b, expected a<<b}
118 try testSaturatingOp(.shl, i8, .{ 1, 2, 4 });
119 try testSaturatingOp(.shl, i8, .{ 127, 1, 127 });
120 try testSaturatingOp(.shl, i8, .{ -128, 1, -128 });
121 // TODO: remove this check once #9668 is completed
122 if (std.builtin.target.cpu.arch != .wasm32) {
123 // skip testing ints > 64 bits on wasm due to miscompilation / wasmtime ci error
124 try testSaturatingOp(.shl, i128, .{ maxInt(i128), 64, maxInt(i128) });
125 try testSaturatingOp(.shl, u128, .{ maxInt(u128), 64, maxInt(u128) });
126 }
127 try testSaturatingOp(.shl, u8, .{ 1, 2, 4 });
128 try testSaturatingOp(.shl, u8, .{ 255, 1, 255 });
129
130 const u8x3 = std.meta.Vector(3, u8);
131 try expectEqual(u8x3{ 255, 255, 255 }, @shlWithSaturation(
132 u8x3{ 255, 255, 255 },
133 u8x3{ 1, 1, 1 },
134 ));
135 }
136 };
137 try S.doTheTest();
138 comptime try S.doTheTest();
139}
test/behavior/syntax.zig deleted-66
...@@ -1,66 +0,0 @@
1// Test trailing comma syntax
2// zig fmt: off
3
4extern var a: c_int;
5extern "c" var b: c_int;
6export var c: c_int = 0;
7threadlocal var d: c_int = 0;
8extern threadlocal var e: c_int;
9extern "c" threadlocal var f: c_int;
10export threadlocal var g: c_int = 0;
11
12const struct_trailing_comma = struct { x: i32, y: i32, };
13const struct_no_comma = struct { x: i32, y: i32 };
14const struct_fn_no_comma = struct { fn m() void {} y: i32 };
15
16const enum_no_comma = enum { A, B };
17
18fn container_init() void {
19 const S = struct { x: i32, y: i32 };
20 _ = S { .x = 1, .y = 2 };
21 _ = S { .x = 1, .y = 2, };
22}
23
24fn type_expr_return1() if (true) A {}
25fn type_expr_return2() for (true) |_| A {}
26fn type_expr_return3() while (true) A {}
27
28fn switch_cases(x: i32) void {
29 switch (x) {
30 1,2,3 => {},
31 4,5, => {},
32 6...8, => {},
33 else => {},
34 }
35}
36
37fn switch_prongs(x: i32) void {
38 switch (x) {
39 0 => {},
40 else => {},
41 }
42 switch (x) {
43 0 => {},
44 else => {}
45 }
46}
47
48const fn_no_comma = fn(i32, i32)void;
49const fn_trailing_comma = fn(i32, i32,)void;
50
51fn fn_calls() void {
52 fn add(x: i32, y: i32,) i32 { x + y };
53 _ = add(1, 2);
54 _ = add(1, 2,);
55}
56
57fn asm_lists() void {
58 if (false) { // Build AST but don't analyze
59 asm ("not real assembly"
60 :[a] "x" (x),);
61 asm ("not real assembly"
62 :[a] "x" (->i32),:[a] "x" (1),);
63 asm volatile ("still not real assembly"
64 :::"a","b",);
65 }
66}
test/behavior/usingnamespace.zig+7-16
...@@ -1,22 +1,13 @@...@@ -1,22 +1,13 @@
1const std = @import("std");1const std = @import("std");
22
3fn Foo(comptime T: type) type {3const A = struct {
4 return struct {4 pub const B = bool;
5 usingnamespace T;5};
6 };
7}
8
9test "usingnamespace inside a generic struct" {
10 const std2 = Foo(std);
11 const testing2 = Foo(std.testing);
12 try std2.testing.expect(true);
13 try testing2.expect(true);
14}
156
16usingnamespace struct {7const C = struct {
17 pub const foo = 42;8 usingnamespace A;
18};9};
1910
20test "usingnamespace does not redeclare an imported variable" {11test "basic usingnamespace" {
21 comptime try std.testing.expect(foo == 42);12 try std.testing.expect(C.B == bool);
22}13}
test/behavior/usingnamespace/a.zig created+7
...@@ -0,0 +1,7 @@
1usingnamespace @import("b.zig");
2
3pub const a_text = "OK\n";
4
5pub fn ok() bool {
6 return @import("std").mem.eql(u8, @This().b_text, "OK\n");
7}
test/behavior/usingnamespace/b.zig created+3
...@@ -0,0 +1,3 @@
1usingnamespace @import("a.zig");
2
3pub const b_text = @This().a_text;
test/behavior/usingnamespace/bar.zig created+8
...@@ -0,0 +1,8 @@
1usingnamespace @import("other.zig");
2
3pub var saw_bar_function = false;
4pub fn bar_function() void {
5 if (@This().foo_function()) {
6 saw_bar_function = true;
7 }
8}
test/behavior/usingnamespace/foo.zig created+14
...@@ -0,0 +1,14 @@
1// purposefully conflicting function with main source file
2// but it's private so it should be OK
3fn privateFunction() bool {
4 return false;
5}
6
7pub fn printText() bool {
8 return privateFunction();
9}
10
11pub var saw_foo_function = false;
12pub fn foo_function() void {
13 saw_foo_function = true;
14}
test/behavior/usingnamespace/import_segregation.zig created+11
...@@ -0,0 +1,11 @@
1const expect = @import("std").testing.expect;
2
3usingnamespace @import("foo.zig");
4usingnamespace @import("bar.zig");
5
6test "no clobbering happened" {
7 @This().foo_function();
8 @This().bar_function();
9 try expect(@This().saw_foo_function);
10 try expect(@This().saw_bar_function);
11}
test/behavior/usingnamespace/other.zig created+4
...@@ -0,0 +1,4 @@
1pub fn foo_function() bool {
2 // this one conflicts with the one from foo
3 return true;
4}
test/behavior/usingnamespace_stage1.zig created+41
...@@ -0,0 +1,41 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4fn Foo(comptime T: type) type {
5 return struct {
6 usingnamespace T;
7 };
8}
9
10test "usingnamespace inside a generic struct" {
11 const std2 = Foo(std);
12 const testing2 = Foo(std.testing);
13 try std2.testing.expect(true);
14 try testing2.expect(true);
15}
16
17usingnamespace struct {
18 pub const foo = 42;
19};
20
21test "usingnamespace does not redeclare an imported variable" {
22 comptime try std.testing.expect(@This().foo == 42);
23}
24
25usingnamespace @import("usingnamespace/foo.zig");
26test "usingnamespace omits mixing in private functions" {
27 try expect(@This().privateFunction());
28 try expect(!@This().printText());
29}
30fn privateFunction() bool {
31 return true;
32}
33
34test {
35 _ = @import("usingnamespace/import_segregation.zig");
36}
37
38usingnamespace @import("usingnamespace/a.zig");
39test "two files usingnamespace import each other" {
40 try expect(@This().ok());
41}
test/cases.zig+7-7
...@@ -1073,37 +1073,37 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1073,37 +1073,37 @@ pub fn addCases(ctx: *TestContext) !void {
1073 case.addError(1073 case.addError(
1074 \\pub fn main() void {1074 \\pub fn main() void {
1075 \\ var i = 0;1075 \\ var i = 0;
1076 \\ for (n) |_, i| {1076 \\ for ("n") |_, i| {
1077 \\ }1077 \\ }
1078 \\}1078 \\}
1079 , &[_][]const u8{1079 , &[_][]const u8{
1080 ":3:17: error: redeclaration of local variable 'i'",1080 ":3:19: error: redeclaration of local variable 'i'",
1081 ":2:9: note: previous declaration here",1081 ":2:9: note: previous declaration here",
1082 });1082 });
1083 case.addError(1083 case.addError(
1084 \\pub fn main() void {1084 \\pub fn main() void {
1085 \\ var i = 0;1085 \\ var i = 0;
1086 \\ for (n) |i| {1086 \\ for ("n") |i| {
1087 \\ }1087 \\ }
1088 \\}1088 \\}
1089 , &[_][]const u8{1089 , &[_][]const u8{
1090 ":3:14: error: redeclaration of local variable 'i'",1090 ":3:16: error: redeclaration of local variable 'i'",
1091 ":2:9: note: previous declaration here",1091 ":2:9: note: previous declaration here",
1092 });1092 });
1093 case.addError(1093 case.addError(
1094 \\pub fn main() void {1094 \\pub fn main() void {
1095 \\ var i = 0;1095 \\ var i = 0;
1096 \\ while (n) |i| {1096 \\ while ("n") |i| {
1097 \\ }1097 \\ }
1098 \\}1098 \\}
1099 , &[_][]const u8{1099 , &[_][]const u8{
1100 ":3:16: error: redeclaration of local variable 'i'",1100 ":3:18: error: redeclaration of local variable 'i'",
1101 ":2:9: note: previous declaration here",1101 ":2:9: note: previous declaration here",
1102 });1102 });
1103 case.addError(1103 case.addError(
1104 \\pub fn main() void {1104 \\pub fn main() void {
1105 \\ var i = 0;1105 \\ var i = 0;
1106 \\ while (n) |bruh| {1106 \\ while ("n") |bruh| {
1107 \\ _ = bruh;1107 \\ _ = bruh;
1108 \\ } else |i| {1108 \\ } else |i| {
1109 \\1109 \\
test/cli.zig-7
...@@ -45,13 +45,6 @@ pub fn main() !void {...@@ -45,13 +45,6 @@ pub fn main() !void {
45 }45 }
46}46}
4747
48fn unwrapArg(arg: UnwrapArgError![]u8) UnwrapArgError![]u8 {
49 return arg catch |err| {
50 warn("Unable to parse command line: {}\n", .{err});
51 return err;
52 };
53}
54
55fn printCmd(cwd: []const u8, argv: []const []const u8) void {48fn printCmd(cwd: []const u8, argv: []const []const u8) void {
56 std.debug.warn("cd {s} && ", .{cwd});49 std.debug.warn("cd {s} && ", .{cwd});
57 for (argv) |arg| {50 for (argv) |arg| {
test/compare_output.zig-105
...@@ -17,111 +17,6 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -17,111 +17,6 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
17 \\}17 \\}
18 , "Hello, world!" ++ std.cstr.line_sep);18 , "Hello, world!" ++ std.cstr.line_sep);
1919
20 cases.addCase(x: {
21 var tc = cases.create("multiple files with private function",
22 \\usingnamespace @import("std").io;
23 \\usingnamespace @import("foo.zig");
24 \\
25 \\pub fn main() void {
26 \\ privateFunction();
27 \\ const stdout = getStdOut().writer();
28 \\ stdout.print("OK 2\n", .{}) catch unreachable;
29 \\}
30 \\
31 \\fn privateFunction() void {
32 \\ printText();
33 \\}
34 , "OK 1\nOK 2\n");
35
36 tc.addSourceFile("foo.zig",
37 \\usingnamespace @import("std").io;
38 \\
39 \\// purposefully conflicting function with main.zig
40 \\// but it's private so it should be OK
41 \\fn privateFunction() void {
42 \\ const stdout = getStdOut().writer();
43 \\ stdout.print("OK 1\n", .{}) catch unreachable;
44 \\}
45 \\
46 \\pub fn printText() void {
47 \\ privateFunction();
48 \\}
49 );
50
51 break :x tc;
52 });
53
54 cases.addCase(x: {
55 var tc = cases.create("import segregation",
56 \\usingnamespace @import("foo.zig");
57 \\usingnamespace @import("bar.zig");
58 \\
59 \\pub fn main() void {
60 \\ foo_function();
61 \\ bar_function();
62 \\}
63 , "OK\nOK\n");
64
65 tc.addSourceFile("foo.zig",
66 \\usingnamespace @import("std").io;
67 \\pub fn foo_function() void {
68 \\ const stdout = getStdOut().writer();
69 \\ stdout.print("OK\n", .{}) catch unreachable;
70 \\}
71 );
72
73 tc.addSourceFile("bar.zig",
74 \\usingnamespace @import("other.zig");
75 \\usingnamespace @import("std").io;
76 \\
77 \\pub fn bar_function() void {
78 \\ if (foo_function()) {
79 \\ const stdout = getStdOut().writer();
80 \\ stdout.print("OK\n", .{}) catch unreachable;
81 \\ }
82 \\}
83 );
84
85 tc.addSourceFile("other.zig",
86 \\pub fn foo_function() bool {
87 \\ // this one conflicts with the one from foo
88 \\ return true;
89 \\}
90 );
91
92 break :x tc;
93 });
94
95 cases.addCase(x: {
96 var tc = cases.create("two files usingnamespace import each other",
97 \\usingnamespace @import("a.zig");
98 \\
99 \\pub fn main() void {
100 \\ ok();
101 \\}
102 , "OK\n");
103
104 tc.addSourceFile("a.zig",
105 \\usingnamespace @import("b.zig");
106 \\const io = @import("std").io;
107 \\
108 \\pub const a_text = "OK\n";
109 \\
110 \\pub fn ok() void {
111 \\ const stdout = io.getStdOut().writer();
112 \\ stdout.print(b_text, .{}) catch unreachable;
113 \\}
114 );
115
116 tc.addSourceFile("b.zig",
117 \\usingnamespace @import("a.zig");
118 \\
119 \\pub const b_text = a_text;
120 );
121
122 break :x tc;
123 });
124
125 cases.add("hello world without libc",20 cases.add("hello world without libc",
126 \\const io = @import("std").io;21 \\const io = @import("std").io;
127 \\22 \\
test/compile_errors.zig+22-2
...@@ -243,9 +243,9 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -243,9 +243,9 @@ pub fn addCases(ctx: *TestContext) !void {
243243
244 ctx.objErrStage1("array in c exported function",244 ctx.objErrStage1("array in c exported function",
245 \\export fn zig_array(x: [10]u8) void {245 \\export fn zig_array(x: [10]u8) void {
246 \\try expect(std.mem.eql(u8, &x, "1234567890"));246 \\ try std.testing.expect(std.mem.eql(u8, &x, "1234567890"));
247 \\}247 \\}
248 \\248 \\const std = @import("std");
249 \\export fn zig_return_array() [10]u8 {249 \\export fn zig_return_array() [10]u8 {
250 \\ return "1234567890".*;250 \\ return "1234567890".*;
251 \\}251 \\}
...@@ -2787,6 +2787,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -2787,6 +2787,7 @@ pub fn addCases(ctx: *TestContext) !void {
2787 \\ _ = msg; _ = error_return_trace;2787 \\ _ = msg; _ = error_return_trace;
2788 \\ while (true) {}2788 \\ while (true) {}
2789 \\}2789 \\}
2790 \\const builtin = @import("std").builtin;
2790 , &[_][]const u8{2791 , &[_][]const u8{
2791 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,anytype) anytype'",2792 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,anytype) anytype'",
2792 "note: only one of the functions is generic",2793 "note: only one of the functions is generic",
...@@ -2832,6 +2833,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -2832,6 +2833,7 @@ pub fn addCases(ctx: *TestContext) !void {
2832 \\ var s: Foo = Foo.E;2833 \\ var s: Foo = Foo.E;
2833 \\ _ = s;2834 \\ _ = s;
2834 \\}2835 \\}
2836 \\const D = 1;
2835 , &[_][]const u8{2837 , &[_][]const u8{
2836 "tmp.zig:1:17: error: enum 'Foo' depends on itself",2838 "tmp.zig:1:17: error: enum 'Foo' depends on itself",
2837 });2839 });
...@@ -8838,4 +8840,22 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -8838,4 +8840,22 @@ pub fn addCases(ctx: *TestContext) !void {
8838 "tmp.zig:2:9: note: declared mutable here",8840 "tmp.zig:2:9: note: declared mutable here",
8839 "tmp.zig:3:12: note: crosses namespace boundary here",8841 "tmp.zig:3:12: note: crosses namespace boundary here",
8840 });8842 });
8843
8844 ctx.objErrStage1("Issue #9619: saturating arithmetic builtins should fail to compile when given floats",
8845 \\pub fn main() !void {
8846 \\ _ = @addWithSaturation(@as(f32, 1.0), @as(f32, 1.0));
8847 \\}
8848 , &[_][]const u8{
8849 "error: invalid operands to binary expression: 'f32' and 'f32'",
8850 });
8851
8852 ctx.objErrStage1("undeclared identifier in unanalyzed branch",
8853 \\export fn a() void {
8854 \\ if (false) {
8855 \\ lol_this_doesnt_exist = nonsense;
8856 \\ }
8857 \\}
8858 , &[_][]const u8{
8859 "tmp.zig:3:9: error: use of undeclared identifier 'lol_this_doesnt_exist'",
8860 });
8841}8861}
test/stage2/cbe.zig+17
...@@ -916,6 +916,23 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -916,6 +916,23 @@ pub fn addCases(ctx: *TestContext) !void {
916 , "");916 , "");
917 }917 }
918918
919 {
920 var case = ctx.exeFromCompiledC("@rem", linux_x64);
921 case.addCompareOutput(
922 \\fn assert(ok: bool) void {
923 \\ if (!ok) unreachable;
924 \\}
925 \\fn rem(lhs: i32, rhs: i32, expected: i32) bool {
926 \\ return @rem(lhs, rhs) == expected;
927 \\}
928 \\pub export fn main() c_int {
929 \\ assert(rem(-5, 3, -2));
930 \\ assert(rem(5, 3, 2));
931 \\ return 0;
932 \\}
933 , "");
934 }
935
919 ctx.h("simple header", linux_x64,936 ctx.h("simple header", linux_x64,
920 \\export fn start() void{}937 \\export fn start() void{}
921 ,938 ,
test/stage2/darwin.zig+11-11
...@@ -27,8 +27,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -27,8 +27,8 @@ pub fn addCases(ctx: *TestContext) !void {
2727
28 // Regular old hello world28 // Regular old hello world
29 case.addCompareOutput(29 case.addCompareOutput(
30 \\extern "c" fn write(usize, usize, usize) usize;30 \\extern fn write(usize, usize, usize) usize;
31 \\extern "c" fn exit(usize) noreturn;31 \\extern fn exit(usize) noreturn;
32 \\32 \\
33 \\pub export fn main() noreturn {33 \\pub export fn main() noreturn {
34 \\ print();34 \\ print();
...@@ -47,8 +47,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -47,8 +47,8 @@ pub fn addCases(ctx: *TestContext) !void {
4747
48 // Print it 4 times and force growth and realloc.48 // Print it 4 times and force growth and realloc.
49 case.addCompareOutput(49 case.addCompareOutput(
50 \\extern "c" fn write(usize, usize, usize) usize;50 \\extern fn write(usize, usize, usize) usize;
51 \\extern "c" fn exit(usize) noreturn;51 \\extern fn exit(usize) noreturn;
52 \\52 \\
53 \\pub export fn main() noreturn {53 \\pub export fn main() noreturn {
54 \\ print();54 \\ print();
...@@ -74,8 +74,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -74,8 +74,8 @@ pub fn addCases(ctx: *TestContext) !void {
7474
75 // Print it once, and change the message.75 // Print it once, and change the message.
76 case.addCompareOutput(76 case.addCompareOutput(
77 \\extern "c" fn write(usize, usize, usize) usize;77 \\extern fn write(usize, usize, usize) usize;
78 \\extern "c" fn exit(usize) noreturn;78 \\extern fn exit(usize) noreturn;
79 \\79 \\
80 \\pub export fn main() noreturn {80 \\pub export fn main() noreturn {
81 \\ print();81 \\ print();
...@@ -94,8 +94,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -94,8 +94,8 @@ pub fn addCases(ctx: *TestContext) !void {
9494
95 // Now we print it twice.95 // Now we print it twice.
96 case.addCompareOutput(96 case.addCompareOutput(
97 \\extern "c" fn write(usize, usize, usize) usize;97 \\extern fn write(usize, usize, usize) usize;
98 \\extern "c" fn exit(usize) noreturn;98 \\extern fn exit(usize) noreturn;
99 \\99 \\
100 \\pub export fn main() noreturn {100 \\pub export fn main() noreturn {
101 \\ print();101 \\ print();
...@@ -121,7 +121,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -121,7 +121,7 @@ pub fn addCases(ctx: *TestContext) !void {
121 // This test case also covers an infrequent scenarion where the string table *may* be relocated121 // This test case also covers an infrequent scenarion where the string table *may* be relocated
122 // into the position preceeding the symbol table which results in a dyld error.122 // into the position preceeding the symbol table which results in a dyld error.
123 case.addCompareOutput(123 case.addCompareOutput(
124 \\extern "c" fn exit(usize) noreturn;124 \\extern fn exit(usize) noreturn;
125 \\125 \\
126 \\pub export fn main() noreturn {126 \\pub export fn main() noreturn {
127 \\ exit(0);127 \\ exit(0);
...@@ -131,8 +131,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -131,8 +131,8 @@ pub fn addCases(ctx: *TestContext) !void {
131 );131 );
132132
133 case.addCompareOutput(133 case.addCompareOutput(
134 \\extern "c" fn exit(usize) noreturn;134 \\extern fn exit(usize) noreturn;
135 \\extern "c" fn write(usize, usize, usize) usize;135 \\extern fn write(usize, usize, usize) usize;
136 \\136 \\
137 \\pub export fn main() noreturn {137 \\pub export fn main() noreturn {
138 \\ _ = write(1, @ptrToInt("Hey!\n"), 5);138 \\ _ = write(1, @ptrToInt("Hey!\n"), 5);
test/stage2/llvm.zig+17
...@@ -225,4 +225,21 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -225,4 +225,21 @@ pub fn addCases(ctx: *TestContext) !void {
225 \\}225 \\}
226 , "");226 , "");
227 }227 }
228
229 {
230 var case = ctx.exeUsingLlvmBackend("@rem", linux_x64);
231 case.addCompareOutput(
232 \\fn assert(ok: bool) void {
233 \\ if (!ok) unreachable;
234 \\}
235 \\fn rem(lhs: i32, rhs: i32, expected: i32) bool {
236 \\ return @rem(lhs, rhs) == expected;
237 \\}
238 \\pub export fn main() c_int {
239 \\ assert(rem(-5, 3, -2));
240 \\ assert(rem(5, 3, 2));
241 \\ return 0;
242 \\}
243 , "");
244 }
228}245}
test/standalone.zig+2
...@@ -5,6 +5,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {...@@ -5,6 +5,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
5 cases.add("test/standalone/hello_world/hello.zig");5 cases.add("test/standalone/hello_world/hello.zig");
6 cases.addC("test/standalone/hello_world/hello_libc.zig");6 cases.addC("test/standalone/hello_world/hello_libc.zig");
7 cases.add("test/standalone/cat/main.zig");7 cases.add("test/standalone/cat/main.zig");
8 cases.add("test/standalone/issue_9693/main.zig");
8 cases.add("test/standalone/guess_number/main.zig");9 cases.add("test/standalone/guess_number/main.zig");
9 cases.add("test/standalone/main_return_error/error_u8.zig");10 cases.add("test/standalone/main_return_error/error_u8.zig");
10 cases.add("test/standalone/main_return_error/error_u8_non_zero.zig");11 cases.add("test/standalone/main_return_error/error_u8_non_zero.zig");
...@@ -26,6 +27,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {...@@ -26,6 +27,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
26 cases.addBuildFile("test/standalone/brace_expansion/build.zig", .{});27 cases.addBuildFile("test/standalone/brace_expansion/build.zig", .{});
27 cases.addBuildFile("test/standalone/empty_env/build.zig", .{});28 cases.addBuildFile("test/standalone/empty_env/build.zig", .{});
28 cases.addBuildFile("test/standalone/issue_7030/build.zig", .{});29 cases.addBuildFile("test/standalone/issue_7030/build.zig", .{});
30 cases.addBuildFile("test/standalone/install_raw_hex/build.zig", .{});
29 if (std.Target.current.os.tag != .wasi) {31 if (std.Target.current.os.tag != .wasi) {
30 cases.addBuildFile("test/standalone/load_dynamic_library/build.zig", .{});32 cases.addBuildFile("test/standalone/load_dynamic_library/build.zig", .{});
31 }33 }
test/standalone/brace_expansion/main.zig+1-1
...@@ -234,7 +234,7 @@ pub fn main() !void {...@@ -234,7 +234,7 @@ pub fn main() !void {
234 var result_buf = ArrayList(u8).init(global_allocator);234 var result_buf = ArrayList(u8).init(global_allocator);
235 defer result_buf.deinit();235 defer result_buf.deinit();
236236
237 try expandString(stdin_buf.items, &result_buf);237 try expandString(stdin.items, &result_buf);
238 try stdout_file.write(result_buf.items);238 try stdout_file.write(result_buf.items);
239}239}
240240
test/standalone/install_raw_hex/build.zig created+173
...@@ -0,0 +1,173 @@
1const Builder = @import("std").build.Builder;
2const builtin = @import("builtin");
3const std = @import("std");
4const CheckFileStep = std.build.CheckFileStep;
5
6pub fn build(b: *Builder) void {
7 const target = .{
8 .cpu_arch = .thumb,
9 .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 },
10 .os_tag = .freestanding,
11 .abi = .gnueabihf,
12 };
13
14 const mode = b.standardReleaseOptions();
15
16 const elf = b.addExecutable("zig-nrf52-blink.elf", "main.zig");
17 elf.setTarget(target);
18 elf.setBuildMode(mode);
19
20 const test_step = b.step("test", "Test the program");
21 b.default_step.dependOn(test_step);
22
23 const hex_step = b.addInstallRaw(elf, "hello.hex");
24 test_step.dependOn(&hex_step.step);
25
26 const explicit_format_hex_step = b.addInstallRawWithFormat(elf, "hello.foo", .hex);
27 test_step.dependOn(&explicit_format_hex_step.step);
28
29 const expected_hex = &[_][]const u8{
30 ":020000021000EC",
31 ":1000D400D001010001000000D20101000100000074",
32 ":1000E40028020100010000002402010001000000B8",
33 ":1000F4003A02010001000000E202010001000000D8",
34 ":100104000C03010001000000A50202000000000031",
35 ":1001140000000000000000000000000000000000DB",
36 ":1001240000000000000000000000000000000000CB",
37 ":1001340000000000000000000000000000000000BB",
38 ":10014400AF02020098020100090000004D02010004",
39 ":100154000900000001000000000000000000000091",
40 ":100164000004000100C0800000020000080000003C",
41 ":100174000000000000000000000000001E0000005D",
42 ":1001840048010100000040888080FF000A14002913",
43 ":1001940000C0B00000020090080000000000000051",
44 ":1001A40000000000000000001E000000000000002D",
45 ":1001B400000000000000000000000000000000003B",
46 ":1001C400000000000000000000000000000000002B",
47 ":1001D400000000000000000000000000000000001B",
48 ":1001E400000000000000000000000000000000000B",
49 ":1001F4000000000000000000000000008702010071",
50 ":1002040010000000200201002C0000006B0201001D",
51 ":100214001B000000570201001300000072656D61AD",
52 ":10022400696E646572206469766973696F6E2062B1",
53 ":1002340079207A65726F206F72206E6567617469C8",
54 ":1002440076652076616C756500636F727465782DD0",
55 ":100254006D3400696E646578206F7574206F662054",
56 ":10026400626F756E647300696E746567657220638E",
57 ":10027400617374207472756E63617465642062695D",
58 ":100284007473006469766973696F6E206279207A89",
59 ":1002940065726F00636F727465785F6D340000007F",
60 ":1002A40081B00091FFE700BEFDE7D0B502AF90B08A",
61 ":1002B4000391029007A800F029F803990020069002",
62 ":1002C40048680490FFE704990698019088420FD289",
63 ":1002D400FFE7019903980068405C07F8310C17F8B0",
64 ":1002E400311C07A800F021F8019801300690EAE7D4",
65 ":1002F400029807A9B1E80C50A0E80C5091E81C50F2",
66 ":1003040080E81C5010B0D0BDFFE7FEE7D0B502AFC7",
67 ":1003140040F2DC11C0F20101B1E80C50A0E80C502D",
68 ":1003240091E81C5080E81C50D0BD80B56F4688B061",
69 ":1003340006906FF35F2127F80A1C37F80A0C049023",
70 ":10034400012038B9FFE740F20020C0F2010000218B",
71 ":10035400FFF7A6FF0498C0F3431027F8020C37F800",
72 ":100364000A0C0390002038B9FFE7039800F01F003F",
73 ":100374000290012038B914E040F20820C0F20100D4",
74 ":100384000021FFF78DFF029800F01F0007F8030C0F",
75 ":100394000698009037F8020C0146019109280ED303",
76 ":1003A40006E040F21020C0F201000021FFF778FFC0",
77 ":1003B40040F21820C0F201000021FFF771FF0099FC",
78 ":1003C400019A51F8220017F803CC012303FA0CF325",
79 ":1003D400184341F8220008B080BD81B000F03F000E",
80 ":1003E4008DF802009DF80200103000F03F00022852",
81 ":1003F40004D3FFE700208DF8030003E001208DF80B",
82 ":100404000300FFE79DF8030001B070470A000000F5",
83 ":1004140012000000020071001200000066000000DB",
84 ":1004240003007D0C06000000000000000001110123",
85 ":10043400250E1305030E10171B0EB44219110112D9",
86 ":0604440006000002340076",
87 ":020000021000EC",
88 ":1000D400D001010001000000D20101000100000074",
89 ":1000E40028020100010000002402010001000000B8",
90 ":1000F4003A02010001000000E202010001000000D8",
91 ":100104000C03010001000000A50202000000000031",
92 ":1001140000000000000000000000000000000000DB",
93 ":1001240000000000000000000000000000000000CB",
94 ":1001340000000000000000000000000000000000BB",
95 ":10014400AF02020098020100090000004D02010004",
96 ":100154000900000001000000000000000000000091",
97 ":100164000004000100C0800000020000080000003C",
98 ":100174000000000000000000000000001E0000005D",
99 ":1001840048010100000040888080FF000A14002913",
100 ":1001940000C0B00000020090080000000000000051",
101 ":1001A40000000000000000001E000000000000002D",
102 ":1001B400000000000000000000000000000000003B",
103 ":1001C400000000000000000000000000000000002B",
104 ":1001D400000000000000000000000000000000001B",
105 ":1001E400000000000000000000000000000000000B",
106 ":1001F4000000000000000000000000008702010071",
107 ":1002040010000000200201002C0000006B0201001D",
108 ":100214001B000000570201001300000072656D61AD",
109 ":10022400696E646572206469766973696F6E2062B1",
110 ":1002340079207A65726F206F72206E6567617469C8",
111 ":1002440076652076616C756500636F727465782DD0",
112 ":100254006D3400696E646578206F7574206F662054",
113 ":10026400626F756E647300696E746567657220638E",
114 ":10027400617374207472756E63617465642062695D",
115 ":100284007473006469766973696F6E206279207A89",
116 ":1002940065726F00636F727465785F6D340000007F",
117 ":1002A40081B00091FFE700BEFDE7D0B502AF90B08A",
118 ":1002B4000391029007A800F029F803990020069002",
119 ":1002C40048680490FFE704990698019088420FD289",
120 ":1002D400FFE7019903980068405C07F8310C17F8B0",
121 ":1002E400311C07A800F021F8019801300690EAE7D4",
122 ":1002F400029807A9B1E80C50A0E80C5091E81C50F2",
123 ":1003040080E81C5010B0D0BDFFE7FEE7D0B502AFC7",
124 ":1003140040F2DC11C0F20101B1E80C50A0E80C502D",
125 ":1003240091E81C5080E81C50D0BD80B56F4688B061",
126 ":1003340006906FF35F2127F80A1C37F80A0C049023",
127 ":10034400012038B9FFE740F20020C0F2010000218B",
128 ":10035400FFF7A6FF0498C0F3431027F8020C37F800",
129 ":100364000A0C0390002038B9FFE7039800F01F003F",
130 ":100374000290012038B914E040F20820C0F20100D4",
131 ":100384000021FFF78DFF029800F01F0007F8030C0F",
132 ":100394000698009037F8020C0146019109280ED303",
133 ":1003A40006E040F21020C0F201000021FFF778FFC0",
134 ":1003B40040F21820C0F201000021FFF771FF0099FC",
135 ":1003C400019A51F8220017F803CC012303FA0CF325",
136 ":1003D400184341F8220008B080BD81B000F03F000E",
137 ":1003E4008DF802009DF80200103000F03F00022852",
138 ":1003F40004D3FFE700208DF8030003E001208DF80B",
139 ":100404000300FFE79DF8030001B070470A000000F5",
140 ":1004140012000000020071001200000066000000DB",
141 ":1004240003007D0C06000000000000000001110123",
142 ":10043400250E1305030E10171B0EB44219110112D9",
143 ":0604440006000002340076",
144 ":020000022000DC",
145 ":1002A40081B00091FFE700BEFDE7D0B502AF90B08A",
146 ":1002B4000391029007A800F029F803990020069002",
147 ":1002C40048680490FFE704990698019088420FD289",
148 ":1002D400FFE7019903980068405C07F8310C17F8B0",
149 ":1002E400311C07A800F021F8019801300690EAE7D4",
150 ":1002F400029807A9B1E80C50A0E80C5091E81C50F2",
151 ":1003040080E81C5010B0D0BDFFE7FEE7D0B502AFC7",
152 ":1003140040F2DC11C0F20101B1E80C50A0E80C502D",
153 ":1003240091E81C5080E81C50D0BD80B56F4688B061",
154 ":1003340006906FF35F2127F80A1C37F80A0C049023",
155 ":10034400012038B9FFE740F20020C0F2010000218B",
156 ":10035400FFF7A6FF0498C0F3431027F8020C37F800",
157 ":100364000A0C0390002038B9FFE7039800F01F003F",
158 ":100374000290012038B914E040F20820C0F20100D4",
159 ":100384000021FFF78DFF029800F01F0007F8030C0F",
160 ":100394000698009037F8020C0146019109280ED303",
161 ":1003A40006E040F21020C0F201000021FFF778FFC0",
162 ":1003B40040F21820C0F201000021FFF771FF0099FC",
163 ":1003C400019A51F8220017F803CC012303FA0CF325",
164 ":1003D400184341F8220008B080BD81B000F03F000E",
165 ":1003E4008DF802009DF80200103000F03F00022852",
166 ":1003F40004D3FFE700208DF8030003E001208DF80B",
167 ":0C0404000300FFE79DF8030001B0704703",
168 ":00000001FF",
169 };
170
171 test_step.dependOn(&CheckFileStep.create(b, hex_step.getOutputSource(), expected_hex).step);
172 test_step.dependOn(&CheckFileStep.create(b, explicit_format_hex_step.getOutputSource(), expected_hex).step);
173}
test/standalone/install_raw_hex/main.zig created+3
...@@ -0,0 +1,3 @@
1export fn _start() callconv(.C) noreturn {
2 while (true) {}
3}
test/standalone/issue_9693/main.zig created+2
...@@ -0,0 +1,2 @@
1pub const io_mode = .evented;
2pub fn main() void {}
test/tests.zig+8
...@@ -137,6 +137,14 @@ const test_targets = blk: {...@@ -137,6 +137,14 @@ const test_targets = blk: {
137 },137 },
138 .link_libc = true,138 .link_libc = true,
139 },139 },
140 TestTarget{
141 .target = .{
142 .cpu_arch = .aarch64,
143 .os_tag = .windows,
144 .abi = .gnu,
145 },
146 .link_libc = true,
147 },
140148
141 TestTarget{149 TestTarget{
142 .target = CrossTarget.parse(.{150 .target = CrossTarget.parse(.{
test/translate_c.zig+37-2
...@@ -195,6 +195,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -195,6 +195,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
195195
196 cases.add("use cast param as macro fn return type",196 cases.add("use cast param as macro fn return type",
197 \\#include <stdint.h>197 \\#include <stdint.h>
198 \\#define SYS_BASE_CACHED 0
198 \\#define MEM_PHYSICAL_TO_K0(x) (void*)((uint32_t)(x) + SYS_BASE_CACHED)199 \\#define MEM_PHYSICAL_TO_K0(x) (void*)((uint32_t)(x) + SYS_BASE_CACHED)
199 , &[_][]const u8{200 , &[_][]const u8{
200 \\pub inline fn MEM_PHYSICAL_TO_K0(x: anytype) ?*c_void {201 \\pub inline fn MEM_PHYSICAL_TO_K0(x: anytype) ?*c_void {
...@@ -228,6 +229,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -228,6 +229,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
228 });229 });
229230
230 cases.add("macro expressions respect C operator precedence",231 cases.add("macro expressions respect C operator precedence",
232 \\int *foo = 0;
231 \\#define FOO *((foo) + 2)233 \\#define FOO *((foo) + 2)
232 \\#define VALUE (1 + 2 * 3 + 4 * 5 + 6 << 7 | 8 == 9)234 \\#define VALUE (1 + 2 * 3 + 4 * 5 + 6 << 7 | 8 == 9)
233 \\#define _AL_READ3BYTES(p) ((*(unsigned char *)(p)) \235 \\#define _AL_READ3BYTES(p) ((*(unsigned char *)(p)) \
...@@ -363,6 +365,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -363,6 +365,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
363 });365 });
364366
365 cases.add("correct semicolon after infixop",367 cases.add("correct semicolon after infixop",
368 \\#define _IO_ERR_SEEN 0
366 \\#define __ferror_unlocked_body(_fp) (((_fp)->_flags & _IO_ERR_SEEN) != 0)369 \\#define __ferror_unlocked_body(_fp) (((_fp)->_flags & _IO_ERR_SEEN) != 0)
367 , &[_][]const u8{370 , &[_][]const u8{
368 \\pub inline fn __ferror_unlocked_body(_fp: anytype) @TypeOf((_fp.*._flags & _IO_ERR_SEEN) != @as(c_int, 0)) {371 \\pub inline fn __ferror_unlocked_body(_fp: anytype) @TypeOf((_fp.*._flags & _IO_ERR_SEEN) != @as(c_int, 0)) {
...@@ -429,6 +432,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -429,6 +432,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
429432
430 cases.add("macro comma operator",433 cases.add("macro comma operator",
431 \\#define foo (foo, bar)434 \\#define foo (foo, bar)
435 \\int baz(int x, int y) { return 0; }
432 \\#define bar(x) (&x, +3, 4 == 4, 5 * 6, baz(1, 2), 2 % 2, baz(1,2))436 \\#define bar(x) (&x, +3, 4 == 4, 5 * 6, baz(1, 2), 2 % 2, baz(1,2))
433 , &[_][]const u8{437 , &[_][]const u8{
434 \\pub const foo = blk: {438 \\pub const foo = blk: {
...@@ -459,6 +463,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -459,6 +463,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
459 });463 });
460464
461 cases.add("macro line continuation",465 cases.add("macro line continuation",
466 \\int BAR = 0;
462 \\#define FOO -\467 \\#define FOO -\
463 \\BAR468 \\BAR
464 , &[_][]const u8{469 , &[_][]const u8{
...@@ -1833,6 +1838,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1833,6 +1838,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1833 });1838 });
18341839
1835 cases.add("macro pointer cast",1840 cases.add("macro pointer cast",
1841 \\#define NRF_GPIO_BASE 0
1836 \\typedef struct { int dummy; } NRF_GPIO_Type;1842 \\typedef struct { int dummy; } NRF_GPIO_Type;
1837 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)1843 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
1838 , &[_][]const u8{1844 , &[_][]const u8{
...@@ -1873,6 +1879,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1873,6 +1879,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1873 });1879 });
18741880
1875 cases.add("macro add",1881 cases.add("macro add",
1882 \\#define D3_AHB1PERIPH_BASE 0
1876 \\#define PERIPH_BASE (0x40000000UL) /*!< Base address of : AHB/APB Peripherals */1883 \\#define PERIPH_BASE (0x40000000UL) /*!< Base address of : AHB/APB Peripherals */
1877 \\#define D3_APB1PERIPH_BASE (PERIPH_BASE + 0x18000000UL)1884 \\#define D3_APB1PERIPH_BASE (PERIPH_BASE + 0x18000000UL)
1878 \\#define RCC_BASE (D3_AHB1PERIPH_BASE + 0x4400UL)1885 \\#define RCC_BASE (D3_AHB1PERIPH_BASE + 0x4400UL)
...@@ -2569,6 +2576,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2569,6 +2576,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
25692576
2570 cases.add("macro call",2577 cases.add("macro call",
2571 \\#define CALL(arg) bar(arg)2578 \\#define CALL(arg) bar(arg)
2579 \\int bar(int x) { return x; }
2572 , &[_][]const u8{2580 , &[_][]const u8{
2573 \\pub inline fn CALL(arg: anytype) @TypeOf(bar(arg)) {2581 \\pub inline fn CALL(arg: anytype) @TypeOf(bar(arg)) {
2574 \\ return bar(arg);2582 \\ return bar(arg);
...@@ -2577,6 +2585,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2577,6 +2585,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
25772585
2578 cases.add("macro call with no args",2586 cases.add("macro call with no args",
2579 \\#define CALL(arg) bar()2587 \\#define CALL(arg) bar()
2588 \\int bar(void) { return 0; }
2580 , &[_][]const u8{2589 , &[_][]const u8{
2581 \\pub inline fn CALL(arg: anytype) @TypeOf(bar()) {2590 \\pub inline fn CALL(arg: anytype) @TypeOf(bar()) {
2582 \\ _ = arg;2591 \\ _ = arg;
...@@ -3135,9 +3144,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3135,9 +3144,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
31353144
3136 cases.add("macro cast",3145 cases.add("macro cast",
3137 \\#include <stdint.h>3146 \\#include <stdint.h>
3147 \\int baz(void *arg) { return 0; }
3138 \\#define FOO(bar) baz((void *)(baz))3148 \\#define FOO(bar) baz((void *)(baz))
3139 \\#define BAR (void*) a3149 \\#define BAR (void*) a
3140 \\#define BAZ (uint32_t)(2)3150 \\#define BAZ (uint32_t)(2)
3151 \\#define a 2
3141 , &[_][]const u8{3152 , &[_][]const u8{
3142 \\pub inline fn FOO(bar: anytype) @TypeOf(baz(@import("std").zig.c_translation.cast(?*c_void, baz))) {3153 \\pub inline fn FOO(bar: anytype) @TypeOf(baz(@import("std").zig.c_translation.cast(?*c_void, baz))) {
3143 \\ _ = bar;3154 \\ _ = bar;
...@@ -3160,6 +3171,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3160,6 +3171,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3160 });3171 });
31613172
3162 cases.add("macro conditional operator",3173 cases.add("macro conditional operator",
3174 \\ int a, b, c;
3163 \\#define FOO a ? b : c3175 \\#define FOO a ? b : c
3164 , &[_][]const u8{3176 , &[_][]const u8{
3165 \\pub const FOO = if (a) b else c;3177 \\pub const FOO = if (a) b else c;
...@@ -3469,11 +3481,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3469,11 +3481,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3469 \\pub const MAY_NEED_PROMOTION_OCT = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0o20000000000, .octal);3481 \\pub const MAY_NEED_PROMOTION_OCT = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0o20000000000, .octal);
3470 });3482 });
34713483
3472 // See __builtin_alloca_with_align comment in std.zig.c_builtins
3473 cases.add("demote un-implemented builtins",3484 cases.add("demote un-implemented builtins",
3474 \\#define FOO(X) __builtin_alloca_with_align((X), 8)3485 \\#define FOO(X) __builtin_alloca_with_align((X), 8)
3475 , &[_][]const u8{3486 , &[_][]const u8{
3476 \\pub const FOO = @compileError("TODO implement function '__builtin_alloca_with_align' in std.zig.c_builtins");3487 \\pub const FOO = @compileError("unable to translate macro: undefined identifier `__builtin_alloca_with_align`");
3477 });3488 });
34783489
3479 cases.add("null sentinel arrays when initialized from string literal. Issue #8256",3490 cases.add("null sentinel arrays when initialized from string literal. Issue #8256",
...@@ -3649,4 +3660,28 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3649,4 +3660,28 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3649 ,3660 ,
3650 \\_ = p[@intCast(c_uint, @as(c_int, 1))];3661 \\_ = p[@intCast(c_uint, @as(c_int, 1))];
3651 });3662 });
3663
3664 cases.add("Undefined macro identifier",
3665 \\#define FOO BAR
3666 , &[_][]const u8{
3667 \\pub const FOO = @compileError("unable to translate macro: undefined identifier `BAR`");
3668 });
3669
3670 cases.add("Macro redefines builtin",
3671 \\#define FOO __builtin_popcount
3672 , &[_][]const u8{
3673 \\pub const FOO = __builtin_popcount;
3674 });
3675
3676 cases.add("Only consider public decls in `isBuiltinDefined`",
3677 \\#define FOO std
3678 , &[_][]const u8{
3679 \\pub const FOO = @compileError("unable to translate macro: undefined identifier `std`");
3680 });
3681
3682 cases.add("Macro without a value",
3683 \\#define FOO
3684 , &[_][]const u8{
3685 \\pub const FOO = "";
3686 });
3652}3687}
tools/update_clang_options.zig+7-1
...@@ -473,7 +473,13 @@ pub fn main() anyerror!void {...@@ -473,7 +473,13 @@ pub fn main() anyerror!void {
473 try stdout.writeAll(473 try stdout.writeAll(
474 \\// This file is generated by tools/update_clang_options.zig.474 \\// This file is generated by tools/update_clang_options.zig.
475 \\// zig fmt: off475 \\// zig fmt: off
476 \\usingnamespace @import("clang_options.zig");476 \\const clang_options = @import("clang_options.zig");
477 \\const CliArg = clang_options.CliArg;
478 \\const flagpd1 = clang_options.flagpd1;
479 \\const flagpsl = clang_options.flagpsl;
480 \\const joinpd1 = clang_options.joinpd1;
481 \\const jspd1 = clang_options.jspd1;
482 \\const sepd1 = clang_options.sepd1;
477 \\pub const data = blk: { @setEvalBranchQuota(6000); break :blk &[_]CliArg{483 \\pub const data = blk: { @setEvalBranchQuota(6000); break :blk &[_]CliArg{
478 \\484 \\
479 );485 );