update translations.
[deliverable/binutils-gdb.git] / gprof / gprof.c
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
28 #include "libiberty.h"
29 #include "gprof.h"
30 #include "search_list.h"
31 #include "source.h"
32 #include "symtab.h"
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"
41 #include "sym_ids.h"
42 #include "demangle.h"
43 #include "getopt.h"
44
45 static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
46 int main PARAMS ((int, char **));
47
48 const char *whoami;
49 const char *function_mapping_file;
50 const char *a_out_name = A_OUTNAME;
51 long hz = HZ_WRONG;
52
53 /*
54 * Default options values:
55 */
56 int debug_level = 0;
57 int output_style = 0;
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;
70
71 boolean first_output = true;
72
73 char copyright[] =
74 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
75 All rights reserved.\n";
76
77 static char *gmon_name = GMONNAME; /* profile filename */
78
79 bfd *abfd;
80
81 /*
82 * Functions that get excluded by default:
83 */
84 static 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
98 static 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'},
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'},
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
156 static void
157 usage (stream, status)
158 FILE *stream;
159 int status;
160 {
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"),
175 whoami);
176 if (status == 0)
177 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
178 done (status);
179 }
180
181
182 int
183 main (argc, argv)
184 int argc;
185 char **argv;
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, "");
193 #endif
194 #if defined (HAVE_SETLOCALE)
195 setlocale (LC_CTYPE, "");
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,
204 "aA::bBcCd::De:E:f:F:hiI:J::k:lLm:n::N::O:p::P::q::Q::st:Tvw:xyzZ::",
205 long_options, 0))
206 != EOF)
207 {
208 switch (ch)
209 {
210 case 'a':
211 ignore_static_funcs = true;
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':
222 print_descriptions = false;
223 break;
224 case 'B':
225 output_style |= STYLE_CALL_GRAPH;
226 user_specified |= STYLE_CALL_GRAPH;
227 break;
228 case 'c':
229 ignore_direct_calls = true;
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':
255 ignore_non_functions = true;
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':
298 line_granularity = true;
299 break;
300 case 'L':
301 print_path = true;
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':
411 bsd_style_output = true;
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 (_("\
418 This 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':
428 bb_annotate_all_lines = true;
429 break;
430 case 'y':
431 create_annotation_files = true;
432 break;
433 case 'z':
434 ignore_zeros = false;
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:
449 demangle = true;
450 if (optarg != NULL)
451 {
452 enum demangling_styles style;
453
454 style = cplus_demangle_name_to_style (optarg);
455 if (style == unknown_demangling)
456 {
457 fprintf (stderr,
458 _("%s: unknown demangling style `%s'\n"),
459 whoami, optarg);
460 xexit (1);
461 }
462
463 cplus_demangle_set_style (style);
464 }
465 break;
466 case OPTION_NO_DEMANGLE:
467 demangle = false;
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
691 void
692 done (status)
693 int status;
694 {
695 exit (status);
696 }
This page took 0.043622 seconds and 5 git commands to generate.