authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-22 13:58:25+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-24 18:56:48+02:00
log52a9d3f03797f1cd387ec5f2c2a1714e1121cdab
tree1115454e62a9c6afb6d7c6473b0100f05f5cb3a8
parent1ff3ebffa36a6d8f0b2489b7cbb0aceaf9189064

zld: clean up memory management and refactor


3 files changed, 44 insertions(+), 46 deletions(-)

src/link/MachO/Stub.zig+19-43
...@@ -41,6 +41,9 @@ pub fn init(allocator: *Allocator) Stub {...@@ -41,6 +41,9 @@ pub fn init(allocator: *Allocator) Stub {
41}41}
4242
43pub fn deinit(self: *Stub) void {43pub fn deinit(self: *Stub) void {
44 for (self.symbols.keys()) |key| {
45 self.allocator.free(key);
46 }
44 self.symbols.deinit(self.allocator);47 self.symbols.deinit(self.allocator);
4548
46 if (self.lib_stub) |*lib_stub| {49 if (self.lib_stub) |*lib_stub| {
...@@ -56,6 +59,18 @@ pub fn deinit(self: *Stub) void {...@@ -56,6 +59,18 @@ pub fn deinit(self: *Stub) void {
56 }59 }
57}60}
5861
62fn addObjCClassSymbols(self: *Stub, sym_name: []const u8) !void {
63 const expanded = &[_][]const u8{
64 try std.fmt.allocPrint(self.allocator, "_OBJC_CLASS_$_{s}", .{sym_name}),
65 try std.fmt.allocPrint(self.allocator, "_OBJC_METACLASS_$_{s}", .{sym_name}),
66 };
67
68 for (expanded) |sym| {
69 if (self.symbols.contains(sym)) continue;
70 try self.symbols.putNoClobber(self.allocator, sym, .{});
71 }
72}
73
59pub fn parse(self: *Stub) !void {74pub fn parse(self: *Stub) !void {
60 const lib_stub = self.lib_stub orelse return error.EmptyStubFile;75 const lib_stub = self.lib_stub orelse return error.EmptyStubFile;
61 if (lib_stub.inner.len == 0) return error.EmptyStubFile;76 if (lib_stub.inner.len == 0) return error.EmptyStubFile;
...@@ -87,32 +102,13 @@ pub fn parse(self: *Stub) !void {...@@ -87,32 +102,13 @@ pub fn parse(self: *Stub) !void {
87 if (exp.symbols) |symbols| {102 if (exp.symbols) |symbols| {
88 for (symbols) |sym_name| {103 for (symbols) |sym_name| {
89 if (self.symbols.contains(sym_name)) continue;104 if (self.symbols.contains(sym_name)) continue;
90 try self.symbols.putNoClobber(self.allocator, sym_name, {});105 try self.symbols.putNoClobber(self.allocator, try self.allocator.dupe(u8, sym_name), {});
91 }106 }
92 }107 }
93108
94 if (exp.objc_classes) |classes| {109 if (exp.objc_classes) |classes| {
95 for (classes) |sym_name| {110 for (classes) |sym_name| {
96 log.debug(" | {s}", .{sym_name});111 try self.addObjCClassSymbols(sym_name);
97 {
98 const actual_sym_name = try std.fmt.allocPrint(
99 self.allocator,
100 "_OBJC_CLASS_$_{s}",
101 .{sym_name},
102 );
103 if (self.symbols.contains(actual_sym_name)) continue;
104 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
105 }
106
107 {
108 const actual_sym_name = try std.fmt.allocPrint(
109 self.allocator,
110 "_OBJC_METACLASS_$_{s}",
111 .{sym_name},
112 );
113 if (self.symbols.contains(actual_sym_name)) continue;
114 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
115 }
116 }112 }
117 }113 }
118 }114 }
...@@ -124,34 +120,14 @@ pub fn parse(self: *Stub) !void {...@@ -124,34 +120,14 @@ pub fn parse(self: *Stub) !void {
124120
125 for (reexp.symbols) |sym_name| {121 for (reexp.symbols) |sym_name| {
126 if (self.symbols.contains(sym_name)) continue;122 if (self.symbols.contains(sym_name)) continue;
127 try self.symbols.putNoClobber(self.allocator, sym_name, {});123 try self.symbols.putNoClobber(self.allocator, try self.allocator.dupe(u8, sym_name), {});
128 }124 }
129 }125 }
130 }126 }
131127
132 if (stub.objc_classes) |classes| {128 if (stub.objc_classes) |classes| {
133 log.debug(" | objc_classes", .{});
134 for (classes) |sym_name| {129 for (classes) |sym_name| {
135 log.debug(" | {s}", .{sym_name});130 try self.addObjCClassSymbols(sym_name);
136 {
137 const actual_sym_name = try std.fmt.allocPrint(
138 self.allocator,
139 "_OBJC_CLASS_$_{s}",
140 .{sym_name},
141 );
142 if (self.symbols.contains(actual_sym_name)) continue;
143 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
144 }
145
146 {
147 const actual_sym_name = try std.fmt.allocPrint(
148 self.allocator,
149 "_OBJC_METACLASS_$_{s}",
150 .{sym_name},
151 );
152 if (self.symbols.contains(actual_sym_name)) continue;
153 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
154 }
155 }131 }
156 }132 }
157 }133 }
src/link/MachO/Symbol.zig+18
...@@ -74,6 +74,8 @@ pub const Regular = struct {...@@ -74,6 +74,8 @@ pub const Regular = struct {
74 global,74 global,
75 };75 };
7676
77 pub fn deinit(regular: *Regular, allocator: *Allocator) void {}
78
77 pub fn isTemp(regular: *Regular) bool {79 pub fn isTemp(regular: *Regular) bool {
78 if (regular.linkage == .translation_unit) {80 if (regular.linkage == .translation_unit) {
79 return mem.startsWith(u8, regular.base.name, "l") or mem.startsWith(u8, regular.base.name, "L");81 return mem.startsWith(u8, regular.base.name, "l") or mem.startsWith(u8, regular.base.name, "L");
...@@ -85,6 +87,8 @@ pub const Regular = struct {...@@ -85,6 +87,8 @@ pub const Regular = struct {
85pub const Proxy = struct {87pub const Proxy = struct {
86 base: Symbol,88 base: Symbol,
8789
90 /// Dynamic binding info - spots within the final
91 /// executable where this proxy is referenced from.
88 bind_info: std.ArrayListUnmanaged(struct {92 bind_info: std.ArrayListUnmanaged(struct {
89 segment_id: u16,93 segment_id: u16,
90 address: u64,94 address: u64,
...@@ -99,6 +103,10 @@ pub const Proxy = struct {...@@ -99,6 +103,10 @@ pub const Proxy = struct {
99103
100 pub const base_type: Symbol.Type = .proxy;104 pub const base_type: Symbol.Type = .proxy;
101105
106 pub fn deinit(proxy: *Proxy, allocator: *Allocator) void {
107 proxy.bind_info.deinit(allocator);
108 }
109
102 pub fn dylibOrdinal(proxy: *Proxy) u16 {110 pub fn dylibOrdinal(proxy: *Proxy) u16 {
103 const file = proxy.file orelse return 0;111 const file = proxy.file orelse return 0;
104 return switch (file) {112 return switch (file) {
...@@ -115,6 +123,8 @@ pub const Unresolved = struct {...@@ -115,6 +123,8 @@ pub const Unresolved = struct {
115 file: *Object,123 file: *Object,
116124
117 pub const base_type: Symbol.Type = .unresolved;125 pub const base_type: Symbol.Type = .unresolved;
126
127 pub fn deinit(unresolved: *Unresolved, allocator: *Allocator) void {}
118};128};
119129
120pub const Tentative = struct {130pub const Tentative = struct {
...@@ -130,10 +140,18 @@ pub const Tentative = struct {...@@ -130,10 +140,18 @@ pub const Tentative = struct {
130 file: *Object,140 file: *Object,
131141
132 pub const base_type: Symbol.Type = .tentative;142 pub const base_type: Symbol.Type = .tentative;
143
144 pub fn deinit(tentative: *Tentative, allocator: *Allocator) void {}
133};145};
134146
135pub fn deinit(base: *Symbol, allocator: *Allocator) void {147pub fn deinit(base: *Symbol, allocator: *Allocator) void {
136 allocator.free(base.name);148 allocator.free(base.name);
149 switch (base.@"type") {
150 .regular => @fieldParentPtr(Regular, "base", base).deinit(allocator),
151 .proxy => @fieldParentPtr(Proxy, "base", base).deinit(allocator),
152 .unresolved => @fieldParentPtr(Unresolved, "base", base).deinit(allocator),
153 .tentative => @fieldParentPtr(Tentative, "base", base).deinit(allocator),
154 }
137}155}
138156
139pub fn cast(base: *Symbol, comptime T: type) ?*T {157pub fn cast(base: *Symbol, comptime T: type) ?*T {
src/link/MachO/Zld.zig+7-3
...@@ -263,7 +263,7 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: L...@@ -263,7 +263,7 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: L
263 self.allocateLinkeditSegment();263 self.allocateLinkeditSegment();
264 try self.allocateSymbols();264 try self.allocateSymbols();
265 try self.allocateTentativeSymbols();265 try self.allocateTentativeSymbols();
266 try self.allocateProxiesBindAddresses();266 try self.allocateProxyBindAddresses();
267 try self.flush();267 try self.flush();
268}268}
269269
...@@ -1347,7 +1347,7 @@ fn allocateTentativeSymbols(self: *Zld) !void {...@@ -1347,7 +1347,7 @@ fn allocateTentativeSymbols(self: *Zld) !void {
1347 }1347 }
1348}1348}
13491349
1350fn allocateProxiesBindAddresses(self: *Zld) !void {1350fn allocateProxyBindAddresses(self: *Zld) !void {
1351 for (self.objects.items) |object| {1351 for (self.objects.items) |object| {
1352 for (object.sections.items) |sect| {1352 for (object.sections.items) |sect| {
1353 const relocs = sect.relocs orelse continue;1353 const relocs = sect.relocs orelse continue;
...@@ -1361,6 +1361,7 @@ fn allocateProxiesBindAddresses(self: *Zld) !void {...@@ -1361,6 +1361,7 @@ fn allocateProxiesBindAddresses(self: *Zld) !void {
1361 const target_map = sect.target_map orelse continue;1361 const target_map = sect.target_map orelse continue;
1362 const target_seg = self.load_commands.items[target_map.segment_id].Segment;1362 const target_seg = self.load_commands.items[target_map.segment_id].Segment;
1363 const target_sect = target_seg.sections.items[target_map.section_id];1363 const target_sect = target_seg.sections.items[target_map.section_id];
1364
1364 try proxy.bind_info.append(self.allocator, .{1365 try proxy.bind_info.append(self.allocator, .{
1365 .segment_id = target_map.segment_id,1366 .segment_id = target_map.segment_id,
1366 .address = target_sect.addr + target_map.offset + rel.offset,1367 .address = target_sect.addr + target_map.offset + rel.offset,
...@@ -2119,7 +2120,10 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T...@@ -2119,7 +2120,10 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T
2119 if (proxy.bind_info.items.len > 0) {2120 if (proxy.bind_info.items.len > 0) {
2120 break :blk 0; // Dynamically bound by dyld.2121 break :blk 0; // Dynamically bound by dyld.
2121 }2122 }
2122 log.err("expected stubs index or dynamic bind address when relocating symbol '{s}'", .{final.name});2123 log.err(
2124 "expected stubs index or dynamic bind address when relocating symbol '{s}'",
2125 .{final.name},
2126 );
2123 log.err("this is an internal linker error", .{});2127 log.err("this is an internal linker error", .{});
2124 return error.FailedToResolveRelocationTarget;2128 return error.FailedToResolveRelocationTarget;
2125 };2129 };