cynix

x86 UNIX-like OS
git clone git://git.2f30.org/cynix
Log | Files | Refs | README | LICENSE

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