From b8490c05c10193363107a1fb2e7c4ffab287f5ad Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 30 Jan 2024 00:08:18 +0100 Subject: [PATCH] macho: improve weak-ref symbols handling --- src/link/MachO/Dylib.zig | 3 ++- src/link/MachO/Object.zig | 5 +++++ src/link/MachO/ZigObject.zig | 2 ++ test/link/macho.zig | 24 ++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/link/MachO/Dylib.zig b/src/link/MachO/Dylib.zig index 32f7a018a2..52f3c782eb 100644 --- a/src/link/MachO/Dylib.zig +++ b/src/link/MachO/Dylib.zig @@ -520,7 +520,6 @@ pub fn resolveSymbols(self: *Dylib, macho_file: *MachO) void { global.nlist_idx = 0; global.file = self.index; global.flags.weak = flags.weak; - global.flags.weak_ref = false; global.flags.tlv = flags.tlv; global.flags.dyn_ref = false; global.flags.tentative = false; @@ -534,9 +533,11 @@ pub fn resetGlobals(self: *Dylib, macho_file: *MachO) void { const sym = macho_file.getSymbol(sym_index); const name = sym.name; const global = sym.flags.global; + const weak_ref = sym.flags.weak_ref; sym.* = .{}; sym.name = name; sym.flags.global = global; + sym.flags.weak_ref = weak_ref; } } diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index d6c5010b31..642e1a0475 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -525,6 +525,9 @@ fn initSymbols(self: *Object, macho_file: *MachO) !void { const off = try macho_file.strings.insert(gpa, name); const gop = try macho_file.getOrCreateGlobal(off); self.symbols.addOneAssumeCapacity().* = gop.index; + if (nlist.undf() and nlist.weakRef()) { + macho_file.getSymbol(gop.index).flags.weak_ref = true; + } continue; } @@ -1099,9 +1102,11 @@ pub fn resetGlobals(self: *Object, macho_file: *MachO) void { const sym = macho_file.getSymbol(sym_index); const name = sym.name; const global = sym.flags.global; + const weak_ref = sym.flags.weak_ref; sym.* = .{}; sym.name = name; sym.flags.global = global; + sym.flags.weak_ref = weak_ref; } } diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index f903c997fb..c05a03e673 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -233,9 +233,11 @@ pub fn resetGlobals(self: *ZigObject, macho_file: *MachO) void { const sym = macho_file.getSymbol(sym_index); const name = sym.name; const global = sym.flags.global; + const weak_ref = sym.flags.weak_ref; sym.* = .{}; sym.name = name; sym.flags.global = global; + sym.flags.weak_ref = weak_ref; } } diff --git a/test/link/macho.zig b/test/link/macho.zig index 2659a156d5..a99b93da8a 100644 --- a/test/link/macho.zig +++ b/test/link/macho.zig @@ -43,6 +43,11 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { macho_step.dependOn(testUnwindInfoNoSubsectionsX64(b, .{ .target = x86_64_target })); macho_step.dependOn(testUnwindInfoNoSubsectionsArm64(b, .{ .target = aarch64_target })); macho_step.dependOn(testWeakBind(b, .{ .target = x86_64_target })); + macho_step.dependOn(testWeakRef(b, .{ .target = b.resolveTargetQuery(.{ + .cpu_arch = .x86_64, + .os_tag = .macos, + .os_version_min = .{ .semver = .{ .major = 10, .minor = 13, .patch = 0 } }, + }) })); // Tests requiring symlinks when tested on Windows if (build_opts.has_symlinks_windows) { @@ -2223,6 +2228,25 @@ fn testWeakLibrary(b: *Build, opts: Options) *Step { return test_step; } +fn testWeakRef(b: *Build, opts: Options) *Step { + const test_step = addTestStep(b, "macho-weak-ref", opts); + + const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = + \\#include + \\#include + \\int main(int argc, char** argv) { + \\ printf("__darwin_check_fd_set_overflow: %p\n", __darwin_check_fd_set_overflow); + \\} + }); + + const check = exe.checkObject(); + check.checkInSymtab(); + check.checkExact("(undefined) weakref external ___darwin_check_fd_set_overflow (from libSystem.B)"); + test_step.dependOn(&check.step); + + return test_step; +} + fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { return link.addTestStep(b, "macho-" ++ prefix, opts); }