authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-11 18:15:36+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:38+01:00
logc023b762cd2898e6d2f5cb3c1f6f188ebeb00069
tree9dcf774d87bd847683e935afa0fba0df86bf5fb1
parentd153bc2f0c01af7027f09dd6d42786c4b4d076ed

macho: parse tbds


2 files changed, 39 insertions(+), 19 deletions(-)

src/link/MachO.zig+35-13
...@@ -385,8 +385,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -385,8 +385,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
385 error.MalformedDylib,385 error.MalformedDylib,
386 error.InvalidCpuArch,386 error.InvalidCpuArch,
387 error.InvalidTarget,387 error.InvalidTarget,
388 error.UnknownFileType,
389 => continue, // already reported388 => continue, // already reported
389 error.UnknownFileType => try self.reportParseError(obj.path, "unknown file type for an object file", .{}),
390 else => |e| try self.reportParseError(390 else => |e| try self.reportParseError(
391 obj.path,391 obj.path,
392 "unexpected error: parsing input file failed with error {s}",392 "unexpected error: parsing input file failed with error {s}",
...@@ -436,8 +436,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -436,8 +436,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
436 error.MalformedArchive,436 error.MalformedArchive,
437 error.MalformedDylib,437 error.MalformedDylib,
438 error.InvalidCpuArch,438 error.InvalidCpuArch,
439 error.UnknownFileType,
440 => continue, // already reported439 => continue, // already reported
440 error.UnknownFileType => try self.reportParseError(lib.path, "unknown file type for a library", .{}),
441 else => |e| try self.reportParseError(441 else => |e| try self.reportParseError(
442 lib.path,442 lib.path,
443 "unexpected error: parsing library failed with error {s}",443 "unexpected error: parsing library failed with error {s}",
...@@ -458,8 +458,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -458,8 +458,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
458 error.MalformedArchive,458 error.MalformedArchive,
459 error.InvalidCpuArch,459 error.InvalidCpuArch,
460 error.InvalidTarget,460 error.InvalidTarget,
461 error.UnknownFileType,
462 => {}, // already reported461 => {}, // already reported
462 error.UnknownFileType => try self.reportParseError(path, "unknown file type for a library", .{}),
463 else => |e| try self.reportParseError(463 else => |e| try self.reportParseError(
464 path,464 path,
465 "unexpected error: parsing input file failed with error {s}",465 "unexpected error: parsing input file failed with error {s}",
...@@ -762,6 +762,7 @@ const ParseError = error{...@@ -762,6 +762,7 @@ const ParseError = error{
762 MalformedObject,762 MalformedObject,
763 MalformedArchive,763 MalformedArchive,
764 MalformedDylib,764 MalformedDylib,
765 MalformedTbd,
765 NotLibStub,766 NotLibStub,
766 InvalidCpuArch,767 InvalidCpuArch,
767 InvalidTarget,768 InvalidTarget,
...@@ -796,16 +797,16 @@ fn parseLibrary(self: *MachO, lib: SystemLib, must_link: bool) ParseError!void {...@@ -796,16 +797,16 @@ fn parseLibrary(self: *MachO, lib: SystemLib, must_link: bool) ParseError!void {
796 try self.parseArchive(lib, must_link, fat_arch);797 try self.parseArchive(lib, must_link, fat_arch);
797 } else if (try Dylib.isDylib(lib.path, fat_arch)) {798 } else if (try Dylib.isDylib(lib.path, fat_arch)) {
798 _ = try self.parseDylib(lib, true, fat_arch);799 _ = try self.parseDylib(lib, true, fat_arch);
799 } else {800 } else return error.UnknownFileType;
800 try self.reportParseError(lib.path, "unknown file type for a library", .{});
801 return error.UnknownFileType;
802 }
803 } else if (try Archive.isArchive(lib.path, null)) {801 } else if (try Archive.isArchive(lib.path, null)) {
804 try self.parseArchive(lib, must_link, null);802 try self.parseArchive(lib, must_link, null);
805 } else if (try Dylib.isDylib(lib.path, null)) {803 } else if (try Dylib.isDylib(lib.path, null)) {
806 _ = try self.parseDylib(lib, true, null);804 _ = try self.parseDylib(lib, true, null);
807 } else {805 } else {
808 try self.parseTbd(lib, true);806 _ = self.parseTbd(lib, true) catch |err| switch (err) {
807 error.MalformedTbd => return error.UnknownFileType,
808 else => |e| return e,
809 };
809 }810 }
810}811}
811812
...@@ -925,11 +926,32 @@ fn parseDylib(self: *MachO, lib: SystemLib, explicit: bool, fat_arch: ?fat.Arch)...@@ -925,11 +926,32 @@ fn parseDylib(self: *MachO, lib: SystemLib, explicit: bool, fat_arch: ?fat.Arch)
925 return index;926 return index;
926}927}
927928
928fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!void {929fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!File.Index {
929 _ = self;930 const tracy = trace(@src());
930 _ = lib;931 defer tracy.end();
931 _ = explicit;932
932 return error.Unhandled;933 const gpa = self.base.comp.gpa;
934 const file = try std.fs.cwd().openFile(lib.path, .{});
935 defer file.close();
936
937 var lib_stub = LibStub.loadFromFile(gpa, file) catch return error.MalformedTbd; // TODO actually handle different errors
938 defer lib_stub.deinit();
939
940 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
941 self.files.set(index, .{ .dylib = .{
942 .path = try gpa.dupe(u8, lib.path),
943 .data = &[0]u8{},
944 .index = index,
945 .needed = lib.needed,
946 .weak = lib.weak,
947 .reexport = lib.reexport,
948 .explicit = explicit,
949 } });
950 const dylib = &self.files.items(.data)[index].dylib;
951 try dylib.parseTbd(self.getTarget().cpu.arch, self.platform, lib_stub, self);
952 try self.dylibs.append(gpa, index);
953
954 return index;
933}955}
934956
935fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void {957fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void {
src/link/MachO/Dylib.zig+4-6
...@@ -230,12 +230,13 @@ fn parseTrie(self: *Dylib, data: []const u8, macho_file: *MachO) !void {...@@ -230,12 +230,13 @@ fn parseTrie(self: *Dylib, data: []const u8, macho_file: *MachO) !void {
230pub fn parseTbd(230pub fn parseTbd(
231 self: *Dylib,231 self: *Dylib,
232 cpu_arch: std.Target.Cpu.Arch,232 cpu_arch: std.Target.Cpu.Arch,
233 platform: ?MachO.Options.Platform,233 platform: MachO.Platform,
234 lib_stub: LibStub,234 lib_stub: LibStub,
235 macho_file: *MachO,235 macho_file: *MachO,
236) !void {236) !void {
237 const tracy = trace(@src());237 const tracy = trace(@src());
238 defer tracy.end();238 defer tracy.end();
239
239 const gpa = macho_file.base.comp.gpa;240 const gpa = macho_file.base.comp.gpa;
240241
241 log.debug("parsing dylib from stub", .{});242 log.debug("parsing dylib from stub", .{});
...@@ -258,12 +259,9 @@ pub fn parseTbd(...@@ -258,12 +259,9 @@ pub fn parseTbd(
258259
259 log.debug(" (install_name '{s}')", .{umbrella_lib.installName()});260 log.debug(" (install_name '{s}')", .{umbrella_lib.installName()});
260261
261 self.platform = platform orelse .{262 self.platform = platform;
262 .platform = .MACOS,
263 .version = .{ .value = 0 },
264 };
265263
266 var matcher = try TargetMatcher.init(gpa, cpu_arch, self.platform.?.platform);264 var matcher = try TargetMatcher.init(gpa, cpu_arch, self.platform.?.toApplePlatform());
267 defer matcher.deinit();265 defer matcher.deinit();
268266
269 for (lib_stub.inner, 0..) |elem, stub_index| {267 for (lib_stub.inner, 0..) |elem, stub_index| {