diff options
| -rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 31 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.h | 31 |
2 files changed, 49 insertions, 13 deletions
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index c929c2a52..3df5ccb7f 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -152,22 +152,33 @@ ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8* me | |||
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | ResultVal<VAddr> VMManager::FindFreeRegion(u64 size) const { | 154 | ResultVal<VAddr> VMManager::FindFreeRegion(u64 size) const { |
| 155 | // Find the first Free VMA. | 155 | return FindFreeRegion(GetASLRRegionBaseAddress(), GetASLRRegionEndAddress(), size); |
| 156 | const VAddr base = GetASLRRegionBaseAddress(); | 156 | } |
| 157 | const VMAHandle vma_handle = std::find_if(vma_map.begin(), vma_map.end(), [&](const auto& vma) { | ||
| 158 | if (vma.second.type != VMAType::Free) | ||
| 159 | return false; | ||
| 160 | 157 | ||
| 161 | const VAddr vma_end = vma.second.base + vma.second.size; | 158 | ResultVal<VAddr> VMManager::FindFreeRegion(VAddr begin, VAddr end, u64 size) const { |
| 162 | return vma_end > base && vma_end >= base + size; | 159 | ASSERT(begin < end); |
| 163 | }); | 160 | ASSERT(size <= end - begin); |
| 164 | 161 | ||
| 165 | if (vma_handle == vma_map.end()) { | 162 | const VMAHandle vma_handle = |
| 163 | std::find_if(vma_map.begin(), vma_map.end(), [begin, end, size](const auto& vma) { | ||
| 164 | if (vma.second.type != VMAType::Free) { | ||
| 165 | return false; | ||
| 166 | } | ||
| 167 | const VAddr vma_base = vma.second.base; | ||
| 168 | const VAddr vma_end = vma_base + vma.second.size; | ||
| 169 | const VAddr assumed_base = (begin < vma_base) ? vma_base : begin; | ||
| 170 | const VAddr used_range = assumed_base + size; | ||
| 171 | |||
| 172 | return vma_base <= assumed_base && assumed_base < used_range && used_range < end && | ||
| 173 | used_range <= vma_end; | ||
| 174 | }); | ||
| 175 | |||
| 176 | if (vma_handle == vma_map.cend()) { | ||
| 166 | // TODO(Subv): Find the correct error code here. | 177 | // TODO(Subv): Find the correct error code here. |
| 167 | return ResultCode(-1); | 178 | return ResultCode(-1); |
| 168 | } | 179 | } |
| 169 | 180 | ||
| 170 | const VAddr target = std::max(base, vma_handle->second.base); | 181 | const VAddr target = std::max(begin, vma_handle->second.base); |
| 171 | return MakeResult<VAddr>(target); | 182 | return MakeResult<VAddr>(target); |
| 172 | } | 183 | } |
| 173 | 184 | ||
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index dfbf7a894..752ae62f9 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h | |||
| @@ -362,14 +362,39 @@ public: | |||
| 362 | ResultVal<VMAHandle> MapBackingMemory(VAddr target, u8* memory, u64 size, MemoryState state); | 362 | ResultVal<VMAHandle> MapBackingMemory(VAddr target, u8* memory, u64 size, MemoryState state); |
| 363 | 363 | ||
| 364 | /** | 364 | /** |
| 365 | * Finds the first free address that can hold a region of the desired size. | 365 | * Finds the first free memory region of the given size within |
| 366 | * the user-addressable ASLR memory region. | ||
| 366 | * | 367 | * |
| 367 | * @param size Size of the desired region. | 368 | * @param size The size of the desired region in bytes. |
| 368 | * @return The found free address. | 369 | * |
| 370 | * @returns If successful, the base address of the free region with | ||
| 371 | * the given size. | ||
| 369 | */ | 372 | */ |
| 370 | ResultVal<VAddr> FindFreeRegion(u64 size) const; | 373 | ResultVal<VAddr> FindFreeRegion(u64 size) const; |
| 371 | 374 | ||
| 372 | /** | 375 | /** |
| 376 | * Finds the first free address range that can hold a region of the desired size | ||
| 377 | * | ||
| 378 | * @param begin The starting address of the range. | ||
| 379 | * This is treated as an inclusive beginning address. | ||
| 380 | * | ||
| 381 | * @param end The ending address of the range. | ||
| 382 | * This is treated as an exclusive ending address. | ||
| 383 | * | ||
| 384 | * @param size The size of the free region to attempt to locate, | ||
| 385 | * in bytes. | ||
| 386 | * | ||
| 387 | * @returns If successful, the base address of the free region with | ||
| 388 | * the given size. | ||
| 389 | * | ||
| 390 | * @returns If unsuccessful, a result containing an error code. | ||
| 391 | * | ||
| 392 | * @pre The starting address must be less than the ending address. | ||
| 393 | * @pre The size must not exceed the address range itself. | ||
| 394 | */ | ||
| 395 | ResultVal<VAddr> FindFreeRegion(VAddr begin, VAddr end, u64 size) const; | ||
| 396 | |||
| 397 | /** | ||
| 373 | * Maps a memory-mapped IO region at a given address. | 398 | * Maps a memory-mapped IO region at a given address. |
| 374 | * | 399 | * |
| 375 | * @param target The guest address to start the mapping at. | 400 | * @param target The guest address to start the mapping at. |