From 22524d81c785ac4bce3063dd099ac2537886f0cc Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Thu, 8 Jul 2021 08:39:59 -0700 Subject: [PATCH 1/7] Recover the BearSSL crash stack before the Heap is initialized and zeros it. --- .../core_esp8266_app_entry_noextra4k.cpp | 2 ++ cores/esp8266/core_esp8266_main.cpp | 6 ++++-- cores/esp8266/hwdt_app_entry.cpp | 19 ++++++++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cores/esp8266/core_esp8266_app_entry_noextra4k.cpp b/cores/esp8266/core_esp8266_app_entry_noextra4k.cpp index 1944787526..58f615c784 100644 --- a/cores/esp8266/core_esp8266_app_entry_noextra4k.cpp +++ b/cores/esp8266/core_esp8266_app_entry_noextra4k.cpp @@ -9,6 +9,7 @@ #include #include "cont.h" #include "coredecls.h" +#include void disable_extra4k_at_link_time (void) { @@ -38,6 +39,7 @@ extern "C" void app_entry_redefinable(void) { g_pcont = &g_cont; + umm_init(); /* Call the entry point of the SDK code. */ call_user_start(); } diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index b052718d51..ad13347154 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -318,6 +318,9 @@ extern "C" void app_entry_redefinable(void) cont_t s_cont __attribute__((aligned(16))); g_pcont = &s_cont; + /* Doing umm_init just once before starting the SDK, allowed us to remove + test and init calls at each malloc API entry point, saving IRAM. */ + umm_init(); /* Call the entry point of the SDK code. */ call_user_start(); } @@ -325,7 +328,6 @@ static void app_entry_custom (void) __attribute__((weakref("app_entry_redefinabl extern "C" void app_entry (void) { - umm_init(); return app_entry_custom(); } @@ -367,7 +369,7 @@ extern "C" void user_init(void) { #if defined(UMM_HEAP_EXTERNAL) install_vm_exception_handler(); #endif - + #if defined(NON32XFER_HANDLER) || defined(MMU_IRAM_HEAP) install_non32xfer_exception_handler(); #endif diff --git a/cores/esp8266/hwdt_app_entry.cpp b/cores/esp8266/hwdt_app_entry.cpp index 4d00fdae95..af7c30bd6b 100644 --- a/cores/esp8266/hwdt_app_entry.cpp +++ b/cores/esp8266/hwdt_app_entry.cpp @@ -1089,6 +1089,7 @@ asm ( ".literal .g_pcont, g_pcont\n\t" ".literal .pcont_stack, hwdt_app_entry__cont_stack\n\t" ".literal .sys_stack_first, sys_stack_first\n\t" + ".literal .umm_init, umm_init\n\t" ".literal .call_user_start, call_user_start\n\t" ".literal .get_noextra4k_g_pcont, get_noextra4k_g_pcont\n\t" ".align 4\n\t" @@ -1147,6 +1148,15 @@ asm ( "movi a3, 0x0b30\n\t" // ROM BSS Size "call0 ets_bzero\n\t" + /* + * Up until this call, the heap at crash time has been available for + * analysis. This is needed for dumping the bearssl stack. Also, future + * improvements could possibly use hwdt_pre_sdk_init() to run other early + * diagnostic tools. + */ + "l32r a0, .umm_init\n\t" + "callx0 a0\n\t" + "l32r a3, .call_user_start\n\t" "movi a0, 0x4000044c\n\t" "jx a3\n\t" @@ -1176,8 +1186,15 @@ void IRAM_ATTR app_entry_start(void) { g_pcont = CONT_STACK; } #if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM) - print_sanity_check_icache(); + hwdt_pre_sdk_init(); #endif + /* + * Up until this call, the heap at crash time has been available for + * analysis. This is needed for dumping the bearssl stack. Also, future + * improvements could possibly use hwdt_pre_sdk_init() to run other early + * diagnostic tools. + */ + umm_init(); /* * Use new calculated SYS stack from top. * Call the entry point of the SDK code. From 228343e22716445f0b998cc98613aca363904e9a Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Thu, 8 Jul 2021 16:23:55 -0700 Subject: [PATCH 2/7] Added comments for hwdt_pre_sdk_init() Keep Basic ASM version of app_entry_redefinable and removed alternate "C"/Extended ASM version. Update comments. --- cores/esp8266/hwdt_app_entry.cpp | 107 ++++++++----------------------- 1 file changed, 27 insertions(+), 80 deletions(-) diff --git a/cores/esp8266/hwdt_app_entry.cpp b/cores/esp8266/hwdt_app_entry.cpp index af7c30bd6b..3a657cfcd9 100644 --- a/cores/esp8266/hwdt_app_entry.cpp +++ b/cores/esp8266/hwdt_app_entry.cpp @@ -1048,6 +1048,22 @@ static void printSanityCheck() { } #endif //DEBUG_ESP_HWDT_DEV_DEBUG +/* + hwdt_pre_sdk_init() is the result of a hook for development diagnotics which + evolved and was generlized to run any optional diagnostic code supplied at + link time. + + Summary of the hwdt_pre_sdk_init() runtime environment: + * The code can run from flash and use PROGMEM strings. + * All functions must be extern "C" type + * C/C++ runtime has not started. Structures have not been initialized and + should have the values prior to reboot. With the exception of hwdt_info, + which was updated before this call. + * You can reference hwdt_info.reset_reason to control the action of the diagnostic. + * The stack is on the SYS stack. You have about 3K available before you + overwrite ROM Data area. + * Printing will work best with ets_uart_printf and umm_info_safe_printf_P. + */ void hwdt_pre_sdk_init(void) __attribute__((weak)); void hwdt_pre_sdk_init(void) { #if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM) @@ -1072,14 +1088,12 @@ void hwdt_pre_sdk_init_icache(void) { Cache_Read_Disable(); } - -#if 1 /* - An asm function alternative to the function with inline asm at the #else. I - find the inline asm requires constant inspection to verify that the compiler - optimizer does not clobber needed registers, after small changes in code or - compiler updates. Hints to the compiler don't always work for me. Last I - checked, the inline version below was working. + For app_entry_redefinable, use Basic ASM instead of "C" with Extended ASM. The + (inline) Extended ASM approach required constant inspection to verify that the + compiler's optimizer did not clobber needed registers or do something weird + after minor changes in code or compiler updates. Also, I think Basic ASM is + the safer route when changing the stack pointer multiple times. */ cont_t *hwdt_app_entry__cont_stack __attribute__((used)) = CONT_STACK; @@ -1136,14 +1150,20 @@ asm ( "l32r a13, .pcont_stack\n\t" "l32r a0, .get_noextra4k_g_pcont\n\t" "l32r a14, .g_pcont\n\t" + // We now switch to the SYS stack the SDK will use "l32i.n a1, a2, 0\n\t" // delayed load for pipeline "l32i.n a13, a13, 0\n\t" "callx0 a0\n\t" "moveqz a2, a13, a2\n\t" "s32i.n a2, a14, 0\n\t" + /* + * Allow for running additional diagnotics supplied at link time. + */ "call0 hwdt_pre_sdk_init_icache\n\t" + // In case somebody cares, leave things as we found them + // - Restore ROM BSS zeros. "movi a2, 0x3FFFE000\n\t" // ROM BSS Area "movi a3, 0x0b30\n\t" // ROM BSS Size "call0 ets_bzero\n\t" @@ -1163,79 +1183,6 @@ asm ( ".size app_entry_redefinable, .-app_entry_redefinable\n\t" ); -#else -void IRAM_ATTR app_entry_start(void) { - -#ifdef USE_IRAM - handle_hwdt(); -#else - handle_hwdt_icache(); -#endif - - /* - * Continuation context is in BSS. - */ - g_pcont = get_noextra4k_g_pcont(); - - if (!g_pcont) { - /* - * The continuation context is on the stack just after the reserved - * space for the ROM/eboot stack and before the SYS stack begins. All - * computations were done at top, save pointer to it now. - */ - g_pcont = CONT_STACK; - } -#if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM) - hwdt_pre_sdk_init(); -#endif - /* - * Up until this call, the heap at crash time has been available for - * analysis. This is needed for dumping the bearssl stack. Also, future - * improvements could possibly use hwdt_pre_sdk_init() to run other early - * diagnostic tools. - */ - umm_init(); - /* - * Use new calculated SYS stack from top. - * Call the entry point of the SDK code. - */ - asm volatile ("mov.n a1, %0\n\t" - "movi a0, 0x4000044c\n\t" /* Should never return; however, set return to Boot ROM Breakpoint */ - "jx %1\n\t" :: - "r" (sys_stack_first), "r" (call_user_start): - "a0", "memory"); - - __builtin_unreachable(); -} - -void IRAM_ATTR app_entry_redefinable(void) { - /* - * There are 4 sections of code that share the stack starting near - * 0x40000000. - * 1) The Boot ROM (uses around 640 bytes) - * 2) The Bootloader, eboot.elf (last seen using 720 bytes.) - * 3) `app_entry_redefinable()` just before it starts the SDK. - * 4) The NONOS SDK, optionally the Core when the extra 4K option is - * selected. - * - * Use the ROM BSS zeroed out memory as the home for our temporary stack. - * This way no additional information will be lost. That will remove this - * tool from the list of possible concerns for stack overwrite. - * - */ - - asm volatile ("movi a1, 0x3fffeb30\n\t" - "j app_entry_start" ::: "memory"); - - /* - * Keep this function with just asm seems to help avoid a stack frame being - * created for this function and things getting really confused. - */ - - __builtin_unreachable(); -} -#endif - #if defined(DEBUG_ESP_HWDT_INFO) || defined(ROM_STACK_DUMP) void debug_hwdt_init(void) { /* From 8c1216b2cd0b0ee90cf643935ccb4caad8b70fae Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Fri, 9 Jul 2021 11:32:47 -0700 Subject: [PATCH 3/7] Improved example HwdtStackDump to use StackThunk --- .../examples/HwdtStackDump/HwdtStackDump.ino | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino index fa01d2ec00..b1e842e591 100644 --- a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino +++ b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino @@ -10,7 +10,7 @@ speed defaults to 115200 bps. The HWDT stack dump will always print on port 'Serial'. - To demonstrates this tool, this Sketch offers a few options for crashing the + To demonstrate this tool, this Sketch offers a few options for crashing the ESP8266 with and without a HWDT reset. */ @@ -20,6 +20,7 @@ #include #include #include // g_pcont - only needed for this debug demo +#include #ifndef STASSID #define STASSID "your-ssid" @@ -29,6 +30,29 @@ const char* ssid = STASSID; const char* password = STAPSK; +//////////////////////////////////////////////////////////////////// +// This block is just for putting something on the BearSSL stack +// to show that it has not been zeroed out before HWDT stack dump +// gets to runs. +extern "C" { + #if CORE_MOCK + int thunk_thk_printf1(const void *fmt) { + return ets_uart_printf(fmt); + } + + #else + int thunk_thk_printf1(const char *fmt); + // Second stack thunked helper - this macro creates the global function thunk_thk_printf1 + make_stack_thunk(thk_printf1); + + // This function is called via thunk_thk_printf1 and will run with the BearSSL stack. + int thk_printf1(const char *fmt) { + return ets_uart_printf(fmt); + } + #endif +}; +//////////////////////////////////////////////////////////////////// + void setup(void) { WiFi.persistent(false); // w/o this a flash write occurs at every boot WiFi.mode(WIFI_OFF); @@ -39,6 +63,10 @@ void setup(void) { Serial.println(F("The Hardware Watchdog Timer Demo is starting ...")); Serial.println(); + // This allows us to test dumping a BearSSL stack after HWDT. + stack_thunk_add_ref(); + thunk_thk_printf1("Using Thunk Stack to print this line.\n\n"); + // We don't need this for this example; however, starting WiFi uses a little // more of the SYS stack. WiFi.mode(WIFI_STA); From 68c76802434f4e0b698890909c1f4a633ceafd49 Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:07:53 -0700 Subject: [PATCH 4/7] Style --- libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino index b1e842e591..05219ba4a1 100644 --- a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino +++ b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino @@ -35,12 +35,12 @@ const char* password = STAPSK; // to show that it has not been zeroed out before HWDT stack dump // gets to runs. extern "C" { - #if CORE_MOCK +#if CORE_MOCK int thunk_thk_printf1(const void *fmt) { return ets_uart_printf(fmt); } - #else +#else int thunk_thk_printf1(const char *fmt); // Second stack thunked helper - this macro creates the global function thunk_thk_printf1 make_stack_thunk(thk_printf1); @@ -49,7 +49,7 @@ extern "C" { int thk_printf1(const char *fmt) { return ets_uart_printf(fmt); } - #endif +#endif }; //////////////////////////////////////////////////////////////////// From 20248f1f1258d9ff3201f3a321480f94a15b1edc Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Sat, 10 Jul 2021 12:59:50 -0700 Subject: [PATCH 5/7] Removed unnecessary wrapper function from example --- .../examples/HwdtStackDump/HwdtStackDump.ino | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino index 05219ba4a1..c72d983836 100644 --- a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino +++ b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino @@ -36,19 +36,12 @@ const char* password = STAPSK; // gets to runs. extern "C" { #if CORE_MOCK - int thunk_thk_printf1(const void *fmt) { - return ets_uart_printf(fmt); - } + #define thunk_ets_uart_printf ets_uart_printf #else - int thunk_thk_printf1(const char *fmt); - // Second stack thunked helper - this macro creates the global function thunk_thk_printf1 - make_stack_thunk(thk_printf1); - - // This function is called via thunk_thk_printf1 and will run with the BearSSL stack. - int thk_printf1(const char *fmt) { - return ets_uart_printf(fmt); - } + int thunk_ets_uart_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2))); + // Second stack thunked helper - this macro creates the global function thunk_ets_uart_printf + make_stack_thunk(ets_uart_printf); #endif }; //////////////////////////////////////////////////////////////////// @@ -65,7 +58,7 @@ void setup(void) { // This allows us to test dumping a BearSSL stack after HWDT. stack_thunk_add_ref(); - thunk_thk_printf1("Using Thunk Stack to print this line.\n\n"); + thunk_ets_uart_printf("Using Thunk Stack to print this line.\n\n"); // We don't need this for this example; however, starting WiFi uses a little // more of the SYS stack. From 57f5d894e31df58816baad1a1aef2a11398006b2 Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Sat, 10 Jul 2021 15:10:11 -0700 Subject: [PATCH 6/7] style --- libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino index c72d983836..5a05b06ec9 100644 --- a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino +++ b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino @@ -36,10 +36,10 @@ const char* password = STAPSK; // gets to runs. extern "C" { #if CORE_MOCK - #define thunk_ets_uart_printf ets_uart_printf +#define thunk_ets_uart_printf ets_uart_printf #else - int thunk_ets_uart_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2))); + int thunk_ets_uart_printf(const char *format, ...) __attribute__((format (printf, 1, 2))); // Second stack thunked helper - this macro creates the global function thunk_ets_uart_printf make_stack_thunk(ets_uart_printf); #endif From 0533decbf97116aa292c2b705c974913d0f589f3 Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Sat, 10 Jul 2021 16:38:20 -0700 Subject: [PATCH 7/7] style --- libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino index 5a05b06ec9..ff1c41e93b 100644 --- a/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino +++ b/libraries/esp8266/examples/HwdtStackDump/HwdtStackDump.ino @@ -39,7 +39,7 @@ extern "C" { #define thunk_ets_uart_printf ets_uart_printf #else - int thunk_ets_uart_printf(const char *format, ...) __attribute__((format (printf, 1, 2))); + int thunk_ets_uart_printf(const char *format, ...) __attribute__((format(printf, 1, 2))); // Second stack thunked helper - this macro creates the global function thunk_ets_uart_printf make_stack_thunk(ets_uart_printf); #endif pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy