update translations.
[external/binutils.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 }