authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-03-12 20:11:01 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-03-12 20:11:01 -07:00
log1616ae24d16ae69d9c9fc08b29248ee5a042721c
treeea08e7d781cebb665b4a4680cb6c9cd96cc6a775
parent299f98e97b0ffc30d1d1d06cddd0c99813200c32
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

rewrite parseTreeDiff and fix a lot of crashes


11 files changed, 11927 insertions(+), 63 deletions(-)

git.zig+96-63
...@@ -602,6 +602,17 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff {...@@ -602,6 +602,17 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff {
602 });602 });
603 }603 }
604604
605 const S = struct {
606 fn eql(comptime a: u8) fn (u8) bool {
607 const SS = struct {
608 fn actual(b: u8) bool {
609 return a == b;
610 }
611 };
612 return SS.actual;
613 }
614 };
615
605 // diff --git a/notes/all_packages.txt b/notes/all_packages.txt616 // diff --git a/notes/all_packages.txt b/notes/all_packages.txt
606 // index c06b41d..e8f91cf 100644617 // index c06b41d..e8f91cf 100644
607 // --- a/notes/all_packages.txt618 // --- a/notes/all_packages.txt
...@@ -611,77 +622,99 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff {...@@ -611,77 +622,99 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff {
611 // freedesktop/xorg/libxmu622 // freedesktop/xorg/libxmu
612 // ncompress623 // ncompress
613 // +freedesktop/xorg/libxpm624 // +freedesktop/xorg/libxpm
614 std.debug.assert(std.mem.startsWith(u8, lineiter.next() orelse return std.mem.zeroes(TreeDiff), "diff --git"));
615 blk: while (true) {625 blk: while (true) {
616 while (lineiter.next()) |lin| {626 const first_line = lineiter.next().?;
617 if (std.mem.startsWith(u8, lin, "index")) break;627 std.debug.assert(std.mem.startsWith(u8, first_line, "diff --git"));
618 if (std.mem.startsWith(u8, lin, "new file mode")) continue;628 const i = diffs.items.len;
619 if (std.mem.startsWith(u8, lin, "deleted file mode")) continue;629 try diffs.append(.{ .before_path = overview.items[i].sub_path, .after_path = overview.items[i].sub_path, .content = "" });
620 if (std.mem.startsWith(u8, lin, "old mode")) continue;630 if (extras.matchesAll(u8, overview.items[i].before.blob.id, S.eql('0'))) diffs.items[i].before_path = "/dev/null";
621 if (std.mem.startsWith(u8, lin, "new mode")) continue;631 if (extras.matchesAll(u8, overview.items[i].after.blob.id, S.eql('0'))) diffs.items[i].after_path = "/dev/null";
622632
623 std.log.err("{s}", .{lin});633 while (true) {
624 unreachable;634 if (lineiter.index.? >= input.len) {
635 break :blk;
636 }
637 if (lineiter.peek()) |lin| {
638 if (std.mem.startsWith(u8, lin, "index")) {
639 lineiter.index.? += lin.len + 1;
640 break;
641 }
642 if (std.mem.startsWith(u8, lin, "new file mode")) {
643 lineiter.index.? += lin.len + 1;
644 continue;
645 }
646 if (std.mem.startsWith(u8, lin, "deleted file mode")) {
647 lineiter.index.? += lin.len + 1;
648 continue;
649 }
650 if (std.mem.startsWith(u8, lin, "old mode")) {
651 lineiter.index.? += lin.len + 1;
652 continue;
653 }
654 if (std.mem.startsWith(u8, lin, "new mode")) {
655 lineiter.index.? += lin.len + 1;
656 continue;
657 }
658 if (std.mem.startsWith(u8, lin, "diff --git")) {
659 continue :blk;
660 }
661 std.log.err("{s}", .{lin});
662 unreachable;
663 }
625 }664 }
626665
627 const before_path_raw = lineiter.next() orelse {666 var content_start: usize = 0;
628 // empty file diff has nothing after 'index' line and this branch handles when its the last item667
629 try diffs.append(.{668 while (true) {
630 .before_path = overview.items[diffs.items.len].sub_path,669 if (lineiter.index.? >= input.len) {
631 .after_path = overview.items[diffs.items.len].sub_path,670 break :blk;
632 .content = "",671 }
633 });672 if (lineiter.peek()) |lin| {
634 break;673 if (std.mem.startsWith(u8, lin, "--- ")) {
635 };674 lineiter.index.? += lin.len + 1;
636 if (std.mem.startsWith(u8, before_path_raw, "Binary files")) {675 continue;
637 try diffs.append(.{676 }
638 .before_path = overview.items[diffs.items.len].sub_path,677 if (std.mem.startsWith(u8, lin, "+++ ")) {
639 .after_path = overview.items[diffs.items.len].sub_path,678 lineiter.index.? += lin.len + 1;
640 .content = before_path_raw,679 continue;
641 });680 }
642 _ = lineiter.index orelse break :blk;681 if (std.mem.startsWith(u8, lin, "@@ ")) {
643 std.debug.assert(std.mem.startsWith(u8, lineiter.next().?, "diff --git"));682 content_start = lineiter.index.?;
644 continue :blk;683 lineiter.index.? += lin.len + 1;
684 break;
685 }
686 if (std.mem.startsWith(u8, lin, "Binary files ")) {
687 content_start = lineiter.index.?;
688 lineiter.index.? += lin.len + 1;
689 break;
690 }
691 if (std.mem.startsWith(u8, lin, "diff --git")) {
692 continue :blk;
693 }
694 std.log.err("{s}", .{lin});
695 unreachable;
696 }
645 }697 }
646 if (std.mem.startsWith(u8, before_path_raw, "diff --git")) {698 if (lineiter.index.? >= input.len) {
647 // empty file in the middle, no diff699 diffs.items[diffs.items.len - 1].content = input[content_start..];
648 try diffs.append(.{700 break :blk;
649 .before_path = overview.items[diffs.items.len].sub_path,
650 .after_path = overview.items[diffs.items.len].sub_path,
651 .content = "",
652 });
653 continue :blk;
654 }701 }
655 const before_path = extras.trimPrefixEnsure(before_path_raw, "--- a/") orelse extras.trimPrefixEnsure(before_path_raw, "--- ") orelse @panic(before_path_raw);
656
657 const after_path_raw = lineiter.next().?;
658 const after_path = extras.trimPrefixEnsure(after_path_raw, "+++ b/") orelse extras.trimPrefixEnsure(after_path_raw, "+++ ") orelse @panic(after_path_raw);
659
660 const start_index = lineiter.index.?;
661702
662 while (lineiter.next()) |lin| {703 while (true) {
663 if (std.mem.startsWith(u8, lin, "diff --git")) {704 if (lineiter.peek()) |lin| {
664 const end_index = lineiter.index.? - lin.len - 2;705 if (std.mem.startsWith(u8, lin, "diff --git")) {
665 const content = input[start_index..end_index];706 const content_end = lineiter.index.? - 1;
666 overview.items[diffs.items.len].adds = @intCast(std.mem.count(u8, content, "\n+"));707 diffs.items[diffs.items.len - 1].content = input[content_start..content_end];
667 overview.items[diffs.items.len].subs = @intCast(std.mem.count(u8, content, "\n-"));708 continue :blk;
668 try diffs.append(.{709 }
669 .before_path = before_path,710 lineiter.index.? += lin.len + 1;
670 .after_path = after_path,711
671 .content = content,712 if (lineiter.index.? >= input.len) {
672 });713 diffs.items[diffs.items.len - 1].content = input[content_start..];
673 continue :blk;714 break :blk;
715 }
674 }716 }
675 }717 }
676 const content = input[start_index..];
677 overview.items[diffs.items.len].adds = @intCast(std.mem.count(u8, content, "\n+"));
678 overview.items[diffs.items.len].subs = @intCast(std.mem.count(u8, content, "\n-"));
679 try diffs.append(.{
680 .before_path = before_path,
681 .after_path = after_path,
682 .content = content,
683 });
684 break :blk;
685 }718 }
686719
687 return TreeDiff{720 return TreeDiff{
test.zig+55
...@@ -189,3 +189,58 @@ test {...@@ -189,3 +189,58 @@ test {
189 const t = try git.parseTreeDiff(alloc, try git.getTreeDiff(alloc, git_dir, .{ .id = "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e" }, .{ .id = "c39f57f6bb01664a7146ddbfc3debe76ec135f44" }));189 const t = try git.parseTreeDiff(alloc, try git.getTreeDiff(alloc, git_dir, .{ .id = "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e" }, .{ .id = "c39f57f6bb01664a7146ddbfc3debe76ec135f44" }));
190 _ = t; // TODO: test fields when we upgrade to 0.14 and have decl literals190 _ = t; // TODO: test fields when we upgrade to 0.14 and have decl literals
191}191}
192
193test {
194 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
195 defer arena.deinit();
196 const alloc = arena.allocator();
197 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-9feb6b667c77c187f547deaf10cd1f04e92fe192")); // magnolia-desktop
198}
199test {
200 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
201 defer arena.deinit();
202 const alloc = arena.allocator();
203 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-f2ccd4d1333aad1175550daf616b061388e1864f")); // magnolia-desktop
204}
205test {
206 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
207 defer arena.deinit();
208 const alloc = arena.allocator();
209 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-47ed809ce10bdfa99351c72935467c9afae47e36")); // magnolia-desktop
210}
211test {
212 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
213 defer arena.deinit();
214 const alloc = arena.allocator();
215 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-15700f9e1c919a3f0c492415d982a09f5e8122cd")); // magnolia-desktop
216}
217test {
218 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
219 defer arena.deinit();
220 const alloc = arena.allocator();
221 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-8480815a00f341a9058a26bf86f34368184615d6")); // magnolia-desktop
222}
223test {
224 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
225 defer arena.deinit();
226 const alloc = arena.allocator();
227 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-c37d23f45ae6bd0db6b072180d7b84566c7dc8a2")); // zig
228}
229test {
230 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
231 defer arena.deinit();
232 const alloc = arena.allocator();
233 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-f58200e3f2967a06f343c9fc9dcae9de18def92a")); // zig
234}
235test {
236 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
237 defer arena.deinit();
238 const alloc = arena.allocator();
239 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-d9165aacce3629d503f87cd2c3f612629127641b")); // zig
240}
241test {
242 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
243 defer arena.deinit();
244 const alloc = arena.allocator();
245 _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-1f7390f3999e80f775dbc0e62f1dcb071c3bed77")); // zig
246}
testdata/diff-15700f9e1c919a3f0c492415d982a09f5e8122cd created+5
...@@ -0,0 +1,5 @@
1:100644 100644 1e5a5a99eb7fe12e6ea2f48fb2ff3e8de186efa0 8aff424ddd2f434448b73c0bf62dca382e783be7 M test/images/demo-border.png
2
3diff --git a/test/images/demo-border.png b/test/images/demo-border.png
4index 1e5a5a9..8aff424 100644
5Binary files a/test/images/demo-border.png and b/test/images/demo-border.png differ
testdata/diff-1f7390f3999e80f775dbc0e62f1dcb071c3bed77 created+96
...@@ -0,0 +1,96 @@
1:100644 100644 e09b8f18abe0652043301349ece259daec0c6241 8f265f9eb61ae03e0b5ab80545fa1ce9aab961aa M src/Compilation.zig
2:100644 100644 af972ccb8665085991070de3235a6da537423dc6 81eb1b00428e9e2c3ef5fdf8b532255ed2e66867 M test/standalone.zig
3:000000 100644 0000000000000000000000000000000000000000 f5e07d8903268bec8527dd555c7c6955af5ff879 A test/standalone/issue_13970/build.zig
4:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A test/standalone/issue_13970/empty.zig
5:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A test/standalone/issue_13970/src/empty.zig
6:000000 100644 0000000000000000000000000000000000000000 d71320d46a61a74ccc3e5908ab46c4d0a1fea69a A test/standalone/issue_13970/src/main.zig
7:000000 100644 0000000000000000000000000000000000000000 4f6037b38dab0c9b800046b0477dc64f3c3b55e8 A test/standalone/issue_13970/src/package.zig
8:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A test/standalone/issue_13970/test_root/empty.zig
9
10diff --git a/src/Compilation.zig b/src/Compilation.zig
11index e09b8f18ab..8f265f9eb6 100644
12--- a/src/Compilation.zig
13+++ b/src/Compilation.zig
14@@ -1621,8 +1621,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
15 const root_pkg = if (options.is_test) root_pkg: {
16 // TODO: we currently have two packages named 'root' here, which is weird. This
17 // should be changed as part of the resolution of #12201
18- const test_pkg = if (options.test_runner_path) |test_runner|
19- try Package.create(gpa, "root", null, test_runner)
20+ const test_pkg = if (options.test_runner_path) |test_runner| test_pkg: {
21+ const test_dir = std.fs.path.dirname(test_runner);
22+ const basename = std.fs.path.basename(test_runner);
23+ break :test_pkg try Package.create(gpa, "root", test_dir, basename);
24+ }
25 else
26 try Package.createWithDir(
27 gpa,
28diff --git a/test/standalone.zig b/test/standalone.zig
29index af972ccb86..81eb1b0042 100644
30--- a/test/standalone.zig
31+++ b/test/standalone.zig
32@@ -27,6 +27,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
33 cases.add("test/standalone/noreturn_call/inline.zig");
34 cases.add("test/standalone/noreturn_call/as_arg.zig");
35 cases.addBuildFile("test/standalone/test_runner_path/build.zig", .{ .requires_stage2 = true });
36+ cases.addBuildFile("test/standalone/issue_13970/build.zig", .{});
37 cases.addBuildFile("test/standalone/main_pkg_path/build.zig", .{});
38 cases.addBuildFile("test/standalone/shared_library/build.zig", .{});
39 cases.addBuildFile("test/standalone/mix_o_files/build.zig", .{});
40diff --git a/test/standalone/issue_13970/build.zig b/test/standalone/issue_13970/build.zig
41new file mode 100644
42index 0000000000..f5e07d8903
43--- /dev/null
44+++ b/test/standalone/issue_13970/build.zig
45@@ -0,0 +1,21 @@
46+const std = @import("std");
47+
48+pub fn build(b: *std.Build) void {
49+ const test1 = b.addTest(.{
50+ .root_source_file = .{ .path = "test_root/empty.zig" },
51+ });
52+ const test2 = b.addTest(.{
53+ .root_source_file = .{ .path = "src/empty.zig" },
54+ });
55+ const test3 = b.addTest(.{
56+ .root_source_file = .{ .path = "empty.zig" },
57+ });
58+ test1.setTestRunner("src/main.zig");
59+ test2.setTestRunner("src/main.zig");
60+ test3.setTestRunner("src/main.zig");
61+
62+ const test_step = b.step("test", "Test package path resolution of custom test runner");
63+ test_step.dependOn(&test1.step);
64+ test_step.dependOn(&test2.step);
65+ test_step.dependOn(&test3.step);
66+}
67diff --git a/test/standalone/issue_13970/empty.zig b/test/standalone/issue_13970/empty.zig
68new file mode 100644
69index 0000000000..e69de29bb2
70diff --git a/test/standalone/issue_13970/src/empty.zig b/test/standalone/issue_13970/src/empty.zig
71new file mode 100644
72index 0000000000..e69de29bb2
73diff --git a/test/standalone/issue_13970/src/main.zig b/test/standalone/issue_13970/src/main.zig
74new file mode 100644
75index 0000000000..d71320d46a
76--- /dev/null
77+++ b/test/standalone/issue_13970/src/main.zig
78@@ -0,0 +1,8 @@
79+const std = @import("std");
80+const package = @import("package.zig");
81+const root = @import("root");
82+const builtin = @import("builtin");
83+
84+pub fn main() !void {
85+ _ = package.decl;
86+}
87diff --git a/test/standalone/issue_13970/src/package.zig b/test/standalone/issue_13970/src/package.zig
88new file mode 100644
89index 0000000000..4f6037b38d
90--- /dev/null
91+++ b/test/standalone/issue_13970/src/package.zig
92@@ -0,0 +1 @@
93+pub const decl = 0;
94diff --git a/test/standalone/issue_13970/test_root/empty.zig b/test/standalone/issue_13970/test_root/empty.zig
95new file mode 100644
96index 0000000000..e69de29bb2
testdata/diff-47ed809ce10bdfa99351c72935467c9afae47e36 created+2384
...@@ -0,0 +1,2384 @@
1:100644 100644 6fee2fedb0a46b84e4cbb6e32f9ca5af821b2b67 49e0a31d4964dca501ce61740340bf8058821781 M Cozette/.version
2:100644 100644 9371252d0bfb5b2ee220f63dbd1431d11abe266a fdbcc86d16227019361b52ab614b3d9667bd48f7 M Cozette/cozette.bdf
3:100644 100644 1d2119c3c794f127a5b366d8db1015dcb6c21e1a 83309362d0d4efa1f7c4a70ef66f2c91d1606b97 M src/e/Label.zig
4:100644 100644 0110829e4de23a2c4f1ae0e66958dfe9ca0fe9ff c669969722abb19329aca3b91037ecc6ae7965ef M test/images/demo-bdf-cozette.png
5:100644 100644 dedbfa87fb441cf6f8aee13537b8654dc18ac38e e0e46496176d0dc5aaa70a4d95837212dd2cf3d7 M test/images/demo-menubar.png
6:100644 100644 94df3421d8f57f38e11f8dc592c6eb123f287d23 5d33be25f2c4e5950780859892cb73b6a3c31e23 M test/layout/demo-bdf-cozette.txt
7:100644 100644 8885fcc94eca961702dc7e7f7dff2f67328dd3e1 9e2be559f6ca6d5c4e1ce86858587db3a68c5c27 M test/layout/demo-menubar.txt
8
9diff --git a/Cozette/.version b/Cozette/.version
10index 6fee2fe..49e0a31 100644
11--- a/Cozette/.version
12+++ b/Cozette/.version
13@@ -1 +1 @@
14-1.22.2
15+1.23.1
16diff --git a/Cozette/cozette.bdf b/Cozette/cozette.bdf
17index 9371252..fdbcc86 100644
18--- a/Cozette/cozette.bdf
19+++ b/Cozette/cozette.bdf
20@@ -1,7 +1,7 @@
21 STARTFONT 2.1
22 FONT -slavfox-Cozette-Medium-R-Normal--13-120-75-75-M-60-ISO10646-1
23 SIZE 12 75 75
24-FONTBOUNDINGBOX 17 28 -5 -3
25+FONTBOUNDINGBOX 13 13 -1 -3
26 COMMENT "Generated by fontforge, http://fontforge.sourceforge.net"
27 COMMENT "(c) 2020-2023 Slavfox"
28 STARTPROPERTIES 40
29@@ -23,7 +23,7 @@ FONTNAME_REGISTRY ""
30 FONT_NAME "Cozette"
31 FACE_NAME "Cozette"
32 COPYRIGHT "(c) 2020-2023 Slavfox"
33-FONT_VERSION "1.222"
34+FONT_VERSION "1.231"
35 FONT_ASCENT 10
36 FONT_DESCENT 3
37 UNDERLINE_POSITION -19
38@@ -46,7 +46,7 @@ FIGURE_WIDTH 6
39 AVG_LOWERCASE_WIDTH 60
40 AVG_UPPERCASE_WIDTH 60
41 ENDPROPERTIES
42-CHARS 3062
43+CHARS 3144
44 STARTCHAR uni0000
45 ENCODING 0
46 SWIDTH 500 0
47@@ -10485,120 +10485,108 @@ STARTCHAR Alphatonos
48 ENCODING 902
49 SWIDTH 500 0
50 DWIDTH 6 0
51-BBX 5 10 1 0
52+BBX 6 8 0 0
53 BITMAP
54-10
55-20
56-00
57-20
58-50
59 50
60-70
61-88
62-88
63-88
64+90
65+28
66+28
67+38
68+44
69+44
70+44
71 ENDCHAR
72 STARTCHAR Epsilontonos
73 ENCODING 904
74 SWIDTH 500 0
75 DWIDTH 6 0
76-BBX 5 10 1 0
77+BBX 6 8 0 0
78 BITMAP
79+5C
80+90
81 10
82-20
83-00
84-F8
85-80
86-F8
87-80
88-80
89-80
90-F8
91+18
92+10
93+10
94+10
95+1C
96 ENDCHAR
97 STARTCHAR Etatonos
98 ENCODING 905
99 SWIDTH 500 0
100 DWIDTH 6 0
101-BBX 5 10 1 0
102+BBX 6 9 0 0
103 BITMAP
104-10
105-20
106-00
107-88
108-88
109-F8
110-88
111-88
112-88
113-88
114+40
115+A4
116+24
117+24
118+3C
119+24
120+24
121+24
122+24
123 ENDCHAR
124 STARTCHAR Iotatonos
125 ENCODING 906
126 SWIDTH 500 0
127 DWIDTH 6 0
128-BBX 3 10 2 0
129+BBX 5 9 0 0
130 BITMAP
131-20
132 40
133-00
134-E0
135-40
136-40
137-40
138-40
139-40
140-E0
141+B8
142+10
143+10
144+10
145+10
146+10
147+10
148+38
149 ENDCHAR
150 STARTCHAR Omicrontonos
151 ENCODING 908
152 SWIDTH 500 0
153 DWIDTH 6 0
154-BBX 5 10 1 0
155+BBX 6 8 0 0
156 BITMAP
157-10
158-20
159-00
160-70
161-88
162-88
163-88
164-88
165-88
166-70
167+58
168+A4
169+24
170+24
171+24
172+24
173+24
174+18
175 ENDCHAR
176 STARTCHAR Upsilontonos
177 ENCODING 910
178 SWIDTH 500 0
179 DWIDTH 6 0
180-BBX 5 10 1 0
181+BBX 6 8 0 0
182 BITMAP
183-10
184-20
185-00
186-88
187-88
188-50
189-20
190-20
191-20
192-20
193+54
194+94
195+14
196+14
197+08
198+08
199+08
200+08
201 ENDCHAR
202 STARTCHAR Omegatonos
203 ENCODING 911
204 SWIDTH 500 0
205 DWIDTH 6 0
206-BBX 5 10 1 0
207+BBX 6 8 0 0
208 BITMAP
209-10
210-20
211-00
212-70
213-88
214-88
215-88
216-D8
217-50
218-D8
219+40
220+B8
221+28
222+44
223+44
224+28
225+28
226+6C
227 ENDCHAR
228 STARTCHAR iotadieresistonos
229 ENCODING 912
230@@ -18145,10 +18133,12 @@ STARTCHAR uni1E66
231 ENCODING 7782
232 SWIDTH 500 0
233 DWIDTH 6 0
234-BBX 5 10 1 0
235+BBX 5 12 1 -2
236 BITMAP
237-28
238-90
239+20
240+00
241+50
242+20
243 00
244 70
245 88
246@@ -18162,10 +18152,12 @@ STARTCHAR uni1E67
247 ENCODING 7783
248 SWIDTH 500 0
249 DWIDTH 6 0
250-BBX 5 9 1 0
251+BBX 5 11 1 -1
252 BITMAP
253-28
254-90
255+20
256+00
257+50
258+20
259 00
260 78
261 80
262@@ -19148,10 +19140,10 @@ BBX 5 10 1 0
263 BITMAP
264 70
265 10
266+20
267 70
268 88
269 88
270-88
271 F8
272 88
273 88
274@@ -19161,11 +19153,12 @@ STARTCHAR uni1EA3
275 ENCODING 7843
276 SWIDTH 500 0
277 DWIDTH 6 0
278-BBX 5 9 1 0
279+BBX 5 10 1 0
280 BITMAP
281 70
282 10
283 20
284+00
285 78
286 88
287 88
288@@ -19194,10 +19187,11 @@ STARTCHAR uni1EA5
289 ENCODING 7845
290 SWIDTH 500 0
291 DWIDTH 6 0
292-BBX 6 9 0 0
293+BBX 6 10 0 0
294 BITMAP
295-44
296-A8
297+04
298+48
299+A0
300 00
301 3C
302 44
303@@ -19227,29 +19221,65 @@ STARTCHAR uni1EA7
304 ENCODING 7847
305 SWIDTH 500 0
306 DWIDTH 6 0
307-BBX 6 9 0 0
308+BBX 5 10 1 0
309 BITMAP
310-88
311-54
312+10
313+48
314+A0
315 00
316-3C
317-44
318-44
319-44
320-4C
321-34
322+78
323+88
324+88
325+88
326+98
327+68
328 ENDCHAR
329-STARTCHAR uni1EAA
330-ENCODING 7850
331+STARTCHAR uni1EA8
332+ENCODING 7848
333 SWIDTH 500 0
334 DWIDTH 6 0
335 BBX 5 12 1 -2
336 BITMAP
337+70
338+10
339+20
340+50
341+00
342+70
343+88
344+88
345+F8
346+88
347+88
348+88
349+ENDCHAR
350+STARTCHAR uni1EA9
351+ENCODING 7849
352+SWIDTH 500 0
353+DWIDTH 6 0
354+BBX 5 10 1 -1
355+BITMAP
356+70
357+10
358 20
359 50
360 00
361+78
362+88
363+88
364+98
365+68
366+ENDCHAR
367+STARTCHAR uni1EAA
368+ENCODING 7850
369+SWIDTH 500 0
370+DWIDTH 6 0
371+BBX 5 12 1 -2
372+BITMAP
373 68
374 B0
375+20
376+50
377 00
378 70
379 88
380@@ -19257,6 +19287,7 @@ B0
381 F8
382 88
383 88
384+88
385 ENDCHAR
386 STARTCHAR uni1EAB
387 ENCODING 7851
388@@ -19536,24 +19567,25 @@ BBX 5 10 1 0
389 BITMAP
390 70
391 10
392+20
393 F8
394 80
395 80
396 F0
397 80
398 80
399-80
400 F8
401 ENDCHAR
402 STARTCHAR uni1EBB
403 ENCODING 7867
404 SWIDTH 500 0
405 DWIDTH 6 0
406-BBX 5 9 1 0
407+BBX 5 10 1 0
408 BITMAP
409 70
410 10
411 20
412+00
413 70
414 88
415 F8
416@@ -19660,27 +19692,73 @@ BITMAP
417 44
418 38
419 ENDCHAR
420+STARTCHAR uni1EC2
421+ENCODING 7874
422+SWIDTH 500 0
423+DWIDTH 6 0
424+BBX 5 12 1 -2
425+BITMAP
426+70
427+10
428+20
429+50
430+00
431+F8
432+80
433+80
434+F0
435+80
436+80
437+F8
438+ENDCHAR
439+STARTCHAR uni1EC3
440+ENCODING 7875
441+SWIDTH 500 0
442+DWIDTH 6 0
443+BBX 5 11 1 -1
444+BITMAP
445+70
446+10
447+20
448+50
449+00
450+70
451+88
452+F8
453+80
454+88
455+70
456+ENDCHAR
457 STARTCHAR uni1EC4
458 ENCODING 7876
459 SWIDTH 500 0
460 DWIDTH 6 0
461-BBX 5 8 1 0
462+BBX 5 12 1 -2
463 BITMAP
464+68
465+B0
466+20
467+50
468+00
469 F8
470 80
471 80
472 F0
473 80
474 80
475-80
476 F8
477 ENDCHAR
478 STARTCHAR uni1EC5
479 ENCODING 7877
480 SWIDTH 500 0
481 DWIDTH 6 0
482-BBX 5 6 1 0
483+BBX 5 11 1 -1
484 BITMAP
485+68
486+B0
487+20
488+50
489+00
490 70
491 88
492 F8
493@@ -19833,24 +19911,25 @@ BBX 5 10 1 0
494 BITMAP
495 70
496 10
497+20
498 70
499 88
500 88
501 88
502 88
503 88
504-88
505 70
506 ENDCHAR
507 STARTCHAR uni1ECF
508 ENCODING 7887
509 SWIDTH 500 0
510 DWIDTH 6 0
511-BBX 5 9 1 0
512+BBX 5 10 1 0
513 BITMAP
514 70
515 10
516 20
517+00
518 70
519 88
520 88
521@@ -19899,8 +19978,9 @@ SWIDTH 500 0
522 DWIDTH 6 0
523 BBX 6 12 0 -2
524 BITMAP
525-88
526-54
527+80
528+48
529+14
530 00
531 38
532 44
533@@ -19909,24 +19989,60 @@ BITMAP
534 44
535 44
536 44
537-44
538 38
539 ENDCHAR
540 STARTCHAR uni1ED3
541 ENCODING 7891
542 SWIDTH 500 0
543 DWIDTH 6 0
544-BBX 6 9 0 0
545+BBX 5 10 1 0
546 BITMAP
547+10
548+48
549+A0
550+00
551+70
552 88
553-54
554+88
555+88
556+88
557+70
558+ENDCHAR
559+STARTCHAR uni1ED4
560+ENCODING 7892
561+SWIDTH 500 0
562+DWIDTH 6 0
563+BBX 5 12 1 -2
564+BITMAP
565+70
566+10
567+20
568+50
569 00
570-38
571-44
572-44
573-44
574-44
575-38
576+70
577+88
578+88
579+88
580+88
581+88
582+70
583+ENDCHAR
584+STARTCHAR uni1ED5
585+ENCODING 7893
586+SWIDTH 500 0
587+DWIDTH 6 0
588+BBX 5 10 1 0
589+BITMAP
590+70
591+10
592+20
593+50
594+00
595+70
596+88
597+88
598+88
599+70
600 ENDCHAR
601 STARTCHAR uni1ED6
602 ENCODING 7894
603@@ -25668,6 +25784,23 @@ A8
604 08
605 10
606 ENDCHAR
607+STARTCHAR uni21AF
608+ENCODING 8623
609+SWIDTH 500 0
610+DWIDTH 6 0
611+BBX 6 10 0 0
612+BITMAP
613+20
614+20
615+4C
616+54
617+A8
618+C8
619+10
620+54
621+38
622+10
623+ENDCHAR
624 STARTCHAR uni21B0
625 ENCODING 8624
626 SWIDTH 500 0
627@@ -25788,6 +25921,19 @@ A0
628 90
629 08
630 ENDCHAR
631+STARTCHAR uni21B9
632+ENCODING 8633
633+SWIDTH 500 0
634+DWIDTH 6 0
635+BBX 6 6 0 0
636+BITMAP
637+A4
638+FC
639+A4
640+94
641+FC
642+94
643+ENDCHAR
644 STARTCHAR uni21BA
645 ENCODING 8634
646 SWIDTH 500 0
647@@ -26708,6 +26854,66 @@ BITMAP
648 AA00
649 D400
650 ENDCHAR
651+STARTCHAR therefore
652+ENCODING 8756
653+SWIDTH 500 0
654+DWIDTH 6 0
655+BBX 5 5 1 1
656+BITMAP
657+20
658+00
659+00
660+00
661+88
662+ENDCHAR
663+STARTCHAR uni2235
664+ENCODING 8757
665+SWIDTH 500 0
666+DWIDTH 6 0
667+BBX 5 5 1 1
668+BITMAP
669+88
670+00
671+00
672+00
673+20
674+ENDCHAR
675+STARTCHAR uni2236
676+ENCODING 8758
677+SWIDTH 500 0
678+DWIDTH 6 0
679+BBX 1 5 3 1
680+BITMAP
681+80
682+00
683+00
684+00
685+80
686+ENDCHAR
687+STARTCHAR uni2237
688+ENCODING 8759
689+SWIDTH 500 0
690+DWIDTH 6 0
691+BBX 5 5 1 1
692+BITMAP
693+88
694+00
695+00
696+00
697+88
698+ENDCHAR
699+STARTCHAR uni223A
700+ENCODING 8762
701+SWIDTH 500 0
702+DWIDTH 6 0
703+BBX 5 5 1 1
704+BITMAP
705+88
706+00
707+F8
708+00
709+88
710+ENDCHAR
711 STARTCHAR uni223E
712 ENCODING 8766
713 SWIDTH 500 0
714@@ -26718,6 +26924,19 @@ BITMAP
715 B4
716 98
717 ENDCHAR
718+STARTCHAR congruent
719+ENCODING 8773
720+SWIDTH 500 0
721+DWIDTH 6 0
722+BBX 5 6 1 2
723+BITMAP
724+68
725+B0
726+00
727+F8
728+00
729+F8
730+ENDCHAR
731 STARTCHAR approxequal
732 ENCODING 8776
733 SWIDTH 500 0
734@@ -27068,6 +27287,20 @@ F8
735 88
736 70
737 ENDCHAR
738+STARTCHAR circlemultiply
739+ENCODING 8855
740+SWIDTH 500 0
741+DWIDTH 6 0
742+BBX 7 7 0 0
743+BITMAP
744+38
745+44
746+AA
747+92
748+AA
749+44
750+38
751+ENDCHAR
752 STARTCHAR uni2298
753 ENCODING 8856
754 SWIDTH 500 0
755@@ -27080,6 +27313,34 @@ A8
756 C8
757 70
758 ENDCHAR
759+STARTCHAR uni229B
760+ENCODING 8859
761+SWIDTH 500 0
762+DWIDTH 6 0
763+BBX 7 7 0 0
764+BITMAP
765+38
766+54
767+BA
768+FE
769+BA
770+54
771+38
772+ENDCHAR
773+STARTCHAR uni229C
774+ENCODING 8860
775+SWIDTH 500 0
776+DWIDTH 6 0
777+BBX 7 7 0 0
778+BITMAP
779+38
780+44
781+BA
782+82
783+BA
784+44
785+38
786+ENDCHAR
787 STARTCHAR uni229D
788 ENCODING 8861
789 SWIDTH 500 0
790@@ -27116,6 +27377,20 @@ F8
791 88
792 F8
793 ENDCHAR
794+STARTCHAR uni22A0
795+ENCODING 8864
796+SWIDTH 500 0
797+DWIDTH 6 0
798+BBX 7 7 0 0
799+BITMAP
800+FE
801+C6
802+AA
803+92
804+AA
805+C6
806+FE
807+ENDCHAR
808 STARTCHAR uni22A1
809 ENCODING 8865
810 SWIDTH 500 0
811@@ -27546,6 +27821,18 @@ BITMAP
812 00
813 E0
814 ENDCHAR
815+STARTCHAR uni2315
816+ENCODING 8981
817+SWIDTH 500 0
818+DWIDTH 6 0
819+BBX 5 5 1 1
820+BITMAP
821+30
822+48
823+48
824+70
825+80
826+ENDCHAR
827 STARTCHAR uni2318
828 ENCODING 8984
829 SWIDTH 500 0
830@@ -27669,6 +27956,16 @@ BITMAP
831 80
832 80
833 ENDCHAR
834+STARTCHAR uni2335
835+ENCODING 9013
836+SWIDTH 500 0
837+DWIDTH 6 0
838+BBX 5 3 1 0
839+BITMAP
840+88
841+50
842+20
843+ENDCHAR
844 STARTCHAR uni2336
845 ENCODING 9014
846 SWIDTH 500 0
847@@ -27931,6 +28228,23 @@ A8
848 20
849 20
850 ENDCHAR
851+STARTCHAR uni2358
852+ENCODING 9048
853+SWIDTH 500 0
854+DWIDTH 6 0
855+BBX 5 10 1 -1
856+BITMAP
857+20
858+20
859+00
860+00
861+00
862+00
863+00
864+00
865+00
866+F8
867+ENDCHAR
868 STARTCHAR uni2359
869 ENCODING 9049
870 SWIDTH 500 0
871@@ -27946,6 +28260,20 @@ F8
872 00
873 F8
874 ENDCHAR
875+STARTCHAR uni235A
876+ENCODING 9050
877+SWIDTH 500 0
878+DWIDTH 6 0
879+BBX 5 7 1 -1
880+BITMAP
881+20
882+50
883+88
884+50
885+20
886+00
887+F8
888+ENDCHAR
889 STARTCHAR uni235B
890 ENCODING 9051
891 SWIDTH 500 0
892@@ -27959,6 +28287,20 @@ BITMAP
893 00
894 F8
895 ENDCHAR
896+STARTCHAR uni235C
897+ENCODING 9052
898+SWIDTH 500 0
899+DWIDTH 6 0
900+BBX 5 7 1 -1
901+BITMAP
902+70
903+88
904+88
905+88
906+70
907+00
908+F8
909+ENDCHAR
910 STARTCHAR uni235D
911 ENCODING 9053
912 SWIDTH 500 0
913@@ -28410,6 +28752,19 @@ AA
914 54
915 38
916 ENDCHAR
917+STARTCHAR uni238B
918+ENCODING 9099
919+SWIDTH 500 0
920+DWIDTH 6 0
921+BBX 6 6 0 1
922+BITMAP
923+E0
924+C8
925+A4
926+14
927+44
928+38
929+ENDCHAR
930 STARTCHAR uni2395
931 ENCODING 9109
932 SWIDTH 500 0
933@@ -31549,6 +31904,20 @@ BITMAP
934 FE
935 FE
936 ENDCHAR
937+STARTCHAR uni25B3
938+ENCODING 9651
939+SWIDTH 500 0
940+DWIDTH 6 0
941+BBX 7 7 0 0
942+BITMAP
943+10
944+28
945+28
946+44
947+44
948+82
949+FE
950+ENDCHAR
951 STARTCHAR uni25B6
952 ENCODING 9654
953 SWIDTH 500 0
954@@ -31579,6 +31948,20 @@ FE
955 38
956 10
957 ENDCHAR
958+STARTCHAR uni25BD
959+ENCODING 9661
960+SWIDTH 500 0
961+DWIDTH 6 0
962+BBX 7 7 0 0
963+BITMAP
964+FE
965+82
966+44
967+44
968+28
969+28
970+10
971+ENDCHAR
972 STARTCHAR uni25C0
973 ENCODING 9664
974 SWIDTH 500 0
975@@ -31775,6 +32158,20 @@ FE
976 7C
977 38
978 ENDCHAR
979+STARTCHAR uni25EB
980+ENCODING 9707
981+SWIDTH 500 0
982+DWIDTH 6 0
983+BBX 7 7 0 0
984+BITMAP
985+FE
986+92
987+92
988+92
989+92
990+92
991+FE
992+ENDCHAR
993 STARTCHAR uni25F0
994 ENCODING 9712
995 SWIDTH 500 0
996@@ -31887,6 +32284,20 @@ BITMAP
997 44
998 38
999 ENDCHAR
1000+STARTCHAR uni25FF
1001+ENCODING 9727
1002+SWIDTH 500 0
1003+DWIDTH 6 0
1004+BBX 7 7 0 0
1005+BITMAP
1006+02
1007+06
1008+0A
1009+12
1010+22
1011+42
1012+FE
1013+ENDCHAR
1014 STARTCHAR uni2601
1015 ENCODING 9729
1016 SWIDTH 500 0
1017@@ -37562,6 +37973,18 @@ FC
1018 08
1019 10
1020 ENDCHAR
1021+STARTCHAR uni29FB
1022+ENCODING 10747
1023+SWIDTH 500 0
1024+DWIDTH 6 0
1025+BBX 7 5 0 1
1026+BITMAP
1027+54
1028+54
1029+FE
1030+54
1031+54
1032+ENDCHAR
1033 STARTCHAR uni2B22
1034 ENCODING 11042
1035 SWIDTH 500 0
1036@@ -37780,6 +38203,16 @@ BITMAP
1037 00
1038 80
1039 ENDCHAR
1040+STARTCHAR uni3002
1041+ENCODING 12290
1042+SWIDTH 500 0
1043+DWIDTH 6 0
1044+BBX 3 3 1 -1
1045+BITMAP
1046+40
1047+A0
1048+40
1049+ENDCHAR
1050 STARTCHAR uni33D1
1051 ENCODING 13265
1052 SWIDTH 500 0
1053@@ -38210,7 +38643,7 @@ STARTCHAR uniE0B8
1054 ENCODING 57528
1055 SWIDTH 500 0
1056 DWIDTH 6 0
1057-BBX 7 13 0 -3
1058+BBX 6 13 0 -3
1059 BITMAP
1060 80
1061 80
1062@@ -38219,12 +38652,12 @@ C0
1063 E0
1064 E0
1065 F0
1066+F0
1067+F0
1068 F8
1069 F8
1070 FC
1071 FC
1072-FE
1073-FE
1074 ENDCHAR
1075 STARTCHAR uniE0B9
1076 ENCODING 57529
1077@@ -38250,21 +38683,21 @@ STARTCHAR uniE0BA
1078 ENCODING 57530
1079 SWIDTH 500 0
1080 DWIDTH 6 0
1081-BBX 7 13 0 -3
1082+BBX 6 13 0 -3
1083 BITMAP
1084-02
1085-02
1086-06
1087-06
1088-0E
1089-0E
1090-1E
1091-3E
1092-3E
1093-7E
1094-7E
1095-FE
1096-FE
1097+04
1098+04
1099+0C
1100+0C
1101+1C
1102+1C
1103+3C
1104+3C
1105+3C
1106+7C
1107+7C
1108+FC
1109+FC
1110 ENDCHAR
1111 STARTCHAR uniE0BB
1112 ENCODING 57531
1113@@ -38290,15 +38723,15 @@ STARTCHAR uniE0BC
1114 ENCODING 57532
1115 SWIDTH 500 0
1116 DWIDTH 6 0
1117-BBX 7 13 0 -3
1118+BBX 6 13 0 -3
1119 BITMAP
1120-FE
1121-FE
1122 FC
1123 FC
1124 F8
1125 F8
1126 F0
1127+F0
1128+E0
1129 E0
1130 E0
1131 C0
1132@@ -38330,21 +38763,21 @@ STARTCHAR uniE0BE
1133 ENCODING 57534
1134 SWIDTH 500 0
1135 DWIDTH 6 0
1136-BBX 7 13 0 -3
1137+BBX 6 13 0 -3
1138 BITMAP
1139-FE
1140-FE
1141-7E
1142-7E
1143-3E
1144-3E
1145-1E
1146-0E
1147-0E
1148-06
1149-06
1150-02
1151-02
1152+FC
1153+FC
1154+7C
1155+7C
1156+3C
1157+3C
1158+1C
1159+1C
1160+1C
1161+0C
1162+0C
1163+04
1164+04
1165 ENDCHAR
1166 STARTCHAR uniE0BF
1167 ENCODING 57535
1168@@ -38582,13 +39015,26 @@ F4
1169 F4
1170 FC
1171 ENDCHAR
1172+STARTCHAR uniE5FA
1173+ENCODING 58874
1174+SWIDTH 500 0
1175+DWIDTH 6 0
1176+BBX 6 6 0 1
1177+BITMAP
1178+F8
1179+FC
1180+84
1181+94
1182+94
1183+FC
1184+ENDCHAR
1185 STARTCHAR uniE5FB
1186 ENCODING 58875
1187 SWIDTH 500 0
1188 DWIDTH 6 0
1189 BBX 5 5 1 1
1190 BITMAP
1191-E0
1192+F0
1193 D8
1194 A8
1195 D8
1196@@ -38600,11 +39046,24 @@ SWIDTH 500 0
1197 DWIDTH 6 0
1198 BBX 5 5 1 1
1199 BITMAP
1200-E0
1201-D8
1202+F0
1203 A8
1204 D8
1205+A8
1206+F8
1207+ENDCHAR
1208+STARTCHAR uniE5FD
1209+ENCODING 58877
1210+SWIDTH 500 0
1211+DWIDTH 6 0
1212+BBX 6 6 0 1
1213+BITMAP
1214 F8
1215+B4
1216+84
1217+B4
1218+CC
1219+FC
1220 ENDCHAR
1221 STARTCHAR uniE5FE
1222 ENCODING 58878
1223@@ -39295,6 +39754,23 @@ FC
1224 BC
1225 78
1226 ENDCHAR
1227+STARTCHAR uniE634
1228+ENCODING 58932
1229+SWIDTH 500 0
1230+DWIDTH 6 0
1231+BBX 7 10 0 0
1232+BITMAP
1233+FE
1234+FC
1235+F8
1236+F0
1237+E0
1238+E0
1239+F0
1240+F8
1241+FC
1242+FE
1243+ENDCHAR
1244 STARTCHAR uniE64E
1245 ENCODING 58958
1246 SWIDTH 500 0
1247@@ -39323,6 +39799,36 @@ BITMAP
1248 52
1249 8C
1250 ENDCHAR
1251+STARTCHAR uniE697
1252+ENCODING 59031
1253+SWIDTH 461 0
1254+DWIDTH 6 0
1255+BBX 6 8 0 -1
1256+BITMAP
1257+18
1258+64
1259+80
1260+98
1261+64
1262+04
1263+98
1264+60
1265+ENDCHAR
1266+STARTCHAR uniE6A9
1267+ENCODING 59049
1268+SWIDTH 461 0
1269+DWIDTH 6 0
1270+BBX 7 8 0 -1
1271+BITMAP
1272+02
1273+DE
1274+8C
1275+9A
1276+B2
1277+62
1278+F6
1279+80
1280+ENDCHAR
1281 STARTCHAR uniE702
1282 ENCODING 59138
1283 SWIDTH 461 0
1284@@ -39891,6 +40397,20 @@ BITMAP
1285 40
1286 80
1287 ENDCHAR
1288+STARTCHAR uniE764
1289+ENCODING 59236
1290+SWIDTH 500 0
1291+DWIDTH 6 0
1292+BBX 7 7 0 0
1293+BITMAP
1294+CE
1295+BA
1296+64
1297+D6
1298+64
1299+BA
1300+CE
1301+ENDCHAR
1302 STARTCHAR uniE768
1303 ENCODING 59240
1304 SWIDTH 500 0
1305@@ -39932,6 +40452,22 @@ D6
1306 78
1307 38
1308 ENDCHAR
1309+STARTCHAR uniE76D
1310+ENCODING 59245
1311+SWIDTH 500 0
1312+DWIDTH 6 0
1313+BBX 7 9 0 -1
1314+BITMAP
1315+10
1316+7C
1317+FE
1318+7C
1319+92
1320+6C
1321+92
1322+6C
1323+10
1324+ENDCHAR
1325 STARTCHAR uniE76E
1326 ENCODING 59246
1327 SWIDTH 500 0
1328@@ -39959,6 +40495,26 @@ B8
1329 A8
1330 AC
1331 ENDCHAR
1332+STARTCHAR uniE779
1333+ENCODING 59257
1334+SWIDTH 500 0
1335+DWIDTH 6 0
1336+BBX 4 13 1 -3
1337+BITMAP
1338+60
1339+90
1340+80
1341+B0
1342+60
1343+00
1344+E0
1345+90
1346+90
1347+00
1348+90
1349+90
1350+70
1351+ENDCHAR
1352 STARTCHAR uniE77B
1353 ENCODING 59259
1354 SWIDTH 500 0
1355@@ -40001,6 +40557,18 @@ BITMAP
1356 52
1357 8C
1358 ENDCHAR
1359+STARTCHAR uniE786
1360+ENCODING 59270
1361+SWIDTH 461 0
1362+DWIDTH 6 0
1363+BBX 7 5 0 1
1364+BITMAP
1365+F8
1366+54
1367+54
1368+54
1369+FE
1370+ENDCHAR
1371 STARTCHAR uniE791
1372 ENCODING 59281
1373 SWIDTH 500 0
1374@@ -40305,6 +40873,21 @@ BITMAP
1375 E4
1376 40
1377 ENDCHAR
1378+STARTCHAR uniF005
1379+ENCODING 61445
1380+SWIDTH 500 0
1381+DWIDTH 6 0
1382+BBX 7 8 0 0
1383+BITMAP
1384+10
1385+10
1386+38
1387+FE
1388+7C
1389+38
1390+6C
1391+44
1392+ENDCHAR
1393 STARTCHAR uniF008
1394 ENCODING 61448
1395 SWIDTH 461 0
1396@@ -40641,6 +41224,20 @@ FF
1397 FF
1398 81
1399 ENDCHAR
1400+STARTCHAR uniF03A
1401+ENCODING 61498
1402+SWIDTH 461 0
1403+DWIDTH 6 0
1404+BBX 7 7 0 0
1405+BITMAP
1406+BE
1407+00
1408+BE
1409+00
1410+BE
1411+00
1412+BE
1413+ENDCHAR
1414 STARTCHAR uniF03D
1415 ENCODING 61501
1416 SWIDTH 500 0
1417@@ -40654,6 +41251,19 @@ FE
1418 F6
1419 72
1420 ENDCHAR
1421+STARTCHAR uniF03E
1422+ENCODING 61502
1423+SWIDTH 461 0
1424+DWIDTH 6 0
1425+BBX 7 6 0 0
1426+BITMAP
1427+FE
1428+82
1429+AA
1430+8E
1431+FE
1432+FE
1433+ENDCHAR
1434 STARTCHAR uniF040
1435 ENCODING 61504
1436 SWIDTH 500 0
1437@@ -40911,6 +41521,19 @@ EE
1438 44
1439 38
1440 ENDCHAR
1441+STARTCHAR uniF064
1442+ENCODING 61540
1443+SWIDTH 500 0
1444+DWIDTH 6 0
1445+BBX 7 6 0 0
1446+BITMAP
1447+08
1448+0C
1449+7E
1450+8C
1451+88
1452+80
1453+ENDCHAR
1454 STARTCHAR uniF067
1455 ENCODING 61543
1456 SWIDTH 500 0
1457@@ -41002,6 +41625,21 @@ FE
1458 60
1459 C0
1460 ENDCHAR
1461+STARTCHAR uniF076
1462+ENCODING 61558
1463+SWIDTH 461 0
1464+DWIDTH 6 0
1465+BBX 6 8 0 -1
1466+BITMAP
1467+CC
1468+CC
1469+00
1470+CC
1471+CC
1472+CC
1473+FC
1474+78
1475+ENDCHAR
1476 STARTCHAR uniF07B
1477 ENCODING 61563
1478 SWIDTH 461 0
1479@@ -41053,6 +41691,22 @@ F0
1480 1C
1481 0C
1482 ENDCHAR
1483+STARTCHAR uniF085
1484+ENCODING 61573
1485+SWIDTH 500 0
1486+DWIDTH 6 0
1487+BBX 7 9 0 -1
1488+BITMAP
1489+04
1490+0E
1491+54
1492+F8
1493+50
1494+F8
1495+54
1496+0E
1497+04
1498+ENDCHAR
1499 STARTCHAR uniF09C
1500 ENCODING 61596
1501 SWIDTH 461 0
1502@@ -41239,6 +41893,20 @@ BITMAP
1503 FE
1504 10
1505 ENDCHAR
1506+STARTCHAR uniF0F4
1507+ENCODING 61684
1508+SWIDTH 500 0
1509+DWIDTH 6 0
1510+BBX 8 7 0 -1
1511+BITMAP
1512+7E
1513+7D
1514+7D
1515+7E
1516+7C
1517+00
1518+FE
1519+ENDCHAR
1520 STARTCHAR uniF0FD
1521 ENCODING 61693
1522 SWIDTH 461 0
1523@@ -41320,6 +41988,18 @@ BE
1524 C2
1525 FC
1526 ENDCHAR
1527+STARTCHAR uniF11C
1528+ENCODING 61724
1529+SWIDTH 461 0
1530+DWIDTH 6 0
1531+BBX 7 5 0 1
1532+BITMAP
1533+FE
1534+82
1535+FE
1536+8A
1537+FE
1538+ENDCHAR
1539 STARTCHAR uniF120
1540 ENCODING 61728
1541 SWIDTH 500 0
1542@@ -41408,6 +42088,21 @@ FE
1543 82
1544 FE
1545 ENDCHAR
1546+STARTCHAR uniF13B
1547+ENCODING 61755
1548+SWIDTH 500 0
1549+DWIDTH 6 0
1550+BBX 7 8 0 0
1551+BITMAP
1552+FE
1553+82
1554+BE
1555+82
1556+FA
1557+82
1558+7C
1559+10
1560+ENDCHAR
1561 STARTCHAR uniF13E
1562 ENCODING 61758
1563 SWIDTH 500 0
1564@@ -41632,6 +42327,20 @@ EE
1565 7C
1566 82
1567 ENDCHAR
1568+STARTCHAR uniF18D
1569+ENCODING 61837
1570+SWIDTH 461 0
1571+DWIDTH 6 0
1572+BBX 6 7 0 0
1573+BITMAP
1574+FC
1575+00
1576+FC
1577+00
1578+FC
1579+08
1580+10
1581+ENDCHAR
1582 STARTCHAR uniF198
1583 ENCODING 61848
1584 SWIDTH 500 0
1585@@ -41901,6 +42610,22 @@ FC
1586 B4
1587 FC
1588 ENDCHAR
1589+STARTCHAR uniF1FA
1590+ENCODING 61946
1591+SWIDTH 500 0
1592+DWIDTH 6 0
1593+BBX 7 9 0 0
1594+BITMAP
1595+38
1596+44
1597+82
1598+BA
1599+AA
1600+BC
1601+80
1602+42
1603+3C
1604+ENDCHAR
1605 STARTCHAR uniF1FE
1606 ENCODING 61950
1607 SWIDTH 500 0
1608@@ -41956,6 +42681,24 @@ FE
1609 38
1610 10
1611 ENDCHAR
1612+STARTCHAR uniF233
1613+ENCODING 62003
1614+SWIDTH 461 0
1615+DWIDTH 6 0
1616+BBX 7 11 0 -2
1617+BITMAP
1618+FE
1619+8A
1620+FE
1621+00
1622+FE
1623+8A
1624+FE
1625+00
1626+FE
1627+8A
1628+FE
1629+ENDCHAR
1630 STARTCHAR uniF240
1631 ENCODING 62016
1632 SWIDTH 500 0
1633@@ -42170,6 +42913,21 @@ BITMAP
1634 86
1635 7A
1636 ENDCHAR
1637+STARTCHAR uniF292
1638+ENCODING 62098
1639+SWIDTH 500 0
1640+DWIDTH 6 0
1641+BBX 7 8 0 0
1642+BITMAP
1643+14
1644+14
1645+7E
1646+28
1647+28
1648+FC
1649+50
1650+50
1651+ENDCHAR
1652 STARTCHAR uniF293
1653 ENCODING 62099
1654 SWIDTH 500 0
1655@@ -42344,6 +43102,22 @@ FC
1656 FC
1657 78
1658 ENDCHAR
1659+STARTCHAR uniF2DC
1660+ENCODING 62172
1661+SWIDTH 500 0
1662+DWIDTH 6 0
1663+BBX 7 9 0 -1
1664+BITMAP
1665+10
1666+38
1667+D6
1668+D6
1669+38
1670+D6
1671+D6
1672+38
1673+10
1674+ENDCHAR
1675 STARTCHAR uniF300
1676 ENCODING 62208
1677 SWIDTH 500 0
1678@@ -42372,6 +43146,21 @@ BE
1679 4C
1680 38
1681 ENDCHAR
1682+STARTCHAR uniF302
1683+ENCODING 62210
1684+SWIDTH 500 0
1685+DWIDTH 6 0
1686+BBX 6 8 0 0
1687+BITMAP
1688+08
1689+10
1690+7C
1691+F8
1692+F8
1693+F8
1694+7C
1695+6C
1696+ENDCHAR
1697 STARTCHAR uniF303
1698 ENCODING 62211
1699 SWIDTH 500 0
1700@@ -42771,6 +43560,33 @@ F8
1701 F8
1702 F8
1703 ENDCHAR
1704+STARTCHAR uniF415
1705+ENCODING 62485
1706+SWIDTH 500 0
1707+DWIDTH 6 0
1708+BBX 7 10 0 0
1709+BITMAP
1710+38
1711+44
1712+82
1713+82
1714+82
1715+44
1716+38
1717+44
1718+82
1719+82
1720+ENDCHAR
1721+STARTCHAR uniF417
1722+ENCODING 62487
1723+SWIDTH 461 0
1724+DWIDTH 6 0
1725+BBX 7 3 0 2
1726+BITMAP
1727+38
1728+EE
1729+38
1730+ENDCHAR
1731 STARTCHAR uniF423
1732 ENCODING 62499
1733 SWIDTH 461 0
1734@@ -42966,6 +43782,21 @@ BITMAP
1735 44
1736 38
1737 ENDCHAR
1738+STARTCHAR uniF471
1739+ENCODING 62577
1740+SWIDTH 500 0
1741+DWIDTH 6 0
1742+BBX 6 8 0 0
1743+BITMAP
1744+F0
1745+98
1746+9C
1747+84
1748+D4
1749+D4
1750+84
1751+FC
1752+ENDCHAR
1753 STARTCHAR uniF475
1754 ENCODING 62581
1755 SWIDTH 500 0
1756@@ -45663,6 +46494,23 @@ A000
1757 07C0
1758 0BC0
1759 ENDCHAR
1760+STARTCHAR u1F429
1761+ENCODING 128041
1762+SWIDTH 922 0
1763+DWIDTH 12 0
1764+BBX 11 10 1 -1
1765+BITMAP
1766+3000
1767+5840
1768+F860
1769+1E60
1770+3F80
1771+3F80
1772+3E40
1773+0840
1774+0820
1775+1860
1776+ENDCHAR
1777 STARTCHAR u1F42A
1778 ENCODING 128042
1779 SWIDTH 922 0
1780@@ -45693,6 +46541,23 @@ EF80
1781 1040
1782 1040
1783 ENDCHAR
1784+STARTCHAR u1F42C
1785+ENCODING 128044
1786+SWIDTH 922 0
1787+DWIDTH 12 0
1788+BBX 9 10 2 -1
1789+BITMAP
1790+0180
1791+3F00
1792+7F00
1793+5F80
1794+7F80
1795+FF80
1796+0780
1797+4380
1798+2700
1799+7C00
1800+ENDCHAR
1801 STARTCHAR u1F439
1802 ENCODING 128057
1803 SWIDTH 461 0
1804@@ -45736,6 +46601,24 @@ FA
1805 22
1806 1C
1807 ENDCHAR
1808+STARTCHAR u1F469
1809+ENCODING 128105
1810+SWIDTH 922 0
1811+DWIDTH 12 0
1812+BBX 11 11 1 -2
1813+BITMAP
1814+1F00
1815+3F80
1816+73C0
1817+E1E0
1818+C060
1819+D160
1820+C060
1821+D160
1822+CE60
1823+E0E0
1824+DF60
1825+ENDCHAR
1826 STARTCHAR u1F47D
1827 ENCODING 128125
1828 SWIDTH 922 0
1829@@ -45818,6 +46701,23 @@ F700
1830 4600
1831 0200
1832 ENDCHAR
1833+STARTCHAR u1F4A9
1834+ENCODING 128169
1835+SWIDTH 922 0
1836+DWIDTH 12 0
1837+BBX 10 10 1 -2
1838+BITMAP
1839+1000
1840+1C00
1841+1200
1842+2100
1843+2100
1844+5280
1845+4080
1846+9240
1847+8C40
1848+7F80
1849+ENDCHAR
1850 STARTCHAR u1F4BC
1851 ENCODING 128188
1852 SWIDTH 922 0
1853@@ -45833,6 +46733,23 @@ F780
1854 FF80
1855 FF80
1856 ENDCHAR
1857+STARTCHAR u1F4C4
1858+ENCODING 128196
1859+SWIDTH 922 0
1860+DWIDTH 12 0
1861+BBX 8 10 2 -1
1862+BITMAP
1863+FC
1864+8A
1865+89
1866+AF
1867+81
1868+BD
1869+81
1870+BD
1871+81
1872+FF
1873+ENDCHAR
1874 STARTCHAR u1F4D6
1875 ENCODING 128214
1876 SWIDTH 922 0
1877@@ -45898,6 +46815,24 @@ C2
1878 82
1879 FE
1880 ENDCHAR
1881+STARTCHAR u1F4E9
1882+ENCODING 128233
1883+SWIDTH 922 0
1884+DWIDTH 12 0
1885+BBX 11 11 1 -2
1886+BITMAP
1887+0E00
1888+0A00
1889+1B00
1890+F1E0
1891+CA60
1892+A4A0
1893+9120
1894+9B20
1895+A4A0
1896+C060
1897+FFE0
1898+ENDCHAR
1899 STARTCHAR u1F50B
1900 ENCODING 128267
1901 SWIDTH 500 0
1902@@ -45996,6 +46931,24 @@ F800
1903 0180
1904 00C0
1905 ENDCHAR
1906+STARTCHAR u1F52C
1907+ENCODING 128300
1908+SWIDTH 922 0
1909+DWIDTH 12 0
1910+BBX 10 11 1 -2
1911+BITMAP
1912+0080
1913+01C0
1914+0780
1915+0F00
1916+1F00
1917+8E80
1918+4480
1919+2080
1920+1100
1921+3F80
1922+7FC0
1923+ENDCHAR
1924 STARTCHAR u1F52E
1925 ENCODING 128302
1926 SWIDTH 500 0
1927@@ -46049,69 +47002,37 @@ STARTCHAR u1F60A
1928 ENCODING 128522
1929 SWIDTH 922 0
1930 DWIDTH 12 0
1931-BBX 17 27 -5 -2
1932-BITMAP
1933-800000
1934-000000
1935-000000
1936-000000
1937-000000
1938-000000
1939-000000
1940-000000
1941-000000
1942-000000
1943-000000
1944-000000
1945-000000
1946-000000
1947-000000
1948-000000
1949-007C00
1950-008200
1951-010100
1952-024480
1953-02AA80
1954-020080
1955-020080
1956-024480
1957-013900
1958-008200
1959-007C00
1960+BBX 11 11 1 -2
1961+BITMAP
1962+1F00
1963+2080
1964+4040
1965+9120
1966+AAA0
1967+8020
1968+8020
1969+9120
1970+4E40
1971+2080
1972+1F00
1973 ENDCHAR
1974 STARTCHAR u1F60E
1975 ENCODING 128526
1976 SWIDTH 922 0
1977 DWIDTH 12 0
1978-BBX 17 27 -5 -2
1979-BITMAP
1980-800000
1981-000000
1982-000000
1983-000000
1984-000000
1985-000000
1986-000000
1987-000000
1988-000000
1989-000000
1990-000000
1991-000000
1992-000000
1993-000000
1994-000000
1995-000000
1996-007C00
1997-008200
1998-010100
1999-03FF80
2000-03EF80
2001-02EE80
2002-020080
2003-024480
2004-013900
2005-008200
2006-007C00
2007+BBX 11 11 1 -2
2008+BITMAP
2009+1F00
2010+2080
2011+4040
2012+FFE0
2013+FBE0
2014+BBA0
2015+8020
2016+9120
2017+4E40
2018+2080
2019+1F00
2020 ENDCHAR
2021 STARTCHAR u1F680
2022 ENCODING 128640
2023@@ -46233,6 +47154,91 @@ BFA0
2024 1B00
2025 0E00
2026 ENDCHAR
2027+STARTCHAR uF0002
2028+ENCODING 983042
2029+SWIDTH 500 0
2030+DWIDTH 6 0
2031+BBX 7 10 0 -1
2032+BITMAP
2033+44
2034+82
2035+AA
2036+BA
2037+AA
2038+82
2039+54
2040+10
2041+FE
2042+38
2043+ENDCHAR
2044+STARTCHAR uF006F
2045+ENCODING 983151
2046+SWIDTH 500 0
2047+DWIDTH 6 0
2048+BBX 7 7 0 0
2049+BITMAP
2050+38
2051+44
2052+82
2053+92
2054+C2
2055+84
2056+38
2057+ENDCHAR
2058+STARTCHAR uF0172
2059+ENCODING 983410
2060+SWIDTH 500 0
2061+DWIDTH 6 0
2062+BBX 6 9 0 -1
2063+BITMAP
2064+48
2065+48
2066+84
2067+84
2068+84
2069+84
2070+84
2071+48
2072+48
2073+ENDCHAR
2074+STARTCHAR uF01A8
2075+ENCODING 983464
2076+SWIDTH 500 0
2077+DWIDTH 6 0
2078+BBX 8 5 0 0
2079+BITMAP
2080+E4
2081+0A
2082+51
2083+0A
2084+24
2085+ENDCHAR
2086+STARTCHAR uF01F0
2087+ENCODING 983536
2088+SWIDTH 500 0
2089+DWIDTH 6 0
2090+BBX 7 6 0 0
2091+BITMAP
2092+FE
2093+C6
2094+AA
2095+92
2096+82
2097+FE
2098+ENDCHAR
2099+STARTCHAR uF0232
2100+ENCODING 983602
2101+SWIDTH 500 0
2102+DWIDTH 6 0
2103+BBX 6 6 0 0
2104+BITMAP
2105+FC
2106+78
2107+30
2108+30
2109+30
2110+10
2111+ENDCHAR
2112 STARTCHAR uF02D1
2113 ENCODING 983761
2114 SWIDTH 500 0
2115@@ -46259,4 +47265,170 @@ EE
2116 28
2117 10
2118 ENDCHAR
2119+STARTCHAR uF0306
2120+ENCODING 983814
2121+SWIDTH 500 0
2122+DWIDTH 6 0
2123+BBX 7 3 0 2
2124+BITMAP
2125+E0
2126+BE
2127+E4
2128+ENDCHAR
2129+STARTCHAR uF031B
2130+ENCODING 983835
2131+SWIDTH 500 0
2132+DWIDTH 6 0
2133+BBX 7 9 0 -1
2134+BITMAP
2135+70
2136+80
2137+94
2138+BE
2139+94
2140+BE
2141+94
2142+80
2143+70
2144+ENDCHAR
2145+STARTCHAR uF0320
2146+ENCODING 983840
2147+SWIDTH 500 0
2148+DWIDTH 6 0
2149+BBX 7 7 0 0
2150+BITMAP
2151+38
2152+18
2153+FA
2154+C6
2155+BE
2156+30
2157+38
2158+ENDCHAR
2159+STARTCHAR uF0411
2160+ENCODING 984081
2161+SWIDTH 500 0
2162+DWIDTH 6 0
2163+BBX 7 9 0 -2
2164+BITMAP
2165+FE
2166+00
2167+FE
2168+00
2169+E8
2170+0C
2171+EE
2172+0C
2173+08
2174+ENDCHAR
2175+STARTCHAR uF048D
2176+ENCODING 984205
2177+SWIDTH 500 0
2178+DWIDTH 6 0
2179+BBX 7 10 0 -1
2180+BITMAP
2181+FE
2182+AE
2183+FE
2184+00
2185+FE
2186+AE
2187+FE
2188+10
2189+FE
2190+38
2191+ENDCHAR
2192+STARTCHAR uF05C6
2193+ENCODING 984518
2194+SWIDTH 500 0
2195+DWIDTH 6 0
2196+BBX 6 6 0 0
2197+BITMAP
2198+CC
2199+FC
2200+48
2201+48
2202+FC
2203+CC
2204+ENDCHAR
2205+STARTCHAR uF0645
2206+ENCODING 984645
2207+SWIDTH 500 0
2208+DWIDTH 6 0
2209+BBX 6 8 0 -1
2210+BITMAP
2211+C0
2212+C0
2213+00
2214+8C
2215+EC
2216+80
2217+EC
2218+0C
2219+ENDCHAR
2220+STARTCHAR uF06A9
2221+ENCODING 984745
2222+SWIDTH 500 0
2223+DWIDTH 6 0
2224+BBX 7 7 0 0
2225+BITMAP
2226+10
2227+38
2228+10
2229+38
2230+7C
2231+D6
2232+7C
2233+ENDCHAR
2234+STARTCHAR uF072B
2235+ENCODING 984875
2236+SWIDTH 500 0
2237+DWIDTH 6 0
2238+BBX 7 9 0 0
2239+BITMAP
2240+10
2241+38
2242+7C
2243+BA
2244+D6
2245+EE
2246+6C
2247+28
2248+10
2249+ENDCHAR
2250+STARTCHAR uF07D4
2251+ENCODING 985044
2252+SWIDTH 500 0
2253+DWIDTH 6 0
2254+BBX 7 6 0 1
2255+BITMAP
2256+78
2257+C4
2258+8E
2259+CA
2260+7C
2261+0A
2262+ENDCHAR
2263+STARTCHAR uF0844
2264+ENCODING 985156
2265+SWIDTH 500 0
2266+DWIDTH 6 0
2267+BBX 7 7 0 0
2268+BITMAP
2269+AA
2270+AA
2271+54
2272+54
2273+28
2274+28
2275+10
2276+ENDCHAR
2277+STARTCHAR uF1417
2278+ENCODING 988183
2279+SWIDTH 461 0
2280+DWIDTH 0 0
2281+BBX 1 1 0 0
2282+BITMAP
2283+00
2284+ENDCHAR
2285 ENDFONT
2286diff --git a/src/e/Label.zig b/src/e/Label.zig
2287index 1d2119c..8330936 100644
2288--- a/src/e/Label.zig
2289+++ b/src/e/Label.zig
2290@@ -113,7 +113,7 @@ pub fn handleMessage(app: *root.App, ele: mag.Element, msg: mag.Message, extra:
2291 }
2292 },
2293 .get_height => {
2294- if (font == .bdf) return extras.safeAdd(@as(u32, 12), -font.bdf.bbox[3]);
2295+ if (font == .bdf) return font.bdf.bbox[1];
2296 return self.size;
2297 },
2298 .enter => {},
2299diff --git a/test/images/demo-bdf-cozette.png b/test/images/demo-bdf-cozette.png
2300index 0110829..c669969 100644
2301Binary files a/test/images/demo-bdf-cozette.png and b/test/images/demo-bdf-cozette.png differ
2302diff --git a/test/images/demo-menubar.png b/test/images/demo-menubar.png
2303index dedbfa8..e0e4649 100644
2304Binary files a/test/images/demo-menubar.png and b/test/images/demo-menubar.png differ
2305diff --git a/test/layout/demo-bdf-cozette.txt b/test/layout/demo-bdf-cozette.txt
2306index 94df342..5d33be2 100644
2307--- a/test/layout/demo-bdf-cozette.txt
2308+++ b/test/layout/demo-bdf-cozette.txt
2309@@ -1,13 +1,13 @@
2310 0 e.Panel @ [0,800,0,600] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,800,0,600] bg_color=#cccccc
2311 1 e.Box @ [325,475,0,50] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[325,475,0,50] bg_color=null
2312- 2 e.Label @ [325,475,50,65] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[325,475,50,65] bg_color=null
2313- 3 e.Label @ [169,631,65,80] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[169,631,65,80] bg_color=null
2314- 4 e.Label @ [343,457,80,95] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[343,457,80,95] bg_color=null
2315- 5 e.Label @ [268,532,95,110] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[268,532,95,110] bg_color=null
2316- 6 e.Label @ [223,577,110,125] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[223,577,110,125] bg_color=null
2317- 7 e.Label @ [352,448,125,140] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,125,140] bg_color=null
2318- 8 e.Label @ [352,448,140,155] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,140,155] bg_color=null
2319- 9 e.Label @ [352,448,155,170] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,155,170] bg_color=null
2320- 10 e.Label @ [352,448,170,185] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,170,185] bg_color=null
2321- 11 e.Label @ [352,448,185,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,185,200] bg_color=null
2322- 12 e.Label @ [352,448,200,215] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,200,215] bg_color=null
2323+ 2 e.Label @ [325,475,50,63] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[325,475,50,63] bg_color=null
2324+ 3 e.Label @ [169,631,63,76] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[169,631,63,76] bg_color=null
2325+ 4 e.Label @ [343,457,76,89] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[343,457,76,89] bg_color=null
2326+ 5 e.Label @ [268,532,89,102] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[268,532,89,102] bg_color=null
2327+ 6 e.Label @ [223,577,102,115] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[223,577,102,115] bg_color=null
2328+ 7 e.Label @ [352,448,115,128] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,115,128] bg_color=null
2329+ 8 e.Label @ [352,448,128,141] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,128,141] bg_color=null
2330+ 9 e.Label @ [352,448,141,154] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,141,154] bg_color=null
2331+ 10 e.Label @ [352,448,154,167] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,154,167] bg_color=null
2332+ 11 e.Label @ [352,448,167,180] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,167,180] bg_color=null
2333+ 12 e.Label @ [352,448,180,193] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[352,448,180,193] bg_color=null
2334diff --git a/test/layout/demo-menubar.txt b/test/layout/demo-menubar.txt
2335index 8885fcc..9e2be55 100644
2336--- a/test/layout/demo-menubar.txt
2337+++ b/test/layout/demo-menubar.txt
2338@@ -1,24 +1,24 @@
2339 23 menubar.A @ [0,300,0,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,300,0,200] bg_color=null
2340 22 e.Panel @ [0,300,0,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,300,0,200] bg_color=null
2341- 21 e.MenuBar @ [0,300,0,26] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,300,0,26] bg_color=null
2342- 20 e.Panel @ [0,300,0,26] margin=[0,0,0,0] border=[0,0,0,1] padding=[0,0,0,0] bounds=[0,300,0,25] bg_color=#f6f5f4
2343- 4 e.Menu @ [0,40,0,25] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,40,0,25] bg_color=null
2344- 1 e.Panel @ [0,40,0,25] margin=[0,0,0,0] border=[0,0,3,3] padding=[8,8,2,2] bounds=[8,32,5,20] bg_color=null
2345- 0 e.Label @ [8,32,5,20] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[8,32,5,20] bg_color=null
2346- 3 e.Panel @ [0,100,25,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,100,25,200] bg_color=null
2347- 2 e.Panel @ [0,100,25,35] margin=[0,0,0,0] border=[1,1,1,1] padding=[0,0,4,4] bounds=[1,99,30,30] bg_color=#f6f5f4
2348- 9 e.Menu @ [40,80,0,25] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[40,80,0,25] bg_color=null
2349- 6 e.Panel @ [40,80,0,25] margin=[0,0,0,0] border=[0,0,3,3] padding=[8,8,2,2] bounds=[48,72,5,20] bg_color=null
2350- 5 e.Label @ [48,72,5,20] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[48,72,5,20] bg_color=null
2351- 8 e.Panel @ [40,140,25,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[40,140,25,200] bg_color=null
2352- 7 e.Panel @ [40,140,25,35] margin=[0,0,0,0] border=[1,1,1,1] padding=[0,0,4,4] bounds=[41,139,30,30] bg_color=#f6f5f4
2353- 14 e.Menu @ [80,120,0,25] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[80,120,0,25] bg_color=null
2354- 11 e.Panel @ [80,120,0,25] margin=[0,0,0,0] border=[0,0,3,3] padding=[8,8,2,2] bounds=[88,112,5,20] bg_color=null
2355- 10 e.Label @ [88,112,5,20] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[88,112,5,20] bg_color=null
2356- 13 e.Panel @ [80,180,25,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[80,180,25,200] bg_color=null
2357- 12 e.Panel @ [80,180,25,35] margin=[0,0,0,0] border=[1,1,1,1] padding=[0,0,4,4] bounds=[81,179,30,30] bg_color=#f6f5f4
2358- 19 e.Menu @ [120,160,0,25] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[120,160,0,25] bg_color=null
2359- 16 e.Panel @ [120,160,0,25] margin=[0,0,0,0] border=[0,0,3,3] padding=[8,8,2,2] bounds=[128,152,5,20] bg_color=null
2360- 15 e.Label @ [128,152,5,20] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[128,152,5,20] bg_color=null
2361- 18 e.Panel @ [120,220,25,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[120,220,25,200] bg_color=null
2362- 17 e.Panel @ [120,220,25,35] margin=[0,0,0,0] border=[1,1,1,1] padding=[0,0,4,4] bounds=[121,219,30,30] bg_color=#f6f5f4
2363+ 21 e.MenuBar @ [0,300,0,24] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,300,0,24] bg_color=null
2364+ 20 e.Panel @ [0,300,0,24] margin=[0,0,0,0] border=[0,0,0,1] padding=[0,0,0,0] bounds=[0,300,0,23] bg_color=#f6f5f4
2365+ 4 e.Menu @ [0,40,0,23] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,40,0,23] bg_color=null
2366+ 1 e.Panel @ [0,40,0,23] margin=[0,0,0,0] border=[0,0,3,3] padding=[8,8,2,2] bounds=[8,32,5,18] bg_color=null
2367+ 0 e.Label @ [8,32,5,18] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[8,32,5,18] bg_color=null
2368+ 3 e.Panel @ [0,100,23,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[0,100,23,200] bg_color=null
2369+ 2 e.Panel @ [0,100,23,33] margin=[0,0,0,0] border=[1,1,1,1] padding=[0,0,4,4] bounds=[1,99,28,28] bg_color=#f6f5f4
2370+ 9 e.Menu @ [40,80,0,23] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[40,80,0,23] bg_color=null
2371+ 6 e.Panel @ [40,80,0,23] margin=[0,0,0,0] border=[0,0,3,3] padding=[8,8,2,2] bounds=[48,72,5,18] bg_color=null
2372+ 5 e.Label @ [48,72,5,18] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[48,72,5,18] bg_color=null
2373+ 8 e.Panel @ [40,140,23,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[40,140,23,200] bg_color=null
2374+ 7 e.Panel @ [40,140,23,33] margin=[0,0,0,0] border=[1,1,1,1] padding=[0,0,4,4] bounds=[41,139,28,28] bg_color=#f6f5f4
2375+ 14 e.Menu @ [80,120,0,23] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[80,120,0,23] bg_color=null
2376+ 11 e.Panel @ [80,120,0,23] margin=[0,0,0,0] border=[0,0,3,3] padding=[8,8,2,2] bounds=[88,112,5,18] bg_color=null
2377+ 10 e.Label @ [88,112,5,18] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[88,112,5,18] bg_color=null
2378+ 13 e.Panel @ [80,180,23,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[80,180,23,200] bg_color=null
2379+ 12 e.Panel @ [80,180,23,33] margin=[0,0,0,0] border=[1,1,1,1] padding=[0,0,4,4] bounds=[81,179,28,28] bg_color=#f6f5f4
2380+ 19 e.Menu @ [120,160,0,23] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[120,160,0,23] bg_color=null
2381+ 16 e.Panel @ [120,160,0,23] margin=[0,0,0,0] border=[0,0,3,3] padding=[8,8,2,2] bounds=[128,152,5,18] bg_color=null
2382+ 15 e.Label @ [128,152,5,18] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[128,152,5,18] bg_color=null
2383+ 18 e.Panel @ [120,220,23,200] margin=[0,0,0,0] border=[0,0,0,0] padding=[0,0,0,0] bounds=[120,220,23,200] bg_color=null
2384+ 17 e.Panel @ [120,220,23,33] margin=[0,0,0,0] border=[1,1,1,1] padding=[0,0,4,4] bounds=[121,219,28,28] bg_color=#f6f5f4
testdata/diff-8480815a00f341a9058a26bf86f34368184615d6 created+33
...@@ -0,0 +1,33 @@
1:100644 100644 fef6239d0dfd8daafcfd62a17a137e3da9c2d8dd 9f1d9c9b30f503c1a0731f31c8b6892990b65746 M notes/potential apps.txt
2
3diff --git a/notes/potential apps.txt b/notes/potential apps.txt
4index fef6239..9f1d9c9 100644
5--- a/notes/potential apps.txt
6+++ b/notes/potential apps.txt
7@@ -116,10 +116,18 @@ system utilities
8
9 developer tools
10 code debugger
11+ program profiler
12+ alt for renderdoc https://renderdoc.org/
13+ strace gui
14+ valgrind gui
15+ alt for https://unicode.link/
16+ alt for https://www.wireshark.org/
17+
18 svg path explorer
19 font explorer
20 sqlite client
21 postgresql client
22+ font maker
23
24 file formats
25 .psd https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
26@@ -179,3 +187,7 @@ linux distro stuff
27 wm/bar (we like i3)
28 screensaver
29 lockscreen
30+
31+handle printing
32+
33+handle faxing
testdata/diff-9feb6b667c77c187f547deaf10cd1f04e92fe192 created+196
...@@ -0,0 +1,196 @@
1:100644 100644 d49352c9c20cea1ca91beb90979e8d4a1670a01c 5b519a35eb2ea8842573d82f13ab965ca8724b69 M README.md
2:100644 100644 b301658a8bea70ef336e7f426c284017b6f48465 9c975af044191b87fcd54769c29bf94a22f9123f M apps/Calculator/main.zig
3:100644 100644 f6990eea8b8db29a2ab4113d5d3d422454108ec9 90c6e9a60ff739b96f9ba78b65e2c6584cbaa2fe M apps/ImageViewer/main.zig
4:100644 100644 30850c59cddc295497c3939b6076bb09c8d36de7 cf55d583ce85b9e026f94f6eabcf1490a450c9fb M build.zig
5:100644 100644 731b5b15f743db7aa587fc5f8b8d98d16df106d8 c2d6942489853658391c971988c85317e0da07d2 M demos/7guis/1counter.zig
6:100644 100644 c6121d73b6adfe4e03889291ca323d0842187b22 da65c9ce2b7ba832d1b748e2ea0bbb6f363f94f4 M demos/logl/hello-window.zig
7:100644 100644 49c152d836ca8470b153957ba90a4376aa2bbbf0 13704daad693cc0054559ff70f5f3e242ecad273 M src/main.zig
8:100644 100644 55ee6c75e23a130d4cca5825925c92438e3c3865 8044e605443388554cecc57cf4fb2b5c4f41987e M zigmod.lock
9:100644 100644 1ce887547a4c312badf1429dc2afbfb2c5647776 e24cb55669911d7502b4e7e9add98995586834cf M zigmod.yml
10
11diff --git a/README.md b/README.md
12index d49352c..5b519a3 100644
13--- a/README.md
14+++ b/README.md
15@@ -21,7 +21,7 @@ Source-Available, All rights reserved. (c) 2023 Meghan Denny
16 Will likely be MPL-2.0 in the future.
17
18 ## Credits
19-- Zig 0.13.0
20+- Zig 0.14.1
21 - See [`zigmod.yml`](./zigmod.yml) and [`zigmod.lock`](./zigmod.lock)
22
23 ## Building
24diff --git a/apps/Calculator/main.zig b/apps/Calculator/main.zig
25index b301658..9c975af 100644
26--- a/apps/Calculator/main.zig
27+++ b/apps/Calculator/main.zig
28@@ -201,7 +201,7 @@ pub const SquareButton = struct {
29 fn onclickNum(comptime n: f64) mag.e.Button.OnClickFn {
30 const S = struct {
31 fn onclick(app: *App, state: ?*anyopaque) u32 {
32- const b = extras.ptrCast(BadTextbox, state.?);
33+ const b: *BadTextbox = @ptrCast(@alignCast(state.?));
34 if (b.active_operator) |_| {
35 b.active_num = .two;
36
37@@ -231,7 +231,7 @@ fn onclickNum(comptime n: f64) mag.e.Button.OnClickFn {
38 }
39
40 fn onclickDot(app: *App, state: ?*anyopaque) u32 {
41- const b = extras.ptrCast(BadTextbox, state.?);
42+ const b: *BadTextbox = @ptrCast(@alignCast(state.?));
43 b.dot = 0;
44 b.update(app);
45 return 1;
46@@ -240,7 +240,7 @@ fn onclickDot(app: *App, state: ?*anyopaque) u32 {
47 fn onclickOp(comptime o: BadTextbox.Op) mag.e.Button.OnClickFn {
48 const S = struct {
49 fn onclick(app: *App, state: ?*anyopaque) u32 {
50- const b = extras.ptrCast(BadTextbox, state.?);
51+ const b: *BadTextbox = @ptrCast(@alignCast(state.?));
52 toggleOpButton(app, b, o);
53 b.active_operator = o;
54 b.dot = null;
55@@ -281,7 +281,7 @@ fn toggleOpButtonOnly(app: *const App, op: BadTextbox.Op, to: enum { on, off })
56 }
57
58 fn onclickNeg(app: *App, state: ?*anyopaque) u32 {
59- const b = extras.ptrCast(BadTextbox, state.?);
60+ const b: *BadTextbox = @ptrCast(@alignCast(state.?));
61 switch (b.active_num) {
62 .one => b.num1 *= -1,
63 .two => b.num2 *= -1,
64@@ -291,7 +291,7 @@ fn onclickNeg(app: *App, state: ?*anyopaque) u32 {
65 }
66
67 fn onclickRoot2(app: *App, state: ?*anyopaque) u32 {
68- const b = extras.ptrCast(BadTextbox, state.?);
69+ const b: *BadTextbox = @ptrCast(@alignCast(state.?));
70 switch (b.active_num) {
71 .one => b.num1 = @sqrt(b.num1),
72 .two => b.num2 = @sqrt(b.num2),
73@@ -301,7 +301,7 @@ fn onclickRoot2(app: *App, state: ?*anyopaque) u32 {
74 }
75
76 fn onclickRoot3(app: *App, state: ?*anyopaque) u32 {
77- const b = extras.ptrCast(BadTextbox, state.?);
78+ const b: *BadTextbox = @ptrCast(@alignCast(state.?));
79 switch (b.active_num) {
80 .one => b.num1 = std.math.cbrt(b.num1),
81 .two => b.num2 = std.math.cbrt(b.num2),
82@@ -311,7 +311,7 @@ fn onclickRoot3(app: *App, state: ?*anyopaque) u32 {
83 }
84
85 fn onclickEql(app: *App, state: ?*anyopaque) u32 {
86- const b = extras.ptrCast(BadTextbox, state.?);
87+ const b: *BadTextbox = @ptrCast(@alignCast(state.?));
88 if (b.active_num == .one) {
89 return 0;
90 }
91@@ -338,7 +338,7 @@ fn onclickEql(app: *App, state: ?*anyopaque) u32 {
92 }
93
94 fn onclickClear(app: *App, state: ?*anyopaque) u32 {
95- const b = extras.ptrCast(BadTextbox, state.?);
96+ const b: *BadTextbox = @ptrCast(@alignCast(state.?));
97 b.active_num = .one;
98 b.num1 = 0;
99 b.num2 = 0;
100diff --git a/apps/ImageViewer/main.zig b/apps/ImageViewer/main.zig
101index f6990ee..90c6e9a 100644
102--- a/apps/ImageViewer/main.zig
103+++ b/apps/ImageViewer/main.zig
104@@ -16,7 +16,7 @@ pub fn main() !void {
105
106 extras.assertLog(std.os.argv.len == 2, "must pass a file to open as an argument", .{});
107 const file_name = std.mem.sliceTo(std.os.argv[1], 0);
108- extras.assertLog(file_name.len <= std.fs.MAX_PATH_BYTES, "file argument longer than MAX_PATH_BYTES", .{});
109+ extras.assertLog(file_name.len <= std.fs.max_path_bytes, "file argument longer than max_path_bytes", .{});
110
111 var app = try App.init(alloc, 300, 200, try std.fmt.allocPrintZ(alloc, "{s} — {s}", .{ file_name, build_options.name }));
112 defer app.deinit();
113diff --git a/build.zig b/build.zig
114index 30850c5..cf55d58 100644
115--- a/build.zig
116+++ b/build.zig
117@@ -3,6 +3,8 @@ const string = []const u8;
118 const deps = @import("./deps.zig");
119
120 pub fn build(b: *std.Build) void {
121+ b.reference_trace = 256;
122+
123 const target = b.standardTargetOptions(.{});
124 const mode = b.option(std.builtin.Mode, "mode", "") orelse .Debug;
125 const doall = b.option(bool, "all", "Build all apps, default only selected steps") orelse false;
126diff --git a/demos/7guis/1counter.zig b/demos/7guis/1counter.zig
127index 731b5b1..c2d6942 100644
128--- a/demos/7guis/1counter.zig
129+++ b/demos/7guis/1counter.zig
130@@ -72,7 +72,7 @@ pub const A = struct {
131
132 fn onclick(app: *const App, state: ?*anyopaque) u32 {
133 _ = app;
134- const a = extras.ptrCast(A, state.?);
135+ const a: *A = @ptrCast(@alignCast(state.?));
136 a.count += 1;
137 return 1;
138 }
139diff --git a/demos/logl/hello-window.zig b/demos/logl/hello-window.zig
140index c6121d7..da65c9c 100644
141--- a/demos/logl/hello-window.zig
142+++ b/demos/logl/hello-window.zig
143@@ -167,7 +167,7 @@ fn WhitePixel(dpy: *c.Display, scr: c_int) c_ulong {
144 return ScreenOfDisplay(dpy, scr).*.white_pixel;
145 }
146
147-// #define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root)
148+// #define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root)
149 fn RootWindow(dpy: *c.Display, scr: c_int) c.Window {
150 return ScreenOfDisplay(dpy, scr).*.root;
151 }
152diff --git a/src/main.zig b/src/main.zig
153index 49c152d..13704da 100644
154--- a/src/main.zig
155+++ b/src/main.zig
156@@ -860,7 +860,7 @@ pub fn App2() type {
157 }
158
159 pub fn get(self: *const Self, element: Element, comptime T: type) *T {
160- return extras.ptrCast(T, self.attr(element, .data));
161+ return @ptrCast(@alignCast(self.attr(element, .data)));
162 }
163
164 pub fn bounds(self: *const Self, element: Element) Rectangle {
165diff --git a/zigmod.lock b/zigmod.lock
166index 55ee6c7..8044e60 100644
167--- a/zigmod.lock
168+++ b/zigmod.lock
169@@ -1,8 +1,8 @@
170 2
171-git https://github.com/nektro/zig-color commit-b1df1f0d3561f2ff59ccddacd9b5c8efdaec2cf2
172-git https://github.com/nektro/zig-extras commit-100510135aa7be25b8b465ac32450678de009103
173-git https://github.com/nektro/zig-time commit-b9a93152af3ba73e5f681f73a67f0d676e2ad433
174-git https://github.com/nektro/zig-tracer commit-662774eedca41771f9ebd1ab45cfdc8e4319d4b4
175-git https://github.com/nektro/zig-xml commit-05aeff20237e0ea0556e4ac0f519a278e45b0cfb
176-git https://github.com/ziglibs/known-folders commit-aa24df42183ad415d10bc0a33e6238c437fc0f59
177+git https://github.com/nektro/zig-color commit-eaf93f7c177e4bd0d6a258e88998e442cd905a69
178+git https://github.com/nektro/zig-extras commit-cc8fb7cb1654df835a48473d67c001a44d2a6ea9
179+git https://github.com/nektro/zig-time commit-25165db8e626434ab6eae2cff64ba5e72e4fa062
180+git https://github.com/nektro/zig-tracer commit-cc75b7f652c7cd51cbfa6e3c7e8155cd153bb68b
181+git https://github.com/nektro/zig-xml commit-fc07c763a98fa7961b65b0a2b95a2d0fa061fafb
182+git https://github.com/ziglibs/known-folders commit-ab5cf5feb936fa3b72c95d3ad0c0c67791937ba1
183 git https://github.com/zigimg/zigimg commit-d9dbbe22b5f7b5f1f4772169ed93ffeed8e8124d
184diff --git a/zigmod.yml b/zigmod.yml
185index 1ce8875..e24cb55 100644
186--- a/zigmod.yml
187+++ b/zigmod.yml
188@@ -1,7 +1,7 @@
189 id: l862p8h05u3xp3w5ydtuhks9wtd961ktm8ivzhdkso0ylf1i
190 name: magnolia
191 main: src/main.zig
192-min_zig_version: 0.13.0
193+min_zig_version: 0.14.1
194
195 root_dependencies:
196 - src: git https://github.com/nektro/zig-extras
testdata/diff-c37d23f45ae6bd0db6b072180d7b84566c7dc8a2 created+5
...@@ -0,0 +1,5 @@
1:100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D crt.c
2
3diff --git a/crt.c b/crt.c
4deleted file mode 100644
5index e69de29bb2..0000000000
testdata/diff-d9165aacce3629d503f87cd2c3f612629127641b created+9
...@@ -0,0 +1,9 @@
1:100644 100755 220aaf12d9f74e95c2ed898a3046d23bc4792369 220aaf12d9f74e95c2ed898a3046d23bc4792369 M ci/aarch64-linux-debug.sh
2:100644 100755 69eed679e3c6041d9fff2d591bac7e2fa110debd 69eed679e3c6041d9fff2d591bac7e2fa110debd M ci/aarch64-linux-release.sh
3
4diff --git a/ci/aarch64-linux-debug.sh b/ci/aarch64-linux-debug.sh
5old mode 100644
6new mode 100755
7diff --git a/ci/aarch64-linux-release.sh b/ci/aarch64-linux-release.sh
8old mode 100644
9new mode 100755
testdata/diff-f2ccd4d1333aad1175550daf616b061388e1864f created+2160
...@@ -0,0 +1,2160 @@
1:000000 100644 0000000000000000000000000000000000000000 e237a22bbc214f03dfa0a99ecd3368eee2bbc22c A src/x11.Keysym.zig
2:100644 100644 9b8cbd2d7cee62cdec69e8febc75ff090cefdd8c a0a2cf47cd45489c5630a351b553aaeae5efad87 M src/x11.zig
3
4diff --git a/src/x11.Keysym.zig b/src/x11.Keysym.zig
5new file mode 100644
6index 0000000..e237a22
7--- /dev/null
8+++ b/src/x11.Keysym.zig
9@@ -0,0 +1,2141 @@
10+/// https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/blob/master/include/X11/keysymdef.h
11+// Last retrieved at f7176375692e47275e89c3064da4cd3a0f8dd1e7
12+pub const Keysym = enum(c_uint) {
13+ XK_VoidSymbol = 0xffffff, // Void symbol
14+
15+ XK_BackSpace = 0xff08, // U+0008 BACKSPACE
16+ XK_Tab = 0xff09, // U+0009 CHARACTER TABULATION
17+ XK_Linefeed = 0xff0a, // U+000A LINE FEED
18+ XK_Clear = 0xff0b, // U+000B LINE TABULATION
19+ XK_Return = 0xff0d, // U+000D CARRIAGE RETURN
20+ XK_Pause = 0xff13, // Pause, hold
21+ XK_Scroll_Lock = 0xff14,
22+ XK_Sys_Req = 0xff15,
23+ XK_Escape = 0xff1b, // U+001B ESCAPE
24+ XK_Delete = 0xffff, // U+007F DELETE
25+ XK_Multi_key = 0xff20, // Multi-key character compose
26+ XK_Codeinput = 0xff37,
27+ XK_SingleCandidate = 0xff3c,
28+ XK_MultipleCandidate = 0xff3d,
29+ XK_PreviousCandidate = 0xff3e,
30+ XK_Kanji = 0xff21, // Kanji, Kanji convert
31+ XK_Muhenkan = 0xff22, // Cancel Conversion
32+ XK_Henkan_Mode = 0xff23, // Start/Stop Conversion
33+ // XK_Henkan = 0xff23, // non-deprecated alias for Henkan_Mode
34+ XK_Romaji = 0xff24, // to Romaji
35+ XK_Hiragana = 0xff25, // to Hiragana
36+ XK_Katakana = 0xff26, // to Katakana
37+ XK_Hiragana_Katakana = 0xff27, // Hiragana/Katakana toggle
38+ XK_Zenkaku = 0xff28, // to Zenkaku
39+ XK_Hankaku = 0xff29, // to Hankaku
40+ XK_Zenkaku_Hankaku = 0xff2a, // Zenkaku/Hankaku toggle
41+ XK_Touroku = 0xff2b, // Add to Dictionary
42+ XK_Massyo = 0xff2c, // Delete from Dictionary
43+ XK_Kana_Lock = 0xff2d, // Kana Lock
44+ XK_Kana_Shift = 0xff2e, // Kana Shift
45+ XK_Eisu_Shift = 0xff2f, // Alphanumeric Shift
46+ XK_Eisu_toggle = 0xff30, // Alphanumeric toggle
47+ // XK_Kanji_Bangou = 0xff37, // Codeinput
48+ // XK_Zen_Koho = 0xff3d, // Multiple/All Candidate(s)
49+ // XK_Mae_Koho = 0xff3e, // Previous Candidate
50+ XK_Home = 0xff50,
51+ XK_Left = 0xff51, // Move left, left arrow
52+ XK_Up = 0xff52, // Move up, up arrow
53+ XK_Right = 0xff53, // Move right, right arrow
54+ XK_Down = 0xff54, // Move down, down arrow
55+ XK_Prior = 0xff55, // Prior, previous
56+ // XK_Page_Up = 0xff55, // deprecated alias for Prior
57+ XK_Next = 0xff56, // Next
58+ // XK_Page_Down = 0xff56, // deprecated alias for Next
59+ XK_End = 0xff57, // EOL
60+ XK_Begin = 0xff58, // BOL
61+ XK_Select = 0xff60, // Select, mark
62+ XK_Print = 0xff61,
63+ XK_Execute = 0xff62, // Execute, run, do
64+ XK_Insert = 0xff63, // Insert, insert here
65+ XK_Undo = 0xff65,
66+ XK_Redo = 0xff66, // Redo, again
67+ XK_Menu = 0xff67,
68+ XK_Find = 0xff68, // Find, search
69+ XK_Cancel = 0xff69, // Cancel, stop, abort, exit
70+ XK_Help = 0xff6a, // Help
71+ XK_Break = 0xff6b,
72+ XK_Mode_switch = 0xff7e, // Character set switch
73+ // XK_script_switch = 0xff7e, // non-deprecated alias for Mode_switch
74+ XK_Num_Lock = 0xff7f,
75+ XK_KP_Space = 0xff80, // <U+0020 SPACE>
76+ XK_KP_Tab = 0xff89, // <U+0009 CHARACTER TABULATION>
77+ XK_KP_Enter = 0xff8d, // <U+000D CARRIAGE RETURN>
78+ XK_KP_F1 = 0xff91, // PF1, KP_A, ...
79+ XK_KP_F2 = 0xff92,
80+ XK_KP_F3 = 0xff93,
81+ XK_KP_F4 = 0xff94,
82+ XK_KP_Home = 0xff95,
83+ XK_KP_Left = 0xff96,
84+ XK_KP_Up = 0xff97,
85+ XK_KP_Right = 0xff98,
86+ XK_KP_Down = 0xff99,
87+ XK_KP_Prior = 0xff9a,
88+ // XK_KP_Page_Up = 0xff9a, // deprecated alias for KP_Prior
89+ XK_KP_Next = 0xff9b,
90+ // XK_KP_Page_Down = 0xff9b, // deprecated alias for KP_Next
91+ XK_KP_End = 0xff9c,
92+ XK_KP_Begin = 0xff9d,
93+ XK_KP_Insert = 0xff9e,
94+ XK_KP_Delete = 0xff9f,
95+ XK_KP_Equal = 0xffbd, // <U+003D EQUALS SIGN>
96+ XK_KP_Multiply = 0xffaa, // <U+002A ASTERISK>
97+ XK_KP_Add = 0xffab, // <U+002B PLUS SIGN>
98+ XK_KP_Separator = 0xffac, // <U+002C COMMA>
99+ XK_KP_Subtract = 0xffad, // <U+002D HYPHEN-MINUS>
100+ XK_KP_Decimal = 0xffae, // <U+002E FULL STOP>
101+ XK_KP_Divide = 0xffaf, // <U+002F SOLIDUS>
102+ XK_KP_0 = 0xffb0, // <U+0030 DIGIT ZERO>
103+ XK_KP_1 = 0xffb1, // <U+0031 DIGIT ONE>
104+ XK_KP_2 = 0xffb2, // <U+0032 DIGIT TWO>
105+ XK_KP_3 = 0xffb3, // <U+0033 DIGIT THREE>
106+ XK_KP_4 = 0xffb4, // <U+0034 DIGIT FOUR>
107+ XK_KP_5 = 0xffb5, // <U+0035 DIGIT FIVE>
108+ XK_KP_6 = 0xffb6, // <U+0036 DIGIT SIX>
109+ XK_KP_7 = 0xffb7, // <U+0037 DIGIT SEVEN>
110+ XK_KP_8 = 0xffb8, // <U+0038 DIGIT EIGHT>
111+ XK_KP_9 = 0xffb9, // <U+0039 DIGIT NINE>
112+ XK_F1 = 0xffbe,
113+ XK_F2 = 0xffbf,
114+ XK_F3 = 0xffc0,
115+ XK_F4 = 0xffc1,
116+ XK_F5 = 0xffc2,
117+ XK_F6 = 0xffc3,
118+ XK_F7 = 0xffc4,
119+ XK_F8 = 0xffc5,
120+ XK_F9 = 0xffc6,
121+ XK_F10 = 0xffc7,
122+ XK_F11 = 0xffc8,
123+ // XK_L1 = 0xffc8, // deprecated alias for F11
124+ XK_F12 = 0xffc9,
125+ // XK_L2 = 0xffc9, // deprecated alias for F12
126+ XK_F13 = 0xffca,
127+ // XK_L3 = 0xffca, // deprecated alias for F13
128+ XK_F14 = 0xffcb,
129+ // XK_L4 = 0xffcb, // deprecated alias for F14
130+ XK_F15 = 0xffcc,
131+ // XK_L5 = 0xffcc, // deprecated alias for F15
132+ XK_F16 = 0xffcd,
133+ // XK_L6 = 0xffcd, // deprecated alias for F16
134+ XK_F17 = 0xffce,
135+ // XK_L7 = 0xffce, // deprecated alias for F17
136+ XK_F18 = 0xffcf,
137+ // XK_L8 = 0xffcf, // deprecated alias for F18
138+ XK_F19 = 0xffd0,
139+ // XK_L9 = 0xffd0, // deprecated alias for F19
140+ XK_F20 = 0xffd1,
141+ // XK_L10 = 0xffd1, // deprecated alias for F20
142+ XK_F21 = 0xffd2,
143+ // XK_R1 = 0xffd2, // deprecated alias for F21
144+ XK_F22 = 0xffd3,
145+ // XK_R2 = 0xffd3, // deprecated alias for F22
146+ XK_F23 = 0xffd4,
147+ // XK_R3 = 0xffd4, // deprecated alias for F23
148+ XK_F24 = 0xffd5,
149+ // XK_R4 = 0xffd5, // deprecated alias for F24
150+ XK_F25 = 0xffd6,
151+ // XK_R5 = 0xffd6, // deprecated alias for F25
152+ XK_F26 = 0xffd7,
153+ // XK_R6 = 0xffd7, // deprecated alias for F26
154+ XK_F27 = 0xffd8,
155+ // XK_R7 = 0xffd8, // deprecated alias for F27
156+ XK_F28 = 0xffd9,
157+ // XK_R8 = 0xffd9, // deprecated alias for F28
158+ XK_F29 = 0xffda,
159+ // XK_R9 = 0xffda, // deprecated alias for F29
160+ XK_F30 = 0xffdb,
161+ // XK_R10 = 0xffdb, // deprecated alias for F30
162+ XK_F31 = 0xffdc,
163+ // XK_R11 = 0xffdc, // deprecated alias for F31
164+ XK_F32 = 0xffdd,
165+ // XK_R12 = 0xffdd, // deprecated alias for F32
166+ XK_F33 = 0xffde,
167+ // XK_R13 = 0xffde, // deprecated alias for F33
168+ XK_F34 = 0xffdf,
169+ // XK_R14 = 0xffdf, // deprecated alias for F34
170+ XK_F35 = 0xffe0,
171+ // XK_R15 = 0xffe0, // deprecated alias for F35
172+ XK_Shift_L = 0xffe1, // Left shift
173+ XK_Shift_R = 0xffe2, // Right shift
174+ XK_Control_L = 0xffe3, // Left control
175+ XK_Control_R = 0xffe4, // Right control
176+ XK_Caps_Lock = 0xffe5, // Caps lock
177+ XK_Shift_Lock = 0xffe6, // Shift lock
178+ XK_Meta_L = 0xffe7, // Left meta
179+ XK_Meta_R = 0xffe8, // Right meta
180+ XK_Alt_L = 0xffe9, // Left alt
181+ XK_Alt_R = 0xffea, // Right alt
182+ XK_Super_L = 0xffeb, // Left super
183+ XK_Super_R = 0xffec, // Right super
184+ XK_Hyper_L = 0xffed, // Left hyper
185+ XK_Hyper_R = 0xffee, // Right hyper
186+
187+ XK_ISO_Lock = 0xfe01,
188+ XK_ISO_Level2_Latch = 0xfe02,
189+ XK_ISO_Level3_Shift = 0xfe03,
190+ XK_ISO_Level3_Latch = 0xfe04,
191+ XK_ISO_Level3_Lock = 0xfe05,
192+ XK_ISO_Level5_Shift = 0xfe11,
193+ XK_ISO_Level5_Latch = 0xfe12,
194+ XK_ISO_Level5_Lock = 0xfe13,
195+ // XK_ISO_Group_Shift = 0xff7e, // non-deprecated alias for Mode_switch
196+ XK_ISO_Group_Latch = 0xfe06,
197+ XK_ISO_Group_Lock = 0xfe07,
198+ XK_ISO_Next_Group = 0xfe08,
199+ XK_ISO_Next_Group_Lock = 0xfe09,
200+ XK_ISO_Prev_Group = 0xfe0a,
201+ XK_ISO_Prev_Group_Lock = 0xfe0b,
202+ XK_ISO_First_Group = 0xfe0c,
203+ XK_ISO_First_Group_Lock = 0xfe0d,
204+ XK_ISO_Last_Group = 0xfe0e,
205+ XK_ISO_Last_Group_Lock = 0xfe0f,
206+ XK_ISO_Left_Tab = 0xfe20,
207+ XK_ISO_Move_Line_Up = 0xfe21,
208+ XK_ISO_Move_Line_Down = 0xfe22,
209+ XK_ISO_Partial_Line_Up = 0xfe23,
210+ XK_ISO_Partial_Line_Down = 0xfe24,
211+ XK_ISO_Partial_Space_Left = 0xfe25,
212+ XK_ISO_Partial_Space_Right = 0xfe26,
213+ XK_ISO_Set_Margin_Left = 0xfe27,
214+ XK_ISO_Set_Margin_Right = 0xfe28,
215+ XK_ISO_Release_Margin_Left = 0xfe29,
216+ XK_ISO_Release_Margin_Right = 0xfe2a,
217+ XK_ISO_Release_Both_Margins = 0xfe2b,
218+ XK_ISO_Fast_Cursor_Left = 0xfe2c,
219+ XK_ISO_Fast_Cursor_Right = 0xfe2d,
220+ XK_ISO_Fast_Cursor_Up = 0xfe2e,
221+ XK_ISO_Fast_Cursor_Down = 0xfe2f,
222+ XK_ISO_Continuous_Underline = 0xfe30,
223+ XK_ISO_Discontinuous_Underline = 0xfe31,
224+ XK_ISO_Emphasize = 0xfe32,
225+ XK_ISO_Center_Object = 0xfe33,
226+ XK_ISO_Enter = 0xfe34,
227+ XK_dead_grave = 0xfe50,
228+ XK_dead_acute = 0xfe51,
229+ XK_dead_circumflex = 0xfe52,
230+ XK_dead_tilde = 0xfe53,
231+ // XK_dead_perispomeni = 0xfe53, // non-deprecated alias for dead_tilde
232+ XK_dead_macron = 0xfe54,
233+ XK_dead_breve = 0xfe55,
234+ XK_dead_abovedot = 0xfe56,
235+ XK_dead_diaeresis = 0xfe57,
236+ XK_dead_abovering = 0xfe58,
237+ XK_dead_doubleacute = 0xfe59,
238+ XK_dead_caron = 0xfe5a,
239+ XK_dead_cedilla = 0xfe5b,
240+ XK_dead_ogonek = 0xfe5c,
241+ XK_dead_iota = 0xfe5d,
242+ XK_dead_voiced_sound = 0xfe5e,
243+ XK_dead_semivoiced_sound = 0xfe5f,
244+ XK_dead_belowdot = 0xfe60,
245+ XK_dead_hook = 0xfe61,
246+ XK_dead_horn = 0xfe62,
247+ XK_dead_stroke = 0xfe63,
248+ XK_dead_abovecomma = 0xfe64,
249+ // XK_dead_psili = 0xfe64, // non-deprecated alias for dead_abovecomma
250+ XK_dead_abovereversedcomma = 0xfe65,
251+ // XK_dead_dasia = 0xfe65, // non-deprecated alias for dead_abovereversedcomma
252+ XK_dead_doublegrave = 0xfe66,
253+ XK_dead_belowring = 0xfe67,
254+ XK_dead_belowmacron = 0xfe68,
255+ XK_dead_belowcircumflex = 0xfe69,
256+ XK_dead_belowtilde = 0xfe6a,
257+ XK_dead_belowbreve = 0xfe6b,
258+ XK_dead_belowdiaeresis = 0xfe6c,
259+ XK_dead_invertedbreve = 0xfe6d,
260+ XK_dead_belowcomma = 0xfe6e,
261+ XK_dead_currency = 0xfe6f,
262+ XK_dead_lowline = 0xfe90,
263+ XK_dead_aboveverticalline = 0xfe91,
264+ XK_dead_belowverticalline = 0xfe92,
265+ XK_dead_longsolidusoverlay = 0xfe93,
266+ XK_dead_a = 0xfe80,
267+ XK_dead_A = 0xfe81,
268+ XK_dead_e = 0xfe82,
269+ XK_dead_E = 0xfe83,
270+ XK_dead_i = 0xfe84,
271+ XK_dead_I = 0xfe85,
272+ XK_dead_o = 0xfe86,
273+ XK_dead_O = 0xfe87,
274+ XK_dead_u = 0xfe88,
275+ XK_dead_U = 0xfe89,
276+ // XK_dead_small_schwa = 0xfe8a, // deprecated alias for dead_schwa
277+ XK_dead_schwa = 0xfe8a,
278+ // XK_dead_capital_schwa = 0xfe8b, // deprecated alias for dead_SCHWA
279+ XK_dead_SCHWA = 0xfe8b,
280+ XK_dead_greek = 0xfe8c,
281+ XK_dead_hamza = 0xfe8d,
282+ XK_First_Virtual_Screen = 0xfed0,
283+ XK_Prev_Virtual_Screen = 0xfed1,
284+ XK_Next_Virtual_Screen = 0xfed2,
285+ XK_Last_Virtual_Screen = 0xfed4,
286+ XK_Terminate_Server = 0xfed5,
287+ XK_AccessX_Enable = 0xfe70,
288+ XK_AccessX_Feedback_Enable = 0xfe71,
289+ XK_RepeatKeys_Enable = 0xfe72,
290+ XK_SlowKeys_Enable = 0xfe73,
291+ XK_BounceKeys_Enable = 0xfe74,
292+ XK_StickyKeys_Enable = 0xfe75,
293+ XK_MouseKeys_Enable = 0xfe76,
294+ XK_MouseKeys_Accel_Enable = 0xfe77,
295+ XK_Overlay1_Enable = 0xfe78,
296+ XK_Overlay2_Enable = 0xfe79,
297+ XK_AudibleBell_Enable = 0xfe7a,
298+ XK_Pointer_Left = 0xfee0,
299+ XK_Pointer_Right = 0xfee1,
300+ XK_Pointer_Up = 0xfee2,
301+ XK_Pointer_Down = 0xfee3,
302+ XK_Pointer_UpLeft = 0xfee4,
303+ XK_Pointer_UpRight = 0xfee5,
304+ XK_Pointer_DownLeft = 0xfee6,
305+ XK_Pointer_DownRight = 0xfee7,
306+ XK_Pointer_Button_Dflt = 0xfee8,
307+ XK_Pointer_Button1 = 0xfee9,
308+ XK_Pointer_Button2 = 0xfeea,
309+ XK_Pointer_Button3 = 0xfeeb,
310+ XK_Pointer_Button4 = 0xfeec,
311+ XK_Pointer_Button5 = 0xfeed,
312+ XK_Pointer_DblClick_Dflt = 0xfeee,
313+ XK_Pointer_DblClick1 = 0xfeef,
314+ XK_Pointer_DblClick2 = 0xfef0,
315+ XK_Pointer_DblClick3 = 0xfef1,
316+ XK_Pointer_DblClick4 = 0xfef2,
317+ XK_Pointer_DblClick5 = 0xfef3,
318+ XK_Pointer_Drag_Dflt = 0xfef4,
319+ XK_Pointer_Drag1 = 0xfef5,
320+ XK_Pointer_Drag2 = 0xfef6,
321+ XK_Pointer_Drag3 = 0xfef7,
322+ XK_Pointer_Drag4 = 0xfef8,
323+ XK_Pointer_Drag5 = 0xfefd,
324+ XK_Pointer_EnableKeys = 0xfef9,
325+ XK_Pointer_Accelerate = 0xfefa,
326+ XK_Pointer_DfltBtnNext = 0xfefb,
327+ XK_Pointer_DfltBtnPrev = 0xfefc,
328+ XK_ch = 0xfea0,
329+ XK_Ch = 0xfea1,
330+ XK_CH = 0xfea2,
331+ XK_c_h = 0xfea3,
332+ XK_C_h = 0xfea4,
333+ XK_C_H = 0xfea5,
334+
335+ XK_3270_Duplicate = 0xfd01,
336+ XK_3270_FieldMark = 0xfd02,
337+ XK_3270_Right2 = 0xfd03,
338+ XK_3270_Left2 = 0xfd04,
339+ XK_3270_BackTab = 0xfd05,
340+ XK_3270_EraseEOF = 0xfd06,
341+ XK_3270_EraseInput = 0xfd07,
342+ XK_3270_Reset = 0xfd08,
343+ XK_3270_Quit = 0xfd09,
344+ XK_3270_PA1 = 0xfd0a,
345+ XK_3270_PA2 = 0xfd0b,
346+ XK_3270_PA3 = 0xfd0c,
347+ XK_3270_Test = 0xfd0d,
348+ XK_3270_Attn = 0xfd0e,
349+ XK_3270_CursorBlink = 0xfd0f,
350+ XK_3270_AltCursor = 0xfd10,
351+ XK_3270_KeyClick = 0xfd11,
352+ XK_3270_Jump = 0xfd12,
353+ XK_3270_Ident = 0xfd13,
354+ XK_3270_Rule = 0xfd14,
355+ XK_3270_Copy = 0xfd15,
356+ XK_3270_Play = 0xfd16,
357+ XK_3270_Setup = 0xfd17,
358+ XK_3270_Record = 0xfd18,
359+ XK_3270_ChangeScreen = 0xfd19,
360+ XK_3270_DeleteWord = 0xfd1a,
361+ XK_3270_ExSelect = 0xfd1b,
362+ XK_3270_CursorSelect = 0xfd1c,
363+ XK_3270_PrintScreen = 0xfd1d,
364+ XK_3270_Enter = 0xfd1e,
365+
366+ XK_space = 0x0020, // U+0020 SPACE
367+ XK_exclam = 0x0021, // U+0021 EXCLAMATION MARK
368+ XK_quotedbl = 0x0022, // U+0022 QUOTATION MARK
369+ XK_numbersign = 0x0023, // U+0023 NUMBER SIGN
370+ XK_dollar = 0x0024, // U+0024 DOLLAR SIGN
371+ XK_percent = 0x0025, // U+0025 PERCENT SIGN
372+ XK_ampersand = 0x0026, // U+0026 AMPERSAND
373+ XK_apostrophe = 0x0027, // U+0027 APOSTROPHE
374+ // XK_quoteright = 0x0027, // deprecated
375+ XK_parenleft = 0x0028, // U+0028 LEFT PARENTHESIS
376+ XK_parenright = 0x0029, // U+0029 RIGHT PARENTHESIS
377+ XK_asterisk = 0x002a, // U+002A ASTERISK
378+ XK_plus = 0x002b, // U+002B PLUS SIGN
379+ XK_comma = 0x002c, // U+002C COMMA
380+ XK_minus = 0x002d, // U+002D HYPHEN-MINUS
381+ XK_period = 0x002e, // U+002E FULL STOP
382+ XK_slash = 0x002f, // U+002F SOLIDUS
383+ XK_0 = 0x0030, // U+0030 DIGIT ZERO
384+ XK_1 = 0x0031, // U+0031 DIGIT ONE
385+ XK_2 = 0x0032, // U+0032 DIGIT TWO
386+ XK_3 = 0x0033, // U+0033 DIGIT THREE
387+ XK_4 = 0x0034, // U+0034 DIGIT FOUR
388+ XK_5 = 0x0035, // U+0035 DIGIT FIVE
389+ XK_6 = 0x0036, // U+0036 DIGIT SIX
390+ XK_7 = 0x0037, // U+0037 DIGIT SEVEN
391+ XK_8 = 0x0038, // U+0038 DIGIT EIGHT
392+ XK_9 = 0x0039, // U+0039 DIGIT NINE
393+ XK_colon = 0x003a, // U+003A COLON
394+ XK_semicolon = 0x003b, // U+003B SEMICOLON
395+ XK_less = 0x003c, // U+003C LESS-THAN SIGN
396+ XK_equal = 0x003d, // U+003D EQUALS SIGN
397+ XK_greater = 0x003e, // U+003E GREATER-THAN SIGN
398+ XK_question = 0x003f, // U+003F QUESTION MARK
399+ XK_at = 0x0040, // U+0040 COMMERCIAL AT
400+ XK_A = 0x0041, // U+0041 LATIN CAPITAL LETTER A
401+ XK_B = 0x0042, // U+0042 LATIN CAPITAL LETTER B
402+ XK_C = 0x0043, // U+0043 LATIN CAPITAL LETTER C
403+ XK_D = 0x0044, // U+0044 LATIN CAPITAL LETTER D
404+ XK_E = 0x0045, // U+0045 LATIN CAPITAL LETTER E
405+ XK_F = 0x0046, // U+0046 LATIN CAPITAL LETTER F
406+ XK_G = 0x0047, // U+0047 LATIN CAPITAL LETTER G
407+ XK_H = 0x0048, // U+0048 LATIN CAPITAL LETTER H
408+ XK_I = 0x0049, // U+0049 LATIN CAPITAL LETTER I
409+ XK_J = 0x004a, // U+004A LATIN CAPITAL LETTER J
410+ XK_K = 0x004b, // U+004B LATIN CAPITAL LETTER K
411+ XK_L = 0x004c, // U+004C LATIN CAPITAL LETTER L
412+ XK_M = 0x004d, // U+004D LATIN CAPITAL LETTER M
413+ XK_N = 0x004e, // U+004E LATIN CAPITAL LETTER N
414+ XK_O = 0x004f, // U+004F LATIN CAPITAL LETTER O
415+ XK_P = 0x0050, // U+0050 LATIN CAPITAL LETTER P
416+ XK_Q = 0x0051, // U+0051 LATIN CAPITAL LETTER Q
417+ XK_R = 0x0052, // U+0052 LATIN CAPITAL LETTER R
418+ XK_S = 0x0053, // U+0053 LATIN CAPITAL LETTER S
419+ XK_T = 0x0054, // U+0054 LATIN CAPITAL LETTER T
420+ XK_U = 0x0055, // U+0055 LATIN CAPITAL LETTER U
421+ XK_V = 0x0056, // U+0056 LATIN CAPITAL LETTER V
422+ XK_W = 0x0057, // U+0057 LATIN CAPITAL LETTER W
423+ XK_X = 0x0058, // U+0058 LATIN CAPITAL LETTER X
424+ XK_Y = 0x0059, // U+0059 LATIN CAPITAL LETTER Y
425+ XK_Z = 0x005a, // U+005A LATIN CAPITAL LETTER Z
426+ XK_bracketleft = 0x005b, // U+005B LEFT SQUARE BRACKET
427+ XK_backslash = 0x005c, // U+005C REVERSE SOLIDUS
428+ XK_bracketright = 0x005d, // U+005D RIGHT SQUARE BRACKET
429+ XK_asciicircum = 0x005e, // U+005E CIRCUMFLEX ACCENT
430+ XK_underscore = 0x005f, // U+005F LOW LINE
431+ XK_grave = 0x0060, // U+0060 GRAVE ACCENT
432+ // XK_quoteleft = 0x0060, // deprecated
433+ XK_a = 0x0061, // U+0061 LATIN SMALL LETTER A
434+ XK_b = 0x0062, // U+0062 LATIN SMALL LETTER B
435+ XK_c = 0x0063, // U+0063 LATIN SMALL LETTER C
436+ XK_d = 0x0064, // U+0064 LATIN SMALL LETTER D
437+ XK_e = 0x0065, // U+0065 LATIN SMALL LETTER E
438+ XK_f = 0x0066, // U+0066 LATIN SMALL LETTER F
439+ XK_g = 0x0067, // U+0067 LATIN SMALL LETTER G
440+ XK_h = 0x0068, // U+0068 LATIN SMALL LETTER H
441+ XK_i = 0x0069, // U+0069 LATIN SMALL LETTER I
442+ XK_j = 0x006a, // U+006A LATIN SMALL LETTER J
443+ XK_k = 0x006b, // U+006B LATIN SMALL LETTER K
444+ XK_l = 0x006c, // U+006C LATIN SMALL LETTER L
445+ XK_m = 0x006d, // U+006D LATIN SMALL LETTER M
446+ XK_n = 0x006e, // U+006E LATIN SMALL LETTER N
447+ XK_o = 0x006f, // U+006F LATIN SMALL LETTER O
448+ XK_p = 0x0070, // U+0070 LATIN SMALL LETTER P
449+ XK_q = 0x0071, // U+0071 LATIN SMALL LETTER Q
450+ XK_r = 0x0072, // U+0072 LATIN SMALL LETTER R
451+ XK_s = 0x0073, // U+0073 LATIN SMALL LETTER S
452+ XK_t = 0x0074, // U+0074 LATIN SMALL LETTER T
453+ XK_u = 0x0075, // U+0075 LATIN SMALL LETTER U
454+ XK_v = 0x0076, // U+0076 LATIN SMALL LETTER V
455+ XK_w = 0x0077, // U+0077 LATIN SMALL LETTER W
456+ XK_x = 0x0078, // U+0078 LATIN SMALL LETTER X
457+ XK_y = 0x0079, // U+0079 LATIN SMALL LETTER Y
458+ XK_z = 0x007a, // U+007A LATIN SMALL LETTER Z
459+ XK_braceleft = 0x007b, // U+007B LEFT CURLY BRACKET
460+ XK_bar = 0x007c, // U+007C VERTICAL LINE
461+ XK_braceright = 0x007d, // U+007D RIGHT CURLY BRACKET
462+ XK_asciitilde = 0x007e, // U+007E TILDE
463+ XK_nobreakspace = 0x00a0, // U+00A0 NO-BREAK SPACE
464+ XK_exclamdown = 0x00a1, // U+00A1 INVERTED EXCLAMATION MARK
465+ XK_cent = 0x00a2, // U+00A2 CENT SIGN
466+ XK_sterling = 0x00a3, // U+00A3 POUND SIGN
467+ XK_currency = 0x00a4, // U+00A4 CURRENCY SIGN
468+ XK_yen = 0x00a5, // U+00A5 YEN SIGN
469+ XK_brokenbar = 0x00a6, // U+00A6 BROKEN BAR
470+ XK_section = 0x00a7, // U+00A7 SECTION SIGN
471+ XK_diaeresis = 0x00a8, // U+00A8 DIAERESIS
472+ XK_copyright = 0x00a9, // U+00A9 COPYRIGHT SIGN
473+ XK_ordfeminine = 0x00aa, // U+00AA FEMININE ORDINAL INDICATOR
474+ // XK_guillemotleft = 0x00ab, // deprecated alias for guillemetleft (misspelling)
475+ XK_guillemetleft = 0x00ab, // U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
476+ XK_notsign = 0x00ac, // U+00AC NOT SIGN
477+ XK_hyphen = 0x00ad, // U+00AD SOFT HYPHEN
478+ XK_registered = 0x00ae, // U+00AE REGISTERED SIGN
479+ XK_macron = 0x00af, // U+00AF MACRON
480+ XK_degree = 0x00b0, // U+00B0 DEGREE SIGN
481+ XK_plusminus = 0x00b1, // U+00B1 PLUS-MINUS SIGN
482+ XK_twosuperior = 0x00b2, // U+00B2 SUPERSCRIPT TWO
483+ XK_threesuperior = 0x00b3, // U+00B3 SUPERSCRIPT THREE
484+ XK_acute = 0x00b4, // U+00B4 ACUTE ACCENT
485+ XK_mu = 0x00b5, // U+00B5 MICRO SIGN
486+ XK_paragraph = 0x00b6, // U+00B6 PILCROW SIGN
487+ XK_periodcentered = 0x00b7, // U+00B7 MIDDLE DOT
488+ XK_cedilla = 0x00b8, // U+00B8 CEDILLA
489+ XK_onesuperior = 0x00b9, // U+00B9 SUPERSCRIPT ONE
490+ // XK_masculine = 0x00ba, // deprecated alias for ordmasculine (inconsistent name)
491+ XK_ordmasculine = 0x00ba, // U+00BA MASCULINE ORDINAL INDICATOR
492+ // XK_guillemotright = 0x00bb, // deprecated alias for guillemetright (misspelling)
493+ XK_guillemetright = 0x00bb, // U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
494+ XK_onequarter = 0x00bc, // U+00BC VULGAR FRACTION ONE QUARTER
495+ XK_onehalf = 0x00bd, // U+00BD VULGAR FRACTION ONE HALF
496+ XK_threequarters = 0x00be, // U+00BE VULGAR FRACTION THREE QUARTERS
497+ XK_questiondown = 0x00bf, // U+00BF INVERTED QUESTION MARK
498+ XK_Agrave = 0x00c0, // U+00C0 LATIN CAPITAL LETTER A WITH GRAVE
499+ XK_Aacute = 0x00c1, // U+00C1 LATIN CAPITAL LETTER A WITH ACUTE
500+ XK_Acircumflex = 0x00c2, // U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
501+ XK_Atilde = 0x00c3, // U+00C3 LATIN CAPITAL LETTER A WITH TILDE
502+ XK_Adiaeresis = 0x00c4, // U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS
503+ XK_Aring = 0x00c5, // U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE
504+ XK_AE = 0x00c6, // U+00C6 LATIN CAPITAL LETTER AE
505+ XK_Ccedilla = 0x00c7, // U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA
506+ XK_Egrave = 0x00c8, // U+00C8 LATIN CAPITAL LETTER E WITH GRAVE
507+ XK_Eacute = 0x00c9, // U+00C9 LATIN CAPITAL LETTER E WITH ACUTE
508+ XK_Ecircumflex = 0x00ca, // U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX
509+ XK_Ediaeresis = 0x00cb, // U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS
510+ XK_Igrave = 0x00cc, // U+00CC LATIN CAPITAL LETTER I WITH GRAVE
511+ XK_Iacute = 0x00cd, // U+00CD LATIN CAPITAL LETTER I WITH ACUTE
512+ XK_Icircumflex = 0x00ce, // U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX
513+ XK_Idiaeresis = 0x00cf, // U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS
514+ XK_ETH = 0x00d0, // U+00D0 LATIN CAPITAL LETTER ETH
515+ // XK_Eth = 0x00d0, // deprecated
516+ XK_Ntilde = 0x00d1, // U+00D1 LATIN CAPITAL LETTER N WITH TILDE
517+ XK_Ograve = 0x00d2, // U+00D2 LATIN CAPITAL LETTER O WITH GRAVE
518+ XK_Oacute = 0x00d3, // U+00D3 LATIN CAPITAL LETTER O WITH ACUTE
519+ XK_Ocircumflex = 0x00d4, // U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
520+ XK_Otilde = 0x00d5, // U+00D5 LATIN CAPITAL LETTER O WITH TILDE
521+ XK_Odiaeresis = 0x00d6, // U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
522+ XK_multiply = 0x00d7, // U+00D7 MULTIPLICATION SIGN
523+ XK_Oslash = 0x00d8, // U+00D8 LATIN CAPITAL LETTER O WITH STROKE
524+ // XK_Ooblique = 0x00d8, // deprecated alias for Oslash
525+ XK_Ugrave = 0x00d9, // U+00D9 LATIN CAPITAL LETTER U WITH GRAVE
526+ XK_Uacute = 0x00da, // U+00DA LATIN CAPITAL LETTER U WITH ACUTE
527+ XK_Ucircumflex = 0x00db, // U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX
528+ XK_Udiaeresis = 0x00dc, // U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS
529+ XK_Yacute = 0x00dd, // U+00DD LATIN CAPITAL LETTER Y WITH ACUTE
530+ XK_THORN = 0x00de, // U+00DE LATIN CAPITAL LETTER THORN
531+ // XK_Thorn = 0x00de, // deprecated
532+ XK_ssharp = 0x00df, // U+00DF LATIN SMALL LETTER SHARP S
533+ XK_agrave = 0x00e0, // U+00E0 LATIN SMALL LETTER A WITH GRAVE
534+ XK_aacute = 0x00e1, // U+00E1 LATIN SMALL LETTER A WITH ACUTE
535+ XK_acircumflex = 0x00e2, // U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX
536+ XK_atilde = 0x00e3, // U+00E3 LATIN SMALL LETTER A WITH TILDE
537+ XK_adiaeresis = 0x00e4, // U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
538+ XK_aring = 0x00e5, // U+00E5 LATIN SMALL LETTER A WITH RING ABOVE
539+ XK_ae = 0x00e6, // U+00E6 LATIN SMALL LETTER AE
540+ XK_ccedilla = 0x00e7, // U+00E7 LATIN SMALL LETTER C WITH CEDILLA
541+ XK_egrave = 0x00e8, // U+00E8 LATIN SMALL LETTER E WITH GRAVE
542+ XK_eacute = 0x00e9, // U+00E9 LATIN SMALL LETTER E WITH ACUTE
543+ XK_ecircumflex = 0x00ea, // U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX
544+ XK_ediaeresis = 0x00eb, // U+00EB LATIN SMALL LETTER E WITH DIAERESIS
545+ XK_igrave = 0x00ec, // U+00EC LATIN SMALL LETTER I WITH GRAVE
546+ XK_iacute = 0x00ed, // U+00ED LATIN SMALL LETTER I WITH ACUTE
547+ XK_icircumflex = 0x00ee, // U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX
548+ XK_idiaeresis = 0x00ef, // U+00EF LATIN SMALL LETTER I WITH DIAERESIS
549+ XK_eth = 0x00f0, // U+00F0 LATIN SMALL LETTER ETH
550+ XK_ntilde = 0x00f1, // U+00F1 LATIN SMALL LETTER N WITH TILDE
551+ XK_ograve = 0x00f2, // U+00F2 LATIN SMALL LETTER O WITH GRAVE
552+ XK_oacute = 0x00f3, // U+00F3 LATIN SMALL LETTER O WITH ACUTE
553+ XK_ocircumflex = 0x00f4, // U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX
554+ XK_otilde = 0x00f5, // U+00F5 LATIN SMALL LETTER O WITH TILDE
555+ XK_odiaeresis = 0x00f6, // U+00F6 LATIN SMALL LETTER O WITH DIAERESIS
556+ XK_division = 0x00f7, // U+00F7 DIVISION SIGN
557+ XK_oslash = 0x00f8, // U+00F8 LATIN SMALL LETTER O WITH STROKE
558+ // XK_ooblique = 0x00f8, // deprecated alias for oslash
559+ XK_ugrave = 0x00f9, // U+00F9 LATIN SMALL LETTER U WITH GRAVE
560+ XK_uacute = 0x00fa, // U+00FA LATIN SMALL LETTER U WITH ACUTE
561+ XK_ucircumflex = 0x00fb, // U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX
562+ XK_udiaeresis = 0x00fc, // U+00FC LATIN SMALL LETTER U WITH DIAERESIS
563+ XK_yacute = 0x00fd, // U+00FD LATIN SMALL LETTER Y WITH ACUTE
564+ XK_thorn = 0x00fe, // U+00FE LATIN SMALL LETTER THORN
565+ XK_ydiaeresis = 0x00ff, // U+00FF LATIN SMALL LETTER Y WITH DIAERESIS
566+
567+ XK_Aogonek = 0x01a1, // U+0104 LATIN CAPITAL LETTER A WITH OGONEK
568+ XK_breve = 0x01a2, // U+02D8 BREVE
569+ XK_Lstroke = 0x01a3, // U+0141 LATIN CAPITAL LETTER L WITH STROKE
570+ XK_Lcaron = 0x01a5, // U+013D LATIN CAPITAL LETTER L WITH CARON
571+ XK_Sacute = 0x01a6, // U+015A LATIN CAPITAL LETTER S WITH ACUTE
572+ XK_Scaron = 0x01a9, // U+0160 LATIN CAPITAL LETTER S WITH CARON
573+ XK_Scedilla = 0x01aa, // U+015E LATIN CAPITAL LETTER S WITH CEDILLA
574+ XK_Tcaron = 0x01ab, // U+0164 LATIN CAPITAL LETTER T WITH CARON
575+ XK_Zacute = 0x01ac, // U+0179 LATIN CAPITAL LETTER Z WITH ACUTE
576+ XK_Zcaron = 0x01ae, // U+017D LATIN CAPITAL LETTER Z WITH CARON
577+ XK_Zabovedot = 0x01af, // U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE
578+ XK_aogonek = 0x01b1, // U+0105 LATIN SMALL LETTER A WITH OGONEK
579+ XK_ogonek = 0x01b2, // U+02DB OGONEK
580+ XK_lstroke = 0x01b3, // U+0142 LATIN SMALL LETTER L WITH STROKE
581+ XK_lcaron = 0x01b5, // U+013E LATIN SMALL LETTER L WITH CARON
582+ XK_sacute = 0x01b6, // U+015B LATIN SMALL LETTER S WITH ACUTE
583+ XK_caron = 0x01b7, // U+02C7 CARON
584+ XK_scaron = 0x01b9, // U+0161 LATIN SMALL LETTER S WITH CARON
585+ XK_scedilla = 0x01ba, // U+015F LATIN SMALL LETTER S WITH CEDILLA
586+ XK_tcaron = 0x01bb, // U+0165 LATIN SMALL LETTER T WITH CARON
587+ XK_zacute = 0x01bc, // U+017A LATIN SMALL LETTER Z WITH ACUTE
588+ XK_doubleacute = 0x01bd, // U+02DD DOUBLE ACUTE ACCENT
589+ XK_zcaron = 0x01be, // U+017E LATIN SMALL LETTER Z WITH CARON
590+ XK_zabovedot = 0x01bf, // U+017C LATIN SMALL LETTER Z WITH DOT ABOVE
591+ XK_Racute = 0x01c0, // U+0154 LATIN CAPITAL LETTER R WITH ACUTE
592+ XK_Abreve = 0x01c3, // U+0102 LATIN CAPITAL LETTER A WITH BREVE
593+ XK_Lacute = 0x01c5, // U+0139 LATIN CAPITAL LETTER L WITH ACUTE
594+ XK_Cacute = 0x01c6, // U+0106 LATIN CAPITAL LETTER C WITH ACUTE
595+ XK_Ccaron = 0x01c8, // U+010C LATIN CAPITAL LETTER C WITH CARON
596+ XK_Eogonek = 0x01ca, // U+0118 LATIN CAPITAL LETTER E WITH OGONEK
597+ XK_Ecaron = 0x01cc, // U+011A LATIN CAPITAL LETTER E WITH CARON
598+ XK_Dcaron = 0x01cf, // U+010E LATIN CAPITAL LETTER D WITH CARON
599+ XK_Dstroke = 0x01d0, // U+0110 LATIN CAPITAL LETTER D WITH STROKE
600+ XK_Nacute = 0x01d1, // U+0143 LATIN CAPITAL LETTER N WITH ACUTE
601+ XK_Ncaron = 0x01d2, // U+0147 LATIN CAPITAL LETTER N WITH CARON
602+ XK_Odoubleacute = 0x01d5, // U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
603+ XK_Rcaron = 0x01d8, // U+0158 LATIN CAPITAL LETTER R WITH CARON
604+ XK_Uring = 0x01d9, // U+016E LATIN CAPITAL LETTER U WITH RING ABOVE
605+ XK_Udoubleacute = 0x01db, // U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
606+ XK_Tcedilla = 0x01de, // U+0162 LATIN CAPITAL LETTER T WITH CEDILLA
607+ XK_racute = 0x01e0, // U+0155 LATIN SMALL LETTER R WITH ACUTE
608+ XK_abreve = 0x01e3, // U+0103 LATIN SMALL LETTER A WITH BREVE
609+ XK_lacute = 0x01e5, // U+013A LATIN SMALL LETTER L WITH ACUTE
610+ XK_cacute = 0x01e6, // U+0107 LATIN SMALL LETTER C WITH ACUTE
611+ XK_ccaron = 0x01e8, // U+010D LATIN SMALL LETTER C WITH CARON
612+ XK_eogonek = 0x01ea, // U+0119 LATIN SMALL LETTER E WITH OGONEK
613+ XK_ecaron = 0x01ec, // U+011B LATIN SMALL LETTER E WITH CARON
614+ XK_dcaron = 0x01ef, // U+010F LATIN SMALL LETTER D WITH CARON
615+ XK_dstroke = 0x01f0, // U+0111 LATIN SMALL LETTER D WITH STROKE
616+ XK_nacute = 0x01f1, // U+0144 LATIN SMALL LETTER N WITH ACUTE
617+ XK_ncaron = 0x01f2, // U+0148 LATIN SMALL LETTER N WITH CARON
618+ XK_odoubleacute = 0x01f5, // U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE
619+ XK_rcaron = 0x01f8, // U+0159 LATIN SMALL LETTER R WITH CARON
620+ XK_uring = 0x01f9, // U+016F LATIN SMALL LETTER U WITH RING ABOVE
621+ XK_udoubleacute = 0x01fb, // U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE
622+ XK_tcedilla = 0x01fe, // U+0163 LATIN SMALL LETTER T WITH CEDILLA
623+ XK_abovedot = 0x01ff, // U+02D9 DOT ABOVE
624+
625+ XK_Hstroke = 0x02a1, // U+0126 LATIN CAPITAL LETTER H WITH STROKE
626+ XK_Hcircumflex = 0x02a6, // U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX
627+ XK_Iabovedot = 0x02a9, // U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE
628+ XK_Gbreve = 0x02ab, // U+011E LATIN CAPITAL LETTER G WITH BREVE
629+ XK_Jcircumflex = 0x02ac, // U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX
630+ XK_hstroke = 0x02b1, // U+0127 LATIN SMALL LETTER H WITH STROKE
631+ XK_hcircumflex = 0x02b6, // U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX
632+ XK_idotless = 0x02b9, // U+0131 LATIN SMALL LETTER DOTLESS I
633+ XK_gbreve = 0x02bb, // U+011F LATIN SMALL LETTER G WITH BREVE
634+ XK_jcircumflex = 0x02bc, // U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX
635+ XK_Cabovedot = 0x02c5, // U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE
636+ XK_Ccircumflex = 0x02c6, // U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX
637+ XK_Gabovedot = 0x02d5, // U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE
638+ XK_Gcircumflex = 0x02d8, // U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX
639+ XK_Ubreve = 0x02dd, // U+016C LATIN CAPITAL LETTER U WITH BREVE
640+ XK_Scircumflex = 0x02de, // U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX
641+ XK_cabovedot = 0x02e5, // U+010B LATIN SMALL LETTER C WITH DOT ABOVE
642+ XK_ccircumflex = 0x02e6, // U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX
643+ XK_gabovedot = 0x02f5, // U+0121 LATIN SMALL LETTER G WITH DOT ABOVE
644+ XK_gcircumflex = 0x02f8, // U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX
645+ XK_ubreve = 0x02fd, // U+016D LATIN SMALL LETTER U WITH BREVE
646+ XK_scircumflex = 0x02fe, // U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX
647+
648+ XK_kra = 0x03a2, // U+0138 LATIN SMALL LETTER KRA
649+ // XK_kappa = 0x03a2, // deprecated
650+ XK_Rcedilla = 0x03a3, // U+0156 LATIN CAPITAL LETTER R WITH CEDILLA
651+ XK_Itilde = 0x03a5, // U+0128 LATIN CAPITAL LETTER I WITH TILDE
652+ XK_Lcedilla = 0x03a6, // U+013B LATIN CAPITAL LETTER L WITH CEDILLA
653+ XK_Emacron = 0x03aa, // U+0112 LATIN CAPITAL LETTER E WITH MACRON
654+ XK_Gcedilla = 0x03ab, // U+0122 LATIN CAPITAL LETTER G WITH CEDILLA
655+ XK_Tslash = 0x03ac, // U+0166 LATIN CAPITAL LETTER T WITH STROKE
656+ XK_rcedilla = 0x03b3, // U+0157 LATIN SMALL LETTER R WITH CEDILLA
657+ XK_itilde = 0x03b5, // U+0129 LATIN SMALL LETTER I WITH TILDE
658+ XK_lcedilla = 0x03b6, // U+013C LATIN SMALL LETTER L WITH CEDILLA
659+ XK_emacron = 0x03ba, // U+0113 LATIN SMALL LETTER E WITH MACRON
660+ XK_gcedilla = 0x03bb, // U+0123 LATIN SMALL LETTER G WITH CEDILLA
661+ XK_tslash = 0x03bc, // U+0167 LATIN SMALL LETTER T WITH STROKE
662+ XK_ENG = 0x03bd, // U+014A LATIN CAPITAL LETTER ENG
663+ XK_eng = 0x03bf, // U+014B LATIN SMALL LETTER ENG
664+ XK_Amacron = 0x03c0, // U+0100 LATIN CAPITAL LETTER A WITH MACRON
665+ XK_Iogonek = 0x03c7, // U+012E LATIN CAPITAL LETTER I WITH OGONEK
666+ XK_Eabovedot = 0x03cc, // U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE
667+ XK_Imacron = 0x03cf, // U+012A LATIN CAPITAL LETTER I WITH MACRON
668+ XK_Ncedilla = 0x03d1, // U+0145 LATIN CAPITAL LETTER N WITH CEDILLA
669+ XK_Omacron = 0x03d2, // U+014C LATIN CAPITAL LETTER O WITH MACRON
670+ XK_Kcedilla = 0x03d3, // U+0136 LATIN CAPITAL LETTER K WITH CEDILLA
671+ XK_Uogonek = 0x03d9, // U+0172 LATIN CAPITAL LETTER U WITH OGONEK
672+ XK_Utilde = 0x03dd, // U+0168 LATIN CAPITAL LETTER U WITH TILDE
673+ XK_Umacron = 0x03de, // U+016A LATIN CAPITAL LETTER U WITH MACRON
674+ XK_amacron = 0x03e0, // U+0101 LATIN SMALL LETTER A WITH MACRON
675+ XK_iogonek = 0x03e7, // U+012F LATIN SMALL LETTER I WITH OGONEK
676+ XK_eabovedot = 0x03ec, // U+0117 LATIN SMALL LETTER E WITH DOT ABOVE
677+ XK_imacron = 0x03ef, // U+012B LATIN SMALL LETTER I WITH MACRON
678+ XK_ncedilla = 0x03f1, // U+0146 LATIN SMALL LETTER N WITH CEDILLA
679+ XK_omacron = 0x03f2, // U+014D LATIN SMALL LETTER O WITH MACRON
680+ XK_kcedilla = 0x03f3, // U+0137 LATIN SMALL LETTER K WITH CEDILLA
681+ XK_uogonek = 0x03f9, // U+0173 LATIN SMALL LETTER U WITH OGONEK
682+ XK_utilde = 0x03fd, // U+0169 LATIN SMALL LETTER U WITH TILDE
683+ XK_umacron = 0x03fe, // U+016B LATIN SMALL LETTER U WITH MACRON
684+
685+ XK_Wcircumflex = 0x1000174, // U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX
686+ XK_wcircumflex = 0x1000175, // U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX
687+ XK_Ycircumflex = 0x1000176, // U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
688+ XK_ycircumflex = 0x1000177, // U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX
689+ XK_Babovedot = 0x1001e02, // U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE
690+ XK_babovedot = 0x1001e03, // U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE
691+ XK_Dabovedot = 0x1001e0a, // U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE
692+ XK_dabovedot = 0x1001e0b, // U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE
693+ XK_Fabovedot = 0x1001e1e, // U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE
694+ XK_fabovedot = 0x1001e1f, // U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE
695+ XK_Mabovedot = 0x1001e40, // U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE
696+ XK_mabovedot = 0x1001e41, // U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE
697+ XK_Pabovedot = 0x1001e56, // U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE
698+ XK_pabovedot = 0x1001e57, // U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE
699+ XK_Sabovedot = 0x1001e60, // U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE
700+ XK_sabovedot = 0x1001e61, // U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE
701+ XK_Tabovedot = 0x1001e6a, // U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE
702+ XK_tabovedot = 0x1001e6b, // U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE
703+ XK_Wgrave = 0x1001e80, // U+1E80 LATIN CAPITAL LETTER W WITH GRAVE
704+ XK_wgrave = 0x1001e81, // U+1E81 LATIN SMALL LETTER W WITH GRAVE
705+ XK_Wacute = 0x1001e82, // U+1E82 LATIN CAPITAL LETTER W WITH ACUTE
706+ XK_wacute = 0x1001e83, // U+1E83 LATIN SMALL LETTER W WITH ACUTE
707+ XK_Wdiaeresis = 0x1001e84, // U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS
708+ XK_wdiaeresis = 0x1001e85, // U+1E85 LATIN SMALL LETTER W WITH DIAERESIS
709+ XK_Ygrave = 0x1001ef2, // U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE
710+ XK_ygrave = 0x1001ef3, // U+1EF3 LATIN SMALL LETTER Y WITH GRAVE
711+
712+ XK_OE = 0x13bc, // U+0152 LATIN CAPITAL LIGATURE OE
713+ XK_oe = 0x13bd, // U+0153 LATIN SMALL LIGATURE OE
714+ XK_Ydiaeresis = 0x13be, // U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS
715+
716+ XK_overline = 0x047e, // U+203E OVERLINE
717+ XK_kana_fullstop = 0x04a1, // U+3002 IDEOGRAPHIC FULL STOP
718+ XK_kana_openingbracket = 0x04a2, // U+300C LEFT CORNER BRACKET
719+ XK_kana_closingbracket = 0x04a3, // U+300D RIGHT CORNER BRACKET
720+ XK_kana_comma = 0x04a4, // U+3001 IDEOGRAPHIC COMMA
721+ XK_kana_conjunctive = 0x04a5, // U+30FB KATAKANA MIDDLE DOT
722+ // XK_kana_middledot = 0x04a5, // deprecated
723+ XK_kana_WO = 0x04a6, // U+30F2 KATAKANA LETTER WO
724+ XK_kana_a = 0x04a7, // U+30A1 KATAKANA LETTER SMALL A
725+ XK_kana_i = 0x04a8, // U+30A3 KATAKANA LETTER SMALL I
726+ XK_kana_u = 0x04a9, // U+30A5 KATAKANA LETTER SMALL U
727+ XK_kana_e = 0x04aa, // U+30A7 KATAKANA LETTER SMALL E
728+ XK_kana_o = 0x04ab, // U+30A9 KATAKANA LETTER SMALL O
729+ XK_kana_ya = 0x04ac, // U+30E3 KATAKANA LETTER SMALL YA
730+ XK_kana_yu = 0x04ad, // U+30E5 KATAKANA LETTER SMALL YU
731+ XK_kana_yo = 0x04ae, // U+30E7 KATAKANA LETTER SMALL YO
732+ XK_kana_tsu = 0x04af, // U+30C3 KATAKANA LETTER SMALL TU
733+ // XK_kana_tu = 0x04af, // deprecated
734+ XK_prolongedsound = 0x04b0, // U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK
735+ XK_kana_A = 0x04b1, // U+30A2 KATAKANA LETTER A
736+ XK_kana_I = 0x04b2, // U+30A4 KATAKANA LETTER I
737+ XK_kana_U = 0x04b3, // U+30A6 KATAKANA LETTER U
738+ XK_kana_E = 0x04b4, // U+30A8 KATAKANA LETTER E
739+ XK_kana_O = 0x04b5, // U+30AA KATAKANA LETTER O
740+ XK_kana_KA = 0x04b6, // U+30AB KATAKANA LETTER KA
741+ XK_kana_KI = 0x04b7, // U+30AD KATAKANA LETTER KI
742+ XK_kana_KU = 0x04b8, // U+30AF KATAKANA LETTER KU
743+ XK_kana_KE = 0x04b9, // U+30B1 KATAKANA LETTER KE
744+ XK_kana_KO = 0x04ba, // U+30B3 KATAKANA LETTER KO
745+ XK_kana_SA = 0x04bb, // U+30B5 KATAKANA LETTER SA
746+ XK_kana_SHI = 0x04bc, // U+30B7 KATAKANA LETTER SI
747+ XK_kana_SU = 0x04bd, // U+30B9 KATAKANA LETTER SU
748+ XK_kana_SE = 0x04be, // U+30BB KATAKANA LETTER SE
749+ XK_kana_SO = 0x04bf, // U+30BD KATAKANA LETTER SO
750+ XK_kana_TA = 0x04c0, // U+30BF KATAKANA LETTER TA
751+ XK_kana_CHI = 0x04c1, // U+30C1 KATAKANA LETTER TI
752+ // XK_kana_TI = 0x04c1, // deprecated
753+ XK_kana_TSU = 0x04c2, // U+30C4 KATAKANA LETTER TU
754+ // XK_kana_TU = 0x04c2, // deprecated
755+ XK_kana_TE = 0x04c3, // U+30C6 KATAKANA LETTER TE
756+ XK_kana_TO = 0x04c4, // U+30C8 KATAKANA LETTER TO
757+ XK_kana_NA = 0x04c5, // U+30CA KATAKANA LETTER NA
758+ XK_kana_NI = 0x04c6, // U+30CB KATAKANA LETTER NI
759+ XK_kana_NU = 0x04c7, // U+30CC KATAKANA LETTER NU
760+ XK_kana_NE = 0x04c8, // U+30CD KATAKANA LETTER NE
761+ XK_kana_NO = 0x04c9, // U+30CE KATAKANA LETTER NO
762+ XK_kana_HA = 0x04ca, // U+30CF KATAKANA LETTER HA
763+ XK_kana_HI = 0x04cb, // U+30D2 KATAKANA LETTER HI
764+ XK_kana_FU = 0x04cc, // U+30D5 KATAKANA LETTER HU
765+ // XK_kana_HU = 0x04cc, // deprecated
766+ XK_kana_HE = 0x04cd, // U+30D8 KATAKANA LETTER HE
767+ XK_kana_HO = 0x04ce, // U+30DB KATAKANA LETTER HO
768+ XK_kana_MA = 0x04cf, // U+30DE KATAKANA LETTER MA
769+ XK_kana_MI = 0x04d0, // U+30DF KATAKANA LETTER MI
770+ XK_kana_MU = 0x04d1, // U+30E0 KATAKANA LETTER MU
771+ XK_kana_ME = 0x04d2, // U+30E1 KATAKANA LETTER ME
772+ XK_kana_MO = 0x04d3, // U+30E2 KATAKANA LETTER MO
773+ XK_kana_YA = 0x04d4, // U+30E4 KATAKANA LETTER YA
774+ XK_kana_YU = 0x04d5, // U+30E6 KATAKANA LETTER YU
775+ XK_kana_YO = 0x04d6, // U+30E8 KATAKANA LETTER YO
776+ XK_kana_RA = 0x04d7, // U+30E9 KATAKANA LETTER RA
777+ XK_kana_RI = 0x04d8, // U+30EA KATAKANA LETTER RI
778+ XK_kana_RU = 0x04d9, // U+30EB KATAKANA LETTER RU
779+ XK_kana_RE = 0x04da, // U+30EC KATAKANA LETTER RE
780+ XK_kana_RO = 0x04db, // U+30ED KATAKANA LETTER RO
781+ XK_kana_WA = 0x04dc, // U+30EF KATAKANA LETTER WA
782+ XK_kana_N = 0x04dd, // U+30F3 KATAKANA LETTER N
783+ XK_voicedsound = 0x04de, // U+309B KATAKANA-HIRAGANA VOICED SOUND MARK
784+ XK_semivoicedsound = 0x04df, // U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
785+ // XK_kana_switch = 0xff7e, // non-deprecated alias for Mode_switch
786+
787+ XK_Farsi_0 = 0x10006f0, // U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO
788+ XK_Farsi_1 = 0x10006f1, // U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE
789+ XK_Farsi_2 = 0x10006f2, // U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO
790+ XK_Farsi_3 = 0x10006f3, // U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE
791+ XK_Farsi_4 = 0x10006f4, // U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR
792+ XK_Farsi_5 = 0x10006f5, // U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE
793+ XK_Farsi_6 = 0x10006f6, // U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX
794+ XK_Farsi_7 = 0x10006f7, // U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN
795+ XK_Farsi_8 = 0x10006f8, // U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT
796+ XK_Farsi_9 = 0x10006f9, // U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE
797+ XK_Arabic_percent = 0x100066a, // U+066A ARABIC PERCENT SIGN
798+ XK_Arabic_superscript_alef = 0x1000670, // U+0670 ARABIC LETTER SUPERSCRIPT ALEF
799+ XK_Arabic_tteh = 0x1000679, // U+0679 ARABIC LETTER TTEH
800+ XK_Arabic_peh = 0x100067e, // U+067E ARABIC LETTER PEH
801+ XK_Arabic_tcheh = 0x1000686, // U+0686 ARABIC LETTER TCHEH
802+ XK_Arabic_ddal = 0x1000688, // U+0688 ARABIC LETTER DDAL
803+ XK_Arabic_rreh = 0x1000691, // U+0691 ARABIC LETTER RREH
804+ XK_Arabic_comma = 0x05ac, // U+060C ARABIC COMMA
805+ XK_Arabic_fullstop = 0x10006d4, // U+06D4 ARABIC FULL STOP
806+ XK_Arabic_0 = 0x1000660, // U+0660 ARABIC-INDIC DIGIT ZERO
807+ XK_Arabic_1 = 0x1000661, // U+0661 ARABIC-INDIC DIGIT ONE
808+ XK_Arabic_2 = 0x1000662, // U+0662 ARABIC-INDIC DIGIT TWO
809+ XK_Arabic_3 = 0x1000663, // U+0663 ARABIC-INDIC DIGIT THREE
810+ XK_Arabic_4 = 0x1000664, // U+0664 ARABIC-INDIC DIGIT FOUR
811+ XK_Arabic_5 = 0x1000665, // U+0665 ARABIC-INDIC DIGIT FIVE
812+ XK_Arabic_6 = 0x1000666, // U+0666 ARABIC-INDIC DIGIT SIX
813+ XK_Arabic_7 = 0x1000667, // U+0667 ARABIC-INDIC DIGIT SEVEN
814+ XK_Arabic_8 = 0x1000668, // U+0668 ARABIC-INDIC DIGIT EIGHT
815+ XK_Arabic_9 = 0x1000669, // U+0669 ARABIC-INDIC DIGIT NINE
816+ XK_Arabic_semicolon = 0x05bb, // U+061B ARABIC SEMICOLON
817+ XK_Arabic_question_mark = 0x05bf, // U+061F ARABIC QUESTION MARK
818+ XK_Arabic_hamza = 0x05c1, // U+0621 ARABIC LETTER HAMZA
819+ XK_Arabic_maddaonalef = 0x05c2, // U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE
820+ XK_Arabic_hamzaonalef = 0x05c3, // U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE
821+ XK_Arabic_hamzaonwaw = 0x05c4, // U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE
822+ XK_Arabic_hamzaunderalef = 0x05c5, // U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW
823+ XK_Arabic_hamzaonyeh = 0x05c6, // U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE
824+ XK_Arabic_alef = 0x05c7, // U+0627 ARABIC LETTER ALEF
825+ XK_Arabic_beh = 0x05c8, // U+0628 ARABIC LETTER BEH
826+ XK_Arabic_tehmarbuta = 0x05c9, // U+0629 ARABIC LETTER TEH MARBUTA
827+ XK_Arabic_teh = 0x05ca, // U+062A ARABIC LETTER TEH
828+ XK_Arabic_theh = 0x05cb, // U+062B ARABIC LETTER THEH
829+ XK_Arabic_jeem = 0x05cc, // U+062C ARABIC LETTER JEEM
830+ XK_Arabic_hah = 0x05cd, // U+062D ARABIC LETTER HAH
831+ XK_Arabic_khah = 0x05ce, // U+062E ARABIC LETTER KHAH
832+ XK_Arabic_dal = 0x05cf, // U+062F ARABIC LETTER DAL
833+ XK_Arabic_thal = 0x05d0, // U+0630 ARABIC LETTER THAL
834+ XK_Arabic_ra = 0x05d1, // U+0631 ARABIC LETTER REH
835+ XK_Arabic_zain = 0x05d2, // U+0632 ARABIC LETTER ZAIN
836+ XK_Arabic_seen = 0x05d3, // U+0633 ARABIC LETTER SEEN
837+ XK_Arabic_sheen = 0x05d4, // U+0634 ARABIC LETTER SHEEN
838+ XK_Arabic_sad = 0x05d5, // U+0635 ARABIC LETTER SAD
839+ XK_Arabic_dad = 0x05d6, // U+0636 ARABIC LETTER DAD
840+ XK_Arabic_tah = 0x05d7, // U+0637 ARABIC LETTER TAH
841+ XK_Arabic_zah = 0x05d8, // U+0638 ARABIC LETTER ZAH
842+ XK_Arabic_ain = 0x05d9, // U+0639 ARABIC LETTER AIN
843+ XK_Arabic_ghain = 0x05da, // U+063A ARABIC LETTER GHAIN
844+ XK_Arabic_tatweel = 0x05e0, // U+0640 ARABIC TATWEEL
845+ XK_Arabic_feh = 0x05e1, // U+0641 ARABIC LETTER FEH
846+ XK_Arabic_qaf = 0x05e2, // U+0642 ARABIC LETTER QAF
847+ XK_Arabic_kaf = 0x05e3, // U+0643 ARABIC LETTER KAF
848+ XK_Arabic_lam = 0x05e4, // U+0644 ARABIC LETTER LAM
849+ XK_Arabic_meem = 0x05e5, // U+0645 ARABIC LETTER MEEM
850+ XK_Arabic_noon = 0x05e6, // U+0646 ARABIC LETTER NOON
851+ XK_Arabic_ha = 0x05e7, // U+0647 ARABIC LETTER HEH
852+ // XK_Arabic_heh = 0x05e7, // deprecated
853+ XK_Arabic_waw = 0x05e8, // U+0648 ARABIC LETTER WAW
854+ XK_Arabic_alefmaksura = 0x05e9, // U+0649 ARABIC LETTER ALEF MAKSURA
855+ XK_Arabic_yeh = 0x05ea, // U+064A ARABIC LETTER YEH
856+ XK_Arabic_fathatan = 0x05eb, // U+064B ARABIC FATHATAN
857+ XK_Arabic_dammatan = 0x05ec, // U+064C ARABIC DAMMATAN
858+ XK_Arabic_kasratan = 0x05ed, // U+064D ARABIC KASRATAN
859+ XK_Arabic_fatha = 0x05ee, // U+064E ARABIC FATHA
860+ XK_Arabic_damma = 0x05ef, // U+064F ARABIC DAMMA
861+ XK_Arabic_kasra = 0x05f0, // U+0650 ARABIC KASRA
862+ XK_Arabic_shadda = 0x05f1, // U+0651 ARABIC SHADDA
863+ XK_Arabic_sukun = 0x05f2, // U+0652 ARABIC SUKUN
864+ XK_Arabic_madda_above = 0x1000653, // U+0653 ARABIC MADDAH ABOVE
865+ XK_Arabic_hamza_above = 0x1000654, // U+0654 ARABIC HAMZA ABOVE
866+ XK_Arabic_hamza_below = 0x1000655, // U+0655 ARABIC HAMZA BELOW
867+ XK_Arabic_jeh = 0x1000698, // U+0698 ARABIC LETTER JEH
868+ XK_Arabic_veh = 0x10006a4, // U+06A4 ARABIC LETTER VEH
869+ XK_Arabic_keheh = 0x10006a9, // U+06A9 ARABIC LETTER KEHEH
870+ XK_Arabic_gaf = 0x10006af, // U+06AF ARABIC LETTER GAF
871+ XK_Arabic_noon_ghunna = 0x10006ba, // U+06BA ARABIC LETTER NOON GHUNNA
872+ XK_Arabic_heh_doachashmee = 0x10006be, // U+06BE ARABIC LETTER HEH DOACHASHMEE
873+ XK_Farsi_yeh = 0x10006cc, // U+06CC ARABIC LETTER FARSI YEH
874+ // XK_Arabic_farsi_yeh = 0x10006cc, // deprecated alias for Farsi_yeh
875+ XK_Arabic_yeh_baree = 0x10006d2, // U+06D2 ARABIC LETTER YEH BARREE
876+ XK_Arabic_heh_goal = 0x10006c1, // U+06C1 ARABIC LETTER HEH GOAL
877+ // XK_Arabic_switch = 0xff7e, // non-deprecated alias for Mode_switch
878+
879+ XK_Cyrillic_GHE_bar = 0x1000492, // U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE
880+ XK_Cyrillic_ghe_bar = 0x1000493, // U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE
881+ XK_Cyrillic_ZHE_descender = 0x1000496, // U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
882+ XK_Cyrillic_zhe_descender = 0x1000497, // U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER
883+ XK_Cyrillic_KA_descender = 0x100049a, // U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER
884+ XK_Cyrillic_ka_descender = 0x100049b, // U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER
885+ XK_Cyrillic_KA_vertstroke = 0x100049c, // U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
886+ XK_Cyrillic_ka_vertstroke = 0x100049d, // U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE
887+ XK_Cyrillic_EN_descender = 0x10004a2, // U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER
888+ XK_Cyrillic_en_descender = 0x10004a3, // U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER
889+ XK_Cyrillic_U_straight = 0x10004ae, // U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U
890+ XK_Cyrillic_u_straight = 0x10004af, // U+04AF CYRILLIC SMALL LETTER STRAIGHT U
891+ XK_Cyrillic_U_straight_bar = 0x10004b0, // U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
892+ XK_Cyrillic_u_straight_bar = 0x10004b1, // U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
893+ XK_Cyrillic_HA_descender = 0x10004b2, // U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER
894+ XK_Cyrillic_ha_descender = 0x10004b3, // U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER
895+ XK_Cyrillic_CHE_descender = 0x10004b6, // U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
896+ XK_Cyrillic_che_descender = 0x10004b7, // U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER
897+ XK_Cyrillic_CHE_vertstroke = 0x10004b8, // U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
898+ XK_Cyrillic_che_vertstroke = 0x10004b9, // U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE
899+ XK_Cyrillic_SHHA = 0x10004ba, // U+04BA CYRILLIC CAPITAL LETTER SHHA
900+ XK_Cyrillic_shha = 0x10004bb, // U+04BB CYRILLIC SMALL LETTER SHHA
901+ XK_Cyrillic_SCHWA = 0x10004d8, // U+04D8 CYRILLIC CAPITAL LETTER SCHWA
902+ XK_Cyrillic_schwa = 0x10004d9, // U+04D9 CYRILLIC SMALL LETTER SCHWA
903+ XK_Cyrillic_I_macron = 0x10004e2, // U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON
904+ XK_Cyrillic_i_macron = 0x10004e3, // U+04E3 CYRILLIC SMALL LETTER I WITH MACRON
905+ XK_Cyrillic_O_bar = 0x10004e8, // U+04E8 CYRILLIC CAPITAL LETTER BARRED O
906+ XK_Cyrillic_o_bar = 0x10004e9, // U+04E9 CYRILLIC SMALL LETTER BARRED O
907+ XK_Cyrillic_U_macron = 0x10004ee, // U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON
908+ XK_Cyrillic_u_macron = 0x10004ef, // U+04EF CYRILLIC SMALL LETTER U WITH MACRON
909+ XK_Serbian_dje = 0x06a1, // U+0452 CYRILLIC SMALL LETTER DJE
910+ XK_Macedonia_gje = 0x06a2, // U+0453 CYRILLIC SMALL LETTER GJE
911+ XK_Cyrillic_io = 0x06a3, // U+0451 CYRILLIC SMALL LETTER IO
912+ XK_Ukrainian_ie = 0x06a4, // U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE
913+ // XK_Ukranian_je = 0x06a4, // deprecated
914+ XK_Macedonia_dse = 0x06a5, // U+0455 CYRILLIC SMALL LETTER DZE
915+ XK_Ukrainian_i = 0x06a6, // U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
916+ // XK_Ukranian_i = 0x06a6, // deprecated
917+ XK_Ukrainian_yi = 0x06a7, // U+0457 CYRILLIC SMALL LETTER YI
918+ // XK_Ukranian_yi = 0x06a7, // deprecated
919+ XK_Cyrillic_je = 0x06a8, // U+0458 CYRILLIC SMALL LETTER JE
920+ // XK_Serbian_je = 0x06a8, // deprecated
921+ XK_Cyrillic_lje = 0x06a9, // U+0459 CYRILLIC SMALL LETTER LJE
922+ // XK_Serbian_lje = 0x06a9, // deprecated
923+ XK_Cyrillic_nje = 0x06aa, // U+045A CYRILLIC SMALL LETTER NJE
924+ // XK_Serbian_nje = 0x06aa, // deprecated
925+ XK_Serbian_tshe = 0x06ab, // U+045B CYRILLIC SMALL LETTER TSHE
926+ XK_Macedonia_kje = 0x06ac, // U+045C CYRILLIC SMALL LETTER KJE
927+ XK_Ukrainian_ghe_with_upturn = 0x06ad, // U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN
928+ XK_Byelorussian_shortu = 0x06ae, // U+045E CYRILLIC SMALL LETTER SHORT U
929+ XK_Cyrillic_dzhe = 0x06af, // U+045F CYRILLIC SMALL LETTER DZHE
930+ // XK_Serbian_dze = 0x06af, // deprecated
931+ XK_numerosign = 0x06b0, // U+2116 NUMERO SIGN
932+ XK_Serbian_DJE = 0x06b1, // U+0402 CYRILLIC CAPITAL LETTER DJE
933+ XK_Macedonia_GJE = 0x06b2, // U+0403 CYRILLIC CAPITAL LETTER GJE
934+ XK_Cyrillic_IO = 0x06b3, // U+0401 CYRILLIC CAPITAL LETTER IO
935+ XK_Ukrainian_IE = 0x06b4, // U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE
936+ // XK_Ukranian_JE = 0x06b4, // deprecated
937+ XK_Macedonia_DSE = 0x06b5, // U+0405 CYRILLIC CAPITAL LETTER DZE
938+ XK_Ukrainian_I = 0x06b6, // U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
939+ // XK_Ukranian_I = 0x06b6, // deprecated
940+ XK_Ukrainian_YI = 0x06b7, // U+0407 CYRILLIC CAPITAL LETTER YI
941+ // XK_Ukranian_YI = 0x06b7, // deprecated
942+ XK_Cyrillic_JE = 0x06b8, // U+0408 CYRILLIC CAPITAL LETTER JE
943+ // XK_Serbian_JE = 0x06b8, // deprecated
944+ XK_Cyrillic_LJE = 0x06b9, // U+0409 CYRILLIC CAPITAL LETTER LJE
945+ // XK_Serbian_LJE = 0x06b9, // deprecated
946+ XK_Cyrillic_NJE = 0x06ba, // U+040A CYRILLIC CAPITAL LETTER NJE
947+ // XK_Serbian_NJE = 0x06ba, // deprecated
948+ XK_Serbian_TSHE = 0x06bb, // U+040B CYRILLIC CAPITAL LETTER TSHE
949+ XK_Macedonia_KJE = 0x06bc, // U+040C CYRILLIC CAPITAL LETTER KJE
950+ XK_Ukrainian_GHE_WITH_UPTURN = 0x06bd, // U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN
951+ XK_Byelorussian_SHORTU = 0x06be, // U+040E CYRILLIC CAPITAL LETTER SHORT U
952+ XK_Cyrillic_DZHE = 0x06bf, // U+040F CYRILLIC CAPITAL LETTER DZHE
953+ // XK_Serbian_DZE = 0x06bf, // deprecated
954+ XK_Cyrillic_yu = 0x06c0, // U+044E CYRILLIC SMALL LETTER YU
955+ XK_Cyrillic_a = 0x06c1, // U+0430 CYRILLIC SMALL LETTER A
956+ XK_Cyrillic_be = 0x06c2, // U+0431 CYRILLIC SMALL LETTER BE
957+ XK_Cyrillic_tse = 0x06c3, // U+0446 CYRILLIC SMALL LETTER TSE
958+ XK_Cyrillic_de = 0x06c4, // U+0434 CYRILLIC SMALL LETTER DE
959+ XK_Cyrillic_ie = 0x06c5, // U+0435 CYRILLIC SMALL LETTER IE
960+ XK_Cyrillic_ef = 0x06c6, // U+0444 CYRILLIC SMALL LETTER EF
961+ XK_Cyrillic_ghe = 0x06c7, // U+0433 CYRILLIC SMALL LETTER GHE
962+ XK_Cyrillic_ha = 0x06c8, // U+0445 CYRILLIC SMALL LETTER HA
963+ XK_Cyrillic_i = 0x06c9, // U+0438 CYRILLIC SMALL LETTER I
964+ XK_Cyrillic_shorti = 0x06ca, // U+0439 CYRILLIC SMALL LETTER SHORT I
965+ XK_Cyrillic_ka = 0x06cb, // U+043A CYRILLIC SMALL LETTER KA
966+ XK_Cyrillic_el = 0x06cc, // U+043B CYRILLIC SMALL LETTER EL
967+ XK_Cyrillic_em = 0x06cd, // U+043C CYRILLIC SMALL LETTER EM
968+ XK_Cyrillic_en = 0x06ce, // U+043D CYRILLIC SMALL LETTER EN
969+ XK_Cyrillic_o = 0x06cf, // U+043E CYRILLIC SMALL LETTER O
970+ XK_Cyrillic_pe = 0x06d0, // U+043F CYRILLIC SMALL LETTER PE
971+ XK_Cyrillic_ya = 0x06d1, // U+044F CYRILLIC SMALL LETTER YA
972+ XK_Cyrillic_er = 0x06d2, // U+0440 CYRILLIC SMALL LETTER ER
973+ XK_Cyrillic_es = 0x06d3, // U+0441 CYRILLIC SMALL LETTER ES
974+ XK_Cyrillic_te = 0x06d4, // U+0442 CYRILLIC SMALL LETTER TE
975+ XK_Cyrillic_u = 0x06d5, // U+0443 CYRILLIC SMALL LETTER U
976+ XK_Cyrillic_zhe = 0x06d6, // U+0436 CYRILLIC SMALL LETTER ZHE
977+ XK_Cyrillic_ve = 0x06d7, // U+0432 CYRILLIC SMALL LETTER VE
978+ XK_Cyrillic_softsign = 0x06d8, // U+044C CYRILLIC SMALL LETTER SOFT SIGN
979+ XK_Cyrillic_yeru = 0x06d9, // U+044B CYRILLIC SMALL LETTER YERU
980+ XK_Cyrillic_ze = 0x06da, // U+0437 CYRILLIC SMALL LETTER ZE
981+ XK_Cyrillic_sha = 0x06db, // U+0448 CYRILLIC SMALL LETTER SHA
982+ XK_Cyrillic_e = 0x06dc, // U+044D CYRILLIC SMALL LETTER E
983+ XK_Cyrillic_shcha = 0x06dd, // U+0449 CYRILLIC SMALL LETTER SHCHA
984+ XK_Cyrillic_che = 0x06de, // U+0447 CYRILLIC SMALL LETTER CHE
985+ XK_Cyrillic_hardsign = 0x06df, // U+044A CYRILLIC SMALL LETTER HARD SIGN
986+ XK_Cyrillic_YU = 0x06e0, // U+042E CYRILLIC CAPITAL LETTER YU
987+ XK_Cyrillic_A = 0x06e1, // U+0410 CYRILLIC CAPITAL LETTER A
988+ XK_Cyrillic_BE = 0x06e2, // U+0411 CYRILLIC CAPITAL LETTER BE
989+ XK_Cyrillic_TSE = 0x06e3, // U+0426 CYRILLIC CAPITAL LETTER TSE
990+ XK_Cyrillic_DE = 0x06e4, // U+0414 CYRILLIC CAPITAL LETTER DE
991+ XK_Cyrillic_IE = 0x06e5, // U+0415 CYRILLIC CAPITAL LETTER IE
992+ XK_Cyrillic_EF = 0x06e6, // U+0424 CYRILLIC CAPITAL LETTER EF
993+ XK_Cyrillic_GHE = 0x06e7, // U+0413 CYRILLIC CAPITAL LETTER GHE
994+ XK_Cyrillic_HA = 0x06e8, // U+0425 CYRILLIC CAPITAL LETTER HA
995+ XK_Cyrillic_I = 0x06e9, // U+0418 CYRILLIC CAPITAL LETTER I
996+ XK_Cyrillic_SHORTI = 0x06ea, // U+0419 CYRILLIC CAPITAL LETTER SHORT I
997+ XK_Cyrillic_KA = 0x06eb, // U+041A CYRILLIC CAPITAL LETTER KA
998+ XK_Cyrillic_EL = 0x06ec, // U+041B CYRILLIC CAPITAL LETTER EL
999+ XK_Cyrillic_EM = 0x06ed, // U+041C CYRILLIC CAPITAL LETTER EM
1000+ XK_Cyrillic_EN = 0x06ee, // U+041D CYRILLIC CAPITAL LETTER EN
1001+ XK_Cyrillic_O = 0x06ef, // U+041E CYRILLIC CAPITAL LETTER O
1002+ XK_Cyrillic_PE = 0x06f0, // U+041F CYRILLIC CAPITAL LETTER PE
1003+ XK_Cyrillic_YA = 0x06f1, // U+042F CYRILLIC CAPITAL LETTER YA
1004+ XK_Cyrillic_ER = 0x06f2, // U+0420 CYRILLIC CAPITAL LETTER ER
1005+ XK_Cyrillic_ES = 0x06f3, // U+0421 CYRILLIC CAPITAL LETTER ES
1006+ XK_Cyrillic_TE = 0x06f4, // U+0422 CYRILLIC CAPITAL LETTER TE
1007+ XK_Cyrillic_U = 0x06f5, // U+0423 CYRILLIC CAPITAL LETTER U
1008+ XK_Cyrillic_ZHE = 0x06f6, // U+0416 CYRILLIC CAPITAL LETTER ZHE
1009+ XK_Cyrillic_VE = 0x06f7, // U+0412 CYRILLIC CAPITAL LETTER VE
1010+ XK_Cyrillic_SOFTSIGN = 0x06f8, // U+042C CYRILLIC CAPITAL LETTER SOFT SIGN
1011+ XK_Cyrillic_YERU = 0x06f9, // U+042B CYRILLIC CAPITAL LETTER YERU
1012+ XK_Cyrillic_ZE = 0x06fa, // U+0417 CYRILLIC CAPITAL LETTER ZE
1013+ XK_Cyrillic_SHA = 0x06fb, // U+0428 CYRILLIC CAPITAL LETTER SHA
1014+ XK_Cyrillic_E = 0x06fc, // U+042D CYRILLIC CAPITAL LETTER E
1015+ XK_Cyrillic_SHCHA = 0x06fd, // U+0429 CYRILLIC CAPITAL LETTER SHCHA
1016+ XK_Cyrillic_CHE = 0x06fe, // U+0427 CYRILLIC CAPITAL LETTER CHE
1017+ XK_Cyrillic_HARDSIGN = 0x06ff, // U+042A CYRILLIC CAPITAL LETTER HARD SIGN
1018+
1019+ XK_Greek_ALPHAaccent = 0x07a1, // U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS
1020+ XK_Greek_EPSILONaccent = 0x07a2, // U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS
1021+ XK_Greek_ETAaccent = 0x07a3, // U+0389 GREEK CAPITAL LETTER ETA WITH TONOS
1022+ XK_Greek_IOTAaccent = 0x07a4, // U+038A GREEK CAPITAL LETTER IOTA WITH TONOS
1023+ XK_Greek_IOTAdieresis = 0x07a5, // U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
1024+ // XK_Greek_IOTAdiaeresis = 0x07a5, // deprecated (old typo)
1025+ XK_Greek_OMICRONaccent = 0x07a7, // U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS
1026+ XK_Greek_UPSILONaccent = 0x07a8, // U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS
1027+ XK_Greek_UPSILONdieresis = 0x07a9, // U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
1028+ XK_Greek_OMEGAaccent = 0x07ab, // U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS
1029+ XK_Greek_accentdieresis = 0x07ae, // U+0385 GREEK DIALYTIKA TONOS
1030+ XK_Greek_horizbar = 0x07af, // U+2015 HORIZONTAL BAR
1031+ XK_Greek_alphaaccent = 0x07b1, // U+03AC GREEK SMALL LETTER ALPHA WITH TONOS
1032+ XK_Greek_epsilonaccent = 0x07b2, // U+03AD GREEK SMALL LETTER EPSILON WITH TONOS
1033+ XK_Greek_etaaccent = 0x07b3, // U+03AE GREEK SMALL LETTER ETA WITH TONOS
1034+ XK_Greek_iotaaccent = 0x07b4, // U+03AF GREEK SMALL LETTER IOTA WITH TONOS
1035+ XK_Greek_iotadieresis = 0x07b5, // U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA
1036+ XK_Greek_iotaaccentdieresis = 0x07b6, // U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
1037+ XK_Greek_omicronaccent = 0x07b7, // U+03CC GREEK SMALL LETTER OMICRON WITH TONOS
1038+ XK_Greek_upsilonaccent = 0x07b8, // U+03CD GREEK SMALL LETTER UPSILON WITH TONOS
1039+ XK_Greek_upsilondieresis = 0x07b9, // U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA
1040+ XK_Greek_upsilonaccentdieresis = 0x07ba, // U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
1041+ XK_Greek_omegaaccent = 0x07bb, // U+03CE GREEK SMALL LETTER OMEGA WITH TONOS
1042+ XK_Greek_ALPHA = 0x07c1, // U+0391 GREEK CAPITAL LETTER ALPHA
1043+ XK_Greek_BETA = 0x07c2, // U+0392 GREEK CAPITAL LETTER BETA
1044+ XK_Greek_GAMMA = 0x07c3, // U+0393 GREEK CAPITAL LETTER GAMMA
1045+ XK_Greek_DELTA = 0x07c4, // U+0394 GREEK CAPITAL LETTER DELTA
1046+ XK_Greek_EPSILON = 0x07c5, // U+0395 GREEK CAPITAL LETTER EPSILON
1047+ XK_Greek_ZETA = 0x07c6, // U+0396 GREEK CAPITAL LETTER ZETA
1048+ XK_Greek_ETA = 0x07c7, // U+0397 GREEK CAPITAL LETTER ETA
1049+ XK_Greek_THETA = 0x07c8, // U+0398 GREEK CAPITAL LETTER THETA
1050+ XK_Greek_IOTA = 0x07c9, // U+0399 GREEK CAPITAL LETTER IOTA
1051+ XK_Greek_KAPPA = 0x07ca, // U+039A GREEK CAPITAL LETTER KAPPA
1052+ XK_Greek_LAMDA = 0x07cb, // U+039B GREEK CAPITAL LETTER LAMDA
1053+ // XK_Greek_LAMBDA = 0x07cb, // non-deprecated alias for Greek_LAMDA
1054+ XK_Greek_MU = 0x07cc, // U+039C GREEK CAPITAL LETTER MU
1055+ XK_Greek_NU = 0x07cd, // U+039D GREEK CAPITAL LETTER NU
1056+ XK_Greek_XI = 0x07ce, // U+039E GREEK CAPITAL LETTER XI
1057+ XK_Greek_OMICRON = 0x07cf, // U+039F GREEK CAPITAL LETTER OMICRON
1058+ XK_Greek_PI = 0x07d0, // U+03A0 GREEK CAPITAL LETTER PI
1059+ XK_Greek_RHO = 0x07d1, // U+03A1 GREEK CAPITAL LETTER RHO
1060+ XK_Greek_SIGMA = 0x07d2, // U+03A3 GREEK CAPITAL LETTER SIGMA
1061+ XK_Greek_TAU = 0x07d4, // U+03A4 GREEK CAPITAL LETTER TAU
1062+ XK_Greek_UPSILON = 0x07d5, // U+03A5 GREEK CAPITAL LETTER UPSILON
1063+ XK_Greek_PHI = 0x07d6, // U+03A6 GREEK CAPITAL LETTER PHI
1064+ XK_Greek_CHI = 0x07d7, // U+03A7 GREEK CAPITAL LETTER CHI
1065+ XK_Greek_PSI = 0x07d8, // U+03A8 GREEK CAPITAL LETTER PSI
1066+ XK_Greek_OMEGA = 0x07d9, // U+03A9 GREEK CAPITAL LETTER OMEGA
1067+ XK_Greek_alpha = 0x07e1, // U+03B1 GREEK SMALL LETTER ALPHA
1068+ XK_Greek_beta = 0x07e2, // U+03B2 GREEK SMALL LETTER BETA
1069+ XK_Greek_gamma = 0x07e3, // U+03B3 GREEK SMALL LETTER GAMMA
1070+ XK_Greek_delta = 0x07e4, // U+03B4 GREEK SMALL LETTER DELTA
1071+ XK_Greek_epsilon = 0x07e5, // U+03B5 GREEK SMALL LETTER EPSILON
1072+ XK_Greek_zeta = 0x07e6, // U+03B6 GREEK SMALL LETTER ZETA
1073+ XK_Greek_eta = 0x07e7, // U+03B7 GREEK SMALL LETTER ETA
1074+ XK_Greek_theta = 0x07e8, // U+03B8 GREEK SMALL LETTER THETA
1075+ XK_Greek_iota = 0x07e9, // U+03B9 GREEK SMALL LETTER IOTA
1076+ XK_Greek_kappa = 0x07ea, // U+03BA GREEK SMALL LETTER KAPPA
1077+ XK_Greek_lamda = 0x07eb, // U+03BB GREEK SMALL LETTER LAMDA
1078+ // XK_Greek_lambda = 0x07eb, // non-deprecated alias for Greek_lamda
1079+ XK_Greek_mu = 0x07ec, // U+03BC GREEK SMALL LETTER MU
1080+ XK_Greek_nu = 0x07ed, // U+03BD GREEK SMALL LETTER NU
1081+ XK_Greek_xi = 0x07ee, // U+03BE GREEK SMALL LETTER XI
1082+ XK_Greek_omicron = 0x07ef, // U+03BF GREEK SMALL LETTER OMICRON
1083+ XK_Greek_pi = 0x07f0, // U+03C0 GREEK SMALL LETTER PI
1084+ XK_Greek_rho = 0x07f1, // U+03C1 GREEK SMALL LETTER RHO
1085+ XK_Greek_sigma = 0x07f2, // U+03C3 GREEK SMALL LETTER SIGMA
1086+ XK_Greek_finalsmallsigma = 0x07f3, // U+03C2 GREEK SMALL LETTER FINAL SIGMA
1087+ XK_Greek_tau = 0x07f4, // U+03C4 GREEK SMALL LETTER TAU
1088+ XK_Greek_upsilon = 0x07f5, // U+03C5 GREEK SMALL LETTER UPSILON
1089+ XK_Greek_phi = 0x07f6, // U+03C6 GREEK SMALL LETTER PHI
1090+ XK_Greek_chi = 0x07f7, // U+03C7 GREEK SMALL LETTER CHI
1091+ XK_Greek_psi = 0x07f8, // U+03C8 GREEK SMALL LETTER PSI
1092+ XK_Greek_omega = 0x07f9, // U+03C9 GREEK SMALL LETTER OMEGA
1093+ // XK_Greek_switch = 0xff7e, // non-deprecated alias for Mode_switch
1094+
1095+ XK_leftradical = 0x08a1, // U+23B7 RADICAL SYMBOL BOTTOM
1096+ XK_topleftradical = 0x08a2, // (U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)
1097+ XK_horizconnector = 0x08a3, // (U+2500 BOX DRAWINGS LIGHT HORIZONTAL)
1098+ XK_topintegral = 0x08a4, // U+2320 TOP HALF INTEGRAL
1099+ XK_botintegral = 0x08a5, // U+2321 BOTTOM HALF INTEGRAL
1100+ XK_vertconnector = 0x08a6, // (U+2502 BOX DRAWINGS LIGHT VERTICAL)
1101+ XK_topleftsqbracket = 0x08a7, // U+23A1 LEFT SQUARE BRACKET UPPER CORNER
1102+ XK_botleftsqbracket = 0x08a8, // U+23A3 LEFT SQUARE BRACKET LOWER CORNER
1103+ XK_toprightsqbracket = 0x08a9, // U+23A4 RIGHT SQUARE BRACKET UPPER CORNER
1104+ XK_botrightsqbracket = 0x08aa, // U+23A6 RIGHT SQUARE BRACKET LOWER CORNER
1105+ XK_topleftparens = 0x08ab, // U+239B LEFT PARENTHESIS UPPER HOOK
1106+ XK_botleftparens = 0x08ac, // U+239D LEFT PARENTHESIS LOWER HOOK
1107+ XK_toprightparens = 0x08ad, // U+239E RIGHT PARENTHESIS UPPER HOOK
1108+ XK_botrightparens = 0x08ae, // U+23A0 RIGHT PARENTHESIS LOWER HOOK
1109+ XK_leftmiddlecurlybrace = 0x08af, // U+23A8 LEFT CURLY BRACKET MIDDLE PIECE
1110+ XK_rightmiddlecurlybrace = 0x08b0, // U+23AC RIGHT CURLY BRACKET MIDDLE PIECE
1111+ XK_topleftsummation = 0x08b1,
1112+ XK_botleftsummation = 0x08b2,
1113+ XK_topvertsummationconnector = 0x08b3,
1114+ XK_botvertsummationconnector = 0x08b4,
1115+ XK_toprightsummation = 0x08b5,
1116+ XK_botrightsummation = 0x08b6,
1117+ XK_rightmiddlesummation = 0x08b7,
1118+ XK_lessthanequal = 0x08bc, // U+2264 LESS-THAN OR EQUAL TO
1119+ XK_notequal = 0x08bd, // U+2260 NOT EQUAL TO
1120+ XK_greaterthanequal = 0x08be, // U+2265 GREATER-THAN OR EQUAL TO
1121+ XK_integral = 0x08bf, // U+222B INTEGRAL
1122+ XK_therefore = 0x08c0, // U+2234 THEREFORE
1123+ XK_variation = 0x08c1, // U+221D PROPORTIONAL TO
1124+ XK_infinity = 0x08c2, // U+221E INFINITY
1125+ XK_nabla = 0x08c5, // U+2207 NABLA
1126+ XK_approximate = 0x08c8, // U+223C TILDE OPERATOR
1127+ XK_similarequal = 0x08c9, // U+2243 ASYMPTOTICALLY EQUAL TO
1128+ XK_ifonlyif = 0x08cd, // U+21D4 LEFT RIGHT DOUBLE ARROW
1129+ XK_implies = 0x08ce, // U+21D2 RIGHTWARDS DOUBLE ARROW
1130+ XK_identical = 0x08cf, // U+2261 IDENTICAL TO
1131+ XK_radical = 0x08d6, // U+221A SQUARE ROOT
1132+ XK_includedin = 0x08da, // U+2282 SUBSET OF
1133+ XK_includes = 0x08db, // U+2283 SUPERSET OF
1134+ XK_intersection = 0x08dc, // U+2229 INTERSECTION
1135+ XK_union = 0x08dd, // U+222A UNION
1136+ XK_logicaland = 0x08de, // U+2227 LOGICAL AND
1137+ XK_logicalor = 0x08df, // U+2228 LOGICAL OR
1138+ XK_partialderivative = 0x08ef, // U+2202 PARTIAL DIFFERENTIAL
1139+ XK_function = 0x08f6, // U+0192 LATIN SMALL LETTER F WITH HOOK
1140+ XK_leftarrow = 0x08fb, // U+2190 LEFTWARDS ARROW
1141+ XK_uparrow = 0x08fc, // U+2191 UPWARDS ARROW
1142+ XK_rightarrow = 0x08fd, // U+2192 RIGHTWARDS ARROW
1143+ XK_downarrow = 0x08fe, // U+2193 DOWNWARDS ARROW
1144+
1145+ XK_blank = 0x09df,
1146+ XK_soliddiamond = 0x09e0, // U+25C6 BLACK DIAMOND
1147+ XK_checkerboard = 0x09e1, // U+2592 MEDIUM SHADE
1148+ XK_ht = 0x09e2, // U+2409 SYMBOL FOR HORIZONTAL TABULATION
1149+ XK_ff = 0x09e3, // U+240C SYMBOL FOR FORM FEED
1150+ XK_cr = 0x09e4, // U+240D SYMBOL FOR CARRIAGE RETURN
1151+ XK_lf = 0x09e5, // U+240A SYMBOL FOR LINE FEED
1152+ XK_nl = 0x09e8, // U+2424 SYMBOL FOR NEWLINE
1153+ XK_vt = 0x09e9, // U+240B SYMBOL FOR VERTICAL TABULATION
1154+ XK_lowrightcorner = 0x09ea, // U+2518 BOX DRAWINGS LIGHT UP AND LEFT
1155+ XK_uprightcorner = 0x09eb, // U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT
1156+ XK_upleftcorner = 0x09ec, // U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT
1157+ XK_lowleftcorner = 0x09ed, // U+2514 BOX DRAWINGS LIGHT UP AND RIGHT
1158+ XK_crossinglines = 0x09ee, // U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
1159+ XK_horizlinescan1 = 0x09ef, // U+23BA HORIZONTAL SCAN LINE-1
1160+ XK_horizlinescan3 = 0x09f0, // U+23BB HORIZONTAL SCAN LINE-3
1161+ XK_horizlinescan5 = 0x09f1, // U+2500 BOX DRAWINGS LIGHT HORIZONTAL
1162+ XK_horizlinescan7 = 0x09f2, // U+23BC HORIZONTAL SCAN LINE-7
1163+ XK_horizlinescan9 = 0x09f3, // U+23BD HORIZONTAL SCAN LINE-9
1164+ XK_leftt = 0x09f4, // U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT
1165+ XK_rightt = 0x09f5, // U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT
1166+ XK_bott = 0x09f6, // U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL
1167+ XK_topt = 0x09f7, // U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
1168+ XK_vertbar = 0x09f8, // U+2502 BOX DRAWINGS LIGHT VERTICAL
1169+
1170+ XK_emspace = 0x0aa1, // U+2003 EM SPACE
1171+ XK_enspace = 0x0aa2, // U+2002 EN SPACE
1172+ XK_em3space = 0x0aa3, // U+2004 THREE-PER-EM SPACE
1173+ XK_em4space = 0x0aa4, // U+2005 FOUR-PER-EM SPACE
1174+ XK_digitspace = 0x0aa5, // U+2007 FIGURE SPACE
1175+ XK_punctspace = 0x0aa6, // U+2008 PUNCTUATION SPACE
1176+ XK_thinspace = 0x0aa7, // U+2009 THIN SPACE
1177+ XK_hairspace = 0x0aa8, // U+200A HAIR SPACE
1178+ XK_emdash = 0x0aa9, // U+2014 EM DASH
1179+ XK_endash = 0x0aaa, // U+2013 EN DASH
1180+ XK_signifblank = 0x0aac, // (U+2423 OPEN BOX)
1181+ XK_ellipsis = 0x0aae, // U+2026 HORIZONTAL ELLIPSIS
1182+ XK_doubbaselinedot = 0x0aaf, // U+2025 TWO DOT LEADER
1183+ XK_onethird = 0x0ab0, // U+2153 VULGAR FRACTION ONE THIRD
1184+ XK_twothirds = 0x0ab1, // U+2154 VULGAR FRACTION TWO THIRDS
1185+ XK_onefifth = 0x0ab2, // U+2155 VULGAR FRACTION ONE FIFTH
1186+ XK_twofifths = 0x0ab3, // U+2156 VULGAR FRACTION TWO FIFTHS
1187+ XK_threefifths = 0x0ab4, // U+2157 VULGAR FRACTION THREE FIFTHS
1188+ XK_fourfifths = 0x0ab5, // U+2158 VULGAR FRACTION FOUR FIFTHS
1189+ XK_onesixth = 0x0ab6, // U+2159 VULGAR FRACTION ONE SIXTH
1190+ XK_fivesixths = 0x0ab7, // U+215A VULGAR FRACTION FIVE SIXTHS
1191+ XK_careof = 0x0ab8, // U+2105 CARE OF
1192+ XK_figdash = 0x0abb, // U+2012 FIGURE DASH
1193+ XK_leftanglebracket = 0x0abc, // (U+2329 LEFT-POINTING ANGLE BRACKET)
1194+ XK_decimalpoint = 0x0abd, // (U+002E FULL STOP)
1195+ XK_rightanglebracket = 0x0abe, // (U+232A RIGHT-POINTING ANGLE BRACKET)
1196+ XK_marker = 0x0abf,
1197+ XK_oneeighth = 0x0ac3, // U+215B VULGAR FRACTION ONE EIGHTH
1198+ XK_threeeighths = 0x0ac4, // U+215C VULGAR FRACTION THREE EIGHTHS
1199+ XK_fiveeighths = 0x0ac5, // U+215D VULGAR FRACTION FIVE EIGHTHS
1200+ XK_seveneighths = 0x0ac6, // U+215E VULGAR FRACTION SEVEN EIGHTHS
1201+ XK_trademark = 0x0ac9, // U+2122 TRADE MARK SIGN
1202+ XK_signaturemark = 0x0aca, // (U+2613 SALTIRE)
1203+ XK_trademarkincircle = 0x0acb,
1204+ XK_leftopentriangle = 0x0acc, // (U+25C1 WHITE LEFT-POINTING TRIANGLE)
1205+ XK_rightopentriangle = 0x0acd, // (U+25B7 WHITE RIGHT-POINTING TRIANGLE)
1206+ XK_emopencircle = 0x0ace, // (U+25CB WHITE CIRCLE)
1207+ XK_emopenrectangle = 0x0acf, // (U+25AF WHITE VERTICAL RECTANGLE)
1208+ XK_leftsinglequotemark = 0x0ad0, // U+2018 LEFT SINGLE QUOTATION MARK
1209+ XK_rightsinglequotemark = 0x0ad1, // U+2019 RIGHT SINGLE QUOTATION MARK
1210+ XK_leftdoublequotemark = 0x0ad2, // U+201C LEFT DOUBLE QUOTATION MARK
1211+ XK_rightdoublequotemark = 0x0ad3, // U+201D RIGHT DOUBLE QUOTATION MARK
1212+ XK_prescription = 0x0ad4, // U+211E PRESCRIPTION TAKE
1213+ XK_permille = 0x0ad5, // U+2030 PER MILLE SIGN
1214+ XK_minutes = 0x0ad6, // U+2032 PRIME
1215+ XK_seconds = 0x0ad7, // U+2033 DOUBLE PRIME
1216+ XK_latincross = 0x0ad9, // U+271D LATIN CROSS
1217+ XK_hexagram = 0x0ada,
1218+ XK_filledrectbullet = 0x0adb, // (U+25AC BLACK RECTANGLE)
1219+ XK_filledlefttribullet = 0x0adc, // (U+25C0 BLACK LEFT-POINTING TRIANGLE)
1220+ XK_filledrighttribullet = 0x0add, // (U+25B6 BLACK RIGHT-POINTING TRIANGLE)
1221+ XK_emfilledcircle = 0x0ade, // (U+25CF BLACK CIRCLE)
1222+ XK_emfilledrect = 0x0adf, // (U+25AE BLACK VERTICAL RECTANGLE)
1223+ XK_enopencircbullet = 0x0ae0, // (U+25E6 WHITE BULLET)
1224+ XK_enopensquarebullet = 0x0ae1, // (U+25AB WHITE SMALL SQUARE)
1225+ XK_openrectbullet = 0x0ae2, // (U+25AD WHITE RECTANGLE)
1226+ XK_opentribulletup = 0x0ae3, // (U+25B3 WHITE UP-POINTING TRIANGLE)
1227+ XK_opentribulletdown = 0x0ae4, // (U+25BD WHITE DOWN-POINTING TRIANGLE)
1228+ XK_openstar = 0x0ae5, // (U+2606 WHITE STAR)
1229+ XK_enfilledcircbullet = 0x0ae6, // (U+2022 BULLET)
1230+ XK_enfilledsqbullet = 0x0ae7, // (U+25AA BLACK SMALL SQUARE)
1231+ XK_filledtribulletup = 0x0ae8, // (U+25B2 BLACK UP-POINTING TRIANGLE)
1232+ XK_filledtribulletdown = 0x0ae9, // (U+25BC BLACK DOWN-POINTING TRIANGLE)
1233+ XK_leftpointer = 0x0aea, // (U+261C WHITE LEFT POINTING INDEX)
1234+ XK_rightpointer = 0x0aeb, // (U+261E WHITE RIGHT POINTING INDEX)
1235+ XK_club = 0x0aec, // U+2663 BLACK CLUB SUIT
1236+ XK_diamond = 0x0aed, // U+2666 BLACK DIAMOND SUIT
1237+ XK_heart = 0x0aee, // U+2665 BLACK HEART SUIT
1238+ XK_maltesecross = 0x0af0, // U+2720 MALTESE CROSS
1239+ XK_dagger = 0x0af1, // U+2020 DAGGER
1240+ XK_doubledagger = 0x0af2, // U+2021 DOUBLE DAGGER
1241+ XK_checkmark = 0x0af3, // U+2713 CHECK MARK
1242+ XK_ballotcross = 0x0af4, // U+2717 BALLOT X
1243+ XK_musicalsharp = 0x0af5, // U+266F MUSIC SHARP SIGN
1244+ XK_musicalflat = 0x0af6, // U+266D MUSIC FLAT SIGN
1245+ XK_malesymbol = 0x0af7, // U+2642 MALE SIGN
1246+ XK_femalesymbol = 0x0af8, // U+2640 FEMALE SIGN
1247+ XK_telephone = 0x0af9, // U+260E BLACK TELEPHONE
1248+ XK_telephonerecorder = 0x0afa, // U+2315 TELEPHONE RECORDER
1249+ XK_phonographcopyright = 0x0afb, // U+2117 SOUND RECORDING COPYRIGHT
1250+ XK_caret = 0x0afc, // U+2038 CARET
1251+ XK_singlelowquotemark = 0x0afd, // U+201A SINGLE LOW-9 QUOTATION MARK
1252+ XK_doublelowquotemark = 0x0afe, // U+201E DOUBLE LOW-9 QUOTATION MARK
1253+ XK_cursor = 0x0aff,
1254+
1255+ XK_leftcaret = 0x0ba3, // (U+003C LESS-THAN SIGN)
1256+ XK_rightcaret = 0x0ba6, // (U+003E GREATER-THAN SIGN)
1257+ XK_downcaret = 0x0ba8, // (U+2228 LOGICAL OR)
1258+ XK_upcaret = 0x0ba9, // (U+2227 LOGICAL AND)
1259+ XK_overbar = 0x0bc0, // (U+00AF MACRON)
1260+ XK_downtack = 0x0bc2, // U+22A4 DOWN TACK
1261+ XK_upshoe = 0x0bc3, // (U+2229 INTERSECTION)
1262+ XK_downstile = 0x0bc4, // U+230A LEFT FLOOR
1263+ XK_underbar = 0x0bc6, // (U+005F LOW LINE)
1264+ XK_jot = 0x0bca, // U+2218 RING OPERATOR
1265+ XK_quad = 0x0bcc, // U+2395 APL FUNCTIONAL SYMBOL QUAD
1266+ XK_uptack = 0x0bce, // U+22A5 UP TACK
1267+ XK_circle = 0x0bcf, // U+25CB WHITE CIRCLE
1268+ XK_upstile = 0x0bd3, // U+2308 LEFT CEILING
1269+ XK_downshoe = 0x0bd6, // (U+222A UNION)
1270+ XK_rightshoe = 0x0bd8, // (U+2283 SUPERSET OF)
1271+ XK_leftshoe = 0x0bda, // (U+2282 SUBSET OF)
1272+ XK_lefttack = 0x0bdc, // U+22A3 LEFT TACK
1273+ XK_righttack = 0x0bfc, // U+22A2 RIGHT TACK
1274+
1275+ XK_hebrew_doublelowline = 0x0cdf, // U+2017 DOUBLE LOW LINE
1276+ XK_hebrew_aleph = 0x0ce0, // U+05D0 HEBREW LETTER ALEF
1277+ XK_hebrew_bet = 0x0ce1, // U+05D1 HEBREW LETTER BET
1278+ // XK_hebrew_beth = 0x0ce1, // deprecated
1279+ XK_hebrew_gimel = 0x0ce2, // U+05D2 HEBREW LETTER GIMEL
1280+ // XK_hebrew_gimmel = 0x0ce2, // deprecated
1281+ XK_hebrew_dalet = 0x0ce3, // U+05D3 HEBREW LETTER DALET
1282+ // XK_hebrew_daleth = 0x0ce3, // deprecated
1283+ XK_hebrew_he = 0x0ce4, // U+05D4 HEBREW LETTER HE
1284+ XK_hebrew_waw = 0x0ce5, // U+05D5 HEBREW LETTER VAV
1285+ XK_hebrew_zain = 0x0ce6, // U+05D6 HEBREW LETTER ZAYIN
1286+ // XK_hebrew_zayin = 0x0ce6, // deprecated
1287+ XK_hebrew_chet = 0x0ce7, // U+05D7 HEBREW LETTER HET
1288+ // XK_hebrew_het = 0x0ce7, // deprecated
1289+ XK_hebrew_tet = 0x0ce8, // U+05D8 HEBREW LETTER TET
1290+ // XK_hebrew_teth = 0x0ce8, // deprecated
1291+ XK_hebrew_yod = 0x0ce9, // U+05D9 HEBREW LETTER YOD
1292+ XK_hebrew_finalkaph = 0x0cea, // U+05DA HEBREW LETTER FINAL KAF
1293+ XK_hebrew_kaph = 0x0ceb, // U+05DB HEBREW LETTER KAF
1294+ XK_hebrew_lamed = 0x0cec, // U+05DC HEBREW LETTER LAMED
1295+ XK_hebrew_finalmem = 0x0ced, // U+05DD HEBREW LETTER FINAL MEM
1296+ XK_hebrew_mem = 0x0cee, // U+05DE HEBREW LETTER MEM
1297+ XK_hebrew_finalnun = 0x0cef, // U+05DF HEBREW LETTER FINAL NUN
1298+ XK_hebrew_nun = 0x0cf0, // U+05E0 HEBREW LETTER NUN
1299+ XK_hebrew_samech = 0x0cf1, // U+05E1 HEBREW LETTER SAMEKH
1300+ // XK_hebrew_samekh = 0x0cf1, // deprecated
1301+ XK_hebrew_ayin = 0x0cf2, // U+05E2 HEBREW LETTER AYIN
1302+ XK_hebrew_finalpe = 0x0cf3, // U+05E3 HEBREW LETTER FINAL PE
1303+ XK_hebrew_pe = 0x0cf4, // U+05E4 HEBREW LETTER PE
1304+ XK_hebrew_finalzade = 0x0cf5, // U+05E5 HEBREW LETTER FINAL TSADI
1305+ // XK_hebrew_finalzadi = 0x0cf5, // deprecated
1306+ XK_hebrew_zade = 0x0cf6, // U+05E6 HEBREW LETTER TSADI
1307+ // XK_hebrew_zadi = 0x0cf6, // deprecated
1308+ XK_hebrew_qoph = 0x0cf7, // U+05E7 HEBREW LETTER QOF
1309+ // XK_hebrew_kuf = 0x0cf7, // deprecated
1310+ XK_hebrew_resh = 0x0cf8, // U+05E8 HEBREW LETTER RESH
1311+ XK_hebrew_shin = 0x0cf9, // U+05E9 HEBREW LETTER SHIN
1312+ XK_hebrew_taw = 0x0cfa, // U+05EA HEBREW LETTER TAV
1313+ // XK_hebrew_taf = 0x0cfa, // deprecated
1314+ // XK_Hebrew_switch = 0xff7e, // non-deprecated alias for Mode_switch
1315+
1316+ XK_Thai_kokai = 0x0da1, // U+0E01 THAI CHARACTER KO KAI
1317+ XK_Thai_khokhai = 0x0da2, // U+0E02 THAI CHARACTER KHO KHAI
1318+ XK_Thai_khokhuat = 0x0da3, // U+0E03 THAI CHARACTER KHO KHUAT
1319+ XK_Thai_khokhwai = 0x0da4, // U+0E04 THAI CHARACTER KHO KHWAI
1320+ XK_Thai_khokhon = 0x0da5, // U+0E05 THAI CHARACTER KHO KHON
1321+ XK_Thai_khorakhang = 0x0da6, // U+0E06 THAI CHARACTER KHO RAKHANG
1322+ XK_Thai_ngongu = 0x0da7, // U+0E07 THAI CHARACTER NGO NGU
1323+ XK_Thai_chochan = 0x0da8, // U+0E08 THAI CHARACTER CHO CHAN
1324+ XK_Thai_choching = 0x0da9, // U+0E09 THAI CHARACTER CHO CHING
1325+ XK_Thai_chochang = 0x0daa, // U+0E0A THAI CHARACTER CHO CHANG
1326+ XK_Thai_soso = 0x0dab, // U+0E0B THAI CHARACTER SO SO
1327+ XK_Thai_chochoe = 0x0dac, // U+0E0C THAI CHARACTER CHO CHOE
1328+ XK_Thai_yoying = 0x0dad, // U+0E0D THAI CHARACTER YO YING
1329+ XK_Thai_dochada = 0x0dae, // U+0E0E THAI CHARACTER DO CHADA
1330+ XK_Thai_topatak = 0x0daf, // U+0E0F THAI CHARACTER TO PATAK
1331+ XK_Thai_thothan = 0x0db0, // U+0E10 THAI CHARACTER THO THAN
1332+ XK_Thai_thonangmontho = 0x0db1, // U+0E11 THAI CHARACTER THO NANGMONTHO
1333+ XK_Thai_thophuthao = 0x0db2, // U+0E12 THAI CHARACTER THO PHUTHAO
1334+ XK_Thai_nonen = 0x0db3, // U+0E13 THAI CHARACTER NO NEN
1335+ XK_Thai_dodek = 0x0db4, // U+0E14 THAI CHARACTER DO DEK
1336+ XK_Thai_totao = 0x0db5, // U+0E15 THAI CHARACTER TO TAO
1337+ XK_Thai_thothung = 0x0db6, // U+0E16 THAI CHARACTER THO THUNG
1338+ XK_Thai_thothahan = 0x0db7, // U+0E17 THAI CHARACTER THO THAHAN
1339+ XK_Thai_thothong = 0x0db8, // U+0E18 THAI CHARACTER THO THONG
1340+ XK_Thai_nonu = 0x0db9, // U+0E19 THAI CHARACTER NO NU
1341+ XK_Thai_bobaimai = 0x0dba, // U+0E1A THAI CHARACTER BO BAIMAI
1342+ XK_Thai_popla = 0x0dbb, // U+0E1B THAI CHARACTER PO PLA
1343+ XK_Thai_phophung = 0x0dbc, // U+0E1C THAI CHARACTER PHO PHUNG
1344+ XK_Thai_fofa = 0x0dbd, // U+0E1D THAI CHARACTER FO FA
1345+ XK_Thai_phophan = 0x0dbe, // U+0E1E THAI CHARACTER PHO PHAN
1346+ XK_Thai_fofan = 0x0dbf, // U+0E1F THAI CHARACTER FO FAN
1347+ XK_Thai_phosamphao = 0x0dc0, // U+0E20 THAI CHARACTER PHO SAMPHAO
1348+ XK_Thai_moma = 0x0dc1, // U+0E21 THAI CHARACTER MO MA
1349+ XK_Thai_yoyak = 0x0dc2, // U+0E22 THAI CHARACTER YO YAK
1350+ XK_Thai_rorua = 0x0dc3, // U+0E23 THAI CHARACTER RO RUA
1351+ XK_Thai_ru = 0x0dc4, // U+0E24 THAI CHARACTER RU
1352+ XK_Thai_loling = 0x0dc5, // U+0E25 THAI CHARACTER LO LING
1353+ XK_Thai_lu = 0x0dc6, // U+0E26 THAI CHARACTER LU
1354+ XK_Thai_wowaen = 0x0dc7, // U+0E27 THAI CHARACTER WO WAEN
1355+ XK_Thai_sosala = 0x0dc8, // U+0E28 THAI CHARACTER SO SALA
1356+ XK_Thai_sorusi = 0x0dc9, // U+0E29 THAI CHARACTER SO RUSI
1357+ XK_Thai_sosua = 0x0dca, // U+0E2A THAI CHARACTER SO SUA
1358+ XK_Thai_hohip = 0x0dcb, // U+0E2B THAI CHARACTER HO HIP
1359+ XK_Thai_lochula = 0x0dcc, // U+0E2C THAI CHARACTER LO CHULA
1360+ XK_Thai_oang = 0x0dcd, // U+0E2D THAI CHARACTER O ANG
1361+ XK_Thai_honokhuk = 0x0dce, // U+0E2E THAI CHARACTER HO NOKHUK
1362+ XK_Thai_paiyannoi = 0x0dcf, // U+0E2F THAI CHARACTER PAIYANNOI
1363+ XK_Thai_saraa = 0x0dd0, // U+0E30 THAI CHARACTER SARA A
1364+ XK_Thai_maihanakat = 0x0dd1, // U+0E31 THAI CHARACTER MAI HAN-AKAT
1365+ XK_Thai_saraaa = 0x0dd2, // U+0E32 THAI CHARACTER SARA AA
1366+ XK_Thai_saraam = 0x0dd3, // U+0E33 THAI CHARACTER SARA AM
1367+ XK_Thai_sarai = 0x0dd4, // U+0E34 THAI CHARACTER SARA I
1368+ XK_Thai_saraii = 0x0dd5, // U+0E35 THAI CHARACTER SARA II
1369+ XK_Thai_saraue = 0x0dd6, // U+0E36 THAI CHARACTER SARA UE
1370+ XK_Thai_sarauee = 0x0dd7, // U+0E37 THAI CHARACTER SARA UEE
1371+ XK_Thai_sarau = 0x0dd8, // U+0E38 THAI CHARACTER SARA U
1372+ XK_Thai_sarauu = 0x0dd9, // U+0E39 THAI CHARACTER SARA UU
1373+ XK_Thai_phinthu = 0x0dda, // U+0E3A THAI CHARACTER PHINTHU
1374+ XK_Thai_maihanakat_maitho = 0x0dde, // (U+0E3E Unassigned code point)
1375+ XK_Thai_baht = 0x0ddf, // U+0E3F THAI CURRENCY SYMBOL BAHT
1376+ XK_Thai_sarae = 0x0de0, // U+0E40 THAI CHARACTER SARA E
1377+ XK_Thai_saraae = 0x0de1, // U+0E41 THAI CHARACTER SARA AE
1378+ XK_Thai_sarao = 0x0de2, // U+0E42 THAI CHARACTER SARA O
1379+ XK_Thai_saraaimaimuan = 0x0de3, // U+0E43 THAI CHARACTER SARA AI MAIMUAN
1380+ XK_Thai_saraaimaimalai = 0x0de4, // U+0E44 THAI CHARACTER SARA AI MAIMALAI
1381+ XK_Thai_lakkhangyao = 0x0de5, // U+0E45 THAI CHARACTER LAKKHANGYAO
1382+ XK_Thai_maiyamok = 0x0de6, // U+0E46 THAI CHARACTER MAIYAMOK
1383+ XK_Thai_maitaikhu = 0x0de7, // U+0E47 THAI CHARACTER MAITAIKHU
1384+ XK_Thai_maiek = 0x0de8, // U+0E48 THAI CHARACTER MAI EK
1385+ XK_Thai_maitho = 0x0de9, // U+0E49 THAI CHARACTER MAI THO
1386+ XK_Thai_maitri = 0x0dea, // U+0E4A THAI CHARACTER MAI TRI
1387+ XK_Thai_maichattawa = 0x0deb, // U+0E4B THAI CHARACTER MAI CHATTAWA
1388+ XK_Thai_thanthakhat = 0x0dec, // U+0E4C THAI CHARACTER THANTHAKHAT
1389+ XK_Thai_nikhahit = 0x0ded, // U+0E4D THAI CHARACTER NIKHAHIT
1390+ XK_Thai_leksun = 0x0df0, // U+0E50 THAI DIGIT ZERO
1391+ XK_Thai_leknung = 0x0df1, // U+0E51 THAI DIGIT ONE
1392+ XK_Thai_leksong = 0x0df2, // U+0E52 THAI DIGIT TWO
1393+ XK_Thai_leksam = 0x0df3, // U+0E53 THAI DIGIT THREE
1394+ XK_Thai_leksi = 0x0df4, // U+0E54 THAI DIGIT FOUR
1395+ XK_Thai_lekha = 0x0df5, // U+0E55 THAI DIGIT FIVE
1396+ XK_Thai_lekhok = 0x0df6, // U+0E56 THAI DIGIT SIX
1397+ XK_Thai_lekchet = 0x0df7, // U+0E57 THAI DIGIT SEVEN
1398+ XK_Thai_lekpaet = 0x0df8, // U+0E58 THAI DIGIT EIGHT
1399+ XK_Thai_lekkao = 0x0df9, // U+0E59 THAI DIGIT NINE
1400+
1401+ XK_Hangul = 0xff31, // Hangul start/stop(toggle)
1402+ XK_Hangul_Start = 0xff32, // Hangul start
1403+ XK_Hangul_End = 0xff33, // Hangul end, English start
1404+ XK_Hangul_Hanja = 0xff34, // Start Hangul->Hanja Conversion
1405+ XK_Hangul_Jamo = 0xff35, // Hangul Jamo mode
1406+ XK_Hangul_Romaja = 0xff36, // Hangul Romaja mode
1407+ // XK_Hangul_Codeinput = 0xff37, // Hangul code input mode
1408+ XK_Hangul_Jeonja = 0xff38, // Jeonja mode
1409+ XK_Hangul_Banja = 0xff39, // Banja mode
1410+ XK_Hangul_PreHanja = 0xff3a, // Pre Hanja conversion
1411+ XK_Hangul_PostHanja = 0xff3b, // Post Hanja conversion
1412+ // XK_Hangul_SingleCandidate = 0xff3c, // Single candidate
1413+ // XK_Hangul_MultipleCandidate = 0xff3d, // Multiple candidate
1414+ // XK_Hangul_PreviousCandidate = 0xff3e, // Previous candidate
1415+ XK_Hangul_Special = 0xff3f, // Special symbols
1416+ // XK_Hangul_switch = 0xff7e, // non-deprecated alias for Mode_switch
1417+ XK_Hangul_Kiyeog = 0x0ea1, // U+3131 HANGUL LETTER KIYEOK
1418+ XK_Hangul_SsangKiyeog = 0x0ea2, // U+3132 HANGUL LETTER SSANGKIYEOK
1419+ XK_Hangul_KiyeogSios = 0x0ea3, // U+3133 HANGUL LETTER KIYEOK-SIOS
1420+ XK_Hangul_Nieun = 0x0ea4, // U+3134 HANGUL LETTER NIEUN
1421+ XK_Hangul_NieunJieuj = 0x0ea5, // U+3135 HANGUL LETTER NIEUN-CIEUC
1422+ XK_Hangul_NieunHieuh = 0x0ea6, // U+3136 HANGUL LETTER NIEUN-HIEUH
1423+ XK_Hangul_Dikeud = 0x0ea7, // U+3137 HANGUL LETTER TIKEUT
1424+ XK_Hangul_SsangDikeud = 0x0ea8, // U+3138 HANGUL LETTER SSANGTIKEUT
1425+ XK_Hangul_Rieul = 0x0ea9, // U+3139 HANGUL LETTER RIEUL
1426+ XK_Hangul_RieulKiyeog = 0x0eaa, // U+313A HANGUL LETTER RIEUL-KIYEOK
1427+ XK_Hangul_RieulMieum = 0x0eab, // U+313B HANGUL LETTER RIEUL-MIEUM
1428+ XK_Hangul_RieulPieub = 0x0eac, // U+313C HANGUL LETTER RIEUL-PIEUP
1429+ XK_Hangul_RieulSios = 0x0ead, // U+313D HANGUL LETTER RIEUL-SIOS
1430+ XK_Hangul_RieulTieut = 0x0eae, // U+313E HANGUL LETTER RIEUL-THIEUTH
1431+ XK_Hangul_RieulPhieuf = 0x0eaf, // U+313F HANGUL LETTER RIEUL-PHIEUPH
1432+ XK_Hangul_RieulHieuh = 0x0eb0, // U+3140 HANGUL LETTER RIEUL-HIEUH
1433+ XK_Hangul_Mieum = 0x0eb1, // U+3141 HANGUL LETTER MIEUM
1434+ XK_Hangul_Pieub = 0x0eb2, // U+3142 HANGUL LETTER PIEUP
1435+ XK_Hangul_SsangPieub = 0x0eb3, // U+3143 HANGUL LETTER SSANGPIEUP
1436+ XK_Hangul_PieubSios = 0x0eb4, // U+3144 HANGUL LETTER PIEUP-SIOS
1437+ XK_Hangul_Sios = 0x0eb5, // U+3145 HANGUL LETTER SIOS
1438+ XK_Hangul_SsangSios = 0x0eb6, // U+3146 HANGUL LETTER SSANGSIOS
1439+ XK_Hangul_Ieung = 0x0eb7, // U+3147 HANGUL LETTER IEUNG
1440+ XK_Hangul_Jieuj = 0x0eb8, // U+3148 HANGUL LETTER CIEUC
1441+ XK_Hangul_SsangJieuj = 0x0eb9, // U+3149 HANGUL LETTER SSANGCIEUC
1442+ XK_Hangul_Cieuc = 0x0eba, // U+314A HANGUL LETTER CHIEUCH
1443+ XK_Hangul_Khieuq = 0x0ebb, // U+314B HANGUL LETTER KHIEUKH
1444+ XK_Hangul_Tieut = 0x0ebc, // U+314C HANGUL LETTER THIEUTH
1445+ XK_Hangul_Phieuf = 0x0ebd, // U+314D HANGUL LETTER PHIEUPH
1446+ XK_Hangul_Hieuh = 0x0ebe, // U+314E HANGUL LETTER HIEUH
1447+ XK_Hangul_A = 0x0ebf, // U+314F HANGUL LETTER A
1448+ XK_Hangul_AE = 0x0ec0, // U+3150 HANGUL LETTER AE
1449+ XK_Hangul_YA = 0x0ec1, // U+3151 HANGUL LETTER YA
1450+ XK_Hangul_YAE = 0x0ec2, // U+3152 HANGUL LETTER YAE
1451+ XK_Hangul_EO = 0x0ec3, // U+3153 HANGUL LETTER EO
1452+ XK_Hangul_E = 0x0ec4, // U+3154 HANGUL LETTER E
1453+ XK_Hangul_YEO = 0x0ec5, // U+3155 HANGUL LETTER YEO
1454+ XK_Hangul_YE = 0x0ec6, // U+3156 HANGUL LETTER YE
1455+ XK_Hangul_O = 0x0ec7, // U+3157 HANGUL LETTER O
1456+ XK_Hangul_WA = 0x0ec8, // U+3158 HANGUL LETTER WA
1457+ XK_Hangul_WAE = 0x0ec9, // U+3159 HANGUL LETTER WAE
1458+ XK_Hangul_OE = 0x0eca, // U+315A HANGUL LETTER OE
1459+ XK_Hangul_YO = 0x0ecb, // U+315B HANGUL LETTER YO
1460+ XK_Hangul_U = 0x0ecc, // U+315C HANGUL LETTER U
1461+ XK_Hangul_WEO = 0x0ecd, // U+315D HANGUL LETTER WEO
1462+ XK_Hangul_WE = 0x0ece, // U+315E HANGUL LETTER WE
1463+ XK_Hangul_WI = 0x0ecf, // U+315F HANGUL LETTER WI
1464+ XK_Hangul_YU = 0x0ed0, // U+3160 HANGUL LETTER YU
1465+ XK_Hangul_EU = 0x0ed1, // U+3161 HANGUL LETTER EU
1466+ XK_Hangul_YI = 0x0ed2, // U+3162 HANGUL LETTER YI
1467+ XK_Hangul_I = 0x0ed3, // U+3163 HANGUL LETTER I
1468+ XK_Hangul_J_Kiyeog = 0x0ed4, // U+11A8 HANGUL JONGSEONG KIYEOK
1469+ XK_Hangul_J_SsangKiyeog = 0x0ed5, // U+11A9 HANGUL JONGSEONG SSANGKIYEOK
1470+ XK_Hangul_J_KiyeogSios = 0x0ed6, // U+11AA HANGUL JONGSEONG KIYEOK-SIOS
1471+ XK_Hangul_J_Nieun = 0x0ed7, // U+11AB HANGUL JONGSEONG NIEUN
1472+ XK_Hangul_J_NieunJieuj = 0x0ed8, // U+11AC HANGUL JONGSEONG NIEUN-CIEUC
1473+ XK_Hangul_J_NieunHieuh = 0x0ed9, // U+11AD HANGUL JONGSEONG NIEUN-HIEUH
1474+ XK_Hangul_J_Dikeud = 0x0eda, // U+11AE HANGUL JONGSEONG TIKEUT
1475+ XK_Hangul_J_Rieul = 0x0edb, // U+11AF HANGUL JONGSEONG RIEUL
1476+ XK_Hangul_J_RieulKiyeog = 0x0edc, // U+11B0 HANGUL JONGSEONG RIEUL-KIYEOK
1477+ XK_Hangul_J_RieulMieum = 0x0edd, // U+11B1 HANGUL JONGSEONG RIEUL-MIEUM
1478+ XK_Hangul_J_RieulPieub = 0x0ede, // U+11B2 HANGUL JONGSEONG RIEUL-PIEUP
1479+ XK_Hangul_J_RieulSios = 0x0edf, // U+11B3 HANGUL JONGSEONG RIEUL-SIOS
1480+ XK_Hangul_J_RieulTieut = 0x0ee0, // U+11B4 HANGUL JONGSEONG RIEUL-THIEUTH
1481+ XK_Hangul_J_RieulPhieuf = 0x0ee1, // U+11B5 HANGUL JONGSEONG RIEUL-PHIEUPH
1482+ XK_Hangul_J_RieulHieuh = 0x0ee2, // U+11B6 HANGUL JONGSEONG RIEUL-HIEUH
1483+ XK_Hangul_J_Mieum = 0x0ee3, // U+11B7 HANGUL JONGSEONG MIEUM
1484+ XK_Hangul_J_Pieub = 0x0ee4, // U+11B8 HANGUL JONGSEONG PIEUP
1485+ XK_Hangul_J_PieubSios = 0x0ee5, // U+11B9 HANGUL JONGSEONG PIEUP-SIOS
1486+ XK_Hangul_J_Sios = 0x0ee6, // U+11BA HANGUL JONGSEONG SIOS
1487+ XK_Hangul_J_SsangSios = 0x0ee7, // U+11BB HANGUL JONGSEONG SSANGSIOS
1488+ XK_Hangul_J_Ieung = 0x0ee8, // U+11BC HANGUL JONGSEONG IEUNG
1489+ XK_Hangul_J_Jieuj = 0x0ee9, // U+11BD HANGUL JONGSEONG CIEUC
1490+ XK_Hangul_J_Cieuc = 0x0eea, // U+11BE HANGUL JONGSEONG CHIEUCH
1491+ XK_Hangul_J_Khieuq = 0x0eeb, // U+11BF HANGUL JONGSEONG KHIEUKH
1492+ XK_Hangul_J_Tieut = 0x0eec, // U+11C0 HANGUL JONGSEONG THIEUTH
1493+ XK_Hangul_J_Phieuf = 0x0eed, // U+11C1 HANGUL JONGSEONG PHIEUPH
1494+ XK_Hangul_J_Hieuh = 0x0eee, // U+11C2 HANGUL JONGSEONG HIEUH
1495+ XK_Hangul_RieulYeorinHieuh = 0x0eef, // U+316D HANGUL LETTER RIEUL-YEORINHIEUH
1496+ XK_Hangul_SunkyeongeumMieum = 0x0ef0, // U+3171 HANGUL LETTER KAPYEOUNMIEUM
1497+ XK_Hangul_SunkyeongeumPieub = 0x0ef1, // U+3178 HANGUL LETTER KAPYEOUNPIEUP
1498+ XK_Hangul_PanSios = 0x0ef2, // U+317F HANGUL LETTER PANSIOS
1499+ XK_Hangul_KkogjiDalrinIeung = 0x0ef3, // U+3181 HANGUL LETTER YESIEUNG
1500+ XK_Hangul_SunkyeongeumPhieuf = 0x0ef4, // U+3184 HANGUL LETTER KAPYEOUNPHIEUPH
1501+ XK_Hangul_YeorinHieuh = 0x0ef5, // U+3186 HANGUL LETTER YEORINHIEUH
1502+ XK_Hangul_AraeA = 0x0ef6, // U+318D HANGUL LETTER ARAEA
1503+ XK_Hangul_AraeAE = 0x0ef7, // U+318E HANGUL LETTER ARAEAE
1504+ XK_Hangul_J_PanSios = 0x0ef8, // U+11EB HANGUL JONGSEONG PANSIOS
1505+ XK_Hangul_J_KkogjiDalrinIeung = 0x0ef9, // U+11F0 HANGUL JONGSEONG YESIEUNG
1506+ XK_Hangul_J_YeorinHieuh = 0x0efa, // U+11F9 HANGUL JONGSEONG YEORINHIEUH
1507+ XK_Korean_Won = 0x0eff, // (U+20A9 WON SIGN)
1508+ XK_Armenian_ligature_ew = 0x1000587, // U+0587 ARMENIAN SMALL LIGATURE ECH YIWN
1509+ XK_Armenian_full_stop = 0x1000589, // U+0589 ARMENIAN FULL STOP
1510+ // XK_Armenian_verjaket = 0x1000589, // deprecated alias for Armenian_full_stop
1511+ XK_Armenian_separation_mark = 0x100055d, // U+055D ARMENIAN COMMA
1512+ // XK_Armenian_but = 0x100055d, // deprecated alias for Armenian_separation_mark
1513+ XK_Armenian_hyphen = 0x100058a, // U+058A ARMENIAN HYPHEN
1514+ // XK_Armenian_yentamna = 0x100058a, // deprecated alias for Armenian_hyphen
1515+ XK_Armenian_exclam = 0x100055c, // U+055C ARMENIAN EXCLAMATION MARK
1516+ // XK_Armenian_amanak = 0x100055c, // deprecated alias for Armenian_exclam
1517+ XK_Armenian_accent = 0x100055b, // U+055B ARMENIAN EMPHASIS MARK
1518+ // XK_Armenian_shesht = 0x100055b, // deprecated alias for Armenian_accent
1519+ XK_Armenian_question = 0x100055e, // U+055E ARMENIAN QUESTION MARK
1520+ // XK_Armenian_paruyk = 0x100055e, // deprecated alias for Armenian_question
1521+ XK_Armenian_AYB = 0x1000531, // U+0531 ARMENIAN CAPITAL LETTER AYB
1522+ XK_Armenian_ayb = 0x1000561, // U+0561 ARMENIAN SMALL LETTER AYB
1523+ XK_Armenian_BEN = 0x1000532, // U+0532 ARMENIAN CAPITAL LETTER BEN
1524+ XK_Armenian_ben = 0x1000562, // U+0562 ARMENIAN SMALL LETTER BEN
1525+ XK_Armenian_GIM = 0x1000533, // U+0533 ARMENIAN CAPITAL LETTER GIM
1526+ XK_Armenian_gim = 0x1000563, // U+0563 ARMENIAN SMALL LETTER GIM
1527+ XK_Armenian_DA = 0x1000534, // U+0534 ARMENIAN CAPITAL LETTER DA
1528+ XK_Armenian_da = 0x1000564, // U+0564 ARMENIAN SMALL LETTER DA
1529+ XK_Armenian_YECH = 0x1000535, // U+0535 ARMENIAN CAPITAL LETTER ECH
1530+ XK_Armenian_yech = 0x1000565, // U+0565 ARMENIAN SMALL LETTER ECH
1531+ XK_Armenian_ZA = 0x1000536, // U+0536 ARMENIAN CAPITAL LETTER ZA
1532+ XK_Armenian_za = 0x1000566, // U+0566 ARMENIAN SMALL LETTER ZA
1533+ XK_Armenian_E = 0x1000537, // U+0537 ARMENIAN CAPITAL LETTER EH
1534+ XK_Armenian_e = 0x1000567, // U+0567 ARMENIAN SMALL LETTER EH
1535+ XK_Armenian_AT = 0x1000538, // U+0538 ARMENIAN CAPITAL LETTER ET
1536+ XK_Armenian_at = 0x1000568, // U+0568 ARMENIAN SMALL LETTER ET
1537+ XK_Armenian_TO = 0x1000539, // U+0539 ARMENIAN CAPITAL LETTER TO
1538+ XK_Armenian_to = 0x1000569, // U+0569 ARMENIAN SMALL LETTER TO
1539+ XK_Armenian_ZHE = 0x100053a, // U+053A ARMENIAN CAPITAL LETTER ZHE
1540+ XK_Armenian_zhe = 0x100056a, // U+056A ARMENIAN SMALL LETTER ZHE
1541+ XK_Armenian_INI = 0x100053b, // U+053B ARMENIAN CAPITAL LETTER INI
1542+ XK_Armenian_ini = 0x100056b, // U+056B ARMENIAN SMALL LETTER INI
1543+ XK_Armenian_LYUN = 0x100053c, // U+053C ARMENIAN CAPITAL LETTER LIWN
1544+ XK_Armenian_lyun = 0x100056c, // U+056C ARMENIAN SMALL LETTER LIWN
1545+ XK_Armenian_KHE = 0x100053d, // U+053D ARMENIAN CAPITAL LETTER XEH
1546+ XK_Armenian_khe = 0x100056d, // U+056D ARMENIAN SMALL LETTER XEH
1547+ XK_Armenian_TSA = 0x100053e, // U+053E ARMENIAN CAPITAL LETTER CA
1548+ XK_Armenian_tsa = 0x100056e, // U+056E ARMENIAN SMALL LETTER CA
1549+ XK_Armenian_KEN = 0x100053f, // U+053F ARMENIAN CAPITAL LETTER KEN
1550+ XK_Armenian_ken = 0x100056f, // U+056F ARMENIAN SMALL LETTER KEN
1551+ XK_Armenian_HO = 0x1000540, // U+0540 ARMENIAN CAPITAL LETTER HO
1552+ XK_Armenian_ho = 0x1000570, // U+0570 ARMENIAN SMALL LETTER HO
1553+ XK_Armenian_DZA = 0x1000541, // U+0541 ARMENIAN CAPITAL LETTER JA
1554+ XK_Armenian_dza = 0x1000571, // U+0571 ARMENIAN SMALL LETTER JA
1555+ XK_Armenian_GHAT = 0x1000542, // U+0542 ARMENIAN CAPITAL LETTER GHAD
1556+ XK_Armenian_ghat = 0x1000572, // U+0572 ARMENIAN SMALL LETTER GHAD
1557+ XK_Armenian_TCHE = 0x1000543, // U+0543 ARMENIAN CAPITAL LETTER CHEH
1558+ XK_Armenian_tche = 0x1000573, // U+0573 ARMENIAN SMALL LETTER CHEH
1559+ XK_Armenian_MEN = 0x1000544, // U+0544 ARMENIAN CAPITAL LETTER MEN
1560+ XK_Armenian_men = 0x1000574, // U+0574 ARMENIAN SMALL LETTER MEN
1561+ XK_Armenian_HI = 0x1000545, // U+0545 ARMENIAN CAPITAL LETTER YI
1562+ XK_Armenian_hi = 0x1000575, // U+0575 ARMENIAN SMALL LETTER YI
1563+ XK_Armenian_NU = 0x1000546, // U+0546 ARMENIAN CAPITAL LETTER NOW
1564+ XK_Armenian_nu = 0x1000576, // U+0576 ARMENIAN SMALL LETTER NOW
1565+ XK_Armenian_SHA = 0x1000547, // U+0547 ARMENIAN CAPITAL LETTER SHA
1566+ XK_Armenian_sha = 0x1000577, // U+0577 ARMENIAN SMALL LETTER SHA
1567+ XK_Armenian_VO = 0x1000548, // U+0548 ARMENIAN CAPITAL LETTER VO
1568+ XK_Armenian_vo = 0x1000578, // U+0578 ARMENIAN SMALL LETTER VO
1569+ XK_Armenian_CHA = 0x1000549, // U+0549 ARMENIAN CAPITAL LETTER CHA
1570+ XK_Armenian_cha = 0x1000579, // U+0579 ARMENIAN SMALL LETTER CHA
1571+ XK_Armenian_PE = 0x100054a, // U+054A ARMENIAN CAPITAL LETTER PEH
1572+ XK_Armenian_pe = 0x100057a, // U+057A ARMENIAN SMALL LETTER PEH
1573+ XK_Armenian_JE = 0x100054b, // U+054B ARMENIAN CAPITAL LETTER JHEH
1574+ XK_Armenian_je = 0x100057b, // U+057B ARMENIAN SMALL LETTER JHEH
1575+ XK_Armenian_RA = 0x100054c, // U+054C ARMENIAN CAPITAL LETTER RA
1576+ XK_Armenian_ra = 0x100057c, // U+057C ARMENIAN SMALL LETTER RA
1577+ XK_Armenian_SE = 0x100054d, // U+054D ARMENIAN CAPITAL LETTER SEH
1578+ XK_Armenian_se = 0x100057d, // U+057D ARMENIAN SMALL LETTER SEH
1579+ XK_Armenian_VEV = 0x100054e, // U+054E ARMENIAN CAPITAL LETTER VEW
1580+ XK_Armenian_vev = 0x100057e, // U+057E ARMENIAN SMALL LETTER VEW
1581+ XK_Armenian_TYUN = 0x100054f, // U+054F ARMENIAN CAPITAL LETTER TIWN
1582+ XK_Armenian_tyun = 0x100057f, // U+057F ARMENIAN SMALL LETTER TIWN
1583+ XK_Armenian_RE = 0x1000550, // U+0550 ARMENIAN CAPITAL LETTER REH
1584+ XK_Armenian_re = 0x1000580, // U+0580 ARMENIAN SMALL LETTER REH
1585+ XK_Armenian_TSO = 0x1000551, // U+0551 ARMENIAN CAPITAL LETTER CO
1586+ XK_Armenian_tso = 0x1000581, // U+0581 ARMENIAN SMALL LETTER CO
1587+ XK_Armenian_VYUN = 0x1000552, // U+0552 ARMENIAN CAPITAL LETTER YIWN
1588+ XK_Armenian_vyun = 0x1000582, // U+0582 ARMENIAN SMALL LETTER YIWN
1589+ XK_Armenian_PYUR = 0x1000553, // U+0553 ARMENIAN CAPITAL LETTER PIWR
1590+ XK_Armenian_pyur = 0x1000583, // U+0583 ARMENIAN SMALL LETTER PIWR
1591+ XK_Armenian_KE = 0x1000554, // U+0554 ARMENIAN CAPITAL LETTER KEH
1592+ XK_Armenian_ke = 0x1000584, // U+0584 ARMENIAN SMALL LETTER KEH
1593+ XK_Armenian_O = 0x1000555, // U+0555 ARMENIAN CAPITAL LETTER OH
1594+ XK_Armenian_o = 0x1000585, // U+0585 ARMENIAN SMALL LETTER OH
1595+ XK_Armenian_FE = 0x1000556, // U+0556 ARMENIAN CAPITAL LETTER FEH
1596+ XK_Armenian_fe = 0x1000586, // U+0586 ARMENIAN SMALL LETTER FEH
1597+ XK_Armenian_apostrophe = 0x100055a, // U+055A ARMENIAN APOSTROPHE
1598+
1599+ XK_Georgian_an = 0x10010d0, // U+10D0 GEORGIAN LETTER AN
1600+ XK_Georgian_ban = 0x10010d1, // U+10D1 GEORGIAN LETTER BAN
1601+ XK_Georgian_gan = 0x10010d2, // U+10D2 GEORGIAN LETTER GAN
1602+ XK_Georgian_don = 0x10010d3, // U+10D3 GEORGIAN LETTER DON
1603+ XK_Georgian_en = 0x10010d4, // U+10D4 GEORGIAN LETTER EN
1604+ XK_Georgian_vin = 0x10010d5, // U+10D5 GEORGIAN LETTER VIN
1605+ XK_Georgian_zen = 0x10010d6, // U+10D6 GEORGIAN LETTER ZEN
1606+ XK_Georgian_tan = 0x10010d7, // U+10D7 GEORGIAN LETTER TAN
1607+ XK_Georgian_in = 0x10010d8, // U+10D8 GEORGIAN LETTER IN
1608+ XK_Georgian_kan = 0x10010d9, // U+10D9 GEORGIAN LETTER KAN
1609+ XK_Georgian_las = 0x10010da, // U+10DA GEORGIAN LETTER LAS
1610+ XK_Georgian_man = 0x10010db, // U+10DB GEORGIAN LETTER MAN
1611+ XK_Georgian_nar = 0x10010dc, // U+10DC GEORGIAN LETTER NAR
1612+ XK_Georgian_on = 0x10010dd, // U+10DD GEORGIAN LETTER ON
1613+ XK_Georgian_par = 0x10010de, // U+10DE GEORGIAN LETTER PAR
1614+ XK_Georgian_zhar = 0x10010df, // U+10DF GEORGIAN LETTER ZHAR
1615+ XK_Georgian_rae = 0x10010e0, // U+10E0 GEORGIAN LETTER RAE
1616+ XK_Georgian_san = 0x10010e1, // U+10E1 GEORGIAN LETTER SAN
1617+ XK_Georgian_tar = 0x10010e2, // U+10E2 GEORGIAN LETTER TAR
1618+ XK_Georgian_un = 0x10010e3, // U+10E3 GEORGIAN LETTER UN
1619+ XK_Georgian_phar = 0x10010e4, // U+10E4 GEORGIAN LETTER PHAR
1620+ XK_Georgian_khar = 0x10010e5, // U+10E5 GEORGIAN LETTER KHAR
1621+ XK_Georgian_ghan = 0x10010e6, // U+10E6 GEORGIAN LETTER GHAN
1622+ XK_Georgian_qar = 0x10010e7, // U+10E7 GEORGIAN LETTER QAR
1623+ XK_Georgian_shin = 0x10010e8, // U+10E8 GEORGIAN LETTER SHIN
1624+ XK_Georgian_chin = 0x10010e9, // U+10E9 GEORGIAN LETTER CHIN
1625+ XK_Georgian_can = 0x10010ea, // U+10EA GEORGIAN LETTER CAN
1626+ XK_Georgian_jil = 0x10010eb, // U+10EB GEORGIAN LETTER JIL
1627+ XK_Georgian_cil = 0x10010ec, // U+10EC GEORGIAN LETTER CIL
1628+ XK_Georgian_char = 0x10010ed, // U+10ED GEORGIAN LETTER CHAR
1629+ XK_Georgian_xan = 0x10010ee, // U+10EE GEORGIAN LETTER XAN
1630+ XK_Georgian_jhan = 0x10010ef, // U+10EF GEORGIAN LETTER JHAN
1631+ XK_Georgian_hae = 0x10010f0, // U+10F0 GEORGIAN LETTER HAE
1632+ XK_Georgian_he = 0x10010f1, // U+10F1 GEORGIAN LETTER HE
1633+ XK_Georgian_hie = 0x10010f2, // U+10F2 GEORGIAN LETTER HIE
1634+ XK_Georgian_we = 0x10010f3, // U+10F3 GEORGIAN LETTER WE
1635+ XK_Georgian_har = 0x10010f4, // U+10F4 GEORGIAN LETTER HAR
1636+ XK_Georgian_hoe = 0x10010f5, // U+10F5 GEORGIAN LETTER HOE
1637+ XK_Georgian_fi = 0x10010f6, // U+10F6 GEORGIAN LETTER FI
1638+
1639+ XK_Xabovedot = 0x1001e8a, // U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE
1640+ XK_Ibreve = 0x100012c, // U+012C LATIN CAPITAL LETTER I WITH BREVE
1641+ XK_Zstroke = 0x10001b5, // U+01B5 LATIN CAPITAL LETTER Z WITH STROKE
1642+ XK_Gcaron = 0x10001e6, // U+01E6 LATIN CAPITAL LETTER G WITH CARON
1643+ XK_Ocaron = 0x10001d1, // U+01D1 LATIN CAPITAL LETTER O WITH CARON
1644+ XK_Obarred = 0x100019f, // U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE
1645+ XK_xabovedot = 0x1001e8b, // U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE
1646+ XK_ibreve = 0x100012d, // U+012D LATIN SMALL LETTER I WITH BREVE
1647+ XK_zstroke = 0x10001b6, // U+01B6 LATIN SMALL LETTER Z WITH STROKE
1648+ XK_gcaron = 0x10001e7, // U+01E7 LATIN SMALL LETTER G WITH CARON
1649+ XK_ocaron = 0x10001d2, // U+01D2 LATIN SMALL LETTER O WITH CARON
1650+ XK_obarred = 0x1000275, // U+0275 LATIN SMALL LETTER BARRED O
1651+ XK_SCHWA = 0x100018f, // U+018F LATIN CAPITAL LETTER SCHWA
1652+ XK_schwa = 0x1000259, // U+0259 LATIN SMALL LETTER SCHWA
1653+ XK_EZH = 0x10001b7, // U+01B7 LATIN CAPITAL LETTER EZH
1654+ XK_ezh = 0x1000292, // U+0292 LATIN SMALL LETTER EZH
1655+ XK_Lbelowdot = 0x1001e36, // U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW
1656+ XK_lbelowdot = 0x1001e37, // U+1E37 LATIN SMALL LETTER L WITH DOT BELOW
1657+
1658+ XK_Abelowdot = 0x1001ea0, // U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW
1659+ XK_abelowdot = 0x1001ea1, // U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW
1660+ XK_Ahook = 0x1001ea2, // U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE
1661+ XK_ahook = 0x1001ea3, // U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE
1662+ XK_Acircumflexacute = 0x1001ea4, // U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
1663+ XK_acircumflexacute = 0x1001ea5, // U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
1664+ XK_Acircumflexgrave = 0x1001ea6, // U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
1665+ XK_acircumflexgrave = 0x1001ea7, // U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
1666+ XK_Acircumflexhook = 0x1001ea8, // U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
1667+ XK_acircumflexhook = 0x1001ea9, // U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
1668+ XK_Acircumflextilde = 0x1001eaa, // U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
1669+ XK_acircumflextilde = 0x1001eab, // U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
1670+ XK_Acircumflexbelowdot = 0x1001eac, // U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
1671+ XK_acircumflexbelowdot = 0x1001ead, // U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
1672+ XK_Abreveacute = 0x1001eae, // U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
1673+ XK_abreveacute = 0x1001eaf, // U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE
1674+ XK_Abrevegrave = 0x1001eb0, // U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
1675+ XK_abrevegrave = 0x1001eb1, // U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE
1676+ XK_Abrevehook = 0x1001eb2, // U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
1677+ XK_abrevehook = 0x1001eb3, // U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
1678+ XK_Abrevetilde = 0x1001eb4, // U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE
1679+ XK_abrevetilde = 0x1001eb5, // U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE
1680+ XK_Abrevebelowdot = 0x1001eb6, // U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
1681+ XK_abrevebelowdot = 0x1001eb7, // U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
1682+ XK_Ebelowdot = 0x1001eb8, // U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW
1683+ XK_ebelowdot = 0x1001eb9, // U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW
1684+ XK_Ehook = 0x1001eba, // U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE
1685+ XK_ehook = 0x1001ebb, // U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE
1686+ XK_Etilde = 0x1001ebc, // U+1EBC LATIN CAPITAL LETTER E WITH TILDE
1687+ XK_etilde = 0x1001ebd, // U+1EBD LATIN SMALL LETTER E WITH TILDE
1688+ XK_Ecircumflexacute = 0x1001ebe, // U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
1689+ XK_ecircumflexacute = 0x1001ebf, // U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
1690+ XK_Ecircumflexgrave = 0x1001ec0, // U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
1691+ XK_ecircumflexgrave = 0x1001ec1, // U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
1692+ XK_Ecircumflexhook = 0x1001ec2, // U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
1693+ XK_ecircumflexhook = 0x1001ec3, // U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
1694+ XK_Ecircumflextilde = 0x1001ec4, // U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
1695+ XK_ecircumflextilde = 0x1001ec5, // U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
1696+ XK_Ecircumflexbelowdot = 0x1001ec6, // U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
1697+ XK_ecircumflexbelowdot = 0x1001ec7, // U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
1698+ XK_Ihook = 0x1001ec8, // U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE
1699+ XK_ihook = 0x1001ec9, // U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE
1700+ XK_Ibelowdot = 0x1001eca, // U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW
1701+ XK_ibelowdot = 0x1001ecb, // U+1ECB LATIN SMALL LETTER I WITH DOT BELOW
1702+ XK_Obelowdot = 0x1001ecc, // U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW
1703+ XK_obelowdot = 0x1001ecd, // U+1ECD LATIN SMALL LETTER O WITH DOT BELOW
1704+ XK_Ohook = 0x1001ece, // U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE
1705+ XK_ohook = 0x1001ecf, // U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE
1706+ XK_Ocircumflexacute = 0x1001ed0, // U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
1707+ XK_ocircumflexacute = 0x1001ed1, // U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
1708+ XK_Ocircumflexgrave = 0x1001ed2, // U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
1709+ XK_ocircumflexgrave = 0x1001ed3, // U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
1710+ XK_Ocircumflexhook = 0x1001ed4, // U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
1711+ XK_ocircumflexhook = 0x1001ed5, // U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
1712+ XK_Ocircumflextilde = 0x1001ed6, // U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
1713+ XK_ocircumflextilde = 0x1001ed7, // U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
1714+ XK_Ocircumflexbelowdot = 0x1001ed8, // U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
1715+ XK_ocircumflexbelowdot = 0x1001ed9, // U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
1716+ XK_Ohornacute = 0x1001eda, // U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE
1717+ XK_ohornacute = 0x1001edb, // U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE
1718+ XK_Ohorngrave = 0x1001edc, // U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE
1719+ XK_ohorngrave = 0x1001edd, // U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE
1720+ XK_Ohornhook = 0x1001ede, // U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
1721+ XK_ohornhook = 0x1001edf, // U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
1722+ XK_Ohorntilde = 0x1001ee0, // U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE
1723+ XK_ohorntilde = 0x1001ee1, // U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE
1724+ XK_Ohornbelowdot = 0x1001ee2, // U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
1725+ XK_ohornbelowdot = 0x1001ee3, // U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW
1726+ XK_Ubelowdot = 0x1001ee4, // U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW
1727+ XK_ubelowdot = 0x1001ee5, // U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW
1728+ XK_Uhook = 0x1001ee6, // U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE
1729+ XK_uhook = 0x1001ee7, // U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE
1730+ XK_Uhornacute = 0x1001ee8, // U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE
1731+ XK_uhornacute = 0x1001ee9, // U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE
1732+ XK_Uhorngrave = 0x1001eea, // U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE
1733+ XK_uhorngrave = 0x1001eeb, // U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE
1734+ XK_Uhornhook = 0x1001eec, // U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
1735+ XK_uhornhook = 0x1001eed, // U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
1736+ XK_Uhorntilde = 0x1001eee, // U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE
1737+ XK_uhorntilde = 0x1001eef, // U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE
1738+ XK_Uhornbelowdot = 0x1001ef0, // U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
1739+ XK_uhornbelowdot = 0x1001ef1, // U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW
1740+ XK_Ybelowdot = 0x1001ef4, // U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW
1741+ XK_ybelowdot = 0x1001ef5, // U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW
1742+ XK_Yhook = 0x1001ef6, // U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE
1743+ XK_yhook = 0x1001ef7, // U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE
1744+ XK_Ytilde = 0x1001ef8, // U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE
1745+ XK_ytilde = 0x1001ef9, // U+1EF9 LATIN SMALL LETTER Y WITH TILDE
1746+ XK_Ohorn = 0x10001a0, // U+01A0 LATIN CAPITAL LETTER O WITH HORN
1747+ XK_ohorn = 0x10001a1, // U+01A1 LATIN SMALL LETTER O WITH HORN
1748+ XK_Uhorn = 0x10001af, // U+01AF LATIN CAPITAL LETTER U WITH HORN
1749+ XK_uhorn = 0x10001b0, // U+01B0 LATIN SMALL LETTER U WITH HORN
1750+ XK_combining_tilde = 0x1000303, // U+0303 COMBINING TILDE
1751+ XK_combining_grave = 0x1000300, // U+0300 COMBINING GRAVE ACCENT
1752+ XK_combining_acute = 0x1000301, // U+0301 COMBINING ACUTE ACCENT
1753+ XK_combining_hook = 0x1000309, // U+0309 COMBINING HOOK ABOVE
1754+ XK_combining_belowdot = 0x1000323, // U+0323 COMBINING DOT BELOW
1755+
1756+ XK_EcuSign = 0x10020a0, // U+20A0 EURO-CURRENCY SIGN
1757+ XK_ColonSign = 0x10020a1, // U+20A1 COLON SIGN
1758+ XK_CruzeiroSign = 0x10020a2, // U+20A2 CRUZEIRO SIGN
1759+ XK_FFrancSign = 0x10020a3, // U+20A3 FRENCH FRANC SIGN
1760+ XK_LiraSign = 0x10020a4, // U+20A4 LIRA SIGN
1761+ XK_MillSign = 0x10020a5, // U+20A5 MILL SIGN
1762+ XK_NairaSign = 0x10020a6, // U+20A6 NAIRA SIGN
1763+ XK_PesetaSign = 0x10020a7, // U+20A7 PESETA SIGN
1764+ XK_RupeeSign = 0x10020a8, // U+20A8 RUPEE SIGN
1765+ XK_WonSign = 0x10020a9, // U+20A9 WON SIGN
1766+ XK_NewSheqelSign = 0x10020aa, // U+20AA NEW SHEQEL SIGN
1767+ XK_DongSign = 0x10020ab, // U+20AB DONG SIGN
1768+ XK_EuroSign = 0x20ac, // U+20AC EURO SIGN
1769+
1770+ XK_zerosuperior = 0x1002070, // U+2070 SUPERSCRIPT ZERO
1771+ XK_foursuperior = 0x1002074, // U+2074 SUPERSCRIPT FOUR
1772+ XK_fivesuperior = 0x1002075, // U+2075 SUPERSCRIPT FIVE
1773+ XK_sixsuperior = 0x1002076, // U+2076 SUPERSCRIPT SIX
1774+ XK_sevensuperior = 0x1002077, // U+2077 SUPERSCRIPT SEVEN
1775+ XK_eightsuperior = 0x1002078, // U+2078 SUPERSCRIPT EIGHT
1776+ XK_ninesuperior = 0x1002079, // U+2079 SUPERSCRIPT NINE
1777+ XK_zerosubscript = 0x1002080, // U+2080 SUBSCRIPT ZERO
1778+ XK_onesubscript = 0x1002081, // U+2081 SUBSCRIPT ONE
1779+ XK_twosubscript = 0x1002082, // U+2082 SUBSCRIPT TWO
1780+ XK_threesubscript = 0x1002083, // U+2083 SUBSCRIPT THREE
1781+ XK_foursubscript = 0x1002084, // U+2084 SUBSCRIPT FOUR
1782+ XK_fivesubscript = 0x1002085, // U+2085 SUBSCRIPT FIVE
1783+ XK_sixsubscript = 0x1002086, // U+2086 SUBSCRIPT SIX
1784+ XK_sevensubscript = 0x1002087, // U+2087 SUBSCRIPT SEVEN
1785+ XK_eightsubscript = 0x1002088, // U+2088 SUBSCRIPT EIGHT
1786+ XK_ninesubscript = 0x1002089, // U+2089 SUBSCRIPT NINE
1787+ XK_partdifferential = 0x1002202, // U+2202 PARTIAL DIFFERENTIAL
1788+ XK_emptyset = 0x1002205, // U+2205 EMPTY SET
1789+ XK_elementof = 0x1002208, // U+2208 ELEMENT OF
1790+ XK_notelementof = 0x1002209, // U+2209 NOT AN ELEMENT OF
1791+ XK_containsas = 0x100220b, // U+220B CONTAINS AS MEMBER
1792+ XK_squareroot = 0x100221a, // U+221A SQUARE ROOT
1793+ XK_cuberoot = 0x100221b, // U+221B CUBE ROOT
1794+ XK_fourthroot = 0x100221c, // U+221C FOURTH ROOT
1795+ XK_dintegral = 0x100222c, // U+222C DOUBLE INTEGRAL
1796+ XK_tintegral = 0x100222d, // U+222D TRIPLE INTEGRAL
1797+ XK_because = 0x1002235, // U+2235 BECAUSE
1798+ XK_approxeq = 0x1002248, // (U+2248 ALMOST EQUAL TO)
1799+ XK_notapproxeq = 0x1002247, // (U+2247 NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO)
1800+ XK_notidentical = 0x1002262, // U+2262 NOT IDENTICAL TO
1801+ XK_stricteq = 0x1002263, // U+2263 STRICTLY EQUIVALENT TO
1802+
1803+ XK_braille_dot_1 = 0xfff1,
1804+ XK_braille_dot_2 = 0xfff2,
1805+ XK_braille_dot_3 = 0xfff3,
1806+ XK_braille_dot_4 = 0xfff4,
1807+ XK_braille_dot_5 = 0xfff5,
1808+ XK_braille_dot_6 = 0xfff6,
1809+ XK_braille_dot_7 = 0xfff7,
1810+ XK_braille_dot_8 = 0xfff8,
1811+ XK_braille_dot_9 = 0xfff9,
1812+ XK_braille_dot_10 = 0xfffa,
1813+ XK_braille_blank = 0x1002800, // U+2800 BRAILLE PATTERN BLANK
1814+ XK_braille_dots_1 = 0x1002801, // U+2801 BRAILLE PATTERN DOTS-1
1815+ XK_braille_dots_2 = 0x1002802, // U+2802 BRAILLE PATTERN DOTS-2
1816+ XK_braille_dots_12 = 0x1002803, // U+2803 BRAILLE PATTERN DOTS-12
1817+ XK_braille_dots_3 = 0x1002804, // U+2804 BRAILLE PATTERN DOTS-3
1818+ XK_braille_dots_13 = 0x1002805, // U+2805 BRAILLE PATTERN DOTS-13
1819+ XK_braille_dots_23 = 0x1002806, // U+2806 BRAILLE PATTERN DOTS-23
1820+ XK_braille_dots_123 = 0x1002807, // U+2807 BRAILLE PATTERN DOTS-123
1821+ XK_braille_dots_4 = 0x1002808, // U+2808 BRAILLE PATTERN DOTS-4
1822+ XK_braille_dots_14 = 0x1002809, // U+2809 BRAILLE PATTERN DOTS-14
1823+ XK_braille_dots_24 = 0x100280a, // U+280A BRAILLE PATTERN DOTS-24
1824+ XK_braille_dots_124 = 0x100280b, // U+280B BRAILLE PATTERN DOTS-124
1825+ XK_braille_dots_34 = 0x100280c, // U+280C BRAILLE PATTERN DOTS-34
1826+ XK_braille_dots_134 = 0x100280d, // U+280D BRAILLE PATTERN DOTS-134
1827+ XK_braille_dots_234 = 0x100280e, // U+280E BRAILLE PATTERN DOTS-234
1828+ XK_braille_dots_1234 = 0x100280f, // U+280F BRAILLE PATTERN DOTS-1234
1829+ XK_braille_dots_5 = 0x1002810, // U+2810 BRAILLE PATTERN DOTS-5
1830+ XK_braille_dots_15 = 0x1002811, // U+2811 BRAILLE PATTERN DOTS-15
1831+ XK_braille_dots_25 = 0x1002812, // U+2812 BRAILLE PATTERN DOTS-25
1832+ XK_braille_dots_125 = 0x1002813, // U+2813 BRAILLE PATTERN DOTS-125
1833+ XK_braille_dots_35 = 0x1002814, // U+2814 BRAILLE PATTERN DOTS-35
1834+ XK_braille_dots_135 = 0x1002815, // U+2815 BRAILLE PATTERN DOTS-135
1835+ XK_braille_dots_235 = 0x1002816, // U+2816 BRAILLE PATTERN DOTS-235
1836+ XK_braille_dots_1235 = 0x1002817, // U+2817 BRAILLE PATTERN DOTS-1235
1837+ XK_braille_dots_45 = 0x1002818, // U+2818 BRAILLE PATTERN DOTS-45
1838+ XK_braille_dots_145 = 0x1002819, // U+2819 BRAILLE PATTERN DOTS-145
1839+ XK_braille_dots_245 = 0x100281a, // U+281A BRAILLE PATTERN DOTS-245
1840+ XK_braille_dots_1245 = 0x100281b, // U+281B BRAILLE PATTERN DOTS-1245
1841+ XK_braille_dots_345 = 0x100281c, // U+281C BRAILLE PATTERN DOTS-345
1842+ XK_braille_dots_1345 = 0x100281d, // U+281D BRAILLE PATTERN DOTS-1345
1843+ XK_braille_dots_2345 = 0x100281e, // U+281E BRAILLE PATTERN DOTS-2345
1844+ XK_braille_dots_12345 = 0x100281f, // U+281F BRAILLE PATTERN DOTS-12345
1845+ XK_braille_dots_6 = 0x1002820, // U+2820 BRAILLE PATTERN DOTS-6
1846+ XK_braille_dots_16 = 0x1002821, // U+2821 BRAILLE PATTERN DOTS-16
1847+ XK_braille_dots_26 = 0x1002822, // U+2822 BRAILLE PATTERN DOTS-26
1848+ XK_braille_dots_126 = 0x1002823, // U+2823 BRAILLE PATTERN DOTS-126
1849+ XK_braille_dots_36 = 0x1002824, // U+2824 BRAILLE PATTERN DOTS-36
1850+ XK_braille_dots_136 = 0x1002825, // U+2825 BRAILLE PATTERN DOTS-136
1851+ XK_braille_dots_236 = 0x1002826, // U+2826 BRAILLE PATTERN DOTS-236
1852+ XK_braille_dots_1236 = 0x1002827, // U+2827 BRAILLE PATTERN DOTS-1236
1853+ XK_braille_dots_46 = 0x1002828, // U+2828 BRAILLE PATTERN DOTS-46
1854+ XK_braille_dots_146 = 0x1002829, // U+2829 BRAILLE PATTERN DOTS-146
1855+ XK_braille_dots_246 = 0x100282a, // U+282A BRAILLE PATTERN DOTS-246
1856+ XK_braille_dots_1246 = 0x100282b, // U+282B BRAILLE PATTERN DOTS-1246
1857+ XK_braille_dots_346 = 0x100282c, // U+282C BRAILLE PATTERN DOTS-346
1858+ XK_braille_dots_1346 = 0x100282d, // U+282D BRAILLE PATTERN DOTS-1346
1859+ XK_braille_dots_2346 = 0x100282e, // U+282E BRAILLE PATTERN DOTS-2346
1860+ XK_braille_dots_12346 = 0x100282f, // U+282F BRAILLE PATTERN DOTS-12346
1861+ XK_braille_dots_56 = 0x1002830, // U+2830 BRAILLE PATTERN DOTS-56
1862+ XK_braille_dots_156 = 0x1002831, // U+2831 BRAILLE PATTERN DOTS-156
1863+ XK_braille_dots_256 = 0x1002832, // U+2832 BRAILLE PATTERN DOTS-256
1864+ XK_braille_dots_1256 = 0x1002833, // U+2833 BRAILLE PATTERN DOTS-1256
1865+ XK_braille_dots_356 = 0x1002834, // U+2834 BRAILLE PATTERN DOTS-356
1866+ XK_braille_dots_1356 = 0x1002835, // U+2835 BRAILLE PATTERN DOTS-1356
1867+ XK_braille_dots_2356 = 0x1002836, // U+2836 BRAILLE PATTERN DOTS-2356
1868+ XK_braille_dots_12356 = 0x1002837, // U+2837 BRAILLE PATTERN DOTS-12356
1869+ XK_braille_dots_456 = 0x1002838, // U+2838 BRAILLE PATTERN DOTS-456
1870+ XK_braille_dots_1456 = 0x1002839, // U+2839 BRAILLE PATTERN DOTS-1456
1871+ XK_braille_dots_2456 = 0x100283a, // U+283A BRAILLE PATTERN DOTS-2456
1872+ XK_braille_dots_12456 = 0x100283b, // U+283B BRAILLE PATTERN DOTS-12456
1873+ XK_braille_dots_3456 = 0x100283c, // U+283C BRAILLE PATTERN DOTS-3456
1874+ XK_braille_dots_13456 = 0x100283d, // U+283D BRAILLE PATTERN DOTS-13456
1875+ XK_braille_dots_23456 = 0x100283e, // U+283E BRAILLE PATTERN DOTS-23456
1876+ XK_braille_dots_123456 = 0x100283f, // U+283F BRAILLE PATTERN DOTS-123456
1877+ XK_braille_dots_7 = 0x1002840, // U+2840 BRAILLE PATTERN DOTS-7
1878+ XK_braille_dots_17 = 0x1002841, // U+2841 BRAILLE PATTERN DOTS-17
1879+ XK_braille_dots_27 = 0x1002842, // U+2842 BRAILLE PATTERN DOTS-27
1880+ XK_braille_dots_127 = 0x1002843, // U+2843 BRAILLE PATTERN DOTS-127
1881+ XK_braille_dots_37 = 0x1002844, // U+2844 BRAILLE PATTERN DOTS-37
1882+ XK_braille_dots_137 = 0x1002845, // U+2845 BRAILLE PATTERN DOTS-137
1883+ XK_braille_dots_237 = 0x1002846, // U+2846 BRAILLE PATTERN DOTS-237
1884+ XK_braille_dots_1237 = 0x1002847, // U+2847 BRAILLE PATTERN DOTS-1237
1885+ XK_braille_dots_47 = 0x1002848, // U+2848 BRAILLE PATTERN DOTS-47
1886+ XK_braille_dots_147 = 0x1002849, // U+2849 BRAILLE PATTERN DOTS-147
1887+ XK_braille_dots_247 = 0x100284a, // U+284A BRAILLE PATTERN DOTS-247
1888+ XK_braille_dots_1247 = 0x100284b, // U+284B BRAILLE PATTERN DOTS-1247
1889+ XK_braille_dots_347 = 0x100284c, // U+284C BRAILLE PATTERN DOTS-347
1890+ XK_braille_dots_1347 = 0x100284d, // U+284D BRAILLE PATTERN DOTS-1347
1891+ XK_braille_dots_2347 = 0x100284e, // U+284E BRAILLE PATTERN DOTS-2347
1892+ XK_braille_dots_12347 = 0x100284f, // U+284F BRAILLE PATTERN DOTS-12347
1893+ XK_braille_dots_57 = 0x1002850, // U+2850 BRAILLE PATTERN DOTS-57
1894+ XK_braille_dots_157 = 0x1002851, // U+2851 BRAILLE PATTERN DOTS-157
1895+ XK_braille_dots_257 = 0x1002852, // U+2852 BRAILLE PATTERN DOTS-257
1896+ XK_braille_dots_1257 = 0x1002853, // U+2853 BRAILLE PATTERN DOTS-1257
1897+ XK_braille_dots_357 = 0x1002854, // U+2854 BRAILLE PATTERN DOTS-357
1898+ XK_braille_dots_1357 = 0x1002855, // U+2855 BRAILLE PATTERN DOTS-1357
1899+ XK_braille_dots_2357 = 0x1002856, // U+2856 BRAILLE PATTERN DOTS-2357
1900+ XK_braille_dots_12357 = 0x1002857, // U+2857 BRAILLE PATTERN DOTS-12357
1901+ XK_braille_dots_457 = 0x1002858, // U+2858 BRAILLE PATTERN DOTS-457
1902+ XK_braille_dots_1457 = 0x1002859, // U+2859 BRAILLE PATTERN DOTS-1457
1903+ XK_braille_dots_2457 = 0x100285a, // U+285A BRAILLE PATTERN DOTS-2457
1904+ XK_braille_dots_12457 = 0x100285b, // U+285B BRAILLE PATTERN DOTS-12457
1905+ XK_braille_dots_3457 = 0x100285c, // U+285C BRAILLE PATTERN DOTS-3457
1906+ XK_braille_dots_13457 = 0x100285d, // U+285D BRAILLE PATTERN DOTS-13457
1907+ XK_braille_dots_23457 = 0x100285e, // U+285E BRAILLE PATTERN DOTS-23457
1908+ XK_braille_dots_123457 = 0x100285f, // U+285F BRAILLE PATTERN DOTS-123457
1909+ XK_braille_dots_67 = 0x1002860, // U+2860 BRAILLE PATTERN DOTS-67
1910+ XK_braille_dots_167 = 0x1002861, // U+2861 BRAILLE PATTERN DOTS-167
1911+ XK_braille_dots_267 = 0x1002862, // U+2862 BRAILLE PATTERN DOTS-267
1912+ XK_braille_dots_1267 = 0x1002863, // U+2863 BRAILLE PATTERN DOTS-1267
1913+ XK_braille_dots_367 = 0x1002864, // U+2864 BRAILLE PATTERN DOTS-367
1914+ XK_braille_dots_1367 = 0x1002865, // U+2865 BRAILLE PATTERN DOTS-1367
1915+ XK_braille_dots_2367 = 0x1002866, // U+2866 BRAILLE PATTERN DOTS-2367
1916+ XK_braille_dots_12367 = 0x1002867, // U+2867 BRAILLE PATTERN DOTS-12367
1917+ XK_braille_dots_467 = 0x1002868, // U+2868 BRAILLE PATTERN DOTS-467
1918+ XK_braille_dots_1467 = 0x1002869, // U+2869 BRAILLE PATTERN DOTS-1467
1919+ XK_braille_dots_2467 = 0x100286a, // U+286A BRAILLE PATTERN DOTS-2467
1920+ XK_braille_dots_12467 = 0x100286b, // U+286B BRAILLE PATTERN DOTS-12467
1921+ XK_braille_dots_3467 = 0x100286c, // U+286C BRAILLE PATTERN DOTS-3467
1922+ XK_braille_dots_13467 = 0x100286d, // U+286D BRAILLE PATTERN DOTS-13467
1923+ XK_braille_dots_23467 = 0x100286e, // U+286E BRAILLE PATTERN DOTS-23467
1924+ XK_braille_dots_123467 = 0x100286f, // U+286F BRAILLE PATTERN DOTS-123467
1925+ XK_braille_dots_567 = 0x1002870, // U+2870 BRAILLE PATTERN DOTS-567
1926+ XK_braille_dots_1567 = 0x1002871, // U+2871 BRAILLE PATTERN DOTS-1567
1927+ XK_braille_dots_2567 = 0x1002872, // U+2872 BRAILLE PATTERN DOTS-2567
1928+ XK_braille_dots_12567 = 0x1002873, // U+2873 BRAILLE PATTERN DOTS-12567
1929+ XK_braille_dots_3567 = 0x1002874, // U+2874 BRAILLE PATTERN DOTS-3567
1930+ XK_braille_dots_13567 = 0x1002875, // U+2875 BRAILLE PATTERN DOTS-13567
1931+ XK_braille_dots_23567 = 0x1002876, // U+2876 BRAILLE PATTERN DOTS-23567
1932+ XK_braille_dots_123567 = 0x1002877, // U+2877 BRAILLE PATTERN DOTS-123567
1933+ XK_braille_dots_4567 = 0x1002878, // U+2878 BRAILLE PATTERN DOTS-4567
1934+ XK_braille_dots_14567 = 0x1002879, // U+2879 BRAILLE PATTERN DOTS-14567
1935+ XK_braille_dots_24567 = 0x100287a, // U+287A BRAILLE PATTERN DOTS-24567
1936+ XK_braille_dots_124567 = 0x100287b, // U+287B BRAILLE PATTERN DOTS-124567
1937+ XK_braille_dots_34567 = 0x100287c, // U+287C BRAILLE PATTERN DOTS-34567
1938+ XK_braille_dots_134567 = 0x100287d, // U+287D BRAILLE PATTERN DOTS-134567
1939+ XK_braille_dots_234567 = 0x100287e, // U+287E BRAILLE PATTERN DOTS-234567
1940+ XK_braille_dots_1234567 = 0x100287f, // U+287F BRAILLE PATTERN DOTS-1234567
1941+ XK_braille_dots_8 = 0x1002880, // U+2880 BRAILLE PATTERN DOTS-8
1942+ XK_braille_dots_18 = 0x1002881, // U+2881 BRAILLE PATTERN DOTS-18
1943+ XK_braille_dots_28 = 0x1002882, // U+2882 BRAILLE PATTERN DOTS-28
1944+ XK_braille_dots_128 = 0x1002883, // U+2883 BRAILLE PATTERN DOTS-128
1945+ XK_braille_dots_38 = 0x1002884, // U+2884 BRAILLE PATTERN DOTS-38
1946+ XK_braille_dots_138 = 0x1002885, // U+2885 BRAILLE PATTERN DOTS-138
1947+ XK_braille_dots_238 = 0x1002886, // U+2886 BRAILLE PATTERN DOTS-238
1948+ XK_braille_dots_1238 = 0x1002887, // U+2887 BRAILLE PATTERN DOTS-1238
1949+ XK_braille_dots_48 = 0x1002888, // U+2888 BRAILLE PATTERN DOTS-48
1950+ XK_braille_dots_148 = 0x1002889, // U+2889 BRAILLE PATTERN DOTS-148
1951+ XK_braille_dots_248 = 0x100288a, // U+288A BRAILLE PATTERN DOTS-248
1952+ XK_braille_dots_1248 = 0x100288b, // U+288B BRAILLE PATTERN DOTS-1248
1953+ XK_braille_dots_348 = 0x100288c, // U+288C BRAILLE PATTERN DOTS-348
1954+ XK_braille_dots_1348 = 0x100288d, // U+288D BRAILLE PATTERN DOTS-1348
1955+ XK_braille_dots_2348 = 0x100288e, // U+288E BRAILLE PATTERN DOTS-2348
1956+ XK_braille_dots_12348 = 0x100288f, // U+288F BRAILLE PATTERN DOTS-12348
1957+ XK_braille_dots_58 = 0x1002890, // U+2890 BRAILLE PATTERN DOTS-58
1958+ XK_braille_dots_158 = 0x1002891, // U+2891 BRAILLE PATTERN DOTS-158
1959+ XK_braille_dots_258 = 0x1002892, // U+2892 BRAILLE PATTERN DOTS-258
1960+ XK_braille_dots_1258 = 0x1002893, // U+2893 BRAILLE PATTERN DOTS-1258
1961+ XK_braille_dots_358 = 0x1002894, // U+2894 BRAILLE PATTERN DOTS-358
1962+ XK_braille_dots_1358 = 0x1002895, // U+2895 BRAILLE PATTERN DOTS-1358
1963+ XK_braille_dots_2358 = 0x1002896, // U+2896 BRAILLE PATTERN DOTS-2358
1964+ XK_braille_dots_12358 = 0x1002897, // U+2897 BRAILLE PATTERN DOTS-12358
1965+ XK_braille_dots_458 = 0x1002898, // U+2898 BRAILLE PATTERN DOTS-458
1966+ XK_braille_dots_1458 = 0x1002899, // U+2899 BRAILLE PATTERN DOTS-1458
1967+ XK_braille_dots_2458 = 0x100289a, // U+289A BRAILLE PATTERN DOTS-2458
1968+ XK_braille_dots_12458 = 0x100289b, // U+289B BRAILLE PATTERN DOTS-12458
1969+ XK_braille_dots_3458 = 0x100289c, // U+289C BRAILLE PATTERN DOTS-3458
1970+ XK_braille_dots_13458 = 0x100289d, // U+289D BRAILLE PATTERN DOTS-13458
1971+ XK_braille_dots_23458 = 0x100289e, // U+289E BRAILLE PATTERN DOTS-23458
1972+ XK_braille_dots_123458 = 0x100289f, // U+289F BRAILLE PATTERN DOTS-123458
1973+ XK_braille_dots_68 = 0x10028a0, // U+28A0 BRAILLE PATTERN DOTS-68
1974+ XK_braille_dots_168 = 0x10028a1, // U+28A1 BRAILLE PATTERN DOTS-168
1975+ XK_braille_dots_268 = 0x10028a2, // U+28A2 BRAILLE PATTERN DOTS-268
1976+ XK_braille_dots_1268 = 0x10028a3, // U+28A3 BRAILLE PATTERN DOTS-1268
1977+ XK_braille_dots_368 = 0x10028a4, // U+28A4 BRAILLE PATTERN DOTS-368
1978+ XK_braille_dots_1368 = 0x10028a5, // U+28A5 BRAILLE PATTERN DOTS-1368
1979+ XK_braille_dots_2368 = 0x10028a6, // U+28A6 BRAILLE PATTERN DOTS-2368
1980+ XK_braille_dots_12368 = 0x10028a7, // U+28A7 BRAILLE PATTERN DOTS-12368
1981+ XK_braille_dots_468 = 0x10028a8, // U+28A8 BRAILLE PATTERN DOTS-468
1982+ XK_braille_dots_1468 = 0x10028a9, // U+28A9 BRAILLE PATTERN DOTS-1468
1983+ XK_braille_dots_2468 = 0x10028aa, // U+28AA BRAILLE PATTERN DOTS-2468
1984+ XK_braille_dots_12468 = 0x10028ab, // U+28AB BRAILLE PATTERN DOTS-12468
1985+ XK_braille_dots_3468 = 0x10028ac, // U+28AC BRAILLE PATTERN DOTS-3468
1986+ XK_braille_dots_13468 = 0x10028ad, // U+28AD BRAILLE PATTERN DOTS-13468
1987+ XK_braille_dots_23468 = 0x10028ae, // U+28AE BRAILLE PATTERN DOTS-23468
1988+ XK_braille_dots_123468 = 0x10028af, // U+28AF BRAILLE PATTERN DOTS-123468
1989+ XK_braille_dots_568 = 0x10028b0, // U+28B0 BRAILLE PATTERN DOTS-568
1990+ XK_braille_dots_1568 = 0x10028b1, // U+28B1 BRAILLE PATTERN DOTS-1568
1991+ XK_braille_dots_2568 = 0x10028b2, // U+28B2 BRAILLE PATTERN DOTS-2568
1992+ XK_braille_dots_12568 = 0x10028b3, // U+28B3 BRAILLE PATTERN DOTS-12568
1993+ XK_braille_dots_3568 = 0x10028b4, // U+28B4 BRAILLE PATTERN DOTS-3568
1994+ XK_braille_dots_13568 = 0x10028b5, // U+28B5 BRAILLE PATTERN DOTS-13568
1995+ XK_braille_dots_23568 = 0x10028b6, // U+28B6 BRAILLE PATTERN DOTS-23568
1996+ XK_braille_dots_123568 = 0x10028b7, // U+28B7 BRAILLE PATTERN DOTS-123568
1997+ XK_braille_dots_4568 = 0x10028b8, // U+28B8 BRAILLE PATTERN DOTS-4568
1998+ XK_braille_dots_14568 = 0x10028b9, // U+28B9 BRAILLE PATTERN DOTS-14568
1999+ XK_braille_dots_24568 = 0x10028ba, // U+28BA BRAILLE PATTERN DOTS-24568
2000+ XK_braille_dots_124568 = 0x10028bb, // U+28BB BRAILLE PATTERN DOTS-124568
2001+ XK_braille_dots_34568 = 0x10028bc, // U+28BC BRAILLE PATTERN DOTS-34568
2002+ XK_braille_dots_134568 = 0x10028bd, // U+28BD BRAILLE PATTERN DOTS-134568
2003+ XK_braille_dots_234568 = 0x10028be, // U+28BE BRAILLE PATTERN DOTS-234568
2004+ XK_braille_dots_1234568 = 0x10028bf, // U+28BF BRAILLE PATTERN DOTS-1234568
2005+ XK_braille_dots_78 = 0x10028c0, // U+28C0 BRAILLE PATTERN DOTS-78
2006+ XK_braille_dots_178 = 0x10028c1, // U+28C1 BRAILLE PATTERN DOTS-178
2007+ XK_braille_dots_278 = 0x10028c2, // U+28C2 BRAILLE PATTERN DOTS-278
2008+ XK_braille_dots_1278 = 0x10028c3, // U+28C3 BRAILLE PATTERN DOTS-1278
2009+ XK_braille_dots_378 = 0x10028c4, // U+28C4 BRAILLE PATTERN DOTS-378
2010+ XK_braille_dots_1378 = 0x10028c5, // U+28C5 BRAILLE PATTERN DOTS-1378
2011+ XK_braille_dots_2378 = 0x10028c6, // U+28C6 BRAILLE PATTERN DOTS-2378
2012+ XK_braille_dots_12378 = 0x10028c7, // U+28C7 BRAILLE PATTERN DOTS-12378
2013+ XK_braille_dots_478 = 0x10028c8, // U+28C8 BRAILLE PATTERN DOTS-478
2014+ XK_braille_dots_1478 = 0x10028c9, // U+28C9 BRAILLE PATTERN DOTS-1478
2015+ XK_braille_dots_2478 = 0x10028ca, // U+28CA BRAILLE PATTERN DOTS-2478
2016+ XK_braille_dots_12478 = 0x10028cb, // U+28CB BRAILLE PATTERN DOTS-12478
2017+ XK_braille_dots_3478 = 0x10028cc, // U+28CC BRAILLE PATTERN DOTS-3478
2018+ XK_braille_dots_13478 = 0x10028cd, // U+28CD BRAILLE PATTERN DOTS-13478
2019+ XK_braille_dots_23478 = 0x10028ce, // U+28CE BRAILLE PATTERN DOTS-23478
2020+ XK_braille_dots_123478 = 0x10028cf, // U+28CF BRAILLE PATTERN DOTS-123478
2021+ XK_braille_dots_578 = 0x10028d0, // U+28D0 BRAILLE PATTERN DOTS-578
2022+ XK_braille_dots_1578 = 0x10028d1, // U+28D1 BRAILLE PATTERN DOTS-1578
2023+ XK_braille_dots_2578 = 0x10028d2, // U+28D2 BRAILLE PATTERN DOTS-2578
2024+ XK_braille_dots_12578 = 0x10028d3, // U+28D3 BRAILLE PATTERN DOTS-12578
2025+ XK_braille_dots_3578 = 0x10028d4, // U+28D4 BRAILLE PATTERN DOTS-3578
2026+ XK_braille_dots_13578 = 0x10028d5, // U+28D5 BRAILLE PATTERN DOTS-13578
2027+ XK_braille_dots_23578 = 0x10028d6, // U+28D6 BRAILLE PATTERN DOTS-23578
2028+ XK_braille_dots_123578 = 0x10028d7, // U+28D7 BRAILLE PATTERN DOTS-123578
2029+ XK_braille_dots_4578 = 0x10028d8, // U+28D8 BRAILLE PATTERN DOTS-4578
2030+ XK_braille_dots_14578 = 0x10028d9, // U+28D9 BRAILLE PATTERN DOTS-14578
2031+ XK_braille_dots_24578 = 0x10028da, // U+28DA BRAILLE PATTERN DOTS-24578
2032+ XK_braille_dots_124578 = 0x10028db, // U+28DB BRAILLE PATTERN DOTS-124578
2033+ XK_braille_dots_34578 = 0x10028dc, // U+28DC BRAILLE PATTERN DOTS-34578
2034+ XK_braille_dots_134578 = 0x10028dd, // U+28DD BRAILLE PATTERN DOTS-134578
2035+ XK_braille_dots_234578 = 0x10028de, // U+28DE BRAILLE PATTERN DOTS-234578
2036+ XK_braille_dots_1234578 = 0x10028df, // U+28DF BRAILLE PATTERN DOTS-1234578
2037+ XK_braille_dots_678 = 0x10028e0, // U+28E0 BRAILLE PATTERN DOTS-678
2038+ XK_braille_dots_1678 = 0x10028e1, // U+28E1 BRAILLE PATTERN DOTS-1678
2039+ XK_braille_dots_2678 = 0x10028e2, // U+28E2 BRAILLE PATTERN DOTS-2678
2040+ XK_braille_dots_12678 = 0x10028e3, // U+28E3 BRAILLE PATTERN DOTS-12678
2041+ XK_braille_dots_3678 = 0x10028e4, // U+28E4 BRAILLE PATTERN DOTS-3678
2042+ XK_braille_dots_13678 = 0x10028e5, // U+28E5 BRAILLE PATTERN DOTS-13678
2043+ XK_braille_dots_23678 = 0x10028e6, // U+28E6 BRAILLE PATTERN DOTS-23678
2044+ XK_braille_dots_123678 = 0x10028e7, // U+28E7 BRAILLE PATTERN DOTS-123678
2045+ XK_braille_dots_4678 = 0x10028e8, // U+28E8 BRAILLE PATTERN DOTS-4678
2046+ XK_braille_dots_14678 = 0x10028e9, // U+28E9 BRAILLE PATTERN DOTS-14678
2047+ XK_braille_dots_24678 = 0x10028ea, // U+28EA BRAILLE PATTERN DOTS-24678
2048+ XK_braille_dots_124678 = 0x10028eb, // U+28EB BRAILLE PATTERN DOTS-124678
2049+ XK_braille_dots_34678 = 0x10028ec, // U+28EC BRAILLE PATTERN DOTS-34678
2050+ XK_braille_dots_134678 = 0x10028ed, // U+28ED BRAILLE PATTERN DOTS-134678
2051+ XK_braille_dots_234678 = 0x10028ee, // U+28EE BRAILLE PATTERN DOTS-234678
2052+ XK_braille_dots_1234678 = 0x10028ef, // U+28EF BRAILLE PATTERN DOTS-1234678
2053+ XK_braille_dots_5678 = 0x10028f0, // U+28F0 BRAILLE PATTERN DOTS-5678
2054+ XK_braille_dots_15678 = 0x10028f1, // U+28F1 BRAILLE PATTERN DOTS-15678
2055+ XK_braille_dots_25678 = 0x10028f2, // U+28F2 BRAILLE PATTERN DOTS-25678
2056+ XK_braille_dots_125678 = 0x10028f3, // U+28F3 BRAILLE PATTERN DOTS-125678
2057+ XK_braille_dots_35678 = 0x10028f4, // U+28F4 BRAILLE PATTERN DOTS-35678
2058+ XK_braille_dots_135678 = 0x10028f5, // U+28F5 BRAILLE PATTERN DOTS-135678
2059+ XK_braille_dots_235678 = 0x10028f6, // U+28F6 BRAILLE PATTERN DOTS-235678
2060+ XK_braille_dots_1235678 = 0x10028f7, // U+28F7 BRAILLE PATTERN DOTS-1235678
2061+ XK_braille_dots_45678 = 0x10028f8, // U+28F8 BRAILLE PATTERN DOTS-45678
2062+ XK_braille_dots_145678 = 0x10028f9, // U+28F9 BRAILLE PATTERN DOTS-145678
2063+ XK_braille_dots_245678 = 0x10028fa, // U+28FA BRAILLE PATTERN DOTS-245678
2064+ XK_braille_dots_1245678 = 0x10028fb, // U+28FB BRAILLE PATTERN DOTS-1245678
2065+ XK_braille_dots_345678 = 0x10028fc, // U+28FC BRAILLE PATTERN DOTS-345678
2066+ XK_braille_dots_1345678 = 0x10028fd, // U+28FD BRAILLE PATTERN DOTS-1345678
2067+ XK_braille_dots_2345678 = 0x10028fe, // U+28FE BRAILLE PATTERN DOTS-2345678
2068+ XK_braille_dots_12345678 = 0x10028ff, // U+28FF BRAILLE PATTERN DOTS-12345678
2069+
2070+ XK_Sinh_ng = 0x1000d82, // U+0D82 SINHALA SIGN ANUSVARAYA
2071+ XK_Sinh_h2 = 0x1000d83, // U+0D83 SINHALA SIGN VISARGAYA
2072+ XK_Sinh_a = 0x1000d85, // U+0D85 SINHALA LETTER AYANNA
2073+ XK_Sinh_aa = 0x1000d86, // U+0D86 SINHALA LETTER AAYANNA
2074+ XK_Sinh_ae = 0x1000d87, // U+0D87 SINHALA LETTER AEYANNA
2075+ XK_Sinh_aee = 0x1000d88, // U+0D88 SINHALA LETTER AEEYANNA
2076+ XK_Sinh_i = 0x1000d89, // U+0D89 SINHALA LETTER IYANNA
2077+ XK_Sinh_ii = 0x1000d8a, // U+0D8A SINHALA LETTER IIYANNA
2078+ XK_Sinh_u = 0x1000d8b, // U+0D8B SINHALA LETTER UYANNA
2079+ XK_Sinh_uu = 0x1000d8c, // U+0D8C SINHALA LETTER UUYANNA
2080+ XK_Sinh_ri = 0x1000d8d, // U+0D8D SINHALA LETTER IRUYANNA
2081+ XK_Sinh_rii = 0x1000d8e, // U+0D8E SINHALA LETTER IRUUYANNA
2082+ XK_Sinh_lu = 0x1000d8f, // U+0D8F SINHALA LETTER ILUYANNA
2083+ XK_Sinh_luu = 0x1000d90, // U+0D90 SINHALA LETTER ILUUYANNA
2084+ XK_Sinh_e = 0x1000d91, // U+0D91 SINHALA LETTER EYANNA
2085+ XK_Sinh_ee = 0x1000d92, // U+0D92 SINHALA LETTER EEYANNA
2086+ XK_Sinh_ai = 0x1000d93, // U+0D93 SINHALA LETTER AIYANNA
2087+ XK_Sinh_o = 0x1000d94, // U+0D94 SINHALA LETTER OYANNA
2088+ XK_Sinh_oo = 0x1000d95, // U+0D95 SINHALA LETTER OOYANNA
2089+ XK_Sinh_au = 0x1000d96, // U+0D96 SINHALA LETTER AUYANNA
2090+ XK_Sinh_ka = 0x1000d9a, // U+0D9A SINHALA LETTER ALPAPRAANA KAYANNA
2091+ XK_Sinh_kha = 0x1000d9b, // U+0D9B SINHALA LETTER MAHAAPRAANA KAYANNA
2092+ XK_Sinh_ga = 0x1000d9c, // U+0D9C SINHALA LETTER ALPAPRAANA GAYANNA
2093+ XK_Sinh_gha = 0x1000d9d, // U+0D9D SINHALA LETTER MAHAAPRAANA GAYANNA
2094+ XK_Sinh_ng2 = 0x1000d9e, // U+0D9E SINHALA LETTER KANTAJA NAASIKYAYA
2095+ XK_Sinh_nga = 0x1000d9f, // U+0D9F SINHALA LETTER SANYAKA GAYANNA
2096+ XK_Sinh_ca = 0x1000da0, // U+0DA0 SINHALA LETTER ALPAPRAANA CAYANNA
2097+ XK_Sinh_cha = 0x1000da1, // U+0DA1 SINHALA LETTER MAHAAPRAANA CAYANNA
2098+ XK_Sinh_ja = 0x1000da2, // U+0DA2 SINHALA LETTER ALPAPRAANA JAYANNA
2099+ XK_Sinh_jha = 0x1000da3, // U+0DA3 SINHALA LETTER MAHAAPRAANA JAYANNA
2100+ XK_Sinh_nya = 0x1000da4, // U+0DA4 SINHALA LETTER TAALUJA NAASIKYAYA
2101+ XK_Sinh_jnya = 0x1000da5, // U+0DA5 SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA
2102+ XK_Sinh_nja = 0x1000da6, // U+0DA6 SINHALA LETTER SANYAKA JAYANNA
2103+ XK_Sinh_tta = 0x1000da7, // U+0DA7 SINHALA LETTER ALPAPRAANA TTAYANNA
2104+ XK_Sinh_ttha = 0x1000da8, // U+0DA8 SINHALA LETTER MAHAAPRAANA TTAYANNA
2105+ XK_Sinh_dda = 0x1000da9, // U+0DA9 SINHALA LETTER ALPAPRAANA DDAYANNA
2106+ XK_Sinh_ddha = 0x1000daa, // U+0DAA SINHALA LETTER MAHAAPRAANA DDAYANNA
2107+ XK_Sinh_nna = 0x1000dab, // U+0DAB SINHALA LETTER MUURDHAJA NAYANNA
2108+ XK_Sinh_ndda = 0x1000dac, // U+0DAC SINHALA LETTER SANYAKA DDAYANNA
2109+ XK_Sinh_tha = 0x1000dad, // U+0DAD SINHALA LETTER ALPAPRAANA TAYANNA
2110+ XK_Sinh_thha = 0x1000dae, // U+0DAE SINHALA LETTER MAHAAPRAANA TAYANNA
2111+ XK_Sinh_dha = 0x1000daf, // U+0DAF SINHALA LETTER ALPAPRAANA DAYANNA
2112+ XK_Sinh_dhha = 0x1000db0, // U+0DB0 SINHALA LETTER MAHAAPRAANA DAYANNA
2113+ XK_Sinh_na = 0x1000db1, // U+0DB1 SINHALA LETTER DANTAJA NAYANNA
2114+ XK_Sinh_ndha = 0x1000db3, // U+0DB3 SINHALA LETTER SANYAKA DAYANNA
2115+ XK_Sinh_pa = 0x1000db4, // U+0DB4 SINHALA LETTER ALPAPRAANA PAYANNA
2116+ XK_Sinh_pha = 0x1000db5, // U+0DB5 SINHALA LETTER MAHAAPRAANA PAYANNA
2117+ XK_Sinh_ba = 0x1000db6, // U+0DB6 SINHALA LETTER ALPAPRAANA BAYANNA
2118+ XK_Sinh_bha = 0x1000db7, // U+0DB7 SINHALA LETTER MAHAAPRAANA BAYANNA
2119+ XK_Sinh_ma = 0x1000db8, // U+0DB8 SINHALA LETTER MAYANNA
2120+ XK_Sinh_mba = 0x1000db9, // U+0DB9 SINHALA LETTER AMBA BAYANNA
2121+ XK_Sinh_ya = 0x1000dba, // U+0DBA SINHALA LETTER YAYANNA
2122+ XK_Sinh_ra = 0x1000dbb, // U+0DBB SINHALA LETTER RAYANNA
2123+ XK_Sinh_la = 0x1000dbd, // U+0DBD SINHALA LETTER DANTAJA LAYANNA
2124+ XK_Sinh_va = 0x1000dc0, // U+0DC0 SINHALA LETTER VAYANNA
2125+ XK_Sinh_sha = 0x1000dc1, // U+0DC1 SINHALA LETTER TAALUJA SAYANNA
2126+ XK_Sinh_ssha = 0x1000dc2, // U+0DC2 SINHALA LETTER MUURDHAJA SAYANNA
2127+ XK_Sinh_sa = 0x1000dc3, // U+0DC3 SINHALA LETTER DANTAJA SAYANNA
2128+ XK_Sinh_ha = 0x1000dc4, // U+0DC4 SINHALA LETTER HAYANNA
2129+ XK_Sinh_lla = 0x1000dc5, // U+0DC5 SINHALA LETTER MUURDHAJA LAYANNA
2130+ XK_Sinh_fa = 0x1000dc6, // U+0DC6 SINHALA LETTER FAYANNA
2131+ XK_Sinh_al = 0x1000dca, // U+0DCA SINHALA SIGN AL-LAKUNA
2132+ XK_Sinh_aa2 = 0x1000dcf, // U+0DCF SINHALA VOWEL SIGN AELA-PILLA
2133+ XK_Sinh_ae2 = 0x1000dd0, // U+0DD0 SINHALA VOWEL SIGN KETTI AEDA-PILLA
2134+ XK_Sinh_aee2 = 0x1000dd1, // U+0DD1 SINHALA VOWEL SIGN DIGA AEDA-PILLA
2135+ XK_Sinh_i2 = 0x1000dd2, // U+0DD2 SINHALA VOWEL SIGN KETTI IS-PILLA
2136+ XK_Sinh_ii2 = 0x1000dd3, // U+0DD3 SINHALA VOWEL SIGN DIGA IS-PILLA
2137+ XK_Sinh_u2 = 0x1000dd4, // U+0DD4 SINHALA VOWEL SIGN KETTI PAA-PILLA
2138+ XK_Sinh_uu2 = 0x1000dd6, // U+0DD6 SINHALA VOWEL SIGN DIGA PAA-PILLA
2139+ XK_Sinh_ru2 = 0x1000dd8, // U+0DD8 SINHALA VOWEL SIGN GAETTA-PILLA
2140+ XK_Sinh_e2 = 0x1000dd9, // U+0DD9 SINHALA VOWEL SIGN KOMBUVA
2141+ XK_Sinh_ee2 = 0x1000dda, // U+0DDA SINHALA VOWEL SIGN DIGA KOMBUVA
2142+ XK_Sinh_ai2 = 0x1000ddb, // U+0DDB SINHALA VOWEL SIGN KOMBU DEKA
2143+ XK_Sinh_o2 = 0x1000ddc, // U+0DDC SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA
2144+ XK_Sinh_oo2 = 0x1000ddd, // U+0DDD SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA
2145+ XK_Sinh_au2 = 0x1000dde, // U+0DDE SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA
2146+ XK_Sinh_lu2 = 0x1000ddf, // U+0DDF SINHALA VOWEL SIGN GAYANUKITTA
2147+ XK_Sinh_ruu2 = 0x1000df2, // U+0DF2 SINHALA VOWEL SIGN DIGA GAETTA-PILLA
2148+ XK_Sinh_luu2 = 0x1000df3, // U+0DF3 SINHALA VOWEL SIGN DIGA GAYANUKITTA
2149+ XK_Sinh_kunddaliya = 0x1000df4, // U+0DF4 SINHALA PUNCTUATION KUNDDALIYA
2150+};
2151diff --git a/src/x11.zig b/src/x11.zig
2152index 9b8cbd2..a0a2cf4 100644
2153--- a/src/x11.zig
2154+++ b/src/x11.zig
2155@@ -37,3 +37,5 @@ pub const EventType = enum(c_int) {
2156 mapping_notify = 34,
2157 generic_event = 35,
2158 };
2159+
2160+pub const Keysym = @import("./x11.Keysym.zig").Keysym;
testdata/diff-f58200e3f2967a06f343c9fc9dcae9de18def92a created+6888
...@@ -0,0 +1,6888 @@
1:100644 100644 41bc62cead176f9307835337b00615e2e1f74f6b d21ea2791c62f3b912f586e56882346c00321647 M CMakeLists.txt
2:100644 100644 0466b79bf2dbeb803d653eff2f2a48880da3669b e8d54cc0cd314cc8a7e8e2cf2fb1c20106b33078 M build.zig
3:100644 100755 0a7ba5d277c3ccdc6357f92807b80bb7eb855bc7 0a7ba5d277c3ccdc6357f92807b80bb7eb855bc7 M ci/x86_64-linux-debug-llvm.sh
4:100644 100644 578139c5ac08a4d7eb4e298ea3354e4b9c1ee72d 79a120d5a2ccdde4c037297e677420b065a24b04 M lib/compiler_rt/fma.zig
5:100644 100644 dad60b725bc267a906e5c88abeb1ee342f818160 0f47a0b64781e423ec680cb162eb33e3ec51eddb M lib/std/Build/Step/Compile.zig
6:100644 100644 bef80d782b20e759701c73a3fe85909985415f42 43b542c09e047ff0ae723f710750f396e18bbf08 M lib/std/elf.zig
7:100644 100644 b2116c1a7429b5791d8e39d66dd7e66ad64337e0 55f1fd14cb6cfa8421a142a142802710c9944bd5 M lib/std/zig/system.zig
8:100644 100644 34953ed11a12e334a1ecd995de399421a896a5bb bf7246b8d8b8fe3df2c4ac1c4fb6124fe55e134b M src/Compilation.zig
9:100644 100644 d8751251da9e24db98c79f7964e0ea1a9bde78c8 45f7e509de609a4ab10651d27e49a1cb645eb2b6 M src/Compilation/Config.zig
10:100644 100644 996549774294455b642ef3286d3d20be0bd404f5 f4344af86d46be017beacf31e90c581493517b0f M src/InternPool.zig
11:100644 100644 946e890ea3566e0cc1ab2aae453d389ecfab702b d0576de33d4d3077f7fa177ba4e0b8e9b438ee69 M src/Sema.zig
12:100644 100644 8de562176107ae28fb15ce2e6ed241aa7f176e16 381eacf45ab2389c950aad0dd9f0ed886e9a8bcb M src/Value.zig
13:100644 100644 706bdb51655409a6e2c23e36d580d0c81c01f350 8e9e9c29025c4e82af1d14ece0eca9b7d9bd06e4 M src/Zcu.zig
14:100644 100644 77cddb204e82eeeba3b349b0ed2216974d06f14c 32782e7e8952462d2991ff0b3bf3bbe8e0b72c64 M src/Zcu/PerThread.zig
15:100644 100644 7b13cfc90d68b760251c236bd43890858a088dd9 fe40ba4bbb16ffcbcc2768af9a6f8a57600c1e4f M src/arch/riscv64/CodeGen.zig
16:100644 100644 2e72aff941072c7e5d7164eace99b5d919dc4ece 64a476007cf9881e5101c5c945158252b1ba5b86 M src/arch/riscv64/Emit.zig
17:100644 100644 6fb8e23a98c3b0e89ee5139429fc11626fb2ecc7 204ab6a3c06226635b1619b60c205f02f8447884 M src/arch/riscv64/Mir.zig
18:100644 100644 d41f1cdf07aa54b3c55a9917826a7b55a7da23b0 26282b09ab4f5c831cea32e9c9dbf8d6e0b2256a M src/arch/sparc64/Emit.zig
19:100644 100644 842ac10fed1af8fbaeadb7b2c0404a20f806abc0 41d135eb831fefe51afd3fde7925596fce9d441b M src/arch/sparc64/Mir.zig
20:100644 100644 b5760c95ac2b54f5e03c32e3d61a4c32e01f3a46 1827b50d61a06e05f525461fb8261922f36920bf M src/arch/x86_64/CodeGen.zig
21:100644 100644 84bb325322ac20c100da1e85c715a99f7e251deb c2b38d8e6d45b3439d2f8bb6cf9e518ac17784cc M src/arch/x86_64/Emit.zig
22:100644 100644 e70018850d621aff1a360044014f1ea1e8516a44 caf41ffb392d07b8a455f09181c77ffb8a679d7e M src/arch/x86_64/Mir.zig
23:100644 100644 835093d11ab8d38f622252233101c1a3c9d8904d 05048109335e0256d91c5f350d7fa900ce08e402 M src/arch/x86_64/bits.zig
24:100644 100644 03ff7134f62d04025081f06b50248545433130ec 1d9c67175ef204933a5463393cad189d0e59e7fa M src/arch/x86_64/encoder.zig
25:100644 100644 56e6e7c99fb3bd8208ce92e912c03f3d2404f2c1 4cbf3f56169ec9227f961a72720898cc23df3f96 M src/codegen.zig
26:100644 100644 318a51da95bfe1c047447f96cde8a83f993c9f80 be6478eae896f3d70d874e609d3c3d263946872a M src/codegen/aarch64/Mir.zig
27:100644 100644 ac30cedecd8318da8f38e96e45d763fc2d70bc1f 266796a2dc2dda022bd7c4c3027c950a446d9dc9 M src/dev.zig
28:100644 100644 27cd6620e359284f0a6398aa23a5f8ade66446d7 277013efb3094cee331db13b15fd1e5d2d08d7e4 M src/link.zig
29:100644 100644 e016473531aede3998c41f42a85745fbf017c63c f3e3b3d0b530d498f1b8d4518c1d9c06d4a69baa M src/link/Coff.zig
30:100644 100644 f4af5f4148ad11f2eeb0688ccd11a39120404d6b 595e3583d5d540bdd0fe0ce1727d0a25eed72f50 M src/link/Dwarf.zig
31:100644 100644 b74406c368d5cc4eb3da41365236bc79387bf7c2 d7e3cf62f3a378970682797fb538227d9c70795d M src/link/Elf/LinkerDefined.zig
32:100644 100644 8c79def16bff14a9878ab22cea2ee6e1aca7c160 4dce40e37094e9a48db41d35ce189af38b63c287 M src/link/Elf/SharedObject.zig
33:100644 100644 bf65d04e4a13b3980749bfcc1af24f52d4ac3b49 a3ede11dc4003cd0f9d1f671dfccc5c095b16a82 M src/link/Elf/ZigObject.zig
34:000000 100644 0000000000000000000000000000000000000000 e43ebf2639ad88db8d125d2a79877173d771f73d A src/link/Elf2.zig
35:100644 100644 b1fc6528d5808663942b0428869f0c72efda1931 5a0a71f380c8a83c66b4f4e5391e4ec54469033e M src/link/MachO/ZigObject.zig
36:000000 100644 0000000000000000000000000000000000000000 d04a8d533a03f8934a8546311007b867bde353d0 A src/link/MappedFile.zig
37:100644 100644 9f4535e1fe4ef7c6458ee94b571b4157ba422dc8 742b4664f178955b4668f130ebbacab0b9ac2550 M src/link/Queue.zig
38:100644 100644 a125a70aae790e7b750c96304bae1bdb3c86376c d60b91c30f93695076b8299c7e92d8f734812d32 M src/link/Wasm.zig
39:100644 100644 26d44c4463be802e0e7dea899980b28010b8ffc7 9d43e47ea2dbd949122ab7abfdf285ade21bc987 M src/main.zig
40:100644 100644 e999d2ae22663bcd84a9eb1fc112a317b12a9c02 1cf5c9b08274a55f6cd956ae433e4fb7141e1abd M src/target.zig
41:100644 100644 01605bdeeb36e4d51e986526e94c9a36e2cf07fa e492930031e7fb5d22d68402bc3e59299a084402 M test/incremental/change_exports
42:100644 100644 3e400b854eb60b4a81a3c9b2f0e3511e11ec3b26 699134100eec6942bc2414d29ab7188332f3a45a M test/incremental/change_panic_handler
43:100644 100644 9f7eb6c12f10b42d80e998f352ac9a0a1d5d0842 2d068d593eeb77a07b9c249fc0d7542f1cee4c6c M test/incremental/change_panic_handler_explicit
44:100644 100644 97049a1fc03ae2d9dfbdd07e6c06a9e756f133aa f3bfbbdd6922a0266e42c41f8e92cc96e15bc9fc M test/incremental/change_struct_same_fields
45:100644 100644 5c5d3329750eadc813f892bce6e05234ad563242 3bcae1cd211281cc29d4b970240174c40613fdd6 M test/incremental/type_becomes_comptime_only
46
47diff --git a/CMakeLists.txt b/CMakeLists.txt
48index 41bc62cead..d21ea2791c 100644
49--- a/CMakeLists.txt
50+++ b/CMakeLists.txt
51@@ -583,6 +583,7 @@ set(ZIG_STAGE2_SOURCES
52 src/link/Elf/relocatable.zig
53 src/link/Elf/relocation.zig
54 src/link/Elf/synthetic_sections.zig
55+ src/link/Elf2.zig
56 src/link/Goff.zig
57 src/link/LdScript.zig
58 src/link/Lld.zig
59@@ -612,6 +613,7 @@ set(ZIG_STAGE2_SOURCES
60 src/link/MachO/synthetic.zig
61 src/link/MachO/Thunk.zig
62 src/link/MachO/uuid.zig
63+ src/link/MappedFile.zig
64 src/link/Queue.zig
65 src/link/StringTable.zig
66 src/link/Wasm.zig
67diff --git a/build.zig b/build.zig
68index 0466b79bf2..e8d54cc0cd 100644
69--- a/build.zig
70+++ b/build.zig
71@@ -202,6 +202,7 @@ pub fn build(b: *std.Build) !void {
72 });
73 exe.pie = pie;
74 exe.entitlements = entitlements;
75+ exe.use_new_linker = b.option(bool, "new-linker", "Use the new linker");
76
77 const use_llvm = b.option(bool, "use-llvm", "Use the llvm backend");
78 exe.use_llvm = use_llvm;
79diff --git a/ci/x86_64-linux-debug-llvm.sh b/ci/x86_64-linux-debug-llvm.sh
80old mode 100644
81new mode 100755
82diff --git a/lib/compiler_rt/fma.zig b/lib/compiler_rt/fma.zig
83index 578139c5ac..79a120d5a2 100644
84--- a/lib/compiler_rt/fma.zig
85+++ b/lib/compiler_rt/fma.zig
86@@ -203,7 +203,7 @@ fn add_adjusted(a: f64, b: f64) f64 {
87 if (uhii & 1 == 0) {
88 // hibits += copysign(1.0, sum.hi, sum.lo)
89 const uloi: u64 = @bitCast(sum.lo);
90- uhii += 1 - ((uhii ^ uloi) >> 62);
91+ uhii = uhii + 1 - ((uhii ^ uloi) >> 62);
92 sum.hi = @bitCast(uhii);
93 }
94 }
95@@ -217,7 +217,7 @@ fn add_and_denorm(a: f64, b: f64, scale: i32) f64 {
96 const bits_lost = -@as(i32, @intCast((uhii >> 52) & 0x7FF)) - scale + 1;
97 if ((bits_lost != 1) == (uhii & 1 != 0)) {
98 const uloi: u64 = @bitCast(sum.lo);
99- uhii += 1 - (((uhii ^ uloi) >> 62) & 2);
100+ uhii = uhii + 1 - (((uhii ^ uloi) >> 62) & 2);
101 sum.hi = @bitCast(uhii);
102 }
103 }
104@@ -259,7 +259,7 @@ fn add_adjusted128(a: f128, b: f128) f128 {
105 if (uhii & 1 == 0) {
106 // hibits += copysign(1.0, sum.hi, sum.lo)
107 const uloi: u128 = @bitCast(sum.lo);
108- uhii += 1 - ((uhii ^ uloi) >> 126);
109+ uhii = uhii + 1 - ((uhii ^ uloi) >> 126);
110 sum.hi = @bitCast(uhii);
111 }
112 }
113@@ -284,7 +284,7 @@ fn add_and_denorm128(a: f128, b: f128, scale: i32) f128 {
114 const bits_lost = -@as(i32, @intCast((uhii >> 112) & 0x7FFF)) - scale + 1;
115 if ((bits_lost != 1) == (uhii & 1 != 0)) {
116 const uloi: u128 = @bitCast(sum.lo);
117- uhii += 1 - (((uhii ^ uloi) >> 126) & 2);
118+ uhii = uhii + 1 - (((uhii ^ uloi) >> 126) & 2);
119 sum.hi = @bitCast(uhii);
120 }
121 }
122diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig
123index dad60b725b..0f47a0b647 100644
124--- a/lib/std/Build/Step/Compile.zig
125+++ b/lib/std/Build/Step/Compile.zig
126@@ -192,6 +192,7 @@ want_lto: ?bool = null,
127
128 use_llvm: ?bool,
129 use_lld: ?bool,
130+use_new_linker: ?bool,
131
132 /// Corresponds to the `-fallow-so-scripts` / `-fno-allow-so-scripts` CLI
133 /// flags, overriding the global user setting provided to the `zig build`
134@@ -441,6 +442,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
135
136 .use_llvm = options.use_llvm,
137 .use_lld = options.use_lld,
138+ .use_new_linker = null,
139
140 .zig_process = null,
141 };
142@@ -1096,6 +1098,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
143
144 try addFlag(&zig_args, "llvm", compile.use_llvm);
145 try addFlag(&zig_args, "lld", compile.use_lld);
146+ try addFlag(&zig_args, "new-linker", compile.use_new_linker);
147
148 if (compile.root_module.resolved_target.?.query.ofmt) |ofmt| {
149 try zig_args.append(try std.fmt.allocPrint(arena, "-ofmt={s}", .{@tagName(ofmt)}));
150diff --git a/lib/std/elf.zig b/lib/std/elf.zig
151index bef80d782b..43b542c09e 100644
152--- a/lib/std/elf.zig
153+++ b/lib/std/elf.zig
154@@ -323,6 +323,8 @@ pub const PT_LOPROC = 0x70000000;
155 /// End of processor-specific
156 pub const PT_HIPROC = 0x7fffffff;
157
158+pub const PN_XNUM = 0xffff;
159+
160 /// Section header table entry unused
161 pub const SHT_NULL = 0;
162 /// Program data
163@@ -385,63 +387,149 @@ pub const SHT_HIUSER = 0xffffffff;
164 // Note type for .note.gnu.build_id
165 pub const NT_GNU_BUILD_ID = 3;
166
167-/// Local symbol
168-pub const STB_LOCAL = 0;
169-/// Global symbol
170-pub const STB_GLOBAL = 1;
171-/// Weak symbol
172-pub const STB_WEAK = 2;
173-/// Number of defined types
174-pub const STB_NUM = 3;
175-/// Start of OS-specific
176-pub const STB_LOOS = 10;
177-/// Unique symbol
178-pub const STB_GNU_UNIQUE = 10;
179-/// End of OS-specific
180-pub const STB_HIOS = 12;
181-/// Start of processor-specific
182-pub const STB_LOPROC = 13;
183-/// End of processor-specific
184-pub const STB_HIPROC = 15;
185-
186-pub const STB_MIPS_SPLIT_COMMON = 13;
187-
188-/// Symbol type is unspecified
189-pub const STT_NOTYPE = 0;
190-/// Symbol is a data object
191-pub const STT_OBJECT = 1;
192-/// Symbol is a code object
193-pub const STT_FUNC = 2;
194-/// Symbol associated with a section
195-pub const STT_SECTION = 3;
196-/// Symbol's name is file name
197-pub const STT_FILE = 4;
198-/// Symbol is a common data object
199-pub const STT_COMMON = 5;
200-/// Symbol is thread-local data object
201-pub const STT_TLS = 6;
202-/// Number of defined types
203-pub const STT_NUM = 7;
204-/// Start of OS-specific
205-pub const STT_LOOS = 10;
206-/// Symbol is indirect code object
207-pub const STT_GNU_IFUNC = 10;
208-/// End of OS-specific
209-pub const STT_HIOS = 12;
210-/// Start of processor-specific
211-pub const STT_LOPROC = 13;
212-/// End of processor-specific
213-pub const STT_HIPROC = 15;
214+/// Deprecated, use `@intFromEnum(std.elf.STB.LOCAL)`
215+pub const STB_LOCAL = @intFromEnum(STB.LOCAL);
216+/// Deprecated, use `@intFromEnum(std.elf.STB.GLOBAL)`
217+pub const STB_GLOBAL = @intFromEnum(STB.GLOBAL);
218+/// Deprecated, use `@intFromEnum(std.elf.STB.WEAK)`
219+pub const STB_WEAK = @intFromEnum(STB.WEAK);
220+/// Deprecated, use `std.elf.STB.NUM`
221+pub const STB_NUM = STB.NUM;
222+/// Deprecated, use `@intFromEnum(std.elf.STB.LOOS)`
223+pub const STB_LOOS = @intFromEnum(STB.LOOS);
224+/// Deprecated, use `@intFromEnum(std.elf.STB.GNU_UNIQUE)`
225+pub const STB_GNU_UNIQUE = @intFromEnum(STB.GNU_UNIQUE);
226+/// Deprecated, use `@intFromEnum(std.elf.STB.HIOS)`
227+pub const STB_HIOS = @intFromEnum(STB.HIOS);
228+/// Deprecated, use `@intFromEnum(std.elf.STB.LOPROC)`
229+pub const STB_LOPROC = @intFromEnum(STB.LOPROC);
230+/// Deprecated, use `@intFromEnum(std.elf.STB.HIPROC)`
231+pub const STB_HIPROC = @intFromEnum(STB.HIPROC);
232+
233+/// Deprecated, use `@intFromEnum(std.elf.STB.MIPS_SPLIT_COMMON)`
234+pub const STB_MIPS_SPLIT_COMMON = @intFromEnum(STB.MIBS_SPLIT_COMMON);
235+
236+/// Deprecated, use `@intFromEnum(std.elf.STT.NOTYPE)`
237+pub const STT_NOTYPE = @intFromEnum(STT.NOTYPE);
238+/// Deprecated, use `@intFromEnum(std.elf.STT.OBJECT)`
239+pub const STT_OBJECT = @intFromEnum(STT.OBJECT);
240+/// Deprecated, use `@intFromEnum(std.elf.STT.FUNC)`
241+pub const STT_FUNC = @intFromEnum(STT.FUNC);
242+/// Deprecated, use `@intFromEnum(std.elf.STT.SECTION)`
243+pub const STT_SECTION = @intFromEnum(STT.SECTION);
244+/// Deprecated, use `@intFromEnum(std.elf.STT.FILE)`
245+pub const STT_FILE = @intFromEnum(STT.FILE);
246+/// Deprecated, use `@intFromEnum(std.elf.STT.COMMON)`
247+pub const STT_COMMON = @intFromEnum(STT.COMMON);
248+/// Deprecated, use `@intFromEnum(std.elf.STT.TLS)`
249+pub const STT_TLS = @intFromEnum(STT.TLS);
250+/// Deprecated, use `std.elf.STT.NUM`
251+pub const STT_NUM = STT.NUM;
252+/// Deprecated, use `@intFromEnum(std.elf.STT.LOOS)`
253+pub const STT_LOOS = @intFromEnum(STT.LOOS);
254+/// Deprecated, use `@intFromEnum(std.elf.STT.GNU_IFUNC)`
255+pub const STT_GNU_IFUNC = @intFromEnum(STT.GNU_IFUNC);
256+/// Deprecated, use `@intFromEnum(std.elf.STT.HIOS)`
257+pub const STT_HIOS = @intFromEnum(STT.HIOS);
258+/// Deprecated, use `@intFromEnum(std.elf.STT.LOPROC)`
259+pub const STT_LOPROC = @intFromEnum(STT.LOPROC);
260+/// Deprecated, use `@intFromEnum(std.elf.STT.HIPROC)`
261+pub const STT_HIPROC = @intFromEnum(STT.HIPROC);
262+
263+/// Deprecated, use `@intFromEnum(std.elf.STT.SPARC_REGISTER)`
264+pub const STT_SPARC_REGISTER = @intFromEnum(STT.SPARC_REGISTER);
265+
266+/// Deprecated, use `@intFromEnum(std.elf.STT.PARISC_MILLICODE)`
267+pub const STT_PARISC_MILLICODE = @intFromEnum(STT.PARISC_MILLICODE);
268+
269+/// Deprecated, use `@intFromEnum(std.elf.STT.HP_OPAQUE)`
270+pub const STT_HP_OPAQUE = @intFromEnum(STT.HP_OPAQUE);
271+/// Deprecated, use `@intFromEnum(std.elf.STT.HP_STUB)`
272+pub const STT_HP_STUB = @intFromEnum(STT.HP_STUB);
273+
274+/// Deprecated, use `@intFromEnum(std.elf.STT.ARM_TFUNC)`
275+pub const STT_ARM_TFUNC = @intFromEnum(STT.ARM_TFUNC);
276+/// Deprecated, use `@intFromEnum(std.elf.STT.ARM_16BIT)`
277+pub const STT_ARM_16BIT = @intFromEnum(STT.ARM_16BIT);
278+
279+pub const STB = enum(u4) {
280+ /// Local symbol
281+ LOCAL = 0,
282+ /// Global symbol
283+ GLOBAL = 1,
284+ /// Weak symbol
285+ WEAK = 2,
286+ _,
287+
288+ /// Number of defined types
289+ pub const NUM = @typeInfo(STB).@"enum".fields.len;
290+
291+ /// Start of OS-specific
292+ pub const LOOS: STB = @enumFromInt(10);
293+ /// End of OS-specific
294+ pub const HIOS: STB = @enumFromInt(12);
295+
296+ /// Unique symbol
297+ pub const GNU_UNIQUE: STB = @enumFromInt(@intFromEnum(LOOS) + 0);
298+
299+ /// Start of processor-specific
300+ pub const LOPROC: STB = @enumFromInt(13);
301+ /// End of processor-specific
302+ pub const HIPROC: STB = @enumFromInt(15);
303+
304+ pub const MIPS_SPLIT_COMMON: STB = @enumFromInt(@intFromEnum(LOPROC) + 0);
305+};
306+
307+pub const STT = enum(u4) {
308+ /// Symbol type is unspecified
309+ NOTYPE = 0,
310+ /// Symbol is a data object
311+ OBJECT = 1,
312+ /// Symbol is a code object
313+ FUNC = 2,
314+ /// Symbol associated with a section
315+ SECTION = 3,
316+ /// Symbol's name is file name
317+ FILE = 4,
318+ /// Symbol is a common data object
319+ COMMON = 5,
320+ /// Symbol is thread-local data object
321+ TLS = 6,
322+ _,
323+
324+ /// Number of defined types
325+ pub const NUM = @typeInfo(STT).@"enum".fields.len;
326+
327+ /// Start of OS-specific
328+ pub const LOOS: STT = @enumFromInt(10);
329+ /// End of OS-specific
330+ pub const HIOS: STT = @enumFromInt(12);
331
332-pub const STT_SPARC_REGISTER = 13;
333+ /// Symbol is indirect code object
334+ pub const GNU_IFUNC: STT = @enumFromInt(@intFromEnum(LOOS) + 0);
335
336-pub const STT_PARISC_MILLICODE = 13;
337+ pub const HP_OPAQUE: STT = @enumFromInt(@intFromEnum(LOOS) + 1);
338+ pub const HP_STUB: STT = @enumFromInt(@intFromEnum(LOOS) + 2);
339
340-pub const STT_HP_OPAQUE = (STT_LOOS + 0x1);
341-pub const STT_HP_STUB = (STT_LOOS + 0x2);
342+ /// Start of processor-specific
343+ pub const LOPROC: STT = @enumFromInt(13);
344+ /// End of processor-specific
345+ pub const HIPROC: STT = @enumFromInt(15);
346
347-pub const STT_ARM_TFUNC = STT_LOPROC;
348-pub const STT_ARM_16BIT = STT_HIPROC;
349+ pub const SPARC_REGISTER: STT = @enumFromInt(@intFromEnum(LOPROC) + 0);
350+
351+ pub const PARISC_MILLICODE: STT = @enumFromInt(@intFromEnum(LOPROC) + 0);
352+
353+ pub const ARM_TFUNC: STT = @enumFromInt(@intFromEnum(LOPROC) + 0);
354+ pub const ARM_16BIT: STT = @enumFromInt(@intFromEnum(HIPROC) + 2);
355+};
356+
357+pub const STV = enum(u3) {
358+ DEFAULT = 0,
359+ INTERNAL = 1,
360+ HIDDEN = 2,
361+ PROTECTED = 3,
362+};
363
364 pub const MAGIC = "\x7fELF";
365
366@@ -534,15 +622,15 @@ pub const Header = struct {
367 const buf = try r.peek(@sizeOf(Elf64_Ehdr));
368
369 if (!mem.eql(u8, buf[0..4], MAGIC)) return error.InvalidElfMagic;
370- if (buf[EI_VERSION] != 1) return error.InvalidElfVersion;
371+ if (buf[EI.VERSION] != 1) return error.InvalidElfVersion;
372
373- const endian: std.builtin.Endian = switch (buf[EI_DATA]) {
374+ const endian: std.builtin.Endian = switch (buf[EI.DATA]) {
375 ELFDATA2LSB => .little,
376 ELFDATA2MSB => .big,
377 else => return error.InvalidElfEndian,
378 };
379
380- return switch (buf[EI_CLASS]) {
381+ return switch (buf[EI.CLASS]) {
382 ELFCLASS32 => .init(try r.takeStruct(Elf32_Ehdr, endian), endian),
383 ELFCLASS64 => .init(try r.takeStruct(Elf64_Ehdr, endian), endian),
384 else => return error.InvalidElfClass,
385@@ -559,8 +647,8 @@ pub const Header = struct {
386 else => @compileError("bad type"),
387 },
388 .endian = endian,
389- .os_abi = @enumFromInt(hdr.e_ident[EI_OSABI]),
390- .abi_version = hdr.e_ident[EI_ABIVERSION],
391+ .os_abi = @enumFromInt(hdr.e_ident[EI.OSABI]),
392+ .abi_version = hdr.e_ident[EI.ABIVERSION],
393 .type = hdr.e_type,
394 .machine = hdr.e_machine,
395 .entry = hdr.e_entry,
396@@ -683,38 +771,200 @@ fn takeShdr(reader: *std.Io.Reader, elf_header: Header) !?Elf64_Shdr {
397 };
398 }
399
400-pub const ELFCLASSNONE = 0;
401-pub const ELFCLASS32 = 1;
402-pub const ELFCLASS64 = 2;
403-pub const ELFCLASSNUM = 3;
404-
405-pub const ELFDATANONE = 0;
406-pub const ELFDATA2LSB = 1;
407-pub const ELFDATA2MSB = 2;
408-pub const ELFDATANUM = 3;
409-
410-pub const EI_CLASS = 4;
411-pub const EI_DATA = 5;
412-pub const EI_VERSION = 6;
413-pub const EI_OSABI = 7;
414-pub const EI_ABIVERSION = 8;
415-pub const EI_PAD = 9;
416-
417-pub const EI_NIDENT = 16;
418+pub const EI = struct {
419+ pub const CLASS = 4;
420+ pub const DATA = 5;
421+ pub const VERSION = 6;
422+ pub const OSABI = 7;
423+ pub const ABIVERSION = 8;
424+ pub const PAD = 9;
425+ pub const NIDENT = 16;
426+};
427+
428+/// Deprecated, use `std.elf.EI.CLASS`
429+pub const EI_CLASS = EI.CLASS;
430+/// Deprecated, use `std.elf.EI.DATA`
431+pub const EI_DATA = EI.DATA;
432+/// Deprecated, use `std.elf.EI.VERSION`
433+pub const EI_VERSION = EI.VERSION;
434+/// Deprecated, use `std.elf.EI.OSABI`
435+pub const EI_OSABI = EI.OSABI;
436+/// Deprecated, use `std.elf.EI.ABIVERSION`
437+pub const EI_ABIVERSION = EI.ABIVERSION;
438+/// Deprecated, use `std.elf.EI.PAD`
439+pub const EI_PAD = EI.PAD;
440+/// Deprecated, use `std.elf.EI.NIDENT`
441+pub const EI_NIDENT = EI.NIDENT;
442
443 pub const Half = u16;
444 pub const Word = u32;
445 pub const Sword = i32;
446-pub const Elf32_Xword = u64;
447-pub const Elf32_Sxword = i64;
448-pub const Elf64_Xword = u64;
449+pub const Xword = u64;
450+pub const Sxword = i64;
451+pub const Section = u16;
452+pub const Elf32 = struct {
453+ pub const Addr = u32;
454+ pub const Off = u32;
455+ pub const Ehdr = extern struct {
456+ ident: [EI.NIDENT]u8,
457+ type: ET,
458+ machine: EM,
459+ version: Word,
460+ entry: Elf32.Addr,
461+ phoff: Elf32.Off,
462+ shoff: Elf32.Off,
463+ flags: Word,
464+ ehsize: Half,
465+ phentsize: Half,
466+ phnum: Half,
467+ shentsize: Half,
468+ shnum: Half,
469+ shstrndx: Half,
470+ };
471+ pub const Phdr = extern struct {
472+ type: Word,
473+ offset: Elf32.Off,
474+ vaddr: Elf32.Addr,
475+ paddr: Elf32.Addr,
476+ filesz: Word,
477+ memsz: Word,
478+ flags: PF,
479+ @"align": Word,
480+ };
481+ pub const Shdr = extern struct {
482+ name: Word,
483+ type: Word,
484+ flags: packed struct { shf: SHF },
485+ addr: Elf32.Addr,
486+ offset: Elf32.Off,
487+ size: Word,
488+ link: Word,
489+ info: Word,
490+ addralign: Word,
491+ entsize: Word,
492+ };
493+ pub const Chdr = extern struct {
494+ type: COMPRESS,
495+ size: Word,
496+ addralign: Word,
497+ };
498+ pub const Sym = extern struct {
499+ name: Word,
500+ value: Elf32.Addr,
501+ size: Word,
502+ info: Info,
503+ other: Other,
504+ shndx: Section,
505+
506+ pub const Info = packed struct(u8) {
507+ type: STT,
508+ bind: STB,
509+ };
510+
511+ pub const Other = packed struct(u8) {
512+ visibility: STV,
513+ unused: u5 = 0,
514+ };
515+ };
516+ comptime {
517+ assert(@sizeOf(Elf32.Ehdr) == 52);
518+ assert(@sizeOf(Elf32.Phdr) == 32);
519+ assert(@sizeOf(Elf32.Shdr) == 40);
520+ assert(@sizeOf(Elf32.Sym) == 16);
521+ }
522+};
523+pub const Elf64 = struct {
524+ pub const Addr = u64;
525+ pub const Off = u64;
526+ pub const Ehdr = extern struct {
527+ ident: [EI.NIDENT]u8,
528+ type: ET,
529+ machine: EM,
530+ version: Word,
531+ entry: Elf64.Addr,
532+ phoff: Elf64.Off,
533+ shoff: Elf64.Off,
534+ flags: Word,
535+ ehsize: Half,
536+ phentsize: Half,
537+ phnum: Half,
538+ shentsize: Half,
539+ shnum: Half,
540+ shstrndx: Half,
541+ };
542+ pub const Phdr = extern struct {
543+ type: Word,
544+ flags: PF,
545+ offset: Elf64.Off,
546+ vaddr: Elf64.Addr,
547+ paddr: Elf64.Addr,
548+ filesz: Xword,
549+ memsz: Xword,
550+ @"align": Xword,
551+ };
552+ pub const Shdr = extern struct {
553+ name: Word,
554+ type: Word,
555+ flags: packed struct { shf: SHF, unused: Word = 0 },
556+ addr: Elf64.Addr,
557+ offset: Elf64.Off,
558+ size: Xword,
559+ link: Word,
560+ info: Word,
561+ addralign: Xword,
562+ entsize: Xword,
563+ };
564+ pub const Chdr = extern struct {
565+ type: COMPRESS,
566+ reserved: Word = 0,
567+ size: Xword,
568+ addralign: Xword,
569+ };
570+ pub const Sym = extern struct {
571+ name: Word,
572+ info: Info,
573+ other: Other,
574+ shndx: Section,
575+ value: Elf64.Addr,
576+ size: Xword,
577+
578+ pub const Info = Elf32.Sym.Info;
579+ pub const Other = Elf32.Sym.Other;
580+ };
581+ comptime {
582+ assert(@sizeOf(Elf64.Ehdr) == 64);
583+ assert(@sizeOf(Elf64.Phdr) == 56);
584+ assert(@sizeOf(Elf64.Shdr) == 64);
585+ assert(@sizeOf(Elf64.Sym) == 24);
586+ }
587+};
588+pub const ElfN = switch (@sizeOf(usize)) {
589+ 4 => Elf32,
590+ 8 => Elf64,
591+ else => @compileError("expected pointer size of 32 or 64"),
592+};
593+
594+/// Deprecated, use `std.elf.Xword`
595+pub const Elf32_Xword = Xword;
596+/// Deprecated, use `std.elf.Sxword`
597+pub const Elf32_Sxword = Sxword;
598+/// Deprecated, use `std.elf.Xword`
599+pub const Elf64_Xword = Xword;
600+/// Deprecated, use `std.elf.Sxword`
601 pub const Elf64_Sxword = i64;
602+/// Deprecated, use `std.elf.Elf32.Addr`
603 pub const Elf32_Addr = u32;
604+/// Deprecated, use `std.elf.Elf64.Addr`
605 pub const Elf64_Addr = u64;
606+/// Deprecated, use `std.elf.Elf32.Off`
607 pub const Elf32_Off = u32;
608+/// Deprecated, use `std.elf.Elf64.Off`
609 pub const Elf64_Off = u64;
610+/// Deprecated, use `std.elf.Section`
611 pub const Elf32_Section = u16;
612+/// Deprecated, use `std.elf.Section`
613 pub const Elf64_Section = u16;
614+/// Deprecated, use `std.elf.Elf32.Ehdr`
615 pub const Elf32_Ehdr = extern struct {
616 e_ident: [EI_NIDENT]u8,
617 e_type: ET,
618@@ -731,8 +981,9 @@ pub const Elf32_Ehdr = extern struct {
619 e_shnum: Half,
620 e_shstrndx: Half,
621 };
622+/// Deprecated, use `std.elf.Elf64.Ehdr`
623 pub const Elf64_Ehdr = extern struct {
624- e_ident: [EI_NIDENT]u8,
625+ e_ident: [EI.NIDENT]u8,
626 e_type: ET,
627 e_machine: EM,
628 e_version: Word,
629@@ -747,6 +998,7 @@ pub const Elf64_Ehdr = extern struct {
630 e_shnum: Half,
631 e_shstrndx: Half,
632 };
633+/// Deprecated, use `std.elf.Elf32.Phdr`
634 pub const Elf32_Phdr = extern struct {
635 p_type: Word,
636 p_offset: Elf32_Off,
637@@ -757,6 +1009,7 @@ pub const Elf32_Phdr = extern struct {
638 p_flags: Word,
639 p_align: Word,
640 };
641+/// Deprecated, use `std.elf.Elf64.Phdr`
642 pub const Elf64_Phdr = extern struct {
643 p_type: Word,
644 p_flags: Word,
645@@ -767,6 +1020,7 @@ pub const Elf64_Phdr = extern struct {
646 p_memsz: Elf64_Xword,
647 p_align: Elf64_Xword,
648 };
649+/// Deprecated, use `std.elf.Elf32.Shdr`
650 pub const Elf32_Shdr = extern struct {
651 sh_name: Word,
652 sh_type: Word,
653@@ -779,6 +1033,7 @@ pub const Elf32_Shdr = extern struct {
654 sh_addralign: Word,
655 sh_entsize: Word,
656 };
657+/// Deprecated, use `std.elf.Elf64.Shdr`
658 pub const Elf64_Shdr = extern struct {
659 sh_name: Word,
660 sh_type: Word,
661@@ -791,17 +1046,20 @@ pub const Elf64_Shdr = extern struct {
662 sh_addralign: Elf64_Xword,
663 sh_entsize: Elf64_Xword,
664 };
665+/// Deprecated, use `std.elf.Elf32.Chdr`
666 pub const Elf32_Chdr = extern struct {
667 ch_type: COMPRESS,
668 ch_size: Word,
669 ch_addralign: Word,
670 };
671+/// Deprecated, use `std.elf.Elf64.Chdr`
672 pub const Elf64_Chdr = extern struct {
673 ch_type: COMPRESS,
674 ch_reserved: Word = 0,
675 ch_size: Elf64_Xword,
676 ch_addralign: Elf64_Xword,
677 };
678+/// Deprecated, use `std.elf.Elf32.Sym`
679 pub const Elf32_Sym = extern struct {
680 st_name: Word,
681 st_value: Elf32_Addr,
682@@ -817,6 +1075,7 @@ pub const Elf32_Sym = extern struct {
683 return @truncate(self.st_info >> 4);
684 }
685 };
686+/// Deprecated, use `std.elf.Elf64.Sym`
687 pub const Elf64_Sym = extern struct {
688 st_name: Word,
689 st_info: u8,
690@@ -1020,27 +1279,18 @@ pub const Elf_MIPS_ABIFlags_v0 = extern struct {
691 flags2: Word,
692 };
693
694-comptime {
695- assert(@sizeOf(Elf32_Ehdr) == 52);
696- assert(@sizeOf(Elf64_Ehdr) == 64);
697-
698- assert(@sizeOf(Elf32_Phdr) == 32);
699- assert(@sizeOf(Elf64_Phdr) == 56);
700-
701- assert(@sizeOf(Elf32_Shdr) == 40);
702- assert(@sizeOf(Elf64_Shdr) == 64);
703-}
704-
705 pub const Auxv = switch (@sizeOf(usize)) {
706 4 => Elf32_auxv_t,
707 8 => Elf64_auxv_t,
708 else => @compileError("expected pointer size of 32 or 64"),
709 };
710+/// Deprecated, use `std.elf.ElfN.Ehdr`
711 pub const Ehdr = switch (@sizeOf(usize)) {
712 4 => Elf32_Ehdr,
713 8 => Elf64_Ehdr,
714 else => @compileError("expected pointer size of 32 or 64"),
715 };
716+/// Deprecated, use `std.elf.ElfN.Phdr`
717 pub const Phdr = switch (@sizeOf(usize)) {
718 4 => Elf32_Phdr,
719 8 => Elf64_Phdr,
720@@ -1071,20 +1321,53 @@ pub const Shdr = switch (@sizeOf(usize)) {
721 8 => Elf64_Shdr,
722 else => @compileError("expected pointer size of 32 or 64"),
723 };
724+/// Deprecated, use `std.elf.ElfN.Chdr`
725 pub const Chdr = switch (@sizeOf(usize)) {
726 4 => Elf32_Chdr,
727 8 => Elf64_Chdr,
728 else => @compileError("expected pointer size of 32 or 64"),
729 };
730+/// Deprecated, use `std.elf.ElfN.Sym`
731 pub const Sym = switch (@sizeOf(usize)) {
732 4 => Elf32_Sym,
733 8 => Elf64_Sym,
734 else => @compileError("expected pointer size of 32 or 64"),
735 };
736-pub const Addr = switch (@sizeOf(usize)) {
737- 4 => Elf32_Addr,
738- 8 => Elf64_Addr,
739- else => @compileError("expected pointer size of 32 or 64"),
740+/// Deprecated, use `std.elf.ElfN.Addr`
741+pub const Addr = ElfN.Addr;
742+
743+/// Deprecated, use `@intFromEnum(std.elf.CLASS.NONE)`
744+pub const ELFCLASSNONE = @intFromEnum(CLASS.NONE);
745+/// Deprecated, use `@intFromEnum(std.elf.CLASS.@"32")`
746+pub const ELFCLASS32 = @intFromEnum(CLASS.@"32");
747+/// Deprecated, use `@intFromEnum(std.elf.CLASS.@"64")`
748+pub const ELFCLASS64 = @intFromEnum(CLASS.@"64");
749+/// Deprecated, use `@intFromEnum(std.elf.CLASS.NUM)`
750+pub const ELFCLASSNUM = CLASS.NUM;
751+pub const CLASS = enum(u8) {
752+ NONE = 0,
753+ @"32" = 1,
754+ @"64" = 2,
755+ _,
756+
757+ pub const NUM = @typeInfo(CLASS).@"enum".fields.len;
758+};
759+
760+/// Deprecated, use `@intFromEnum(std.elf.DATA.NONE)`
761+pub const ELFDATANONE = @intFromEnum(DATA.NONE);
762+/// Deprecated, use `@intFromEnum(std.elf.DATA.@"2LSB")`
763+pub const ELFDATA2LSB = @intFromEnum(DATA.@"2LSB");
764+/// Deprecated, use `@intFromEnum(std.elf.DATA.@"2MSB")`
765+pub const ELFDATA2MSB = @intFromEnum(DATA.@"2MSB");
766+/// Deprecated, use `@intFromEnum(std.elf.DATA.NUM)`
767+pub const ELFDATANUM = DATA.NUM;
768+pub const DATA = enum(u8) {
769+ NONE = 0,
770+ @"2LSB" = 1,
771+ @"2MSB" = 2,
772+ _,
773+
774+ pub const NUM = @typeInfo(DATA).@"enum".fields.len;
775 };
776
777 pub const OSABI = enum(u8) {
778@@ -1718,6 +2001,108 @@ pub const SHF_MIPS_STRING = 0x80000000;
779 /// Make code section unreadable when in execute-only mode
780 pub const SHF_ARM_PURECODE = 0x2000000;
781
782+pub const SHF = packed struct(Word) {
783+ /// Section data should be writable during execution.
784+ WRITE: bool = false,
785+ /// Section occupies memory during program execution.
786+ ALLOC: bool = false,
787+ /// Section contains executable machine instructions.
788+ EXECINSTR: bool = false,
789+ unused3: u1 = 0,
790+ /// The data in this section may be merged.
791+ MERGE: bool = false,
792+ /// The data in this section is null-terminated strings.
793+ STRINGS: bool = false,
794+ /// A field in this section holds a section header table index.
795+ INFO_LINK: bool = false,
796+ /// Adds special ordering requirements for link editors.
797+ LINK_ORDER: bool = false,
798+ /// This section requires special OS-specific processing to avoid incorrect behavior.
799+ OS_NONCONFORMING: bool = false,
800+ /// This section is a member of a section group.
801+ GROUP: bool = false,
802+ /// This section holds Thread-Local Storage.
803+ TLS: bool = false,
804+ /// Identifies a section containing compressed data.
805+ COMPRESSED: bool = false,
806+ unused12: u8 = 0,
807+ OS: packed union {
808+ MASK: u8,
809+ GNU: packed struct(u8) {
810+ unused0: u1 = 0,
811+ /// Not to be GCed by the linker
812+ RETAIN: bool = false,
813+ unused2: u6 = 0,
814+ },
815+ MIPS: packed struct(u8) {
816+ unused0: u4 = 0,
817+ /// Section contains text/data which may be replicated in other sections.
818+ /// Linker must retain only one copy.
819+ NODUPES: bool = false,
820+ /// Linker must generate implicit hidden weak names.
821+ NAMES: bool = false,
822+ /// Section data local to process.
823+ LOCAL: bool = false,
824+ /// Do not strip this section.
825+ NOSTRIP: bool = false,
826+ },
827+ ARM: packed struct(u8) {
828+ unused0: u5 = 0,
829+ /// Make code section unreadable when in execute-only mode
830+ PURECODE: bool = false,
831+ unused6: u2 = 0,
832+ },
833+ } = .{ .MASK = 0 },
834+ PROC: packed union {
835+ MASK: u4,
836+ XCORE: packed struct(u4) {
837+ /// All sections with the "d" flag are grouped together by the linker to form
838+ /// the data section and the dp register is set to the start of the section by
839+ /// the boot code.
840+ DP_SECTION: bool = false,
841+ /// All sections with the "c" flag are grouped together by the linker to form
842+ /// the constant pool and the cp register is set to the start of the constant
843+ /// pool by the boot code.
844+ CP_SECTION: bool = false,
845+ unused2: u1 = 0,
846+ /// This section is excluded from the final executable or shared library.
847+ EXCLUDE: bool = false,
848+ },
849+ X86_64: packed struct(u4) {
850+ /// If an object file section does not have this flag set, then it may not hold
851+ /// more than 2GB and can be freely referred to in objects using smaller code
852+ /// models. Otherwise, only objects using larger code models can refer to them.
853+ /// For example, a medium code model object can refer to data in a section that
854+ /// sets this flag besides being able to refer to data in a section that does
855+ /// not set it; likewise, a small code model object can refer only to code in a
856+ /// section that does not set this flag.
857+ LARGE: bool = false,
858+ unused1: u2 = 0,
859+ /// This section is excluded from the final executable or shared library.
860+ EXCLUDE: bool = false,
861+ },
862+ HEX: packed struct(u4) {
863+ /// All sections with the GPREL flag are grouped into a global data area
864+ /// for faster accesses
865+ GPREL: bool = false,
866+ unused1: u2 = 0,
867+ /// This section is excluded from the final executable or shared library.
868+ EXCLUDE: bool = false,
869+ },
870+ MIPS: packed struct(u4) {
871+ /// All sections with the GPREL flag are grouped into a global data area
872+ /// for faster accesses
873+ GPREL: bool = false,
874+ /// This section should be merged.
875+ MERGE: bool = false,
876+ /// Address size to be inferred from section entry size.
877+ ADDR: bool = false,
878+ /// Section data is string data by default.
879+ STRING: bool = false,
880+ },
881+ } = .{ .MASK = 0 },
882+};
883+
884 /// Execute
885 pub const PF_X = 1;
886
887@@ -1733,6 +2118,19 @@ pub const PF_MASKOS = 0x0ff00000;
888 /// Bits for processor-specific semantics.
889 pub const PF_MASKPROC = 0xf0000000;
890
891+pub const PF = packed struct(Word) {
892+ X: bool = false,
893+ W: bool = false,
894+ R: bool = false,
895+ unused3: u17 = 0,
896+ OS: packed union {
897+ MASK: u8,
898+ } = .{ .MASK = 0 },
899+ PROC: packed union {
900+ MASK: u4,
901+ } = .{ .MASK = 0 },
902+};
903+
904 /// Undefined section
905 pub const SHN_UNDEF = 0;
906 /// Start of reserved indices
907@@ -2303,13 +2701,6 @@ pub const R_PPC64 = enum(u32) {
908 _,
909 };
910
911-pub const STV = enum(u3) {
912- DEFAULT = 0,
913- INTERNAL = 1,
914- HIDDEN = 2,
915- PROTECTED = 3,
916-};
917-
918 pub const ar_hdr = extern struct {
919 /// Member file name, sometimes / terminated.
920 ar_name: [16]u8,
921diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig
922index b2116c1a74..55f1fd14cb 100644
923--- a/lib/std/zig/system.zig
924+++ b/lib/std/zig/system.zig
925@@ -516,15 +516,15 @@ pub fn abiAndDynamicLinkerFromFile(
926 const hdr32: *elf.Elf32_Ehdr = @ptrCast(&hdr_buf);
927 const hdr64: *elf.Elf64_Ehdr = @ptrCast(&hdr_buf);
928 if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic;
929- const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) {
930+ const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI.DATA]) {
931 elf.ELFDATA2LSB => .little,
932 elf.ELFDATA2MSB => .big,
933 else => return error.InvalidElfEndian,
934 };
935 const need_bswap = elf_endian != native_endian;
936- if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion;
937+ if (hdr32.e_ident[elf.EI.VERSION] != 1) return error.InvalidElfVersion;
938
939- const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) {
940+ const is_64 = switch (hdr32.e_ident[elf.EI.CLASS]) {
941 elf.ELFCLASS32 => false,
942 elf.ELFCLASS64 => true,
943 else => return error.InvalidElfClass,
944@@ -920,15 +920,15 @@ fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion {
945 const hdr32: *elf.Elf32_Ehdr = @ptrCast(&hdr_buf);
946 const hdr64: *elf.Elf64_Ehdr = @ptrCast(&hdr_buf);
947 if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic;
948- const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) {
949+ const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI.DATA]) {
950 elf.ELFDATA2LSB => .little,
951 elf.ELFDATA2MSB => .big,
952 else => return error.InvalidElfEndian,
953 };
954 const need_bswap = elf_endian != native_endian;
955- if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion;
956+ if (hdr32.e_ident[elf.EI.VERSION] != 1) return error.InvalidElfVersion;
957
958- const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) {
959+ const is_64 = switch (hdr32.e_ident[elf.EI.CLASS]) {
960 elf.ELFCLASS32 => false,
961 elf.ELFCLASS64 => true,
962 else => return error.InvalidElfClass,
963diff --git a/src/Compilation.zig b/src/Compilation.zig
964index 34953ed11a..bf7246b8d8 100644
965--- a/src/Compilation.zig
966+++ b/src/Compilation.zig
967@@ -177,7 +177,6 @@ debug_compiler_runtime_libs: bool,
968 debug_compile_errors: bool,
969 /// Do not check this field directly. Instead, use the `debugIncremental` wrapper function.
970 debug_incremental: bool,
971-incremental: bool,
972 alloc_failure_occurred: bool = false,
973 last_update_was_cache_hit: bool = false,
974
975@@ -256,7 +255,9 @@ mutex: if (builtin.single_threaded) struct {
976 test_filters: []const []const u8,
977
978 link_task_wait_group: WaitGroup = .{},
979-link_prog_node: std.Progress.Node = std.Progress.Node.none,
980+link_prog_node: std.Progress.Node = .none,
981+link_uav_prog_node: std.Progress.Node = .none,
982+link_lazy_prog_node: std.Progress.Node = .none,
983
984 llvm_opt_bisect_limit: c_int,
985
986@@ -1746,7 +1747,6 @@ pub const CreateOptions = struct {
987 debug_compiler_runtime_libs: bool = false,
988 debug_compile_errors: bool = false,
989 debug_incremental: bool = false,
990- incremental: bool = false,
991 /// Normally when you create a `Compilation`, Zig will automatically build
992 /// and link in required dependencies, such as compiler-rt and libc. When
993 /// building such dependencies themselves, this flag must be set to avoid
994@@ -1982,6 +1982,7 @@ pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options
995 };
996 if (have_zcu and (!need_llvm or use_llvm)) {
997 if (output_mode == .Obj) break :s .zcu;
998+ if (options.config.use_new_linker) break :s .zcu;
999 switch (target_util.zigBackend(target, use_llvm)) {
1000 else => {},
1001 .stage2_aarch64, .stage2_x86_64 => if (target.ofmt == .coff) {
1002@@ -2188,8 +2189,8 @@ pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options
1003 .inherited = .{},
1004 .global = options.config,
1005 .parent = options.root_mod,
1006- }) catch |err| return switch (err) {
1007- error.OutOfMemory => |e| return e,
1008+ }) catch |err| switch (err) {
1009+ error.OutOfMemory => return error.OutOfMemory,
1010 // None of these are possible because the configuration matches the root module
1011 // which already passed these checks.
1012 error.ValgrindUnsupportedOnTarget => unreachable,
1013@@ -2266,7 +2267,6 @@ pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options
1014 .debug_compiler_runtime_libs = options.debug_compiler_runtime_libs,
1015 .debug_compile_errors = options.debug_compile_errors,
1016 .debug_incremental = options.debug_incremental,
1017- .incremental = options.incremental,
1018 .root_name = root_name,
1019 .sysroot = sysroot,
1020 .windows_libs = .empty,
1021@@ -2409,6 +2409,8 @@ pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options
1022 // Synchronize with other matching comments: ZigOnlyHashStuff
1023 hash.add(use_llvm);
1024 hash.add(options.config.use_lib_llvm);
1025+ hash.add(options.config.use_lld);
1026+ hash.add(options.config.use_new_linker);
1027 hash.add(options.config.dll_export_fns);
1028 hash.add(options.config.is_test);
1029 hash.addListOfBytes(options.test_filters);
1030@@ -3075,14 +3077,29 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
1031
1032 // The linker progress node is set up here instead of in `performAllTheWork`, because
1033 // we also want it around during `flush`.
1034- const have_link_node = comp.bin_file != null;
1035- if (have_link_node) {
1036+ if (comp.bin_file) |lf| {
1037 comp.link_prog_node = main_progress_node.start("Linking", 0);
1038+ if (lf.cast(.elf2)) |elf| {
1039+ comp.link_prog_node.increaseEstimatedTotalItems(3);
1040+ comp.link_uav_prog_node = comp.link_prog_node.start("Constants", 0);
1041+ comp.link_lazy_prog_node = comp.link_prog_node.start("Synthetics", 0);
1042+ elf.mf.update_prog_node = comp.link_prog_node.start("Relocations", elf.mf.updates.items.len);
1043+ }
1044 }
1045- defer if (have_link_node) {
1046+ defer {
1047 comp.link_prog_node.end();
1048 comp.link_prog_node = .none;
1049- };
1050+ comp.link_uav_prog_node.end();
1051+ comp.link_uav_prog_node = .none;
1052+ comp.link_lazy_prog_node.end();
1053+ comp.link_lazy_prog_node = .none;
1054+ if (comp.bin_file) |lf| {
1055+ if (lf.cast(.elf2)) |elf| {
1056+ elf.mf.update_prog_node.end();
1057+ elf.mf.update_prog_node = .none;
1058+ }
1059+ }
1060+ }
1061
1062 try comp.performAllTheWork(main_progress_node);
1063
1064@@ -3100,6 +3117,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
1065 try pt.populateTestFunctions();
1066 }
1067
1068+ link.updateErrorData(pt);
1069+
1070 try pt.processExports();
1071 }
1072
1073@@ -3474,6 +3493,8 @@ fn addNonIncrementalStuffToCacheManifest(
1074
1075 man.hash.add(comp.config.use_llvm);
1076 man.hash.add(comp.config.use_lib_llvm);
1077+ man.hash.add(comp.config.use_lld);
1078+ man.hash.add(comp.config.use_new_linker);
1079 man.hash.add(comp.config.is_test);
1080 man.hash.add(comp.config.import_memory);
1081 man.hash.add(comp.config.export_memory);
1082@@ -4073,7 +4094,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
1083 defer sorted_failed_analysis.deinit(gpa);
1084 var added_any_analysis_error = false;
1085 for (sorted_failed_analysis.items(.key), sorted_failed_analysis.items(.value)) |anal_unit, error_msg| {
1086- if (comp.incremental) {
1087+ if (comp.config.incremental) {
1088 const refs = try zcu.resolveReferences();
1089 if (!refs.contains(anal_unit)) continue;
1090 }
1091@@ -4240,7 +4261,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
1092
1093 // TODO: eventually, this should be behind `std.debug.runtime_safety`. But right now, this is a
1094 // very common way for incremental compilation bugs to manifest, so let's always check it.
1095- if (comp.zcu) |zcu| if (comp.incremental and bundle.root_list.items.len == 0) {
1096+ if (comp.zcu) |zcu| if (comp.config.incremental and bundle.root_list.items.len == 0) {
1097 for (zcu.transitive_failed_analysis.keys()) |failed_unit| {
1098 const refs = try zcu.resolveReferences();
1099 var ref = refs.get(failed_unit) orelse continue;
1100@@ -4949,7 +4970,7 @@ fn performAllTheWork(
1101 tr.stats.n_reachable_files = @intCast(zcu.alive_files.count());
1102 }
1103
1104- if (comp.incremental) {
1105+ if (comp.config.incremental) {
1106 const update_zir_refs_node = main_progress_node.start("Update ZIR References", 0);
1107 defer update_zir_refs_node.end();
1108 try pt.updateZirRefs();
1109diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig
1110index d8751251da..45f7e509de 100644
1111--- a/src/Compilation/Config.zig
1112+++ b/src/Compilation/Config.zig
1113@@ -49,6 +49,8 @@ use_lib_llvm: bool,
1114 use_lld: bool,
1115 c_frontend: CFrontend,
1116 lto: std.zig.LtoMode,
1117+use_new_linker: bool,
1118+incremental: bool,
1119 /// WASI-only. Type of WASI execution model ("command" or "reactor").
1120 /// Always set to `command` for non-WASI targets.
1121 wasi_exec_model: std.builtin.WasiExecModel,
1122@@ -104,6 +106,8 @@ pub const Options = struct {
1123 use_lld: ?bool = null,
1124 use_clang: ?bool = null,
1125 lto: ?std.zig.LtoMode = null,
1126+ use_new_linker: ?bool = null,
1127+ incremental: bool = false,
1128 /// WASI-only. Type of WASI execution model ("command" or "reactor").
1129 wasi_exec_model: ?std.builtin.WasiExecModel = null,
1130 import_memory: ?bool = null,
1131@@ -147,6 +151,8 @@ pub const ResolveError = error{
1132 LldUnavailable,
1133 ClangUnavailable,
1134 DllExportFnsRequiresWindows,
1135+ NewLinkerIncompatibleWithLld,
1136+ NewLinkerIncompatibleObjectFormat,
1137 };
1138
1139 pub fn resolve(options: Options) ResolveError!Config {
1140@@ -458,6 +464,22 @@ pub fn resolve(options: Options) ResolveError!Config {
1141 break :b .none;
1142 };
1143
1144+ const use_new_linker = b: {
1145+ if (use_lld) {
1146+ if (options.use_new_linker == true) return error.NewLinkerIncompatibleWithLld;
1147+ break :b false;
1148+ }
1149+
1150+ if (!target_util.hasNewLinkerSupport(target.ofmt)) {
1151+ if (options.use_new_linker == true) return error.NewLinkerIncompatibleObjectFormat;
1152+ break :b false;
1153+ }
1154+
1155+ if (options.use_new_linker) |x| break :b x;
1156+
1157+ break :b options.incremental;
1158+ };
1159+
1160 const root_strip = b: {
1161 if (options.root_strip) |x| break :b x;
1162 if (root_optimize_mode == .ReleaseSmall) break :b true;
1163@@ -531,6 +553,8 @@ pub fn resolve(options: Options) ResolveError!Config {
1164 .root_error_tracing = root_error_tracing,
1165 .pie = pie,
1166 .lto = lto,
1167+ .use_new_linker = use_new_linker,
1168+ .incremental = options.incremental,
1169 .import_memory = import_memory,
1170 .export_memory = export_memory,
1171 .shared_memory = shared_memory,
1172diff --git a/src/InternPool.zig b/src/InternPool.zig
1173index 9965497742..f4344af86d 100644
1174--- a/src/InternPool.zig
1175+++ b/src/InternPool.zig
1176@@ -6424,14 +6424,25 @@ pub const Alignment = enum(u6) {
1177 return n + 1;
1178 }
1179
1180+ pub fn toStdMem(a: Alignment) std.mem.Alignment {
1181+ assert(a != .none);
1182+ return @enumFromInt(@intFromEnum(a));
1183+ }
1184+
1185+ pub fn fromStdMem(a: std.mem.Alignment) Alignment {
1186+ const r: Alignment = @enumFromInt(@intFromEnum(a));
1187+ assert(r != .none);
1188+ return r;
1189+ }
1190+
1191 const LlvmBuilderAlignment = std.zig.llvm.Builder.Alignment;
1192
1193- pub fn toLlvm(this: @This()) LlvmBuilderAlignment {
1194- return @enumFromInt(@intFromEnum(this));
1195+ pub fn toLlvm(a: Alignment) LlvmBuilderAlignment {
1196+ return @enumFromInt(@intFromEnum(a));
1197 }
1198
1199- pub fn fromLlvm(other: LlvmBuilderAlignment) @This() {
1200- return @enumFromInt(@intFromEnum(other));
1201+ pub fn fromLlvm(a: LlvmBuilderAlignment) Alignment {
1202+ return @enumFromInt(@intFromEnum(a));
1203 }
1204 };
1205
1206diff --git a/src/Sema.zig b/src/Sema.zig
1207index 946e890ea3..d0576de33d 100644
1208--- a/src/Sema.zig
1209+++ b/src/Sema.zig
1210@@ -3032,7 +3032,7 @@ fn zirStructDecl(
1211 });
1212 errdefer pt.destroyNamespace(new_namespace_index);
1213
1214- if (pt.zcu.comp.incremental) {
1215+ if (pt.zcu.comp.config.incremental) {
1216 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = tracked_inst });
1217 }
1218
1219@@ -3430,7 +3430,7 @@ fn zirUnionDecl(
1220 });
1221 errdefer pt.destroyNamespace(new_namespace_index);
1222
1223- if (pt.zcu.comp.incremental) {
1224+ if (pt.zcu.comp.config.incremental) {
1225 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = tracked_inst });
1226 }
1227
1228@@ -6217,7 +6217,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
1229 if (ptr_info.byte_offset != 0) {
1230 return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});
1231 }
1232- if (options.linkage == .internal) return;
1233+ if (zcu.llvm_object != null and options.linkage == .internal) return;
1234 const export_ty = Value.fromInterned(uav.val).typeOf(zcu);
1235 if (!try sema.validateExternType(export_ty, .other)) {
1236 return sema.failWithOwnedErrorMsg(block, msg: {
1237@@ -6256,7 +6256,7 @@ pub fn analyzeExport(
1238 const zcu = pt.zcu;
1239 const ip = &zcu.intern_pool;
1240
1241- if (options.linkage == .internal)
1242+ if (zcu.llvm_object != null and options.linkage == .internal)
1243 return;
1244
1245 try sema.ensureNavResolved(block, src, orig_nav_index, .fully);
1246@@ -7709,7 +7709,7 @@ fn analyzeCall(
1247 // TODO: comptime call memoization is currently not supported under incremental compilation
1248 // since dependencies are not marked on callers. If we want to keep this around (we should
1249 // check that it's worthwhile first!), each memoized call needs an `AnalUnit`.
1250- if (zcu.comp.incremental) break :m false;
1251+ if (zcu.comp.config.incremental) break :m false;
1252 if (!block.isComptime()) break :m false;
1253 for (args) |a| {
1254 const val = (try sema.resolveValue(a)).?;
1255@@ -31208,7 +31208,7 @@ fn addReferenceEntry(
1256 .func => |f| assert(ip.unwrapCoercedFunc(f) == f), // for `.{ .func = f }`, `f` must be uncoerced
1257 else => {},
1258 }
1259- if (!zcu.comp.incremental and zcu.comp.reference_trace == 0) return;
1260+ if (!zcu.comp.config.incremental and zcu.comp.reference_trace == 0) return;
1261 const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);
1262 if (gop.found_existing) return;
1263 try zcu.addUnitReference(sema.owner, referenced_unit, src, inline_frame: {
1264@@ -31225,7 +31225,7 @@ pub fn addTypeReferenceEntry(
1265 referenced_type: InternPool.Index,
1266 ) !void {
1267 const zcu = sema.pt.zcu;
1268- if (!zcu.comp.incremental and zcu.comp.reference_trace == 0) return;
1269+ if (!zcu.comp.config.incremental and zcu.comp.reference_trace == 0) return;
1270 const gop = try sema.type_references.getOrPut(sema.gpa, referenced_type);
1271 if (gop.found_existing) return;
1272 try zcu.addTypeReference(sema.owner, referenced_type, src);
1273@@ -36875,7 +36875,7 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool
1274
1275 pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
1276 const pt = sema.pt;
1277- if (!pt.zcu.comp.incremental) return;
1278+ if (!pt.zcu.comp.config.incremental) return;
1279
1280 const gop = try sema.dependencies.getOrPut(sema.gpa, dependee);
1281 if (gop.found_existing) return;
1282diff --git a/src/Value.zig b/src/Value.zig
1283index 8de5621761..381eacf45a 100644
1284--- a/src/Value.zig
1285+++ b/src/Value.zig
1286@@ -23,7 +23,7 @@ pub fn format(val: Value, writer: *std.Io.Writer) !void {
1287
1288 /// This is a debug function. In order to print values in a meaningful way
1289 /// we also need access to the type.
1290-pub fn dump(start_val: Value, w: std.Io.Writer) std.Io.Writer.Error!void {
1291+pub fn dump(start_val: Value, w: *std.Io.Writer) std.Io.Writer.Error!void {
1292 try w.print("(interned: {})", .{start_val.toIntern()});
1293 }
1294
1295diff --git a/src/Zcu.zig b/src/Zcu.zig
1296index 706bdb5165..8e9e9c2902 100644
1297--- a/src/Zcu.zig
1298+++ b/src/Zcu.zig
1299@@ -3166,7 +3166,7 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
1300 }
1301
1302 pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
1303- if (!zcu.comp.incremental) return null;
1304+ if (!zcu.comp.config.incremental) return null;
1305
1306 if (zcu.outdated.count() == 0) {
1307 // Any units in `potentially_outdated` must just be stuck in loops with one another: none of those
1308diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig
1309index 77cddb204e..32782e7e89 100644
1310--- a/src/Zcu/PerThread.zig
1311+++ b/src/Zcu/PerThread.zig
1312@@ -1815,7 +1815,7 @@ fn createFileRootStruct(
1313 wip_ty.setName(ip, try file.internFullyQualifiedName(pt), .none);
1314 ip.namespacePtr(namespace_index).owner_type = wip_ty.index;
1315
1316- if (zcu.comp.incremental) {
1317+ if (zcu.comp.config.incremental) {
1318 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = tracked_inst });
1319 }
1320
1321diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig
1322index 7b13cfc90d..fe40ba4bbb 100644
1323--- a/src/arch/riscv64/CodeGen.zig
1324+++ b/src/arch/riscv64/CodeGen.zig
1325@@ -858,9 +858,11 @@ pub fn generateLazy(
1326 pt: Zcu.PerThread,
1327 src_loc: Zcu.LazySrcLoc,
1328 lazy_sym: link.File.LazySymbol,
1329- code: *std.ArrayListUnmanaged(u8),
1330+ atom_index: u32,
1331+ w: *std.Io.Writer,
1332 debug_output: link.File.DebugInfoOutput,
1333-) CodeGenError!void {
1334+) (CodeGenError || std.Io.Writer.Error)!void {
1335+ _ = atom_index;
1336 const comp = bin_file.comp;
1337 const gpa = comp.gpa;
1338 const mod = comp.root_mod;
1339@@ -914,7 +916,7 @@ pub fn generateLazy(
1340 },
1341 .bin_file = bin_file,
1342 .debug_output = debug_output,
1343- .code = code,
1344+ .w = w,
1345 .prev_di_pc = undefined, // no debug info yet
1346 .prev_di_line = undefined, // no debug info yet
1347 .prev_di_column = undefined, // no debug info yet
1348diff --git a/src/arch/riscv64/Emit.zig b/src/arch/riscv64/Emit.zig
1349index 2e72aff941..64a476007c 100644
1350--- a/src/arch/riscv64/Emit.zig
1351+++ b/src/arch/riscv64/Emit.zig
1352@@ -3,7 +3,7 @@
1353 bin_file: *link.File,
1354 lower: Lower,
1355 debug_output: link.File.DebugInfoOutput,
1356-code: *std.ArrayListUnmanaged(u8),
1357+w: *std.Io.Writer,
1358
1359 prev_di_line: u32,
1360 prev_di_column: u32,
1361@@ -13,7 +13,7 @@ prev_di_pc: usize,
1362 code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty,
1363 relocs: std.ArrayListUnmanaged(Reloc) = .empty,
1364
1365-pub const Error = Lower.Error || error{
1366+pub const Error = Lower.Error || std.Io.Writer.Error || error{
1367 EmitFail,
1368 };
1369
1370@@ -25,13 +25,13 @@ pub fn emitMir(emit: *Emit) Error!void {
1371 try emit.code_offset_mapping.putNoClobber(
1372 emit.lower.allocator,
1373 mir_index,
1374- @intCast(emit.code.items.len),
1375+ @intCast(emit.w.end),
1376 );
1377 const lowered = try emit.lower.lowerMir(mir_index, .{ .allow_frame_locs = true });
1378 var lowered_relocs = lowered.relocs;
1379 for (lowered.insts, 0..) |lowered_inst, lowered_index| {
1380- const start_offset: u32 = @intCast(emit.code.items.len);
1381- std.mem.writeInt(u32, try emit.code.addManyAsArray(gpa, 4), lowered_inst.toU32(), .little);
1382+ const start_offset: u32 = @intCast(emit.w.end);
1383+ try emit.w.writeInt(u32, lowered_inst.toU32(), .little);
1384
1385 while (lowered_relocs.len > 0 and
1386 lowered_relocs[0].lowered_inst_index == lowered_index) : ({
1387@@ -175,7 +175,7 @@ fn fixupRelocs(emit: *Emit) Error!void {
1388 return emit.fail("relocation target not found!", .{});
1389
1390 const disp = @as(i32, @intCast(target)) - @as(i32, @intCast(reloc.source));
1391- const code: *[4]u8 = emit.code.items[reloc.source + reloc.offset ..][0..4];
1392+ const code = emit.w.buffered()[reloc.source + reloc.offset ..][0..4];
1393
1394 switch (reloc.fmt) {
1395 .J => riscv_util.writeInstJ(code, @bitCast(disp)),
1396@@ -187,7 +187,7 @@ fn fixupRelocs(emit: *Emit) Error!void {
1397
1398 fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
1399 const delta_line = @as(i33, line) - @as(i33, emit.prev_di_line);
1400- const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
1401+ const delta_pc: usize = emit.w.end - emit.prev_di_pc;
1402 log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
1403 switch (emit.debug_output) {
1404 .dwarf => |dw| {
1405@@ -196,7 +196,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
1406 try dw.advancePCAndLine(delta_line, delta_pc);
1407 emit.prev_di_line = line;
1408 emit.prev_di_column = column;
1409- emit.prev_di_pc = emit.code.items.len;
1410+ emit.prev_di_pc = emit.w.end;
1411 },
1412 .none => {},
1413 }
1414diff --git a/src/arch/riscv64/Mir.zig b/src/arch/riscv64/Mir.zig
1415index 6fb8e23a98..204ab6a3c0 100644
1416--- a/src/arch/riscv64/Mir.zig
1417+++ b/src/arch/riscv64/Mir.zig
1418@@ -109,9 +109,11 @@ pub fn emit(
1419 pt: Zcu.PerThread,
1420 src_loc: Zcu.LazySrcLoc,
1421 func_index: InternPool.Index,
1422- code: *std.ArrayListUnmanaged(u8),
1423+ atom_index: u32,
1424+ w: *std.Io.Writer,
1425 debug_output: link.File.DebugInfoOutput,
1426-) codegen.CodeGenError!void {
1427+) (codegen.CodeGenError || std.Io.Writer.Error)!void {
1428+ _ = atom_index;
1429 const zcu = pt.zcu;
1430 const comp = zcu.comp;
1431 const gpa = comp.gpa;
1432@@ -132,7 +134,7 @@ pub fn emit(
1433 },
1434 .bin_file = lf,
1435 .debug_output = debug_output,
1436- .code = code,
1437+ .w = w,
1438 .prev_di_pc = 0,
1439 .prev_di_line = func.lbrace_line,
1440 .prev_di_column = func.lbrace_column,
1441diff --git a/src/arch/sparc64/Emit.zig b/src/arch/sparc64/Emit.zig
1442index d41f1cdf07..26282b09ab 100644
1443--- a/src/arch/sparc64/Emit.zig
1444+++ b/src/arch/sparc64/Emit.zig
1445@@ -21,7 +21,7 @@ debug_output: link.File.DebugInfoOutput,
1446 target: *const std.Target,
1447 err_msg: ?*ErrorMsg = null,
1448 src_loc: Zcu.LazySrcLoc,
1449-code: *std.ArrayListUnmanaged(u8),
1450+w: *std.Io.Writer,
1451
1452 prev_di_line: u32,
1453 prev_di_column: u32,
1454@@ -40,7 +40,7 @@ branch_forward_origins: std.AutoHashMapUnmanaged(Mir.Inst.Index, std.ArrayListUn
1455 /// instruction
1456 code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty,
1457
1458-const InnerError = error{
1459+const InnerError = std.Io.Writer.Error || error{
1460 OutOfMemory,
1461 EmitFail,
1462 };
1463@@ -292,7 +292,7 @@ fn mirConditionalBranch(emit: *Emit, inst: Mir.Inst.Index) !void {
1464 .bpcc => switch (tag) {
1465 .bpcc => {
1466 const branch_predict_int = emit.mir.instructions.items(.data)[inst].branch_predict_int;
1467- const offset = @as(i64, @intCast(emit.code_offset_mapping.get(branch_predict_int.inst).?)) - @as(i64, @intCast(emit.code.items.len));
1468+ const offset = @as(i64, @intCast(emit.code_offset_mapping.get(branch_predict_int.inst).?)) - @as(i64, @intCast(emit.w.end));
1469 log.debug("mirConditionalBranch: {} offset={}", .{ inst, offset });
1470
1471 try emit.writeInstruction(
1472@@ -310,7 +310,7 @@ fn mirConditionalBranch(emit: *Emit, inst: Mir.Inst.Index) !void {
1473 .bpr => switch (tag) {
1474 .bpr => {
1475 const branch_predict_reg = emit.mir.instructions.items(.data)[inst].branch_predict_reg;
1476- const offset = @as(i64, @intCast(emit.code_offset_mapping.get(branch_predict_reg.inst).?)) - @as(i64, @intCast(emit.code.items.len));
1477+ const offset = @as(i64, @intCast(emit.code_offset_mapping.get(branch_predict_reg.inst).?)) - @as(i64, @intCast(emit.w.end));
1478 log.debug("mirConditionalBranch: {} offset={}", .{ inst, offset });
1479
1480 try emit.writeInstruction(
1481@@ -494,13 +494,13 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index {
1482
1483 fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void {
1484 const delta_line = @as(i32, @intCast(line)) - @as(i32, @intCast(emit.prev_di_line));
1485- const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
1486+ const delta_pc: usize = emit.w.end - emit.prev_di_pc;
1487 switch (emit.debug_output) {
1488 .dwarf => |dbg_out| {
1489 try dbg_out.advancePCAndLine(delta_line, delta_pc);
1490 emit.prev_di_line = line;
1491 emit.prev_di_column = column;
1492- emit.prev_di_pc = emit.code.items.len;
1493+ emit.prev_di_pc = emit.w.end;
1494 },
1495 else => {},
1496 }
1497@@ -675,13 +675,8 @@ fn optimalBranchType(emit: *Emit, tag: Mir.Inst.Tag, offset: i64) !BranchType {
1498 }
1499
1500 fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
1501- const comp = emit.bin_file.comp;
1502- const gpa = comp.gpa;
1503-
1504 // SPARCv9 instructions are always arranged in BE regardless of the
1505 // endianness mode the CPU is running in (Section 3.1 of the ISA specification).
1506 // This is to ease porting in case someone wants to do a LE SPARCv9 backend.
1507- const endian: Endian = .big;
1508-
1509- std.mem.writeInt(u32, try emit.code.addManyAsArray(gpa, 4), instruction.toU32(), endian);
1510+ try emit.w.writeInt(u32, instruction.toU32(), .big);
1511 }
1512diff --git a/src/arch/sparc64/Mir.zig b/src/arch/sparc64/Mir.zig
1513index 842ac10fed..41d135eb83 100644
1514--- a/src/arch/sparc64/Mir.zig
1515+++ b/src/arch/sparc64/Mir.zig
1516@@ -380,9 +380,11 @@ pub fn emit(
1517 pt: Zcu.PerThread,
1518 src_loc: Zcu.LazySrcLoc,
1519 func_index: InternPool.Index,
1520- code: *std.ArrayListUnmanaged(u8),
1521+ atom_index: u32,
1522+ w: *std.Io.Writer,
1523 debug_output: link.File.DebugInfoOutput,
1524-) codegen.CodeGenError!void {
1525+) (codegen.CodeGenError || std.Io.Writer.Error)!void {
1526+ _ = atom_index;
1527 const zcu = pt.zcu;
1528 const func = zcu.funcInfo(func_index);
1529 const nav = func.owner_nav;
1530@@ -393,7 +395,7 @@ pub fn emit(
1531 .debug_output = debug_output,
1532 .target = &mod.resolved_target.result,
1533 .src_loc = src_loc,
1534- .code = code,
1535+ .w = w,
1536 .prev_di_pc = 0,
1537 .prev_di_line = func.lbrace_line,
1538 .prev_di_column = func.lbrace_column,
1539diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
1540index b5760c95ac..1827b50d61 100644
1541--- a/src/arch/x86_64/CodeGen.zig
1542+++ b/src/arch/x86_64/CodeGen.zig
1543@@ -550,9 +550,9 @@ pub const MCValue = union(enum) {
1544 @tagName(pl.reg),
1545 }),
1546 .indirect => |pl| try w.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
1547- .indirect_load_frame => |pl| try w.print("[[{} + 0x{x}]]", .{ pl.index, pl.off }),
1548- .load_frame => |pl| try w.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
1549- .lea_frame => |pl| try w.print("{} + 0x{x}", .{ pl.index, pl.off }),
1550+ .indirect_load_frame => |pl| try w.print("[[{f} + 0x{x}]]", .{ pl.index, pl.off }),
1551+ .load_frame => |pl| try w.print("[{f} + 0x{x}]", .{ pl.index, pl.off }),
1552+ .lea_frame => |pl| try w.print("{f} + 0x{x}", .{ pl.index, pl.off }),
1553 .load_nav => |pl| try w.print("[nav:{d}]", .{@intFromEnum(pl)}),
1554 .lea_nav => |pl| try w.print("nav:{d}", .{@intFromEnum(pl)}),
1555 .load_uav => |pl| try w.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
1556@@ -561,10 +561,10 @@ pub const MCValue = union(enum) {
1557 .lea_lazy_sym => |pl| try w.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
1558 .load_extern_func => |pl| try w.print("[extern:{d}]", .{@intFromEnum(pl)}),
1559 .lea_extern_func => |pl| try w.print("extern:{d}", .{@intFromEnum(pl)}),
1560- .elementwise_args => |pl| try w.print("elementwise:{d}:[{} + 0x{x}]", .{
1561+ .elementwise_args => |pl| try w.print("elementwise:{d}:[{f} + 0x{x}]", .{
1562 pl.regs, pl.frame_index, pl.frame_off,
1563 }),
1564- .reserved_frame => |pl| try w.print("(dead:{})", .{pl}),
1565+ .reserved_frame => |pl| try w.print("(dead:{f})", .{pl}),
1566 .air_ref => |pl| try w.print("(air:0x{x})", .{@intFromEnum(pl)}),
1567 }
1568 }
1569@@ -1038,7 +1038,8 @@ pub fn generateLazy(
1570 pt: Zcu.PerThread,
1571 src_loc: Zcu.LazySrcLoc,
1572 lazy_sym: link.File.LazySymbol,
1573- code: *std.ArrayListUnmanaged(u8),
1574+ atom_index: u32,
1575+ w: *std.Io.Writer,
1576 debug_output: link.File.DebugInfoOutput,
1577 ) codegen.CodeGenError!void {
1578 const gpa = pt.zcu.gpa;
1579@@ -1081,7 +1082,7 @@ pub fn generateLazy(
1580 else => |e| return e,
1581 };
1582
1583- try function.getTmpMir().emitLazy(bin_file, pt, src_loc, lazy_sym, code, debug_output);
1584+ try function.getTmpMir().emitLazy(bin_file, pt, src_loc, lazy_sym, atom_index, w, debug_output);
1585 }
1586
1587 const FormatNavData = struct {
1588@@ -2022,7 +2023,7 @@ fn gen(
1589 .{},
1590 );
1591 self.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } };
1592- tracking_log.debug("spill {f} to {}", .{ self.ret_mcv.long, frame_index });
1593+ tracking_log.debug("spill {f} to {f}", .{ self.ret_mcv.long, frame_index });
1594 },
1595 else => unreachable,
1596 }
1597diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig
1598index 84bb325322..c2b38d8e6d 100644
1599--- a/src/arch/x86_64/Emit.zig
1600+++ b/src/arch/x86_64/Emit.zig
1601@@ -6,7 +6,7 @@ pt: Zcu.PerThread,
1602 pic: bool,
1603 atom_index: u32,
1604 debug_output: link.File.DebugInfoOutput,
1605-code: *std.ArrayListUnmanaged(u8),
1606+w: *std.Io.Writer,
1607
1608 prev_di_loc: Loc,
1609 /// Relative to the beginning of `code`.
1610@@ -18,7 +18,8 @@ table_relocs: std.ArrayListUnmanaged(TableReloc),
1611
1612 pub const Error = Lower.Error || error{
1613 EmitFail,
1614-} || link.File.UpdateDebugInfoError;
1615+ NotFile,
1616+} || std.posix.MMapError || std.posix.MRemapError || link.File.UpdateDebugInfoError;
1617
1618 pub fn emitMir(emit: *Emit) Error!void {
1619 const comp = emit.bin_file.comp;
1620@@ -29,12 +30,12 @@ pub fn emitMir(emit: *Emit) Error!void {
1621 var local_index: usize = 0;
1622 for (0..emit.lower.mir.instructions.len) |mir_i| {
1623 const mir_index: Mir.Inst.Index = @intCast(mir_i);
1624- emit.code_offset_mapping.items[mir_index] = @intCast(emit.code.items.len);
1625+ emit.code_offset_mapping.items[mir_index] = @intCast(emit.w.end);
1626 const lowered = try emit.lower.lowerMir(mir_index);
1627 var lowered_relocs = lowered.relocs;
1628 lowered_inst: for (lowered.insts, 0..) |lowered_inst, lowered_index| {
1629 if (lowered_inst.prefix == .directive) {
1630- const start_offset: u32 = @intCast(emit.code.items.len);
1631+ const start_offset: u32 = @intCast(emit.w.end);
1632 switch (emit.debug_output) {
1633 .dwarf => |dwarf| switch (lowered_inst.encoding.mnemonic) {
1634 .@".cfi_def_cfa" => try dwarf.genDebugFrame(start_offset, .{ .def_cfa = .{
1635@@ -164,6 +165,8 @@ pub fn emitMir(emit: *Emit) Error!void {
1636 .index = if (emit.bin_file.cast(.elf)) |elf_file|
1637 elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, emit.pt, lazy_sym) catch |err|
1638 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
1639+ else if (emit.bin_file.cast(.elf2)) |elf|
1640+ @intFromEnum(try elf.lazySymbol(lazy_sym))
1641 else if (emit.bin_file.cast(.macho)) |macho_file|
1642 macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
1643 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
1644@@ -180,12 +183,15 @@ pub fn emitMir(emit: *Emit) Error!void {
1645 .extern_func => |extern_func| .{
1646 .index = if (emit.bin_file.cast(.elf)) |elf_file|
1647 try elf_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)
1648- else if (emit.bin_file.cast(.macho)) |macho_file|
1649+ else if (emit.bin_file.cast(.elf2)) |elf| @intFromEnum(try elf.globalSymbol(.{
1650+ .name = extern_func.toSlice(&emit.lower.mir).?,
1651+ .type = .FUNC,
1652+ })) else if (emit.bin_file.cast(.macho)) |macho_file|
1653 try macho_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)
1654 else if (emit.bin_file.cast(.coff)) |coff_file|
1655 try coff_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, "compiler_rt")
1656 else
1657- return emit.fail("external symbols unimplemented for {s}", .{@tagName(emit.bin_file.tag)}),
1658+ return emit.fail("external symbol unimplemented for {s}", .{@tagName(emit.bin_file.tag)}),
1659 .is_extern = true,
1660 .type = .symbol,
1661 },
1662@@ -205,7 +211,7 @@ pub fn emitMir(emit: *Emit) Error!void {
1663 },
1664 else => {},
1665 }
1666- if (emit.bin_file.cast(.elf)) |_| {
1667+ if (emit.bin_file.cast(.elf) != null or emit.bin_file.cast(.elf2) != null) {
1668 if (!emit.pic) switch (lowered_inst.encoding.mnemonic) {
1669 .lea => try emit.encodeInst(try .new(.none, .mov, &.{
1670 lowered_inst.ops[0],
1671@@ -315,7 +321,7 @@ pub fn emitMir(emit: *Emit) Error!void {
1672 },
1673 .branch, .tls => unreachable,
1674 .tlv => {
1675- if (emit.bin_file.cast(.elf)) |elf_file| {
1676+ if (emit.bin_file.cast(.elf) != null or emit.bin_file.cast(.elf2) != null) {
1677 // TODO handle extern TLS vars, i.e., emit GD model
1678 if (emit.pic) switch (lowered_inst.encoding.mnemonic) {
1679 .lea, .mov => {
1680@@ -337,7 +343,12 @@ pub fn emitMir(emit: *Emit) Error!void {
1681 }, emit.lower.target), &.{.{
1682 .op_index = 0,
1683 .target = .{
1684- .index = try elf_file.getGlobalSymbol("__tls_get_addr", null),
1685+ .index = if (emit.bin_file.cast(.elf)) |elf_file|
1686+ try elf_file.getGlobalSymbol("__tls_get_addr", null)
1687+ else if (emit.bin_file.cast(.elf2)) |elf| @intFromEnum(try elf.globalSymbol(.{
1688+ .name = "__tls_get_addr",
1689+ .type = .FUNC,
1690+ })) else unreachable,
1691 .is_extern = true,
1692 .type = .branch,
1693 },
1694@@ -441,7 +452,7 @@ pub fn emitMir(emit: *Emit) Error!void {
1695 log.debug("mirDbgEnterBlock (line={d}, col={d})", .{
1696 emit.prev_di_loc.line, emit.prev_di_loc.column,
1697 });
1698- try dwarf.enterBlock(emit.code.items.len);
1699+ try dwarf.enterBlock(emit.w.end);
1700 },
1701 .none => {},
1702 },
1703@@ -450,7 +461,7 @@ pub fn emitMir(emit: *Emit) Error!void {
1704 log.debug("mirDbgLeaveBlock (line={d}, col={d})", .{
1705 emit.prev_di_loc.line, emit.prev_di_loc.column,
1706 });
1707- try dwarf.leaveBlock(emit.code.items.len);
1708+ try dwarf.leaveBlock(emit.w.end);
1709 },
1710 .none => {},
1711 },
1712@@ -459,7 +470,7 @@ pub fn emitMir(emit: *Emit) Error!void {
1713 log.debug("mirDbgEnterInline (line={d}, col={d})", .{
1714 emit.prev_di_loc.line, emit.prev_di_loc.column,
1715 });
1716- try dwarf.enterInlineFunc(mir_inst.data.ip_index, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);
1717+ try dwarf.enterInlineFunc(mir_inst.data.ip_index, emit.w.end, emit.prev_di_loc.line, emit.prev_di_loc.column);
1718 },
1719 .none => {},
1720 },
1721@@ -468,7 +479,7 @@ pub fn emitMir(emit: *Emit) Error!void {
1722 log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
1723 emit.prev_di_loc.line, emit.prev_di_loc.column,
1724 });
1725- try dwarf.leaveInlineFunc(mir_inst.data.ip_index, emit.code.items.len);
1726+ try dwarf.leaveInlineFunc(mir_inst.data.ip_index, emit.w.end);
1727 },
1728 .none => {},
1729 },
1730@@ -634,7 +645,7 @@ pub fn emitMir(emit: *Emit) Error!void {
1731 for (emit.relocs.items) |reloc| {
1732 const target = emit.code_offset_mapping.items[reloc.target];
1733 const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.inst_offset + reloc.inst_length)) + reloc.target_offset;
1734- const inst_bytes = emit.code.items[reloc.inst_offset..][0..reloc.inst_length];
1735+ const inst_bytes = emit.w.buffered()[reloc.inst_offset..][0..reloc.inst_length];
1736 switch (reloc.source_length) {
1737 else => unreachable,
1738 inline 1, 4 => |source_length| std.mem.writeInt(
1739@@ -646,12 +657,12 @@ pub fn emitMir(emit: *Emit) Error!void {
1740 }
1741 }
1742 if (emit.lower.mir.table.len > 0) {
1743+ const ptr_size = @divExact(emit.lower.target.ptrBitWidth(), 8);
1744+ var table_offset = std.mem.alignForward(u32, @intCast(emit.w.end), ptr_size);
1745 if (emit.bin_file.cast(.elf)) |elf_file| {
1746 const zo = elf_file.zigObjectPtr().?;
1747 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
1748
1749- const ptr_size = @divExact(emit.lower.target.ptrBitWidth(), 8);
1750- var table_offset = std.mem.alignForward(u32, @intCast(emit.code.items.len), ptr_size);
1751 for (emit.table_relocs.items) |table_reloc| try atom.addReloc(gpa, .{
1752 .r_offset = table_reloc.source_offset,
1753 .r_info = @as(u64, emit.atom_index) << 32 | @intFromEnum(std.elf.R_X86_64.@"32"),
1754@@ -665,7 +676,26 @@ pub fn emitMir(emit: *Emit) Error!void {
1755 }, zo);
1756 table_offset += ptr_size;
1757 }
1758- try emit.code.appendNTimes(gpa, 0, table_offset - emit.code.items.len);
1759+ try emit.w.splatByteAll(0, table_offset - emit.w.end);
1760+ } else if (emit.bin_file.cast(.elf2)) |elf| {
1761+ for (emit.table_relocs.items) |table_reloc| try elf.addReloc(
1762+ @enumFromInt(emit.atom_index),
1763+ table_reloc.source_offset,
1764+ @enumFromInt(emit.atom_index),
1765+ @as(i64, table_offset) + table_reloc.target_offset,
1766+ .{ .x86_64 = .@"32" },
1767+ );
1768+ for (emit.lower.mir.table) |entry| {
1769+ try elf.addReloc(
1770+ @enumFromInt(emit.atom_index),
1771+ table_offset,
1772+ @enumFromInt(emit.atom_index),
1773+ emit.code_offset_mapping.items[entry],
1774+ .{ .x86_64 = .@"64" },
1775+ );
1776+ table_offset += ptr_size;
1777+ }
1778+ try emit.w.splatByteAll(0, table_offset - emit.w.end);
1779 } else unreachable;
1780 }
1781 }
1782@@ -696,16 +726,12 @@ const RelocInfo = struct {
1783 fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocInfo) Error!void {
1784 const comp = emit.bin_file.comp;
1785 const gpa = comp.gpa;
1786- const start_offset: u32 = @intCast(emit.code.items.len);
1787- {
1788- var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, emit.code);
1789- defer emit.code.* = aw.toArrayList();
1790- lowered_inst.encode(&aw.writer, .{}) catch |err| switch (err) {
1791- error.WriteFailed => return error.OutOfMemory,
1792- else => |e| return e,
1793- };
1794- }
1795- const end_offset: u32 = @intCast(emit.code.items.len);
1796+ const start_offset: u32 = @intCast(emit.w.end);
1797+ lowered_inst.encode(emit.w, .{}) catch |err| switch (err) {
1798+ error.WriteFailed => return error.OutOfMemory,
1799+ else => |e| return e,
1800+ };
1801+ const end_offset: u32 = @intCast(emit.w.end);
1802 for (reloc_info) |reloc| switch (reloc.target.type) {
1803 .inst => {
1804 const inst_length: u4 = @intCast(end_offset - start_offset);
1805@@ -769,7 +795,13 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
1806 .symbolnum = @intCast(reloc.target.index),
1807 },
1808 });
1809- } else if (emit.bin_file.cast(.coff)) |coff_file| {
1810+ } else if (emit.bin_file.cast(.elf2)) |elf| try elf.addReloc(
1811+ @enumFromInt(emit.atom_index),
1812+ end_offset - 4,
1813+ @enumFromInt(reloc.target.index),
1814+ reloc.off,
1815+ .{ .x86_64 = .@"32" },
1816+ ) else if (emit.bin_file.cast(.coff)) |coff_file| {
1817 const atom_index = coff_file.getAtomIndexForSymbol(
1818 .{ .sym_index = emit.atom_index, .file = null },
1819 ).?;
1820@@ -794,7 +826,13 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
1821 .r_info = @as(u64, reloc.target.index) << 32 | @intFromEnum(r_type),
1822 .r_addend = reloc.off - 4,
1823 }, zo);
1824- } else if (emit.bin_file.cast(.macho)) |macho_file| {
1825+ } else if (emit.bin_file.cast(.elf2)) |elf| try elf.addReloc(
1826+ @enumFromInt(emit.atom_index),
1827+ end_offset - 4,
1828+ @enumFromInt(reloc.target.index),
1829+ reloc.off - 4,
1830+ .{ .x86_64 = .PC32 },
1831+ ) else if (emit.bin_file.cast(.macho)) |macho_file| {
1832 const zo = macho_file.getZigObject().?;
1833 const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
1834 try atom.addReloc(macho_file, .{
1835@@ -849,7 +887,13 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
1836 .r_info = @as(u64, reloc.target.index) << 32 | @intFromEnum(r_type),
1837 .r_addend = reloc.off,
1838 }, zo);
1839- } else if (emit.bin_file.cast(.macho)) |macho_file| {
1840+ } else if (emit.bin_file.cast(.elf2)) |elf| try elf.addReloc(
1841+ @enumFromInt(emit.atom_index),
1842+ end_offset - 4,
1843+ @enumFromInt(reloc.target.index),
1844+ reloc.off,
1845+ .{ .x86_64 = .TPOFF32 },
1846+ ) else if (emit.bin_file.cast(.macho)) |macho_file| {
1847 const zo = macho_file.getZigObject().?;
1848 const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
1849 try atom.addReloc(macho_file, .{
1850@@ -908,7 +952,7 @@ const Loc = struct {
1851
1852 fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
1853 const delta_line = @as(i33, loc.line) - @as(i33, emit.prev_di_loc.line);
1854- const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
1855+ const delta_pc: usize = emit.w.end - emit.prev_di_pc;
1856 log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
1857 switch (emit.debug_output) {
1858 .dwarf => |dwarf| {
1859@@ -916,7 +960,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
1860 if (loc.column != emit.prev_di_loc.column) try dwarf.setColumn(loc.column);
1861 try dwarf.advancePCAndLine(delta_line, delta_pc);
1862 emit.prev_di_loc = loc;
1863- emit.prev_di_pc = emit.code.items.len;
1864+ emit.prev_di_pc = emit.w.end;
1865 },
1866 .none => {},
1867 }
1868diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig
1869index e70018850d..caf41ffb39 100644
1870--- a/src/arch/x86_64/Mir.zig
1871+++ b/src/arch/x86_64/Mir.zig
1872@@ -1976,7 +1976,8 @@ pub fn emit(
1873 pt: Zcu.PerThread,
1874 src_loc: Zcu.LazySrcLoc,
1875 func_index: InternPool.Index,
1876- code: *std.ArrayListUnmanaged(u8),
1877+ atom_index: u32,
1878+ w: *std.Io.Writer,
1879 debug_output: link.File.DebugInfoOutput,
1880 ) codegen.CodeGenError!void {
1881 const zcu = pt.zcu;
1882@@ -1997,17 +1998,9 @@ pub fn emit(
1883 .bin_file = lf,
1884 .pt = pt,
1885 .pic = mod.pic,
1886- .atom_index = sym: {
1887- if (lf.cast(.elf)) |ef| break :sym try ef.zigObjectPtr().?.getOrCreateMetadataForNav(zcu, nav);
1888- if (lf.cast(.macho)) |mf| break :sym try mf.getZigObject().?.getOrCreateMetadataForNav(mf, nav);
1889- if (lf.cast(.coff)) |cf| {
1890- const atom = try cf.getOrCreateAtomForNav(nav);
1891- break :sym cf.getAtom(atom).getSymbolIndex().?;
1892- }
1893- unreachable;
1894- },
1895+ .atom_index = atom_index,
1896 .debug_output = debug_output,
1897- .code = code,
1898+ .w = w,
1899
1900 .prev_di_loc = .{
1901 .line = func.lbrace_line,
1902@@ -2037,7 +2030,8 @@ pub fn emitLazy(
1903 pt: Zcu.PerThread,
1904 src_loc: Zcu.LazySrcLoc,
1905 lazy_sym: link.File.LazySymbol,
1906- code: *std.ArrayListUnmanaged(u8),
1907+ atom_index: u32,
1908+ w: *std.Io.Writer,
1909 debug_output: link.File.DebugInfoOutput,
1910 ) codegen.CodeGenError!void {
1911 const zcu = pt.zcu;
1912@@ -2055,20 +2049,9 @@ pub fn emitLazy(
1913 .bin_file = lf,
1914 .pt = pt,
1915 .pic = mod.pic,
1916- .atom_index = sym: {
1917- if (lf.cast(.elf)) |ef| break :sym ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_sym) catch |err|
1918- return zcu.codegenFailType(lazy_sym.ty, "{s} creating lazy symbol", .{@errorName(err)});
1919- if (lf.cast(.macho)) |mf| break :sym mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_sym) catch |err|
1920- return zcu.codegenFailType(lazy_sym.ty, "{s} creating lazy symbol", .{@errorName(err)});
1921- if (lf.cast(.coff)) |cf| {
1922- const atom = cf.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
1923- return zcu.codegenFailType(lazy_sym.ty, "{s} creating lazy symbol", .{@errorName(err)});
1924- break :sym cf.getAtom(atom).getSymbolIndex().?;
1925- }
1926- unreachable;
1927- },
1928+ .atom_index = atom_index,
1929 .debug_output = debug_output,
1930- .code = code,
1931+ .w = w,
1932
1933 .prev_di_loc = undefined,
1934 .prev_di_pc = undefined,
1935diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig
1936index 835093d11a..0504810933 100644
1937--- a/src/arch/x86_64/bits.zig
1938+++ b/src/arch/x86_64/bits.zig
1939@@ -727,6 +727,14 @@ pub const FrameIndex = enum(u32) {
1940 pub fn isNamed(fi: FrameIndex) bool {
1941 return @intFromEnum(fi) < named_count;
1942 }
1943+
1944+ pub fn format(fi: FrameIndex, writer: *std.Io.Writer) std.Io.Writer.Error!void {
1945+ if (fi.isNamed()) {
1946+ try writer.print("FrameIndex.{t}", .{fi});
1947+ } else {
1948+ try writer.print("FrameIndex({d})", .{@intFromEnum(fi)});
1949+ }
1950+ }
1951 };
1952
1953 pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
1954diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig
1955index 03ff7134f6..1d9c67175e 100644
1956--- a/src/arch/x86_64/encoder.zig
1957+++ b/src/arch/x86_64/encoder.zig
1958@@ -259,7 +259,7 @@ pub const Instruction = struct {
1959 switch (sib.base) {
1960 .none => any = false,
1961 .reg => |reg| try w.print("{s}", .{@tagName(reg)}),
1962- .frame => |frame_index| try w.print("{}", .{frame_index}),
1963+ .frame => |frame_index| try w.print("{f}", .{frame_index}),
1964 .table => try w.print("Table", .{}),
1965 .rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}),
1966 .nav => |nav| try w.print("Nav({d})", .{@intFromEnum(nav)}),
1967diff --git a/src/codegen.zig b/src/codegen.zig
1968index 56e6e7c99f..4cbf3f5616 100644
1969--- a/src/codegen.zig
1970+++ b/src/codegen.zig
1971@@ -6,7 +6,6 @@ const link = @import("link.zig");
1972 const log = std.log.scoped(.codegen);
1973 const mem = std.mem;
1974 const math = std.math;
1975-const ArrayList = std.ArrayList;
1976 const target_util = @import("target.zig");
1977 const trace = @import("tracy.zig").trace;
1978
1979@@ -179,10 +178,11 @@ pub fn emitFunction(
1980 pt: Zcu.PerThread,
1981 src_loc: Zcu.LazySrcLoc,
1982 func_index: InternPool.Index,
1983+ atom_index: u32,
1984 any_mir: *const AnyMir,
1985- code: *ArrayList(u8),
1986+ w: *std.Io.Writer,
1987 debug_output: link.File.DebugInfoOutput,
1988-) CodeGenError!void {
1989+) (CodeGenError || std.Io.Writer.Error)!void {
1990 const zcu = pt.zcu;
1991 const func = zcu.funcInfo(func_index);
1992 const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
1993@@ -195,7 +195,7 @@ pub fn emitFunction(
1994 => |backend| {
1995 dev.check(devFeatureForBackend(backend));
1996 const mir = &@field(any_mir, AnyMir.tag(backend));
1997- return mir.emit(lf, pt, src_loc, func_index, code, debug_output);
1998+ return mir.emit(lf, pt, src_loc, func_index, atom_index, w, debug_output);
1999 },
2000 }
2001 }
2002@@ -205,9 +205,10 @@ pub fn generateLazyFunction(
2003 pt: Zcu.PerThread,
2004 src_loc: Zcu.LazySrcLoc,
2005 lazy_sym: link.File.LazySymbol,
2006- code: *ArrayList(u8),
2007+ atom_index: u32,
2008+ w: *std.Io.Writer,
2009 debug_output: link.File.DebugInfoOutput,
2010-) CodeGenError!void {
2011+) (CodeGenError || std.Io.Writer.Error)!void {
2012 const zcu = pt.zcu;
2013 const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|
2014 &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result
2015@@ -217,19 +218,11 @@ pub fn generateLazyFunction(
2016 else => unreachable,
2017 inline .stage2_riscv64, .stage2_x86_64 => |backend| {
2018 dev.check(devFeatureForBackend(backend));
2019- return importBackend(backend).generateLazy(lf, pt, src_loc, lazy_sym, code, debug_output);
2020+ return importBackend(backend).generateLazy(lf, pt, src_loc, lazy_sym, atom_index, w, debug_output);
2021 },
2022 }
2023 }
2024
2025-fn writeFloat(comptime F: type, f: F, target: *const std.Target, endian: std.builtin.Endian, code: []u8) void {
2026- _ = target;
2027- const bits = @typeInfo(F).float.bits;
2028- const Int = @Type(.{ .int = .{ .signedness = .unsigned, .bits = bits } });
2029- const int: Int = @bitCast(f);
2030- mem.writeInt(Int, code[0..@divExact(bits, 8)], int, endian);
2031-}
2032-
2033 pub fn generateLazySymbol(
2034 bin_file: *link.File,
2035 pt: Zcu.PerThread,
2036@@ -237,17 +230,14 @@ pub fn generateLazySymbol(
2037 lazy_sym: link.File.LazySymbol,
2038 // TODO don't use an "out" parameter like this; put it in the result instead
2039 alignment: *Alignment,
2040- code: *ArrayList(u8),
2041+ w: *std.Io.Writer,
2042 debug_output: link.File.DebugInfoOutput,
2043 reloc_parent: link.File.RelocInfo.Parent,
2044-) CodeGenError!void {
2045- _ = reloc_parent;
2046-
2047+) (CodeGenError || std.Io.Writer.Error)!void {
2048 const tracy = trace(@src());
2049 defer tracy.end();
2050
2051 const comp = bin_file.comp;
2052- const gpa = comp.gpa;
2053 const zcu = pt.zcu;
2054 const ip = &zcu.intern_pool;
2055 const target = &comp.root_mod.resolved_target.result;
2056@@ -260,37 +250,36 @@ pub fn generateLazySymbol(
2057
2058 if (lazy_sym.kind == .code) {
2059 alignment.* = target_util.defaultFunctionAlignment(target);
2060- return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, code, debug_output);
2061+ return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, reloc_parent.atom_index, w, debug_output);
2062 }
2063
2064 if (lazy_sym.ty == .anyerror_type) {
2065 alignment.* = .@"4";
2066 const err_names = ip.global_error_set.getNamesFromMainThread();
2067- var offset_index: u32 = @intCast(code.items.len);
2068- var string_index: u32 = @intCast(4 * (1 + err_names.len + @intFromBool(err_names.len > 0)));
2069- try code.resize(gpa, offset_index + string_index);
2070- mem.writeInt(u32, code.items[offset_index..][0..4], @intCast(err_names.len), endian);
2071+ const strings_start: u32 = @intCast(4 * (1 + err_names.len + @intFromBool(err_names.len > 0)));
2072+ var string_index = strings_start;
2073+ try w.rebase(w.end, string_index);
2074+ w.writeInt(u32, @intCast(err_names.len), endian) catch unreachable;
2075 if (err_names.len == 0) return;
2076- offset_index += 4;
2077 for (err_names) |err_name_nts| {
2078- const err_name = err_name_nts.toSlice(ip);
2079- mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);
2080- offset_index += 4;
2081- try code.ensureUnusedCapacity(gpa, err_name.len + 1);
2082- code.appendSliceAssumeCapacity(err_name);
2083- code.appendAssumeCapacity(0);
2084- string_index += @intCast(err_name.len + 1);
2085+ w.writeInt(u32, string_index, endian) catch unreachable;
2086+ string_index += @intCast(err_name_nts.toSlice(ip).len + 1);
2087+ }
2088+ w.writeInt(u32, string_index, endian) catch unreachable;
2089+ try w.rebase(w.end, string_index - strings_start);
2090+ for (err_names) |err_name_nts| {
2091+ w.writeAll(err_name_nts.toSlice(ip)) catch unreachable;
2092+ w.writeByte(0) catch unreachable;
2093 }
2094- mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);
2095 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu) == .@"enum") {
2096 alignment.* = .@"1";
2097 const enum_ty = Type.fromInterned(lazy_sym.ty);
2098 const tag_names = enum_ty.enumFields(zcu);
2099 for (0..tag_names.len) |tag_index| {
2100 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
2101- try code.ensureUnusedCapacity(gpa, tag_name.len + 1);
2102- code.appendSliceAssumeCapacity(tag_name);
2103- code.appendAssumeCapacity(0);
2104+ try w.rebase(w.end, tag_name.len + 1);
2105+ w.writeAll(tag_name) catch unreachable;
2106+ w.writeByte(0) catch unreachable;
2107 }
2108 } else {
2109 return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {f}", .{
2110@@ -312,14 +301,13 @@ pub fn generateSymbol(
2111 pt: Zcu.PerThread,
2112 src_loc: Zcu.LazySrcLoc,
2113 val: Value,
2114- code: *ArrayList(u8),
2115+ w: *std.Io.Writer,
2116 reloc_parent: link.File.RelocInfo.Parent,
2117-) GenerateSymbolError!void {
2118+) (GenerateSymbolError || std.Io.Writer.Error)!void {
2119 const tracy = trace(@src());
2120 defer tracy.end();
2121
2122 const zcu = pt.zcu;
2123- const gpa = zcu.gpa;
2124 const ip = &zcu.intern_pool;
2125 const ty = val.typeOf(zcu);
2126
2127@@ -330,7 +318,7 @@ pub fn generateSymbol(
2128
2129 if (val.isUndef(zcu)) {
2130 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
2131- try code.appendNTimes(gpa, 0xaa, abi_size);
2132+ try w.splatByteAll(0xaa, abi_size);
2133 return;
2134 }
2135
2136@@ -360,7 +348,7 @@ pub fn generateSymbol(
2137 .null => unreachable, // non-runtime value
2138 .@"unreachable" => unreachable, // non-runtime value
2139 .empty_tuple => return,
2140- .false, .true => try code.append(gpa, switch (simple_value) {
2141+ .false, .true => try w.writeByte(switch (simple_value) {
2142 .false => 0,
2143 .true => 1,
2144 else => unreachable,
2145@@ -376,11 +364,11 @@ pub fn generateSymbol(
2146 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
2147 var space: Value.BigIntSpace = undefined;
2148 const int_val = val.toBigInt(&space, zcu);
2149- int_val.writeTwosComplement(try code.addManyAsSlice(gpa, abi_size), endian);
2150+ int_val.writeTwosComplement(try w.writableSlice(abi_size), endian);
2151 },
2152 .err => |err| {
2153 const int = try pt.getErrorValue(err.name);
2154- mem.writeInt(u16, try code.addManyAsArray(gpa, 2), @intCast(int), endian);
2155+ try w.writeInt(u16, @intCast(int), endian);
2156 },
2157 .error_union => |error_union| {
2158 const payload_ty = ty.errorUnionPayload(zcu);
2159@@ -390,7 +378,7 @@ pub fn generateSymbol(
2160 };
2161
2162 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2163- mem.writeInt(u16, try code.addManyAsArray(gpa, 2), err_val, endian);
2164+ try w.writeInt(u16, err_val, endian);
2165 return;
2166 }
2167
2168@@ -400,63 +388,63 @@ pub fn generateSymbol(
2169
2170 // error value first when its type is larger than the error union's payload
2171 if (error_align.order(payload_align) == .gt) {
2172- mem.writeInt(u16, try code.addManyAsArray(gpa, 2), err_val, endian);
2173+ try w.writeInt(u16, err_val, endian);
2174 }
2175
2176 // emit payload part of the error union
2177 {
2178- const begin = code.items.len;
2179+ const begin = w.end;
2180 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) {
2181 .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),
2182 .payload => |payload| payload,
2183- }), code, reloc_parent);
2184- const unpadded_end = code.items.len - begin;
2185+ }), w, reloc_parent);
2186+ const unpadded_end = w.end - begin;
2187 const padded_end = abi_align.forward(unpadded_end);
2188 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
2189
2190 if (padding > 0) {
2191- try code.appendNTimes(gpa, 0, padding);
2192+ try w.splatByteAll(0, padding);
2193 }
2194 }
2195
2196 // Payload size is larger than error set, so emit our error set last
2197 if (error_align.compare(.lte, payload_align)) {
2198- const begin = code.items.len;
2199- mem.writeInt(u16, try code.addManyAsArray(gpa, 2), err_val, endian);
2200- const unpadded_end = code.items.len - begin;
2201+ const begin = w.end;
2202+ try w.writeInt(u16, err_val, endian);
2203+ const unpadded_end = w.end - begin;
2204 const padded_end = abi_align.forward(unpadded_end);
2205 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
2206
2207 if (padding > 0) {
2208- try code.appendNTimes(gpa, 0, padding);
2209+ try w.splatByteAll(0, padding);
2210 }
2211 }
2212 },
2213 .enum_tag => |enum_tag| {
2214 const int_tag_ty = ty.intTagType(zcu);
2215- try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent);
2216+ try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), w, reloc_parent);
2217 },
2218 .float => |float| storage: switch (float.storage) {
2219- .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(gpa, 2)),
2220- .f32 => |f32_val| writeFloat(f32, f32_val, target, endian, try code.addManyAsArray(gpa, 4)),
2221- .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(gpa, 8)),
2222+ .f16 => |f16_val| try w.writeInt(u16, @bitCast(f16_val), endian),
2223+ .f32 => |f32_val| try w.writeInt(u32, @bitCast(f32_val), endian),
2224+ .f64 => |f64_val| try w.writeInt(u64, @bitCast(f64_val), endian),
2225 .f80 => |f80_val| {
2226- writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(gpa, 10));
2227+ try w.writeInt(u80, @bitCast(f80_val), endian);
2228 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
2229- try code.appendNTimes(gpa, 0, abi_size - 10);
2230+ try w.splatByteAll(0, abi_size - 10);
2231 },
2232 .f128 => |f128_val| switch (Type.fromInterned(float.ty).floatBits(target)) {
2233 else => unreachable,
2234 16 => continue :storage .{ .f16 = @floatCast(f128_val) },
2235 32 => continue :storage .{ .f32 = @floatCast(f128_val) },
2236 64 => continue :storage .{ .f64 = @floatCast(f128_val) },
2237- 128 => writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(gpa, 16)),
2238+ 128 => try w.writeInt(u128, @bitCast(f128_val), endian),
2239 },
2240 },
2241- .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0),
2242+ .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0),
2243 .slice => |slice| {
2244- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent);
2245- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent);
2246+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent);
2247+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent);
2248 },
2249 .opt => {
2250 const payload_type = ty.optionalChild(zcu);
2251@@ -465,9 +453,9 @@ pub fn generateSymbol(
2252
2253 if (ty.optionalReprIsPayload(zcu)) {
2254 if (payload_val) |value| {
2255- try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
2256+ try generateSymbol(bin_file, pt, src_loc, value, w, reloc_parent);
2257 } else {
2258- try code.appendNTimes(gpa, 0, abi_size);
2259+ try w.splatByteAll(0, abi_size);
2260 }
2261 } else {
2262 const padding = abi_size - (math.cast(usize, payload_type.abiSize(zcu)) orelse return error.Overflow) - 1;
2263@@ -475,15 +463,15 @@ pub fn generateSymbol(
2264 const value = payload_val orelse Value.fromInterned(try pt.intern(.{
2265 .undef = payload_type.toIntern(),
2266 }));
2267- try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
2268+ try generateSymbol(bin_file, pt, src_loc, value, w, reloc_parent);
2269 }
2270- try code.append(gpa, @intFromBool(payload_val != null));
2271- try code.appendNTimes(gpa, 0, padding);
2272+ try w.writeByte(@intFromBool(payload_val != null));
2273+ try w.splatByteAll(0, padding);
2274 }
2275 },
2276 .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) {
2277 .array_type => |array_type| switch (aggregate.storage) {
2278- .bytes => |bytes| try code.appendSlice(gpa, bytes.toSlice(array_type.lenIncludingSentinel(), ip)),
2279+ .bytes => |bytes| try w.writeAll(bytes.toSlice(array_type.lenIncludingSentinel(), ip)),
2280 .elems, .repeated_elem => {
2281 var index: u64 = 0;
2282 while (index < array_type.lenIncludingSentinel()) : (index += 1) {
2283@@ -494,14 +482,14 @@ pub fn generateSymbol(
2284 elem
2285 else
2286 array_type.sentinel,
2287- }), code, reloc_parent);
2288+ }), w, reloc_parent);
2289 }
2290 },
2291 },
2292 .vector_type => |vector_type| {
2293 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
2294 if (vector_type.child == .bool_type) {
2295- const bytes = try code.addManyAsSlice(gpa, abi_size);
2296+ const bytes = try w.writableSlice(abi_size);
2297 @memset(bytes, 0xaa);
2298 var index: usize = 0;
2299 const len = math.cast(usize, vector_type.len) orelse return error.Overflow;
2300@@ -540,7 +528,7 @@ pub fn generateSymbol(
2301 }
2302 } else {
2303 switch (aggregate.storage) {
2304- .bytes => |bytes| try code.appendSlice(gpa, bytes.toSlice(vector_type.len, ip)),
2305+ .bytes => |bytes| try w.writeAll(bytes.toSlice(vector_type.len, ip)),
2306 .elems, .repeated_elem => {
2307 var index: u64 = 0;
2308 while (index < vector_type.len) : (index += 1) {
2309@@ -550,7 +538,7 @@ pub fn generateSymbol(
2310 math.cast(usize, index) orelse return error.Overflow
2311 ],
2312 .repeated_elem => |elem| elem,
2313- }), code, reloc_parent);
2314+ }), w, reloc_parent);
2315 }
2316 },
2317 }
2318@@ -558,11 +546,11 @@ pub fn generateSymbol(
2319 const padding = abi_size -
2320 (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len) orelse
2321 return error.Overflow);
2322- if (padding > 0) try code.appendNTimes(gpa, 0, padding);
2323+ if (padding > 0) try w.splatByteAll(0, padding);
2324 }
2325 },
2326 .tuple_type => |tuple| {
2327- const struct_begin = code.items.len;
2328+ const struct_begin = w.end;
2329 for (
2330 tuple.types.get(ip),
2331 tuple.values.get(ip),
2332@@ -580,8 +568,8 @@ pub fn generateSymbol(
2333 .repeated_elem => |elem| elem,
2334 };
2335
2336- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
2337- const unpadded_field_end = code.items.len - struct_begin;
2338+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);
2339+ const unpadded_field_end = w.end - struct_begin;
2340
2341 // Pad struct members if required
2342 const padded_field_end = ty.structFieldOffset(index + 1, zcu);
2343@@ -589,7 +577,7 @@ pub fn generateSymbol(
2344 return error.Overflow;
2345
2346 if (padding > 0) {
2347- try code.appendNTimes(gpa, 0, padding);
2348+ try w.splatByteAll(0, padding);
2349 }
2350 }
2351 },
2352@@ -598,8 +586,9 @@ pub fn generateSymbol(
2353 switch (struct_type.layout) {
2354 .@"packed" => {
2355 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
2356- const current_pos = code.items.len;
2357- try code.appendNTimes(gpa, 0, abi_size);
2358+ const start = w.end;
2359+ const buffer = try w.writableSlice(abi_size);
2360+ @memset(buffer, 0);
2361 var bits: u16 = 0;
2362
2363 for (struct_type.field_types.get(ip), 0..) |field_ty, index| {
2364@@ -619,22 +608,20 @@ pub fn generateSymbol(
2365 error.DivisionByZero => unreachable,
2366 error.UnexpectedRemainder => return error.RelocationNotByteAligned,
2367 };
2368- code.items.len = current_pos + field_offset;
2369- // TODO: code.lockPointers();
2370+ w.end = start + field_offset;
2371 defer {
2372- assert(code.items.len == current_pos + field_offset + @divExact(target.ptrBitWidth(), 8));
2373- // TODO: code.unlockPointers();
2374- code.items.len = current_pos + abi_size;
2375+ assert(w.end == start + field_offset + @divExact(target.ptrBitWidth(), 8));
2376+ w.end = start + abi_size;
2377 }
2378- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
2379+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);
2380 } else {
2381- Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable;
2382+ Value.fromInterned(field_val).writeToPackedMemory(.fromInterned(field_ty), pt, buffer, bits) catch unreachable;
2383 }
2384 bits += @intCast(Type.fromInterned(field_ty).bitSize(zcu));
2385 }
2386 },
2387 .auto, .@"extern" => {
2388- const struct_begin = code.items.len;
2389+ const struct_begin = w.end;
2390 const field_types = struct_type.field_types.get(ip);
2391 const offsets = struct_type.offsets.get(ip);
2392
2393@@ -654,11 +641,11 @@ pub fn generateSymbol(
2394
2395 const padding = math.cast(
2396 usize,
2397- offsets[field_index] - (code.items.len - struct_begin),
2398+ offsets[field_index] - (w.end - struct_begin),
2399 ) orelse return error.Overflow;
2400- if (padding > 0) try code.appendNTimes(gpa, 0, padding);
2401+ if (padding > 0) try w.splatByteAll(0, padding);
2402
2403- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
2404+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);
2405 }
2406
2407 const size = struct_type.sizeUnordered(ip);
2408@@ -666,10 +653,9 @@ pub fn generateSymbol(
2409
2410 const padding = math.cast(
2411 usize,
2412- std.mem.alignForward(u64, size, @max(alignment, 1)) -
2413- (code.items.len - struct_begin),
2414+ std.mem.alignForward(u64, size, @max(alignment, 1)) - (w.end - struct_begin),
2415 ) orelse return error.Overflow;
2416- if (padding > 0) try code.appendNTimes(gpa, 0, padding);
2417+ if (padding > 0) try w.splatByteAll(0, padding);
2418 },
2419 }
2420 },
2421@@ -679,12 +665,12 @@ pub fn generateSymbol(
2422 const layout = ty.unionGetLayout(zcu);
2423
2424 if (layout.payload_size == 0) {
2425- return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
2426+ return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), w, reloc_parent);
2427 }
2428
2429 // Check if we should store the tag first.
2430 if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {
2431- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
2432+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), w, reloc_parent);
2433 }
2434
2435 const union_obj = zcu.typeToUnion(ty).?;
2436@@ -692,24 +678,24 @@ pub fn generateSymbol(
2437 const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
2438 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
2439 if (!field_ty.hasRuntimeBits(zcu)) {
2440- try code.appendNTimes(gpa, 0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
2441+ try w.splatByteAll(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
2442 } else {
2443- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
2444+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), w, reloc_parent);
2445
2446 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow;
2447 if (padding > 0) {
2448- try code.appendNTimes(gpa, 0, padding);
2449+ try w.splatByteAll(0, padding);
2450 }
2451 }
2452 } else {
2453- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
2454+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), w, reloc_parent);
2455 }
2456
2457 if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {
2458- try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
2459+ try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), w, reloc_parent);
2460
2461 if (layout.padding > 0) {
2462- try code.appendNTimes(gpa, 0, layout.padding);
2463+ try w.splatByteAll(0, layout.padding);
2464 }
2465 }
2466 },
2467@@ -722,30 +708,30 @@ fn lowerPtr(
2468 pt: Zcu.PerThread,
2469 src_loc: Zcu.LazySrcLoc,
2470 ptr_val: InternPool.Index,
2471- code: *ArrayList(u8),
2472+ w: *std.Io.Writer,
2473 reloc_parent: link.File.RelocInfo.Parent,
2474 prev_offset: u64,
2475-) GenerateSymbolError!void {
2476+) (GenerateSymbolError || std.Io.Writer.Error)!void {
2477 const zcu = pt.zcu;
2478 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
2479 const offset: u64 = prev_offset + ptr.byte_offset;
2480 return switch (ptr.base_addr) {
2481- .nav => |nav| try lowerNavRef(bin_file, pt, nav, code, reloc_parent, offset),
2482- .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, code, reloc_parent, offset),
2483- .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, reloc_parent),
2484+ .nav => |nav| try lowerNavRef(bin_file, pt, nav, w, reloc_parent, offset),
2485+ .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, w, reloc_parent, offset),
2486+ .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), w, reloc_parent),
2487 .eu_payload => |eu_ptr| try lowerPtr(
2488 bin_file,
2489 pt,
2490 src_loc,
2491 eu_ptr,
2492- code,
2493+ w,
2494 reloc_parent,
2495 offset + errUnionPayloadOffset(
2496 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu),
2497 zcu,
2498 ),
2499 ),
2500- .opt_payload => |opt_ptr| try lowerPtr(bin_file, pt, src_loc, opt_ptr, code, reloc_parent, offset),
2501+ .opt_payload => |opt_ptr| try lowerPtr(bin_file, pt, src_loc, opt_ptr, w, reloc_parent, offset),
2502 .field => |field| {
2503 const base_ptr = Value.fromInterned(field.base);
2504 const base_ty = base_ptr.typeOf(zcu).childType(zcu);
2505@@ -764,7 +750,7 @@ fn lowerPtr(
2506 },
2507 else => unreachable,
2508 };
2509- return lowerPtr(bin_file, pt, src_loc, field.base, code, reloc_parent, offset + field_off);
2510+ return lowerPtr(bin_file, pt, src_loc, field.base, w, reloc_parent, offset + field_off);
2511 },
2512 .arr_elem, .comptime_field, .comptime_alloc => unreachable,
2513 };
2514@@ -775,12 +761,11 @@ fn lowerUavRef(
2515 pt: Zcu.PerThread,
2516 src_loc: Zcu.LazySrcLoc,
2517 uav: InternPool.Key.Ptr.BaseAddr.Uav,
2518- code: *ArrayList(u8),
2519+ w: *std.Io.Writer,
2520 reloc_parent: link.File.RelocInfo.Parent,
2521 offset: u64,
2522-) GenerateSymbolError!void {
2523+) (GenerateSymbolError || std.Io.Writer.Error)!void {
2524 const zcu = pt.zcu;
2525- const gpa = zcu.gpa;
2526 const ip = &zcu.intern_pool;
2527 const comp = lf.comp;
2528 const target = &comp.root_mod.resolved_target.result;
2529@@ -790,10 +775,9 @@ fn lowerUavRef(
2530 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
2531
2532 log.debug("lowerUavRef: ty = {f}", .{uav_ty.fmt(pt)});
2533- try code.ensureUnusedCapacity(gpa, ptr_width_bytes);
2534
2535 if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) {
2536- code.appendNTimesAssumeCapacity(0xaa, ptr_width_bytes);
2537+ try w.splatByteAll(0xaa, ptr_width_bytes);
2538 return;
2539 }
2540
2541@@ -804,29 +788,32 @@ fn lowerUavRef(
2542 dev.check(link.File.Tag.wasm.devFeature());
2543 const wasm = lf.cast(.wasm).?;
2544 assert(reloc_parent == .none);
2545- try wasm.addUavReloc(code.items.len, uav.val, uav.orig_ty, @intCast(offset));
2546- code.appendNTimesAssumeCapacity(0, ptr_width_bytes);
2547+ try wasm.addUavReloc(w.end, uav.val, uav.orig_ty, @intCast(offset));
2548+ try w.splatByteAll(0, ptr_width_bytes);
2549 return;
2550 },
2551 else => {},
2552 }
2553
2554- const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
2555+ const uav_align = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
2556 switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) {
2557 .sym_index => {},
2558 .fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}),
2559 }
2560
2561- const vaddr = try lf.getUavVAddr(uav_val, .{
2562+ const vaddr = lf.getUavVAddr(uav_val, .{
2563 .parent = reloc_parent,
2564- .offset = code.items.len,
2565+ .offset = w.end,
2566 .addend = @intCast(offset),
2567- });
2568+ }) catch |err| switch (err) {
2569+ error.OutOfMemory => return error.OutOfMemory,
2570+ else => |e| std.debug.panic("TODO rework lowerUav. internal error: {t}", .{e}),
2571+ };
2572 const endian = target.cpu.arch.endian();
2573 switch (ptr_width_bytes) {
2574- 2 => mem.writeInt(u16, code.addManyAsArrayAssumeCapacity(2), @intCast(vaddr), endian),
2575- 4 => mem.writeInt(u32, code.addManyAsArrayAssumeCapacity(4), @intCast(vaddr), endian),
2576- 8 => mem.writeInt(u64, code.addManyAsArrayAssumeCapacity(8), vaddr, endian),
2577+ 2 => try w.writeInt(u16, @intCast(vaddr), endian),
2578+ 4 => try w.writeInt(u32, @intCast(vaddr), endian),
2579+ 8 => try w.writeInt(u64, vaddr, endian),
2580 else => unreachable,
2581 }
2582 }
2583@@ -835,10 +822,10 @@ fn lowerNavRef(
2584 lf: *link.File,
2585 pt: Zcu.PerThread,
2586 nav_index: InternPool.Nav.Index,
2587- code: *ArrayList(u8),
2588+ w: *std.Io.Writer,
2589 reloc_parent: link.File.RelocInfo.Parent,
2590 offset: u64,
2591-) GenerateSymbolError!void {
2592+) (GenerateSymbolError || std.Io.Writer.Error)!void {
2593 const zcu = pt.zcu;
2594 const gpa = zcu.gpa;
2595 const ip = &zcu.intern_pool;
2596@@ -848,10 +835,8 @@ fn lowerNavRef(
2597 const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip));
2598 const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
2599
2600- try code.ensureUnusedCapacity(gpa, ptr_width_bytes);
2601-
2602 if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) {
2603- code.appendNTimesAssumeCapacity(0xaa, ptr_width_bytes);
2604+ try w.splatByteAll(0xaa, ptr_width_bytes);
2605 return;
2606 }
2607
2608@@ -870,13 +855,13 @@ fn lowerNavRef(
2609 } else {
2610 try wasm.func_table_fixups.append(gpa, .{
2611 .table_index = @enumFromInt(gop.index),
2612- .offset = @intCast(code.items.len),
2613+ .offset = @intCast(w.end),
2614 });
2615 }
2616 } else {
2617 if (is_obj) {
2618 try wasm.out_relocs.append(gpa, .{
2619- .offset = @intCast(code.items.len),
2620+ .offset = @intCast(w.end),
2621 .pointee = .{ .symbol_index = try wasm.navSymbolIndex(nav_index) },
2622 .tag = if (ptr_width_bytes == 4) .memory_addr_i32 else .memory_addr_i64,
2623 .addend = @intCast(offset),
2624@@ -885,12 +870,12 @@ fn lowerNavRef(
2625 try wasm.nav_fixups.ensureUnusedCapacity(gpa, 1);
2626 wasm.nav_fixups.appendAssumeCapacity(.{
2627 .navs_exe_index = try wasm.refNavExe(nav_index),
2628- .offset = @intCast(code.items.len),
2629+ .offset = @intCast(w.end),
2630 .addend = @intCast(offset),
2631 });
2632 }
2633 }
2634- code.appendNTimesAssumeCapacity(0, ptr_width_bytes);
2635+ try w.splatByteAll(0, ptr_width_bytes);
2636 return;
2637 },
2638 else => {},
2639@@ -898,14 +883,14 @@ fn lowerNavRef(
2640
2641 const vaddr = lf.getNavVAddr(pt, nav_index, .{
2642 .parent = reloc_parent,
2643- .offset = code.items.len,
2644+ .offset = w.end,
2645 .addend = @intCast(offset),
2646 }) catch @panic("TODO rework getNavVAddr");
2647 const endian = target.cpu.arch.endian();
2648 switch (ptr_width_bytes) {
2649- 2 => mem.writeInt(u16, code.addManyAsArrayAssumeCapacity(2), @intCast(vaddr), endian),
2650- 4 => mem.writeInt(u32, code.addManyAsArrayAssumeCapacity(4), @intCast(vaddr), endian),
2651- 8 => mem.writeInt(u64, code.addManyAsArrayAssumeCapacity(8), vaddr, endian),
2652+ 2 => try w.writeInt(u16, @intCast(vaddr), endian),
2653+ 4 => try w.writeInt(u32, @intCast(vaddr), endian),
2654+ 8 => try w.writeInt(u64, vaddr, endian),
2655 else => unreachable,
2656 }
2657 }
2658@@ -962,6 +947,16 @@ pub fn genNavRef(
2659 },
2660 .link_once => unreachable,
2661 }
2662+ } else if (lf.cast(.elf2)) |elf| {
2663+ return .{ .sym_index = @intFromEnum(elf.navSymbol(zcu, nav_index) catch |err| switch (err) {
2664+ error.OutOfMemory => return error.OutOfMemory,
2665+ else => |e| return .{ .fail = try ErrorMsg.create(
2666+ zcu.gpa,
2667+ src_loc,
2668+ "linker failed to create a nav: {t}",
2669+ .{e},
2670+ ) },
2671+ }) };
2672 } else if (lf.cast(.macho)) |macho_file| {
2673 const zo = macho_file.getZigObject().?;
2674 switch (linkage) {
2675diff --git a/src/codegen/aarch64/Mir.zig b/src/codegen/aarch64/Mir.zig
2676index 318a51da95..be6478eae8 100644
2677--- a/src/codegen/aarch64/Mir.zig
2678+++ b/src/codegen/aarch64/Mir.zig
2679@@ -56,13 +56,13 @@ pub fn emit(
2680 pt: Zcu.PerThread,
2681 src_loc: Zcu.LazySrcLoc,
2682 func_index: InternPool.Index,
2683- code: *std.ArrayListUnmanaged(u8),
2684+ atom_index: u32,
2685+ w: *std.Io.Writer,
2686 debug_output: link.File.DebugInfoOutput,
2687 ) !void {
2688 _ = debug_output;
2689 const zcu = pt.zcu;
2690 const ip = &zcu.intern_pool;
2691- const gpa = zcu.gpa;
2692 const func = zcu.funcInfo(func_index);
2693 const nav = ip.getNav(func.owner_nav);
2694 const mod = zcu.navFileScope(func.owner_nav).mod.?;
2695@@ -81,20 +81,19 @@ pub fn emit(
2696 @as(u5, @intCast(func_align.minStrict(.@"16").toByteUnits().?)),
2697 Instruction.size,
2698 ) - 1);
2699- try code.ensureUnusedCapacity(gpa, Instruction.size *
2700- (code_len + literals_align_gap + mir.literals.len));
2701- emitInstructionsForward(code, mir.prologue);
2702- emitInstructionsBackward(code, mir.body);
2703- const body_end: u32 = @intCast(code.items.len);
2704- emitInstructionsBackward(code, mir.epilogue);
2705- code.appendNTimesAssumeCapacity(0, Instruction.size * literals_align_gap);
2706- code.appendSliceAssumeCapacity(@ptrCast(mir.literals));
2707+ try w.rebase(w.end, Instruction.size * (code_len + literals_align_gap + mir.literals.len));
2708+ emitInstructionsForward(w, mir.prologue) catch unreachable;
2709+ emitInstructionsBackward(w, mir.body) catch unreachable;
2710+ const body_end: u32 = @intCast(w.end);
2711+ emitInstructionsBackward(w, mir.epilogue) catch unreachable;
2712+ w.splatByteAll(0, Instruction.size * literals_align_gap) catch unreachable;
2713+ w.writeAll(@ptrCast(mir.literals)) catch unreachable;
2714 mir_log.debug("", .{});
2715
2716 for (mir.nav_relocs) |nav_reloc| try emitReloc(
2717 lf,
2718 zcu,
2719- func.owner_nav,
2720+ atom_index,
2721 switch (try @import("../../codegen.zig").genNavRef(
2722 lf,
2723 pt,
2724@@ -112,7 +111,7 @@ pub fn emit(
2725 for (mir.uav_relocs) |uav_reloc| try emitReloc(
2726 lf,
2727 zcu,
2728- func.owner_nav,
2729+ atom_index,
2730 switch (try lf.lowerUav(
2731 pt,
2732 uav_reloc.uav.val,
2733@@ -129,7 +128,7 @@ pub fn emit(
2734 for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
2735 lf,
2736 zcu,
2737- func.owner_nav,
2738+ atom_index,
2739 if (lf.cast(.elf)) |ef|
2740 ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err|
2741 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
2742@@ -150,7 +149,7 @@ pub fn emit(
2743 for (mir.global_relocs) |global_reloc| try emitReloc(
2744 lf,
2745 zcu,
2746- func.owner_nav,
2747+ atom_index,
2748 if (lf.cast(.elf)) |ef|
2749 try ef.getGlobalSymbol(std.mem.span(global_reloc.name), null)
2750 else if (lf.cast(.macho)) |mf|
2751@@ -168,30 +167,30 @@ pub fn emit(
2752 var instruction = mir.body[literal_reloc.label];
2753 instruction.load_store.register_literal.group.imm19 += literal_reloc_offset;
2754 instruction.write(
2755- code.items[body_end - Instruction.size * (1 + literal_reloc.label) ..][0..Instruction.size],
2756+ w.buffered()[body_end - Instruction.size * (1 + literal_reloc.label) ..][0..Instruction.size],
2757 );
2758 }
2759 }
2760
2761-fn emitInstructionsForward(code: *std.ArrayListUnmanaged(u8), instructions: []const Instruction) void {
2762- for (instructions) |instruction| emitInstruction(code, instruction);
2763+fn emitInstructionsForward(w: *std.Io.Writer, instructions: []const Instruction) !void {
2764+ for (instructions) |instruction| try emitInstruction(w, instruction);
2765 }
2766-fn emitInstructionsBackward(code: *std.ArrayListUnmanaged(u8), instructions: []const Instruction) void {
2767+fn emitInstructionsBackward(w: *std.Io.Writer, instructions: []const Instruction) !void {
2768 var instruction_index = instructions.len;
2769 while (instruction_index > 0) {
2770 instruction_index -= 1;
2771- emitInstruction(code, instructions[instruction_index]);
2772+ try emitInstruction(w, instructions[instruction_index]);
2773 }
2774 }
2775-fn emitInstruction(code: *std.ArrayListUnmanaged(u8), instruction: Instruction) void {
2776+fn emitInstruction(w: *std.Io.Writer, instruction: Instruction) !void {
2777 mir_log.debug(" {f}", .{instruction});
2778- instruction.write(code.addManyAsArrayAssumeCapacity(Instruction.size));
2779+ instruction.write(try w.writableArray(Instruction.size));
2780 }
2781
2782 fn emitReloc(
2783 lf: *link.File,
2784 zcu: *Zcu,
2785- owner_nav: InternPool.Nav.Index,
2786+ atom_index: u32,
2787 sym_index: u32,
2788 instruction: Instruction,
2789 offset: u32,
2790@@ -202,7 +201,7 @@ fn emitReloc(
2791 else => unreachable,
2792 .data_processing_immediate => |decoded| if (lf.cast(.elf)) |ef| {
2793 const zo = ef.zigObjectPtr().?;
2794- const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
2795+ const atom = zo.symbol(atom_index).atom(ef).?;
2796 const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {
2797 else => unreachable,
2798 .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
2799@@ -221,7 +220,7 @@ fn emitReloc(
2800 }, zo);
2801 } else if (lf.cast(.macho)) |mf| {
2802 const zo = mf.getZigObject().?;
2803- const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
2804+ const atom = zo.symbols.items[atom_index].getAtom(mf).?;
2805 switch (decoded.decode()) {
2806 else => unreachable,
2807 .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
2808@@ -260,7 +259,7 @@ fn emitReloc(
2809 },
2810 .branch_exception_generating_system => |decoded| if (lf.cast(.elf)) |ef| {
2811 const zo = ef.zigObjectPtr().?;
2812- const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
2813+ const atom = zo.symbol(atom_index).atom(ef).?;
2814 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().unconditional_branch_immediate.group.op) {
2815 .b => .JUMP26,
2816 .bl => .CALL26,
2817@@ -272,7 +271,7 @@ fn emitReloc(
2818 }, zo);
2819 } else if (lf.cast(.macho)) |mf| {
2820 const zo = mf.getZigObject().?;
2821- const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
2822+ const atom = zo.symbols.items[atom_index].getAtom(mf).?;
2823 try atom.addReloc(mf, .{
2824 .tag = .@"extern",
2825 .offset = offset,
2826@@ -289,7 +288,7 @@ fn emitReloc(
2827 },
2828 .load_store => |decoded| if (lf.cast(.elf)) |ef| {
2829 const zo = ef.zigObjectPtr().?;
2830- const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
2831+ const atom = zo.symbol(atom_index).atom(ef).?;
2832 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
2833 .integer => |integer| switch (integer.decode()) {
2834 .unallocated, .prfm => unreachable,
2835@@ -316,7 +315,7 @@ fn emitReloc(
2836 }, zo);
2837 } else if (lf.cast(.macho)) |mf| {
2838 const zo = mf.getZigObject().?;
2839- const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
2840+ const atom = zo.symbols.items[atom_index].getAtom(mf).?;
2841 try atom.addReloc(mf, .{
2842 .tag = .@"extern",
2843 .offset = offset,
2844diff --git a/src/dev.zig b/src/dev.zig
2845index ac30cedecd..266796a2dc 100644
2846--- a/src/dev.zig
2847+++ b/src/dev.zig
2848@@ -97,6 +97,7 @@ pub const Env = enum {
2849 .lld_linker,
2850 .coff_linker,
2851 .elf_linker,
2852+ .elf2_linker,
2853 .macho_linker,
2854 .c_linker,
2855 .wasm_linker,
2856@@ -163,6 +164,7 @@ pub const Env = enum {
2857 .incremental,
2858 .aarch64_backend,
2859 .elf_linker,
2860+ .elf2_linker,
2861 => true,
2862 else => Env.sema.supports(feature),
2863 },
2864@@ -210,6 +212,7 @@ pub const Env = enum {
2865 .legalize,
2866 .x86_64_backend,
2867 .elf_linker,
2868+ .elf2_linker,
2869 => true,
2870 else => Env.sema.supports(feature),
2871 },
2872@@ -282,6 +285,7 @@ pub const Feature = enum {
2873 lld_linker,
2874 coff_linker,
2875 elf_linker,
2876+ elf2_linker,
2877 macho_linker,
2878 c_linker,
2879 wasm_linker,
2880diff --git a/src/link.zig b/src/link.zig
2881index 27cd6620e3..277013efb3 100644
2882--- a/src/link.zig
2883+++ b/src/link.zig
2884@@ -219,6 +219,7 @@ pub const Diags = struct {
2885 }
2886
2887 pub fn addError(diags: *Diags, comptime format: []const u8, args: anytype) void {
2888+ @branchHint(.cold);
2889 return addErrorSourceLocation(diags, .none, format, args);
2890 }
2891
2892@@ -529,7 +530,7 @@ pub const File = struct {
2893 const lld: *Lld = try .createEmpty(arena, comp, emit, options);
2894 return &lld.base;
2895 }
2896- switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt)) {
2897+ switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt, comp.config.use_new_linker)) {
2898 .plan9 => return error.UnsupportedObjectFormat,
2899 inline else => |tag| {
2900 dev.check(tag.devFeature());
2901@@ -552,7 +553,7 @@ pub const File = struct {
2902 const lld: *Lld = try .createEmpty(arena, comp, emit, options);
2903 return &lld.base;
2904 }
2905- switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt)) {
2906+ switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt, comp.config.use_new_linker)) {
2907 .plan9 => return error.UnsupportedObjectFormat,
2908 inline else => |tag| {
2909 dev.check(tag.devFeature());
2910@@ -579,7 +580,8 @@ pub const File = struct {
2911 const emit = base.emit;
2912 if (base.child_pid) |pid| {
2913 if (builtin.os.tag == .windows) {
2914- base.cast(.coff).?.ptraceAttach(pid) catch |err| {
2915+ const coff_file = base.cast(.coff).?;
2916+ coff_file.ptraceAttach(pid) catch |err| {
2917 log.warn("attaching failed with error: {s}", .{@errorName(err)});
2918 };
2919 } else {
2920@@ -597,8 +599,11 @@ pub const File = struct {
2921 .linux => std.posix.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| {
2922 log.warn("ptrace failure: {s}", .{@errorName(err)});
2923 },
2924- .macos => base.cast(.macho).?.ptraceAttach(pid) catch |err| {
2925- log.warn("attaching failed with error: {s}", .{@errorName(err)});
2926+ .macos => {
2927+ const macho_file = base.cast(.macho).?;
2928+ macho_file.ptraceAttach(pid) catch |err| {
2929+ log.warn("attaching failed with error: {s}", .{@errorName(err)});
2930+ };
2931 },
2932 .windows => unreachable,
2933 else => return error.HotSwapUnavailableOnHostOperatingSystem,
2934@@ -613,6 +618,20 @@ pub const File = struct {
2935 .mode = determineMode(output_mode, link_mode),
2936 });
2937 },
2938+ .elf2 => {
2939+ const elf = base.cast(.elf2).?;
2940+ if (base.file == null) {
2941+ elf.mf.file = try base.emit.root_dir.handle.createFile(base.emit.sub_path, .{
2942+ .truncate = false,
2943+ .read = true,
2944+ .mode = determineMode(comp.config.output_mode, comp.config.link_mode),
2945+ });
2946+ base.file = elf.mf.file;
2947+ try elf.mf.ensureTotalCapacity(
2948+ @intCast(elf.mf.nodes.items[0].location().resolve(&elf.mf)[1]),
2949+ );
2950+ }
2951+ },
2952 .c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }),
2953 .plan9 => unreachable,
2954 }
2955@@ -669,14 +688,30 @@ pub const File = struct {
2956
2957 if (base.child_pid) |pid| {
2958 switch (builtin.os.tag) {
2959- .macos => base.cast(.macho).?.ptraceDetach(pid) catch |err| {
2960- log.warn("detaching failed with error: {s}", .{@errorName(err)});
2961+ .macos => {
2962+ const macho_file = base.cast(.macho).?;
2963+ macho_file.ptraceDetach(pid) catch |err| {
2964+ log.warn("detaching failed with error: {s}", .{@errorName(err)});
2965+ };
2966+ },
2967+ .windows => {
2968+ const coff_file = base.cast(.coff).?;
2969+ coff_file.ptraceDetach(pid);
2970 },
2971- .windows => base.cast(.coff).?.ptraceDetach(pid),
2972 else => return error.HotSwapUnavailableOnHostOperatingSystem,
2973 }
2974 }
2975 },
2976+ .elf2 => {
2977+ const elf = base.cast(.elf2).?;
2978+ if (base.file) |f| {
2979+ elf.mf.unmap();
2980+ assert(elf.mf.file.handle == f.handle);
2981+ elf.mf.file = undefined;
2982+ f.close();
2983+ base.file = null;
2984+ }
2985+ },
2986 .c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }),
2987 .plan9 => unreachable,
2988 }
2989@@ -793,6 +828,7 @@ pub const File = struct {
2990 .spirv => {},
2991 .goff, .xcoff => {},
2992 .plan9 => unreachable,
2993+ .elf2 => {},
2994 inline else => |tag| {
2995 dev.check(tag.devFeature());
2996 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id);
2997@@ -825,6 +861,26 @@ pub const File = struct {
2998 }
2999 }
3000
3001+ pub fn idle(base: *File, tid: Zcu.PerThread.Id) !bool {
3002+ switch (base.tag) {
3003+ else => return false,
3004+ inline .elf2 => |tag| {
3005+ dev.check(tag.devFeature());
3006+ return @as(*tag.Type(), @fieldParentPtr("base", base)).idle(tid);
3007+ },
3008+ }
3009+ }
3010+
3011+ pub fn updateErrorData(base: *File, pt: Zcu.PerThread) !void {
3012+ switch (base.tag) {
3013+ else => {},
3014+ inline .elf2 => |tag| {
3015+ dev.check(tag.devFeature());
3016+ return @as(*tag.Type(), @fieldParentPtr("base", base)).updateErrorData(pt);
3017+ },
3018+ }
3019+ }
3020+
3021 pub const FlushError = error{
3022 /// Indicates an error will be present in `Compilation.link_diags`.
3023 LinkFailure,
3024@@ -1099,7 +1155,7 @@ pub const File = struct {
3025 if (base.zcu_object_basename != null) return;
3026
3027 switch (base.tag) {
3028- inline .wasm => |tag| {
3029+ inline .elf2, .wasm => |tag| {
3030 dev.check(tag.devFeature());
3031 return @as(*tag.Type(), @fieldParentPtr("base", base)).prelink(base.comp.link_prog_node);
3032 },
3033@@ -1110,6 +1166,7 @@ pub const File = struct {
3034 pub const Tag = enum {
3035 coff,
3036 elf,
3037+ elf2,
3038 macho,
3039 c,
3040 wasm,
3041@@ -1123,6 +1180,7 @@ pub const File = struct {
3042 return switch (tag) {
3043 .coff => Coff,
3044 .elf => Elf,
3045+ .elf2 => Elf2,
3046 .macho => MachO,
3047 .c => C,
3048 .wasm => Wasm,
3049@@ -1134,10 +1192,10 @@ pub const File = struct {
3050 };
3051 }
3052
3053- fn fromObjectFormat(ofmt: std.Target.ObjectFormat) Tag {
3054+ fn fromObjectFormat(ofmt: std.Target.ObjectFormat, use_new_linker: bool) Tag {
3055 return switch (ofmt) {
3056 .coff => .coff,
3057- .elf => .elf,
3058+ .elf => if (use_new_linker) .elf2 else .elf,
3059 .macho => .macho,
3060 .wasm => .wasm,
3061 .plan9 => .plan9,
3062@@ -1223,6 +1281,7 @@ pub const File = struct {
3063 pub const C = @import("link/C.zig");
3064 pub const Coff = @import("link/Coff.zig");
3065 pub const Elf = @import("link/Elf.zig");
3066+ pub const Elf2 = @import("link/Elf2.zig");
3067 pub const MachO = @import("link/MachO.zig");
3068 pub const SpirV = @import("link/SpirV.zig");
3069 pub const Wasm = @import("link/Wasm.zig");
3070@@ -1548,6 +1607,9 @@ pub fn doZcuTask(comp: *Compilation, tid: usize, task: ZcuTask) void {
3071 }
3072 }
3073 }
3074+pub fn doIdleTask(comp: *Compilation, tid: usize) error{ OutOfMemory, LinkFailure }!bool {
3075+ return if (comp.bin_file) |lf| lf.idle(@enumFromInt(tid)) else false;
3076+}
3077 /// After the main pipeline is done, but before flush, the compilation may need to link one final
3078 /// `Nav` into the binary: the `builtin.test_functions` value. Since the link thread isn't running
3079 /// by then, we expose this function which can be called directly.
3080@@ -1573,6 +1635,13 @@ pub fn linkTestFunctionsNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
3081 };
3082 }
3083 }
3084+pub fn updateErrorData(pt: Zcu.PerThread) void {
3085+ const comp = pt.zcu.comp;
3086+ if (comp.bin_file) |lf| lf.updateErrorData(pt) catch |err| switch (err) {
3087+ error.OutOfMemory => comp.link_diags.setAllocFailure(),
3088+ error.LinkFailure => {},
3089+ };
3090+}
3091
3092 /// Provided by the CLI, processed into `LinkInput` instances at the start of
3093 /// the compilation pipeline.
3094diff --git a/src/link/Coff.zig b/src/link/Coff.zig
3095index e016473531..f3e3b3d0b5 100644
3096--- a/src/link/Coff.zig
3097+++ b/src/link/Coff.zig
3098@@ -953,7 +953,7 @@ fn writeOffsetTableEntry(coff: *Coff, index: usize) !void {
3099 }
3100
3101 fn markRelocsDirtyByTarget(coff: *Coff, target: SymbolWithLoc) void {
3102- if (!coff.base.comp.incremental) return;
3103+ if (!coff.base.comp.config.incremental) return;
3104 // TODO: reverse-lookup might come in handy here
3105 for (coff.relocs.values()) |*relocs| {
3106 for (relocs.items) |*reloc| {
3107@@ -964,7 +964,7 @@ fn markRelocsDirtyByTarget(coff: *Coff, target: SymbolWithLoc) void {
3108 }
3109
3110 fn markRelocsDirtyByAddress(coff: *Coff, addr: u32) void {
3111- if (!coff.base.comp.incremental) return;
3112+ if (!coff.base.comp.config.incremental) return;
3113 const got_moved = blk: {
3114 const sect_id = coff.got_section_index orelse break :blk false;
3115 break :blk coff.sections.items(.header)[sect_id].virtual_address >= addr;
3116@@ -1111,20 +1111,24 @@ pub fn updateFunc(
3117
3118 coff.navs.getPtr(func.owner_nav).?.section = coff.text_section_index.?;
3119
3120- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
3121- defer code_buffer.deinit(gpa);
3122+ var aw: std.Io.Writer.Allocating = .init(gpa);
3123+ defer aw.deinit();
3124
3125- try codegen.emitFunction(
3126+ codegen.emitFunction(
3127 &coff.base,
3128 pt,
3129 zcu.navSrcLoc(nav_index),
3130 func_index,
3131+ coff.getAtom(atom_index).getSymbolIndex().?,
3132 mir,
3133- &code_buffer,
3134+ &aw.writer,
3135 .none,
3136- );
3137+ ) catch |err| switch (err) {
3138+ error.WriteFailed => return error.OutOfMemory,
3139+ else => |e| return e,
3140+ };
3141
3142- try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION);
3143+ try coff.updateNavCode(pt, nav_index, aw.written(), .FUNCTION);
3144
3145 // Exports will be updated by `Zcu.processExports` after the update.
3146 }
3147@@ -1145,18 +1149,18 @@ fn lowerConst(
3148 ) !LowerConstResult {
3149 const gpa = coff.base.comp.gpa;
3150
3151- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
3152- defer code_buffer.deinit(gpa);
3153+ var aw: std.Io.Writer.Allocating = .init(gpa);
3154+ defer aw.deinit();
3155
3156 const atom_index = try coff.createAtom();
3157 const sym = coff.getAtom(atom_index).getSymbolPtr(coff);
3158 try coff.setSymbolName(sym, name);
3159 sym.section_number = @as(coff_util.SectionNumber, @enumFromInt(sect_id + 1));
3160
3161- try codegen.generateSymbol(&coff.base, pt, src_loc, val, &code_buffer, .{
3162+ try codegen.generateSymbol(&coff.base, pt, src_loc, val, &aw.writer, .{
3163 .atom_index = coff.getAtom(atom_index).getSymbolIndex().?,
3164 });
3165- const code = code_buffer.items;
3166+ const code = aw.written();
3167
3168 const atom = coff.getAtomPtr(atom_index);
3169 atom.size = @intCast(code.len);
3170@@ -1170,7 +1174,7 @@ fn lowerConst(
3171 log.debug("allocated atom for {s} at 0x{x}", .{ name, atom.getSymbol(coff).value });
3172 log.debug(" (required alignment 0x{x})", .{required_alignment});
3173
3174- try coff.writeAtom(atom_index, code, coff.base.comp.incremental);
3175+ try coff.writeAtom(atom_index, code, coff.base.comp.config.incremental);
3176
3177 return .{ .ok = atom_index };
3178 }
3179@@ -1214,19 +1218,22 @@ pub fn updateNav(
3180
3181 coff.navs.getPtr(nav_index).?.section = coff.getNavOutputSection(nav_index);
3182
3183- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
3184- defer code_buffer.deinit(gpa);
3185+ var aw: std.Io.Writer.Allocating = .init(gpa);
3186+ defer aw.deinit();
3187
3188- try codegen.generateSymbol(
3189+ codegen.generateSymbol(
3190 &coff.base,
3191 pt,
3192 zcu.navSrcLoc(nav_index),
3193 nav_init,
3194- &code_buffer,
3195+ &aw.writer,
3196 .{ .atom_index = atom.getSymbolIndex().? },
3197- );
3198+ ) catch |err| switch (err) {
3199+ error.WriteFailed => return error.OutOfMemory,
3200+ else => |e| return e,
3201+ };
3202
3203- try coff.updateNavCode(pt, nav_index, code_buffer.items, .NULL);
3204+ try coff.updateNavCode(pt, nav_index, aw.written(), .NULL);
3205 }
3206
3207 // Exports will be updated by `Zcu.processExports` after the update.
3208@@ -1244,8 +1251,8 @@ fn updateLazySymbolAtom(
3209 const gpa = comp.gpa;
3210
3211 var required_alignment: InternPool.Alignment = .none;
3212- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
3213- defer code_buffer.deinit(gpa);
3214+ var aw: std.Io.Writer.Allocating = .init(gpa);
3215+ defer aw.deinit();
3216
3217 const name = try allocPrint(gpa, "__lazy_{s}_{f}", .{
3218 @tagName(sym.kind),
3219@@ -1262,11 +1269,11 @@ fn updateLazySymbolAtom(
3220 src,
3221 sym,
3222 &required_alignment,
3223- &code_buffer,
3224+ &aw.writer,
3225 .none,
3226 .{ .atom_index = local_sym_index },
3227 );
3228- const code = code_buffer.items;
3229+ const code = aw.written();
3230
3231 const atom = coff.getAtomPtr(atom_index);
3232 const symbol = atom.getSymbolPtr(coff);
3233@@ -1285,7 +1292,7 @@ fn updateLazySymbolAtom(
3234 symbol.value = vaddr;
3235
3236 try coff.addGotEntry(.{ .sym_index = local_sym_index });
3237- try coff.writeAtom(atom_index, code, coff.base.comp.incremental);
3238+ try coff.writeAtom(atom_index, code, coff.base.comp.config.incremental);
3239 }
3240
3241 pub fn getOrCreateAtomForLazySymbol(
3242@@ -1437,7 +1444,7 @@ fn updateNavCode(
3243 };
3244 }
3245
3246- coff.writeAtom(atom_index, code, coff.base.comp.incremental) catch |err| switch (err) {
3247+ coff.writeAtom(atom_index, code, coff.base.comp.config.incremental) catch |err| switch (err) {
3248 error.OutOfMemory => return error.OutOfMemory,
3249 else => |e| return coff.base.cgFail(nav_index, "failed to write atom: {s}", .{@errorName(e)}),
3250 };
3251@@ -1539,14 +1546,12 @@ pub fn updateExports(
3252 sym.section_number = @as(coff_util.SectionNumber, @enumFromInt(metadata.section + 1));
3253 sym.type = atom.getSymbol(coff).type;
3254
3255- switch (exp.opts.linkage) {
3256- .strong => {
3257- sym.storage_class = .EXTERNAL;
3258- },
3259- .internal => @panic("TODO Internal"),
3260+ sym.storage_class = switch (exp.opts.linkage) {
3261+ .internal => .EXTERNAL,
3262+ .strong => .EXTERNAL,
3263 .weak => @panic("TODO WeakExternal"),
3264 else => unreachable,
3265- }
3266+ };
3267
3268 try coff.resolveGlobalSymbol(sym_loc);
3269 }
3270diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig
3271index f4af5f4148..595e3583d5 100644
3272--- a/src/link/Dwarf.zig
3273+++ b/src/link/Dwarf.zig
3274@@ -2126,19 +2126,22 @@ pub const WipNav = struct {
3275 const size = if (ty.hasRuntimeBits(wip_nav.pt.zcu)) ty.abiSize(wip_nav.pt.zcu) else 0;
3276 try diw.writeUleb128(size);
3277 if (size == 0) return;
3278- var bytes = wip_nav.debug_info.toArrayList();
3279- defer wip_nav.debug_info = .fromArrayList(wip_nav.dwarf.gpa, &bytes);
3280- const old_len = bytes.items.len;
3281+ const old_end = wip_nav.debug_info.writer.end;
3282 try codegen.generateSymbol(
3283 wip_nav.dwarf.bin_file,
3284 wip_nav.pt,
3285 src_loc,
3286 val,
3287- &bytes,
3288+ &wip_nav.debug_info.writer,
3289 .{ .debug_output = .{ .dwarf = wip_nav } },
3290 );
3291- if (old_len + size != bytes.items.len) {
3292- std.debug.print("{f} [{}]: {} != {}\n", .{ ty.fmt(wip_nav.pt), ty.toIntern(), size, bytes.items.len - old_len });
3293+ if (old_end + size != wip_nav.debug_info.writer.end) {
3294+ std.debug.print("{f} [{}]: {} != {}\n", .{
3295+ ty.fmt(wip_nav.pt),
3296+ ty.toIntern(),
3297+ size,
3298+ wip_nav.debug_info.writer.end - old_end,
3299+ });
3300 unreachable;
3301 }
3302 }
3303@@ -6429,7 +6432,7 @@ fn sleb128Bytes(value: anytype) u32 {
3304 /// overrides `-fno-incremental` for testing incremental debug info until `-fincremental` is functional
3305 const force_incremental = false;
3306 inline fn incremental(dwarf: Dwarf) bool {
3307- return force_incremental or dwarf.bin_file.comp.incremental;
3308+ return force_incremental or dwarf.bin_file.comp.config.incremental;
3309 }
3310
3311 const Allocator = std.mem.Allocator;
3312diff --git a/src/link/Elf/LinkerDefined.zig b/src/link/Elf/LinkerDefined.zig
3313index b74406c368..d7e3cf62f3 100644
3314--- a/src/link/Elf/LinkerDefined.zig
3315+++ b/src/link/Elf/LinkerDefined.zig
3316@@ -47,7 +47,7 @@ fn newSymbolAssumeCapacity(self: *LinkerDefined, name_off: u32, elf_file: *Elf)
3317 const esym = self.symtab.addOneAssumeCapacity();
3318 esym.* = .{
3319 .st_name = name_off,
3320- .st_info = elf.STB_WEAK << 4,
3321+ .st_info = @as(u8, elf.STB_WEAK) << 4,
3322 .st_other = @intFromEnum(elf.STV.HIDDEN),
3323 .st_shndx = elf.SHN_ABS,
3324 .st_value = 0,
3325diff --git a/src/link/Elf/SharedObject.zig b/src/link/Elf/SharedObject.zig
3326index 8c79def16b..4dce40e370 100644
3327--- a/src/link/Elf/SharedObject.zig
3328+++ b/src/link/Elf/SharedObject.zig
3329@@ -105,7 +105,7 @@ pub fn parseHeader(
3330 if (amt != buf.len) return error.UnexpectedEndOfFile;
3331 }
3332 if (!mem.eql(u8, ehdr.e_ident[0..4], "\x7fELF")) return error.BadMagic;
3333- if (ehdr.e_ident[elf.EI_VERSION] != 1) return error.BadElfVersion;
3334+ if (ehdr.e_ident[elf.EI.VERSION] != 1) return error.BadElfVersion;
3335 if (ehdr.e_type != elf.ET.DYN) return error.NotSharedObject;
3336
3337 if (target.toElfMachine() != ehdr.e_machine)
3338diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig
3339index bf65d04e4a..a3ede11dc4 100644
3340--- a/src/link/Elf/ZigObject.zig
3341+++ b/src/link/Elf/ZigObject.zig
3342@@ -277,8 +277,8 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
3343 pt,
3344 .{ .kind = .code, .ty = .anyerror_type },
3345 metadata.text_symbol_index,
3346- ) catch |err| return switch (err) {
3347- error.CodegenFail => error.LinkFailure,
3348+ ) catch |err| switch (err) {
3349+ error.CodegenFail => return error.LinkFailure,
3350 else => |e| return e,
3351 };
3352 if (metadata.rodata_state != .unused) self.updateLazySymbol(
3353@@ -286,8 +286,8 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
3354 pt,
3355 .{ .kind = .const_data, .ty = .anyerror_type },
3356 metadata.rodata_symbol_index,
3357- ) catch |err| return switch (err) {
3358- error.CodegenFail => error.LinkFailure,
3359+ ) catch |err| switch (err) {
3360+ error.CodegenFail => return error.LinkFailure,
3361 else => |e| return e,
3362 };
3363 }
3364@@ -1533,22 +1533,26 @@ pub fn updateFunc(
3365 const sym_index = try self.getOrCreateMetadataForNav(zcu, func.owner_nav);
3366 self.atom(self.symbol(sym_index).ref.index).?.freeRelocs(self);
3367
3368- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
3369- defer code_buffer.deinit(gpa);
3370+ var aw: std.Io.Writer.Allocating = .init(gpa);
3371+ defer aw.deinit();
3372
3373 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
3374 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
3375
3376- try codegen.emitFunction(
3377+ codegen.emitFunction(
3378 &elf_file.base,
3379 pt,
3380 zcu.navSrcLoc(func.owner_nav),
3381 func_index,
3382+ sym_index,
3383 mir,
3384- &code_buffer,
3385+ &aw.writer,
3386 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,
3387- );
3388- const code = code_buffer.items;
3389+ ) catch |err| switch (err) {
3390+ error.WriteFailed => return error.OutOfMemory,
3391+ else => |e| return e,
3392+ };
3393+ const code = aw.written();
3394
3395 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);
3396 log.debug("setting shdr({x},{s}) for {f}", .{
3397@@ -1663,21 +1667,24 @@ pub fn updateNav(
3398 const sym_index = try self.getOrCreateMetadataForNav(zcu, nav_index);
3399 self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
3400
3401- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
3402- defer code_buffer.deinit(zcu.gpa);
3403+ var aw: std.Io.Writer.Allocating = .init(zcu.gpa);
3404+ defer aw.deinit();
3405
3406 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
3407 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
3408
3409- try codegen.generateSymbol(
3410+ codegen.generateSymbol(
3411 &elf_file.base,
3412 pt,
3413 zcu.navSrcLoc(nav_index),
3414 Value.fromInterned(nav_init),
3415- &code_buffer,
3416+ &aw.writer,
3417 .{ .atom_index = sym_index },
3418- );
3419- const code = code_buffer.items;
3420+ ) catch |err| switch (err) {
3421+ error.WriteFailed => return error.OutOfMemory,
3422+ else => |e| return e,
3423+ };
3424+ const code = aw.written();
3425
3426 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);
3427 log.debug("setting shdr({x},{s}) for {f}", .{
3428@@ -1722,8 +1729,8 @@ fn updateLazySymbol(
3429 const gpa = zcu.gpa;
3430
3431 var required_alignment: InternPool.Alignment = .none;
3432- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
3433- defer code_buffer.deinit(gpa);
3434+ var aw: std.Io.Writer.Allocating = .init(gpa);
3435+ defer aw.deinit();
3436
3437 const name_str_index = blk: {
3438 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{
3439@@ -1734,18 +1741,20 @@ fn updateLazySymbol(
3440 break :blk try self.strtab.insert(gpa, name);
3441 };
3442
3443- const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
3444- try codegen.generateLazySymbol(
3445+ codegen.generateLazySymbol(
3446 &elf_file.base,
3447 pt,
3448- src,
3449+ Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse .unneeded,
3450 sym,
3451 &required_alignment,
3452- &code_buffer,
3453+ &aw.writer,
3454 .none,
3455 .{ .atom_index = symbol_index },
3456- );
3457- const code = code_buffer.items;
3458+ ) catch |err| switch (err) {
3459+ error.WriteFailed => return error.OutOfMemory,
3460+ else => |e| return e,
3461+ };
3462+ const code = aw.written();
3463
3464 const output_section_index = switch (sym.kind) {
3465 .code => if (self.text_index) |sym_index|
3466@@ -1807,21 +1816,24 @@ fn lowerConst(
3467 ) !codegen.SymbolResult {
3468 const gpa = pt.zcu.gpa;
3469
3470- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
3471- defer code_buffer.deinit(gpa);
3472+ var aw: std.Io.Writer.Allocating = .init(gpa);
3473+ defer aw.deinit();
3474
3475 const name_off = try self.addString(gpa, name);
3476 const sym_index = try self.newSymbolWithAtom(gpa, name_off);
3477
3478- try codegen.generateSymbol(
3479+ codegen.generateSymbol(
3480 &elf_file.base,
3481 pt,
3482 src_loc,
3483 val,
3484- &code_buffer,
3485+ &aw.writer,
3486 .{ .atom_index = sym_index },
3487- );
3488- const code = code_buffer.items;
3489+ ) catch |err| switch (err) {
3490+ error.WriteFailed => return error.OutOfMemory,
3491+ else => |e| return e,
3492+ };
3493+ const code = aw.written();
3494
3495 const local_sym = self.symbol(sym_index);
3496 const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index];
3497diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig
3498new file mode 100644
3499index 0000000000..e43ebf2639
3500--- /dev/null
3501+++ b/src/link/Elf2.zig
3502@@ -0,0 +1,2036 @@
3503+base: link.File,
3504+mf: MappedFile,
3505+nodes: std.MultiArrayList(Node),
3506+symtab: std.ArrayList(Symbol),
3507+shstrtab: StringTable,
3508+strtab: StringTable,
3509+globals: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index),
3510+navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Symbol.Index),
3511+uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Symbol.Index),
3512+lazy: std.EnumArray(link.File.LazySymbol.Kind, struct {
3513+ map: std.AutoArrayHashMapUnmanaged(InternPool.Index, Symbol.Index),
3514+ pending_index: u32,
3515+}),
3516+pending_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, struct {
3517+ alignment: InternPool.Alignment,
3518+ src_loc: Zcu.LazySrcLoc,
3519+}),
3520+relocs: std.ArrayList(Reloc),
3521+/// This is hiding actual bugs with global symbols! Reconsider once they are implemented correctly.
3522+entry_hack: Symbol.Index,
3523+
3524+pub const Node = union(enum) {
3525+ file,
3526+ ehdr,
3527+ shdr,
3528+ segment: u32,
3529+ section: Symbol.Index,
3530+ nav: InternPool.Nav.Index,
3531+ uav: InternPool.Index,
3532+ lazy_code: InternPool.Index,
3533+ lazy_const_data: InternPool.Index,
3534+
3535+ pub const Tag = @typeInfo(Node).@"union".tag_type.?;
3536+
3537+ const known_count = @typeInfo(@TypeOf(known)).@"struct".fields.len;
3538+ const known = known: {
3539+ const Known = enum {
3540+ file,
3541+ seg_rodata,
3542+ ehdr,
3543+ phdr,
3544+ shdr,
3545+ seg_text,
3546+ seg_data,
3547+ };
3548+ var mut_known: std.enums.EnumFieldStruct(
3549+ Known,
3550+ MappedFile.Node.Index,
3551+ null,
3552+ ) = undefined;
3553+ for (@typeInfo(Known).@"enum".fields) |field|
3554+ @field(mut_known, field.name) = @enumFromInt(field.value);
3555+ break :known mut_known;
3556+ };
3557+
3558+ comptime {
3559+ if (!std.debug.runtime_safety) std.debug.assert(@sizeOf(Node) == 8);
3560+ }
3561+};
3562+
3563+pub const StringTable = struct {
3564+ map: std.HashMapUnmanaged(u32, void, StringTable.Context, std.hash_map.default_max_load_percentage),
3565+ size: u32,
3566+
3567+ const Context = struct {
3568+ slice: []const u8,
3569+
3570+ pub fn eql(_: Context, lhs_key: u32, rhs_key: u32) bool {
3571+ return lhs_key == rhs_key;
3572+ }
3573+
3574+ pub fn hash(ctx: Context, key: u32) u64 {
3575+ return std.hash_map.hashString(std.mem.sliceTo(ctx.slice[key..], 0));
3576+ }
3577+ };
3578+
3579+ const Adapter = struct {
3580+ slice: []const u8,
3581+
3582+ pub fn eql(adapter: Adapter, lhs_key: []const u8, rhs_key: u32) bool {
3583+ return std.mem.startsWith(u8, adapter.slice[rhs_key..], lhs_key) and
3584+ adapter.slice[rhs_key + lhs_key.len] == 0;
3585+ }
3586+
3587+ pub fn hash(_: Adapter, key: []const u8) u64 {
3588+ assert(std.mem.indexOfScalar(u8, key, 0) == null);
3589+ return std.hash_map.hashString(key);
3590+ }
3591+ };
3592+
3593+ pub fn get(
3594+ st: *StringTable,
3595+ gpa: std.mem.Allocator,
3596+ mf: *MappedFile,
3597+ ni: MappedFile.Node.Index,
3598+ key: []const u8,
3599+ ) !u32 {
3600+ const slice_const = ni.sliceConst(mf);
3601+ const gop = try st.map.getOrPutContextAdapted(
3602+ gpa,
3603+ key,
3604+ StringTable.Adapter{ .slice = slice_const },
3605+ .{ .slice = slice_const },
3606+ );
3607+ if (gop.found_existing) return gop.key_ptr.*;
3608+ const old_size = st.size;
3609+ const new_size: u32 = @intCast(old_size + key.len + 1);
3610+ st.size = new_size;
3611+ try ni.resize(mf, gpa, new_size);
3612+ const slice = ni.slice(mf)[old_size..];
3613+ @memcpy(slice[0..key.len], key);
3614+ slice[key.len] = 0;
3615+ gop.key_ptr.* = old_size;
3616+ return old_size;
3617+ }
3618+};
3619+
3620+pub const Symbol = struct {
3621+ ni: MappedFile.Node.Index,
3622+ /// Relocations contained within this symbol
3623+ loc_relocs: Reloc.Index,
3624+ /// Relocations targeting this symbol
3625+ target_relocs: Reloc.Index,
3626+ unused: u32 = 0,
3627+
3628+ pub const Index = enum(u32) {
3629+ null,
3630+ symtab,
3631+ shstrtab,
3632+ strtab,
3633+ rodata,
3634+ text,
3635+ data,
3636+ tdata,
3637+ _,
3638+
3639+ pub fn get(si: Symbol.Index, elf: *Elf) *Symbol {
3640+ return &elf.symtab.items[@intFromEnum(si)];
3641+ }
3642+
3643+ pub fn node(si: Symbol.Index, elf: *Elf) MappedFile.Node.Index {
3644+ const ni = si.get(elf).ni;
3645+ assert(ni != .none);
3646+ return ni;
3647+ }
3648+
3649+ pub const InitOptions = struct {
3650+ name: []const u8 = "",
3651+ size: std.elf.Word = 0,
3652+ type: std.elf.STT,
3653+ bind: std.elf.STB = .LOCAL,
3654+ visibility: std.elf.STV = .DEFAULT,
3655+ shndx: std.elf.Section = std.elf.SHN_UNDEF,
3656+ };
3657+ pub fn init(si: Symbol.Index, elf: *Elf, opts: InitOptions) !void {
3658+ const name_entry = try elf.string(.strtab, opts.name);
3659+ try Symbol.Index.symtab.node(elf).resize(
3660+ &elf.mf,
3661+ elf.base.comp.gpa,
3662+ @as(usize, switch (elf.identClass()) {
3663+ .NONE, _ => unreachable,
3664+ .@"32" => @sizeOf(std.elf.Elf32.Sym),
3665+ .@"64" => @sizeOf(std.elf.Elf64.Sym),
3666+ }) * elf.symtab.items.len,
3667+ );
3668+ switch (elf.symPtr(si)) {
3669+ inline else => |sym| sym.* = .{
3670+ .name = name_entry,
3671+ .value = 0,
3672+ .size = opts.size,
3673+ .info = .{
3674+ .type = opts.type,
3675+ .bind = opts.bind,
3676+ },
3677+ .other = .{
3678+ .visibility = opts.visibility,
3679+ },
3680+ .shndx = opts.shndx,
3681+ },
3682+ }
3683+ }
3684+
3685+ pub fn applyLocationRelocs(si: Symbol.Index, elf: *Elf) void {
3686+ for (elf.relocs.items[@intFromEnum(si.get(elf).loc_relocs)..]) |*reloc| {
3687+ if (reloc.loc != si) break;
3688+ reloc.apply(elf);
3689+ }
3690+ }
3691+
3692+ pub fn applyTargetRelocs(si: Symbol.Index, elf: *Elf) void {
3693+ var ri = si.get(elf).target_relocs;
3694+ while (ri != .none) {
3695+ const reloc = ri.get(elf);
3696+ assert(reloc.target == si);
3697+ reloc.apply(elf);
3698+ ri = reloc.next;
3699+ }
3700+ }
3701+
3702+ pub fn deleteLocationRelocs(si: Symbol.Index, elf: *Elf) void {
3703+ const sym = si.get(elf);
3704+ for (elf.relocs.items[@intFromEnum(sym.loc_relocs)..]) |*reloc| {
3705+ if (reloc.loc != si) break;
3706+ reloc.delete(elf);
3707+ }
3708+ sym.loc_relocs = .none;
3709+ }
3710+ };
3711+
3712+ comptime {
3713+ if (!std.debug.runtime_safety) std.debug.assert(@sizeOf(Symbol) == 16);
3714+ }
3715+};
3716+
3717+pub const Reloc = extern struct {
3718+ type: Reloc.Type,
3719+ prev: Reloc.Index,
3720+ next: Reloc.Index,
3721+ loc: Symbol.Index,
3722+ target: Symbol.Index,
3723+ unused: u32,
3724+ offset: u64,
3725+ addend: i64,
3726+
3727+ pub const Type = extern union {
3728+ x86_64: std.elf.R_X86_64,
3729+ aarch64: std.elf.R_AARCH64,
3730+ riscv: std.elf.R_RISCV,
3731+ ppc64: std.elf.R_PPC64,
3732+ };
3733+
3734+ pub const Index = enum(u32) {
3735+ none = std.math.maxInt(u32),
3736+ _,
3737+
3738+ pub fn get(si: Reloc.Index, elf: *Elf) *Reloc {
3739+ return &elf.relocs.items[@intFromEnum(si)];
3740+ }
3741+ };
3742+
3743+ pub fn apply(reloc: *const Reloc, elf: *Elf) void {
3744+ const target_endian = elf.endian();
3745+ switch (reloc.loc.get(elf).ni) {
3746+ .none => return,
3747+ else => |ni| if (ni.hasMoved(&elf.mf)) return,
3748+ }
3749+ switch (reloc.target.get(elf).ni) {
3750+ .none => return,
3751+ else => |ni| if (ni.hasMoved(&elf.mf)) return,
3752+ }
3753+ switch (elf.shdrSlice()) {
3754+ inline else => |shdr, class| {
3755+ const sym = @field(elf.symSlice(), @tagName(class));
3756+ const loc_sym = &sym[@intFromEnum(reloc.loc)];
3757+ const loc_shndx =
3758+ std.mem.toNative(@TypeOf(loc_sym.shndx), loc_sym.shndx, target_endian);
3759+ assert(loc_shndx != std.elf.SHN_UNDEF);
3760+ const loc_sh = &shdr[loc_shndx];
3761+ const loc_value = std.mem.toNative(
3762+ @TypeOf(loc_sym.value),
3763+ loc_sym.value,
3764+ target_endian,
3765+ ) + reloc.offset;
3766+ const loc_sh_addr =
3767+ std.mem.toNative(@TypeOf(loc_sh.addr), loc_sh.addr, target_endian);
3768+ const loc_sh_offset =
3769+ std.mem.toNative(@TypeOf(loc_sh.offset), loc_sh.offset, target_endian);
3770+ const loc_file_offset: usize = @intCast(loc_value - loc_sh_addr + loc_sh_offset);
3771+ const target_sym = &sym[@intFromEnum(reloc.target)];
3772+ const target_value = std.mem.toNative(
3773+ @TypeOf(target_sym.value),
3774+ target_sym.value,
3775+ target_endian,
3776+ ) +% @as(u64, @bitCast(reloc.addend));
3777+ switch (elf.ehdrField(.machine)) {
3778+ else => |machine| @panic(@tagName(machine)),
3779+ .X86_64 => switch (reloc.type.x86_64) {
3780+ else => |kind| @panic(@tagName(kind)),
3781+ .@"64" => std.mem.writeInt(
3782+ u64,
3783+ elf.mf.contents[loc_file_offset..][0..8],
3784+ target_value,
3785+ target_endian,
3786+ ),
3787+ .PC32 => std.mem.writeInt(
3788+ i32,
3789+ elf.mf.contents[loc_file_offset..][0..4],
3790+ @intCast(@as(i64, @bitCast(target_value -% loc_value))),
3791+ target_endian,
3792+ ),
3793+ .@"32" => std.mem.writeInt(
3794+ u32,
3795+ elf.mf.contents[loc_file_offset..][0..4],
3796+ @intCast(target_value),
3797+ target_endian,
3798+ ),
3799+ .TPOFF32 => {
3800+ const phdr = @field(elf.phdrSlice(), @tagName(class));
3801+ const ph = &phdr[4];
3802+ assert(std.mem.toNative(
3803+ @TypeOf(ph.type),
3804+ ph.type,
3805+ target_endian,
3806+ ) == std.elf.PT_TLS);
3807+ std.mem.writeInt(
3808+ i32,
3809+ elf.mf.contents[loc_file_offset..][0..4],
3810+ @intCast(@as(i64, @bitCast(target_value -% std.mem.toNative(
3811+ @TypeOf(ph.memsz),
3812+ ph.memsz,
3813+ target_endian,
3814+ )))),
3815+ target_endian,
3816+ );
3817+ },
3818+ },
3819+ }
3820+ },
3821+ }
3822+ }
3823+
3824+ pub fn delete(reloc: *Reloc, elf: *Elf) void {
3825+ switch (reloc.prev) {
3826+ .none => {
3827+ const target = reloc.target.get(elf);
3828+ assert(target.target_relocs.get(elf) == reloc);
3829+ target.target_relocs = reloc.next;
3830+ },
3831+ else => |prev| prev.get(elf).next = reloc.next,
3832+ }
3833+ switch (reloc.next) {
3834+ .none => {},
3835+ else => |next| next.get(elf).prev = reloc.prev,
3836+ }
3837+ reloc.* = undefined;
3838+ }
3839+
3840+ comptime {
3841+ if (!std.debug.runtime_safety) std.debug.assert(@sizeOf(Reloc) == 40);
3842+ }
3843+};
3844+
3845+pub fn open(
3846+ arena: std.mem.Allocator,
3847+ comp: *Compilation,
3848+ path: std.Build.Cache.Path,
3849+ options: link.File.OpenOptions,
3850+) !*Elf {
3851+ return create(arena, comp, path, options);
3852+}
3853+pub fn createEmpty(
3854+ arena: std.mem.Allocator,
3855+ comp: *Compilation,
3856+ path: std.Build.Cache.Path,
3857+ options: link.File.OpenOptions,
3858+) !*Elf {
3859+ return create(arena, comp, path, options);
3860+}
3861+fn create(
3862+ arena: std.mem.Allocator,
3863+ comp: *Compilation,
3864+ path: std.Build.Cache.Path,
3865+ options: link.File.OpenOptions,
3866+) !*Elf {
3867+ _ = options;
3868+ const target = &comp.root_mod.resolved_target.result;
3869+ assert(target.ofmt == .elf);
3870+ const class: std.elf.CLASS = switch (target.ptrBitWidth()) {
3871+ 0...32 => .@"32",
3872+ 33...64 => .@"64",
3873+ else => return error.UnsupportedELFArchitecture,
3874+ };
3875+ const data: std.elf.DATA = switch (target.cpu.arch.endian()) {
3876+ .little => .@"2LSB",
3877+ .big => .@"2MSB",
3878+ };
3879+ const osabi: std.elf.OSABI = switch (target.os.tag) {
3880+ else => .NONE,
3881+ .freestanding, .other => .STANDALONE,
3882+ .netbsd => .NETBSD,
3883+ .solaris => .SOLARIS,
3884+ .aix => .AIX,
3885+ .freebsd => .FREEBSD,
3886+ .cuda => .CUDA,
3887+ .amdhsa => .AMDGPU_HSA,
3888+ .amdpal => .AMDGPU_PAL,
3889+ .mesa3d => .AMDGPU_MESA3D,
3890+ };
3891+ const @"type": std.elf.ET = switch (comp.config.output_mode) {
3892+ .Exe => if (comp.config.pie or target.os.tag == .haiku) .DYN else .EXEC,
3893+ .Lib => switch (comp.config.link_mode) {
3894+ .static => .REL,
3895+ .dynamic => .DYN,
3896+ },
3897+ .Obj => .REL,
3898+ };
3899+ const machine: std.elf.EM = switch (target.cpu.arch) {
3900+ .spirv32, .spirv64, .wasm32, .wasm64 => .NONE,
3901+ .sparc => .SPARC,
3902+ .x86 => .@"386",
3903+ .m68k => .@"68K",
3904+ .mips, .mipsel, .mips64, .mips64el => .MIPS,
3905+ .powerpc, .powerpcle => .PPC,
3906+ .powerpc64, .powerpc64le => .PPC64,
3907+ .s390x => .S390,
3908+ .arm, .armeb, .thumb, .thumbeb => .ARM,
3909+ .hexagon => .SH,
3910+ .sparc64 => .SPARCV9,
3911+ .arc => .ARC,
3912+ .x86_64 => .X86_64,
3913+ .or1k => .OR1K,
3914+ .xtensa => .XTENSA,
3915+ .msp430 => .MSP430,
3916+ .avr => .AVR,
3917+ .nvptx, .nvptx64 => .CUDA,
3918+ .kalimba => .CSR_KALIMBA,
3919+ .aarch64, .aarch64_be => .AARCH64,
3920+ .xcore => .XCORE,
3921+ .amdgcn => .AMDGPU,
3922+ .riscv32, .riscv32be, .riscv64, .riscv64be => .RISCV,
3923+ .lanai => .LANAI,
3924+ .bpfel, .bpfeb => .BPF,
3925+ .ve => .VE,
3926+ .csky => .CSKY,
3927+ .loongarch32, .loongarch64 => .LOONGARCH,
3928+ .propeller => if (target.cpu.has(.propeller, .p2)) .PROPELLER2 else .PROPELLER,
3929+ };
3930+ const maybe_interp = switch (comp.config.output_mode) {
3931+ .Exe, .Lib => switch (comp.config.link_mode) {
3932+ .static => null,
3933+ .dynamic => target.dynamic_linker.get(),
3934+ },
3935+ .Obj => null,
3936+ };
3937+
3938+ const elf = try arena.create(Elf);
3939+ const file = try path.root_dir.handle.createFile(path.sub_path, .{
3940+ .read = true,
3941+ .mode = link.File.determineMode(comp.config.output_mode, comp.config.link_mode),
3942+ });
3943+ errdefer file.close();
3944+ elf.* = .{
3945+ .base = .{
3946+ .tag = .elf2,
3947+
3948+ .comp = comp,
3949+ .emit = path,
3950+
3951+ .file = file,
3952+ .gc_sections = false,
3953+ .print_gc_sections = false,
3954+ .build_id = .none,
3955+ .allow_shlib_undefined = false,
3956+ .stack_size = 0,
3957+ },
3958+ .mf = try .init(file, comp.gpa),
3959+ .nodes = .empty,
3960+ .symtab = .empty,
3961+ .shstrtab = .{
3962+ .map = .empty,
3963+ .size = 1,
3964+ },
3965+ .strtab = .{
3966+ .map = .empty,
3967+ .size = 1,
3968+ },
3969+ .globals = .empty,
3970+ .navs = .empty,
3971+ .uavs = .empty,
3972+ .lazy = .initFill(.{
3973+ .map = .empty,
3974+ .pending_index = 0,
3975+ }),
3976+ .pending_uavs = .empty,
3977+ .relocs = .empty,
3978+ .entry_hack = .null,
3979+ };
3980+ errdefer elf.deinit();
3981+
3982+ switch (class) {
3983+ .NONE, _ => unreachable,
3984+ inline .@"32", .@"64" => |ct_class| try elf.initHeaders(
3985+ ct_class,
3986+ data,
3987+ osabi,
3988+ @"type",
3989+ machine,
3990+ maybe_interp,
3991+ ),
3992+ }
3993+
3994+ return elf;
3995+}
3996+
3997+pub fn deinit(elf: *Elf) void {
3998+ const gpa = elf.base.comp.gpa;
3999+ elf.mf.deinit(gpa);
4000+ elf.nodes.deinit(gpa);
4001+ elf.symtab.deinit(gpa);
4002+ elf.shstrtab.map.deinit(gpa);
4003+ elf.strtab.map.deinit(gpa);
4004+ elf.globals.deinit(gpa);
4005+ elf.navs.deinit(gpa);
4006+ elf.uavs.deinit(gpa);
4007+ for (&elf.lazy.values) |*lazy| lazy.map.deinit(gpa);
4008+ elf.pending_uavs.deinit(gpa);
4009+ elf.relocs.deinit(gpa);
4010+ elf.* = undefined;
4011+}
4012+
4013+fn initHeaders(
4014+ elf: *Elf,
4015+ comptime class: std.elf.CLASS,
4016+ data: std.elf.DATA,
4017+ osabi: std.elf.OSABI,
4018+ @"type": std.elf.ET,
4019+ machine: std.elf.EM,
4020+ maybe_interp: ?[]const u8,
4021+) !void {
4022+ const comp = elf.base.comp;
4023+ const gpa = comp.gpa;
4024+ const ElfN = switch (class) {
4025+ .NONE, _ => comptime unreachable,
4026+ .@"32" => std.elf.Elf32,
4027+ .@"64" => std.elf.Elf64,
4028+ };
4029+ const addr_align: std.mem.Alignment = comptime .fromByteUnits(@sizeOf(ElfN.Addr));
4030+ const target_endian: std.builtin.Endian = switch (data) {
4031+ .NONE, _ => unreachable,
4032+ .@"2LSB" => .little,
4033+ .@"2MSB" => .big,
4034+ };
4035+
4036+ var phnum: u32 = 0;
4037+ const phdr_phndx = phnum;
4038+ phnum += 1;
4039+ const interp_phndx = if (maybe_interp) |_| phndx: {
4040+ defer phnum += 1;
4041+ break :phndx phnum;
4042+ } else undefined;
4043+ const rodata_phndx = phnum;
4044+ phnum += 1;
4045+ const text_phndx = phnum;
4046+ phnum += 1;
4047+ const data_phndx = phnum;
4048+ phnum += 1;
4049+ const tls_phndx = if (comp.config.any_non_single_threaded) phndx: {
4050+ defer phnum += 1;
4051+ break :phndx phnum;
4052+ } else undefined;
4053+
4054+ try elf.nodes.ensureTotalCapacity(gpa, Node.known_count);
4055+ elf.nodes.appendAssumeCapacity(.file);
4056+
4057+ const seg_rodata_ni = Node.known.seg_rodata;
4058+ assert(seg_rodata_ni == try elf.mf.addOnlyChildNode(gpa, .root, .{
4059+ .alignment = elf.mf.flags.block_size,
4060+ .fixed = true,
4061+ .moved = true,
4062+ }));
4063+ elf.nodes.appendAssumeCapacity(.{ .segment = rodata_phndx });
4064+
4065+ const ehdr_ni = Node.known.ehdr;
4066+ assert(ehdr_ni == try elf.mf.addOnlyChildNode(gpa, seg_rodata_ni, .{
4067+ .size = @sizeOf(ElfN.Ehdr),
4068+ .alignment = addr_align,
4069+ .fixed = true,
4070+ }));
4071+ elf.nodes.appendAssumeCapacity(.ehdr);
4072+
4073+ const ehdr: *ElfN.Ehdr = @ptrCast(@alignCast(ehdr_ni.slice(&elf.mf)));
4074+ const EI = std.elf.EI;
4075+ @memcpy(ehdr.ident[0..std.elf.MAGIC.len], std.elf.MAGIC);
4076+ ehdr.ident[EI.CLASS] = @intFromEnum(class);
4077+ ehdr.ident[EI.DATA] = @intFromEnum(data);
4078+ ehdr.ident[EI.VERSION] = 1;
4079+ ehdr.ident[EI.OSABI] = @intFromEnum(osabi);
4080+ ehdr.ident[EI.ABIVERSION] = 0;
4081+ @memset(ehdr.ident[EI.PAD..], 0);
4082+ ehdr.type = @"type";
4083+ ehdr.machine = machine;
4084+ ehdr.version = 1;
4085+ ehdr.entry = 0;
4086+ ehdr.phoff = 0;
4087+ ehdr.shoff = 0;
4088+ ehdr.flags = 0;
4089+ ehdr.ehsize = @sizeOf(ElfN.Ehdr);
4090+ ehdr.phentsize = @sizeOf(ElfN.Phdr);
4091+ ehdr.phnum = @min(phnum, std.elf.PN_XNUM);
4092+ ehdr.shentsize = @sizeOf(ElfN.Shdr);
4093+ ehdr.shnum = 1;
4094+ ehdr.shstrndx = 0;
4095+ if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Ehdr, ehdr);
4096+
4097+ const phdr_ni = Node.known.phdr;
4098+ assert(phdr_ni == try elf.mf.addLastChildNode(gpa, seg_rodata_ni, .{
4099+ .size = @sizeOf(ElfN.Phdr) * phnum,
4100+ .alignment = addr_align,
4101+ .moved = true,
4102+ .resized = true,
4103+ }));
4104+ elf.nodes.appendAssumeCapacity(.{ .segment = phdr_phndx });
4105+
4106+ const shdr_ni = Node.known.shdr;
4107+ assert(shdr_ni == try elf.mf.addLastChildNode(gpa, seg_rodata_ni, .{
4108+ .size = @sizeOf(ElfN.Shdr),
4109+ .alignment = addr_align,
4110+ }));
4111+ elf.nodes.appendAssumeCapacity(.shdr);
4112+
4113+ const seg_text_ni = Node.known.seg_text;
4114+ assert(seg_text_ni == try elf.mf.addLastChildNode(gpa, .root, .{
4115+ .alignment = elf.mf.flags.block_size,
4116+ .moved = true,
4117+ }));
4118+ elf.nodes.appendAssumeCapacity(.{ .segment = text_phndx });
4119+
4120+ const seg_data_ni = Node.known.seg_data;
4121+ assert(seg_data_ni == try elf.mf.addLastChildNode(gpa, .root, .{
4122+ .alignment = elf.mf.flags.block_size,
4123+ .moved = true,
4124+ }));
4125+ elf.nodes.appendAssumeCapacity(.{ .segment = data_phndx });
4126+
4127+ assert(elf.nodes.len == Node.known_count);
4128+
4129+ {
4130+ const phdr: []ElfN.Phdr = @ptrCast(@alignCast(phdr_ni.slice(&elf.mf)));
4131+ const ph_phdr = &phdr[phdr_phndx];
4132+ ph_phdr.* = .{
4133+ .type = std.elf.PT_PHDR,
4134+ .offset = 0,
4135+ .vaddr = 0,
4136+ .paddr = 0,
4137+ .filesz = 0,
4138+ .memsz = 0,
4139+ .flags = .{ .R = true },
4140+ .@"align" = @intCast(phdr_ni.alignment(&elf.mf).toByteUnits()),
4141+ };
4142+ if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_phdr);
4143+
4144+ if (maybe_interp) |_| {
4145+ const ph_interp = &phdr[interp_phndx];
4146+ ph_interp.* = .{
4147+ .type = std.elf.PT_INTERP,
4148+ .offset = 0,
4149+ .vaddr = 0,
4150+ .paddr = 0,
4151+ .filesz = 0,
4152+ .memsz = 0,
4153+ .flags = .{ .R = true },
4154+ .@"align" = 1,
4155+ };
4156+ if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_interp);
4157+ }
4158+
4159+ const ph_rodata = &phdr[rodata_phndx];
4160+ ph_rodata.* = .{
4161+ .type = std.elf.PT_NULL,
4162+ .offset = 0,
4163+ .vaddr = 0,
4164+ .paddr = 0,
4165+ .filesz = 0,
4166+ .memsz = 0,
4167+ .flags = .{ .R = true },
4168+ .@"align" = @intCast(seg_rodata_ni.alignment(&elf.mf).toByteUnits()),
4169+ };
4170+ if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_rodata);
4171+
4172+ const ph_text = &phdr[text_phndx];
4173+ ph_text.* = .{
4174+ .type = std.elf.PT_NULL,
4175+ .offset = 0,
4176+ .vaddr = 0,
4177+ .paddr = 0,
4178+ .filesz = 0,
4179+ .memsz = 0,
4180+ .flags = .{ .R = true, .X = true },
4181+ .@"align" = @intCast(seg_text_ni.alignment(&elf.mf).toByteUnits()),
4182+ };
4183+ if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_text);
4184+
4185+ const ph_data = &phdr[data_phndx];
4186+ ph_data.* = .{
4187+ .type = std.elf.PT_NULL,
4188+ .offset = 0,
4189+ .vaddr = 0,
4190+ .paddr = 0,
4191+ .filesz = 0,
4192+ .memsz = 0,
4193+ .flags = .{ .R = true, .W = true },
4194+ .@"align" = @intCast(seg_data_ni.alignment(&elf.mf).toByteUnits()),
4195+ };
4196+ if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_data);
4197+
4198+ if (comp.config.any_non_single_threaded) {
4199+ const ph_tls = &phdr[tls_phndx];
4200+ ph_tls.* = .{
4201+ .type = std.elf.PT_TLS,
4202+ .offset = 0,
4203+ .vaddr = 0,
4204+ .paddr = 0,
4205+ .filesz = 0,
4206+ .memsz = 0,
4207+ .flags = .{ .R = true },
4208+ .@"align" = @intCast(elf.mf.flags.block_size.toByteUnits()),
4209+ };
4210+ if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_tls);
4211+ }
4212+
4213+ const sh_null: *ElfN.Shdr = @ptrCast(@alignCast(shdr_ni.slice(&elf.mf)));
4214+ sh_null.* = .{
4215+ .name = try elf.string(.shstrtab, ""),
4216+ .type = std.elf.SHT_NULL,
4217+ .flags = .{ .shf = .{} },
4218+ .addr = 0,
4219+ .offset = 0,
4220+ .size = 0,
4221+ .link = 0,
4222+ .info = if (phnum >= std.elf.PN_XNUM) phnum else 0,
4223+ .addralign = 0,
4224+ .entsize = 0,
4225+ };
4226+ if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Shdr, sh_null);
4227+ }
4228+
4229+ try elf.symtab.ensureTotalCapacity(gpa, 1);
4230+ elf.symtab.addOneAssumeCapacity().* = .{
4231+ .ni = .none,
4232+ .loc_relocs = .none,
4233+ .target_relocs = .none,
4234+ .unused = 0,
4235+ };
4236+ assert(try elf.addSection(seg_rodata_ni, .{
4237+ .type = std.elf.SHT_SYMTAB,
4238+ .addralign = addr_align,
4239+ .entsize = @sizeOf(ElfN.Sym),
4240+ }) == .symtab);
4241+ const symtab: *ElfN.Sym = @ptrCast(@alignCast(Symbol.Index.symtab.node(elf).slice(&elf.mf)));
4242+ symtab.* = .{
4243+ .name = try elf.string(.strtab, ""),
4244+ .value = 0,
4245+ .size = 0,
4246+ .info = .{
4247+ .type = .NOTYPE,
4248+ .bind = .LOCAL,
4249+ },
4250+ .other = .{
4251+ .visibility = .DEFAULT,
4252+ },
4253+ .shndx = std.elf.SHN_UNDEF,
4254+ };
4255+ ehdr.shstrndx = ehdr.shnum;
4256+ assert(try elf.addSection(seg_rodata_ni, .{
4257+ .type = std.elf.SHT_STRTAB,
4258+ .addralign = elf.mf.flags.block_size,
4259+ .entsize = 1,
4260+ }) == .shstrtab);
4261+ assert(try elf.addSection(seg_rodata_ni, .{
4262+ .type = std.elf.SHT_STRTAB,
4263+ .addralign = elf.mf.flags.block_size,
4264+ .entsize = 1,
4265+ }) == .strtab);
4266+ try elf.renameSection(.symtab, ".symtab");
4267+ try elf.renameSection(.shstrtab, ".shstrtab");
4268+ try elf.renameSection(.strtab, ".strtab");
4269+ try elf.linkSections(.symtab, .strtab);
4270+ Symbol.Index.shstrtab.node(elf).slice(&elf.mf)[0] = 0;
4271+ Symbol.Index.strtab.node(elf).slice(&elf.mf)[0] = 0;
4272+
4273+ assert(try elf.addSection(seg_rodata_ni, .{
4274+ .name = ".rodata",
4275+ .flags = .{ .ALLOC = true },
4276+ .addralign = elf.mf.flags.block_size,
4277+ }) == .rodata);
4278+ assert(try elf.addSection(seg_text_ni, .{
4279+ .name = ".text",
4280+ .flags = .{ .ALLOC = true, .EXECINSTR = true },
4281+ .addralign = elf.mf.flags.block_size,
4282+ }) == .text);
4283+ assert(try elf.addSection(seg_data_ni, .{
4284+ .name = ".data",
4285+ .flags = .{ .WRITE = true, .ALLOC = true },
4286+ .addralign = elf.mf.flags.block_size,
4287+ }) == .data);
4288+ if (comp.config.any_non_single_threaded) {
4289+ try elf.nodes.ensureUnusedCapacity(gpa, 1);
4290+ const seg_tls_ni = try elf.mf.addLastChildNode(gpa, seg_data_ni, .{
4291+ .alignment = elf.mf.flags.block_size,
4292+ .moved = true,
4293+ });
4294+ elf.nodes.appendAssumeCapacity(.{ .segment = tls_phndx });
4295+
4296+ assert(try elf.addSection(seg_tls_ni, .{
4297+ .name = ".tdata",
4298+ .flags = .{ .WRITE = true, .ALLOC = true, .TLS = true },
4299+ .addralign = elf.mf.flags.block_size,
4300+ }) == .tdata);
4301+ }
4302+ if (maybe_interp) |interp| {
4303+ try elf.nodes.ensureUnusedCapacity(gpa, 1);
4304+ const seg_interp_ni = try elf.mf.addLastChildNode(gpa, seg_rodata_ni, .{
4305+ .size = interp.len + 1,
4306+ .moved = true,
4307+ .resized = true,
4308+ });
4309+ elf.nodes.appendAssumeCapacity(.{ .segment = interp_phndx });
4310+
4311+ const sec_interp_si = try elf.addSection(seg_interp_ni, .{
4312+ .name = ".interp",
4313+ .size = @intCast(interp.len + 1),
4314+ .flags = .{ .ALLOC = true },
4315+ });
4316+ const sec_interp = sec_interp_si.node(elf).slice(&elf.mf);
4317+ @memcpy(sec_interp[0..interp.len], interp);
4318+ sec_interp[interp.len] = 0;
4319+ }
4320+}
4321+
4322+fn getNode(elf: *Elf, ni: MappedFile.Node.Index) Node {
4323+ return elf.nodes.get(@intFromEnum(ni));
4324+}
4325+
4326+pub const EhdrPtr = union(std.elf.CLASS) {
4327+ NONE: noreturn,
4328+ @"32": *std.elf.Elf32.Ehdr,
4329+ @"64": *std.elf.Elf64.Ehdr,
4330+};
4331+pub fn ehdrPtr(elf: *Elf) EhdrPtr {
4332+ const slice = Node.known.ehdr.slice(&elf.mf);
4333+ return switch (elf.identClass()) {
4334+ .NONE, _ => unreachable,
4335+ inline .@"32", .@"64" => |class| @unionInit(
4336+ EhdrPtr,
4337+ @tagName(class),
4338+ @ptrCast(@alignCast(slice)),
4339+ ),
4340+ };
4341+}
4342+pub fn ehdrField(
4343+ elf: *Elf,
4344+ comptime field: enum { type, machine },
4345+) @FieldType(std.elf.Elf32.Ehdr, @tagName(field)) {
4346+ const Field = @FieldType(std.elf.Elf32.Ehdr, @tagName(field));
4347+ comptime assert(@FieldType(std.elf.Elf64.Ehdr, @tagName(field)) == Field);
4348+ return @enumFromInt(std.mem.toNative(
4349+ @typeInfo(Field).@"enum".tag_type,
4350+ @intFromEnum(switch (elf.ehdrPtr()) {
4351+ inline else => |ehdr| @field(ehdr, @tagName(field)),
4352+ }),
4353+ elf.endian(),
4354+ ));
4355+}
4356+
4357+pub fn identClass(elf: *Elf) std.elf.CLASS {
4358+ return @enumFromInt(elf.mf.contents[std.elf.EI.CLASS]);
4359+}
4360+
4361+pub fn identData(elf: *Elf) std.elf.DATA {
4362+ return @enumFromInt(elf.mf.contents[std.elf.EI.DATA]);
4363+}
4364+fn endianForData(data: std.elf.DATA) std.builtin.Endian {
4365+ return switch (data) {
4366+ .NONE, _ => unreachable,
4367+ .@"2LSB" => .little,
4368+ .@"2MSB" => .big,
4369+ };
4370+}
4371+pub fn endian(elf: *Elf) std.builtin.Endian {
4372+ return endianForData(elf.identData());
4373+}
4374+
4375+fn baseAddrForType(@"type": std.elf.ET) u64 {
4376+ return switch (@"type") {
4377+ else => 0,
4378+ .EXEC => 0x1000000,
4379+ };
4380+}
4381+pub fn baseAddr(elf: *Elf) u64 {
4382+ return baseAddrForType(elf.ehdrField(.type));
4383+}
4384+
4385+pub const PhdrSlice = union(std.elf.CLASS) {
4386+ NONE: noreturn,
4387+ @"32": []std.elf.Elf32.Phdr,
4388+ @"64": []std.elf.Elf64.Phdr,
4389+};
4390+pub fn phdrSlice(elf: *Elf) PhdrSlice {
4391+ const slice = Node.known.phdr.slice(&elf.mf);
4392+ return switch (elf.identClass()) {
4393+ .NONE, _ => unreachable,
4394+ inline .@"32", .@"64" => |class| @unionInit(
4395+ PhdrSlice,
4396+ @tagName(class),
4397+ @ptrCast(@alignCast(slice)),
4398+ ),
4399+ };
4400+}
4401+
4402+pub const ShdrSlice = union(std.elf.CLASS) {
4403+ NONE: noreturn,
4404+ @"32": []std.elf.Elf32.Shdr,
4405+ @"64": []std.elf.Elf64.Shdr,
4406+};
4407+pub fn shdrSlice(elf: *Elf) ShdrSlice {
4408+ const slice = Node.known.shdr.slice(&elf.mf);
4409+ return switch (elf.identClass()) {
4410+ .NONE, _ => unreachable,
4411+ inline .@"32", .@"64" => |class| @unionInit(
4412+ ShdrSlice,
4413+ @tagName(class),
4414+ @ptrCast(@alignCast(slice)),
4415+ ),
4416+ };
4417+}
4418+
4419+pub const SymSlice = union(std.elf.CLASS) {
4420+ NONE: noreturn,
4421+ @"32": []std.elf.Elf32.Sym,
4422+ @"64": []std.elf.Elf64.Sym,
4423+};
4424+pub fn symSlice(elf: *Elf) SymSlice {
4425+ const slice = Symbol.Index.symtab.node(elf).slice(&elf.mf);
4426+ return switch (elf.identClass()) {
4427+ .NONE, _ => unreachable,
4428+ inline .@"32", .@"64" => |class| @unionInit(
4429+ SymSlice,
4430+ @tagName(class),
4431+ @ptrCast(@alignCast(slice)),
4432+ ),
4433+ };
4434+}
4435+
4436+pub const SymPtr = union(std.elf.CLASS) {
4437+ NONE: noreturn,
4438+ @"32": *std.elf.Elf32.Sym,
4439+ @"64": *std.elf.Elf64.Sym,
4440+};
4441+pub fn symPtr(elf: *Elf, si: Symbol.Index) SymPtr {
4442+ return switch (elf.symSlice()) {
4443+ inline else => |sym, class| @unionInit(SymPtr, @tagName(class), &sym[@intFromEnum(si)]),
4444+ };
4445+}
4446+
4447+fn addSymbolAssumeCapacity(elf: *Elf) !Symbol.Index {
4448+ defer elf.symtab.addOneAssumeCapacity().* = .{
4449+ .ni = .none,
4450+ .loc_relocs = .none,
4451+ .target_relocs = .none,
4452+ .unused = 0,
4453+ };
4454+ return @enumFromInt(elf.symtab.items.len);
4455+}
4456+
4457+fn initSymbolAssumeCapacity(elf: *Elf, opts: Symbol.Index.InitOptions) !Symbol.Index {
4458+ const si = try elf.addSymbolAssumeCapacity();
4459+ try si.init(elf, opts);
4460+ return si;
4461+}
4462+
4463+pub fn globalSymbol(
4464+ elf: *Elf,
4465+ opts: struct {
4466+ name: []const u8,
4467+ type: std.elf.STT,
4468+ bind: std.elf.STB = .GLOBAL,
4469+ visibility: std.elf.STV = .DEFAULT,
4470+ },
4471+) !Symbol.Index {
4472+ const gpa = elf.base.comp.gpa;
4473+ try elf.symtab.ensureUnusedCapacity(gpa, 1);
4474+ const sym_gop = try elf.globals.getOrPut(gpa, try elf.string(.strtab, opts.name));
4475+ if (!sym_gop.found_existing) sym_gop.value_ptr.* = try elf.initSymbolAssumeCapacity(.{
4476+ .name = opts.name,
4477+ .type = opts.type,
4478+ .bind = opts.bind,
4479+ .visibility = opts.visibility,
4480+ });
4481+ return sym_gop.value_ptr.*;
4482+}
4483+
4484+fn navType(
4485+ ip: *const InternPool,
4486+ nav_status: @FieldType(InternPool.Nav, "status"),
4487+ any_non_single_threaded: bool,
4488+) std.elf.STT {
4489+ return switch (nav_status) {
4490+ .unresolved => unreachable,
4491+ .type_resolved => |tr| if (any_non_single_threaded and tr.is_threadlocal)
4492+ .TLS
4493+ else if (ip.isFunctionType(tr.type))
4494+ .FUNC
4495+ else
4496+ .OBJECT,
4497+ .fully_resolved => |fr| switch (ip.indexToKey(fr.val)) {
4498+ else => .OBJECT,
4499+ .variable => |variable| if (any_non_single_threaded and variable.is_threadlocal)
4500+ .TLS
4501+ else
4502+ .OBJECT,
4503+ .@"extern" => |@"extern"| if (any_non_single_threaded and @"extern".is_threadlocal)
4504+ .TLS
4505+ else if (ip.isFunctionType(@"extern".ty))
4506+ .FUNC
4507+ else
4508+ .OBJECT,
4509+ .func => .FUNC,
4510+ },
4511+ };
4512+}
4513+pub fn navSymbol(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol.Index {
4514+ const gpa = zcu.gpa;
4515+ const ip = &zcu.intern_pool;
4516+ const nav = ip.getNav(nav_index);
4517+ if (nav.getExtern(ip)) |@"extern"| return elf.globalSymbol(.{
4518+ .name = @"extern".name.toSlice(ip),
4519+ .type = navType(ip, nav.status, elf.base.comp.config.any_non_single_threaded),
4520+ .bind = switch (@"extern".linkage) {
4521+ .internal => .LOCAL,
4522+ .strong => .GLOBAL,
4523+ .weak => .WEAK,
4524+ .link_once => return error.LinkOnceUnsupported,
4525+ },
4526+ .visibility = switch (@"extern".visibility) {
4527+ .default => .DEFAULT,
4528+ .hidden => .HIDDEN,
4529+ .protected => .PROTECTED,
4530+ },
4531+ });
4532+ try elf.symtab.ensureUnusedCapacity(gpa, 1);
4533+ const sym_gop = try elf.navs.getOrPut(gpa, nav_index);
4534+ if (!sym_gop.found_existing) {
4535+ sym_gop.value_ptr.* = try elf.initSymbolAssumeCapacity(.{
4536+ .name = nav.fqn.toSlice(ip),
4537+ .type = navType(ip, nav.status, elf.base.comp.config.any_non_single_threaded),
4538+ });
4539+ }
4540+ return sym_gop.value_ptr.*;
4541+}
4542+
4543+pub fn uavSymbol(elf: *Elf, uav_val: InternPool.Index) !Symbol.Index {
4544+ const gpa = elf.base.comp.gpa;
4545+ try elf.symtab.ensureUnusedCapacity(gpa, 1);
4546+ const sym_gop = try elf.uavs.getOrPut(gpa, uav_val);
4547+ if (!sym_gop.found_existing)
4548+ sym_gop.value_ptr.* = try elf.initSymbolAssumeCapacity(.{ .type = .OBJECT });
4549+ return sym_gop.value_ptr.*;
4550+}
4551+
4552+pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !Symbol.Index {
4553+ const gpa = elf.base.comp.gpa;
4554+ try elf.symtab.ensureUnusedCapacity(gpa, 1);
4555+ const sym_gop = try elf.lazy.getPtr(lazy.kind).map.getOrPut(gpa, lazy.ty);
4556+ if (!sym_gop.found_existing) {
4557+ sym_gop.value_ptr.* = try elf.initSymbolAssumeCapacity(.{
4558+ .type = switch (lazy.kind) {
4559+ .code => .FUNC,
4560+ .const_data => .OBJECT,
4561+ },
4562+ });
4563+ elf.base.comp.link_lazy_prog_node.increaseEstimatedTotalItems(1);
4564+ }
4565+ return sym_gop.value_ptr.*;
4566+}
4567+
4568+pub fn getNavVAddr(
4569+ elf: *Elf,
4570+ pt: Zcu.PerThread,
4571+ nav: InternPool.Nav.Index,
4572+ reloc_info: link.File.RelocInfo,
4573+) !u64 {
4574+ return elf.getVAddr(reloc_info, try elf.navSymbol(pt.zcu, nav));
4575+}
4576+
4577+pub fn getUavVAddr(
4578+ elf: *Elf,
4579+ uav: InternPool.Index,
4580+ reloc_info: link.File.RelocInfo,
4581+) !u64 {
4582+ return elf.getVAddr(reloc_info, try elf.uavSymbol(uav));
4583+}
4584+
4585+pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) !u64 {
4586+ try elf.addReloc(
4587+ @enumFromInt(reloc_info.parent.atom_index),
4588+ reloc_info.offset,
4589+ target_si,
4590+ reloc_info.addend,
4591+ switch (elf.ehdrField(.machine)) {
4592+ else => unreachable,
4593+ .X86_64 => .{ .x86_64 = switch (elf.identClass()) {
4594+ .NONE, _ => unreachable,
4595+ .@"32" => .@"32",
4596+ .@"64" => .@"64",
4597+ } },
4598+ },
4599+ );
4600+ return 0;
4601+}
4602+
4603+fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
4604+ name: []const u8 = "",
4605+ type: std.elf.Word = std.elf.SHT_NULL,
4606+ size: std.elf.Word = 0,
4607+ flags: std.elf.SHF = .{},
4608+ addralign: std.mem.Alignment = .@"1",
4609+ entsize: std.elf.Word = 0,
4610+}) !Symbol.Index {
4611+ const gpa = elf.base.comp.gpa;
4612+ const target_endian = elf.endian();
4613+ try elf.nodes.ensureUnusedCapacity(gpa, 1);
4614+ try elf.symtab.ensureUnusedCapacity(gpa, 1);
4615+
4616+ const shstrtab_entry = try elf.string(.shstrtab, opts.name);
4617+ const shndx, const shdr_size = shndx: switch (elf.ehdrPtr()) {
4618+ inline else => |ehdr| {
4619+ const shentsize = std.mem.toNative(@TypeOf(ehdr.shentsize), ehdr.shentsize, target_endian);
4620+ const shndx = std.mem.toNative(@TypeOf(ehdr.shnum), ehdr.shnum, target_endian);
4621+ const shnum = shndx + 1;
4622+ ehdr.shnum = std.mem.nativeTo(@TypeOf(ehdr.shnum), shnum, target_endian);
4623+ break :shndx .{ shndx, shentsize * shnum };
4624+ },
4625+ };
4626+ try Node.known.shdr.resize(&elf.mf, gpa, shdr_size);
4627+ const ni = try elf.mf.addLastChildNode(gpa, segment_ni, .{
4628+ .alignment = opts.addralign,
4629+ .size = opts.size,
4630+ .moved = true,
4631+ });
4632+ const si = try elf.addSymbolAssumeCapacity();
4633+ elf.nodes.appendAssumeCapacity(.{ .section = si });
4634+ si.get(elf).ni = ni;
4635+ try si.init(elf, .{
4636+ .name = opts.name,
4637+ .size = opts.size,
4638+ .type = .SECTION,
4639+ .shndx = shndx,
4640+ });
4641+ switch (elf.shdrSlice()) {
4642+ inline else => |shdr| {
4643+ const sh = &shdr[shndx];
4644+ sh.* = .{
4645+ .name = shstrtab_entry,
4646+ .type = opts.type,
4647+ .flags = .{ .shf = opts.flags },
4648+ .addr = 0,
4649+ .offset = 0,
4650+ .size = opts.size,
4651+ .link = 0,
4652+ .info = 0,
4653+ .addralign = @intCast(opts.addralign.toByteUnits()),
4654+ .entsize = opts.entsize,
4655+ };
4656+ if (target_endian != native_endian) std.mem.byteSwapAllFields(@TypeOf(sh.*), sh);
4657+ },
4658+ }
4659+ return si;
4660+}
4661+
4662+fn renameSection(elf: *Elf, si: Symbol.Index, name: []const u8) !void {
4663+ const strtab_entry = try elf.string(.strtab, name);
4664+ const shstrtab_entry = try elf.string(.shstrtab, name);
4665+ const target_endian = elf.endian();
4666+ switch (elf.shdrSlice()) {
4667+ inline else => |shdr, class| {
4668+ const sym = @field(elf.symPtr(si), @tagName(class));
4669+ sym.name = std.mem.nativeTo(@TypeOf(sym.name), strtab_entry, target_endian);
4670+ const shndx = std.mem.toNative(@TypeOf(sym.shndx), sym.shndx, target_endian);
4671+ const sh = &shdr[shndx];
4672+ sh.name = std.mem.nativeTo(@TypeOf(sh.name), shstrtab_entry, target_endian);
4673+ },
4674+ }
4675+}
4676+
4677+fn linkSections(elf: *Elf, si: Symbol.Index, link_si: Symbol.Index) !void {
4678+ const target_endian = elf.endian();
4679+ switch (elf.shdrSlice()) {
4680+ inline else => |shdr, class| {
4681+ const sym = @field(elf.symPtr(si), @tagName(class));
4682+ const shndx = std.mem.toNative(@TypeOf(sym.shndx), sym.shndx, target_endian);
4683+ shdr[shndx].link = @field(elf.symPtr(link_si), @tagName(class)).shndx;
4684+ },
4685+ }
4686+}
4687+
4688+fn sectionName(elf: *Elf, si: Symbol.Index) [:0]const u8 {
4689+ const target_endian = elf.endian();
4690+ const name = Symbol.Index.shstrtab.node(elf).slice(&elf.mf)[name: switch (elf.shdrSlice()) {
4691+ inline else => |shndx, class| {
4692+ const sym = @field(elf.symPtr(si), @tagName(class));
4693+ const sh = &shndx[std.mem.toNative(@TypeOf(sym.shndx), sym.shndx, target_endian)];
4694+ break :name std.mem.toNative(@TypeOf(sh.name), sh.name, target_endian);
4695+ },
4696+ }..];
4697+ return name[0..std.mem.indexOfScalar(u8, name, 0).? :0];
4698+}
4699+
4700+fn string(elf: *Elf, comptime section: enum { shstrtab, strtab }, key: []const u8) !u32 {
4701+ if (key.len == 0) return 0;
4702+ return @field(elf, @tagName(section)).get(
4703+ elf.base.comp.gpa,
4704+ &elf.mf,
4705+ @field(Symbol.Index, @tagName(section)).node(elf),
4706+ key,
4707+ );
4708+}
4709+
4710+pub fn addReloc(
4711+ elf: *Elf,
4712+ loc_si: Symbol.Index,
4713+ offset: u64,
4714+ target_si: Symbol.Index,
4715+ addend: i64,
4716+ @"type": Reloc.Type,
4717+) !void {
4718+ const gpa = elf.base.comp.gpa;
4719+ const target = target_si.get(elf);
4720+ const ri: link.File.Elf2.Reloc.Index = @enumFromInt(elf.relocs.items.len);
4721+ (try elf.relocs.addOne(gpa)).* = .{
4722+ .type = @"type",
4723+ .prev = .none,
4724+ .next = target.target_relocs,
4725+ .loc = loc_si,
4726+ .target = target_si,
4727+ .unused = 0,
4728+ .offset = offset,
4729+ .addend = addend,
4730+ };
4731+ switch (target.target_relocs) {
4732+ .none => {},
4733+ else => |target_ri| target_ri.get(elf).prev = ri,
4734+ }
4735+ target.target_relocs = ri;
4736+}
4737+
4738+pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) void {
4739+ _ = elf;
4740+ _ = prog_node;
4741+}
4742+
4743+pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
4744+ elf.updateNavInner(pt, nav_index) catch |err| switch (err) {
4745+ error.OutOfMemory,
4746+ error.Overflow,
4747+ error.RelocationNotByteAligned,
4748+ => |e| return e,
4749+ else => |e| return elf.base.cgFail(nav_index, "linker failed to update variable: {t}", .{e}),
4750+ };
4751+}
4752+fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
4753+ const comp = elf.base.comp;
4754+ const zcu = pt.zcu;
4755+ const gpa = zcu.gpa;
4756+ const ip = &zcu.intern_pool;
4757+
4758+ const nav = ip.getNav(nav_index);
4759+ const nav_val = nav.status.fully_resolved.val;
4760+ const nav_init, const is_threadlocal = switch (ip.indexToKey(nav_val)) {
4761+ else => .{ nav_val, false },
4762+ .variable => |variable| .{ variable.init, variable.is_threadlocal },
4763+ .@"extern" => return,
4764+ .func => .{ .none, false },
4765+ };
4766+ if (nav_init == .none or !Type.fromInterned(ip.typeOf(nav_init)).hasRuntimeBits(zcu)) return;
4767+
4768+ const si = try elf.navSymbol(zcu, nav_index);
4769+ const ni = ni: {
4770+ const sym = si.get(elf);
4771+ switch (sym.ni) {
4772+ .none => {
4773+ try elf.nodes.ensureUnusedCapacity(gpa, 1);
4774+ const sec_si: Symbol.Index =
4775+ if (is_threadlocal and comp.config.any_non_single_threaded) .tdata else .data;
4776+ const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{
4777+ .alignment = pt.navAlignment(nav_index).toStdMem(),
4778+ .moved = true,
4779+ });
4780+ elf.nodes.appendAssumeCapacity(.{ .nav = nav_index });
4781+ sym.ni = ni;
4782+ switch (elf.symPtr(si)) {
4783+ inline else => |sym_ptr, class| sym_ptr.shndx =
4784+ @field(elf.symPtr(sec_si), @tagName(class)).shndx,
4785+ }
4786+ },
4787+ else => si.deleteLocationRelocs(elf),
4788+ }
4789+ assert(sym.loc_relocs == .none);
4790+ sym.loc_relocs = @enumFromInt(elf.relocs.items.len);
4791+ break :ni sym.ni;
4792+ };
4793+
4794+ const size = size: {
4795+ var nw: MappedFile.Node.Writer = undefined;
4796+ ni.writer(&elf.mf, gpa, &nw);
4797+ defer nw.deinit();
4798+ codegen.generateSymbol(
4799+ &elf.base,
4800+ pt,
4801+ zcu.navSrcLoc(nav_index),
4802+ .fromInterned(nav_init),
4803+ &nw.interface,
4804+ .{ .atom_index = @intFromEnum(si) },
4805+ ) catch |err| switch (err) {
4806+ error.WriteFailed => return error.OutOfMemory,
4807+ else => |e| return e,
4808+ };
4809+ break :size nw.interface.end;
4810+ };
4811+
4812+ const target_endian = elf.endian();
4813+ switch (elf.symPtr(si)) {
4814+ inline else => |sym| sym.size =
4815+ std.mem.nativeTo(@TypeOf(sym.size), @intCast(size), target_endian),
4816+ }
4817+ si.applyLocationRelocs(elf);
4818+}
4819+
4820+pub fn lowerUav(
4821+ elf: *Elf,
4822+ pt: Zcu.PerThread,
4823+ uav_val: InternPool.Index,
4824+ uav_align: InternPool.Alignment,
4825+ src_loc: Zcu.LazySrcLoc,
4826+) !codegen.SymbolResult {
4827+ const zcu = pt.zcu;
4828+ const gpa = zcu.gpa;
4829+
4830+ try elf.pending_uavs.ensureUnusedCapacity(gpa, 1);
4831+ const si = elf.uavSymbol(uav_val) catch |err| switch (err) {
4832+ error.OutOfMemory => return error.OutOfMemory,
4833+ else => |e| return .{ .fail = try Zcu.ErrorMsg.create(
4834+ gpa,
4835+ src_loc,
4836+ "linker failed to update constant: {s}",
4837+ .{@errorName(e)},
4838+ ) },
4839+ };
4840+ if (switch (si.get(elf).ni) {
4841+ .none => true,
4842+ else => |ni| uav_align.toStdMem().order(ni.alignment(&elf.mf)).compare(.gt),
4843+ }) {
4844+ const gop = elf.pending_uavs.getOrPutAssumeCapacity(uav_val);
4845+ if (gop.found_existing) {
4846+ gop.value_ptr.alignment = gop.value_ptr.alignment.max(uav_align);
4847+ } else {
4848+ gop.value_ptr.* = .{
4849+ .alignment = uav_align,
4850+ .src_loc = src_loc,
4851+ };
4852+ elf.base.comp.link_uav_prog_node.increaseEstimatedTotalItems(1);
4853+ }
4854+ }
4855+ return .{ .sym_index = @intFromEnum(si) };
4856+}
4857+
4858+pub fn updateFunc(
4859+ elf: *Elf,
4860+ pt: Zcu.PerThread,
4861+ func_index: InternPool.Index,
4862+ mir: *const codegen.AnyMir,
4863+) !void {
4864+ elf.updateFuncInner(pt, func_index, mir) catch |err| switch (err) {
4865+ error.OutOfMemory,
4866+ error.Overflow,
4867+ error.RelocationNotByteAligned,
4868+ error.CodegenFail,
4869+ => |e| return e,
4870+ else => |e| return elf.base.cgFail(
4871+ pt.zcu.funcInfo(func_index).owner_nav,
4872+ "linker failed to update function: {s}",
4873+ .{@errorName(e)},
4874+ ),
4875+ };
4876+}
4877+fn updateFuncInner(
4878+ elf: *Elf,
4879+ pt: Zcu.PerThread,
4880+ func_index: InternPool.Index,
4881+ mir: *const codegen.AnyMir,
4882+) !void {
4883+ const zcu = pt.zcu;
4884+ const gpa = zcu.gpa;
4885+ const ip = &zcu.intern_pool;
4886+ const func = zcu.funcInfo(func_index);
4887+ const nav = ip.getNav(func.owner_nav);
4888+
4889+ const si = try elf.navSymbol(zcu, func.owner_nav);
4890+ log.debug("updateFunc({f}) = {d}", .{ nav.fqn.fmt(ip), si });
4891+ const ni = ni: {
4892+ const sym = si.get(elf);
4893+ switch (sym.ni) {
4894+ .none => {
4895+ try elf.nodes.ensureUnusedCapacity(gpa, 1);
4896+ const mod = zcu.navFileScope(func.owner_nav).mod.?;
4897+ const target = &mod.resolved_target.result;
4898+ const ni = try elf.mf.addLastChildNode(gpa, Symbol.Index.text.node(elf), .{
4899+ .alignment = switch (nav.status.fully_resolved.alignment) {
4900+ .none => switch (mod.optimize_mode) {
4901+ .Debug,
4902+ .ReleaseSafe,
4903+ .ReleaseFast,
4904+ => target_util.defaultFunctionAlignment(target),
4905+ .ReleaseSmall => target_util.minFunctionAlignment(target),
4906+ },
4907+ else => |a| a.maxStrict(target_util.minFunctionAlignment(target)),
4908+ }.toStdMem(),
4909+ .moved = true,
4910+ });
4911+ elf.nodes.appendAssumeCapacity(.{ .nav = func.owner_nav });
4912+ sym.ni = ni;
4913+ switch (elf.symPtr(si)) {
4914+ inline else => |sym_ptr, class| sym_ptr.shndx =
4915+ @field(elf.symPtr(.text), @tagName(class)).shndx,
4916+ }
4917+ },
4918+ else => si.deleteLocationRelocs(elf),
4919+ }
4920+ assert(sym.loc_relocs == .none);
4921+ sym.loc_relocs = @enumFromInt(elf.relocs.items.len);
4922+ break :ni sym.ni;
4923+ };
4924+
4925+ const size = size: {
4926+ var nw: MappedFile.Node.Writer = undefined;
4927+ ni.writer(&elf.mf, gpa, &nw);
4928+ defer nw.deinit();
4929+ codegen.emitFunction(
4930+ &elf.base,
4931+ pt,
4932+ zcu.navSrcLoc(func.owner_nav),
4933+ func_index,
4934+ @intFromEnum(si),
4935+ mir,
4936+ &nw.interface,
4937+ .none,
4938+ ) catch |err| switch (err) {
4939+ error.WriteFailed => return nw.err.?,
4940+ else => |e| return e,
4941+ };
4942+ break :size nw.interface.end;
4943+ };
4944+
4945+ const target_endian = elf.endian();
4946+ switch (elf.symPtr(si)) {
4947+ inline else => |sym| sym.size =
4948+ std.mem.nativeTo(@TypeOf(sym.size), @intCast(size), target_endian),
4949+ }
4950+ si.applyLocationRelocs(elf);
4951+}
4952+
4953+pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) !void {
4954+ const si = elf.lazy.getPtr(.const_data).map.get(.anyerror_type) orelse return;
4955+ elf.flushLazy(pt, .{ .kind = .const_data, .ty = .anyerror_type }, si) catch |err| switch (err) {
4956+ error.OutOfMemory => return error.OutOfMemory,
4957+ error.CodegenFail => return error.LinkFailure,
4958+ else => |e| return elf.base.comp.link_diags.fail("updateErrorData failed {t}", .{e}),
4959+ };
4960+}
4961+
4962+pub fn flush(
4963+ elf: *Elf,
4964+ arena: std.mem.Allocator,
4965+ tid: Zcu.PerThread.Id,
4966+ prog_node: std.Progress.Node,
4967+) !void {
4968+ _ = arena;
4969+ _ = prog_node;
4970+ while (try elf.idle(tid)) {}
4971+}
4972+
4973+pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool {
4974+ const comp = elf.base.comp;
4975+ task: {
4976+ while (elf.pending_uavs.pop()) |pending_uav| {
4977+ const sub_prog_node =
4978+ elf.idleProgNode(
4979+ tid,
4980+ comp.link_uav_prog_node,
4981+ .{ .uav = pending_uav.key },
4982+ );
4983+ defer sub_prog_node.end();
4984+ break :task elf.flushUav(
4985+ .{ .zcu = elf.base.comp.zcu.?, .tid = tid },
4986+ pending_uav.key,
4987+ pending_uav.value.alignment,
4988+ pending_uav.value.src_loc,
4989+ ) catch |err| switch (err) {
4990+ error.OutOfMemory => return error.OutOfMemory,
4991+ else => |e| return elf.base.comp.link_diags.fail(
4992+ "linker failed to lower constant: {t}",
4993+ .{e},
4994+ ),
4995+ };
4996+ }
4997+ var lazy_it = elf.lazy.iterator();
4998+ while (lazy_it.next()) |lazy| for (
4999+ lazy.value.map.keys()[lazy.value.pending_index..],
5000+ lazy.value.map.values()[lazy.value.pending_index..],
5001+ ) |ty, si| {
5002+ lazy.value.pending_index += 1;
5003+ const pt: Zcu.PerThread = .{ .zcu = elf.base.comp.zcu.?, .tid = tid };
5004+ const kind = switch (lazy.key) {
5005+ .code => "code",
5006+ .const_data => "data",
5007+ };
5008+ var name: [std.Progress.Node.max_name_len]u8 = undefined;
5009+ const sub_prog_node = comp.link_lazy_prog_node.start(
5010+ std.fmt.bufPrint(&name, "lazy {s} for {f}", .{
5011+ kind,
5012+ Type.fromInterned(ty).fmt(pt),
5013+ }) catch &name,
5014+ 0,
5015+ );
5016+ defer sub_prog_node.end();
5017+ break :task elf.flushLazy(pt, .{
5018+ .kind = lazy.key,
5019+ .ty = ty,
5020+ }, si) catch |err| switch (err) {
5021+ error.OutOfMemory => return error.OutOfMemory,
5022+ else => |e| return elf.base.comp.link_diags.fail(
5023+ "linker failed to lower lazy {s}: {t}",
5024+ .{ kind, e },
5025+ ),
5026+ };
5027+ };
5028+ while (elf.mf.updates.pop()) |ni| {
5029+ const clean_moved = ni.cleanMoved(&elf.mf);
5030+ const clean_resized = ni.cleanResized(&elf.mf);
5031+ if (clean_moved or clean_resized) {
5032+ const sub_prog_node = elf.idleProgNode(tid, elf.mf.update_prog_node, elf.getNode(ni));
5033+ defer sub_prog_node.end();
5034+ if (clean_moved) try elf.flushMoved(ni);
5035+ if (clean_resized) try elf.flushResized(ni);
5036+ break :task;
5037+ } else elf.mf.update_prog_node.completeOne();
5038+ }
5039+ }
5040+ if (elf.pending_uavs.count() > 0) return true;
5041+ for (&elf.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true;
5042+ if (elf.mf.updates.items.len > 0) return true;
5043+ return false;
5044+}
5045+
5046+fn idleProgNode(
5047+ elf: *Elf,
5048+ tid: Zcu.PerThread.Id,
5049+ prog_node: std.Progress.Node,
5050+ node: Node,
5051+) std.Progress.Node {
5052+ var name: [std.Progress.Node.max_name_len]u8 = undefined;
5053+ return prog_node.start(name: switch (node) {
5054+ else => |tag| @tagName(tag),
5055+ .section => |si| elf.sectionName(si),
5056+ .nav => |nav| {
5057+ const ip = &elf.base.comp.zcu.?.intern_pool;
5058+ break :name ip.getNav(nav).fqn.toSlice(ip);
5059+ },
5060+ .uav => |uav| std.fmt.bufPrint(&name, "{f}", .{
5061+ Value.fromInterned(uav).fmtValue(.{ .zcu = elf.base.comp.zcu.?, .tid = tid }),
5062+ }) catch &name,
5063+ }, 0);
5064+}
5065+
5066+fn flushUav(
5067+ elf: *Elf,
5068+ pt: Zcu.PerThread,
5069+ uav_val: InternPool.Index,
5070+ uav_align: InternPool.Alignment,
5071+ src_loc: Zcu.LazySrcLoc,
5072+) !void {
5073+ const zcu = pt.zcu;
5074+ const gpa = zcu.gpa;
5075+
5076+ const si = try elf.uavSymbol(uav_val);
5077+ const ni = ni: {
5078+ const sym = si.get(elf);
5079+ switch (sym.ni) {
5080+ .none => {
5081+ try elf.nodes.ensureUnusedCapacity(gpa, 1);
5082+ const ni = try elf.mf.addLastChildNode(gpa, Symbol.Index.data.node(elf), .{
5083+ .alignment = uav_align.toStdMem(),
5084+ .moved = true,
5085+ });
5086+ elf.nodes.appendAssumeCapacity(.{ .uav = uav_val });
5087+ sym.ni = ni;
5088+ switch (elf.symPtr(si)) {
5089+ inline else => |sym_ptr, class| sym_ptr.shndx =
5090+ @field(elf.symPtr(.data), @tagName(class)).shndx,
5091+ }
5092+ },
5093+ else => {
5094+ if (sym.ni.alignment(&elf.mf).order(uav_align.toStdMem()).compare(.gte)) return;
5095+ si.deleteLocationRelocs(elf);
5096+ },
5097+ }
5098+ assert(sym.loc_relocs == .none);
5099+ sym.loc_relocs = @enumFromInt(elf.relocs.items.len);
5100+ break :ni sym.ni;
5101+ };
5102+
5103+ const size = size: {
5104+ var nw: MappedFile.Node.Writer = undefined;
5105+ ni.writer(&elf.mf, gpa, &nw);
5106+ defer nw.deinit();
5107+ codegen.generateSymbol(
5108+ &elf.base,
5109+ pt,
5110+ src_loc,
5111+ .fromInterned(uav_val),
5112+ &nw.interface,
5113+ .{ .atom_index = @intFromEnum(si) },
5114+ ) catch |err| switch (err) {
5115+ error.WriteFailed => return error.OutOfMemory,
5116+ else => |e| return e,
5117+ };
5118+ break :size nw.interface.end;
5119+ };
5120+
5121+ const target_endian = elf.endian();
5122+ switch (elf.symPtr(si)) {
5123+ inline else => |sym| sym.size =
5124+ std.mem.nativeTo(@TypeOf(sym.size), @intCast(size), target_endian),
5125+ }
5126+ si.applyLocationRelocs(elf);
5127+}
5128+
5129+fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol, si: Symbol.Index) !void {
5130+ const zcu = pt.zcu;
5131+ const gpa = zcu.gpa;
5132+
5133+ const ni = ni: {
5134+ const sym = si.get(elf);
5135+ switch (sym.ni) {
5136+ .none => {
5137+ try elf.nodes.ensureUnusedCapacity(gpa, 1);
5138+ const sec_si: Symbol.Index = switch (lazy.kind) {
5139+ .code => .text,
5140+ .const_data => .rodata,
5141+ };
5142+ const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{ .moved = true });
5143+ elf.nodes.appendAssumeCapacity(switch (lazy.kind) {
5144+ .code => .{ .lazy_code = lazy.ty },
5145+ .const_data => .{ .lazy_const_data = lazy.ty },
5146+ });
5147+ sym.ni = ni;
5148+ switch (elf.symPtr(si)) {
5149+ inline else => |sym_ptr, class| sym_ptr.shndx =
5150+ @field(elf.symPtr(sec_si), @tagName(class)).shndx,
5151+ }
5152+ },
5153+ else => si.deleteLocationRelocs(elf),
5154+ }
5155+ assert(sym.loc_relocs == .none);
5156+ sym.loc_relocs = @enumFromInt(elf.relocs.items.len);
5157+ break :ni sym.ni;
5158+ };
5159+
5160+ const size = size: {
5161+ var required_alignment: InternPool.Alignment = .none;
5162+ var nw: MappedFile.Node.Writer = undefined;
5163+ ni.writer(&elf.mf, gpa, &nw);
5164+ defer nw.deinit();
5165+ try codegen.generateLazySymbol(
5166+ &elf.base,
5167+ pt,
5168+ Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded,
5169+ lazy,
5170+ &required_alignment,
5171+ &nw.interface,
5172+ .none,
5173+ .{ .atom_index = @intFromEnum(si) },
5174+ );
5175+ break :size nw.interface.end;
5176+ };
5177+
5178+ const target_endian = elf.endian();
5179+ switch (elf.symPtr(si)) {
5180+ inline else => |sym| sym.size =
5181+ std.mem.nativeTo(@TypeOf(sym.size), @intCast(size), target_endian),
5182+ }
5183+ si.applyLocationRelocs(elf);
5184+}
5185+
5186+fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
5187+ const target_endian = elf.endian();
5188+ const file_offset = ni.fileLocation(&elf.mf, false).offset;
5189+ const node = elf.getNode(ni);
5190+ switch (node) {
5191+ else => |tag| @panic(@tagName(tag)),
5192+ .ehdr => assert(file_offset == 0),
5193+ .shdr => switch (elf.ehdrPtr()) {
5194+ inline else => |ehdr| ehdr.shoff =
5195+ std.mem.nativeTo(@TypeOf(ehdr.shoff), @intCast(file_offset), target_endian),
5196+ },
5197+ .segment => |phndx| switch (elf.phdrSlice()) {
5198+ inline else => |phdr, class| {
5199+ const ph = &phdr[phndx];
5200+ switch (std.mem.toNative(@TypeOf(ph.type), ph.type, target_endian)) {
5201+ else => unreachable,
5202+ std.elf.PT_NULL, std.elf.PT_LOAD, std.elf.PT_DYNAMIC, std.elf.PT_INTERP => {},
5203+ std.elf.PT_PHDR => {
5204+ const ehdr = @field(elf.ehdrPtr(), @tagName(class));
5205+ ehdr.phoff =
5206+ std.mem.nativeTo(@TypeOf(ehdr.phoff), @intCast(file_offset), target_endian);
5207+ },
5208+ std.elf.PT_TLS => {},
5209+ }
5210+ ph.offset = std.mem.nativeTo(@TypeOf(ph.offset), @intCast(file_offset), target_endian);
5211+ ph.vaddr = std.mem.nativeTo(
5212+ @TypeOf(ph.vaddr),
5213+ @intCast(elf.baseAddr() + file_offset),
5214+ target_endian,
5215+ );
5216+ ph.paddr = ph.vaddr;
5217+ },
5218+ },
5219+ .section => |si| switch (elf.shdrSlice()) {
5220+ inline else => |shdr, class| {
5221+ const sym = @field(elf.symPtr(si), @tagName(class));
5222+ const shndx = std.mem.toNative(@TypeOf(sym.shndx), sym.shndx, target_endian);
5223+ const sh = &shdr[shndx];
5224+ const flags: @TypeOf(sh.flags) = @bitCast(std.mem.toNative(
5225+ @typeInfo(@TypeOf(sh.flags)).@"struct".backing_integer.?,
5226+ @bitCast(sh.flags),
5227+ target_endian,
5228+ ));
5229+ if (flags.shf.ALLOC) {
5230+ sym.value = std.mem.nativeTo(
5231+ @TypeOf(sym.value),
5232+ @intCast(elf.baseAddr() + file_offset),
5233+ target_endian,
5234+ );
5235+ sh.addr = sym.value;
5236+ }
5237+ sh.offset = std.mem.nativeTo(@TypeOf(sh.offset), @intCast(file_offset), target_endian);
5238+ },
5239+ },
5240+ .nav, .uav, .lazy_code, .lazy_const_data => {
5241+ const si = switch (node) {
5242+ else => unreachable,
5243+ .nav => |nav| elf.navs.get(nav),
5244+ .uav => |uav| elf.uavs.get(uav),
5245+ .lazy_code => |ty| elf.lazy.getPtr(.code).map.get(ty),
5246+ .lazy_const_data => |ty| elf.lazy.getPtr(.const_data).map.get(ty),
5247+ }.?;
5248+ switch (elf.shdrSlice()) {
5249+ inline else => |shdr, class| {
5250+ const sym = @field(elf.symPtr(si), @tagName(class));
5251+ const sh = &shdr[std.mem.toNative(@TypeOf(sym.shndx), sym.shndx, target_endian)];
5252+ const flags: @TypeOf(sh.flags) = @bitCast(std.mem.toNative(
5253+ @typeInfo(@TypeOf(sh.flags)).@"struct".backing_integer.?,
5254+ @bitCast(sh.flags),
5255+ target_endian,
5256+ ));
5257+ const sh_addr = if (flags.shf.TLS)
5258+ 0
5259+ else
5260+ std.mem.toNative(@TypeOf(sh.addr), sh.addr, target_endian);
5261+ const sh_offset = std.mem.toNative(@TypeOf(sh.offset), sh.offset, target_endian);
5262+ sym.value = std.mem.nativeTo(
5263+ @TypeOf(sym.value),
5264+ @intCast(file_offset - sh_offset + sh_addr),
5265+ target_endian,
5266+ );
5267+ if (si == elf.entry_hack) @field(elf.ehdrPtr(), @tagName(class)).entry = sym.value;
5268+ },
5269+ }
5270+ si.applyLocationRelocs(elf);
5271+ si.applyTargetRelocs(elf);
5272+ },
5273+ }
5274+ try ni.childrenMoved(elf.base.comp.gpa, &elf.mf);
5275+}
5276+
5277+fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void {
5278+ const target_endian = elf.endian();
5279+ _, const size = ni.location(&elf.mf).resolve(&elf.mf);
5280+ const node = elf.getNode(ni);
5281+ switch (node) {
5282+ else => |tag| @panic(@tagName(tag)),
5283+ .file, .shdr => {},
5284+ .segment => |phndx| switch (elf.phdrSlice()) {
5285+ inline else => |phdr| {
5286+ const ph = &phdr[phndx];
5287+ ph.filesz = std.mem.nativeTo(@TypeOf(ph.filesz), @intCast(size), target_endian);
5288+ ph.memsz = ph.filesz;
5289+ switch (std.mem.toNative(@TypeOf(ph.type), ph.type, target_endian)) {
5290+ else => unreachable,
5291+ std.elf.PT_NULL => {
5292+ if (size > 0) ph.type = std.mem.nativeTo(
5293+ @TypeOf(ph.type),
5294+ std.elf.PT_LOAD,
5295+ target_endian,
5296+ );
5297+ },
5298+ std.elf.PT_LOAD => {
5299+ if (size == 0) ph.type = std.mem.nativeTo(
5300+ @TypeOf(ph.type),
5301+ std.elf.PT_NULL,
5302+ target_endian,
5303+ );
5304+ },
5305+ std.elf.PT_DYNAMIC, std.elf.PT_INTERP, std.elf.PT_PHDR => {},
5306+ std.elf.PT_TLS => try ni.childrenMoved(elf.base.comp.gpa, &elf.mf),
5307+ }
5308+ },
5309+ },
5310+ .section => |si| switch (elf.shdrSlice()) {
5311+ inline else => |shdr, class| {
5312+ const sym = @field(elf.symPtr(si), @tagName(class));
5313+ const shndx = std.mem.toNative(@TypeOf(sym.shndx), sym.shndx, target_endian);
5314+ const sh = &shdr[shndx];
5315+ switch (std.mem.toNative(@TypeOf(sh.type), sh.type, target_endian)) {
5316+ else => unreachable,
5317+ std.elf.SHT_NULL => {
5318+ if (size > 0) sh.type = std.mem.nativeTo(
5319+ @TypeOf(sh.type),
5320+ std.elf.SHT_PROGBITS,
5321+ target_endian,
5322+ );
5323+ },
5324+ std.elf.SHT_PROGBITS => {
5325+ if (size == 0) sh.type = std.mem.nativeTo(
5326+ @TypeOf(sh.type),
5327+ std.elf.SHT_NULL,
5328+ target_endian,
5329+ );
5330+ },
5331+ std.elf.SHT_SYMTAB => sh.info = std.mem.nativeTo(
5332+ @TypeOf(sh.info),
5333+ @intCast(@divExact(
5334+ size,
5335+ std.mem.toNative(@TypeOf(sh.entsize), sh.entsize, target_endian),
5336+ )),
5337+ target_endian,
5338+ ),
5339+ std.elf.SHT_STRTAB => {},
5340+ }
5341+ sh.size = std.mem.nativeTo(@TypeOf(sh.size), @intCast(size), target_endian);
5342+ },
5343+ },
5344+ .nav, .uav, .lazy_code, .lazy_const_data => {},
5345+ }
5346+}
5347+
5348+pub fn updateExports(
5349+ elf: *Elf,
5350+ pt: Zcu.PerThread,
5351+ exported: Zcu.Exported,
5352+ export_indices: []const Zcu.Export.Index,
5353+) !void {
5354+ return elf.updateExportsInner(pt, exported, export_indices) catch |err| switch (err) {
5355+ error.OutOfMemory => error.OutOfMemory,
5356+ error.LinkFailure => error.AnalysisFail,
5357+ else => |e| switch (elf.base.comp.link_diags.fail(
5358+ "linker failed to update exports: {t}",
5359+ .{e},
5360+ )) {
5361+ error.LinkFailure => return error.AnalysisFail,
5362+ },
5363+ };
5364+}
5365+fn updateExportsInner(
5366+ elf: *Elf,
5367+ pt: Zcu.PerThread,
5368+ exported: Zcu.Exported,
5369+ export_indices: []const Zcu.Export.Index,
5370+) !void {
5371+ const zcu = pt.zcu;
5372+ const gpa = zcu.gpa;
5373+ const ip = &zcu.intern_pool;
5374+
5375+ switch (exported) {
5376+ .nav => |nav| log.debug("updateExports({f})", .{ip.getNav(nav).fqn.fmt(ip)}),
5377+ .uav => |uav| log.debug("updateExports(@as({f}, {f}))", .{
5378+ Type.fromInterned(ip.typeOf(uav)).fmt(pt),
5379+ Value.fromInterned(uav).fmtValue(pt),
5380+ }),
5381+ }
5382+ try elf.symtab.ensureUnusedCapacity(gpa, export_indices.len);
5383+ const exported_si: Symbol.Index, const @"type": std.elf.STT = switch (exported) {
5384+ .nav => |nav| .{
5385+ try elf.navSymbol(zcu, nav),
5386+ navType(ip, ip.getNav(nav).status, elf.base.comp.config.any_non_single_threaded),
5387+ },
5388+ .uav => |uav| .{ @enumFromInt(switch (try elf.lowerUav(
5389+ pt,
5390+ uav,
5391+ Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu),
5392+ export_indices[0].ptr(zcu).src,
5393+ )) {
5394+ .sym_index => |si| si,
5395+ .fail => |em| {
5396+ defer em.destroy(gpa);
5397+ return elf.base.comp.link_diags.fail("{s}", .{em.msg});
5398+ },
5399+ }), .OBJECT },
5400+ };
5401+ while (try elf.idle(pt.tid)) {}
5402+ const exported_ni = exported_si.node(elf);
5403+ const value, const size, const shndx = switch (elf.symPtr(exported_si)) {
5404+ inline else => |exported_sym| .{ exported_sym.value, exported_sym.size, exported_sym.shndx },
5405+ };
5406+ for (export_indices) |export_index| {
5407+ const @"export" = export_index.ptr(zcu);
5408+ const name = @"export".opts.name.toSlice(ip);
5409+ const export_si = try elf.globalSymbol(.{
5410+ .name = name,
5411+ .type = @"type",
5412+ .bind = switch (@"export".opts.linkage) {
5413+ .internal => .LOCAL,
5414+ .strong => .GLOBAL,
5415+ .weak => .WEAK,
5416+ .link_once => return error.LinkOnceUnsupported,
5417+ },
5418+ .visibility = switch (@"export".opts.visibility) {
5419+ .default => .DEFAULT,
5420+ .hidden => .HIDDEN,
5421+ .protected => .PROTECTED,
5422+ },
5423+ });
5424+ export_si.get(elf).ni = exported_ni;
5425+ switch (elf.symPtr(export_si)) {
5426+ inline else => |export_sym| {
5427+ export_sym.value = @intCast(value);
5428+ export_sym.size = @intCast(size);
5429+ export_sym.shndx = shndx;
5430+ },
5431+ }
5432+ export_si.applyTargetRelocs(elf);
5433+ if (std.mem.eql(u8, name, "_start")) {
5434+ elf.entry_hack = exported_si;
5435+ switch (elf.ehdrPtr()) {
5436+ inline else => |ehdr| ehdr.entry = @intCast(value),
5437+ }
5438+ }
5439+ }
5440+}
5441+
5442+pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerminatedString) void {
5443+ _ = elf;
5444+ _ = exported;
5445+ _ = name;
5446+}
5447+
5448+pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) void {
5449+ const w = std.debug.lockStderrWriter(&.{});
5450+ defer std.debug.unlockStderrWriter();
5451+ elf.printNode(tid, w, .root, 0) catch {};
5452+}
5453+
5454+pub fn printNode(
5455+ elf: *Elf,
5456+ tid: Zcu.PerThread.Id,
5457+ w: *std.Io.Writer,
5458+ ni: MappedFile.Node.Index,
5459+ indent: usize,
5460+) !void {
5461+ const node = elf.getNode(ni);
5462+ const mf_node = &elf.mf.nodes.items[@intFromEnum(ni)];
5463+ const off, const size = mf_node.location().resolve(&elf.mf);
5464+ try w.splatByteAll(' ', indent);
5465+ try w.writeAll(@tagName(node));
5466+ switch (node) {
5467+ else => {},
5468+ .section => |si| try w.print("({s})", .{elf.sectionName(si)}),
5469+ .nav => |nav_index| {
5470+ const zcu = elf.base.comp.zcu.?;
5471+ const ip = &zcu.intern_pool;
5472+ const nav = ip.getNav(nav_index);
5473+ try w.print("({f}, {f})", .{
5474+ Type.fromInterned(nav.typeOf(ip)).fmt(.{ .zcu = zcu, .tid = tid }),
5475+ nav.fqn.fmt(ip),
5476+ });
5477+ },
5478+ .uav => |uav| {
5479+ const zcu = elf.base.comp.zcu.?;
5480+ const val: Value = .fromInterned(uav);
5481+ try w.print("({f}, {f})", .{
5482+ val.typeOf(zcu).fmt(.{ .zcu = zcu, .tid = tid }),
5483+ val.fmtValue(.{ .zcu = zcu, .tid = tid }),
5484+ });
5485+ },
5486+ }
5487+ try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x}{s}{s}{s}{s}\n", .{
5488+ @intFromEnum(ni),
5489+ off,
5490+ size,
5491+ mf_node.flags.alignment.toByteUnits(),
5492+ if (mf_node.flags.fixed) " fixed" else "",
5493+ if (mf_node.flags.moved) " moved" else "",
5494+ if (mf_node.flags.resized) " resized" else "",
5495+ if (mf_node.flags.has_content) " has_content" else "",
5496+ });
5497+ var child_ni = mf_node.first;
5498+ switch (child_ni) {
5499+ .none => {
5500+ const file_loc = ni.fileLocation(&elf.mf, false);
5501+ if (file_loc.size == 0) return;
5502+ var address = file_loc.offset;
5503+ const line_len = 0x10;
5504+ var line_it = std.mem.window(
5505+ u8,
5506+ elf.mf.contents[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)],
5507+ line_len,
5508+ line_len,
5509+ );
5510+ while (line_it.next()) |line_bytes| : (address += line_len) {
5511+ try w.splatByteAll(' ', indent + 1);
5512+ try w.print("{x:0>8}", .{address});
5513+ for (line_bytes) |byte| try w.print(" {x:0>2}", .{byte});
5514+ try w.writeByte('\n');
5515+ }
5516+ },
5517+ else => while (child_ni != .none) {
5518+ try elf.printNode(tid, w, child_ni, indent + 1);
5519+ child_ni = elf.mf.nodes.items[@intFromEnum(child_ni)].next;
5520+ },
5521+ }
5522+}
5523+
5524+const assert = std.debug.assert;
5525+const builtin = @import("builtin");
5526+const codegen = @import("../codegen.zig");
5527+const Compilation = @import("../Compilation.zig");
5528+const Elf = @This();
5529+const InternPool = @import("../InternPool.zig");
5530+const link = @import("../link.zig");
5531+const log = std.log.scoped(.link);
5532+const MappedFile = @import("MappedFile.zig");
5533+const native_endian = builtin.cpu.arch.endian();
5534+const std = @import("std");
5535+const target_util = @import("../target.zig");
5536+const Type = @import("../Type.zig");
5537+const Value = @import("../Value.zig");
5538+const Zcu = @import("../Zcu.zig");
5539diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig
5540index b1fc6528d5..5a0a71f380 100644
5541--- a/src/link/MachO/ZigObject.zig
5542+++ b/src/link/MachO/ZigObject.zig
5543@@ -784,22 +784,26 @@ pub fn updateFunc(
5544 const sym_index = try self.getOrCreateMetadataForNav(macho_file, func.owner_nav);
5545 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
5546
5547- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
5548- defer code_buffer.deinit(gpa);
5549+ var aw: std.Io.Writer.Allocating = .init(gpa);
5550+ defer aw.deinit();
5551
5552 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
5553 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
5554
5555- try codegen.emitFunction(
5556+ codegen.emitFunction(
5557 &macho_file.base,
5558 pt,
5559 zcu.navSrcLoc(func.owner_nav),
5560 func_index,
5561+ sym_index,
5562 mir,
5563- &code_buffer,
5564+ &aw.writer,
5565 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
5566- );
5567- const code = code_buffer.items;
5568+ ) catch |err| switch (err) {
5569+ error.WriteFailed => return error.OutOfMemory,
5570+ else => |e| return e,
5571+ };
5572+ const code = aw.written();
5573
5574 const sect_index = try self.getNavOutputSection(macho_file, zcu, func.owner_nav, code);
5575 const old_rva, const old_alignment = blk: {
5576@@ -895,21 +899,24 @@ pub fn updateNav(
5577 const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index);
5578 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
5579
5580- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
5581- defer code_buffer.deinit(zcu.gpa);
5582+ var aw: std.Io.Writer.Allocating = .init(zcu.gpa);
5583+ defer aw.deinit();
5584
5585 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
5586 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
5587
5588- try codegen.generateSymbol(
5589+ codegen.generateSymbol(
5590 &macho_file.base,
5591 pt,
5592 zcu.navSrcLoc(nav_index),
5593 Value.fromInterned(nav_init),
5594- &code_buffer,
5595+ &aw.writer,
5596 .{ .atom_index = sym_index },
5597- );
5598- const code = code_buffer.items;
5599+ ) catch |err| switch (err) {
5600+ error.WriteFailed => return error.OutOfMemory,
5601+ else => |e| return e,
5602+ };
5603+ const code = aw.written();
5604
5605 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);
5606 if (isThreadlocal(macho_file, nav_index))
5607@@ -1198,21 +1205,24 @@ fn lowerConst(
5608 ) !codegen.SymbolResult {
5609 const gpa = macho_file.base.comp.gpa;
5610
5611- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
5612- defer code_buffer.deinit(gpa);
5613+ var aw: std.Io.Writer.Allocating = .init(gpa);
5614+ defer aw.deinit();
5615
5616 const name_str = try self.addString(gpa, name);
5617 const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file);
5618
5619- try codegen.generateSymbol(
5620+ codegen.generateSymbol(
5621 &macho_file.base,
5622 pt,
5623 src_loc,
5624 val,
5625- &code_buffer,
5626+ &aw.writer,
5627 .{ .atom_index = sym_index },
5628- );
5629- const code = code_buffer.items;
5630+ ) catch |err| switch (err) {
5631+ error.WriteFailed => return error.OutOfMemory,
5632+ else => |e| return e,
5633+ };
5634+ const code = aw.written();
5635
5636 const sym = &self.symbols.items[sym_index];
5637 sym.out_n_sect = output_section_index;
5638@@ -1349,8 +1359,8 @@ fn updateLazySymbol(
5639 const gpa = zcu.gpa;
5640
5641 var required_alignment: Atom.Alignment = .none;
5642- var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
5643- defer code_buffer.deinit(gpa);
5644+ var aw: std.Io.Writer.Allocating = .init(gpa);
5645+ defer aw.deinit();
5646
5647 const name_str = blk: {
5648 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{
5649@@ -1368,11 +1378,11 @@ fn updateLazySymbol(
5650 src,
5651 lazy_sym,
5652 &required_alignment,
5653- &code_buffer,
5654+ &aw.writer,
5655 .none,
5656 .{ .atom_index = symbol_index },
5657 );
5658- const code = code_buffer.items;
5659+ const code = aw.written();
5660
5661 const output_section_index = switch (lazy_sym.kind) {
5662 .code => macho_file.zig_text_sect_index.?,
5663diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig
5664new file mode 100644
5665index 0000000000..d04a8d533a
5666--- /dev/null
5667+++ b/src/link/MappedFile.zig
5668@@ -0,0 +1,929 @@
5669+file: std.fs.File,
5670+flags: packed struct {
5671+ block_size: std.mem.Alignment,
5672+ copy_file_range_unsupported: bool,
5673+ fallocate_punch_hole_unsupported: bool,
5674+ fallocate_insert_range_unsupported: bool,
5675+},
5676+section: if (is_windows) windows.HANDLE else void,
5677+contents: []align(std.heap.page_size_min) u8,
5678+nodes: std.ArrayList(Node),
5679+free_ni: Node.Index,
5680+large: std.ArrayList(u64),
5681+updates: std.ArrayList(Node.Index),
5682+update_prog_node: std.Progress.Node,
5683+writers: std.SinglyLinkedList,
5684+
5685+pub const Error = std.posix.MMapError ||
5686+ std.posix.MRemapError ||
5687+ std.fs.File.SetEndPosError ||
5688+ std.fs.File.CopyRangeError ||
5689+ error{NotFile};
5690+
5691+pub fn init(file: std.fs.File, gpa: std.mem.Allocator) !MappedFile {
5692+ var mf: MappedFile = .{
5693+ .file = file,
5694+ .flags = undefined,
5695+ .section = if (is_windows) windows.INVALID_HANDLE_VALUE else {},
5696+ .contents = &.{},
5697+ .nodes = .empty,
5698+ .free_ni = .none,
5699+ .large = .empty,
5700+ .updates = .empty,
5701+ .update_prog_node = .none,
5702+ .writers = .{},
5703+ };
5704+ errdefer mf.deinit(gpa);
5705+ const size: u64, const blksize = if (is_windows)
5706+ .{ try windows.GetFileSizeEx(file.handle), 1 }
5707+ else stat: {
5708+ const stat = try std.posix.fstat(mf.file.handle);
5709+ if (!std.posix.S.ISREG(stat.mode)) return error.PathAlreadyExists;
5710+ break :stat .{ @bitCast(stat.size), stat.blksize };
5711+ };
5712+ mf.flags = .{
5713+ .block_size = .fromByteUnits(
5714+ std.math.ceilPowerOfTwoAssert(usize, @max(std.heap.pageSize(), blksize)),
5715+ ),
5716+ .copy_file_range_unsupported = false,
5717+ .fallocate_insert_range_unsupported = false,
5718+ .fallocate_punch_hole_unsupported = false,
5719+ };
5720+ try mf.nodes.ensureUnusedCapacity(gpa, 1);
5721+ assert(try mf.addNode(gpa, .{
5722+ .add_node = .{
5723+ .size = size,
5724+ .fixed = true,
5725+ },
5726+ }) == Node.Index.root);
5727+ try mf.ensureTotalCapacity(@intCast(size));
5728+ return mf;
5729+}
5730+
5731+pub fn deinit(mf: *MappedFile, gpa: std.mem.Allocator) void {
5732+ mf.unmap();
5733+ mf.nodes.deinit(gpa);
5734+ mf.large.deinit(gpa);
5735+ mf.updates.deinit(gpa);
5736+ mf.update_prog_node.end();
5737+ assert(mf.writers.first == null);
5738+ mf.* = undefined;
5739+}
5740+
5741+pub const Node = extern struct {
5742+ parent: Node.Index,
5743+ prev: Node.Index,
5744+ next: Node.Index,
5745+ first: Node.Index,
5746+ last: Node.Index,
5747+ flags: Flags,
5748+ location_payload: Location.Payload,
5749+
5750+ pub const Flags = packed struct(u32) {
5751+ location_tag: Location.Tag,
5752+ alignment: std.mem.Alignment,
5753+ /// Whether this node can be moved.
5754+ fixed: bool,
5755+ /// Whether this node has been moved.
5756+ moved: bool,
5757+ /// Whether this node has been resized.
5758+ resized: bool,
5759+ /// Whether this node might contain non-zero bytes.
5760+ has_content: bool,
5761+ unused: @Type(.{ .int = .{
5762+ .signedness = .unsigned,
5763+ .bits = 32 - @bitSizeOf(std.mem.Alignment) - 5,
5764+ } }) = 0,
5765+ };
5766+
5767+ pub const Location = union(enum(u1)) {
5768+ small: extern struct {
5769+ /// Relative to `parent`.
5770+ offset: u32,
5771+ size: u32,
5772+ },
5773+ large: extern struct {
5774+ index: usize,
5775+ unused: @Type(.{ .int = .{
5776+ .signedness = .unsigned,
5777+ .bits = 64 - @bitSizeOf(usize),
5778+ } }) = 0,
5779+ },
5780+
5781+ pub const Tag = @typeInfo(Location).@"union".tag_type.?;
5782+ pub const Payload = @Type(.{ .@"union" = .{
5783+ .layout = .@"extern",
5784+ .tag_type = null,
5785+ .fields = @typeInfo(Location).@"union".fields,
5786+ .decls = &.{},
5787+ } });
5788+
5789+ pub fn resolve(loc: Location, mf: *const MappedFile) [2]u64 {
5790+ return switch (loc) {
5791+ .small => |small| .{ small.offset, small.size },
5792+ .large => |large| mf.large.items[large.index..][0..2].*,
5793+ };
5794+ }
5795+ };
5796+
5797+ pub const Index = enum(u32) {
5798+ none,
5799+ _,
5800+
5801+ pub const root: Node.Index = .none;
5802+
5803+ fn get(ni: Node.Index, mf: *const MappedFile) *Node {
5804+ return &mf.nodes.items[@intFromEnum(ni)];
5805+ }
5806+
5807+ pub fn childrenMoved(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) !void {
5808+ var child_ni = ni.get(mf).last;
5809+ while (child_ni != .none) {
5810+ try child_ni.moved(gpa, mf);
5811+ child_ni = child_ni.get(mf).prev;
5812+ }
5813+ }
5814+
5815+ pub fn hasMoved(ni: Node.Index, mf: *const MappedFile) bool {
5816+ var parent_ni = ni;
5817+ while (parent_ni != .none) {
5818+ const parent = parent_ni.get(mf);
5819+ if (parent.flags.moved) return true;
5820+ parent_ni = parent.parent;
5821+ }
5822+ return false;
5823+ }
5824+ pub fn moved(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) !void {
5825+ try mf.updates.ensureUnusedCapacity(gpa, 1);
5826+ ni.movedAssumeCapacity(mf);
5827+ }
5828+ pub fn cleanMoved(ni: Node.Index, mf: *const MappedFile) bool {
5829+ const node_moved = &ni.get(mf).flags.moved;
5830+ defer node_moved.* = false;
5831+ return node_moved.*;
5832+ }
5833+ fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {
5834+ var parent_ni = ni;
5835+ while (parent_ni != .none) {
5836+ const parent_node = parent_ni.get(mf);
5837+ if (parent_node.flags.moved) return;
5838+ parent_ni = parent_node.parent;
5839+ }
5840+ const node = ni.get(mf);
5841+ node.flags.moved = true;
5842+ if (node.flags.resized) return;
5843+ mf.updates.appendAssumeCapacity(ni);
5844+ mf.update_prog_node.increaseEstimatedTotalItems(1);
5845+ }
5846+
5847+ pub fn hasResized(ni: Node.Index, mf: *const MappedFile) bool {
5848+ return ni.get(mf).flags.resized;
5849+ }
5850+ pub fn resized(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) !void {
5851+ try mf.updates.ensureUnusedCapacity(gpa, 1);
5852+ ni.resizedAssumeCapacity(mf);
5853+ }
5854+ pub fn cleanResized(ni: Node.Index, mf: *const MappedFile) bool {
5855+ const node_resized = &ni.get(mf).flags.resized;
5856+ defer node_resized.* = false;
5857+ return node_resized.*;
5858+ }
5859+ fn resizedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {
5860+ const node = ni.get(mf);
5861+ if (node.flags.resized) return;
5862+ node.flags.resized = true;
5863+ if (node.flags.moved) return;
5864+ mf.updates.appendAssumeCapacity(ni);
5865+ mf.update_prog_node.increaseEstimatedTotalItems(1);
5866+ }
5867+
5868+ pub fn alignment(ni: Node.Index, mf: *const MappedFile) std.mem.Alignment {
5869+ return ni.get(mf).flags.alignment;
5870+ }
5871+
5872+ fn setLocationAssumeCapacity(ni: Node.Index, mf: *MappedFile, offset: u64, size: u64) void {
5873+ const node = ni.get(mf);
5874+ if (size == 0) node.flags.has_content = false;
5875+ switch (node.location()) {
5876+ .small => |small| {
5877+ if (small.offset != offset) ni.movedAssumeCapacity(mf);
5878+ if (small.size != size) ni.resizedAssumeCapacity(mf);
5879+ if (std.math.cast(u32, offset)) |small_offset| {
5880+ if (std.math.cast(u32, size)) |small_size| {
5881+ node.location_payload.small = .{
5882+ .offset = small_offset,
5883+ .size = small_size,
5884+ };
5885+ return;
5886+ }
5887+ }
5888+ defer mf.large.appendSliceAssumeCapacity(&.{ offset, size });
5889+ node.flags.location_tag = .large;
5890+ node.location_payload = .{ .large = .{ .index = mf.large.items.len } };
5891+ },
5892+ .large => |large| {
5893+ const large_items = mf.large.items[large.index..][0..2];
5894+ if (large_items[0] != offset) ni.movedAssumeCapacity(mf);
5895+ if (large_items[1] != size) ni.resizedAssumeCapacity(mf);
5896+ large_items.* = .{ offset, size };
5897+ },
5898+ }
5899+ }
5900+
5901+ pub fn location(ni: Node.Index, mf: *const MappedFile) Location {
5902+ return ni.get(mf).location();
5903+ }
5904+
5905+ pub fn fileLocation(
5906+ ni: Node.Index,
5907+ mf: *const MappedFile,
5908+ set_has_content: bool,
5909+ ) struct { offset: u64, size: u64 } {
5910+ var offset, const size = ni.location(mf).resolve(mf);
5911+ var parent_ni = ni;
5912+ while (true) {
5913+ const parent = parent_ni.get(mf);
5914+ if (set_has_content) parent.flags.has_content = true;
5915+ if (parent_ni == .none) break;
5916+ parent_ni = parent.parent;
5917+ offset += parent_ni.location(mf).resolve(mf)[0];
5918+ }
5919+ return .{ .offset = offset, .size = size };
5920+ }
5921+
5922+ pub fn slice(ni: Node.Index, mf: *const MappedFile) []u8 {
5923+ const file_loc = ni.fileLocation(mf, true);
5924+ return mf.contents[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)];
5925+ }
5926+
5927+ pub fn sliceConst(ni: Node.Index, mf: *const MappedFile) []const u8 {
5928+ const file_loc = ni.fileLocation(mf, false);
5929+ return mf.contents[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)];
5930+ }
5931+
5932+ pub fn resize(ni: Node.Index, mf: *MappedFile, gpa: std.mem.Allocator, size: u64) !void {
5933+ try mf.resizeNode(gpa, ni, size);
5934+ var writers_it = mf.writers.first;
5935+ while (writers_it) |writer_node| : (writers_it = writer_node.next) {
5936+ const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node);
5937+ w.interface.buffer = w.ni.slice(mf);
5938+ }
5939+ }
5940+
5941+ pub fn writer(ni: Node.Index, mf: *MappedFile, gpa: std.mem.Allocator, w: *Writer) void {
5942+ w.* = .{
5943+ .gpa = gpa,
5944+ .mf = mf,
5945+ .writer_node = .{},
5946+ .ni = ni,
5947+ .interface = .{
5948+ .buffer = ni.slice(mf),
5949+ .vtable = &Writer.vtable,
5950+ },
5951+ .err = null,
5952+ };
5953+ mf.writers.prepend(&w.writer_node);
5954+ }
5955+ };
5956+
5957+ pub fn location(node: *const Node) Location {
5958+ return switch (node.flags.location_tag) {
5959+ inline else => |tag| @unionInit(
5960+ Location,
5961+ @tagName(tag),
5962+ @field(node.location_payload, @tagName(tag)),
5963+ ),
5964+ };
5965+ }
5966+
5967+ pub const Writer = struct {
5968+ gpa: std.mem.Allocator,
5969+ mf: *MappedFile,
5970+ writer_node: std.SinglyLinkedList.Node,
5971+ ni: Node.Index,
5972+ interface: std.Io.Writer,
5973+ err: ?Error,
5974+
5975+ pub fn deinit(w: *Writer) void {
5976+ assert(w.mf.writers.popFirst() == &w.writer_node);
5977+ w.* = undefined;
5978+ }
5979+
5980+ const vtable: std.Io.Writer.VTable = .{
5981+ .drain = drain,
5982+ .sendFile = sendFile,
5983+ .flush = std.Io.Writer.noopFlush,
5984+ .rebase = growingRebase,
5985+ };
5986+
5987+ fn drain(
5988+ interface: *std.Io.Writer,
5989+ data: []const []const u8,
5990+ splat: usize,
5991+ ) std.Io.Writer.Error!usize {
5992+ const pattern = data[data.len - 1];
5993+ const splat_len = pattern.len * splat;
5994+ const start_len = interface.end;
5995+ assert(data.len != 0);
5996+ for (data) |bytes| {
5997+ try growingRebase(interface, interface.end, bytes.len + splat_len + 1);
5998+ @memcpy(interface.buffer[interface.end..][0..bytes.len], bytes);
5999+ interface.end += bytes.len;
6000+ }
6001+ if (splat == 0) {
6002+ interface.end -= pattern.len;
6003+ } else switch (pattern.len) {
6004+ 0 => {},
6005+ 1 => {
6006+ @memset(interface.buffer[interface.end..][0 .. splat - 1], pattern[0]);
6007+ interface.end += splat - 1;
6008+ },
6009+ else => for (0..splat - 1) |_| {
6010+ @memcpy(interface.buffer[interface.end..][0..pattern.len], pattern);
6011+ interface.end += pattern.len;
6012+ },
6013+ }
6014+ return interface.end - start_len;
6015+ }
6016+
6017+ fn sendFile(
6018+ interface: *std.Io.Writer,
6019+ file_reader: *std.fs.File.Reader,
6020+ limit: std.Io.Limit,
6021+ ) std.Io.Writer.FileError!usize {
6022+ if (limit == .nothing) return 0;
6023+ const pos = file_reader.logicalPos();
6024+ const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line;
6025+ if (additional == 0) return error.EndOfStream;
6026+ try growingRebase(interface, interface.end, limit.minInt64(additional));
6027+ switch (file_reader.mode) {
6028+ .positional => {
6029+ const fr_buf = file_reader.interface.buffered();
6030+ const buf_copy_size = interface.write(fr_buf) catch unreachable;
6031+ file_reader.interface.toss(buf_copy_size);
6032+ if (buf_copy_size < fr_buf.len) return buf_copy_size;
6033+ assert(file_reader.logicalPos() == file_reader.pos);
6034+
6035+ const w: *Writer = @fieldParentPtr("interface", interface);
6036+ const copy_size: usize = @intCast(w.mf.copyFileRange(
6037+ file_reader.file,
6038+ file_reader.pos,
6039+ w.ni.fileLocation(w.mf, true).offset + interface.end,
6040+ limit.minInt(interface.unusedCapacityLen()),
6041+ ) catch |err| {
6042+ w.err = err;
6043+ return error.WriteFailed;
6044+ });
6045+ interface.end += copy_size;
6046+ return copy_size;
6047+ },
6048+ .streaming,
6049+ .streaming_reading,
6050+ .positional_reading,
6051+ .failure,
6052+ => {
6053+ const dest = limit.slice(interface.unusedCapacitySlice());
6054+ const n = try file_reader.read(dest);
6055+ interface.end += n;
6056+ return n;
6057+ },
6058+ }
6059+ }
6060+
6061+ fn growingRebase(
6062+ interface: *std.Io.Writer,
6063+ preserve: usize,
6064+ unused_capacity: usize,
6065+ ) std.Io.Writer.Error!void {
6066+ _ = preserve;
6067+ const total_capacity = interface.end + unused_capacity;
6068+ if (interface.buffer.len >= total_capacity) return;
6069+ const w: *Writer = @fieldParentPtr("interface", interface);
6070+ w.ni.resize(w.mf, w.gpa, total_capacity +| total_capacity / 2) catch |err| {
6071+ w.err = err;
6072+ return error.WriteFailed;
6073+ };
6074+ }
6075+ };
6076+
6077+ comptime {
6078+ if (!std.debug.runtime_safety) std.debug.assert(@sizeOf(Node) == 32);
6079+ }
6080+};
6081+
6082+fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct {
6083+ parent: Node.Index = .none,
6084+ prev: Node.Index = .none,
6085+ next: Node.Index = .none,
6086+ offset: u64 = 0,
6087+ add_node: AddNodeOptions,
6088+}) !Node.Index {
6089+ if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1);
6090+ const offset = opts.add_node.alignment.forward(@intCast(opts.offset));
6091+ const location_tag: Node.Location.Tag, const location_payload: Node.Location.Payload = location: {
6092+ if (std.math.cast(u32, offset)) |small_offset| break :location .{ .small, .{
6093+ .small = .{ .offset = small_offset, .size = 0 },
6094+ } };
6095+ try mf.large.ensureUnusedCapacity(gpa, 2);
6096+ defer mf.large.appendSliceAssumeCapacity(&.{ offset, 0 });
6097+ break :location .{ .large, .{ .large = .{ .index = mf.large.items.len } } };
6098+ };
6099+ const free_ni: Node.Index, const free_node = free: switch (mf.free_ni) {
6100+ .none => .{ @enumFromInt(mf.nodes.items.len), mf.nodes.addOneAssumeCapacity() },
6101+ else => |free_ni| {
6102+ const free_node = free_ni.get(mf);
6103+ mf.free_ni = free_node.next;
6104+ break :free .{ free_ni, free_node };
6105+ },
6106+ };
6107+ free_node.* = .{
6108+ .parent = opts.parent,
6109+ .prev = opts.prev,
6110+ .next = opts.next,
6111+ .first = .none,
6112+ .last = .none,
6113+ .flags = .{
6114+ .location_tag = location_tag,
6115+ .alignment = opts.add_node.alignment,
6116+ .fixed = opts.add_node.fixed,
6117+ .moved = true,
6118+ .resized = true,
6119+ .has_content = false,
6120+ },
6121+ .location_payload = location_payload,
6122+ };
6123+ {
6124+ defer {
6125+ free_node.flags.moved = false;
6126+ free_node.flags.resized = false;
6127+ }
6128+ if (offset > opts.parent.location(mf).resolve(mf)[1]) try opts.parent.resize(mf, gpa, offset);
6129+ try free_ni.resize(mf, gpa, opts.add_node.size);
6130+ }
6131+ if (opts.add_node.moved) free_ni.movedAssumeCapacity(mf);
6132+ if (opts.add_node.resized) free_ni.resizedAssumeCapacity(mf);
6133+ return free_ni;
6134+}
6135+
6136+pub const AddNodeOptions = struct {
6137+ size: u64 = 0,
6138+ alignment: std.mem.Alignment = .@"1",
6139+ fixed: bool = false,
6140+ moved: bool = false,
6141+ resized: bool = false,
6142+};
6143+
6144+pub fn addOnlyChildNode(
6145+ mf: *MappedFile,
6146+ gpa: std.mem.Allocator,
6147+ parent_ni: Node.Index,
6148+ opts: AddNodeOptions,
6149+) !Node.Index {
6150+ try mf.nodes.ensureUnusedCapacity(gpa, 1);
6151+ const parent = parent_ni.get(mf);
6152+ assert(parent.first == .none and parent.last == .none);
6153+ const ni = try mf.addNode(gpa, .{
6154+ .parent = parent_ni,
6155+ .add_node = opts,
6156+ });
6157+ parent.first = ni;
6158+ parent.last = ni;
6159+ return ni;
6160+}
6161+
6162+pub fn addLastChildNode(
6163+ mf: *MappedFile,
6164+ gpa: std.mem.Allocator,
6165+ parent_ni: Node.Index,
6166+ opts: AddNodeOptions,
6167+) !Node.Index {
6168+ try mf.nodes.ensureUnusedCapacity(gpa, 1);
6169+ const parent = parent_ni.get(mf);
6170+ const ni = try mf.addNode(gpa, .{
6171+ .parent = parent_ni,
6172+ .prev = parent.last,
6173+ .offset = offset: switch (parent.last) {
6174+ .none => 0,
6175+ else => |last_ni| {
6176+ const last_offset, const last_size = last_ni.location(mf).resolve(mf);
6177+ break :offset last_offset + last_size;
6178+ },
6179+ },
6180+ .add_node = opts,
6181+ });
6182+ switch (parent.last) {
6183+ .none => parent.first = ni,
6184+ else => |last_ni| last_ni.get(mf).next = ni,
6185+ }
6186+ parent.last = ni;
6187+ return ni;
6188+}
6189+
6190+pub fn addNodeAfter(
6191+ mf: *MappedFile,
6192+ gpa: std.mem.Allocator,
6193+ prev_ni: Node.Index,
6194+ opts: AddNodeOptions,
6195+) !Node.Index {
6196+ assert(prev_ni != .none);
6197+ try mf.nodes.ensureUnusedCapacity(gpa, 1);
6198+ const prev = prev_ni.get(mf);
6199+ const prev_offset, const prev_size = prev.location().resolve(mf);
6200+ const ni = try mf.addNode(gpa, .{
6201+ .parent = prev.parent,
6202+ .prev = prev_ni,
6203+ .next = prev.next,
6204+ .offset = prev_offset + prev_size,
6205+ .add_node = opts,
6206+ });
6207+ switch (prev.next) {
6208+ .none => prev.parent.get(mf).last = ni,
6209+ else => |next_ni| next_ni.get(mf).prev = ni,
6210+ }
6211+ prev.next = ni;
6212+ return ni;
6213+}
6214+
6215+fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) !void {
6216+ const node = ni.get(mf);
6217+ var old_offset, const old_size = node.location().resolve(mf);
6218+ const new_size = node.flags.alignment.forward(@intCast(requested_size));
6219+ // Resize the entire file
6220+ if (ni == Node.Index.root) {
6221+ try mf.file.setEndPos(new_size);
6222+ try mf.ensureTotalCapacity(@intCast(new_size));
6223+ try mf.ensureCapacityForSetLocation(gpa);
6224+ ni.setLocationAssumeCapacity(mf, old_offset, new_size);
6225+ return;
6226+ }
6227+ while (true) {
6228+ const parent = node.parent.get(mf);
6229+ _, const old_parent_size = parent.location().resolve(mf);
6230+ const trailing_end = switch (node.next) {
6231+ .none => parent.location().resolve(mf)[1],
6232+ else => |next_ni| next_ni.location(mf).resolve(mf)[0],
6233+ };
6234+ assert(old_offset + old_size <= trailing_end);
6235+ // Expand the node into available trailing free space
6236+ if (old_offset + new_size <= trailing_end) {
6237+ try mf.ensureCapacityForSetLocation(gpa);
6238+ ni.setLocationAssumeCapacity(mf, old_offset, new_size);
6239+ return;
6240+ }
6241+ // Ask the filesystem driver to insert an extent into the file without copying any data
6242+ if (is_linux and !mf.flags.fallocate_insert_range_unsupported and
6243+ node.flags.alignment.order(mf.flags.block_size).compare(.gte))
6244+ insert_range: {
6245+ const last_offset, const last_size = parent.last.location(mf).resolve(mf);
6246+ const last_end = last_offset + last_size;
6247+ assert(last_end <= old_parent_size);
6248+ const range_size =
6249+ node.flags.alignment.forward(@intCast(requested_size +| requested_size / 2)) - old_size;
6250+ const new_parent_size = last_end + range_size;
6251+ if (new_parent_size > old_parent_size) {
6252+ try mf.resizeNode(gpa, node.parent, new_parent_size +| new_parent_size / 2);
6253+ continue;
6254+ }
6255+ const range_file_offset = ni.fileLocation(mf, false).offset + old_size;
6256+ retry: while (true) {
6257+ switch (linux.E.init(linux.fallocate(
6258+ mf.file.handle,
6259+ linux.FALLOC.FL_INSERT_RANGE,
6260+ @intCast(range_file_offset),
6261+ @intCast(range_size),
6262+ ))) {
6263+ .SUCCESS => {
6264+ var enclosing_ni = ni;
6265+ while (enclosing_ni != .none) {
6266+ try mf.ensureCapacityForSetLocation(gpa);
6267+ const enclosing = enclosing_ni.get(mf);
6268+ const enclosing_offset, const enclosing_size =
6269+ enclosing.location().resolve(mf);
6270+ enclosing_ni.setLocationAssumeCapacity(
6271+ mf,
6272+ enclosing_offset,
6273+ enclosing_size + range_size,
6274+ );
6275+ var after_ni = enclosing.next;
6276+ while (after_ni != .none) {
6277+ try mf.ensureCapacityForSetLocation(gpa);
6278+ const after = after_ni.get(mf);
6279+ const after_offset, const after_size = after.location().resolve(mf);
6280+ after_ni.setLocationAssumeCapacity(
6281+ mf,
6282+ range_size + after_offset,
6283+ after_size,
6284+ );
6285+ after_ni = after.next;
6286+ }
6287+ enclosing_ni = enclosing.parent;
6288+ }
6289+ return;
6290+ },
6291+ .INTR => continue :retry,
6292+ .BADF, .FBIG, .INVAL => unreachable,
6293+ .IO => return error.InputOutput,
6294+ .NODEV => return error.NotFile,
6295+ .NOSPC => return error.NoSpaceLeft,
6296+ .NOSYS, .OPNOTSUPP => {
6297+ mf.flags.fallocate_insert_range_unsupported = true;
6298+ break :insert_range;
6299+ },
6300+ .PERM => return error.PermissionDenied,
6301+ .SPIPE => return error.Unseekable,
6302+ .TXTBSY => return error.FileBusy,
6303+ else => |e| return std.posix.unexpectedErrno(e),
6304+ }
6305+ }
6306+ }
6307+ switch (node.next) {
6308+ .none => {
6309+ // As this is the last node, we simply need more space in the parent
6310+ const new_parent_size = old_offset + new_size;
6311+ try mf.resizeNode(gpa, node.parent, new_parent_size +| new_parent_size / 2);
6312+ },
6313+ else => |*next_ni_ptr| switch (node.flags.fixed) {
6314+ false => {
6315+ // Make space at the end of the parent for this floating node
6316+ const last = parent.last.get(mf);
6317+ const last_offset, const last_size = last.location().resolve(mf);
6318+ const new_offset = node.flags.alignment.forward(@intCast(last_offset + last_size));
6319+ const new_parent_size = new_offset + new_size;
6320+ if (new_parent_size > old_parent_size) {
6321+ try mf.resizeNode(
6322+ gpa,
6323+ node.parent,
6324+ new_parent_size +| new_parent_size / 2,
6325+ );
6326+ continue;
6327+ }
6328+ const next_ni = next_ni_ptr.*;
6329+ next_ni.get(mf).prev = node.prev;
6330+ switch (node.prev) {
6331+ .none => parent.first = next_ni,
6332+ else => |prev_ni| prev_ni.get(mf).next = next_ni,
6333+ }
6334+ last.next = ni;
6335+ node.prev = parent.last;
6336+ next_ni_ptr.* = .none;
6337+ parent.last = ni;
6338+ if (node.flags.has_content) {
6339+ const parent_file_offset = node.parent.fileLocation(mf, false).offset;
6340+ try mf.moveRange(
6341+ parent_file_offset + old_offset,
6342+ parent_file_offset + new_offset,
6343+ old_size,
6344+ );
6345+ }
6346+ old_offset = new_offset;
6347+ },
6348+ true => {
6349+ // Move the next floating node to make space for this fixed node
6350+ const next_ni = next_ni_ptr.*;
6351+ const next = next_ni.get(mf);
6352+ assert(!next.flags.fixed);
6353+ const next_offset, const next_size = next.location().resolve(mf);
6354+ const last = parent.last.get(mf);
6355+ const last_offset, const last_size = last.location().resolve(mf);
6356+ const new_offset = next.flags.alignment.forward(@intCast(
6357+ @max(old_offset + new_size, last_offset + last_size),
6358+ ));
6359+ const new_parent_size = new_offset + next_size;
6360+ if (new_parent_size > old_parent_size) {
6361+ try mf.resizeNode(
6362+ gpa,
6363+ node.parent,
6364+ new_parent_size +| new_parent_size / 2,
6365+ );
6366+ continue;
6367+ }
6368+ try mf.ensureCapacityForSetLocation(gpa);
6369+ next.prev = parent.last;
6370+ parent.last = next_ni;
6371+ last.next = next_ni;
6372+ next_ni_ptr.* = next.next;
6373+ switch (next.next) {
6374+ .none => {},
6375+ else => |next_next_ni| next_next_ni.get(mf).prev = ni,
6376+ }
6377+ next.next = .none;
6378+ if (node.flags.has_content) {
6379+ const parent_file_offset = node.parent.fileLocation(mf, false).offset;
6380+ try mf.moveRange(
6381+ parent_file_offset + next_offset,
6382+ parent_file_offset + new_offset,
6383+ next_size,
6384+ );
6385+ }
6386+ next_ni.setLocationAssumeCapacity(mf, new_offset, next_size);
6387+ },
6388+ },
6389+ }
6390+ }
6391+}
6392+
6393+fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) !void {
6394+ // make a copy of this node at the new location
6395+ try mf.copyRange(old_file_offset, new_file_offset, size);
6396+ // delete the copy of this node at the old location
6397+ if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and
6398+ size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true)
6399+ {
6400+ switch (linux.E.init(linux.fallocate(
6401+ mf.file.handle,
6402+ linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE,
6403+ @intCast(old_file_offset),
6404+ @intCast(size),
6405+ ))) {
6406+ .SUCCESS => return,
6407+ .INTR => continue,
6408+ .BADF, .FBIG, .INVAL => unreachable,
6409+ .IO => return error.InputOutput,
6410+ .NODEV => return error.NotFile,
6411+ .NOSPC => return error.NoSpaceLeft,
6412+ .NOSYS, .OPNOTSUPP => {
6413+ mf.flags.fallocate_punch_hole_unsupported = true;
6414+ break;
6415+ },
6416+ .PERM => return error.PermissionDenied,
6417+ .SPIPE => return error.Unseekable,
6418+ .TXTBSY => return error.FileBusy,
6419+ else => |e| return std.posix.unexpectedErrno(e),
6420+ }
6421+ };
6422+ @memset(mf.contents[@intCast(old_file_offset)..][0..@intCast(size)], 0);
6423+}
6424+
6425+fn copyRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) !void {
6426+ const copy_size = try mf.copyFileRange(mf.file, old_file_offset, new_file_offset, size);
6427+ if (copy_size < size) @memcpy(
6428+ mf.contents[@intCast(new_file_offset + copy_size)..][0..@intCast(size - copy_size)],
6429+ mf.contents[@intCast(old_file_offset + copy_size)..][0..@intCast(size - copy_size)],
6430+ );
6431+}
6432+
6433+fn copyFileRange(
6434+ mf: *MappedFile,
6435+ old_file: std.fs.File,
6436+ old_file_offset: u64,
6437+ new_file_offset: u64,
6438+ size: u64,
6439+) !u64 {
6440+ var remaining_size = size;
6441+ if (is_linux and !mf.flags.copy_file_range_unsupported) {
6442+ var old_file_offset_mut: i64 = @intCast(old_file_offset);
6443+ var new_file_offset_mut: i64 = @intCast(new_file_offset);
6444+ while (remaining_size >= mf.flags.block_size.toByteUnits() * 2 - 1) {
6445+ const copy_len = linux.copy_file_range(
6446+ old_file.handle,
6447+ &old_file_offset_mut,
6448+ mf.file.handle,
6449+ &new_file_offset_mut,
6450+ @intCast(remaining_size),
6451+ 0,
6452+ );
6453+ switch (linux.E.init(copy_len)) {
6454+ .SUCCESS => {
6455+ if (copy_len == 0) break;
6456+ remaining_size -= copy_len;
6457+ if (remaining_size == 0) break;
6458+ },
6459+ .INTR => continue,
6460+ .BADF, .FBIG, .INVAL, .OVERFLOW => unreachable,
6461+ .IO => return error.InputOutput,
6462+ .ISDIR => return error.IsDir,
6463+ .NOMEM => return error.SystemResources,
6464+ .NOSPC => return error.NoSpaceLeft,
6465+ .NOSYS, .OPNOTSUPP, .XDEV => {
6466+ mf.flags.copy_file_range_unsupported = true;
6467+ break;
6468+ },
6469+ .PERM => return error.PermissionDenied,
6470+ .TXTBSY => return error.FileBusy,
6471+ else => |e| return std.posix.unexpectedErrno(e),
6472+ }
6473+ }
6474+ }
6475+ return size - remaining_size;
6476+}
6477+
6478+fn ensureCapacityForSetLocation(mf: *MappedFile, gpa: std.mem.Allocator) !void {
6479+ try mf.large.ensureUnusedCapacity(gpa, 2);
6480+ try mf.updates.ensureUnusedCapacity(gpa, 1);
6481+}
6482+
6483+pub fn ensureTotalCapacity(mf: *MappedFile, new_capacity: usize) !void {
6484+ if (mf.contents.len >= new_capacity) return;
6485+ try mf.ensureTotalCapacityPrecise(new_capacity +| new_capacity / 2);
6486+}
6487+
6488+pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {
6489+ if (mf.contents.len >= new_capacity) return;
6490+ const aligned_capacity = mf.flags.block_size.forward(new_capacity);
6491+ if (!is_linux) mf.unmap() else if (mf.contents.len > 0) {
6492+ mf.contents = try std.posix.mremap(
6493+ mf.contents.ptr,
6494+ mf.contents.len,
6495+ aligned_capacity,
6496+ .{ .MAYMOVE = true },
6497+ null,
6498+ );
6499+ return;
6500+ }
6501+ if (is_windows) {
6502+ if (mf.section == windows.INVALID_HANDLE_VALUE) switch (windows.ntdll.NtCreateSection(
6503+ &mf.section,
6504+ windows.STANDARD_RIGHTS_REQUIRED | windows.SECTION_QUERY |
6505+ windows.SECTION_MAP_WRITE | windows.SECTION_MAP_READ | windows.SECTION_EXTEND_SIZE,
6506+ null,
6507+ @constCast(&@as(i64, @intCast(aligned_capacity))),
6508+ windows.PAGE_READWRITE,
6509+ windows.SEC_COMMIT,
6510+ mf.file.handle,
6511+ )) {
6512+ .SUCCESS => {},
6513+ else => return error.MemoryMappingNotSupported,
6514+ };
6515+ var contents_ptr: ?[*]align(std.heap.page_size_min) u8 = null;
6516+ var contents_len = aligned_capacity;
6517+ switch (windows.ntdll.NtMapViewOfSection(
6518+ mf.section,
6519+ windows.GetCurrentProcess(),
6520+ @ptrCast(&contents_ptr),
6521+ null,
6522+ 0,
6523+ null,
6524+ &contents_len,
6525+ .ViewUnmap,
6526+ 0,
6527+ windows.PAGE_READWRITE,
6528+ )) {
6529+ .SUCCESS => mf.contents = contents_ptr.?[0..contents_len],
6530+ else => return error.MemoryMappingNotSupported,
6531+ }
6532+ } else mf.contents = try std.posix.mmap(
6533+ null,
6534+ aligned_capacity,
6535+ std.posix.PROT.READ | std.posix.PROT.WRITE,
6536+ .{ .TYPE = if (is_linux) .SHARED_VALIDATE else .SHARED },
6537+ mf.file.handle,
6538+ 0,
6539+ );
6540+}
6541+
6542+pub fn unmap(mf: *MappedFile) void {
6543+ if (mf.contents.len == 0) return;
6544+ if (is_windows)
6545+ _ = windows.ntdll.NtUnmapViewOfSection(windows.GetCurrentProcess(), mf.contents.ptr)
6546+ else
6547+ std.posix.munmap(mf.contents);
6548+ mf.contents = &.{};
6549+ if (is_windows and mf.section != windows.INVALID_HANDLE_VALUE) {
6550+ windows.CloseHandle(mf.section);
6551+ mf.section = windows.INVALID_HANDLE_VALUE;
6552+ }
6553+}
6554+
6555+fn verify(mf: *MappedFile) void {
6556+ const root = Node.Index.root.get(mf);
6557+ assert(root.parent == .none);
6558+ assert(root.prev == .none);
6559+ assert(root.next == .none);
6560+ mf.verifyNode(Node.Index.root);
6561+}
6562+
6563+fn verifyNode(mf: *MappedFile, parent_ni: Node.Index) void {
6564+ const parent = parent_ni.get(mf);
6565+ const parent_offset, const parent_size = parent.location().resolve(mf);
6566+ var prev_ni: Node.Index = .none;
6567+ var prev_end: u64 = 0;
6568+ var ni = parent.first;
6569+ while (true) {
6570+ if (ni == .none) {
6571+ assert(parent.last == prev_ni);
6572+ return;
6573+ }
6574+ const node = ni.get(mf);
6575+ assert(node.parent == parent_ni);
6576+ const offset, const size = node.location().resolve(mf);
6577+ assert(node.flags.alignment.check(@intCast(offset)));
6578+ assert(node.flags.alignment.check(@intCast(size)));
6579+ const end = offset + size;
6580+ assert(end <= parent_offset + parent_size);
6581+ assert(offset >= prev_end);
6582+ assert(node.prev == prev_ni);
6583+ mf.verifyNode(ni);
6584+ prev_ni = ni;
6585+ prev_end = end;
6586+ ni = node.next;
6587+ }
6588+}
6589+
6590+const assert = std.debug.assert;
6591+const builtin = @import("builtin");
6592+const is_linux = builtin.os.tag == .linux;
6593+const is_windows = builtin.os.tag == .windows;
6594+const linux = std.os.linux;
6595+const MappedFile = @This();
6596+const std = @import("std");
6597+const windows = std.os.windows;
6598diff --git a/src/link/Queue.zig b/src/link/Queue.zig
6599index 9f4535e1fe..742b4664f1 100644
6600--- a/src/link/Queue.zig
6601+++ b/src/link/Queue.zig
6602@@ -22,17 +22,17 @@ prelink_wait_count: u32,
6603
6604 /// Prelink tasks which have been enqueued and are not yet owned by the worker thread.
6605 /// Allocated into `gpa`, guarded by `mutex`.
6606-queued_prelink: std.ArrayListUnmanaged(PrelinkTask),
6607+queued_prelink: std.ArrayList(PrelinkTask),
6608 /// The worker thread moves items from `queued_prelink` into this array in order to process them.
6609 /// Allocated into `gpa`, accessed only by the worker thread.
6610-wip_prelink: std.ArrayListUnmanaged(PrelinkTask),
6611+wip_prelink: std.ArrayList(PrelinkTask),
6612
6613 /// Like `queued_prelink`, but for ZCU tasks.
6614 /// Allocated into `gpa`, guarded by `mutex`.
6615-queued_zcu: std.ArrayListUnmanaged(ZcuTask),
6616+queued_zcu: std.ArrayList(ZcuTask),
6617 /// Like `wip_prelink`, but for ZCU tasks.
6618 /// Allocated into `gpa`, accessed only by the worker thread.
6619-wip_zcu: std.ArrayListUnmanaged(ZcuTask),
6620+wip_zcu: std.ArrayList(ZcuTask),
6621
6622 /// When processing ZCU link tasks, we might have to block due to unpopulated MIR. When this
6623 /// happens, some tasks in `wip_zcu` have been run, and some are still pending. This is the
6624@@ -213,32 +213,41 @@ pub fn enqueueZcu(q: *Queue, comp: *Compilation, task: ZcuTask) Allocator.Error!
6625
6626 fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
6627 q.flush_safety.lock(); // every `return` site should unlock this before unlocking `q.mutex`
6628-
6629 if (std.debug.runtime_safety) {
6630 q.mutex.lock();
6631 defer q.mutex.unlock();
6632 assert(q.state == .running);
6633 }
6634+
6635+ var have_idle_tasks = true;
6636 prelink: while (true) {
6637 assert(q.wip_prelink.items.len == 0);
6638- {
6639- q.mutex.lock();
6640- defer q.mutex.unlock();
6641- std.mem.swap(std.ArrayListUnmanaged(PrelinkTask), &q.queued_prelink, &q.wip_prelink);
6642- if (q.wip_prelink.items.len == 0) {
6643- if (q.prelink_wait_count == 0) {
6644- break :prelink; // prelink is done
6645- } else {
6646+ swap_queues: while (true) {
6647+ {
6648+ q.mutex.lock();
6649+ defer q.mutex.unlock();
6650+ std.mem.swap(std.ArrayList(PrelinkTask), &q.queued_prelink, &q.wip_prelink);
6651+ if (q.wip_prelink.items.len > 0) break :swap_queues;
6652+ if (q.prelink_wait_count == 0) break :prelink; // prelink is done
6653+ if (!have_idle_tasks) {
6654 // We're expecting more prelink tasks so can't move on to ZCU tasks.
6655 q.state = .finished;
6656 q.flush_safety.unlock();
6657 return;
6658 }
6659 }
6660+ have_idle_tasks = link.doIdleTask(comp, tid) catch |err| switch (err) {
6661+ error.OutOfMemory => have_idle_tasks: {
6662+ comp.link_diags.setAllocFailure();
6663+ break :have_idle_tasks false;
6664+ },
6665+ error.LinkFailure => false,
6666+ };
6667 }
6668 for (q.wip_prelink.items) |task| {
6669 link.doPrelinkTask(comp, task);
6670 }
6671+ have_idle_tasks = true;
6672 q.wip_prelink.clearRetainingCapacity();
6673 }
6674
6675@@ -256,17 +265,29 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
6676
6677 // Now we can run ZCU tasks.
6678 while (true) {
6679- if (q.wip_zcu.items.len == q.wip_zcu_idx) {
6680+ if (q.wip_zcu.items.len == q.wip_zcu_idx) swap_queues: {
6681 q.wip_zcu.clearRetainingCapacity();
6682 q.wip_zcu_idx = 0;
6683- q.mutex.lock();
6684- defer q.mutex.unlock();
6685- std.mem.swap(std.ArrayListUnmanaged(ZcuTask), &q.queued_zcu, &q.wip_zcu);
6686- if (q.wip_zcu.items.len == 0) {
6687- // We've exhausted all available tasks.
6688- q.state = .finished;
6689- q.flush_safety.unlock();
6690- return;
6691+ while (true) {
6692+ {
6693+ q.mutex.lock();
6694+ defer q.mutex.unlock();
6695+ std.mem.swap(std.ArrayList(ZcuTask), &q.queued_zcu, &q.wip_zcu);
6696+ if (q.wip_zcu.items.len > 0) break :swap_queues;
6697+ if (!have_idle_tasks) {
6698+ // We've exhausted all available tasks.
6699+ q.state = .finished;
6700+ q.flush_safety.unlock();
6701+ return;
6702+ }
6703+ }
6704+ have_idle_tasks = link.doIdleTask(comp, tid) catch |err| switch (err) {
6705+ error.OutOfMemory => have_idle_tasks: {
6706+ comp.link_diags.setAllocFailure();
6707+ break :have_idle_tasks false;
6708+ },
6709+ error.LinkFailure => false,
6710+ };
6711 }
6712 }
6713 const task = q.wip_zcu.items[q.wip_zcu_idx];
6714@@ -274,8 +295,18 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
6715 pending: {
6716 if (task != .link_func) break :pending;
6717 const status_ptr = &task.link_func.mir.status;
6718- // First check without the mutex to optimize for the common case where MIR is ready.
6719- if (status_ptr.load(.acquire) != .pending) break :pending;
6720+ while (true) {
6721+ // First check without the mutex to optimize for the common case where MIR is ready.
6722+ if (status_ptr.load(.acquire) != .pending) break :pending;
6723+ if (have_idle_tasks) have_idle_tasks = link.doIdleTask(comp, tid) catch |err| switch (err) {
6724+ error.OutOfMemory => have_idle_tasks: {
6725+ comp.link_diags.setAllocFailure();
6726+ break :have_idle_tasks false;
6727+ },
6728+ error.LinkFailure => false,
6729+ };
6730+ if (!have_idle_tasks) break;
6731+ }
6732 q.mutex.lock();
6733 defer q.mutex.unlock();
6734 if (status_ptr.load(.acquire) != .pending) break :pending;
6735@@ -298,6 +329,7 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
6736 }
6737 }
6738 q.wip_zcu_idx += 1;
6739+ have_idle_tasks = true;
6740 }
6741 }
6742
6743diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
6744index a125a70aae..d60b91c30f 100644
6745--- a/src/link/Wasm.zig
6746+++ b/src/link/Wasm.zig
6747@@ -4257,7 +4257,14 @@ fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Zcu
6748 const func_table_fixups_start: u32 = @intCast(wasm.func_table_fixups.items.len);
6749 wasm.string_bytes_lock.lock();
6750
6751- try codegen.generateSymbol(&wasm.base, pt, .unneeded, .fromInterned(ip_index), &wasm.string_bytes, .none);
6752+ {
6753+ var aw: std.Io.Writer.Allocating = .fromArrayList(wasm.base.comp.gpa, &wasm.string_bytes);
6754+ defer wasm.string_bytes = aw.toArrayList();
6755+ codegen.generateSymbol(&wasm.base, pt, .unneeded, .fromInterned(ip_index), &aw.writer, .none) catch |err| switch (err) {
6756+ error.WriteFailed => return error.OutOfMemory,
6757+ else => |e| return e,
6758+ };
6759+ }
6760
6761 const code_len: u32 = @intCast(wasm.string_bytes.items.len - code_start);
6762 const relocs_len: u32 = @intCast(wasm.out_relocs.len - relocs_start);
6763diff --git a/src/main.zig b/src/main.zig
6764index 26d44c4463..9d43e47ea2 100644
6765--- a/src/main.zig
6766+++ b/src/main.zig
6767@@ -904,7 +904,6 @@ fn buildOutputType(
6768 var mingw_unicode_entry_point: bool = false;
6769 var enable_link_snapshots: bool = false;
6770 var debug_compiler_runtime_libs = false;
6771- var opt_incremental: ?bool = null;
6772 var install_name: ?[]const u8 = null;
6773 var hash_style: link.File.Lld.Elf.HashStyle = .both;
6774 var entitlements: ?[]const u8 = null;
6775@@ -1374,9 +1373,9 @@ fn buildOutputType(
6776 }
6777 } else if (mem.eql(u8, arg, "-fincremental")) {
6778 dev.check(.incremental);
6779- opt_incremental = true;
6780+ create_module.opts.incremental = true;
6781 } else if (mem.eql(u8, arg, "-fno-incremental")) {
6782- opt_incremental = false;
6783+ create_module.opts.incremental = false;
6784 } else if (mem.eql(u8, arg, "--entitlements")) {
6785 entitlements = args_iter.nextOrFatal();
6786 } else if (mem.eql(u8, arg, "-fcompiler-rt")) {
6787@@ -1479,6 +1478,10 @@ fn buildOutputType(
6788 create_module.opts.use_lld = true;
6789 } else if (mem.eql(u8, arg, "-fno-lld")) {
6790 create_module.opts.use_lld = false;
6791+ } else if (mem.eql(u8, arg, "-fnew-linker")) {
6792+ create_module.opts.use_new_linker = true;
6793+ } else if (mem.eql(u8, arg, "-fno-new-linker")) {
6794+ create_module.opts.use_new_linker = false;
6795 } else if (mem.eql(u8, arg, "-fclang")) {
6796 create_module.opts.use_clang = true;
6797 } else if (mem.eql(u8, arg, "-fno-clang")) {
6798@@ -3371,7 +3374,7 @@ fn buildOutputType(
6799 else => false,
6800 };
6801
6802- const incremental = opt_incremental orelse false;
6803+ const incremental = create_module.resolved_options.incremental;
6804 if (debug_incremental and !incremental) {
6805 fatal("--debug-incremental requires -fincremental", .{});
6806 }
6807@@ -3502,7 +3505,6 @@ fn buildOutputType(
6808 .subsystem = subsystem,
6809 .debug_compile_errors = debug_compile_errors,
6810 .debug_incremental = debug_incremental,
6811- .incremental = incremental,
6812 .enable_link_snapshots = enable_link_snapshots,
6813 .install_name = install_name,
6814 .entitlements = entitlements,
6815@@ -4016,6 +4018,8 @@ fn createModule(
6816 error.LldUnavailable => fatal("zig was compiled without LLD libraries", .{}),
6817 error.ClangUnavailable => fatal("zig was compiled without Clang libraries", .{}),
6818 error.DllExportFnsRequiresWindows => fatal("only Windows OS targets support DLLs", .{}),
6819+ error.NewLinkerIncompatibleObjectFormat => fatal("using the new linker to link {s} files is unsupported", .{@tagName(target.ofmt)}),
6820+ error.NewLinkerIncompatibleWithLld => fatal("using the new linker is incompatible with using lld", .{}),
6821 };
6822 }
6823
6824diff --git a/src/target.zig b/src/target.zig
6825index e999d2ae22..1cf5c9b082 100644
6826--- a/src/target.zig
6827+++ b/src/target.zig
6828@@ -231,6 +231,13 @@ pub fn hasLldSupport(ofmt: std.Target.ObjectFormat) bool {
6829 };
6830 }
6831
6832+pub fn hasNewLinkerSupport(ofmt: std.Target.ObjectFormat) bool {
6833+ return switch (ofmt) {
6834+ .elf => true,
6835+ else => false,
6836+ };
6837+}
6838+
6839 /// The set of targets that our own self-hosted backends have robust support for.
6840 /// Used to select between LLVM backend and self-hosted backend when compiling in
6841 /// debug mode. A given target should only return true here if it is passing greater
6842diff --git a/test/incremental/change_exports b/test/incremental/change_exports
6843index 01605bdeeb..e492930031 100644
6844--- a/test/incremental/change_exports
6845+++ b/test/incremental/change_exports
6846@@ -1,4 +1,4 @@
6847-//#target=x86_64-linux-selfhosted
6848+#target=x86_64-linux-selfhosted
6849 #target=x86_64-linux-cbe
6850 #target=x86_64-windows-cbe
6851
6852diff --git a/test/incremental/change_panic_handler b/test/incremental/change_panic_handler
6853index 3e400b854e..699134100e 100644
6854--- a/test/incremental/change_panic_handler
6855+++ b/test/incremental/change_panic_handler
6856@@ -1,3 +1,4 @@
6857+#target=x86_64-linux-selfhosted
6858 #target=x86_64-linux-cbe
6859 #target=x86_64-windows-cbe
6860 #update=initial version
6861diff --git a/test/incremental/change_panic_handler_explicit b/test/incremental/change_panic_handler_explicit
6862index 9f7eb6c12f..2d068d593e 100644
6863--- a/test/incremental/change_panic_handler_explicit
6864+++ b/test/incremental/change_panic_handler_explicit
6865@@ -1,3 +1,4 @@
6866+#target=x86_64-linux-selfhosted
6867 #target=x86_64-linux-cbe
6868 #target=x86_64-windows-cbe
6869 #update=initial version
6870diff --git a/test/incremental/change_struct_same_fields b/test/incremental/change_struct_same_fields
6871index 97049a1fc0..f3bfbbdd69 100644
6872--- a/test/incremental/change_struct_same_fields
6873+++ b/test/incremental/change_struct_same_fields
6874@@ -1,4 +1,4 @@
6875-//#target=x86_64-linux-selfhosted
6876+#target=x86_64-linux-selfhosted
6877 #target=x86_64-linux-cbe
6878 #target=x86_64-windows-cbe
6879 #target=wasm32-wasi-selfhosted
6880diff --git a/test/incremental/type_becomes_comptime_only b/test/incremental/type_becomes_comptime_only
6881index 5c5d332975..3bcae1cd21 100644
6882--- a/test/incremental/type_becomes_comptime_only
6883+++ b/test/incremental/type_becomes_comptime_only
6884@@ -1,3 +1,4 @@
6885+#target=x86_64-linux-selfhosted
6886 #target=x86_64-linux-cbe
6887 #target=x86_64-windows-cbe
6888 #target=wasm32-wasi-selfhosted