merge from gcc
[binutils.git] / gprof / corefile.c
blob1619ffa71fd3752b432c07727796e1aa67cd3ce7
1 /* corefile.c
3 Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "libiberty.h"
23 #include "gprof.h"
24 #include "search_list.h"
25 #include "source.h"
26 #include "symtab.h"
27 #include "corefile.h"
29 bfd *core_bfd;
30 int core_num_syms;
31 asymbol **core_syms;
32 asection *core_text_sect;
33 PTR core_text_space;
35 int min_insn_size;
36 int offset_to_code;
38 /* For mapping symbols to specific .o files during file ordering. */
39 struct function_map *symbol_map;
40 unsigned int symbol_map_count;
42 static void read_function_mappings (const char *);
43 static int core_sym_class (asymbol *);
44 static bfd_boolean get_src_info
45 (bfd_vma, const char **, const char **, int *);
47 extern void i386_find_call (Sym *, bfd_vma, bfd_vma);
48 extern void alpha_find_call (Sym *, bfd_vma, bfd_vma);
49 extern void vax_find_call (Sym *, bfd_vma, bfd_vma);
50 extern void tahoe_find_call (Sym *, bfd_vma, bfd_vma);
51 extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
52 extern void mips_find_call (Sym *, bfd_vma, bfd_vma);
54 static void
55 read_function_mappings (const char *filename)
57 FILE *file = fopen (filename, "r");
58 char dummy[1024];
59 int count = 0;
61 if (!file)
63 fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
64 done (1);
67 /* First parse the mapping file so we know how big we need to
68 make our tables. We also do some sanity checks at this
69 time. */
70 while (!feof (file))
72 int matches;
74 matches = fscanf (file, "%[^\n:]", dummy);
75 if (!matches)
77 fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
78 whoami, filename);
79 done (1);
82 /* Just skip messages about files with no symbols. */
83 if (!strncmp (dummy, "No symbols in ", 14))
85 fscanf (file, "\n");
86 continue;
89 /* Don't care what else is on this line at this point. */
90 fscanf (file, "%[^\n]\n", dummy);
91 count++;
94 /* Now we know how big we need to make our table. */
95 symbol_map = ((struct function_map *)
96 xmalloc (count * sizeof (struct function_map)));
98 /* Rewind the input file so we can read it again. */
99 rewind (file);
101 /* Read each entry and put it into the table. */
102 count = 0;
103 while (!feof (file))
105 int matches;
106 char *tmp;
108 matches = fscanf (file, "%[^\n:]", dummy);
109 if (!matches)
111 fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
112 whoami, filename);
113 done (1);
116 /* Just skip messages about files with no symbols. */
117 if (!strncmp (dummy, "No symbols in ", 14))
119 fscanf (file, "\n");
120 continue;
123 /* dummy has the filename, go ahead and copy it. */
124 symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
125 strcpy (symbol_map[count].file_name, dummy);
127 /* Now we need the function name. */
128 fscanf (file, "%[^\n]\n", dummy);
129 tmp = strrchr (dummy, ' ') + 1;
130 symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
131 strcpy (symbol_map[count].function_name, tmp);
132 count++;
135 /* Record the size of the map table for future reference. */
136 symbol_map_count = count;
140 void
141 core_init (const char *aout_name)
143 int core_sym_bytes;
144 core_bfd = bfd_openr (aout_name, 0);
146 if (!core_bfd)
148 perror (aout_name);
149 done (1);
152 if (!bfd_check_format (core_bfd, bfd_object))
154 fprintf (stderr, _("%s: %s: not in a.out format\n"), whoami, aout_name);
155 done (1);
158 /* Get core's text section. */
159 core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
160 if (!core_text_sect)
162 core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
163 if (!core_text_sect)
165 fprintf (stderr, _("%s: can't find .text section in %s\n"),
166 whoami, aout_name);
167 done (1);
171 /* Read core's symbol table. */
173 /* This will probably give us more than we need, but that's ok. */
174 core_sym_bytes = bfd_get_symtab_upper_bound (core_bfd);
175 if (core_sym_bytes < 0)
177 fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
178 bfd_errmsg (bfd_get_error ()));
179 done (1);
182 core_syms = (asymbol **) xmalloc (core_sym_bytes);
183 core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
185 if (core_num_syms < 0)
187 fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
188 bfd_errmsg (bfd_get_error ()));
189 done (1);
192 min_insn_size = 1;
193 offset_to_code = 0;
195 switch (bfd_get_arch (core_bfd))
197 case bfd_arch_vax:
198 case bfd_arch_tahoe:
199 offset_to_code = 2;
200 break;
202 case bfd_arch_alpha:
203 min_insn_size = 4;
204 break;
206 default:
207 break;
210 if (function_mapping_file)
211 read_function_mappings (function_mapping_file);
214 /* Read in the text space of an a.out file. */
216 void
217 core_get_text_space (bfd *cbfd)
219 core_text_space = malloc (bfd_get_section_size (core_text_sect));
221 if (!core_text_space)
223 fprintf (stderr, _("%s: ran out room for %lu bytes of text space\n"),
224 whoami, (unsigned long) bfd_get_section_size (core_text_sect));
225 done (1);
228 if (!bfd_get_section_contents (cbfd, core_text_sect, core_text_space,
229 0, bfd_get_section_size (core_text_sect)))
231 bfd_perror ("bfd_get_section_contents");
232 free (core_text_space);
233 core_text_space = 0;
236 if (!core_text_space)
237 fprintf (stderr, _("%s: can't do -c\n"), whoami);
241 void
242 find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
244 switch (bfd_get_arch (core_bfd))
246 case bfd_arch_i386:
247 i386_find_call (parent, p_lowpc, p_highpc);
248 break;
250 case bfd_arch_alpha:
251 alpha_find_call (parent, p_lowpc, p_highpc);
252 break;
254 case bfd_arch_vax:
255 vax_find_call (parent, p_lowpc, p_highpc);
256 break;
258 case bfd_arch_sparc:
259 sparc_find_call (parent, p_lowpc, p_highpc);
260 break;
262 case bfd_arch_tahoe:
263 tahoe_find_call (parent, p_lowpc, p_highpc);
264 break;
266 case bfd_arch_mips:
267 mips_find_call (parent, p_lowpc, p_highpc);
268 break;
270 default:
271 fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
272 whoami, bfd_printable_name(core_bfd));
274 /* Don't give the error more than once. */
275 ignore_direct_calls = FALSE;
279 /* Return class of symbol SYM. The returned class can be any of:
280 0 -> symbol is not interesting to us
281 'T' -> symbol is a global name
282 't' -> symbol is a local (static) name. */
284 static int
285 core_sym_class (asymbol *sym)
287 symbol_info syminfo;
288 const char *name;
289 char sym_prefix;
290 int i;
292 if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
293 return 0;
295 /* Must be a text symbol, and static text symbols
296 don't qualify if ignore_static_funcs set. */
297 if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
299 DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
300 sym->name));
301 return 0;
304 bfd_get_symbol_info (core_bfd, sym, &syminfo);
305 i = syminfo.type;
307 if (i == 'T')
308 return i; /* It's a global symbol. */
310 if (i == 'W')
311 /* Treat weak symbols as text symbols. FIXME: a weak symbol may
312 also be a data symbol. */
313 return 'T';
315 if (i != 't')
317 /* Not a static text symbol. */
318 DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
319 sym->name, i));
320 return 0;
323 /* Do some more filtering on static function-names. */
324 if (ignore_static_funcs)
325 return 0;
327 /* Can't zero-length name or funny characters in name, where
328 `funny' includes: `.' (.o file names) and `$' (Pascal labels). */
329 if (!sym->name || sym->name[0] == '\0')
330 return 0;
332 for (name = sym->name; *name; ++name)
334 if (*name == '.' || *name == '$')
335 return 0;
338 /* On systems where the C compiler adds an underscore to all
339 names, static names without underscores seem usually to be
340 labels in hand written assembler in the library. We don't want
341 these names. This is certainly necessary on a Sparc running
342 SunOS 4.1 (try profiling a program that does a lot of
343 division). I don't know whether it has harmful side effects on
344 other systems. Perhaps it should be made configurable. */
345 sym_prefix = bfd_get_symbol_leading_char (core_bfd);
347 if ((sym_prefix && sym_prefix != sym->name[0])
348 /* GCC may add special symbols to help gdb figure out the file
349 language. We want to ignore these, since sometimes they mask
350 the real function. (dj@ctron) */
351 || !strncmp (sym->name, "__gnu_compiled", 14)
352 || !strncmp (sym->name, "___gnu_compiled", 15))
354 return 0;
357 /* If the object file supports marking of function symbols, then
358 we can zap anything that doesn't have BSF_FUNCTION set. */
359 if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
360 return 0;
362 return 't'; /* It's a static text symbol. */
365 /* Get whatever source info we can get regarding address ADDR. */
367 static bfd_boolean
368 get_src_info (bfd_vma addr, const char **filename, const char **name, int *line_num)
370 const char *fname = 0, *func_name = 0;
371 int l = 0;
373 if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
374 addr - core_text_sect->vma,
375 &fname, &func_name, (unsigned int *) &l)
376 && fname && func_name && l)
378 DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
379 (unsigned long) addr, fname, l, func_name));
380 *filename = fname;
381 *name = func_name;
382 *line_num = l;
383 return TRUE;
385 else
387 DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
388 (long) addr, fname ? fname : "<unknown>", l,
389 func_name ? func_name : "<unknown>"));
390 return FALSE;
394 /* Read in symbol table from core.
395 One symbol per function is entered. */
397 void
398 core_create_function_syms ()
400 bfd_vma min_vma = ~(bfd_vma) 0;
401 bfd_vma max_vma = 0;
402 int class;
403 long i, found, skip;
404 unsigned int j;
406 /* Pass 1 - determine upper bound on number of function names. */
407 symtab.len = 0;
409 for (i = 0; i < core_num_syms; ++i)
411 if (!core_sym_class (core_syms[i]))
412 continue;
414 /* This should be replaced with a binary search or hashed
415 search. Gross.
417 Don't create a symtab entry for a function that has
418 a mapping to a file, unless it's the first function
419 in the file. */
420 skip = 0;
421 for (j = 0; j < symbol_map_count; j++)
422 if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
424 if (j > 0 && ! strcmp (symbol_map [j].file_name,
425 symbol_map [j - 1].file_name))
426 skip = 1;
427 break;
430 if (!skip)
431 ++symtab.len;
434 if (symtab.len == 0)
436 fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
437 done (1);
440 /* The "+ 2" is for the sentinels. */
441 symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
443 /* Pass 2 - create symbols. */
444 symtab.limit = symtab.base;
446 for (i = 0; i < core_num_syms; ++i)
448 asection *sym_sec;
450 class = core_sym_class (core_syms[i]);
452 if (!class)
454 DBG (AOUTDEBUG,
455 printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
456 (unsigned long) core_syms[i]->value,
457 core_syms[i]->name));
458 continue;
461 /* This should be replaced with a binary search or hashed
462 search. Gross. */
463 skip = 0;
464 found = 0;
466 for (j = 0; j < symbol_map_count; j++)
467 if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
469 if (j > 0 && ! strcmp (symbol_map [j].file_name,
470 symbol_map [j - 1].file_name))
471 skip = 1;
472 else
473 found = j;
474 break;
477 if (skip)
478 continue;
480 sym_init (symtab.limit);
482 /* Symbol offsets are always section-relative. */
483 sym_sec = core_syms[i]->section;
484 symtab.limit->addr = core_syms[i]->value;
485 if (sym_sec)
486 symtab.limit->addr += bfd_get_section_vma (sym_sec->owner, sym_sec);
488 if (symbol_map_count
489 && !strcmp (core_syms[i]->name, symbol_map[found].function_name))
491 symtab.limit->name = symbol_map[found].file_name;
492 symtab.limit->mapped = 1;
494 else
496 symtab.limit->name = core_syms[i]->name;
497 symtab.limit->mapped = 0;
500 /* Lookup filename and line number, if we can. */
502 const char *filename, *func_name;
504 if (get_src_info (symtab.limit->addr, &filename, &func_name,
505 &symtab.limit->line_num))
507 symtab.limit->file = source_file_lookup_path (filename);
509 /* FIXME: Checking __osf__ here does not work with a cross
510 gprof. */
511 #ifdef __osf__
512 /* Suppress symbols that are not function names. This is
513 useful to suppress code-labels and aliases.
515 This is known to be useful under DEC's OSF/1. Under SunOS 4.x,
516 labels do not appear in the symbol table info, so this isn't
517 necessary. */
519 if (strcmp (symtab.limit->name, func_name) != 0)
521 /* The symbol's address maps to a different name, so
522 it can't be a function-entry point. This happens
523 for labels, for example. */
524 DBG (AOUTDEBUG,
525 printf ("[core_create_function_syms: rej %s (maps to %s)\n",
526 symtab.limit->name, func_name));
527 continue;
529 #endif
533 symtab.limit->is_func = TRUE;
534 symtab.limit->is_bb_head = TRUE;
536 if (class == 't')
537 symtab.limit->is_static = TRUE;
539 /* Keep track of the minimum and maximum vma addresses used by all
540 symbols. When computing the max_vma, use the ending address of the
541 section containing the symbol, if available. */
542 min_vma = MIN (symtab.limit->addr, min_vma);
543 if (sym_sec)
544 max_vma = MAX (bfd_get_section_vma (sym_sec->owner, sym_sec)
545 + bfd_section_size (sym_sec->owner, sym_sec) - 1,
546 max_vma);
547 else
548 max_vma = MAX (symtab.limit->addr, max_vma);
550 /* If we see "main" without an initial '_', we assume names
551 are *not* prefixed by '_'. */
552 if (symtab.limit->name[0] == 'm' && discard_underscores
553 && strcmp (symtab.limit->name, "main") == 0)
554 discard_underscores = 0;
556 DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
557 (long) (symtab.limit - symtab.base),
558 symtab.limit->name,
559 (unsigned long) symtab.limit->addr));
560 ++symtab.limit;
563 /* Create sentinels. */
564 sym_init (symtab.limit);
565 symtab.limit->name = "<locore>";
566 symtab.limit->addr = 0;
567 symtab.limit->end_addr = min_vma - 1;
568 ++symtab.limit;
570 sym_init (symtab.limit);
571 symtab.limit->name = "<hicore>";
572 symtab.limit->addr = max_vma + 1;
573 symtab.limit->end_addr = ~(bfd_vma) 0;
574 ++symtab.limit;
576 symtab.len = symtab.limit - symtab.base;
577 symtab_finalize (&symtab);
580 /* Read in symbol table from core.
581 One symbol per line of source code is entered. */
583 void
584 core_create_line_syms ()
586 char *prev_name, *prev_filename;
587 unsigned int prev_name_len, prev_filename_len;
588 bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0;
589 Sym *prev, dummy, *sentinel, *sym;
590 const char *filename;
591 int prev_line_num;
592 Sym_Table ltab;
593 bfd_vma vma_high;
595 /* Create symbols for functions as usual. This is necessary in
596 cases where parts of a program were not compiled with -g. For
597 those parts we still want to get info at the function level. */
598 core_create_function_syms ();
600 /* Pass 1: count the number of symbols. */
602 /* To find all line information, walk through all possible
603 text-space addresses (one by one!) and get the debugging
604 info for each address. When the debugging info changes,
605 it is time to create a new symbol.
607 Of course, this is rather slow and it would be better if
608 BFD would provide an iterator for enumerating all line infos. */
609 prev_name_len = PATH_MAX;
610 prev_filename_len = PATH_MAX;
611 prev_name = xmalloc (prev_name_len);
612 prev_filename = xmalloc (prev_filename_len);
613 ltab.len = 0;
614 prev_line_num = 0;
616 vma_high = core_text_sect->vma + bfd_get_section_size (core_text_sect);
617 for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
619 unsigned int len;
621 if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
622 || (prev_line_num == dummy.line_num
623 && prev_name != NULL
624 && strcmp (prev_name, dummy.name) == 0
625 && strcmp (prev_filename, filename) == 0))
626 continue;
628 ++ltab.len;
629 prev_line_num = dummy.line_num;
631 len = strlen (dummy.name);
632 if (len >= prev_name_len)
634 prev_name_len = len + 1024;
635 free (prev_name);
636 prev_name = xmalloc (prev_name_len);
639 strcpy (prev_name, dummy.name);
640 len = strlen (filename);
642 if (len >= prev_filename_len)
644 prev_filename_len = len + 1024;
645 free (prev_filename);
646 prev_filename = xmalloc (prev_filename_len);
649 strcpy (prev_filename, filename);
651 min_vma = MIN (vma, min_vma);
652 max_vma = MAX (vma, max_vma);
655 free (prev_name);
656 free (prev_filename);
658 /* Make room for function symbols, too. */
659 ltab.len += symtab.len;
660 ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
661 ltab.limit = ltab.base;
663 /* Pass 2 - create symbols. */
665 /* We now set is_static as we go along, rather than by running
666 through the symbol table at the end.
668 The old way called symtab_finalize before the is_static pass,
669 causing a problem since symtab_finalize uses is_static as part of
670 its address conflict resolution algorithm. Since global symbols
671 were prefered over static symbols, and all line symbols were
672 global at that point, static function names that conflicted with
673 their own line numbers (static, but labeled as global) were
674 rejected in favor of the line num.
676 This was not the desired functionality. We always want to keep
677 our function symbols and discard any conflicting line symbols.
678 Perhaps symtab_finalize should be modified to make this
679 distinction as well, but the current fix works and the code is a
680 lot cleaner now. */
681 prev = 0;
683 for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
685 sym_init (ltab.limit);
687 if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
688 || (prev && prev->line_num == ltab.limit->line_num
689 && strcmp (prev->name, ltab.limit->name) == 0
690 && strcmp (prev->file->name, filename) == 0))
691 continue;
693 /* Make name pointer a malloc'ed string. */
694 ltab.limit->name = xstrdup (ltab.limit->name);
695 ltab.limit->file = source_file_lookup_path (filename);
697 ltab.limit->addr = vma;
699 /* Set is_static based on the enclosing function, using either:
700 1) the previous symbol, if it's from the same function, or
701 2) a symtab lookup. */
702 if (prev && ltab.limit->file == prev->file &&
703 strcmp (ltab.limit->name, prev->name) == 0)
705 ltab.limit->is_static = prev->is_static;
707 else
709 sym = sym_lookup(&symtab, ltab.limit->addr);
710 ltab.limit->is_static = sym->is_static;
713 prev = ltab.limit;
715 /* If we see "main" without an initial '_', we assume names
716 are *not* prefixed by '_'. */
717 if (ltab.limit->name[0] == 'm' && discard_underscores
718 && strcmp (ltab.limit->name, "main") == 0)
719 discard_underscores = 0;
721 DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
722 (unsigned long) (ltab.limit - ltab.base),
723 ltab.limit->name,
724 (unsigned long) ltab.limit->addr));
725 ++ltab.limit;
728 /* Update sentinels. */
729 sentinel = sym_lookup (&symtab, (bfd_vma) 0);
731 if (sentinel
732 && strcmp (sentinel->name, "<locore>") == 0
733 && min_vma <= sentinel->end_addr)
734 sentinel->end_addr = min_vma - 1;
736 sentinel = sym_lookup (&symtab, ~(bfd_vma) 0);
738 if (sentinel
739 && strcmp (sentinel->name, "<hicore>") == 0
740 && max_vma >= sentinel->addr)
741 sentinel->addr = max_vma + 1;
743 /* Copy in function symbols. */
744 memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
745 ltab.limit += symtab.len;
747 if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
749 fprintf (stderr,
750 _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
751 whoami, ltab.len, (long) (ltab.limit - ltab.base));
752 done (1);
755 /* Finalize ltab and make it symbol table. */
756 symtab_finalize (&ltab);
757 free (symtab.base);
758 symtab = ltab;