| ... | ... | @@ -497,6 +497,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 497 | 497 | } |
| 498 | 498 | |
| 499 | 499 | try self.addUndefinedGlobals(); |
| 500 | try self.resolveSymbols(); |
| 500 | 501 | |
| 501 | 502 | state_log.debug("{}", .{self.dumpState()}); |
| 502 | 503 | |
| ... | ... | @@ -1157,6 +1158,63 @@ fn addUndefinedGlobals(self: *MachO) !void { |
| 1157 | 1158 | } |
| 1158 | 1159 | } |
| 1159 | 1160 | |
| 1161 | /// When resolving symbols, we approach the problem similarly to `mold`. |
| 1162 | /// 1. Resolve symbols across all objects (including those preemptively extracted archives). |
| 1163 | /// 2. Resolve symbols across all shared objects. |
| 1164 | /// 3. Mark live objects (see `MachO.markLive`) |
| 1165 | /// 4. Reset state of all resolved globals since we will redo this bit on the pruned set. |
| 1166 | /// 5. Remove references to dead objects/shared objects |
| 1167 | /// 6. Re-run symbol resolution on pruned objects and shared objects sets. |
| 1168 | pub fn resolveSymbols(self: *MachO) !void { |
| 1169 | const tracy = trace(@src()); |
| 1170 | defer tracy.end(); |
| 1171 | |
| 1172 | // Resolve symbols on the set of all objects and shared objects (even if some are unneeded). |
| 1173 | for (self.objects.items) |index| self.getFile(index).?.resolveSymbols(self); |
| 1174 | for (self.dylibs.items) |index| self.getFile(index).?.resolveSymbols(self); |
| 1175 | |
| 1176 | // Mark live objects. |
| 1177 | self.markLive(); |
| 1178 | |
| 1179 | // Reset state of all globals after marking live objects. |
| 1180 | for (self.objects.items) |index| self.getFile(index).?.resetGlobals(self); |
| 1181 | for (self.dylibs.items) |index| self.getFile(index).?.resetGlobals(self); |
| 1182 | |
| 1183 | // Prune dead objects. |
| 1184 | var i: usize = 0; |
| 1185 | while (i < self.objects.items.len) { |
| 1186 | const index = self.objects.items[i]; |
| 1187 | if (!self.getFile(index).?.object.alive) { |
| 1188 | _ = self.objects.orderedRemove(i); |
| 1189 | } else i += 1; |
| 1190 | } |
| 1191 | |
| 1192 | // Re-resolve the symbols. |
| 1193 | for (self.objects.items) |index| self.getFile(index).?.resolveSymbols(self); |
| 1194 | for (self.dylibs.items) |index| self.getFile(index).?.resolveSymbols(self); |
| 1195 | } |
| 1196 | |
| 1197 | fn markLive(self: *MachO) void { |
| 1198 | const tracy = trace(@src()); |
| 1199 | defer tracy.end(); |
| 1200 | |
| 1201 | for (self.undefined_symbols.items) |index| { |
| 1202 | if (self.getSymbol(index).getFile(self)) |file| { |
| 1203 | if (file == .object) file.object.alive = true; |
| 1204 | } |
| 1205 | } |
| 1206 | if (self.entry_index) |index| { |
| 1207 | const sym = self.getSymbol(index); |
| 1208 | if (sym.getFile(self)) |file| { |
| 1209 | if (file == .object) file.object.alive = true; |
| 1210 | } |
| 1211 | } |
| 1212 | for (self.objects.items) |index| { |
| 1213 | const object = self.getFile(index).?.object; |
| 1214 | if (object.alive) object.markLive(self); |
| 1215 | } |
| 1216 | } |
| 1217 | |
| 1160 | 1218 | fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { |
| 1161 | 1219 | _ = self; |
| 1162 | 1220 | _ = atom_index; |
| ... | ... | @@ -1791,18 +1849,18 @@ fn fmtDumpState( |
| 1791 | 1849 | object.fmtSymtab(self), |
| 1792 | 1850 | }); |
| 1793 | 1851 | } |
| 1794 | | // for (self.dylibs.items) |index| { |
| 1795 | | // const dylib = self.getFile(index).?.dylib; |
| 1796 | | // try writer.print("dylib({d}) : {s} : needed({}) : weak({})", .{ |
| 1797 | | // index, |
| 1798 | | // dylib.path, |
| 1799 | | // dylib.needed, |
| 1800 | | // dylib.weak, |
| 1801 | | // }); |
| 1802 | | // if (!dylib.isAlive(self)) try writer.writeAll(" : ([*])"); |
| 1803 | | // try writer.writeByte('\n'); |
| 1804 | | // try writer.print("{}\n", .{dylib.fmtSymtab(self)}); |
| 1805 | | // } |
| 1852 | for (self.dylibs.items) |index| { |
| 1853 | const dylib = self.getFile(index).?.dylib; |
| 1854 | try writer.print("dylib({d}) : {s} : needed({}) : weak({})", .{ |
| 1855 | index, |
| 1856 | dylib.path, |
| 1857 | dylib.needed, |
| 1858 | dylib.weak, |
| 1859 | }); |
| 1860 | if (!dylib.isAlive(self)) try writer.writeAll(" : ([*])"); |
| 1861 | try writer.writeByte('\n'); |
| 1862 | try writer.print("{}\n", .{dylib.fmtSymtab(self)}); |
| 1863 | } |
| 1806 | 1864 | if (self.getInternalObject()) |internal| { |
| 1807 | 1865 | try writer.print("internal({d}) : internal\n", .{internal.index}); |
| 1808 | 1866 | try writer.print("{}{}\n", .{ internal.fmtAtoms(self), internal.fmtSymtab(self) }); |