authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-01-20 18:28:16+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-01-20 18:28:16+01:00
log74b72a766de96c7c70fc8a02d3e2ee3cd353f225
tree0c0cc7e1aa65f0ef6f9b1d29ea88b965f9f21c47
parent37fe41792c72f98657e5c51caa5bfd9ded7eb409
parent9f0cb763a4b78d386291bdd912cc5c85c5752b3a
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14386 from ziglang/macho-fixes

macho: fix nondeterministic failures in the macOS CI

1 files changed, 42 insertions(+), 63 deletions(-)

src/link/MachO.zig+42-63
...@@ -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,
...@@ -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
469469
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();
473473
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();
477478
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
546547
547 try self.allocateSpecialSymbols();548 try self.allocateSpecialSymbols();
548549
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 }
555553
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 {
10171015
1018fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void {1016fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void {
1019 // TODO: reverse-lookup might come in handy here1017 // 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}
10281025
1029fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void {1026fn 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);
13931389
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);
13971393
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 }
17861782
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);
17941787
1795 self.atom_by_index_table.deinit(gpa);1788 self.atom_by_index_table.deinit(gpa);
17961789
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);
18041794
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);
18121799
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);
18201804
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}
18291810
1830fn freeAtom(self: *MachO, atom: *Atom) void {1811fn 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}
25802561
2581fn freeRelocationsForAtom(self: *MachO, atom: *Atom) void {2562fn 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}
25912572
...@@ -3198,11 +3179,8 @@ fn writeLinkeditSegmentData(self: *MachO) !void {...@@ -3198,11 +3179,8 @@ fn writeLinkeditSegmentData(self: *MachO) !void {
3198fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {3179fn 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.*;
32053182
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) });
32073185
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 {
32113189
3212 const base_offset = sym.n_value - seg.vmaddr;3190 const base_offset = sym.n_value - seg.vmaddr;
32133191
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);
32163194
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 {
3230fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {3208fn 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.*;
32373211
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) });
32393214
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 {
32433218
3244 const base_offset = sym.n_value - seg.vmaddr;3219 const base_offset = sym.n_value - seg.vmaddr;
32453220
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);
32483223
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.?;
34233398
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];
34293404
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 });
34313410
3432 try self.base.file.?.pwriteAll(mem.asBytes(&bind_offset), file_offset);3411 try self.base.file.?.pwriteAll(mem.asBytes(&bind_offset), file_offset);
34333412