diff options
| author | Zephyron <zephyron@citron-emu.org> | 2025-03-27 23:25:24 +1000 |
|---|---|---|
| committer | Mike Lothian <mike@fireburn.co.uk> | 2025-05-12 12:46:19 +0100 |
| commit | 79c7213e9f6173750b836997e78a4ddf3a10fead (patch) | |
| tree | 49e5fa72e91e1b506bc611277b832ef24fa15b74 /src/core/memory.cpp | |
| parent | 898ef9d51113e2b77dbe32e74dc215926399878e (diff) | |
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 <zephyron@citron-emu.org>
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 49 |
1 files changed, 48 insertions, 1 deletions
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 <algorithm> @@ -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<Impl>(system_)), gen(rd()) { + // Initialize the random number distribution + dis = std::uniform_int_distribution<u64>(0, std::numeric_limits<u64>::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 |
