diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-06-22 13:58:25 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2021-06-24 18:56:48 +0200 |
| commit | 52a9d3f03797f1cd387ec5f2c2a1714e1121cdab (patch) | |
| tree | 1115454e62a9c6afb6d7c6473b0100f05f5cb3a8 /src | |
| parent | 1ff3ebffa36a6d8f0b2489b7cbb0aceaf9189064 (diff) | |
| download | zig-52a9d3f03797f1cd387ec5f2c2a1714e1121cdab.tar.gz zig-52a9d3f03797f1cd387ec5f2c2a1714e1121cdab.zip | |
zld: clean up memory management and refactor
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO/Stub.zig | 62 | ||||
| -rw-r--r-- | src/link/MachO/Symbol.zig | 18 | ||||
| -rw-r--r-- | src/link/MachO/Zld.zig | 10 |
3 files changed, 44 insertions, 46 deletions
diff --git a/src/link/MachO/Stub.zig b/src/link/MachO/Stub.zig index d71c454c79..40ed63b673 100644 --- a/src/link/MachO/Stub.zig +++ b/src/link/MachO/Stub.zig @@ -41,6 +41,9 @@ pub fn init(allocator: *Allocator) Stub { } pub fn deinit(self: *Stub) void { + for (self.symbols.keys()) |key| { + self.allocator.free(key); + } self.symbols.deinit(self.allocator); if (self.lib_stub) |*lib_stub| { @@ -56,6 +59,18 @@ pub fn deinit(self: *Stub) void { } } +fn addObjCClassSymbols(self: *Stub, sym_name: []const u8) !void { + const expanded = &[_][]const u8{ + try std.fmt.allocPrint(self.allocator, "_OBJC_CLASS_$_{s}", .{sym_name}), + try std.fmt.allocPrint(self.allocator, "_OBJC_METACLASS_$_{s}", .{sym_name}), + }; + + for (expanded) |sym| { + if (self.symbols.contains(sym)) continue; + try self.symbols.putNoClobber(self.allocator, sym, .{}); + } +} + pub fn parse(self: *Stub) !void { const lib_stub = self.lib_stub orelse return error.EmptyStubFile; if (lib_stub.inner.len == 0) return error.EmptyStubFile; @@ -87,32 +102,13 @@ pub fn parse(self: *Stub) !void { if (exp.symbols) |symbols| { for (symbols) |sym_name| { if (self.symbols.contains(sym_name)) continue; - try self.symbols.putNoClobber(self.allocator, sym_name, {}); + try self.symbols.putNoClobber(self.allocator, try self.allocator.dupe(u8, sym_name), {}); } } if (exp.objc_classes) |classes| { for (classes) |sym_name| { - log.debug(" | {s}", .{sym_name}); - { - const actual_sym_name = try std.fmt.allocPrint( - self.allocator, - "_OBJC_CLASS_$_{s}", - .{sym_name}, - ); - if (self.symbols.contains(actual_sym_name)) continue; - try self.symbols.putNoClobber(self.allocator, actual_sym_name, {}); - } - - { - const actual_sym_name = try std.fmt.allocPrint( - self.allocator, - "_OBJC_METACLASS_$_{s}", - .{sym_name}, - ); - if (self.symbols.contains(actual_sym_name)) continue; - try self.symbols.putNoClobber(self.allocator, actual_sym_name, {}); - } + try self.addObjCClassSymbols(sym_name); } } } @@ -124,34 +120,14 @@ pub fn parse(self: *Stub) !void { for (reexp.symbols) |sym_name| { if (self.symbols.contains(sym_name)) continue; - try self.symbols.putNoClobber(self.allocator, sym_name, {}); + try self.symbols.putNoClobber(self.allocator, try self.allocator.dupe(u8, sym_name), {}); } } } if (stub.objc_classes) |classes| { - log.debug(" | objc_classes", .{}); for (classes) |sym_name| { - log.debug(" | {s}", .{sym_name}); - { - const actual_sym_name = try std.fmt.allocPrint( - self.allocator, - "_OBJC_CLASS_$_{s}", - .{sym_name}, - ); - if (self.symbols.contains(actual_sym_name)) continue; - try self.symbols.putNoClobber(self.allocator, actual_sym_name, {}); - } - - { - const actual_sym_name = try std.fmt.allocPrint( - self.allocator, - "_OBJC_METACLASS_$_{s}", - .{sym_name}, - ); - if (self.symbols.contains(actual_sym_name)) continue; - try self.symbols.putNoClobber(self.allocator, actual_sym_name, {}); - } + try self.addObjCClassSymbols(sym_name); } } } diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig index 01fcd15984..b2e7867ca3 100644 --- a/src/link/MachO/Symbol.zig +++ b/src/link/MachO/Symbol.zig @@ -74,6 +74,8 @@ pub const Regular = struct { global, }; + pub fn deinit(regular: *Regular, allocator: *Allocator) void {} + pub fn isTemp(regular: *Regular) bool { if (regular.linkage == .translation_unit) { return mem.startsWith(u8, regular.base.name, "l") or mem.startsWith(u8, regular.base.name, "L"); @@ -85,6 +87,8 @@ pub const Regular = struct { pub const Proxy = struct { base: Symbol, + /// Dynamic binding info - spots within the final + /// executable where this proxy is referenced from. bind_info: std.ArrayListUnmanaged(struct { segment_id: u16, address: u64, @@ -99,6 +103,10 @@ pub const Proxy = struct { pub const base_type: Symbol.Type = .proxy; + pub fn deinit(proxy: *Proxy, allocator: *Allocator) void { + proxy.bind_info.deinit(allocator); + } + pub fn dylibOrdinal(proxy: *Proxy) u16 { const file = proxy.file orelse return 0; return switch (file) { @@ -115,6 +123,8 @@ pub const Unresolved = struct { file: *Object, pub const base_type: Symbol.Type = .unresolved; + + pub fn deinit(unresolved: *Unresolved, allocator: *Allocator) void {} }; pub const Tentative = struct { @@ -130,10 +140,18 @@ pub const Tentative = struct { file: *Object, pub const base_type: Symbol.Type = .tentative; + + pub fn deinit(tentative: *Tentative, allocator: *Allocator) void {} }; pub fn deinit(base: *Symbol, allocator: *Allocator) void { allocator.free(base.name); + switch (base.@"type") { + .regular => @fieldParentPtr(Regular, "base", base).deinit(allocator), + .proxy => @fieldParentPtr(Proxy, "base", base).deinit(allocator), + .unresolved => @fieldParentPtr(Unresolved, "base", base).deinit(allocator), + .tentative => @fieldParentPtr(Tentative, "base", base).deinit(allocator), + } } pub fn cast(base: *Symbol, comptime T: type) ?*T { diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index c229fe9742..f2c0fbf718 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -263,7 +263,7 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: L self.allocateLinkeditSegment(); try self.allocateSymbols(); try self.allocateTentativeSymbols(); - try self.allocateProxiesBindAddresses(); + try self.allocateProxyBindAddresses(); try self.flush(); } @@ -1347,7 +1347,7 @@ fn allocateTentativeSymbols(self: *Zld) !void { } } -fn allocateProxiesBindAddresses(self: *Zld) !void { +fn allocateProxyBindAddresses(self: *Zld) !void { for (self.objects.items) |object| { for (object.sections.items) |sect| { const relocs = sect.relocs orelse continue; @@ -1361,6 +1361,7 @@ fn allocateProxiesBindAddresses(self: *Zld) !void { const target_map = sect.target_map orelse continue; const target_seg = self.load_commands.items[target_map.segment_id].Segment; const target_sect = target_seg.sections.items[target_map.section_id]; + try proxy.bind_info.append(self.allocator, .{ .segment_id = target_map.segment_id, .address = target_sect.addr + target_map.offset + rel.offset, @@ -2119,7 +2120,10 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T if (proxy.bind_info.items.len > 0) { break :blk 0; // Dynamically bound by dyld. } - log.err("expected stubs index or dynamic bind address when relocating symbol '{s}'", .{final.name}); + log.err( + "expected stubs index or dynamic bind address when relocating symbol '{s}'", + .{final.name}, + ); log.err("this is an internal linker error", .{}); return error.FailedToResolveRelocationTarget; }; |
