| ... | @@ -90,7 +90,12 @@ relocs: RelocTable = .{}, | ... | @@ -90,7 +90,12 @@ relocs: RelocTable = .{}, |
| 90 | base_relocs: BaseRelocationTable = .{}, | 90 | base_relocs: BaseRelocationTable = .{}, |
| 91 | | 91 | |
| 92 | /// Hot-code swapping state. | 92 | /// Hot-code swapping state. |
| 93 | hot_state: HotUpdateState = .{}, | 93 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, |
| | 94 | |
| | 95 | const is_hot_update_compatible = switch (builtin.target.os.tag) { |
| | 96 | .windows => true, |
| | 97 | else => false, |
| | 98 | }; |
| 94 | | 99 | |
| 95 | const HotUpdateState = struct { | 100 | const 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 | } |
| 807 | | 812 | |
| 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.?); |
| 810 | | 816 | |
| 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); |
| 814 | | 820 | |
| 815 | const vaddr = sym.value + slide; | 821 | const vaddr = sym.value + slide; |
| 816 | const pvaddr = @intToPtr(*anyopaque, vaddr); | 822 | const pvaddr = @intToPtr(*anyopaque, vaddr); |
| 817 | | 823 | |
| 818 | log.debug("writing to memory at address {x}", .{vaddr}); | 824 | log.debug("writing to memory at address {x}", .{vaddr}); |
| 819 | | 825 | |
| 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 | } |
| 823 | | 829 | |
| 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 | } |
| 834 | | 841 | |
| ... | @@ -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 | } |
| 904 | | 911 | |
| 905 | pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void { | 912 | pub 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 | } |
| 912 | | 921 | |
| 913 | pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void { | 922 | pub 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 | } |