From 7772fc07314d568939b0e9c12e4ead47e35d3c86 Mon Sep 17 00:00:00 2001 From: Subv 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 be2b2e25f..d6be16ef6 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(addr_pos - start_offset)); + VAddr addr = HexToInt(start_offset, static_cast(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 data(len); + Memory::ReadBlock(addr, data.data(), len); + + MemToGdbHex(reply, data.data(), len); reply[len * 2] = '\0'; SendReply(reinterpret_cast(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(addr_pos - start_offset)); + VAddr addr = HexToInt(start_offset, static_cast(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(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 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 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 5e6002f4e..17892d81c 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h @@ -58,12 +58,12 @@ void Wrap() { FuncReturn(retval); } -template +template void Wrap() { s32 param_1 = 0; - s32 retval = func(¶m_1, (Kernel::Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), - (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0))) - .raw; + s32 retval = + func(¶m_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 6be5db13f..9edce7ab7 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 objects(handle_count); for (int i = 0; i < handle_count; ++i) { - auto object = Kernel::g_handle_table.Get(handles[i]); + Kernel::Handle handle = Memory::Read32(handles_address + i * sizeof(Kernel::Handle)); + auto object = Kernel::g_handle_table.Get(handle); if (object == nullptr) return ERR_INVALID_HANDLE; objects[i] = object; From 0cfb231e002629172337c048e8cabc8c653e34e3 Mon Sep 17 00:00:00 2001 From: Subv 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 17892d81c..cd500e83d 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h @@ -69,11 +69,10 @@ void Wrap() { FuncReturn(retval); } -template +template void Wrap() { s32 param_1 = 0; - u32 retval = - func(¶m_1, (Kernel::Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), PARAM(3)).raw; + u32 retval = func(¶m_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 9edce7ab7..61360bede 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 objects(handle_count); for (int i = 0; i < handle_count; ++i) { - auto object = Kernel::g_handle_table.Get(handles[i]); + Kernel::Handle handle = Memory::Read32(handles_address + i * sizeof(Kernel::Handle)); + auto object = Kernel::g_handle_table.Get(handle); if (object == nullptr) return ERR_INVALID_HANDLE; objects[i] = object; From 3c0113632dc4fb4e55b5dad9278a5b766dcaec14 Mon Sep 17 00:00:00 2001 From: Subv 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 cd500e83d..cb0b430ee 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 +template void Wrap() { - func((char*)Memory::GetPointer(PARAM(0)), PARAM(1)); + func(PARAM(0), PARAM(1)); } template diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 61360bede..37eeeb860 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 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 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 cb0b430ee..a982b2b54 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 -void Wrap() { - FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), - (u32*)Memory::GetPointer(PARAM(2)), (s32)PARAM(3)) - .raw); -} - -template -void Wrap() { - u32 param_1 = 0; - u32 retval = func(¶m_1, (char*)Memory::GetPointer(PARAM(1))).raw; - Core::CPU().SetReg(1, param_1); - FuncReturn(retval); -} - template void Wrap() { u32 param_1 = 0; diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 37eeeb860..2ae177ab5 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 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 a982b2b54..f93439f21 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 +template void Wrap() { Kernel::Handle param_1 = 0; Kernel::Handle param_2 = 0; - u32 retval = func(¶m_1, ¶m_2, - reinterpret_cast(Memory::GetPointer(PARAM(2))), PARAM(3)) - .raw; + u32 retval = func(¶m_1, ¶m_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 2ae177ab5..b72ca3581 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 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 b72ca3581..e8ca419d5 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 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 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; }