| ... | ... | @@ -384,6 +384,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 384 | 384 | error.MalformedArchive, |
| 385 | 385 | error.InvalidCpuArch, |
| 386 | 386 | error.InvalidTarget, |
| 387 | error.UnknownFileType, |
| 387 | 388 | => continue, // already reported |
| 388 | 389 | else => |e| try self.reportParseError( |
| 389 | 390 | obj.path, |
| ... | ... | @@ -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 | 472 | state_log.debug("{}", .{self.dumpState()}); |
| 397 | 473 | |
| 398 | 474 | @panic("TODO"); |
| ... | ... | @@ -626,13 +702,12 @@ pub fn resolveLibSystem( |
| 626 | 702 | }; |
| 627 | 703 | |
| 628 | 704 | try self.reportMissingLibraryError(checked_paths.items, "unable to find libSystem system library", .{}); |
| 629 | | return; |
| 705 | return error.MissingLibSystem; |
| 630 | 706 | } |
| 631 | 707 | |
| 632 | 708 | const libsystem_path = try arena.dupe(u8, test_path.items); |
| 633 | | try out_libs.put(libsystem_path, .{ |
| 709 | try out_libs.append(.{ |
| 634 | 710 | .needed = true, |
| 635 | | .weak = false, |
| 636 | 711 | .path = libsystem_path, |
| 637 | 712 | }); |
| 638 | 713 | } |
| ... | ... | @@ -685,6 +760,7 @@ fn accessLibPath( |
| 685 | 760 | const ParseError = error{ |
| 686 | 761 | MalformedObject, |
| 687 | 762 | MalformedArchive, |
| 763 | MalformedDylib, |
| 688 | 764 | NotLibStub, |
| 689 | 765 | InvalidCpuArch, |
| 690 | 766 | InvalidTarget, |
| ... | ... | @@ -696,6 +772,8 @@ const ParseError = error{ |
| 696 | 772 | EndOfStream, |
| 697 | 773 | FileSystem, |
| 698 | 774 | NotSupported, |
| 775 | Unhandled, |
| 776 | UnknownFileType, |
| 699 | 777 | } || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError || tapi.TapiError; |
| 700 | 778 | |
| 701 | 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 | 787 | } |
| 710 | 788 | |
| 711 | 789 | fn parseLibrary(self: *MachO, lib: SystemLib, must_link: bool) ParseError!void { |
| 712 | | _ = self; |
| 713 | | _ = lib; |
| 714 | | _ = must_link; |
| 790 | const tracy = trace(@src()); |
| 791 | defer tracy.end(); |
| 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 | 811 | fn parseObject(self: *MachO, path: []const u8) ParseError!void { |
| ... | ... | @@ -739,6 +833,40 @@ fn parseObject(self: *MachO, path: []const u8) ParseError!void { |
| 739 | 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 | 870 | fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { |
| 743 | 871 | _ = self; |
| 744 | 872 | _ = atom_index; |