aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/shared_memory.cpp
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2018-08-03 20:45:39 -0400
committerLioncash <mathew1800@gmail.com>2018-08-03 23:49:10 -0400
commit6f3a3ed8c5a786d14f0238c21f1442fbb0397583 (patch)
tree3c54d3fc5af88d887123897e0c69b7dd54e2601e /src/core/hle/kernel/shared_memory.cpp
parent67b4326d93e2c88374ab1394c8df69880b0e5207 (diff)
kernel/thread: Fix potential crashes introduced in 3bcf090d37e20e0096954c478179487d071bb37b
This amends cases where crashes can occur that were missed due to the odd way the previous code was set up (using 3DS memory regions that don't exist).
Diffstat (limited to 'src/core/hle/kernel/shared_memory.cpp')
-rw-r--r--src/core/hle/kernel/shared_memory.cpp38
1 files changed, 25 insertions, 13 deletions
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index b3ddebb3d4..21ddc2f7dc 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -28,20 +28,32 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
shared_memory->permissions = permissions;
shared_memory->other_permissions = other_permissions;
- auto& vm_manager = shared_memory->owner_process->vm_manager;
-
- // The memory is already available and mapped in the owner process.
- auto vma = vm_manager.FindVMA(address);
- ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
- ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address");
-
- // The returned VMA might be a bigger one encompassing the desired address.
- auto vma_offset = address - vma->first;
- ASSERT_MSG(vma_offset + size <= vma->second.size,
- "Shared memory exceeds bounds of mapped block");
+ if (address == 0) {
+ shared_memory->backing_block = std::make_shared<std::vector<u8>>(size);
+ shared_memory->backing_block_offset = 0;
+
+ // Refresh the address mappings for the current process.
+ if (Core::CurrentProcess() != nullptr) {
+ Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(
+ shared_memory->backing_block.get());
+ }
+ } else {
+ auto& vm_manager = shared_memory->owner_process->vm_manager;
+
+ // The memory is already available and mapped in the owner process.
+ auto vma = vm_manager.FindVMA(address);
+ ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
+ ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address");
+
+ // The returned VMA might be a bigger one encompassing the desired address.
+ auto vma_offset = address - vma->first;
+ ASSERT_MSG(vma_offset + size <= vma->second.size,
+ "Shared memory exceeds bounds of mapped block");
+
+ shared_memory->backing_block = vma->second.backing_block;
+ shared_memory->backing_block_offset = vma->second.offset + vma_offset;
+ }
- shared_memory->backing_block = vma->second.backing_block;
- shared_memory->backing_block_offset = vma->second.offset + vma_offset;
shared_memory->base_address = address;
return shared_memory;