| ... | ... | @@ -596,6 +596,47 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 596 | 596 | state_log.debug("{}", .{self.dumpState()}); |
| 597 | 597 | |
| 598 | 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 | 640 | self.writeAtoms() catch |err| switch (err) { |
| 600 | 641 | error.ResolveFailed => return error.FlushFailure, |
| 601 | 642 | else => |e| { |
| ... | ... | @@ -1955,6 +1996,28 @@ pub fn sortSections(self: *MachO) !void { |
| 1955 | 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 | 2021 | for (self.objects.items) |index| { |
| 1959 | 2022 | for (self.getFile(index).?.object.atoms.items) |atom_index| { |
| 1960 | 2023 | const atom = self.getAtom(atom_index) orelse continue; |
| ... | ... | @@ -1962,6 +2025,7 @@ pub fn sortSections(self: *MachO) !void { |
| 1962 | 2025 | atom.out_n_sect = backlinks[atom.out_n_sect]; |
| 1963 | 2026 | } |
| 1964 | 2027 | } |
| 2028 | |
| 1965 | 2029 | if (self.getInternalObject()) |object| { |
| 1966 | 2030 | for (object.atoms.items) |atom_index| { |
| 1967 | 2031 | const atom = self.getAtom(atom_index) orelse continue; |
| ... | ... | @@ -2517,6 +2581,7 @@ fn writeAtoms(self: *MachO) !void { |
| 2517 | 2581 | const atom = self.getAtom(atom_index).?; |
| 2518 | 2582 | assert(atom.flags.alive); |
| 2519 | 2583 | const off = atom.value - header.addr; |
| 2584 | @memcpy(buffer[off..][0..atom.size], atom.getFile(self).object.getAtomData(atom.*)); |
| 2520 | 2585 | atom.resolveRelocs(self, buffer[off..][0..atom.size]) catch |err| switch (err) { |
| 2521 | 2586 | error.ResolveFailed => has_resolve_error = true, |
| 2522 | 2587 | else => |e| return e, |
| ... | ... | @@ -2757,7 +2822,8 @@ pub fn calcSymtabSize(self: *MachO) !void { |
| 2757 | 2822 | |
| 2758 | 2823 | var files = std.ArrayList(File.Index).init(gpa); |
| 2759 | 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 | 2827 | for (self.objects.items) |index| files.appendAssumeCapacity(index); |
| 2762 | 2828 | for (self.dylibs.items) |index| files.appendAssumeCapacity(index); |
| 2763 | 2829 | if (self.internal_object) |index| files.appendAssumeCapacity(index); |
| ... | ... | @@ -2816,6 +2882,9 @@ pub fn writeSymtab(self: *MachO, off: u32) !u32 { |
| 2816 | 2882 | try self.symtab.resize(gpa, cmd.nsyms); |
| 2817 | 2883 | try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1); |
| 2818 | 2884 | |
| 2885 | if (self.getZigObject()) |zo| { |
| 2886 | zo.writeSymtab(self); |
| 2887 | } |
| 2819 | 2888 | for (self.objects.items) |index| { |
| 2820 | 2889 | self.getFile(index).?.writeSymtab(self); |
| 2821 | 2890 | } |
| ... | ... | @@ -3752,7 +3821,7 @@ fn reportDependencyError( |
| 3752 | 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 | 3825 | var err = try self.addErrorWithNotes(1); |
| 3757 | 3826 | try err.addMsg(self, format, args); |
| 3758 | 3827 | try err.addNote(self, "please report this as a linker bug on https://github.com/ziglang/zig/issues/new/choose", .{}); |