authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-28 09:12:43+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-28 09:19:01+02:00
logcd5dcfbf41dc6f40a853b2a207bd3ab0ea0dc0ee
treeb2d82230a602dd951dc8a5ba5f22eddf05aa532a
parentf353b59efac62dd8bc2ec966e6ea46131a64b19a

macho: annotate weak imports when linking with weak lib/framework


2 files changed, 19 insertions(+), 4 deletions(-)

src/link/MachO.zig+16-2
...@@ -3117,6 +3117,10 @@ fn resolveSymbolsInDylibs(self: *MachO) !void {...@@ -3117,6 +3117,10 @@ fn resolveSymbolsInDylibs(self: *MachO) !void {
3117 undef.n_type |= macho.N_EXT;3117 undef.n_type |= macho.N_EXT;
3118 undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;3118 undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;
31193119
3120 if (dylib.weak) {
3121 undef.n_desc |= macho.N_WEAK_REF;
3122 }
3123
3120 if (self.unresolved.fetchSwapRemove(resolv.where_index)) |entry| outer_blk: {3124 if (self.unresolved.fetchSwapRemove(resolv.where_index)) |entry| outer_blk: {
3121 switch (entry.value) {3125 switch (entry.value) {
3122 .none => {},3126 .none => {},
...@@ -5806,11 +5810,16 @@ fn writeDyldInfoData(self: *MachO) !void {...@@ -5806,11 +5810,16 @@ fn writeDyldInfoData(self: *MachO) !void {
5806 },5810 },
5807 .undef => {5811 .undef => {
5808 const bind_sym = self.undefs.items[resolv.where_index];5812 const bind_sym = self.undefs.items[resolv.where_index];
5813 var flags: u4 = 0;
5814 if (bind_sym.weakRef()) {
5815 flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT);
5816 }
5809 try bind_pointers.append(.{5817 try bind_pointers.append(.{
5810 .offset = binding.offset + base_offset,5818 .offset = binding.offset + base_offset,
5811 .segment_id = match.seg,5819 .segment_id = match.seg,
5812 .dylib_ordinal = @divExact(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),5820 .dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),
5813 .name = self.getString(bind_sym.n_strx),5821 .name = self.getString(bind_sym.n_strx),
5822 .bind_flags = flags,
5814 });5823 });
5815 },5824 },
5816 }5825 }
...@@ -5828,11 +5837,16 @@ fn writeDyldInfoData(self: *MachO) !void {...@@ -5828,11 +5837,16 @@ fn writeDyldInfoData(self: *MachO) !void {
5828 },5837 },
5829 .undef => {5838 .undef => {
5830 const bind_sym = self.undefs.items[resolv.where_index];5839 const bind_sym = self.undefs.items[resolv.where_index];
5840 var flags: u4 = 0;
5841 if (bind_sym.weakRef()) {
5842 flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT);
5843 }
5831 try lazy_bind_pointers.append(.{5844 try lazy_bind_pointers.append(.{
5832 .offset = binding.offset + base_offset,5845 .offset = binding.offset + base_offset,
5833 .segment_id = match.seg,5846 .segment_id = match.seg,
5834 .dylib_ordinal = @divExact(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),5847 .dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),
5835 .name = self.getString(bind_sym.n_strx),5848 .name = self.getString(bind_sym.n_strx),
5849 .bind_flags = flags,
5836 });5850 });
5837 },5851 },
5838 }5852 }
src/link/MachO/bind.zig+3-2
...@@ -7,6 +7,7 @@ pub const Pointer = struct {...@@ -7,6 +7,7 @@ pub const Pointer = struct {
7 segment_id: u16,7 segment_id: u16,
8 dylib_ordinal: ?i64 = null,8 dylib_ordinal: ?i64 = null,
9 name: ?[]const u8 = null,9 name: ?[]const u8 = null,
10 bind_flags: u4 = 0,
10};11};
1112
12pub fn rebaseInfoSize(pointers: []const Pointer) !u64 {13pub fn rebaseInfoSize(pointers: []const Pointer) !u64 {
...@@ -73,7 +74,7 @@ pub fn writeBindInfo(pointers: []const Pointer, writer: anytype) !void {...@@ -73,7 +74,7 @@ pub fn writeBindInfo(pointers: []const Pointer, writer: anytype) !void {
73 }74 }
74 try writer.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @truncate(u4, macho.BIND_TYPE_POINTER));75 try writer.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @truncate(u4, macho.BIND_TYPE_POINTER));
7576
76 try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM); // TODO Sometimes we might want to add flags.77 try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | pointer.bind_flags);
77 try writer.writeAll(pointer.name.?);78 try writer.writeAll(pointer.name.?);
78 try writer.writeByte(0);79 try writer.writeByte(0);
7980
...@@ -127,7 +128,7 @@ pub fn writeLazyBindInfo(pointers: []const Pointer, writer: anytype) !void {...@@ -127,7 +128,7 @@ pub fn writeLazyBindInfo(pointers: []const Pointer, writer: anytype) !void {
127 try writer.writeByte(macho.BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | @truncate(u4, @bitCast(u64, pointer.dylib_ordinal.?)));128 try writer.writeByte(macho.BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | @truncate(u4, @bitCast(u64, pointer.dylib_ordinal.?)));
128 }129 }
129130
130 try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM); // TODO Sometimes we might want to add flags.131 try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | pointer.bind_flags);
131 try writer.writeAll(pointer.name.?);132 try writer.writeAll(pointer.name.?);
132 try writer.writeByte(0);133 try writer.writeByte(0);
133134