| ... | @@ -384,6 +384,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node | ... | @@ -384,6 +384,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 384 | error.MalformedArchive, | 384 | error.MalformedArchive, |
| 385 | error.InvalidCpuArch, | 385 | error.InvalidCpuArch, |
| 386 | error.InvalidTarget, | 386 | error.InvalidTarget, |
| | 387 | error.UnknownFileType, |
| 387 | => continue, // already reported | 388 | => continue, // already reported |
| 388 | else => |e| try self.reportParseError( | 389 | else => |e| try self.reportParseError( |
| 389 | obj.path, | 390 | obj.path, |
| ... | @@ -393,6 +394,81 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node | ... | @@ -393,6 +394,81 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 393 | }; | 394 | }; |
| 394 | } | 395 | } |
| 395 | | 396 | |
| | 397 | var system_libs = std.ArrayList(SystemLib).init(gpa); |
| | 398 | defer system_libs.deinit(); |
| | 399 | |
| | 400 | // libs |
| | 401 | try system_libs.ensureUnusedCapacity(comp.system_libs.values().len); |
| | 402 | for (comp.system_libs.values()) |info| { |
| | 403 | system_libs.appendAssumeCapacity(.{ |
| | 404 | .needed = info.needed, |
| | 405 | .weak = info.weak, |
| | 406 | .path = info.path.?, |
| | 407 | }); |
| | 408 | } |
| | 409 | |
| | 410 | // frameworks |
| | 411 | try system_libs.ensureUnusedCapacity(self.frameworks.len); |
| | 412 | for (self.frameworks) |info| { |
| | 413 | system_libs.appendAssumeCapacity(.{ |
| | 414 | .needed = info.needed, |
| | 415 | .weak = info.weak, |
| | 416 | .path = info.path, |
| | 417 | }); |
| | 418 | } |
| | 419 | |
| | 420 | // libc++ dep |
| | 421 | if (comp.config.link_libcpp) { |
| | 422 | try system_libs.ensureUnusedCapacity(2); |
| | 423 | system_libs.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path }); |
| | 424 | system_libs.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path }); |
| | 425 | } |
| | 426 | |
| | 427 | // libc/libSystem dep |
| | 428 | self.resolveLibSystem(arena, comp, &system_libs) catch |err| switch (err) { |
| | 429 | error.MissingLibSystem => {}, // already reported |
| | 430 | else => |e| return e, // TODO: convert into an error |
| | 431 | }; |
| | 432 | |
| | 433 | for (system_libs.items) |lib| { |
| | 434 | self.parseLibrary(lib, false) catch |err| switch (err) { |
| | 435 | error.MalformedDylib, |
| | 436 | error.MalformedArchive, |
| | 437 | error.InvalidCpuArch, |
| | 438 | error.UnknownFileType, |
| | 439 | => continue, // already reported |
| | 440 | else => |e| try self.reportParseError( |
| | 441 | lib.path, |
| | 442 | "unexpected error: parsing library failed with error {s}", |
| | 443 | .{@errorName(e)}, |
| | 444 | ), |
| | 445 | }; |
| | 446 | } |
| | 447 | |
| | 448 | // Finally, link against compiler_rt. |
| | 449 | const compiler_rt_path: ?[]const u8 = blk: { |
| | 450 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| | 451 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; |
| | 452 | break :blk null; |
| | 453 | }; |
| | 454 | if (compiler_rt_path) |path| { |
| | 455 | self.parsePositional(path, false) catch |err| switch (err) { |
| | 456 | error.MalformedObject, |
| | 457 | error.MalformedArchive, |
| | 458 | error.InvalidCpuArch, |
| | 459 | error.InvalidTarget, |
| | 460 | error.UnknownFileType, |
| | 461 | => {}, // already reported |
| | 462 | else => |e| try self.reportParseError( |
| | 463 | path, |
| | 464 | "unexpected error: parsing input file failed with error {s}", |
| | 465 | .{@errorName(e)}, |
| | 466 | ), |
| | 467 | }; |
| | 468 | } |
| | 469 | |
| | 470 | if (comp.link_errors.items.len > 0) return error.FlushFailure; |
| | 471 | |
| 396 | state_log.debug("{}", .{self.dumpState()}); | 472 | state_log.debug("{}", .{self.dumpState()}); |
| 397 | | 473 | |
| 398 | @panic("TODO"); | 474 | @panic("TODO"); |
| ... | @@ -626,13 +702,12 @@ pub fn resolveLibSystem( | ... | @@ -626,13 +702,12 @@ pub fn resolveLibSystem( |
| 626 | }; | 702 | }; |
| 627 | | 703 | |
| 628 | try self.reportMissingLibraryError(checked_paths.items, "unable to find libSystem system library", .{}); | 704 | try self.reportMissingLibraryError(checked_paths.items, "unable to find libSystem system library", .{}); |
| 629 | return; | 705 | return error.MissingLibSystem; |
| 630 | } | 706 | } |
| 631 | | 707 | |
| 632 | const libsystem_path = try arena.dupe(u8, test_path.items); | 708 | const libsystem_path = try arena.dupe(u8, test_path.items); |
| 633 | try out_libs.put(libsystem_path, .{ | 709 | try out_libs.append(.{ |
| 634 | .needed = true, | 710 | .needed = true, |
| 635 | .weak = false, | | |
| 636 | .path = libsystem_path, | 711 | .path = libsystem_path, |
| 637 | }); | 712 | }); |
| 638 | } | 713 | } |
| ... | @@ -685,6 +760,7 @@ fn accessLibPath( | ... | @@ -685,6 +760,7 @@ fn accessLibPath( |
| 685 | const ParseError = error{ | 760 | const ParseError = error{ |
| 686 | MalformedObject, | 761 | MalformedObject, |
| 687 | MalformedArchive, | 762 | MalformedArchive, |
| | 763 | MalformedDylib, |
| 688 | NotLibStub, | 764 | NotLibStub, |
| 689 | InvalidCpuArch, | 765 | InvalidCpuArch, |
| 690 | InvalidTarget, | 766 | InvalidTarget, |
| ... | @@ -696,6 +772,8 @@ const ParseError = error{ | ... | @@ -696,6 +772,8 @@ const ParseError = error{ |
| 696 | EndOfStream, | 772 | EndOfStream, |
| 697 | FileSystem, | 773 | FileSystem, |
| 698 | NotSupported, | 774 | NotSupported, |
| | 775 | Unhandled, |
| | 776 | UnknownFileType, |
| 699 | } || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError || tapi.TapiError; | 777 | } || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError || tapi.TapiError; |
| 700 | | 778 | |
| 701 | fn parsePositional(self: *MachO, path: []const u8, must_link: bool) ParseError!void { | 779 | fn parsePositional(self: *MachO, path: []const u8, must_link: bool) ParseError!void { |
| ... | @@ -709,9 +787,25 @@ fn parsePositional(self: *MachO, path: []const u8, must_link: bool) ParseError!v | ... | @@ -709,9 +787,25 @@ fn parsePositional(self: *MachO, path: []const u8, must_link: bool) ParseError!v |
| 709 | } | 787 | } |
| 710 | | 788 | |
| 711 | fn parseLibrary(self: *MachO, lib: SystemLib, must_link: bool) ParseError!void { | 789 | fn parseLibrary(self: *MachO, lib: SystemLib, must_link: bool) ParseError!void { |
| 712 | _ = self; | 790 | const tracy = trace(@src()); |
| 713 | _ = lib; | 791 | defer tracy.end(); |
| 714 | _ = must_link; | 792 | if (try fat.isFatLibrary(lib.path)) { |
| | 793 | const fat_arch = try self.parseFatLibrary(lib.path); |
| | 794 | if (try Archive.isArchive(lib.path, fat_arch)) { |
| | 795 | try self.parseArchive(lib, must_link, fat_arch); |
| | 796 | } else if (try Dylib.isDylib(lib.path, fat_arch)) { |
| | 797 | try self.parseDylib(lib, true, fat_arch); |
| | 798 | } else { |
| | 799 | try self.reportParseError(lib.path, "unknown file type for a library", .{}); |
| | 800 | return error.UnknownFileType; |
| | 801 | } |
| | 802 | } else if (try Archive.isArchive(lib.path, null)) { |
| | 803 | try self.parseArchive(lib, must_link, null); |
| | 804 | } else if (try Dylib.isDylib(lib.path, null)) { |
| | 805 | try self.parseDylib(lib, true, null); |
| | 806 | } else { |
| | 807 | try self.parseTbd(lib, true); |
| | 808 | } |
| 715 | } | 809 | } |
| 716 | | 810 | |
| 717 | fn parseObject(self: *MachO, path: []const u8) ParseError!void { | 811 | fn parseObject(self: *MachO, path: []const u8) ParseError!void { |
| ... | @@ -739,6 +833,40 @@ fn parseObject(self: *MachO, path: []const u8) ParseError!void { | ... | @@ -739,6 +833,40 @@ fn parseObject(self: *MachO, path: []const u8) ParseError!void { |
| 739 | try object.parse(self); | 833 | try object.parse(self); |
| 740 | } | 834 | } |
| 741 | | 835 | |
| | 836 | fn parseFatLibrary(self: *MachO, path: []const u8) !fat.Arch { |
| | 837 | var buffer: [2]fat.Arch = undefined; |
| | 838 | const fat_archs = try fat.parseArchs(path, &buffer); |
| | 839 | const cpu_arch = self.getTarget().cpu.arch; |
| | 840 | for (fat_archs) |arch| { |
| | 841 | if (arch.tag == cpu_arch) return arch; |
| | 842 | } |
| | 843 | try self.reportParseError(path, "missing arch in universal file: expected {s}", .{@tagName(cpu_arch)}); |
| | 844 | return error.InvalidCpuArch; |
| | 845 | } |
| | 846 | |
| | 847 | fn parseArchive(self: *MachO, lib: SystemLib, must_link: bool, fat_arch: ?fat.Arch) ParseError!void { |
| | 848 | _ = self; |
| | 849 | _ = lib; |
| | 850 | _ = must_link; |
| | 851 | _ = fat_arch; |
| | 852 | return error.Unhandled; |
| | 853 | } |
| | 854 | |
| | 855 | fn parseDylib(self: *MachO, lib: SystemLib, explicit: bool, fat_arch: ?fat.Arch) ParseError!void { |
| | 856 | _ = self; |
| | 857 | _ = lib; |
| | 858 | _ = explicit; |
| | 859 | _ = fat_arch; |
| | 860 | return error.Unhandled; |
| | 861 | } |
| | 862 | |
| | 863 | fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!void { |
| | 864 | _ = self; |
| | 865 | _ = lib; |
| | 866 | _ = explicit; |
| | 867 | return error.Unhandled; |
| | 868 | } |
| | 869 | |
| 742 | fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { | 870 | fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { |
| 743 | _ = self; | 871 | _ = self; |
| 744 | _ = atom_index; | 872 | _ = atom_index; |