From 954d563fc12c2cc151c7ccb27883ac78ad870662 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 29 Jun 2014 18:51:15 +0200 Subject: [PATCH] remove unportable,glibc/gcc specific remote profiling support the code is not 64 bit safe and depends on glibc specifics. the purpose of the code was to enable GBA developers to profile their GBA binaries. since probably less than a 1000th of every VBA user needed that feature, it's quite safe to remove it... those that still need it can use the win32 version, or the old code. --- src/prof/Makefile.am | 7 - src/prof/gmon.h | 148 ------------------ src/prof/gmon_out.h | 45 ------ src/prof/prof.c | 427 --------------------------------------------------- src/prof/prof.h | 52 ------- 5 files changed, 679 deletions(-) delete mode 100644 src/prof/Makefile.am delete mode 100644 src/prof/gmon.h delete mode 100644 src/prof/gmon_out.h delete mode 100644 src/prof/prof.c delete mode 100644 src/prof/prof.h diff --git a/src/prof/Makefile.am b/src/prof/Makefile.am deleted file mode 100644 index d1ae6fc..0000000 --- a/src/prof/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -noinst_LIBRARIES = libprof.a - -libprof_a_SOURCES = \ - gmon.h \ - gmon_out.h \ - prof.cpp \ - prof.h diff --git a/src/prof/gmon.h b/src/prof/gmon.h deleted file mode 100644 index 7f1c333..0000000 --- a/src/prof/gmon.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 1983, 1991, 1993, 2001 - * 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. - * 3. 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. - */ -#ifndef gmon_h -#define gmon_h - -/* Size of the 4.4BSD gmon header */ -#define GMON_HDRSIZE_BSD44_32 (4 + 4 + 4 + 4 + 4 + (3 * 4)) -#define GMON_HDRSIZE_BSD44_64 (8 + 8 + 4 + 4 + 4 + (3 * 4)) - -#if 0 /* For documentation purposes only. */ - struct raw_phdr - { - char low_pc[sizeof(void *)]; /* base pc address of sample buffer */ - char high_pc[sizeof(void *)];/* max pc address of sampled buffer */ - char ncnt[4]; /* size of sample buffer (plus this - header) */ - - char version[4]; /* version number */ - char profrate[4]; /* profiling clock rate */ - char spare[3*4]; /* reserved */ - }; -#endif - -#define GMONVERSION 0x00051879 - -/* Size of the old BSD gmon header */ -#define GMON_HDRSIZE_OLDBSD_32 (4 + 4 + 4) - -/* FIXME: Checking host compiler defines here means that we can't - use a cross gprof alpha OSF. */ -#if defined(__alpha__) && defined (__osf__) -#define GMON_HDRSIZE_OLDBSD_64 (8 + 8 + 4 + 4) -#else -#define GMON_HDRSIZE_OLDBSD_64 (8 + 8 + 4) -#endif - -#if 0 /* For documentation purposes only. */ - struct old_raw_phdr - { - char low_pc[sizeof(void *)]; /* base pc address of sample buffer */ - char high_pc[sizeof(void *)];/* max pc address of sampled buffer */ - char ncnt[4]; /* size of sample buffer (plus this - header) */ -#if defined (__alpha__) && defined (__osf__) - /* - * DEC's OSF v3.0 uses 4 bytes of padding to bring the header to - * a size that is a multiple of 8. - */ - char pad[4]; -#endif - }; -#endif - -/* - * Histogram counters are unsigned shorts: - */ -#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 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! - */ -#define HASHFRACTION 1 - -/* - * Percent of text space to allocate for tostructs with a minimum: - */ -#define ARCDENSITY 2 -#define MINARCS 50 - -struct tostruct - { - char *selfpc; - int count; - unsigned short link; - }; - -/* - * A raw arc, with pointers to the calling site and the called site - * and a count. Everything is defined in terms of characters so - * as to get a packed representation (otherwise, different compilers - * might introduce different padding): - */ -#if 0 /* For documentation purposes only. */ - struct raw_arc - { - char from_pc[sizeof(void *)]; - char self_pc[sizeof(void *)]; - char count[sizeof(long)]; - }; -#endif - -/* - * General rounding functions: - */ -#define ROUNDDOWN(x,y) (((x)/(y))*(y)) -#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) - -#endif /* gmon_h */ diff --git a/src/prof/gmon_out.h b/src/prof/gmon_out.h deleted file mode 100644 index 25dce59..0000000 --- a/src/prof/gmon_out.h +++ /dev/null @@ -1,45 +0,0 @@ -/* gmon_out.h - - Copyright 2000, 2001 Free Software Foundation, Inc. - -This file is part of GNU Binutils. - -This program 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 2 of the License, or -(at your option) any later version. - -This program 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. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* A gmon.out file consists of a header (defined by gmon_hdr) followed - by a sequence of records. Each record starts with a one-byte tag - identifying the type of records, followed by records specific data. */ -#ifndef gmon_out_h -#define gmon_out_h - -#define GMON_MAGIC "gmon" /* magic cookie */ -#define GMON_VERSION 1 /* version number */ - -/* Raw header as it appears on file (without padding). */ -struct gmon_hdr - { - char cookie[4]; - char version[4]; - char spare[3 * 4]; - }; - -/* Types of records in this file. */ -typedef enum - { - GMON_TAG_TIME_HIST = 0, GMON_TAG_CG_ARC = 1, GMON_TAG_BB_COUNT = 2 - } -GMON_Record_Tag; - -#endif /* gmon_out_h */ diff --git a/src/prof/prof.c b/src/prof/prof.c deleted file mode 100644 index fcc63a8..0000000 --- a/src/prof/prof.c +++ /dev/null @@ -1,427 +0,0 @@ -// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. -// Copyright (C) 1999-2003 Forgotten -// Copyright (C) 2004 Forgotten and the VBA development team - -// This program 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 2, or(at your option) -// any later version. -// -// This program 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. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation, -// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -// adapted from gmon.c -/*- - * Copyright (c) 1991, 1998 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. - * 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. - * - * 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. - */ - -#ifndef PROFILING -void profSetHertz(int h) {} -void profCleanup() {} -void profStartup(unsigned lowpc, unsigned highpc) {} -void profCount() {} -void profControl(int mode) {} -#else - -#include -#include -#include - -#include "gmon.h" -#include "gmon_out.h" - -#include "../GBA.h" -#include "../NLS.h" - -#include "prof.h" /* for struct profile_segment */ - -/* - * froms is actually a bunch of unsigned shorts indexing tos - */ -static int profiling = 3; - -static profile_segment *first_segment = NULL; - -static int hz = 0; -static int hist_num_bins = 0; -static char hist_dimension[16] = "seconds"; -static char hist_dimension_abbrev = 's'; - -/* see profil(2) where this is describe (incorrectly) */ -#define SCALE_1_TO_1 0x10000L - -void profPut32(char *b, u32 v) -{ - b[0] = v & 255; - b[1] = (v >> 8) & 255; - b[2] = (v >> 16) & 255; - b[3] = (v >> 24) & 255; -} - -void profPut16(char *b, u16 v) -{ - b[0] = v & 255; - b[1] = (v >> 8) & 255; -} - -int profWrite8(FILE *f, u8 b) -{ - if(fwrite(&b, 1, 1, f) != 1) - return 1; - return 0; -} - -int profWrite32(FILE *f, u32 v) -{ - char buf[4]; - - profPut32(buf, v); - if(fwrite(buf, 1, 4, f) != 4) - return 1; - return 0; -} - -int profWrite(FILE *f, char *buf, unsigned int n) -{ - if(fwrite(buf, 1, n, f) != n) - return 1; - return 0; -} - -/* Control profiling; - profiling is what mcount checks to see if - all the data structures are ready. */ - -void profControl(int mode) -{ - if (mode) { - /* start */ -#ifdef PROFILING - cpuProfil(first_segment); -#endif - profiling = 0; - } else { - /* stop */ -#ifdef PROFILING - cpuProfil(NULL); -#endif - profiling = 3; - } -} - - -#define MSG N_("No space for profiling buffer(s)\n") - -void profStartup(u32 lowpc, u32 highpc) -{ - int monsize; - char *buffer; - int o; - profile_segment *newseg = (profile_segment*)calloc(1,sizeof(profile_segment)); - - if (newseg) { - newseg->next = first_segment; - first_segment = newseg; - } else { - systemMessage(0, MSG); - return; - } - /* - * 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 = ROUNDDOWN(lowpc, HISTFRACTION*sizeof(HISTCOUNTER)); - newseg->s_lowpc = lowpc; - highpc = ROUNDUP(highpc, HISTFRACTION*sizeof(HISTCOUNTER)); - newseg->s_highpc = highpc; - newseg->s_textsize = highpc - lowpc; - monsize = (newseg->s_textsize / HISTFRACTION); - buffer = (char *)calloc(1, 2*monsize ); - if ( buffer == NULL ) { - systemMessage(0, MSG); - return; - } - newseg->froms = (unsigned short *) calloc(1, 4*newseg->s_textsize / HASHFRACTION ); - if ( newseg->froms == NULL ) { - systemMessage(0, MSG); - free(buffer); - buffer = NULL; - return; - } - newseg->tolimit = newseg->s_textsize * ARCDENSITY / 100; - if ( newseg->tolimit < MINARCS ) { - newseg->tolimit = MINARCS; - } else if ( newseg->tolimit > 65534 ) { - newseg->tolimit = 65534; - } - newseg->tos = (struct tostruct *) calloc(1, newseg->tolimit * sizeof( struct tostruct ) ); - if ( newseg->tos == NULL ) { - systemMessage(0, MSG); - - free(buffer); - buffer = NULL; - - free(newseg->froms); - newseg->froms = NULL; - - return; - } - newseg->tos[0].link = 0; - newseg->sbuf = buffer; - newseg->ssiz = monsize; - if ( monsize <= 0 ) - return; - o = highpc - lowpc; - if( monsize < o ) - newseg->s_scale = (int)(( (float) monsize / o ) * SCALE_1_TO_1); - else - newseg->s_scale = SCALE_1_TO_1; - profControl(1); -} - -void profCleanup() -{ - FILE *fd; - int fromindex; - int endfrom; - u32 frompc; - int toindex; - struct gmon_hdr ghdr; - profile_segment *seg = first_segment; - - profControl(0); - fd = fopen( "gmon.out" , "wb" ); - if ( fd == NULL ) { - systemMessage( 0, "mcount: gmon.out" ); - return; - } - - memcpy(&ghdr.cookie[0], GMON_MAGIC, 4); - profPut32((char *)ghdr.version, GMON_VERSION); - - if(fwrite(&ghdr, sizeof(ghdr), 1, fd) != 1) { - systemMessage(0, "mcount: gmon.out header"); - fclose(fd); - return; - } - - if(hz == 0) - hz = 100; - - while(seg) { - - hist_num_bins = seg->ssiz; - - if(profWrite8(fd, GMON_TAG_TIME_HIST) || - profWrite32(fd, (u32)seg->s_lowpc) || - profWrite32(fd, (u32)seg->s_highpc) || - profWrite32(fd, hist_num_bins) || - profWrite32(fd, hz) || - profWrite(fd, hist_dimension, 15) || - profWrite(fd, &hist_dimension_abbrev, 1)) { - systemMessage(0, "mcount: gmon.out hist"); - fclose(fd); - return; - } - u16 *hist_sample = (u16 *)seg->sbuf; - - u16 count; - int i; - - for(i = 0; i < hist_num_bins; ++i) { - profPut16((char *)&count, hist_sample[i]); - - if(fwrite(&count, sizeof(count), 1, fd) != 1) { - systemMessage(0, "mcount: gmon.out sample"); - fclose(fd); - return; - } - } - - endfrom = seg->s_textsize / (HASHFRACTION * sizeof(*seg->froms)); - for ( fromindex = 0 ; fromindex < endfrom ; fromindex++ ) { - if ( seg->froms[fromindex] == 0 ) { - continue; - } - frompc = seg->s_lowpc + (fromindex * HASHFRACTION * sizeof(*seg->froms)); - for (toindex=seg->froms[fromindex]; toindex!=0; toindex=seg->tos[toindex].link) { - if(profWrite8(fd, GMON_TAG_CG_ARC) || - profWrite32(fd, (u32)frompc) || - profWrite32(fd, (u32)seg->tos[toindex].selfpc) || - profWrite32(fd, seg->tos[toindex].count)) { - systemMessage(0, "mcount: arc"); - fclose(fd); - return; - } - } - } - seg = seg->next; - } - fclose(fd); -} - -void profCount() -{ - register char *selfpc; - register unsigned short *frompcindex; - register struct tostruct *top; - register struct tostruct *prevtop; - register long toindex; - profile_segment *seg = first_segment; - - /* - * find the return address for mcount, - * and the return address for mcount's caller. - */ - - /* selfpc = pc pushed by mcount call. - This identifies the function that was just entered. */ - selfpc = (char *) reg[14].I; - /* frompcindex = pc in preceding frame. - This identifies the caller of the function just entered. */ - frompcindex = (unsigned short *) reg[12].I; - /* - * check that we are profiling - * and that we aren't recursively invoked. - */ - if (profiling) { - goto out; - } - profiling++; - /* - * check that frompcindex is a reasonable pc value. - * for example: signal catchers get called from the stack, - * not from text space. too bad. - */ - while(seg) { - u32 index = (long)frompcindex - (long)seg->s_lowpc; - if (index <= seg->s_textsize) { - frompcindex = (unsigned short *) index; - break; - } - seg = seg->next; - } - if ((unsigned long) frompcindex > seg->s_textsize) { - goto done; - } - frompcindex = - &(seg->froms[((long) frompcindex) / (HASHFRACTION * sizeof(*seg->froms))]); - toindex = *frompcindex; - if (toindex == 0) { - /* - * first time traversing this arc - */ - toindex = ++seg->tos[0].link; - if (toindex >= seg->tolimit) { - goto overflow; - } - *frompcindex = (unsigned short)toindex; - top = &seg->tos[toindex]; - top->selfpc = selfpc; - top->count = 1; - top->link = 0; - goto done; - } - top = &seg->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 = ++seg->tos[0].link; - if (toindex >= seg->tolimit) { - goto overflow; - } - top = &seg->tos[toindex]; - top->selfpc = selfpc; - top->count = 1; - top->link = *frompcindex; - *frompcindex = (unsigned short)toindex; - goto done; - } - /* - * otherwise, check the next arc on the chain. - */ - prevtop = top; - top = &seg->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 = (unsigned short)toindex; - goto done; - } - - } - done: - profiling--; - /* and fall through */ - out: - return; /* normal return restores saved registers */ - - overflow: - profiling++; /* halt further profiling */ -#define TOLIMIT "mcount: tos overflow\n" - systemMessage(0, TOLIMIT); - goto out; -} - -void profSetHertz(int h) -{ - hz = h; -} -#endif diff --git a/src/prof/prof.h b/src/prof/prof.h deleted file mode 100644 index 06ac553..0000000 --- a/src/prof/prof.h +++ /dev/null @@ -1,52 +0,0 @@ -// -*- C++ -*- -// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. -// Copyright (C) 1999-2003 Forgotten -// Copyright (C) 2004 Forgotten and the VBA development team - -// This program 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 2, or(at your option) -// any later version. -// -// This program 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. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation, -// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef VBA_PROF_PROF_H -#define VBA_PROF_PROF_H - -/* Control profiling; - profiling is what mcount checks to see if - all the data structures are ready. */ - - -typedef struct profile_segment { - unsigned short *froms; - struct tostruct *tos; - long tolimit; - - u32 s_lowpc; - u32 s_highpc; - unsigned long s_textsize; - - int ssiz; - char *sbuf; - int s_scale; - - struct profile_segment *next; - -} profile_segment; - -extern void profControl(int mode); -extern void profStartup(u32 lowpc, u32 highpc); -extern void profCleanup(); -extern void profCount(); - -extern void profSetHertz(int hertz); -#endif - -- 2.11.4.GIT