Commit b8490c05c1

Jakub Konka <kubkon@jakubkonka.com>
2024-01-30 00:08:18
macho: improve weak-ref symbols handling
1 parent a2ad851
Changed files (4)
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;
     }
 }
 
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;
     }
 }
 
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;
     }
 }
 
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 <stdio.h>
+    \\#include <sys/_types/_fd_def.h>
+    \\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);
 }