summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Lioncash2019-06-05 14:20:13 -0400
committerGravatar Lioncash2019-07-03 20:29:49 -0400
commit55481df50f98feb04b18beb518904681b8fcc345 (patch)
tree204f9e55abae9b53e4ba78ad0a7a3251b828734b
parentMerge pull request #2613 from ogniK5377/InitalizeApplicationInfo (diff)
downloadyuzu-55481df50f98feb04b18beb518904681b8fcc345.tar.gz
yuzu-55481df50f98feb04b18beb518904681b8fcc345.tar.xz
yuzu-55481df50f98feb04b18beb518904681b8fcc345.zip
kernel/vm_manager: Add overload of FindFreeRegion() that operates on a boundary
This will be necessary for making our TLS slot management slightly more straightforward. This can also be utilized for other purposes in the future. We can implement the existing simpler overload in terms of this one anyways, we just pass the beginning and end of the ASLR region as the boundaries.
-rw-r--r--src/core/hle/kernel/vm_manager.cpp31
-rw-r--r--src/core/hle/kernel/vm_manager.h31
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
154ResultVal<VAddr> VMManager::FindFreeRegion(u64 size) const { 154ResultVal<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; 158ResultVal<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.