* Usability improvement
[binutils-gdb.git] / gprof / corefile.c
blob255a0a3933cd41da0ad2e5c40b1f29d411fd2b73
1 /* corefile.c
3 Copyright (C) 2000 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 "corefile.h"
25 #include "symtab.h"
27 bfd *core_bfd;
28 int core_num_syms;
29 asymbol **core_syms;
30 asection *core_text_sect;
31 PTR core_text_space;
33 int min_insn_size;
34 int offset_to_code;
36 /* For mapping symbols to specific .o files during file ordering. */
37 struct function_map
39 char *function_name;
40 char *file_name;
43 struct function_map *symbol_map;
44 unsigned int symbol_map_count;
46 extern void i386_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
47 extern void alpha_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
48 extern void vax_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
49 extern void tahoe_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
50 extern void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
52 static void
53 DEFUN (read_function_mappings, (filename), const char *filename)
55 FILE *file = fopen (filename, "r");
56 char dummy[1024];
57 int count = 0;
59 if (!file)
61 fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
62 done (1);
65 /* First parse the mapping file so we know how big we need to
66 make our tables. We also do some sanity checks at this
67 time. */
68 while (!feof (file))
70 int matches;
72 matches = fscanf (file, "%[^\n:]", dummy);
73 if (!matches)
75 fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
76 whoami, filename);
77 done (1);
80 /* Just skip messages about files with no symbols. */
81 if (!strncmp (dummy, "No symbols in ", 14))
83 fscanf (file, "\n");
84 continue;
87 /* Don't care what else is on this line at this point. */
88 fscanf (file, "%[^\n]\n", dummy);
89 count++;
92 /* Now we know how big we need to make our table. */
93 symbol_map = ((struct function_map *)
94 xmalloc (count * sizeof (struct function_map)));
96 /* Rewind the input file so we can read it again. */
97 rewind (file);
99 /* Read each entry and put it into the table. */
100 count = 0;
101 while (!feof (file))
103 int matches;
104 char *tmp;
106 matches = fscanf (file, "%[^\n:]", dummy);
107 if (!matches)
109 fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
110 whoami, filename);
111 done (1);
114 /* Just skip messages about files with no symbols. */
115 if (!strncmp (dummy, "No symbols in ", 14))
117 fscanf (file, "\n");
118 continue;
121 /* dummy has the filename, go ahead and copy it. */
122 symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
123 strcpy (symbol_map[count].file_name, dummy);
125 /* Now we need the function name. */
126 fscanf (file, "%[^\n]\n", dummy);
127 tmp = strrchr (dummy, ' ') + 1;
128 symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
129 strcpy (symbol_map[count].function_name, tmp);
130 count++;
133 /* Record the size of the map table for future reference. */
134 symbol_map_count = count;
138 void
139 DEFUN (core_init, (a_out_name), const char *a_out_name)
141 core_bfd = bfd_openr (a_out_name, 0);
143 if (!core_bfd)
145 perror (a_out_name);
146 done (1);
149 if (!bfd_check_format (core_bfd, bfd_object))
151 fprintf (stderr, _("%s: %s: not in a.out format\n"), whoami, a_out_name);
152 done (1);
155 /* Get core's text section. */
156 core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
157 if (!core_text_sect)
159 core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
160 if (!core_text_sect)
162 fprintf (stderr, _("%s: can't find .text section in %s\n"),
163 whoami, a_out_name);
164 done (1);
168 /* Read core's symbol table. */
170 /* This will probably give us more than we need, but that's ok. */
171 core_num_syms = bfd_get_symtab_upper_bound (core_bfd);
172 if (core_num_syms < 0)
174 fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
175 bfd_errmsg (bfd_get_error ()));
176 done (1);
179 core_syms = (asymbol **) xmalloc (core_num_syms);
180 core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
182 if (core_num_syms < 0)
184 fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
185 bfd_errmsg (bfd_get_error ()));
186 done (1);
189 min_insn_size = 1;
190 offset_to_code = 0;
192 switch (bfd_get_arch (core_bfd))
194 case bfd_arch_vax:
195 case bfd_arch_tahoe:
196 offset_to_code = 2;
197 break;
199 case bfd_arch_alpha:
200 min_insn_size = 4;
201 break;
203 default:
204 break;
207 if (function_mapping_file)
208 read_function_mappings (function_mapping_file);
211 /* Read in the text space of an a.out file. */
213 void
214 DEFUN (core_get_text_space, (core_bfd), bfd * core_bfd)
216 core_text_space = (PTR) malloc (core_text_sect->_raw_size);
218 if (!core_text_space)
220 fprintf (stderr, _("%s: ran out room for %lu bytes of text space\n"),
221 whoami, (unsigned long) core_text_sect->_raw_size);
222 done (1);
225 if (!bfd_get_section_contents (core_bfd, core_text_sect, core_text_space,
226 0, core_text_sect->_raw_size))
228 bfd_perror ("bfd_get_section_contents");
229 free (core_text_space);
230 core_text_space = 0;
233 if (!core_text_space)
234 fprintf (stderr, _("%s: can't do -c\n"), whoami);
238 void
239 DEFUN (find_call, (parent, p_lowpc, p_highpc),
240 Sym * parent AND bfd_vma p_lowpc AND bfd_vma p_highpc)
242 switch (bfd_get_arch (core_bfd))
244 case bfd_arch_i386:
245 i386_find_call (parent, p_lowpc, p_highpc);
246 break;
248 case bfd_arch_alpha:
249 alpha_find_call (parent, p_lowpc, p_highpc);
250 break;
252 case bfd_arch_vax:
253 vax_find_call (parent, p_lowpc, p_highpc);
254 break;
256 case bfd_arch_sparc:
257 sparc_find_call (parent, p_lowpc, p_highpc);
258 break;
260 case bfd_arch_tahoe:
261 tahoe_find_call (parent, p_lowpc, p_highpc);
262 break;
264 default:
265 fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
266 whoami, bfd_printable_name(core_bfd));
268 /* Don't give the error more than once. */
269 ignore_direct_calls = FALSE;
273 /* Return class of symbol SYM. The returned class can be any of:
274 0 -> symbol is not interesting to us
275 'T' -> symbol is a global name
276 't' -> symbol is a local (static) name. */
278 static int
279 DEFUN (core_sym_class, (sym), asymbol * sym)
281 symbol_info syminfo;
282 const char *name;
283 char sym_prefix;
284 int i;
286 if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
287 return 0;
289 /* Must be a text symbol, and static text symbols
290 don't qualify if ignore_static_funcs set. */
291 if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
293 DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
294 sym->name));
295 return 0;
298 bfd_get_symbol_info (core_bfd, sym, &syminfo);
299 i = syminfo.type;
301 if (i == 'T')
302 return i; /* It's a global symbol. */
304 if (i == 'W')
305 /* Treat weak symbols as text symbols. FIXME: a weak symbol may
306 also be a data symbol. */
307 return 'T';
309 if (i != 't')
311 /* Not a static text symbol. */
312 DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
313 sym->name, i));
314 return 0;
317 /* Do some more filtering on static function-names. */
318 if (ignore_static_funcs)
319 return 0;
321 /* Can't zero-length name or funny characters in name, where
322 `funny' includes: `.' (.o file names) and `$' (Pascal labels). */
323 if (!sym->name || sym->name[0] == '\0')
324 return 0;
326 for (name = sym->name; *name; ++name)
328 if (*name == '.' || *name == '$')
329 return 0;
332 /* On systems where the C compiler adds an underscore to all
333 names, static names without underscores seem usually to be
334 labels in hand written assembler in the library. We don't want
335 these names. This is certainly necessary on a Sparc running
336 SunOS 4.1 (try profiling a program that does a lot of
337 division). I don't know whether it has harmful side effects on
338 other systems. Perhaps it should be made configurable. */
339 sym_prefix = bfd_get_symbol_leading_char (core_bfd);
341 if ((sym_prefix && sym_prefix != sym->name[0])
342 /* GCC may add special symbols to help gdb figure out the file
343 language. We want to ignore these, since sometimes they mask
344 the real function. (dj@ctron) */
345 || !strncmp (sym->name, "__gnu_compiled", 14)
346 || !strncmp (sym->name, "___gnu_compiled", 15))
348 return 0;
351 /* If the object file supports marking of function symbols, then
352 we can zap anything that doesn't have BSF_FUNCTION set. */
353 if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
354 return 0;
356 return 't'; /* It's a static text symbol. */
359 /* Get whatever source info we can get regarding address ADDR. */
361 static bool
362 DEFUN (get_src_info, (addr, filename, name, line_num),
363 bfd_vma addr AND const char **filename AND const char **name
364 AND int *line_num)
366 const char *fname = 0, *func_name = 0;
367 int l = 0;
369 if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
370 addr - core_text_sect->vma,
371 &fname, &func_name, (unsigned int *) &l)
372 && fname && func_name && l)
374 DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
375 (unsigned long) addr, fname, l, func_name));
376 *filename = fname;
377 *name = func_name;
378 *line_num = l;
379 return TRUE;
381 else
383 DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
384 (long) addr, fname ? fname : "<unknown>", l,
385 func_name ? func_name : "<unknown>"));
386 return FALSE;
390 /* Read in symbol table from core.
391 One symbol per function is entered. */
393 void
394 core_create_function_syms (core_bfd)
395 bfd *core_bfd ATTRIBUTE_UNUSED;
397 bfd_vma min_vma = ~0, max_vma = 0;
398 int class;
399 long i, found, skip;
400 unsigned int j;
402 /* Pass 1 - determine upper bound on number of function names. */
403 symtab.len = 0;
405 for (i = 0; i < core_num_syms; ++i)
407 if (!core_sym_class (core_syms[i]))
408 continue;
410 /* This should be replaced with a binary search or hashed
411 search. Gross.
413 Don't create a symtab entry for a function that has
414 a mapping to a file, unless it's the first function
415 in the file. */
416 skip = 0;
417 for (j = 0; j < symbol_map_count; j++)
418 if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
420 if (j > 0 && ! strcmp (symbol_map [j].file_name,
421 symbol_map [j - 1].file_name))
422 skip = 1;
423 break;
426 if (!skip)
427 ++symtab.len;
430 if (symtab.len == 0)
432 fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
433 done (1);
436 /* The "+ 2" is for the sentinels. */
437 symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
439 /* Pass 2 - create symbols. */
440 symtab.limit = symtab.base;
442 for (i = 0; i < core_num_syms; ++i)
444 class = core_sym_class (core_syms[i]);
446 if (!class)
448 DBG (AOUTDEBUG,
449 printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
450 (unsigned long) core_syms[i]->value,
451 core_syms[i]->name));
452 continue;
455 /* This should be replaced with a binary search or hashed
456 search. Gross. */
457 skip = 0;
458 found = 0;
460 for (j = 0; j < symbol_map_count; j++)
461 if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
463 if (j > 0 && ! strcmp (symbol_map [j].file_name,
464 symbol_map [j - 1].file_name))
465 skip = 1;
466 else
467 found = j;
468 break;
471 if (skip)
472 continue;
474 sym_init (symtab.limit);
476 /* Symbol offsets are always section-relative. */
477 symtab.limit->addr = core_syms[i]->value + core_syms[i]->section->vma;
479 if (symbol_map_count
480 && !strcmp (core_syms[i]->name, symbol_map[found].function_name))
482 symtab.limit->name = symbol_map[found].file_name;
483 symtab.limit->mapped = 1;
485 else
487 symtab.limit->name = core_syms[i]->name;
488 symtab.limit->mapped = 0;
491 /* Lookup filename and line number, if we can. */
493 const char *filename, *func_name;
495 if (get_src_info (symtab.limit->addr, &filename, &func_name,
496 &symtab.limit->line_num))
498 symtab.limit->file = source_file_lookup_path (filename);
500 /* FIXME: Checking __osf__ here does not work with a cross
501 gprof. */
502 #ifdef __osf__
503 /* Suppress symbols that are not function names. This is
504 useful to suppress code-labels and aliases.
506 This is known to be useful under DEC's OSF/1. Under SunOS 4.x,
507 labels do not appear in the symbol table info, so this isn't
508 necessary. */
510 if (strcmp (symtab.limit->name, func_name) != 0)
512 /* The symbol's address maps to a different name, so
513 it can't be a function-entry point. This happens
514 for labels, for example. */
515 DBG (AOUTDEBUG,
516 printf ("[core_create_function_syms: rej %s (maps to %s)\n",
517 symtab.limit->name, func_name));
518 continue;
520 #endif
524 symtab.limit->is_func = TRUE;
525 symtab.limit->is_bb_head = TRUE;
527 if (class == 't')
528 symtab.limit->is_static = TRUE;
530 min_vma = MIN (symtab.limit->addr, min_vma);
531 max_vma = MAX (symtab.limit->addr, max_vma);
533 /* If we see "main" without an initial '_', we assume names
534 are *not* prefixed by '_'. */
535 if (symtab.limit->name[0] == 'm' && discard_underscores
536 && strcmp (symtab.limit->name, "main") == 0)
537 discard_underscores = 0;
539 DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
540 (long) (symtab.limit - symtab.base),
541 symtab.limit->name,
542 (unsigned long) symtab.limit->addr));
543 ++symtab.limit;
546 /* Create sentinels. */
547 sym_init (symtab.limit);
548 symtab.limit->name = "<locore>";
549 symtab.limit->addr = 0;
550 symtab.limit->end_addr = min_vma - 1;
551 ++symtab.limit;
553 sym_init (symtab.limit);
554 symtab.limit->name = "<hicore>";
555 symtab.limit->addr = max_vma + 1;
556 symtab.limit->end_addr = ~0;
557 ++symtab.limit;
559 symtab.len = symtab.limit - symtab.base;
560 symtab_finalize (&symtab);
563 /* Read in symbol table from core.
564 One symbol per line of source code is entered. */
566 void
567 DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
569 char *prev_name, *prev_filename;
570 int prev_name_len, prev_filename_len;
571 bfd_vma vma, min_vma = ~0, max_vma = 0;
572 bfd_vma offset;
573 Sym *prev, dummy, *sentinel, *sym;
574 const char *filename;
575 int prev_line_num;
576 Sym_Table ltab;
578 /* Create symbols for functions as usual. This is necessary in
579 cases where parts of a program were not compiled with -g. For
580 those parts we still want to get info at the function level. */
581 core_create_function_syms (core_bfd);
583 /* Pass 1 - counter number of symbols. */
585 /* To find all line information, walk through all possible
586 text-space addresses (one by one!) and get the debugging
587 info for each address. When the debugging info changes,
588 it is time to create a new symbol.
590 Of course, this is rather slow and it would be better if
591 bfd would provide an iterator for enumerating all line infos. */
592 prev_name_len = PATH_MAX;
593 prev_filename_len = PATH_MAX;
594 prev_name = xmalloc (prev_name_len);
595 prev_filename = xmalloc (prev_filename_len);
596 ltab.len = 0;
597 prev_line_num = 0;
599 for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
601 int len;
603 vma = core_text_sect->vma + offset;
605 if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
606 || (prev_line_num == dummy.line_num
607 && prev_name != NULL
608 && strcmp (prev_name, dummy.name) == 0
609 && strcmp (prev_filename, filename) == 0))
610 continue;
612 ++ltab.len;
613 prev_line_num = dummy.line_num;
615 len = strlen (dummy.name);
616 if (len >= prev_name_len)
618 prev_name_len = len + 1024;
619 free (prev_name);
620 prev_name = xmalloc (prev_name_len);
623 strcpy (prev_name, dummy.name);
624 len = strlen (filename);
626 if (len >= prev_filename_len)
628 prev_filename_len = len + 1024;
629 free (prev_filename);
630 prev_filename = xmalloc (prev_filename_len);
633 strcpy (prev_filename, filename);
635 min_vma = MIN (vma, min_vma);
636 max_vma = MAX (vma, max_vma);
639 free (prev_name);
640 free (prev_filename);
642 /* Make room for function symbols, too. */
643 ltab.len += symtab.len;
644 ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
645 ltab.limit = ltab.base;
647 /* Pass 2 - create symbols. */
649 /* We now set is_static as we go along, rather than by running
650 through the symbol table at the end.
652 The old way called symtab_finalize before the is_static pass,
653 causing a problem since symtab_finalize uses is_static as part of
654 its address conflict resolution algorithm. Since global symbols
655 were prefered over static symbols, and all line symbols were
656 global at that point, static function names that conflicted with
657 their own line numbers (static, but labeled as global) were
658 rejected in favor of the line num.
660 This was not the desired functionality. We always want to keep
661 our function symbols and discard any conflicting line symbols.
662 Perhaps symtab_finalize should be modified to make this
663 distinction as well, but the current fix works and the code is a
664 lot cleaner now. */
665 prev = 0;
667 for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
669 sym_init (ltab.limit);
671 if (!get_src_info (core_text_sect->vma + offset, &filename,
672 &ltab.limit->name, &ltab.limit->line_num)
673 || (prev && prev->line_num == ltab.limit->line_num
674 && strcmp (prev->name, ltab.limit->name) == 0
675 && strcmp (prev->file->name, filename) == 0))
676 continue;
678 /* Make name pointer a malloc'ed string. */
679 ltab.limit->name = xstrdup (ltab.limit->name);
680 ltab.limit->file = source_file_lookup_path (filename);
682 ltab.limit->addr = core_text_sect->vma + offset;
684 /* Set is_static based on the enclosing function, using either:
685 1) the previous symbol, if it's from the same function, or
686 2) a symtab lookup. */
687 if (prev && ltab.limit->file == prev->file &&
688 strcmp (ltab.limit->name, prev->name) == 0)
690 ltab.limit->is_static = prev->is_static;
692 else
694 sym = sym_lookup(&symtab, ltab.limit->addr);
695 ltab.limit->is_static = sym->is_static;
698 prev = ltab.limit;
700 /* If we see "main" without an initial '_', we assume names
701 are *not* prefixed by '_'. */
702 if (ltab.limit->name[0] == 'm' && discard_underscores
703 && strcmp (ltab.limit->name, "main") == 0)
704 discard_underscores = 0;
706 DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
707 (unsigned long) (ltab.limit - ltab.base),
708 ltab.limit->name,
709 (unsigned long) ltab.limit->addr));
710 ++ltab.limit;
713 /* Update sentinels. */
714 sentinel = sym_lookup (&symtab, 0);
716 if (strcmp (sentinel->name, "<locore>") == 0
717 && min_vma <= sentinel->end_addr)
718 sentinel->end_addr = min_vma - 1;
720 sentinel = sym_lookup (&symtab, ~0);
722 if (strcmp (sentinel->name, "<hicore>") == 0 && max_vma >= sentinel->addr)
723 sentinel->addr = max_vma + 1;
725 /* Copy in function symbols. */
726 memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
727 ltab.limit += symtab.len;
729 if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
731 fprintf (stderr,
732 _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
733 whoami, ltab.len, (long) (ltab.limit - ltab.base));
734 done (1);
737 /* Finalize ltab and make it symbol table. */
738 symtab_finalize (&ltab);
739 free (symtab.base);
740 symtab = ltab;