mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 21:40:04 +00:00
Memory: IsValidVirtualAddress can be global
This commit is contained in:
parent
42edab01d9
commit
c6b3186475
@ -832,8 +832,8 @@ static void ReadMemory() {
|
|||||||
SendReply("E01");
|
SendReply("E01");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Core::System::GetInstance().Memory().IsValidVirtualAddress(
|
if (!Memory::IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(),
|
||||||
*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr)) {
|
addr)) {
|
||||||
return SendReply("E00");
|
return SendReply("E00");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,8 +856,8 @@ static void WriteMemory() {
|
|||||||
auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
|
auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
|
||||||
u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset));
|
u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset));
|
||||||
|
|
||||||
if (!Core::System::GetInstance().Memory().IsValidVirtualAddress(
|
if (!Memory::IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(),
|
||||||
*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr)) {
|
addr)) {
|
||||||
return SendReply("E00");
|
return SendReply("E00");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ ResultCode SVC::UnmapMemoryBlock(Handle handle, u32 addr) {
|
|||||||
|
|
||||||
/// Connect to an OS service given the port name, returns the handle to the port to out
|
/// Connect to an OS service given the port name, returns the handle to the port to out
|
||||||
ResultCode SVC::ConnectToPort(Handle* out_handle, VAddr port_name_address) {
|
ResultCode SVC::ConnectToPort(Handle* out_handle, VAddr port_name_address) {
|
||||||
if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), port_name_address))
|
if (!Memory::IsValidVirtualAddress(*kernel.GetCurrentProcess(), port_name_address))
|
||||||
return ERR_NOT_FOUND;
|
return ERR_NOT_FOUND;
|
||||||
|
|
||||||
static constexpr std::size_t PortNameMaxLength = 11;
|
static constexpr std::size_t PortNameMaxLength = 11;
|
||||||
@ -452,7 +452,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle
|
|||||||
bool wait_all, s64 nano_seconds) {
|
bool wait_all, s64 nano_seconds) {
|
||||||
Thread* thread = kernel.GetThreadManager().GetCurrentThread();
|
Thread* thread = kernel.GetThreadManager().GetCurrentThread();
|
||||||
|
|
||||||
if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address))
|
if (!Memory::IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address))
|
||||||
return ERR_INVALID_POINTER;
|
return ERR_INVALID_POINTER;
|
||||||
|
|
||||||
// NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If
|
// NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If
|
||||||
@ -623,7 +623,7 @@ static ResultCode ReceiveIPCRequest(SharedPtr<ServerSession> server_session,
|
|||||||
/// In a single operation, sends a IPC reply and waits for a new request.
|
/// In a single operation, sends a IPC reply and waits for a new request.
|
||||||
ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count,
|
ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count,
|
||||||
Handle reply_target) {
|
Handle reply_target) {
|
||||||
if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address))
|
if (!Memory::IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address))
|
||||||
return ERR_INVALID_POINTER;
|
return ERR_INVALID_POINTER;
|
||||||
|
|
||||||
// Check if 'handle_count' is invalid
|
// Check if 'handle_count' is invalid
|
||||||
|
@ -303,7 +303,7 @@ ResultVal<SharedPtr<Thread>> KernelSystem::CreateThread(std::string name, VAddr
|
|||||||
|
|
||||||
// TODO(yuriks): Other checks, returning 0xD9001BEA
|
// TODO(yuriks): Other checks, returning 0xD9001BEA
|
||||||
|
|
||||||
if (!memory.IsValidVirtualAddress(owner_process, entry_point)) {
|
if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) {
|
||||||
LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:08x}", name, entry_point);
|
LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:08x}", name, entry_point);
|
||||||
// TODO: Verify error
|
// TODO: Verify error
|
||||||
return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
|
return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
|
||||||
|
@ -28,7 +28,7 @@ void MemorySystem::SetCurrentPageTable(PageTable* page_table) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PageTable* MemorySystem::GetCurrentPageTable() {
|
PageTable* MemorySystem::GetCurrentPageTable() const {
|
||||||
return current_page_table;
|
return current_page_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemorySystem::IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
|
bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = process.vm_manager.page_table;
|
||||||
|
|
||||||
const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
|
const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
|
||||||
|
@ -212,7 +212,7 @@ class MemorySystem {
|
|||||||
public:
|
public:
|
||||||
/// Currently active page table
|
/// Currently active page table
|
||||||
void SetCurrentPageTable(PageTable* page_table);
|
void SetCurrentPageTable(PageTable* page_table);
|
||||||
PageTable* GetCurrentPageTable();
|
PageTable* GetCurrentPageTable() const;
|
||||||
|
|
||||||
u8 Read8(VAddr addr);
|
u8 Read8(VAddr addr);
|
||||||
u16 Read16(VAddr addr);
|
u16 Read16(VAddr addr);
|
||||||
@ -236,9 +236,6 @@ public:
|
|||||||
|
|
||||||
std::string ReadCString(VAddr vaddr, std::size_t max_length);
|
std::string ReadCString(VAddr vaddr, std::size_t max_length);
|
||||||
|
|
||||||
/// Determines if the given VAddr is valid for the specified process.
|
|
||||||
bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a pointer to the memory region beginning at the specified physical address.
|
* Gets a pointer to the memory region beginning at the specified physical address.
|
||||||
*/
|
*/
|
||||||
@ -279,4 +276,7 @@ private:
|
|||||||
PageTable* current_page_table = nullptr;
|
PageTable* current_page_table = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Determines if the given VAddr is valid for the specified process.
|
||||||
|
bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr);
|
||||||
|
|
||||||
} // namespace Memory
|
} // namespace Memory
|
||||||
|
@ -10,27 +10,27 @@
|
|||||||
#include "core/hle/kernel/shared_page.h"
|
#include "core/hle/kernel/shared_page.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
TEST_CASE("MemorySystem::IsValidVirtualAddress", "[core][memory]") {
|
TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
|
||||||
// HACK: see comments of member timing
|
// HACK: see comments of member timing
|
||||||
Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
|
Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
|
||||||
Memory::MemorySystem memory;
|
Memory::MemorySystem memory;
|
||||||
Kernel::KernelSystem kernel(memory, 0);
|
Kernel::KernelSystem kernel(memory, 0);
|
||||||
SECTION("these regions should not be mapped on an empty process") {
|
SECTION("these regions should not be mapped on an empty process") {
|
||||||
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
|
SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
|
||||||
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
kernel.MapSharedPages(process->vm_manager);
|
kernel.MapSharedPages(process->vm_manager);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("special regions should be valid after mapping them") {
|
SECTION("special regions should be valid after mapping them") {
|
||||||
@ -38,13 +38,13 @@ TEST_CASE("MemorySystem::IsValidVirtualAddress", "[core][memory]") {
|
|||||||
SECTION("VRAM") {
|
SECTION("VRAM") {
|
||||||
kernel.HandleSpecialMapping(process->vm_manager,
|
kernel.HandleSpecialMapping(process->vm_manager,
|
||||||
{Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
|
{Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("IO (Not yet implemented)") {
|
SECTION("IO (Not yet implemented)") {
|
||||||
kernel.HandleSpecialMapping(
|
kernel.HandleSpecialMapping(
|
||||||
process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false});
|
process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false});
|
||||||
CHECK_FALSE(memory.IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true);
|
CHECK_FALSE(Memory::IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +52,6 @@ TEST_CASE("MemorySystem::IsValidVirtualAddress", "[core][memory]") {
|
|||||||
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
kernel.MapSharedPages(process->vm_manager);
|
kernel.MapSharedPages(process->vm_manager);
|
||||||
process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
|
process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
|
||||||
CHECK(memory.IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user