diff --git a/elks/kernel/printk.c b/elks/kernel/printk.c index 53b4ce5f3..5aa4cf8fd 100644 --- a/elks/kernel/printk.c +++ b/elks/kernel/printk.c @@ -193,6 +193,8 @@ static void vprintk(const char *fmt, va_list p) break; case 'P': v = current->pid; + c = 'd'; + n = 10; goto out; case 'D': c += 'X' - 'D'; diff --git a/elkscmd/debug/Makefile b/elkscmd/debug/Makefile index 2a319e0cf..0a6004a0a 100644 --- a/elkscmd/debug/Makefile +++ b/elkscmd/debug/Makefile @@ -22,8 +22,8 @@ CFLAGS += -fno-optimize-sibling-calls CFLAGS += -fno-omit-frame-pointer # optional instrumentation for function tracing CFLAGS += -finstrument-functions-simple -# include symbol table in executable and heap to read it -LDFLAGS += -maout-symtab -maout-heap=12000 +# include symbol table in executable +LDFLAGS += -maout-symtab # added after CFLAGS for non-instrumented .c files in this directory NOINSTFLAGS = -fno-instrument-functions -fno-instrument-functions-simple @@ -37,7 +37,7 @@ testsym: $(TESTOBJS) ./nm86 $@ > $@.map disasm: $(DISASMOBJS) - $(LD) $(LDFLAGS) -maout-heap=0xffff -o $@ $^ $(LDLIBS) + $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) system.sym: cp -p $(TOPDIR)/elks/arch/i86/boot/system.sym $(TOPDIR)/elkscmd/debug @@ -53,7 +53,7 @@ dis.o: dis.c $(CC) $(CFLAGS) $(NOINSTFLAGS) -c -o $*.o $< nm86: nm86.c syms.c - $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ + $(HOSTCC) $(HOSTCFLAGS) -D__far= -o $@ $^ hostdisasm: dis.c disasm.c syms.c $(HOSTCC) $(HOSTCFLAGS) -D__far= -Wno-int-to-void-pointer-cast -Wno-format -o $@ $^ diff --git a/elkscmd/debug/instrument.c b/elkscmd/debug/instrument.c index c14129831..57783f305 100644 --- a/elkscmd/debug/instrument.c +++ b/elkscmd/debug/instrument.c @@ -13,10 +13,10 @@ /* turn on for microcycle (CPU cycle/1000) timing info */ #define HAS_RDTSC 0 /* has RDTSC instruction: requires 386+ CPU */ -static char ftrace; -static int count; +static size_t ftrace; static size_t start_sp; static size_t max_stack; +static int count; /* runs before main and rewrites argc/argv on stack if --ftrace found */ __attribute__((no_instrument_function,constructor(120))) @@ -24,14 +24,17 @@ static void ftrace_checkargs(void) { char **avp = __argv + 1; - if ((*avp && !strcmp(*avp, "--ftrace")) || getenv("FTRACE")) { + ftrace = (size_t)getenv("FTRACE"); + if ((*avp && !strcmp(*avp, "--ftrace"))) { while (*avp) { *avp = *(avp + 1); avp++; } - ftrace = 1; __argc--; + ftrace = 1; } + if (ftrace) + sym_read_exe_symbols(__program_filename); #if HAS_RDTSC _get_micro_count(); /* init timer base */ #endif diff --git a/elkscmd/debug/readprologue.c b/elkscmd/debug/readprologue.c index 85fa8921c..1a5e0d92c 100644 --- a/elkscmd/debug/readprologue.c +++ b/elkscmd/debug/readprologue.c @@ -8,6 +8,8 @@ #include "instrument.h" #include "syms.h" +#define ADDR_CRT0 0x35 /* address within crt0.S (=_start) */ + #define _get_csbyte(ip) __extension__ ({ \ unsigned char _v; \ asm volatile ("mov %%cs:(%%bx),%%al" \ @@ -34,8 +36,8 @@ int * noinstrument _get_fn_start_address(int *addr) /* look backwards for prologue: push %bp/mov %sp,%bp (55 89 e5) */ for(;;) { - /* main called at 0x37 from crt0.S which has no prologue at _start */ - if ((unsigned int)ip-i <= 0x37) + /* main called at ADDR_CRT0 from crt0.S which has no prologue at _start */ + if ((size_t)ip-i < ADDR_CRT0) return 0; /* _start address or start address not found */ if (_get_csbyte(ip-i+0) == 0x55 && /* push %bp */ @@ -68,8 +70,7 @@ int noinstrument _get_push_count(int *fnstart) if (opcode == 0x57) /* push %di */ count = (count+1) | DI_PUSHED, opcode = _get_csbyte(fp++); if (opcode == 0x55 || /* push %bp */ - (opcode == 0x59 && (unsigned int)fp < 0x40)) /* hack for crt0.S 'pop %cx' start */ + (opcode == 0x59 && (size_t)fp < ADDR_CRT0)) /* hack for crt0.S 'pop %cx' start */ count = (count + 1) | BP_PUSHED, opcode = _get_csbyte(fp); - //printf("%s (%x) pushes %x\n", sym_text_symbol(addr, 1), (int)addr, count); return count; } diff --git a/elkscmd/debug/stacktrace.c b/elkscmd/debug/stacktrace.c index 20fc528c7..1eddeaac4 100644 --- a/elkscmd/debug/stacktrace.c +++ b/elkscmd/debug/stacktrace.c @@ -4,6 +4,7 @@ * June 2022 Greg Haerr */ #include +#include #include "instrument.h" #include "syms.h" @@ -54,6 +55,7 @@ void noinstrument _print_stack(int arg1) int *fn = (int *)_print_stack; int i = 0; + sym_read_exe_symbols(__program_filename); printf("Level Addr BP DI SI Ret Arg Arg2 Arg3 Arg4\n" "~~~~~ ~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); do { diff --git a/elkscmd/debug/syms.c b/elkscmd/debug/syms.c index 3e9483103..013049b9d 100644 --- a/elkscmd/debug/syms.c +++ b/elkscmd/debug/syms.c @@ -14,42 +14,71 @@ #include #include "syms.h" -static unsigned char *syms; +static unsigned char __far *syms; struct minix_exec_hdr sym_hdr; +#define MAGIC 0x0301 /* magic number for executable progs */ + +static void noinstrument fmemcpy(unsigned char __far *dst, unsigned char *src, int n) +{ + do { + *dst++ = *src++; + } while (--n); +} + +/* allocate space and read symbol table */ +static unsigned char __far * noinstrument alloc_read(int fd, size_t size) +{ + if (size == 0 || size > 32767) + return NULL; #if __ia16__ -#define ALLOC(s,n) ((int)(s = sbrk(n)) != -1) + unsigned char __far *s; + size_t n, t = 0; + unsigned char buf[512]; + if (!(s = fmemalloc(size))) + return NULL; + do { + n = size > sizeof(buf)? sizeof(buf): size; + if (read(fd, buf, n) != n) + return NULL; // FIXME no fmemfree + fmemcpy(s+t, buf, n); + t += n; + size -= n; + } while (size); + return s; #else -#define ALLOC(s,n) ((s = malloc(n)) != NULL) -char * __program_filename; + unsigned char *s; + if (!(s = malloc(size))) + return NULL; + if (read(fd, s, size) != size) + return NULL; + return (unsigned char __far *)s; #endif - -#define MAGIC 0x0301 /* magic number for executable progs */ +} /* read symbol table from executable into memory */ -unsigned char * noinstrument sym_read_exe_symbols(char *path) +unsigned char __far * noinstrument sym_read_exe_symbols(char *path) { int fd; - unsigned char *s; + unsigned char __far *s; char fullpath[PATH_MAX]; if (syms) return syms; if ((fd = open(path, O_RDONLY)) < 0) { - sprintf(fullpath, "/bin/%s", path); // FIXME use PATH + strcpy(fullpath, "/bin/"); // FIXME use path + strcpy(fullpath+5, path); if ((fd = open(fullpath, O_RDONLY)) < 0) return NULL; } errno = 0; if (read(fd, &sym_hdr, sizeof(sym_hdr)) != sizeof(sym_hdr) || ((sym_hdr.type & 0xFFFF) != MAGIC) - || (sym_hdr.syms == 0 || sym_hdr.syms > 32767) - || (!ALLOC(s, (int)sym_hdr.syms)) || (lseek(fd, -(int)sym_hdr.syms, SEEK_END) < 0) - || (read(fd, s, (int)sym_hdr.syms) != (int)sym_hdr.syms)) { - int e = errno; - close(fd); - errno = e; - return NULL; + || !(s = alloc_read(fd, (size_t)sym_hdr.syms))) { + int e = errno; + close(fd); + errno = e; + return NULL; } close(fd); syms = s; @@ -57,10 +86,10 @@ unsigned char * noinstrument sym_read_exe_symbols(char *path) } /* read symbol table file into memory */ -unsigned char * noinstrument sym_read_symbols(char *path) +unsigned char __far * noinstrument sym_read_symbols(char *path) { int fd; - unsigned char *s; + unsigned char __far *s; struct stat sbuf; if (syms) return syms; @@ -68,70 +97,91 @@ unsigned char * noinstrument sym_read_symbols(char *path) return NULL; errno = 0; if (fstat(fd, &sbuf) < 0 - || (sbuf.st_size == 0 || sbuf.st_size > 32767) - || (!ALLOC(s, (int)sbuf.st_size)) - || (read(fd, s, (int)sbuf.st_size) != (int)sbuf.st_size)) { - int e = errno; - close(fd); - errno = e; - return NULL; + || !(s = alloc_read(fd, (size_t)sbuf.st_size))) { + int e = errno; + close(fd); + errno = e; + return NULL; } close(fd); syms = s; return syms; } -static int noinstrument type_text(unsigned char *p) +static int noinstrument type_text(unsigned char __far *p) { return (p[TYPE] == 'T' || p[TYPE] == 't' || p[TYPE] == 'W'); } -static int noinstrument type_ftext(unsigned char *p) +static int noinstrument type_ftext(unsigned char __far *p) { return (p[TYPE] == 'F' || p[TYPE] == 'f'); } -static int noinstrument type_data(unsigned char *p) +static int noinstrument type_data(unsigned char __far *p) { return (p[TYPE] == 'D' || p[TYPE] == 'd' || p[TYPE] == 'B' || p[TYPE] == 'b' || p[TYPE] == 'V'); } -#if UNUSED -/* map .text address to function start address */ -void * noinstrument sym_fn_start_address(void *addr) +static char * noinstrument hexout(char *buf, unsigned int v, int zstart) { - unsigned char *p, *lastp; + int sh = 12; + + do { + int c = (v >> sh) & 15; + if (!c && sh > zstart) + continue; + if (c > 9) + *buf++ = 'a' - 10 + c; + else + *buf++ = '0' + c; + } while ((sh -= 4) >= 0); + *buf = '\0'; + return buf; +} - if (!syms && !sym_read_exe_symbols(__program_filename)) - return 0; +static char * noinstrument hex(char *buf, unsigned int v) +{ + return hexout(buf, v, 0); /* %x */ +} - lastp = syms; - for (p = next(lastp); ; lastp = p, p = next(p)) { - if (!type_text(p) || ((unsigned short)addr < *(unsigned short *)(&p[ADDR]))) - break; - } - return (void *) (intptr_t) *(unsigned short *)(&lastp[ADDR]); +static char * noinstrument hex4(char *buf, unsigned int v) +{ + return hexout(buf, v, 12); /* %04x */ +} + +static char * noinstrument fstrncpy(char *dst, unsigned char __far *src, int n) +{ + do { + *dst++ = *src++; + } while (--n); + *dst = '\0'; + return dst; } -#endif /* * Convert address to symbol string+offset, * offset = 0 don't show offset, offset = -1 no offset specified. */ static char * noinstrument sym_string(void *addr, int offset, - int (*istype)(unsigned char *p)) + int (*istype)(unsigned char __far *p)) { - unsigned char *p, *lastp; + unsigned char __far *p; + unsigned char __far *lastp; + char *cp; static char buf[64]; - if (!syms && !sym_read_exe_symbols(__program_filename)) { + if (!syms) { hex: - if (!offset || offset == -1) - sprintf(buf, "%04x", (unsigned int)addr); - else - sprintf(buf, "%04x+%x", (unsigned int)addr-offset, offset); + if (!offset || offset == -1) { + hex4(buf, (size_t)addr); + } else { + cp = hex4(buf, (size_t)addr-offset); + *cp++ = '+'; + hex(cp, offset); + } return buf; } @@ -142,14 +192,17 @@ static char * noinstrument sym_string(void *addr, int offset, goto hex; } for (p = next(lastp); ; lastp = p, p = next(p)) { - if (!istype(p) || ((unsigned short)addr < *(unsigned short *)(&p[ADDR]))) + if (!istype(p) || ((unsigned short)addr < *(unsigned short __far *)(&p[ADDR]))) break; } - int lastaddr = *(unsigned short *)(&lastp[ADDR]); + int lastaddr = *(unsigned short __far *)(&lastp[ADDR]); if (offset && addr - lastaddr) { - sprintf(buf, "%.*s+%x", lastp[SYMLEN], lastp+SYMBOL, - (unsigned int)addr - lastaddr); - } else sprintf(buf, "%.*s", lastp[SYMLEN], lastp+SYMBOL); + cp = fstrncpy(buf, lastp+SYMBOL, lastp[SYMLEN]); + *cp++ = '+'; + hex(cp, (size_t)addr - lastaddr); + } else { + fstrncpy(buf, lastp+SYMBOL, lastp[SYMLEN]); + } return buf; } @@ -172,6 +225,21 @@ char * noinstrument sym_data_symbol(void *addr, int offset) } #if UNUSED +/* map .text address to function start address */ +void * noinstrument sym_fn_start_address(void *addr) +{ + unsigned char __far *p; + unsigned char __far *lastp; + + if (!syms) return NULL; + lastp = syms; + for (p = next(lastp); ; lastp = p, p = next(p)) { + if (!type_text(p) || ((unsigned short)addr < *(unsigned short __far *)(&p[ADDR]))) + break; + } + return (void *) (intptr_t) *(unsigned short __far *)(&lastp[ADDR]); +} + static int noinstrument type_any(unsigned char *p) { return p[TYPE] != '\0'; diff --git a/elkscmd/debug/syms.h b/elkscmd/debug/syms.h index 8a557e745..f5f46d18e 100644 --- a/elkscmd/debug/syms.h +++ b/elkscmd/debug/syms.h @@ -11,7 +11,7 @@ */ #define next(sym) \ - ((sym) + 1 + sizeof(unsigned short) + ((unsigned char *)sym)[SYMLEN] + 1) + ((sym) + 1 + sizeof(unsigned short) + ((unsigned char __far *)sym)[SYMLEN] + 1) #define TYPE 0 #define ADDR 1 #define SYMLEN 3 @@ -19,8 +19,8 @@ #define noinstrument __attribute__((no_instrument_function)) -unsigned char * noinstrument sym_read_exe_symbols(char *path); -unsigned char * noinstrument sym_read_symbols(char *path); +unsigned char __far * noinstrument sym_read_exe_symbols(char *path); +unsigned char __far * noinstrument sym_read_symbols(char *path); char * noinstrument sym_text_symbol(void *addr, int offset); char * noinstrument sym_ftext_symbol(void *addr, int offset); char * noinstrument sym_data_symbol(void *addr, int offset); diff --git a/libc/misc/instrument.c b/libc/misc/instrument.c index 57787bc92..ac4be98cb 100644 --- a/libc/misc/instrument.c +++ b/libc/misc/instrument.c @@ -5,10 +5,10 @@ #include #define noinstrument __attribute__((no_instrument_function)) -static char ftrace; -static int count; +static size_t ftrace; static size_t start_sp; static size_t max_stack; +static int count; /* runs before main and rewrites argc/argv on stack if --ftrace found */ __attribute__((no_instrument_function,constructor(120))) @@ -16,13 +16,14 @@ static void ftrace_checkargs(void) { char **avp = __argv + 1; - if ((*avp && !strcmp(*avp, "--ftrace")) || getenv("FTRACE")) { + ftrace = (size_t)getenv("FTRACE"); + if ((*avp && !strcmp(*avp, "--ftrace"))) { while (*avp) { *avp = *(avp + 1); avp++; } - ftrace = 1; __argc--; + ftrace = 1; } } @@ -41,7 +42,7 @@ void noinstrument __cyg_profile_func_enter_simple(void) for (i=0; i