From 4a120c3c1697683df839e0a510d86107866be188 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 20 Jun 2019 05:01:24 -0700 Subject: [PATCH] libstrat: refactor for R_TRY --- Makefile | 2 + include/stratosphere/event.hpp | 37 ++-- include/stratosphere/hossynch.hpp | 103 ++++++----- .../stratosphere/ipc/ipc_serialization.hpp | 91 +++++---- .../stratosphere/ipc/ipc_service_session.hpp | 159 ++++++++-------- include/stratosphere/mitm/mitm_server.hpp | 17 +- include/stratosphere/mitm/mitm_session.hpp | 173 +++++++++--------- include/stratosphere/results/utilities.h | 8 +- include/stratosphere/servers.hpp | 13 +- include/stratosphere/utilities.hpp | 64 +++---- include/stratosphere/waitable_manager.hpp | 32 ++-- source/emummc_utilities.cpp | 15 +- source/firmware_version.cpp | 3 +- source/mitm_query_service.cpp | 15 +- source/mitm_server.cpp | 16 +- source/on_crash.cpp | 11 +- source/random.cpp | 4 +- 17 files changed, 345 insertions(+), 418 deletions(-) diff --git a/Makefile b/Makefile index ff0e010e..8edd2a64 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,8 @@ SOURCES := source DATA := data INCLUDES := include +DEFINES := -DRESULT_ABORT_ON_ASSERT + #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- diff --git a/include/stratosphere/event.hpp b/include/stratosphere/event.hpp index 66d9cb18..aa33419c 100644 --- a/include/stratosphere/event.hpp +++ b/include/stratosphere/event.hpp @@ -13,13 +13,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include #include #include "iwaitable.hpp" +#include "results.hpp" class IEvent : public IWaitable { public: @@ -31,7 +32,7 @@ class IEvent : public IWaitable { IEvent(bool a = false) : r_h(INVALID_HANDLE), w_h(INVALID_HANDLE), autoclear(a) { } IEvent(Handle r, bool a = false) : r_h(r), w_h(INVALID_HANDLE), autoclear(a) { } IEvent(Handle r, Handle w, bool a = false) : r_h(r), w_h(w), autoclear(a) { } - + ~IEvent() { if (r_h != INVALID_HANDLE) { svcCloseHandle(r_h); @@ -40,17 +41,17 @@ class IEvent : public IWaitable { svcCloseHandle(w_h); } } - + /* Make it non-copyable */ IEvent() = delete; IEvent(const IEvent &) = delete; IEvent& operator=(const IEvent&) = delete; - + bool IsAutoClear() { return this->autoclear; } - + void Clear() { std::scoped_lock lock(this->sig_lock); this->is_signaled = false; @@ -60,31 +61,31 @@ class IEvent : public IWaitable { svcResetSignal(this->r_h); } } - + void Signal() { std::scoped_lock lock(this->sig_lock); - + if (this->w_h == INVALID_HANDLE && this->r_h != INVALID_HANDLE) { /* We can't signal an event if we only have a read handle. */ std::abort(); } - + if (this->w_h == INVALID_HANDLE && this->is_signaled) { return; } - + this->is_signaled = true; - + if (this->w_h != INVALID_HANDLE) { svcSignalEvent(this->w_h); } else { this->NotifyManagerSignaled(); } } - + virtual Result HandleSignaled(u64 timeout) = 0; - - /* IWaitable */ + + /* IWaitable */ virtual Handle GetHandle() override { return this->r_h; } @@ -98,7 +99,7 @@ class HosEvent : public IEvent { HosEvent(F f, bool a = false) : IEvent(a), callback(std::move(f)) { } HosEvent(Handle r, F f, bool a = false) : IEvent(r, a), callback(std::move(f)) { } HosEvent(Handle r, Handle w, F f, bool a = false) : IEvent(r, w, a), callback(std::move(f)) { } - + virtual Result HandleSignaled(u64 timeout) override { if (this->IsAutoClear()) { this->Clear(); @@ -115,9 +116,7 @@ static IEvent *CreateHosEvent(F f, bool autoclear = false) { template static IEvent *CreateSystemEvent(F f, bool autoclear = false) { Handle w_h, r_h; - if (R_FAILED(svcCreateEvent(&w_h, &r_h))) { - std::abort(); - } + R_ASSERT(svcCreateEvent(&w_h, &r_h)); return new HosEvent(r_h, w_h, std::move(f), autoclear); } @@ -125,9 +124,7 @@ template static IEvent *CreateInterruptEvent(F f, u64 irq, bool autoclear = false) { Handle r_h; /* flag is "rising edge vs level". */ - if (R_FAILED(svcCreateInterruptEvent(&r_h, irq, autoclear ? 0 : 1))) { - std::abort(); - } + R_ASSERT(svcCreateInterruptEvent(&r_h, irq, autoclear ? 0 : 1)); return new HosEvent(r_h, INVALID_HANDLE, std::move(f), autoclear); } diff --git a/include/stratosphere/hossynch.hpp b/include/stratosphere/hossynch.hpp index 128b0a00..242f882b 100644 --- a/include/stratosphere/hossynch.hpp +++ b/include/stratosphere/hossynch.hpp @@ -13,11 +13,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include #include +#include "results.hpp" class HosMutex { private: @@ -29,31 +30,31 @@ class HosMutex { HosMutex() { mutexInit(GetMutex()); } - + void lock() { mutexLock(GetMutex()); } - + void unlock() { mutexUnlock(GetMutex()); } - + bool try_lock() { return mutexTryLock(GetMutex()); } - + void Lock() { lock(); } - + void Unlock() { unlock(); } - + bool TryLock() { return try_lock(); } - + friend class HosCondVar; }; @@ -67,27 +68,27 @@ class HosRecursiveMutex { HosRecursiveMutex() { rmutexInit(GetMutex()); } - + void lock() { rmutexLock(GetMutex()); } - + void unlock() { rmutexUnlock(GetMutex()); } - + bool try_lock() { return rmutexTryLock(GetMutex()); } - + void Lock() { lock(); } - + void Unlock() { unlock(); } - + bool TryLock() { return try_lock(); } @@ -100,31 +101,31 @@ class HosCondVar { HosCondVar() { condvarInit(&cv); } - + Result TimedWait(u64 timeout, HosMutex *hm) { return TimedWait(timeout, hm->GetMutex()); } - + Result Wait(HosMutex *hm) { return Wait(hm->GetMutex()); } - + Result TimedWait(u64 timeout, Mutex *m) { return condvarWaitTimeout(&cv, m, timeout); } - + Result Wait(Mutex *m) { return condvarWait(&cv, m); } - + Result Wake(int num) { return condvarWake(&cv, num); } - + Result WakeOne() { return condvarWakeOne(&cv); } - + Result WakeAll() { return condvarWakeAll(&cv); } @@ -137,19 +138,19 @@ class HosSemaphore { HosSemaphore() { semaphoreInit(&s, 0); } - + HosSemaphore(u64 c) { semaphoreInit(&s, c); } - + void Signal() { semaphoreSignal(&s); } - + void Wait() { semaphoreWait(&s); } - + bool TryWait() { return semaphoreTryWait(&s); } @@ -165,34 +166,34 @@ class TimeoutHelper { end_tick = 0; return; } - + u64 cur_tick = armGetSystemTick(); this->end_tick = cur_tick + NsToTick(ns) + 1; } - + static inline u64 NsToTick(u64 ns) { return (ns * 12) / 625; } - + static inline u64 TickToNs(u64 tick) { return (tick * 625) / 12; } - + u64 NsUntilTimeout() { u64 diff = TickToNs(this->end_tick - armGetSystemTick()); - + if (TimedOut()) { return 0; } - + return diff; } - + bool TimedOut() { if (this->end_tick == 0) { return true; } - + return armGetSystemTick() >= this->end_tick; } }; @@ -208,47 +209,47 @@ class HosSignal { mutexInit(&m); signaled = false; } - + void Signal() { mutexLock(&m); signaled = true; condvarWakeAll(&cv); mutexUnlock(&m); } - + void Reset() { mutexLock(&m); signaled = false; mutexUnlock(&m); } - + void Wait() { mutexLock(&m); - + while (!signaled) { condvarWait(&cv, &m); } - + mutexUnlock(&m); } - + bool TryWait() { mutexLock(&m); bool success = signaled; mutexUnlock(&m); return success; } - + Result TimedWait(u64 ns) { mutexLock(&m); TimeoutHelper timeout_helper(ns); - + while (!signaled) { if (R_FAILED(condvarWaitTimeout(&cv, &m, timeout_helper.NsUntilTimeout()))) { return false; } } - + mutexUnlock(&m); return true; } @@ -259,27 +260,25 @@ class HosThread { Thread thr = {}; public: HosThread() {} - + Result Initialize(ThreadFunc entry, void *arg, size_t stack_sz, int prio, int cpuid = -2) { return threadCreate(&this->thr, entry, arg, stack_sz, prio, cpuid); } - + Handle GetHandle() const { return this->thr.handle; } - + Result Start() { return threadStart(&this->thr); } - + Result Join() { - Result rc = threadWaitForExit(&this->thr); - if (R_SUCCEEDED(rc)) { - rc = threadClose(&this->thr); - } - return rc; + R_TRY(threadWaitForExit(&this->thr)); + R_TRY(threadClose(&this->thr)); + return ResultSuccess; } - + Result CancelSynchronization() { return svcCancelSynchronization(this->thr.handle); } diff --git a/include/stratosphere/ipc/ipc_serialization.hpp b/include/stratosphere/ipc/ipc_serialization.hpp index 4c856b89..e69dd991 100644 --- a/include/stratosphere/ipc/ipc_serialization.hpp +++ b/include/stratosphere/ipc/ipc_serialization.hpp @@ -572,11 +572,7 @@ constexpr Result WrapIpcCommandImpl(IpcResponseContext *ctx) { ipcInitialize(&ctx->reply); memset(ctx->out_data, 0, CommandMetaData::OutRawArgSize); - Result rc = Validator::Validate(ctx); - - if (R_FAILED(rc)) { - return rc; - } + R_TRY(Validator::Validate(ctx)); ClassType *this_ptr = nullptr; if (IsDomainObject(ctx->obj_holder)) { @@ -588,41 +584,19 @@ constexpr Result WrapIpcCommandImpl(IpcResponseContext *ctx) { return ResultServiceFrameworkTargetNotFound; } + size_t num_out_objects; std::shared_ptr out_objects[CommandMetaData::NumOutSessions]; - /* Allocate out object IDs. */ - size_t num_out_objects; - if (IsDomainObject(ctx->obj_holder)) { - for (num_out_objects = 0; num_out_objects < CommandMetaData::NumOutSessions; num_out_objects++) { - if (R_FAILED((rc = ctx->obj_holder->GetServiceObject()->ReserveObject(&ctx->out_object_ids[num_out_objects])))) { - break; - } - ctx->out_objs[num_out_objects] = &out_objects[num_out_objects]; - } - } else { - for (num_out_objects = 0; num_out_objects < CommandMetaData::NumOutSessions; num_out_objects++) { - Handle server_h, client_h; - if (R_FAILED((rc = SessionManagerBase::CreateSessionHandles(&server_h, &client_h)))) { - break; - } - ctx->out_object_server_handles[num_out_objects] = server_h; - ctx->out_handles[CommandMetaData::NumOutHandles + num_out_objects].handle = client_h; - ctx->out_objs[num_out_objects] = &out_objects[num_out_objects]; - } - } - - ON_SCOPE_EXIT { + auto cleanup_guard = SCOPE_GUARD { /* Clean up objects as necessary. */ - if (R_FAILED(rc)) { - if (IsDomainObject(ctx->obj_holder)) { - for (unsigned int i = 0; i < num_out_objects; i++) { - ctx->obj_holder->GetServiceObject()->FreeObject(ctx->out_object_ids[i]); - } - } else { - for (unsigned int i = 0; i < num_out_objects; i++) { - svcCloseHandle(ctx->out_object_server_handles[i]); - svcCloseHandle(ctx->out_handles[CommandMetaData::NumOutHandles + i].handle); - } + if (IsDomainObject(ctx->obj_holder)) { + for (unsigned int i = 0; i < num_out_objects; i++) { + ctx->obj_holder->GetServiceObject()->FreeObject(ctx->out_object_ids[i]); + } + } else { + for (unsigned int i = 0; i < num_out_objects; i++) { + svcCloseHandle(ctx->out_object_server_handles[i]); + svcCloseHandle(ctx->out_handles[CommandMetaData::NumOutHandles + i].handle); } } @@ -631,25 +605,48 @@ constexpr Result WrapIpcCommandImpl(IpcResponseContext *ctx) { } }; - if (R_SUCCEEDED(rc)) { + /* Allocate out object IDs. */ + if (IsDomainObject(ctx->obj_holder)) { + for (num_out_objects = 0; num_out_objects < CommandMetaData::NumOutSessions; num_out_objects++) { + R_TRY_CLEANUP(ctx->obj_holder->GetServiceObject()->ReserveObject(&ctx->out_object_ids[num_out_objects]), { + std::apply(Encoder::EncodeFailure, std::tuple_cat(std::make_tuple(ctx), std::make_tuple(R_CLEANUP_RESULT))); + }); + ctx->out_objs[num_out_objects] = &out_objects[num_out_objects]; + } + } else { + for (num_out_objects = 0; num_out_objects < CommandMetaData::NumOutSessions; num_out_objects++) { + Handle server_h, client_h; + R_TRY_CLEANUP(SessionManagerBase::CreateSessionHandles(&server_h, &client_h), { + std::apply(Encoder::EncodeFailure, std::tuple_cat(std::make_tuple(ctx), std::make_tuple(R_CLEANUP_RESULT))); + }); + ctx->out_object_server_handles[num_out_objects] = server_h; + ctx->out_handles[CommandMetaData::NumOutHandles + num_out_objects].handle = client_h; + ctx->out_objs[num_out_objects] = &out_objects[num_out_objects]; + } + } + + /* Decode, apply, encode. */ + { auto args = Decoder::Decode(ctx); if constexpr (CommandMetaData::ReturnsResult) { - rc = std::apply( [=](auto&&... args) { return (this_ptr->*IpcCommandImpl)(args...); }, args); + R_TRY_CLEANUP(std::apply( [=](auto&&... args) { return (this_ptr->*IpcCommandImpl)(args...); }, args), { + std::apply(Encoder::EncodeFailure, std::tuple_cat(std::make_tuple(ctx), std::make_tuple(R_CLEANUP_RESULT))); + }); } else { std::apply( [=](auto&&... args) { (this_ptr->*IpcCommandImpl)(args...); }, args); } - if (R_SUCCEEDED(rc)) { - std::apply(Encoder::EncodeSuccess, std::tuple_cat(std::make_tuple(ctx), args)); - } else { - std::apply(Encoder::EncodeFailure, std::tuple_cat(std::make_tuple(ctx), std::make_tuple(rc))); - } - } else { - std::apply(Encoder::EncodeFailure, std::tuple_cat(std::make_tuple(ctx), std::make_tuple(rc))); + std::apply(Encoder::EncodeSuccess, std::tuple_cat(std::make_tuple(ctx), args)); } - return rc; + /* Cancel object guard, clear remaining object references. */ + cleanup_guard.Cancel(); + for (unsigned int i = 0; i < num_out_objects; i++) { + ctx->out_objs[i] = nullptr; + } + + return ResultSuccess; } diff --git a/include/stratosphere/ipc/ipc_service_session.hpp b/include/stratosphere/ipc/ipc_service_session.hpp index 68455de6..758c4745 100644 --- a/include/stratosphere/ipc/ipc_service_session.hpp +++ b/include/stratosphere/ipc/ipc_service_session.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include @@ -38,14 +38,14 @@ class ServiceSession : public IWaitable ServiceObjectHolder obj_holder; ServiceObjectHolder control_holder = ServiceObjectHolder(std::make_shared(this)); u8 backup_tls[0x100]; - + ServiceSession(Handle s_h) : session_handle(s_h) { } public: template ServiceSession(Handle s_h, size_t pbs) : session_handle(s_h), pointer_buffer(pbs), obj_holder(std::make_shared()) { } - + ServiceSession(Handle s_h, size_t pbs, ServiceObjectHolder &&h) : session_handle(s_h), pointer_buffer(pbs), obj_holder(std::move(h)) { } - + virtual ~ServiceSession() override { svcCloseHandle(this->session_handle); } @@ -53,11 +53,11 @@ class ServiceSession : public IWaitable SessionManagerBase *GetSessionManager() { return static_cast(this->GetManager()); } - + DomainManager *GetDomainManager() { return static_cast(this->GetSessionManager()); } - + Result Receive() { int handle_index; /* Prepare pointer buffer... */ @@ -66,28 +66,26 @@ class ServiceSession : public IWaitable if (this->pointer_buffer.size() > 0) { ipcAddRecvStatic(&c, this->pointer_buffer.data(), this->pointer_buffer.size(), 0); ipcPrepareHeader(&c, 0); - + /* Fix libnx bug in serverside C descriptor handling. */ ((u32 *)armGetTls())[1] &= 0xFFFFC3FF; ((u32 *)armGetTls())[1] |= (2) << 10; } else { ipcPrepareHeader(&c, 0); } - + /* Receive. */ - Result rc = svcReplyAndReceive(&handle_index, &this->session_handle, 1, 0, U64_MAX); - if (R_SUCCEEDED(rc)) { - std::memcpy(this->backup_tls, armGetTls(), sizeof(this->backup_tls)); - } - - return rc; + R_TRY(svcReplyAndReceive(&handle_index, &this->session_handle, 1, 0, U64_MAX)); + + std::memcpy(this->backup_tls, armGetTls(), sizeof(this->backup_tls)); + return ResultSuccess; } - + Result Reply() { int handle_index; return svcReplyAndReceive(&handle_index, &this->session_handle, 0, this->session_handle, 0); } - + /* For preparing basic replies. */ Result PrepareBasicResponse(IpcResponseContext *ctx, Result rc) { ipcInitialize(&ctx->reply); @@ -95,12 +93,12 @@ class ServiceSession : public IWaitable u64 magic; u64 result; } *raw = (decltype(raw))ipcPrepareHeader(&ctx->reply, sizeof(*raw)); - + raw->magic = SFCO_MAGIC; raw->result = rc; return raw->result; } - + Result PrepareBasicDomainResponse(IpcResponseContext *ctx, Result rc) { ipcInitialize(&ctx->reply); struct { @@ -108,13 +106,13 @@ class ServiceSession : public IWaitable u64 magic; u64 result; } *raw = (decltype(raw))ipcPrepareHeader(&ctx->reply, sizeof(*raw)); - + raw->hdr = {}; raw->magic = SFCO_MAGIC; raw->result = rc; return raw->result; } - + /* For making a new response context. */ void InitializeResponseContext(IpcResponseContext *ctx) { std::memset(ctx, 0, sizeof(*ctx)); @@ -123,19 +121,18 @@ class ServiceSession : public IWaitable ctx->pb = this->pointer_buffer.data(); ctx->pb_size = this->pointer_buffer.size(); } - - /* IWaitable */ + + /* IWaitable */ virtual Handle GetHandle() { return this->session_handle; } - + virtual Result GetResponse(IpcResponseContext *ctx) { - Result rc = ResultKernelConnectionClosed; FirmwareVersion fw = GetRuntimeFirmwareVersion(); - + const ServiceCommandMeta *dispatch_table = ctx->obj_holder->GetDispatchTable(); size_t entry_count = ctx->obj_holder->GetDispatchTableEntryCount(); - + if (IsDomainObject(ctx->obj_holder)) { switch (ctx->request.InMessageType) { case DomainMessageType_Invalid: @@ -156,22 +153,22 @@ class ServiceSession : public IWaitable for (size_t i = 0; i < entry_count; i++) { if (ctx->cmd_id == dispatch_table[i].cmd_id && dispatch_table[i].fw_low <= fw && fw <= dispatch_table[i].fw_high) { - rc = dispatch_table[i].handler(ctx); + R_TRY(dispatch_table[i].handler(ctx)); break; } } - - return rc; + + return ResultSuccess; } - + virtual Result HandleReceived() { IpcResponseContext ctx; this->InitializeResponseContext(&ctx); - + ctx.cmd_type = (IpcCommandType)(*(u16 *)(armGetTls())); - + ctx.rc = ResultSuccess; - + /* Parse based on command type. */ switch (ctx.cmd_type) { case IpcCommandType_Invalid: @@ -201,14 +198,14 @@ class ServiceSession : public IWaitable default: return ResultKernelConnectionClosed; } - - + + if (R_SUCCEEDED(ctx.rc)) { ctx.cmd_id = ((u32 *)ctx.request.Raw)[2]; this->PreProcessRequest(&ctx); ctx.rc = this->GetResponse(&ctx); } - + if (ctx.rc == ResultServiceFrameworkRequestDeferredByUser) { /* Session defer. */ this->SetDeferred(true); @@ -218,124 +215,118 @@ class ServiceSession : public IWaitable if (R_SUCCEEDED(ctx.rc)) { this->PostProcessResponse(&ctx); } - + ctx.rc = this->Reply(); - + if (ctx.rc == ResultKernelTimedOut) { ctx.rc = ResultSuccess; } - + this->CleanupResponse(&ctx); } - + return ctx.rc; } - + virtual Result HandleDeferred() override { memcpy(armGetTls(), this->backup_tls, sizeof(this->backup_tls)); - Result rc = this->HandleReceived(); - - if (rc != ResultServiceFrameworkRequestDeferredByUser) { + + auto defer_guard = SCOPE_GUARD { this->SetDeferred(false); - } - return rc; + }; + + R_TRY_CATCH(this->HandleReceived()) { + R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { + defer_guard.Cancel(); + return ResultServiceFrameworkRequestDeferredByUser; + } + } R_END_TRY_CATCH; + + return ResultSuccess; } - + virtual Result HandleSignaled(u64 timeout) { - Result rc; - - if (R_SUCCEEDED(rc = this->Receive())) { - rc = this->HandleReceived(); - } - - return rc; + R_TRY(this->Receive()); + R_TRY(this->HandleReceived()); + return ResultSuccess; } - + virtual void PreProcessRequest(IpcResponseContext *ctx) { /* ... */ (void)(ctx); } - + virtual void PostProcessResponse(IpcResponseContext *ctx) { /* ... */ (void)(ctx); } - + virtual void CleanupResponse(IpcResponseContext *ctx) { std::memset(this->backup_tls, 0, sizeof(this->backup_tls)); } - + public: class IHipcControlService : public IServiceObject { private: ServiceSession *session; public: explicit IHipcControlService(ServiceSession *s) : session(s) { - + } - + virtual ~IHipcControlService() override { } - + Result ConvertCurrentObjectToDomain(Out object_id) { /* Allocate new domain. */ auto new_domain = this->session->GetDomainManager()->AllocateDomain(); if (new_domain == nullptr) { return ResultHipcOutOfDomains; } - + /* Reserve an object in the domain for our session. */ u32 reserved_id; - Result rc = new_domain->ReserveObject(&reserved_id); - if (R_FAILED(rc)) { - return rc; - } + R_TRY(new_domain->ReserveObject(&reserved_id)); new_domain->SetObject(reserved_id, std::move(this->session->obj_holder)); this->session->obj_holder = std::move(ServiceObjectHolder(std::move(new_domain))); - + /* Return the object id. */ object_id.SetValue(reserved_id); return ResultSuccess; } - + Result CopyFromCurrentDomain(Out out_h, u32 id) { auto domain = this->session->obj_holder.GetServiceObject(); if (domain == nullptr) { return ResultHipcTargetNotDomain; } - - + + auto object = domain->GetObject(id); if (object == nullptr) { return ResultHipcDomainObjectNotFound; } - + Handle server_h, client_h; - if (R_FAILED(SessionManagerBase::CreateSessionHandles(&server_h, &client_h))) { - /* N aborts here. Should we error code? */ - std::abort(); - } - + R_ASSERT(SessionManagerBase::CreateSessionHandles(&server_h, &client_h)); + this->session->GetSessionManager()->AddSession(server_h, std::move(object->Clone())); out_h.SetValue(client_h); return ResultSuccess; } - + void CloneCurrentObject(Out out_h) { Handle server_h, client_h; - if (R_FAILED(SessionManagerBase::CreateSessionHandles(&server_h, &client_h))) { - /* N aborts here. Should we error code? */ - std::abort(); - } - + R_ASSERT(SessionManagerBase::CreateSessionHandles(&server_h, &client_h)); + this->session->GetSessionManager()->AddSession(server_h, std::move(this->session->obj_holder.Clone())); out_h.SetValue(client_h); } - + void QueryPointerBufferSize(Out size) { size.SetValue(this->session->pointer_buffer.size()); } - + void CloneCurrentObjectEx(Out out_h, u32 which) { /* TODO: Figure out what this u32 controls. */ return CloneCurrentObject(out_h); diff --git a/include/stratosphere/mitm/mitm_server.hpp b/include/stratosphere/mitm/mitm_server.hpp index d6bff695..5fd688fb 100644 --- a/include/stratosphere/mitm/mitm_server.hpp +++ b/include/stratosphere/mitm/mitm_server.hpp @@ -41,9 +41,7 @@ class MitmServer : public IWaitable { DoWithSmMitmSession([&]() { strncpy(mitm_name, service_name, 8); mitm_name[8] = '\x00'; - if (R_FAILED(smMitMInstall(&this->port_handle, &query_h, mitm_name))) { - std::abort(); - } + R_ASSERT(smMitMInstall(&this->port_handle, &query_h, mitm_name)); }); #pragma GCC diagnostic pop @@ -53,9 +51,7 @@ class MitmServer : public IWaitable { virtual ~MitmServer() override { if (this->port_handle) { DoWithSmMitmSession([&]() { - if (R_FAILED(smMitMUninstall(this->mitm_name))) { - std::abort(); - } + R_ASSERT(smMitMUninstall(this->mitm_name)); }); svcCloseHandle(port_handle); } @@ -73,10 +69,7 @@ class MitmServer : public IWaitable { virtual Result HandleSignaled(u64 timeout) override { /* If this server's port was signaled, accept a new session. */ Handle session_h; - Result rc = svcAcceptSession(&session_h, this->port_handle); - if (R_FAILED(rc)) { - return rc; - } + R_TRY(svcAcceptSession(&session_h, this->port_handle)); /* Create a forward service for this instance. */ std::shared_ptr forward_service(new Service(), [](Service *s) { @@ -88,9 +81,7 @@ class MitmServer : public IWaitable { u64 client_pid; DoWithSmMitmSession([&]() { - if (R_FAILED(smMitMAcknowledgeSession(forward_service.get(), &client_pid, mitm_name))) { - std::abort(); - } + R_ASSERT(smMitMAcknowledgeSession(forward_service.get(), &client_pid, mitm_name)); }); this->GetSessionManager()->AddWaitable(new MitmSession(session_h, client_pid, forward_service, MakeShared(forward_service, client_pid))); diff --git a/include/stratosphere/mitm/mitm_session.hpp b/include/stratosphere/mitm/mitm_session.hpp index d9bfe18f..69689c48 100644 --- a/include/stratosphere/mitm/mitm_session.hpp +++ b/include/stratosphere/mitm/mitm_session.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include @@ -26,14 +26,14 @@ class MitmSession final : public ServiceSession { private: /* This will be for the actual session. */ std::shared_ptr forward_service; - + struct PostProcessHandlerContext { bool closed; void (*handler)(IMitmServiceObject *, IpcResponseContext *); - }; + }; /* Store a handler for the service. */ std::shared_ptr service_post_process_ctx; - + /* For cleanup usage. */ u64 client_pid; u32 num_fwd_copy_hnds = 0; @@ -43,36 +43,32 @@ class MitmSession final : public ServiceSession { MitmSession(Handle s_h, u64 pid, std::shared_ptr fs, std::shared_ptr srv) : ServiceSession(s_h), client_pid(pid) { this->forward_service = std::move(fs); this->obj_holder = std::move(ServiceObjectHolder(std::move(srv))); - + this->service_post_process_ctx = std::make_shared(); this->service_post_process_ctx->closed = false; this->service_post_process_ctx->handler = T::PostProcess; - + size_t pbs; - if (R_FAILED(ipcQueryPointerBufferSize(forward_service->handle, &pbs))) { - std::abort(); - } + R_ASSERT(ipcQueryPointerBufferSize(forward_service->handle, &pbs)); this->pointer_buffer.resize(pbs); this->control_holder.Reset(); this->control_holder = std::move(ServiceObjectHolder(std::move(std::make_shared(this)))); } - + MitmSession(Handle s_h, u64 pid, std::shared_ptr fs, ServiceObjectHolder &&h, std::shared_ptr ppc) : ServiceSession(s_h), client_pid(pid) { this->session_handle = s_h; this->forward_service = std::move(fs); this->obj_holder = std::move(h); - + this->service_post_process_ctx = ppc; - + size_t pbs; - if (R_FAILED(ipcQueryPointerBufferSize(forward_service->handle, &pbs))) { - std::abort(); - } + R_ASSERT(ipcQueryPointerBufferSize(forward_service->handle, &pbs)); this->pointer_buffer.resize(pbs); this->control_holder.Reset(); this->control_holder = std::move(ServiceObjectHolder(std::move(std::make_shared(this)))); } - + virtual void PreProcessRequest(IpcResponseContext *ctx) override { u32 *cmdbuf = (u32 *)armGetTls(); u32 *backup_cmdbuf = (u32 *)this->backup_tls; @@ -82,12 +78,15 @@ class MitmSession final : public ServiceSession { backup_cmdbuf[4] = cmdbuf[4]; } } - + Result ForwardRequest(IpcResponseContext *ctx) { - IpcParsedCommand r; - Result rc = serviceIpcDispatch(this->forward_service.get()); - if (R_SUCCEEDED(rc)) { - if (ctx->request.IsDomainRequest) { + /* Dispatch forwards. */ + R_TRY(serviceIpcDispatch(this->forward_service.get())); + + /* Parse. */ + { + IpcParsedCommand r; + if (ctx->request.IsDomainRequest) { /* We never work with out object ids, so this should be fine. */ ipcParseDomainResponse(&r, 0); } else { @@ -99,24 +98,24 @@ class MitmSession final : public ServiceSession { u64 result; } *resp = (decltype(resp))r.Raw; - rc = resp->result; - for (unsigned int i = 0; i < r.NumHandles; i++) { if (r.WasHandleCopied[i]) { this->fwd_copy_hnds[num_fwd_copy_hnds++] = r.Handles[i]; } } + + R_TRY(resp->result); } - return rc; + + return ResultSuccess; } virtual Result GetResponse(IpcResponseContext *ctx) { - Result rc = ResultKernelConnectionClosed; FirmwareVersion fw = GetRuntimeFirmwareVersion(); - + const ServiceCommandMeta *dispatch_table = ctx->obj_holder->GetDispatchTable(); size_t entry_count = ctx->obj_holder->GetDispatchTableEntryCount(); - + if (IsDomainObject(ctx->obj_holder)) { switch (ctx->request.InMessageType) { case DomainMessageType_Invalid: @@ -125,56 +124,61 @@ class MitmSession final : public ServiceSession { { auto sub_obj = ctx->obj_holder->GetServiceObject()->GetObject(ctx->request.InThisObjectId); if (sub_obj == nullptr) { - rc = ForwardRequest(ctx); - return rc; + R_TRY(ForwardRequest(ctx)); + return ResultSuccess; } if (sub_obj->IsMitmObject()) { - rc = ForwardRequest(ctx); - if (R_SUCCEEDED(rc)) { - ctx->obj_holder->GetServiceObject()->FreeObject(ctx->request.InThisObjectId); - } + R_TRY(ForwardRequest(ctx)); + ctx->obj_holder->GetServiceObject()->FreeObject(ctx->request.InThisObjectId); } else { - rc = ctx->obj_holder->GetServiceObject()->FreeObject(ctx->request.InThisObjectId); + R_TRY(ctx->obj_holder->GetServiceObject()->FreeObject(ctx->request.InThisObjectId)); } - if (R_SUCCEEDED(rc) && ctx->request.InThisObjectId == serviceGetObjectId(this->forward_service.get()) && !this->service_post_process_ctx->closed) { + if (ctx->request.InThisObjectId == serviceGetObjectId(this->forward_service.get()) && !this->service_post_process_ctx->closed) { /* If we're not longer MitMing anything, we'll no longer do any postprocessing. */ this->service_post_process_ctx->closed = true; } - return rc; + return ResultSuccess; } case DomainMessageType_SendMessage: { auto sub_obj = ctx->obj_holder->GetServiceObject()->GetObject(ctx->request.InThisObjectId); if (sub_obj == nullptr) { - rc = ForwardRequest(ctx); - return rc; + R_TRY(ForwardRequest(ctx)); + return ResultSuccess; } dispatch_table = sub_obj->GetDispatchTable(); entry_count = sub_obj->GetDispatchTableEntryCount(); } } } - - bool found_entry = false; + + Result (*handler)(IpcResponseContext *ctx) = nullptr; for (size_t i = 0; i < entry_count; i++) { if (ctx->cmd_id == dispatch_table[i].cmd_id && dispatch_table[i].fw_low <= fw && fw <= dispatch_table[i].fw_high) { - rc = dispatch_table[i].handler(ctx); - found_entry = true; + handler = dispatch_table[i].handler; break; } } - - if (!found_entry || rc == ResultAtmosphereMitmShouldForwardToSession) { - memcpy(armGetTls(), this->backup_tls, sizeof(this->backup_tls)); - rc = ForwardRequest(ctx); + + if (handler == nullptr) { + R_TRY(ForwardRequest(ctx)); + return ResultSuccess; } - - return rc; + + R_TRY_CATCH(handler(ctx)) { + R_CATCH(ResultAtmosphereMitmShouldForwardToSession) { + std::memcpy(armGetTls(), this->backup_tls, sizeof(this->backup_tls)); + R_TRY(ForwardRequest(ctx)); + return ResultSuccess; + } + } R_END_TRY_CATCH; + + return ResultSuccess; } - + virtual void PostProcessResponse(IpcResponseContext *ctx) override { if ((ctx->cmd_type == IpcCommandType_Request || ctx->cmd_type == IpcCommandType_RequestWithContext) && R_SUCCEEDED(ctx->rc)) { if (this->service_post_process_ctx->closed) { @@ -197,11 +201,11 @@ class MitmSession final : public ServiceSession { } } } - + virtual void CleanupResponse(IpcResponseContext *ctx) override { /* Cleanup tls backup. */ std::memset(this->backup_tls, 0, sizeof(this->backup_tls)); - + /* Clean up copy handles. */ for (unsigned int i = 0; i < ctx->request.NumHandles; i++) { if (ctx->request.WasHandleCopied[i]) { @@ -213,16 +217,16 @@ class MitmSession final : public ServiceSession { } this->num_fwd_copy_hnds = 0; } - + public: class IMitmHipcControlService : public IServiceObject { private: MitmSession *session; public: explicit IMitmHipcControlService(MitmSession *s) : session(s) { - + } - + virtual ~IMitmHipcControlService() override { } public: @@ -230,40 +234,37 @@ class MitmSession final : public ServiceSession { if (IsDomainObject(this->session->obj_holder)) { return ResultKernelConnectionClosed; } - - Result rc = serviceConvertToDomain(this->session->forward_service.get()); - if (R_FAILED(rc)) { - return rc; - } - + + R_TRY(serviceConvertToDomain(this->session->forward_service.get())); + u32 expected_id = serviceGetObjectId(this->session->forward_service.get()); - + /* Allocate new domain. */ auto new_domain = this->session->GetDomainManager()->AllocateDomain(); if (new_domain == nullptr) { /* If our domains mismatch, we're in trouble. */ return ResultKernelConnectionClosed; } - + /* Reserve the expected object in the domain for our session. */ if (R_FAILED(new_domain->ReserveSpecificObject(expected_id))) { return ResultKernelConnectionClosed; } new_domain->SetObject(expected_id, std::move(this->session->obj_holder)); this->session->obj_holder = std::move(ServiceObjectHolder(std::move(new_domain))); - + /* Return the object id. */ object_id.SetValue(expected_id); return ResultSuccess; } - + Result CopyFromCurrentDomain(Out out_h, u32 id) { auto domain = this->session->obj_holder.GetServiceObject(); if (domain == nullptr) { return ResultHipcTargetNotDomain; } - - + + auto object = domain->GetObject(id); if (object == nullptr) { /* Forward onwards. */ @@ -276,31 +277,26 @@ class MitmSession final : public ServiceSession { buf[7] = 0; buf[8] = id; buf[9] = 0; - Result rc = ipcDispatch(this->session->forward_service->handle); - if (R_SUCCEEDED(rc)) { + R_TRY(ipcDispatch(this->session->forward_service->handle)); + { IpcParsedCommand r; ipcParse(&r); struct { u64 magic; u64 result; } *raw = (decltype(raw))r.Raw; - rc = raw->result; - - if (R_SUCCEEDED(rc)) { - out_h.SetValue(r.Handles[0]); - this->session->fwd_copy_hnds[this->session->num_fwd_copy_hnds++] = r.Handles[0]; - } + R_TRY(raw->result); + + out_h.SetValue(r.Handles[0]); + this->session->fwd_copy_hnds[this->session->num_fwd_copy_hnds++] = r.Handles[0]; } - return rc; + return ResultSuccess; } - + Handle server_h, client_h; - if (R_FAILED(SessionManagerBase::CreateSessionHandles(&server_h, &client_h))) { - /* N aborts here. Should we error code? */ - std::abort(); - } + R_ASSERT(SessionManagerBase::CreateSessionHandles(&server_h, &client_h)); out_h.SetValue(client_h); - + if (id == serviceGetObjectId(this->session->forward_service.get())) { this->session->GetSessionManager()->AddWaitable(new MitmSession(server_h, this->session->client_pid, this->session->forward_service, std::move(object->Clone()), this->session->service_post_process_ctx)); } else { @@ -308,27 +304,24 @@ class MitmSession final : public ServiceSession { } return ResultSuccess; } - + void CloneCurrentObject(Out out_h) { Handle server_h, client_h; - if (R_FAILED(SessionManagerBase::CreateSessionHandles(&server_h, &client_h))) { - /* N aborts here. Should we error code? */ - std::abort(); - } - + R_ASSERT(SessionManagerBase::CreateSessionHandles(&server_h, &client_h)); + this->session->GetSessionManager()->AddWaitable(new MitmSession(server_h, this->session->client_pid, this->session->forward_service, std::move(this->session->obj_holder.Clone()), this->session->service_post_process_ctx)); out_h.SetValue(client_h); } - + void QueryPointerBufferSize(Out size) { size.SetValue(this->session->pointer_buffer.size()); } - + void CloneCurrentObjectEx(Out out_h, u32 which) { /* TODO: Figure out what this u32 controls. */ return CloneCurrentObject(out_h); } - + public: DEFINE_SERVICE_DISPATCH_TABLE { MakeServiceCommandMeta(), diff --git a/include/stratosphere/results/utilities.h b/include/stratosphere/results/utilities.h index 2e1c9b92..2638dc09 100644 --- a/include/stratosphere/results/utilities.h +++ b/include/stratosphere/results/utilities.h @@ -75,12 +75,14 @@ extern "C" { }) /// Evaluates an expression that returns a result, and returns the result (after evaluating a cleanup expression) if it would fail. +#define R_CLEANUP_RESULT _tmp_r_try_cleanup_rc + #define R_TRY_CLEANUP(res_expr, cleanup_expr) \ ({ \ - const Result _tmp_r_try_cleanup_rc = res_expr; \ - if (R_FAILED(_tmp_r_try_cleanup_rc)) { \ + const Result R_CLEANUP_RESULT = res_expr; \ + if (R_FAILED(R_CLEANUP_RESULT)) { \ ({ cleanup_expr }); \ - return _tmp_r_try_cleanup_rc; \ + return R_CLEANUP_RESULT; \ } \ }) diff --git a/include/stratosphere/servers.hpp b/include/stratosphere/servers.hpp index 3ed59653..52292790 100644 --- a/include/stratosphere/servers.hpp +++ b/include/stratosphere/servers.hpp @@ -49,10 +49,7 @@ class IServer : public IWaitable { virtual Result HandleSignaled(u64 timeout) override { /* If this server's port was signaled, accept a new session. */ Handle session_h; - Result rc = svcAcceptSession(&session_h, this->port_handle); - if (R_FAILED(rc)) { - return rc; - } + R_TRY(svcAcceptSession(&session_h, this->port_handle)); this->GetSessionManager()->AddSession(session_h, std::move(ServiceObjectHolder(std::move(MakeShared())))); return ResultSuccess; @@ -64,9 +61,7 @@ class ServiceServer : public IServer { public: ServiceServer(const char *service_name, unsigned int max_s) : IServer(max_s) { DoWithSmSession([&]() { - if (R_FAILED(smRegisterService(&this->port_handle, service_name, false, this->max_sessions))) { - std::abort(); - } + R_ASSERT(smRegisterService(&this->port_handle, service_name, false, this->max_sessions)); }); } }; @@ -83,8 +78,6 @@ template > class ManagedPortServer : public IServer { public: ManagedPortServer(const char *service_name, unsigned int max_s) : IServer(max_s) { - if (R_FAILED(svcManageNamedPort(&this->port_handle, service_name, this->max_sessions))) { - std::abort(); - } + R_ASSERT(svcManageNamedPort(&this->port_handle, service_name, this->max_sessions)); } }; \ No newline at end of file diff --git a/include/stratosphere/utilities.hpp b/include/stratosphere/utilities.hpp index 98ccdccf..3d1f3dc0 100644 --- a/include/stratosphere/utilities.hpp +++ b/include/stratosphere/utilities.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include @@ -70,51 +70,41 @@ static inline Result SmcGetConfig(SplConfigItem config_item, u64 *out_config) { args.X[0] = 0xC3000002; /* smcGetConfig */ args.X[1] = (u64)config_item; /* config item */ - Result rc = svcCallSecureMonitor(&args); - if (R_SUCCEEDED(rc)) { - if (args.X[0] == 0) { - if (out_config) { - *out_config = args.X[1]; - } - } else { - /* SPL result n = SMC result n */ - rc = MAKERESULT(26, args.X[0]); - } + R_TRY(svcCallSecureMonitor(&args)); + if (args.X[0] != 0) { + /* SPL result n = SMC result n */ + return MAKERESULT(26, args.X[0]); } - return rc; + + if (out_config) { + *out_config = args.X[1]; + } + return ResultSuccess; } static inline Result GetRcmBugPatched(bool *out) { u64 tmp = 0; - Result rc = SmcGetConfig((SplConfigItem)65004, &tmp); - if (R_SUCCEEDED(rc)) { - *out = (tmp != 0); - } - return rc; + R_TRY(SmcGetConfig((SplConfigItem)65004, &tmp)); + *out = (tmp != 0); + return ResultSuccess; } static inline bool IsRcmBugPatched() { bool rcm_bug_patched; - if (R_FAILED(GetRcmBugPatched(&rcm_bug_patched))) { - std::abort(); - } + R_ASSERT(GetRcmBugPatched(&rcm_bug_patched)); return rcm_bug_patched; } static inline Result GetShouldBlankProdInfo(bool *out) { u64 tmp = 0; - Result rc = SmcGetConfig((SplConfigItem)65005, &tmp); - if (R_SUCCEEDED(rc)) { - *out = (tmp != 0); - } - return rc; + R_TRY(SmcGetConfig((SplConfigItem)65005, &tmp)); + *out = (tmp != 0); + return ResultSuccess; } static inline bool ShouldBlankProdInfo() { bool should_blank_prodinfo; - if (R_FAILED(GetShouldBlankProdInfo(&should_blank_prodinfo))) { - std::abort(); - } + R_ASSERT(GetShouldBlankProdInfo(&should_blank_prodinfo)); return should_blank_prodinfo; } @@ -125,13 +115,8 @@ template static void DoWithSmSession(F f) { std::scoped_lock lk(GetSmSessionMutex()); { - Result rc; - if (R_SUCCEEDED((rc = smInitialize()))) { - f(); - } else { - /* TODO: fatalSimple(rc); ? */ - std::abort(); - } + R_ASSERT(smInitialize()); + f(); smExit(); } } @@ -140,13 +125,8 @@ template static void DoWithSmMitmSession(F f) { std::scoped_lock lk(GetSmMitmSessionMutex()); { - Result rc; - if (R_SUCCEEDED((rc = smMitMInitialize()))) { - f(); - } else { - /* TODO: fatalSimple(rc); ? */ - std::abort(); - } + R_ASSERT(smMitMInitialize()); + f(); smMitMExit(); } } diff --git a/include/stratosphere/waitable_manager.hpp b/include/stratosphere/waitable_manager.hpp index d0ae8c2f..a39e3524 100644 --- a/include/stratosphere/waitable_manager.hpp +++ b/include/stratosphere/waitable_manager.hpp @@ -75,16 +75,11 @@ class WaitableManager : public SessionManagerBase { public: WaitableManager(u32 n, u32 ss = 0x8000) : num_extra_threads(n-1) { u32 prio; - Result rc; if (num_extra_threads) { threads = new HosThread[num_extra_threads]; - if (R_FAILED((rc = svcGetThreadPriority(&prio, CUR_THREAD_HANDLE)))) { - fatalSimple(rc); - } + R_ASSERT(svcGetThreadPriority(&prio, CUR_THREAD_HANDLE)); for (unsigned int i = 0; i < num_extra_threads; i++) { - if (R_FAILED(threads[i].Initialize(&WaitableManager::ProcessLoop, this, ss, prio))) { - std::abort(); - } + R_ASSERT(threads[i].Initialize(&WaitableManager::ProcessLoop, this, ss, prio)); } } } @@ -130,11 +125,8 @@ class WaitableManager : public SessionManagerBase { /* Set main thread handle. */ this->main_thread_handle = GetCurrentThreadHandle(); - Result rc; for (unsigned int i = 0; i < num_extra_threads; i++) { - if (R_FAILED((rc = threads[i].Start()))) { - fatalSimple(rc); - } + R_ASSERT(threads[i].Start()); } ProcessLoop(this); @@ -167,8 +159,7 @@ class WaitableManager : public SessionManagerBase { } } if (w) { - Result rc = w->HandleSignaled(0); - if (rc == ResultKernelConnectionClosed) { + if (w->HandleSignaled(0) == ResultKernelConnectionClosed) { /* Close! */ delete w; } else { @@ -189,11 +180,11 @@ class WaitableManager : public SessionManagerBase { undeferred_any = false; for (auto it = this_ptr->deferred_waitables.begin(); it != this_ptr->deferred_waitables.end();) { auto w = *it; - Result rc = w->HandleDeferred(); - if (rc == ResultKernelConnectionClosed || !w->IsDeferred()) { + const bool closed = (w->HandleDeferred() == ResultKernelConnectionClosed); + if (closed || !w->IsDeferred()) { /* Remove from the deferred list, set iterator. */ it = this_ptr->deferred_waitables.erase(it); - if (rc == ResultKernelConnectionClosed) { + if (closed) { /* Delete the closed waitable. */ delete w; } else { @@ -249,7 +240,6 @@ class WaitableManager : public SessionManagerBase { std::vector wait_list; int handle_index = 0; - Result rc; while (result == nullptr) { /* Sort waitables by priority. */ std::sort(this->waitables.begin(), this->waitables.end(), IWaitable::Compare); @@ -269,21 +259,21 @@ class WaitableManager : public SessionManagerBase { } /* Wait forever. */ - rc = svcWaitSynchronization(&handle_index, handles.data(), num_handles, U64_MAX); + const Result wait_res = svcWaitSynchronization(&handle_index, handles.data(), num_handles, U64_MAX); if (this->should_stop) { return nullptr; } - if (R_SUCCEEDED(rc)) { + if (R_SUCCEEDED(wait_res)) { IWaitable *w = wait_list[handle_index]; size_t w_ind = std::distance(this->waitables.begin(), std::find(this->waitables.begin(), this->waitables.end(), w)); std::for_each(waitables.begin(), waitables.begin() + w_ind + 1, std::mem_fn(&IWaitable::UpdatePriority)); result = w; - } else if (rc == ResultKernelTimedOut) { + } else if (wait_res == ResultKernelTimedOut) { /* Timeout: Just update priorities. */ std::for_each(waitables.begin(), waitables.end(), std::mem_fn(&IWaitable::UpdatePriority)); - } else if (rc == ResultKernelCancelled) { + } else if (wait_res == ResultKernelCancelled) { /* svcCancelSynchronization was called. */ AddWaitablesInternal(); { diff --git a/source/emummc_utilities.cpp b/source/emummc_utilities.cpp index cef3b9af..ba73ae13 100644 --- a/source/emummc_utilities.cpp +++ b/source/emummc_utilities.cpp @@ -74,20 +74,21 @@ static void _CacheValues(void) char file_path[EmummcMaxDirLength+1]; char nintendo_path[EmummcMaxDirLength+1]; } __attribute__((aligned(0x1000))) paths; - + { SecmonArgs args = {0}; args.X[0] = 0xF0000404; /* smcAmsGetEmunandConfig */ args.X[1] = 0; /* NAND */ args.X[2] = reinterpret_cast(&paths); /* path output */ - if (R_FAILED(svcCallSecureMonitor(&args)) || args.X[0] != 0) { + R_ASSERT(svcCallSecureMonitor(&args)); + if (args.X[0] != 0) { std::abort(); } std::memcpy(&g_exo_emummc_config, &args.X[1], sizeof(args) - sizeof(args.X[0])); } - + const EmummcType emummc_type = static_cast(g_exo_emummc_config.base_cfg.type); - + /* Ignore format warnings. */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" @@ -98,11 +99,11 @@ static void _CacheValues(void) default: break; } - + std::snprintf(g_exo_emummc_config.emu_dir_path, sizeof(g_exo_emummc_config.emu_dir_path), "/%s", paths.nintendo_path); - + g_IsEmummc = g_exo_emummc_config.base_cfg.magic == EmummcStorageMagic && emummc_type != EmummcType_Emmc; - + /* Default Nintendo redirection path. */ if (g_IsEmummc) { if (std::strcmp(g_exo_emummc_config.emu_dir_path, "/") == 0) { diff --git a/source/firmware_version.cpp b/source/firmware_version.cpp index 53e3f9e4..77b3a562 100644 --- a/source/firmware_version.cpp +++ b/source/firmware_version.cpp @@ -39,7 +39,8 @@ static void _CacheValues(void) SecmonArgs args = {0}; args.X[0] = 0xC3000002; /* smcGetConfig */ args.X[1] = 65000; /* ConfigItem_ExosphereVersion */ - if (R_FAILED(svcCallSecureMonitor(&args)) || args.X[0] != 0) { + R_ASSERT(svcCallSecureMonitor(&args)); + if (args.X[0] != 0) { std::abort(); } diff --git a/source/mitm_query_service.cpp b/source/mitm_query_service.cpp index 83e6add8..619ada30 100644 --- a/source/mitm_query_service.cpp +++ b/source/mitm_query_service.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include @@ -23,20 +23,21 @@ static std::vector g_known_tids; static HosMutex g_pid_tid_mutex; Result MitmQueryUtils::GetAssociatedTidForPid(u64 pid, u64 *tid) { - Result rc = ResultAtmosphereMitmProcessNotAssociated; - std::scoped_lock lk{g_pid_tid_mutex}; + std::scoped_lock lk(g_pid_tid_mutex); + for (unsigned int i = 0; i < g_known_pids.size(); i++) { if (g_known_pids[i] == pid) { *tid = g_known_tids[i]; - rc = ResultSuccess; - break; + return ResultSuccess; } } - return rc; + + return ResultAtmosphereMitmProcessNotAssociated; } void MitmQueryUtils::AssociatePidToTid(u64 pid, u64 tid) { - std::scoped_lock lk{g_pid_tid_mutex}; + std::scoped_lock lk(g_pid_tid_mutex); + g_known_pids.push_back(pid); g_known_tids.push_back(tid); } diff --git a/source/mitm_server.cpp b/source/mitm_server.cpp index c5692478..cc636c27 100644 --- a/source/mitm_server.cpp +++ b/source/mitm_server.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include @@ -28,23 +28,19 @@ static void ServerQueryManagerThreadFunc(void *arg) { void RegisterMitmServerQueryHandle(Handle query_h, ServiceObjectHolder &&service) { std::scoped_lock lock(g_server_query_mutex); - + const bool exists = g_server_query_manager != nullptr; if (!exists) { /* Create a new waitable manager if it doesn't exist already. */ g_server_query_manager = new WaitableManager(1); } - + /* Add session to the manager. */ g_server_query_manager->AddSession(query_h, std::move(service)); - + /* If this is our first time, launch thread. */ if (!exists) { - if (R_FAILED(g_server_query_manager_thread.Initialize(&ServerQueryManagerThreadFunc, nullptr, 0x4000, 27))) { - std::abort(); - } - if (R_FAILED(g_server_query_manager_thread.Start())) { - std::abort(); - } + R_ASSERT(g_server_query_manager_thread.Initialize(&ServerQueryManagerThreadFunc, nullptr, 0x4000, 27)); + R_ASSERT(g_server_query_manager_thread.Start()); } } \ No newline at end of file diff --git a/source/on_crash.cpp b/source/on_crash.cpp index 54d898b9..9dab2652 100644 --- a/source/on_crash.cpp +++ b/source/on_crash.cpp @@ -120,14 +120,9 @@ void StratosphereCrashHandler(ThreadExceptionDump *ctx) { /* Default exception handler behavior. */ void __attribute__((weak)) __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx) { - Result rc = bpcAmsInitialize(); - if (R_SUCCEEDED(rc)) { - rc = bpcAmsRebootToFatalError(ctx); - bpcAmsExit(); - } - if (R_FAILED(rc)) { - std::abort(); - } + R_ASSERT(bpcAmsInitialize()); + R_ASSERT(bpcAmsRebootToFatalError(ctx)); + bpcAmsExit(); while (1) { } } diff --git a/source/random.cpp b/source/random.cpp index 8bd83304..0d442c15 100644 --- a/source/random.cpp +++ b/source/random.cpp @@ -34,9 +34,7 @@ class XorShiftGenerator { /* Seed using process entropy. */ u64 val = 0; for (size_t i = 0; i < num_seed_dwords; i++) { - if (R_FAILED(svcGetInfo(&val, 0xB, 0, i))) { - std::abort(); - } + R_ASSERT(svcGetInfo(&val, 0xB, 0, i)); this->random_state[i] = result_type(val); } }