| ... | @@ -138,6 +138,7 @@ locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | ... | @@ -138,6 +138,7 @@ locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 138 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 138 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 139 | undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 139 | undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 140 | symbol_resolver: std.AutoHashMapUnmanaged(u32, SymbolWithLoc) = .{}, | 140 | symbol_resolver: std.AutoHashMapUnmanaged(u32, SymbolWithLoc) = .{}, |
| | 141 | unresolved: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, |
| 141 | | 142 | |
| 142 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 143 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 143 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 144 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| ... | @@ -2082,7 +2083,6 @@ fn resolveSymbolsInObject( | ... | @@ -2082,7 +2083,6 @@ fn resolveSymbolsInObject( |
| 2082 | self: *MachO, | 2083 | self: *MachO, |
| 2083 | object_id: u16, | 2084 | object_id: u16, |
| 2084 | tentatives: *std.AutoArrayHashMap(u32, void), | 2085 | tentatives: *std.AutoArrayHashMap(u32, void), |
| 2085 | unresolved: *std.AutoArrayHashMap(u32, void), | | |
| 2086 | ) !void { | 2086 | ) !void { |
| 2087 | const object = &self.objects.items[object_id]; | 2087 | const object = &self.objects.items[object_id]; |
| 2088 | | 2088 | |
| ... | @@ -2181,7 +2181,7 @@ fn resolveSymbolsInObject( | ... | @@ -2181,7 +2181,7 @@ fn resolveSymbolsInObject( |
| 2181 | .n_desc = 0, | 2181 | .n_desc = 0, |
| 2182 | .n_value = 0, | 2182 | .n_value = 0, |
| 2183 | }; | 2183 | }; |
| 2184 | _ = unresolved.fetchSwapRemove(resolv.where_index); | 2184 | _ = self.unresolved.fetchSwapRemove(resolv.where_index); |
| 2185 | }, | 2185 | }, |
| 2186 | } | 2186 | } |
| 2187 | | 2187 | |
| ... | @@ -2252,7 +2252,7 @@ fn resolveSymbolsInObject( | ... | @@ -2252,7 +2252,7 @@ fn resolveSymbolsInObject( |
| 2252 | .n_desc = 0, | 2252 | .n_desc = 0, |
| 2253 | .n_value = 0, | 2253 | .n_value = 0, |
| 2254 | }; | 2254 | }; |
| 2255 | _ = unresolved.fetchSwapRemove(resolv.where_index); | 2255 | _ = self.unresolved.fetchSwapRemove(resolv.where_index); |
| 2256 | }, | 2256 | }, |
| 2257 | } | 2257 | } |
| 2258 | } else { | 2258 | } else { |
| ... | @@ -2272,7 +2272,7 @@ fn resolveSymbolsInObject( | ... | @@ -2272,7 +2272,7 @@ fn resolveSymbolsInObject( |
| 2272 | .where_index = undef_sym_index, | 2272 | .where_index = undef_sym_index, |
| 2273 | .file = object_id, | 2273 | .file = object_id, |
| 2274 | }); | 2274 | }); |
| 2275 | _ = try unresolved.getOrPut(undef_sym_index); | 2275 | _ = try self.unresolved.getOrPut(self.base.allocator, undef_sym_index); |
| 2276 | } | 2276 | } |
| 2277 | } | 2277 | } |
| 2278 | } | 2278 | } |
| ... | @@ -2281,18 +2281,15 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2281,18 +2281,15 @@ fn resolveSymbols(self: *MachO) !void { |
| 2281 | var tentatives = std.AutoArrayHashMap(u32, void).init(self.base.allocator); | 2281 | var tentatives = std.AutoArrayHashMap(u32, void).init(self.base.allocator); |
| 2282 | defer tentatives.deinit(); | 2282 | defer tentatives.deinit(); |
| 2283 | | 2283 | |
| 2284 | var unresolved = std.AutoArrayHashMap(u32, void).init(self.base.allocator); | | |
| 2285 | defer unresolved.deinit(); | | |
| 2286 | | | |
| 2287 | // First pass, resolve symbols in provided objects. | 2284 | // First pass, resolve symbols in provided objects. |
| 2288 | for (self.objects.items) |_, object_id| { | 2285 | for (self.objects.items) |_, object_id| { |
| 2289 | try self.resolveSymbolsInObject(@intCast(u16, object_id), &tentatives, &unresolved); | 2286 | try self.resolveSymbolsInObject(@intCast(u16, object_id), &tentatives); |
| 2290 | } | 2287 | } |
| 2291 | | 2288 | |
| 2292 | // Second pass, resolve symbols in static libraries. | 2289 | // Second pass, resolve symbols in static libraries. |
| 2293 | var next_sym: usize = 0; | 2290 | var next_sym: usize = 0; |
| 2294 | loop: while (next_sym < unresolved.count()) { | 2291 | loop: while (next_sym < self.unresolved.count()) { |
| 2295 | const sym = self.undefs.items[unresolved.keys()[next_sym]]; | 2292 | const sym = self.undefs.items[self.unresolved.keys()[next_sym]]; |
| 2296 | const sym_name = self.getString(sym.n_strx); | 2293 | const sym_name = self.getString(sym.n_strx); |
| 2297 | | 2294 | |
| 2298 | for (self.archives.items) |archive| { | 2295 | for (self.archives.items) |archive| { |
| ... | @@ -2306,7 +2303,7 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2306,7 +2303,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2306 | const object_id = @intCast(u16, self.objects.items.len); | 2303 | const object_id = @intCast(u16, self.objects.items.len); |
| 2307 | const object = try self.objects.addOne(self.base.allocator); | 2304 | const object = try self.objects.addOne(self.base.allocator); |
| 2308 | object.* = try archive.parseObject(self.base.allocator, self.base.options.target, offsets.items[0]); | 2305 | object.* = try archive.parseObject(self.base.allocator, self.base.options.target, offsets.items[0]); |
| 2309 | try self.resolveSymbolsInObject(object_id, &tentatives, &unresolved); | 2306 | try self.resolveSymbolsInObject(object_id, &tentatives); |
| 2310 | | 2307 | |
| 2311 | continue :loop; | 2308 | continue :loop; |
| 2312 | } | 2309 | } |
| ... | @@ -2382,8 +2379,8 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2382,8 +2379,8 @@ fn resolveSymbols(self: *MachO) !void { |
| 2382 | | 2379 | |
| 2383 | // Third pass, resolve symbols in dynamic libraries. | 2380 | // Third pass, resolve symbols in dynamic libraries. |
| 2384 | next_sym = 0; | 2381 | next_sym = 0; |
| 2385 | loop: while (next_sym < unresolved.count()) { | 2382 | loop: while (next_sym < self.unresolved.count()) { |
| 2386 | const sym = self.undefs.items[unresolved.keys()[next_sym]]; | 2383 | const sym = self.undefs.items[self.unresolved.keys()[next_sym]]; |
| 2387 | const sym_name = self.getString(sym.n_strx); | 2384 | const sym_name = self.getString(sym.n_strx); |
| 2388 | | 2385 | |
| 2389 | for (self.dylibs.items) |dylib, id| { | 2386 | for (self.dylibs.items) |dylib, id| { |
| ... | @@ -2400,7 +2397,7 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2400,7 +2397,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2400 | undef.n_type |= macho.N_EXT; | 2397 | undef.n_type |= macho.N_EXT; |
| 2401 | undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER; | 2398 | undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER; |
| 2402 | | 2399 | |
| 2403 | _ = unresolved.fetchSwapRemove(resolv.where_index); | 2400 | _ = self.unresolved.fetchSwapRemove(resolv.where_index); |
| 2404 | | 2401 | |
| 2405 | continue :loop; | 2402 | continue :loop; |
| 2406 | } | 2403 | } |
| ... | @@ -2434,7 +2431,7 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2434,7 +2431,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2434 | nlist.n_desc = macho.N_WEAK_DEF; | 2431 | nlist.n_desc = macho.N_WEAK_DEF; |
| 2435 | try self.globals.append(self.base.allocator, nlist); | 2432 | try self.globals.append(self.base.allocator, nlist); |
| 2436 | | 2433 | |
| 2437 | _ = unresolved.fetchSwapRemove(resolv.where_index); | 2434 | _ = self.unresolved.fetchSwapRemove(resolv.where_index); |
| 2438 | | 2435 | |
| 2439 | undef.* = .{ | 2436 | undef.* = .{ |
| 2440 | .n_strx = 0, | 2437 | .n_strx = 0, |
| ... | @@ -2468,7 +2465,7 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2468,7 +2465,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2468 | } | 2465 | } |
| 2469 | } | 2466 | } |
| 2470 | | 2467 | |
| 2471 | for (unresolved.keys()) |index| { | 2468 | for (self.unresolved.keys()) |index| { |
| 2472 | const sym = self.undefs.items[index]; | 2469 | const sym = self.undefs.items[index]; |
| 2473 | const sym_name = self.getString(sym.n_strx); | 2470 | const sym_name = self.getString(sym.n_strx); |
| 2474 | const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable; | 2471 | const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable; |
| ... | @@ -2477,7 +2474,7 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2477,7 +2474,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2477 | log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name}); | 2474 | log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name}); |
| 2478 | } | 2475 | } |
| 2479 | | 2476 | |
| 2480 | if (unresolved.count() > 0) | 2477 | if (self.unresolved.count() > 0) |
| 2481 | return error.UndefinedSymbolReference; | 2478 | return error.UndefinedSymbolReference; |
| 2482 | } | 2479 | } |
| 2483 | | 2480 | |
| ... | @@ -3122,6 +3119,7 @@ pub fn deinit(self: *MachO) void { | ... | @@ -3122,6 +3119,7 @@ pub fn deinit(self: *MachO) void { |
| 3122 | self.locals.deinit(self.base.allocator); | 3119 | self.locals.deinit(self.base.allocator); |
| 3123 | self.locals_free_list.deinit(self.base.allocator); | 3120 | self.locals_free_list.deinit(self.base.allocator); |
| 3124 | self.symbol_resolver.deinit(self.base.allocator); | 3121 | self.symbol_resolver.deinit(self.base.allocator); |
| | 3122 | self.unresolved.deinit(self.base.allocator); |
| 3125 | | 3123 | |
| 3126 | for (self.objects.items) |*object| { | 3124 | for (self.objects.items) |*object| { |
| 3127 | object.deinit(self.base.allocator); | 3125 | object.deinit(self.base.allocator); |
| ... | @@ -4332,6 +4330,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { | ... | @@ -4332,6 +4330,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { |
| 4332 | .where = .undef, | 4330 | .where = .undef, |
| 4333 | .where_index = sym_index, | 4331 | .where_index = sym_index, |
| 4334 | }); | 4332 | }); |
| | 4333 | _ = try self.unresolved.getOrPut(self.base.allocator, sym_index); |
| 4335 | | 4334 | |
| 4336 | const stubs_index = @intCast(u32, self.stubs.items.len); | 4335 | const stubs_index = @intCast(u32, self.stubs.items.len); |
| 4337 | try self.stubs.append(self.base.allocator, sym_index); | 4336 | try self.stubs.append(self.base.allocator, sym_index); |
| ... | @@ -4340,8 +4339,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { | ... | @@ -4340,8 +4339,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { |
| 4340 | // TODO discuss this. The caller context expects codegen.InnerError{ OutOfMemory, CodegenFail }, | 4339 | // TODO discuss this. The caller context expects codegen.InnerError{ OutOfMemory, CodegenFail }, |
| 4341 | // which obviously doesn't include file writing op errors. So instead of trying to write the stub | 4340 | // which obviously doesn't include file writing op errors. So instead of trying to write the stub |
| 4342 | // entry right here and now, queue it up and dispose of when updating decl. | 4341 | // entry right here and now, queue it up and dispose of when updating decl. |
| 4343 | try self.pending_updates.ensureUnusedCapacity(self.base.allocator, 2); | 4342 | try self.pending_updates.ensureUnusedCapacity(self.base.allocator, 1); |
| 4344 | self.pending_updates.appendAssumeCapacity(.{ .resolve_undef = sym_index }); | | |
| 4345 | self.pending_updates.appendAssumeCapacity(.{ .add_stub_entry = stubs_index }); | 4343 | self.pending_updates.appendAssumeCapacity(.{ .add_stub_entry = stubs_index }); |
| 4346 | | 4344 | |
| 4347 | return sym_index; | 4345 | return sym_index; |