| ... | @@ -596,6 +596,47 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node | ... | @@ -596,6 +596,47 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 596 | state_log.debug("{}", .{self.dumpState()}); | 596 | state_log.debug("{}", .{self.dumpState()}); |
| 597 | | 597 | |
| 598 | try self.initDyldInfoSections(); | 598 | try self.initDyldInfoSections(); |
| | 599 | |
| | 600 | // Beyond this point, everything has been allocated a virtual address and we can resolve |
| | 601 | // the relocations, and commit objects to file. |
| | 602 | if (self.getZigObject()) |zo| { |
| | 603 | var has_resolve_error = false; |
| | 604 | |
| | 605 | for (zo.atoms.items) |atom_index| { |
| | 606 | const atom = self.getAtom(atom_index) orelse continue; |
| | 607 | if (!atom.flags.alive) continue; |
| | 608 | const sect = &self.sections.items(.header)[atom.out_n_sect]; |
| | 609 | if (sect.isZerofill()) continue; |
| | 610 | const code = zo.getAtomDataAlloc(self, atom.*) catch |err| switch (err) { |
| | 611 | error.InputOutput => { |
| | 612 | try self.reportUnexpectedError("fetching code for '{s}' failed", .{ |
| | 613 | atom.getName(self), |
| | 614 | }); |
| | 615 | return error.FlushFailure; |
| | 616 | }, |
| | 617 | else => |e| { |
| | 618 | try self.reportUnexpectedError("unexpected error while fetching code for '{s}': {s}", .{ |
| | 619 | atom.getName(self), |
| | 620 | @errorName(e), |
| | 621 | }); |
| | 622 | return error.FlushFailure; |
| | 623 | }, |
| | 624 | }; |
| | 625 | defer gpa.free(code); |
| | 626 | const file_offset = sect.offset + atom.value - sect.addr; |
| | 627 | atom.resolveRelocs(self, code) catch |err| switch (err) { |
| | 628 | error.ResolveFailed => has_resolve_error = true, |
| | 629 | else => |e| { |
| | 630 | try self.reportUnexpectedError("unexpected error while resolving relocations", .{}); |
| | 631 | return e; |
| | 632 | }, |
| | 633 | }; |
| | 634 | try self.base.file.?.pwriteAll(code, file_offset); |
| | 635 | } |
| | 636 | |
| | 637 | if (has_resolve_error) return error.FlushFailure; |
| | 638 | } |
| | 639 | |
| 599 | self.writeAtoms() catch |err| switch (err) { | 640 | self.writeAtoms() catch |err| switch (err) { |
| 600 | error.ResolveFailed => return error.FlushFailure, | 641 | error.ResolveFailed => return error.FlushFailure, |
| 601 | else => |e| { | 642 | else => |e| { |
| ... | @@ -1955,6 +1996,28 @@ pub fn sortSections(self: *MachO) !void { | ... | @@ -1955,6 +1996,28 @@ pub fn sortSections(self: *MachO) !void { |
| 1955 | self.sections.appendAssumeCapacity(slice.get(sorted.index)); | 1996 | self.sections.appendAssumeCapacity(slice.get(sorted.index)); |
| 1956 | } | 1997 | } |
| 1957 | | 1998 | |
| | 1999 | if (self.getZigObject()) |zo| { |
| | 2000 | for (zo.atoms.items) |atom_index| { |
| | 2001 | const atom = self.getAtom(atom_index) orelse continue; |
| | 2002 | if (!atom.flags.alive) continue; |
| | 2003 | atom.out_n_sect = backlinks[atom.out_n_sect]; |
| | 2004 | } |
| | 2005 | |
| | 2006 | for (zo.symtab.items(.nlist)) |*sym| { |
| | 2007 | if (sym.sect()) { |
| | 2008 | sym.n_sect = backlinks[sym.n_sect]; |
| | 2009 | } |
| | 2010 | } |
| | 2011 | |
| | 2012 | for (zo.symbols.items) |sym_index| { |
| | 2013 | const sym = self.getSymbol(sym_index); |
| | 2014 | const atom = sym.getAtom(self) orelse continue; |
| | 2015 | if (!atom.flags.alive) continue; |
| | 2016 | if (sym.getFile(self).?.getIndex() != zo.index) continue; |
| | 2017 | sym.out_n_sect = backlinks[sym.out_n_sect]; |
| | 2018 | } |
| | 2019 | } |
| | 2020 | |
| 1958 | for (self.objects.items) |index| { | 2021 | for (self.objects.items) |index| { |
| 1959 | for (self.getFile(index).?.object.atoms.items) |atom_index| { | 2022 | for (self.getFile(index).?.object.atoms.items) |atom_index| { |
| 1960 | const atom = self.getAtom(atom_index) orelse continue; | 2023 | const atom = self.getAtom(atom_index) orelse continue; |
| ... | @@ -1962,6 +2025,7 @@ pub fn sortSections(self: *MachO) !void { | ... | @@ -1962,6 +2025,7 @@ pub fn sortSections(self: *MachO) !void { |
| 1962 | atom.out_n_sect = backlinks[atom.out_n_sect]; | 2025 | atom.out_n_sect = backlinks[atom.out_n_sect]; |
| 1963 | } | 2026 | } |
| 1964 | } | 2027 | } |
| | 2028 | |
| 1965 | if (self.getInternalObject()) |object| { | 2029 | if (self.getInternalObject()) |object| { |
| 1966 | for (object.atoms.items) |atom_index| { | 2030 | for (object.atoms.items) |atom_index| { |
| 1967 | const atom = self.getAtom(atom_index) orelse continue; | 2031 | const atom = self.getAtom(atom_index) orelse continue; |
| ... | @@ -2517,6 +2581,7 @@ fn writeAtoms(self: *MachO) !void { | ... | @@ -2517,6 +2581,7 @@ fn writeAtoms(self: *MachO) !void { |
| 2517 | const atom = self.getAtom(atom_index).?; | 2581 | const atom = self.getAtom(atom_index).?; |
| 2518 | assert(atom.flags.alive); | 2582 | assert(atom.flags.alive); |
| 2519 | const off = atom.value - header.addr; | 2583 | const off = atom.value - header.addr; |
| | 2584 | @memcpy(buffer[off..][0..atom.size], atom.getFile(self).object.getAtomData(atom.*)); |
| 2520 | atom.resolveRelocs(self, buffer[off..][0..atom.size]) catch |err| switch (err) { | 2585 | atom.resolveRelocs(self, buffer[off..][0..atom.size]) catch |err| switch (err) { |
| 2521 | error.ResolveFailed => has_resolve_error = true, | 2586 | error.ResolveFailed => has_resolve_error = true, |
| 2522 | else => |e| return e, | 2587 | else => |e| return e, |
| ... | @@ -2757,7 +2822,8 @@ pub fn calcSymtabSize(self: *MachO) !void { | ... | @@ -2757,7 +2822,8 @@ pub fn calcSymtabSize(self: *MachO) !void { |
| 2757 | | 2822 | |
| 2758 | var files = std.ArrayList(File.Index).init(gpa); | 2823 | var files = std.ArrayList(File.Index).init(gpa); |
| 2759 | defer files.deinit(); | 2824 | defer files.deinit(); |
| 2760 | try files.ensureTotalCapacityPrecise(self.objects.items.len + self.dylibs.items.len + 1); | 2825 | try files.ensureTotalCapacityPrecise(self.objects.items.len + self.dylibs.items.len + 2); |
| | 2826 | if (self.zig_object) |index| files.appendAssumeCapacity(index); |
| 2761 | for (self.objects.items) |index| files.appendAssumeCapacity(index); | 2827 | for (self.objects.items) |index| files.appendAssumeCapacity(index); |
| 2762 | for (self.dylibs.items) |index| files.appendAssumeCapacity(index); | 2828 | for (self.dylibs.items) |index| files.appendAssumeCapacity(index); |
| 2763 | if (self.internal_object) |index| files.appendAssumeCapacity(index); | 2829 | if (self.internal_object) |index| files.appendAssumeCapacity(index); |
| ... | @@ -2816,6 +2882,9 @@ pub fn writeSymtab(self: *MachO, off: u32) !u32 { | ... | @@ -2816,6 +2882,9 @@ pub fn writeSymtab(self: *MachO, off: u32) !u32 { |
| 2816 | try self.symtab.resize(gpa, cmd.nsyms); | 2882 | try self.symtab.resize(gpa, cmd.nsyms); |
| 2817 | try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1); | 2883 | try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1); |
| 2818 | | 2884 | |
| | 2885 | if (self.getZigObject()) |zo| { |
| | 2886 | zo.writeSymtab(self); |
| | 2887 | } |
| 2819 | for (self.objects.items) |index| { | 2888 | for (self.objects.items) |index| { |
| 2820 | self.getFile(index).?.writeSymtab(self); | 2889 | self.getFile(index).?.writeSymtab(self); |
| 2821 | } | 2890 | } |
| ... | @@ -3752,7 +3821,7 @@ fn reportDependencyError( | ... | @@ -3752,7 +3821,7 @@ fn reportDependencyError( |
| 3752 | try err.addNote(self, "a dependency of {}", .{self.getFile(parent).?.fmtPath()}); | 3821 | try err.addNote(self, "a dependency of {}", .{self.getFile(parent).?.fmtPath()}); |
| 3753 | } | 3822 | } |
| 3754 | | 3823 | |
| 3755 | fn reportUnexpectedError(self: *MachO, comptime format: []const u8, args: anytype) error{OutOfMemory}!void { | 3824 | pub fn reportUnexpectedError(self: *MachO, comptime format: []const u8, args: anytype) error{OutOfMemory}!void { |
| 3756 | var err = try self.addErrorWithNotes(1); | 3825 | var err = try self.addErrorWithNotes(1); |
| 3757 | try err.addMsg(self, format, args); | 3826 | try err.addMsg(self, format, args); |
| 3758 | try err.addNote(self, "please report this as a linker bug on https://github.com/ziglang/zig/issues/new/choose", .{}); | 3827 | try err.addNote(self, "please report this as a linker bug on https://github.com/ziglang/zig/issues/new/choose", .{}); |