From 7772fc07314d568939b0e9c12e4ead47e35d3c86 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Wed, 4 Oct 2017 11:33:32 -0500
Subject: [PATCH 1/7] Memory: Remove all GetPointer usages from the GDB stub.

---
 src/core/gdbstub/gdbstub.cpp | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index be2b2e25f3..d6be16ef66 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -644,7 +644,7 @@ static void ReadMemory() {
 
     auto start_offset = command_buffer + 1;
     auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
-    PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
+    VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
 
     start_offset = addr_pos + 1;
     u32 len =
@@ -656,12 +656,14 @@ static void ReadMemory() {
         SendReply("E01");
     }
 
-    const u8* data = Memory::GetPointer(addr);
-    if (!data) {
+    if (!Memory::IsValidVirtualAddress(addr)) {
         return SendReply("E00");
     }
 
-    MemToGdbHex(reply, data, len);
+    std::vector<u8> data(len);
+    Memory::ReadBlock(addr, data.data(), len);
+
+    MemToGdbHex(reply, data.data(), len);
     reply[len * 2] = '\0';
     SendReply(reinterpret_cast<char*>(reply));
 }
@@ -670,18 +672,20 @@ static void ReadMemory() {
 static void WriteMemory() {
     auto start_offset = command_buffer + 1;
     auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
-    PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
+    VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
 
     start_offset = addr_pos + 1;
     auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
     u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset));
 
-    u8* dst = Memory::GetPointer(addr);
-    if (!dst) {
+    if (!Memory::IsValidVirtualAddress(addr)) {
         return SendReply("E00");
     }
 
-    GdbHexToMem(dst, len_pos + 1, len);
+    std::vector<u8> data(len);
+
+    GdbHexToMem(data.data(), len_pos + 1, len);
+    Memory::WriteBlock(addr, data.data(), len);
     SendReply("OK");
 }
 

From b863d6c86043226c8c88749c4e0eecaf9865c569 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Wed, 4 Oct 2017 11:40:40 -0500
Subject: [PATCH 2/7] SVC: Replace GetPointer usage with Read32 in
 WaitSynchronizationN.

---
 src/core/hle/function_wrappers.h | 8 ++++----
 src/core/hle/svc.cpp             | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 5e6002f4ee..17892d81cd 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -58,12 +58,12 @@ void Wrap() {
     FuncReturn(retval);
 }
 
-template <ResultCode func(s32*, u32*, s32, bool, s64)>
+template <ResultCode func(s32*, VAddr, s32, bool, s64)>
 void Wrap() {
     s32 param_1 = 0;
-    s32 retval = func(&param_1, (Kernel::Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2),
-                      (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0)))
-                     .raw;
+    s32 retval =
+        func(&param_1, PARAM(1), (s32)PARAM(2), (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0)))
+            .raw;
 
     Core::CPU().SetReg(1, (u32)param_1);
     FuncReturn(retval);
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 6be5db13ff..9edce7ab7f 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -303,12 +303,11 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds)
 }
 
 /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
-static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 handle_count,
+static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle_count,
                                        bool wait_all, s64 nano_seconds) {
     Kernel::Thread* thread = Kernel::GetCurrentThread();
 
-    // Check if 'handles' is invalid
-    if (handles == nullptr)
+    if (!Memory::IsValidVirtualAddress(handles_address))
         return Kernel::ERR_INVALID_POINTER;
 
     // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If
@@ -323,7 +322,8 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
     std::vector<ObjectPtr> objects(handle_count);
 
     for (int i = 0; i < handle_count; ++i) {
-        auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handles[i]);
+        Kernel::Handle handle = Memory::Read32(handles_address + i * sizeof(Kernel::Handle));
+        auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handle);
         if (object == nullptr)
             return ERR_INVALID_HANDLE;
         objects[i] = object;

From 0cfb231e002629172337c048e8cabc8c653e34e3 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Wed, 4 Oct 2017 11:49:29 -0500
Subject: [PATCH 3/7] SVC: Replace GetPointer usage with Read32 in
 ReplyAndReceive.

---
 src/core/hle/function_wrappers.h | 5 ++---
 src/core/hle/svc.cpp             | 8 ++++----
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 17892d81cd..cd500e83da 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -69,11 +69,10 @@ void Wrap() {
     FuncReturn(retval);
 }
 
-template <ResultCode func(s32*, u32*, s32, u32)>
+template <ResultCode func(s32*, VAddr, s32, u32)>
 void Wrap() {
     s32 param_1 = 0;
-    u32 retval =
-        func(&param_1, (Kernel::Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), PARAM(3)).raw;
+    u32 retval = func(&param_1, PARAM(1), (s32)PARAM(2), PARAM(3)).raw;
 
     Core::CPU().SetReg(1, (u32)param_1);
     FuncReturn(retval);
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 9edce7ab7f..61360bedeb 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -452,10 +452,9 @@ static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 hand
 }
 
 /// In a single operation, sends a IPC reply and waits for a new request.
-static ResultCode ReplyAndReceive(s32* index, Kernel::Handle* handles, s32 handle_count,
+static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count,
                                   Kernel::Handle reply_target) {
-    // 'handles' has to be a valid pointer even if 'handle_count' is 0.
-    if (handles == nullptr)
+    if (!Memory::IsValidVirtualAddress(handles_address))
         return Kernel::ERR_INVALID_POINTER;
 
     // Check if 'handle_count' is invalid
@@ -466,7 +465,8 @@ static ResultCode ReplyAndReceive(s32* index, Kernel::Handle* handles, s32 handl
     std::vector<ObjectPtr> objects(handle_count);
 
     for (int i = 0; i < handle_count; ++i) {
-        auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handles[i]);
+        Kernel::Handle handle = Memory::Read32(handles_address + i * sizeof(Kernel::Handle));
+        auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handle);
         if (object == nullptr)
             return ERR_INVALID_HANDLE;
         objects[i] = object;

From 3c0113632dc4fb4e55b5dad9278a5b766dcaec14 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Wed, 4 Oct 2017 11:52:39 -0500
Subject: [PATCH 4/7] SVC: Replace GetPointer usage with ReadBlock in
 OutputDebugString.

---
 src/core/hle/function_wrappers.h | 4 ++--
 src/core/hle/svc.cpp             | 6 ++++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index cd500e83da..cb0b430ee9 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -267,9 +267,9 @@ void Wrap() {
     func(((s64)PARAM(1) << 32) | PARAM(0));
 }
 
-template <void func(const char*, int len)>
+template <void func(VAddr, int len)>
 void Wrap() {
-    func((char*)Memory::GetPointer(PARAM(0)), PARAM(1));
+    func(PARAM(0), PARAM(1));
 }
 
 template <void func(u8)>
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 61360bedeb..37eeeb860b 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -619,8 +619,10 @@ static void Break(u8 break_reason) {
 }
 
 /// Used to output a message on a debug hardware unit - does nothing on a retail unit
-static void OutputDebugString(const char* string, int len) {
-    LOG_DEBUG(Debug_Emulated, "%.*s", len, string);
+static void OutputDebugString(VAddr address, int len) {
+    std::vector<char> string(len);
+    Memory::ReadBlock(address, string.data(), len);
+    LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data());
 }
 
 /// Get resource limit

From 7b09b30ef11d1d4001a50bbb91abdfb86b954ce2 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Wed, 4 Oct 2017 12:05:13 -0500
Subject: [PATCH 5/7] SVC: Replace GetPointer usage with ReadCString in
 ConnectToPort.

---
 src/core/hle/function_wrappers.h | 15 ---------------
 src/core/hle/svc.cpp             | 14 +++++++++-----
 2 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index cb0b430ee9..a982b2b545 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -151,21 +151,6 @@ void Wrap() {
     FuncReturn(func(PARAM(0)).raw);
 }
 
-template <ResultCode func(s64*, u32, u32*, u32)>
-void Wrap() {
-    FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1),
-                    (u32*)Memory::GetPointer(PARAM(2)), (s32)PARAM(3))
-                   .raw);
-}
-
-template <ResultCode func(u32*, const char*)>
-void Wrap() {
-    u32 param_1 = 0;
-    u32 retval = func(&param_1, (char*)Memory::GetPointer(PARAM(1))).raw;
-    Core::CPU().SetReg(1, param_1);
-    FuncReturn(retval);
-}
-
 template <ResultCode func(u32*, s32, s32)>
 void Wrap() {
     u32 param_1 = 0;
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 37eeeb860b..2ae177ab56 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -201,17 +201,21 @@ static ResultCode UnmapMemoryBlock(Kernel::Handle handle, u32 addr) {
 }
 
 /// Connect to an OS service given the port name, returns the handle to the port to out
-static ResultCode ConnectToPort(Kernel::Handle* out_handle, const char* port_name) {
-    if (port_name == nullptr)
+static ResultCode ConnectToPort(Kernel::Handle* out_handle, VAddr port_name_address) {
+    if (!Memory::IsValidVirtualAddress(port_name_address))
         return Kernel::ERR_NOT_FOUND;
-    if (std::strlen(port_name) > 11)
+
+    static constexpr std::size_t PortNameMaxLength = 11;
+    // Read 1 char beyond the max allowed port name to detect names that are too long.
+    std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1);
+    if (port_name.size() > PortNameMaxLength)
         return Kernel::ERR_PORT_NAME_TOO_LONG;
 
-    LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name);
+    LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name.c_str());
 
     auto it = Service::g_kernel_named_ports.find(port_name);
     if (it == Service::g_kernel_named_ports.end()) {
-        LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name);
+        LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name.c_str());
         return Kernel::ERR_NOT_FOUND;
     }
 

From 46fc7595b4f5f161ecd5ae21259c661c15ca46f3 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Wed, 4 Oct 2017 12:11:55 -0500
Subject: [PATCH 6/7] SVC: Remove GetPointer usage in CreatePort.

---
 src/core/hle/function_wrappers.h | 6 ++----
 src/core/hle/svc.cpp             | 4 ++--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index a982b2b545..f93439f21f 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -206,13 +206,11 @@ void Wrap() {
     FuncReturn(func(PARAM(0), PARAM(1)).raw);
 }
 
-template <ResultCode func(Kernel::Handle*, Kernel::Handle*, const char*, u32)>
+template <ResultCode func(Kernel::Handle*, Kernel::Handle*, VAddr, u32)>
 void Wrap() {
     Kernel::Handle param_1 = 0;
     Kernel::Handle param_2 = 0;
-    u32 retval = func(&param_1, &param_2,
-                      reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3))
-                     .raw;
+    u32 retval = func(&param_1, &param_2, PARAM(2), PARAM(3)).raw;
     Core::CPU().SetReg(1, param_1);
     Core::CPU().SetReg(2, param_2);
     FuncReturn(retval);
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 2ae177ab56..b72ca3581c 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -1104,9 +1104,9 @@ static ResultCode CreateMemoryBlock(Kernel::Handle* out_handle, u32 addr, u32 si
 }
 
 static ResultCode CreatePort(Kernel::Handle* server_port, Kernel::Handle* client_port,
-                             const char* name, u32 max_sessions) {
+                             VAddr name_address, u32 max_sessions) {
     // TODO(Subv): Implement named ports.
-    ASSERT_MSG(name == nullptr, "Named ports are currently unimplemented");
+    ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented");
 
     using Kernel::ServerPort;
     using Kernel::ClientPort;

From 97f262c1f5c39e51d6fe2e32429610599299db60 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Wed, 4 Oct 2017 12:23:08 -0500
Subject: [PATCH 7/7] SVC: Removed GetPointer usage in the GetResourceLimit
 functions.

---
 src/core/hle/svc.cpp | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index b72ca3581c..e8ca419d5e 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -644,9 +644,9 @@ static ResultCode GetResourceLimit(Kernel::Handle* resource_limit, Kernel::Handl
 }
 
 /// Get resource limit current values
-static ResultCode GetResourceLimitCurrentValues(s64* values, Kernel::Handle resource_limit_handle,
-                                                u32* names, u32 name_count) {
-    LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
+static ResultCode GetResourceLimitCurrentValues(VAddr values, Kernel::Handle resource_limit_handle,
+                                                VAddr names, u32 name_count) {
+    LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%08X, name_count=%d",
               resource_limit_handle, names, name_count);
 
     SharedPtr<Kernel::ResourceLimit> resource_limit =
@@ -654,16 +654,19 @@ static ResultCode GetResourceLimitCurrentValues(s64* values, Kernel::Handle reso
     if (resource_limit == nullptr)
         return ERR_INVALID_HANDLE;
 
-    for (unsigned int i = 0; i < name_count; ++i)
-        values[i] = resource_limit->GetCurrentResourceValue(names[i]);
+    for (unsigned int i = 0; i < name_count; ++i) {
+        u32 name = Memory::Read32(names + i * sizeof(u32));
+        s64 value = resource_limit->GetCurrentResourceValue(name);
+        Memory::Write64(values + i * sizeof(u64), value);
+    }
 
     return RESULT_SUCCESS;
 }
 
 /// Get resource limit max values
-static ResultCode GetResourceLimitLimitValues(s64* values, Kernel::Handle resource_limit_handle,
-                                              u32* names, u32 name_count) {
-    LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
+static ResultCode GetResourceLimitLimitValues(VAddr values, Kernel::Handle resource_limit_handle,
+                                              VAddr names, u32 name_count) {
+    LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%08X, name_count=%d",
               resource_limit_handle, names, name_count);
 
     SharedPtr<Kernel::ResourceLimit> resource_limit =
@@ -671,8 +674,11 @@ static ResultCode GetResourceLimitLimitValues(s64* values, Kernel::Handle resour
     if (resource_limit == nullptr)
         return ERR_INVALID_HANDLE;
 
-    for (unsigned int i = 0; i < name_count; ++i)
-        values[i] = resource_limit->GetMaxResourceValue(names[i]);
+    for (unsigned int i = 0; i < name_count; ++i) {
+        u32 name = Memory::Read32(names + i * sizeof(u32));
+        s64 value = resource_limit->GetMaxResourceValue(names);
+        Memory::Write64(values + i * sizeof(u64), value);
+    }
 
     return RESULT_SUCCESS;
 }