#include "pk.h" #include "file.h" #include "frontend.h" #include #include #include #include int vsnprintf(char* out, size_t n, const char* s, va_list vl) { bool format = false; bool longarg = false; size_t pos = 0; for( ; *s; s++) { if(format) { switch(*s) { case 'l': longarg = true; break; case 'p': longarg = true; if (++pos < n) out[pos-1] = '0'; if (++pos < n) out[pos-1] = 'x'; case 'x': { long num = longarg ? va_arg(vl, long) : va_arg(vl, int); for(int i = 2*(longarg ? sizeof(long) : sizeof(int))-1; i >= 0; i--) { int d = (num >> (4*i)) & 0xF; if (++pos < n) out[pos-1] = (d < 10 ? '0'+d : 'a'+d-10); } longarg = false; format = false; break; } case 'd': { long num = longarg ? va_arg(vl, long) : va_arg(vl, int); if (num < 0) { num = -num; if (++pos < n) out[pos-1] = '-'; } long digits = 1; for (long nn = num; nn /= 10; digits++) ; for (int i = digits-1; i >= 0; i--) { if (pos + i + 1 < n) out[pos + i] = '0' + (num % 10); num /= 10; } pos += digits; longarg = false; format = false; break; } case 's': { const char* s2 = va_arg(vl,const char*); while(*s2) if (++pos < n) out[pos-1] = *s2++; longarg = false; format = false; break; } case 'c': { if (++pos < n) out[pos-1] = (char)va_arg(vl,int); longarg = false; format = false; break; } default: panic("bad fmt"); } } else if(*s == '%') format = true; else if (++pos < n) out[pos-1] = *s; } if (pos < n) out[pos] = 0; else if (n) out[n-1] = 0; return pos; } static void vprintk(const char* s, va_list vl) { char out[256]; // XXX int res = vsnprintf(out, sizeof(out), s, vl); file_write(stderr, out, res < sizeof(out) ? res : sizeof(out)); } void printk(const char* s, ...) { va_list vl; va_start(vl, s); vprintk(s, vl); va_end(vl); } int snprintf(char* out, size_t n, const char* s, ...) { va_list vl; va_start(vl, s); int res = vsnprintf(out, n, s, vl); va_end(vl); return res; } void dump_tf(trapframe_t* tf) { static const char* regnames[] = { "z ", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "sA", "sB", "t3", "t4", "t5", "t6" }; tf->gpr[0] = 0; for(int i = 0; i < 32; i+=4) { for(int j = 0; j < 4; j++) printk("%s %lx%c",regnames[i+j],tf->gpr[i+j],j < 3 ? ' ' : '\n'); } printk("pc %lx va %lx insn %x sr %lx\n", tf->epc, tf->badvaddr, (uint32_t)tf->insn, tf->status); } void do_panic(const char* s, ...) { va_list vl; va_start(vl, s); vprintk(s, vl); die(-1); va_end(vl); } void kassert_fail(const char* s) { register uintptr_t ra asm ("ra"); do_panic("assertion failed @ %p: %s\n", ra, s); }