@@ -110,10 +110,26 @@ static void cut_here() {
110110 ets_putc (' \n ' );
111111}
112112
113- void __wrap_system_restart_local () {
114- register uint32_t sp asm (" a1" );
115- uint32_t sp_dump = sp;
116-
113+ /*
114+ Add some assembly to grab the stack pointer and pass it as an argument before
115+ it grows for the target function. Should stabilize the stack offsets, used to
116+ find the relevant stack content for dumping.
117+ */
118+ extern " C" void __wrap_system_restart_local (void );
119+ asm (
120+ " .section .text.__wrap_system_restart_local,\" ax\" ,@progbits\n\t "
121+ " .literal_position\n\t "
122+ " .align 4\n\t "
123+ " .global __wrap_system_restart_local\n\t "
124+ " .type __wrap_system_restart_local, @function\n\t "
125+ " \n "
126+ " __wrap_system_restart_local:\n\t "
127+ " mov a2, a1\n\t "
128+ " j postmortem_report\n\t "
129+ " .size __wrap_system_restart_local, .-__wrap_system_restart_local\n\t "
130+ );
131+
132+ static void postmortem_report (uint32_t sp_dump) {
117133 struct rst_info rst_info;
118134 memset (&rst_info, 0 , sizeof (rst_info));
119135 if (s_user_reset_reason == REASON_DEFAULT_RST)
@@ -152,9 +168,17 @@ void __wrap_system_restart_local() {
152168 else if (rst_info.reason == REASON_EXCEPTION_RST) {
153169 // The GCC divide routine in ROM jumps to the address below and executes ILL (00 00 00) on div-by-zero
154170 // In that case, print the exception as (6) which is IntegerDivZero
155- bool div_zero = (rst_info.exccause == 0 ) && (rst_info.epc1 == 0x4000dce5 );
171+ uint32_t epc1 = rst_info.epc1 ;
172+ uint32_t exccause = rst_info.exccause ;
173+ bool div_zero = (exccause == 0 ) && (epc1 == 0x4000dce5u );
174+ if (div_zero) {
175+ exccause = 6 ;
176+ // In place of the detached 'ILL' instruction., redirect attention
177+ // back to the code that called the ROM divide function.
178+ __asm__ __volatile__ (" rsr.excsave1 %0\n\t " : " =r" (epc1) :: " memory" );
179+ }
156180 ets_printf_P (PSTR (" \n Exception (%d):\n epc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n " ),
157- div_zero ? 6 : rst_info. exccause , rst_info. epc1 , rst_info.epc2 , rst_info.epc3 , rst_info.excvaddr , rst_info.depc );
181+ exccause, epc1, rst_info.epc2 , rst_info.epc3 , rst_info.excvaddr , rst_info.depc );
158182 }
159183 else if (rst_info.reason == REASON_SOFT_WDT_RST) {
160184 ets_printf_P (PSTR (" \n Soft WDT reset\n " ));
@@ -174,16 +198,31 @@ void __wrap_system_restart_local() {
174198
175199 // amount of stack taken by interrupt or exception handler
176200 // and everything up to __wrap_system_restart_local
177- // (determined empirically, might break)
201+ // ~ (determined empirically, might break)~
178202 uint32_t offset = 0 ;
179203 if (rst_info.reason == REASON_SOFT_WDT_RST) {
180- offset = 0x1a0 ;
204+ // Stack Tally
205+ // 256 User Exception vector handler reserves stack space
206+ // directed to _xtos_l1int_handler function in Boot ROM
207+ // 48 wDev_ProcessFiq - its address appears in a vector table at 0x3FFFC27C
208+ // 16 ?unnamed? - index into a table, pull out pointer, and call if non-zero
209+ // appears near near wDev_ProcessFiq
210+ // 32 pp_soft_wdt_feed_local - gather the specifics and call __wrap_system_restart_local
211+ offset = 32 + 16 + 48 + 256 ;
181212 }
182213 else if (rst_info.reason == REASON_EXCEPTION_RST) {
183- offset = 0x190 ;
214+ // Stack Tally
215+ // 256 Exception vector reserves stack space
216+ // filled in by "C" wrapper handler
217+ // 16 Handler level 1 - enable icache
218+ // 64 Handler level 2 - exception report
219+ offset = 64 + 16 + 256 ;
184220 }
185221 else if (rst_info.reason == REASON_WDT_RST) {
186- offset = 0x10 ;
222+ offset = 16 ;
223+ }
224+ else if (rst_info.reason == REASON_USER_SWEXCEPTION_RST) {
225+ offset = 16 ;
187226 }
188227
189228 ets_printf_P (PSTR (" \n >>>stack>>>\n " ));
@@ -280,8 +319,9 @@ static void raise_exception() {
280319
281320 s_user_reset_reason = REASON_USER_SWEXCEPTION_RST;
282321 ets_printf_P (PSTR (" \n User exception (panic/abort/assert)" ));
283- __wrap_system_restart_local ();
284-
322+ uint32_t sp;
323+ __asm__ __volatile__ (" mov %0, a1\n\t " : " =r" (sp) :: " memory" );
324+ postmortem_report (sp);
285325 while (1 ); // never reached, needed to satisfy "noreturn" attribute
286326}
287327
@@ -321,7 +361,9 @@ void __stack_chk_fail(void) {
321361 if (gdb_present ())
322362 __asm__ __volatile__ (" syscall" ); // triggers GDB when enabled
323363
324- __wrap_system_restart_local ();
364+ uint32_t sp;
365+ __asm__ __volatile__ (" mov %0, a1\n\t " : " =r" (sp) :: " memory" );
366+ postmortem_report (sp);
325367
326368 __builtin_unreachable (); // never reached, needed to satisfy "noreturn" attribute
327369}
0 commit comments