authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2026-09-19 17:06:14-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2026-09-19 17:06:14-04:00
log68680bbd00ae43cd25d8c613d666bd1554d67131
tree7c94918b36dd64ddc974e2bad0f9103f5d226945
parent5dab6a4533dbb5222be5b6309eea25115659bacf

link: fix not calling `makeWritable` for dynamic libs during updates


3 files changed, 19 insertions(+), 18 deletions(-)

src/Compilation.zig+3-2
......@@ -3528,7 +3528,7 @@ fn emitFromCObject(
35283528/// Having the file open for writing is problematic as far as executing the
35293529/// binary is concerned. This will remove the write flag, or close the file,
35303530/// or whatever is needed so that it can be executed.
3531/// After this, one must call` makeFileWritable` before calling `update`.
3531/// After this, one must call `makeFileWritable` before calling `update`.
35323532pub fn makeBinFileExecutable(comp: *Compilation) !void {
35333533 if (!dev.env.supports(.make_executable)) return;
35343534 const lf = comp.bin_file orelse return;
......@@ -3537,7 +3537,8 @@ pub fn makeBinFileExecutable(comp: *Compilation) !void {
35373537
35383538pub fn makeBinFileWritable(comp: *Compilation) !void {
35393539 const lf = comp.bin_file orelse return;
3540 return lf.makeWritable();
3540 if (lf.canMakeExecutable())
3541 try lf.makeWritable();
35413542}
35423543
35433544const Header = extern struct {
src/link.zig+14-8
......@@ -689,18 +689,24 @@ pub const File = struct {
689689 return macho.reopenDebugInfo();
690690 }
691691
692 pub fn canMakeExecutable(base: *File) bool {
693 const comp = base.comp;
694 return switch (comp.config.output_mode) {
695 .Obj => false,
696 .Lib => switch (comp.config.link_mode) {
697 .static => false,
698 .dynamic => true,
699 },
700 .Exe => true,
701 };
702 }
703
692704 pub fn makeExecutable(base: *File) !void {
693705 dev.check(.make_executable);
694706 const comp = base.comp;
695707 const io = comp.io;
696 switch (comp.config.output_mode) {
697 .Obj => return,
698 .Lib => switch (comp.config.link_mode) {
699 .static => return,
700 .dynamic => {},
701 },
702 .Exe => {},
703 }
708 if (!base.canMakeExecutable())
709 return;
704710 switch (base.tag) {
705711 .lld => assert(base.file == null),
706712 .elf => if (base.file) |f| {
src/main.zig+2-8
......@@ -4440,12 +4440,8 @@ fn serve(
44404440 continue;
44414441 }
44424442
4443 if (comp.config.output_mode == .Exe) {
4444 try comp.makeBinFileWritable();
4445 }
4446
4443 try comp.makeBinFileWritable();
44474444 try comp.update(main_progress_node);
4448
44494445 try comp.makeBinFileExecutable();
44504446 try serveUpdateResults(&server, comp);
44514447 },
......@@ -4476,9 +4472,7 @@ fn serve(
44764472 try comp.hotCodeSwap(main_progress_node, pid);
44774473 try serveUpdateResults(&server, comp);
44784474 } else {
4479 if (comp.config.output_mode == .Exe) {
4480 try comp.makeBinFileWritable();
4481 }
4475 try comp.makeBinFileWritable();
44824476 try comp.update(main_progress_node);
44834477 try comp.makeBinFileExecutable();
44844478 try serveUpdateResults(&server, comp);