diff options
Diffstat (limited to 'gprof/gmon_io.c')
-rw-r--r-- | gprof/gmon_io.c | 123 |
1 files changed, 67 insertions, 56 deletions
diff --git a/gprof/gmon_io.c b/gprof/gmon_io.c index f2ac524ac6f..af1d7677451 100644 --- a/gprof/gmon_io.c +++ b/gprof/gmon_io.c @@ -1,6 +1,24 @@ -/* - * Input and output from/to gmon.out files. - */ +/* gmon_io.c - Input and output from/to gmon.out files. + + Copyright (C) 2000 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. */ + #include "cg_arcs.h" #include "basic_blocks.h" #include "bfd.h" @@ -8,18 +26,17 @@ #include "call_graph.h" #include "gmon_io.h" #include "gmon_out.h" -#include "gmon.h" /* fetch header for old format */ +#include "gmon.h" /* Fetch header for old format. */ #include "gprof.h" #include "hertz.h" #include "hist.h" #include "libiberty.h" int gmon_input = 0; -int gmon_file_version = 0; /* 0 == old (non-versioned) file format */ +int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */ + +/* This probably ought to be in libbfd. */ -/* - * This probably ought to be in libbfd. - */ bfd_vma DEFUN (get_vma, (abfd, addr), bfd * abfd AND bfd_byte * addr) { @@ -37,9 +54,8 @@ DEFUN (get_vma, (abfd, addr), bfd * abfd AND bfd_byte * addr) } -/* - * This probably ought to be in libbfd. - */ +/* This probably ought to be in libbfd. */ + void DEFUN (put_vma, (abfd, val, addr), bfd * abfd AND bfd_vma val AND bfd_byte * addr) { @@ -67,8 +83,7 @@ DEFUN (gmon_out_read, (filename), const char *filename) unsigned char tag; int nhist = 0, narcs = 0, nbbs = 0; - /* open gmon.out file: */ - + /* Open gmon.out file. */ if (strcmp (filename, "-") == 0) { ifp = stdin; @@ -79,12 +94,14 @@ DEFUN (gmon_out_read, (filename), const char *filename) else { ifp = fopen (filename, FOPEN_RB); + if (!ifp) { perror (filename); done (1); } } + if (fread (&ghdr, sizeof (struct gmon_hdr), 1, ifp) != 1) { fprintf (stderr, _("%s: file too short to be a gmon file\n"), @@ -102,9 +119,9 @@ DEFUN (gmon_out_read, (filename), const char *filename) done (1); } - /* right magic, so it's probably really a new gmon.out file */ - + /* Right magic, so it's probably really a new gmon.out file. */ gmon_file_version = bfd_get_32 (core_bfd, (bfd_byte *) ghdr.version); + if (gmon_file_version != GMON_VERSION && gmon_file_version != 0) { fprintf (stderr, @@ -113,7 +130,7 @@ DEFUN (gmon_out_read, (filename), const char *filename) done (1); } - /* read in all the records: */ + /* Read in all the records. */ while (fread (&tag, sizeof (tag), 1, ifp) == 1) { switch (tag) @@ -163,22 +180,19 @@ DEFUN (gmon_out_read, (filename), const char *filename) UNIT raw_bin_count; struct hdr tmp; - /* - * Information from a gmon.out file is in two parts: an array of - * sampling hits within pc ranges, and the arcs. - */ + /* Information from a gmon.out file is in two parts: an array of + sampling hits within pc ranges, and the arcs. */ gmon_input = INPUT_HISTOGRAM | INPUT_CALL_GRAPH; - /* - * This fseek() ought to work even on stdin as long as it's - * not an interactive device (heck, is there anybody who would - * want to type in a gmon.out at the terminal?). - */ + /* This fseek() ought to work even on stdin as long as it's + not an interactive device (heck, is there anybody who would + want to type in a gmon.out at the terminal?). */ if (fseek (ifp, 0, SEEK_SET) < 0) { perror (filename); done (1); } + if (fread (&raw, 1, sizeof (struct raw_phdr), ifp) != sizeof (struct raw_phdr)) { @@ -186,6 +200,7 @@ DEFUN (gmon_out_read, (filename), const char *filename) filename); done (1); } + tmp.low_pc = get_vma (core_bfd, (bfd_byte *) &raw.low_pc[0]); tmp.high_pc = get_vma (core_bfd, (bfd_byte *) &raw.high_pc[0]); tmp.ncnt = bfd_get_32 (core_bfd, (bfd_byte *) &raw.ncnt[0]); @@ -196,8 +211,8 @@ DEFUN (gmon_out_read, (filename), const char *filename) int profrate; /* 4.4BSD format header. */ - profrate = bfd_get_32 (core_bfd, (bfd_byte *) &raw.profrate[0]); + if (!s_highpc) hz = profrate; else if (hz != profrate) @@ -212,7 +227,7 @@ DEFUN (gmon_out_read, (filename), const char *filename) } else { - /* old style BSD format. */ + /* Old style BSD format. */ if (file_format == FF_BSD44) { fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"), @@ -236,6 +251,7 @@ DEFUN (gmon_out_read, (filename), const char *filename) filename); done (1); } + h = tmp; s_lowpc = (bfd_vma) h.low_pc; s_highpc = (bfd_vma) h.high_pc; @@ -243,6 +259,7 @@ DEFUN (gmon_out_read, (filename), const char *filename) highpc = (bfd_vma) h.high_pc / sizeof (UNIT); samp_bytes = h.ncnt - header_size; hist_num_bins = samp_bytes / sizeof (UNIT); + DBG (SAMPLEDEBUG, printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n", (unsigned long) h.low_pc, (unsigned long) h.high_pc, @@ -264,14 +281,13 @@ DEFUN (gmon_out_read, (filename), const char *filename) } if (hist_num_bins) - { - ++nhist; - } + ++nhist; if (!hist_sample) { hist_sample = (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0])); + memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0])); } @@ -284,34 +300,35 @@ DEFUN (gmon_out_read, (filename), const char *filename) whoami, --i, hist_num_bins); done (1); } + hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count); } - /* - * The rest of the file consists of a bunch of <from,self,count> - * tuples: - */ + /* The rest of the file consists of a bunch of + <from,self,count> tuples. */ while (fread (&raw_arc, sizeof (raw_arc), 1, ifp) == 1) { ++narcs; from_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.from_pc); self_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.self_pc); count = bfd_get_32 (core_bfd, (bfd_byte *) raw_arc.count); + DBG (SAMPLEDEBUG, printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n", (unsigned long) from_pc, (unsigned long) self_pc, count)); - /* add this arc: */ + + /* Add this arc. */ cg_tally (from_pc, self_pc, count); } + fclose (ifp); if (hz == HZ_WRONG) { - /* - * How many ticks per second? If we can't tell, report - * time in ticks. - */ + /* How many ticks per second? If we can't tell, report + time in ticks. */ hz = hertz (); + if (hz == HZ_WRONG) { hz = 1; @@ -356,33 +373,28 @@ DEFUN (gmon_out_write, (filename), const char *filename) if (file_format == FF_AUTO || file_format == FF_MAGIC) { - /* write gmon header: */ + /* Write gmon header. */ memcpy (&ghdr.cookie[0], GMON_MAGIC, 4); bfd_put_32 (core_bfd, GMON_VERSION, (bfd_byte *) ghdr.version); + if (fwrite (&ghdr, sizeof (ghdr), 1, ofp) != 1) { perror (filename); done (1); } - /* write execution time histogram if we have one: */ + /* Write execution time histogram if we have one. */ if (gmon_input & INPUT_HISTOGRAM) - { - hist_write_hist (ofp, filename); - } + hist_write_hist (ofp, filename); - /* write call graph arcs if we have any: */ + /* Write call graph arcs if we have any. */ if (gmon_input & INPUT_CALL_GRAPH) - { - cg_write_arcs (ofp, filename); - } + cg_write_arcs (ofp, filename); - /* write basic-block info if we have it: */ + /* Write basic-block info if we have it. */ if (gmon_input & INPUT_BB_COUNTS) - { - bb_write_blocks (ofp, filename); - } + bb_write_blocks (ofp, filename); } else if (file_format == FF_BSD || file_format == FF_BSD44) { @@ -423,8 +435,7 @@ DEFUN (gmon_out_write, (filename), const char *filename) } } - /* dump the samples: */ - + /* Dump the samples. */ for (i = 0; i < hist_num_bins; ++i) { bfd_put_16 (core_bfd, hist_sample[i], (bfd_byte *) & raw_bin_count[0]); @@ -435,8 +446,7 @@ DEFUN (gmon_out_write, (filename), const char *filename) } } - /* dump the normalized raw arc information: */ - + /* Dump the normalized raw arc information. */ for (sym = symtab.base; sym < symtab.limit; ++sym) { for (arc = sym->cg.children; arc; arc = arc->next_child) @@ -457,6 +467,7 @@ DEFUN (gmon_out_write, (filename), const char *filename) (unsigned long) arc->child->addr, arc->count)); } } + fclose (ofp); } else |