ams: dump tls in fatal error context

This commit is contained in:
Michael Scire 2020-03-08 17:01:53 -07:00
parent 08d9de6907
commit 4c5e980e07
4 changed files with 24 additions and 13 deletions

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* 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 <stdio.h>
#include "panic.h" #include "panic.h"
#include "di.h" #include "di.h"
@ -51,8 +51,10 @@ static const char *get_error_desc_str(uint32_t error_desc) {
static void _check_and_display_atmosphere_fatal_error(void) { static void _check_and_display_atmosphere_fatal_error(void) {
/* Check for valid magic. */ /* Check for valid magic. */
if (ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC && if (ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC &&
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0) { ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 &&
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0)
{
return; return;
} }
@ -69,10 +71,10 @@ static void _check_and_display_atmosphere_fatal_error(void) {
/* Turn on the backlight after initializing the lfb */ /* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */ /* to avoid flickering. */
display_backlight(true); display_backlight(true);
/* Override the global logging level. */ /* Override the global logging level. */
log_set_log_level(SCREEN_LOG_LEVEL_ERROR); log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
/* Copy fatal error context to the stack. */ /* Copy fatal error context to the stack. */
atmosphere_fatal_error_ctx ctx = *(ATMOSPHERE_FATAL_ERROR_CONTEXT); atmosphere_fatal_error_ctx ctx = *(ATMOSPHERE_FATAL_ERROR_CONTEXT);
@ -103,7 +105,7 @@ static void _check_and_display_atmosphere_fatal_error(void) {
void check_and_display_panic(void) { void check_and_display_panic(void) {
/* Handle a panic sent via a stratosphere module. */ /* Handle a panic sent via a stratosphere module. */
_check_and_display_atmosphere_fatal_error(); _check_and_display_atmosphere_fatal_error();
/* We also handle our own panics. */ /* We also handle our own panics. */
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));
uint32_t code = (g_panic_code == 0) ? APBDEV_PMC_SCRATCH200_0 : g_panic_code; uint32_t code = (g_panic_code == 0) ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
@ -152,10 +154,10 @@ void check_and_display_panic(void) {
/* Initialize the display. */ /* Initialize the display. */
display_init(); display_init();
/* Fill the screen. */ /* Fill the screen. */
display_color_screen(color); display_color_screen(color);
/* Wait for button and reboot. */ /* Wait for button and reboot. */
wait_for_button_and_reboot(); wait_for_button_and_reboot();
} else { } else {

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef FUSEE_PANIC_H #ifndef FUSEE_PANIC_H
#define FUSEE_PANIC_H #define FUSEE_PANIC_H
@ -30,6 +30,7 @@
#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20 #define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20
#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100 #define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100
#define AMS_FATAL_ERROR_TLS_SIZE 0x100
/* Atmosphere reboot-to-fatal-error. */ /* Atmosphere reboot-to-fatal-error. */
typedef struct { typedef struct {
@ -57,10 +58,13 @@ typedef struct {
uint64_t stack_dump_size; uint64_t stack_dump_size;
uint64_t stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE]; uint64_t stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE];
uint8_t stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP]; uint8_t stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP];
uint8_t tls[AMS_FATAL_ERROR_TLS_SIZE];
} atmosphere_fatal_error_ctx; } atmosphere_fatal_error_ctx;
/* "AFE2" */
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x32454641
/* "AFE1" */ /* "AFE1" */
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x31454641 #define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 0x31454641
/* "AFE0" */ /* "AFE0" */
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0 0x30454641 #define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0 0x30454641

View file

@ -83,12 +83,13 @@ namespace ams {
struct FatalErrorContext : sf::LargeData, sf::PrefersMapAliasTransferMode { struct FatalErrorContext : sf::LargeData, sf::PrefersMapAliasTransferMode {
static constexpr size_t MaxStackTrace = 0x20; static constexpr size_t MaxStackTrace = 0x20;
static constexpr size_t MaxStackDumpSize = 0x100; static constexpr size_t MaxStackDumpSize = 0x100;
static constexpr size_t ThreadLocalSize = 0x100;
static constexpr size_t NumGprs = 29; static constexpr size_t NumGprs = 29;
static constexpr uintptr_t StdAbortMagicAddress = 0x8; static constexpr uintptr_t StdAbortMagicAddress = 0x8;
static constexpr u64 StdAbortMagicValue = 0xA55AF00DDEADCAFEul; static constexpr u64 StdAbortMagicValue = 0xA55AF00DDEADCAFEul;
static constexpr u32 StdAbortErrorDesc = 0xFFE; static constexpr u32 StdAbortErrorDesc = 0xFFE;
static constexpr u32 DataAbortErrorDesc = 0x101; static constexpr u32 DataAbortErrorDesc = 0x101;
static constexpr u32 Magic = util::FourCC<'A', 'F', 'E', '1'>::Code; static constexpr u32 Magic = util::FourCC<'A', 'F', 'E', '2'>::Code;
u32 magic; u32 magic;
u32 error_desc; u32 error_desc;
@ -113,10 +114,11 @@ namespace ams {
u64 stack_trace_size; u64 stack_trace_size;
u64 stack_dump_size; u64 stack_dump_size;
u64 stack_trace[MaxStackTrace]; u64 stack_trace[MaxStackTrace];
u8 stack_dump[MaxStackDumpSize]; u8 stack_dump[MaxStackDumpSize];
u8 tls[ThreadLocalSize];
}; };
static_assert(sizeof(FatalErrorContext) == 0x350, "sizeof(FatalErrorContext)"); static_assert(sizeof(FatalErrorContext) == 0x450, "sizeof(FatalErrorContext)");
static_assert(std::is_pod<FatalErrorContext>::value, "FatalErrorContext"); static_assert(std::is_pod<FatalErrorContext>::value, "FatalErrorContext");
#ifdef ATMOSPHERE_GIT_BRANCH #ifdef ATMOSPHERE_GIT_BRANCH

View file

@ -119,6 +119,9 @@ namespace ams {
ams_ctx.stack_dump_size = 0; ams_ctx.stack_dump_size = 0;
} }
} }
/* Grab 0x100 of tls. */
std::memcpy(ams_ctx.tls, armGetTls(), sizeof(ams_ctx.tls));
} }
/* Just call the user exception handler. */ /* Just call the user exception handler. */