| ... | @@ -807,33 +807,53 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { | ... | @@ -807,33 +807,53 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { |
| 807 | // binaries up! | 807 | // binaries up! |
| 808 | var parser = Parser.init(self.base.allocator); | 808 | var parser = Parser.init(self.base.allocator); |
| 809 | defer parser.deinit(); | 809 | defer parser.deinit(); |
| 810 | const out_file = try directory.handle.openFile(full_out_path, .{}); | 810 | const out_file = try directory.handle.openFile(full_out_path, .{ .write = true }); |
| | 811 | defer out_file.close(); |
| 811 | try parser.parseFile(out_file); | 812 | try parser.parseFile(out_file); |
| 812 | out_file.close(); | | |
| 813 | var end_pos: ?usize = null; | | |
| 814 | var text_fileoff: ?usize = null; | | |
| 815 | var text_filesize: ?usize = null; | | |
| 816 | for (parser.load_commands.items) |cmd| { | | |
| 817 | switch (cmd.cmd()) { | | |
| 818 | macho.LC_SYMTAB => switch (cmd) { | | |
| 819 | .Symtab => |x| { | | |
| 820 | end_pos = x.stroff + x.strsize; | | |
| 821 | }, | | |
| 822 | else => unreachable, | | |
| 823 | }, | | |
| 824 | macho.LC_SEGMENT_64 => switch (cmd) { | | |
| 825 | .Segment => |x| { | | |
| 826 | if (!mem.eql(u8, x.inner.segname[0..6], "__TEXT")) continue; | | |
| 827 | text_fileoff = x.inner.fileoff; | | |
| 828 | text_filesize = x.inner.filesize; | | |
| 829 | }, | | |
| 830 | else => unreachable, | | |
| 831 | }, | | |
| 832 | else => {}, | | |
| 833 | } | | |
| 834 | } | | |
| 835 | // Pad out space for code signature | 813 | // Pad out space for code signature |
| 836 | std.debug.print("end_pos={},text_fileoff={},text_filesize={}\n", .{ end_pos, text_fileoff, text_filesize }); | 814 | const text_cmd = parser.load_commands.items[parser.text_cmd_index.?].Segment.inner; |
| | 815 | std.debug.print("end_pos={},text_fileoff={},text_filesize={}\n", .{ |
| | 816 | parser.end_pos, |
| | 817 | text_cmd.fileoff, |
| | 818 | text_cmd.filesize, |
| | 819 | }); |
| | 820 | const dataoff = @intCast(u32, mem.alignForward(parser.end_pos.?, @sizeOf(u64))); |
| | 821 | const code_sig = macho.linkedit_data_command{ |
| | 822 | .cmd = macho.LC_CODE_SIGNATURE, |
| | 823 | .cmdsize = @sizeOf(macho.linkedit_data_command), |
| | 824 | .dataoff = dataoff, |
| | 825 | .datasize = 0x1000, |
| | 826 | }; |
| | 827 | |
| | 828 | const linkedit_seg = parser.load_commands.items[parser.linkedit_cmd_index.?].Segment.inner; |
| | 829 | const linkedit = macho.segment_command_64{ |
| | 830 | .cmd = linkedit_seg.cmd, |
| | 831 | .cmdsize = linkedit_seg.cmdsize, |
| | 832 | .segname = linkedit_seg.segname, |
| | 833 | .vmaddr = linkedit_seg.vmaddr, |
| | 834 | .vmsize = mem.alignForwardGeneric(u64, linkedit_seg.vmsize + 0x1000, self.page_size), |
| | 835 | .fileoff = linkedit_seg.fileoff, |
| | 836 | .filesize = linkedit_seg.filesize + (dataoff - parser.end_pos.?) + 0x1000, |
| | 837 | .maxprot = linkedit_seg.maxprot, |
| | 838 | .initprot = linkedit_seg.initprot, |
| | 839 | .nsects = linkedit_seg.nsects, |
| | 840 | .flags = linkedit_seg.flags, |
| | 841 | }; |
| | 842 | const header_cmd = parser.header.?; |
| | 843 | const header = macho.mach_header_64{ |
| | 844 | .magic = header_cmd.magic, |
| | 845 | .cputype = header_cmd.cputype, |
| | 846 | .cpusubtype = header_cmd.cpusubtype, |
| | 847 | .filetype = header_cmd.filetype, |
| | 848 | .ncmds = header_cmd.ncmds + 1, |
| | 849 | .sizeofcmds = header_cmd.sizeofcmds + @sizeOf(macho.linkedit_data_command), |
| | 850 | .flags = header_cmd.flags, |
| | 851 | .reserved = header_cmd.reserved, |
| | 852 | }; |
| | 853 | try out_file.pwriteAll(&[_]u8{0}, code_sig.dataoff + code_sig.datasize); |
| | 854 | try out_file.pwriteAll(mem.sliceAsBytes(&[_]macho.linkedit_data_command{code_sig}), parser.code_sig_cmd_offset.?); |
| | 855 | try out_file.pwriteAll(mem.sliceAsBytes(&[_]macho.segment_command_64{linkedit}), parser.linkedit_cmd_offset.?); |
| | 856 | try out_file.pwriteAll(mem.sliceAsBytes(&[_]macho.mach_header_64{header}), 0); |
| 837 | } | 857 | } |
| 838 | } | 858 | } |
| 839 | | 859 | |