aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-12-15 23:43:50 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-12-16 18:05:58 +0100
commit585c21e54d339f207028d871a45546da2d1b6871 (patch)
tree0b830739f4a388e4767b54d55a7f070e2209ece4 /src
parent1928ed7dab3949db964d96dad82beb776e69554f (diff)
downloadzig-585c21e54d339f207028d871a45546da2d1b6871.tar.gz
zig-585c21e54d339f207028d871a45546da2d1b6871.zip
macho: move parallel file hashing back to CodeSignature
I need to think some more how to calculate UUID in parallel, if it is even possible, to preserve UUID's determinism.
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO/CodeSignature.zig65
-rw-r--r--src/link/MachO/hasher.zig68
-rw-r--r--src/link/MachO/zld.zig34
3 files changed, 67 insertions, 100 deletions
diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig
index 391ac28efa..116ed254f8 100644
--- a/src/link/MachO/CodeSignature.zig
+++ b/src/link/MachO/CodeSignature.zig
@@ -10,8 +10,9 @@ const testing = std.testing;
const Allocator = mem.Allocator;
const Compilation = @import("../../Compilation.zig");
-const Hasher = @import("hasher.zig").ParallelHasher;
const Sha256 = std.crypto.hash.sha2.Sha256;
+const ThreadPool = @import("../../ThreadPool.zig");
+const WaitGroup = @import("../../WaitGroup.zig");
const hash_size = Sha256.digest_length;
@@ -288,11 +289,7 @@ pub fn writeAdhocSignature(
self.code_directory.inner.nCodeSlots = total_pages;
// Calculate hash for each page (in file) and write it to the buffer
- var hasher = Hasher(Sha256){};
- try hasher.hash(gpa, comp.thread_pool, opts.file, self.code_directory.code_slots.items, .{
- .chunk_size = self.page_size,
- .max_file_size = opts.file_size,
- });
+ try self.parallelHash(gpa, comp.thread_pool, opts.file, opts.file_size);
try blobs.append(.{ .code_directory = &self.code_directory });
header.length += @sizeOf(macho.BlobIndex);
@@ -351,6 +348,62 @@ pub fn writeAdhocSignature(
}
}
+fn parallelHash(
+ self: *CodeSignature,
+ gpa: Allocator,
+ pool: *ThreadPool,
+ file: fs.File,
+ file_size: u64,
+) !void {
+ var wg: WaitGroup = .{};
+
+ const total_num_chunks = mem.alignForward(file_size, self.page_size) / self.page_size;
+ assert(self.code_directory.code_slots.items.len >= total_num_chunks);
+
+ const buffer = try gpa.alloc(u8, self.page_size * total_num_chunks);
+ defer gpa.free(buffer);
+
+ const results = try gpa.alloc(fs.File.PReadError!usize, total_num_chunks);
+ defer gpa.free(results);
+
+ {
+ wg.reset();
+ defer wg.wait();
+
+ var i: usize = 0;
+ while (i < total_num_chunks) : (i += 1) {
+ const fstart = i * self.page_size;
+ const fsize = if (fstart + self.page_size > file_size)
+ file_size - fstart
+ else
+ self.page_size;
+ wg.start();
+ try pool.spawn(worker, .{
+ file,
+ fstart,
+ buffer[fstart..][0..fsize],
+ &self.code_directory.code_slots.items[i],
+ &results[i],
+ &wg,
+ });
+ }
+ }
+ for (results) |result| _ = try result;
+}
+
+fn worker(
+ file: fs.File,
+ fstart: usize,
+ buffer: []u8,
+ out: *[hash_size]u8,
+ err: *fs.File.PReadError!usize,
+ wg: *WaitGroup,
+) void {
+ defer wg.finish();
+ err.* = file.preadAll(buffer, fstart);
+ Sha256.hash(buffer, out, .{});
+}
+
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/hasher.zig b/src/link/MachO/hasher.zig
deleted file mode 100644
index bb0531286c..0000000000
--- a/src/link/MachO/hasher.zig
+++ /dev/null
@@ -1,68 +0,0 @@
-const std = @import("std");
-const assert = std.debug.assert;
-const fs = std.fs;
-const mem = std.mem;
-
-const Allocator = mem.Allocator;
-const ThreadPool = @import("../../ThreadPool.zig");
-const WaitGroup = @import("../../WaitGroup.zig");
-
-pub fn ParallelHasher(comptime Hasher: type) type {
- const hash_size = Hasher.digest_length;
-
- return struct {
- pub fn hash(self: @This(), gpa: Allocator, pool: *ThreadPool, file: fs.File, out: [][hash_size]u8, opts: struct {
- chunk_size: u16 = 0x4000,
- file_pos: u64 = 0,
- max_file_size: ?u64 = null,
- }) !void {
- _ = self;
-
- var wg: WaitGroup = .{};
-
- const file_size = opts.max_file_size orelse try file.getEndPos();
- const total_num_chunks = mem.alignForward(file_size, opts.chunk_size) / opts.chunk_size;
- assert(out.len >= total_num_chunks);
-
- const buffer = try gpa.alloc(u8, opts.chunk_size * total_num_chunks);
- defer gpa.free(buffer);
-
- const results = try gpa.alloc(fs.File.PReadError!usize, total_num_chunks);
- defer gpa.free(results);
-
- {
- wg.reset();
- defer wg.wait();
-
- var i: usize = 0;
- while (i < total_num_chunks) : (i += 1) {
- const fstart = i * opts.chunk_size;
- const fsize = if (fstart + opts.chunk_size > file_size) file_size - fstart else opts.chunk_size;
- wg.start();
- try pool.spawn(worker, .{
- file,
- fstart + opts.file_pos,
- buffer[fstart..][0..fsize],
- &out[i],
- &results[i],
- &wg,
- });
- }
- }
- for (results) |result| _ = try result;
- }
-
- fn worker(
- file: fs.File,
- fstart: usize,
- buffer: []u8,
- out: *[hash_size]u8,
- err: *fs.File.PReadError!usize,
- wg: *WaitGroup,
- ) void {
- defer wg.finish();
- err.* = file.preadAll(buffer, fstart);
- Hasher.hash(buffer, out, .{});
- }
- };
-}
diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig
index 23a7963cc0..e7e78b9aef 100644
--- a/src/link/MachO/zld.zig
+++ b/src/link/MachO/zld.zig
@@ -2692,7 +2692,12 @@ pub const Zld = struct {
conformUuid(&self.uuid_cmd.uuid);
},
else => {
- const max_file_size = self.symtab_cmd.stroff + self.symtab_cmd.strsize;
+ const max_file_end = self.symtab_cmd.stroff + self.symtab_cmd.strsize;
+
+ const FileSubsection = struct {
+ start: u32,
+ end: u32,
+ };
var subsections: [5]FileSubsection = undefined;
var count: usize = 0;
@@ -2743,7 +2748,7 @@ pub const Zld = struct {
@as(u32, @sizeOf(macho.symtab_command) + @sizeOf(macho.dysymtab_command))
else
@sizeOf(macho.linkedit_data_command),
- .end = max_file_size,
+ .end = max_file_end,
};
count += 1;
} else {
@@ -2773,7 +2778,7 @@ pub const Zld = struct {
@as(u32, @sizeOf(macho.symtab_command) + @sizeOf(macho.dysymtab_command))
else
@sizeOf(macho.linkedit_data_command),
- .end = max_file_size,
+ .end = max_file_end,
};
count += 1;
}
@@ -2816,29 +2821,6 @@ pub const Zld = struct {
out[8] = (out[8] & 0x3F) | 0x80;
}
- const FileSubsection = struct {
- start: u32,
- end: u32,
- };
-
- // fn calcUuidHashes(
- // self: *Zld,
- // comp: *const Compilation,
- // cut: FileSubsection,
- // hashes: *std.ArrayList([Md5.digest_length]u8),
- // ) !void {
- // const chunk_size = 0x4000;
- // const total_hashes = mem.alignForward(cut.end - cut.start, chunk_size) / chunk_size;
- // try hashes.resize(hashes.items.len + total_hashes);
-
- // var hasher = Hasher(Md5){};
- // try hasher.hash(self.gpa, comp.thread_pool, self.file, hashes.items, .{
- // .chunk_size = chunk_size,
- // .file_pos = cut.start,
- // .max_file_size = cut.end - cut.start,
- // });
- // }
-
fn writeCodeSignaturePadding(self: *Zld, code_sig: *CodeSignature) !void {
const seg = self.getLinkeditSegmentPtr();
// Code signature data has to be 16-bytes aligned for Apple tools to recognize the file