mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-03-29 00:26:26 +01:00
[rpcsx-os] implement sys_query_memory_protection
This commit is contained in:
parent
5edfdb037c
commit
0c59167c38
|
|
@ -1,4 +1,3 @@
|
||||||
#include <array>
|
|
||||||
#include <orbis/error.hpp>
|
#include <orbis/error.hpp>
|
||||||
#include <orbis/thread.hpp>
|
#include <orbis/thread.hpp>
|
||||||
#include <orbis/time.hpp>
|
#include <orbis/time.hpp>
|
||||||
|
|
@ -12,6 +11,7 @@ using cpuwhich_t = sint;
|
||||||
using cpulevel_t = sint;
|
using cpulevel_t = sint;
|
||||||
using SceKernelModule = ModuleHandle;
|
using SceKernelModule = ModuleHandle;
|
||||||
|
|
||||||
|
struct MemoryProtection;
|
||||||
struct ModuleInfo;
|
struct ModuleInfo;
|
||||||
struct ModuleInfoEx;
|
struct ModuleInfoEx;
|
||||||
struct KEvent;
|
struct KEvent;
|
||||||
|
|
@ -631,7 +631,8 @@ SysResult sys_evf_set(Thread *thread, sint id, uint64_t value);
|
||||||
SysResult sys_evf_clear(Thread *thread, sint id, uint64_t value);
|
SysResult sys_evf_clear(Thread *thread, sint id, uint64_t value);
|
||||||
SysResult sys_evf_cancel(Thread *thread, sint id, uint64_t value,
|
SysResult sys_evf_cancel(Thread *thread, sint id, uint64_t value,
|
||||||
ptr<sint> pNumWaitThreads);
|
ptr<sint> pNumWaitThreads);
|
||||||
SysResult sys_query_memory_protection(Thread *thread /* TODO */);
|
SysResult sys_query_memory_protection(Thread *thread, ptr<void> address,
|
||||||
|
ptr<MemoryProtection> protection);
|
||||||
SysResult sys_batch_map(Thread *thread /* TODO */);
|
SysResult sys_batch_map(Thread *thread /* TODO */);
|
||||||
SysResult sys_osem_create(Thread *thread, ptr<const char[32]> name, uint attrs,
|
SysResult sys_osem_create(Thread *thread, ptr<const char[32]> name, uint attrs,
|
||||||
sint initCount, sint maxCount);
|
sint initCount, sint maxCount);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ struct Thread;
|
||||||
struct Module;
|
struct Module;
|
||||||
struct timespec;
|
struct timespec;
|
||||||
struct File;
|
struct File;
|
||||||
|
struct MemoryProtection;
|
||||||
|
|
||||||
struct ProcessOps {
|
struct ProcessOps {
|
||||||
SysResult (*mmap)(Thread *thread, caddr_t addr, size_t len, sint prot,
|
SysResult (*mmap)(Thread *thread, caddr_t addr, size_t len, sint prot,
|
||||||
|
|
@ -32,6 +33,8 @@ struct ProcessOps {
|
||||||
SysResult (*munlock)(Thread *thread, ptr<const void> addr, size_t len);
|
SysResult (*munlock)(Thread *thread, ptr<const void> addr, size_t len);
|
||||||
SysResult (*virtual_query)(Thread *thread, ptr<const void> addr, sint flags,
|
SysResult (*virtual_query)(Thread *thread, ptr<const void> addr, sint flags,
|
||||||
ptr<void> info, ulong infoSize);
|
ptr<void> info, ulong infoSize);
|
||||||
|
SysResult (*query_memory_protection)(Thread *thread, ptr<void> address,
|
||||||
|
ptr<MemoryProtection> protection);
|
||||||
|
|
||||||
SysResult (*open)(Thread *thread, ptr<const char> path, sint flags, sint mode,
|
SysResult (*open)(Thread *thread, ptr<const char> path, sint flags, sint mode,
|
||||||
Ref<File> *file);
|
Ref<File> *file);
|
||||||
|
|
|
||||||
13
orbis-kernel/include/orbis/vm.hpp
Normal file
13
orbis-kernel/include/orbis/vm.hpp
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "orbis-config.hpp"
|
||||||
|
|
||||||
|
namespace orbis {
|
||||||
|
struct MemoryProtection {
|
||||||
|
uint64_t startAddress;
|
||||||
|
uint64_t endAddress;
|
||||||
|
int32_t prot;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(MemoryProtection) == 24);
|
||||||
|
} // namespace orbis
|
||||||
|
|
@ -299,7 +299,14 @@ orbis::SysResult orbis::sys_evf_cancel(Thread *thread, sint id, uint64_t value,
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
orbis::SysResult orbis::sys_query_memory_protection(Thread *thread /* TODO */) {
|
orbis::SysResult
|
||||||
|
orbis::sys_query_memory_protection(Thread *thread, ptr<void> address,
|
||||||
|
ptr<MemoryProtection> protection) {
|
||||||
|
if (auto query_memory_protection =
|
||||||
|
thread->tproc->ops->query_memory_protection) {
|
||||||
|
return query_memory_protection(thread, address, protection);
|
||||||
|
}
|
||||||
|
|
||||||
return ErrorCode::NOSYS;
|
return ErrorCode::NOSYS;
|
||||||
}
|
}
|
||||||
orbis::SysResult orbis::sys_batch_map(Thread *thread /* TODO */) {
|
orbis::SysResult orbis::sys_batch_map(Thread *thread /* TODO */) {
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@ struct HostFile : orbis::File {
|
||||||
int hostFd = -1;
|
int hostFd = -1;
|
||||||
|
|
||||||
~HostFile() {
|
~HostFile() {
|
||||||
std::printf("Destroying host file\n");
|
|
||||||
|
|
||||||
if (hostFd > 0) {
|
if (hostFd > 0) {
|
||||||
::close(hostFd);
|
::close(hostFd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include "orbis/umtx.hpp"
|
#include "orbis/umtx.hpp"
|
||||||
#include "orbis/utils/Logs.hpp"
|
#include "orbis/utils/Logs.hpp"
|
||||||
#include "orbis/utils/Rc.hpp"
|
#include "orbis/utils/Rc.hpp"
|
||||||
|
#include "orbis/vm.hpp"
|
||||||
#include "thread.hpp"
|
#include "thread.hpp"
|
||||||
#include "vfs.hpp"
|
#include "vfs.hpp"
|
||||||
#include "vm.hpp"
|
#include "vm.hpp"
|
||||||
|
|
@ -247,6 +248,16 @@ orbis::SysResult virtual_query(orbis::Thread *thread,
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
orbis::SysResult
|
||||||
|
query_memory_protection(orbis::Thread *thread, orbis::ptr<void> address,
|
||||||
|
orbis::ptr<MemoryProtection> protection) {
|
||||||
|
if (rx::vm::queryProtection(address, &protection->startAddress,
|
||||||
|
&protection->endAddress, &protection->prot)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return ErrorCode::INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
orbis::SysResult open(orbis::Thread *thread, orbis::ptr<const char> path,
|
orbis::SysResult open(orbis::Thread *thread, orbis::ptr<const char> path,
|
||||||
orbis::sint flags, orbis::sint mode,
|
orbis::sint flags, orbis::sint mode,
|
||||||
orbis::Ref<orbis::File> *file) {
|
orbis::Ref<orbis::File> *file) {
|
||||||
|
|
@ -588,6 +599,7 @@ ProcessOps rx::procOpsTable = {
|
||||||
.munlockall = munlockall,
|
.munlockall = munlockall,
|
||||||
.munlock = munlock,
|
.munlock = munlock,
|
||||||
.virtual_query = virtual_query,
|
.virtual_query = virtual_query,
|
||||||
|
.query_memory_protection = query_memory_protection,
|
||||||
.open = open,
|
.open = open,
|
||||||
.shm_open = shm_open,
|
.shm_open = shm_open,
|
||||||
.blockpool_open = blockpool_open,
|
.blockpool_open = blockpool_open,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
@ -915,10 +916,60 @@ bool rx::vm::protect(void *addr, std::uint64_t size, std::int32_t prot) {
|
||||||
return ::mprotect(addr, size, prot & kMapProtCpuAll) == 0;
|
return ::mprotect(addr, size, prot & kMapProtCpuAll) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::int32_t getPageProtectionImpl(std::uint64_t address) {
|
||||||
|
return gBlocks[(address >> kBlockShift) - kFirstBlock].getProtection(
|
||||||
|
(address & kBlockMask) >> rx::vm::kPageShift);
|
||||||
|
}
|
||||||
|
|
||||||
bool rx::vm::queryProtection(const void *addr, std::uint64_t *startAddress,
|
bool rx::vm::queryProtection(const void *addr, std::uint64_t *startAddress,
|
||||||
std::uint64_t *endAddress, std::int64_t *prot) {
|
std::uint64_t *endAddress, std::int32_t *prot) {
|
||||||
// TODO
|
auto address = reinterpret_cast<std::uintptr_t>(addr);
|
||||||
return false;
|
if (address < kMinAddress || address >= kMaxAddress) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t start = address & ~kPageMask;
|
||||||
|
std::uint64_t end = start + kPageSize;
|
||||||
|
|
||||||
|
std::lock_guard lock(g_mtx);
|
||||||
|
|
||||||
|
auto resultProt = getPageProtectionImpl(address);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto testAddr = start - kPageSize;
|
||||||
|
if (testAddr < kMinAddress) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto testProt = getPageProtectionImpl(testAddr);
|
||||||
|
|
||||||
|
if (resultProt != testProt) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = testAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto testAddr = end;
|
||||||
|
if (testAddr >= kMaxAddress) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto testProt = getPageProtectionImpl(testAddr);
|
||||||
|
|
||||||
|
if (resultProt != testProt) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = testAddr + kPageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
*startAddress = start;
|
||||||
|
*endAddress = end;
|
||||||
|
*prot = resultProt;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned rx::vm::getPageProtection(std::uint64_t address) {
|
unsigned rx::vm::getPageProtection(std::uint64_t address) {
|
||||||
|
|
@ -929,8 +980,7 @@ unsigned rx::vm::getPageProtection(std::uint64_t address) {
|
||||||
|
|
||||||
std::lock_guard lock(g_mtx);
|
std::lock_guard lock(g_mtx);
|
||||||
|
|
||||||
return gBlocks[(address >> kBlockShift) - kFirstBlock].getProtection(
|
return getPageProtectionImpl(address);
|
||||||
(address & kBlockMask) >> kPageShift);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rx::vm::virtualQuery(const void *addr, std::int32_t flags,
|
bool rx::vm::virtualQuery(const void *addr, std::int32_t flags,
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,6 @@ bool protect(void *addr, std::uint64_t size, std::int32_t prot);
|
||||||
|
|
||||||
bool virtualQuery(const void *addr, std::int32_t flags, VirtualQueryInfo *info);
|
bool virtualQuery(const void *addr, std::int32_t flags, VirtualQueryInfo *info);
|
||||||
bool queryProtection(const void *addr, std::uint64_t *startAddress,
|
bool queryProtection(const void *addr, std::uint64_t *startAddress,
|
||||||
std::uint64_t *endAddress, std::int64_t *prot);
|
std::uint64_t *endAddress, std::int32_t *prot);
|
||||||
unsigned getPageProtection(std::uint64_t address);
|
unsigned getPageProtection(std::uint64_t address);
|
||||||
} // namespace rx::vm
|
} // namespace rx::vm
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue