summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/sysdeps/linux/alpha/__longjmp.S9
-rw-r--r--libc/sysdeps/linux/alpha/bits/machine-gmon.h26
-rw-r--r--libc/sysdeps/linux/alpha/brk.S6
-rw-r--r--libc/sysdeps/linux/alpha/clone.S11
-rw-r--r--libc/sysdeps/linux/alpha/divrem.h31
-rw-r--r--libc/sysdeps/linux/alpha/setjmp.S6
-rw-r--r--libc/sysdeps/linux/arm/Makefile8
-rw-r--r--libc/sysdeps/linux/arm/bits/machine-gmon.h67
-rw-r--r--libc/sysdeps/linux/arm/crt0.S7
-rw-r--r--libc/sysdeps/linux/common/Makefile3
-rw-r--r--libc/sysdeps/linux/common/bits/dlfcn.h22
-rw-r--r--libc/sysdeps/linux/common/bits/machine-gmon.h58
-rw-r--r--libc/sysdeps/linux/common/gmon-start.c58
-rw-r--r--libc/sysdeps/linux/common/gmon.c640
-rw-r--r--libc/sysdeps/linux/cris/bits/machine-gmon.h28
-rw-r--r--libc/sysdeps/linux/cris/sysdep.h24
-rw-r--r--libc/sysdeps/linux/frv/Makefile12
-rw-r--r--libc/sysdeps/linux/frv/crt0.S6
-rw-r--r--libc/sysdeps/linux/i386/Makefile11
-rw-r--r--libc/sysdeps/linux/i386/bits/machine-gmon.h41
-rw-r--r--libc/sysdeps/linux/i386/crt0.S6
-rw-r--r--libc/sysdeps/linux/i386/mcount.S54
-rw-r--r--libc/sysdeps/linux/mips/bits/dlfcn.h22
-rw-r--r--libc/sysdeps/linux/mips/bits/machine-gmon.h73
-rw-r--r--libc/sysdeps/linux/mips/clone.S6
-rw-r--r--libc/sysdeps/linux/mips/pipe.S7
-rw-r--r--libc/sysdeps/linux/powerpc/Makefile11
-rw-r--r--libc/sysdeps/linux/powerpc/bits/machine-gmon.h31
-rw-r--r--libc/sysdeps/linux/powerpc/crt0.S6
-rw-r--r--libc/sysdeps/linux/powerpc/mcount.S100
-rw-r--r--libc/sysdeps/linux/sh/Makefile8
-rw-r--r--libc/sysdeps/linux/sh/bits/machine-gmon.h83
-rw-r--r--libc/sysdeps/linux/sh/crt0.S6
33 files changed, 11 insertions, 1476 deletions
diff --git a/libc/sysdeps/linux/alpha/__longjmp.S b/libc/sysdeps/linux/alpha/__longjmp.S
index 2db4e22e9..b78489f53 100644
--- a/libc/sysdeps/linux/alpha/__longjmp.S
+++ b/libc/sysdeps/linux/alpha/__longjmp.S
@@ -29,16 +29,7 @@
__longjmp:
.frame $30 , 0, $26
-#ifdef PROF
- ldgp gp, 0(pv)
- .set noat
- lda AT, _mcount
- jsr AT, (AT), _mcount
- .set at
- .prologue 1
-#else
.prologue 0
-#endif
mov $17, $0
ldq $9, JB_S0*8(a0)
diff --git a/libc/sysdeps/linux/alpha/bits/machine-gmon.h b/libc/sysdeps/linux/alpha/bits/machine-gmon.h
deleted file mode 100644
index 5f5522c0b..000000000
--- a/libc/sysdeps/linux/alpha/bits/machine-gmon.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Machine-specific calling sequence for `mcount' profiling function. alpha
- Copyright (C) 1995, 1996, 1997 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. */
-
-#define _MCOUNT_DECL(from, self) \
- void __mcount (u_long from, u_long self)
-
-/* Call __mcount with our the return PC for our caller, and the return
- PC our caller will return to. Empty since we use an assembly stub
- instead. */
-#define MCOUNT
diff --git a/libc/sysdeps/linux/alpha/brk.S b/libc/sysdeps/linux/alpha/brk.S
index 8c70a0ce5..4e15518d2 100644
--- a/libc/sysdeps/linux/alpha/brk.S
+++ b/libc/sysdeps/linux/alpha/brk.S
@@ -46,12 +46,6 @@ __brk:
.frame $30 , 8 , $26
ldgp $29, 0($27)
subq $30, 8, $30
-#ifdef PROF
- .set noat
- lda AT, _mcount
- jsr AT, (AT), _mcount
- .set at
-#endif
.prologue 1
/* Save the requested brk across the system call. */
diff --git a/libc/sysdeps/linux/alpha/clone.S b/libc/sysdeps/linux/alpha/clone.S
index b17a5ec68..396816184 100644
--- a/libc/sysdeps/linux/alpha/clone.S
+++ b/libc/sysdeps/linux/alpha/clone.S
@@ -44,16 +44,7 @@
__clone:
.frame $30 , 0, $26
-#ifdef PROF
- ldgp gp,0(pv)
- .set noat
- lda AT, _mcount
- jsr AT, (AT), _mcount
- .set at
- .prologue 1
-#else
.prologue 0
-#endif
/* Sanity check arguments. */
ldiq v0,EINVAL
@@ -78,10 +69,8 @@ __clone:
/* Something bad happened -- no child created */
$error:
-#ifndef PROF
br gp,1f
1: ldgp gp,0(gp)
-#endif
jmp zero,__syscall_error
.end __clone
diff --git a/libc/sysdeps/linux/alpha/divrem.h b/libc/sysdeps/linux/alpha/divrem.h
index d22759e40..ca3db4b49 100644
--- a/libc/sysdeps/linux/alpha/divrem.h
+++ b/libc/sysdeps/linux/alpha/divrem.h
@@ -130,22 +130,6 @@
UFUNC_NAME:
lda sp, -STACK(sp)
.frame sp, STACK, retaddr, 0
-#ifdef PROF
- stq ra, 0(sp)
- stq pv, 8(sp)
- stq gp, 16(sp)
-
- br AT, 1f
-1: ldgp gp, 0(AT)
-
- mov retaddr, ra
- lda AT, _mcount
- jsr AT, (AT), _mcount
-
- ldq ra, 0(sp)
- ldq pv, 8(sp)
- ldq gp, 16(sp)
-#endif
.prologue 0
$udiv:
@@ -216,21 +200,6 @@ $divbyzero:
SFUNC_NAME:
lda sp, -STACK(sp)
.frame sp, STACK, retaddr, 0
-#ifdef PROF
- stq ra, 0(sp)
- stq pv, 8(sp)
- stq gp, 16(sp)
-
- br AT, 1f
-1: ldgp gp, 0(AT)
-
- mov retaddr, ra
- jsr AT, _mcount
-
- ldq ra, 0(sp)
- ldq pv, 8(sp)
- ldq gp, 16(sp)
-#endif
.prologue 0
or arg1, arg2, AT
diff --git a/libc/sysdeps/linux/alpha/setjmp.S b/libc/sysdeps/linux/alpha/setjmp.S
index 69649eeab..105cc8292 100644
--- a/libc/sysdeps/linux/alpha/setjmp.S
+++ b/libc/sysdeps/linux/alpha/setjmp.S
@@ -34,12 +34,6 @@ $sigsetjmp_local:
.frame $26, 16, $26, 0
stq $26, 0($30)
.mask 0x04000000, -16
-#ifdef PROF
- .set noat
- lda AT, _mcount
- jsr AT, (AT), _mcount
- .set at
-#endif
.prologue 1
stq $9, JB_S0*8(a0)
diff --git a/libc/sysdeps/linux/arm/Makefile b/libc/sysdeps/linux/arm/Makefile
index f2582e1a8..6a80686a7 100644
--- a/libc/sysdeps/linux/arm/Makefile
+++ b/libc/sysdeps/linux/arm/Makefile
@@ -21,7 +21,7 @@ include $(TOPDIR)Rules.mak
ASFLAGS=$(CFLAGS)
CRT0_SRC = crt0.S
-CRT0_OBJ = crt0.o crt1.o gcrt1.o
+CRT0_OBJ = crt0.o crt1.o
CRT0_DEPS=gmon-start.S
CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
@@ -54,12 +54,6 @@ $(COBJS): %.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
-ifeq ($(strip $(UCLIBC_PROFILING)),y)
-gmon-start.S: ../common/gmon-start.c
- $(CC) $(CFLAGS) -c $< -S -o $*.S
-gcrt1.o: $(CRT0_DEPS)
-endif
-
ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
crti.o: crti.S
$(CC) $(CFLAGS) -c crti.S -o crti.o
diff --git a/libc/sysdeps/linux/arm/bits/machine-gmon.h b/libc/sysdeps/linux/arm/bits/machine-gmon.h
deleted file mode 100644
index 039dfd951..000000000
--- a/libc/sysdeps/linux/arm/bits/machine-gmon.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Machine-dependent definitions for profiling support. ARM 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. */
-
-/* GCC for the ARM cannot compile __builtin_return_address(N) for N != 0,
- so we must use an assembly stub. */
-
-#include <sysdep.h>
-#ifndef NO_UNDERSCORES
-/* The asm symbols for C functions are `_function'.
- The canonical name for the counter function is `mcount', no _. */
-void _mcount (void) asm ("mcount");
-#else
-/* The canonical name for the function is `_mcount' in both C and asm,
- but some old asm code might assume it's `mcount'. */
-void _mcount (void);
-weak_alias (_mcount, mcount)
-#endif
-
-static void mcount_internal (u_long frompc, u_long selfpc);
-
-#define _MCOUNT_DECL(frompc, selfpc) \
-static void mcount_internal (u_long frompc, u_long selfpc)
-
-/* This macro/func MUST save r0, r1 because the compiler inserts
- blind calls to _mount(), ignoring the fact that _mcount may
- clobber registers; therefore, _mcount may NOT clobber registers */
-/* if (this_fp!=0) {
- r0 = this_fp
- r1 = this_lr
- r1 = [r1-4] which is caller's lr
- if (r1!=0)
- r1 = caller's lr
- call mcount_internal(this_lr, caller's_lr)
- }
-*/
-
-#define MCOUNT \
-void _mcount (void) \
-{ \
- __asm__("stmdb sp!, {r0, r1, r2, r3};" \
- "movs fp, fp;" \
- "moveq r1, #0;" \
- "ldrne r1, [fp, $-4];" \
- "ldrne r0, [fp, $-12];" \
- "movnes r0, r0;" \
- "ldrne r0, [r0, $-4];" \
- "movs r0, r0;" \
- "blne mcount_internal;" \
- "ldmia sp!, {r0, r1, r2, r3}"); \
-}
-
diff --git a/libc/sysdeps/linux/arm/crt0.S b/libc/sysdeps/linux/arm/crt0.S
index 6704a81e2..455d35d2d 100644
--- a/libc/sysdeps/linux/arm/crt0.S
+++ b/libc/sysdeps/linux/arm/crt0.S
@@ -92,7 +92,7 @@ _start:
ldr r2,[sp, #8]
#endif
-#if (defined L_crt1 || defined L_gcrt1 ) && defined __UCLIBC_CTOR_DTOR__
+#if (defined L_crt1 ) && defined __UCLIBC_CTOR_DTOR__
/* Store the address of _init in r3 as an argument to main() */
ldr r3, =_init
@@ -123,11 +123,6 @@ _start:
.long 2,0,0
3: .align 4
-#if defined L_gcrt1 && defined __UCLIBC_PROFILING__
-# include "./gmon-start.S"
-#endif
-
-
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
diff --git a/libc/sysdeps/linux/common/Makefile b/libc/sysdeps/linux/common/Makefile
index 1256e2376..1930351fb 100644
--- a/libc/sysdeps/linux/common/Makefile
+++ b/libc/sysdeps/linux/common/Makefile
@@ -57,9 +57,6 @@ CSRC= __rt_sigtimedwait.c __socketcall.c __syscall_fcntl.c \
ifneq ($(strip $(EXCLUDE_BRK)),y)
CSRC+=sbrk.c
endif
-ifeq ($(strip $(UCLIBC_PROFILING)),y)
-CSRC+=gmon.c
-endif
ifeq ($(strip $(UCLIBC_PROPOLICE)),y)
CSRC+=ssp.c
endif
diff --git a/libc/sysdeps/linux/common/bits/dlfcn.h b/libc/sysdeps/linux/common/bits/dlfcn.h
index e96b5c17a..75122a98a 100644
--- a/libc/sysdeps/linux/common/bits/dlfcn.h
+++ b/libc/sysdeps/linux/common/bits/dlfcn.h
@@ -40,25 +40,3 @@
/* Do not delete object when closed. */
#define RTLD_NODELETE 0x01000
-#ifdef __USE_GNU
-/* To support profiling of shared objects it is a good idea to call
- the function found using `dlsym' using the following macro since
- these calls do not use the PLT. But this would mean the dynamic
- loader has no chance to find out when the function is called. The
- macro applies the necessary magic so that profiling is possible.
- Rewrite
- foo = (*fctp) (arg1, arg2);
- into
- foo = DL_CALL_FCT (fctp, (arg1, arg2));
-*/
-# define DL_CALL_FCT(fctp, args) \
- (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
-
-__BEGIN_DECLS
-
-/* This function calls the profiling functions. */
-extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;
-
-__END_DECLS
-
-#endif
diff --git a/libc/sysdeps/linux/common/bits/machine-gmon.h b/libc/sysdeps/linux/common/bits/machine-gmon.h
deleted file mode 100644
index 7dd36308b..000000000
--- a/libc/sysdeps/linux/common/bits/machine-gmon.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Machine-dependent definitions for profiling support. Generic GCC 2 version.
- Copyright (C) 1996, 1997, 2000 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. */
-
-/* GCC version 2 gives us a perfect magical function to get
- just the information we need:
- void *__builtin_return_address (unsigned int N)
- returns the return address of the frame N frames up. */
-
-/* Be warned that GCC cannot usefully compile __builtin_return_address(N)
- for N != 0 on all machines. In this case, you may have to write
- your own version of _mcount(). */
-
-#if __GNUC__ < 2
- #error "This file uses __builtin_return_address, a GCC 2 extension."
-#endif
-
-#include <sysdep.h>
-#ifndef NO_UNDERSCORES
-/* The asm symbols for C functions are `_function'.
- The canonical name for the counter function is `mcount', no _. */
-void _mcount (void) asm ("mcount");
-#else
-/* The canonical name for the function is `_mcount' in both C and asm,
- but some old asm code might assume it's `mcount'. */
-void _mcount (void);
-weak_alias (_mcount, mcount)
-#endif
-
-static void mcount_internal (u_long frompc, u_long selfpc);
-
-#define _MCOUNT_DECL(frompc, selfpc) \
-static inline void mcount_internal (u_long frompc, u_long selfpc)
-
-#ifndef RETURN_ADDRESS
-#define RETURN_ADDRESS(n) __builtin_return_address(n)
-#endif
-
-#define MCOUNT \
-void _mcount (void) \
-{ \
- mcount_internal ((u_long) RETURN_ADDRESS (1), (u_long) RETURN_ADDRESS (0)); \
-}
diff --git a/libc/sysdeps/linux/common/gmon-start.c b/libc/sysdeps/linux/common/gmon-start.c
deleted file mode 100644
index 6878a7a71..000000000
--- a/libc/sysdeps/linux/common/gmon-start.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Code to enable profiling at program startup.
- Copyright (C) 1995,1996,1997,2000,2001,2002 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 <features.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/gmon.h>
-
-#ifdef __UCLIBC_PROFILING__
-
-/* Beginning and end of our code segment. We cannot declare them
- as the external functions since we want the addresses of those
- labels. Taking the address of a function may have different
- meanings on different platforms. */
-
-extern void _start;
-extern void etext;
-
-
-void __gmon_start__ (void)
-{
-#ifdef __UCLIBC_CTOR_DTOR__
- /* Protect from being called more than once. Since crti.o is linked
- into every shared library, each of their init functions will call us. */
- static int called;
-
- if (called)
- return;
-
- called = 1;
-#endif
-
- /* Start keeping profiling records. */
- monstartup ((u_long) &_start, (u_long) &etext);
-
- /* Call _mcleanup before exiting; it will write out gmon.out from the
- collected data. */
- atexit (&_mcleanup);
-}
-#endif
-
diff --git a/libc/sysdeps/linux/common/gmon.c b/libc/sysdeps/linux/common/gmon.c
deleted file mode 100644
index a3444a28e..000000000
--- a/libc/sysdeps/linux/common/gmon.c
+++ /dev/null
@@ -1,640 +0,0 @@
-/*-
- * Copyright (c) 1983, 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 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.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <features.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/gmon.h>
-#include <sys/gmon_out.h>
-#include <sys/uio.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-#ifdef __UCLIBC_PROFILING__
-
-/* Head of basic-block list or NULL. */
-struct __bb *__bb_head;
-
-struct gmonparam _gmonparam = { state: GMON_PROF_OFF };
-
-/*
- * See profil(2) where this is described:
- */
-static int s_scale;
-#define SCALE_1_TO_1 0x10000L
-
-#define ERR(s) write (STDERR_FILENO, s, sizeof (s) - 1)
-
-void moncontrol __P ((int mode));
-static void write_hist __P ((int fd));
-static void write_call_graph __P ((int fd));
-static void write_bb_counts __P ((int fd));
-
-/*
- * Control profiling
- * profiling is what mcount checks to see if
- * all the data structures are ready.
- */
-void moncontrol (int mode)
-{
- struct gmonparam *p = &_gmonparam;
-
- /* Don't change the state if we ran into an error. */
- if (p->state == GMON_PROF_ERROR)
- return;
-
- if (mode)
- {
- /* start */
- profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale);
- p->state = GMON_PROF_ON;
- }
- else
- {
- /* stop */
- profil(NULL, 0, 0, 0);
- p->state = GMON_PROF_OFF;
- }
-}
-
-
-void monstartup (u_long lowpc, u_long highpc)
-{
- register int o;
- char *cp;
- struct gmonparam *p = &_gmonparam;
-
- /*
- * 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.
- */
- p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
- p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
- p->textsize = p->highpc - p->lowpc;
- p->kcountsize = p->textsize / HISTFRACTION;
- p->hashfraction = HASHFRACTION;
- p->log_hashfraction = -1;
- /* The following test must be kept in sync with the corresponding
- test in mcount.c. */
- if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) {
- /* if HASHFRACTION is a power of two, mcount can use shifting
- instead of integer division. Precompute shift amount. */
- p->log_hashfraction = ffs(p->hashfraction * sizeof(*p->froms)) - 1;
- }
- p->fromssize = p->textsize / HASHFRACTION;
- p->tolimit = p->textsize * ARCDENSITY / 100;
- if (p->tolimit < MINARCS)
- p->tolimit = MINARCS;
- else if (p->tolimit > MAXARCS)
- p->tolimit = MAXARCS;
- p->tossize = p->tolimit * sizeof(struct tostruct);
-
- cp = calloc (p->kcountsize + p->fromssize + p->tossize, 1);
- if (! cp)
- {
- ERR("monstartup: out of memory\n");
- p->tos = NULL;
- p->state = GMON_PROF_ERROR;
- return;
- }
- p->tos = (struct tostruct *)cp;
- cp += p->tossize;
- p->kcount = (HISTCOUNTER *)cp;
- cp += p->kcountsize;
- p->froms = (ARCINDEX *)cp;
-
- p->tos[0].link = 0;
-
- o = p->highpc - p->lowpc;
- if (p->kcountsize < (u_long) o)
- {
-#ifndef hp300
- s_scale = ((float)p->kcountsize / o ) * SCALE_1_TO_1;
-#else
- /* avoid floating point operations */
- int quot = o / p->kcountsize;
-
- if (quot >= 0x10000)
- s_scale = 1;
- else if (quot >= 0x100)
- s_scale = 0x10000 / quot;
- else if (o >= 0x800000)
- s_scale = 0x1000000 / (o / (p->kcountsize >> 8));
- else
- s_scale = 0x1000000 / ((o << 8) / p->kcountsize);
-#endif
- } else
- s_scale = SCALE_1_TO_1;
-
- moncontrol(1);
-}
-
-
-/* Return frequency of ticks reported by profil. */
-static int profile_frequency (void)
-{
- /*
- * Discover the tick frequency of the machine if something goes wrong,
- * we return 0, an impossible hertz.
- */
- struct itimerval tim;
-
- tim.it_interval.tv_sec = 0;
- tim.it_interval.tv_usec = 1;
- tim.it_value.tv_sec = 0;
- tim.it_value.tv_usec = 0;
- setitimer(ITIMER_REAL, &tim, 0);
- setitimer(ITIMER_REAL, 0, &tim);
- if (tim.it_interval.tv_usec < 2)
- return 0;
- return (1000000 / tim.it_interval.tv_usec);
-}
-
-
-static void write_hist (int fd)
-{
- u_char tag = GMON_TAG_TIME_HIST;
- struct gmon_hist_hdr thdr __attribute__ ((aligned (__alignof__ (char *))));
-
- if (_gmonparam.kcountsize > 0)
- {
- struct iovec iov[3] =
- {
- { &tag, sizeof (tag) },
- { &thdr, sizeof (struct gmon_hist_hdr) },
- { _gmonparam.kcount, _gmonparam.kcountsize }
- };
-
- *(char **) thdr.low_pc = (char *) _gmonparam.lowpc;
- *(char **) thdr.high_pc = (char *) _gmonparam.highpc;
- *(int32_t *) thdr.hist_size = (_gmonparam.kcountsize
- / sizeof (HISTCOUNTER));
- *(int32_t *) thdr.prof_rate = profile_frequency ();
- strncpy (thdr.dimen, "seconds", sizeof (thdr.dimen));
- thdr.dimen_abbrev = 's';
-
- writev (fd, iov, 3);
- }
-}
-
-
-static void write_call_graph (int fd)
-{
-#define NARCS_PER_WRITEV 32
- u_char tag = GMON_TAG_CG_ARC;
- struct gmon_cg_arc_record raw_arc[NARCS_PER_WRITEV]
- __attribute__ ((aligned (__alignof__ (char*))));
- ARCINDEX from_index, to_index, from_len;
- u_long frompc;
- struct iovec iov[2 * NARCS_PER_WRITEV];
- int nfilled;
-
- for (nfilled = 0; nfilled < NARCS_PER_WRITEV; ++nfilled)
- {
- iov[2 * nfilled].iov_base = &tag;
- iov[2 * nfilled].iov_len = sizeof (tag);
-
- iov[2 * nfilled + 1].iov_base = &raw_arc[nfilled];
- iov[2 * nfilled + 1].iov_len = sizeof (struct gmon_cg_arc_record);
- }
-
- nfilled = 0;
- from_len = _gmonparam.fromssize / sizeof (*_gmonparam.froms);
- for (from_index = 0; from_index < from_len; ++from_index)
- {
- if (_gmonparam.froms[from_index] == 0)
- continue;
-
- frompc = _gmonparam.lowpc;
- frompc += (from_index * _gmonparam.hashfraction
- * sizeof (*_gmonparam.froms));
- for (to_index = _gmonparam.froms[from_index];
- to_index != 0;
- to_index = _gmonparam.tos[to_index].link)
- {
- struct arc
- {
- char *frompc;
- char *selfpc;
- int32_t count;
- }
- arc;
-
- arc.frompc = (char *) frompc;
- arc.selfpc = (char *) _gmonparam.tos[to_index].selfpc;
- arc.count = _gmonparam.tos[to_index].count;
- memcpy (raw_arc + nfilled, &arc, sizeof (raw_arc [0]));
-
- if (++nfilled == NARCS_PER_WRITEV)
- {
- writev (fd, iov, 2 * nfilled);
- nfilled = 0;
- }
- }
- }
- if (nfilled > 0)
- writev (fd, iov, 2 * nfilled);
-}
-
-
-static void write_bb_counts (int fd)
-{
- struct __bb *grp;
- u_char tag = GMON_TAG_BB_COUNT;
- size_t ncounts;
- size_t i;
-
- struct iovec bbhead[2] =
- {
- { &tag, sizeof (tag) },
- { &ncounts, sizeof (ncounts) }
- };
- struct iovec bbbody[8];
- size_t nfilled;
-
- for (i = 0; i < (sizeof (bbbody) / sizeof (bbbody[0])); i += 2)
- {
- bbbody[i].iov_len = sizeof (grp->addresses[0]);
- bbbody[i + 1].iov_len = sizeof (grp->counts[0]);
- }
-
- /* Write each group of basic-block info (all basic-blocks in a
- compilation unit form a single group). */
-
- for (grp = __bb_head; grp; grp = grp->next)
- {
- ncounts = grp->ncounts;
- writev (fd, bbhead, 2);
- for (nfilled = i = 0; i < ncounts; ++i)
- {
- if (nfilled > (sizeof (bbbody) / sizeof (bbbody[0])) - 2)
- {
- writev (fd, bbbody, nfilled);
- nfilled = 0;
- }
-
- bbbody[nfilled++].iov_base = (char *) &grp->addresses[i];
- bbbody[nfilled++].iov_base = &grp->counts[i];
- }
- if (nfilled > 0)
- writev (fd, bbbody, nfilled);
- }
-}
-
-
-static void write_gmon (void)
-{
- struct gmon_hdr ghdr __attribute__ ((aligned (__alignof__ (int))));
- int fd = -1;
- char *env;
-
-#ifndef O_NOFOLLOW
-# define O_NOFOLLOW 0
-#endif
-
- env = getenv ("GMON_OUT_PREFIX");
- if (env != NULL
-#if 0
- && !__libc_enable_secure
-#endif
- )
- {
- size_t len = strlen (env);
- char buf[len + 20];
- sprintf (buf, "%s.%u", env, getpid ());
- fd = open (buf, O_CREAT|O_TRUNC|O_WRONLY|O_NOFOLLOW, 0666);
- }
-
- if (fd == -1)
- {
- fd = open ("gmon.out", O_CREAT|O_TRUNC|O_WRONLY|O_NOFOLLOW, 0666);
- if (fd < 0)
- {
- char buf[300];
- int errnum = errno;
- fprintf (stderr, "_mcleanup: gmon.out: %s\n",
- strerror_r (errnum, buf, sizeof buf));
- return;
- }
- }
-
- /* write gmon.out header: */
- memset (&ghdr, '\0', sizeof (struct gmon_hdr));
- memcpy (&ghdr.cookie[0], GMON_MAGIC, sizeof (ghdr.cookie));
- *(int32_t *) ghdr.version = GMON_VERSION;
- write (fd, &ghdr, sizeof (struct gmon_hdr));
-
- /* write PC histogram: */
- write_hist (fd);
-
- /* write call-graph: */
- write_call_graph (fd);
-
- /* write basic-block execution counts: */
- write_bb_counts (fd);
-
- close (fd);
-}
-
-
-void write_profiling (void)
-{
- int save = _gmonparam.state;
- _gmonparam.state = GMON_PROF_OFF;
- if (save == GMON_PROF_ON)
- write_gmon ();
- _gmonparam.state