authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-07-26 18:22:43+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-07-26 18:22:43+02:00
logcb475aa161238ef0d77fc49b13c23f2c4b48bfc5
tree7068693650ad4cb2da4abcd9818aa55b2f9d69e8
parent584b062a302ca10ecab4488a473440db7173bb2a
parent780f0b872a964fe4a411a603b733a3d39700ec1c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #16563 from ziglang/issues-16308

macho: create export trie root explicitly with Trie.init rather than implicitly on first Trie.put

6 files changed, 43 insertions(+), 11 deletions(-)

src/link/MachO.zig+1
...@@ -3227,6 +3227,7 @@ fn writeDyldInfoData(self: *MachO) !void {...@@ -3227,6 +3227,7 @@ fn writeDyldInfoData(self: *MachO) !void {
32273227
3228 var trie: Trie = .{};3228 var trie: Trie = .{};
3229 defer trie.deinit(gpa);3229 defer trie.deinit(gpa);
3230 try trie.init(gpa);
3230 try self.collectExportData(&trie);3231 try self.collectExportData(&trie);
32313232
3232 const link_seg = self.getLinkeditSegmentPtr();3233 const link_seg = self.getLinkeditSegmentPtr();
src/link/MachO/Trie.zig+13-11
...@@ -309,7 +309,6 @@ pub const ExportSymbol = struct {...@@ -309,7 +309,6 @@ pub const ExportSymbol = struct {
309/// This operation may change the layout of the trie by splicing edges in309/// This operation may change the layout of the trie by splicing edges in
310/// certain circumstances.310/// certain circumstances.
311pub fn put(self: *Trie, allocator: Allocator, symbol: ExportSymbol) !void {311pub fn put(self: *Trie, allocator: Allocator, symbol: ExportSymbol) !void {
312 try self.createRoot(allocator);
313 const node = try self.root.?.put(allocator, symbol.name);312 const node = try self.root.?.put(allocator, symbol.name);
314 node.terminal_info = .{313 node.terminal_info = .{
315 .vmaddr_offset = symbol.vmaddr_offset,314 .vmaddr_offset = symbol.vmaddr_offset,
...@@ -362,7 +361,6 @@ const ReadError = error{...@@ -362,7 +361,6 @@ const ReadError = error{
362361
363/// Parse the trie from a byte stream.362/// Parse the trie from a byte stream.
364pub fn read(self: *Trie, allocator: Allocator, reader: anytype) ReadError!usize {363pub fn read(self: *Trie, allocator: Allocator, reader: anytype) ReadError!usize {
365 try self.createRoot(allocator);
366 return self.root.?.read(allocator, reader);364 return self.root.?.read(allocator, reader);
367}365}
368366
...@@ -377,6 +375,14 @@ pub fn write(self: Trie, writer: anytype) !u64 {...@@ -377,6 +375,14 @@ pub fn write(self: Trie, writer: anytype) !u64 {
377 return counting_writer.bytes_written;375 return counting_writer.bytes_written;
378}376}
379377
378pub fn init(self: *Trie, allocator: Allocator) !void {
379 assert(self.root == null);
380 const root = try allocator.create(Node);
381 root.* = .{ .base = self };
382 self.root = root;
383 self.node_count += 1;
384}
385
380pub fn deinit(self: *Trie, allocator: Allocator) void {386pub fn deinit(self: *Trie, allocator: Allocator) void {
381 if (self.root) |root| {387 if (self.root) |root| {
382 root.deinit(allocator);388 root.deinit(allocator);
...@@ -385,19 +391,11 @@ pub fn deinit(self: *Trie, allocator: Allocator) void {...@@ -385,19 +391,11 @@ pub fn deinit(self: *Trie, allocator: Allocator) void {
385 self.ordered_nodes.deinit(allocator);391 self.ordered_nodes.deinit(allocator);
386}392}
387393
388fn createRoot(self: *Trie, allocator: Allocator) !void {
389 if (self.root == null) {
390 const root = try allocator.create(Node);
391 root.* = .{ .base = self };
392 self.root = root;
393 self.node_count += 1;
394 }
395}
396
397test "Trie node count" {394test "Trie node count" {
398 var gpa = testing.allocator;395 var gpa = testing.allocator;
399 var trie: Trie = .{};396 var trie: Trie = .{};
400 defer trie.deinit(gpa);397 defer trie.deinit(gpa);
398 try trie.init(gpa);
401399
402 try testing.expectEqual(trie.node_count, 0);400 try testing.expectEqual(trie.node_count, 0);
403 try testing.expect(trie.root == null);401 try testing.expect(trie.root == null);
...@@ -443,6 +441,7 @@ test "Trie basic" {...@@ -443,6 +441,7 @@ test "Trie basic" {
443 var gpa = testing.allocator;441 var gpa = testing.allocator;
444 var trie: Trie = .{};442 var trie: Trie = .{};
445 defer trie.deinit(gpa);443 defer trie.deinit(gpa);
444 try trie.init(gpa);
446445
447 // root --- _st ---> node446 // root --- _st ---> node
448 try trie.put(gpa, .{447 try trie.put(gpa, .{
...@@ -508,6 +507,7 @@ test "write Trie to a byte stream" {...@@ -508,6 +507,7 @@ test "write Trie to a byte stream" {
508 var gpa = testing.allocator;507 var gpa = testing.allocator;
509 var trie: Trie = .{};508 var trie: Trie = .{};
510 defer trie.deinit(gpa);509 defer trie.deinit(gpa);
510 try trie.init(gpa);
511511
512 try trie.put(gpa, .{512 try trie.put(gpa, .{
513 .name = "__mh_execute_header",513 .name = "__mh_execute_header",
...@@ -566,6 +566,7 @@ test "parse Trie from byte stream" {...@@ -566,6 +566,7 @@ test "parse Trie from byte stream" {
566 var in_stream = std.io.fixedBufferStream(&in_buffer);566 var in_stream = std.io.fixedBufferStream(&in_buffer);
567 var trie: Trie = .{};567 var trie: Trie = .{};
568 defer trie.deinit(gpa);568 defer trie.deinit(gpa);
569 try trie.init(gpa);
569 const nread = try trie.read(gpa, in_stream.reader());570 const nread = try trie.read(gpa, in_stream.reader());
570571
571 try testing.expect(nread == in_buffer.len);572 try testing.expect(nread == in_buffer.len);
...@@ -583,6 +584,7 @@ test "ordering bug" {...@@ -583,6 +584,7 @@ test "ordering bug" {
583 var gpa = testing.allocator;584 var gpa = testing.allocator;
584 var trie: Trie = .{};585 var trie: Trie = .{};
585 defer trie.deinit(gpa);586 defer trie.deinit(gpa);
587 try trie.init(gpa);
586588
587 try trie.put(gpa, .{589 try trie.put(gpa, .{
588 .name = "_asStr",590 .name = "_asStr",
src/link/MachO/zld.zig+1
...@@ -2107,6 +2107,7 @@ pub const Zld = struct {...@@ -2107,6 +2107,7 @@ pub const Zld = struct {
21072107
2108 var trie = Trie{};2108 var trie = Trie{};
2109 defer trie.deinit(gpa);2109 defer trie.deinit(gpa);
2110 try trie.init(gpa);
2110 try self.collectExportData(&trie);2111 try self.collectExportData(&trie);
21112112
2112 const link_seg = self.getLinkeditSegmentPtr();2113 const link_seg = self.getLinkeditSegmentPtr();
test/link.zig+4
...@@ -92,6 +92,10 @@ pub const cases = [_]Case{...@@ -92,6 +92,10 @@ pub const cases = [_]Case{
92 .build_root = "test/link/macho/bugs/13457",92 .build_root = "test/link/macho/bugs/13457",
93 .import = @import("link/macho/bugs/13457/build.zig"),93 .import = @import("link/macho/bugs/13457/build.zig"),
94 },94 },
95 .{
96 .build_root = "test/link/macho/bugs/16308",
97 .import = @import("link/macho/bugs/16308/build.zig"),
98 },
95 .{99 .{
96 .build_root = "test/link/macho/dead_strip",100 .build_root = "test/link/macho/dead_strip",
97 .import = @import("link/macho/dead_strip/build.zig"),101 .import = @import("link/macho/dead_strip/build.zig"),
test/link/macho/bugs/16308/build.zig created+23
...@@ -0,0 +1,23 @@
1const std = @import("std");
2
3pub const requires_symlinks = true;
4
5pub fn build(b: *std.Build) void {
6 const test_step = b.step("test", "Test it");
7 b.default_step = test_step;
8
9 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
10
11 const lib = b.addSharedLibrary(.{
12 .name = "a",
13 .root_source_file = .{ .path = "main.zig" },
14 .optimize = .Debug,
15 .target = target,
16 });
17
18 const check = lib.checkObject();
19 check.checkInSymtab();
20 check.checkNotPresent("external");
21
22 test_step.dependOn(&check.step);
23}
test/link/macho/bugs/16308/main.zig created+1
...@@ -0,0 +1 @@
1fn abc() void {}