| ... | @@ -238,10 +238,10 @@ const Entry = struct { | ... | @@ -238,10 +238,10 @@ const Entry = struct { |
| 238 | } | 238 | } |
| 239 | }; | 239 | }; |
| 240 | | 240 | |
| 241 | const BindingTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Atom.Binding)); | 241 | const BindingTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Atom.Binding)); |
| 242 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom)); | 242 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom)); |
| 243 | const RebaseTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(u32)); | 243 | const RebaseTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(u32)); |
| 244 | const RelocationTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Relocation)); | 244 | const RelocationTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Relocation)); |
| 245 | | 245 | |
| 246 | const PendingUpdate = union(enum) { | 246 | const PendingUpdate = union(enum) { |
| 247 | resolve_undef: u32, | 247 | resolve_undef: u32, |
| ... | @@ -469,10 +469,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -469,10 +469,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 469 | | 469 | |
| 470 | const cache_dir_handle = module.zig_cache_artifact_directory.handle; | 470 | const cache_dir_handle = module.zig_cache_artifact_directory.handle; |
| 471 | var man: Cache.Manifest = undefined; | 471 | var man: Cache.Manifest = undefined; |
| 472 | defer if (!self.base.options.disable_lld_caching) man.deinit(); | 472 | defer man.deinit(); |
| 473 | | 473 | |
| 474 | var digest: [Cache.hex_digest_len]u8 = undefined; | 474 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 475 | man = comp.cache_parent.obtain(); | 475 | man = comp.cache_parent.obtain(); |
| | 476 | man.want_shared_lock = false; |
| 476 | self.base.releaseLock(); | 477 | self.base.releaseLock(); |
| 477 | | 478 | |
| 478 | man.hash.addListOfBytes(libs.keys()); | 479 | man.hash.addListOfBytes(libs.keys()); |
| ... | @@ -546,11 +547,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -546,11 +547,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 546 | | 547 | |
| 547 | try self.allocateSpecialSymbols(); | 548 | try self.allocateSpecialSymbols(); |
| 548 | | 549 | |
| 549 | { | 550 | for (self.relocs.keys()) |atom| { |
| 550 | var it = self.relocs.keyIterator(); | 551 | try atom.resolveRelocations(self); |
| 551 | while (it.next()) |atom| { | | |
| 552 | try atom.*.resolveRelocations(self); | | |
| 553 | } | | |
| 554 | } | 552 | } |
| 555 | | 553 | |
| 556 | if (build_options.enable_logging) { | 554 | if (build_options.enable_logging) { |
| ... | @@ -1017,8 +1015,7 @@ fn writePtrWidthAtom(self: *MachO, atom: *Atom) !void { | ... | @@ -1017,8 +1015,7 @@ fn writePtrWidthAtom(self: *MachO, atom: *Atom) !void { |
| 1017 | | 1015 | |
| 1018 | fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { | 1016 | fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { |
| 1019 | // TODO: reverse-lookup might come in handy here | 1017 | // TODO: reverse-lookup might come in handy here |
| 1020 | var it = self.relocs.valueIterator(); | 1018 | for (self.relocs.values()) |*relocs| { |
| 1021 | while (it.next()) |relocs| { | | |
| 1022 | for (relocs.items) |*reloc| { | 1019 | for (relocs.items) |*reloc| { |
| 1023 | if (!reloc.target.eql(target)) continue; | 1020 | if (!reloc.target.eql(target)) continue; |
| 1024 | reloc.dirty = true; | 1021 | reloc.dirty = true; |
| ... | @@ -1027,8 +1024,7 @@ fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { | ... | @@ -1027,8 +1024,7 @@ fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { |
| 1027 | } | 1024 | } |
| 1028 | | 1025 | |
| 1029 | fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void { | 1026 | fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void { |
| 1030 | var it = self.relocs.valueIterator(); | 1027 | for (self.relocs.values()) |*relocs| { |
| 1031 | while (it.next()) |relocs| { | | |
| 1032 | for (relocs.items) |*reloc| { | 1028 | for (relocs.items) |*reloc| { |
| 1033 | const target_atom = reloc.getTargetAtom(self) orelse continue; | 1029 | const target_atom = reloc.getTargetAtom(self) orelse continue; |
| 1034 | const target_sym = target_atom.getSymbol(self); | 1030 | const target_sym = target_atom.getSymbol(self); |
| ... | @@ -1392,7 +1388,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi | ... | @@ -1392,7 +1388,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi |
| 1392 | try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom); | 1388 | try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom); |
| 1393 | | 1389 | |
| 1394 | sym.n_value = try self.allocateAtom(atom, atom.size, @alignOf(u64)); | 1390 | sym.n_value = try self.allocateAtom(atom, atom.size, @alignOf(u64)); |
| 1395 | log.debug("allocated lazy pointer atom at 0x{x}", .{sym.n_value}); | 1391 | log.debug("allocated lazy pointer atom at 0x{x} ({s})", .{ sym.n_value, self.getSymbolName(target) }); |
| 1396 | try self.writePtrWidthAtom(atom); | 1392 | try self.writePtrWidthAtom(atom); |
| 1397 | | 1393 | |
| 1398 | return atom; | 1394 | return atom; |
| ... | @@ -1784,47 +1780,32 @@ pub fn deinit(self: *MachO) void { | ... | @@ -1784,47 +1780,32 @@ pub fn deinit(self: *MachO) void { |
| 1784 | assert(self.decls.count() == 0); | 1780 | assert(self.decls.count() == 0); |
| 1785 | } | 1781 | } |
| 1786 | | 1782 | |
| 1787 | { | 1783 | for (self.unnamed_const_atoms.values()) |*atoms| { |
| 1788 | var it = self.unnamed_const_atoms.valueIterator(); | 1784 | atoms.deinit(gpa); |
| 1789 | while (it.next()) |atoms| { | | |
| 1790 | atoms.deinit(gpa); | | |
| 1791 | } | | |
| 1792 | self.unnamed_const_atoms.deinit(gpa); | | |
| 1793 | } | 1785 | } |
| | 1786 | self.unnamed_const_atoms.deinit(gpa); |
| 1794 | | 1787 | |
| 1795 | self.atom_by_index_table.deinit(gpa); | 1788 | self.atom_by_index_table.deinit(gpa); |
| 1796 | | 1789 | |
| 1797 | { | 1790 | for (self.relocs.values()) |*relocs| { |
| 1798 | var it = self.relocs.valueIterator(); | 1791 | relocs.deinit(gpa); |
| 1799 | while (it.next()) |relocs| { | | |
| 1800 | relocs.deinit(gpa); | | |
| 1801 | } | | |
| 1802 | self.relocs.deinit(gpa); | | |
| 1803 | } | 1792 | } |
| | 1793 | self.relocs.deinit(gpa); |
| 1804 | | 1794 | |
| 1805 | { | 1795 | for (self.rebases.values()) |*rebases| { |
| 1806 | var it = self.rebases.valueIterator(); | 1796 | rebases.deinit(gpa); |
| 1807 | while (it.next()) |rebases| { | | |
| 1808 | rebases.deinit(gpa); | | |
| 1809 | } | | |
| 1810 | self.rebases.deinit(gpa); | | |
| 1811 | } | 1797 | } |
| | 1798 | self.rebases.deinit(gpa); |
| 1812 | | 1799 | |
| 1813 | { | 1800 | for (self.bindings.values()) |*bindings| { |
| 1814 | var it = self.bindings.valueIterator(); | 1801 | bindings.deinit(gpa); |
| 1815 | while (it.next()) |bindings| { | | |
| 1816 | bindings.deinit(gpa); | | |
| 1817 | } | | |
| 1818 | self.bindings.deinit(gpa); | | |
| 1819 | } | 1802 | } |
| | 1803 | self.bindings.deinit(gpa); |
| 1820 | | 1804 | |
| 1821 | { | 1805 | for (self.lazy_bindings.values()) |*bindings| { |
| 1822 | var it = self.lazy_bindings.valueIterator(); | 1806 | bindings.deinit(gpa); |
| 1823 | while (it.next()) |bindings| { | | |
| 1824 | bindings.deinit(gpa); | | |
| 1825 | } | | |
| 1826 | self.lazy_bindings.deinit(gpa); | | |
| 1827 | } | 1807 | } |
| | 1808 | self.lazy_bindings.deinit(gpa); |
| 1828 | } | 1809 | } |
| 1829 | | 1810 | |
| 1830 | fn freeAtom(self: *MachO, atom: *Atom) void { | 1811 | fn freeAtom(self: *MachO, atom: *Atom) void { |
| ... | @@ -2579,13 +2560,13 @@ pub fn deleteExport(self: *MachO, exp: Export) void { | ... | @@ -2579,13 +2560,13 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 2579 | } | 2560 | } |
| 2580 | | 2561 | |
| 2581 | fn freeRelocationsForAtom(self: *MachO, atom: *Atom) void { | 2562 | fn freeRelocationsForAtom(self: *MachO, atom: *Atom) void { |
| 2582 | var removed_relocs = self.relocs.fetchRemove(atom); | 2563 | var removed_relocs = self.relocs.fetchOrderedRemove(atom); |
| 2583 | if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator); | 2564 | if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator); |
| 2584 | var removed_rebases = self.rebases.fetchRemove(atom); | 2565 | var removed_rebases = self.rebases.fetchOrderedRemove(atom); |
| 2585 | if (removed_rebases) |*rebases| rebases.value.deinit(self.base.allocator); | 2566 | if (removed_rebases) |*rebases| rebases.value.deinit(self.base.allocator); |
| 2586 | var removed_bindings = self.bindings.fetchRemove(atom); | 2567 | var removed_bindings = self.bindings.fetchOrderedRemove(atom); |
| 2587 | if (removed_bindings) |*bindings| bindings.value.deinit(self.base.allocator); | 2568 | if (removed_bindings) |*bindings| bindings.value.deinit(self.base.allocator); |
| 2588 | var removed_lazy_bindings = self.lazy_bindings.fetchRemove(atom); | 2569 | var removed_lazy_bindings = self.lazy_bindings.fetchOrderedRemove(atom); |
| 2589 | 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); |
| 2590 | } | 2571 | } |
| 2591 | | 2572 | |
| ... | @@ -3198,11 +3179,8 @@ fn writeLinkeditSegmentData(self: *MachO) !void { | ... | @@ -3198,11 +3179,8 @@ fn writeLinkeditSegmentData(self: *MachO) !void { |
| 3198 | fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { | 3179 | fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3199 | const gpa = self.base.allocator; | 3180 | const gpa = self.base.allocator; |
| 3200 | const slice = self.sections.slice(); | 3181 | const slice = self.sections.slice(); |
| 3201 | var it = self.rebases.keyIterator(); | | |
| 3202 | | | |
| 3203 | while (it.next()) |key_ptr| { | | |
| 3204 | const atom = key_ptr.*; | | |
| 3205 | | 3182 | |
| | 3183 | for (self.rebases.keys()) |atom, i| { |
| 3206 | log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) }); | 3184 | log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) }); |
| 3207 | | 3185 | |
| 3208 | const sym = atom.getSymbol(self); | 3186 | const sym = atom.getSymbol(self); |
| ... | @@ -3211,7 +3189,7 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { | ... | @@ -3211,7 +3189,7 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3211 | | 3189 | |
| 3212 | const base_offset = sym.n_value - seg.vmaddr; | 3190 | const base_offset = sym.n_value - seg.vmaddr; |
| 3213 | | 3191 | |
| 3214 | const rebases = self.rebases.get(atom).?; | 3192 | const rebases = self.rebases.values()[i]; |
| 3215 | try rebase.entries.ensureUnusedCapacity(gpa, rebases.items.len); | 3193 | try rebase.entries.ensureUnusedCapacity(gpa, rebases.items.len); |
| 3216 | | 3194 | |
| 3217 | for (rebases.items) |offset| { | 3195 | for (rebases.items) |offset| { |
| ... | @@ -3230,11 +3208,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { | ... | @@ -3230,11 +3208,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3230 | fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { | 3208 | fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { |
| 3231 | const gpa = self.base.allocator; | 3209 | const gpa = self.base.allocator; |
| 3232 | const slice = self.sections.slice(); | 3210 | const slice = self.sections.slice(); |
| 3233 | var it = raw_bindings.keyIterator(); | | |
| 3234 | | | |
| 3235 | while (it.next()) |key_ptr| { | | |
| 3236 | const atom = key_ptr.*; | | |
| 3237 | | 3211 | |
| | 3212 | for (raw_bindings.keys()) |atom, i| { |
| 3238 | log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) }); | 3213 | log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) }); |
| 3239 | | 3214 | |
| 3240 | const sym = atom.getSymbol(self); | 3215 | const sym = atom.getSymbol(self); |
| ... | @@ -3243,7 +3218,7 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { | ... | @@ -3243,7 +3218,7 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { |
| 3243 | | 3218 | |
| 3244 | const base_offset = sym.n_value - seg.vmaddr; | 3219 | const base_offset = sym.n_value - seg.vmaddr; |
| 3245 | | 3220 | |
| 3246 | const bindings = raw_bindings.get(atom).?; | 3221 | const bindings = raw_bindings.values()[i]; |
| 3247 | try bind.entries.ensureUnusedCapacity(gpa, bindings.items.len); | 3222 | try bind.entries.ensureUnusedCapacity(gpa, bindings.items.len); |
| 3248 | | 3223 | |
| 3249 | for (bindings.items) |binding| { | 3224 | for (bindings.items) |binding| { |
| ... | @@ -3421,13 +3396,17 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void | ... | @@ -3421,13 +3396,17 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void |
| 3421 | const header = section.header; | 3396 | const header = section.header; |
| 3422 | var atom = section.last_atom.?; | 3397 | var atom = section.last_atom.?; |
| 3423 | | 3398 | |
| 3424 | var index: usize = 0; | 3399 | var index: usize = lazy_bind.offsets.items.len; |
| 3425 | while (index < lazy_bind.offsets.items.len) : (index += 1) { | 3400 | while (index > 0) : (index -= 1) { |
| 3426 | const sym = atom.getSymbol(self); | 3401 | const sym = atom.getSymbol(self); |
| 3427 | const file_offset = header.offset + sym.n_value - header.addr + stub_offset; | 3402 | const file_offset = header.offset + sym.n_value - header.addr + stub_offset; |
| 3428 | const bind_offset = lazy_bind.offsets.items[index]; | 3403 | const bind_offset = lazy_bind.offsets.items[index - 1]; |
| 3429 | | 3404 | |
| 3430 | log.debug("writing lazy bind offset 0x{x} in stub helper at 0x{x}", .{ bind_offset, file_offset }); | 3405 | log.debug("writing lazy bind offset 0x{x} ({s}) in stub helper at 0x{x}", .{ |
| | 3406 | bind_offset, |
| | 3407 | self.getSymbolName(lazy_bind.entries.items[index - 1].target), |
| | 3408 | file_offset, |
| | 3409 | }); |
| 3431 | | 3410 | |
| 3432 | try self.base.file.?.pwriteAll(mem.asBytes(&bind_offset), file_offset); | 3411 | try self.base.file.?.pwriteAll(mem.asBytes(&bind_offset), file_offset); |
| 3433 | | 3412 | |