common.c (3240B)
1 /* 2 * core/common.c 3 * 4 * Copyright (C) 2009 stateless 5 */ 6 7 #include <common.h> 8 #include <tty.h> 9 #include <ctype.h> 10 #include <elf.h> 11 #include <serial.h> 12 #include <x86.h> 13 #include <tss.h> 14 15 extern uint8_t __code[0]; 16 extern uint8_t __end[0]; 17 extern unsigned long int initial_esp; 18 19 void 20 dump_regs(void) 21 { 22 uint32_t eax, ebx, ecx, edx, esp, ebp; 23 uint32_t edi, esi; 24 25 asm volatile ("movl %%eax, %0" : "=r"(eax)); 26 asm volatile ("movl %%ebx, %0" : "=r"(ebx)); 27 asm volatile ("movl %%ecx, %0" : "=r"(ecx)); 28 asm volatile ("movl %%edx, %0" : "=r"(edx)); 29 asm volatile ("movl %%esp, %0" : "=r"(esp)); 30 asm volatile ("movl %%ebp, %0" : "=r"(ebp)); 31 asm volatile ("movl %%esi, %0" : "=r"(esi)); 32 asm volatile ("movl %%edi, %0" : "=r"(edi)); 33 34 printf("eax = 0x%08lx\nebx = 0x%08lx\necx = 0x%08lx\n", 35 eax, ebx, ecx); 36 printf("edx = 0x%08lx\nesp = 0x%08lx\nebp = 0x%08lx\n", 37 edx, esp, ebp); 38 printf("esi = 0x%08lx\nedi = 0x%08lx\n", 39 esi, edi); 40 serial_dump("eax = 0x%08lx\nebx = 0x%08lx\necx = 0x%08lx\n", 41 eax, ebx, ecx); 42 serial_dump("edx = 0x%08lx\nesp = 0x%08lx\nebp = 0x%08lx\n", 43 edx, esp, ebp); 44 serial_dump("esi = 0x%08lx\nedi = 0x%08lx\n", 45 esi, edi); 46 } 47 48 void 49 panic_internal(const char *file, const char *fn, uint32_t line, const char *fmt, ...) 50 { 51 va_list ap; 52 char buf[512], line_s[32]; 53 54 asm volatile ("cli"); 55 printf("~~~ kernel panic ~~~\n"); 56 stacktrace(8); 57 itoa(line, line_s, 10); 58 printf("%s:%s:%s ", file, fn, line_s); 59 va_start(ap, fmt); 60 vsprintf(buf, fmt, ap); 61 va_end(ap); 62 printf("%s\n", buf); 63 update_cursor(cursor_y, cursor_x); 64 serial_dump("~~~ kernel panic ~~~\n"); 65 serial_dump("%s:%s:%s ", file, fn, line_s); 66 serial_dump("%s\n", buf); 67 dump_regs(); 68 asm volatile ("hlt"); 69 } 70 71 void 72 hexdump(const void *ptr, size_t len) 73 { 74 const char *addr = (const char *)ptr; 75 size_t i; 76 int j; 77 78 for (i = 0; i < len; i += 16) { 79 serial_dump("0x%08lx: ", (uint32_t)addr); 80 serial_dump("0x%08lx 0x%08lx 0x%08lx 0x%08lx |", 81 *(uint32_t *)addr, 82 *(uint32_t *)(addr + 4), 83 *(uint32_t *)(addr + 8), 84 *(uint32_t *)(addr + 12) 85 ); 86 printf("0x%08lx: ", (uint32_t)addr); 87 printf("0x%08lx 0x%08lx 0x%08lx 0x%08lx |", 88 *(uint32_t *)addr, 89 *(uint32_t *)(addr + 4), 90 *(uint32_t *)(addr + 8), 91 *(uint32_t *)(addr + 12) 92 ); 93 94 for (j = 0; j < 16; ++j) { 95 serial_dump("%c", (isalpha(addr[j])) ? addr[j] : '.'); 96 printf("%c", (isalpha(addr[j])) ? addr[j] : '.'); 97 } 98 serial_dump("|\n"); 99 printf("|\n"); 100 addr += 16; 101 } 102 } 103 104 void 105 stacktrace(int depth) 106 { 107 uint32_t *addr, ebp, stack_top; 108 const char *p; 109 110 stack_top = (!curr_proc) ? initial_esp : 111 (uint32_t)curr_proc->stack + TASK_STACK_SIZE - sizeof(struct cswitch_frame_t); 112 GET_EBP(ebp); 113 addr = (uint32_t *)(ebp + 4); 114 if (curr_proc) 115 printf("Stack trace for thread [%d:%s]\n", curr_proc->pid, curr_proc->name); 116 printf("\t\t%-12s %-12s\n", "Address", "Function"); 117 while (depth--) { 118 p = find_symbol(*addr); 119 if (!p) 120 ++depth; 121 else 122 printf("\t\t0x%-12.8lx%-12s\n", *addr, p); 123 for (;;) { 124 if ((uint32_t)addr + 4 >= stack_top) 125 return; 126 addr += 4; 127 /* this is just a heuristic */ 128 if (*addr > (uint32_t)__code && *addr < (uint32_t)__end) 129 break; 130 } 131 } 132 } 133