void *mem_alloc(ulong size, byte cat); void *mem_realloc(void *vptr, ulong size, byte cat); void mem_free(void *vptr); void sys_panic(const char *error, const char *fmt, ...) { va_list ap; va_start(ap, fmt); void *rip; void *rsp; void *rbp; void **bt; char **bs; int frames; asm volatile("lea (%%rip),%%rax \n\tmov %%rax,%0" : "=m" (rip) : ); asm volatile("mov %%rsp,%0" : "=m" (rsp) : ); asm volatile("mov %%rbp,%0" : "=m" (rbp) : ); fprintf(stderr, "\n========================= !ABSTURZ! ========================="); fprintf(stderr, "\n TRACEBACK [Jetzt: %%rsp=$%llx, %%rbp=$%llx]:", (ulong)(rsp), (ulong)(rbp)); bs = backtrace_symbols(&rip, 1); if(bs) { fprintf(stderr, "\n -> [RIP] %s", bs[0] ? bs[0] : ""); free(bs); } else { fprintf(stderr, "\n -> [RIP] $%llx", (ulong)(rip)); } if(bt = malloc(128 * sizeof(void *))) { // memset(bt, 0, 128 * sizeof(void *)); frames = backtrace(bt, 128); if(bs = backtrace_symbols(bt, frames)) { for(int z = 0; (z < frames) && bt[z]; z++) { fprintf(stderr, "\n -> [%03d] %s", z, bs[z] ? bs[z] : ""); } free(bs); } else { for(int z = 0; (z < frames) && bt[z]; z++) { fprintf(stderr, "\n -> [%03d] $%llx", z, bt[z]); } } free(bt); } else { fprintf(stderr, "\n *Konnte keinen Speicher für Traceback reservieren*"); } fprintf(stderr, "\n\n FEHLER#: %s\n URSACHE: ", error); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n======================== ABGEBROCHEN ========================\n\n"); // abort(); va_end(ap); abort(); } void sys_abort() { sys_panic("MANUAL_ABORT", "*Programm wurde manuell abgebrochen*"); } ulong sys_segtest(ulong addr) { ulong *ptr = (ulong*)addr; *ptr = 666ULL; return *ptr; } ulong sys_fpetest() { ulong cma = 666ULL; ulong cmb = 0ULL; return cma / cmb; } ulong sys_overtest(ulong v) { ulong cma = 666ULL; return sys_overtest(v * cma); } ulong sys_illtest() { asm volatile(".byte 0x0f, 0x04"); // asm volatile("jmp *%0" : : "m" (cma)); } void sys_coretest() { srand(time(0)); sys_panic("CORE_MELTDOWN", "Nuclear processor core meltdown imminent\n\n" " ************************ CAUTION ************************\n" " KCTL: Processor core #%02d has reached a critical\n" " temperature, system explosion is imminent! \n" " According to the general core density \n" " calculation routine defined by the SKC \n" " (Hard) Warfare Testing Facility (SKC-WTF) \n" " your processor will cause a detonation with \n" " a radius of (roughly) %d.%d kilometers. \n" " In addition, it will release appoximately \n" " %d megajoules of ionizing radiation. \n" " You have an estimate time of %d minutes and \n" " %d seconds left to clear the detonation area. \n" " ************************ CAUTION ************************\n" , 1 + (rand() % 64), 1 + (rand() % 9), rand() % 10, 10000 + (rand() % 30000), 3 + (rand() % 7), 2 + (rand() % 58)); } void sys_handle_seg(int sig, siginfo_t *info, void *ucontext) { if(info->si_addr) { sys_panic("SEGMENTATION_FAULT", "Speicherzugriffsfehler bei $%llx", (ulong)info->si_addr); } else { sys_panic("NULL_POINTER", "Versuchte Zugriff auf Speicher bei $0"); } } void sys_handle_ill(int sig, siginfo_t *info, void *ucontext) { sys_panic("ILLEGAL_INSTRUCTION", "Ungültige Prozessorinstruktion bei $%llx", (ulong)info->si_addr); } void sys_handle_fpe(int sig, siginfo_t *info, void *ucontext) { sys_panic("FLOATING_POINT_EXCEPTION", "Ungültige Gleitkommaoperation bei $%llx", (ulong)info->si_addr); } void sys_test_handlers(const char *test) { if(!test) { return; } else if(!strcmp("NULL", test)) { sys_segtest(0ULL); } else if(!strcmp("SEG", test)) { sys_segtest(0x666ULL); } else if(!strcmp("FPE", test)) { sys_fpetest(); } else if(!strcmp("OVER", test)) { sys_overtest(1); } else if(!strcmp("ILL", test)) { sys_illtest(); } else if(!strcmp("ABORT", test)) { sys_abort(); } else if(!strcmp("CORE", test)) { sys_coretest(); } else if(!strcmp("MEM", test)) { mem_alloc(0x7ffffffffffffff0, 0); } } void *sys_altstack; void sys_setup_handlers() { struct sigaction seg; stack_t stack; memset(&seg, 0, sizeof(struct sigaction)); seg.sa_sigaction = sys_handle_seg; seg.sa_flags = SA_ONSTACK | SA_SIGINFO; sigaction(SIGSEGV, &seg, NULL); memset(&seg, 0, sizeof(struct sigaction)); seg.sa_sigaction = sys_handle_fpe; seg.sa_flags = SA_ONSTACK | SA_SIGINFO; sigaction(SIGFPE, &seg, NULL); memset(&seg, 0, sizeof(struct sigaction)); seg.sa_sigaction = sys_handle_ill; seg.sa_flags = SA_ONSTACK | SA_SIGINFO; sigaction(SIGILL, &seg, NULL); stack.ss_sp = sys_altstack = malloc(16384); stack.ss_flags = 0; stack.ss_size = 16384; sigaltstack(&stack, NULL); } void sys_remove_handlers() { free(sys_altstack); }