| ... | @@ -1766,20 +1766,60 @@ fn allocateGlobalSymbols(self: *MachO) !void { | ... | @@ -1766,20 +1766,60 @@ fn allocateGlobalSymbols(self: *MachO) !void { |
| 1766 | } | 1766 | } |
| 1767 | | 1767 | |
| 1768 | fn writeAtoms(self: *MachO) !void { | 1768 | fn writeAtoms(self: *MachO) !void { |
| | 1769 | var buffer = std.ArrayList(u8).init(self.base.allocator); |
| | 1770 | defer buffer.deinit(); |
| | 1771 | var file_offset: ?u64 = null; |
| | 1772 | |
| 1769 | var it = self.blocks.iterator(); | 1773 | var it = self.blocks.iterator(); |
| 1770 | while (it.next()) |entry| { | 1774 | while (it.next()) |entry| { |
| 1771 | const match = entry.key_ptr.*; | 1775 | const match = entry.key_ptr.*; |
| | 1776 | const seg = self.load_commands.items[match.seg].Segment; |
| | 1777 | const sect = seg.sections.items[match.sect]; |
| 1772 | var atom: *TextBlock = entry.value_ptr.*; | 1778 | var atom: *TextBlock = entry.value_ptr.*; |
| 1773 | | 1779 | |
| | 1780 | while (atom.prev) |prev| { |
| | 1781 | atom = prev; |
| | 1782 | } |
| | 1783 | |
| 1774 | while (true) { | 1784 | while (true) { |
| 1775 | if (atom.dirty) { | 1785 | if (atom.dirty) { |
| 1776 | try self.writeAtom(atom, match); | 1786 | const atom_sym = self.locals.items[atom.local_sym_index]; |
| | 1787 | const padding_size: u64 = if (atom.next) |next| blk: { |
| | 1788 | const next_sym = self.locals.items[next.local_sym_index]; |
| | 1789 | break :blk next_sym.n_value - (atom_sym.n_value + atom.size); |
| | 1790 | } else 0; |
| | 1791 | |
| | 1792 | try atom.resolveRelocs(self); |
| | 1793 | try buffer.appendSlice(atom.code.items); |
| | 1794 | try buffer.ensureUnusedCapacity(padding_size); |
| | 1795 | |
| | 1796 | var i: usize = 0; |
| | 1797 | while (i < padding_size) : (i += 1) { |
| | 1798 | buffer.appendAssumeCapacity(0); |
| | 1799 | } |
| | 1800 | |
| | 1801 | if (file_offset == null) { |
| | 1802 | file_offset = sect.offset + atom_sym.n_value - sect.addr; |
| | 1803 | } |
| 1777 | atom.dirty = false; | 1804 | atom.dirty = false; |
| | 1805 | } else { |
| | 1806 | if (file_offset) |off| { |
| | 1807 | try self.base.file.?.pwriteAll(buffer.items, off); |
| | 1808 | } |
| | 1809 | file_offset = null; |
| | 1810 | buffer.clearRetainingCapacity(); |
| 1778 | } | 1811 | } |
| 1779 | | 1812 | |
| 1780 | if (atom.prev) |prev| { | 1813 | if (atom.next) |next| { |
| 1781 | atom = prev; | 1814 | atom = next; |
| 1782 | } else break; | 1815 | } else { |
| | 1816 | if (file_offset) |off| { |
| | 1817 | try self.base.file.?.pwriteAll(buffer.items, off); |
| | 1818 | } |
| | 1819 | file_offset = null; |
| | 1820 | buffer.clearRetainingCapacity(); |
| | 1821 | break; |
| | 1822 | } |
| 1783 | } | 1823 | } |
| 1784 | } | 1824 | } |
| 1785 | } | 1825 | } |