diff options
author | Sebastian Valle <subv2112@gmail.com> | 2017-10-08 10:11:12 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-08 10:11:12 -0500 |
commit | 20e19a340ca6eb2e6e2f1e80370bcc7882d027fa (patch) | |
tree | 76c81c04f06a10d5d9375038d25afd4e7eda2a46 /src/core/hle/svc.cpp | |
parent | 74d4050924e63f98c76570cafb5a6ad95d2ea5b1 (diff) | |
parent | 97f262c1f5c39e51d6fe2e32429610599299db60 (diff) |
Merge pull request #2991 from Subv/getpointer
Remove more usages of GetPointer.
Diffstat (limited to 'src/core/hle/svc.cpp')
-rw-r--r-- | src/core/hle/svc.cpp | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 6be5db13f..e8ca419d5 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; } @@ -303,12 +307,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 +326,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; @@ -452,10 +456,9 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha } /// 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 +469,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; @@ -619,8 +623,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 @@ -638,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 = @@ -648,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 = @@ -665,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; } @@ -1098,9 +1110,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; |