authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-01 18:02:12+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-01 18:03:31+01:00
loged180465182fb95424f1c08793b529d5ec577018
tree614b7046ba82a2749370f54ce5d7743a10289ae7
parentabb697e751cb0febf4e5e26f0190c01d7c5fd922

macho: dynamically calculate code signature padding


2 files changed, 11 insertions(+), 3 deletions(-)

src/link/MachO.zig+3-3
...@@ -733,7 +733,8 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -733,7 +733,8 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
733 // Pad out space for code signature733 // Pad out space for code signature
734 const text_cmd = parser.load_commands.items[parser.text_cmd_index.?].Segment.inner;734 const text_cmd = parser.load_commands.items[parser.text_cmd_index.?].Segment.inner;
735 const dataoff = @intCast(u32, mem.alignForward(parser.end_pos.?, @sizeOf(u64)));735 const dataoff = @intCast(u32, mem.alignForward(parser.end_pos.?, @sizeOf(u64)));
736 const datasize = 0x400000;736 const emit = self.base.options.emit.?;
737 const datasize = CodeSignature.calcCodeSignaturePadding(emit.sub_path, dataoff);
737 const code_sig = macho.linkedit_data_command{738 const code_sig = macho.linkedit_data_command{
738 .cmd = macho.LC_CODE_SIGNATURE,739 .cmd = macho.LC_CODE_SIGNATURE,
739 .cmdsize = @sizeOf(macho.linkedit_data_command),740 .cmdsize = @sizeOf(macho.linkedit_data_command),
...@@ -772,7 +773,6 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -772,7 +773,6 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
772 // Generate adhoc code signature773 // Generate adhoc code signature
773 var signature = CodeSignature.init(self.base.allocator);774 var signature = CodeSignature.init(self.base.allocator);
774 defer signature.deinit();775 defer signature.deinit();
775 const emit = self.base.options.emit.?;
776 try signature.calcAdhocSignature(776 try signature.calcAdhocSignature(
777 out_file,777 out_file,
778 emit.sub_path,778 emit.sub_path,
...@@ -1723,7 +1723,7 @@ fn writeSymbolTable(self: *MachO) !void {...@@ -1723,7 +1723,7 @@ fn writeSymbolTable(self: *MachO) !void {
1723fn writeCodeSignaturePadding(self: *MachO) !void {1723fn writeCodeSignaturePadding(self: *MachO) !void {
1724 const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData;1724 const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData;
1725 const fileoff = self.linkedit_segment_next_offset.?;1725 const fileoff = self.linkedit_segment_next_offset.?;
1726 const datasize: u32 = 0x1000; // TODO Calculate the expected size of the signature.1726 const datasize = CodeSignature.calcCodeSignaturePadding(self.base.options.emit.?.sub_path, fileoff);
1727 code_sig_cmd.dataoff = fileoff;1727 code_sig_cmd.dataoff = fileoff;
1728 code_sig_cmd.datasize = datasize;1728 code_sig_cmd.datasize = datasize;
17291729
src/link/MachO/CodeSignature.zig+8
...@@ -179,3 +179,11 @@ test "CodeSignature header" {...@@ -179,3 +179,11 @@ test "CodeSignature header" {
179 const expected = &[_]u8{ 0xfa, 0xde, 0x0c, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0 };179 const expected = &[_]u8{ 0xfa, 0xde, 0x0c, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0 };
180 testing.expect(mem.eql(u8, expected[0..], buffer[0..]));180 testing.expect(mem.eql(u8, expected[0..], buffer[0..]));
181}181}
182
183pub fn calcCodeSignaturePadding(id: []const u8, file_size: u64) u32 {
184 const ident_size = id.len + 1;
185 const total_pages = mem.alignForwardGeneric(u64, file_size, page_size) / page_size;
186 const hashed_size = total_pages * hash_size;
187 const codesig_header = @sizeOf(macho.SuperBlob) + @sizeOf(macho.BlobIndex) + @sizeOf(macho.CodeDirectory);
188 return @intCast(u32, mem.alignForwardGeneric(u64, codesig_header + ident_size + hashed_size, @sizeOf(u64)));
189}