* configure.ac (FN_PTRS_IN_SO_WITHOUT_PIC): Add sparc64.
[deliverable/binutils-gdb.git] / gprof / hist.c
CommitLineData
ef368dac
NC
1/* hist.c - Histogram related operations.
2
651dbc76 3 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2007
d6a39701 4 Free Software Foundation, Inc.
ef368dac
NC
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
651dbc76 10 the Free Software Foundation; either version 3 of the License, or
ef368dac
NC
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
44eb1801
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
ef368dac 22\f
252b5132
RH
23#include "libiberty.h"
24#include "gprof.h"
6d9c411a
AM
25#include "search_list.h"
26#include "source.h"
27#include "symtab.h"
252b5132
RH
28#include "corefile.h"
29#include "gmon_io.h"
30#include "gmon_out.h"
31#include "hist.h"
252b5132
RH
32#include "sym_ids.h"
33#include "utils.h"
b3296dc5
VP
34#include "math.h"
35#include "stdio.h"
36#include "stdlib.h"
252b5132
RH
37
38#define UNITS_TO_CODE (offset_to_code / sizeof(UNIT))
39
3e8f6abf
BE
40static void scale_and_align_entries (void);
41static void print_header (int);
42static void print_line (Sym *, double);
43static int cmp_time (const PTR, const PTR);
252b5132 44
ef368dac 45/* Declarations of automatically generated functions to output blurbs. */
3e8f6abf 46extern void flat_blurb (FILE * fp);
252b5132 47
b3296dc5
VP
48static histogram *find_histogram (bfd_vma lowpc, bfd_vma highpc);
49static histogram *find_histogram_for_pc (bfd_vma pc);
50
252b5132 51double hist_scale;
9e972ca0
BE
52static char hist_dimension[16] = "seconds";
53static char hist_dimension_abbrev = 's';
252b5132 54
0eee5820 55static double accum_time; /* Accumulated time so far for print_line(). */
ef368dac
NC
56static double total_time; /* Total time for all routines. */
57
58/* Table of SI prefixes for powers of 10 (used to automatically
59 scale some of the values in the flat profile). */
252b5132
RH
60const struct
61 {
62 char prefix;
63 double scale;
64 }
65SItab[] =
66{
0eee5820
AM
67 { 'T', 1e-12 }, /* tera */
68 { 'G', 1e-09 }, /* giga */
69 { 'M', 1e-06 }, /* mega */
70 { 'K', 1e-03 }, /* kilo */
71 { ' ', 1e-00 },
72 { 'm', 1e+03 }, /* milli */
73 { 'u', 1e+06 }, /* micro */
74 { 'n', 1e+09 }, /* nano */
75 { 'p', 1e+12 }, /* pico */
76 { 'f', 1e+15 }, /* femto */
77 { 'a', 1e+18 } /* ato */
252b5132
RH
78};
79
b3296dc5
VP
80/* Reads just the header part of histogram record into
81 *RECORD from IFP. FILENAME is the name of IFP and
82 is provided for formatting error messages only.
ef368dac 83
b3296dc5
VP
84 If FIRST is non-zero, sets global variables HZ, HIST_DIMENSION,
85 HIST_DIMENSION_ABBREV, HIST_SCALE. If FIRST is zero, checks
86 that the new histogram is compatible with already-set values
87 of those variables and emits an error if that's not so. */
88static void
89read_histogram_header (histogram *record,
90 FILE *ifp, const char *filename,
91 int first)
252b5132 92{
b3296dc5
VP
93 unsigned int profrate;
94 char n_hist_dimension[15];
95 char n_hist_dimension_abbrev;
96 double n_hist_scale;
97
98 if (gmon_io_read_vma (ifp, &record->lowpc)
99 || gmon_io_read_vma (ifp, &record->highpc)
100 || gmon_io_read_32 (ifp, &record->num_bins)
0eee5820 101 || gmon_io_read_32 (ifp, &profrate)
b3296dc5
VP
102 || gmon_io_read (ifp, n_hist_dimension, 15)
103 || gmon_io_read (ifp, &n_hist_dimension_abbrev, 1))
252b5132
RH
104 {
105 fprintf (stderr, _("%s: %s: unexpected end of file\n"),
106 whoami, filename);
0eee5820 107
252b5132
RH
108 done (1);
109 }
110
b3296dc5
VP
111 n_hist_scale = (double)((record->highpc - record->lowpc) / sizeof (UNIT))
112 / record->num_bins;
113
114 if (first)
252b5132 115 {
b3296dc5
VP
116 /* We don't try to veryfy profrate is the same for all histogram
117 records. If we have two histogram records for the same
118 address range and profiling samples is done as often
119 as possible as opposed on timer, then the actual profrate will
120 be slightly different. Most of the time the difference does not
121 matter and insisting that profiling rate is exactly the same
122 will only create inconvenient. */
252b5132 123 hz = profrate;
b3296dc5
VP
124 memcpy (hist_dimension, n_hist_dimension, 15);
125 hist_dimension_abbrev = n_hist_dimension_abbrev;
126 hist_scale = n_hist_scale;
252b5132 127 }
b3296dc5 128 else
252b5132 129 {
b3296dc5
VP
130 if (strncmp (n_hist_dimension, hist_dimension, 15) != 0)
131 {
132 fprintf (stderr,
133 _("%s: dimension unit changed between histogram records\n"
134 "%s: from '%s'\n"
135 "%s: to '%s'\n"),
136 whoami, whoami, hist_dimension, whoami, n_hist_dimension);
137 done (1);
138 }
139
140 if (n_hist_dimension_abbrev != hist_dimension_abbrev)
141 {
142 fprintf (stderr,
143 _("%s: dimension abbreviation changed between histogram records\n"
144 "%s: from '%c'\n"
145 "%s: to '%c'\n"),
146 whoami, whoami, hist_dimension_abbrev, whoami, n_hist_dimension_abbrev);
147 done (1);
148 }
149
150 /* The only reason we require the same scale for histograms is that
151 there's code (notably printing code), that prints units,
152 and it would be very confusing to have one unit mean different
153 things for different functions. */
154 if (fabs (hist_scale - n_hist_scale) > 0.000001)
155 {
156 fprintf (stderr,
157 _("%s: different scales in histogram records"),
158 whoami);
159 done (1);
160 }
252b5132 161 }
b3296dc5 162}
252b5132 163
b3296dc5
VP
164/* Read the histogram from file IFP. FILENAME is the name of IFP and
165 is provided for formatting error messages only. */
166
167void
168hist_read_rec (FILE * ifp, const char *filename)
169{
170 bfd_vma lowpc, highpc;
171 histogram n_record;
172 histogram *record, *existing_record;
173 unsigned i;
174
175 /* 1. Read the header and see if there's existing record for the
176 same address range and that there are no overlapping records. */
177 read_histogram_header (&n_record, ifp, filename, num_histograms == 0);
178
179 existing_record = find_histogram (n_record.lowpc, n_record.highpc);
180 if (existing_record)
252b5132 181 {
b3296dc5
VP
182 record = existing_record;
183 }
184 else
185 {
186 /* If this record overlaps, but does not completely match an existing
187 record, it's an error. */
188 lowpc = n_record.lowpc;
189 highpc = n_record.highpc;
190 hist_clip_symbol_address (&lowpc, &highpc);
191 if (lowpc != highpc)
192 {
193 fprintf (stderr,
194 _("%s: overlapping histogram records\n"),
195 whoami);
196 done (1);
197 }
198
199 /* This is new record. Add it to global array and allocate space for
200 the samples. */
201 histograms = xrealloc (histograms,
202 sizeof (histogram) * (num_histograms + 1));
203 memcpy (histograms + num_histograms,
204 &n_record, sizeof (histogram));
205 record = &histograms[num_histograms];
206 ++num_histograms;
207
208 record->sample = (int *) xmalloc (record->num_bins
209 * sizeof (record->sample[0]));
210 memset (record->sample, 0, record->num_bins * sizeof (record->sample[0]));
252b5132
RH
211 }
212
b3296dc5
VP
213 /* 2. We have either a new record (with zeroed histogram data), or an existing
214 record with some data in the histogram already. Read new data into the
215 record, adding hit counts. */
216
217 DBG (SAMPLEDEBUG,
218 printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %u\n",
219 (unsigned long) record->lowpc, (unsigned long) record->highpc,
220 record->num_bins));
221
222 for (i = 0; i < record->num_bins; ++i)
252b5132 223 {
b3296dc5 224 UNIT count;
252b5132
RH
225 if (fread (&count[0], sizeof (count), 1, ifp) != 1)
226 {
227 fprintf (stderr,
8c62e9e1 228 _("%s: %s: unexpected EOF after reading %u of %u samples\n"),
b3296dc5 229 whoami, filename, i, record->num_bins);
252b5132
RH
230 done (1);
231 }
b3296dc5 232 record->sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
0eee5820
AM
233 DBG (SAMPLEDEBUG,
234 printf ("[hist_read_rec] 0x%lx: %u\n",
b3296dc5
VP
235 (unsigned long) (record->lowpc
236 + i * (record->highpc - record->lowpc)
237 / record->num_bins),
238 record->sample[i]));
252b5132
RH
239 }
240}
241
242
b3296dc5 243/* Write all execution histograms file OFP. FILENAME is the name
ef368dac
NC
244 of OFP and is provided for formatting error-messages only. */
245
252b5132 246void
3e8f6abf 247hist_write_hist (FILE * ofp, const char *filename)
252b5132 248{
252b5132 249 UNIT count;
b3296dc5 250 unsigned int i, r;
252b5132 251
b3296dc5 252 for (r = 0; r < num_histograms; ++r)
252b5132 253 {
b3296dc5
VP
254 histogram *record = &histograms[r];
255
256 /* Write header. */
257
258 if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST)
259 || gmon_io_write_vma (ofp, record->lowpc)
260 || gmon_io_write_vma (ofp, record->highpc)
261 || gmon_io_write_32 (ofp, record->num_bins)
262 || gmon_io_write_32 (ofp, hz)
263 || gmon_io_write (ofp, hist_dimension, 15)
264 || gmon_io_write (ofp, &hist_dimension_abbrev, 1))
252b5132
RH
265 {
266 perror (filename);
267 done (1);
268 }
b3296dc5
VP
269
270 for (i = 0; i < record->num_bins; ++i)
271 {
272 bfd_put_16 (core_bfd, (bfd_vma) record->sample[i], (bfd_byte *) &count[0]);
273
274 if (fwrite (&count[0], sizeof (count), 1, ofp) != 1)
275 {
276 perror (filename);
277 done (1);
278 }
279 }
252b5132
RH
280 }
281}
282
ef368dac
NC
283/* Calculate scaled entry point addresses (to save time in
284 hist_assign_samples), and, on architectures that have procedure
285 entry masks at the start of a function, possibly push the scaled
286 entry points over the procedure entry mask, if it turns out that
287 the entry point is in one bin and the code for a routine is in the
288 next bin. */
289
252b5132
RH
290static void
291scale_and_align_entries ()
292{
293 Sym *sym;
294 bfd_vma bin_of_entry;
295 bfd_vma bin_of_code;
296
297 for (sym = symtab.base; sym < symtab.limit; sym++)
298 {
b3296dc5
VP
299 histogram *r = find_histogram_for_pc (sym->addr);
300
74bad5d4
L
301 sym->hist.scaled_addr = sym->addr / sizeof (UNIT);
302
b3296dc5 303 if (r)
252b5132 304 {
b3296dc5
VP
305 bin_of_entry = (sym->hist.scaled_addr - r->lowpc) / hist_scale;
306 bin_of_code = ((sym->hist.scaled_addr + UNITS_TO_CODE - r->lowpc)
307 / hist_scale);
308 if (bin_of_entry < bin_of_code)
309 {
310 DBG (SAMPLEDEBUG,
311 printf ("[scale_and_align_entries] pushing 0x%lx to 0x%lx\n",
312 (unsigned long) sym->hist.scaled_addr,
313 (unsigned long) (sym->hist.scaled_addr
314 + UNITS_TO_CODE)));
315 sym->hist.scaled_addr += UNITS_TO_CODE;
316 }
252b5132
RH
317 }
318 }
319}
320
321
ef368dac 322/* Assign samples to the symbol to which they belong.
0eee5820 323
ef368dac
NC
324 Histogram bin I covers some address range [BIN_LOWPC,BIN_HIGH_PC)
325 which may overlap one more symbol address ranges. If a symbol
326 overlaps with the bin's address range by O percent, then O percent
327 of the bin's count is credited to that symbol.
0eee5820 328
ef368dac
NC
329 There are three cases as to where BIN_LOW_PC and BIN_HIGH_PC can be
330 with respect to the symbol's address range [SYM_LOW_PC,
331 SYM_HIGH_PC) as shown in the following diagram. OVERLAP computes
332 the distance (in UNITs) between the arrows, the fraction of the
333 sample that is to be credited to the symbol which starts at
334 SYM_LOW_PC.
0eee5820
AM
335
336 sym_low_pc sym_high_pc
337 | |
338 v v
339
340 +-----------------------------------------------+
341 | |
342 | ->| |<- ->| |<- ->| |<- |
343 | | | | | |
344 +---------+ +---------+ +---------+
345
346 ^ ^ ^ ^ ^ ^
347 | | | | | |
ef368dac 348 bin_low_pc bin_high_pc bin_low_pc bin_high_pc bin_low_pc bin_high_pc
0eee5820 349
ef368dac
NC
350 For the VAX we assert that samples will never fall in the first two
351 bytes of any routine, since that is the entry mask, thus we call
352 scale_and_align_entries() to adjust the entry points if the entry
353 mask falls in one bin but the code for the routine doesn't start
354 until the next bin. In conjunction with the alignment of routine
355 addresses, this should allow us to have only one sample for every
356 four bytes of text space and never have any overlap (the two end
357 cases, above). */
358
b3296dc5
VP
359static void
360hist_assign_samples_1 (histogram *r)
252b5132
RH
361{
362 bfd_vma bin_low_pc, bin_high_pc;
363 bfd_vma sym_low_pc, sym_high_pc;
364 bfd_vma overlap, addr;
8c62e9e1
AM
365 unsigned int bin_count;
366 unsigned int i, j;
252b5132
RH
367 double time, credit;
368
b3296dc5 369 bfd_vma lowpc = r->lowpc / sizeof (UNIT);
252b5132 370
ef368dac 371 /* Iterate over all sample bins. */
b3296dc5 372 for (i = 0, j = 1; i < r->num_bins; ++i)
252b5132 373 {
b3296dc5 374 bin_count = r->sample[i];
ef368dac
NC
375 if (! bin_count)
376 continue;
377
252b5132
RH
378 bin_low_pc = lowpc + (bfd_vma) (hist_scale * i);
379 bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1));
380 time = bin_count;
0eee5820 381
252b5132
RH
382 DBG (SAMPLEDEBUG,
383 printf (
8c62e9e1 384 "[assign_samples] bin_low_pc=0x%lx, bin_high_pc=0x%lx, bin_count=%u\n",
fdcf7d43
ILT
385 (unsigned long) (sizeof (UNIT) * bin_low_pc),
386 (unsigned long) (sizeof (UNIT) * bin_high_pc),
252b5132
RH
387 bin_count));
388 total_time += time;
389
ef368dac 390 /* Credit all symbols that are covered by bin I. */
252b5132
RH
391 for (j = j - 1; j < symtab.len; ++j)
392 {
393 sym_low_pc = symtab.base[j].hist.scaled_addr;
394 sym_high_pc = symtab.base[j + 1].hist.scaled_addr;
0eee5820 395
ef368dac
NC
396 /* If high end of bin is below entry address,
397 go for next bin. */
252b5132 398 if (bin_high_pc < sym_low_pc)
ef368dac
NC
399 break;
400
401 /* If low end of bin is above high end of symbol,
402 go for next symbol. */
252b5132 403 if (bin_low_pc >= sym_high_pc)
ef368dac
NC
404 continue;
405
252b5132
RH
406 overlap =
407 MIN (bin_high_pc, sym_high_pc) - MAX (bin_low_pc, sym_low_pc);
408 if (overlap > 0)
409 {
410 DBG (SAMPLEDEBUG,
411 printf (
0eee5820
AM
412 "[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
413 (unsigned long) symtab.base[j].addr,
414 (unsigned long) (sizeof (UNIT) * sym_high_pc),
415 symtab.base[j].name, overlap * time / hist_scale,
416 (long) overlap));
417
252b5132
RH
418 addr = symtab.base[j].addr;
419 credit = overlap * time / hist_scale;
0eee5820 420
ef368dac 421 /* Credit symbol if it appears in INCL_FLAT or that
0eee5820
AM
422 table is empty and it does not appear it in
423 EXCL_FLAT. */
252b5132
RH
424 if (sym_lookup (&syms[INCL_FLAT], addr)
425 || (syms[INCL_FLAT].len == 0
426 && !sym_lookup (&syms[EXCL_FLAT], addr)))
427 {
428 symtab.base[j].hist.time += credit;
429 }
430 else
431 {
432 total_time -= credit;
433 }
434 }
435 }
436 }
0eee5820 437
252b5132
RH
438 DBG (SAMPLEDEBUG, printf ("[assign_samples] total_time %f\n",
439 total_time));
440}
441
b3296dc5
VP
442/* Calls 'hist_assign_sampes_1' for all histogram records read so far. */
443void
444hist_assign_samples ()
445{
446 unsigned i;
447
448 scale_and_align_entries ();
449
450 for (i = 0; i < num_histograms; ++i)
451 hist_assign_samples_1 (&histograms[i]);
452
453}
252b5132 454
ef368dac
NC
455/* Print header for flag histogram profile. */
456
252b5132 457static void
3e8f6abf 458print_header (int prefix)
252b5132
RH
459{
460 char unit[64];
461
462 sprintf (unit, _("%c%c/call"), prefix, hist_dimension_abbrev);
463
464 if (bsd_style_output)
465 {
466 printf (_("\ngranularity: each sample hit covers %ld byte(s)"),
d2df793a 467 (long) hist_scale * (long) sizeof (UNIT));
252b5132
RH
468 if (total_time > 0.0)
469 {
470 printf (_(" for %.2f%% of %.2f %s\n\n"),
471 100.0 / total_time, total_time / hz, hist_dimension);
472 }
473 }
474 else
475 {
476 printf (_("\nEach sample counts as %g %s.\n"), 1.0 / hz, hist_dimension);
477 }
478
479 if (total_time <= 0.0)
480 {
481 printf (_(" no time accumulated\n\n"));
0eee5820 482
ef368dac 483 /* This doesn't hurt since all the numerators will be zero. */
252b5132
RH
484 total_time = 1.0;
485 }
486
487 printf ("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
0eee5820
AM
488 "% ", _("cumulative"), _("self "), "", _("self "), _("total "),
489 "");
252b5132
RH
490 printf ("%5.5s %9.9s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
491 _("time"), hist_dimension, hist_dimension, _("calls"), unit, unit,
492 _("name"));
493}
494
495
496static void
3e8f6abf 497print_line (Sym *sym, double scale)
252b5132
RH
498{
499 if (ignore_zeros && sym->ncalls == 0 && sym->hist.time == 0)
ef368dac 500 return;
252b5132
RH
501
502 accum_time += sym->hist.time;
0eee5820 503
252b5132 504 if (bsd_style_output)
ef368dac
NC
505 printf ("%5.1f %10.2f %8.2f",
506 total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
507 accum_time / hz, sym->hist.time / hz);
252b5132 508 else
ef368dac
NC
509 printf ("%6.2f %9.2f %8.2f",
510 total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
511 accum_time / hz, sym->hist.time / hz);
0eee5820 512
252b5132 513 if (sym->ncalls != 0)
ef368dac
NC
514 printf (" %8lu %8.2f %8.2f ",
515 sym->ncalls, scale * sym->hist.time / hz / sym->ncalls,
516 scale * (sym->hist.time + sym->cg.child_time) / hz / sym->ncalls);
252b5132 517 else
ef368dac 518 printf (" %8.8s %8.8s %8.8s ", "", "", "");
0eee5820 519
252b5132 520 if (bsd_style_output)
ef368dac 521 print_name (sym);
252b5132 522 else
ef368dac
NC
523 print_name_only (sym);
524
252b5132
RH
525 printf ("\n");
526}
527
528
ef368dac
NC
529/* Compare LP and RP. The primary comparison key is execution time,
530 the secondary is number of invocation, and the tertiary is the
531 lexicographic order of the function names. */
532
252b5132 533static int
3e8f6abf 534cmp_time (const PTR lp, const PTR rp)
252b5132
RH
535{
536 const Sym *left = *(const Sym **) lp;
537 const Sym *right = *(const Sym **) rp;
538 double time_diff;
539
540 time_diff = right->hist.time - left->hist.time;
0eee5820 541
252b5132 542 if (time_diff > 0.0)
ef368dac 543 return 1;
0eee5820 544
252b5132 545 if (time_diff < 0.0)
ef368dac 546 return -1;
252b5132
RH
547
548 if (right->ncalls > left->ncalls)
ef368dac
NC
549 return 1;
550
252b5132 551 if (right->ncalls < left->ncalls)
ef368dac 552 return -1;
252b5132
RH
553
554 return strcmp (left->name, right->name);
555}
556
557
ef368dac
NC
558/* Print the flat histogram profile. */
559
252b5132 560void
1355568a 561hist_print ()
252b5132
RH
562{
563 Sym **time_sorted_syms, *top_dog, *sym;
564 unsigned int index;
be5523fb 565 unsigned log_scale;
252b5132
RH
566 double top_time, time;
567 bfd_vma addr;
568
569 if (first_output)
b34976b6 570 first_output = FALSE;
252b5132 571 else
ef368dac 572 printf ("\f\n");
252b5132
RH
573
574 accum_time = 0.0;
0eee5820 575
252b5132
RH
576 if (bsd_style_output)
577 {
578 if (print_descriptions)
579 {
580 printf (_("\n\n\nflat profile:\n"));
581 flat_blurb (stdout);
582 }
583 }
584 else
585 {
586 printf (_("Flat profile:\n"));
587 }
0eee5820 588
ef368dac
NC
589 /* Sort the symbol table by time (call-count and name as secondary
590 and tertiary keys). */
252b5132 591 time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
0eee5820 592
252b5132 593 for (index = 0; index < symtab.len; ++index)
ef368dac
NC
594 time_sorted_syms[index] = &symtab.base[index];
595
252b5132
RH
596 qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time);
597
598 if (bsd_style_output)
599 {
ef368dac 600 log_scale = 5; /* Milli-seconds is BSD-default. */
252b5132
RH
601 }
602 else
603 {
ef368dac
NC
604 /* Search for symbol with highest per-call
605 execution time and scale accordingly. */
252b5132
RH
606 log_scale = 0;
607 top_dog = 0;
608 top_time = 0.0;
0eee5820 609
252b5132
RH
610 for (index = 0; index < symtab.len; ++index)
611 {
612 sym = time_sorted_syms[index];
0eee5820 613
252b5132
RH
614 if (sym->ncalls != 0)
615 {
616 time = (sym->hist.time + sym->cg.child_time) / sym->ncalls;
0eee5820 617
252b5132
RH
618 if (time > top_time)
619 {
620 top_dog = sym;
621 top_time = time;
622 }
623 }
624 }
0eee5820 625
252b5132
RH
626 if (top_dog && top_dog->ncalls != 0 && top_time > 0.0)
627 {
628 top_time /= hz;
0eee5820 629
be5523fb 630 for (log_scale = 0; log_scale < ARRAY_SIZE (SItab); log_scale ++)
252b5132 631 {
be5523fb
FCE
632 double scaled_value = SItab[log_scale].scale * top_time;
633
634 if (scaled_value >= 1.0 && scaled_value < 1000.0)
635 break;
252b5132
RH
636 }
637 }
638 }
639
ef368dac
NC
640 /* For now, the dimension is always seconds. In the future, we
641 may also want to support other (pseudo-)dimensions (such as
642 I-cache misses etc.). */
252b5132 643 print_header (SItab[log_scale].prefix);
0eee5820 644
252b5132
RH
645 for (index = 0; index < symtab.len; ++index)
646 {
647 addr = time_sorted_syms[index]->addr;
0eee5820 648
ef368dac 649 /* Print symbol if its in INCL_FLAT table or that table
0eee5820 650 is empty and the symbol is not in EXCL_FLAT. */
252b5132
RH
651 if (sym_lookup (&syms[INCL_FLAT], addr)
652 || (syms[INCL_FLAT].len == 0
653 && !sym_lookup (&syms[EXCL_FLAT], addr)))
ef368dac 654 print_line (time_sorted_syms[index], SItab[log_scale].scale);
252b5132 655 }
0eee5820 656
252b5132
RH
657 free (time_sorted_syms);
658
659 if (print_descriptions && !bsd_style_output)
ef368dac 660 flat_blurb (stdout);
252b5132 661}
b3296dc5
VP
662
663int
664hist_check_address (unsigned address)
665{
666 unsigned i;
667
668 for (i = 0; i < num_histograms; ++i)
669 if (histograms[i].lowpc <= address && address < histograms[i].highpc)
670 return 1;
671
672 return 0;
673}
674
675#if ! defined(min)
676#define min(a,b) (((a)<(b)) ? (a) : (b))
677#endif
678#if ! defined(max)
679#define max(a,b) (((a)>(b)) ? (a) : (b))
680#endif
681
682void
683hist_clip_symbol_address (bfd_vma *p_lowpc, bfd_vma *p_highpc)
684{
685 unsigned i;
686 int found = 0;
687
688 if (num_histograms == 0)
689 {
690 *p_highpc = *p_lowpc;
691 return;
692 }
693
694 for (i = 0; i < num_histograms; ++i)
695 {
696 bfd_vma common_low, common_high;
697 common_low = max (histograms[i].lowpc, *p_lowpc);
698 common_high = min (histograms[i].highpc, *p_highpc);
699
700 if (common_low < common_high)
701 {
702 if (found)
703 {
704 fprintf (stderr,
705 _("%s: found a symbol that covers "
e701ca86 706 "several histogram records"),
b3296dc5
VP
707 whoami);
708 done (1);
709 }
710
711 found = 1;
712 *p_lowpc = common_low;
713 *p_highpc = common_high;
714 }
715 }
716
717 if (!found)
718 *p_highpc = *p_lowpc;
719}
720
721/* Find and return exising histogram record having the same lowpc and
722 highpc as passed via the parameters. Return NULL if nothing is found.
723 The return value is valid until any new histogram is read. */
724static histogram *
725find_histogram (bfd_vma lowpc, bfd_vma highpc)
726{
727 unsigned i;
728 for (i = 0; i < num_histograms; ++i)
729 {
730 if (histograms[i].lowpc == lowpc && histograms[i].highpc == highpc)
731 return &histograms[i];
732 }
733 return 0;
734}
735
736/* Given a PC, return histogram record which address range include this PC.
737 Return NULL if there's no such record. */
738static histogram *
739find_histogram_for_pc (bfd_vma pc)
740{
741 unsigned i;
742 for (i = 0; i < num_histograms; ++i)
743 {
744 if (histograms[i].lowpc <= pc && pc < histograms[i].highpc)
745 return &histograms[i];
746 }
747 return 0;
748}
This page took 0.362898 seconds and 4 git commands to generate.