authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-09 11:34:38+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-18 09:13:08+02:00
log355992cbdff96db66dd79e8bbbee04cb081f683f
tree3e9e22b55ec62002538df03e6db0875e558e2537
parentb9bac32a2562985ca7a67877169343975fd8f851

macho: migrate some of MachO driver


2 files changed, 32 insertions(+), 83 deletions(-)

src/link/MachO.zig+29-82
...@@ -224,15 +224,8 @@ pub fn createEmpty(...@@ -224,15 +224,8 @@ pub fn createEmpty(
224224
225 // Append null file225 // Append null file
226 try self.files.append(gpa, .null);226 try self.files.append(gpa, .null);
227 // Atom at index 0 is reserved as null atom
228 try self.atoms.append(gpa, .{});
229 try self.atoms_extra.append(gpa, 0);
230 // Append empty string to string tables227 // Append empty string to string tables
231 try self.strings.buffer.append(gpa, 0);
232 try self.strtab.append(gpa, 0);228 try self.strtab.append(gpa, 0);
233 // Append null symbols
234 try self.symbols.append(gpa, .{});
235 try self.symbols_extra.append(gpa, 0);
236229
237 if (opt_zcu) |zcu| {230 if (opt_zcu) |zcu| {
238 if (!use_llvm) {231 if (!use_llvm) {
...@@ -301,10 +294,7 @@ pub fn deinit(self: *MachO) void {...@@ -301,10 +294,7 @@ pub fn deinit(self: *MachO) void {
301 }294 }
302 self.sections.deinit(gpa);295 self.sections.deinit(gpa);
303296
304 self.symbols.deinit(gpa);297 self.resolver.deinit(gpa);
305 self.symbols_extra.deinit(gpa);
306 self.symbols_free_list.deinit(gpa);
307 self.globals.deinit(gpa);
308 {298 {
309 var it = self.undefs.iterator();299 var it = self.undefs.iterator();
310 while (it.next()) |entry| {300 while (it.next()) |entry| {
...@@ -312,10 +302,7 @@ pub fn deinit(self: *MachO) void {...@@ -312,10 +302,7 @@ pub fn deinit(self: *MachO) void {
312 }302 }
313 self.undefs.deinit(gpa);303 self.undefs.deinit(gpa);
314 }304 }
315 self.undefined_symbols.deinit(gpa);
316 self.boundary_symbols.deinit(gpa);
317305
318 self.strings.deinit(gpa);
319 self.symtab.deinit(gpa);306 self.symtab.deinit(gpa);
320 self.strtab.deinit(gpa);307 self.strtab.deinit(gpa);
321 self.got.deinit(gpa);308 self.got.deinit(gpa);
...@@ -330,11 +317,6 @@ pub fn deinit(self: *MachO) void {...@@ -330,11 +317,6 @@ pub fn deinit(self: *MachO) void {
330 self.export_trie.deinit(gpa);317 self.export_trie.deinit(gpa);
331 self.unwind_info.deinit(gpa);318 self.unwind_info.deinit(gpa);
332319
333 self.atoms.deinit(gpa);
334 self.atoms_extra.deinit(gpa);
335 for (self.thunks.items) |*thunk| {
336 thunk.deinit(gpa);
337 }
338 self.thunks.deinit(gpa);320 self.thunks.deinit(gpa);
339}321}
340322
...@@ -513,17 +495,14 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -513,17 +495,14 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
513 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));495 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
514 self.files.set(index, .{ .internal = .{ .index = index } });496 self.files.set(index, .{ .internal = .{ .index = index } });
515 self.internal_object = index;497 self.internal_object = index;
498 const object = self.getInternalObject().?;
499 try object.init(gpa);
500 try object.initSymbols(self);
516 }501 }
517502
518 try self.addUndefinedGlobals();
519 try self.resolveSymbols();503 try self.resolveSymbols();
520 try self.parseDebugInfo();504 try self.convertTentativeDefsAndResolveSpecialSymbols();
521 try self.resolveSyntheticSymbols();
522
523 try self.convertTentativeDefinitions();
524 try self.createObjcSections();
525 try self.dedupLiterals();505 try self.dedupLiterals();
526 try self.claimUnresolved();
527506
528 if (self.base.gc_sections) {507 if (self.base.gc_sections) {
529 try dead_strip.gcAtoms(self);508 try dead_strip.gcAtoms(self);
...@@ -546,6 +525,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -546,6 +525,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
546 dylib.ordinal = @intCast(ord);525 dylib.ordinal = @intCast(ord);
547 }526 }
548527
528 try self.claimUnresolved();
529
549 self.scanRelocs() catch |err| switch (err) {530 self.scanRelocs() catch |err| switch (err) {
550 error.HasUndefinedSymbols => return error.FlushFailure,531 error.HasUndefinedSymbols => return error.FlushFailure,
551 else => |e| {532 else => |e| {
...@@ -1307,35 +1288,6 @@ fn parseDependentDylibs(self: *MachO) !void {...@@ -1307,35 +1288,6 @@ fn parseDependentDylibs(self: *MachO) !void {
1307 if (has_errors) return error.MissingLibraryDependencies;1288 if (has_errors) return error.MissingLibraryDependencies;
1308}1289}
13091290
1310pub fn addUndefinedGlobals(self: *MachO) !void {
1311 const gpa = self.base.comp.gpa;
1312
1313 try self.undefined_symbols.ensureUnusedCapacity(gpa, self.base.comp.force_undefined_symbols.keys().len);
1314 for (self.base.comp.force_undefined_symbols.keys()) |name| {
1315 const off = try self.strings.insert(gpa, name);
1316 const gop = try self.getOrCreateGlobal(off);
1317 self.undefined_symbols.appendAssumeCapacity(gop.index);
1318 }
1319
1320 if (!self.base.isDynLib() and self.entry_name != null) {
1321 const off = try self.strings.insert(gpa, self.entry_name.?);
1322 const gop = try self.getOrCreateGlobal(off);
1323 self.entry_index = gop.index;
1324 }
1325
1326 {
1327 const off = try self.strings.insert(gpa, "dyld_stub_binder");
1328 const gop = try self.getOrCreateGlobal(off);
1329 self.dyld_stub_binder_index = gop.index;
1330 }
1331
1332 {
1333 const off = try self.strings.insert(gpa, "_objc_msgSend");
1334 const gop = try self.getOrCreateGlobal(off);
1335 self.objc_msg_send_index = gop.index;
1336 }
1337}
1338
1339/// When resolving symbols, we approach the problem similarly to `mold`.1291/// When resolving symbols, we approach the problem similarly to `mold`.
1340/// 1. Resolve symbols across all objects (including those preemptively extracted archives).1292/// 1. Resolve symbols across all objects (including those preemptively extracted archives).
1341/// 2. Resolve symbols across all shared objects.1293/// 2. Resolve symbols across all shared objects.
...@@ -1348,18 +1300,17 @@ pub fn resolveSymbols(self: *MachO) !void {...@@ -1348,18 +1300,17 @@ pub fn resolveSymbols(self: *MachO) !void {
1348 defer tracy.end();1300 defer tracy.end();
13491301
1350 // Resolve symbols in the ZigObject. For now, we assume that it's always live.1302 // Resolve symbols in the ZigObject. For now, we assume that it's always live.
1351 if (self.getZigObject()) |zo| zo.asFile().resolveSymbols(self);1303 if (self.getZigObject()) |zo| try zo.asFile().resolveSymbols(self);
1352 // Resolve symbols on the set of all objects and shared objects (even if some are unneeded).1304 // Resolve symbols on the set of all objects and shared objects (even if some are unneeded).
1353 for (self.objects.items) |index| self.getFile(index).?.resolveSymbols(self);1305 for (self.objects.items) |index| try self.getFile(index).?.resolveSymbols(self);
1354 for (self.dylibs.items) |index| self.getFile(index).?.resolveSymbols(self);1306 for (self.dylibs.items) |index| try self.getFile(index).?.resolveSymbols(self);
1307 if (self.getInternalObject()) |obj| try obj.resolveSymbols(self);
13551308
1356 // Mark live objects.1309 // Mark live objects.
1357 self.markLive();1310 self.markLive();
13581311
1359 // Reset state of all globals after marking live objects.1312 // Reset state of all globals after marking live objects.
1360 if (self.getZigObject()) |zo| zo.asFile().resetGlobals(self);1313 self.resolver.reset();
1361 for (self.objects.items) |index| self.getFile(index).?.resetGlobals(self);
1362 for (self.dylibs.items) |index| self.getFile(index).?.resetGlobals(self);
13631314
1364 // Prune dead objects.1315 // Prune dead objects.
1365 var i: usize = 0;1316 var i: usize = 0;
...@@ -1373,37 +1324,26 @@ pub fn resolveSymbols(self: *MachO) !void {...@@ -1373,37 +1324,26 @@ pub fn resolveSymbols(self: *MachO) !void {
1373 }1324 }
13741325
1375 // Re-resolve the symbols.1326 // Re-resolve the symbols.
1376 if (self.getZigObject()) |zo| zo.resolveSymbols(self);1327 if (self.getZigObject()) |zo| try zo.resolveSymbols(self);
1377 for (self.objects.items) |index| self.getFile(index).?.resolveSymbols(self);1328 for (self.objects.items) |index| try self.getFile(index).?.resolveSymbols(self);
1378 for (self.dylibs.items) |index| self.getFile(index).?.resolveSymbols(self);1329 for (self.dylibs.items) |index| try self.getFile(index).?.resolveSymbols(self);
1330 if (self.getInternalObject()) |obj| try obj.resolveSymbols(self);
1331
1332 // Merge symbol visibility
1333 if (self.getZigObject()) |zo| zo.mergeSymbolVisibility(self);
1334 for (self.objects.items) |index| self.getFile(index).?.object.mergeSymbolVisibility(self);
1379}1335}
13801336
1381fn markLive(self: *MachO) void {1337fn markLive(self: *MachO) void {
1382 const tracy = trace(@src());1338 const tracy = trace(@src());
1383 defer tracy.end();1339 defer tracy.end();
13841340
1385 for (self.undefined_symbols.items) |index| {
1386 if (self.getSymbol(index).getFile(self)) |file| {
1387 if (file == .object) file.object.alive = true;
1388 }
1389 }
1390 if (self.entry_index) |index| {
1391 const sym = self.getSymbol(index);
1392 if (sym.getFile(self)) |file| {
1393 if (file == .object) file.object.alive = true;
1394 }
1395 }
1396 if (self.getZigObject()) |zo| zo.markLive(self);1341 if (self.getZigObject()) |zo| zo.markLive(self);
1397 for (self.objects.items) |index| {1342 for (self.objects.items) |index| {
1398 const object = self.getFile(index).?.object;1343 const object = self.getFile(index).?.object;
1399 if (object.alive) object.markLive(self);1344 if (object.alive) object.markLive(self);
1400 }1345 }
1401}1346 if (self.getInternalObject()) |obj| obj.markLive(self);
1402
1403pub fn parseDebugInfo(self: *MachO) !void {
1404 for (self.objects.items) |index| {
1405 try self.getFile(index).?.object.parseDebugInfo(self);
1406 }
1407}1347}
14081348
1409fn resolveSyntheticSymbols(self: *MachO) !void {1349fn resolveSyntheticSymbols(self: *MachO) !void {
...@@ -1453,10 +1393,14 @@ fn resolveSyntheticSymbols(self: *MachO) !void {...@@ -1453,10 +1393,14 @@ fn resolveSyntheticSymbols(self: *MachO) !void {
1453 }1393 }
1454}1394}
14551395
1456fn convertTentativeDefinitions(self: *MachO) !void {1396fn convertTentativeDefsAndResolveSpecialSymbols(self: *MachO) !void {
1457 for (self.objects.items) |index| {1397 for (self.objects.items) |index| {
1458 try self.getFile(index).?.object.convertTentativeDefinitions(self);1398 try self.getFile(index).?.object.convertTentativeDefinitions(self);
1459 }1399 }
1400 if (self.getInternalObject()) |obj| {
1401 try obj.resolveBoundarySymbols(self);
1402 try obj.resolveObjcMsgSendSymbols(self);
1403 }
1460}1404}
14611405
1462fn createObjcSections(self: *MachO) !void {1406fn createObjcSections(self: *MachO) !void {
...@@ -1494,6 +1438,9 @@ fn createObjcSections(self: *MachO) !void {...@@ -1494,6 +1438,9 @@ fn createObjcSections(self: *MachO) !void {
1494}1438}
14951439
1496pub fn dedupLiterals(self: *MachO) !void {1440pub fn dedupLiterals(self: *MachO) !void {
1441 const tracy = trace(@src());
1442 defer tracy.end();
1443
1497 const gpa = self.base.comp.gpa;1444 const gpa = self.base.comp.gpa;
1498 var lp: LiteralPool = .{};1445 var lp: LiteralPool = .{};
1499 defer lp.deinit(gpa);1446 defer lp.deinit(gpa);
src/link/MachO/Object.zig+3-1
...@@ -259,6 +259,8 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -259,6 +259,8 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
259 // }259 // }
260 }260 }
261261
262 try self.parseDebugInfo(macho_file);
263
262 for (self.atoms.items) |atom_index| {264 for (self.atoms.items) |atom_index| {
263 const atom = self.getAtom(atom_index) orelse continue;265 const atom = self.getAtom(atom_index) orelse continue;
264 const isec = atom.getInputSection(macho_file);266 const isec = atom.getInputSection(macho_file);
...@@ -1317,7 +1319,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target....@@ -1317,7 +1319,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target.
1317/// and record that so that we can emit symbol stabs.1319/// and record that so that we can emit symbol stabs.
1318/// TODO in the future, we want parse debug info and debug line sections so that1320/// TODO in the future, we want parse debug info and debug line sections so that
1319/// we can provide nice error locations to the user.1321/// we can provide nice error locations to the user.
1320pub fn parseDebugInfo(self: *Object, macho_file: *MachO) !void {1322fn parseDebugInfo(self: *Object, macho_file: *MachO) !void {
1321 const tracy = trace(@src());1323 const tracy = trace(@src());
1322 defer tracy.end();1324 defer tracy.end();
13231325