From 67eff66438688fddebe41f77fd252a3b2b135271 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 3 Mar 2003 20:58:42 +0000 Subject: Initial effort at adding profiling support. --- libc/sysdeps/linux/i386/Makefile | 13 +++++- libc/sysdeps/linux/i386/bits/atomicity.h | 57 +++++++++++++++++++++++++++ libc/sysdeps/linux/i386/bits/machine-gmon.h | 41 +++++++++++++++++++ libc/sysdeps/linux/i386/bits/profil-counter.h | 27 +++++++++++++ libc/sysdeps/linux/i386/bits/sigcontextinfo.h | 51 ++++++++++++++++++++++++ libc/sysdeps/linux/i386/bits/stackinfo.h | 28 +++++++++++++ libc/sysdeps/linux/i386/crt0.S | 7 +++- libc/sysdeps/linux/i386/mcount.S | 54 +++++++++++++++++++++++++ 8 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 libc/sysdeps/linux/i386/bits/atomicity.h create mode 100644 libc/sysdeps/linux/i386/bits/machine-gmon.h create mode 100644 libc/sysdeps/linux/i386/bits/profil-counter.h create mode 100644 libc/sysdeps/linux/i386/bits/sigcontextinfo.h create mode 100644 libc/sysdeps/linux/i386/bits/stackinfo.h create mode 100644 libc/sysdeps/linux/i386/mcount.S (limited to 'libc/sysdeps/linux/i386') diff --git a/libc/sysdeps/linux/i386/Makefile b/libc/sysdeps/linux/i386/Makefile index 9ca790cff..c7e1db947 100644 --- a/libc/sysdeps/linux/i386/Makefile +++ b/libc/sysdeps/linux/i386/Makefile @@ -21,10 +21,14 @@ include $(TOPDIR)Rules.mak ASFLAGS=$(CFLAGS) CRT0_SRC = crt0.S -CRT0_OBJ = crt0.o crt1.o +CRT0_OBJ = crt0.o crt1.o gcrt1.o +CRT0_DEPS=gmon-start.S SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S \ bsd-_setjmp.S syscall.S +ifeq ($(strip $(UCLIBC_PROFILING)),y) +SSRC+=mcount.S +endif SOBJS=$(patsubst %.S,%.o, $(SSRC)) CSRC=brk.c sigaction.c @@ -53,6 +57,13 @@ $(COBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o +ifeq ($(strip $(UCLIBC_PROFILING)),y) +SAFECFLAGS := $(subst -g,,$(CFLAGS)) +gmon-start.S: ../common/gmon-start.c + $(CC) $(SAFECFLAGS) -c $< -S -o $*.S +gcrt1.o: $(CRT0_DEPS) +endif + headers: diff --git a/libc/sysdeps/linux/i386/bits/atomicity.h b/libc/sysdeps/linux/i386/bits/atomicity.h new file mode 100644 index 000000000..df2fb8184 --- /dev/null +++ b/libc/sysdeps/linux/i386/bits/atomicity.h @@ -0,0 +1,57 @@ +/* Low-level functions for atomic operations. ix86 version, x >= 4. + Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _ATOMICITY_H +#define _ATOMICITY_H 1 + +#include + + +static inline uint32_t +__attribute__ ((unused)) +exchange_and_add (volatile uint32_t *mem, uint32_t val) +{ + register uint32_t result; + __asm__ __volatile__ ("lock; xaddl %0,%1" + : "=r" (result), "=m" (*mem) : "0" (val), "1" (*mem)); + return result; +} + +static inline void +__attribute__ ((unused)) +atomic_add (volatile uint32_t *mem, int val) +{ + __asm__ __volatile__ ("lock; addl %1,%0" + : "=m" (*mem) : "ir" (val), "0" (*mem)); +} + +static inline char +__attribute__ ((unused)) +compare_and_swap (volatile long int *p, long int oldval, long int newval) +{ + char ret; + long int readval; + + __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0" + : "=q" (ret), "=m" (*p), "=a" (readval) + : "r" (newval), "1" (*p), "a" (oldval)); + return ret; +} + +#endif /* atomicity.h */ diff --git a/libc/sysdeps/linux/i386/bits/machine-gmon.h b/libc/sysdeps/linux/i386/bits/machine-gmon.h new file mode 100644 index 000000000..6c860bc01 --- /dev/null +++ b/libc/sysdeps/linux/i386/bits/machine-gmon.h @@ -0,0 +1,41 @@ +/* i386-specific implementation of profiling support. + Copyright (C) 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +/* We need a special version of the `mcount' function since for ix86 it + must not clobber any register. This has several reasons: + - there is a bug in gcc as of version 2.7.2.2 which prohibits the + use of profiling together with nested functions + - the ELF `fixup' function uses GCC's regparm feature + - some (future) systems might want to pass parameters in registers. */ + +/* We must not pollute the global namespace. */ +#define mcount_internal __mcount_internal + +extern void mcount_internal (u_long frompc, u_long selfpc); + +#define _MCOUNT_DECL(frompc, selfpc) \ +void mcount_internal (u_long frompc, u_long selfpc) + + +/* Define MCOUNT as empty since we have the implementation in another + file. */ +#define MCOUNT diff --git a/libc/sysdeps/linux/i386/bits/profil-counter.h b/libc/sysdeps/linux/i386/bits/profil-counter.h new file mode 100644 index 000000000..80933a36f --- /dev/null +++ b/libc/sysdeps/linux/i386/bits/profil-counter.h @@ -0,0 +1,27 @@ +/* Low-level statistical profiling support function. Linux/i386 version. + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +static void +profil_counter (int signo, SIGCONTEXT scp) +{ + profil_count ((void *) GET_PC (scp)); +} diff --git a/libc/sysdeps/linux/i386/bits/sigcontextinfo.h b/libc/sysdeps/linux/i386/bits/sigcontextinfo.h new file mode 100644 index 000000000..6530ba6f3 --- /dev/null +++ b/libc/sysdeps/linux/i386/bits/sigcontextinfo.h @@ -0,0 +1,51 @@ +/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define SIGCONTEXT struct sigcontext +#define SIGCONTEXT_EXTRA_ARGS +#define GET_PC(ctx) ((void *) ctx.eip) +#define GET_FRAME(ctx) ((void *) ctx.ebp) +#define GET_STACK(ctx) ((void *) ctx.esp_at_signal) +#define CALL_SIGHANDLER(handler, signo, ctx) \ +do { \ + int __tmp1, __tmp2, __tmp3, __tmp4; \ + __asm __volatile ("movl\t%%esp, %%edi\n\t" \ + "andl\t$-16, %%esp\n\t" \ + "subl\t%8, %%esp\n\t" \ + "movl\t%%edi, %c8-4(%%esp)\n\t" \ + "movl\t%1, 0(%%esp)\n\t" \ + "leal\t4(%%esp), %%edi\n\t" \ + "cld\n\t" \ + "rep\tmovsl\n\t" \ + "call\t*%0\n\t" \ + "cld\n\t" \ + "movl\t%9, %%ecx\n\t" \ + "subl\t%%edi, %%esi\n\t" \ + "leal\t4(%%esp,%%esi,1), %%edi\n\t" \ + "leal\t4(%%esp), %%esi\n\t" \ + "rep\tmovsl\n\t" \ + "movl\t%c8-4(%%esp), %%esp\n\t" \ + : "=a" (__tmp1), "=d" (__tmp2), "=S" (__tmp3), \ + "=c" (__tmp4) \ + : "0" (handler), "1" (signo), "2" (&ctx), \ + "3" (sizeof (struct sigcontext) / 4), \ + "n" ((sizeof (struct sigcontext) + 19) & ~15), \ + "i" (sizeof (struct sigcontext) / 4) \ + : "cc", "edi"); \ +} while (0) diff --git a/libc/sysdeps/linux/i386/bits/stackinfo.h b/libc/sysdeps/linux/i386/bits/stackinfo.h new file mode 100644 index 000000000..a9a6745aa --- /dev/null +++ b/libc/sysdeps/linux/i386/bits/stackinfo.h @@ -0,0 +1,28 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +/* On x86 the stack grows down. */ +#define _STACK_GROWS_DOWN 1 + +#endif /* stackinfo.h */ diff --git a/libc/sysdeps/linux/i386/crt0.S b/libc/sysdeps/linux/i386/crt0.S index e871c0876..3930a1690 100644 --- a/libc/sysdeps/linux/i386/crt0.S +++ b/libc/sysdeps/linux/i386/crt0.S @@ -74,7 +74,7 @@ _start: pushl %ebp /* callers %ebp (frame pointer) */ movl %esp,%ebp /* mark callers stack frame as invalid */ -#if defined L_crt1 && defined __UCLIBC_CTOR_DTOR__ +#if (defined L_crt1 || defined L_gcrt1 ) && defined __UCLIBC_CTOR_DTOR__ /* Push .init and .fini arguments to __uClibc_start_main() on the stack */ pushl $_fini pushl $_init @@ -99,3 +99,8 @@ _start: hlt .size _start,.-_start + +#if defined L_gcrt1 +# include "./gmon-start.S" +#endif + diff --git a/libc/sysdeps/linux/i386/mcount.S b/libc/sysdeps/linux/i386/mcount.S new file mode 100644 index 000000000..704a7b851 --- /dev/null +++ b/libc/sysdeps/linux/i386/mcount.S @@ -0,0 +1,54 @@ +/* i386-specific implemetation of profiling support. + Copyright (C) 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +/* We need a special version of the `mcount' function since for ix86 it + must not clobber any register. This has several reasons: + - there is a bug in gcc as of version 2.7.2.2 which prohibits the + use of profiling together with nested functions + - the ELF `fixup' function uses GCC's regparm feature + - some (future) systems might want to pass parameters in registers. */ + + .globl _mcount + .type _mcount,@function; + .align 1<<4 +_mcount: + /* Save the caller-clobbered registers. */ + pushl %eax + pushl %ecx + pushl %edx + + movl 12(%esp), %edx + movl 4(%ebp), %eax + + /* No need to access the PLT or GOT, __mcount_internal is an + internal function and we can make a relative call. */ + call __mcount_internal + + /* Pop the saved registers. Please note that `mcount' has no + return value. */ + popl %edx + popl %ecx + popl %eax + ret + .size _mcount,.-_mcount; + +#undef mcount +.weak mcount ; mcount = _mcount -- cgit v1.2.3