Commit 22540e5402

Jakub Konka <kubkon@jakubkonka.com>
2023-06-19 22:28:03
macho: exclude code signature padding from uuid calculation
1 parent ef9d633
Changed files (3)
src/link/MachO/uuid.zig
@@ -15,9 +15,10 @@ const Hasher = @import("hasher.zig").ParallelHasher;
 /// output files. Should we also do that?
 pub fn calcUuid(comp: *const Compilation, file: fs.File, file_size: u64, out: *[Md5.digest_length]u8) !void {
     const num_chunks = comp.thread_pool.threads.len * 0x10;
-    const chunk_size = @divTrunc(file_size + num_chunks - 1, num_chunks);
+    const chunk_size = @divTrunc(file_size, num_chunks);
+    const actual_num_chunks = if (@rem(file_size, num_chunks) > 0) num_chunks + 1 else num_chunks;
 
-    const hashes = try comp.gpa.alloc([Md5.digest_length]u8, num_chunks);
+    const hashes = try comp.gpa.alloc([Md5.digest_length]u8, actual_num_chunks);
     defer comp.gpa.free(hashes);
 
     var hasher = Hasher(Md5){ .allocator = comp.gpa, .thread_pool = comp.thread_pool };
@@ -26,7 +27,7 @@ pub fn calcUuid(comp: *const Compilation, file: fs.File, file_size: u64, out: *[
         .max_file_size = file_size,
     });
 
-    const final_buffer = try comp.gpa.alloc(u8, num_chunks * Md5.digest_length);
+    const final_buffer = try comp.gpa.alloc(u8, actual_num_chunks * Md5.digest_length);
     defer comp.gpa.free(final_buffer);
 
     for (hashes, 0..) |hash, i| {
src/link/MachO/zld.zig
@@ -2576,9 +2576,11 @@ pub const Zld = struct {
         self.dysymtab_cmd.nindirectsyms = nindirectsyms;
     }
 
-    fn writeUuid(self: *Zld, comp: *const Compilation, uuid_cmd_offset: u32) !void {
-        const seg = self.getLinkeditSegmentPtr();
-        const file_size = seg.fileoff + seg.filesize;
+    fn writeUuid(self: *Zld, comp: *const Compilation, uuid_cmd_offset: u32, has_codesig: bool) !void {
+        const file_size = if (!has_codesig) blk: {
+            const seg = self.getLinkeditSegmentPtr();
+            break :blk seg.fileoff + seg.filesize;
+        } else self.codesig_cmd.dataoff;
         try calcUuid(comp, self.file, file_size, &self.uuid_cmd.uuid);
         const offset = uuid_cmd_offset + @sizeOf(macho.load_command);
         try self.file.pwriteAll(&self.uuid_cmd.uuid, offset);
@@ -3953,7 +3955,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
         const ncmds = load_commands.calcNumOfLCs(lc_buffer.items);
         try zld.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64));
         try zld.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len));
-        try zld.writeUuid(comp, uuid_cmd_offset);
+        try zld.writeUuid(comp, uuid_cmd_offset, requires_codesig);
 
         if (codesig) |*csig| {
             try zld.writeCodeSignature(comp, csig); // code signing always comes last
src/link/MachO.zig
@@ -769,7 +769,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
     const ncmds = load_commands.calcNumOfLCs(lc_buffer.items);
     try self.base.file.?.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64));
     try self.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len));
-    try self.writeUuid(comp, uuid_cmd_offset);
+    try self.writeUuid(comp, uuid_cmd_offset, requires_codesig);
 
     if (codesig) |*csig| {
         try self.writeCodeSignature(comp, csig); // code signing always comes last
@@ -3507,9 +3507,11 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
     self.dysymtab_cmd.nindirectsyms = nindirectsyms;
 }
 
-fn writeUuid(self: *MachO, comp: *const Compilation, uuid_cmd_offset: u32) !void {
-    const seg = self.getLinkeditSegmentPtr();
-    const file_size = seg.fileoff + seg.filesize;
+fn writeUuid(self: *MachO, comp: *const Compilation, uuid_cmd_offset: u32, has_codesig: bool) !void {
+    const file_size = if (!has_codesig) blk: {
+        const seg = self.getLinkeditSegmentPtr();
+        break :blk seg.fileoff + seg.filesize;
+    } else self.codesig_cmd.dataoff;
     try calcUuid(comp, self.base.file.?, file_size, &self.uuid_cmd.uuid);
     const offset = uuid_cmd_offset + @sizeOf(macho.load_command);
     try self.base.file.?.pwriteAll(&self.uuid_cmd.uuid, offset);