From 9714db14d2a296b9e37dd258a0b87d25d19b2f0e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 13 Nov 2018 20:22:54 -0800 Subject: [PATCH] fatal/creport: Add cpu context. --- .../creport/source/creport_code_info.hpp | 2 +- .../creport/source/creport_crash_report.cpp | 29 +++++++++++++++++++ .../creport/source/creport_crash_report.hpp | 1 + stratosphere/creport/source/creport_main.cpp | 4 ++- .../creport/source/creport_thread_info.hpp | 2 +- stratosphere/fatal/source/fatal_task.cpp | 2 +- stratosphere/fatal/source/fatal_task.hpp | 6 ++-- .../fatal/source/fatal_task_clock.hpp | 2 +- .../fatal/source/fatal_task_error_report.hpp | 2 +- .../fatal/source/fatal_task_power.hpp | 6 ++-- .../fatal/source/fatal_task_screen.cpp | 5 ++-- .../fatal/source/fatal_task_screen.hpp | 4 +-- .../fatal/source/fatal_task_sound.hpp | 2 +- stratosphere/fatal/source/fatal_throw.cpp | 10 +++++-- stratosphere/fatal/source/fatal_types.hpp | 3 +- 15 files changed, 60 insertions(+), 20 deletions(-) diff --git a/stratosphere/creport/source/creport_code_info.hpp b/stratosphere/creport/source/creport_code_info.hpp index ff1c1fb1c..6f1baca95 100644 --- a/stratosphere/creport/source/creport_code_info.hpp +++ b/stratosphere/creport/source/creport_code_info.hpp @@ -28,7 +28,7 @@ struct CodeInfo { }; class CodeList { - private: + public: static const size_t max_code_count = 0x10; u32 code_count = 0; CodeInfo code_infos[max_code_count]; diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index cd9d1f9bb..6f2a2e62f 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -42,6 +42,35 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) { } } +FatalContext *CrashReport::GetFatalContext() { + FatalContext *ctx = new FatalContext; + *ctx = (FatalContext){0}; + + ctx->is_aarch32 = false; + ctx->type = static_cast(this->exception_info.type); + + for (size_t i = 0; i < 29; i++) { + ctx->aarch64_ctx.x[i] = this->crashed_thread_info.context.cpu_gprs[i].x; + } + ctx->aarch64_ctx.fp = this->crashed_thread_info.context.fp; + ctx->aarch64_ctx.lr = this->crashed_thread_info.context.lr; + ctx->aarch64_ctx.pc = this->crashed_thread_info.context.pc.x; + + ctx->aarch64_ctx.stack_trace_size = this->crashed_thread_info.stack_trace_size; + for (size_t i = 0; i < ctx->aarch64_ctx.stack_trace_size; i++) { + ctx->aarch64_ctx.stack_trace[i] = this->crashed_thread_info.stack_trace[i]; + } + + if (this->code_list.code_count) { + ctx->aarch64_ctx.start_address = this->code_list.code_infos[0].start_address; + } + + /* For ams fatal... */ + ctx->aarch64_ctx.afsr0 = this->process_info.title_id; + + return ctx; +} + void CrashReport::ProcessExceptions() { if (!IsOpen()) { return; diff --git a/stratosphere/creport/source/creport_crash_report.hpp b/stratosphere/creport/source/creport_crash_report.hpp index 049610c87..38aa28568 100644 --- a/stratosphere/creport/source/creport_crash_report.hpp +++ b/stratosphere/creport/source/creport_crash_report.hpp @@ -61,6 +61,7 @@ class CrashReport { public: void BuildReport(u64 pid, bool has_extra_info); + FatalContext *GetFatalContext(); void SaveReport(); bool IsAddressReadable(u64 address, u64 size, MemoryInfo *mi = NULL); diff --git a/stratosphere/creport/source/creport_main.cpp b/stratosphere/creport/source/creport_main.cpp index 77fd7b400..d106268e8 100644 --- a/stratosphere/creport/source/creport_main.cpp +++ b/stratosphere/creport/source/creport_main.cpp @@ -132,7 +132,9 @@ int main(int argc, char **argv) { return 0; } - fatalWithType(g_Creport.GetResult(), FatalType_ErrorScreen); + FatalContext *ctx = g_Creport.GetFatalContext(); + + fatalWithContext(g_Creport.GetResult(), FatalType_ErrorScreen, ctx); } } \ No newline at end of file diff --git a/stratosphere/creport/source/creport_thread_info.hpp b/stratosphere/creport/source/creport_thread_info.hpp index 0b3d3f07f..2995342cf 100644 --- a/stratosphere/creport/source/creport_thread_info.hpp +++ b/stratosphere/creport/source/creport_thread_info.hpp @@ -22,7 +22,7 @@ #include "creport_code_info.hpp" class ThreadInfo { - private: + public: ThreadContext context{}; u64 thread_id = 0; u64 stack_top = 0; diff --git a/stratosphere/fatal/source/fatal_task.cpp b/stratosphere/fatal/source/fatal_task.cpp index 62b39cdbb..6cf13428f 100644 --- a/stratosphere/fatal/source/fatal_task.cpp +++ b/stratosphere/fatal/source/fatal_task.cpp @@ -53,7 +53,7 @@ static void RunTask(IFatalTask *task, u32 stack_size = 0x4000) { cur_thread->Start(); } -void RunFatalTasks(FatalContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event) { +void RunFatalTasks(FatalThrowContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event) { RunTask(new ErrorReportTask(ctx, title_id, error_report, erpt_event)); RunTask(new PowerControlTask(ctx, title_id, erpt_event, battery_event)); RunTask(new ShowFatalTask(ctx, title_id, battery_event), 0x10000); diff --git a/stratosphere/fatal/source/fatal_task.hpp b/stratosphere/fatal/source/fatal_task.hpp index ef19fbbc1..6926f96f2 100644 --- a/stratosphere/fatal/source/fatal_task.hpp +++ b/stratosphere/fatal/source/fatal_task.hpp @@ -21,12 +21,12 @@ class IFatalTask { protected: - FatalContext *ctx; + FatalThrowContext *ctx; u64 title_id; public: - IFatalTask(FatalContext *ctx, u64 tid) : ctx(ctx), title_id(tid) { } + IFatalTask(FatalThrowContext *ctx, u64 tid) : ctx(ctx), title_id(tid) { } virtual Result Run() = 0; virtual const char *GetName() const = 0; }; -void RunFatalTasks(FatalContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event); +void RunFatalTasks(FatalThrowContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event); diff --git a/stratosphere/fatal/source/fatal_task_clock.hpp b/stratosphere/fatal/source/fatal_task_clock.hpp index 8ceba6945..65aa609d3 100644 --- a/stratosphere/fatal/source/fatal_task_clock.hpp +++ b/stratosphere/fatal/source/fatal_task_clock.hpp @@ -23,7 +23,7 @@ class AdjustClockTask : public IFatalTask { private: Result AdjustClock(); public: - AdjustClockTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { } + AdjustClockTask(FatalThrowContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { } virtual Result Run() override; virtual const char *GetName() const override { return "AdjustClockTask"; diff --git a/stratosphere/fatal/source/fatal_task_error_report.hpp b/stratosphere/fatal/source/fatal_task_error_report.hpp index 7ade00bcf..71b220f4d 100644 --- a/stratosphere/fatal/source/fatal_task_error_report.hpp +++ b/stratosphere/fatal/source/fatal_task_error_report.hpp @@ -24,7 +24,7 @@ class ErrorReportTask : public IFatalTask { bool create_report; Event *erpt_event; public: - ErrorReportTask(FatalContext *ctx, u64 title_id, bool error_report, Event *evt) : IFatalTask(ctx, title_id), create_report(error_report), erpt_event(evt) { } + ErrorReportTask(FatalThrowContext *ctx, u64 title_id, bool error_report, Event *evt) : IFatalTask(ctx, title_id), create_report(error_report), erpt_event(evt) { } virtual Result Run() override; virtual const char *GetName() const override { return "WriteErrorReport"; diff --git a/stratosphere/fatal/source/fatal_task_power.hpp b/stratosphere/fatal/source/fatal_task_power.hpp index d31e78752..a4aedc155 100644 --- a/stratosphere/fatal/source/fatal_task_power.hpp +++ b/stratosphere/fatal/source/fatal_task_power.hpp @@ -27,7 +27,7 @@ class PowerControlTask : public IFatalTask { bool TryShutdown(); void MonitorBatteryState(); public: - PowerControlTask(FatalContext *ctx, u64 title_id, Event *er_evt, Event *bt_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt), battery_event(bt_evt) { } + PowerControlTask(FatalThrowContext *ctx, u64 title_id, Event *er_evt, Event *bt_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt), battery_event(bt_evt) { } virtual Result Run() override; virtual const char *GetName() const override { return "PowerControlTask"; @@ -40,7 +40,7 @@ class PowerButtonObserveTask : public IFatalTask { private: void WaitForPowerButton(); public: - PowerButtonObserveTask(FatalContext *ctx, u64 title_id, Event *er_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt) { } + PowerButtonObserveTask(FatalThrowContext *ctx, u64 title_id, Event *er_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt) { } virtual Result Run() override; virtual const char *GetName() const override { return "PowerButtonObserveTask"; @@ -49,7 +49,7 @@ class PowerButtonObserveTask : public IFatalTask { class StateTransitionStopTask : public IFatalTask { public: - StateTransitionStopTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { } + StateTransitionStopTask(FatalThrowContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { } virtual Result Run() override; virtual const char *GetName() const override { return "StateTransitionStopTask"; diff --git a/stratosphere/fatal/source/fatal_task_screen.cpp b/stratosphere/fatal/source/fatal_task_screen.cpp index c20b14d7a..94fa1bacb 100644 --- a/stratosphere/fatal/source/fatal_task_screen.cpp +++ b/stratosphere/fatal/source/fatal_task_screen.cpp @@ -293,7 +293,7 @@ Result ShowFatalTask::ShowFatal() { } } else { if (this->ctx->cpu_ctx.is_aarch32) { - FontManager::PrintFormatLine("Backtrace - Start Address: "); + FontManager::Print("Backtrace - Start Address: "); FontManager::PrintMonospaceU32(this->ctx->cpu_ctx.aarch32_ctx.start_address); FontManager::PrintLine(""); FontManager::AddSpacingLines(0.5f); @@ -325,9 +325,10 @@ Result ShowFatalTask::ShowFatal() { FontManager::SetPosition(backtrace_x, FontManager::GetY()); } } else { - FontManager::PrintFormatLine("Backtrace - Start Address: "); + FontManager::Print("Backtrace - Start Address: "); FontManager::PrintMonospaceU64(this->ctx->cpu_ctx.aarch64_ctx.start_address); FontManager::PrintLine(""); + FontManager::AddSpacingLines(0.5f); for (u32 i = 0; i < Aarch64CpuContext::MaxStackTraceDepth / 2; i++) { u64 bt_cur = 0, bt_next = 0; if (i < this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size) { diff --git a/stratosphere/fatal/source/fatal_task_screen.hpp b/stratosphere/fatal/source/fatal_task_screen.hpp index bfaed2cea..9a2f7188c 100644 --- a/stratosphere/fatal/source/fatal_task_screen.hpp +++ b/stratosphere/fatal/source/fatal_task_screen.hpp @@ -32,7 +32,7 @@ class ShowFatalTask : public IFatalTask { Result PrepareScreenForDrawing(); Result ShowFatal(); public: - ShowFatalTask(FatalContext *ctx, u64 title_id, Event *evt) : IFatalTask(ctx, title_id), battery_event(evt) { } + ShowFatalTask(FatalThrowContext *ctx, u64 title_id, Event *evt) : IFatalTask(ctx, title_id), battery_event(evt) { } virtual Result Run() override; virtual const char *GetName() const override { return "ShowFatal"; @@ -43,7 +43,7 @@ class BacklightControlTask : public IFatalTask { private: void TurnOnBacklight(); public: - BacklightControlTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { } + BacklightControlTask(FatalThrowContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { } virtual Result Run() override; virtual const char *GetName() const override { return "BacklightControlTask"; diff --git a/stratosphere/fatal/source/fatal_task_sound.hpp b/stratosphere/fatal/source/fatal_task_sound.hpp index a6feea049..67954088b 100644 --- a/stratosphere/fatal/source/fatal_task_sound.hpp +++ b/stratosphere/fatal/source/fatal_task_sound.hpp @@ -23,7 +23,7 @@ class StopSoundTask : public IFatalTask { private: void StopSound(); public: - StopSoundTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { } + StopSoundTask(FatalThrowContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { } virtual Result Run() override; virtual const char *GetName() const override { return "SoundTask"; diff --git a/stratosphere/fatal/source/fatal_throw.cpp b/stratosphere/fatal/source/fatal_throw.cpp index 2eb617593..dbd6eba3b 100644 --- a/stratosphere/fatal/source/fatal_throw.cpp +++ b/stratosphere/fatal/source/fatal_throw.cpp @@ -42,7 +42,7 @@ Result ThrowFatalForSelf(u32 error) { Result ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCpuContext *cpu_ctx) { Result rc = 0; - FatalContext ctx; + FatalThrowContext ctx; ctx.error_code = error; ctx.cpu_ctx = *cpu_ctx; @@ -51,7 +51,13 @@ Result ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCpuContext *cpu /* Get title id. On failure, it'll be zero. */ u64 title_id = 0; - pminfoGetTitleId(&title_id, pid); + pminfoGetTitleId(&title_id, pid); + ctx.is_creport = title_id == 0x0100000000000036; + + /* Support for ams creport. TODO: Make this its own command? */ + if (ctx.is_creport && !cpu_ctx->is_aarch32 && cpu_ctx->aarch64_ctx.afsr0 != 0) { + title_id = cpu_ctx->aarch64_ctx.afsr0; + } switch (policy) { case FatalType_ErrorReport: diff --git a/stratosphere/fatal/source/fatal_types.hpp b/stratosphere/fatal/source/fatal_types.hpp index 06c435364..99be9c524 100644 --- a/stratosphere/fatal/source/fatal_types.hpp +++ b/stratosphere/fatal/source/fatal_types.hpp @@ -96,8 +96,9 @@ struct FatalCpuContext { u32 type; }; -struct FatalContext { +struct FatalThrowContext { u32 error_code; + bool is_creport; FatalCpuContext cpu_ctx; };