| ... | @@ -590,9 +590,9 @@ pub const Zld = struct { | ... | @@ -590,9 +590,9 @@ pub const Zld = struct { |
| 590 | } | 590 | } |
| 591 | | 591 | |
| 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 | } |
| 934 | | 935 | |
| 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 | } |
| 954 | | 955 | |
| 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 | } |
| 959 | | 960 | |
| 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 | } |
| 963 | | 964 | |
| 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 | } |
| 1243 | | 1253 | |
| 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; |
| 1283 | | 1256 | |