From 79c7213e9f6173750b836997e78a4ddf3a10fead Mon Sep 17 00:00:00 2001 From: Zephyron Date: Thu, 27 Mar 2025 23:25:24 +1000 Subject: memory: Implement enhanced memory management system Add a flexible memory region management system that provides: - Memory region type classification (System, Graphics, IO, Binary) - Memory region permission management (executable, writable) - Binary base address randomization for ASLR - Dynamic memory mapping capabilities Credit: boss.smc@citron-emu.org Signed-off-by: Zephyron --- src/core/memory.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'src/core/memory.cpp') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index abb2ce314..0b249ff0c 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: 2015 Citra Emulator Project // SPDX-FileCopyrightText: 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -909,7 +910,9 @@ struct Memory::Impl { #endif }; -Memory::Memory(Core::System& system_) : system{system_} { +Memory::Memory(Core::System& system_) : system(system_), impl(std::make_unique(system_)), gen(rd()) { + // Initialize the random number distribution + dis = std::uniform_int_distribution(0, std::numeric_limits::max()); Reset(); } @@ -1151,4 +1154,48 @@ bool Memory::InvalidateSeparateHeap(void* fault_address) { #endif } +Common::ProcessAddress Memory::GenerateRandomBaseAddress() { + u64 random_bits = dis(gen); + return Common::ProcessAddress((random_bits & ~NRO_BASE_ADDRESS_RANDOMIZATION_MASK) | + (random_bits & NRO_BASE_ADDRESS_RANDOMIZATION_MASK)); +} + +Memory::MemoryRegion* Memory::FindRegion(Common::ProcessAddress address) { + for (auto& entry : memory_regions) { + if (address >= entry.second.start_address && + address < entry.second.start_address + entry.second.size) { + return &entry.second; + } + } + return nullptr; +} + +void Memory::MapMemoryRegion(Common::ProcessAddress start_address, u64 size, MemoryRegionType type, + bool exec, bool write) { + if (start_address + size > EMULATED_MEMORY_SIZE) { + LOG_ERROR(HW_Memory, "Memory mapping exceeds emulated memory boundaries at address {:016X}", + GetInteger(start_address)); + return; + } + + // Create the memory region + memory_regions[start_address] = MemoryRegion(start_address, size, type, exec, write); + + // Map the region in the page table + Common::MemoryPermission perms{}; + if (exec) perms |= Common::MemoryPermission::Execute; + if (write) perms |= Common::MemoryPermission::Write; + perms |= Common::MemoryPermission::Read; + + // Using the MapMemoryRegion method defined in the Impl struct + impl->MapMemoryRegion(*impl->current_page_table, start_address, size, + Common::PhysicalAddress(GetInteger(start_address)), perms, false); +} + +Common::ProcessAddress Memory::MapBinary(u64 size) { + Common::ProcessAddress base_address = GenerateRandomBaseAddress(); + MapMemoryRegion(base_address, size, MemoryRegionType::BinaryMemory, true, true); + return base_address; +} + } // namespace Core::Memory -- cgit v1.2.3