authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-20 09:12:26+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-20 09:12:26+02:00
log153e2317748cff7d59d2709f72fe8b22c14f2a7b
tree0b51fed3f45eb424f417b4777f81c1e35d3e54ee
parent30247fbb6a46231154f051119228829c6a0dfd90

macho: track unresolved externs globally

this way we share state between incremental and traditional paths.

1 files changed, 17 insertions(+), 19 deletions(-)

src/link/MachO.zig+17-19
......@@ -138,6 +138,7 @@ locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
138138globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
139139undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},
140140symbol_resolver: std.AutoHashMapUnmanaged(u32, SymbolWithLoc) = .{},
141unresolved: std.AutoArrayHashMapUnmanaged(u32, void) = .{},
141142
142143locals_free_list: std.ArrayListUnmanaged(u32) = .{},
143144globals_free_list: std.ArrayListUnmanaged(u32) = .{},
......@@ -2082,7 +2083,6 @@ fn resolveSymbolsInObject(
20822083 self: *MachO,
20832084 object_id: u16,
20842085 tentatives: *std.AutoArrayHashMap(u32, void),
2085 unresolved: *std.AutoArrayHashMap(u32, void),
20862086) !void {
20872087 const object = &self.objects.items[object_id];
20882088
......@@ -2181,7 +2181,7 @@ fn resolveSymbolsInObject(
21812181 .n_desc = 0,
21822182 .n_value = 0,
21832183 };
2184 _ = unresolved.fetchSwapRemove(resolv.where_index);
2184 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
21852185 },
21862186 }
21872187
......@@ -2252,7 +2252,7 @@ fn resolveSymbolsInObject(
22522252 .n_desc = 0,
22532253 .n_value = 0,
22542254 };
2255 _ = unresolved.fetchSwapRemove(resolv.where_index);
2255 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
22562256 },
22572257 }
22582258 } else {
......@@ -2272,7 +2272,7 @@ fn resolveSymbolsInObject(
22722272 .where_index = undef_sym_index,
22732273 .file = object_id,
22742274 });
2275 _ = try unresolved.getOrPut(undef_sym_index);
2275 _ = try self.unresolved.getOrPut(self.base.allocator, undef_sym_index);
22762276 }
22772277 }
22782278}
......@@ -2281,18 +2281,15 @@ fn resolveSymbols(self: *MachO) !void {
22812281 var tentatives = std.AutoArrayHashMap(u32, void).init(self.base.allocator);
22822282 defer tentatives.deinit();
22832283
2284 var unresolved = std.AutoArrayHashMap(u32, void).init(self.base.allocator);
2285 defer unresolved.deinit();
2286
22872284 // First pass, resolve symbols in provided objects.
22882285 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);
22902287 }
22912288
22922289 // Second pass, resolve symbols in static libraries.
22932290 var next_sym: usize = 0;
2294 loop: while (next_sym < unresolved.count()) {
2295 const sym = self.undefs.items[unresolved.keys()[next_sym]];
2291 loop: while (next_sym < self.unresolved.count()) {
2292 const sym = self.undefs.items[self.unresolved.keys()[next_sym]];
22962293 const sym_name = self.getString(sym.n_strx);
22972294
22982295 for (self.archives.items) |archive| {
......@@ -2306,7 +2303,7 @@ fn resolveSymbols(self: *MachO) !void {
23062303 const object_id = @intCast(u16, self.objects.items.len);
23072304 const object = try self.objects.addOne(self.base.allocator);
23082305 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);
23102307
23112308 continue :loop;
23122309 }
......@@ -2382,8 +2379,8 @@ fn resolveSymbols(self: *MachO) !void {
23822379
23832380 // Third pass, resolve symbols in dynamic libraries.
23842381 next_sym = 0;
2385 loop: while (next_sym < unresolved.count()) {
2386 const sym = self.undefs.items[unresolved.keys()[next_sym]];
2382 loop: while (next_sym < self.unresolved.count()) {
2383 const sym = self.undefs.items[self.unresolved.keys()[next_sym]];
23872384 const sym_name = self.getString(sym.n_strx);
23882385
23892386 for (self.dylibs.items) |dylib, id| {
......@@ -2400,7 +2397,7 @@ fn resolveSymbols(self: *MachO) !void {
24002397 undef.n_type |= macho.N_EXT;
24012398 undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;
24022399
2403 _ = unresolved.fetchSwapRemove(resolv.where_index);
2400 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
24042401
24052402 continue :loop;
24062403 }
......@@ -2434,7 +2431,7 @@ fn resolveSymbols(self: *MachO) !void {
24342431 nlist.n_desc = macho.N_WEAK_DEF;
24352432 try self.globals.append(self.base.allocator, nlist);
24362433
2437 _ = unresolved.fetchSwapRemove(resolv.where_index);
2434 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
24382435
24392436 undef.* = .{
24402437 .n_strx = 0,
......@@ -2468,7 +2465,7 @@ fn resolveSymbols(self: *MachO) !void {
24682465 }
24692466 }
24702467
2471 for (unresolved.keys()) |index| {
2468 for (self.unresolved.keys()) |index| {
24722469 const sym = self.undefs.items[index];
24732470 const sym_name = self.getString(sym.n_strx);
24742471 const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;
......@@ -2477,7 +2474,7 @@ fn resolveSymbols(self: *MachO) !void {
24772474 log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name});
24782475 }
24792476
2480 if (unresolved.count() > 0)
2477 if (self.unresolved.count() > 0)
24812478 return error.UndefinedSymbolReference;
24822479}
24832480
......@@ -3122,6 +3119,7 @@ pub fn deinit(self: *MachO) void {
31223119 self.locals.deinit(self.base.allocator);
31233120 self.locals_free_list.deinit(self.base.allocator);
31243121 self.symbol_resolver.deinit(self.base.allocator);
3122 self.unresolved.deinit(self.base.allocator);
31253123
31263124 for (self.objects.items) |*object| {
31273125 object.deinit(self.base.allocator);
......@@ -4332,6 +4330,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
43324330 .where = .undef,
43334331 .where_index = sym_index,
43344332 });
4333 _ = try self.unresolved.getOrPut(self.base.allocator, sym_index);
43354334
43364335 const stubs_index = @intCast(u32, self.stubs.items.len);
43374336 try self.stubs.append(self.base.allocator, sym_index);
......@@ -4340,8 +4339,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
43404339 // TODO discuss this. The caller context expects codegen.InnerError{ OutOfMemory, CodegenFail },
43414340 // which obviously doesn't include file writing op errors. So instead of trying to write the stub
43424341 // entry right here and now, queue it up and dispose of when updating decl.
4343 try self.pending_updates.ensureUnusedCapacity(self.base.allocator, 2);
4344 self.pending_updates.appendAssumeCapacity(.{ .resolve_undef = sym_index });
4342 try self.pending_updates.ensureUnusedCapacity(self.base.allocator, 1);
43454343 self.pending_updates.appendAssumeCapacity(.{ .add_stub_entry = stubs_index });
43464344
43474345 return sym_index;