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 {...@@ -590,9 +590,9 @@ pub const Zld = struct {
590 }590 }
591591
592 fn createDyldStubBinderGotAtom(self: *Zld) !void {592 fn createDyldStubBinderGotAtom(self: *Zld) !void {
593 const sym_index = self.dyld_stub_binder_index orelse return;
594 const gpa = self.gpa;593 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];
596 const atom_index = try self.createGotAtom();596 const atom_index = try self.createGotAtom();
597 const got_index = @intCast(u32, self.got_entries.items.len);597 const got_index = @intCast(u32, self.got_entries.items.len);
598 try self.got_entries.append(gpa, .{598 try self.got_entries.append(gpa, .{
...@@ -661,7 +661,8 @@ pub const Zld = struct {...@@ -661,7 +661,8 @@ pub const Zld = struct {
661 break :blk sym.n_value;661 break :blk sym.n_value;
662 };662 };
663 const dyld_stub_binder_got_addr = blk: {663 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).?;
665 const entry = self.got_entries.items[index];666 const entry = self.got_entries.items[index];
666 break :blk entry.getAtomSymbol(self).n_value;667 break :blk entry.getAtomSymbol(self).n_value;
667 };668 };
...@@ -932,12 +933,12 @@ pub const Zld = struct {...@@ -932,12 +933,12 @@ pub const Zld = struct {
932 }933 }
933 }934 }
934935
935 fn forceSymbolDefined(self: *Zld, name: []const u8, resolver: *SymbolResolver) !void {936 fn addUndefined(self: *Zld, name: []const u8, resolver: *SymbolResolver) !void {
936 const sym_index = try self.allocateSymbol();937 const sym_index = try self.allocateSymbol();
937 const sym_loc = SymbolWithLoc{ .sym_index = sym_index };938 const sym_loc = SymbolWithLoc{ .sym_index = sym_index };
938 const sym = self.getSymbolPtr(sym_loc);939 const sym = self.getSymbolPtr(sym_loc);
939 sym.n_strx = try self.strtab.insert(self.gpa, name);940 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;
941 const global_index = try self.addGlobal(sym_loc);942 const global_index = try self.addGlobal(sym_loc);
942 try resolver.table.putNoClobber(name, global_index);943 try resolver.table.putNoClobber(name, global_index);
943 try resolver.unresolved.putNoClobber(global_index, {});944 try resolver.unresolved.putNoClobber(global_index, {});
...@@ -949,12 +950,12 @@ pub const Zld = struct {...@@ -949,12 +950,12 @@ pub const Zld = struct {
949 // on the linker line.950 // on the linker line.
950 if (self.options.output_mode == .Exe) {951 if (self.options.output_mode == .Exe) {
951 const entry_name = self.options.entry orelse load_commands.default_entry_point;952 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);
953 }954 }
954955
955 // Force resolution of any symbols requested by the user.956 // Force resolution of any symbols requested by the user.
956 for (self.options.force_undefined_symbols.keys()) |sym_name| {957 for (self.options.force_undefined_symbols.keys()) |sym_name| {
957 try self.forceSymbolDefined(sym_name, resolver);958 try self.addUndefined(sym_name, resolver);
958 }959 }
959960
960 for (self.objects.items, 0..) |_, object_id| {961 for (self.objects.items, 0..) |_, object_id| {
...@@ -962,8 +963,17 @@ pub const Zld = struct {...@@ -962,8 +963,17 @@ pub const Zld = struct {
962 }963 }
963964
964 try self.resolveSymbolsInArchives(resolver);965 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
966 try self.resolveSymbolsInDylibs(resolver);973 try self.resolveSymbolsInDylibs(resolver);
974
975 self.dyld_stub_binder_index = resolver.table.get("dyld_stub_binder");
976
967 try self.createMhExecuteHeaderSymbol(resolver);977 try self.createMhExecuteHeaderSymbol(resolver);
968 try self.createDsoHandleSymbol(resolver);978 try self.createDsoHandleSymbol(resolver);
969 try self.resolveSymbolsAtLoading(resolver);979 try self.resolveSymbolsAtLoading(resolver);
...@@ -1241,43 +1251,6 @@ pub const Zld = struct {...@@ -1241,43 +1251,6 @@ pub const Zld = struct {
1241 global.* = sym_loc;1251 global.* = sym_loc;
1242 }1252 }
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
1281 pub fn deinit(self: *Zld) void {1254 pub fn deinit(self: *Zld) void {
1282 const gpa = self.gpa;1255 const gpa = self.gpa;
12831256