| ... | ... | @@ -27,7 +27,7 @@ sections: std.MultiArrayList(Section) = .{}, |
| 27 | 27 | resolver: SymbolResolver = .{}, |
| 28 | 28 | /// This table will be populated after `scanRelocs` has run. |
| 29 | 29 | /// Key is symbol index. |
| 30 | | undefs: std.AutoArrayHashMapUnmanaged(SymbolResolver.Index, std.ArrayListUnmanaged(Ref)) = .empty, |
| 30 | undefs: std.AutoArrayHashMapUnmanaged(SymbolResolver.Index, UndefRefs) = .empty, |
| 31 | 31 | undefs_mutex: std.Thread.Mutex = .{}, |
| 32 | 32 | dupes: std.AutoArrayHashMapUnmanaged(SymbolResolver.Index, std.ArrayListUnmanaged(File.Index)) = .empty, |
| 33 | 33 | dupes_mutex: std.Thread.Mutex = .{}, |
| ... | ... | @@ -1470,6 +1470,9 @@ fn scanRelocs(self: *MachO) !void { |
| 1470 | 1470 | |
| 1471 | 1471 | if (self.has_errors.swap(false, .seq_cst)) return error.FlushFailure; |
| 1472 | 1472 | |
| 1473 | if (self.getInternalObject()) |obj| { |
| 1474 | try obj.checkUndefs(self); |
| 1475 | } |
| 1473 | 1476 | try self.reportUndefs(); |
| 1474 | 1477 | |
| 1475 | 1478 | if (self.getZigObject()) |zo| { |
| ... | ... | @@ -1530,29 +1533,43 @@ fn reportUndefs(self: *MachO) !void { |
| 1530 | 1533 | } |
| 1531 | 1534 | }.lessThan; |
| 1532 | 1535 | |
| 1533 | | for (self.undefs.values()) |*refs| { |
| 1534 | | mem.sort(Ref, refs.items, {}, refLessThan); |
| 1535 | | } |
| 1536 | for (self.undefs.values()) |*undefs| switch (undefs.*) { |
| 1537 | .refs => |refs| mem.sort(Ref, refs.items, {}, refLessThan), |
| 1538 | else => {}, |
| 1539 | }; |
| 1536 | 1540 | |
| 1537 | 1541 | for (keys.items) |key| { |
| 1538 | 1542 | const undef_sym = self.resolver.keys.items[key - 1]; |
| 1539 | 1543 | const notes = self.undefs.get(key).?; |
| 1540 | | const nnotes = @min(notes.items.len, max_notes) + @intFromBool(notes.items.len > max_notes); |
| 1544 | const nnotes = nnotes: { |
| 1545 | const nnotes = switch (notes) { |
| 1546 | .refs => |refs| refs.items.len, |
| 1547 | else => 1, |
| 1548 | }; |
| 1549 | break :nnotes @min(nnotes, max_notes) + @intFromBool(nnotes > max_notes); |
| 1550 | }; |
| 1541 | 1551 | |
| 1542 | 1552 | var err = try self.base.addErrorWithNotes(nnotes); |
| 1543 | 1553 | try err.addMsg("undefined symbol: {s}", .{undef_sym.getName(self)}); |
| 1544 | 1554 | |
| 1545 | | var inote: usize = 0; |
| 1546 | | while (inote < @min(notes.items.len, max_notes)) : (inote += 1) { |
| 1547 | | const note = notes.items[inote]; |
| 1548 | | const file = self.getFile(note.file).?; |
| 1549 | | const atom = note.getAtom(self).?; |
| 1550 | | try err.addNote("referenced by {}:{s}", .{ file.fmtPath(), atom.getName(self) }); |
| 1551 | | } |
| 1555 | switch (notes) { |
| 1556 | .force_undefined => try err.addNote("referenced with linker flag -u", .{}), |
| 1557 | .entry => try err.addNote("referenced with linker flag -e", .{}), |
| 1558 | .dyld_stub_binder, .objc_msgsend => try err.addNote("referenced implicitly", .{}), |
| 1559 | .refs => |refs| { |
| 1560 | var inote: usize = 0; |
| 1561 | while (inote < @min(refs.items.len, max_notes)) : (inote += 1) { |
| 1562 | const ref = refs.items[inote]; |
| 1563 | const file = self.getFile(ref.file).?; |
| 1564 | const atom = ref.getAtom(self).?; |
| 1565 | try err.addNote("referenced by {}:{s}", .{ file.fmtPath(), atom.getName(self) }); |
| 1566 | } |
| 1552 | 1567 | |
| 1553 | | if (notes.items.len > max_notes) { |
| 1554 | | const remaining = notes.items.len - max_notes; |
| 1555 | | try err.addNote("referenced {d} more times", .{remaining}); |
| 1568 | if (refs.items.len > max_notes) { |
| 1569 | const remaining = refs.items.len - max_notes; |
| 1570 | try err.addNote("referenced {d} more times", .{remaining}); |
| 1571 | } |
| 1572 | }, |
| 1556 | 1573 | } |
| 1557 | 1574 | } |
| 1558 | 1575 | |
| ... | ... | @@ -4584,78 +4601,20 @@ pub const String = struct { |
| 4584 | 4601 | len: u32 = 0, |
| 4585 | 4602 | }; |
| 4586 | 4603 | |
| 4587 | | const MachO = @This(); |
| 4588 | | |
| 4589 | | const std = @import("std"); |
| 4590 | | const build_options = @import("build_options"); |
| 4591 | | const builtin = @import("builtin"); |
| 4592 | | const assert = std.debug.assert; |
| 4593 | | const fs = std.fs; |
| 4594 | | const log = std.log.scoped(.link); |
| 4595 | | const state_log = std.log.scoped(.link_state); |
| 4596 | | const macho = std.macho; |
| 4597 | | const math = std.math; |
| 4598 | | const mem = std.mem; |
| 4599 | | const meta = std.meta; |
| 4600 | | |
| 4601 | | const aarch64 = @import("../arch/aarch64/bits.zig"); |
| 4602 | | const bind = @import("MachO/dyld_info/bind.zig"); |
| 4603 | | const calcUuid = @import("MachO/uuid.zig").calcUuid; |
| 4604 | | const codegen = @import("../codegen.zig"); |
| 4605 | | const dead_strip = @import("MachO/dead_strip.zig"); |
| 4606 | | const eh_frame = @import("MachO/eh_frame.zig"); |
| 4607 | | const fat = @import("MachO/fat.zig"); |
| 4608 | | const link = @import("../link.zig"); |
| 4609 | | const load_commands = @import("MachO/load_commands.zig"); |
| 4610 | | const relocatable = @import("MachO/relocatable.zig"); |
| 4611 | | const tapi = @import("tapi.zig"); |
| 4612 | | const target_util = @import("../target.zig"); |
| 4613 | | const trace = @import("../tracy.zig").trace; |
| 4614 | | const synthetic = @import("MachO/synthetic.zig"); |
| 4604 | pub const UndefRefs = union(enum) { |
| 4605 | force_undefined, |
| 4606 | entry, |
| 4607 | dyld_stub_binder, |
| 4608 | objc_msgsend, |
| 4609 | refs: std.ArrayListUnmanaged(Ref), |
| 4615 | 4610 | |
| 4616 | | const Air = @import("../Air.zig"); |
| 4617 | | const Alignment = Atom.Alignment; |
| 4618 | | const Allocator = mem.Allocator; |
| 4619 | | const Archive = @import("MachO/Archive.zig"); |
| 4620 | | pub const Atom = @import("MachO/Atom.zig"); |
| 4621 | | const AtomicBool = std.atomic.Value(bool); |
| 4622 | | const Bind = bind.Bind; |
| 4623 | | const Cache = std.Build.Cache; |
| 4624 | | const Path = Cache.Path; |
| 4625 | | const CodeSignature = @import("MachO/CodeSignature.zig"); |
| 4626 | | const Compilation = @import("../Compilation.zig"); |
| 4627 | | const DataInCode = synthetic.DataInCode; |
| 4628 | | pub const DebugSymbols = @import("MachO/DebugSymbols.zig"); |
| 4629 | | const Dylib = @import("MachO/Dylib.zig"); |
| 4630 | | const ExportTrie = @import("MachO/dyld_info/Trie.zig"); |
| 4631 | | const File = @import("MachO/file.zig").File; |
| 4632 | | const GotSection = synthetic.GotSection; |
| 4633 | | const Hash = std.hash.Wyhash; |
| 4634 | | const Indsymtab = synthetic.Indsymtab; |
| 4635 | | const InternalObject = @import("MachO/InternalObject.zig"); |
| 4636 | | const ObjcStubsSection = synthetic.ObjcStubsSection; |
| 4637 | | const Object = @import("MachO/Object.zig"); |
| 4638 | | const LazyBind = bind.LazyBind; |
| 4639 | | const LaSymbolPtrSection = synthetic.LaSymbolPtrSection; |
| 4640 | | const Liveness = @import("../Liveness.zig"); |
| 4641 | | const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 4642 | | const Md5 = std.crypto.hash.Md5; |
| 4643 | | const Zcu = @import("../Zcu.zig"); |
| 4644 | | const InternPool = @import("../InternPool.zig"); |
| 4645 | | const Rebase = @import("MachO/dyld_info/Rebase.zig"); |
| 4646 | | pub const Relocation = @import("MachO/Relocation.zig"); |
| 4647 | | const StringTable = @import("StringTable.zig"); |
| 4648 | | const StubsSection = synthetic.StubsSection; |
| 4649 | | const StubsHelperSection = synthetic.StubsHelperSection; |
| 4650 | | const Symbol = @import("MachO/Symbol.zig"); |
| 4651 | | const Thunk = @import("MachO/Thunk.zig"); |
| 4652 | | const TlvPtrSection = synthetic.TlvPtrSection; |
| 4653 | | const Value = @import("../Value.zig"); |
| 4654 | | const UnwindInfo = @import("MachO/UnwindInfo.zig"); |
| 4655 | | const WaitGroup = std.Thread.WaitGroup; |
| 4656 | | const WeakBind = bind.WeakBind; |
| 4657 | | const ZigObject = @import("MachO/ZigObject.zig"); |
| 4658 | | const dev = @import("../dev.zig"); |
| 4611 | pub fn deinit(self: *UndefRefs, allocator: Allocator) void { |
| 4612 | switch (self.*) { |
| 4613 | .refs => |*refs| refs.deinit(allocator), |
| 4614 | else => {}, |
| 4615 | } |
| 4616 | } |
| 4617 | }; |
| 4659 | 4618 | |
| 4660 | 4619 | pub const MachError = error{ |
| 4661 | 4620 | /// Not enough permissions held to perform the requested kernel |
| ... | ... | @@ -5392,3 +5351,76 @@ const max_distance = (1 << (jump_bits - 1)); |
| 5392 | 5351 | /// mold uses 5MiB margin, while ld64 uses 4MiB margin. We will follow mold |
| 5393 | 5352 | /// and assume margin to be 5MiB. |
| 5394 | 5353 | const max_allowed_distance = max_distance - 0x500_000; |
| 5354 | |
| 5355 | const MachO = @This(); |
| 5356 | |
| 5357 | const std = @import("std"); |
| 5358 | const build_options = @import("build_options"); |
| 5359 | const builtin = @import("builtin"); |
| 5360 | const assert = std.debug.assert; |
| 5361 | const fs = std.fs; |
| 5362 | const log = std.log.scoped(.link); |
| 5363 | const state_log = std.log.scoped(.link_state); |
| 5364 | const macho = std.macho; |
| 5365 | const math = std.math; |
| 5366 | const mem = std.mem; |
| 5367 | const meta = std.meta; |
| 5368 | |
| 5369 | const aarch64 = @import("../arch/aarch64/bits.zig"); |
| 5370 | const bind = @import("MachO/dyld_info/bind.zig"); |
| 5371 | const calcUuid = @import("MachO/uuid.zig").calcUuid; |
| 5372 | const codegen = @import("../codegen.zig"); |
| 5373 | const dead_strip = @import("MachO/dead_strip.zig"); |
| 5374 | const eh_frame = @import("MachO/eh_frame.zig"); |
| 5375 | const fat = @import("MachO/fat.zig"); |
| 5376 | const link = @import("../link.zig"); |
| 5377 | const load_commands = @import("MachO/load_commands.zig"); |
| 5378 | const relocatable = @import("MachO/relocatable.zig"); |
| 5379 | const tapi = @import("tapi.zig"); |
| 5380 | const target_util = @import("../target.zig"); |
| 5381 | const trace = @import("../tracy.zig").trace; |
| 5382 | const synthetic = @import("MachO/synthetic.zig"); |
| 5383 | |
| 5384 | const Air = @import("../Air.zig"); |
| 5385 | const Alignment = Atom.Alignment; |
| 5386 | const Allocator = mem.Allocator; |
| 5387 | const Archive = @import("MachO/Archive.zig"); |
| 5388 | pub const Atom = @import("MachO/Atom.zig"); |
| 5389 | const AtomicBool = std.atomic.Value(bool); |
| 5390 | const Bind = bind.Bind; |
| 5391 | const Cache = std.Build.Cache; |
| 5392 | const Path = Cache.Path; |
| 5393 | const CodeSignature = @import("MachO/CodeSignature.zig"); |
| 5394 | const Compilation = @import("../Compilation.zig"); |
| 5395 | const DataInCode = synthetic.DataInCode; |
| 5396 | pub const DebugSymbols = @import("MachO/DebugSymbols.zig"); |
| 5397 | const Dylib = @import("MachO/Dylib.zig"); |
| 5398 | const ExportTrie = @import("MachO/dyld_info/Trie.zig"); |
| 5399 | const File = @import("MachO/file.zig").File; |
| 5400 | const GotSection = synthetic.GotSection; |
| 5401 | const Hash = std.hash.Wyhash; |
| 5402 | const Indsymtab = synthetic.Indsymtab; |
| 5403 | const InternalObject = @import("MachO/InternalObject.zig"); |
| 5404 | const ObjcStubsSection = synthetic.ObjcStubsSection; |
| 5405 | const Object = @import("MachO/Object.zig"); |
| 5406 | const LazyBind = bind.LazyBind; |
| 5407 | const LaSymbolPtrSection = synthetic.LaSymbolPtrSection; |
| 5408 | const Liveness = @import("../Liveness.zig"); |
| 5409 | const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 5410 | const Md5 = std.crypto.hash.Md5; |
| 5411 | const Zcu = @import("../Zcu.zig"); |
| 5412 | const InternPool = @import("../InternPool.zig"); |
| 5413 | const Rebase = @import("MachO/dyld_info/Rebase.zig"); |
| 5414 | pub const Relocation = @import("MachO/Relocation.zig"); |
| 5415 | const StringTable = @import("StringTable.zig"); |
| 5416 | const StubsSection = synthetic.StubsSection; |
| 5417 | const StubsHelperSection = synthetic.StubsHelperSection; |
| 5418 | const Symbol = @import("MachO/Symbol.zig"); |
| 5419 | const Thunk = @import("MachO/Thunk.zig"); |
| 5420 | const TlvPtrSection = synthetic.TlvPtrSection; |
| 5421 | const Value = @import("../Value.zig"); |
| 5422 | const UnwindInfo = @import("MachO/UnwindInfo.zig"); |
| 5423 | const WaitGroup = std.Thread.WaitGroup; |
| 5424 | const WeakBind = bind.WeakBind; |
| 5425 | const ZigObject = @import("MachO/ZigObject.zig"); |
| 5426 | const dev = @import("../dev.zig"); |