mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
stratosphere: custom exception handlers (reboot to fusee)
This commit is contained in:
parent
b03a778611
commit
ac07971211
23 changed files with 307 additions and 11 deletions
1
Makefile
1
Makefile
|
@ -53,6 +53,7 @@ dist: all
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032
|
||||||
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
||||||
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/010000000000000D
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/010000000000000D
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||||
|
|
|
@ -90,9 +90,6 @@ static void setup_env(void) {
|
||||||
/* Initialize hardware. */
|
/* Initialize hardware. */
|
||||||
nx_hwinit();
|
nx_hwinit();
|
||||||
|
|
||||||
/* Check for panics. */
|
|
||||||
check_and_display_panic();
|
|
||||||
|
|
||||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||||
video_init(g_framebuffer);
|
video_init(g_framebuffer);
|
||||||
|
|
||||||
|
@ -139,6 +136,9 @@ int main(void) {
|
||||||
/* Initialize the display, console, etc. */
|
/* Initialize the display, console, etc. */
|
||||||
setup_env();
|
setup_env();
|
||||||
|
|
||||||
|
/* Check for panics. */
|
||||||
|
check_and_display_panic();
|
||||||
|
|
||||||
/* Load the BCT0 configuration ini off of the SD. */
|
/* Load the BCT0 configuration ini off of the SD. */
|
||||||
bct0 = load_config();
|
bct0 = load_config();
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,75 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "di.h"
|
#include "di.h"
|
||||||
#include "pmc.h"
|
#include "pmc.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "fs_utils.h"
|
||||||
|
#include "lib/log.h"
|
||||||
|
|
||||||
static uint32_t g_panic_code = 0;
|
static uint32_t g_panic_code = 0;
|
||||||
|
|
||||||
|
static const char *get_error_desc_str(uint32_t error_desc) {
|
||||||
|
switch (error_desc) {
|
||||||
|
case 0x100:
|
||||||
|
return "Instruction Abort";
|
||||||
|
case 0x101:
|
||||||
|
return "Data Abort";
|
||||||
|
case 0x102:
|
||||||
|
return "PC Misalignment";
|
||||||
|
case 0x103:
|
||||||
|
return "SP Misalignment";
|
||||||
|
case 0x104:
|
||||||
|
return "Trap";
|
||||||
|
case 0x106:
|
||||||
|
return "SError";
|
||||||
|
case 0x301:
|
||||||
|
return "Bad SVC";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _check_and_display_atmosphere_fatal_error(void) {
|
||||||
|
/* Check for valid magic. */
|
||||||
|
if (ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Copy fatal error context to the stack. */
|
||||||
|
atmosphere_fatal_error_ctx ctx = *(ATMOSPHERE_FATAL_ERROR_CONTEXT);
|
||||||
|
|
||||||
|
/* Change magic to invalid, to prevent double-display of error/bootlooping. */
|
||||||
|
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic = 0xCCCCCCCC;
|
||||||
|
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "A fatal error occurred when running Atmosph\xe8re.\n");
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Title ID: %016llx\n", ctx.title_id);
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Error Desc: %s (0x%x)\n", get_error_desc_str(ctx.error_desc), ctx.error_desc);
|
||||||
|
|
||||||
|
/* Save context to the SD card. */
|
||||||
|
{
|
||||||
|
char filepath[0x40];
|
||||||
|
snprintf(filepath, sizeof(filepath) - 1, "/atmosphere/fatal_errors/report_%016llx.bin", ctx.report_identifier);
|
||||||
|
filepath[sizeof(filepath)-1] = 0;
|
||||||
|
write_to_file(&ctx, sizeof(ctx), filepath);
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"Report saved to %s\n", filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display error. */
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_button_and_reboot();
|
||||||
|
}
|
||||||
|
|
||||||
void check_and_display_panic(void) {
|
void check_and_display_panic(void) {
|
||||||
|
/* Handle a panic sent via a stratosphere module. */
|
||||||
|
_check_and_display_atmosphere_fatal_error();
|
||||||
|
|
||||||
/* We also handle our own panics. */
|
/* We also handle our own panics. */
|
||||||
/* In the case of our own panics, we assume that the display has already been initialized. */
|
/* In the case of our own panics, we assume that the display has already been initialized. */
|
||||||
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0;
|
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0;
|
||||||
|
|
|
@ -28,6 +28,35 @@
|
||||||
|
|
||||||
#define PANIC_CODE_SAFEMODE 0x00000020
|
#define PANIC_CODE_SAFEMODE 0x00000020
|
||||||
|
|
||||||
|
/* Atmosphere reboot-to-fatal-error. */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t error_desc;
|
||||||
|
uint64_t title_id;
|
||||||
|
union {
|
||||||
|
uint64_t gprs[32];
|
||||||
|
struct {
|
||||||
|
uint64_t _gprs[29];
|
||||||
|
uint64_t fp;
|
||||||
|
uint64_t lr;
|
||||||
|
uint64_t sp;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
uint64_t pc;
|
||||||
|
uint64_t padding;
|
||||||
|
uint32_t pstate;
|
||||||
|
uint32_t afsr0;
|
||||||
|
uint32_t afsr1;
|
||||||
|
uint32_t esr;
|
||||||
|
uint64_t far;
|
||||||
|
uint64_t report_identifier; /* Normally just system tick. */
|
||||||
|
} atmosphere_fatal_error_ctx;
|
||||||
|
|
||||||
|
/* "AFE0" */
|
||||||
|
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x30454641
|
||||||
|
|
||||||
|
#define ATMOSPHERE_FATAL_ERROR_CONTEXT ((volatile atmosphere_fatal_error_ctx *)(0x4003E000))
|
||||||
|
|
||||||
void check_and_display_panic(void);
|
void check_and_display_panic(void);
|
||||||
__attribute__ ((noreturn)) void panic(uint32_t code);
|
__attribute__ ((noreturn)) void panic(uint32_t code);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
"svcMapDeviceAddressSpaceAligned": "0x5a",
|
"svcMapDeviceAddressSpaceAligned": "0x5a",
|
||||||
"svcUnmapDeviceAddressSpace": "0x5c",
|
"svcUnmapDeviceAddressSpace": "0x5c",
|
||||||
"svcGetSystemInfo": "0x6f",
|
"svcGetSystemInfo": "0x6f",
|
||||||
|
"svcManageNamedPort": "0x71",
|
||||||
"svcCallSecureMonitor": "0x7F"
|
"svcCallSecureMonitor": "0x7F"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,23 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = 0x010041544D530000ul;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx) {
|
||||||
|
/* We're bpc-mitm (or ams_mitm, anyway), so manually reboot to fatal error. */
|
||||||
|
Utils::RebootToFatalError(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void __libnx_initheap(void) {
|
void __libnx_initheap(void) {
|
||||||
void* addr = nx_inner_heap;
|
void* addr = nx_inner_heap;
|
||||||
|
|
32
stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.cpp
Normal file
32
stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "bpc_ams_service.hpp"
|
||||||
|
#include "bpcmitm_reboot_manager.hpp"
|
||||||
|
|
||||||
|
Result BpcAtmosphereService::RebootToFatalError(InBuffer<AtmosphereFatalErrorContext> ctx) {
|
||||||
|
if (ctx.buffer == nullptr || ctx.num_elements != 1) {
|
||||||
|
return ResultKernelConnectionClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reboot to fusee with the input context. */
|
||||||
|
BpcRebootManager::RebootForFatalError(ctx.buffer);
|
||||||
|
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
34
stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.hpp
Normal file
34
stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
#include "../utils.hpp"
|
||||||
|
|
||||||
|
enum BpcAtmosphereCmd : u32 {
|
||||||
|
BpcAtmosphereCmd_RebootToFatalError = 65000,
|
||||||
|
};
|
||||||
|
|
||||||
|
class BpcAtmosphereService : public IServiceObject {
|
||||||
|
private:
|
||||||
|
Result RebootToFatalError(InBuffer<AtmosphereFatalErrorContext> ctx);
|
||||||
|
public:
|
||||||
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
|
MakeServiceCommandMeta<BpcAtmosphereCmd_RebootToFatalError, &BpcAtmosphereService::RebootToFatalError>(),
|
||||||
|
};
|
||||||
|
};
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "bpcmitm_main.hpp"
|
#include "bpcmitm_main.hpp"
|
||||||
#include "bpc_mitm_service.hpp"
|
#include "bpc_mitm_service.hpp"
|
||||||
|
#include "bpc_ams_service.hpp"
|
||||||
#include "bpcmitm_reboot_manager.hpp"
|
#include "bpcmitm_reboot_manager.hpp"
|
||||||
|
|
||||||
#include "../utils.hpp"
|
#include "../utils.hpp"
|
||||||
|
@ -46,6 +47,10 @@ void BpcMitmMain(void *arg) {
|
||||||
}
|
}
|
||||||
AddMitmServerToManager<BpcMitmService>(server_manager, service_name, 13);
|
AddMitmServerToManager<BpcMitmService>(server_manager, service_name, 13);
|
||||||
|
|
||||||
|
/* Extension: Allow for reboot-to-error. */
|
||||||
|
/* Must be managed port in order for sm to be able to access. */
|
||||||
|
server_manager->AddWaitable(new ManagedPortServer<BpcAtmosphereService>("bpc:ams", 1));
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
/* Loop forever, servicing our services. */
|
||||||
server_manager->Process();
|
server_manager->Process();
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ static void ClearIram() {
|
||||||
memset(g_work_page, 0xFF, sizeof(g_work_page));
|
memset(g_work_page, 0xFF, sizeof(g_work_page));
|
||||||
|
|
||||||
/* Overwrite all of IRAM with FFs. */
|
/* Overwrite all of IRAM with FFs. */
|
||||||
for (size_t ofs = 0; ofs < IRAM_PAYLOAD_MAX_SIZE; ofs += sizeof(g_work_page)) {
|
for (size_t ofs = 0; ofs < IRAM_SIZE; ofs += sizeof(g_work_page)) {
|
||||||
CopyToIram(IRAM_PAYLOAD_BASE + ofs, g_work_page, sizeof(g_work_page));
|
CopyToIram(IRAM_BASE + ofs, g_work_page, sizeof(g_work_page));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,3 +99,24 @@ Result BpcRebootManager::PerformReboot() {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BpcRebootManager::RebootForFatalError(AtmosphereFatalErrorContext *ctx) {
|
||||||
|
/* If we don't actually have a payload loaded, just go to RCM. */
|
||||||
|
if (!g_payload_loaded) {
|
||||||
|
RebootToRcm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure clean IRAM state. */
|
||||||
|
ClearIram();
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy in payload. */
|
||||||
|
for (size_t ofs = 0; ofs < sizeof(g_reboot_payload); ofs += 0x1000) {
|
||||||
|
CopyToIram(IRAM_PAYLOAD_BASE + ofs, &g_reboot_payload[ofs], 0x1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(g_work_page, ctx, sizeof(*ctx));
|
||||||
|
CopyToIram(IRAM_PAYLOAD_BASE + IRAM_PAYLOAD_MAX_SIZE, g_work_page, sizeof(g_work_page));
|
||||||
|
|
||||||
|
RebootToIramPayload();
|
||||||
|
}
|
|
@ -18,7 +18,9 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
#define IRAM_PAYLOAD_MAX_SIZE 0x2F000
|
#define IRAM_BASE 0x40000000ull
|
||||||
|
#define IRAM_SIZE 0x40000
|
||||||
|
#define IRAM_PAYLOAD_MAX_SIZE 0x2E000
|
||||||
#define IRAM_PAYLOAD_BASE 0x40010000ull
|
#define IRAM_PAYLOAD_BASE 0x40010000ull
|
||||||
|
|
||||||
enum class BpcRebootType : u32 {
|
enum class BpcRebootType : u32 {
|
||||||
|
@ -31,4 +33,5 @@ class BpcRebootManager {
|
||||||
public:
|
public:
|
||||||
static void Initialize();
|
static void Initialize();
|
||||||
static Result PerformReboot();
|
static Result PerformReboot();
|
||||||
|
static void RebootForFatalError(AtmosphereFatalErrorContext *ctx);
|
||||||
};
|
};
|
|
@ -25,6 +25,7 @@
|
||||||
#include "ini.h"
|
#include "ini.h"
|
||||||
|
|
||||||
#include "set_mitm/setsys_settings_items.hpp"
|
#include "set_mitm/setsys_settings_items.hpp"
|
||||||
|
#include "bpc_mitm/bpcmitm_reboot_manager.hpp"
|
||||||
|
|
||||||
static FsFileSystem g_sd_filesystem = {0};
|
static FsFileSystem g_sd_filesystem = {0};
|
||||||
static HosSignal g_sd_signal;
|
static HosSignal g_sd_signal;
|
||||||
|
@ -652,3 +653,7 @@ Result Utils::GetSettingsItemBooleanValue(const char *name, const char *key, boo
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utils::RebootToFatalError(AtmosphereFatalErrorContext *ctx) {
|
||||||
|
BpcRebootManager::RebootForFatalError(ctx);
|
||||||
|
}
|
||||||
|
|
|
@ -87,6 +87,9 @@ class Utils {
|
||||||
static Result GetSettingsItemValue(const char *name, const char *key, void *out, size_t max_size, u64 *out_size);
|
static Result GetSettingsItemValue(const char *name, const char *key, void *out, size_t max_size, u64 *out_size);
|
||||||
|
|
||||||
static Result GetSettingsItemBooleanValue(const char *name, const char *key, bool *out);
|
static Result GetSettingsItemBooleanValue(const char *name, const char *key, bool *out);
|
||||||
|
|
||||||
|
/* Error occurred. */
|
||||||
|
static void RebootToFatalError(AtmosphereFatalErrorContext *ctx);
|
||||||
private:
|
private:
|
||||||
static void RefreshConfiguration();
|
static void RefreshConfiguration();
|
||||||
};
|
};
|
|
@ -49,6 +49,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Boot;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __libnx_initheap(void) {
|
void __libnx_initheap(void) {
|
||||||
|
|
|
@ -38,6 +38,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Creport;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Dmnt;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Eclct;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Fatal;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1f9e2d042cb028cee1777b3d63a7cda06d2cffd0
|
Subproject commit b9724cdcadd5ea5fbead8f1a9c9b7de11daf6b60
|
|
@ -41,6 +41,16 @@ extern "C" {
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Loader;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Pm;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Sm;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue