| ... | ... | @@ -110,6 +110,8 @@ main_cmd_index: ?u16 = null, |
| 110 | 110 | version_min_cmd_index: ?u16 = null, |
| 111 | 111 | /// Source version |
| 112 | 112 | source_version_cmd_index: ?u16 = null, |
| 113 | /// Code signature |
| 114 | code_signature_cmd_index: ?u16 = null, |
| 113 | 115 | |
| 114 | 116 | /// Table of all sections |
| 115 | 117 | sections: std.ArrayListUnmanaged(macho.section_64) = .{}, |
| ... | ... | @@ -401,6 +403,15 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 401 | 403 | |
| 402 | 404 | // TODO remove when we add our own codesigning mechanism |
| 403 | 405 | try self.writeStringTable(); |
| 406 | try self.codeSign(); |
| 407 | |
| 408 | { |
| 409 | // TODO rework how we preallocate space for the entire __LINKEDIT segment instead of |
| 410 | // doing dynamic updates like this. |
| 411 | const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 412 | const code_sig = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData; |
| 413 | linkedit.filesize = code_sig.dataoff + code_sig.datasize - linkedit.fileoff; |
| 414 | } |
| 404 | 415 | |
| 405 | 416 | if (self.cmd_table_dirty) { |
| 406 | 417 | try self.writeCmdHeaders(); |
| ... | ... | @@ -1413,6 +1424,17 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1413 | 1424 | }, |
| 1414 | 1425 | }); |
| 1415 | 1426 | } |
| 1427 | if (self.code_signature_cmd_index == null) { |
| 1428 | self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 1429 | try self.load_commands.append(self.base.allocator, .{ |
| 1430 | .LinkeditData = .{ |
| 1431 | .cmd = macho.LC_CODE_SIGNATURE, |
| 1432 | .cmdsize = @sizeOf(macho.linkedit_data_command), |
| 1433 | .dataoff = 0, |
| 1434 | .datasize = 0, |
| 1435 | }, |
| 1436 | }); |
| 1437 | } |
| 1416 | 1438 | { |
| 1417 | 1439 | const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1418 | 1440 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo; |
| ... | ... | @@ -1458,6 +1480,17 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1458 | 1480 | linkedit.vmsize += segment_size; |
| 1459 | 1481 | } |
| 1460 | 1482 | } |
| 1483 | { |
| 1484 | const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1485 | const code_sig = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData; |
| 1486 | if (code_sig.dataoff == 0) { |
| 1487 | const file_size = 0x1000; // TODO what is a good guesstimate for initial code signature? |
| 1488 | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); |
| 1489 | log.debug("found code signature free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 1490 | code_sig.dataoff = off; |
| 1491 | code_sig.datasize = file_size; |
| 1492 | } |
| 1493 | } |
| 1461 | 1494 | if (self.dyld_stub_binder_index == null) { |
| 1462 | 1495 | self.dyld_stub_binder_index = @intCast(u16, self.undef_symbols.items.len); |
| 1463 | 1496 | const name = try self.makeString("dyld_stub_binder"); |
| ... | ... | @@ -1722,6 +1755,16 @@ fn writeAllUndefSymbols(self: *MachO) !void { |
| 1722 | 1755 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undef_symbols.items), off); |
| 1723 | 1756 | } |
| 1724 | 1757 | |
| 1758 | fn codeSign(self: *MachO) !void { |
| 1759 | const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData; |
| 1760 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 1761 | const off = mem.alignForwardGeneric(u32, symtab.stroff + symtab.strsize, @sizeOf(u64)); |
| 1762 | symtab.strsize = off - symtab.stroff; |
| 1763 | code_sig_cmd.dataoff = off; |
| 1764 | // TODO add actual code signing mechanism |
| 1765 | try self.base.file.?.pwriteAll(&[_]u8{ 0 }, code_sig_cmd.dataoff + code_sig_cmd.datasize - 1); |
| 1766 | } |
| 1767 | |
| 1725 | 1768 | fn writeExportTrie(self: *MachO) !void { |
| 1726 | 1769 | if (self.global_symbols.items.len == 0) return; // No exports, nothing to do. |
| 1727 | 1770 | |
| ... | ... | @@ -1763,11 +1806,6 @@ fn writeStringTable(self: *MachO) !void { |
| 1763 | 1806 | log.debug("writing string table from 0x{x} to 0x{x}\n", .{ symtab.stroff, symtab.stroff + symtab.strsize }); |
| 1764 | 1807 | |
| 1765 | 1808 | try self.base.file.?.pwriteAll(self.string_table.items, symtab.stroff); |
| 1766 | | |
| 1767 | | // TODO rework how we preallocate space for the entire __LINKEDIT segment instead of |
| 1768 | | // doing dynamic updates like this. |
| 1769 | | const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1770 | | linkedit.filesize = symtab.stroff + symtab.strsize - linkedit.fileoff; |
| 1771 | 1809 | } |
| 1772 | 1810 | |
| 1773 | 1811 | fn writeCmdHeaders(self: *MachO) !void { |