X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gprof%2Fhist.c;h=2fc2ad45f32f059156ca2c03a85c5e8f18145209;hb=2480b6fa946bb2d2dc993b1c4a83a8e1258a75e8;hp=465655e93096beb471f0d5eb090dca4f7c64ee52;hpb=b3296dc54c51d28ada4c97aca7f55a4abfe09d9a;p=deliverable%2Fbinutils-gdb.git diff --git a/gprof/hist.c b/gprof/hist.c index 465655e930..2fc2ad45f3 100644 --- a/gprof/hist.c +++ b/gprof/hist.c @@ -1,13 +1,12 @@ /* hist.c - Histogram related operations. - Copyright 1999, 2000, 2001, 2002, 2004, 2005 - Free Software Foundation, Inc. + Copyright (C) 1999-2019 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -20,8 +19,8 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "libiberty.h" #include "gprof.h" +#include "libiberty.h" #include "search_list.h" #include "source.h" #include "symtab.h" @@ -48,6 +47,8 @@ extern void flat_blurb (FILE * fp); static histogram *find_histogram (bfd_vma lowpc, bfd_vma highpc); static histogram *find_histogram_for_pc (bfd_vma pc); +histogram * histograms; +unsigned num_histograms; double hist_scale; static char hist_dimension[16] = "seconds"; static char hist_dimension_abbrev = 's'; @@ -79,14 +80,14 @@ SItab[] = /* Reads just the header part of histogram record into *RECORD from IFP. FILENAME is the name of IFP and - is provided for formatting error messages only. + is provided for formatting error messages only. If FIRST is non-zero, sets global variables HZ, HIST_DIMENSION, HIST_DIMENSION_ABBREV, HIST_SCALE. If FIRST is zero, checks that the new histogram is compatible with already-set values of those variables and emits an error if that's not so. */ static void -read_histogram_header (histogram *record, +read_histogram_header (histogram *record, FILE *ifp, const char *filename, int first) { @@ -108,7 +109,7 @@ read_histogram_header (histogram *record, done (1); } - n_hist_scale = (double)((record->highpc - record->lowpc) / sizeof (UNIT)) + n_hist_scale = (double)((record->highpc - record->lowpc) / sizeof (UNIT)) / record->num_bins; if (first) @@ -123,13 +124,13 @@ read_histogram_header (histogram *record, hz = profrate; memcpy (hist_dimension, n_hist_dimension, 15); hist_dimension_abbrev = n_hist_dimension_abbrev; - hist_scale = n_hist_scale; + hist_scale = n_hist_scale; } else { if (strncmp (n_hist_dimension, hist_dimension, 15) != 0) { - fprintf (stderr, + fprintf (stderr, _("%s: dimension unit changed between histogram records\n" "%s: from '%s'\n" "%s: to '%s'\n"), @@ -139,12 +140,12 @@ read_histogram_header (histogram *record, if (n_hist_dimension_abbrev != hist_dimension_abbrev) { - fprintf (stderr, + fprintf (stderr, _("%s: dimension abbreviation changed between histogram records\n" "%s: from '%c'\n" "%s: to '%c'\n"), whoami, whoami, hist_dimension_abbrev, whoami, n_hist_dimension_abbrev); - done (1); + done (1); } /* The only reason we require the same scale for histograms is that @@ -153,10 +154,10 @@ read_histogram_header (histogram *record, things for different functions. */ if (fabs (hist_scale - n_hist_scale) > 0.000001) { - fprintf (stderr, + fprintf (stderr, _("%s: different scales in histogram records"), whoami); - done (1); + done (1); } } } @@ -190,22 +191,22 @@ hist_read_rec (FILE * ifp, const char *filename) hist_clip_symbol_address (&lowpc, &highpc); if (lowpc != highpc) { - fprintf (stderr, + fprintf (stderr, _("%s: overlapping histogram records\n"), whoami); - done (1); + done (1); } /* This is new record. Add it to global array and allocate space for the samples. */ - histograms = xrealloc (histograms, - sizeof (histogram) * (num_histograms + 1)); + histograms = (struct histogram *) + xrealloc (histograms, sizeof (histogram) * (num_histograms + 1)); memcpy (histograms + num_histograms, &n_record, sizeof (histogram)); - record = &histograms[num_histograms]; + record = &histograms[num_histograms]; ++num_histograms; - record->sample = (int *) xmalloc (record->num_bins + record->sample = (int *) xmalloc (record->num_bins * sizeof (record->sample[0])); memset (record->sample, 0, record->num_bins * sizeof (record->sample[0])); } @@ -216,9 +217,9 @@ hist_read_rec (FILE * ifp, const char *filename) DBG (SAMPLEDEBUG, printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %u\n", - (unsigned long) record->lowpc, (unsigned long) record->highpc, + (unsigned long) record->lowpc, (unsigned long) record->highpc, record->num_bins)); - + for (i = 0; i < record->num_bins; ++i) { UNIT count; @@ -232,8 +233,8 @@ hist_read_rec (FILE * ifp, const char *filename) record->sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]); DBG (SAMPLEDEBUG, printf ("[hist_read_rec] 0x%lx: %u\n", - (unsigned long) (record->lowpc - + i * (record->highpc - record->lowpc) + (unsigned long) (record->lowpc + + i * (record->highpc - record->lowpc) / record->num_bins), record->sample[i])); } @@ -254,7 +255,7 @@ hist_write_hist (FILE * ofp, const char *filename) histogram *record = &histograms[r]; /* Write header. */ - + if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST) || gmon_io_write_vma (ofp, record->lowpc) || gmon_io_write_vma (ofp, record->highpc) @@ -266,11 +267,11 @@ hist_write_hist (FILE * ofp, const char *filename) perror (filename); done (1); } - + for (i = 0; i < record->num_bins; ++i) { bfd_put_16 (core_bfd, (bfd_vma) record->sample[i], (bfd_byte *) &count[0]); - + if (fwrite (&count[0], sizeof (count), 1, ofp) != 1) { perror (filename); @@ -288,7 +289,7 @@ hist_write_hist (FILE * ofp, const char *filename) next bin. */ static void -scale_and_align_entries () +scale_and_align_entries (void) { Sym *sym; bfd_vma bin_of_entry; @@ -296,10 +297,10 @@ scale_and_align_entries () for (sym = symtab.base; sym < symtab.limit; sym++) { - sym->hist.scaled_addr = sym->addr / sizeof (UNIT); - histogram *r = find_histogram_for_pc (sym->addr); + sym->hist.scaled_addr = sym->addr / sizeof (UNIT); + if (r) { bin_of_entry = (sym->hist.scaled_addr - r->lowpc) / hist_scale; @@ -363,13 +364,13 @@ hist_assign_samples_1 (histogram *r) bfd_vma sym_low_pc, sym_high_pc; bfd_vma overlap, addr; unsigned int bin_count; - unsigned int i, j; - double time, credit; + unsigned int i, j, k; + double count_time, credit; bfd_vma lowpc = r->lowpc / sizeof (UNIT); /* Iterate over all sample bins. */ - for (i = 0, j = 1; i < r->num_bins; ++i) + for (i = 0, k = 1; i < r->num_bins; ++i) { bin_count = r->sample[i]; if (! bin_count) @@ -377,7 +378,7 @@ hist_assign_samples_1 (histogram *r) bin_low_pc = lowpc + (bfd_vma) (hist_scale * i); bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1)); - time = bin_count; + count_time = bin_count; DBG (SAMPLEDEBUG, printf ( @@ -385,10 +386,13 @@ hist_assign_samples_1 (histogram *r) (unsigned long) (sizeof (UNIT) * bin_low_pc), (unsigned long) (sizeof (UNIT) * bin_high_pc), bin_count)); - total_time += time; + total_time += count_time; - /* Credit all symbols that are covered by bin I. */ - for (j = j - 1; j < symtab.len; ++j) + /* Credit all symbols that are covered by bin I. + + PR gprof/13325: Make sure that K does not get decremented + and J will never be less than 0. */ + for (j = k - 1; j < symtab.len; k = ++j) { sym_low_pc = symtab.base[j].hist.scaled_addr; sym_high_pc = symtab.base[j + 1].hist.scaled_addr; @@ -412,11 +416,11 @@ hist_assign_samples_1 (histogram *r) "[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n", (unsigned long) symtab.base[j].addr, (unsigned long) (sizeof (UNIT) * sym_high_pc), - symtab.base[j].name, overlap * time / hist_scale, + symtab.base[j].name, overlap * count_time / hist_scale, (long) overlap)); addr = symtab.base[j].addr; - credit = overlap * time / hist_scale; + credit = overlap * count_time / hist_scale; /* Credit symbol if it appears in INCL_FLAT or that table is empty and it does not appear it in @@ -441,7 +445,7 @@ hist_assign_samples_1 (histogram *r) /* Calls 'hist_assign_sampes_1' for all histogram records read so far. */ void -hist_assign_samples () +hist_assign_samples (void) { unsigned i; @@ -449,7 +453,7 @@ hist_assign_samples () for (i = 0; i < num_histograms; ++i) hist_assign_samples_1 (&histograms[i]); - + } /* Print header for flag histogram profile. */ @@ -464,7 +468,7 @@ print_header (int prefix) if (bsd_style_output) { printf (_("\ngranularity: each sample hit covers %ld byte(s)"), - (long) hist_scale * sizeof (UNIT)); + (long) hist_scale * (long) sizeof (UNIT)); if (total_time > 0.0) { printf (_(" for %.2f%% of %.2f %s\n\n"), @@ -558,12 +562,12 @@ cmp_time (const PTR lp, const PTR rp) /* Print the flat histogram profile. */ void -hist_print () +hist_print (void) { Sym **time_sorted_syms, *top_dog, *sym; - unsigned int index; + unsigned int sym_index; unsigned log_scale; - double top_time, time; + double top_time; bfd_vma addr; if (first_output) @@ -590,8 +594,8 @@ hist_print () and tertiary keys). */ time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); - for (index = 0; index < symtab.len; ++index) - time_sorted_syms[index] = &symtab.base[index]; + for (sym_index = 0; sym_index < symtab.len; ++sym_index) + time_sorted_syms[sym_index] = &symtab.base[sym_index]; qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time); @@ -607,18 +611,20 @@ hist_print () top_dog = 0; top_time = 0.0; - for (index = 0; index < symtab.len; ++index) + for (sym_index = 0; sym_index < symtab.len; ++sym_index) { - sym = time_sorted_syms[index]; + sym = time_sorted_syms[sym_index]; if (sym->ncalls != 0) { - time = (sym->hist.time + sym->cg.child_time) / sym->ncalls; + double call_time; + + call_time = (sym->hist.time + sym->cg.child_time) / sym->ncalls; - if (time > top_time) + if (call_time > top_time) { top_dog = sym; - top_time = time; + top_time = call_time; } } } @@ -631,7 +637,7 @@ hist_print () { double scaled_value = SItab[log_scale].scale * top_time; - if (scaled_value >= 1.0 && scaled_value < 1000.0) + if (scaled_value >= 1.0 && scaled_value < 1000.0) break; } } @@ -642,16 +648,16 @@ hist_print () I-cache misses etc.). */ print_header (SItab[log_scale].prefix); - for (index = 0; index < symtab.len; ++index) + for (sym_index = 0; sym_index < symtab.len; ++sym_index) { - addr = time_sorted_syms[index]->addr; + addr = time_sorted_syms[sym_index]->addr; /* Print symbol if its in INCL_FLAT table or that table is empty and the symbol is not in EXCL_FLAT. */ if (sym_lookup (&syms[INCL_FLAT], addr) || (syms[INCL_FLAT].len == 0 && !sym_lookup (&syms[EXCL_FLAT], addr))) - print_line (time_sorted_syms[index], SItab[log_scale].scale); + print_line (time_sorted_syms[sym_index], SItab[log_scale].scale); } free (time_sorted_syms); @@ -669,7 +675,7 @@ hist_check_address (unsigned address) if (histograms[i].lowpc <= address && address < histograms[i].highpc) return 1; - return 0; + return 0; } #if ! defined(min) @@ -703,7 +709,7 @@ hist_clip_symbol_address (bfd_vma *p_lowpc, bfd_vma *p_highpc) { fprintf (stderr, _("%s: found a symbol that covers " - "several histogram records") + "several histogram records"), whoami); done (1); } @@ -744,5 +750,5 @@ find_histogram_for_pc (bfd_vma pc) if (histograms[i].lowpc <= pc && pc < histograms[i].highpc) return &histograms[i]; } - return 0; + return 0; }