From ed180465182fb95424f1c08793b529d5ec577018 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 1 Dec 2020 18:02:12 +0100 Subject: [PATCH] macho: dynamically calculate code signature padding --- src/link/MachO.zig | 6 +++--- src/link/MachO/CodeSignature.zig | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 921c49763d..cbc63b10eb 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -733,7 +733,8 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { // Pad out space for code signature const text_cmd = parser.load_commands.items[parser.text_cmd_index.?].Segment.inner; const dataoff = @intCast(u32, mem.alignForward(parser.end_pos.?, @sizeOf(u64))); - const datasize = 0x400000; + const emit = self.base.options.emit.?; + const datasize = CodeSignature.calcCodeSignaturePadding(emit.sub_path, dataoff); const code_sig = macho.linkedit_data_command{ .cmd = macho.LC_CODE_SIGNATURE, .cmdsize = @sizeOf(macho.linkedit_data_command), @@ -772,7 +773,6 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { // Generate adhoc code signature var signature = CodeSignature.init(self.base.allocator); defer signature.deinit(); - const emit = self.base.options.emit.?; try signature.calcAdhocSignature( out_file, emit.sub_path, @@ -1723,7 +1723,7 @@ fn writeSymbolTable(self: *MachO) !void { fn writeCodeSignaturePadding(self: *MachO) !void { const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData; const fileoff = self.linkedit_segment_next_offset.?; - const datasize: u32 = 0x1000; // TODO Calculate the expected size of the signature. + const datasize = CodeSignature.calcCodeSignaturePadding(self.base.options.emit.?.sub_path, fileoff); code_sig_cmd.dataoff = fileoff; code_sig_cmd.datasize = datasize; diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig index c7cfdfcb44..442132dac1 100644 --- a/src/link/MachO/CodeSignature.zig +++ b/src/link/MachO/CodeSignature.zig @@ -179,3 +179,11 @@ test "CodeSignature header" { const expected = &[_]u8{ 0xfa, 0xde, 0x0c, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0 }; testing.expect(mem.eql(u8, expected[0..], buffer[0..])); } + +pub fn calcCodeSignaturePadding(id: []const u8, file_size: u64) u32 { + const ident_size = id.len + 1; + const total_pages = mem.alignForwardGeneric(u64, file_size, page_size) / page_size; + const hashed_size = total_pages * hash_size; + const codesig_header = @sizeOf(macho.SuperBlob) + @sizeOf(macho.BlobIndex) + @sizeOf(macho.CodeDirectory); + return @intCast(u32, mem.alignForwardGeneric(u64, codesig_header + ident_size + hashed_size, @sizeOf(u64))); +}