| ... | ... | @@ -932,6 +932,34 @@ pub const Zld = struct { |
| 932 | 932 | } |
| 933 | 933 | } |
| 934 | 934 | |
| 935 | fn resolveSymbols(self: *Zld, resolver: *SymbolResolver) !void { |
| 936 | // We add the specified entrypoint as the first unresolved symbols so that |
| 937 | // we search for it in libraries should there be no object files specified |
| 938 | // on the linker line. |
| 939 | if (self.options.output_mode == .Exe) { |
| 940 | const entry_name = self.options.entry orelse load_commands.default_entry_point; |
| 941 | const sym_index = try self.allocateSymbol(); |
| 942 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| 943 | const sym = self.getSymbolPtr(sym_loc); |
| 944 | sym.n_strx = try self.strtab.insert(self.gpa, entry_name); |
| 945 | sym.n_type = macho.N_UNDF | macho.N_EXT; |
| 946 | const global_index = try self.addGlobal(sym_loc); |
| 947 | try resolver.table.putNoClobber(entry_name, global_index); |
| 948 | try resolver.unresolved.putNoClobber(global_index, {}); |
| 949 | } |
| 950 | |
| 951 | for (self.objects.items, 0..) |_, object_id| { |
| 952 | try self.resolveSymbolsInObject(@intCast(u32, object_id), resolver); |
| 953 | } |
| 954 | |
| 955 | try self.resolveSymbolsInArchives(resolver); |
| 956 | try self.resolveDyldStubBinder(resolver); |
| 957 | try self.resolveSymbolsInDylibs(resolver); |
| 958 | try self.createMhExecuteHeaderSymbol(resolver); |
| 959 | try self.createDsoHandleSymbol(resolver); |
| 960 | try self.resolveSymbolsAtLoading(resolver); |
| 961 | } |
| 962 | |
| 935 | 963 | fn resolveSymbolsInObject(self: *Zld, object_id: u32, resolver: *SymbolResolver) !void { |
| 936 | 964 | const object = &self.objects.items[object_id]; |
| 937 | 965 | const in_symtab = object.in_symtab orelse return; |
| ... | ... | @@ -975,9 +1003,7 @@ pub const Zld = struct { |
| 975 | 1003 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id + 1 }; |
| 976 | 1004 | |
| 977 | 1005 | const global_index = resolver.table.get(sym_name) orelse { |
| 978 | | const gpa = self.gpa; |
| 979 | | const global_index = @intCast(u32, self.globals.items.len); |
| 980 | | try self.globals.append(gpa, sym_loc); |
| 1006 | const global_index = try self.addGlobal(sym_loc); |
| 981 | 1007 | try resolver.table.putNoClobber(sym_name, global_index); |
| 982 | 1008 | if (sym.undf() and !sym.tentative()) { |
| 983 | 1009 | try resolver.unresolved.putNoClobber(global_index, {}); |
| ... | ... | @@ -1034,8 +1060,10 @@ pub const Zld = struct { |
| 1034 | 1060 | }; |
| 1035 | 1061 | |
| 1036 | 1062 | if (update_global) { |
| 1037 | | const global_object = &self.objects.items[global.getFile().?]; |
| 1038 | | global_object.globals_lookup[global.sym_index] = global_index; |
| 1063 | if (global.getFile()) |file| { |
| 1064 | const global_object = &self.objects.items[file]; |
| 1065 | global_object.globals_lookup[global.sym_index] = global_index; |
| 1066 | } |
| 1039 | 1067 | _ = resolver.unresolved.swapRemove(resolver.table.get(sym_name).?); |
| 1040 | 1068 | global.* = sym_loc; |
| 1041 | 1069 | } else { |
| ... | ... | @@ -1180,9 +1208,7 @@ pub const Zld = struct { |
| 1180 | 1208 | global.* = sym_loc; |
| 1181 | 1209 | self.mh_execute_header_index = global_index; |
| 1182 | 1210 | } else { |
| 1183 | | const global_index = @intCast(u32, self.globals.items.len); |
| 1184 | | try self.globals.append(gpa, sym_loc); |
| 1185 | | self.mh_execute_header_index = global_index; |
| 1211 | self.mh_execute_header_index = try self.addGlobal(sym_loc); |
| 1186 | 1212 | } |
| 1187 | 1213 | } |
| 1188 | 1214 | |
| ... | ... | @@ -1358,6 +1384,12 @@ pub const Zld = struct { |
| 1358 | 1384 | return index; |
| 1359 | 1385 | } |
| 1360 | 1386 | |
| 1387 | fn addGlobal(self: *Zld, sym_loc: SymbolWithLoc) !u32 { |
| 1388 | const global_index = @intCast(u32, self.globals.items.len); |
| 1389 | try self.globals.append(self.gpa, sym_loc); |
| 1390 | return global_index; |
| 1391 | } |
| 1392 | |
| 1361 | 1393 | fn allocateSpecialSymbols(self: *Zld) !void { |
| 1362 | 1394 | for (&[_]?u32{ |
| 1363 | 1395 | self.dso_handle_index, |
| ... | ... | @@ -3980,17 +4012,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3980 | 4012 | .table = std.StringHashMap(u32).init(arena), |
| 3981 | 4013 | .unresolved = std.AutoArrayHashMap(u32, void).init(arena), |
| 3982 | 4014 | }; |
| 3983 | | |
| 3984 | | for (zld.objects.items, 0..) |_, object_id| { |
| 3985 | | try zld.resolveSymbolsInObject(@intCast(u32, object_id), &resolver); |
| 3986 | | } |
| 3987 | | |
| 3988 | | try zld.resolveSymbolsInArchives(&resolver); |
| 3989 | | try zld.resolveDyldStubBinder(&resolver); |
| 3990 | | try zld.resolveSymbolsInDylibs(&resolver); |
| 3991 | | try zld.createMhExecuteHeaderSymbol(&resolver); |
| 3992 | | try zld.createDsoHandleSymbol(&resolver); |
| 3993 | | try zld.resolveSymbolsAtLoading(&resolver); |
| 4015 | try zld.resolveSymbols(&resolver); |
| 3994 | 4016 | |
| 3995 | 4017 | if (resolver.unresolved.count() > 0) { |
| 3996 | 4018 | return error.UndefinedSymbolReference; |
| ... | ... | @@ -4003,11 +4025,8 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 4003 | 4025 | } |
| 4004 | 4026 | |
| 4005 | 4027 | if (options.output_mode == .Exe) { |
| 4006 | | const entry_name = options.entry orelse "_main"; |
| 4007 | | const global_index = resolver.table.get(entry_name) orelse { |
| 4008 | | log.err("entrypoint '{s}' not found", .{entry_name}); |
| 4009 | | return error.MissingMainEntrypoint; |
| 4010 | | }; |
| 4028 | const entry_name = options.entry orelse load_commands.default_entry_point; |
| 4029 | const global_index = resolver.table.get(entry_name).?; // Error was flagged earlier |
| 4011 | 4030 | zld.entry_index = global_index; |
| 4012 | 4031 | } |
| 4013 | 4032 | |