From 81dba3da4b8bcf008615357bc4aaf1c54b84a9b9 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sat, 11 Jan 2020 19:28:44 +0000 Subject: [PATCH] KProcess: Use process_{read, write}_vm to access guest memory This is much quicker than pread/write however we now need to abide by the regions permissions, so fallback to pread/write if read/write vm fails. --- .../cpp/skyline/kernel/types/KProcess.cpp | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/app/src/main/cpp/skyline/kernel/types/KProcess.cpp b/app/src/main/cpp/skyline/kernel/types/KProcess.cpp index 50c232e1..7da4cab0 100644 --- a/app/src/main/cpp/skyline/kernel/types/KProcess.cpp +++ b/app/src/main/cpp/skyline/kernel/types/KProcess.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace skyline::kernel::type { KProcess::TlsPage::TlsPage(u64 address) : address(address) {} @@ -89,11 +90,31 @@ namespace skyline::kernel::type { } void KProcess::ReadMemory(void *destination, u64 offset, size_t size) const { - pread64(memFd, destination, size, offset); + struct iovec local[1]; + struct iovec remote[1]; + + remote[0].iov_base = reinterpret_cast(offset); + remote[0].iov_len = size; + + local[0].iov_base = destination; + local[0].iov_len = size; + + if (process_vm_readv(pid, local, 1, remote, 1, 0) < 0) + pread64(memFd, destination, size, offset); } void KProcess::WriteMemory(void *source, u64 offset, size_t size) const { - pwrite64(memFd, source, size, offset); + struct iovec local[1]; + struct iovec remote[1]; + + remote[0].iov_base = reinterpret_cast(offset); + remote[0].iov_len = size; + + local[0].iov_base = source; + local[0].iov_len = size; + + if (process_vm_writev(pid, local, 1, remote, 1, 0) < 0) + pwrite64(memFd, source, size, offset); } KProcess::HandleOut KProcess::MapPrivateRegion(u64 address, size_t size, const memory::Permission perms, const memory::Type type, const memory::Region region) {