From 68680bbd00ae43cd25d8c613d666bd1554d67131 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Sat, 19 Sep 2026 17:06:14 -0400 Subject: [PATCH] link: fix not calling `makeWritable` for dynamic libs during updates --- src/Compilation.zig | 5 +++-- src/link.zig | 22 ++++++++++++++-------- src/main.zig | 10 ++-------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index d94b7146b59afed2774f83d89b63604794a1ddbd..e7da1d5a790a8ac1c6a5e3f8edaab6341b7b77aa 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3528,7 +3528,7 @@ fn emitFromCObject( /// Having the file open for writing is problematic as far as executing the /// binary is concerned. This will remove the write flag, or close the file, /// or whatever is needed so that it can be executed. -/// After this, one must call` makeFileWritable` before calling `update`. +/// After this, one must call `makeFileWritable` before calling `update`. pub fn makeBinFileExecutable(comp: *Compilation) !void { if (!dev.env.supports(.make_executable)) return; const lf = comp.bin_file orelse return; @@ -3537,7 +3537,8 @@ pub fn makeBinFileExecutable(comp: *Compilation) !void { pub fn makeBinFileWritable(comp: *Compilation) !void { const lf = comp.bin_file orelse return; - return lf.makeWritable(); + if (lf.canMakeExecutable()) + try lf.makeWritable(); } const Header = extern struct { diff --git a/src/link.zig b/src/link.zig index 0096023099d00dcdd59e42a4e3e1cae12e777e47..8dc5988ee05b247bede01e8e303d1ae9429a9e2c 100644 --- a/src/link.zig +++ b/src/link.zig @@ -689,18 +689,24 @@ pub const File = struct { return macho.reopenDebugInfo(); } + pub fn canMakeExecutable(base: *File) bool { + const comp = base.comp; + return switch (comp.config.output_mode) { + .Obj => false, + .Lib => switch (comp.config.link_mode) { + .static => false, + .dynamic => true, + }, + .Exe => true, + }; + } + pub fn makeExecutable(base: *File) !void { dev.check(.make_executable); const comp = base.comp; const io = comp.io; - switch (comp.config.output_mode) { - .Obj => return, - .Lib => switch (comp.config.link_mode) { - .static => return, - .dynamic => {}, - }, - .Exe => {}, - } + if (!base.canMakeExecutable()) + return; switch (base.tag) { .lld => assert(base.file == null), .elf => if (base.file) |f| { diff --git a/src/main.zig b/src/main.zig index 41b4e841d36f4bfe598cb23fd300d6ffe248b0f8..5323ea936fa88c1a611ef02d69f5855495e92b73 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4440,12 +4440,8 @@ fn serve( continue; } - if (comp.config.output_mode == .Exe) { - try comp.makeBinFileWritable(); - } - + try comp.makeBinFileWritable(); try comp.update(main_progress_node); - try comp.makeBinFileExecutable(); try serveUpdateResults(&server, comp); }, @@ -4476,9 +4472,7 @@ fn serve( try comp.hotCodeSwap(main_progress_node, pid); try serveUpdateResults(&server, comp); } else { - if (comp.config.output_mode == .Exe) { - try comp.makeBinFileWritable(); - } + try comp.makeBinFileWritable(); try comp.update(main_progress_node); try comp.makeBinFileExecutable(); try serveUpdateResults(&server, comp); -- 2.54.0