mirror of
https://github.com/ziglang/zig.git
synced 2025-12-27 16:43:07 +00:00
link: move macOS kernel inode cache invalidation to MachO linker
This commit is contained in:
parent
e1e414e62a
commit
76afdd0586
21
src/link.zig
21
src/link.zig
@ -418,26 +418,7 @@ pub const File = struct {
|
||||
.Exe => {},
|
||||
}
|
||||
switch (base.tag) {
|
||||
.macho => if (base.file) |f| {
|
||||
if (build_options.only_c) unreachable;
|
||||
if (comptime builtin.target.isDarwin() and builtin.target.cpu.arch == .aarch64) {
|
||||
if (base.options.target.cpu.arch == .aarch64) {
|
||||
// XNU starting with Big Sur running on arm64 is caching inodes of running binaries.
|
||||
// Any change to the binary will effectively invalidate the kernel's cache
|
||||
// resulting in a SIGKILL on each subsequent run. Since when doing incremental
|
||||
// linking we're modifying a binary in-place, this will end up with the kernel
|
||||
// killing it on every subsequent run. To circumvent it, we will copy the file
|
||||
// into a new inode, remove the original file, and rename the copy to match
|
||||
// the original file. This is super messy, but there doesn't seem any other
|
||||
// way to please the XNU.
|
||||
const emit = base.options.emit orelse return;
|
||||
try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, emit.sub_path, .{});
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
base.file = null;
|
||||
},
|
||||
.coff, .elf, .plan9, .wasm => if (base.file) |f| {
|
||||
.coff, .elf, .macho, .plan9, .wasm => if (base.file) |f| {
|
||||
if (build_options.only_c) unreachable;
|
||||
if (base.intermediary_basename != null) {
|
||||
// The file we have open is not the final file that we want to
|
||||
|
||||
@ -662,6 +662,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
|
||||
if (codesig) |*csig| {
|
||||
try self.writeCodeSignature(comp, csig); // code signing always comes last
|
||||
const emit = self.base.options.emit.?;
|
||||
try invalidateKernelCache(emit.directory.handle, emit.sub_path);
|
||||
}
|
||||
|
||||
if (self.d_sym) |*d_sym| {
|
||||
@ -691,6 +693,21 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
|
||||
self.cold_start = false;
|
||||
}
|
||||
|
||||
/// XNU starting with Big Sur running on arm64 is caching inodes of running binaries.
|
||||
/// Any change to the binary will effectively invalidate the kernel's cache
|
||||
/// resulting in a SIGKILL on each subsequent run. Since when doing incremental
|
||||
/// linking we're modifying a binary in-place, this will end up with the kernel
|
||||
/// killing it on every subsequent run. To circumvent it, we will copy the file
|
||||
/// into a new inode, remove the original file, and rename the copy to match
|
||||
/// the original file. This is super messy, but there doesn't seem any other
|
||||
/// way to please the XNU.
|
||||
pub fn invalidateKernelCache(dir: std.fs.Dir, sub_path: []const u8) !void {
|
||||
if (comptime builtin.target.isDarwin() and builtin.target.cpu.arch == .aarch64) {
|
||||
try dir.copyFile(sub_path, dir, sub_path, .{});
|
||||
}
|
||||
}
|
||||
|
||||
inline fn conformUuid(out: *[Md5.digest_length]u8) void {
|
||||
// LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats
|
||||
out[6] = (out[6] & 0x0F) | (3 << 4);
|
||||
|
||||
@ -4172,6 +4172,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
|
||||
|
||||
if (codesig) |*csig| {
|
||||
try zld.writeCodeSignature(comp, csig); // code signing always comes last
|
||||
try MachO.invalidateKernelCache(directory.handle, zld.options.emit.?.sub_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user