stratosphere: custom exception handlers (reboot to fusee)
This commit is contained in:
@@ -71,6 +71,7 @@
|
||||
"svcMapDeviceAddressSpaceAligned": "0x5a",
|
||||
"svcUnmapDeviceAddressSpace": "0x5c",
|
||||
"svcGetSystemInfo": "0x6f",
|
||||
"svcManageNamedPort": "0x71",
|
||||
"svcCallSecureMonitor": "0x7F"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +38,23 @@ extern "C" {
|
||||
void __libnx_initheap(void);
|
||||
void __appInit(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* 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,7 +25,7 @@ enum BpcCmd : u32 {
|
||||
BpcCmd_RebootSystem = 1,
|
||||
};
|
||||
|
||||
class BpcMitmService : public IMitmServiceObject {
|
||||
class BpcMitmService : public IMitmServiceObject {
|
||||
public:
|
||||
BpcMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
||||
/* ... */
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "bpcmitm_main.hpp"
|
||||
#include "bpc_mitm_service.hpp"
|
||||
#include "bpc_ams_service.hpp"
|
||||
#include "bpcmitm_reboot_manager.hpp"
|
||||
|
||||
#include "../utils.hpp"
|
||||
@@ -46,6 +47,10 @@ void BpcMitmMain(void *arg) {
|
||||
}
|
||||
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. */
|
||||
server_manager->Process();
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ static void ClearIram() {
|
||||
memset(g_work_page, 0xFF, sizeof(g_work_page));
|
||||
|
||||
/* Overwrite all of IRAM with FFs. */
|
||||
for (size_t ofs = 0; ofs < IRAM_PAYLOAD_MAX_SIZE; ofs += sizeof(g_work_page)) {
|
||||
CopyToIram(IRAM_PAYLOAD_BASE + ofs, g_work_page, sizeof(g_work_page));
|
||||
for (size_t ofs = 0; ofs < IRAM_SIZE; ofs += sizeof(g_work_page)) {
|
||||
CopyToIram(IRAM_BASE + ofs, g_work_page, sizeof(g_work_page));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,3 +99,24 @@ Result BpcRebootManager::PerformReboot() {
|
||||
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 <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
|
||||
|
||||
enum class BpcRebootType : u32 {
|
||||
@@ -31,4 +33,5 @@ class BpcRebootManager {
|
||||
public:
|
||||
static void Initialize();
|
||||
static Result PerformReboot();
|
||||
static void RebootForFatalError(AtmosphereFatalErrorContext *ctx);
|
||||
};
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "ini.h"
|
||||
|
||||
#include "set_mitm/setsys_settings_items.hpp"
|
||||
#include "bpc_mitm/bpcmitm_reboot_manager.hpp"
|
||||
|
||||
static FsFileSystem g_sd_filesystem = {0};
|
||||
static HosSignal g_sd_signal;
|
||||
@@ -652,3 +653,7 @@ Result Utils::GetSettingsItemBooleanValue(const char *name, const char *key, boo
|
||||
}
|
||||
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 GetSettingsItemBooleanValue(const char *name, const char *key, bool *out);
|
||||
|
||||
/* Error occurred. */
|
||||
static void RebootToFatalError(AtmosphereFatalErrorContext *ctx);
|
||||
private:
|
||||
static void RefreshConfiguration();
|
||||
};
|
||||
@@ -49,6 +49,17 @@ extern "C" {
|
||||
void __libnx_initheap(void);
|
||||
void __appInit(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) {
|
||||
|
||||
@@ -38,6 +38,17 @@ extern "C" {
|
||||
void __libnx_initheap(void);
|
||||
void __appInit(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 __appInit(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 __appInit(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 __appInit(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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Submodule stratosphere/libstratosphere updated: 1f9e2d042c...b9724cdcad
@@ -41,6 +41,16 @@ extern "C" {
|
||||
void __appInit(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);
|
||||
}
|
||||
|
||||
|
||||
@@ -103,9 +113,9 @@ struct LoaderServerOptions {
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
consoleDebugInit(debugDevice_SVC);
|
||||
|
||||
|
||||
auto server_manager = new WaitableManager<LoaderServerOptions>(1);
|
||||
|
||||
|
||||
/* Add services to manager. */
|
||||
server_manager->AddWaitable(new ServiceServer<ProcessManagerService>("ldr:pm", 1));
|
||||
server_manager->AddWaitable(new ServiceServer<ShellService>("ldr:shel", 3));
|
||||
|
||||
@@ -42,6 +42,17 @@ extern "C" {
|
||||
void __libnx_initheap(void);
|
||||
void __appInit(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 __appInit(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);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +84,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* TODO: What's a good timeout value to use here? */
|
||||
auto server_manager = new WaitableManager(1);
|
||||
|
||||
|
||||
/* Create sm:, (and thus allow things to register to it). */
|
||||
server_manager->AddWaitable(new ManagedPortServer<UserService>("sm:", 0x40));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user