Home | History | Annotate | Download | only in gprof
      1 /*  bb_exit_func.c - dumps all the basic-block statistics linked into
      2     the bb_head chain to .d files.
      3 
      4    Copyright (C) 2000-2016 Free Software Foundation, Inc.
      5 
      6    This file is part of GNU Binutils.
      7 
      8    This program is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3 of the License, or
     11    (at your option) any later version.
     12 
     13    This program is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program; if not, write to the Free Software
     20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
     21    02110-1301, USA.
     22 
     23    This code was contributed by:
     24 
     25      David Mosberger-Tang <David.Mosberger (at) acm.org>  */
     26 
     27 #include <stdio.h>
     29 #include <strings.h>
     30 #include "bfd.h"
     31 #include "gmon_out.h"
     32 
     33 /* structure emitted by -a */
     34 struct bb
     35 {
     36   long zero_word;
     37   const char *filename;
     38   long *counts;
     39   long ncounts;
     40   struct bb *next;
     41   const unsigned long *addresses;
     42 };
     43 
     44 struct bb *__bb_head = (struct bb *) 0;
     45 
     46 
     47 void
     48 __bb_exit_func ()
     49 {
     50   const int version = GMON_VERSION;
     51   struct gmon_hdr ghdr;
     52   struct bb *ptr;
     53   FILE *fp;
     54   /* GEN_GMON_CNT_FILE should be defined on systems with mcleanup()
     55      functions that do not write basic-block to gmon.out.  In such
     56      cases profiling with "-pg -a" would result in a gmon.out file
     57      without basic-block info (because the file written here would be
     58      overwritten.  Thus, a separate file is generated instead.  The
     59      two files can easily be combined by specifying them on gprof's
     60      command line (and possibly generating a gmon.sum file with "gprof
     61      -s"). */
     62 #ifndef GEN_GMON_CNT_FILE
     63 #   define OUT_NAME	"gmon.out"
     64 #else
     65 #   define OUT_NAME	"gmon.cnt"
     66 #endif
     67   fp = fopen (OUT_NAME, "wb");
     68   if (!fp)
     69     {
     70       perror (OUT_NAME);
     71       return;
     72     }
     73   memcpy (&ghdr.cookie[0], GMON_MAGIC, 4);
     74   memcpy (&ghdr.version, &version, sizeof (version));
     75   fwrite (&ghdr, sizeof (ghdr), 1, fp);
     76 
     77   for (ptr = __bb_head; ptr != 0; ptr = ptr->next)
     78     {
     79       u_int ncounts = ptr->ncounts;
     80       u_char tag;
     81       u_int i;
     82 
     83       tag = GMON_TAG_BB_COUNT;
     84       fwrite (&tag, sizeof (tag), 1, fp);
     85       fwrite (&ncounts, sizeof (ncounts), 1, fp);
     86 
     87       for (i = 0; i < ncounts; ++i)
     88 	{
     89 	  fwrite (&ptr->addresses[i], sizeof (ptr->addresses[0]), 1, fp);
     90 	  fwrite (&ptr->counts[i], sizeof (ptr->counts[0]), 1, fp);
     91 	}
     92     }
     93   fclose (fp);
     94 }
     95