authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-28 12:17:55+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-28 15:14:50+02:00
logeca12b74b8f2ff9510de67907df2bc272614c8c8
tree9fa91b35ec449e2190dbbe9ba1168c179be84d2c
parent5aff1d5d6fde5f95576cd639e6fa80281524e2d6

zld: recurse dylibs reexports when defined and desired


4 files changed, 116 insertions(+), 139 deletions(-)

src/link/MachO.zig+14-9
...@@ -871,17 +871,19 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -871,17 +871,19 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
871871
872 // If we're compiling native and we can find libSystem.B.{dylib, tbd},872 // If we're compiling native and we can find libSystem.B.{dylib, tbd},
873 // we link against that instead of embedded libSystem.B.tbd file.873 // we link against that instead of embedded libSystem.B.tbd file.
874 const libc_stub_path = blk: {874 var link_native_libsystem = false;
875 if (self.base.options.is_native_os) {875 if (self.base.options.is_native_os) {
876 if (try resolveLib(arena, lib_dirs.items, "System", .lib)) |full_path| {876 if (try resolveLib(arena, lib_dirs.items, "System", .lib)) |full_path| {
877 break :blk full_path;877 try libs.append(full_path);
878 }878 link_native_libsystem = true;
879 }879 }
880880 }
881 break :blk try comp.zig_lib_directory.join(arena, &[_][]const u8{881 if (!link_native_libsystem) {
882 const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
882 "libc", "darwin", "libSystem.B.tbd",883 "libc", "darwin", "libSystem.B.tbd",
883 });884 });
884 };885 try positionals.append(full_path);
886 }
885887
886 // frameworks888 // frameworks
887 var framework_dirs = std.ArrayList([]const u8).init(arena);889 var framework_dirs = std.ArrayList([]const u8).init(arena);
...@@ -935,6 +937,10 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -935,6 +937,10 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
935 try argv.append("-o");937 try argv.append("-o");
936 try argv.append(full_out_path);938 try argv.append(full_out_path);
937939
940 if (link_native_libsystem) {
941 try argv.append("-lSystem");
942 }
943
938 for (search_lib_names.items) |l_name| {944 for (search_lib_names.items) |l_name| {
939 try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{l_name}));945 try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{l_name}));
940 }946 }
...@@ -950,7 +956,6 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -950,7 +956,6 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
950 .syslibroot = self.base.options.sysroot,956 .syslibroot = self.base.options.sysroot,
951 .libs = libs.items,957 .libs = libs.items,
952 .rpaths = rpaths.items,958 .rpaths = rpaths.items,
953 .libc_stub_path = libc_stub_path,
954 });959 });
955960
956 break :outer;961 break :outer;
src/link/MachO/Dylib.zig+79-49
...@@ -45,8 +45,8 @@ id: ?Id = null,...@@ -45,8 +45,8 @@ id: ?Id = null,
45/// a symbol is referenced by an object file.45/// a symbol is referenced by an object file.
46symbols: std.StringArrayHashMapUnmanaged(void) = .{},46symbols: std.StringArrayHashMapUnmanaged(void) = .{},
4747
48// TODO add parsing re-exported libs from binary dylibs48/// Array list of all dependent libs of this dylib.
49dependent_libs: std.StringArrayHashMapUnmanaged(void) = .{},49dependent_libs: std.ArrayListUnmanaged(Id) = .{},
5050
51pub const Id = struct {51pub const Id = struct {
52 name: []const u8,52 name: []const u8,
...@@ -54,15 +54,28 @@ pub const Id = struct {...@@ -54,15 +54,28 @@ pub const Id = struct {
54 current_version: u32,54 current_version: u32,
55 compatibility_version: u32,55 compatibility_version: u32,
5656
57 pub fn default(name: []const u8) Id {57 pub fn default(allocator: *Allocator, name: []const u8) !Id {
58 return .{58 return Id{
59 .name = name,59 .name = try allocator.dupe(u8, name),
60 .timestamp = 2,60 .timestamp = 2,
61 .current_version = 0x10000,61 .current_version = 0x10000,
62 .compatibility_version = 0x10000,62 .compatibility_version = 0x10000,
63 };63 };
64 }64 }
6565
66 pub fn fromLoadCommand(allocator: *Allocator, lc: GenericCommandWithData(macho.dylib_command)) !Id {
67 const dylib = lc.inner.dylib;
68 const dylib_name = @ptrCast([*:0]const u8, lc.data[dylib.name - @sizeOf(macho.dylib_command) ..]);
69 const name = try allocator.dupe(u8, mem.spanZ(dylib_name));
70
71 return Id{
72 .name = name,
73 .timestamp = dylib.timestamp,
74 .current_version = dylib.current_version,
75 .compatibility_version = dylib.compatibility_version,
76 };
77 }
78
66 pub fn deinit(id: *Id, allocator: *Allocator) void {79 pub fn deinit(id: *Id, allocator: *Allocator) void {
67 allocator.free(id.name);80 allocator.free(id.name);
68 }81 }
...@@ -129,12 +142,12 @@ pub const Error = error{...@@ -129,12 +142,12 @@ pub const Error = error{
129 UnsupportedCpuArchitecture,142 UnsupportedCpuArchitecture,
130} || fs.File.OpenError || std.os.PReadError || Id.ParseError;143} || fs.File.OpenError || std.os.PReadError || Id.ParseError;
131144
132pub fn createAndParseFromPath(145pub const CreateOpts = struct {
133 allocator: *Allocator,146 syslibroot: ?[]const u8 = null,
134 arch: Arch,147 id: ?Id = null,
135 path: []const u8,148};
136 syslibroot: ?[]const u8,149
137) Error!?[]*Dylib {150pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u8, opts: CreateOpts) Error!?[]*Dylib {
138 const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) {151 const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) {
139 error.FileNotFound => return null,152 error.FileNotFound => return null,
140 else => |e| return e,153 else => |e| return e,
...@@ -152,7 +165,7 @@ pub fn createAndParseFromPath(...@@ -152,7 +165,7 @@ pub fn createAndParseFromPath(
152 .arch = arch,165 .arch = arch,
153 .name = name,166 .name = name,
154 .file = file,167 .file = file,
155 .syslibroot = syslibroot,168 .syslibroot = opts.syslibroot,
156 };169 };
157170
158 dylib.parse() catch |err| switch (err) {171 dylib.parse() catch |err| switch (err) {
...@@ -171,6 +184,20 @@ pub fn createAndParseFromPath(...@@ -171,6 +184,20 @@ pub fn createAndParseFromPath(
171 else => |e| return e,184 else => |e| return e,
172 };185 };
173186
187 if (opts.id) |id| {
188 if (dylib.id.?.current_version < id.compatibility_version) {
189 log.warn("found dylib is incompatible with the required minimum version", .{});
190 log.warn(" | dylib: {s}", .{id.name});
191 log.warn(" | required minimum version: {}", .{id.compatibility_version});
192 log.warn(" | dylib version: {}", .{dylib.id.?.current_version});
193
194 // TODO maybe this should be an error and facilitate auto-cleanup?
195 dylib.deinit();
196 allocator.destroy(dylib);
197 return null;
198 }
199 }
200
174 var dylibs = std.ArrayList(*Dylib).init(allocator);201 var dylibs = std.ArrayList(*Dylib).init(allocator);
175 defer dylibs.deinit();202 defer dylibs.deinit();
176203
...@@ -191,8 +218,8 @@ pub fn deinit(self: *Dylib) void {...@@ -191,8 +218,8 @@ pub fn deinit(self: *Dylib) void {
191 }218 }
192 self.symbols.deinit(self.allocator);219 self.symbols.deinit(self.allocator);
193220
194 for (self.dependent_libs.keys()) |key| {221 for (self.dependent_libs.items) |*id| {
195 self.allocator.free(key);222 id.deinit(self.allocator);
196 }223 }
197 self.dependent_libs.deinit(self.allocator);224 self.dependent_libs.deinit(self.allocator);
198225
...@@ -287,6 +314,8 @@ fn readFatStruct(reader: anytype, comptime T: type) !T {...@@ -287,6 +314,8 @@ fn readFatStruct(reader: anytype, comptime T: type) !T {
287}314}
288315
289fn readLoadCommands(self: *Dylib, reader: anytype) !void {316fn readLoadCommands(self: *Dylib, reader: anytype) !void {
317 const should_lookup_reexports = self.header.?.flags & macho.MH_NO_REEXPORTED_DYLIBS == 0;
318
290 try self.load_commands.ensureCapacity(self.allocator, self.header.?.ncmds);319 try self.load_commands.ensureCapacity(self.allocator, self.header.?.ncmds);
291320
292 var i: u16 = 0;321 var i: u16 = 0;
...@@ -302,6 +331,13 @@ fn readLoadCommands(self: *Dylib, reader: anytype) !void {...@@ -302,6 +331,13 @@ fn readLoadCommands(self: *Dylib, reader: anytype) !void {
302 macho.LC_ID_DYLIB => {331 macho.LC_ID_DYLIB => {
303 self.id_cmd_index = i;332 self.id_cmd_index = i;
304 },333 },
334 macho.LC_REEXPORT_DYLIB => {
335 if (should_lookup_reexports) {
336 // Parse install_name to dependent dylib.
337 const id = try Id.fromLoadCommand(self.allocator, cmd.Dylib);
338 try self.dependent_libs.append(self.allocator, id);
339 }
340 },
305 else => {341 else => {
306 log.debug("Unknown load command detected: 0x{x}.", .{cmd.cmd()});342 log.debug("Unknown load command detected: 0x{x}.", .{cmd.cmd()});
307 },343 },
...@@ -313,22 +349,10 @@ fn readLoadCommands(self: *Dylib, reader: anytype) !void {...@@ -313,22 +349,10 @@ fn readLoadCommands(self: *Dylib, reader: anytype) !void {
313fn parseId(self: *Dylib) !void {349fn parseId(self: *Dylib) !void {
314 const index = self.id_cmd_index orelse {350 const index = self.id_cmd_index orelse {
315 log.debug("no LC_ID_DYLIB load command found; using hard-coded defaults...", .{});351 log.debug("no LC_ID_DYLIB load command found; using hard-coded defaults...", .{});
316 self.id = Id.default(try self.allocator.dupe(u8, self.name.?));352 self.id = try Id.default(self.allocator, self.name.?);
317 return;353 return;
318 };354 };
319 const id_cmd = self.load_commands.items[index].Dylib;355 self.id = try Id.fromLoadCommand(self.allocator, self.load_commands.items[index].Dylib);
320 const dylib = id_cmd.inner.dylib;
321
322 // TODO should we compare the name from the dylib's id with the user-specified one?
323 const dylib_name = @ptrCast([*:0]const u8, id_cmd.data[dylib.name - @sizeOf(macho.dylib_command) ..]);
324 const name = try self.allocator.dupe(u8, mem.spanZ(dylib_name));
325
326 self.id = .{
327 .name = name,
328 .timestamp = dylib.timestamp,
329 .current_version = dylib.current_version,
330 .compatibility_version = dylib.compatibility_version,
331 };
332}356}
333357
334fn parseSymbols(self: *Dylib) !void {358fn parseSymbols(self: *Dylib) !void {
...@@ -380,7 +404,7 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {...@@ -380,7 +404,7 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {
380404
381 const umbrella_lib = lib_stub.inner[0];405 const umbrella_lib = lib_stub.inner[0];
382406
383 var id = Id.default(try self.allocator.dupe(u8, umbrella_lib.install_name));407 var id = try Id.default(self.allocator, umbrella_lib.install_name);
384 if (umbrella_lib.current_version) |version| {408 if (umbrella_lib.current_version) |version| {
385 try id.parseCurrentVersion(version);409 try id.parseCurrentVersion(version);
386 }410 }
...@@ -470,7 +494,9 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {...@@ -470,7 +494,9 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {
470 }494 }
471495
472 log.debug(" | {s}", .{lib});496 log.debug(" | {s}", .{lib});
473 try self.dependent_libs.put(self.allocator, try self.allocator.dupe(u8, lib), {});497
498 const dep_id = try Id.default(self.allocator, lib);
499 try self.dependent_libs.append(self.allocator, dep_id);
474 }500 }
475 }501 }
476 }502 }
...@@ -478,36 +504,40 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {...@@ -478,36 +504,40 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {
478}504}
479505
480pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {506pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {
481 outer: for (self.dependent_libs.keys()) |lib| {507 outer: for (self.dependent_libs.items) |id| {
482 const dirname = fs.path.dirname(lib) orelse {508 const has_ext = blk: {
483 log.warn("unable to resolve dependency {s}", .{lib});509 const basename = fs.path.basename(id.name);
484 continue;510 break :blk mem.lastIndexOfScalar(u8, basename, '.') != null;
485 };511 };
486 const filename = fs.path.basename(lib);512 const extension = if (has_ext) fs.path.extension(id.name) else "";
487 const without_ext = if (mem.lastIndexOfScalar(u8, filename, '.')) |index|513 const without_ext = if (has_ext) blk: {
488 filename[0..index]514 const index = mem.lastIndexOfScalar(u8, id.name, '.') orelse unreachable;
489 else515 break :blk id.name[0..index];
490 filename;516 } else id.name;
491517
492 for (&[_][]const u8{ "dylib", "tbd" }) |ext| {518 for (&[_][]const u8{ extension, ".tbd" }) |ext| {
493 const with_ext = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{519 const with_ext = try std.fmt.allocPrint(self.allocator, "{s}{s}", .{
494 without_ext,520 without_ext,
495 ext,521 ext,
496 });522 });
497 defer self.allocator.free(with_ext);523 defer self.allocator.free(with_ext);
498524
499 const lib_path = if (self.syslibroot) |syslibroot|525 const full_path = if (self.syslibroot) |syslibroot|
500 try fs.path.join(self.allocator, &.{ syslibroot, dirname, with_ext })526 try fs.path.join(self.allocator, &.{ syslibroot, with_ext })
501 else527 else
502 try fs.path.join(self.allocator, &.{ dirname, with_ext });528 with_ext;
529 defer if (self.syslibroot) |_| self.allocator.free(full_path);
503530
504 log.debug("trying dependency at fully resolved path {s}", .{lib_path});531 log.debug("trying dependency at fully resolved path {s}", .{full_path});
505532
506 const dylibs = (try createAndParseFromPath(533 const dylibs = (try createAndParseFromPath(
507 self.allocator,534 self.allocator,
508 self.arch.?,535 self.arch.?,
509 lib_path,536 full_path,
510 self.syslibroot,537 .{
538 .id = id,
539 .syslibroot = self.syslibroot,
540 },
511 )) orelse {541 )) orelse {
512 continue;542 continue;
513 };543 };
...@@ -516,7 +546,7 @@ pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {...@@ -516,7 +546,7 @@ pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {
516546
517 continue :outer;547 continue :outer;
518 } else {548 } else {
519 log.warn("unable to resolve dependency {s}", .{lib});549 log.warn("unable to resolve dependency {s}", .{id.name});
520 }550 }
521 }551 }
522}552}
src/link/MachO/Symbol.zig+2-1
...@@ -111,7 +111,8 @@ pub const Unresolved = struct {...@@ -111,7 +111,8 @@ pub const Unresolved = struct {
111 base: Symbol,111 base: Symbol,
112112
113 /// File where this symbol was referenced.113 /// File where this symbol was referenced.
114 file: *Object,114 /// null means synthetic, e.g., dyld_stub_binder.
115 file: ?*Object = null,
115116
116 pub const base_type: Symbol.Type = .unresolved;117 pub const base_type: Symbol.Type = .unresolved;
117};118};
src/link/MachO/Zld.zig+21-80
...@@ -38,7 +38,6 @@ objects: std.ArrayListUnmanaged(*Object) = .{},...@@ -38,7 +38,6 @@ objects: std.ArrayListUnmanaged(*Object) = .{},
38archives: std.ArrayListUnmanaged(*Archive) = .{},38archives: std.ArrayListUnmanaged(*Archive) = .{},
39dylibs: std.ArrayListUnmanaged(*Dylib) = .{},39dylibs: std.ArrayListUnmanaged(*Dylib) = .{},
4040
41libsystem_dylib_index: ?u16 = null,
42next_dylib_ordinal: u16 = 1,41next_dylib_ordinal: u16 = 1,
4342
44load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},43load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},
...@@ -199,7 +198,6 @@ const LinkArgs = struct {...@@ -199,7 +198,6 @@ const LinkArgs = struct {
199 syslibroot: ?[]const u8,198 syslibroot: ?[]const u8,
200 libs: []const []const u8,199 libs: []const []const u8,
201 rpaths: []const []const u8,200 rpaths: []const []const u8,
202 libc_stub_path: []const u8,
203};201};
204202
205pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: LinkArgs) !void {203pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: LinkArgs) !void {
...@@ -240,7 +238,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: L...@@ -240,7 +238,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: L
240 try self.populateMetadata();238 try self.populateMetadata();
241 try self.parseInputFiles(files, args.syslibroot);239 try self.parseInputFiles(files, args.syslibroot);
242 try self.parseLibs(args.libs, args.syslibroot);240 try self.parseLibs(args.libs, args.syslibroot);
243 try self.parseLibSystem(args.libc_stub_path, args.syslibroot);
244 try self.resolveSymbols();241 try self.resolveSymbols();
245 try self.resolveStubsAndGotEntries();242 try self.resolveStubsAndGotEntries();
246 try self.updateMetadata();243 try self.updateMetadata();
...@@ -280,7 +277,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8, syslibroot: ?[]const u...@@ -280,7 +277,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8, syslibroot: ?[]const u
280 self.allocator,277 self.allocator,
281 self.arch.?,278 self.arch.?,
282 full_path,279 full_path,
283 syslibroot,280 .{ .syslibroot = syslibroot },
284 )) |dylibs| {281 )) |dylibs| {
285 defer self.allocator.free(dylibs);282 defer self.allocator.free(dylibs);
286 try self.dylibs.appendSlice(self.allocator, dylibs);283 try self.dylibs.appendSlice(self.allocator, dylibs);
...@@ -297,7 +294,7 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi...@@ -297,7 +294,7 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi
297 self.allocator,294 self.allocator,
298 self.arch.?,295 self.arch.?,
299 lib,296 lib,
300 syslibroot,297 .{ .syslibroot = syslibroot },
301 )) |dylibs| {298 )) |dylibs| {
302 defer self.allocator.free(dylibs);299 defer self.allocator.free(dylibs);
303 try self.dylibs.appendSlice(self.allocator, dylibs);300 try self.dylibs.appendSlice(self.allocator, dylibs);
...@@ -313,36 +310,6 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi...@@ -313,36 +310,6 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi
313 }310 }
314}311}
315312
316fn parseLibSystem(self: *Zld, libc_stub_path: []const u8, syslibroot: ?[]const u8) !void {
317 const dylibs = (try Dylib.createAndParseFromPath(
318 self.allocator,
319 self.arch.?,
320 libc_stub_path,
321 syslibroot,
322 )) orelse return error.FailedToParseLibSystem;
323 defer self.allocator.free(dylibs);
324
325 assert(dylibs.len == 1); // More than one dylib output from parsing libSystem!
326 const dylib = dylibs[0];
327
328 self.libsystem_dylib_index = @intCast(u16, self.dylibs.items.len);
329 try self.dylibs.append(self.allocator, dylib);
330
331 // Add LC_LOAD_DYLIB load command.
332 dylib.ordinal = self.next_dylib_ordinal;
333 const dylib_id = dylib.id orelse unreachable;
334 var dylib_cmd = try createLoadDylibCommand(
335 self.allocator,
336 dylib_id.name,
337 dylib_id.timestamp,
338 dylib_id.current_version,
339 dylib_id.compatibility_version,
340 );
341 errdefer dylib_cmd.deinit(self.allocator);
342 try self.load_commands.append(self.allocator, .{ .Dylib = dylib_cmd });
343 self.next_dylib_ordinal += 1;
344}
345
346fn mapAndUpdateSections(313fn mapAndUpdateSections(
347 self: *Zld,314 self: *Zld,
348 object: *Object,315 object: *Object,
...@@ -1656,6 +1623,21 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1656,6 +1623,21 @@ fn resolveSymbols(self: *Zld) !void {
1656 }1623 }
1657 self.unresolved.clearRetainingCapacity();1624 self.unresolved.clearRetainingCapacity();
16581625
1626 // Put dyld_stub_binder as an unresolved special symbol.
1627 {
1628 const name = try self.allocator.dupe(u8, "dyld_stub_binder");
1629 errdefer self.allocator.free(name);
1630 const undef = try self.allocator.create(Symbol.Unresolved);
1631 errdefer self.allocator.destroy(undef);
1632 undef.* = .{
1633 .base = .{
1634 .@"type" = .unresolved,
1635 .name = name,
1636 },
1637 };
1638 try unresolved.append(&undef.base);
1639 }
1640
1659 var referenced = std.AutoHashMap(*Dylib, void).init(self.allocator);1641 var referenced = std.AutoHashMap(*Dylib, void).init(self.allocator);
1660 defer referenced.deinit();1642 defer referenced.deinit();
16611643
...@@ -1664,9 +1646,7 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1664,9 +1646,7 @@ fn resolveSymbols(self: *Zld) !void {
1664 const proxy = inner: {1646 const proxy = inner: {
1665 for (self.dylibs.items) |dylib, i| {1647 for (self.dylibs.items) |dylib, i| {
1666 const proxy = (try dylib.createProxy(undef.name)) orelse continue;1648 const proxy = (try dylib.createProxy(undef.name)) orelse continue;
1667 if (self.libsystem_dylib_index.? != @intCast(u16, i)) { // LibSystem gets load command seperately.1649 try referenced.put(dylib, {});
1668 try referenced.put(dylib, {});
1669 }
1670 break :inner proxy;1650 break :inner proxy;
1671 }1651 }
1672 if (mem.eql(u8, undef.name, "___dso_handle")) {1652 if (mem.eql(u8, undef.name, "___dso_handle")) {
...@@ -1681,7 +1661,6 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1681,7 +1661,6 @@ fn resolveSymbols(self: *Zld) !void {
1681 .@"type" = .proxy,1661 .@"type" = .proxy,
1682 .name = name,1662 .name = name,
1683 },1663 },
1684 .file = null,
1685 };1664 };
1686 break :inner &proxy.base;1665 break :inner &proxy.base;
1687 }1666 }
...@@ -1717,21 +1696,13 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1717,21 +1696,13 @@ fn resolveSymbols(self: *Zld) !void {
1717 if (self.unresolved.count() > 0) {1696 if (self.unresolved.count() > 0) {
1718 for (self.unresolved.values()) |undef| {1697 for (self.unresolved.values()) |undef| {
1719 log.err("undefined reference to symbol '{s}'", .{undef.name});1698 log.err("undefined reference to symbol '{s}'", .{undef.name});
1720 log.err(" | referenced in {s}", .{1699 if (undef.cast(Symbol.Unresolved).?.file) |file| {
1721 undef.cast(Symbol.Unresolved).?.file.name.?,1700 log.err(" | referenced in {s}", .{file.name.?});
1722 });1701 }
1723 }1702 }
17241703
1725 return error.UndefinedSymbolReference;1704 return error.UndefinedSymbolReference;
1726 }1705 }
1727
1728 // Finally put dyld_stub_binder as an Import
1729 const libsystem_dylib = self.dylibs.items[self.libsystem_dylib_index.?];
1730 const proxy = (try libsystem_dylib.createProxy("dyld_stub_binder")) orelse {
1731 log.err("undefined reference to symbol 'dyld_stub_binder'", .{});
1732 return error.UndefinedSymbolReference;
1733 };
1734 try self.imports.putNoClobber(self.allocator, proxy.name, proxy);
1735}1706}
17361707
1737fn resolveStubsAndGotEntries(self: *Zld) !void {1708fn resolveStubsAndGotEntries(self: *Zld) !void {
...@@ -3173,33 +3144,3 @@ pub fn parseName(name: *const [16]u8) []const u8 {...@@ -3173,33 +3144,3 @@ pub fn parseName(name: *const [16]u8) []const u8 {
3173 const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len;3144 const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len;
3174 return name[0..len];3145 return name[0..len];
3175}3146}
3176
3177fn printSymbols(self: *Zld) void {
3178 log.debug("globals", .{});
3179 for (self.globals.values()) |value| {
3180 const sym = value.cast(Symbol.Regular) orelse unreachable;
3181 log.debug(" | {s} @ {*}", .{ sym.base.name, value });
3182 log.debug(" => alias of {*}", .{sym.base.alias});
3183 log.debug(" => linkage {s}", .{sym.linkage});
3184 log.debug(" => defined in {s}", .{sym.file.name.?});
3185 }
3186 for (self.objects.items) |object| {
3187 log.debug("locals in {s}", .{object.name.?});
3188 for (object.symbols.items) |sym| {
3189 log.debug(" | {s} @ {*}", .{ sym.name, sym });
3190 log.debug(" => alias of {*}", .{sym.alias});
3191 if (sym.cast(Symbol.Regular)) |reg| {
3192 log.debug(" => linkage {s}", .{reg.linkage});
3193 } else {
3194 log.debug(" => unresolved", .{});
3195 }
3196 }
3197 }
3198 log.debug("proxies", .{});
3199 for (self.imports.values()) |value| {
3200 const sym = value.cast(Symbol.Proxy) orelse unreachable;
3201 log.debug(" | {s} @ {*}", .{ sym.base.name, value });
3202 log.debug(" => alias of {*}", .{sym.base.alias});
3203 log.debug(" => defined in libSystem.B.dylib", .{});
3204 }
3205}