| ... | ... | @@ -224,15 +224,8 @@ pub fn createEmpty( |
| 224 | 224 | |
| 225 | 225 | // Append null file |
| 226 | 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 | 227 | // Append empty string to string tables |
| 231 | | try self.strings.buffer.append(gpa, 0); |
| 232 | 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); |
| 236 | 229 | |
| 237 | 230 | if (opt_zcu) |zcu| { |
| 238 | 231 | if (!use_llvm) { |
| ... | ... | @@ -301,10 +294,7 @@ pub fn deinit(self: *MachO) void { |
| 301 | 294 | } |
| 302 | 295 | self.sections.deinit(gpa); |
| 303 | 296 | |
| 304 | | self.symbols.deinit(gpa); |
| 305 | | self.symbols_extra.deinit(gpa); |
| 306 | | self.symbols_free_list.deinit(gpa); |
| 307 | | self.globals.deinit(gpa); |
| 297 | self.resolver.deinit(gpa); |
| 308 | 298 | { |
| 309 | 299 | var it = self.undefs.iterator(); |
| 310 | 300 | while (it.next()) |entry| { |
| ... | ... | @@ -312,10 +302,7 @@ pub fn deinit(self: *MachO) void { |
| 312 | 302 | } |
| 313 | 303 | self.undefs.deinit(gpa); |
| 314 | 304 | } |
| 315 | | self.undefined_symbols.deinit(gpa); |
| 316 | | self.boundary_symbols.deinit(gpa); |
| 317 | 305 | |
| 318 | | self.strings.deinit(gpa); |
| 319 | 306 | self.symtab.deinit(gpa); |
| 320 | 307 | self.strtab.deinit(gpa); |
| 321 | 308 | self.got.deinit(gpa); |
| ... | ... | @@ -330,11 +317,6 @@ pub fn deinit(self: *MachO) void { |
| 330 | 317 | self.export_trie.deinit(gpa); |
| 331 | 318 | self.unwind_info.deinit(gpa); |
| 332 | 319 | |
| 333 | | self.atoms.deinit(gpa); |
| 334 | | self.atoms_extra.deinit(gpa); |
| 335 | | for (self.thunks.items) |*thunk| { |
| 336 | | thunk.deinit(gpa); |
| 337 | | } |
| 338 | 320 | self.thunks.deinit(gpa); |
| 339 | 321 | } |
| 340 | 322 | |
| ... | ... | @@ -513,17 +495,14 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n |
| 513 | 495 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); |
| 514 | 496 | self.files.set(index, .{ .internal = .{ .index = index } }); |
| 515 | 497 | self.internal_object = index; |
| 498 | const object = self.getInternalObject().?; |
| 499 | try object.init(gpa); |
| 500 | try object.initSymbols(self); |
| 516 | 501 | } |
| 517 | 502 | |
| 518 | | try self.addUndefinedGlobals(); |
| 519 | 503 | try self.resolveSymbols(); |
| 520 | | try self.parseDebugInfo(); |
| 521 | | try self.resolveSyntheticSymbols(); |
| 522 | | |
| 523 | | try self.convertTentativeDefinitions(); |
| 524 | | try self.createObjcSections(); |
| 504 | try self.convertTentativeDefsAndResolveSpecialSymbols(); |
| 525 | 505 | try self.dedupLiterals(); |
| 526 | | try self.claimUnresolved(); |
| 527 | 506 | |
| 528 | 507 | if (self.base.gc_sections) { |
| 529 | 508 | try dead_strip.gcAtoms(self); |
| ... | ... | @@ -546,6 +525,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n |
| 546 | 525 | dylib.ordinal = @intCast(ord); |
| 547 | 526 | } |
| 548 | 527 | |
| 528 | try self.claimUnresolved(); |
| 529 | |
| 549 | 530 | self.scanRelocs() catch |err| switch (err) { |
| 550 | 531 | error.HasUndefinedSymbols => return error.FlushFailure, |
| 551 | 532 | else => |e| { |
| ... | ... | @@ -1307,35 +1288,6 @@ fn parseDependentDylibs(self: *MachO) !void { |
| 1307 | 1288 | if (has_errors) return error.MissingLibraryDependencies; |
| 1308 | 1289 | } |
| 1309 | 1290 | |
| 1310 | | pub 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 | 1291 | /// When resolving symbols, we approach the problem similarly to `mold`. |
| 1340 | 1292 | /// 1. Resolve symbols across all objects (including those preemptively extracted archives). |
| 1341 | 1293 | /// 2. Resolve symbols across all shared objects. |
| ... | ... | @@ -1348,18 +1300,17 @@ pub fn resolveSymbols(self: *MachO) !void { |
| 1348 | 1300 | defer tracy.end(); |
| 1349 | 1301 | |
| 1350 | 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 | 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); |
| 1354 | | for (self.dylibs.items) |index| self.getFile(index).?.resolveSymbols(self); |
| 1305 | for (self.objects.items) |index| try 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); |
| 1355 | 1308 | |
| 1356 | 1309 | // Mark live objects. |
| 1357 | 1310 | self.markLive(); |
| 1358 | 1311 | |
| 1359 | 1312 | // Reset state of all globals after marking live objects. |
| 1360 | | if (self.getZigObject()) |zo| zo.asFile().resetGlobals(self); |
| 1361 | | for (self.objects.items) |index| self.getFile(index).?.resetGlobals(self); |
| 1362 | | for (self.dylibs.items) |index| self.getFile(index).?.resetGlobals(self); |
| 1313 | self.resolver.reset(); |
| 1363 | 1314 | |
| 1364 | 1315 | // Prune dead objects. |
| 1365 | 1316 | var i: usize = 0; |
| ... | ... | @@ -1373,37 +1324,26 @@ pub fn resolveSymbols(self: *MachO) !void { |
| 1373 | 1324 | } |
| 1374 | 1325 | |
| 1375 | 1326 | // Re-resolve the symbols. |
| 1376 | | if (self.getZigObject()) |zo| zo.resolveSymbols(self); |
| 1377 | | for (self.objects.items) |index| self.getFile(index).?.resolveSymbols(self); |
| 1378 | | for (self.dylibs.items) |index| self.getFile(index).?.resolveSymbols(self); |
| 1327 | if (self.getZigObject()) |zo| try zo.resolveSymbols(self); |
| 1328 | for (self.objects.items) |index| try 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 | } |
| 1380 | 1336 | |
| 1381 | 1337 | fn markLive(self: *MachO) void { |
| 1382 | 1338 | const tracy = trace(@src()); |
| 1383 | 1339 | defer tracy.end(); |
| 1384 | 1340 | |
| 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 | 1341 | if (self.getZigObject()) |zo| zo.markLive(self); |
| 1397 | 1342 | for (self.objects.items) |index| { |
| 1398 | 1343 | const object = self.getFile(index).?.object; |
| 1399 | 1344 | if (object.alive) object.markLive(self); |
| 1400 | 1345 | } |
| 1401 | | } |
| 1402 | | |
| 1403 | | pub fn parseDebugInfo(self: *MachO) !void { |
| 1404 | | for (self.objects.items) |index| { |
| 1405 | | try self.getFile(index).?.object.parseDebugInfo(self); |
| 1406 | | } |
| 1346 | if (self.getInternalObject()) |obj| obj.markLive(self); |
| 1407 | 1347 | } |
| 1408 | 1348 | |
| 1409 | 1349 | fn resolveSyntheticSymbols(self: *MachO) !void { |
| ... | ... | @@ -1453,10 +1393,14 @@ fn resolveSyntheticSymbols(self: *MachO) !void { |
| 1453 | 1393 | } |
| 1454 | 1394 | } |
| 1455 | 1395 | |
| 1456 | | fn convertTentativeDefinitions(self: *MachO) !void { |
| 1396 | fn convertTentativeDefsAndResolveSpecialSymbols(self: *MachO) !void { |
| 1457 | 1397 | for (self.objects.items) |index| { |
| 1458 | 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 | } |
| 1461 | 1405 | |
| 1462 | 1406 | fn createObjcSections(self: *MachO) !void { |
| ... | ... | @@ -1494,6 +1438,9 @@ fn createObjcSections(self: *MachO) !void { |
| 1494 | 1438 | } |
| 1495 | 1439 | |
| 1496 | 1440 | pub fn dedupLiterals(self: *MachO) !void { |
| 1441 | const tracy = trace(@src()); |
| 1442 | defer tracy.end(); |
| 1443 | |
| 1497 | 1444 | const gpa = self.base.comp.gpa; |
| 1498 | 1445 | var lp: LiteralPool = .{}; |
| 1499 | 1446 | defer lp.deinit(gpa); |