authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-04 09:32:26+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-04 15:44:01+02:00
log3a8362e751d210f1cecfce7c33cae2e582bd4b94
tree3955a78331f58c2cfe14f31048e8ff19e8d821a4
parent49b56f88b92eb0f0e66e7cfa329392c918c1777e

macho+zld: refactor how we resolve dyld_stub_binder symbol


1 files changed, 18 insertions(+), 45 deletions(-)

src/link/MachO/zld.zig+18-45
......@@ -590,9 +590,9 @@ pub const Zld = struct {
590590 }
591591
592592 fn createDyldStubBinderGotAtom(self: *Zld) !void {
593 const sym_index = self.dyld_stub_binder_index orelse return;
594593 const gpa = self.gpa;
595 const target = SymbolWithLoc{ .sym_index = sym_index };
594 const global_index = self.dyld_stub_binder_index orelse return;
595 const target = self.globals.items[global_index];
596596 const atom_index = try self.createGotAtom();
597597 const got_index = @intCast(u32, self.got_entries.items.len);
598598 try self.got_entries.append(gpa, .{
......@@ -661,7 +661,8 @@ pub const Zld = struct {
661661 break :blk sym.n_value;
662662 };
663663 const dyld_stub_binder_got_addr = blk: {
664 const index = self.got_table.get(.{ .sym_index = self.dyld_stub_binder_index.? }).?;
664 const sym_loc = self.globals.items[self.dyld_stub_binder_index.?];
665 const index = self.got_table.get(sym_loc).?;
665666 const entry = self.got_entries.items[index];
666667 break :blk entry.getAtomSymbol(self).n_value;
667668 };
......@@ -932,12 +933,12 @@ pub const Zld = struct {
932933 }
933934 }
934935
935 fn forceSymbolDefined(self: *Zld, name: []const u8, resolver: *SymbolResolver) !void {
936 fn addUndefined(self: *Zld, name: []const u8, resolver: *SymbolResolver) !void {
936937 const sym_index = try self.allocateSymbol();
937938 const sym_loc = SymbolWithLoc{ .sym_index = sym_index };
938939 const sym = self.getSymbolPtr(sym_loc);
939940 sym.n_strx = try self.strtab.insert(self.gpa, name);
940 sym.n_type = macho.N_UNDF | macho.N_EXT;
941 sym.n_type = macho.N_UNDF;
941942 const global_index = try self.addGlobal(sym_loc);
942943 try resolver.table.putNoClobber(name, global_index);
943944 try resolver.unresolved.putNoClobber(global_index, {});
......@@ -949,12 +950,12 @@ pub const Zld = struct {
949950 // on the linker line.
950951 if (self.options.output_mode == .Exe) {
951952 const entry_name = self.options.entry orelse load_commands.default_entry_point;
952 try self.forceSymbolDefined(entry_name, resolver);
953 try self.addUndefined(entry_name, resolver);
953954 }
954955
955956 // Force resolution of any symbols requested by the user.
956957 for (self.options.force_undefined_symbols.keys()) |sym_name| {
957 try self.forceSymbolDefined(sym_name, resolver);
958 try self.addUndefined(sym_name, resolver);
958959 }
959960
960961 for (self.objects.items, 0..) |_, object_id| {
......@@ -962,8 +963,17 @@ pub const Zld = struct {
962963 }
963964
964965 try self.resolveSymbolsInArchives(resolver);
965 try self.resolveDyldStubBinder(resolver);
966
967 // Finally, force resolution of dyld_stub_binder if there are imports
968 // requested.
969 if (resolver.unresolved.count() > 0) {
970 try self.addUndefined("dyld_stub_binder", resolver);
971 }
972
966973 try self.resolveSymbolsInDylibs(resolver);
974
975 self.dyld_stub_binder_index = resolver.table.get("dyld_stub_binder");
976
967977 try self.createMhExecuteHeaderSymbol(resolver);
968978 try self.createDsoHandleSymbol(resolver);
969979 try self.resolveSymbolsAtLoading(resolver);
......@@ -1241,43 +1251,6 @@ pub const Zld = struct {
12411251 global.* = sym_loc;
12421252 }
12431253
1244 fn resolveDyldStubBinder(self: *Zld, resolver: *SymbolResolver) !void {
1245 if (self.dyld_stub_binder_index != null) return;
1246 if (resolver.unresolved.count() == 0) return; // no need for a stub binder if we don't have any imports
1247
1248 const gpa = self.gpa;
1249 const sym_name = "dyld_stub_binder";
1250 const sym_index = try self.allocateSymbol();
1251 const sym_loc = SymbolWithLoc{ .sym_index = sym_index };
1252 const sym = self.getSymbolPtr(sym_loc);
1253 sym.n_strx = try self.strtab.insert(gpa, sym_name);
1254 sym.n_type = macho.N_UNDF;
1255
1256 const global = SymbolWithLoc{ .sym_index = sym_index };
1257 try self.globals.append(gpa, global);
1258
1259 for (self.dylibs.items, 0..) |dylib, id| {
1260 if (!dylib.symbols.contains(sym_name)) continue;
1261
1262 const dylib_id = @intCast(u16, id);
1263 if (!self.referenced_dylibs.contains(dylib_id)) {
1264 try self.referenced_dylibs.putNoClobber(gpa, dylib_id, {});
1265 }
1266
1267 const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable;
1268 sym.n_type |= macho.N_EXT;
1269 sym.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;
1270 self.dyld_stub_binder_index = sym_index;
1271
1272 break;
1273 }
1274
1275 if (self.dyld_stub_binder_index == null) {
1276 log.err("undefined reference to symbol '{s}'", .{sym_name});
1277 return error.UndefinedSymbolReference;
1278 }
1279 }
1280
12811254 pub fn deinit(self: *Zld) void {
12821255 const gpa = self.gpa;
12831256