Tue Feb 3 14:25:25 1998 Brent Baccala <baccala@freesoft.org>
[platform/upstream/binutils.git] / gprof / core.c
1 #include "libiberty.h"
2 #include "gprof.h"
3 #include "core.h"
4 #include "symtab.h"
5
6 bfd *core_bfd;
7 int core_num_syms;
8 asymbol **core_syms;
9 asection *core_text_sect;
10 PTR core_text_space;
11
12 int min_insn_size;
13 int offset_to_code;
14
15 /* For mapping symbols to specific .o files during file ordering.  */
16 struct function_map {
17   char *function_name;
18   char *file_name;
19 };
20
21 struct function_map *symbol_map;
22 int symbol_map_count;
23
24 extern void i386_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
25 extern void alpha_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
26 extern void vax_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
27 extern void tahoe_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
28 extern void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
29
30 static void
31 DEFUN (read_function_mappings, (filename), const char *filename)
32 {
33   FILE *file = fopen (filename, "r");
34   char dummy[1024];
35   int count = 0;
36
37   if (!file)
38     {
39       fprintf (stderr, "%s: could not open %s.\n", whoami, filename);
40       done (1);
41     }
42
43   /* First parse the mapping file so we know how big we need to
44      make our tables.  We also do some sanity checks at this
45      time.  */
46   while (!feof (file))
47     {
48       int matches;
49
50       matches = fscanf (file, "%[^\n:]", dummy);
51       if (!matches)
52         {
53           fprintf (stderr, "%s: unable to parse mapping file %s.\n",
54                    whoami, filename);
55           done (1);
56         }
57
58       /* Just skip messages about files with no symbols.  */
59       if (!strncmp (dummy, "No symbols in ", 14))
60         {
61           fscanf (file, "\n");
62           continue;
63         }
64
65       /* Don't care what else is on this line at this point.  */
66       fscanf (file, "%[^\n]\n", dummy);
67       count++;
68     }
69
70   /* Now we know how big we need to make our table.  */
71   symbol_map = ((struct function_map *)
72                 xmalloc (count * sizeof (struct function_map)));
73
74   /* Rewind the input file so we can read it again.  */
75   rewind (file);
76
77   /* Read each entry and put it into the table.  */
78   count = 0;
79   while (!feof (file))
80     {
81       int matches;
82       char *tmp;
83
84       matches = fscanf (file, "%[^\n:]", dummy);
85       if (!matches)
86         {
87           fprintf (stderr, "%s: unable to parse mapping file %s.\n",
88                    whoami, filename);
89           done (1);
90         }
91
92       /* Just skip messages about files with no symbols.  */
93       if (!strncmp (dummy, "No symbols in ", 14))
94         {
95           fscanf (file, "\n");
96           continue;
97         }
98
99       /* dummy has the filename, go ahead and copy it.  */
100       symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
101       strcpy (symbol_map[count].file_name, dummy);
102
103       /* Now we need the function name.  */
104       fscanf (file, "%[^\n]\n", dummy);
105       tmp = strrchr (dummy, ' ') + 1;
106       symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
107       strcpy (symbol_map[count].function_name, tmp);
108       count++;
109     }
110
111   /* Record the size of the map table for future reference.  */
112   symbol_map_count = count;
113 }
114
115 void
116 DEFUN (core_init, (a_out_name), const char *a_out_name)
117 {
118   core_bfd = bfd_openr (a_out_name, 0);
119
120   if (!core_bfd)
121     {
122       perror (a_out_name);
123       done (1);
124     }
125
126   if (!bfd_check_format (core_bfd, bfd_object))
127     {
128       fprintf (stderr, "%s: %s: not in a.out format\n", whoami, a_out_name);
129       done (1);
130     }
131
132   /* get core's text section: */
133   core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
134   if (!core_text_sect)
135     {
136       core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
137       if (!core_text_sect)
138         {
139           fprintf (stderr, "%s: can't find .text section in %s\n",
140                    whoami, a_out_name);
141           done (1);
142         }
143     }
144
145   /* read core's symbol table: */
146
147   /* this will probably give us more than we need, but that's ok:  */
148   core_num_syms = bfd_get_symtab_upper_bound (core_bfd);
149   if (core_num_syms < 0)
150     {
151       fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
152                bfd_errmsg (bfd_get_error ()));
153       done (1);
154     }
155
156   core_syms = (asymbol **) xmalloc (core_num_syms);
157   core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
158   if (core_num_syms < 0)
159     {
160       fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
161                bfd_errmsg (bfd_get_error ()));
162       done (1);
163     }
164
165   min_insn_size = 1;
166   offset_to_code = 0;
167
168   switch (bfd_get_arch (core_bfd))
169     {
170     case bfd_arch_vax:
171     case bfd_arch_tahoe:
172       offset_to_code = 2;
173       break;
174
175     case bfd_arch_alpha:
176       min_insn_size = 4;
177       break;
178
179     default:
180     }
181
182   if (function_mapping_file)
183     read_function_mappings (function_mapping_file);
184 }
185
186
187 /*
188  * Read in the text space of an a.out file
189  */
190 void
191 DEFUN (core_get_text_space, (core_bfd), bfd * core_bfd)
192 {
193   core_text_space = (PTR) malloc (core_text_sect->_raw_size);
194
195   if (!core_text_space)
196     {
197       fprintf (stderr, "%s: ran out room for %ld bytes of text space\n",
198                whoami, core_text_sect->_raw_size);
199       done (1);
200     }
201   if (!bfd_get_section_contents (core_bfd, core_text_sect, core_text_space,
202                                  0, core_text_sect->_raw_size))
203     {
204       bfd_perror ("bfd_get_section_contents");
205       free (core_text_space);
206       core_text_space = 0;
207     }
208   if (!core_text_space)
209     {
210       fprintf (stderr, "%s: can't do -c\n", whoami);
211     }
212 }
213
214
215 void
216 DEFUN (find_call, (parent, p_lowpc, p_highpc),
217        Sym * parent AND bfd_vma p_lowpc AND bfd_vma p_highpc)
218 {
219   switch (bfd_get_arch (core_bfd))
220     {
221     case bfd_arch_i386:
222       i386_find_call (parent, p_lowpc, p_highpc);
223       break;
224
225     case bfd_arch_alpha:
226       alpha_find_call (parent, p_lowpc, p_highpc);
227       break;
228
229     case bfd_arch_vax:
230       vax_find_call (parent, p_lowpc, p_highpc);
231       break;
232
233     case bfd_arch_sparc:
234       sparc_find_call (parent, p_lowpc, p_highpc);
235       break;
236
237     case bfd_arch_tahoe:
238       tahoe_find_call (parent, p_lowpc, p_highpc);
239       break;
240
241     default:
242       fprintf (stderr, "%s: -c not supported on architecture %s\n",
243                whoami, bfd_printable_name(core_bfd));
244
245       /* Don't give the error more than once.  */
246       ignore_direct_calls = FALSE;
247     }
248 }
249
250 /*
251  * Return class of symbol SYM.  The returned class can be any of:
252  *      0   -> symbol is not interesting to us
253  *      'T' -> symbol is a global name
254  *      't' -> symbol is a local (static) name
255  */
256 static int
257 DEFUN (core_sym_class, (sym), asymbol * sym)
258 {
259   symbol_info syminfo;
260   const char *name;
261   char sym_prefix;
262   int i;
263
264   if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
265     {
266       return 0;
267     }
268
269   /*
270    * Must be a text symbol, and static text symbols don't qualify if
271    * ignore_static_funcs set.
272    */
273   if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
274     {
275       DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
276                               sym->name));
277       return 0;
278     }
279
280   bfd_get_symbol_info (core_bfd, sym, &syminfo);
281   i = syminfo.type;
282
283   if (i == 'T')
284     {
285       return i;                 /* it's a global symbol */
286     }
287
288   if (i == 'W')
289     {
290       /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
291          also be a data symbol.  */
292       return 'T';
293     }
294
295   if (i != 't')
296     {
297       /* not a static text symbol */
298       DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
299                               sym->name, i));
300       return 0;
301     }
302
303   /* do some more filtering on static function-names: */
304
305   if (ignore_static_funcs)
306     {
307       return 0;
308     }
309   /*
310    * Can't zero-length name or funny characters in name, where
311    * `funny' includes: `.' (.o file names) and `$' (Pascal labels).
312    */
313   if (!sym->name || sym->name[0] == '\0')
314     {
315       return 0;
316     }
317
318   for (name = sym->name; *name; ++name)
319     {
320       if (*name == '.' || *name == '$')
321         {
322           return 0;
323         }
324     }
325   /*
326    * On systems where the C compiler adds an underscore to all
327    * names, static names without underscores seem usually to be
328    * labels in hand written assembler in the library.  We don't want
329    * these names.  This is certainly necessary on a Sparc running
330    * SunOS 4.1 (try profiling a program that does a lot of
331    * division). I don't know whether it has harmful side effects on
332    * other systems.  Perhaps it should be made configurable.
333    */
334   sym_prefix = bfd_get_symbol_leading_char (core_bfd);
335   if ((sym_prefix && sym_prefix != sym->name[0])
336   /*
337    * GCC may add special symbols to help gdb figure out the file
338    * language.  We want to ignore these, since sometimes they mask
339    * the real function.  (dj@ctron)
340    */
341       || !strncmp (sym->name, "__gnu_compiled", 14)
342       || !strncmp (sym->name, "___gnu_compiled", 15))
343     {
344       return 0;
345     }
346
347   /* If the object file supports marking of function symbols, then we can
348      zap anything that doesn't have BSF_FUNCTION set.  */
349   if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
350     return 0;
351
352   return 't';                   /* it's a static text symbol */
353 }
354
355
356 /*
357  * Get whatever source info we can get regarding address ADDR:
358  */
359 static bool
360 DEFUN (get_src_info, (addr, filename, name, line_num),
361        bfd_vma addr AND const char **filename AND const char **name
362        AND int *line_num)
363 {
364   const char *fname = 0, *func_name = 0;
365   int l = 0;
366
367   if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
368                              addr - core_text_sect->vma,
369                              &fname, &func_name, (unsigned int *) &l)
370       && fname && func_name && l)
371     {
372       DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
373                               addr, fname, l, func_name));
374       *filename = fname;
375       *name = func_name;
376       *line_num = l;
377       return TRUE;
378     }
379   else
380     {
381       DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
382                               (long) addr, fname ? fname : "<unknown>", l,
383                               func_name ? func_name : "<unknown>"));
384       return FALSE;
385     }
386 }
387
388
389 /*
390  * Read in symbol table from core.  One symbol per function is
391  * entered.
392  */
393 void
394 DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
395 {
396   bfd_vma min_vma = ~0, max_vma = 0;
397   int class;
398   long i, j, found, skip;
399
400   /* pass 1 - determine upper bound on number of function names: */
401   symtab.len = 0;
402   for (i = 0; i < core_num_syms; ++i)
403     {
404       if (!core_sym_class (core_syms[i]))
405         {
406           continue;
407         }
408
409       /* This should be replaced with a binary search or hashed
410          search.  Gross. 
411
412          Don't create a symtab entry for a function that has
413          a mapping to a file, unless it's the first function
414          in the file.  */
415       skip = 0;
416       for (j = 0; j < symbol_map_count; j++)
417         if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
418           {
419             if (j > 0 && ! strcmp (symbol_map [j].file_name,
420                                    symbol_map [j - 1].file_name))
421               skip = 1;
422             break;
423           }
424       if (!skip)
425         ++symtab.len;
426     }
427
428   if (symtab.len == 0)
429     {
430       fprintf (stderr, "%s: file `%s' has no symbols\n", whoami, a_out_name);
431       done (1);
432     }
433
434   /* the "+ 2" is for the sentinels: */
435   symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
436
437   /* pass 2 - create symbols: */
438
439   symtab.limit = symtab.base;
440   for (i = 0; i < core_num_syms; ++i)
441     {
442       class = core_sym_class (core_syms[i]);
443       if (!class)
444         {
445           DBG (AOUTDEBUG,
446                printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
447                        core_syms[i]->value, core_syms[i]->name));
448           continue;
449         }
450       /* This should be replaced with a binary search or hashed
451          search.  Gross.   */
452
453       skip = 0;
454       found = 0;
455       for (j = 0; j < symbol_map_count; j++)
456         if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
457           {
458             if (j > 0 && ! strcmp (symbol_map [j].file_name,
459                                    symbol_map [j - 1].file_name))
460               skip = 1;
461             else
462               found = j;
463             break;
464           }
465
466       if (skip)
467         continue;
468
469       sym_init (symtab.limit);
470
471       /* symbol offsets are always section-relative: */
472
473       symtab.limit->addr = core_syms[i]->value + core_syms[i]->section->vma;
474       if (symbol_map_count
475           && !strcmp (core_syms[i]->name, symbol_map[found].function_name))
476         {
477           symtab.limit->name = symbol_map[found].file_name;
478           symtab.limit->mapped = 1;
479         }
480       else
481         {
482           symtab.limit->name = core_syms[i]->name;
483           symtab.limit->mapped = 0;
484         }
485
486       /* Lookup filename and line number, if we can */
487
488       {
489         const char *filename, *func_name;
490         
491         if (get_src_info (symtab.limit->addr, &filename, &func_name,
492                           &symtab.limit->line_num))
493           {
494             symtab.limit->file = source_file_lookup_path (filename);
495
496             /* FIXME: Checking __osf__ here does not work with a cross
497                gprof.  */
498 #ifdef __osf__
499             /*
500              * Suppress symbols that are not function names.  This is
501              * useful to suppress code-labels and aliases.
502              *
503              * This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
504              * labels do not appear in the symbol table info, so this isn't
505              * necessary.
506              */
507
508             if (strcmp (symtab.limit->name, func_name) != 0)
509               {
510                 /*
511                  * The symbol's address maps to a different name, so
512                  * it can't be a function-entry point.  This happens
513                  * for labels, for example.
514                  */
515                 DBG (AOUTDEBUG,
516                      printf ("[core_create_function_syms: rej %s (maps to %s)\n",
517                              symtab.limit->name, func_name));
518                 continue;
519               }
520 #endif
521           }
522       }
523
524       symtab.limit->is_func = TRUE;
525       symtab.limit->is_bb_head = TRUE;
526       if (class == 't')
527         {
528           symtab.limit->is_static = TRUE;
529         }
530
531       min_vma = MIN (symtab.limit->addr, min_vma);
532       max_vma = MAX (symtab.limit->addr, max_vma);
533
534       /*
535        * If we see "main" without an initial '_', we assume names
536        * are *not* prefixed by '_'.
537        */
538       if (symtab.limit->name[0] == 'm' && discard_underscores
539           && strcmp (symtab.limit->name, "main") == 0)
540         {
541           discard_underscores = 0;
542         }
543
544       DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
545                               (long) (symtab.limit - symtab.base),
546                               symtab.limit->name, symtab.limit->addr));
547       ++symtab.limit;
548     }
549
550   /* create sentinels: */
551
552   sym_init (symtab.limit);
553   symtab.limit->name = "<locore>";
554   symtab.limit->addr = 0;
555   symtab.limit->end_addr = min_vma - 1;
556   ++symtab.limit;
557
558   sym_init (symtab.limit);
559   symtab.limit->name = "<hicore>";
560   symtab.limit->addr = max_vma + 1;
561   symtab.limit->end_addr = ~0;
562   ++symtab.limit;
563
564   symtab.len = symtab.limit - symtab.base;
565   symtab_finalize (&symtab);
566 }
567
568
569 /*
570  * Read in symbol table from core.  One symbol per line of source code
571  * is entered.
572  */
573 void
574 DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
575 {
576   char prev_name[PATH_MAX], prev_filename[PATH_MAX];
577   bfd_vma vma, min_vma = ~0, max_vma = 0;
578   bfd_vma offset;
579   Sym *prev, dummy, *sentinel, *sym;
580   const char *filename;
581   int prev_line_num;
582   Sym_Table ltab;
583   /*
584    * Create symbols for functions as usual.  This is necessary in
585    * cases where parts of a program were not compiled with -g.  For
586    * those parts we still want to get info at the function level:
587    */
588   core_create_function_syms (core_bfd);
589
590   /* pass 1 - counter number of symbols: */
591
592   /*
593    * To find all line information, walk through all possible
594    * text-space addresses (one by one!) and get the debugging
595    * info for each address.  When the debugging info changes,
596    * it is time to create a new symbol.
597    *
598    * Of course, this is rather slow and it would be better if
599    * bfd would provide an iterator for enumerating all line infos
600    */
601   prev_name[0] = '\0';
602   ltab.len = 0;
603   prev_filename[0] = '\0';
604   prev_line_num = 0;
605   for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
606     {
607       vma = core_text_sect->vma + offset;
608       if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
609           || (prev_line_num == dummy.line_num &&
610               strcmp (prev_name, dummy.name) == 0
611               && strcmp (prev_filename, filename) == 0))
612         {
613           continue;
614         }
615
616       ++ltab.len;
617       prev_line_num = dummy.line_num;
618       strcpy (prev_name, dummy.name);
619       strcpy (prev_filename, filename);
620
621       min_vma = MIN (vma, min_vma);
622       max_vma = MAX (vma, max_vma);
623     }
624
625   /* make room for function symbols, too: */
626   ltab.len += symtab.len;
627   ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
628   ltab.limit = ltab.base;
629
630   /* pass 2 - create symbols: */
631
632   /* We now set is_static as we go along, rather than by running
633      through the symbol table at the end.
634
635      The old way called symtab_finalize before the is_static pass,
636      causing a problem since symtab_finalize uses is_static as part of
637      its address conflict resolution algorithm.  Since global symbols
638      were prefered over static symbols, and all line symbols were
639      global at that point, static function names that conflicted with
640      their own line numbers (static, but labeled as global) were
641      rejected in favor of the line num.
642
643      This was not the desired functionality.  We always want to keep
644      our function symbols and discard any conflicting line symbols.
645      Perhaps symtab_finalize should be modified to make this
646      distinction as well, but the current fix works and the code is a
647      lot cleaner now.  */
648
649   prev = 0;
650   for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
651     {
652       sym_init (ltab.limit);
653       if (!get_src_info (core_text_sect->vma + offset, &filename,
654                          &ltab.limit->name, &ltab.limit->line_num)
655           || (prev && prev->line_num == ltab.limit->line_num
656               && strcmp (prev->name, ltab.limit->name) == 0
657               && strcmp (prev->file->name, filename) == 0))
658         {
659           continue;
660         }
661
662       /* make name pointer a malloc'ed string: */
663       ltab.limit->name = xstrdup (ltab.limit->name);
664       ltab.limit->file = source_file_lookup_path (filename);
665
666       ltab.limit->addr = core_text_sect->vma + offset;
667
668       /* Set is_static based on the enclosing function, using either:
669        * 1) the previous symbol, if it's from the same function, or
670        * 2) a symtab lookup
671        */
672
673       if (prev && ltab.limit->file == prev->file &&
674           strcmp (ltab.limit->name, prev->name) == 0)
675         {
676           ltab.limit->is_static = prev->is_static;
677         }
678       else
679         {
680           sym = sym_lookup(&symtab, ltab.limit->addr);
681           ltab.limit->is_static = sym->is_static;
682         }
683
684       prev = ltab.limit;
685
686       /*
687        * If we see "main" without an initial '_', we assume names
688        * are *not* prefixed by '_'.
689        */
690       if (ltab.limit->name[0] == 'm' && discard_underscores
691           && strcmp (ltab.limit->name, "main") == 0)
692         {
693           discard_underscores = 0;
694         }
695
696       DBG (AOUTDEBUG, printf ("[core_create_line_syms] %d %s 0x%lx\n",
697                               ltab.limit - ltab.base, ltab.limit->name,
698                               ltab.limit->addr));
699       ++ltab.limit;
700     }
701
702   /* update sentinels: */
703
704   sentinel = sym_lookup (&symtab, 0);
705   if (strcmp (sentinel->name, "<locore>") == 0
706       && min_vma <= sentinel->end_addr)
707     {
708       sentinel->end_addr = min_vma - 1;
709     }
710
711   sentinel = sym_lookup (&symtab, ~0);
712   if (strcmp (sentinel->name, "<hicore>") == 0 && max_vma >= sentinel->addr)
713     {
714       sentinel->addr = max_vma + 1;
715     }
716
717   /* copy in function symbols: */
718   memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
719   ltab.limit += symtab.len;
720
721   if (ltab.limit - ltab.base != ltab.len)
722     {
723       fprintf (stderr,
724                "%s: somebody miscounted: ltab.len=%d instead of %ld\n",
725                whoami, ltab.len, (long) (ltab.limit - ltab.base));
726       done (1);
727     }
728
729   /* finalize ltab and make it symbol table: */
730
731   symtab_finalize (&ltab);
732   free (symtab.base);
733   symtab = ltab;
734
735 }