authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-30 21:24:49+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-30 21:24:49+02:00
log908ccce064a898d5db1d43dbdc4a3590fd84d4ba
tree528a13922ced3d06e01a9a236eb63746dcc5b4ac
parentee0c4457657523e218c1e211c447d3e196575ddc

coff: enable hot-code swapping on a compatible host only


1 files changed, 31 insertions(+), 20 deletions(-)

src/link/Coff.zig+31-20
...@@ -90,7 +90,12 @@ relocs: RelocTable = .{},...@@ -90,7 +90,12 @@ relocs: RelocTable = .{},
90base_relocs: BaseRelocationTable = .{},90base_relocs: BaseRelocationTable = .{},
9191
92/// Hot-code swapping state.92/// Hot-code swapping state.
93hot_state: HotUpdateState = .{},93hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},
94
95const is_hot_update_compatible = switch (builtin.target.os.tag) {
96 .windows => true,
97 else => false,
98};
9499
95const HotUpdateState = struct {100const HotUpdateState = struct {
96 /// Base address at which the process (image) got loaded.101 /// Base address at which the process (image) got loaded.
...@@ -805,30 +810,32 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void {...@@ -805,30 +810,32 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void {
805 }810 }
806 }811 }
807812
808 if (self.base.child_pid) |handle| {813 if (is_hot_update_compatible) {
809 const slide = @ptrToInt(self.hot_state.loaded_base_address.?);814 if (self.base.child_pid) |handle| {
815 const slide = @ptrToInt(self.hot_state.loaded_base_address.?);
810816
811 const mem_code = try gpa.dupe(u8, code);817 const mem_code = try gpa.dupe(u8, code);
812 defer gpa.free(mem_code);818 defer gpa.free(mem_code);
813 self.resolveRelocs(atom_index, relocs.items, mem_code, slide);819 self.resolveRelocs(atom_index, relocs.items, mem_code, slide);
814820
815 const vaddr = sym.value + slide;821 const vaddr = sym.value + slide;
816 const pvaddr = @intToPtr(*anyopaque, vaddr);822 const pvaddr = @intToPtr(*anyopaque, vaddr);
817823
818 log.debug("writing to memory at address {x}", .{vaddr});824 log.debug("writing to memory at address {x}", .{vaddr});
819825
820 if (build_options.enable_logging) {826 if (build_options.enable_logging) {
821 try debugMem(gpa, handle, pvaddr, mem_code);827 try debugMem(gpa, handle, pvaddr, mem_code);
822 }828 }
823829
824 if (section.header.flags.MEM_WRITE == 0) {830 if (section.header.flags.MEM_WRITE == 0) {
825 writeMemProtected(handle, pvaddr, mem_code) catch |err| {831 writeMemProtected(handle, pvaddr, mem_code) catch |err| {
826 log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)});832 log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)});
827 };833 };
828 } else {834 } else {
829 writeMem(handle, pvaddr, mem_code) catch |err| {835 writeMem(handle, pvaddr, mem_code) catch |err| {
830 log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)});836 log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)});
831 };837 };
838 }
832 }839 }
833 }840 }
834841
...@@ -903,6 +910,8 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, relocs: []*const Relocatio...@@ -903,6 +910,8 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, relocs: []*const Relocatio
903}910}
904911
905pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void {912pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void {
913 if (!is_hot_update_compatible) return;
914
906 log.debug("attaching to process with handle {*}", .{handle});915 log.debug("attaching to process with handle {*}", .{handle});
907 self.hot_state.loaded_base_address = std.os.windows.ProcessBaseAddress(handle) catch |err| {916 self.hot_state.loaded_base_address = std.os.windows.ProcessBaseAddress(handle) catch |err| {
908 log.warn("failed to get base address for the process with error: {s}", .{@errorName(err)});917 log.warn("failed to get base address for the process with error: {s}", .{@errorName(err)});
...@@ -911,6 +920,8 @@ pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void {...@@ -911,6 +920,8 @@ pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void {
911}920}
912921
913pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void {922pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void {
923 if (!is_hot_update_compatible) return;
924
914 log.debug("detaching from process with handle {*}", .{handle});925 log.debug("detaching from process with handle {*}", .{handle});
915 self.hot_state.loaded_base_address = null;926 self.hot_state.loaded_base_address = null;
916}927}