summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2018-12-12 11:48:06 -0500
committerGravatar Lioncash2018-12-12 15:43:31 -0500
commitd8deb39b83409f1d9b5eeec0a719d560e4409aae (patch)
tree6dcc744b9761db6c5107e3adf752e81c383a5ff5 /src
parentvm_manager: Correct ordering of last two struct members of MemoryInfo (diff)
downloadyuzu-d8deb39b83409f1d9b5eeec0a719d560e4409aae.tar.gz
yuzu-d8deb39b83409f1d9b5eeec0a719d560e4409aae.tar.xz
yuzu-d8deb39b83409f1d9b5eeec0a719d560e4409aae.zip
svc: Handle memory writing explicitly within QueryProcessMemory
Moves the memory writes directly into QueryProcessMemory instead of letting the wrapper function do it. It would be inaccurate to allow the handler to do it because there's cases where memory shouldn't even be written to. For example, if the given process handle is invalid. HOWEVER, if the memory writing is within the wrapper, then we have no control over if these memory writes occur, meaning in an error case, 68 bytes of memory randomly get trashed with zeroes, 64 of those being written to wherever the memory info address points to, and the remaining 4 being written wherever the page info address points to. One solution in this case would be to just conditionally check within the handler itself, but this is kind of smelly, given the handler shouldn't be performing conditional behavior itself, it's a behavior of the managed function. In other words, if you remove the handler from the equation entirely, does the function still retain its proper behavior? In this case, no. Now, we don't potentially trash memory from this function if an invalid query is performed.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/svc.cpp31
-rw-r--r--src/core/hle/kernel/svc_wrap.h17
2 files changed, 22 insertions, 26 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 8b079bc40..a1ecc4540 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -35,6 +35,7 @@
35#include "core/hle/lock.h" 35#include "core/hle/lock.h"
36#include "core/hle/result.h" 36#include "core/hle/result.h"
37#include "core/hle/service/service.h" 37#include "core/hle/service/service.h"
38#include "core/memory.h"
38 39
39namespace Kernel { 40namespace Kernel {
40namespace { 41namespace {
@@ -1066,9 +1067,8 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
1066 return shared_memory->Unmap(*current_process, addr); 1067 return shared_memory->Unmap(*current_process, addr);
1067} 1068}
1068 1069
1069/// Query process memory 1070static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_address,
1070static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, 1071 Handle process_handle, VAddr address) {
1071 Handle process_handle, u64 address) {
1072 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); 1072 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
1073 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1073 const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
1074 SharedPtr<Process> process = handle_table.Get<Process>(process_handle); 1074 SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
@@ -1079,16 +1079,29 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
1079 } 1079 }
1080 1080
1081 const auto& vm_manager = process->VMManager(); 1081 const auto& vm_manager = process->VMManager();
1082 const auto result = vm_manager.QueryMemory(address); 1082 const MemoryInfo memory_info = vm_manager.QueryMemory(address);
1083
1084 Memory::Write64(memory_info_address, memory_info.base_address);
1085 Memory::Write64(memory_info_address + 8, memory_info.size);
1086 Memory::Write32(memory_info_address + 16, memory_info.state);
1087 Memory::Write32(memory_info_address + 20, memory_info.attributes);
1088 Memory::Write32(memory_info_address + 24, memory_info.permission);
1089
1090 // Page info appears to be currently unused by the kernel and is always set to zero.
1091 Memory::Write32(page_info_address, 0);
1083 1092
1084 *memory_info = result;
1085 return RESULT_SUCCESS; 1093 return RESULT_SUCCESS;
1086} 1094}
1087 1095
1088/// Query memory 1096static ResultCode QueryMemory(VAddr memory_info_address, VAddr page_info_address,
1089static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) { 1097 VAddr query_address) {
1090 LOG_TRACE(Kernel_SVC, "called, addr={:X}", addr); 1098 LOG_TRACE(Kernel_SVC,
1091 return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr); 1099 "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, "
1100 "query_address=0x{:016X}",
1101 memory_info_address, page_info_address, query_address);
1102
1103 return QueryProcessMemory(memory_info_address, page_info_address, CurrentProcess,
1104 query_address);
1092} 1105}
1093 1106
1094/// Exits the current process 1107/// Exits the current process
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 27a11d82e..f03b5438b 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -7,9 +7,7 @@
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/arm/arm_interface.h" 8#include "core/arm/arm_interface.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "core/hle/kernel/vm_manager.h"
11#include "core/hle/result.h" 10#include "core/hle/result.h"
12#include "core/memory.h"
13 11
14namespace Kernel { 12namespace Kernel {
15 13
@@ -191,21 +189,6 @@ void SvcWrap() {
191 FuncReturn(retval); 189 FuncReturn(retval);
192} 190}
193 191
194template <ResultCode func(MemoryInfo*, PageInfo*, u64)>
195void SvcWrap() {
196 MemoryInfo memory_info = {};
197 PageInfo page_info = {};
198 u32 retval = func(&memory_info, &page_info, Param(2)).raw;
199
200 Memory::Write64(Param(0), memory_info.base_address);
201 Memory::Write64(Param(0) + 8, memory_info.size);
202 Memory::Write32(Param(0) + 16, memory_info.state);
203 Memory::Write32(Param(0) + 20, memory_info.attributes);
204 Memory::Write32(Param(0) + 24, memory_info.permission);
205
206 FuncReturn(retval);
207}
208
209template <ResultCode func(u32*, u64, u64, u32)> 192template <ResultCode func(u32*, u64, u64, u32)>
210void SvcWrap() { 193void SvcWrap() {
211 u32 param_1 = 0; 194 u32 param_1 = 0;