diff --git a/nx/include/switch.h b/nx/include/switch.h index 1a21e546..f93296ca 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -155,6 +155,7 @@ extern "C" { #include "switch/runtime/env.h" #include "switch/runtime/hosversion.h" +#include "switch/runtime/diag.h" #include "switch/runtime/nxlink.h" #include "switch/runtime/resolver.h" #include "switch/runtime/ringcon.h" diff --git a/nx/include/switch/runtime/diag.h b/nx/include/switch/runtime/diag.h new file mode 100644 index 00000000..fde2426e --- /dev/null +++ b/nx/include/switch/runtime/diag.h @@ -0,0 +1,15 @@ +/** + * @file diag.h + * @brief Debugging and diagnostics utilities + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../result.h" + +/** + * @brief Aborts program execution with a result code. + * @param[in] res Result code. + */ +void NORETURN diagAbortWithResult(Result res); diff --git a/nx/source/display/default_window.c b/nx/source/display/default_window.c index 9e0e859a..d7ed7c85 100644 --- a/nx/source/display/default_window.c +++ b/nx/source/display/default_window.c @@ -2,7 +2,7 @@ #include "types.h" #include "result.h" #include "services/vi.h" -#include "services/fatal.h" +#include "runtime/diag.h" #include "display/binder.h" #include "display/buffer_producer.h" #include "display/native_window.h" @@ -42,7 +42,7 @@ void __nx_win_init(void) viExit(); } if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadGfxInit)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadGfxInit)); } void __nx_win_exit(void) diff --git a/nx/source/display/framebuffer.c b/nx/source/display/framebuffer.c index 9a24e6a2..25043812 100644 --- a/nx/source/display/framebuffer.c +++ b/nx/source/display/framebuffer.c @@ -3,9 +3,9 @@ #include "types.h" #include "result.h" #include "arm/cache.h" -#include "services/fatal.h" #include "services/nv.h" #include "services/vi.h" +#include "runtime/diag.h" #include "display/binder.h" #include "display/buffer_producer.h" #include "display/native_window.h" @@ -154,7 +154,7 @@ void* framebufferBegin(Framebuffer* fb, u32* out_stride) s32 slot; Result rc = nwindowDequeueBuffer(fb->win, &slot, NULL); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadGfxDequeueBuffer)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadGfxDequeueBuffer)); if (out_stride) *out_stride = fb->stride; @@ -223,5 +223,5 @@ void framebufferEnd(Framebuffer* fb) Result rc = nwindowQueueBuffer(fb->win, fb->win->cur_slot, NULL); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadGfxQueueBuffer)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadGfxQueueBuffer)); } diff --git a/nx/source/kernel/random.c b/nx/source/kernel/random.c index 49335da5..6d875ae7 100644 --- a/nx/source/kernel/random.c +++ b/nx/source/kernel/random.c @@ -9,11 +9,11 @@ #include #include "types.h" #include "result.h" -#include "services/fatal.h" #include "kernel/mutex.h" #include "kernel/svc.h" #include "kernel/random.h" #include "runtime/env.h" +#include "runtime/diag.h" #define ROTL32(x, n) (((x) << (n)) | ((x) >> (32-(n)))) @@ -137,7 +137,7 @@ static void _randomInit(void) { // Get process TRNG seeds from kernel. if (R_FAILED(svcGetInfo(&seed[i], InfoType_RandomEntropy, INVALID_HANDLE, i))) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Rng)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Rng)); } if (envHasRandomSeed()) diff --git a/nx/source/kernel/thread.c b/nx/source/kernel/thread.c index b5d6ed55..32581d93 100644 --- a/nx/source/kernel/thread.c +++ b/nx/source/kernel/thread.c @@ -8,8 +8,8 @@ #include "kernel/mutex.h" #include "kernel/thread.h" #include "kernel/wait.h" -#include "services/fatal.h" #include "runtime/env.h" +#include "runtime/diag.h" #include "../internal.h" #define USER_TLS_BEGIN 0x108 @@ -192,7 +192,7 @@ Result threadCreate( void threadExit(void) { Thread* t = getThreadVars()->thread_ptr; if (!t) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_NotInitialized)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_NotInitialized)); u64 tls_mask = __atomic_load_n(&g_tlsUsageMask, __ATOMIC_SEQ_CST); for (s32 i = 0; i < NUM_TLS_SLOTS; i ++) { diff --git a/nx/source/kernel/tmem.c b/nx/source/kernel/tmem.c index 9c7aae53..e5a9f7fe 100644 --- a/nx/source/kernel/tmem.c +++ b/nx/source/kernel/tmem.c @@ -6,7 +6,7 @@ #include "kernel/svc.h" #include "kernel/tmem.h" #include "kernel/virtmem.h" -#include "services/fatal.h" +#include "runtime/diag.h" Result tmemCreate(TransferMemory* t, size_t size, Permission perm) { diff --git a/nx/source/kernel/virtmem.c b/nx/source/kernel/virtmem.c index eaa43818..74a48275 100644 --- a/nx/source/kernel/virtmem.c +++ b/nx/source/kernel/virtmem.c @@ -1,10 +1,10 @@ #include "types.h" #include "result.h" -#include "services/fatal.h" #include "kernel/mutex.h" #include "kernel/svc.h" #include "kernel/virtmem.h" #include "kernel/random.h" +#include "runtime/diag.h" #define SEQUENTIAL_GUARD_REGION_SIZE 0x1000 #define RANDOM_MAX_ATTEMPTS 0x200 @@ -63,7 +63,7 @@ NX_INLINE bool _memregionIsUnmapped(uintptr_t start, uintptr_t end, uintptr_t gu u32 pageinfo; Result rc = svcQueryMemory(&meminfo, &pageinfo, start); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadQueryMemory)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadQueryMemory)); // Return error if there's anything mapped. uintptr_t memend = meminfo.addr + meminfo.size; @@ -121,14 +121,14 @@ void virtmemSetup(void) { rc = _memregionInitWithInfo(&g_AliasRegion, InfoType_AliasRegionAddress, InfoType_AliasRegionSize); if (R_FAILED(rc)) { // Wat. - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_WeirdKernel)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_WeirdKernel)); } // Retrieve memory region information for the reserved heap region. rc = _memregionInitWithInfo(&g_HeapRegion, InfoType_HeapRegionAddress, InfoType_HeapRegionSize); if (R_FAILED(rc)) { // Wat. - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Heap)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Heap)); } // Retrieve memory region information for the aslr/stack regions if available [2.0.0+] @@ -136,7 +136,7 @@ void virtmemSetup(void) { if (R_SUCCEEDED(rc)) { rc = _memregionInitWithInfo(&g_StackRegion, InfoType_StackRegionAddress, InfoType_StackRegionSize); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Stack)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Stack)); } else { // [1.0.0] doesn't expose aslr/stack region information so we have to do this dirty hack to detect it. @@ -156,7 +156,7 @@ void virtmemSetup(void) { } else { // Wat. - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_WeirdKernel)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_WeirdKernel)); } } } diff --git a/nx/source/runtime/devices/usb_comms.c b/nx/source/runtime/devices/usb_comms.c index fd22cfc5..d0fcb933 100644 --- a/nx/source/runtime/devices/usb_comms.c +++ b/nx/source/runtime/devices/usb_comms.c @@ -3,9 +3,9 @@ #include "types.h" #include "result.h" #include "kernel/rwlock.h" -#include "services/fatal.h" #include "services/usbds.h" #include "runtime/hosversion.h" +#include "runtime/diag.h" #include "runtime/devices/usb_comms.h" #define TOTAL_INTERFACES 4 @@ -552,7 +552,7 @@ size_t usbCommsReadEx(void* buffer, size_t size, u32 interface) rwlockWriteUnlock(&inter->lock_out); } } - if (R_FAILED(rc) && g_usbCommsErrorHandling) fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadUsbCommsRead)); + if (R_FAILED(rc) && g_usbCommsErrorHandling) diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadUsbCommsRead)); } return transferredSize; } @@ -589,7 +589,7 @@ size_t usbCommsWriteEx(const void* buffer, size_t size, u32 interface) rwlockWriteUnlock(&inter->lock_in); } } - if (R_FAILED(rc) && g_usbCommsErrorHandling) fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadUsbCommsWrite)); + if (R_FAILED(rc) && g_usbCommsErrorHandling) diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadUsbCommsWrite)); } return transferredSize; } diff --git a/nx/source/runtime/diag.c b/nx/source/runtime/diag.c new file mode 100644 index 00000000..b4477a44 --- /dev/null +++ b/nx/source/runtime/diag.c @@ -0,0 +1,8 @@ +#include "kernel/svc.h" +#include "runtime/diag.h" + +__attribute__((weak)) void diagAbortWithResult(Result res) +{ + svcBreak(BreakReason_Panic, (uintptr_t)&res, sizeof(res)); + __builtin_unreachable(); +} diff --git a/nx/source/runtime/dynamic.c b/nx/source/runtime/dynamic.c index 56b119a1..cc79582f 100644 --- a/nx/source/runtime/dynamic.c +++ b/nx/source/runtime/dynamic.c @@ -1,5 +1,5 @@ #include "result.h" -#include "services/fatal.h" +#include "runtime/diag.h" #include void __nx_dynamic(uintptr_t base, const Elf64_Dyn* dyn) @@ -21,7 +21,7 @@ void __nx_dynamic(uintptr_t base, const Elf64_Dyn* dyn) } if (rela == NULL) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadReloc)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadReloc)); for (; relasz--; rela++) { diff --git a/nx/source/runtime/env.c b/nx/source/runtime/env.c index 7fe8add0..4f9e1534 100644 --- a/nx/source/runtime/env.c +++ b/nx/source/runtime/env.c @@ -3,9 +3,9 @@ #include "runtime/env.h" #include "runtime/hosversion.h" #include "services/sm.h" -#include "services/fatal.h" #include "services/applet.h" #include "services/acc.h" +#include "runtime/diag.h" void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr); @@ -138,7 +138,7 @@ Handle envGetMainThreadHandle(void) { return g_mainThreadHandle; } - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_HandleTooEarly)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_HandleTooEarly)); } bool envIsNso(void) { diff --git a/nx/source/runtime/init.c b/nx/source/runtime/init.c index 9495a230..cf9e6171 100644 --- a/nx/source/runtime/init.c +++ b/nx/source/runtime/init.c @@ -2,12 +2,12 @@ #include "runtime/env.h" #include "runtime/hosversion.h" #include "services/sm.h" -#include "services/fatal.h" #include "services/fs.h" #include "services/hid.h" #include "services/time.h" #include "services/applet.h" #include "services/set.h" +#include "runtime/diag.h" #include "runtime/devices/fs_dev.h" void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr); @@ -87,7 +87,7 @@ void __attribute__((weak)) __libnx_initheap(void) Result rc = svcSetHeapSize(&addr, size); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_HeapAllocFailed)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_HeapAllocFailed)); } // Newlib @@ -108,7 +108,7 @@ void __attribute__((weak)) __appInit(void) // Initialize default services. rc = smInitialize(); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); if (hosversionGet() == 0) { rc = setsysInitialize(); @@ -123,23 +123,23 @@ void __attribute__((weak)) __appInit(void) rc = appletInitialize(); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_InitFail_AM)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_InitFail_AM)); if (__nx_applet_type != AppletType_None) { rc = hidInitialize(); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_InitFail_HID)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_InitFail_HID)); } rc = timeInitialize(); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_InitFail_Time)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_InitFail_Time)); __libnx_init_time(); rc = fsInitialize(); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS)); fsdevMountSdmc(); __libnx_init_cwd(); diff --git a/nx/source/runtime/newlib.c b/nx/source/runtime/newlib.c index 56e6542f..faee450e 100644 --- a/nx/source/runtime/newlib.c +++ b/nx/source/runtime/newlib.c @@ -15,8 +15,8 @@ #include "kernel/condvar.h" #include "kernel/thread.h" #include "kernel/svc.h" -#include "services/fatal.h" #include "services/time.h" +#include "runtime/diag.h" #include "result.h" #define THRD_MAIN_HANDLE ((struct __pthread_t*)~(uintptr_t)0) @@ -59,7 +59,7 @@ struct _reent* __syscall_getreent(void) { ThreadVars* tv = getThreadVars(); if (tv->magic != THREADVARS_MAGIC) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadReent)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadReent)); return tv->reent; } diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index d71ddea1..aa978db3 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -1,10 +1,10 @@ #include #include "service_guard.h" #include "arm/counter.h" -#include "services/fatal.h" #include "services/applet.h" #include "runtime/env.h" #include "runtime/hosversion.h" +#include "runtime/diag.h" __attribute__((weak)) u32 __nx_applet_type = AppletType_Default; __attribute__((weak)) bool __nx_applet_auto_notifyrunning = true; @@ -162,7 +162,7 @@ Result _appletInitialize(void) { case AppletType_OverlayApplet: cmd_id = 300; break; case AppletType_SystemApplication: cmd_id = 350; break; // TODO: Replace error code - default: fatalThrow(MAKERESULT(Module_Libnx, LibnxError_AppletCmdidNotFound)); + default: diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_AppletCmdidNotFound)); } if (__nx_applet_type == AppletType_LibraryApplet && hosversionAtLeast(3,0,0)) { @@ -2027,7 +2027,7 @@ void appletNotifyRunning(bool *out) { Result rc = _appletCmdNoInOutBool(&g_appletIFunctions, out, 40); - if (R_FAILED(rc)) fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadAppletNotifyRunning)); + if (R_FAILED(rc)) diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadAppletNotifyRunning)); } Result appletGetPseudoDeviceId(Uuid *out) { @@ -2921,7 +2921,7 @@ Result appletGetMessage(u32 *msg) { if (R_VALUE(rc) == MAKERESULT(128, 3)) return rc; - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadAppletReceiveMessage)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadAppletReceiveMessage)); } return 0; @@ -2939,7 +2939,7 @@ bool appletProcessMessage(u32 msg) { case AppletMessage_FocusStateChanged: rc = _appletGetCurrentFocusState(&g_appletFocusState); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadAppletGetCurrentFocusState)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadAppletGetCurrentFocusState)); appletCallHook(AppletHookType_OnFocusState); break; @@ -2951,7 +2951,7 @@ bool appletProcessMessage(u32 msg) { case AppletMessage_OperationModeChanged: rc = _appletGetOperationMode(&g_appletOperationMode); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadAppletGetOperationMode)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadAppletGetOperationMode)); appletCallHook(AppletHookType_OnOperationMode); break; @@ -2959,7 +2959,7 @@ bool appletProcessMessage(u32 msg) { case AppletMessage_PerformanceModeChanged: rc = _appletGetPerformanceMode(&g_appletPerformanceMode); if (R_FAILED(rc)) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadAppletGetPerformanceMode)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_BadAppletGetPerformanceMode)); appletCallHook(AppletHookType_OnPerformanceMode); break; diff --git a/nx/source/services/sm.c b/nx/source/services/sm.c index a2352ff4..24d4f979 100644 --- a/nx/source/services/sm.c +++ b/nx/source/services/sm.c @@ -1,6 +1,6 @@ #define NX_SERVICE_ASSUME_NON_DOMAIN #include "service_guard.h" -#include "services/fatal.h" +#include "runtime/diag.h" static Service g_smSrv; @@ -15,7 +15,7 @@ static size_t g_smOverridesNum = 0; void smAddOverrideHandle(SmServiceName name, Handle handle) { if (g_smOverridesNum == MAX_OVERRIDES) - fatalThrow(MAKERESULT(Module_Libnx, LibnxError_TooManyOverrides)); + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_TooManyOverrides)); size_t i = g_smOverridesNum;