| ... | ... | @@ -63,9 +63,9 @@ entry_addr: ?u64 = null, |
| 63 | 63 | |
| 64 | 64 | objects: std.ArrayListUnmanaged(Object) = .{}, |
| 65 | 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 | 70 | load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, |
| 71 | 71 | |
| ... | ... | @@ -929,6 +929,17 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { |
| 929 | 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 | 943 | // Initialize section ordinals with null ordinal pointing at |
| 933 | 944 | // PAGEZERO segment. |
| 934 | 945 | try self.section_ordinals.append(self.base.allocator, .{ |
| ... | ... | @@ -958,7 +969,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { |
| 958 | 969 | } |
| 959 | 970 | |
| 960 | 971 | try self.sortSections(); |
| 961 | | try self.addRpaths(rpaths.items); |
| 972 | try self.addRpathLCs(rpaths.items); |
| 973 | try self.addLoadDylibLCs(); |
| 962 | 974 | try self.addDataInCodeLC(); |
| 963 | 975 | try self.addCodeSignatureLC(); |
| 964 | 976 | try self.allocateTextSegment(); |
| ... | ... | @@ -2196,17 +2208,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { |
| 2196 | 2208 | } |
| 2197 | 2209 | |
| 2198 | 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 | 2211 | // First pass, resolve symbols in provided objects. |
| 2211 | 2212 | for (self.objects.items) |_, object_id| { |
| 2212 | 2213 | try self.resolveSymbolsInObject(@intCast(u16, object_id)); |
| ... | ... | @@ -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 | 2339 | loop: for (self.undefs.items) |sym| { |
| 2342 | 2340 | if (symbolIsNull(sym)) continue; |
| 2343 | 2341 | |
| ... | ... | @@ -2345,23 +2343,12 @@ fn resolveSymbols(self: *MachO) !void { |
| 2345 | 2343 | for (self.dylibs.items) |*dylib, id| { |
| 2346 | 2344 | if (!dylib.symbols.contains(sym_name)) continue; |
| 2347 | 2345 | |
| 2348 | | if (!referenced.contains(@intCast(u16, id))) { |
| 2349 | | // Add LC_LOAD_DYLIB load command for each referenced dylib/stub. |
| 2350 | | dylib.ordinal = self.next_dylib_ordinal; |
| 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), {}); |
| 2346 | const dylib_id = @intCast(u16, id); |
| 2347 | if (!self.referenced_dylibs.contains(dylib_id)) { |
| 2348 | try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {}); |
| 2363 | 2349 | } |
| 2364 | 2350 | |
| 2351 | const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; |
| 2365 | 2352 | const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable; |
| 2366 | 2353 | const undef = &self.undefs.items[resolv.where_index]; |
| 2367 | 2354 | const import_sym_index = @intCast(u32, self.imports.items.len); |
| ... | ... | @@ -2369,7 +2356,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2369 | 2356 | .n_strx = undef.n_strx, |
| 2370 | 2357 | .n_type = macho.N_UNDF | macho.N_EXT, |
| 2371 | 2358 | .n_sect = 0, |
| 2372 | | .n_desc = packDylibOrdinal(dylib.ordinal.?), |
| 2359 | .n_desc = packDylibOrdinal(@intCast(u16, ordinal + 1)), |
| 2373 | 2360 | .n_value = 0, |
| 2374 | 2361 | }); |
| 2375 | 2362 | resolv.* = .{ |
| ... | ... | @@ -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 | 2795 | for (rpaths) |rpath| { |
| 2809 | 2796 | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| 2810 | 2797 | u64, |
| ... | ... | @@ -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 | 2829 | fn flushZld(self: *MachO) !void { |
| 2827 | 2830 | self.load_commands_dirty = true; |
| 2828 | 2831 | try self.writeTextBlocks(); |
| ... | ... | @@ -3353,6 +3356,7 @@ pub fn deinit(self: *MachO) void { |
| 3353 | 3356 | dylib.deinit(self.base.allocator); |
| 3354 | 3357 | } |
| 3355 | 3358 | self.dylibs.deinit(self.base.allocator); |
| 3359 | self.referenced_dylibs.deinit(self.base.allocator); |
| 3356 | 3360 | |
| 3357 | 3361 | for (self.load_commands.items) |*lc| { |
| 3358 | 3362 | lc.deinit(self.base.allocator); |