]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprof/gprof.c
* ld-discard/discard.exp, ld-scripts/phdrs.exp, ld-scripts/phdrs2.exp,
[thirdparty/binutils-gdb.git] / gprof / gprof.c
CommitLineData
0461a601
NC
1/* Copyright (c) 1983, 1998, 2001, 2002 Regents of the University of California.
2 All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice,
8 this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the University of California, Berkeley nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 THE POSSIBILITY OF SUCH DAMAGE. */
27
252b5132
RH
28#include "libiberty.h"
29#include "gprof.h"
6d9c411a
AM
30#include "search_list.h"
31#include "source.h"
32#include "symtab.h"
252b5132
RH
33#include "basic_blocks.h"
34#include "call_graph.h"
35#include "cg_arcs.h"
36#include "cg_print.h"
37#include "corefile.h"
38#include "gmon_io.h"
39#include "hertz.h"
40#include "hist.h"
252b5132 41#include "sym_ids.h"
28c309a2 42#include "demangle.h"
82fe033f 43#include "getopt.h"
252b5132 44
1355568a
AM
45static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
46int main PARAMS ((int, char **));
47
252b5132
RH
48const char *whoami;
49const char *function_mapping_file;
50const char *a_out_name = A_OUTNAME;
51long hz = HZ_WRONG;
52
53/*
54 * Default options values:
55 */
56int debug_level = 0;
57int output_style = 0;
58int output_width = 80;
bde52789
AM
59boolean bsd_style_output = false;
60boolean demangle = true;
61boolean discard_underscores = true;
62boolean ignore_direct_calls = false;
63boolean ignore_static_funcs = false;
64boolean ignore_zeros = true;
65boolean line_granularity = false;
66boolean print_descriptions = true;
67boolean print_path = false;
68boolean ignore_non_functions = false;
252b5132
RH
69File_Format file_format = FF_AUTO;
70
bde52789 71boolean first_output = true;
252b5132
RH
72
73char copyright[] =
ff096a7c
AO
74 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
75 All rights reserved.\n";
252b5132
RH
76
77static char *gmon_name = GMONNAME; /* profile filename */
78
79bfd *abfd;
80
81/*
82 * Functions that get excluded by default:
83 */
84static char *default_excluded_list[] =
85{
86 "_gprof_mcount", "mcount", "_mcount", "__mcount", "__mcount_internal",
87 "__mcleanup",
88 "<locore>", "<hicore>",
89 0
90};
91
92/* Codes used for the long options with no short synonyms. 150 isn't
93 special; it's just an arbitrary non-ASCII char value. */
94
95#define OPTION_DEMANGLE (150)
96#define OPTION_NO_DEMANGLE (OPTION_DEMANGLE + 1)
97
98static struct option long_options[] =
99{
100 {"line", no_argument, 0, 'l'},
101 {"no-static", no_argument, 0, 'a'},
102 {"ignore-non-functions", no_argument, 0, 'D'},
103
104 /* output styles: */
105
106 {"annotated-source", optional_argument, 0, 'A'},
107 {"no-annotated-source", optional_argument, 0, 'J'},
108 {"flat-profile", optional_argument, 0, 'p'},
109 {"no-flat-profile", optional_argument, 0, 'P'},
110 {"graph", optional_argument, 0, 'q'},
111 {"no-graph", optional_argument, 0, 'Q'},
112 {"exec-counts", optional_argument, 0, 'C'},
113 {"no-exec-counts", optional_argument, 0, 'Z'},
114 {"function-ordering", no_argument, 0, 'r'},
115 {"file-ordering", required_argument, 0, 'R'},
116 {"file-info", no_argument, 0, 'i'},
117 {"sum", no_argument, 0, 's'},
118
119 /* various options to affect output: */
120
121 {"all-lines", no_argument, 0, 'x'},
28c309a2 122 {"demangle", optional_argument, 0, OPTION_DEMANGLE},
252b5132
RH
123 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLE},
124 {"directory-path", required_argument, 0, 'I'},
125 {"display-unused-functions", no_argument, 0, 'z'},
126 {"min-count", required_argument, 0, 'm'},
127 {"print-path", no_argument, 0, 'L'},
128 {"separate-files", no_argument, 0, 'y'},
129 {"static-call-graph", no_argument, 0, 'c'},
130 {"table-length", required_argument, 0, 't'},
131 {"time", required_argument, 0, 'n'},
132 {"no-time", required_argument, 0, 'N'},
133 {"width", required_argument, 0, 'w'},
134 /*
135 * These are for backwards-compatibility only. Their functionality
136 * is provided by the output style options already:
137 */
138 {"", required_argument, 0, 'e'},
139 {"", required_argument, 0, 'E'},
140 {"", required_argument, 0, 'f'},
141 {"", required_argument, 0, 'F'},
142 {"", required_argument, 0, 'k'},
143
144 /* miscellaneous: */
145
146 {"brief", no_argument, 0, 'b'},
147 {"debug", optional_argument, 0, 'd'},
148 {"help", no_argument, 0, 'h'},
149 {"file-format", required_argument, 0, 'O'},
150 {"traditional", no_argument, 0, 'T'},
151 {"version", no_argument, 0, 'v'},
152 {0, no_argument, 0, 0}
153};
154
155
156static void
1355568a
AM
157usage (stream, status)
158 FILE *stream;
159 int status;
252b5132
RH
160{
161 fprintf (stream, _("\
162Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n\
163 [-d[num]] [-k from/to] [-m min-count] [-t table-length]\n\
164 [--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n\
165 [--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n\
166 [--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n\
167 [--function-ordering] [--file-ordering]\n\
168 [--directory-path=dirs] [--display-unused-functions]\n\
169 [--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n\
170 [--no-static] [--print-path] [--separate-files]\n\
171 [--static-call-graph] [--sum] [--table-length=len] [--traditional]\n\
172 [--version] [--width=n] [--ignore-non-functions]\n\
28c309a2 173 [--demangle[=STYLE]] [--no-demangle]\n\
252b5132
RH
174 [image-file] [profile-file...]\n"),
175 whoami);
176 if (status == 0)
8ad3436c 177 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
178 done (status);
179}
180
181
182int
1355568a
AM
183main (argc, argv)
184 int argc;
185 char **argv;
252b5132
RH
186{
187 char **sp, *str;
188 Sym **cg = 0;
189 int ch, user_specified = 0;
190
191#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
192 setlocale (LC_MESSAGES, "");
3882b010
L
193#endif
194#if defined (HAVE_SETLOCALE)
195 setlocale (LC_CTYPE, "");
252b5132
RH
196#endif
197 bindtextdomain (PACKAGE, LOCALEDIR);
198 textdomain (PACKAGE);
199
200 whoami = argv[0];
201 xmalloc_set_program_name (whoami);
202
203 while ((ch = getopt_long (argc, argv,
a799cbe2 204 "aA::bBcCd::De:E:f:F:hiI:J::k:lLm:n::N::O:p::P::q::Q::st:Tvw:xyzZ::",
252b5132
RH
205 long_options, 0))
206 != EOF)
207 {
208 switch (ch)
209 {
210 case 'a':
bde52789 211 ignore_static_funcs = true;
252b5132
RH
212 break;
213 case 'A':
214 if (optarg)
215 {
216 sym_id_add (optarg, INCL_ANNO);
217 }
218 output_style |= STYLE_ANNOTATED_SOURCE;
219 user_specified |= STYLE_ANNOTATED_SOURCE;
220 break;
221 case 'b':
bde52789 222 print_descriptions = false;
252b5132
RH
223 break;
224 case 'B':
225 output_style |= STYLE_CALL_GRAPH;
226 user_specified |= STYLE_CALL_GRAPH;
227 break;
228 case 'c':
bde52789 229 ignore_direct_calls = true;
252b5132
RH
230 break;
231 case 'C':
232 if (optarg)
233 {
234 sym_id_add (optarg, INCL_EXEC);
235 }
236 output_style |= STYLE_EXEC_COUNTS;
237 user_specified |= STYLE_EXEC_COUNTS;
238 break;
239 case 'd':
240 if (optarg)
241 {
242 debug_level |= atoi (optarg);
243 debug_level |= ANYDEBUG;
244 }
245 else
246 {
247 debug_level = ~0;
248 }
249 DBG (ANYDEBUG, printf ("[main] debug-level=0x%x\n", debug_level));
250#ifndef DEBUG
251 printf (_("%s: debugging not supported; -d ignored\n"), whoami);
252#endif /* DEBUG */
253 break;
254 case 'D':
bde52789 255 ignore_non_functions = true;
252b5132
RH
256 break;
257 case 'E':
258 sym_id_add (optarg, EXCL_TIME);
259 case 'e':
260 sym_id_add (optarg, EXCL_GRAPH);
261 break;
262 case 'F':
263 sym_id_add (optarg, INCL_TIME);
264 case 'f':
265 sym_id_add (optarg, INCL_GRAPH);
266 break;
267 case 'g':
268 sym_id_add (optarg, EXCL_FLAT);
269 break;
270 case 'G':
271 sym_id_add (optarg, INCL_FLAT);
272 break;
273 case 'h':
274 usage (stdout, 0);
275 case 'i':
276 output_style |= STYLE_GMON_INFO;
277 user_specified |= STYLE_GMON_INFO;
278 break;
279 case 'I':
280 search_list_append (&src_search_list, optarg);
281 break;
282 case 'J':
283 if (optarg)
284 {
285 sym_id_add (optarg, EXCL_ANNO);
286 output_style |= STYLE_ANNOTATED_SOURCE;
287 }
288 else
289 {
290 output_style &= ~STYLE_ANNOTATED_SOURCE;
291 }
292 user_specified |= STYLE_ANNOTATED_SOURCE;
293 break;
294 case 'k':
295 sym_id_add (optarg, EXCL_ARCS);
296 break;
297 case 'l':
bde52789 298 line_granularity = true;
252b5132
RH
299 break;
300 case 'L':
bde52789 301 print_path = true;
252b5132
RH
302 break;
303 case 'm':
304 bb_min_calls = (unsigned long) strtoul (optarg, (char **) NULL, 10);
305 break;
306 case 'n':
307 sym_id_add (optarg, INCL_TIME);
308 break;
309 case 'N':
310 sym_id_add (optarg, EXCL_TIME);
311 break;
312 case 'O':
313 switch (optarg[0])
314 {
315 case 'a':
316 file_format = FF_AUTO;
317 break;
318 case 'm':
319 file_format = FF_MAGIC;
320 break;
321 case 'b':
322 file_format = FF_BSD;
323 break;
324 case '4':
325 file_format = FF_BSD44;
326 break;
327 case 'p':
328 file_format = FF_PROF;
329 break;
330 default:
331 fprintf (stderr, _("%s: unknown file format %s\n"),
332 optarg, whoami);
333 done (1);
334 }
335 break;
336 case 'p':
337 if (optarg)
338 {
339 sym_id_add (optarg, INCL_FLAT);
340 }
341 output_style |= STYLE_FLAT_PROFILE;
342 user_specified |= STYLE_FLAT_PROFILE;
343 break;
344 case 'P':
345 if (optarg)
346 {
347 sym_id_add (optarg, EXCL_FLAT);
348 output_style |= STYLE_FLAT_PROFILE;
349 }
350 else
351 {
352 output_style &= ~STYLE_FLAT_PROFILE;
353 }
354 user_specified |= STYLE_FLAT_PROFILE;
355 break;
356 case 'q':
357 if (optarg)
358 {
359 if (strchr (optarg, '/'))
360 {
361 sym_id_add (optarg, INCL_ARCS);
362 }
363 else
364 {
365 sym_id_add (optarg, INCL_GRAPH);
366 }
367 }
368 output_style |= STYLE_CALL_GRAPH;
369 user_specified |= STYLE_CALL_GRAPH;
370 break;
371 case 'r':
372 output_style |= STYLE_FUNCTION_ORDER;
373 user_specified |= STYLE_FUNCTION_ORDER;
374 break;
375 case 'R':
376 output_style |= STYLE_FILE_ORDER;
377 user_specified |= STYLE_FILE_ORDER;
378 function_mapping_file = optarg;
379 break;
380 case 'Q':
381 if (optarg)
382 {
383 if (strchr (optarg, '/'))
384 {
385 sym_id_add (optarg, EXCL_ARCS);
386 }
387 else
388 {
389 sym_id_add (optarg, EXCL_GRAPH);
390 }
391 output_style |= STYLE_CALL_GRAPH;
392 }
393 else
394 {
395 output_style &= ~STYLE_CALL_GRAPH;
396 }
397 user_specified |= STYLE_CALL_GRAPH;
398 break;
399 case 's':
400 output_style |= STYLE_SUMMARY_FILE;
401 user_specified |= STYLE_SUMMARY_FILE;
402 break;
403 case 't':
404 bb_table_length = atoi (optarg);
405 if (bb_table_length < 0)
406 {
407 bb_table_length = 0;
408 }
409 break;
410 case 'T':
bde52789 411 bsd_style_output = true;
252b5132
RH
412 break;
413 case 'v':
414 /* This output is intended to follow the GNU standards document. */
415 printf (_("GNU gprof %s\n"), VERSION);
416 printf (_("Based on BSD gprof, copyright 1983 Regents of the University of California.\n"));
417 printf (_("\
418This program is free software. This program has absolutely no warranty.\n"));
419 done (0);
420 case 'w':
421 output_width = atoi (optarg);
422 if (output_width < 1)
423 {
424 output_width = 1;
425 }
426 break;
427 case 'x':
bde52789 428 bb_annotate_all_lines = true;
252b5132
RH
429 break;
430 case 'y':
bde52789 431 create_annotation_files = true;
252b5132
RH
432 break;
433 case 'z':
bde52789 434 ignore_zeros = false;
252b5132
RH
435 break;
436 case 'Z':
437 if (optarg)
438 {
439 sym_id_add (optarg, EXCL_EXEC);
440 output_style |= STYLE_EXEC_COUNTS;
441 }
442 else
443 {
444 output_style &= ~STYLE_EXEC_COUNTS;
445 }
446 user_specified |= STYLE_ANNOTATED_SOURCE;
447 break;
448 case OPTION_DEMANGLE:
bde52789 449 demangle = true;
28c309a2
NC
450 if (optarg != NULL)
451 {
452 enum demangling_styles style;
0eee5820 453
28c309a2 454 style = cplus_demangle_name_to_style (optarg);
0eee5820 455 if (style == unknown_demangling)
28c309a2
NC
456 {
457 fprintf (stderr,
458 _("%s: unknown demangling style `%s'\n"),
459 whoami, optarg);
460 xexit (1);
461 }
0eee5820 462
28c309a2 463 cplus_demangle_set_style (style);
0eee5820 464 }
252b5132
RH
465 break;
466 case OPTION_NO_DEMANGLE:
bde52789 467 demangle = false;
252b5132
RH
468 break;
469 default:
470 usage (stderr, 1);
471 }
472 }
473
474 /* Don't allow both ordering options, they modify the arc data in-place. */
475 if ((user_specified & STYLE_FUNCTION_ORDER)
476 && (user_specified & STYLE_FILE_ORDER))
477 {
478 fprintf (stderr,_("\
479%s: Only one of --function-ordering and --file-ordering may be specified.\n"),
480 whoami);
481 done (1);
482 }
483
484 /* --sum implies --line, otherwise we'd lose b-b counts in gmon.sum */
485 if (output_style & STYLE_SUMMARY_FILE)
486 {
487 line_granularity = 1;
488 }
489
490 /* append value of GPROF_PATH to source search list if set: */
491 str = (char *) getenv ("GPROF_PATH");
492 if (str)
493 {
494 search_list_append (&src_search_list, str);
495 }
496
497 if (optind < argc)
498 {
499 a_out_name = argv[optind++];
500 }
501 if (optind < argc)
502 {
503 gmon_name = argv[optind++];
504 }
505
506 /*
507 * Turn off default functions:
508 */
509 for (sp = &default_excluded_list[0]; *sp; sp++)
510 {
511 sym_id_add (*sp, EXCL_TIME);
512 sym_id_add (*sp, EXCL_GRAPH);
513#ifdef __alpha__
514 sym_id_add (*sp, EXCL_FLAT);
515#endif
516 }
517
518 /*
519 * For line-by-line profiling, also want to keep those
520 * functions off the flat profile:
521 */
522 if (line_granularity)
523 {
524 for (sp = &default_excluded_list[0]; *sp; sp++)
525 {
526 sym_id_add (*sp, EXCL_FLAT);
527 }
528 }
529
530 /*
531 * Read symbol table from core file:
532 */
533 core_init (a_out_name);
534
535 /*
536 * If we should ignore direct function calls, we need to load
537 * to core's text-space:
538 */
539 if (ignore_direct_calls)
540 {
541 core_get_text_space (core_bfd);
542 }
543
544 /*
545 * Create symbols from core image:
546 */
547 if (line_granularity)
548 {
549 core_create_line_syms (core_bfd);
550 }
551 else
552 {
553 core_create_function_syms (core_bfd);
554 }
555
556 /*
557 * Translate sym specs into syms:
558 */
559 sym_id_parse ();
560
561 if (file_format == FF_PROF)
562 {
563#ifdef PROF_SUPPORT_IMPLEMENTED
564 /*
565 * Get information about mon.out file(s):
566 */
567 do
568 {
569 mon_out_read (gmon_name);
570 if (optind < argc)
571 {
572 gmon_name = argv[optind];
573 }
574 }
575 while (optind++ < argc);
576#else
577 fprintf (stderr,
578 _("%s: sorry, file format `prof' is not yet supported\n"),
579 whoami);
580 done (1);
581#endif
582 }
583 else
584 {
585 /*
586 * Get information about gmon.out file(s):
587 */
588 do
589 {
590 gmon_out_read (gmon_name);
591 if (optind < argc)
592 {
593 gmon_name = argv[optind];
594 }
595 }
596 while (optind++ < argc);
597 }
598
599 /*
600 * If user did not specify output style, try to guess something
601 * reasonable:
602 */
603 if (output_style == 0)
604 {
605 if (gmon_input & (INPUT_HISTOGRAM | INPUT_CALL_GRAPH))
606 {
607 output_style = STYLE_FLAT_PROFILE | STYLE_CALL_GRAPH;
608 }
609 else
610 {
611 output_style = STYLE_EXEC_COUNTS;
612 }
613 output_style &= ~user_specified;
614 }
615
616 /*
617 * Dump a gmon.sum file if requested (before any other processing!):
618 */
619 if (output_style & STYLE_SUMMARY_FILE)
620 {
621 gmon_out_write (GMONSUM);
622 }
623
624 if (gmon_input & INPUT_HISTOGRAM)
625 {
626 hist_assign_samples ();
627 }
628
629 if (gmon_input & INPUT_CALL_GRAPH)
630 {
631 cg = cg_assemble ();
632 }
633
634 /* do some simple sanity checks: */
635
636 if ((output_style & STYLE_FLAT_PROFILE)
637 && !(gmon_input & INPUT_HISTOGRAM))
638 {
639 fprintf (stderr, _("%s: gmon.out file is missing histogram\n"), whoami);
640 done (1);
641 }
642
643 if ((output_style & STYLE_CALL_GRAPH) && !(gmon_input & INPUT_CALL_GRAPH))
644 {
645 fprintf (stderr,
646 _("%s: gmon.out file is missing call-graph data\n"), whoami);
647 done (1);
648 }
649
650 /* output whatever user whishes to see: */
651
652 if (cg && (output_style & STYLE_CALL_GRAPH) && bsd_style_output)
653 {
654 cg_print (cg); /* print the dynamic profile */
655 }
656
657 if (output_style & STYLE_FLAT_PROFILE)
658 {
659 hist_print (); /* print the flat profile */
660 }
661
662 if (cg && (output_style & STYLE_CALL_GRAPH))
663 {
664 if (!bsd_style_output)
665 {
666 cg_print (cg); /* print the dynamic profile */
667 }
668 cg_print_index ();
669 }
670
671 if (output_style & STYLE_EXEC_COUNTS)
672 {
673 print_exec_counts ();
674 }
675
676 if (output_style & STYLE_ANNOTATED_SOURCE)
677 {
678 print_annotated_source ();
679 }
680 if (output_style & STYLE_FUNCTION_ORDER)
681 {
682 cg_print_function_ordering ();
683 }
684 if (output_style & STYLE_FILE_ORDER)
685 {
686 cg_print_file_ordering ();
687 }
688 return 0;
689}
690
691void
692done (status)
693 int status;
694{
695 exit (status);
696}