aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-07-26 18:22:43 +0200
committerGitHub <noreply@github.com>2023-07-26 18:22:43 +0200
commitcb475aa161238ef0d77fc49b13c23f2c4b48bfc5 (patch)
tree7068693650ad4cb2da4abcd9818aa55b2f9d69e8
parent584b062a302ca10ecab4488a473440db7173bb2a (diff)
parent780f0b872a964fe4a411a603b733a3d39700ec1c (diff)
downloadzig-cb475aa161238ef0d77fc49b13c23f2c4b48bfc5.tar.gz
zig-cb475aa161238ef0d77fc49b13c23f2c4b48bfc5.zip
Merge pull request #16563 from ziglang/issues-16308
macho: create export trie root explicitly with Trie.init rather than implicitly on first Trie.put
-rw-r--r--src/link/MachO.zig1
-rw-r--r--src/link/MachO/Trie.zig24
-rw-r--r--src/link/MachO/zld.zig1
-rw-r--r--test/link.zig4
-rw-r--r--test/link/macho/bugs/16308/build.zig23
-rw-r--r--test/link/macho/bugs/16308/main.zig1
6 files changed, 43 insertions, 11 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 6953cda929..d124a1f51c 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -3227,6 +3227,7 @@ fn writeDyldInfoData(self: *MachO) !void {
var trie: Trie = .{};
defer trie.deinit(gpa);
+ try trie.init(gpa);
try self.collectExportData(&trie);
const link_seg = self.getLinkeditSegmentPtr();
diff --git a/src/link/MachO/Trie.zig b/src/link/MachO/Trie.zig
index cabe611b64..962ead72fa 100644
--- a/src/link/MachO/Trie.zig
+++ b/src/link/MachO/Trie.zig
@@ -309,7 +309,6 @@ pub const ExportSymbol = struct {
/// This operation may change the layout of the trie by splicing edges in
/// certain circumstances.
pub fn put(self: *Trie, allocator: Allocator, symbol: ExportSymbol) !void {
- try self.createRoot(allocator);
const node = try self.root.?.put(allocator, symbol.name);
node.terminal_info = .{
.vmaddr_offset = symbol.vmaddr_offset,
@@ -362,7 +361,6 @@ const ReadError = error{
/// Parse the trie from a byte stream.
pub fn read(self: *Trie, allocator: Allocator, reader: anytype) ReadError!usize {
- try self.createRoot(allocator);
return self.root.?.read(allocator, reader);
}
@@ -377,6 +375,14 @@ pub fn write(self: Trie, writer: anytype) !u64 {
return counting_writer.bytes_written;
}
+pub fn init(self: *Trie, allocator: Allocator) !void {
+ assert(self.root == null);
+ const root = try allocator.create(Node);
+ root.* = .{ .base = self };
+ self.root = root;
+ self.node_count += 1;
+}
+
pub fn deinit(self: *Trie, allocator: Allocator) void {
if (self.root) |root| {
root.deinit(allocator);
@@ -385,19 +391,11 @@ pub fn deinit(self: *Trie, allocator: Allocator) void {
self.ordered_nodes.deinit(allocator);
}
-fn createRoot(self: *Trie, allocator: Allocator) !void {
- if (self.root == null) {
- const root = try allocator.create(Node);
- root.* = .{ .base = self };
- self.root = root;
- self.node_count += 1;
- }
-}
-
test "Trie node count" {
var gpa = testing.allocator;
var trie: Trie = .{};
defer trie.deinit(gpa);
+ try trie.init(gpa);
try testing.expectEqual(trie.node_count, 0);
try testing.expect(trie.root == null);
@@ -443,6 +441,7 @@ test "Trie basic" {
var gpa = testing.allocator;
var trie: Trie = .{};
defer trie.deinit(gpa);
+ try trie.init(gpa);
// root --- _st ---> node
try trie.put(gpa, .{
@@ -508,6 +507,7 @@ test "write Trie to a byte stream" {
var gpa = testing.allocator;
var trie: Trie = .{};
defer trie.deinit(gpa);
+ try trie.init(gpa);
try trie.put(gpa, .{
.name = "__mh_execute_header",
@@ -566,6 +566,7 @@ test "parse Trie from byte stream" {
var in_stream = std.io.fixedBufferStream(&in_buffer);
var trie: Trie = .{};
defer trie.deinit(gpa);
+ try trie.init(gpa);
const nread = try trie.read(gpa, in_stream.reader());
try testing.expect(nread == in_buffer.len);
@@ -583,6 +584,7 @@ test "ordering bug" {
var gpa = testing.allocator;
var trie: Trie = .{};
defer trie.deinit(gpa);
+ try trie.init(gpa);
try trie.put(gpa, .{
.name = "_asStr",
diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig
index 3e828984a9..0ba55a217c 100644
--- a/src/link/MachO/zld.zig
+++ b/src/link/MachO/zld.zig
@@ -2107,6 +2107,7 @@ pub const Zld = struct {
var trie = Trie{};
defer trie.deinit(gpa);
+ try trie.init(gpa);
try self.collectExportData(&trie);
const link_seg = self.getLinkeditSegmentPtr();
diff --git a/test/link.zig b/test/link.zig
index ac0bcf3df8..c877e6c357 100644
--- a/test/link.zig
+++ b/test/link.zig
@@ -93,6 +93,10 @@ pub const cases = [_]Case{
.import = @import("link/macho/bugs/13457/build.zig"),
},
.{
+ .build_root = "test/link/macho/bugs/16308",
+ .import = @import("link/macho/bugs/16308/build.zig"),
+ },
+ .{
.build_root = "test/link/macho/dead_strip",
.import = @import("link/macho/dead_strip/build.zig"),
},
diff --git a/test/link/macho/bugs/16308/build.zig b/test/link/macho/bugs/16308/build.zig
new file mode 100644
index 0000000000..a6329074a0
--- /dev/null
+++ b/test/link/macho/bugs/16308/build.zig
@@ -0,0 +1,23 @@
+const std = @import("std");
+
+pub const requires_symlinks = true;
+
+pub fn build(b: *std.Build) void {
+ const test_step = b.step("test", "Test it");
+ b.default_step = test_step;
+
+ const target: std.zig.CrossTarget = .{ .os_tag = .macos };
+
+ const lib = b.addSharedLibrary(.{
+ .name = "a",
+ .root_source_file = .{ .path = "main.zig" },
+ .optimize = .Debug,
+ .target = target,
+ });
+
+ const check = lib.checkObject();
+ check.checkInSymtab();
+ check.checkNotPresent("external");
+
+ test_step.dependOn(&check.step);
+}
diff --git a/test/link/macho/bugs/16308/main.zig b/test/link/macho/bugs/16308/main.zig
new file mode 100644
index 0000000000..fd94789461
--- /dev/null
+++ b/test/link/macho/bugs/16308/main.zig
@@ -0,0 +1 @@
+fn abc() void {}