mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 00:08:56 +00:00
macho+zld: write code signature padding before commiting LCs
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.
This commit is contained in:
parent
4aa8462cc9
commit
550ebcce9a
@ -558,6 +558,28 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
|
||||
try self.writeLinkeditSegmentData();
|
||||
|
||||
const target = self.base.options.target;
|
||||
const requires_codesig = blk: {
|
||||
if (self.base.options.entitlements) |_| break :blk true;
|
||||
if (target.cpu.arch == .aarch64 and (target.os.tag == .macos or target.abi == .simulator))
|
||||
break :blk true;
|
||||
break :blk false;
|
||||
};
|
||||
var codesig: ?CodeSignature = if (requires_codesig) blk: {
|
||||
// Preallocate space for the code signature.
|
||||
// We need to do this at this stage so that we have the load commands with proper values
|
||||
// written out to the file.
|
||||
// The most important here is to have the correct vm and filesize of the __LINKEDIT segment
|
||||
// where the code signature goes into.
|
||||
var codesig = CodeSignature.init(self.page_size);
|
||||
codesig.code_directory.ident = self.base.options.emit.?.sub_path;
|
||||
if (self.base.options.entitlements) |path| {
|
||||
try codesig.addEntitlements(arena, path);
|
||||
}
|
||||
try self.writeCodeSignaturePadding(&codesig);
|
||||
break :blk codesig;
|
||||
} else null;
|
||||
|
||||
// Write load commands
|
||||
var lc_buffer = std.ArrayList(u8).init(arena);
|
||||
const lc_writer = lc_buffer.writer();
|
||||
@ -606,28 +628,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
|
||||
try load_commands.writeLoadDylibLCs(self.dylibs.items, self.referenced_dylibs.keys(), lc_writer);
|
||||
|
||||
const target = self.base.options.target;
|
||||
const requires_codesig = blk: {
|
||||
if (self.base.options.entitlements) |_| break :blk true;
|
||||
if (target.cpu.arch == .aarch64 and (target.os.tag == .macos or target.abi == .simulator))
|
||||
break :blk true;
|
||||
break :blk false;
|
||||
};
|
||||
var codesig: ?CodeSignature = if (requires_codesig) blk: {
|
||||
// Preallocate space for the code signature.
|
||||
// We need to do this at this stage so that we have the load commands with proper values
|
||||
// written out to the file.
|
||||
// The most important here is to have the correct vm and filesize of the __LINKEDIT segment
|
||||
// where the code signature goes into.
|
||||
var codesig = CodeSignature.init(self.page_size);
|
||||
codesig.code_directory.ident = self.base.options.emit.?.sub_path;
|
||||
if (self.base.options.entitlements) |path| {
|
||||
try codesig.addEntitlements(arena, path);
|
||||
}
|
||||
try self.writeCodeSignaturePadding(&codesig);
|
||||
if (requires_codesig) {
|
||||
try lc_writer.writeStruct(self.codesig_cmd);
|
||||
break :blk codesig;
|
||||
} else null;
|
||||
}
|
||||
|
||||
try self.base.file.?.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64));
|
||||
|
||||
|
||||
@ -4100,6 +4100,27 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
|
||||
}
|
||||
}
|
||||
|
||||
// Write code signature padding if required
|
||||
const requires_codesig = blk: {
|
||||
if (options.entitlements) |_| break :blk true;
|
||||
if (cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator)) break :blk true;
|
||||
break :blk false;
|
||||
};
|
||||
var codesig: ?CodeSignature = if (requires_codesig) blk: {
|
||||
// Preallocate space for the code signature.
|
||||
// We need to do this at this stage so that we have the load commands with proper values
|
||||
// written out to the file.
|
||||
// The most important here is to have the correct vm and filesize of the __LINKEDIT segment
|
||||
// where the code signature goes into.
|
||||
var codesig = CodeSignature.init(page_size);
|
||||
codesig.code_directory.ident = fs.path.basename(full_out_path);
|
||||
if (options.entitlements) |path| {
|
||||
try codesig.addEntitlements(arena, path);
|
||||
}
|
||||
try zld.writeCodeSignaturePadding(&codesig);
|
||||
break :blk codesig;
|
||||
} else null;
|
||||
|
||||
// Write load commands
|
||||
var lc_buffer = std.ArrayList(u8).init(arena);
|
||||
const lc_writer = lc_buffer.writer();
|
||||
@ -4142,29 +4163,11 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
|
||||
|
||||
try load_commands.writeLoadDylibLCs(zld.dylibs.items, zld.referenced_dylibs.keys(), lc_writer);
|
||||
|
||||
const requires_codesig = blk: {
|
||||
if (options.entitlements) |_| break :blk true;
|
||||
if (cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator)) break :blk true;
|
||||
break :blk false;
|
||||
};
|
||||
var codesig_cmd_offset: ?u32 = null;
|
||||
var codesig: ?CodeSignature = if (requires_codesig) blk: {
|
||||
// Preallocate space for the code signature.
|
||||
// We need to do this at this stage so that we have the load commands with proper values
|
||||
// written out to the file.
|
||||
// The most important here is to have the correct vm and filesize of the __LINKEDIT segment
|
||||
// where the code signature goes into.
|
||||
var codesig = CodeSignature.init(page_size);
|
||||
codesig.code_directory.ident = fs.path.basename(full_out_path);
|
||||
if (options.entitlements) |path| {
|
||||
try codesig.addEntitlements(gpa, path);
|
||||
}
|
||||
try zld.writeCodeSignaturePadding(&codesig);
|
||||
if (requires_codesig) {
|
||||
codesig_cmd_offset = @sizeOf(macho.mach_header_64) + @intCast(u32, lc_buffer.items.len);
|
||||
try lc_writer.writeStruct(zld.codesig_cmd);
|
||||
break :blk codesig;
|
||||
} else null;
|
||||
defer if (codesig) |*csig| csig.deinit(gpa);
|
||||
}
|
||||
|
||||
const ncmds = load_commands.calcNumOfLCs(lc_buffer.items);
|
||||
try zld.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user