From aaaa7df15264edd38d755eb77253d54073e9f192 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sun, 6 Nov 2022 00:10:12 +0100 Subject: [PATCH 1/2] macho: add linker test case for issue 13457 --- test/link.zig | 4 ++++ test/link/macho/bugs/13457/build.zig | 17 +++++++++++++++++ test/link/macho/bugs/13457/main.zig | 1 + 3 files changed, 22 insertions(+) create mode 100644 test/link/macho/bugs/13457/build.zig create mode 100644 test/link/macho/bugs/13457/main.zig diff --git a/test/link.zig b/test/link.zig index 40635b86a0..ab02e587c1 100644 --- a/test/link.zig +++ b/test/link.zig @@ -74,6 +74,10 @@ fn addWasmCases(cases: *tests.StandaloneContext) void { } fn addMachOCases(cases: *tests.StandaloneContext) void { + cases.addBuildFile("test/link/macho/bugs/13457/build.zig", .{ + .build_modes = true, + }); + cases.addBuildFile("test/link/macho/dead_strip/build.zig", .{ .build_modes = false, }); diff --git a/test/link/macho/bugs/13457/build.zig b/test/link/macho/bugs/13457/build.zig new file mode 100644 index 0000000000..2de8c01c6a --- /dev/null +++ b/test/link/macho/bugs/13457/build.zig @@ -0,0 +1,17 @@ +const std = @import("std"); +const Builder = std.build.Builder; +const LibExeObjectStep = std.build.LibExeObjStep; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + + const test_step = b.step("test", "Test the program"); + + const exe = b.addExecutable("test", "main.zig"); + exe.setBuildMode(mode); + exe.setTarget(target); + + const run = exe.runEmulatable(); + test_step.dependOn(&run.step); +} diff --git a/test/link/macho/bugs/13457/main.zig b/test/link/macho/bugs/13457/main.zig new file mode 100644 index 0000000000..902b554db0 --- /dev/null +++ b/test/link/macho/bugs/13457/main.zig @@ -0,0 +1 @@ +pub fn main() void {} From 76fb3e062161e84554e0665444135281f7bcaf74 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sun, 6 Nov 2022 00:36:27 +0100 Subject: [PATCH 2/2] macho: do not zero-out file if there are no nonzerofill sects If the `__DATA` segment comprises of only zerofill sections, do not accidentally zero out all of file. --- src/link/MachO/zld.zig | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 9508d68895..7aaa3887bb 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -4305,24 +4305,21 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr // segment and the beginning of __LINKEDIT segment is zerofilled as the loader will // copy-paste this space into memory for quicker zerofill operation. if (zld.getSegmentByName("__DATA")) |data_seg_id| blk: { - var physical_zerofill_start: u64 = 0; + var physical_zerofill_start: ?u64 = null; const section_indexes = zld.getSectionIndexes(data_seg_id); for (zld.sections.items(.header)[section_indexes.start..section_indexes.end]) |header| { if (header.isZerofill() and header.size > 0) break; physical_zerofill_start = header.offset + header.size; } else break :blk; + const start = physical_zerofill_start orelse break :blk; const linkedit = zld.getLinkeditSegmentPtr(); - const physical_zerofill_size = math.cast(usize, linkedit.fileoff - physical_zerofill_start) orelse - return error.Overflow; - if (physical_zerofill_size > 0) { - log.debug("zeroing out zerofill area of length {x} at {x}", .{ - physical_zerofill_size, - physical_zerofill_start, - }); - var padding = try zld.gpa.alloc(u8, physical_zerofill_size); + const size = math.cast(usize, linkedit.fileoff - start) orelse return error.Overflow; + if (size > 0) { + log.debug("zeroing out zerofill area of length {x} at {x}", .{ size, start }); + var padding = try zld.gpa.alloc(u8, size); defer zld.gpa.free(padding); mem.set(u8, padding, 0); - try zld.file.pwriteAll(padding, physical_zerofill_start); + try zld.file.pwriteAll(padding, start); } }