@@ -110,10 +110,26 @@ static void cut_here() {
110
110
ets_putc (' \n ' );
111
111
}
112
112
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) {
117
133
struct rst_info rst_info;
118
134
memset (&rst_info, 0 , sizeof (rst_info));
119
135
if (s_user_reset_reason == REASON_DEFAULT_RST)
@@ -152,9 +168,17 @@ void __wrap_system_restart_local() {
152
168
else if (rst_info.reason == REASON_EXCEPTION_RST) {
153
169
// The GCC divide routine in ROM jumps to the address below and executes ILL (00 00 00) on div-by-zero
154
170
// 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
+ }
156
180
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 );
158
182
}
159
183
else if (rst_info.reason == REASON_SOFT_WDT_RST) {
160
184
ets_printf_P (PSTR (" \n Soft WDT reset\n " ));
@@ -174,16 +198,31 @@ void __wrap_system_restart_local() {
174
198
175
199
// amount of stack taken by interrupt or exception handler
176
200
// and everything up to __wrap_system_restart_local
177
- // (determined empirically, might break)
201
+ // ~ (determined empirically, might break)~
178
202
uint32_t offset = 0 ;
179
203
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 ;
181
212
}
182
213
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 ;
184
220
}
185
221
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 ;
187
226
}
188
227
189
228
ets_printf_P (PSTR (" \n >>>stack>>>\n " ));
@@ -280,8 +319,9 @@ static void raise_exception() {
280
319
281
320
s_user_reset_reason = REASON_USER_SWEXCEPTION_RST;
282
321
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);
285
325
while (1 ); // never reached, needed to satisfy "noreturn" attribute
286
326
}
287
327
@@ -321,7 +361,9 @@ void __stack_chk_fail(void) {
321
361
if (gdb_present ())
322
362
__asm__ __volatile__ (" syscall" ); // triggers GDB when enabled
323
363
324
- __wrap_system_restart_local ();
364
+ uint32_t sp;
365
+ __asm__ __volatile__ (" mov %0, a1\n\t " : " =r" (sp) :: " memory" );
366
+ postmortem_report (sp);
325
367
326
368
__builtin_unreachable (); // never reached, needed to satisfy "noreturn" attribute
327
369
}
0 commit comments