authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-02 17:40:39+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-02 19:49:32+02:00
logf3b328ee8cb9c8340afaec510055d41aa4895583
tree3de9a1b39c03965b6f353d87144f16d712405a77
parent159cd528b164f77177e71309dee9fa79d2d5f4f4

macho: refactor tracking of referenced dylibs

Now, index in the global referenced array hashmap is equivalent to the dylib's ordinal in the final linked image.

2 files changed, 38 insertions(+), 36 deletions(-)

src/link/MachO.zig+38-34
...@@ -63,9 +63,9 @@ entry_addr: ?u64 = null,...@@ -63,9 +63,9 @@ entry_addr: ?u64 = null,
6363
64objects: std.ArrayListUnmanaged(Object) = .{},64objects: std.ArrayListUnmanaged(Object) = .{},
65archives: std.ArrayListUnmanaged(Archive) = .{},65archives: std.ArrayListUnmanaged(Archive) = .{},
66dylibs: std.ArrayListUnmanaged(Dylib) = .{},
6766
68next_dylib_ordinal: u16 = 1,67dylibs: std.ArrayListUnmanaged(Dylib) = .{},
68referenced_dylibs: std.AutoArrayHashMapUnmanaged(u16, void) = .{},
6969
70load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},70load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},
7171
...@@ -929,6 +929,17 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -929,6 +929,17 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
929 else => unreachable,929 else => unreachable,
930 };930 };
931931
932 // TODO mimicking insertion of null symbol from incremental linker.
933 // This will need to moved.
934 try self.locals.append(self.base.allocator, .{
935 .n_strx = 0,
936 .n_type = macho.N_UNDF,
937 .n_sect = 0,
938 .n_desc = 0,
939 .n_value = 0,
940 });
941 try self.strtab.append(self.base.allocator, 0);
942
932 // Initialize section ordinals with null ordinal pointing at943 // Initialize section ordinals with null ordinal pointing at
933 // PAGEZERO segment.944 // PAGEZERO segment.
934 try self.section_ordinals.append(self.base.allocator, .{945 try self.section_ordinals.append(self.base.allocator, .{
...@@ -958,7 +969,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -958,7 +969,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
958 }969 }
959970
960 try self.sortSections();971 try self.sortSections();
961 try self.addRpaths(rpaths.items);972 try self.addRpathLCs(rpaths.items);
973 try self.addLoadDylibLCs();
962 try self.addDataInCodeLC();974 try self.addDataInCodeLC();
963 try self.addCodeSignatureLC();975 try self.addCodeSignatureLC();
964 try self.allocateTextSegment();976 try self.allocateTextSegment();
...@@ -2196,17 +2208,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {...@@ -2196,17 +2208,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
2196}2208}
21972209
2198fn resolveSymbols(self: *MachO) !void {2210fn resolveSymbols(self: *MachO) !void {
2199 // TODO mimicking insertion of null symbol from incremental linker.
2200 // This will need to moved.
2201 try self.locals.append(self.base.allocator, .{
2202 .n_strx = 0,
2203 .n_type = macho.N_UNDF,
2204 .n_sect = 0,
2205 .n_desc = 0,
2206 .n_value = 0,
2207 });
2208 try self.strtab.append(self.base.allocator, 0);
2209
2210 // First pass, resolve symbols in provided objects.2211 // First pass, resolve symbols in provided objects.
2211 for (self.objects.items) |_, object_id| {2212 for (self.objects.items) |_, object_id| {
2212 try self.resolveSymbolsInObject(@intCast(u16, object_id));2213 try self.resolveSymbolsInObject(@intCast(u16, object_id));
...@@ -2335,9 +2336,6 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2335,9 +2336,6 @@ fn resolveSymbols(self: *MachO) !void {
2335 });2336 });
2336 }2337 }
23372338
2338 var referenced = std.AutoHashMap(u16, void).init(self.base.allocator);
2339 defer referenced.deinit();
2340
2341 loop: for (self.undefs.items) |sym| {2339 loop: for (self.undefs.items) |sym| {
2342 if (symbolIsNull(sym)) continue;2340 if (symbolIsNull(sym)) continue;
23432341
...@@ -2345,23 +2343,12 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2345,23 +2343,12 @@ fn resolveSymbols(self: *MachO) !void {
2345 for (self.dylibs.items) |*dylib, id| {2343 for (self.dylibs.items) |*dylib, id| {
2346 if (!dylib.symbols.contains(sym_name)) continue;2344 if (!dylib.symbols.contains(sym_name)) continue;
23472345
2348 if (!referenced.contains(@intCast(u16, id))) {2346 const dylib_id = @intCast(u16, id);
2349 // Add LC_LOAD_DYLIB load command for each referenced dylib/stub.2347 if (!self.referenced_dylibs.contains(dylib_id)) {
2350 dylib.ordinal = self.next_dylib_ordinal;2348 try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});
2351 const dylib_id = dylib.id orelse unreachable;
2352 var dylib_cmd = try commands.createLoadDylibCommand(
2353 self.base.allocator,
2354 dylib_id.name,
2355 dylib_id.timestamp,
2356 dylib_id.current_version,
2357 dylib_id.compatibility_version,
2358 );
2359 errdefer dylib_cmd.deinit(self.base.allocator);
2360 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
2361 self.next_dylib_ordinal += 1;
2362 try referenced.putNoClobber(@intCast(u16, id), {});
2363 }2349 }
23642350
2351 const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable;
2365 const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable;2352 const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable;
2366 const undef = &self.undefs.items[resolv.where_index];2353 const undef = &self.undefs.items[resolv.where_index];
2367 const import_sym_index = @intCast(u32, self.imports.items.len);2354 const import_sym_index = @intCast(u32, self.imports.items.len);
...@@ -2369,7 +2356,7 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2369,7 +2356,7 @@ fn resolveSymbols(self: *MachO) !void {
2369 .n_strx = undef.n_strx,2356 .n_strx = undef.n_strx,
2370 .n_type = macho.N_UNDF | macho.N_EXT,2357 .n_type = macho.N_UNDF | macho.N_EXT,
2371 .n_sect = 0,2358 .n_sect = 0,
2372 .n_desc = packDylibOrdinal(dylib.ordinal.?),2359 .n_desc = packDylibOrdinal(@intCast(u16, ordinal + 1)),
2373 .n_value = 0,2360 .n_value = 0,
2374 });2361 });
2375 resolv.* = .{2362 resolv.* = .{
...@@ -2804,7 +2791,7 @@ fn addCodeSignatureLC(self: *MachO) !void {...@@ -2804,7 +2791,7 @@ fn addCodeSignatureLC(self: *MachO) !void {
2804 }2791 }
2805}2792}
28062793
2807fn addRpaths(self: *MachO, rpaths: []const []const u8) !void {2794fn addRpathLCs(self: *MachO, rpaths: []const []const u8) !void {
2808 for (rpaths) |rpath| {2795 for (rpaths) |rpath| {
2809 const cmdsize = @intCast(u32, mem.alignForwardGeneric(2796 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
2810 u64,2797 u64,
...@@ -2823,6 +2810,22 @@ fn addRpaths(self: *MachO, rpaths: []const []const u8) !void {...@@ -2823,6 +2810,22 @@ fn addRpaths(self: *MachO, rpaths: []const []const u8) !void {
2823 }2810 }
2824}2811}
28252812
2813fn addLoadDylibLCs(self: *MachO) !void {
2814 for (self.referenced_dylibs.keys()) |id| {
2815 const dylib = self.dylibs.items[id];
2816 const dylib_id = dylib.id orelse unreachable;
2817 var dylib_cmd = try commands.createLoadDylibCommand(
2818 self.base.allocator,
2819 dylib_id.name,
2820 dylib_id.timestamp,
2821 dylib_id.current_version,
2822 dylib_id.compatibility_version,
2823 );
2824 errdefer dylib_cmd.deinit(self.base.allocator);
2825 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
2826 }
2827}
2828
2826fn flushZld(self: *MachO) !void {2829fn flushZld(self: *MachO) !void {
2827 self.load_commands_dirty = true;2830 self.load_commands_dirty = true;
2828 try self.writeTextBlocks();2831 try self.writeTextBlocks();
...@@ -3353,6 +3356,7 @@ pub fn deinit(self: *MachO) void {...@@ -3353,6 +3356,7 @@ pub fn deinit(self: *MachO) void {
3353 dylib.deinit(self.base.allocator);3356 dylib.deinit(self.base.allocator);
3354 }3357 }
3355 self.dylibs.deinit(self.base.allocator);3358 self.dylibs.deinit(self.base.allocator);
3359 self.referenced_dylibs.deinit(self.base.allocator);
33563360
3357 for (self.load_commands.items) |*lc| {3361 for (self.load_commands.items) |*lc| {
3358 lc.deinit(self.base.allocator);3362 lc.deinit(self.base.allocator);
src/link/MachO/Dylib.zig-2
...@@ -22,8 +22,6 @@ name: []const u8,...@@ -22,8 +22,6 @@ name: []const u8,
2222
23header: ?macho.mach_header_64 = null,23header: ?macho.mach_header_64 = null,
2424
25ordinal: ?u16 = null,
26
27// The actual dylib contents we care about linking with will be embedded at25// The actual dylib contents we care about linking with will be embedded at
28// an offset within a file if we are linking against a fat lib26// an offset within a file if we are linking against a fat lib
29library_offset: u64 = 0,27library_offset: u64 = 0,