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-02-02 21:22:15-07:00
log252fb642d59e47a11c1f6644dc798f2b7d781696
treedb4d85c8c8d743220e5c82c504851670c349d16b
parentdcbab17b628ff26ceba2ee34544fca94d5bd97a2

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(+), 35 deletions(-)

src/link/MachO.zig+18-35
...@@ -867,17 +867,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -867,17 +867,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
867 try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs);867 try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs);
868 }868 }
869869
870 if (self.bss_section_index) |idx| {
871 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
872 const sect = &seg.sections.items[idx];
873 sect.offset = self.bss_file_offset;
874 }
875 if (self.tlv_bss_section_index) |idx| {
876 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
877 const sect = &seg.sections.items[idx];
878 sect.offset = self.tlv_bss_file_offset;
879 }
880
881 try self.createMhExecuteHeaderAtom();870 try self.createMhExecuteHeaderAtom();
882 for (self.objects.items) |*object, object_id| {871 for (self.objects.items) |*object, object_id| {
883 if (object.analyzed) continue;872 if (object.analyzed) continue;
...@@ -964,19 +953,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -964,19 +953,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
964 try self.writeAtoms();953 try self.writeAtoms();
965 }954 }
966955
967 if (self.bss_section_index) |idx| {
968 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
969 const sect = &seg.sections.items[idx];
970 self.bss_file_offset = sect.offset;
971 sect.offset = 0;
972 }
973 if (self.tlv_bss_section_index) |idx| {
974 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
975 const sect = &seg.sections.items[idx];
976 self.tlv_bss_file_offset = sect.offset;
977 sect.offset = 0;
978 }
979
980 try self.setEntryPoint();956 try self.setEntryPoint();
981 try self.updateSectionOrdinals();957 try self.updateSectionOrdinals();
982 try self.writeLinkeditSegment();958 try self.writeLinkeditSegment();
...@@ -2021,6 +1997,8 @@ fn writeAllAtoms(self: *MachO) !void {...@@ -2021,6 +1997,8 @@ fn writeAllAtoms(self: *MachO) !void {
2021 const sect = seg.sections.items[match.sect];1997 const sect = seg.sections.items[match.sect];
2022 var atom: *Atom = entry.value_ptr.*;1998 var atom: *Atom = entry.value_ptr.*;
20231999
2000 if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;
2001
2024 var buffer = std.ArrayList(u8).init(self.base.allocator);2002 var buffer = std.ArrayList(u8).init(self.base.allocator);
2025 defer buffer.deinit();2003 defer buffer.deinit();
2026 try buffer.ensureTotalCapacity(try math.cast(usize, sect.size));2004 try buffer.ensureTotalCapacity(try math.cast(usize, sect.size));
...@@ -2073,6 +2051,8 @@ fn writeAtoms(self: *MachO) !void {...@@ -2073,6 +2051,8 @@ fn writeAtoms(self: *MachO) !void {
2073 const sect = seg.sections.items[match.sect];2051 const sect = seg.sections.items[match.sect];
2074 var atom: *Atom = entry.value_ptr.*;2052 var atom: *Atom = entry.value_ptr.*;
20752053
2054 if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;
2055
2076 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });2056 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });
20772057
2078 while (atom.prev) |prev| {2058 while (atom.prev) |prev| {
...@@ -4194,9 +4174,6 @@ fn populateMissingMetadata(self: *MachO) !void {...@@ -4194,9 +4174,6 @@ fn populateMissingMetadata(self: *MachO) !void {
4194 .flags = macho.S_THREAD_LOCAL_ZEROFILL,4174 .flags = macho.S_THREAD_LOCAL_ZEROFILL,
4195 },4175 },
4196 );4176 );
4197 const seg = self.load_commands.items[self.data_segment_cmd_index.?].segment;
4198 const sect = seg.sections.items[self.tlv_bss_section_index.?];
4199 self.tlv_bss_file_offset = sect.offset;
4200 }4177 }
42014178
4202 if (self.bss_section_index == null) {4179 if (self.bss_section_index == null) {
...@@ -4211,9 +4188,6 @@ fn populateMissingMetadata(self: *MachO) !void {...@@ -4211,9 +4188,6 @@ fn populateMissingMetadata(self: *MachO) !void {
4211 .flags = macho.S_ZEROFILL,4188 .flags = macho.S_ZEROFILL,
4212 },4189 },
4213 );4190 );
4214 const seg = self.load_commands.items[self.data_segment_cmd_index.?].segment;
4215 const sect = seg.sections.items[self.bss_section_index.?];
4216 self.bss_file_offset = sect.offset;
4217 }4191 }
42184192
4219 if (self.linkedit_segment_cmd_index == null) {4193 if (self.linkedit_segment_cmd_index == null) {
...@@ -4513,9 +4487,10 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4513,9 +4487,10 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
4513 // Allocate the sections according to their alignment at the beginning of the segment.4487 // Allocate the sections according to their alignment at the beginning of the segment.
4514 var start: u64 = offset;4488 var start: u64 = offset;
4515 for (seg.sections.items) |*sect, sect_id| {4489 for (seg.sections.items) |*sect, sect_id| {
4490 const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;
4516 const alignment = try math.powi(u32, 2, sect.@"align");4491 const alignment = try math.powi(u32, 2, sect.@"align");
4517 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);4492 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);
4518 sect.offset = @intCast(u32, seg.inner.fileoff + start_aligned);4493 sect.offset = if (is_zerofill) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);
4519 sect.addr = seg.inner.vmaddr + start_aligned;4494 sect.addr = seg.inner.vmaddr + start_aligned;
45204495
4521 // Recalculate section size given the allocated start address4496 // Recalculate section size given the allocated start address
...@@ -4542,11 +4517,15 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4542,11 +4517,15 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
4542 } else 0;4517 } else 0;
45434518
4544 start = start_aligned + sect.size;4519 start = start_aligned + sect.size;
4520
4521 if (!is_zerofill) {
4522 seg.inner.filesize = start;
4523 }
4524 seg.inner.vmsize = start;
4545 }4525 }
45464526
4547 const seg_size_aligned = mem.alignForwardGeneric(u64, start, self.page_size);4527 seg.inner.filesize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size);
4548 seg.inner.filesize = seg_size_aligned;4528 seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.vmsize, self.page_size);
4549 seg.inner.vmsize = seg_size_aligned;
4550}4529}
45514530
4552const InitSectionOpts = struct {4531const InitSectionOpts = struct {
...@@ -4584,8 +4563,12 @@ fn initSection(...@@ -4584,8 +4563,12 @@ fn initSection(
4584 off,4563 off,
4585 off + size,4564 off + size,
4586 });4565 });
4566
4587 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;4567 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;
4588 sect.offset = @intCast(u32, off);4568
4569 if (opts.flags != macho.S_ZEROFILL and opts.flags != macho.S_THREAD_LOCAL_ZEROFILL) {
4570 sect.offset = @intCast(u32, off);
4571 }
4589 }4572 }
45904573
4591 const index = @intCast(u16, seg.sections.items.len);4574 const index = @intCast(u16, seg.sections.items.len);