diff options
| author | 2017-10-08 10:11:12 -0500 | |
|---|---|---|
| committer | 2017-10-08 10:11:12 -0500 | |
| commit | 20e19a340ca6eb2e6e2f1e80370bcc7882d027fa (patch) | |
| tree | 76c81c04f06a10d5d9375038d25afd4e7eda2a46 /src/core/hle/svc.cpp | |
| parent | Merge pull request #2975 from shinyquagsire23/archive-ncch-container-and-over... (diff) | |
| parent | SVC: Removed GetPointer usage in the GetResourceLimit functions. (diff) | |
| download | yuzu-20e19a340ca6eb2e6e2f1e80370bcc7882d027fa.tar.gz yuzu-20e19a340ca6eb2e6e2f1e80370bcc7882d027fa.tar.xz yuzu-20e19a340ca6eb2e6e2f1e80370bcc7882d027fa.zip | |
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) { | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | /// Connect to an OS service given the port name, returns the handle to the port to out | 203 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 204 | static ResultCode ConnectToPort(Kernel::Handle* out_handle, const char* port_name) { | 204 | static ResultCode ConnectToPort(Kernel::Handle* out_handle, VAddr port_name_address) { |
| 205 | if (port_name == nullptr) | 205 | if (!Memory::IsValidVirtualAddress(port_name_address)) |
| 206 | return Kernel::ERR_NOT_FOUND; | 206 | return Kernel::ERR_NOT_FOUND; |
| 207 | if (std::strlen(port_name) > 11) | 207 | |
| 208 | static constexpr std::size_t PortNameMaxLength = 11; | ||
| 209 | // Read 1 char beyond the max allowed port name to detect names that are too long. | ||
| 210 | std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); | ||
| 211 | if (port_name.size() > PortNameMaxLength) | ||
| 208 | return Kernel::ERR_PORT_NAME_TOO_LONG; | 212 | return Kernel::ERR_PORT_NAME_TOO_LONG; |
| 209 | 213 | ||
| 210 | LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); | 214 | LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name.c_str()); |
| 211 | 215 | ||
| 212 | auto it = Service::g_kernel_named_ports.find(port_name); | 216 | auto it = Service::g_kernel_named_ports.find(port_name); |
| 213 | if (it == Service::g_kernel_named_ports.end()) { | 217 | if (it == Service::g_kernel_named_ports.end()) { |
| 214 | LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name); | 218 | LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name.c_str()); |
| 215 | return Kernel::ERR_NOT_FOUND; | 219 | return Kernel::ERR_NOT_FOUND; |
| 216 | } | 220 | } |
| 217 | 221 | ||
| @@ -303,12 +307,11 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds) | |||
| 303 | } | 307 | } |
| 304 | 308 | ||
| 305 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 309 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds |
| 306 | static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 handle_count, | 310 | static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle_count, |
| 307 | bool wait_all, s64 nano_seconds) { | 311 | bool wait_all, s64 nano_seconds) { |
| 308 | Kernel::Thread* thread = Kernel::GetCurrentThread(); | 312 | Kernel::Thread* thread = Kernel::GetCurrentThread(); |
| 309 | 313 | ||
| 310 | // Check if 'handles' is invalid | 314 | if (!Memory::IsValidVirtualAddress(handles_address)) |
| 311 | if (handles == nullptr) | ||
| 312 | return Kernel::ERR_INVALID_POINTER; | 315 | return Kernel::ERR_INVALID_POINTER; |
| 313 | 316 | ||
| 314 | // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If | 317 | // 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 | |||
| 323 | std::vector<ObjectPtr> objects(handle_count); | 326 | std::vector<ObjectPtr> objects(handle_count); |
| 324 | 327 | ||
| 325 | for (int i = 0; i < handle_count; ++i) { | 328 | for (int i = 0; i < handle_count; ++i) { |
| 326 | auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handles[i]); | 329 | Kernel::Handle handle = Memory::Read32(handles_address + i * sizeof(Kernel::Handle)); |
| 330 | auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handle); | ||
| 327 | if (object == nullptr) | 331 | if (object == nullptr) |
| 328 | return ERR_INVALID_HANDLE; | 332 | return ERR_INVALID_HANDLE; |
| 329 | objects[i] = object; | 333 | objects[i] = object; |
| @@ -452,10 +456,9 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha | |||
| 452 | } | 456 | } |
| 453 | 457 | ||
| 454 | /// In a single operation, sends a IPC reply and waits for a new request. | 458 | /// In a single operation, sends a IPC reply and waits for a new request. |
| 455 | static ResultCode ReplyAndReceive(s32* index, Kernel::Handle* handles, s32 handle_count, | 459 | static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count, |
| 456 | Kernel::Handle reply_target) { | 460 | Kernel::Handle reply_target) { |
| 457 | // 'handles' has to be a valid pointer even if 'handle_count' is 0. | 461 | if (!Memory::IsValidVirtualAddress(handles_address)) |
| 458 | if (handles == nullptr) | ||
| 459 | return Kernel::ERR_INVALID_POINTER; | 462 | return Kernel::ERR_INVALID_POINTER; |
| 460 | 463 | ||
| 461 | // Check if 'handle_count' is invalid | 464 | // Check if 'handle_count' is invalid |
| @@ -466,7 +469,8 @@ static ResultCode ReplyAndReceive(s32* index, Kernel::Handle* handles, s32 handl | |||
| 466 | std::vector<ObjectPtr> objects(handle_count); | 469 | std::vector<ObjectPtr> objects(handle_count); |
| 467 | 470 | ||
| 468 | for (int i = 0; i < handle_count; ++i) { | 471 | for (int i = 0; i < handle_count; ++i) { |
| 469 | auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handles[i]); | 472 | Kernel::Handle handle = Memory::Read32(handles_address + i * sizeof(Kernel::Handle)); |
| 473 | auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handle); | ||
| 470 | if (object == nullptr) | 474 | if (object == nullptr) |
| 471 | return ERR_INVALID_HANDLE; | 475 | return ERR_INVALID_HANDLE; |
| 472 | objects[i] = object; | 476 | objects[i] = object; |
| @@ -619,8 +623,10 @@ static void Break(u8 break_reason) { | |||
| 619 | } | 623 | } |
| 620 | 624 | ||
| 621 | /// Used to output a message on a debug hardware unit - does nothing on a retail unit | 625 | /// Used to output a message on a debug hardware unit - does nothing on a retail unit |
| 622 | static void OutputDebugString(const char* string, int len) { | 626 | static void OutputDebugString(VAddr address, int len) { |
| 623 | LOG_DEBUG(Debug_Emulated, "%.*s", len, string); | 627 | std::vector<char> string(len); |
| 628 | Memory::ReadBlock(address, string.data(), len); | ||
| 629 | LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data()); | ||
| 624 | } | 630 | } |
| 625 | 631 | ||
| 626 | /// Get resource limit | 632 | /// Get resource limit |
| @@ -638,9 +644,9 @@ static ResultCode GetResourceLimit(Kernel::Handle* resource_limit, Kernel::Handl | |||
| 638 | } | 644 | } |
| 639 | 645 | ||
| 640 | /// Get resource limit current values | 646 | /// Get resource limit current values |
| 641 | static ResultCode GetResourceLimitCurrentValues(s64* values, Kernel::Handle resource_limit_handle, | 647 | static ResultCode GetResourceLimitCurrentValues(VAddr values, Kernel::Handle resource_limit_handle, |
| 642 | u32* names, u32 name_count) { | 648 | VAddr names, u32 name_count) { |
| 643 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", | 649 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%08X, name_count=%d", |
| 644 | resource_limit_handle, names, name_count); | 650 | resource_limit_handle, names, name_count); |
| 645 | 651 | ||
| 646 | SharedPtr<Kernel::ResourceLimit> resource_limit = | 652 | SharedPtr<Kernel::ResourceLimit> resource_limit = |
| @@ -648,16 +654,19 @@ static ResultCode GetResourceLimitCurrentValues(s64* values, Kernel::Handle reso | |||
| 648 | if (resource_limit == nullptr) | 654 | if (resource_limit == nullptr) |
| 649 | return ERR_INVALID_HANDLE; | 655 | return ERR_INVALID_HANDLE; |
| 650 | 656 | ||
| 651 | for (unsigned int i = 0; i < name_count; ++i) | 657 | for (unsigned int i = 0; i < name_count; ++i) { |
| 652 | values[i] = resource_limit->GetCurrentResourceValue(names[i]); | 658 | u32 name = Memory::Read32(names + i * sizeof(u32)); |
| 659 | s64 value = resource_limit->GetCurrentResourceValue(name); | ||
| 660 | Memory::Write64(values + i * sizeof(u64), value); | ||
| 661 | } | ||
| 653 | 662 | ||
| 654 | return RESULT_SUCCESS; | 663 | return RESULT_SUCCESS; |
| 655 | } | 664 | } |
| 656 | 665 | ||
| 657 | /// Get resource limit max values | 666 | /// Get resource limit max values |
| 658 | static ResultCode GetResourceLimitLimitValues(s64* values, Kernel::Handle resource_limit_handle, | 667 | static ResultCode GetResourceLimitLimitValues(VAddr values, Kernel::Handle resource_limit_handle, |
| 659 | u32* names, u32 name_count) { | 668 | VAddr names, u32 name_count) { |
| 660 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", | 669 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%08X, name_count=%d", |
| 661 | resource_limit_handle, names, name_count); | 670 | resource_limit_handle, names, name_count); |
| 662 | 671 | ||
| 663 | SharedPtr<Kernel::ResourceLimit> resource_limit = | 672 | SharedPtr<Kernel::ResourceLimit> resource_limit = |
| @@ -665,8 +674,11 @@ static ResultCode GetResourceLimitLimitValues(s64* values, Kernel::Handle resour | |||
| 665 | if (resource_limit == nullptr) | 674 | if (resource_limit == nullptr) |
| 666 | return ERR_INVALID_HANDLE; | 675 | return ERR_INVALID_HANDLE; |
| 667 | 676 | ||
| 668 | for (unsigned int i = 0; i < name_count; ++i) | 677 | for (unsigned int i = 0; i < name_count; ++i) { |
| 669 | values[i] = resource_limit->GetMaxResourceValue(names[i]); | 678 | u32 name = Memory::Read32(names + i * sizeof(u32)); |
| 679 | s64 value = resource_limit->GetMaxResourceValue(names); | ||
| 680 | Memory::Write64(values + i * sizeof(u64), value); | ||
| 681 | } | ||
| 670 | 682 | ||
| 671 | return RESULT_SUCCESS; | 683 | return RESULT_SUCCESS; |
| 672 | } | 684 | } |
| @@ -1098,9 +1110,9 @@ static ResultCode CreateMemoryBlock(Kernel::Handle* out_handle, u32 addr, u32 si | |||
| 1098 | } | 1110 | } |
| 1099 | 1111 | ||
| 1100 | static ResultCode CreatePort(Kernel::Handle* server_port, Kernel::Handle* client_port, | 1112 | static ResultCode CreatePort(Kernel::Handle* server_port, Kernel::Handle* client_port, |
| 1101 | const char* name, u32 max_sessions) { | 1113 | VAddr name_address, u32 max_sessions) { |
| 1102 | // TODO(Subv): Implement named ports. | 1114 | // TODO(Subv): Implement named ports. |
| 1103 | ASSERT_MSG(name == nullptr, "Named ports are currently unimplemented"); | 1115 | ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented"); |
| 1104 | 1116 | ||
| 1105 | using Kernel::ServerPort; | 1117 | using Kernel::ServerPort; |
| 1106 | using Kernel::ClientPort; | 1118 | using Kernel::ClientPort; |