authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-20 00:14:00+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-20 02:21:58-05:00
log5eaac2fb99ad7357eb7bf2451adcaeec4108aec3
treef7c2037f8dc1e235a48e3d7777c2cc868d4b28bf
parent538c9e7bafd859148352e76c1d8053e1ba426a06

macho: do not write out ZEROFILL physically to file

Prior to this change, `__DATA,__bss` and `__DATA,__thread_bss` would get actually, physically written out to the output file, unnecessarily filling the output file with 0s.

1 files changed, 18 insertions(+), 34 deletions(-)

src/link/MachO.zig+18-34
...@@ -919,17 +919,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -919,17 +919,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
919 try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs);919 try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs);
920 }920 }
921921
922 if (self.bss_section_index) |idx| {
923 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
924 const sect = &seg.sections.items[idx];
925 sect.offset = self.bss_file_offset;
926 }
927 if (self.tlv_bss_section_index) |idx| {
928 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
929 const sect = &seg.sections.items[idx];
930 sect.offset = self.tlv_bss_file_offset;
931 }
932
933 try self.createMhExecuteHeaderAtom();922 try self.createMhExecuteHeaderAtom();
934 for (self.objects.items) |*object, object_id| {923 for (self.objects.items) |*object, object_id| {
935 if (object.analyzed) continue;924 if (object.analyzed) continue;
...@@ -1021,18 +1010,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -1021,18 +1010,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
1021 const sect = &seg.sections.items[id];1010 const sect = &seg.sections.items[id];
1022 sect.size = self.rustc_section_size;1011 sect.size = self.rustc_section_size;
1023 }1012 }
1024 if (self.bss_section_index) |idx| {
1025 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
1026 const sect = &seg.sections.items[idx];
1027 self.bss_file_offset = sect.offset;
1028 sect.offset = 0;
1029 }
1030 if (self.tlv_bss_section_index) |idx| {
1031 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
1032 const sect = &seg.sections.items[idx];
1033 self.tlv_bss_file_offset = sect.offset;
1034 sect.offset = 0;
1035 }
10361013
1037 try self.setEntryPoint();1014 try self.setEntryPoint();
1038 try self.updateSectionOrdinals();1015 try self.updateSectionOrdinals();
...@@ -2127,6 +2104,8 @@ fn writeAllAtoms(self: *MachO) !void {...@@ -2127,6 +2104,8 @@ fn writeAllAtoms(self: *MachO) !void {
2127 const sect = seg.sections.items[match.sect];2104 const sect = seg.sections.items[match.sect];
2128 var atom: *Atom = entry.value_ptr.*;2105 var atom: *Atom = entry.value_ptr.*;
21292106
2107 if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;
2108
2130 var buffer = std.ArrayList(u8).init(self.base.allocator);2109 var buffer = std.ArrayList(u8).init(self.base.allocator);
2131 defer buffer.deinit();2110 defer buffer.deinit();
2132 try buffer.ensureTotalCapacity(try math.cast(usize, sect.size));2111 try buffer.ensureTotalCapacity(try math.cast(usize, sect.size));
...@@ -2179,6 +2158,8 @@ fn writeAtoms(self: *MachO) !void {...@@ -2179,6 +2158,8 @@ fn writeAtoms(self: *MachO) !void {
2179 const sect = seg.sections.items[match.sect];2158 const sect = seg.sections.items[match.sect];
2180 var atom: *Atom = entry.value_ptr.*;2159 var atom: *Atom = entry.value_ptr.*;
21812160
2161 if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;
2162
2182 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });2163 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });
21832164
2184 while (atom.prev) |prev| {2165 while (atom.prev) |prev| {
...@@ -4463,9 +4444,6 @@ fn populateMissingMetadata(self: *MachO) !void {...@@ -4463,9 +4444,6 @@ fn populateMissingMetadata(self: *MachO) !void {
4463 .flags = macho.S_THREAD_LOCAL_ZEROFILL,4444 .flags = macho.S_THREAD_LOCAL_ZEROFILL,
4464 },4445 },
4465 );4446 );
4466 const seg = self.load_commands.items[self.data_segment_cmd_index.?].segment;
4467 const sect = seg.sections.items[self.tlv_bss_section_index.?];
4468 self.tlv_bss_file_offset = sect.offset;
4469 }4447 }
44704448
4471 if (self.bss_section_index == null) {4449 if (self.bss_section_index == null) {
...@@ -4480,9 +4458,6 @@ fn populateMissingMetadata(self: *MachO) !void {...@@ -4480,9 +4458,6 @@ fn populateMissingMetadata(self: *MachO) !void {
4480 .flags = macho.S_ZEROFILL,4458 .flags = macho.S_ZEROFILL,
4481 },4459 },
4482 );4460 );
4483 const seg = self.load_commands.items[self.data_segment_cmd_index.?].segment;
4484 const sect = seg.sections.items[self.bss_section_index.?];
4485 self.bss_file_offset = sect.offset;
4486 }4461 }
44874462
4488 if (self.linkedit_segment_cmd_index == null) {4463 if (self.linkedit_segment_cmd_index == null) {
...@@ -4782,9 +4757,10 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4782,9 +4757,10 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
4782 // Allocate the sections according to their alignment at the beginning of the segment.4757 // Allocate the sections according to their alignment at the beginning of the segment.
4783 var start: u64 = offset;4758 var start: u64 = offset;
4784 for (seg.sections.items) |*sect, sect_id| {4759 for (seg.sections.items) |*sect, sect_id| {
4760 const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;
4785 const alignment = try math.powi(u32, 2, sect.@"align");4761 const alignment = try math.powi(u32, 2, sect.@"align");
4786 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);4762 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);
4787 sect.offset = @intCast(u32, seg.inner.fileoff + start_aligned);4763 sect.offset = if (is_zerofill) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);
4788 sect.addr = seg.inner.vmaddr + start_aligned;4764 sect.addr = seg.inner.vmaddr + start_aligned;
47894765
4790 // Recalculate section size given the allocated start address4766 // Recalculate section size given the allocated start address
...@@ -4811,11 +4787,15 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4811,11 +4787,15 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
4811 } else 0;4787 } else 0;
48124788
4813 start = start_aligned + sect.size;4789 start = start_aligned + sect.size;
4790
4791 if (!is_zerofill) {
4792 seg.inner.filesize = start;
4793 }
4794 seg.inner.vmsize = start;
4814 }4795 }
48154796
4816 const seg_size_aligned = mem.alignForwardGeneric(u64, start, self.page_size);4797 seg.inner.filesize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size);
4817 seg.inner.filesize = seg_size_aligned;4798 seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.vmsize, self.page_size);
4818 seg.inner.vmsize = seg_size_aligned;
4819}4799}
48204800
4821const InitSectionOpts = struct {4801const InitSectionOpts = struct {
...@@ -4853,8 +4833,12 @@ fn initSection(...@@ -4853,8 +4833,12 @@ fn initSection(
4853 off,4833 off,
4854 off + size,4834 off + size,
4855 });4835 });
4836
4856 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;4837 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;
4857 sect.offset = @intCast(u32, off);4838
4839 if (opts.flags != macho.S_ZEROFILL and opts.flags != macho.S_THREAD_LOCAL_ZEROFILL) {
4840 sect.offset = @intCast(u32, off);
4841 }
4858 }4842 }
48594843
4860 const index = @intCast(u16, seg.sections.items.len);4844 const index = @intCast(u16, seg.sections.items.len);