| ... | ... | @@ -90,7 +90,12 @@ relocs: RelocTable = .{}, |
| 90 | 90 | base_relocs: BaseRelocationTable = .{}, |
| 91 | 91 | |
| 92 | 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 | 100 | const HotUpdateState = struct { |
| 96 | 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 | 810 | } |
| 806 | 811 | } |
| 807 | 812 | |
| 808 | | if (self.base.child_pid) |handle| { |
| 809 | | const slide = @ptrToInt(self.hot_state.loaded_base_address.?); |
| 813 | if (is_hot_update_compatible) { |
| 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); |
| 812 | | defer gpa.free(mem_code); |
| 813 | | self.resolveRelocs(atom_index, relocs.items, mem_code, slide); |
| 817 | const mem_code = try gpa.dupe(u8, code); |
| 818 | defer gpa.free(mem_code); |
| 819 | self.resolveRelocs(atom_index, relocs.items, mem_code, slide); |
| 814 | 820 | |
| 815 | | const vaddr = sym.value + slide; |
| 816 | | const pvaddr = @intToPtr(*anyopaque, vaddr); |
| 821 | const vaddr = sym.value + slide; |
| 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) { |
| 821 | | try debugMem(gpa, handle, pvaddr, mem_code); |
| 822 | | } |
| 826 | if (build_options.enable_logging) { |
| 827 | try debugMem(gpa, handle, pvaddr, mem_code); |
| 828 | } |
| 823 | 829 | |
| 824 | | if (section.header.flags.MEM_WRITE == 0) { |
| 825 | | writeMemProtected(handle, pvaddr, mem_code) catch |err| { |
| 826 | | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); |
| 827 | | }; |
| 828 | | } else { |
| 829 | | writeMem(handle, pvaddr, mem_code) catch |err| { |
| 830 | | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); |
| 831 | | }; |
| 830 | if (section.header.flags.MEM_WRITE == 0) { |
| 831 | writeMemProtected(handle, pvaddr, mem_code) catch |err| { |
| 832 | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); |
| 833 | }; |
| 834 | } else { |
| 835 | writeMem(handle, pvaddr, mem_code) catch |err| { |
| 836 | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); |
| 837 | }; |
| 838 | } |
| 832 | 839 | } |
| 833 | 840 | } |
| 834 | 841 | |
| ... | ... | @@ -903,6 +910,8 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, relocs: []*const Relocatio |
| 903 | 910 | } |
| 904 | 911 | |
| 905 | 912 | pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void { |
| 913 | if (!is_hot_update_compatible) return; |
| 914 | |
| 906 | 915 | log.debug("attaching to process with handle {*}", .{handle}); |
| 907 | 916 | self.hot_state.loaded_base_address = std.os.windows.ProcessBaseAddress(handle) catch |err| { |
| 908 | 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 | 920 | } |
| 912 | 921 | |
| 913 | 922 | pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void { |
| 923 | if (!is_hot_update_compatible) return; |
| 924 | |
| 914 | 925 | log.debug("detaching from process with handle {*}", .{handle}); |
| 915 | 926 | self.hot_state.loaded_base_address = null; |
| 916 | 927 | } |