X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fconfig%2Fi386%2Fgmon-sol2.c;h=e0923a0770f6aeed436b3afbd8da8f9a58335569;hp=35ac1c9abb708b305919e36fe8a338f3c70338b5;hb=4dcd7ab324cb52d2d0ef482173ea8284300944eb;hpb=ed52ae90a3ef61112ed603954ed247e96c5e2733 diff --git a/gcc/config/i386/gmon-sol2.c b/gcc/config/i386/gmon-sol2.c index 35ac1c9abb7..e0923a0770f 100644 --- a/gcc/config/i386/gmon-sol2.c +++ b/gcc/config/i386/gmon-sol2.c @@ -10,10 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * 3. [rescinded 22 July 1999] * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -56,22 +53,25 @@ * This code could easily be integrated with the original gmon.c and perhaps * should be. */ +#include "tconfig.h" +#include "tsystem.h" +#include /* for creat() */ -#ifndef lint -static char sccsid[] = "@(#)gmon.c 5.3 (Berkeley) 5/22/91"; -#endif /* not lint */ - -#if 0 -#include - -#endif #ifdef DEBUG #include #endif -#if 0 -#include "i386/gmon.h" +static void moncontrol (int); +extern void monstartup (char *, char *); +extern void _mcleanup (void); +extern void internal_mcount ( +#ifdef __x86_64__ + char *, unsigned short * #else + void +#endif + ); + struct phdr { char *lpc; @@ -93,6 +93,7 @@ struct tostruct { long count; unsigned short link; }; + struct rawarc { unsigned long raw_frompc; unsigned long raw_selfpc; @@ -100,13 +101,11 @@ struct rawarc { }; #define ROUNDDOWN(x,y) (((x)/(y))*(y)) #define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) -#endif /* char *minbrk; */ -#ifdef __alpha -extern char *sbrk (); -#endif +typedef __SIZE_TYPE__ size_t; +typedef __PTRDIFF_TYPE__ intptr_t; /* * froms is actually a bunch of unsigned shorts indexing tos @@ -117,7 +116,7 @@ static struct tostruct *tos = 0; static long tolimit = 0; static char *s_lowpc = 0; static char *s_highpc = 0; -static unsigned long s_textsize = 0; +static size_t s_textsize = 0; static int ssiz; static char *sbuf; @@ -129,23 +128,24 @@ static int s_scale; extern int errno; -monstartup(lowpc, highpc) - char *lowpc; - char *highpc; +extern void *sbrk (intptr_t); + +void +monstartup(char *lowpc, char *highpc) { - int monsize; + size_t monsize; char *buffer; - register int o; + register size_t o; /* * round lowpc and highpc to multiples of the density we're using * so the rest of the scaling (here and in gprof) stays in ints. */ lowpc = (char *) - ROUNDDOWN((unsigned)lowpc, HISTFRACTION*sizeof(HISTCOUNTER)); + ROUNDDOWN((size_t)lowpc, HISTFRACTION*sizeof(HISTCOUNTER)); s_lowpc = lowpc; highpc = (char *) - ROUNDUP((unsigned)highpc, HISTFRACTION*sizeof(HISTCOUNTER)); + ROUNDUP((size_t)highpc, HISTFRACTION*sizeof(HISTCOUNTER)); s_highpc = highpc; s_textsize = highpc - lowpc; monsize = (s_textsize / HISTFRACTION) + sizeof(struct phdr); @@ -206,7 +206,8 @@ monstartup(lowpc, highpc) moncontrol(1); } -_mcleanup() +void +_mcleanup (void) { int fd; int fromindex; @@ -223,7 +224,7 @@ _mcleanup() } # ifdef DEBUG fprintf( stderr , "[mcleanup] sbuf 0x%x ssiz %d\n" , sbuf , ssiz ); -# endif DEBUG +# endif /* DEBUG */ write( fd , sbuf , ssiz ); endfrom = s_textsize / (HASHFRACTION * sizeof(*froms)); @@ -237,7 +238,7 @@ _mcleanup() fprintf( stderr , "[mcleanup] frompc 0x%x selfpc 0x%x count %d\n" , frompc , tos[toindex].selfpc , tos[toindex].count ); -# endif DEBUG +# endif /* DEBUG */ rawarc.raw_frompc = (unsigned long) frompc; rawarc.raw_selfpc = (unsigned long) tos[toindex].selfpc; rawarc.raw_count = tos[toindex].count; @@ -247,20 +248,65 @@ _mcleanup() close( fd ); } +#ifdef __x86_64__ +/* See GLIBC for additional information about this technique. */ +asm(".globl _mcount\n" + "\t.type\t_mcount, @function\n" + "_mcount:\n" + /* The compiler calls _mcount after the prologue, and does not + save any of the registers. Therefore we must preserve all + seven registers which may contain function arguments. */ + "\tsubq\t$0x38,%rsp\n" + "\tmovq\t%rax,(%rsp)\n" + "\tmovq\t%rcx,0x08(%rsp)\n" + "\tmovq\t%rdx,0x10(%rsp)\n" + "\tmovq\t%rsi,0x18(%rsp)\n" + "\tmovq\t%rdi,0x20(%rsp)\n" + "\tmovq\t%r8,0x28(%rsp)\n" + "\tmovq\t%r9,0x30(%rsp)\n" + /* Get SELFPC (pushed by the call to this function) and + FROMPCINDEX (via the frame pointer. */ + "\tmovq\t0x38(%rsp),%rdi\n" + "\tmovq\t0x8(%rbp),%rsi\n" + "\tcall\tinternal_mcount\n" + /* Restore the saved registers. */ + "\tmovq\t0x30(%rsp),%r9\n" + "\tmovq\t0x28(%rsp),%r8\n" + "\tmovq\t0x20(%rsp),%rdi\n" + "\tmovq\t0x18(%rsp),%rsi\n" + "\tmovq\t0x10(%rsp),%rdx\n" + "\tmovq\t0x08(%rsp),%rdx\n" + "\tmovq\t(%rsp),%rax\n" + "\taddq\t$0x38,%rsp\n" + "\tretq\n" + ); +#else /* Solaris 2 libraries use _mcount. */ asm(".globl _mcount; _mcount: jmp internal_mcount"); /* This is for compatibility with old versions of gcc which used mcount. */ asm(".globl mcount; mcount: jmp internal_mcount"); +#endif -internal_mcount() +void +internal_mcount ( +#ifdef __x86_64__ + char *selfpc, + unsigned short *frompcindex +#else + void +#endif + ) { +#ifndef __x86_64__ register char *selfpc; register unsigned short *frompcindex; +#endif register struct tostruct *top; register struct tostruct *prevtop; register long toindex; static char already_setup; +#ifndef __x86_64__ /* * find the return address for mcount, * and the return address for mcount's caller. @@ -272,12 +318,16 @@ internal_mcount() /* frompcindex = pc in preceding frame. This identifies the caller of the function just entered. */ frompcindex = (void *) __builtin_return_address (1); +#endif if(!already_setup) { - extern etext(); + extern char etext[]; already_setup = 1; -/* monstartup(0, etext); */ - monstartup(0x08040000, etext); +#ifdef __x86_64__ + monstartup(0, etext); +#else + monstartup((char*)0x08040000, etext); +#endif #ifdef USE_ONEXIT on_exit(_mcleanup, 0); #else @@ -390,15 +440,15 @@ overflow: * profiling is what mcount checks to see if * all the data structures are ready. */ -moncontrol(mode) - int mode; +static void +moncontrol(int mode) { if (mode) { /* start */ profil((unsigned short *)(sbuf + sizeof(struct phdr)), ssiz - sizeof(struct phdr), - (int)s_lowpc, s_scale); + (size_t)s_lowpc, s_scale); profiling = 0; } else {