diff --git a/src/libc/crt0/makefile b/src/libc/crt0/makefile index 34abdf385..029b073a9 100644 --- a/src/libc/crt0/makefile +++ b/src/libc/crt0/makefile @@ -12,7 +12,8 @@ SRC += c1args.c SRC += c1loadef.c SRC += c1pglob.c SRC += crt1.c -SRC += mcount.c +SRC += mcount_i.c +SRC += mcount.S SRC += memhandl.c SRC += rfinfo.c SRC += dfinfo.c @@ -40,5 +41,5 @@ $(LIB)/gcrt0.o : gcrt0.S crt0.S exit16.ah sbrk16.ah $(MISC) rm gcrt0.o sed 's@gcrt0.o@$(LIB)/gcrt0.o@' gcrt0.d > gcrt02.d -mcount.o : mcount.c +mcount_i.o : mcount_i.c $(XNOPGGCC) -c $< diff --git a/src/libc/crt0/mcount.S b/src/libc/crt0/mcount.S new file mode 100644 index 000000000..823580d5b --- /dev/null +++ b/src/libc/crt0/mcount.S @@ -0,0 +1,25 @@ + .intel_syntax noprefix + .text + .globl _mcount +_mcount: + cmp esp, offset _etext + jb Lstack_overflow + push ebp + push ecx + push eax + mov ecx, [ebp+4] + mov ebp, esp + and esp, -16 # Keep stack aligned + mov eax, [ebp+12] + sub esp, 4 + push edx # Pointer to cached MTAB entry + push eax # Our return address (callee) + push ecx # Callee's return address (caller) + call ___mcount_internal + mov esp, ebp + pop eax + pop ecx + pop ebp + ret +Lstack_overflow: + ud2 diff --git a/src/libc/crt0/mcount.c b/src/libc/crt0/mcount_i.c similarity index 91% rename from src/libc/crt0/mcount.c rename to src/libc/crt0/mcount_i.c index a0479b1bd..7b16ac062 100644 --- a/src/libc/crt0/mcount.c +++ b/src/libc/crt0/mcount_i.c @@ -38,7 +38,7 @@ typedef struct MTAB { static header h; static short *histogram; -static int mcount_skip = 1; +static volatile unsigned char mcount_skip = 1; static int histlen; static MTAB *mtab=0; @@ -48,35 +48,24 @@ extern int etext __asm__("etext"); static int profiling_p; -/* called by functions. Use the pointer it provides to cache +/* called by mcount. Use the pointer it provides to cache ** the last used MTABE, so that repeated calls to/from the same ** pair works quickly - no lookup. */ -void mcount(int _to); -void mcount(int _to) +void __mcount_internal(unsigned long from, unsigned long to, MTABE **cache); +void __mcount_internal(unsigned long from, unsigned long to, MTABE **cache) { MTAB *m; int i; - unsigned int to; - int ebp; - unsigned int from; int mtabi; - MTABE **cache; - - /* obtain the cached pointer */ - __asm__ __volatile__ ("movl %%edx,%0" : "=g" (cache)); mcount_skip = 1; /* Do nothing if profiling is disabled. */ if (!profiling_p) return; - if (&_to < &etext) - *(int *)(-1) = 0; /* fault! */ + to -= 12; - to = *((&_to)-1) - 12; - ebp = *((&_to)-2); /* glean the caller's return address from the stack */ - from = ((int *)ebp)[1]; /* Do nothing if the FROM address is outside the sampling range. */ if (from < h.low || from >= h.high) return;