From cd5dcfbf41dc6f40a853b2a207bd3ab0ea0dc0ee Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Jun 2022 09:12:43 +0200 Subject: [PATCH] macho: annotate weak imports when linking with weak lib/framework --- src/link/MachO.zig | 18 ++++++++++++++++-- src/link/MachO/bind.zig | 5 +++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index a406923329..f5e1bf4b4d 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3117,6 +3117,10 @@ fn resolveSymbolsInDylibs(self: *MachO) !void { undef.n_type |= macho.N_EXT; undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER; + if (dylib.weak) { + undef.n_desc |= macho.N_WEAK_REF; + } + if (self.unresolved.fetchSwapRemove(resolv.where_index)) |entry| outer_blk: { switch (entry.value) { .none => {}, @@ -5806,11 +5810,16 @@ fn writeDyldInfoData(self: *MachO) !void { }, .undef => { const bind_sym = self.undefs.items[resolv.where_index]; + var flags: u4 = 0; + if (bind_sym.weakRef()) { + flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT); + } try bind_pointers.append(.{ .offset = binding.offset + base_offset, .segment_id = match.seg, - .dylib_ordinal = @divExact(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER), + .dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER), .name = self.getString(bind_sym.n_strx), + .bind_flags = flags, }); }, } @@ -5828,11 +5837,16 @@ fn writeDyldInfoData(self: *MachO) !void { }, .undef => { const bind_sym = self.undefs.items[resolv.where_index]; + var flags: u4 = 0; + if (bind_sym.weakRef()) { + flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT); + } try lazy_bind_pointers.append(.{ .offset = binding.offset + base_offset, .segment_id = match.seg, - .dylib_ordinal = @divExact(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER), + .dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER), .name = self.getString(bind_sym.n_strx), + .bind_flags = flags, }); }, } diff --git a/src/link/MachO/bind.zig b/src/link/MachO/bind.zig index 14a5ba3e30..9e34581a23 100644 --- a/src/link/MachO/bind.zig +++ b/src/link/MachO/bind.zig @@ -7,6 +7,7 @@ pub const Pointer = struct { segment_id: u16, dylib_ordinal: ?i64 = null, name: ?[]const u8 = null, + bind_flags: u4 = 0, }; pub fn rebaseInfoSize(pointers: []const Pointer) !u64 { @@ -73,7 +74,7 @@ pub fn writeBindInfo(pointers: []const Pointer, writer: anytype) !void { } try writer.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @truncate(u4, macho.BIND_TYPE_POINTER)); - try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM); // TODO Sometimes we might want to add flags. + try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | pointer.bind_flags); try writer.writeAll(pointer.name.?); try writer.writeByte(0); @@ -127,7 +128,7 @@ pub fn writeLazyBindInfo(pointers: []const Pointer, writer: anytype) !void { try writer.writeByte(macho.BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | @truncate(u4, @bitCast(u64, pointer.dylib_ordinal.?))); } - try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM); // TODO Sometimes we might want to add flags. + try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | pointer.bind_flags); try writer.writeAll(pointer.name.?); try writer.writeByte(0);