authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-06 15:19:14+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-06 15:19:17+01:00
log351031b6c7b01f45a4ee366eb1c0b28bce89145c
tree747aa84686966ca730dd314336afcffbfef9c2d0
parent1aeef297337985c5fd8647462cc7c78ea1a4df43

macho: parse weak symbols in tbds

However, we will treat them as standard imports rather than refs to weak imports until I investigate more how it actually works underneath.

2 files changed, 39 insertions(+), 6 deletions(-)

src/link/MachO/Dylib.zig+36-6
......@@ -22,7 +22,14 @@ weak: bool = false,
2222/// Parsed symbol table represented as hash map of symbols'
2323/// names. We can and should defer creating *Symbols until
2424/// a symbol is referenced by an object file.
25symbols: std.StringArrayHashMapUnmanaged(void) = .{},
25///
26/// The value for each parsed symbol represents whether the
27/// symbol is defined as a weak symbol or strong.
28/// TODO when the referenced symbol is weak, ld64 marks it as
29/// N_REF_TO_WEAK but need to investigate if there's more to it
30/// such as weak binding entry or simply weak. For now, we generate
31/// standard bind or lazy bind.
32symbols: std.StringArrayHashMapUnmanaged(bool) = .{},
2633
2734pub const Id = struct {
2835 name: []const u8,
......@@ -168,7 +175,7 @@ pub fn parseFromBinary(
168175 if (!add_to_symtab) continue;
169176
170177 const sym_name = mem.sliceTo(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx), 0);
171 try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), {});
178 try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), false);
172179 }
173180 },
174181 .ID_DYLIB => {
......@@ -202,25 +209,30 @@ fn addObjCClassSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8)
202209
203210 for (expanded) |sym| {
204211 if (self.symbols.contains(sym)) continue;
205 try self.symbols.putNoClobber(allocator, sym, {});
212 try self.symbols.putNoClobber(allocator, sym, false);
206213 }
207214}
208215
209216fn addObjCIVarSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
210217 const expanded = try std.fmt.allocPrint(allocator, "_OBJC_IVAR_$_{s}", .{sym_name});
211218 if (self.symbols.contains(expanded)) return;
212 try self.symbols.putNoClobber(allocator, expanded, {});
219 try self.symbols.putNoClobber(allocator, expanded, false);
213220}
214221
215222fn addObjCEhTypeSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
216223 const expanded = try std.fmt.allocPrint(allocator, "_OBJC_EHTYPE_$_{s}", .{sym_name});
217224 if (self.symbols.contains(expanded)) return;
218 try self.symbols.putNoClobber(allocator, expanded, {});
225 try self.symbols.putNoClobber(allocator, expanded, false);
219226}
220227
221228fn addSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
222229 if (self.symbols.contains(sym_name)) return;
223 try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), {});
230 try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), false);
231}
232
233fn addWeakSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
234 if (self.symbols.contains(sym_name)) return;
235 try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), true);
224236}
225237
226238const TargetMatcher = struct {
......@@ -359,6 +371,12 @@ pub fn parseFromStub(
359371 }
360372 }
361373
374 if (exp.weak_symbols) |symbols| {
375 for (symbols) |sym_name| {
376 try self.addWeakSymbol(allocator, sym_name);
377 }
378 }
379
362380 if (exp.objc_classes) |objc_classes| {
363381 for (objc_classes) |class_name| {
364382 try self.addObjCClassSymbol(allocator, class_name);
......@@ -402,6 +420,12 @@ pub fn parseFromStub(
402420 }
403421 }
404422
423 if (exp.weak_symbols) |symbols| {
424 for (symbols) |sym_name| {
425 try self.addWeakSymbol(allocator, sym_name);
426 }
427 }
428
405429 if (exp.objc_classes) |classes| {
406430 for (classes) |sym_name| {
407431 try self.addObjCClassSymbol(allocator, sym_name);
......@@ -432,6 +456,12 @@ pub fn parseFromStub(
432456 }
433457 }
434458
459 if (reexp.weak_symbols) |symbols| {
460 for (symbols) |sym_name| {
461 try self.addWeakSymbol(allocator, sym_name);
462 }
463 }
464
435465 if (reexp.objc_classes) |classes| {
436466 for (classes) |sym_name| {
437467 try self.addObjCClassSymbol(allocator, sym_name);
src/link/tapi.zig+3
......@@ -26,6 +26,7 @@ pub const TbdV3 = struct {
2626 allowable_clients: ?[]const []const u8,
2727 re_exports: ?[]const []const u8,
2828 symbols: ?[]const []const u8,
29 weak_symbols: ?[]const []const u8,
2930 objc_classes: ?[]const []const u8,
3031 objc_ivars: ?[]const []const u8,
3132 objc_eh_types: ?[]const []const u8,
......@@ -53,6 +54,7 @@ pub const TbdV4 = struct {
5354 exports: ?[]const struct {
5455 targets: []const []const u8,
5556 symbols: ?[]const []const u8,
57 weak_symbols: ?[]const []const u8,
5658 objc_classes: ?[]const []const u8,
5759 objc_ivars: ?[]const []const u8,
5860 objc_eh_types: ?[]const []const u8,
......@@ -60,6 +62,7 @@ pub const TbdV4 = struct {
6062 reexports: ?[]const struct {
6163 targets: []const []const u8,
6264 symbols: ?[]const []const u8,
65 weak_symbols: ?[]const []const u8,
6366 objc_classes: ?[]const []const u8,
6467 objc_ivars: ?[]const []const u8,
6568 objc_eh_types: ?[]const []const u8,