diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-08-02 17:40:39 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2021-08-02 19:49:32 +0200 |
| commit | f3b328ee8cb9c8340afaec510055d41aa4895583 (patch) | |
| tree | 3de9a1b39c03965b6f353d87144f16d712405a77 /src/link | |
| parent | 159cd528b164f77177e71309dee9fa79d2d5f4f4 (diff) | |
| download | zig-f3b328ee8cb9c8340afaec510055d41aa4895583.tar.gz zig-f3b328ee8cb9c8340afaec510055d41aa4895583.zip | |
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.
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/MachO.zig | 72 | ||||
| -rw-r--r-- | src/link/MachO/Dylib.zig | 2 |
2 files changed, 38 insertions, 36 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 61b2ff888c..bfc0ab8ff6 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -63,9 +63,9 @@ entry_addr: ?u64 = null, objects: std.ArrayListUnmanaged(Object) = .{}, archives: std.ArrayListUnmanaged(Archive) = .{}, -dylibs: std.ArrayListUnmanaged(Dylib) = .{}, -next_dylib_ordinal: u16 = 1, +dylibs: std.ArrayListUnmanaged(Dylib) = .{}, +referenced_dylibs: std.AutoArrayHashMapUnmanaged(u16, void) = .{}, load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, @@ -929,6 +929,17 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { else => unreachable, }; + // TODO mimicking insertion of null symbol from incremental linker. + // This will need to moved. + try self.locals.append(self.base.allocator, .{ + .n_strx = 0, + .n_type = macho.N_UNDF, + .n_sect = 0, + .n_desc = 0, + .n_value = 0, + }); + try self.strtab.append(self.base.allocator, 0); + // Initialize section ordinals with null ordinal pointing at // PAGEZERO segment. try self.section_ordinals.append(self.base.allocator, .{ @@ -958,7 +969,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { } try self.sortSections(); - try self.addRpaths(rpaths.items); + try self.addRpathLCs(rpaths.items); + try self.addLoadDylibLCs(); try self.addDataInCodeLC(); try self.addCodeSignatureLC(); try self.allocateTextSegment(); @@ -2196,17 +2208,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { } fn resolveSymbols(self: *MachO) !void { - // TODO mimicking insertion of null symbol from incremental linker. - // This will need to moved. - try self.locals.append(self.base.allocator, .{ - .n_strx = 0, - .n_type = macho.N_UNDF, - .n_sect = 0, - .n_desc = 0, - .n_value = 0, - }); - try self.strtab.append(self.base.allocator, 0); - // First pass, resolve symbols in provided objects. for (self.objects.items) |_, object_id| { try self.resolveSymbolsInObject(@intCast(u16, object_id)); @@ -2335,9 +2336,6 @@ fn resolveSymbols(self: *MachO) !void { }); } - var referenced = std.AutoHashMap(u16, void).init(self.base.allocator); - defer referenced.deinit(); - loop: for (self.undefs.items) |sym| { if (symbolIsNull(sym)) continue; @@ -2345,23 +2343,12 @@ fn resolveSymbols(self: *MachO) !void { for (self.dylibs.items) |*dylib, id| { if (!dylib.symbols.contains(sym_name)) continue; - if (!referenced.contains(@intCast(u16, id))) { - // Add LC_LOAD_DYLIB load command for each referenced dylib/stub. - dylib.ordinal = self.next_dylib_ordinal; - const dylib_id = dylib.id orelse unreachable; - var dylib_cmd = try commands.createLoadDylibCommand( - self.base.allocator, - dylib_id.name, - dylib_id.timestamp, - dylib_id.current_version, - dylib_id.compatibility_version, - ); - errdefer dylib_cmd.deinit(self.base.allocator); - try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd }); - self.next_dylib_ordinal += 1; - try referenced.putNoClobber(@intCast(u16, id), {}); + const dylib_id = @intCast(u16, id); + if (!self.referenced_dylibs.contains(dylib_id)) { + try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {}); } + const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable; const undef = &self.undefs.items[resolv.where_index]; const import_sym_index = @intCast(u32, self.imports.items.len); @@ -2369,7 +2356,7 @@ fn resolveSymbols(self: *MachO) !void { .n_strx = undef.n_strx, .n_type = macho.N_UNDF | macho.N_EXT, .n_sect = 0, - .n_desc = packDylibOrdinal(dylib.ordinal.?), + .n_desc = packDylibOrdinal(@intCast(u16, ordinal + 1)), .n_value = 0, }); resolv.* = .{ @@ -2804,7 +2791,7 @@ fn addCodeSignatureLC(self: *MachO) !void { } } -fn addRpaths(self: *MachO, rpaths: []const []const u8) !void { +fn addRpathLCs(self: *MachO, rpaths: []const []const u8) !void { for (rpaths) |rpath| { const cmdsize = @intCast(u32, mem.alignForwardGeneric( u64, @@ -2823,6 +2810,22 @@ fn addRpaths(self: *MachO, rpaths: []const []const u8) !void { } } +fn addLoadDylibLCs(self: *MachO) !void { + for (self.referenced_dylibs.keys()) |id| { + const dylib = self.dylibs.items[id]; + const dylib_id = dylib.id orelse unreachable; + var dylib_cmd = try commands.createLoadDylibCommand( + self.base.allocator, + dylib_id.name, + dylib_id.timestamp, + dylib_id.current_version, + dylib_id.compatibility_version, + ); + errdefer dylib_cmd.deinit(self.base.allocator); + try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd }); + } +} + fn flushZld(self: *MachO) !void { self.load_commands_dirty = true; try self.writeTextBlocks(); @@ -3353,6 +3356,7 @@ pub fn deinit(self: *MachO) void { dylib.deinit(self.base.allocator); } self.dylibs.deinit(self.base.allocator); + self.referenced_dylibs.deinit(self.base.allocator); for (self.load_commands.items) |*lc| { lc.deinit(self.base.allocator); diff --git a/src/link/MachO/Dylib.zig b/src/link/MachO/Dylib.zig index 7b2f94ba67..1d2833c764 100644 --- a/src/link/MachO/Dylib.zig +++ b/src/link/MachO/Dylib.zig @@ -22,8 +22,6 @@ name: []const u8, header: ?macho.mach_header_64 = null, -ordinal: ?u16 = null, - // The actual dylib contents we care about linking with will be embedded at // an offset within a file if we are linking against a fat lib library_offset: u64 = 0, |
