1 /* Copyright (c) 1983, 1998, 2001, 2002 Regents of the University of California.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
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.
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. */
28 #include "libiberty.h"
30 #include "search_list.h"
33 #include "basic_blocks.h"
34 #include "call_graph.h"
45 static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
46 int main PARAMS ((int, char **));
49 const char *function_mapping_file;
50 const char *a_out_name = A_OUTNAME;
54 * Default options values:
58 int output_width = 80;
59 boolean bsd_style_output = false;
60 boolean demangle = true;
61 boolean discard_underscores = true;
62 boolean ignore_direct_calls = false;
63 boolean ignore_static_funcs = false;
64 boolean ignore_zeros = true;
65 boolean line_granularity = false;
66 boolean print_descriptions = true;
67 boolean print_path = false;
68 boolean ignore_non_functions = false;
69 File_Format file_format = FF_AUTO;
71 boolean first_output = true;
74 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
75 All rights reserved.\n";
77 static char *gmon_name = GMONNAME; /* profile filename */
82 * Functions that get excluded by default:
84 static char *default_excluded_list[] =
86 "_gprof_mcount", "mcount", "_mcount", "__mcount", "__mcount_internal",
88 "<locore>", "<hicore>",
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. */
95 #define OPTION_DEMANGLE (150)
96 #define OPTION_NO_DEMANGLE (OPTION_DEMANGLE + 1)
98 static struct option long_options[] =
100 {"line", no_argument, 0, 'l'},
101 {"no-static", no_argument, 0, 'a'},
102 {"ignore-non-functions", no_argument, 0, 'D'},
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'},
119 /* various options to affect output: */
121 {"all-lines", no_argument, 0, 'x'},
122 {"demangle", optional_argument, 0, OPTION_DEMANGLE},
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'},
135 * These are for backwards-compatibility only. Their functionality
136 * is provided by the output style options already:
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'},
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}
157 usage (stream, status)
161 fprintf (stream, _("\
162 Usage: %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\
173 [--demangle[=STYLE]] [--no-demangle]\n\
174 [image-file] [profile-file...]\n"),
177 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
189 int ch, user_specified = 0;
191 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
192 setlocale (LC_MESSAGES, "");
194 #if defined (HAVE_SETLOCALE)
195 setlocale (LC_CTYPE, "");
197 bindtextdomain (PACKAGE, LOCALEDIR);
198 textdomain (PACKAGE);
201 xmalloc_set_program_name (whoami);
203 while ((ch = getopt_long (argc, argv,
204 "aA::bBcCd::De:E:f:F:hiI:J::k:lLm:n::N::O:p::P::q::Q::st:Tvw:xyzZ::",
211 ignore_static_funcs = true;
216 sym_id_add (optarg, INCL_ANNO);
218 output_style |= STYLE_ANNOTATED_SOURCE;
219 user_specified |= STYLE_ANNOTATED_SOURCE;
222 print_descriptions = false;
225 output_style |= STYLE_CALL_GRAPH;
226 user_specified |= STYLE_CALL_GRAPH;
229 ignore_direct_calls = true;
234 sym_id_add (optarg, INCL_EXEC);
236 output_style |= STYLE_EXEC_COUNTS;
237 user_specified |= STYLE_EXEC_COUNTS;
242 debug_level |= atoi (optarg);
243 debug_level |= ANYDEBUG;
249 DBG (ANYDEBUG, printf ("[main] debug-level=0x%x\n", debug_level));
251 printf (_("%s: debugging not supported; -d ignored\n"), whoami);
255 ignore_non_functions = true;
258 sym_id_add (optarg, EXCL_TIME);
260 sym_id_add (optarg, EXCL_GRAPH);
263 sym_id_add (optarg, INCL_TIME);
265 sym_id_add (optarg, INCL_GRAPH);
268 sym_id_add (optarg, EXCL_FLAT);
271 sym_id_add (optarg, INCL_FLAT);
276 output_style |= STYLE_GMON_INFO;
277 user_specified |= STYLE_GMON_INFO;
280 search_list_append (&src_search_list, optarg);
285 sym_id_add (optarg, EXCL_ANNO);
286 output_style |= STYLE_ANNOTATED_SOURCE;
290 output_style &= ~STYLE_ANNOTATED_SOURCE;
292 user_specified |= STYLE_ANNOTATED_SOURCE;
295 sym_id_add (optarg, EXCL_ARCS);
298 line_granularity = true;
304 bb_min_calls = (unsigned long) strtoul (optarg, (char **) NULL, 10);
307 sym_id_add (optarg, INCL_TIME);
310 sym_id_add (optarg, EXCL_TIME);
316 file_format = FF_AUTO;
319 file_format = FF_MAGIC;
322 file_format = FF_BSD;
325 file_format = FF_BSD44;
328 file_format = FF_PROF;
331 fprintf (stderr, _("%s: unknown file format %s\n"),
339 sym_id_add (optarg, INCL_FLAT);
341 output_style |= STYLE_FLAT_PROFILE;
342 user_specified |= STYLE_FLAT_PROFILE;
347 sym_id_add (optarg, EXCL_FLAT);
348 output_style |= STYLE_FLAT_PROFILE;
352 output_style &= ~STYLE_FLAT_PROFILE;
354 user_specified |= STYLE_FLAT_PROFILE;
359 if (strchr (optarg, '/'))
361 sym_id_add (optarg, INCL_ARCS);
365 sym_id_add (optarg, INCL_GRAPH);
368 output_style |= STYLE_CALL_GRAPH;
369 user_specified |= STYLE_CALL_GRAPH;
372 output_style |= STYLE_FUNCTION_ORDER;
373 user_specified |= STYLE_FUNCTION_ORDER;
376 output_style |= STYLE_FILE_ORDER;
377 user_specified |= STYLE_FILE_ORDER;
378 function_mapping_file = optarg;
383 if (strchr (optarg, '/'))
385 sym_id_add (optarg, EXCL_ARCS);
389 sym_id_add (optarg, EXCL_GRAPH);
391 output_style |= STYLE_CALL_GRAPH;
395 output_style &= ~STYLE_CALL_GRAPH;
397 user_specified |= STYLE_CALL_GRAPH;
400 output_style |= STYLE_SUMMARY_FILE;
401 user_specified |= STYLE_SUMMARY_FILE;
404 bb_table_length = atoi (optarg);
405 if (bb_table_length < 0)
411 bsd_style_output = true;
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"));
418 This program is free software. This program has absolutely no warranty.\n"));
421 output_width = atoi (optarg);
422 if (output_width < 1)
428 bb_annotate_all_lines = true;
431 create_annotation_files = true;
434 ignore_zeros = false;
439 sym_id_add (optarg, EXCL_EXEC);
440 output_style |= STYLE_EXEC_COUNTS;
444 output_style &= ~STYLE_EXEC_COUNTS;
446 user_specified |= STYLE_ANNOTATED_SOURCE;
448 case OPTION_DEMANGLE:
452 enum demangling_styles style;
454 style = cplus_demangle_name_to_style (optarg);
455 if (style == unknown_demangling)
458 _("%s: unknown demangling style `%s'\n"),
463 cplus_demangle_set_style (style);
466 case OPTION_NO_DEMANGLE:
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))
479 %s: Only one of --function-ordering and --file-ordering may be specified.\n"),
484 /* --sum implies --line, otherwise we'd lose b-b counts in gmon.sum */
485 if (output_style & STYLE_SUMMARY_FILE)
487 line_granularity = 1;
490 /* append value of GPROF_PATH to source search list if set: */
491 str = (char *) getenv ("GPROF_PATH");
494 search_list_append (&src_search_list, str);
499 a_out_name = argv[optind++];
503 gmon_name = argv[optind++];
507 * Turn off default functions:
509 for (sp = &default_excluded_list[0]; *sp; sp++)
511 sym_id_add (*sp, EXCL_TIME);
512 sym_id_add (*sp, EXCL_GRAPH);
514 sym_id_add (*sp, EXCL_FLAT);
519 * For line-by-line profiling, also want to keep those
520 * functions off the flat profile:
522 if (line_granularity)
524 for (sp = &default_excluded_list[0]; *sp; sp++)
526 sym_id_add (*sp, EXCL_FLAT);
531 * Read symbol table from core file:
533 core_init (a_out_name);
536 * If we should ignore direct function calls, we need to load
537 * to core's text-space:
539 if (ignore_direct_calls)
541 core_get_text_space (core_bfd);
545 * Create symbols from core image:
547 if (line_granularity)
549 core_create_line_syms (core_bfd);
553 core_create_function_syms (core_bfd);
557 * Translate sym specs into syms:
561 if (file_format == FF_PROF)
563 #ifdef PROF_SUPPORT_IMPLEMENTED
565 * Get information about mon.out file(s):
569 mon_out_read (gmon_name);
572 gmon_name = argv[optind];
575 while (optind++ < argc);
578 _("%s: sorry, file format `prof' is not yet supported\n"),
586 * Get information about gmon.out file(s):
590 gmon_out_read (gmon_name);
593 gmon_name = argv[optind];
596 while (optind++ < argc);
600 * If user did not specify output style, try to guess something
603 if (output_style == 0)
605 if (gmon_input & (INPUT_HISTOGRAM | INPUT_CALL_GRAPH))
607 output_style = STYLE_FLAT_PROFILE | STYLE_CALL_GRAPH;
611 output_style = STYLE_EXEC_COUNTS;
613 output_style &= ~user_specified;
617 * Dump a gmon.sum file if requested (before any other processing!):
619 if (output_style & STYLE_SUMMARY_FILE)
621 gmon_out_write (GMONSUM);
624 if (gmon_input & INPUT_HISTOGRAM)
626 hist_assign_samples ();
629 if (gmon_input & INPUT_CALL_GRAPH)
634 /* do some simple sanity checks: */
636 if ((output_style & STYLE_FLAT_PROFILE)
637 && !(gmon_input & INPUT_HISTOGRAM))
639 fprintf (stderr, _("%s: gmon.out file is missing histogram\n"), whoami);
643 if ((output_style & STYLE_CALL_GRAPH) && !(gmon_input & INPUT_CALL_GRAPH))
646 _("%s: gmon.out file is missing call-graph data\n"), whoami);
650 /* output whatever user whishes to see: */
652 if (cg && (output_style & STYLE_CALL_GRAPH) && bsd_style_output)
654 cg_print (cg); /* print the dynamic profile */
657 if (output_style & STYLE_FLAT_PROFILE)
659 hist_print (); /* print the flat profile */
662 if (cg && (output_style & STYLE_CALL_GRAPH))
664 if (!bsd_style_output)
666 cg_print (cg); /* print the dynamic profile */
671 if (output_style & STYLE_EXEC_COUNTS)
673 print_exec_counts ();
676 if (output_style & STYLE_ANNOTATED_SOURCE)
678 print_annotated_source ();
680 if (output_style & STYLE_FUNCTION_ORDER)
682 cg_print_function_ordering ();
684 if (output_style & STYLE_FILE_ORDER)
686 cg_print_file_ordering ();