* Makefile.in (maintainer-clean): New target, synonym for
[deliverable/binutils-gdb.git] / gprof / gprof.c
CommitLineData
3d6c6501
SEF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that: (1) source distributions retain this entire copyright
7 * notice and comment, and (2) distributions including binaries display
8 * the following acknowledgement: ``This product includes software
9 * developed by the University of California, Berkeley and its contributors''
10 * in the documentation or other materials provided with the distribution
11 * and in all advertising materials mentioning features or use of this
12 * software. Neither the name of the University nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
5489fcc3
KR
19#include "getopt.h"
20#include "libiberty.h"
21#include "gprof.h"
22#include "basic_blocks.h"
23#include "call_graph.h"
24#include "cg_arcs.h"
25#include "cg_print.h"
26#include "core.h"
27#include "gmon_io.h"
28#include "hertz.h"
29#include "hist.h"
30#include "source.h"
31#include "sym_ids.h"
32
33#define VERSION "2.6"
34
35const char *whoami;
36const char *a_out_name = A_OUTNAME;
37long hz = HZ_WRONG;
3d6c6501 38
5489fcc3
KR
39/*
40 * Default options values:
41 */
42int debug_level = 0;
43int output_style = 0;
44int output_width = 80;
45bool bsd_style_output = FALSE;
46bool discard_underscores = TRUE;
47bool ignore_direct_calls = FALSE;
48bool ignore_static_funcs = FALSE;
49bool ignore_zeros = TRUE;
50bool line_granularity = FALSE;
51bool print_descriptions = TRUE;
52bool print_path = FALSE;
53File_Format file_format = FF_AUTO;
54
55bool first_output = TRUE;
b4f476e9 56
3d6c6501
SEF
57char copyright[] =
58"@(#) Copyright (c) 1983 Regents of the University of California.\n\
59 All rights reserved.\n";
3d6c6501 60
12516a37 61static char *gmon_name = GMONNAME; /* profile filename */
c06e55d9 62
12516a37 63bfd *abfd;
77c9b2c3 64
5489fcc3
KR
65/*
66 * Functions that get excluded by default:
67 */
12516a37
KR
68static char *default_excluded_list[] =
69{
70 "_gprof_mcount", "mcount", "_mcount", "__mcleanup",
71 "<locore>", "<hicore>",
72 0
5489fcc3 73};
3d6c6501 74
5489fcc3
KR
75static struct option long_options[] =
76{
12516a37
KR
77 {"line", no_argument, 0, 'l'},
78 {"no-static", no_argument, 0, 'a'},
5489fcc3
KR
79
80 /* output styles: */
81
12516a37
KR
82 {"annotated-source", optional_argument, 0, 'A'},
83 {"no-annotated-source", optional_argument, 0, 'J'},
84 {"flat-profile", optional_argument, 0, 'p'},
85 {"no-flat-profile", optional_argument, 0, 'P'},
86 {"graph", optional_argument, 0, 'q'},
87 {"no-graph", optional_argument, 0, 'Q'},
88 {"exec-counts", optional_argument, 0, 'C'},
89 {"no-exec-counts", optional_argument, 0, 'Z'},
90 {"file-info", no_argument, 0, 'i'},
91 {"sum", no_argument, 0, 's'},
5489fcc3
KR
92
93 /* various options to affect output: */
94
12516a37
KR
95 {"all-lines", no_argument, 0, 'x'},
96 {"directory-path", required_argument, 0, 'I'},
97 {"display-unused-functions", no_argument, 0, 'z'},
98 {"min-count", required_argument, 0, 'm'},
99 {"print-path", no_argument, 0, 'L'},
100 {"separate-files", no_argument, 0, 'y'},
101 {"static-call-graph", no_argument, 0, 'c'},
102 {"table-length", required_argument, 0, 't'},
103 {"time", required_argument, 0, 'n'},
104 {"no-time", required_argument, 0, 'N'},
105 {"width", required_argument, 0, 'w'},
3d6c6501 106 /*
5489fcc3
KR
107 * These are for backwards-compatibility only. Their functionality
108 * is provided by the output style options already:
3d6c6501 109 */
12516a37
KR
110 {"", required_argument, 0, 'e'},
111 {"", required_argument, 0, 'E'},
112 {"", required_argument, 0, 'f'},
113 {"", required_argument, 0, 'F'},
114 {"", required_argument, 0, 'k'},
5489fcc3
KR
115
116 /* miscellaneous: */
117
12516a37
KR
118 {"brief", no_argument, 0, 'b'},
119 {"debug", optional_argument, 0, 'd'},
120 {"help", no_argument, 0, 'h'},
121 {"file-format", required_argument, 0, 'O'},
122 {"traditional", no_argument, 0, 'T'},
123 {"version", no_argument, 0, 'v'},
124 {0, no_argument, 0, 0}
5489fcc3
KR
125};
126
127
128static void
12516a37 129DEFUN (usage, (stream, status), FILE * stream AND int status)
5489fcc3 130{
12516a37 131 fprintf (stream, "\
5489fcc3
KR
132Usage: %s [-[abchilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n\
133 [-d[num]] [-k from/to] [-m min-count] [-t table-length]\n\
134 [--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n\
135 [--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n\
136 [--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n\
137 [--directory-path=dirs] [--display-unused-functions]\n\
138 [--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n\
139 [--no-static] [--print-path] [--separate-files]\n\
140 [--static-call-graph] [--sum] [--table-length=len] [--traditional]\n\
141 [--version] [--width=n]\n\
142 [image-file] [profile-file...]\n",
12516a37
KR
143 whoami);
144 done (status);
03c35bcb 145}
5489fcc3
KR
146
147
148int
12516a37 149DEFUN (main, (argc, argv), int argc AND char **argv)
3d6c6501 150{
12516a37
KR
151 char **sp, *str;
152 Sym **cg = 0;
153 int ch, user_specified = 0;
3d6c6501 154
12516a37
KR
155 whoami = argv[0];
156 xmalloc_set_program_name (whoami);
5489fcc3 157
12516a37
KR
158 while ((ch = getopt_long (argc, argv,
159 "aA::bBcCd::e:E:f:F:hiI:J::k:lLm:n::N::O:p::P::q::Q::st:Tvw:xyzZ::",
160 long_options, 0))
161 != EOF)
5489fcc3 162 {
12516a37
KR
163 switch (ch)
164 {
165 case 'a':
166 ignore_static_funcs = TRUE;
167 break;
168 case 'A':
169 if (optarg)
170 {
171 sym_id_add (optarg, INCL_ANNO);
03c35bcb 172 }
12516a37
KR
173 output_style |= STYLE_ANNOTATED_SOURCE;
174 user_specified |= STYLE_ANNOTATED_SOURCE;
175 break;
176 case 'b':
177 print_descriptions = FALSE;
178 break;
179 case 'B':
180 output_style |= STYLE_CALL_GRAPH;
181 user_specified |= STYLE_CALL_GRAPH;
182 break;
183 case 'c':
184 ignore_direct_calls = TRUE;
185 break;
186 case 'C':
187 if (optarg)
188 {
189 sym_id_add (optarg, INCL_EXEC);
03c35bcb 190 }
12516a37
KR
191 output_style |= STYLE_EXEC_COUNTS;
192 user_specified |= STYLE_EXEC_COUNTS;
193 break;
194 case 'd':
195 if (optarg)
196 {
197 debug_level |= atoi (optarg);
198 debug_level |= ANYDEBUG;
199 }
200 else
201 {
202 debug_level = ~0;
03c35bcb 203 }
12516a37 204 DBG (ANYDEBUG, printf ("[main] debug-level=0x%x\n", debug_level));
5489fcc3 205#ifndef DEBUG
12516a37
KR
206 printf ("%s: debugging not supported; -d ignored\n", whoami);
207#endif /* DEBUG */
208 break;
209 case 'E':
210 sym_id_add (optarg, EXCL_TIME);
211 case 'e':
212 sym_id_add (optarg, EXCL_GRAPH);
213 break;
214 case 'F':
215 sym_id_add (optarg, INCL_TIME);
216 case 'f':
217 sym_id_add (optarg, INCL_GRAPH);
218 break;
219 case 'g':
220 sym_id_add (optarg, EXCL_FLAT);
221 break;
222 case 'G':
223 sym_id_add (optarg, INCL_FLAT);
224 break;
225 case 'h':
226 usage (stdout, 0);
227 case 'i':
228 output_style |= STYLE_GMON_INFO;
229 user_specified |= STYLE_GMON_INFO;
230 break;
231 case 'I':
232 search_list_append (&src_search_list, optarg);
233 break;
234 case 'J':
235 if (optarg)
236 {
237 sym_id_add (optarg, EXCL_ANNO);
238 output_style |= STYLE_ANNOTATED_SOURCE;
239 }
240 else
241 {
242 output_style &= ~STYLE_ANNOTATED_SOURCE;
03c35bcb 243 }
12516a37
KR
244 user_specified |= STYLE_ANNOTATED_SOURCE;
245 break;
246 case 'k':
247 sym_id_add (optarg, EXCL_ARCS);
248 break;
249 case 'l':
250 line_granularity = TRUE;
251 break;
252 case 'L':
253 print_path = TRUE;
254 break;
255 case 'm':
256 bb_min_calls = atoi (optarg);
257 break;
258 case 'n':
259 sym_id_add (optarg, INCL_TIME);
260 break;
261 case 'N':
262 sym_id_add (optarg, EXCL_TIME);
263 break;
264 case 'O':
265 switch (optarg[0])
266 {
267 case 'a':
268 file_format = FF_AUTO;
269 break;
270 case 'm':
271 file_format = FF_MAGIC;
272 break;
273 case 'b':
274 file_format = FF_BSD;
275 break;
276 case 'p':
277 file_format = FF_PROF;
278 break;
279 default:
280 fprintf (stderr, "%s: unknown file format %s\n",
281 optarg, whoami);
282 done (1);
03c35bcb 283 }
12516a37
KR
284 break;
285 case 'p':
286 if (optarg)
287 {
288 sym_id_add (optarg, INCL_FLAT);
03c35bcb 289 }
12516a37
KR
290 output_style |= STYLE_FLAT_PROFILE;
291 user_specified |= STYLE_FLAT_PROFILE;
292 break;
293 case 'P':
294 if (optarg)
295 {
296 sym_id_add (optarg, EXCL_FLAT);
297 output_style |= STYLE_FLAT_PROFILE;
298 }
299 else
300 {
301 output_style &= ~STYLE_FLAT_PROFILE;
03c35bcb 302 }
12516a37
KR
303 user_specified |= STYLE_FLAT_PROFILE;
304 break;
305 case 'q':
306 if (optarg)
307 {
308 if (strchr (optarg, '/'))
309 {
310 sym_id_add (optarg, INCL_ARCS);
311 }
312 else
313 {
314 sym_id_add (optarg, INCL_GRAPH);
03c35bcb
KR
315 }
316 }
12516a37
KR
317 output_style |= STYLE_CALL_GRAPH;
318 user_specified |= STYLE_CALL_GRAPH;
319 break;
320 case 'Q':
321 if (optarg)
322 {
323 if (strchr (optarg, '/'))
324 {
325 sym_id_add (optarg, EXCL_ARCS);
326 }
327 else
328 {
329 sym_id_add (optarg, EXCL_GRAPH);
03c35bcb 330 }
12516a37
KR
331 output_style |= STYLE_CALL_GRAPH;
332 }
333 else
334 {
335 output_style &= ~STYLE_CALL_GRAPH;
03c35bcb 336 }
12516a37
KR
337 user_specified |= STYLE_CALL_GRAPH;
338 break;
339 case 's':
340 output_style |= STYLE_SUMMARY_FILE;
341 user_specified |= STYLE_SUMMARY_FILE;
342 break;
343 case 't':
344 bb_table_length = atoi (optarg);
345 if (bb_table_length < 0)
346 {
347 bb_table_length = 0;
03c35bcb 348 }
12516a37
KR
349 break;
350 case 'T':
351 bsd_style_output = TRUE;
352 break;
353 case 'v':
354 printf ("%s version %s\n", whoami, VERSION);
355 done (0);
356 case 'w':
357 output_width = atoi (optarg);
358 if (output_width < 1)
359 {
360 output_width = 1;
03c35bcb 361 }
12516a37
KR
362 break;
363 case 'x':
364 bb_annotate_all_lines = TRUE;
365 break;
366 case 'y':
367 create_annotation_files = TRUE;
368 break;
369 case 'z':
370 ignore_zeros = FALSE;
371 break;
372 case 'Z':
373 if (optarg)
374 {
375 sym_id_add (optarg, EXCL_EXEC);
376 output_style |= STYLE_EXEC_COUNTS;
377 }
378 else
379 {
380 output_style &= ~STYLE_EXEC_COUNTS;
03c35bcb 381 }
12516a37
KR
382 user_specified |= STYLE_ANNOTATED_SOURCE;
383 break;
384 default:
385 usage (stderr, 1);
03c35bcb
KR
386 }
387 }
12516a37
KR
388
389 /* append value of GPROF_PATH to source search list if set: */
390 str = getenv ("GPROF_PATH");
391 if (str)
392 {
393 search_list_append (&src_search_list, str);
03c35bcb 394 }
3d6c6501 395
12516a37
KR
396 if (optind < argc)
397 {
398 a_out_name = argv[optind++];
03c35bcb 399 }
12516a37
KR
400 if (optind < argc)
401 {
402 gmon_name = argv[optind++];
03c35bcb 403 }
12516a37
KR
404
405 /*
406 * Turn off default functions:
407 */
408 for (sp = &default_excluded_list[0]; *sp; sp++)
409 {
410 sym_id_add (*sp, EXCL_TIME);
411 sym_id_add (*sp, EXCL_GRAPH);
5489fcc3 412#ifdef __osf__
12516a37 413 sym_id_add (*sp, EXCL_FLAT);
5489fcc3 414#endif
03c35bcb 415 }
5489fcc3 416
12516a37
KR
417 /*
418 * For line-by-line profiling, also want to keep those
419 * functions off the flat profile:
420 */
421 if (line_granularity)
422 {
423 for (sp = &default_excluded_list[0]; *sp; sp++)
424 {
425 sym_id_add (*sp, EXCL_FLAT);
03c35bcb
KR
426 }
427 }
12516a37
KR
428
429 /*
430 * Read symbol table from core file:
431 */
432 core_init (a_out_name);
433
434 /*
435 * If we should ignore direct function calls, we need to load
436 * to core's text-space:
437 */
438 if (ignore_direct_calls)
439 {
440 core_get_text_space (core_bfd);
03c35bcb 441 }
3d6c6501 442
12516a37
KR
443 /*
444 * Create symbols from core image:
445 */
446 if (line_granularity)
447 {
448 core_create_line_syms (core_bfd);
449 }
450 else
451 {
452 core_create_function_syms (core_bfd);
03c35bcb 453 }
3d6c6501 454
12516a37
KR
455 /*
456 * Translate sym specs into syms:
457 */
458 sym_id_parse ();
3d6c6501 459
12516a37
KR
460 if (file_format == FF_PROF)
461 {
5489fcc3 462#ifdef PROF_SUPPORT_IMPLEMENTED
12516a37
KR
463 /*
464 * Get information about mon.out file(s):
465 */
466 do
467 {
468 mon_out_read (gmon_name);
469 if (optind < argc)
470 {
471 gmon_name = argv[optind];
03c35bcb 472 }
12516a37
KR
473 }
474 while (optind++ < argc);
5489fcc3 475#else
12516a37
KR
476 fprintf (stderr,
477 "%s: sorry, file format `prof' is not yet supported\n",
478 whoami);
479 done (1);
811e3c6a 480#endif
12516a37
KR
481 }
482 else
483 {
484 /*
485 * Get information about gmon.out file(s):
486 */
487 do
488 {
489 gmon_out_read (gmon_name);
490 if (optind < argc)
491 {
492 gmon_name = argv[optind];
03c35bcb 493 }
12516a37
KR
494 }
495 while (optind++ < argc);
03c35bcb 496 }
12516a37
KR
497
498 /*
499 * If user did not specify output style, try to guess something
500 * reasonable:
501 */
502 if (output_style == 0)
503 {
504 if (gmon_input & (INPUT_HISTOGRAM | INPUT_CALL_GRAPH))
505 {
506 output_style = STYLE_FLAT_PROFILE | STYLE_CALL_GRAPH;
507 }
508 else
509 {
510 output_style = STYLE_EXEC_COUNTS;
03c35bcb 511 }
12516a37 512 output_style &= ~user_specified;
03c35bcb 513 }
12516a37
KR
514
515 /*
516 * Dump a gmon.sum file if requested (before any other processing!):
517 */
518 if (output_style & STYLE_SUMMARY_FILE)
519 {
520 gmon_out_write (GMONSUM);
03c35bcb 521 }
4b8250bd 522
12516a37
KR
523 if (gmon_input & INPUT_HISTOGRAM)
524 {
525 hist_assign_samples ();
03c35bcb 526 }
2ea5f325 527
12516a37
KR
528 if (gmon_input & INPUT_CALL_GRAPH)
529 {
530 cg = cg_assemble ();
03c35bcb 531 }
12516a37
KR
532
533 /* do some simple sanity checks: */
534
535 if ((output_style & STYLE_FLAT_PROFILE)
536 && !(gmon_input & INPUT_HISTOGRAM))
537 {
538 fprintf (stderr, "%s: gmon.out file is missing histogram\n", whoami);
539 done (1);
03c35bcb 540 }
5489fcc3 541
12516a37
KR
542 if ((output_style & STYLE_CALL_GRAPH) && !(gmon_input & INPUT_CALL_GRAPH))
543 {
544 fprintf (stderr,
545 "%s: gmon.out file is missing call-graph data\n", whoami);
546 done (1);
03c35bcb 547 }
5489fcc3 548
12516a37 549 /* output whatever user whishes to see: */
5489fcc3 550
12516a37
KR
551 if (cg && (output_style & STYLE_CALL_GRAPH) && bsd_style_output)
552 {
553 cg_print (cg); /* print the dynamic profile */
03c35bcb 554 }
5489fcc3 555
12516a37
KR
556 if (output_style & STYLE_FLAT_PROFILE)
557 {
558 hist_print (); /* print the flat profile */
03c35bcb 559 }
12516a37
KR
560
561 if (cg && (output_style & STYLE_CALL_GRAPH))
562 {
563 if (!bsd_style_output)
564 {
565 cg_print (cg); /* print the dynamic profile */
03c35bcb 566 }
12516a37 567 cg_print_index ();
03c35bcb 568 }
12516a37
KR
569
570 if (output_style & STYLE_EXEC_COUNTS)
5489fcc3 571 {
12516a37 572 print_exec_counts ();
03c35bcb 573 }
5489fcc3 574
12516a37 575 if (output_style & STYLE_ANNOTATED_SOURCE)
5489fcc3 576 {
12516a37 577 print_annotated_source ();
03c35bcb 578 }
12516a37 579 return 0;
3d6c6501
SEF
580}
581
5489fcc3
KR
582void
583done (status)
584 int status;
3d6c6501 585{
12516a37 586 exit (status);
3d6c6501 587}
This page took 0.39799 seconds and 4 git commands to generate.