authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-31 22:36:10+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-01 14:22:44+02:00
logf2587de4e915423d0224b8b6ef0cb3d9cb7e60e2
treef03f33b4b1c0a80eea3e8cc10f1ae21186dceb40
parent381dc2d9509ffeaf60a1775ee0983c7dd1b9e346

macho: look for entry in archives/dylibs too


3 files changed, 48 insertions(+), 25 deletions(-)

src/link/MachO.zig+1-1
...@@ -3981,7 +3981,7 @@ pub fn getStubsAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?At...@@ -3981,7 +3981,7 @@ pub fn getStubsAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?At
3981/// Returns symbol location corresponding to the set entrypoint.3981/// Returns symbol location corresponding to the set entrypoint.
3982/// Asserts output mode is executable.3982/// Asserts output mode is executable.
3983pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc {3983pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc {
3984 const entry_name = self.base.options.entry orelse "_main";3984 const entry_name = self.base.options.entry orelse load_commands.default_entry_point;
3985 const global = self.getGlobal(entry_name) orelse {3985 const global = self.getGlobal(entry_name) orelse {
3986 log.err("entrypoint '{s}' not found", .{entry_name});3986 log.err("entrypoint '{s}' not found", .{entry_name});
3987 return error.MissingMainEntrypoint;3987 return error.MissingMainEntrypoint;
src/link/MachO/load_commands.zig+4
...@@ -8,6 +8,10 @@ const mem = std.mem;...@@ -8,6 +8,10 @@ const mem = std.mem;
8const Allocator = mem.Allocator;8const Allocator = mem.Allocator;
9const Dylib = @import("Dylib.zig");9const Dylib = @import("Dylib.zig");
1010
11/// Default implicit entrypoint symbol name.
12pub const default_entry_point: []const u8 = "_main";
13
14/// Default path to dyld.
11pub const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld";15pub const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld";
1216
13fn calcInstallNameLen(cmd_size: u64, name: []const u8, assume_max_path_len: bool) u64 {17fn calcInstallNameLen(cmd_size: u64, name: []const u8, assume_max_path_len: bool) u64 {
src/link/MachO/zld.zig+43-24
...@@ -932,6 +932,34 @@ pub const Zld = struct {...@@ -932,6 +932,34 @@ pub const Zld = struct {
932 }932 }
933 }933 }
934934
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 };
9761004
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 };
10351061
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 }
11881214
...@@ -1358,6 +1384,12 @@ pub const Zld = struct {...@@ -1358,6 +1384,12 @@ pub const Zld = struct {
1358 return index;1384 return index;
1359 }1385 }
13601386
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 };
39834015 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);
39944016
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 }
40044026
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 }
40134032