Commit 4f4ddf5ef2
lib/std/os/linux.zig
@@ -1716,26 +1716,26 @@ pub fn pidfd_send_signal(pidfd: fd_t, sig: i32, info: ?*siginfo_t, flags: u32) u
);
}
-pub fn process_vm_readv(pid: pid_t, local: [*]const iovec, local_count: usize, remote: [*]const iovec, remote_count: usize, flags: usize) usize {
+pub fn process_vm_readv(pid: pid_t, local: []iovec, remote: []const iovec_const, flags: usize) usize {
return syscall6(
.process_vm_readv,
@bitCast(usize, @as(isize, pid)),
- @ptrToInt(local),
- local_count,
- @ptrToInt(remote),
- remote_count,
+ @ptrToInt(local.ptr),
+ local.len,
+ @ptrToInt(remote.ptr),
+ remote.len,
flags,
);
}
-pub fn process_vm_writev(pid: pid_t, local: [*]const iovec, local_count: usize, remote: [*]const iovec, remote_count: usize, flags: usize) usize {
+pub fn process_vm_writev(pid: pid_t, local: []const iovec_const, remote: []const iovec_const, flags: usize) usize {
return syscall6(
.process_vm_writev,
@bitCast(usize, @as(isize, pid)),
- @ptrToInt(local),
- local_count,
- @ptrToInt(remote),
- remote_count,
+ @ptrToInt(local.ptr),
+ local.len,
+ @ptrToInt(remote.ptr),
+ remote.len,
flags,
);
}
src/link/Elf.zig
@@ -467,7 +467,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
.p_paddr = entry_addr,
.p_memsz = file_size,
.p_align = p_align,
- .p_flags = elf.PF_X | elf.PF_R,
+ .p_flags = elf.PF_X | elf.PF_R | elf.PF_W,
});
self.entry_addr = null;
self.phdr_table_dirty = true;
@@ -493,7 +493,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
.p_paddr = got_addr,
.p_memsz = file_size,
.p_align = p_align,
- .p_flags = elf.PF_R,
+ .p_flags = elf.PF_R | elf.PF_W,
});
self.phdr_table_dirty = true;
}
@@ -516,7 +516,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
.p_paddr = rodata_addr,
.p_memsz = file_size,
.p_align = p_align,
- .p_flags = elf.PF_R,
+ .p_flags = elf.PF_R | elf.PF_W,
});
self.phdr_table_dirty = true;
}
@@ -2451,6 +2451,23 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
const phdr_index = self.sections.items(.phdr_index)[shdr_index];
const section_offset = local_sym.st_value - self.program_headers.items[phdr_index].p_vaddr;
const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset;
+
+ if (self.base.child_pid) |pid| {
+ var code_vec: [1]std.os.iovec_const = .{.{
+ .iov_base = code.ptr,
+ .iov_len = code.len,
+ }};
+ var remote_vec: [1]std.os.iovec_const = .{.{
+ .iov_base = @intToPtr([*]u8, local_sym.st_value),
+ .iov_len = code.len,
+ }};
+ const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);
+ switch (std.os.errno(rc)) {
+ .SUCCESS => assert(rc == code.len),
+ else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
+ }
+ }
+
try self.base.file.?.pwriteAll(code, file_offset);
return local_sym;
@@ -2820,6 +2837,8 @@ fn writeOffsetTableEntry(self: *Elf, index: usize) !void {
const endian = self.base.options.target.cpu.arch.endian();
const shdr = &self.sections.items(.shdr)[self.got_section_index.?];
const off = shdr.sh_offset + @as(u64, entry_size) * index;
+ const phdr = &self.program_headers.items[self.phdr_got_index.?];
+ const vaddr = phdr.p_vaddr + @as(u64, entry_size) * index;
switch (entry_size) {
2 => {
var buf: [2]u8 = undefined;
@@ -2835,6 +2854,22 @@ fn writeOffsetTableEntry(self: *Elf, index: usize) !void {
var buf: [8]u8 = undefined;
mem.writeInt(u64, &buf, self.offset_table.items[index], endian);
try self.base.file.?.pwriteAll(&buf, off);
+
+ if (self.base.child_pid) |pid| {
+ var local_vec: [1]std.os.iovec_const = .{.{
+ .iov_base = &buf,
+ .iov_len = buf.len,
+ }};
+ var remote_vec: [1]std.os.iovec_const = .{.{
+ .iov_base = @intToPtr([*]u8, vaddr),
+ .iov_len = buf.len,
+ }};
+ const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0);
+ switch (std.os.errno(rc)) {
+ .SUCCESS => assert(rc == buf.len),
+ else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
+ }
+ }
},
else => unreachable,
}