| ... | @@ -224,15 +224,8 @@ pub fn createEmpty( | ... | @@ -224,15 +224,8 @@ pub fn createEmpty( |
| 224 | | 224 | |
| 225 | // Append null file | 225 | // 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 tables | 227 | // 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); | | |
| 236 | | 229 | |
| 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); |
| 303 | | 296 | |
| 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); | | |
| 317 | | 305 | |
| 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); |
| 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 | self.thunks.deinit(gpa); | 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,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 | } |
| 517 | | 502 | |
| 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(); | | |
| 527 | | 506 | |
| 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 | } |
| 548 | | 527 | |
| | 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 | } |
| 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 | /// 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(); |
| 1349 | | 1301 | |
| 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); |
| 1355 | | 1308 | |
| 1356 | // Mark live objects. | 1309 | // Mark live objects. |
| 1357 | self.markLive(); | 1310 | self.markLive(); |
| 1358 | | 1311 | |
| 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); | | |
| 1363 | | 1314 | |
| 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 | } |
| 1374 | | 1325 | |
| 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 | } |
| 1380 | | 1336 | |
| 1381 | fn markLive(self: *MachO) void { | 1337 | fn markLive(self: *MachO) void { |
| 1382 | const tracy = trace(@src()); | 1338 | const tracy = trace(@src()); |
| 1383 | defer tracy.end(); | 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 | 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 | | | |
| 1403 | pub fn parseDebugInfo(self: *MachO) !void { | | |
| 1404 | for (self.objects.items) |index| { | | |
| 1405 | try self.getFile(index).?.object.parseDebugInfo(self); | | |
| 1406 | } | | |
| 1407 | } | 1347 | } |
| 1408 | | 1348 | |
| 1409 | fn resolveSyntheticSymbols(self: *MachO) !void { | 1349 | fn 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 | } |
| 1455 | | 1395 | |
| 1456 | fn convertTentativeDefinitions(self: *MachO) !void { | 1396 | fn 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 | } |
| 1461 | | 1405 | |
| 1462 | fn createObjcSections(self: *MachO) !void { | 1406 | fn createObjcSections(self: *MachO) !void { |
| ... | @@ -1494,6 +1438,9 @@ fn createObjcSections(self: *MachO) !void { | ... | @@ -1494,6 +1438,9 @@ fn createObjcSections(self: *MachO) !void { |
| 1494 | } | 1438 | } |
| 1495 | | 1439 | |
| 1496 | pub fn dedupLiterals(self: *MachO) !void { | 1440 | pub 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); |