// The OS/K Team licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #include int dying = 0; void _except(ctx_t *ctx, int _code, char *fmt, ...) { va_list ap; ulong handler; uint code = _code; ulong orig_frame; logerr("\nException %u - ", code); va_start(ap, fmt); vlog(fmt, ap); va_end(ap); logerr("\n\n"); // // Interrupted earlier? // if (dying) { logerr("Exception thrown while dying=1\n"); enable_stdin_echoing(); exit(-12); } if (code >= IDT_SLOTS) goto actually_die; // // Check for E/I handlers // if (idt[code] == 0) { if (code < 512 && code != E_DBF) handler = idt[0]; else if (code < 768) handler = idt[512]; else handler = idt[768]; } else handler = idt[code]; // Found nothing? if (handler == 0) goto actually_die; // oh well // Is another handler already running? if (idt_handling[code] > 0) { // Triple fault? if (code == E_DBF) goto actually_die; // Double fault then? if (code < 512) _except(ctx, E_DBF, "Double Fault; previously handling: #%u", code); // XXX Queue TRAPs and INTs else goto actually_die; } // Is this a valid frame? if (rfs[handler] != NULL) { orig_frame = rfs_current_idx; ctx->rf = rfs[handler]; rfs_current_idx = handler; rax = code; R(CR6) = rip; R(CR7) = orig_frame; idt_handling[code]++; longjmp(exc_jmp_buf, code); } actually_die: dying = 1; dumpregs(ctx); trace("\n"); die(code); }