diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO.zig | 6 | ||||
| -rw-r--r-- | src/link/MachO/CodeSignature.zig | 77 | ||||
| -rw-r--r-- | src/link/MachO/zld.zig | 11 |
3 files changed, 64 insertions, 30 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 30bbc2b6c0..ca8ca6f2bd 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -625,7 +625,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No try self.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len + headers_buf.items.len)); if (codesig) |*csig| { - try self.writeCodeSignature(csig, codesig_offset.?); // code signing always comes last + try self.writeCodeSignature(comp, csig, codesig_offset.?); // code signing always comes last } if (self.d_sym) |*d_sym| { @@ -4037,13 +4037,13 @@ fn writeCodeSignaturePadding( return @intCast(u32, offset); } -fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature, offset: u32) !void { +fn writeCodeSignature(self: *MachO, comp: *const Compilation, code_sig: *CodeSignature, offset: u32) !void { const seg = self.getSegment(self.text_section_index.?); var buffer = std.ArrayList(u8).init(self.base.allocator); defer buffer.deinit(); try buffer.ensureTotalCapacityPrecise(code_sig.size()); - try code_sig.writeAdhocSignature(self.base.allocator, .{ + try code_sig.writeAdhocSignature(comp, .{ .file = self.base.file.?, .exec_seg_base = seg.fileoff, .exec_seg_limit = seg.filesize, diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig index 530a13dc51..ed1245d0d8 100644 --- a/src/link/MachO/CodeSignature.zig +++ b/src/link/MachO/CodeSignature.zig @@ -1,4 +1,6 @@ const CodeSignature = @This(); +const Compilation = @import("../../Compilation.zig"); +const WaitGroup = @import("../../WaitGroup.zig"); const std = @import("std"); const assert = std.debug.assert; @@ -258,17 +260,19 @@ pub const WriteOpts = struct { pub fn writeAdhocSignature( self: *CodeSignature, - allocator: Allocator, + comp: *const Compilation, opts: WriteOpts, writer: anytype, ) !void { + const gpa = comp.gpa; + var header: macho.SuperBlob = .{ .magic = macho.CSMAGIC_EMBEDDED_SIGNATURE, .length = @sizeOf(macho.SuperBlob), .count = 0, }; - var blobs = std.ArrayList(Blob).init(allocator); + var blobs = std.ArrayList(Blob).init(gpa); defer blobs.deinit(); self.code_directory.inner.execSegBase = opts.exec_seg_base; @@ -276,37 +280,49 @@ pub fn writeAdhocSignature( self.code_directory.inner.execSegFlags = if (opts.output_mode == .Exe) macho.CS_EXECSEG_MAIN_BINARY else 0; self.code_directory.inner.codeLimit = opts.file_size; - const total_pages = mem.alignForward(opts.file_size, self.page_size) / self.page_size; - - var buffer = try allocator.alloc(u8, self.page_size); - defer allocator.free(buffer); + const total_pages = @intCast(u32, mem.alignForward(opts.file_size, self.page_size) / self.page_size); - try self.code_directory.code_slots.ensureTotalCapacityPrecise(allocator, total_pages); + try self.code_directory.code_slots.ensureTotalCapacityPrecise(gpa, total_pages); + self.code_directory.code_slots.items.len = total_pages; + self.code_directory.inner.nCodeSlots += total_pages; // Calculate hash for each page (in file) and write it to the buffer - var hash: [hash_size]u8 = undefined; - var i: usize = 0; - while (i < total_pages) : (i += 1) { - const fstart = i * self.page_size; - const fsize = if (fstart + self.page_size > opts.file_size) - opts.file_size - fstart - else - self.page_size; - const len = try opts.file.preadAll(buffer, fstart); - assert(fsize <= len); - - Sha256.hash(buffer[0..fsize], &hash, .{}); - - self.code_directory.code_slots.appendAssumeCapacity(hash); - self.code_directory.inner.nCodeSlots += 1; + var wg: WaitGroup = .{}; + { + const results = try gpa.alloc(fs.File.PReadError!usize, total_pages); + defer gpa.free(results); + { + const buffer = try gpa.alloc(u8, self.page_size * total_pages); + defer gpa.free(buffer); + + wg.reset(); + defer wg.wait(); + + var i: usize = 0; + while (i < total_pages) : (i += 1) { + const fstart = i * self.page_size; + const fsize = if (fstart + self.page_size > opts.file_size) + opts.file_size - fstart + else + self.page_size; + const out_hash = &self.code_directory.code_slots.items[i]; + wg.start(); + try comp.thread_pool.spawn(workerSha256Hash, .{ + opts.file, fstart, buffer[0..fsize], out_hash, &results[i], &wg, + }); + } + } + for (results) |result| _ = try result; } try blobs.append(.{ .code_directory = &self.code_directory }); header.length += @sizeOf(macho.BlobIndex); header.count += 1; + var hash: [hash_size]u8 = undefined; + if (self.requirements) |*req| { - var buf = std.ArrayList(u8).init(allocator); + var buf = std.ArrayList(u8).init(gpa); defer buf.deinit(); try req.write(buf.writer()); Sha256.hash(buf.items, &hash, .{}); @@ -318,7 +334,7 @@ pub fn writeAdhocSignature( } if (self.entitlements) |*ents| { - var buf = std.ArrayList(u8).init(allocator); + var buf = std.ArrayList(u8).init(gpa); defer buf.deinit(); try ents.write(buf.writer()); Sha256.hash(buf.items, &hash, .{}); @@ -356,6 +372,19 @@ pub fn writeAdhocSignature( } } +fn workerSha256Hash( + file: fs.File, + fstart: usize, + buffer: []u8, + hash: *[hash_size]u8, + err: *fs.File.PReadError!usize, + wg: *WaitGroup, +) void { + defer wg.finish(); + err.* = file.preadAll(buffer, fstart); + Sha256.hash(buffer, hash, .{}); +} + pub fn size(self: CodeSignature) u32 { var ssize: u32 = @sizeOf(macho.SuperBlob) + @sizeOf(macho.BlobIndex) + self.code_directory.size(); if (self.requirements) |req| { diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index b9adaf7bf0..8d599e0185 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -3035,14 +3035,19 @@ pub const Zld = struct { return @intCast(u32, offset); } - fn writeCodeSignature(self: *Zld, code_sig: *CodeSignature, offset: u32) !void { + fn writeCodeSignature( + self: *Zld, + comp: *const Compilation, + code_sig: *CodeSignature, + offset: u32, + ) !void { const seg_id = self.getSegmentByName("__TEXT").?; const seg = self.segments.items[seg_id]; var buffer = std.ArrayList(u8).init(self.gpa); defer buffer.deinit(); try buffer.ensureTotalCapacityPrecise(code_sig.size()); - try code_sig.writeAdhocSignature(self.gpa, .{ + try code_sig.writeAdhocSignature(comp, .{ .file = self.file, .exec_seg_base = seg.fileoff, .exec_seg_limit = seg.filesize, @@ -4379,7 +4384,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr try zld.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len + headers_buf.items.len)); if (codesig) |*csig| { - try zld.writeCodeSignature(csig, codesig_offset.?); // code signing always comes last + try zld.writeCodeSignature(comp, csig, codesig_offset.?); // code signing always comes last } } |
