kprof did not guess correctly the kernel start address, nor did take into account that it should compare addresses using symboladdress>>3 and not using profilingaddress<<3, because that might report the wrong function even if resolution suffices. It now uses libmach kernel start address instead of trying to guess it. the start address for 386 seems to be wrong in libmach Reference: /n/sources/patch/applied/kprof Date: Fri Nov 18 16:52:56 CET 2011 Signed-off-by: nemo@lsub.org --- /sys/src/cmd/kprof.c Fri Nov 18 16:52:01 2011 +++ /sys/src/cmd/kprof.c Fri Nov 18 16:51:58 2011 @@ -94,19 +94,25 @@ exits(0); if (!textsym(&s, 0)) error(0, "no text symbols"); - tbase = s.value & ~(mach->pgsize-1); /* align down to page */ - print("KTZERO %.8llux\n", tbase); + + tbase = mach->kbase; + if(tbase != s.value & ~0xFFF) + print("warning: kbase %.8llux != tbase %.8llux\n", + tbase, s.value&~0xFFF); + print("KTZERO %.8llux PGSIZE %dKb\n", tbase, mach->pgsize/1024); /* * Accumulate counts for each function */ cp = 0; k = 0; - for (i = 0, j = (s.value-tbase)/PCRES+2; j < n; i++) { + for (i = 0, j = 2; j < n; i++) { name = s.name; /* save name */ if (!textsym(&s, i)) /* get next symbol */ break; + s.value -= tbase; + s.value /= PCRES; sum = 0; - while (j < n && j*PCRES < s.value-tbase) + while (j < n && j < s.value) sum += data[j++]; if (sum) { cp = realloc(cp, (k+1)*sizeof(struct COUNTER)); --- /sys/src/libmach/8.c Fri Nov 18 16:52:06 2011 +++ /sys/src/libmach/8.c Fri Nov 18 16:52:03 2011 @@ -68,7 +68,7 @@ "setSB", /* static base register name (bogus anyways) */ 0, /* static base register value */ 0x1000, /* page size */ - 0x80100000ULL, /* kernel base */ + 0xF0100000ULL, /* kernel base */ 0xF0000000ULL, /* kernel text mask */ 0x7FFFFFFFULL, /* user stack top */ 1, /* quantization of pc */