| author | |
| committer | |
| log | 550ebcce9abe9db9453509b38820756a1fff8391 |
| tree | 41398a47cd5ea6a95f4bd4abdc5f0708b16ba525 |
| parent | 4aa8462cc936820bc2c81ea1f3cfc613ff07a9f7 |
Otherwise, we were prematurely committing `__LINKEDIT` segment LC
with outdated size (i.e., without code signature being taken into account).
This would scaffold into strict validation failures by Apple tooling.2 files changed, 47 insertions(+), 41 deletions(-)
src/link/MachO.zig+24-21| ... | ... | @@ -558,6 +558,28 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 558 | 558 | |
| 559 | 559 | try self.writeLinkeditSegmentData(); |
| 560 | 560 | |
| 561 | const target = self.base.options.target; | |
| 562 | const requires_codesig = blk: { | |
| 563 | if (self.base.options.entitlements) |_| break :blk true; | |
| 564 | if (target.cpu.arch == .aarch64 and (target.os.tag == .macos or target.abi == .simulator)) | |
| 565 | break :blk true; | |
| 566 | break :blk false; | |
| 567 | }; | |
| 568 | var codesig: ?CodeSignature = if (requires_codesig) blk: { | |
| 569 | // Preallocate space for the code signature. | |
| 570 | // We need to do this at this stage so that we have the load commands with proper values | |
| 571 | // written out to the file. | |
| 572 | // The most important here is to have the correct vm and filesize of the __LINKEDIT segment | |
| 573 | // where the code signature goes into. | |
| 574 | var codesig = CodeSignature.init(self.page_size); | |
| 575 | codesig.code_directory.ident = self.base.options.emit.?.sub_path; | |
| 576 | if (self.base.options.entitlements) |path| { | |
| 577 | try codesig.addEntitlements(arena, path); | |
| 578 | } | |
| 579 | try self.writeCodeSignaturePadding(&codesig); | |
| 580 | break :blk codesig; | |
| 581 | } else null; | |
| 582 | ||
| 561 | 583 | // Write load commands |
| 562 | 584 | var lc_buffer = std.ArrayList(u8).init(arena); |
| 563 | 585 | const lc_writer = lc_buffer.writer(); |
| ... | ... | @@ -606,28 +628,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 606 | 628 | |
| 607 | 629 | try load_commands.writeLoadDylibLCs(self.dylibs.items, self.referenced_dylibs.keys(), lc_writer); |
| 608 | 630 | |
| 609 | const target = self.base.options.target; | |
| 610 | const requires_codesig = blk: { | |
| 611 | if (self.base.options.entitlements) |_| break :blk true; | |
| 612 | if (target.cpu.arch == .aarch64 and (target.os.tag == .macos or target.abi == .simulator)) | |
| 613 | break :blk true; | |
| 614 | break :blk false; | |
| 615 | }; | |
| 616 | var codesig: ?CodeSignature = if (requires_codesig) blk: { | |
| 617 | // Preallocate space for the code signature. | |
| 618 | // We need to do this at this stage so that we have the load commands with proper values | |
| 619 | // written out to the file. | |
| 620 | // The most important here is to have the correct vm and filesize of the __LINKEDIT segment | |
| 621 | // where the code signature goes into. | |
| 622 | var codesig = CodeSignature.init(self.page_size); | |
| 623 | codesig.code_directory.ident = self.base.options.emit.?.sub_path; | |
| 624 | if (self.base.options.entitlements) |path| { | |
| 625 | try codesig.addEntitlements(arena, path); | |
| 626 | } | |
| 627 | try self.writeCodeSignaturePadding(&codesig); | |
| 631 | if (requires_codesig) { | |
| 628 | 632 | try lc_writer.writeStruct(self.codesig_cmd); |
| 629 | break :blk codesig; | |
| 630 | } else null; | |
| 633 | } | |
| 631 | 634 | |
| 632 | 635 | try self.base.file.?.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64)); |
| 633 | 636 |
src/link/MachO/zld.zig+23-20| ... | ... | @@ -4100,6 +4100,27 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 4100 | 4100 | } |
| 4101 | 4101 | } |
| 4102 | 4102 | |
| 4103 | // Write code signature padding if required | |
| 4104 | const requires_codesig = blk: { | |
| 4105 | if (options.entitlements) |_| break :blk true; | |
| 4106 | if (cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator)) break :blk true; | |
| 4107 | break :blk false; | |
| 4108 | }; | |
| 4109 | var codesig: ?CodeSignature = if (requires_codesig) blk: { | |
| 4110 | // Preallocate space for the code signature. | |
| 4111 | // We need to do this at this stage so that we have the load commands with proper values | |
| 4112 | // written out to the file. | |
| 4113 | // The most important here is to have the correct vm and filesize of the __LINKEDIT segment | |
| 4114 | // where the code signature goes into. | |
| 4115 | var codesig = CodeSignature.init(page_size); | |
| 4116 | codesig.code_directory.ident = fs.path.basename(full_out_path); | |
| 4117 | if (options.entitlements) |path| { | |
| 4118 | try codesig.addEntitlements(arena, path); | |
| 4119 | } | |
| 4120 | try zld.writeCodeSignaturePadding(&codesig); | |
| 4121 | break :blk codesig; | |
| 4122 | } else null; | |
| 4123 | ||
| 4103 | 4124 | // Write load commands |
| 4104 | 4125 | var lc_buffer = std.ArrayList(u8).init(arena); |
| 4105 | 4126 | const lc_writer = lc_buffer.writer(); |
| ... | ... | @@ -4142,29 +4163,11 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 4142 | 4163 | |
| 4143 | 4164 | try load_commands.writeLoadDylibLCs(zld.dylibs.items, zld.referenced_dylibs.keys(), lc_writer); |
| 4144 | 4165 | |
| 4145 | const requires_codesig = blk: { | |
| 4146 | if (options.entitlements) |_| break :blk true; | |
| 4147 | if (cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator)) break :blk true; | |
| 4148 | break :blk false; | |
| 4149 | }; | |
| 4150 | 4166 | var codesig_cmd_offset: ?u32 = null; |
| 4151 | var codesig: ?CodeSignature = if (requires_codesig) blk: { | |
| 4152 | // Preallocate space for the code signature. | |
| 4153 | // We need to do this at this stage so that we have the load commands with proper values | |
| 4154 | // written out to the file. | |
| 4155 | // The most important here is to have the correct vm and filesize of the __LINKEDIT segment | |
| 4156 | // where the code signature goes into. | |
| 4157 | var codesig = CodeSignature.init(page_size); | |
| 4158 | codesig.code_directory.ident = fs.path.basename(full_out_path); | |
| 4159 | if (options.entitlements) |path| { | |
| 4160 | try codesig.addEntitlements(gpa, path); | |
| 4161 | } | |
| 4162 | try zld.writeCodeSignaturePadding(&codesig); | |
| 4167 | if (requires_codesig) { | |
| 4163 | 4168 | codesig_cmd_offset = @sizeOf(macho.mach_header_64) + @intCast(u32, lc_buffer.items.len); |
| 4164 | 4169 | try lc_writer.writeStruct(zld.codesig_cmd); |
| 4165 | break :blk codesig; | |
| 4166 | } else null; | |
| 4167 | defer if (codesig) |*csig| csig.deinit(gpa); | |
| 4170 | } | |
| 4168 | 4171 | |
| 4169 | 4172 | const ncmds = load_commands.calcNumOfLCs(lc_buffer.items); |
| 4170 | 4173 | try zld.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64)); |