Commit 90c54f1eb6

Jakub Konka <kubkon@jakubkonka.com>
2024-07-11 14:49:16
macho: fix symbol visibility merging logic
1 parent 3d58fae
Changed files (3)
src/link/MachO/Object.zig
@@ -1536,7 +1536,7 @@ pub fn mergeSymbolVisibility(self: *Object, macho_file: *MachO) void {
     for (self.symbols.items, 0..) |sym, i| {
         const ref = self.getSymbolRef(@intCast(i), macho_file);
         const global = ref.getSymbol(macho_file) orelse continue;
-        if (global.visibility != .global) {
+        if (sym.visibility.rank() < global.visibility.rank()) {
             global.visibility = sym.visibility;
         }
         if (sym.flags.weak_ref) {
src/link/MachO/Symbol.zig
@@ -331,9 +331,14 @@ fn format2(
         if (symbol.getAtom(ctx.macho_file)) |atom| {
             try writer.print(" : atom({d})", .{atom.atom_index});
         }
-        var buf: [2]u8 = .{'_'} ** 2;
+        var buf: [3]u8 = .{'_'} ** 3;
         if (symbol.flags.@"export") buf[0] = 'E';
         if (symbol.flags.import) buf[1] = 'I';
+        switch (symbol.visibility) {
+            .local => buf[2] = 'L',
+            .hidden => buf[2] = 'H',
+            .global => buf[2] = 'G',
+        }
         try writer.print(" : {s}", .{&buf});
         if (symbol.flags.weak) try writer.writeAll(" : weak");
         if (symbol.isSymbolStab(ctx.macho_file)) try writer.writeAll(" : stab");
@@ -402,6 +407,14 @@ pub const Visibility = enum {
     global,
     hidden,
     local,
+
+    pub fn rank(vis: Visibility) u2 {
+        return switch (vis) {
+            .local => 2,
+            .hidden => 1,
+            .global => 0,
+        };
+    }
 };
 
 pub const Extra = struct {
src/link/MachO/ZigObject.zig
@@ -267,7 +267,7 @@ pub fn mergeSymbolVisibility(self: *ZigObject, macho_file: *MachO) void {
     for (self.symbols.items, 0..) |sym, i| {
         const ref = self.getSymbolRef(@intCast(i), macho_file);
         const global = ref.getSymbol(macho_file) orelse continue;
-        if (global.visibility != .global) {
+        if (sym.visibility.rank() < global.visibility.rank()) {
             global.visibility = sym.visibility;
         }
         if (sym.flags.weak_ref) {