mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
81 lines
2.1 KiB
C
81 lines
2.1 KiB
C
// Copyright 2017 plutoo
|
|
#include "types.h"
|
|
#include "result.h"
|
|
#include "kernel/ipc.h"
|
|
#include "kernel/detect.h"
|
|
#include "kernel/svc.h"
|
|
#include "services/fatal.h"
|
|
#include "services/sm.h"
|
|
|
|
static void _fatalImpl(u32 cmd_id, Result err, FatalType type, FatalContext *ctx) {
|
|
Result rc = 0;
|
|
|
|
//Only 3.0.0+ supports FatalType_ErrorScreen, when specified on pre-3.0.0 use FatalType_ErrorReportAndErrorScreen instead.
|
|
if (type == FatalType_ErrorScreen && !kernelAbove300()) type = FatalType_ErrorReportAndErrorScreen;
|
|
|
|
if (detectDebugger()) {
|
|
svcBreak(0x80000000, err, 0);
|
|
}
|
|
|
|
if (!smHasInitialized()) {
|
|
rc = smInitialize();
|
|
}
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
Handle srv;
|
|
rc = smGetServiceOriginal(&srv, smEncodeName("fatal:u"));
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
ipcSendPid(&c);
|
|
if (ctx != NULL) {
|
|
ipcAddSendBuffer(&c, ctx, sizeof(*ctx), BufferType_Normal);
|
|
}
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u32 result;
|
|
u32 type;
|
|
u64 pid_placeholder;
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = cmd_id;
|
|
raw->result = err;
|
|
raw->type = type;
|
|
raw->pid_placeholder = 0; // Overwritten by fatal with PID descriptor.
|
|
|
|
ipcDispatch(srv);
|
|
}
|
|
}
|
|
|
|
switch (type) {
|
|
case FatalType_ErrorReport:
|
|
break;
|
|
case FatalType_ErrorReportAndErrorScreen:
|
|
case FatalType_ErrorScreen:
|
|
default:
|
|
svcExitProcess();
|
|
__builtin_unreachable();
|
|
}
|
|
}
|
|
|
|
void NORETURN fatalSimple(Result err) {
|
|
/* By default, do not generate an error report. */
|
|
fatalWithType(err, FatalType_ErrorScreen);
|
|
svcExitProcess();
|
|
__builtin_unreachable();
|
|
}
|
|
|
|
void fatalWithType(Result err, FatalType type) {
|
|
_fatalImpl(1, err, type, NULL);
|
|
}
|
|
|
|
void fatalWithContext(Result err, FatalType type, FatalContext *ctx) {
|
|
_fatalImpl(2, err, type, ctx);
|
|
}
|