authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-01-20 12:10:16+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-01-20 12:10:16+01:00
log9d2711a3d9bfcacef2c23c9dd9c07f77ab110744
tree2dbd54c45a681d65dd0aa9d68b273102791dc4e4
parente17c551a2e3a0130339b6f1e5817fea2214c260f

macho: use ArrayHashMap for tracking of dyld runtime metadata


1 files changed, 31 insertions(+), 57 deletions(-)

src/link/MachO.zig+31-57
...@@ -238,10 +238,10 @@ const Entry = struct {...@@ -238,10 +238,10 @@ const Entry = struct {
238 }238 }
239};239};
240240
241const BindingTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Atom.Binding));241const BindingTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Atom.Binding));
242const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom));242const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom));
243const RebaseTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(u32));243const RebaseTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(u32));
244const RelocationTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Relocation));244const RelocationTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Relocation));
245245
246const PendingUpdate = union(enum) {246const PendingUpdate = union(enum) {
247 resolve_undef: u32,247 resolve_undef: u32,
...@@ -547,11 +547,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -547,11 +547,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
547547
548 try self.allocateSpecialSymbols();548 try self.allocateSpecialSymbols();
549549
550 {550 for (self.relocs.keys()) |atom| {
551 var it = self.relocs.keyIterator();551 try atom.resolveRelocations(self);
552 while (it.next()) |atom| {
553 try atom.*.resolveRelocations(self);
554 }
555 }552 }
556553
557 if (build_options.enable_logging) {554 if (build_options.enable_logging) {
...@@ -1018,8 +1015,7 @@ fn writePtrWidthAtom(self: *MachO, atom: *Atom) !void {...@@ -1018,8 +1015,7 @@ fn writePtrWidthAtom(self: *MachO, atom: *Atom) !void {
10181015
1019fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void {1016fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void {
1020 // TODO: reverse-lookup might come in handy here1017 // TODO: reverse-lookup might come in handy here
1021 var it = self.relocs.valueIterator();1018 for (self.relocs.values()) |*relocs| {
1022 while (it.next()) |relocs| {
1023 for (relocs.items) |*reloc| {1019 for (relocs.items) |*reloc| {
1024 if (!reloc.target.eql(target)) continue;1020 if (!reloc.target.eql(target)) continue;
1025 reloc.dirty = true;1021 reloc.dirty = true;
...@@ -1028,8 +1024,7 @@ fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void {...@@ -1028,8 +1024,7 @@ fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void {
1028}1024}
10291025
1030fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void {1026fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void {
1031 var it = self.relocs.valueIterator();1027 for (self.relocs.values()) |*relocs| {
1032 while (it.next()) |relocs| {
1033 for (relocs.items) |*reloc| {1028 for (relocs.items) |*reloc| {
1034 const target_atom = reloc.getTargetAtom(self) orelse continue;1029 const target_atom = reloc.getTargetAtom(self) orelse continue;
1035 const target_sym = target_atom.getSymbol(self);1030 const target_sym = target_atom.getSymbol(self);
...@@ -1785,47 +1780,32 @@ pub fn deinit(self: *MachO) void {...@@ -1785,47 +1780,32 @@ pub fn deinit(self: *MachO) void {
1785 assert(self.decls.count() == 0);1780 assert(self.decls.count() == 0);
1786 }1781 }
17871782
1788 {1783 for (self.unnamed_const_atoms.values()) |*atoms| {
1789 var it = self.unnamed_const_atoms.valueIterator();1784 atoms.deinit(gpa);
1790 while (it.next()) |atoms| {
1791 atoms.deinit(gpa);
1792 }
1793 self.unnamed_const_atoms.deinit(gpa);
1794 }1785 }
1786 self.unnamed_const_atoms.deinit(gpa);
17951787
1796 self.atom_by_index_table.deinit(gpa);1788 self.atom_by_index_table.deinit(gpa);
17971789
1798 {1790 for (self.relocs.values()) |*relocs| {
1799 var it = self.relocs.valueIterator();1791 relocs.deinit(gpa);
1800 while (it.next()) |relocs| {
1801 relocs.deinit(gpa);
1802 }
1803 self.relocs.deinit(gpa);
1804 }1792 }
1793 self.relocs.deinit(gpa);
18051794
1806 {1795 for (self.rebases.values()) |*rebases| {
1807 var it = self.rebases.valueIterator();1796 rebases.deinit(gpa);
1808 while (it.next()) |rebases| {
1809 rebases.deinit(gpa);
1810 }
1811 self.rebases.deinit(gpa);
1812 }1797 }
1798 self.rebases.deinit(gpa);
18131799
1814 {1800 for (self.bindings.values()) |*bindings| {
1815 var it = self.bindings.valueIterator();1801 bindings.deinit(gpa);
1816 while (it.next()) |bindings| {
1817 bindings.deinit(gpa);
1818 }
1819 self.bindings.deinit(gpa);
1820 }1802 }
1803 self.bindings.deinit(gpa);
18211804
1822 {1805 for (self.lazy_bindings.values()) |*bindings| {
1823 var it = self.lazy_bindings.valueIterator();1806 bindings.deinit(gpa);
1824 while (it.next()) |bindings| {
1825 bindings.deinit(gpa);
1826 }
1827 self.lazy_bindings.deinit(gpa);
1828 }1807 }
1808 self.lazy_bindings.deinit(gpa);
1829}1809}
18301810
1831fn freeAtom(self: *MachO, atom: *Atom) void {1811fn freeAtom(self: *MachO, atom: *Atom) void {
...@@ -2580,13 +2560,13 @@ pub fn deleteExport(self: *MachO, exp: Export) void {...@@ -2580,13 +2560,13 @@ pub fn deleteExport(self: *MachO, exp: Export) void {
2580}2560}
25812561
2582fn freeRelocationsForAtom(self: *MachO, atom: *Atom) void {2562fn freeRelocationsForAtom(self: *MachO, atom: *Atom) void {
2583 var removed_relocs = self.relocs.fetchRemove(atom);2563 var removed_relocs = self.relocs.fetchOrderedRemove(atom);
2584 if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator);2564 if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator);
2585 var removed_rebases = self.rebases.fetchRemove(atom);2565 var removed_rebases = self.rebases.fetchOrderedRemove(atom);
2586 if (removed_rebases) |*rebases| rebases.value.deinit(self.base.allocator);2566 if (removed_rebases) |*rebases| rebases.value.deinit(self.base.allocator);
2587 var removed_bindings = self.bindings.fetchRemove(atom);2567 var removed_bindings = self.bindings.fetchOrderedRemove(atom);
2588 if (removed_bindings) |*bindings| bindings.value.deinit(self.base.allocator);2568 if (removed_bindings) |*bindings| bindings.value.deinit(self.base.allocator);
2589 var removed_lazy_bindings = self.lazy_bindings.fetchRemove(atom);2569 var removed_lazy_bindings = self.lazy_bindings.fetchOrderedRemove(atom);
2590 if (removed_lazy_bindings) |*lazy_bindings| lazy_bindings.value.deinit(self.base.allocator);2570 if (removed_lazy_bindings) |*lazy_bindings| lazy_bindings.value.deinit(self.base.allocator);
2591}2571}
25922572
...@@ -3199,11 +3179,8 @@ fn writeLinkeditSegmentData(self: *MachO) !void {...@@ -3199,11 +3179,8 @@ fn writeLinkeditSegmentData(self: *MachO) !void {
3199fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {3179fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
3200 const gpa = self.base.allocator;3180 const gpa = self.base.allocator;
3201 const slice = self.sections.slice();3181 const slice = self.sections.slice();
3202 var it = self.rebases.keyIterator();
3203
3204 while (it.next()) |key_ptr| {
3205 const atom = key_ptr.*;
32063182
3183 for (self.rebases.keys()) |atom, i| {
3207 log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) });3184 log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) });
32083185
3209 const sym = atom.getSymbol(self);3186 const sym = atom.getSymbol(self);
...@@ -3212,7 +3189,7 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {...@@ -3212,7 +3189,7 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
32123189
3213 const base_offset = sym.n_value - seg.vmaddr;3190 const base_offset = sym.n_value - seg.vmaddr;
32143191
3215 const rebases = self.rebases.get(atom).?;3192 const rebases = self.rebases.values()[i];
3216 try rebase.entries.ensureUnusedCapacity(gpa, rebases.items.len);3193 try rebase.entries.ensureUnusedCapacity(gpa, rebases.items.len);
32173194
3218 for (rebases.items) |offset| {3195 for (rebases.items) |offset| {
...@@ -3231,11 +3208,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {...@@ -3231,11 +3208,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
3231fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {3208fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
3232 const gpa = self.base.allocator;3209 const gpa = self.base.allocator;
3233 const slice = self.sections.slice();3210 const slice = self.sections.slice();
3234 var it = raw_bindings.keyIterator();
3235
3236 while (it.next()) |key_ptr| {
3237 const atom = key_ptr.*;
32383211
3212 for (raw_bindings.keys()) |atom, i| {
3239 log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) });3213 log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) });
32403214
3241 const sym = atom.getSymbol(self);3215 const sym = atom.getSymbol(self);
...@@ -3244,7 +3218,7 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {...@@ -3244,7 +3218,7 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
32443218
3245 const base_offset = sym.n_value - seg.vmaddr;3219 const base_offset = sym.n_value - seg.vmaddr;
32463220
3247 const bindings = raw_bindings.get(atom).?;3221 const bindings = raw_bindings.values()[i];
3248 try bind.entries.ensureUnusedCapacity(gpa, bindings.items.len);3222 try bind.entries.ensureUnusedCapacity(gpa, bindings.items.len);
32493223
3250 for (bindings.items) |binding| {3224 for (bindings.items) |binding| {