| ... | ... | @@ -725,43 +725,46 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { |
| 725 | 725 | |
| 726 | 726 | // At this stage, LLD has done its job. It is time to patch the resultant |
| 727 | 727 | // binaries up! |
| 728 | | const out_file = try directory.handle.openFile(self.base.options.emit.?.sub_path, .{ .write = true }); |
| 729 | | try self.parseFromFile(out_file); |
| 730 | | if (self.code_signature_cmd_index == null) { |
| 731 | | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 732 | | const text_section = text_segment.sections.items[self.text_section_index.?]; |
| 733 | | const after_last_cmd_offset = self.header.?.sizeofcmds + @sizeOf(macho.mach_header_64); |
| 734 | | const needed_size = @sizeOf(macho.linkedit_data_command); |
| 735 | | if (needed_size + after_last_cmd_offset > text_section.offset) { |
| 736 | | // TODO We are in the position to be able to increase the padding by moving all sections |
| 737 | | // by the required offset, but this requires a little bit more thinking and bookkeeping. |
| 738 | | // For now, return an error informing the user of the problem. |
| 739 | | std.log.err("Not enough padding between load commands and start of __text section:\n", .{}); |
| 740 | | std.log.err("Offset after last load command: 0x{x}\n", .{after_last_cmd_offset}); |
| 741 | | std.log.err("Beginning of __text section: 0x{x}\n", .{text_section.offset}); |
| 742 | | std.log.err("Needed size: 0x{x}\n", .{needed_size}); |
| 743 | | return error.NotEnoughPadding; |
| 728 | // This is currently needed only for aarch64 targets. |
| 729 | if (target.cpu.arch == .aarch64) { |
| 730 | const out_file = try directory.handle.openFile(self.base.options.emit.?.sub_path, .{ .write = true }); |
| 731 | try self.parseFromFile(out_file); |
| 732 | if (self.code_signature_cmd_index == null) { |
| 733 | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 734 | const text_section = text_segment.sections.items[self.text_section_index.?]; |
| 735 | const after_last_cmd_offset = self.header.?.sizeofcmds + @sizeOf(macho.mach_header_64); |
| 736 | const needed_size = @sizeOf(macho.linkedit_data_command); |
| 737 | if (needed_size + after_last_cmd_offset > text_section.offset) { |
| 738 | // TODO We are in the position to be able to increase the padding by moving all sections |
| 739 | // by the required offset, but this requires a little bit more thinking and bookkeeping. |
| 740 | // For now, return an error informing the user of the problem. |
| 741 | std.log.err("Not enough padding between load commands and start of __text section:\n", .{}); |
| 742 | std.log.err("Offset after last load command: 0x{x}\n", .{after_last_cmd_offset}); |
| 743 | std.log.err("Beginning of __text section: 0x{x}\n", .{text_section.offset}); |
| 744 | std.log.err("Needed size: 0x{x}\n", .{needed_size}); |
| 745 | return error.NotEnoughPadding; |
| 746 | } |
| 747 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 748 | // TODO This is clunky. |
| 749 | self.linkedit_segment_next_offset = @intCast(u32, mem.alignForwardGeneric(u64, linkedit_segment.inner.fileoff + linkedit_segment.inner.filesize, @sizeOf(u64))); |
| 750 | // Add code signature load command |
| 751 | self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 752 | try self.load_commands.append(self.base.allocator, .{ |
| 753 | .LinkeditData = .{ |
| 754 | .cmd = macho.LC_CODE_SIGNATURE, |
| 755 | .cmdsize = @sizeOf(macho.linkedit_data_command), |
| 756 | .dataoff = 0, |
| 757 | .datasize = 0, |
| 758 | }, |
| 759 | }); |
| 760 | // Pad out space for code signature |
| 761 | try self.writeCodeSignaturePadding(); |
| 762 | // Write updated load commands and the header |
| 763 | try self.writeLoadCommands(); |
| 764 | try self.writeHeader(); |
| 765 | // Generate adhoc code signature |
| 766 | try self.writeCodeSignature(); |
| 744 | 767 | } |
| 745 | | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 746 | | // TODO This is clunky. |
| 747 | | self.linkedit_segment_next_offset = @intCast(u32, mem.alignForwardGeneric(u64, linkedit_segment.inner.fileoff + linkedit_segment.inner.filesize, @sizeOf(u64))); |
| 748 | | // Add code signature load command |
| 749 | | self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 750 | | try self.load_commands.append(self.base.allocator, .{ |
| 751 | | .LinkeditData = .{ |
| 752 | | .cmd = macho.LC_CODE_SIGNATURE, |
| 753 | | .cmdsize = @sizeOf(macho.linkedit_data_command), |
| 754 | | .dataoff = 0, |
| 755 | | .datasize = 0, |
| 756 | | }, |
| 757 | | }); |
| 758 | | // Pad out space for code signature |
| 759 | | try self.writeCodeSignaturePadding(); |
| 760 | | // Write updated load commands and the header |
| 761 | | try self.writeLoadCommands(); |
| 762 | | try self.writeHeader(); |
| 763 | | // Generate adhoc code signature |
| 764 | | try self.writeCodeSignature(); |
| 765 | 768 | } |
| 766 | 769 | } |
| 767 | 770 | } |