diff options
Diffstat (limited to 'libgcc/config/arc/gmon')
-rw-r--r-- | libgcc/config/arc/gmon/atomic.h | 26 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/auxreg.h | 35 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/dcache_linesz.S | 55 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/gmon.c | 450 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/machine-gmon.h | 65 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/mcount.c | 206 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/prof-freq-stub.S | 40 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/prof-freq.c | 60 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/profil.S | 153 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/sys/gmon.h | 217 | ||||
-rw-r--r-- | libgcc/config/arc/gmon/sys/gmon_out.h | 55 |
11 files changed, 1362 insertions, 0 deletions
diff --git a/libgcc/config/arc/gmon/atomic.h b/libgcc/config/arc/gmon/atomic.h new file mode 100644 index 00000000000..857b85cefb3 --- /dev/null +++ b/libgcc/config/arc/gmon/atomic.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributor: Joern Rennecke <joern.rennecke@embecosm.com> + on behalf of Synopsys Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +/* File deliberately left blank. */ diff --git a/libgcc/config/arc/gmon/auxreg.h b/libgcc/config/arc/gmon/auxreg.h new file mode 100644 index 00000000000..10efa169eed --- /dev/null +++ b/libgcc/config/arc/gmon/auxreg.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributor: Joern Rennecke <joern.rennecke@embecosm.com> + on behalf of Synopsys Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#define LP_START 0x02 +#define LP_END 0x03 +#define IDENTITY 0x04 +#define STATUS32 0x0a +#define COUNT0 0x21 /* Timer 0 count */ +#define CONTROL0 0x22 /* Timer 0 control */ +#define LIMIT0 0x23 /* Timer 0 limit */ +#define INT_VECTOR_BASE 0x25 +#define D_CACHE_BUILD 0x72 +#define DC_FLDL 0x4c diff --git a/libgcc/config/arc/gmon/dcache_linesz.S b/libgcc/config/arc/gmon/dcache_linesz.S new file mode 100644 index 00000000000..402a8331943 --- /dev/null +++ b/libgcc/config/arc/gmon/dcache_linesz.S @@ -0,0 +1,55 @@ +/* This file contains code to do profiling. + + Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributor: Joern Rennecke <joern.rennecke@embecosm.com> + on behalf of Synopsys Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "../asm.h" +#include "auxreg.h" +/* This file contains code to do profiling. */ + .weak __profile_timer_cycles + .global __profile_timer_cycles + .set __profile_timer_cycles, 200 + .text + ; For Arctangent-A5, if no data cache is present, a read of the + ; cache build register returns the ID register. For ARC600 and + ; later, the version field will be zero. + .global __dcache_linesz + .balign 4 +__dcache_linesz: + lr r12,[D_CACHE_BUILD] + extb_s r0,r12 + breq_s r0,0,.Lsz_nocache + brge r0,0x20,.Lsz_havecache + lr r0,[IDENTITY] + breq r12,r0,.Lsz_nocache +.Lsz_havecache: + lsr_s r12,r12,16 + mov_s r0,16 + bmsk_s r12,r12,3 + asl_s r0,r0,r12 + j_s [blink] +.Lsz_nocache: + mov_s r0,1 + j_s [blink] diff --git a/libgcc/config/arc/gmon/gmon.c b/libgcc/config/arc/gmon/gmon.c new file mode 100644 index 00000000000..098351f1664 --- /dev/null +++ b/libgcc/config/arc/gmon/gmon.c @@ -0,0 +1,450 @@ +/*- + * Copyright (c) 1983, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * Copyright (C) 2007-2013 Free Software Foundation, Inc. + * + * 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. + */ +#if 0 +#include <sys/param.h> +#include <sys/time.h> +#endif +#include <sys/gmon.h> +#include <sys/gmon_out.h> + +#include <stddef.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> +#if 0 +#include <libc-internal.h> +#include <not-cancel.h> + +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif +#endif +#define internal_function +#define weak_alias(fun,aliasid) extern __typeof(fun) aliasid __attribute__ ((weak, alias (#fun))); +#define __libc_enable_secure 0 + +/* Head of basic-block list or NULL. */ +struct __bb *__bb_head attribute_hidden; + +struct gmonparam _gmonparam attribute_hidden = { 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 (int mode); +void __moncontrol (int mode); +static void write_hist (int fd) internal_function; +static void write_call_graph (int fd) internal_function; +static void write_bb_counts (int fd) internal_function; + +/* + * 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; + } +} +weak_alias (__moncontrol, moncontrol) + + +void +__monstartup (u_long lowpc, u_long highpc) +{ + register int o; + char *cp; + struct gmonparam *p = &_gmonparam; + int linesz; + + /* + * 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)); + if (sizeof *p->froms % sizeof(HISTCOUNTER) != 0) + { + p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER)); + p->textsize = p->highpc - p->lowpc; + p->kcountsize = ROUNDUP((p->textsize + HISTFRACTION - 1) / HISTFRACTION, + sizeof (*p->froms)); + } + else + { + /* Avoid odd scales by rounding up highpc to get kcountsize rounded. */ + p->textsize = ROUNDUP (highpc - p->lowpc, + HISTFRACTION * sizeof (*p->froms)); + p->highpc = p->lowpc + p->textsize; + 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->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); + + /* p->kcount must not share cache lines with the adjacent data, because + we use uncached accesses while profiling. */ + linesz = __dcache_linesz (); + cp = calloc (ROUNDUP (p->kcountsize, linesz) + p->tossize + + (linesz - 1), 1); + if (! cp) + { + ERR("monstartup: out of memory\n"); + p->tos = NULL; + p->state = GMON_PROF_ERROR; + /* In case we loose the error state due to a race, + prevent invalid writes also by clearing tolimit. */ + p->tolimit = 0; + return; + } + p->tos = (struct tostruct *)cp; + cp += p->tossize; + cp = (char *) ROUNDUP ((ptrdiff_t) cp, linesz); + p->kcount = (HISTCOUNTER *)cp; + cp += ROUNDUP (p->kcountsize, linesz); + + 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); +} +weak_alias (__monstartup, monstartup) + + +static void +internal_function +write_hist (int fd) +{ + u_char tag = GMON_TAG_TIME_HIST; + struct arc_gmon_hist_hdr thdr __attribute__ ((aligned (__alignof__ (char *)))); + int r; + + if (_gmonparam.kcountsize > 0) + { + *(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'; + + r = write (fd, &tag, sizeof tag); + if (r != sizeof tag) + return; + r = write (fd, &thdr, sizeof thdr); + if (r != sizeof thdr) + return; + r = write (fd,_gmonparam.kcount, _gmonparam.kcountsize); + if ((unsigned) r != _gmonparam.kcountsize) + return; + } +} + + +static void +internal_function +write_call_graph (int fd) +{ +#define NARCS_PER_WRITE 64 +#define BYTES_PER_ARC (1 + sizeof (struct gmon_cg_arc_record)) +#define BYTES_PER_WRITE (BYTES_PER_ARC * NARCS_PER_WRITE) + ARCINDEX to_index; + u_long frompc, selfpc, count; + char buffer[BYTES_PER_WRITE], *p; + u_long *prof_desc = __arc_profile_desc_secstart; + u_long *prof_count = __arc_profile_counters_secstart; + u_long *prof_desc_end = __arc_profile_desc_secend; + u_long *prof_forward = __arc_profile_forward_secstart; + + for (p = buffer; p < buffer + BYTES_PER_WRITE; p += BYTES_PER_ARC) + *p = GMON_TAG_CG_ARC; + p = buffer; + frompc = *prof_desc++ & -2; + while (prof_desc < prof_desc_end) + { + selfpc = *prof_desc++; + if (selfpc & 1) + { + frompc = selfpc & -2; + selfpc = *prof_desc++; + } + count = *prof_count++; + if (selfpc) + { + struct arc + { + char *frompc; + char *selfpc; + int32_t count; + } + arc; + + if (!count) + continue; + arc.frompc = (char *) frompc; + arc.selfpc = (char *) selfpc; + arc.count = count; + memcpy (p + 1, &arc, sizeof arc); + p += 1 + sizeof arc; + + if (p == buffer + BYTES_PER_WRITE) + { + write (fd, buffer, BYTES_PER_WRITE); + p = buffer; + } + } + else + { + for (to_index = count; + 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 (p + 1, &arc, sizeof arc); + p += 1 + sizeof arc; + + if (p == buffer + BYTES_PER_WRITE) + { + write (fd, buffer, BYTES_PER_WRITE); + p = buffer; + } + } + } + } + while (prof_forward < __arc_profile_forward_secend) + { + /* ??? The 'call count' is actually supposed to be a fixed point + factor, with 16 bits each before and after the point. + It would be much nicer if we figured out the actual number + of calls to the caller, and multiplied that with the fixed point + factor to arrive at the estimated calls for the callee. */ + memcpy (p + 1, prof_forward, 3 * sizeof *prof_forward); + prof_forward += 3; + p += 1 + 3 * sizeof *prof_forward; + if (p == buffer + BYTES_PER_WRITE) + { + write (fd, buffer, BYTES_PER_WRITE); + p = buffer; + } + } + if (p != buffer) + write (fd, buffer, p - buffer); +} + + +static void +internal_function +write_bb_counts (int fd) +{ + struct __bb *grp; + u_char tag = GMON_TAG_BB_COUNT; + size_t ncounts; + size_t i; + + struct { unsigned long address; long count; } bbbody[8]; + size_t nfilled; + + /* 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; + write (fd, &tag, 1); + write (fd, &ncounts, sizeof ncounts); + for (nfilled = i = 0; i < ncounts; ++i) + { + if (nfilled == sizeof (bbbody) / sizeof (bbbody[0])) + { + write (fd, bbbody, sizeof bbbody); + nfilled = 0; + } + + bbbody[nfilled].address = grp->addresses[i]; + bbbody[nfilled++].count = grp->counts[i]; + } + if (nfilled > 0) + write (fd, bbbody, nfilled * sizeof bbbody[0]); + } +} + + +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 && !__libc_enable_secure) + { + size_t len = strlen (env); + char buf[len + 20]; + snprintf (buf, sizeof (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) + { + perror ("_mcleanup: gmon.out"); + 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 = save; +} +#ifndef SHARED +/* This symbol isn't used anywhere in the DSO and it is not exported. + This would normally mean it should be removed to get the same API + in static libraries. But since profiling is special in static libs + anyway we keep it. But not when building the DSO since some + quality assurance tests will otherwise trigger. */ +weak_alias (__write_profiling, write_profiling) +#endif + + +void +_mcleanup (void) +{ + __moncontrol (0); + + if (_gmonparam.state != GMON_PROF_ERROR) + write_gmon (); + + /* free the memory. */ + if (_gmonparam.tos != NULL) + free (_gmonparam.tos); +} diff --git a/libgcc/config/arc/gmon/machine-gmon.h b/libgcc/config/arc/gmon/machine-gmon.h new file mode 100644 index 00000000000..25ad0dd2882 --- /dev/null +++ b/libgcc/config/arc/gmon/machine-gmon.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributor: Joern Rennecke <joern.rennecke@embecosm.com> + on behalf of Synopsys Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#ifndef MACHINE_GMON_H +#define MACHINE_GMON_H + +/* We can't fake out own <sys/types.h> header because the newlib / uclibc + headers in GCC_FOR_TARGET take precedence. */ + +#define __BEGIN_DECLS +#define __END_DECLS + +#define __THROW + +extern int __dcache_linesz (void); + +#define _MCOUNT_DECL(countp, selfpc) \ + static inline void _mcount_internal (void *countp, u_long selfpc) + +extern void _mcount (void); +extern void _mcount_call (void); + +/* N.B.: the calling point might be a sibcall, thus blink does not necessarily + hold the caller's address. r8 doesn't hold the caller's address, either, + but rather a pointer to the counter data structure associated with the + caller. + This function must be compiled with optimization turned on in order to + enable a sibcall for the final call to selfpc; this is important when trying + to profile a program with deep tail-recursion that would get a stack + overflow otherwise. */ +#define MCOUNT \ +void \ +_mcount_call (void) \ +{ \ + register void *countp __asm("r8"); \ + register u_long selfpc __asm("r9"); \ + _mcount_internal (countp, selfpc); \ + ((void (*)(void)) selfpc) (); \ +} + +extern int __profil (u_short *,size_t, size_t, u_int); + +#endif /* MACHINE_GMON_H */ diff --git a/libgcc/config/arc/gmon/mcount.c b/libgcc/config/arc/gmon/mcount.c new file mode 100644 index 00000000000..c99dcd7bd7e --- /dev/null +++ b/libgcc/config/arc/gmon/mcount.c @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 1983, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Copyright (C) 2007-2013 Free Software Foundation, Inc. + * + * 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. + */ + +#if !defined(lint) && !defined(KERNEL) && defined(LIBC_SCCS) +static char sccsid[] = "@(#)mcount.c 8.1 (Berkeley) 6/4/93"; +#endif + +#if 0 +#include <unistd.h> +#include <sys/param.h> +#endif +#include <sys/gmon.h> + +/* This file provides the machine-dependent definitions of the _MCOUNT_DECL + and MCOUNT macros. */ +#include <machine-gmon.h> + +#include <atomic.h> + +/* + * mcount is called on entry to each function compiled with the profiling + * switch set. _mcount(), which is declared in a machine-dependent way + * with _MCOUNT_DECL, does the actual work and is either inlined into a + * C routine or called by an assembly stub. In any case, this magic is + * taken care of by the MCOUNT definition in <machine/profile.h>. + * + * _mcount updates data structures that represent traversals of the + * program's call graph edges. frompc and selfpc are the return + * address and function address that represents the given call graph edge. + * + * Note: the original BSD code used the same variable (frompcindex) for + * both frompcindex and frompc. Any reasonable, modern compiler will + * perform this optimization. + */ +_MCOUNT_DECL(count_ptr, selfpc) /* _mcount; may be static, inline, etc */ +{ + register ARCINDEX *frompcindex; + register struct tostruct *top, *prevtop; + register struct gmonparam *p; + register ARCINDEX toindex; + + /* Check for nested function trampoline. */ + if (selfpc & 2) + selfpc = *(u_long *) (selfpc + 10); + + p = &_gmonparam; + /* + * check that we are profiling + * and that we aren't recursively invoked. + */ +#if 0 + if (catomic_compare_and_exchange_bool_acq (&p->state, GMON_PROF_BUSY, + GMON_PROF_ON)) + return; +#elif defined (__ARC700__) +/* ??? This could temporarily lose the ERROR / OFF condition in a race, + but doing an actual compare_and_exchange would be too costly. It would + be better if we had a semaphore independent of the 'sticky' state, but + then we could run into ABI compatibility problems with the size of struct + gmonparam. */ + { + u_long old_state; + + __asm ("ex %0,%1": "=r" (old_state), "+m" (p->state) + : "0" (GMON_PROF_BUSY)); + if (old_state != GMON_PROF_ON) + { + switch (old_state) + { + case GMON_PROF_OFF: + __asm ("ex %0,%1": "+r" (old_state), "+m" (p->state)); + if (old_state == GMON_PROF_BUSY + /* Switching off while we say we are busy while profiling + was actually already switched off is all right. */ + || old_state == GMON_PROF_OFF) + break; + /* It is not clear if we should allow switching on + profiling at this point, and how to handle further races. + For now, record an error in this case. */ + /* Fall through. */ + default: /* We expect here only GMON_PROF_ERROR. */ + p->state = GMON_PROF_ERROR; + break; + case GMON_PROF_BUSY: break; + } + return; + } + } +#else /* ??? No semaphore primitives available. */ + if (p->state != GMON_PROF_ON) + return; + p->state = GMON_PROF_BUSY; +#endif + + frompcindex = count_ptr; + toindex = *frompcindex; + if (toindex == 0) { + /* + * first time traversing this arc + */ + toindex = ++p->tos[0].link; + if (toindex >= (ARCINDEX) p->tolimit) + /* halt further profiling */ + goto overflow; + + *frompcindex = toindex; + top = &p->tos[toindex]; + top->selfpc = selfpc; + top->count = 1; + top->link = 0; + goto done; + } + top = &p->tos[toindex]; + if (top->selfpc == selfpc) { + /* + * arc at front of chain; usual case. + */ + top->count++; + goto done; + } + /* + * have to go looking down chain for it. + * top points to what we are looking at, + * prevtop points to previous top. + * we know it is not at the head of the chain. + */ + for (; /* goto done */; ) { + if (top->link == 0) { + /* + * top is end of the chain and none of the chain + * had top->selfpc == selfpc. + * so we allocate a new tostruct + * and link it to the head of the chain. + */ + toindex = ++p->tos[0].link; + if (toindex >= (ARCINDEX) p->tolimit) + goto overflow; + + top = &p->tos[toindex]; + top->selfpc = selfpc; + top->count = 1; + top->link = *frompcindex; + *frompcindex = toindex; + goto done; + } + /* + * otherwise, check the next arc on the chain. + */ + prevtop = top; + top = &p->tos[top->link]; + if (top->selfpc == selfpc) { + /* + * there it is. + * increment its count + * move it to the head of the chain. + */ + top->count++; + toindex = prevtop->link; + prevtop->link = top->link; + top->link = *frompcindex; + *frompcindex = toindex; + goto done; + } + + } +done: + p->state = GMON_PROF_ON; + return; +overflow: + p->state = GMON_PROF_ERROR; + return; +} + +/* + * Actual definition of mcount function. Defined in <machine/profile.h>, + * which is included by <sys/gmon.h>. + */ +MCOUNT diff --git a/libgcc/config/arc/gmon/prof-freq-stub.S b/libgcc/config/arc/gmon/prof-freq-stub.S new file mode 100644 index 00000000000..dc9ec681b36 --- /dev/null +++ b/libgcc/config/arc/gmon/prof-freq-stub.S @@ -0,0 +1,40 @@ +/* This file contains code to do profiling. + + Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributor: Joern Rennecke <joern.rennecke@embecosm.com> + on behalf of Synopsys Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "../asm.h" +/* This file contains code to do profiling. */ + .weak __profile_frequency_value + .global __profile_frequency_value + .set __profile_frequency_value, 1000 + .text + .balign 4 + .global __profile_frequency + FUNC(__profile_frequency) +__profile_frequency: + mov_s r0,__profile_frequency_value + j_s [blink] + ENDFUNC(__profile_frequency) diff --git a/libgcc/config/arc/gmon/prof-freq.c b/libgcc/config/arc/gmon/prof-freq.c new file mode 100644 index 00000000000..39395b1acd3 --- /dev/null +++ b/libgcc/config/arc/gmon/prof-freq.c @@ -0,0 +1,60 @@ +/* Return frequency of ticks reported by profil. Generic version. */ +/*- + * Copyright (c) 1983, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Copyright (C) 2007-2013 Free Software Foundation, Inc. + * + * 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 <sys/types.h> +#include <sys/time.h> +#if 0 +#include <libc-internal.h> +#else +#include "sys/gmon.h" +#endif + +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); +} diff --git a/libgcc/config/arc/gmon/profil.S b/libgcc/config/arc/gmon/profil.S new file mode 100644 index 00000000000..3835fe37944 --- /dev/null +++ b/libgcc/config/arc/gmon/profil.S @@ -0,0 +1,153 @@ +/* This file contains code to do profiling. + + Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributor: Joern Rennecke <joern.rennecke@embecosm.com> + on behalf of Synopsys Inc. + + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "../asm.h" +#include "auxreg.h" +/* This file contains code to do profiling. */ + .weak __profile_timer_cycles + .global __profile_timer_cycles + .set __profile_timer_cycles, 200 + + .section .bss + .global __profil_offset + .align 4 + .type __profil_offset, @object + .size __profil_offset, 4 +__profil_offset: + .zero 4 + + .text + .global __dcache_linesz + .global __profil + FUNC(__profil) +.Lstop_profiling: + sr r0,[CONTROL0] + j_s [blink] + .balign 4 +__profil: +.Lprofil: + breq_s r0,0,.Lstop_profiling + ; r0: buf r1: bufsiz r2: offset r3: scale + bxor.f r3,r3,15; scale must be 0x8000, i.e. 1/2; generate 0. + push_s blink + lsr_s r2,r2,1 + mov_s r8,r0 + flag.ne 1 ; halt if wrong scale + sub_s r0,r0,r2 + st r0,[__profil_offset] + bl __dcache_linesz + pop_s blink + bbit1.d r0,0,nocache + mov_s r0,r8 +#ifdef __ARC700__ + add_s r1,r1,31 + lsr.f lp_count,r1,5 + lpne 2f + sr r0,[DC_FLDL] + add_s r0,r0,32 +#else /* !__ARC700__ */ +# FIX ME: set up loop according to cache line size + lr r12,[D_CACHE_BUILD] + sub_s r0,r0,16 + sub_s r1,r1,1 + lsr_s r12,r12,16 + asr_s r1,r1,4 + bmsk_s r12,r12,3 + asr_s r1,r1,r12 + add.f lp_count,r1,1 + mov_s r1,16 + asl_s r1,r1,r12 + lpne 2f + add r0,r0,r1 + sr r0,[DC_FLDL] +#endif /* __ARC700__ */ +2: b_s .Lcounters_cleared +nocache: +.Lcounters_cleared: + lr r1,[INT_VECTOR_BASE] ; disable timer0 interrupts + sr r3,[CONTROL0] + sr r3,[COUNT0] +0: ld_s r0,[pcl,1f-0b+((0b-.Lprofil) & 2)] ; 1f@GOTOFF +0: ld_s r12,[pcl,1f+4-0b+((0b-.Lprofil) & 2)] ; 1f@GOTOFF + 4 + st_s r0,[r1,24]; timer0 uses vector3 + st_s r12,[r1,24+4]; timer0 uses vector3 + ;sr 10000,[LIMIT0] + sr __profile_timer_cycles,[LIMIT0] + mov_s r12,3 ; enable timer interrupts; count only when not halted. + sr r12,[CONTROL0] + lr r12,[STATUS32] + bset_s r12,r12,1 ; allow level 1 interrupts + flag r12 + mov_s r0,0 + j_s [blink] + .balign 4 +1: j __profil_irq + ENDFUNC(__profil) + + FUNC(__profil_irq) + .balign 4 ; make final jump unaligned to avoid delay penalty + .balign 32,0,12 ; make sure the code spans no more that two cache lines + nop_s +__profil_irq: + push_s r0 + ld r0,[__profil_offset] + push_s r1 + lsr r1,ilink1,2 + push_s r2 + ldw.as.di r2,[r0,r1] + add1 r0,r0,r1 + ld_s r1,[sp,4] + add_s r2,r2,1 + bbit1 r2,16,nostore + stw.di r2,[r0] +nostore:ld.ab r2,[sp,8] + pop_s r0 + j.f [ilink1] + ENDFUNC(__profil_irq) + +; could save one cycle if the counters were allocated at link time and +; the contents of __profil_offset were pre-computed at link time, like this: +#if 0 +; __profil_offset needs to be PROVIDEd as __profile_base-text/4 + .global __profil_offset + .balign 4 +__profil_irq: + push_s r0 + lsr r0,ilink1,2 + add1 r0,__profil_offset,r0 + push_s r1 + ldw.di r1,[r0] + + + add_s r1,r1,1 + bbit1 r1,16,nostore + stw.di r1,[r0] +nostore:pop_s r1 + pop_s r0 + j [ilink1] +#endif /* 0 */ diff --git a/libgcc/config/arc/gmon/sys/gmon.h b/libgcc/config/arc/gmon/sys/gmon.h new file mode 100644 index 00000000000..03171136281 --- /dev/null +++ b/libgcc/config/arc/gmon/sys/gmon.h @@ -0,0 +1,217 @@ +/*- + * Copyright (c) 1982, 1986, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * Copyright (C) 2007-2013 Free Software Foundation, Inc. + * + * 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. + * + * @(#)gmon.h 8.2 (Berkeley) 1/4/94 + */ + +#ifndef _SYS_GMON_H +#define _SYS_GMON_H 1 + +#if 0 +#include <features.h> +#include <sys/types.h> +#else +#include <sys/types.h> +#include "machine-gmon.h" +#define attribute_hidden __attribute__ ((visibility("hidden"))) +#endif + +#include <stdint.h> + +/* + * See gmon_out.h for gmon.out format. + */ + +/* structure emitted by "gcc -a". This must match struct bb in + gcc/libgcc2.c. It is OK for gcc to declare a longer structure as + long as the members below are present. */ +struct __bb +{ + long zero_word; + const char *filename; + long *counts; + long ncounts; + struct __bb *next; + const unsigned long *addresses; +}; + +extern struct __bb *__bb_head; + +/* + * histogram counters are unsigned shorts (according to the kernel). + */ +#define HISTCOUNTER unsigned short + +/* + * fraction of text space to allocate for histogram counters here, 1/2 + */ +#define HISTFRACTION 2 + +/* + * Fraction of text space to allocate for from hash buckets. + * The value of HASHFRACTION is based on the minimum number of bytes + * of separation between two subroutine call points in the object code. + * Given MIN_SUBR_SEPARATION bytes of separation the value of + * HASHFRACTION is calculated as: + * + * HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1); + * + * For example, on the VAX, the shortest two call sequence is: + * + * calls $0,(r0) + * calls $0,(r0) + * + * which is separated by only three bytes, thus HASHFRACTION is + * calculated as: + * + * HASHFRACTION = 3 / (2 * 2 - 1) = 1 + * + * Note that the division above rounds down, thus if MIN_SUBR_FRACTION + * is less than three, this algorithm will not work! + * + * In practice, however, call instructions are rarely at a minimal + * distance. Hence, we will define HASHFRACTION to be 2 across all + * architectures. This saves a reasonable amount of space for + * profiling data structures without (in practice) sacrificing + * any granularity. + */ +#define HASHFRACTION 2 + +/* + * Percent of text space to allocate for tostructs. + * This is a heuristic; we will fail with a warning when profiling programs + * with a very large number of very small functions, but that's + * normally OK. + * 2 is probably still a good value for normal programs. + * Profiling a test case with 64000 small functions will work if + * you raise this value to 3 and link statically (which bloats the + * text size, thus raising the number of arcs expected by the heuristic). + */ +#define ARCDENSITY 3 + +/* + * Always allocate at least this many tostructs. This + * hides the inadequacy of the ARCDENSITY heuristic, at least + * for small programs. + */ +#define MINARCS 50 + +/* + * The type used to represent indices into gmonparam.tos[]. + */ +#define ARCINDEX u_long + +/* + * Maximum number of arcs we want to allow. + * Used to be max representable value of ARCINDEX minus 2, but now + * that ARCINDEX is a long, that's too large; we don't really want + * to allow a 48 gigabyte table. + * The old value of 1<<16 wasn't high enough in practice for large C++ + * programs; will 1<<20 be adequate for long? FIXME + */ +#define MAXARCS (1 << 20) + +struct tostruct { + u_long selfpc; + long count; + ARCINDEX link; +}; + +/* + * a raw arc, with pointers to the calling site and + * the called site and a count. + */ +struct rawarc { + u_long raw_frompc; + u_long raw_selfpc; + long raw_count; +}; + +/* + * general rounding functions. + */ +#define ROUNDDOWN(x,y) (((x)/(y))*(y)) +#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) + +/* + * The profiling data structures are housed in this structure. + */ +struct gmonparam { + long int state; + u_short *kcount; + u_long kcountsize; + ARCINDEX *froms; + u_long fromssize; + struct tostruct *tos; + u_long tossize; + long tolimit; + u_long lowpc; + u_long highpc; + u_long textsize; + u_long hashfraction; + long log_hashfraction; +}; +extern struct gmonparam _gmonparam; + +/* + * Possible states of profiling. + */ +#define GMON_PROF_ON 0 +#define GMON_PROF_BUSY 1 +#define GMON_PROF_ERROR 2 +#define GMON_PROF_OFF 3 + +/* + * Sysctl definitions for extracting profiling information from the kernel. + */ +#define GPROF_STATE 0 /* int: profiling enabling variable */ +#define GPROF_COUNT 1 /* struct: profile tick count buffer */ +#define GPROF_FROMS 2 /* struct: from location hash bucket */ +#define GPROF_TOS 3 /* struct: destination/count structure */ +#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */ + +__BEGIN_DECLS + +/* Set up data structures and start profiling. */ +extern void __monstartup (u_long __lowpc, u_long __highpc) __THROW; +extern void monstartup (u_long __lowpc, u_long __highpc) __THROW; + +/* Clean up profiling and write out gmon.out. */ +extern void _mcleanup (void) __THROW; + +extern void __write_profiling (void); +extern int attribute_hidden __profile_frequency (void); + +extern u_long __arc_profile_desc_secstart[], __arc_profile_desc_secend[]; +extern u_long __arc_profile_forward_secstart[], __arc_profile_forward_secend[]; +extern u_long __arc_profile_counters_secstart[]; + +__END_DECLS + +#endif /* sys/gmon.h */ diff --git a/libgcc/config/arc/gmon/sys/gmon_out.h b/libgcc/config/arc/gmon/sys/gmon_out.h new file mode 100644 index 00000000000..ae38145b145 --- /dev/null +++ b/libgcc/config/arc/gmon/sys/gmon_out.h @@ -0,0 +1,55 @@ +/* Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributor: Joern Rennecke <joern.rennecke@embecosm.com> + on behalf of Synopsys Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#define GMON_TAG_TIME_HIST 0 +#define GMON_TAG_CG_ARC 1 +#define GMON_TAG_BB_COUNT 2 + +#define GMON_MAGIC "gmon" +#define GMON_VERSION 1 + +struct arc_gmon_hist_hdr +{ + char low_pc[4]; + char high_pc[4]; + char hist_size[4]; + char prof_rate[4]; + char dimen[15]; + char dimen_abbrev; +}; + +struct gmon_cg_arc_record +{ + char afrompc[4]; + char selfpc[4]; + char count[4]; +}; + +struct gmon_hdr +{ + char cookie[4]; + char version[4]; + char c[12]; +}; |