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.
This commit is contained in:
Billy Laws 2020-01-11 19:28:44 +00:00 committed by ◱ PixelyIon
parent 65018aedbc
commit 81dba3da4b

View File

@ -3,6 +3,7 @@
#include <os.h> #include <os.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/uio.h>
namespace skyline::kernel::type { namespace skyline::kernel::type {
KProcess::TlsPage::TlsPage(u64 address) : address(address) {} KProcess::TlsPage::TlsPage(u64 address) : address(address) {}
@ -89,10 +90,30 @@ namespace skyline::kernel::type {
} }
void KProcess::ReadMemory(void *destination, u64 offset, size_t size) const { void KProcess::ReadMemory(void *destination, u64 offset, size_t size) const {
struct iovec local[1];
struct iovec remote[1];
remote[0].iov_base = reinterpret_cast<void*>(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); pread64(memFd, destination, size, offset);
} }
void KProcess::WriteMemory(void *source, u64 offset, size_t size) const { void KProcess::WriteMemory(void *source, u64 offset, size_t size) const {
struct iovec local[1];
struct iovec remote[1];
remote[0].iov_base = reinterpret_cast<void*>(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); pwrite64(memFd, source, size, offset);
} }