| ... | @@ -63,9 +63,9 @@ entry_addr: ?u64 = null, | ... | @@ -63,9 +63,9 @@ entry_addr: ?u64 = null, |
| 63 | | 63 | |
| 64 | objects: std.ArrayListUnmanaged(Object) = .{}, | 64 | objects: std.ArrayListUnmanaged(Object) = .{}, |
| 65 | archives: std.ArrayListUnmanaged(Archive) = .{}, | 65 | archives: std.ArrayListUnmanaged(Archive) = .{}, |
| 66 | dylibs: std.ArrayListUnmanaged(Dylib) = .{}, | | |
| 67 | | 66 | |
| 68 | next_dylib_ordinal: u16 = 1, | 67 | dylibs: std.ArrayListUnmanaged(Dylib) = .{}, |
| | 68 | referenced_dylibs: std.AutoArrayHashMapUnmanaged(u16, void) = .{}, |
| 69 | | 69 | |
| 70 | load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, | 70 | load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, |
| 71 | | 71 | |
| ... | @@ -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 | }; |
| 931 | | 931 | |
| | 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 at | 943 | // 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 | } |
| 959 | | 970 | |
| 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 | } |
| 2197 | | 2209 | |
| 2198 | fn resolveSymbols(self: *MachO) !void { | 2210 | fn 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 | } |
| 2337 | | 2338 | |
| 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; |
| 2343 | | 2341 | |
| ... | @@ -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; |
| 2347 | | 2345 | |
| 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 | } |
| 2364 | | 2350 | |
| | 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 | } |
| 2806 | | 2793 | |
| 2807 | fn addRpaths(self: *MachO, rpaths: []const []const u8) !void { | 2794 | fn 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 | } |
| 2825 | | 2812 | |
| | 2813 | fn 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 | |
| 2826 | fn flushZld(self: *MachO) !void { | 2829 | fn 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); |
| 3356 | | 3360 | |
| 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); |