authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-30 00:09:32+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-30 00:09:32+01:00
log2e690f5c74cbfd16757cc301ac0d899caa8b2fb3
treead622a039430932b24f69d968d73c3e4fb8c8ed8
parent71dfea1f174b0531139e33e8aa4fe86ccd9f23dd

macho: implement enough of extern handling to pass comptime export tests


7 files changed, 121 insertions(+), 73 deletions(-)

src/arch/x86_64/CodeGen.zig+2-1
......@@ -13080,12 +13080,13 @@ fn genExternSymbolRef(
1308013080 else => unreachable,
1308113081 }
1308213082 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
13083 const global_index = try macho_file.getGlobalSymbol(callee, lib);
1308313084 _ = try self.addInst(.{
1308413085 .tag = .call,
1308513086 .ops = .extern_fn_reloc,
1308613087 .data = .{ .reloc = .{
1308713088 .atom_index = atom_index,
13088 .sym_index = try macho_file.getGlobalSymbol(callee, lib),
13089 .sym_index = link.File.MachO.global_symbol_bit | global_index,
1308913090 } },
1309013091 });
1309113092 } else return self.fail("TODO implement calling extern functions", .{});
src/arch/x86_64/Emit.zig+9-2
......@@ -52,7 +52,10 @@ pub fn emitMir(emit: *Emit) Error!void {
5252 // Add relocation to the decl.
5353 const atom_index =
5454 macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
55 const target = macho_file.getGlobalByIndex(symbol.sym_index);
55 const target = if (link.File.MachO.global_symbol_bit & symbol.sym_index != 0)
56 macho_file.getGlobalByIndex(link.File.MachO.global_symbol_mask & symbol.sym_index)
57 else
58 link.File.MachO.SymbolWithLoc{ .sym_index = symbol.sym_index };
5659 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
5760 .type = .branch,
5861 .target = target,
......@@ -116,6 +119,10 @@ pub fn emitMir(emit: *Emit) Error!void {
116119 } else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
117120 const atom_index =
118121 macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
122 const target = if (link.File.MachO.global_symbol_bit & symbol.sym_index != 0)
123 macho_file.getGlobalByIndex(link.File.MachO.global_symbol_mask & symbol.sym_index)
124 else
125 link.File.MachO.SymbolWithLoc{ .sym_index = symbol.sym_index };
119126 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
120127 .type = switch (lowered_relocs[0].target) {
121128 .linker_got => .got,
......@@ -123,7 +130,7 @@ pub fn emitMir(emit: *Emit) Error!void {
123130 .linker_tlv => .tlv,
124131 else => unreachable,
125132 },
126 .target = .{ .sym_index = symbol.sym_index },
133 .target = target,
127134 .offset = @as(u32, @intCast(end_offset - 4)),
128135 .addend = 0,
129136 .pcrel = true,
src/codegen.zig+9
......@@ -721,6 +721,7 @@ fn lowerAnonDeclRef(
721721 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
722722 const decl_val = anon_decl.val;
723723 const decl_ty = mod.intern_pool.typeOf(decl_val).toType();
724 log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(mod)});
724725 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
725726 if (!is_fn_body and !decl_ty.hasRuntimeBits(mod)) {
726727 try code.appendNTimes(0xaa, ptr_width_bytes);
......@@ -911,6 +912,14 @@ fn genDeclRef(
911912 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
912913 return GenResult.mcv(.{ .load_symbol = sym.esym_index });
913914 } else if (bin_file.cast(link.File.MachO)) |macho_file| {
915 if (is_extern) {
916 // TODO make this part of getGlobalSymbol
917 const name = mod.intern_pool.stringToSlice(decl.name);
918 const sym_name = try std.fmt.allocPrint(bin_file.allocator, "_{s}", .{name});
919 defer bin_file.allocator.free(sym_name);
920 const global_index = try macho_file.addUndefined(sym_name, .{ .add_got = true });
921 return GenResult.mcv(.{ .load_got = link.File.MachO.global_symbol_bit | global_index });
922 }
914923 const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
915924 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
916925 if (is_threadlocal) {
src/link/MachO.zig+74-42
......@@ -50,7 +50,7 @@ tlv_ptr_section_index: ?u8 = null,
5050locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
5151globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{},
5252resolver: std.StringHashMapUnmanaged(u32) = .{},
53unresolved: std.AutoArrayHashMapUnmanaged(u32, ResolveAction.Kind) = .{},
53unresolved: std.AutoArrayHashMapUnmanaged(u32, void) = .{},
5454
5555locals_free_list: std.ArrayListUnmanaged(u32) = .{},
5656globals_free_list: std.ArrayListUnmanaged(u32) = .{},
......@@ -115,6 +115,10 @@ anon_decls: AnonDeclTable = .{},
115115/// Note that once we refactor `Atom`'s lifetime and ownership rules,
116116/// this will be a table indexed by index into the list of Atoms.
117117relocs: RelocationTable = .{},
118/// TODO I do not have time to make this right but this will go once
119/// MachO linker is rewritten more-or-less to feature the same resolution
120/// mechanism as the ELF linker.
121actions: ActionTable = .{},
118122
119123/// A table of rebases indexed by the owning them `Atom`.
120124/// Note that once we refactor `Atom`'s lifetime and ownership rules,
......@@ -417,9 +421,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
417421 try self.parseDependentLibs(&dependent_libs);
418422 }
419423
420 var actions = std.ArrayList(ResolveAction).init(self.base.allocator);
421 defer actions.deinit();
422 try self.resolveSymbols(&actions);
424 try self.resolveSymbols();
423425
424426 if (self.getEntryPoint() == null) {
425427 self.error_flags.no_entry_point_found = true;
......@@ -429,11 +431,16 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
429431 return error.FlushFailure;
430432 }
431433
432 for (actions.items) |action| switch (action.kind) {
433 .none => {},
434 .add_got => try self.addGotEntry(action.target),
435 .add_stub => try self.addStubEntry(action.target),
436 };
434 {
435 var it = self.actions.iterator();
436 while (it.next()) |entry| {
437 const global_index = entry.key_ptr.*;
438 const global = self.globals.items[global_index];
439 const flags = entry.value_ptr.*;
440 if (flags.add_got) try self.addGotEntry(global);
441 if (flags.add_stub) try self.addStubEntry(global);
442 }
443 }
437444
438445 try self.createDyldPrivateAtom();
439446 try self.writeStubHelperPreamble();
......@@ -1589,18 +1596,18 @@ pub fn createDsoHandleSymbol(self: *MachO) !void {
15891596 _ = self.unresolved.swapRemove(self.getGlobalIndex("___dso_handle").?);
15901597}
15911598
1592pub fn resolveSymbols(self: *MachO, actions: *std.ArrayList(ResolveAction)) !void {
1599pub fn resolveSymbols(self: *MachO) !void {
15931600 // We add the specified entrypoint as the first unresolved symbols so that
15941601 // we search for it in libraries should there be no object files specified
15951602 // on the linker line.
15961603 if (self.base.options.output_mode == .Exe) {
15971604 const entry_name = self.base.options.entry orelse load_commands.default_entry_point;
1598 _ = try self.addUndefined(entry_name, .none);
1605 _ = try self.addUndefined(entry_name, .{});
15991606 }
16001607
16011608 // Force resolution of any symbols requested by the user.
16021609 for (self.base.options.force_undefined_symbols.keys()) |sym_name| {
1603 _ = try self.addUndefined(sym_name, .none);
1610 _ = try self.addUndefined(sym_name, .{});
16041611 }
16051612
16061613 for (self.objects.items, 0..) |_, object_id| {
......@@ -1612,13 +1619,13 @@ pub fn resolveSymbols(self: *MachO, actions: *std.ArrayList(ResolveAction)) !voi
16121619 // Finally, force resolution of dyld_stub_binder if there are imports
16131620 // requested.
16141621 if (self.unresolved.count() > 0 and self.dyld_stub_binder_index == null) {
1615 self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .add_got);
1622 self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .{ .add_got = true });
16161623 }
16171624 if (!self.base.options.single_threaded and self.mode == .incremental) {
1618 _ = try self.addUndefined("__tlv_bootstrap", .none);
1625 _ = try self.addUndefined("__tlv_bootstrap", .{});
16191626 }
16201627
1621 try self.resolveSymbolsInDylibs(actions);
1628 try self.resolveSymbolsInDylibs();
16221629
16231630 try self.createMhExecuteHeaderSymbol();
16241631 try self.createDsoHandleSymbol();
......@@ -1634,7 +1641,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void {
16341641 if (!gop.found_existing) {
16351642 gop.value_ptr.* = current;
16361643 if (sym.undf() and !sym.tentative()) {
1637 try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, .none);
1644 try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, {});
16381645 }
16391646 return;
16401647 }
......@@ -1766,7 +1773,7 @@ fn resolveSymbolsInArchives(self: *MachO) !void {
17661773 }
17671774}
17681775
1769fn resolveSymbolsInDylibs(self: *MachO, actions: *std.ArrayList(ResolveAction)) !void {
1776fn resolveSymbolsInDylibs(self: *MachO) !void {
17701777 if (self.dylibs.items.len == 0) return;
17711778
17721779 const gpa = self.base.allocator;
......@@ -1793,11 +1800,7 @@ fn resolveSymbolsInDylibs(self: *MachO, actions: *std.ArrayList(ResolveAction))
17931800 sym.n_desc |= macho.N_WEAK_REF;
17941801 }
17951802
1796 if (self.unresolved.fetchSwapRemove(global_index)) |entry| blk: {
1797 if (!sym.undf()) break :blk;
1798 if (self.mode == .zld) break :blk;
1799 try actions.append(.{ .kind = entry.value, .target = global });
1800 }
1803 _ = self.unresolved.swapRemove(global_index);
18011804
18021805 continue :loop;
18031806 }
......@@ -1927,6 +1930,7 @@ pub fn deinit(self: *MachO) void {
19271930 relocs.deinit(gpa);
19281931 }
19291932 self.relocs.deinit(gpa);
1933 self.actions.deinit(gpa);
19301934
19311935 for (self.rebases.values()) |*rebases| {
19321936 rebases.deinit(gpa);
......@@ -2266,6 +2270,7 @@ fn lowerConst(
22662270 log.debug(" (required alignment 0x{x})", .{required_alignment});
22672271
22682272 try self.writeAtom(atom_index, code);
2273 self.markRelocsDirtyByTarget(atom.getSymbolWithLoc());
22692274
22702275 return .{ .ok = atom_index };
22712276}
......@@ -2281,12 +2286,16 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: Module.Decl.Index) !vo
22812286 const decl = mod.declPtr(decl_index);
22822287
22832288 if (decl.val.getExternFunc(mod)) |_| {
2284 return; // TODO Should we do more when front-end analyzed extern decl?
2289 return;
22852290 }
2286 if (decl.val.getVariable(mod)) |variable| {
2287 if (variable.is_extern) {
2288 return; // TODO Should we do more when front-end analyzed extern decl?
2289 }
2291
2292 if (decl.isExtern(mod)) {
2293 // TODO make this part of getGlobalSymbol
2294 const name = mod.intern_pool.stringToSlice(decl.name);
2295 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
2296 defer self.base.allocator.free(sym_name);
2297 _ = try self.addUndefined(sym_name, .{ .add_got = true });
2298 return;
22902299 }
22912300
22922301 const is_threadlocal = if (decl.val.getVariable(mod)) |variable|
......@@ -2753,7 +2762,17 @@ pub fn updateExports(
27532762 }
27542763
27552764 const global_sym_index = metadata.getExport(self, exp_name) orelse blk: {
2756 const global_sym_index = try self.allocateSymbol();
2765 const global_sym_index = if (self.getGlobalIndex(exp_name)) |global_index| ind: {
2766 const global = self.globals.items[global_index];
2767 // TODO this is just plain wrong as it all should happen in a single `resolveSymbols`
2768 // pass. This will go away once we abstact away Zig's incremental compilation into
2769 // its own module.
2770 if (global.getFile() == null and self.getSymbol(global).undf()) {
2771 _ = self.unresolved.swapRemove(global_index);
2772 break :ind global.sym_index;
2773 }
2774 break :ind try self.allocateSymbol();
2775 } else try self.allocateSymbol();
27572776 try metadata.exports.append(gpa, global_sym_index);
27582777 break :blk global_sym_index;
27592778 };
......@@ -3422,7 +3441,7 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u
34223441 const gpa = self.base.allocator;
34233442 const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
34243443 defer gpa.free(sym_name);
3425 return self.addUndefined(sym_name, .add_stub);
3444 return self.addUndefined(sym_name, .{ .add_stub = true });
34263445}
34273446
34283447pub fn writeSegmentHeaders(self: *MachO, writer: anytype) !void {
......@@ -4706,13 +4725,16 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void {
47064725 self.hot_state.mach_task = null;
47074726}
47084727
4709fn addUndefined(self: *MachO, name: []const u8, action: ResolveAction.Kind) !u32 {
4728pub fn addUndefined(self: *MachO, name: []const u8, flags: RelocFlags) !u32 {
47104729 const gpa = self.base.allocator;
47114730
47124731 const gop = try self.getOrPutGlobalPtr(name);
47134732 const global_index = self.getGlobalIndex(name).?;
47144733
4715 if (gop.found_existing) return global_index;
4734 if (gop.found_existing) {
4735 try self.updateRelocActions(global_index, flags);
4736 return global_index;
4737 }
47164738
47174739 const sym_index = try self.allocateSymbol();
47184740 const sym_loc = SymbolWithLoc{ .sym_index = sym_index };
......@@ -4720,13 +4742,23 @@ fn addUndefined(self: *MachO, name: []const u8, action: ResolveAction.Kind) !u32
47204742
47214743 const sym = self.getSymbolPtr(sym_loc);
47224744 sym.n_strx = try self.strtab.insert(gpa, name);
4723 sym.n_type = macho.N_UNDF;
4745 sym.n_type = macho.N_EXT | macho.N_UNDF;
47244746
4725 try self.unresolved.putNoClobber(gpa, global_index, action);
4747 try self.unresolved.putNoClobber(gpa, global_index, {});
4748 try self.updateRelocActions(global_index, flags);
47264749
47274750 return global_index;
47284751}
47294752
4753fn updateRelocActions(self: *MachO, global_index: u32, flags: RelocFlags) !void {
4754 const act_gop = try self.actions.getOrPut(self.base.allocator, global_index);
4755 if (!act_gop.found_existing) {
4756 act_gop.value_ptr.* = .{};
4757 }
4758 act_gop.value_ptr.add_got = act_gop.value_ptr.add_got or flags.add_got;
4759 act_gop.value_ptr.add_stub = act_gop.value_ptr.add_stub or flags.add_stub;
4760}
4761
47304762pub fn makeStaticString(bytes: []const u8) [16]u8 {
47314763 var buf = [_]u8{0} ** 16;
47324764 @memcpy(buf[0..bytes.len], bytes);
......@@ -4838,6 +4870,11 @@ const GetOrPutGlobalPtrResult = struct {
48384870 value_ptr: *SymbolWithLoc,
48394871};
48404872
4873/// Used only for disambiguating local from global at relocation level.
4874/// TODO this must go away.
4875pub const global_symbol_bit: u32 = 0x80000000;
4876pub const global_symbol_mask: u32 = 0x7fffffff;
4877
48414878/// Return pointer to the global entry for `name` if one exists.
48424879/// Puts a new global entry for `name` if one doesn't exist, and
48434880/// returns a pointer to it.
......@@ -5510,16 +5547,11 @@ const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnma
55105547const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));
55115548const RebaseTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32));
55125549const RelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation));
5550const ActionTable = std.AutoHashMapUnmanaged(u32, RelocFlags);
55135551
5514pub const ResolveAction = struct {
5515 kind: Kind,
5516 target: SymbolWithLoc,
5517
5518 const Kind = enum {
5519 none,
5520 add_got,
5521 add_stub,
5522 };
5552pub const RelocFlags = packed struct {
5553 add_got: bool = false,
5554 add_stub: bool = false,
55235555};
55245556
55255557pub const SymbolWithLoc = extern struct {
src/link/MachO/Atom.zig+24-23
......@@ -300,7 +300,7 @@ pub fn resolveRelocations(
300300 relocs: []*const Relocation,
301301 code: []u8,
302302) void {
303 log.debug("relocating '{s}'", .{macho_file.getAtom(atom_index).getName(macho_file)});
303 relocs_log.debug("relocating '{s}'", .{macho_file.getAtom(atom_index).getName(macho_file)});
304304 for (relocs) |reloc| {
305305 reloc.resolve(macho_file, atom_index, code);
306306 }
......@@ -603,7 +603,7 @@ pub fn resolveRelocs(
603603 const atom = macho_file.getAtom(atom_index);
604604 assert(atom.getFile() != null); // synthetic atoms do not have relocs
605605
606 log.debug("resolving relocations in ATOM(%{d}, '{s}')", .{
606 relocs_log.debug("resolving relocations in ATOM(%{d}, '{s}')", .{
607607 atom.sym_index,
608608 macho_file.getSymbolName(atom.getSymbolWithLoc()),
609609 });
......@@ -683,7 +683,7 @@ fn resolveRelocsArm64(
683683 .ARM64_RELOC_ADDEND => {
684684 assert(addend == null);
685685
686 log.debug(" RELA({s}) @ {x} => {x}", .{ @tagName(rel_type), rel.r_address, rel.r_symbolnum });
686 relocs_log.debug(" RELA({s}) @ {x} => {x}", .{ @tagName(rel_type), rel.r_address, rel.r_symbolnum });
687687
688688 addend = rel.r_symbolnum;
689689 continue;
......@@ -691,7 +691,7 @@ fn resolveRelocsArm64(
691691 .ARM64_RELOC_SUBTRACTOR => {
692692 assert(subtractor == null);
693693
694 log.debug(" RELA({s}) @ {x} => %{d} in object({?d})", .{
694 relocs_log.debug(" RELA({s}) @ {x} => %{d} in object({?d})", .{
695695 @tagName(rel_type),
696696 rel.r_address,
697697 rel.r_symbolnum,
......@@ -719,7 +719,7 @@ fn resolveRelocsArm64(
719719 });
720720 const rel_offset = @as(u32, @intCast(rel.r_address - context.base_offset));
721721
722 log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{
722 relocs_log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{
723723 @tagName(rel_type),
724724 rel.r_address,
725725 target.sym_index,
......@@ -745,11 +745,11 @@ fn resolveRelocsArm64(
745745 break :blk getRelocTargetAddress(macho_file, target, is_tlv);
746746 };
747747
748 log.debug(" | source_addr = 0x{x}", .{source_addr});
748 relocs_log.debug(" | source_addr = 0x{x}", .{source_addr});
749749
750750 switch (rel_type) {
751751 .ARM64_RELOC_BRANCH26 => {
752 log.debug(" source {s} (object({?})), target {s}", .{
752 relocs_log.debug(" source {s} (object({?})), target {s}", .{
753753 macho_file.getSymbolName(atom.getSymbolWithLoc()),
754754 atom.getFile(),
755755 macho_file.getSymbolName(target),
......@@ -759,7 +759,7 @@ fn resolveRelocsArm64(
759759 source_addr,
760760 target_addr,
761761 )) |disp| blk: {
762 log.debug(" | target_addr = 0x{x}", .{target_addr});
762 relocs_log.debug(" | target_addr = 0x{x}", .{target_addr});
763763 break :blk disp;
764764 } else |_| blk: {
765765 const thunk_index = macho_file.thunk_table.get(atom_index).?;
......@@ -769,7 +769,7 @@ fn resolveRelocsArm64(
769769 else
770770 thunk.getTrampoline(macho_file, .atom, target).?;
771771 const thunk_addr = macho_file.getSymbol(thunk_sym_loc).n_value;
772 log.debug(" | target_addr = 0x{x} (thunk)", .{thunk_addr});
772 relocs_log.debug(" | target_addr = 0x{x} (thunk)", .{thunk_addr});
773773 break :blk try Relocation.calcPcRelativeDisplacementArm64(source_addr, thunk_addr);
774774 };
775775
......@@ -790,7 +790,7 @@ fn resolveRelocsArm64(
790790 => {
791791 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + (addend orelse 0)));
792792
793 log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
793 relocs_log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
794794
795795 const pages = @as(u21, @bitCast(Relocation.calcNumberOfPages(source_addr, adjusted_target_addr)));
796796 const code = atom_code[rel_offset..][0..4];
......@@ -809,7 +809,7 @@ fn resolveRelocsArm64(
809809 .ARM64_RELOC_PAGEOFF12 => {
810810 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + (addend orelse 0)));
811811
812 log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
812 relocs_log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
813813
814814 const code = atom_code[rel_offset..][0..4];
815815 if (Relocation.isArithmeticOp(code)) {
......@@ -848,7 +848,7 @@ fn resolveRelocsArm64(
848848 const code = atom_code[rel_offset..][0..4];
849849 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + (addend orelse 0)));
850850
851 log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
851 relocs_log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
852852
853853 const off = try Relocation.calcPageOffset(adjusted_target_addr, .load_store_64);
854854 var inst: aarch64.Instruction = .{
......@@ -866,7 +866,7 @@ fn resolveRelocsArm64(
866866 const code = atom_code[rel_offset..][0..4];
867867 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + (addend orelse 0)));
868868
869 log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
869 relocs_log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
870870
871871 const RegInfo = struct {
872872 rd: u5,
......@@ -923,7 +923,7 @@ fn resolveRelocsArm64(
923923 },
924924
925925 .ARM64_RELOC_POINTER_TO_GOT => {
926 log.debug(" | target_addr = 0x{x}", .{target_addr});
926 relocs_log.debug(" | target_addr = 0x{x}", .{target_addr});
927927 const result = math.cast(i32, @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr))) orelse
928928 return error.Overflow;
929929 mem.writeIntLittle(u32, atom_code[rel_offset..][0..4], @as(u32, @bitCast(result)));
......@@ -951,7 +951,7 @@ fn resolveRelocsArm64(
951951 break :blk @as(i64, @intCast(target_addr)) + ptr_addend;
952952 }
953953 };
954 log.debug(" | target_addr = 0x{x}", .{result});
954 relocs_log.debug(" | target_addr = 0x{x}", .{result});
955955
956956 if (rel.r_length == 3) {
957957 mem.writeIntLittle(u64, atom_code[rel_offset..][0..8], @as(u64, @bitCast(result)));
......@@ -987,7 +987,7 @@ fn resolveRelocsX86(
987987 .X86_64_RELOC_SUBTRACTOR => {
988988 assert(subtractor == null);
989989
990 log.debug(" RELA({s}) @ {x} => %{d} in object({?d})", .{
990 relocs_log.debug(" RELA({s}) @ {x} => %{d} in object({?d})", .{
991991 @tagName(rel_type),
992992 rel.r_address,
993993 rel.r_symbolnum,
......@@ -1015,7 +1015,7 @@ fn resolveRelocsX86(
10151015 });
10161016 const rel_offset = @as(u32, @intCast(rel.r_address - context.base_offset));
10171017
1018 log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{
1018 relocs_log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{
10191019 @tagName(rel_type),
10201020 rel.r_address,
10211021 target.sym_index,
......@@ -1041,13 +1041,13 @@ fn resolveRelocsX86(
10411041 break :blk getRelocTargetAddress(macho_file, target, is_tlv);
10421042 };
10431043
1044 log.debug(" | source_addr = 0x{x}", .{source_addr});
1044 relocs_log.debug(" | source_addr = 0x{x}", .{source_addr});
10451045
10461046 switch (rel_type) {
10471047 .X86_64_RELOC_BRANCH => {
10481048 const addend = mem.readIntLittle(i32, atom_code[rel_offset..][0..4]);
10491049 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));
1050 log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
1050 relocs_log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
10511051 const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0);
10521052 mem.writeIntLittle(i32, atom_code[rel_offset..][0..4], disp);
10531053 },
......@@ -1057,7 +1057,7 @@ fn resolveRelocsX86(
10571057 => {
10581058 const addend = mem.readIntLittle(i32, atom_code[rel_offset..][0..4]);
10591059 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));
1060 log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
1060 relocs_log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
10611061 const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0);
10621062 mem.writeIntLittle(i32, atom_code[rel_offset..][0..4], disp);
10631063 },
......@@ -1065,7 +1065,7 @@ fn resolveRelocsX86(
10651065 .X86_64_RELOC_TLV => {
10661066 const addend = mem.readIntLittle(i32, atom_code[rel_offset..][0..4]);
10671067 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));
1068 log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
1068 relocs_log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
10691069 const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0);
10701070
10711071 if (macho_file.tlv_ptr_table.lookup.get(target) == null) {
......@@ -1101,7 +1101,7 @@ fn resolveRelocsX86(
11011101
11021102 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));
11031103
1104 log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
1104 relocs_log.debug(" | target_addr = 0x{x}", .{adjusted_target_addr});
11051105
11061106 const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, correction);
11071107 mem.writeIntLittle(i32, atom_code[rel_offset..][0..4], disp);
......@@ -1129,7 +1129,7 @@ fn resolveRelocsX86(
11291129 break :blk @as(i64, @intCast(target_addr)) + addend;
11301130 }
11311131 };
1132 log.debug(" | target_addr = 0x{x}", .{result});
1132 relocs_log.debug(" | target_addr = 0x{x}", .{result});
11331133
11341134 if (rel.r_length == 3) {
11351135 mem.writeIntLittle(u64, atom_code[rel_offset..][0..8], @as(u64, @bitCast(result)));
......@@ -1247,6 +1247,7 @@ const build_options = @import("build_options");
12471247const aarch64 = @import("../../arch/aarch64/bits.zig");
12481248const assert = std.debug.assert;
12491249const log = std.log.scoped(.link);
1250const relocs_log = std.log.scoped(.link_relocs);
12501251const macho = std.macho;
12511252const math = std.math;
12521253const mem = std.mem;
src/link/MachO/Relocation.zig+2-2
......@@ -99,7 +99,7 @@ pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, cod
9999 else => @as(i64, @intCast(target_base_addr)) + self.addend,
100100 };
101101
102 log.debug(" ({x}: [() => 0x{x} ({s})) ({s})", .{
102 relocs_log.debug(" ({x}: [() => 0x{x} ({s})) ({s})", .{
103103 source_addr,
104104 target_addr,
105105 macho_file.getSymbolName(self.target),
......@@ -256,7 +256,7 @@ const Relocation = @This();
256256const std = @import("std");
257257const aarch64 = @import("../../arch/aarch64/bits.zig");
258258const assert = std.debug.assert;
259const log = std.log.scoped(.link);
259const relocs_log = std.log.scoped(.link_relocs);
260260const macho = std.macho;
261261const math = std.math;
262262const mem = std.mem;
src/link/MachO/zld.zig+1-3
......@@ -390,9 +390,7 @@ pub fn linkWithZld(
390390
391391 try macho_file.parseDependentLibs(&dependent_libs);
392392
393 var actions = std.ArrayList(MachO.ResolveAction).init(gpa);
394 defer actions.deinit();
395 try macho_file.resolveSymbols(&actions);
393 try macho_file.resolveSymbols();
396394 if (macho_file.unresolved.count() > 0) {
397395 try macho_file.reportUndefined();
398396 return error.FlushFailure;