authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-10 15:37:51+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-10 15:37:51+02:00
log8e5f7f5fe89e1c2979df2c735046c81e37c3f842
treeb54d65f52cedf1accb5d99deb6c98856d03215f0
parentaaacfc0d0a23918c6712272e10bb1cdca1daaf04

macho: write adjacent atoms to in-memory buffer

and then commit the large buffer into file.

1 files changed, 44 insertions(+), 4 deletions(-)

src/link/MachO.zig+44-4
......@@ -1766,20 +1766,60 @@ fn allocateGlobalSymbols(self: *MachO) !void {
17661766}
17671767
17681768fn 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
17691773 var it = self.blocks.iterator();
17701774 while (it.next()) |entry| {
17711775 const match = entry.key_ptr.*;
1776 const seg = self.load_commands.items[match.seg].Segment;
1777 const sect = seg.sections.items[match.sect];
17721778 var atom: *TextBlock = entry.value_ptr.*;
17731779
1780 while (atom.prev) |prev| {
1781 atom = prev;
1782 }
1783
17741784 while (true) {
17751785 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 }
17771804 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();
17781811 }
17791812
1780 if (atom.prev) |prev| {
1781 atom = prev;
1782 } else break;
1813 if (atom.next) |next| {
1814 atom = next;
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 }
17831823 }
17841824 }
17851825}