diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 55936ed97..2348cdbef 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -831,8 +831,8 @@ static void ReadMemory() { SendReply("E01"); } - if (!Memory::IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(), - addr)) { + if (!Core::System::GetInstance().Memory().IsValidVirtualAddress( + *Core::System::GetInstance().Kernel().GetCurrentProcess(), addr)) { return SendReply("E00"); } @@ -855,8 +855,8 @@ static void WriteMemory() { auto len_pos = std::find(start_offset, command_buffer + command_length, ':'); u32 len = HexToInt(start_offset, static_cast(len_pos - start_offset)); - if (!Memory::IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(), - addr)) { + if (!Core::System::GetInstance().Memory().IsValidVirtualAddress( + *Core::System::GetInstance().Kernel().GetCurrentProcess(), addr)) { return SendReply("E00"); } diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 465ba76a5..660361720 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -105,6 +105,7 @@ public: private: Core::System& system; Kernel::KernelSystem& kernel; + Memory::MemorySystem& memory; friend class SVCWrapper; @@ -346,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 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; static constexpr std::size_t PortNameMaxLength = 11; @@ -451,7 +452,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle bool wait_all, s64 nano_seconds) { Thread* thread = kernel.GetThreadManager().GetCurrentThread(); - if (!Memory::IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address)) + if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address)) return ERR_INVALID_POINTER; // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If @@ -622,7 +623,7 @@ static ResultCode ReceiveIPCRequest(SharedPtr server_session, /// 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, Handle reply_target) { - if (!Memory::IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address)) + if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address)) return ERR_INVALID_POINTER; // Check if 'handle_count' is invalid @@ -1584,7 +1585,7 @@ void SVC::CallSVC(u32 immediate) { } } -SVC::SVC(Core::System& system) : system(system), kernel(system.Kernel()) {} +SVC::SVC(Core::System& system) : system(system), kernel(system.Kernel()), memory(system.Memory()) {} u32 SVC::GetReg(std::size_t n) { return system.CPU().GetReg(static_cast(n)); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index d686947aa..597678215 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -303,7 +303,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, VAddr // 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); // TODO: Verify error return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 0f91040d3..27d6109c4 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -185,7 +185,7 @@ void Write(const VAddr vaddr, const T data) { } } -bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) { +bool MemorySystem::IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) { auto& page_table = process.vm_manager.page_table; const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; diff --git a/src/core/memory.h b/src/core/memory.h index 1f66a3e64..97645c0b9 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -180,9 +180,6 @@ enum : VAddr { extern std::array fcram; -/// Determines if the given VAddr is valid for the specified process. -bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); - u8 Read8(VAddr addr); u16 Read16(VAddr addr); u32 Read32(VAddr addr); @@ -246,6 +243,9 @@ public: void SetCurrentPageTable(PageTable* page_table); PageTable* GetCurrentPageTable(); + /// 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. */ diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp index 376eb283a..46d25cffe 100644 --- a/src/tests/core/memory/memory.cpp +++ b/src/tests/core/memory/memory.cpp @@ -10,27 +10,27 @@ #include "core/hle/kernel/shared_page.h" #include "core/memory.h" -TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") { +TEST_CASE("MemorySystem::IsValidVirtualAddress", "[core][memory]") { // HACK: see comments of member timing Core::System::GetInstance().timing = std::make_unique(); Memory::MemorySystem memory; Kernel::KernelSystem kernel(memory, 0); SECTION("these regions should not be mapped on an empty process") { auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); - CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false); - CHECK(Memory::IsValidVirtualAddress(*process, Memory::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::CONFIG_MEMORY_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::PROCESS_IMAGE_VADDR) == false); + CHECK(memory.IsValidVirtualAddress(*process, Memory::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::CONFIG_MEMORY_VADDR) == false); + CHECK(memory.IsValidVirtualAddress(*process, Memory::SHARED_PAGE_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") { auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); kernel.MapSharedPages(process->vm_manager); - CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true); - CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true); + CHECK(memory.IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true); + CHECK(memory.IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true); } SECTION("special regions should be valid after mapping them") { @@ -38,13 +38,13 @@ TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") { SECTION("VRAM") { kernel.HandleSpecialMapping(process->vm_manager, {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)") { kernel.HandleSpecialMapping( 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("Memory::IsValidVirtualAddress", "[core][memory]") { auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); kernel.MapSharedPages(process->vm_manager); 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); } }