summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/gdbstub/gdbstub.cpp18
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp8
-rw-r--r--src/core/hle/kernel/svc.cpp4
-rw-r--r--src/core/hle/kernel/thread.cpp4
-rw-r--r--src/core/memory.cpp51
-rw-r--r--src/core/memory.h24
6 files changed, 70 insertions, 39 deletions
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 54ed680db..78e44f3bd 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -969,7 +969,8 @@ static void ReadMemory() {
969 SendReply("E01"); 969 SendReply("E01");
970 } 970 }
971 971
972 if (!Memory::IsValidVirtualAddress(addr)) { 972 const auto& memory = Core::System::GetInstance().Memory();
973 if (!memory.IsValidVirtualAddress(addr)) {
973 return SendReply("E00"); 974 return SendReply("E00");
974 } 975 }
975 976
@@ -984,22 +985,23 @@ static void ReadMemory() {
984/// Modify location in memory with data received from the gdb client. 985/// Modify location in memory with data received from the gdb client.
985static void WriteMemory() { 986static void WriteMemory() {
986 auto start_offset = command_buffer + 1; 987 auto start_offset = command_buffer + 1;
987 auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); 988 const auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
988 VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); 989 const VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
989 990
990 start_offset = addr_pos + 1; 991 start_offset = addr_pos + 1;
991 auto len_pos = std::find(start_offset, command_buffer + command_length, ':'); 992 const auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
992 u64 len = HexToLong(start_offset, static_cast<u64>(len_pos - start_offset)); 993 const u64 len = HexToLong(start_offset, static_cast<u64>(len_pos - start_offset));
993 994
994 if (!Memory::IsValidVirtualAddress(addr)) { 995 auto& system = Core::System::GetInstance();
996 const auto& memory = system.Memory();
997 if (!memory.IsValidVirtualAddress(addr)) {
995 return SendReply("E00"); 998 return SendReply("E00");
996 } 999 }
997 1000
998 std::vector<u8> data(len); 1001 std::vector<u8> data(len);
999
1000 GdbHexToMem(data.data(), len_pos + 1, len); 1002 GdbHexToMem(data.data(), len_pos + 1, len);
1001 Memory::WriteBlock(addr, data.data(), len); 1003 Memory::WriteBlock(addr, data.data(), len);
1002 Core::System::GetInstance().InvalidateCpuInstructionCaches(); 1004 system.InvalidateCpuInstructionCaches();
1003 SendReply("OK"); 1005 SendReply("OK");
1004} 1006}
1005 1007
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 4859954cb..7f9a559d2 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -68,7 +68,7 @@ ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) {
68ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, 68ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 value,
69 s32 num_to_wake) { 69 s32 num_to_wake) {
70 // Ensure that we can write to the address. 70 // Ensure that we can write to the address.
71 if (!Memory::IsValidVirtualAddress(address)) { 71 if (!system.Memory().IsValidVirtualAddress(address)) {
72 return ERR_INVALID_ADDRESS_STATE; 72 return ERR_INVALID_ADDRESS_STATE;
73 } 73 }
74 74
@@ -83,7 +83,7 @@ ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32
83ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, 83ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value,
84 s32 num_to_wake) { 84 s32 num_to_wake) {
85 // Ensure that we can write to the address. 85 // Ensure that we can write to the address.
86 if (!Memory::IsValidVirtualAddress(address)) { 86 if (!system.Memory().IsValidVirtualAddress(address)) {
87 return ERR_INVALID_ADDRESS_STATE; 87 return ERR_INVALID_ADDRESS_STATE;
88 } 88 }
89 89
@@ -135,7 +135,7 @@ ResultCode AddressArbiter::WaitForAddress(VAddr address, ArbitrationType type, s
135ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, 135ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout,
136 bool should_decrement) { 136 bool should_decrement) {
137 // Ensure that we can read the address. 137 // Ensure that we can read the address.
138 if (!Memory::IsValidVirtualAddress(address)) { 138 if (!system.Memory().IsValidVirtualAddress(address)) {
139 return ERR_INVALID_ADDRESS_STATE; 139 return ERR_INVALID_ADDRESS_STATE;
140 } 140 }
141 141
@@ -158,7 +158,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6
158 158
159ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { 159ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) {
160 // Ensure that we can read the address. 160 // Ensure that we can read the address.
161 if (!Memory::IsValidVirtualAddress(address)) { 161 if (!system.Memory().IsValidVirtualAddress(address)) {
162 return ERR_INVALID_ADDRESS_STATE; 162 return ERR_INVALID_ADDRESS_STATE;
163 } 163 }
164 // Only wait for the address if equal. 164 // Only wait for the address if equal.
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 9928b3a26..eddafaf60 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -332,7 +332,7 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad
332/// Connect to an OS service given the port name, returns the handle to the port to out 332/// Connect to an OS service given the port name, returns the handle to the port to out
333static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, 333static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
334 VAddr port_name_address) { 334 VAddr port_name_address) {
335 if (!Memory::IsValidVirtualAddress(port_name_address)) { 335 if (!system.Memory().IsValidVirtualAddress(port_name_address)) {
336 LOG_ERROR(Kernel_SVC, 336 LOG_ERROR(Kernel_SVC,
337 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", 337 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}",
338 port_name_address); 338 port_name_address);
@@ -452,7 +452,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
452 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", 452 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}",
453 handles_address, handle_count, nano_seconds); 453 handles_address, handle_count, nano_seconds);
454 454
455 if (!Memory::IsValidVirtualAddress(handles_address)) { 455 if (!system.Memory().IsValidVirtualAddress(handles_address)) {
456 LOG_ERROR(Kernel_SVC, 456 LOG_ERROR(Kernel_SVC,
457 "Handle address is not a valid virtual address, handle_address=0x{:016X}", 457 "Handle address is not a valid virtual address, handle_address=0x{:016X}",
458 handles_address); 458 handles_address);
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 735019d96..e84e5ce0d 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -162,13 +162,13 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::strin
162 return ERR_INVALID_PROCESSOR_ID; 162 return ERR_INVALID_PROCESSOR_ID;
163 } 163 }
164 164
165 if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) { 165 auto& system = Core::System::GetInstance();
166 if (!system.Memory().IsValidVirtualAddress(owner_process, entry_point)) {
166 LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); 167 LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point);
167 // TODO (bunnei): Find the correct error code to use here 168 // TODO (bunnei): Find the correct error code to use here
168 return RESULT_UNKNOWN; 169 return RESULT_UNKNOWN;
169 } 170 }
170 171
171 auto& system = Core::System::GetInstance();
172 std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel); 172 std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel);
173 173
174 thread->thread_id = kernel.CreateNewThreadID(); 174 thread->thread_id = kernel.CreateNewThreadID();
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 28b65ca5e..4c13ea1e7 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -75,6 +75,29 @@ struct Memory::Impl {
75 std::make_pair(interval, std::set<Common::SpecialRegion>{region})); 75 std::make_pair(interval, std::set<Common::SpecialRegion>{region}));
76 } 76 }
77 77
78 bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const {
79 const auto& page_table = process.VMManager().page_table;
80
81 const u8* const page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
82 if (page_pointer != nullptr) {
83 return true;
84 }
85
86 if (page_table.attributes[vaddr >> PAGE_BITS] == Common::PageType::RasterizerCachedMemory) {
87 return true;
88 }
89
90 if (page_table.attributes[vaddr >> PAGE_BITS] != Common::PageType::Special) {
91 return false;
92 }
93
94 return false;
95 }
96
97 bool IsValidVirtualAddress(VAddr vaddr) const {
98 return IsValidVirtualAddress(*system.CurrentProcess(), vaddr);
99 }
100
78 /** 101 /**
79 * Maps a region of pages as a specific type. 102 * Maps a region of pages as a specific type.
80 * 103 *
@@ -148,6 +171,14 @@ void Memory::RemoveDebugHook(Common::PageTable& page_table, VAddr base, u64 size
148 impl->RemoveDebugHook(page_table, base, size, std::move(hook)); 171 impl->RemoveDebugHook(page_table, base, size, std::move(hook));
149} 172}
150 173
174bool Memory::IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const {
175 return impl->IsValidVirtualAddress(process, vaddr);
176}
177
178bool Memory::IsValidVirtualAddress(const VAddr vaddr) const {
179 return impl->IsValidVirtualAddress(vaddr);
180}
181
151void SetCurrentPageTable(Kernel::Process& process) { 182void SetCurrentPageTable(Kernel::Process& process) {
152 current_page_table = &process.VMManager().page_table; 183 current_page_table = &process.VMManager().page_table;
153 184
@@ -256,26 +287,6 @@ void Write(const VAddr vaddr, const T data) {
256 } 287 }
257} 288}
258 289
259bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
260 const auto& page_table = process.VMManager().page_table;
261
262 const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
263 if (page_pointer)
264 return true;
265
266 if (page_table.attributes[vaddr >> PAGE_BITS] == Common::PageType::RasterizerCachedMemory)
267 return true;
268
269 if (page_table.attributes[vaddr >> PAGE_BITS] != Common::PageType::Special)
270 return false;
271
272 return false;
273}
274
275bool IsValidVirtualAddress(const VAddr vaddr) {
276 return IsValidVirtualAddress(*Core::System::GetInstance().CurrentProcess(), vaddr);
277}
278
279bool IsKernelVirtualAddress(const VAddr vaddr) { 290bool IsKernelVirtualAddress(const VAddr vaddr) {
280 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; 291 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END;
281} 292}
diff --git a/src/core/memory.h b/src/core/memory.h
index 87ed3b696..cacf4fb1a 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -111,6 +111,27 @@ public:
111 void RemoveDebugHook(Common::PageTable& page_table, VAddr base, u64 size, 111 void RemoveDebugHook(Common::PageTable& page_table, VAddr base, u64 size,
112 Common::MemoryHookPointer hook); 112 Common::MemoryHookPointer hook);
113 113
114 /**
115 * Checks whether or not the supplied address is a valid virtual
116 * address for the given process.
117 *
118 * @param process The emulated process to check the address against.
119 * @param vaddr The virtual address to check the validity of.
120 *
121 * @returns True if the given virtual address is valid, false otherwise.
122 */
123 bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr) const;
124
125 /**
126 * Checks whether or not the supplied address is a valid virtual
127 * address for the current process.
128 *
129 * @param vaddr The virtual address to check the validity of.
130 *
131 * @returns True if the given virtual address is valid, false otherwise.
132 */
133 bool IsValidVirtualAddress(VAddr vaddr) const;
134
114private: 135private:
115 struct Impl; 136 struct Impl;
116 std::unique_ptr<Impl> impl; 137 std::unique_ptr<Impl> impl;
@@ -120,9 +141,6 @@ private:
120/// the given process instance. 141/// the given process instance.
121void SetCurrentPageTable(Kernel::Process& process); 142void SetCurrentPageTable(Kernel::Process& process);
122 143
123/// Determines if the given VAddr is valid for the specified process.
124bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr);
125bool IsValidVirtualAddress(VAddr vaddr);
126/// Determines if the given VAddr is a kernel address 144/// Determines if the given VAddr is a kernel address
127bool IsKernelVirtualAddress(VAddr vaddr); 145bool IsKernelVirtualAddress(VAddr vaddr);
128 146