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 {
32273227
32283228 var trie: Trie = .{};
32293229 defer trie.deinit(gpa);
3230 try trie.init(gpa);
32303231 try self.collectExportData(&trie);
32313232
32323233 const link_seg = self.getLinkeditSegmentPtr();
src/link/MachO/Trie.zig+13-11
......@@ -309,7 +309,6 @@ pub const ExportSymbol = struct {
309309/// This operation may change the layout of the trie by splicing edges in
310310/// certain circumstances.
311311pub fn put(self: *Trie, allocator: Allocator, symbol: ExportSymbol) !void {
312 try self.createRoot(allocator);
313312 const node = try self.root.?.put(allocator, symbol.name);
314313 node.terminal_info = .{
315314 .vmaddr_offset = symbol.vmaddr_offset,
......@@ -362,7 +361,6 @@ const ReadError = error{
362361
363362/// Parse the trie from a byte stream.
364363pub fn read(self: *Trie, allocator: Allocator, reader: anytype) ReadError!usize {
365 try self.createRoot(allocator);
366364 return self.root.?.read(allocator, reader);
367365}
368366
......@@ -377,6 +375,14 @@ pub fn write(self: Trie, writer: anytype) !u64 {
377375 return counting_writer.bytes_written;
378376}
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
380386pub fn deinit(self: *Trie, allocator: Allocator) void {
381387 if (self.root) |root| {
382388 root.deinit(allocator);
......@@ -385,19 +391,11 @@ pub fn deinit(self: *Trie, allocator: Allocator) void {
385391 self.ordered_nodes.deinit(allocator);
386392}
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
397394test "Trie node count" {
398395 var gpa = testing.allocator;
399396 var trie: Trie = .{};
400397 defer trie.deinit(gpa);
398 try trie.init(gpa);
401399
402400 try testing.expectEqual(trie.node_count, 0);
403401 try testing.expect(trie.root == null);
......@@ -443,6 +441,7 @@ test "Trie basic" {
443441 var gpa = testing.allocator;
444442 var trie: Trie = .{};
445443 defer trie.deinit(gpa);
444 try trie.init(gpa);
446445
447446 // root --- _st ---> node
448447 try trie.put(gpa, .{
......@@ -508,6 +507,7 @@ test "write Trie to a byte stream" {
508507 var gpa = testing.allocator;
509508 var trie: Trie = .{};
510509 defer trie.deinit(gpa);
510 try trie.init(gpa);
511511
512512 try trie.put(gpa, .{
513513 .name = "__mh_execute_header",
......@@ -566,6 +566,7 @@ test "parse Trie from byte stream" {
566566 var in_stream = std.io.fixedBufferStream(&in_buffer);
567567 var trie: Trie = .{};
568568 defer trie.deinit(gpa);
569 try trie.init(gpa);
569570 const nread = try trie.read(gpa, in_stream.reader());
570571
571572 try testing.expect(nread == in_buffer.len);
......@@ -583,6 +584,7 @@ test "ordering bug" {
583584 var gpa = testing.allocator;
584585 var trie: Trie = .{};
585586 defer trie.deinit(gpa);
587 try trie.init(gpa);
586588
587589 try trie.put(gpa, .{
588590 .name = "_asStr",
src/link/MachO/zld.zig+1
......@@ -2107,6 +2107,7 @@ pub const Zld = struct {
21072107
21082108 var trie = Trie{};
21092109 defer trie.deinit(gpa);
2110 try trie.init(gpa);
21102111 try self.collectExportData(&trie);
21112112
21122113 const link_seg = self.getLinkeditSegmentPtr();
test/link.zig+4
......@@ -92,6 +92,10 @@ pub const cases = [_]Case{
9292 .build_root = "test/link/macho/bugs/13457",
9393 .import = @import("link/macho/bugs/13457/build.zig"),
9494 },
95 .{
96 .build_root = "test/link/macho/bugs/16308",
97 .import = @import("link/macho/bugs/16308/build.zig"),
98 },
9599 .{
96100 .build_root = "test/link/macho/dead_strip",
97101 .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 {}