| ... | @@ -932,6 +932,34 @@ pub const Zld = struct { | ... | @@ -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 | fn resolveSymbolsInObject(self: *Zld, object_id: u32, resolver: *SymbolResolver) !void { | 963 | fn resolveSymbolsInObject(self: *Zld, object_id: u32, resolver: *SymbolResolver) !void { |
| 936 | const object = &self.objects.items[object_id]; | 964 | const object = &self.objects.items[object_id]; |
| 937 | const in_symtab = object.in_symtab orelse return; | 965 | const in_symtab = object.in_symtab orelse return; |
| ... | @@ -975,9 +1003,7 @@ pub const Zld = struct { | ... | @@ -975,9 +1003,7 @@ pub const Zld = struct { |
| 975 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id + 1 }; | 1003 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id + 1 }; |
| 976 | | 1004 | |
| 977 | const global_index = resolver.table.get(sym_name) orelse { | 1005 | const global_index = resolver.table.get(sym_name) orelse { |
| 978 | const gpa = self.gpa; | 1006 | const global_index = try self.addGlobal(sym_loc); |
| 979 | const global_index = @intCast(u32, self.globals.items.len); | | |
| 980 | try self.globals.append(gpa, sym_loc); | | |
| 981 | try resolver.table.putNoClobber(sym_name, global_index); | 1007 | try resolver.table.putNoClobber(sym_name, global_index); |
| 982 | if (sym.undf() and !sym.tentative()) { | 1008 | if (sym.undf() and !sym.tentative()) { |
| 983 | try resolver.unresolved.putNoClobber(global_index, {}); | 1009 | try resolver.unresolved.putNoClobber(global_index, {}); |
| ... | @@ -1034,8 +1060,10 @@ pub const Zld = struct { | ... | @@ -1034,8 +1060,10 @@ pub const Zld = struct { |
| 1034 | }; | 1060 | }; |
| 1035 | | 1061 | |
| 1036 | if (update_global) { | 1062 | if (update_global) { |
| 1037 | const global_object = &self.objects.items[global.getFile().?]; | 1063 | if (global.getFile()) |file| { |
| 1038 | global_object.globals_lookup[global.sym_index] = global_index; | 1064 | const global_object = &self.objects.items[file]; |
| | 1065 | global_object.globals_lookup[global.sym_index] = global_index; |
| | 1066 | } |
| 1039 | _ = resolver.unresolved.swapRemove(resolver.table.get(sym_name).?); | 1067 | _ = resolver.unresolved.swapRemove(resolver.table.get(sym_name).?); |
| 1040 | global.* = sym_loc; | 1068 | global.* = sym_loc; |
| 1041 | } else { | 1069 | } else { |
| ... | @@ -1180,9 +1208,7 @@ pub const Zld = struct { | ... | @@ -1180,9 +1208,7 @@ pub const Zld = struct { |
| 1180 | global.* = sym_loc; | 1208 | global.* = sym_loc; |
| 1181 | self.mh_execute_header_index = global_index; | 1209 | self.mh_execute_header_index = global_index; |
| 1182 | } else { | 1210 | } else { |
| 1183 | const global_index = @intCast(u32, self.globals.items.len); | 1211 | self.mh_execute_header_index = try self.addGlobal(sym_loc); |
| 1184 | try self.globals.append(gpa, sym_loc); | | |
| 1185 | self.mh_execute_header_index = global_index; | | |
| 1186 | } | 1212 | } |
| 1187 | } | 1213 | } |
| 1188 | | 1214 | |
| ... | @@ -1358,6 +1384,12 @@ pub const Zld = struct { | ... | @@ -1358,6 +1384,12 @@ pub const Zld = struct { |
| 1358 | return index; | 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 | fn allocateSpecialSymbols(self: *Zld) !void { | 1393 | fn allocateSpecialSymbols(self: *Zld) !void { |
| 1362 | for (&[_]?u32{ | 1394 | for (&[_]?u32{ |
| 1363 | self.dso_handle_index, | 1395 | self.dso_handle_index, |
| ... | @@ -3980,17 +4012,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3980,17 +4012,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3980 | .table = std.StringHashMap(u32).init(arena), | 4012 | .table = std.StringHashMap(u32).init(arena), |
| 3981 | .unresolved = std.AutoArrayHashMap(u32, void).init(arena), | 4013 | .unresolved = std.AutoArrayHashMap(u32, void).init(arena), |
| 3982 | }; | 4014 | }; |
| 3983 | | 4015 | try zld.resolveSymbols(&resolver); |
| 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); | | |
| 3994 | | 4016 | |
| 3995 | if (resolver.unresolved.count() > 0) { | 4017 | if (resolver.unresolved.count() > 0) { |
| 3996 | return error.UndefinedSymbolReference; | 4018 | return error.UndefinedSymbolReference; |
| ... | @@ -4003,11 +4025,8 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -4003,11 +4025,8 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 4003 | } | 4025 | } |
| 4004 | | 4026 | |
| 4005 | if (options.output_mode == .Exe) { | 4027 | if (options.output_mode == .Exe) { |
| 4006 | const entry_name = options.entry orelse "_main"; | 4028 | const entry_name = options.entry orelse load_commands.default_entry_point; |
| 4007 | const global_index = resolver.table.get(entry_name) orelse { | 4029 | const global_index = resolver.table.get(entry_name).?; // Error was flagged earlier |
| 4008 | log.err("entrypoint '{s}' not found", .{entry_name}); | | |
| 4009 | return error.MissingMainEntrypoint; | | |
| 4010 | }; | | |
| 4011 | zld.entry_index = global_index; | 4030 | zld.entry_index = global_index; |
| 4012 | } | 4031 | } |
| 4013 | | 4032 | |