xref: /netbsd-src/external/gpl3/binutils/dist/gprof/corefile.c (revision dd7241df2fae9da4ea2bd20a68f001fa86ecf909)
1 /* corefile.c
2 
3    Copyright (C) 1999-2024 Free Software Foundation, Inc.
4 
5    This file is part of GNU Binutils.
6 
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 3 of the License, or
10    (at your option) any later version.
11 
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.
16 
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., 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, USA.  */
21 
22 #include "gprof.h"
23 #include "libiberty.h"
24 #include "filenames.h"
25 #include "search_list.h"
26 #include "source.h"
27 #include "symtab.h"
28 #include "hist.h"
29 #include "corefile.h"
30 #include "safe-ctype.h"
31 #include <limits.h>    /* For UINT_MAX.  */
32 
33 #include <stdlib.h>
34 
35 bfd *core_bfd;
36 static int core_num_syms;
37 static asymbol **core_syms;
38 asection *core_text_sect;
39 void * core_text_space;
40 
41 static int min_insn_size;
42 int offset_to_code;
43 
44 /* For mapping symbols to specific .o files during file ordering.  */
45 struct function_map * symbol_map;
46 unsigned int symbol_map_count;
47 
48 static void read_function_mappings (const char *);
49 static int core_sym_class (asymbol *);
50 static bool get_src_info
51   (bfd_vma, const char **, const char **, int *);
52 
53 extern void i386_find_call  (Sym *, bfd_vma, bfd_vma);
54 extern void alpha_find_call (Sym *, bfd_vma, bfd_vma);
55 extern void vax_find_call   (Sym *, bfd_vma, bfd_vma);
56 extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
57 extern void mips_find_call  (Sym *, bfd_vma, bfd_vma);
58 extern void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
59 
60 static void
parse_error(const char * filename)61 parse_error (const char *filename)
62 {
63   fprintf (stderr, _("%s: unable to parse mapping file %s.\n"), whoami, filename);
64   done (1);
65 }
66 
67 /* Compare two function_map structs based on function name.
68    We want to sort in ascending order.  */
69 
70 static int
cmp_symbol_map(const void * l,const void * r)71 cmp_symbol_map (const void * l, const void * r)
72 {
73   return strcmp (((struct function_map *) l)->function_name,
74 		 ((struct function_map *) r)->function_name);
75 }
76 
77 #define BUFSIZE      (1024)
78 /* This is BUFSIZE - 1 as a string.  Suitable for use in fprintf/sscanf format strings.  */
79 #define STR_BUFSIZE  "1023"
80 
81 static void
read_function_mappings(const char * filename)82 read_function_mappings (const char *filename)
83 {
84   FILE * file = fopen (filename, "r");
85   char dummy[BUFSIZE];
86   int count = 0;
87   unsigned int i;
88 
89   if (!file)
90     {
91       fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
92       done (1);
93     }
94 
95   /* First parse the mapping file so we know how big we need to
96      make our tables.  We also do some sanity checks at this
97      time.  */
98   while (!feof (file))
99     {
100       int matches;
101 
102       matches = fscanf (file, "%" STR_BUFSIZE "[^\n:]", dummy);
103       if (!matches)
104 	parse_error (filename);
105 
106       /* Just skip messages about files with no symbols.  */
107       if (!strncmp (dummy, "No symbols in ", 14))
108 	{
109 	  matches = fscanf (file, "\n");
110 	  if (matches == EOF)
111 	    parse_error (filename);
112 	  continue;
113 	}
114 
115       /* Don't care what else is on this line at this point.  */
116       matches = fscanf (file, "%" STR_BUFSIZE "[^\n]\n", dummy);
117       if (!matches)
118 	parse_error (filename);
119       count++;
120     }
121 
122   /* Now we know how big we need to make our table.  */
123   symbol_map = ((struct function_map *)
124 		xmalloc (count * sizeof (struct function_map)));
125 
126   /* Rewind the input file so we can read it again.  */
127   rewind (file);
128 
129   /* Read each entry and put it into the table.  */
130   count = 0;
131   while (!feof (file))
132     {
133       int matches;
134       char *tmp;
135 
136       matches = fscanf (file, "%" STR_BUFSIZE "[^\n:]", dummy);
137       if (!matches)
138 	parse_error (filename);
139 
140       /* Just skip messages about files with no symbols.  */
141       if (!strncmp (dummy, "No symbols in ", 14))
142 	{
143 	  matches = fscanf (file, "\n");
144 	  if (matches == EOF)
145 	    parse_error (filename);
146 	  continue;
147 	}
148 
149       /* dummy has the filename, go ahead and copy it.  */
150       symbol_map[count].file_name = (char *) xmalloc (strlen (dummy) + 1);
151       strcpy (symbol_map[count].file_name, dummy);
152 
153       /* Now we need the function name.  */
154       matches = fscanf (file, "%" STR_BUFSIZE "[^\n]\n", dummy);
155       if (!matches)
156 	parse_error (filename);
157       tmp = strrchr (dummy, ' ') + 1;
158       symbol_map[count].function_name = (char *) xmalloc (strlen (tmp) + 1);
159       strcpy (symbol_map[count].function_name, tmp);
160       count++;
161     }
162 
163   /* Record the size of the map table for future reference.  */
164   symbol_map_count = count;
165 
166   for (i = 0; i < symbol_map_count; ++i)
167     if (i == 0
168         || filename_cmp (symbol_map[i].file_name, symbol_map[i - 1].file_name))
169       symbol_map[i].is_first = 1;
170 
171   qsort (symbol_map, symbol_map_count, sizeof (struct function_map), cmp_symbol_map);
172 
173   fclose (file);
174 }
175 
176 void
core_init(const char * aout_name)177 core_init (const char * aout_name)
178 {
179   int core_sym_bytes;
180   asymbol *synthsyms;
181   long synth_count;
182 
183   core_bfd = bfd_openr (aout_name, 0);
184 
185   if (!core_bfd)
186     {
187       perror (aout_name);
188       done (1);
189     }
190 
191   core_bfd->flags |= BFD_DECOMPRESS;
192 
193   if (!bfd_check_format (core_bfd, bfd_object))
194     {
195       fprintf (stderr, _("%s: %s: not in executable format\n"), whoami, aout_name);
196       done (1);
197     }
198 
199   /* Get core's text section.  */
200   core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
201   if (!core_text_sect)
202     {
203       core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
204       if (!core_text_sect)
205 	{
206 	  fprintf (stderr, _("%s: can't find .text section in %s\n"),
207 		   whoami, aout_name);
208 	  done (1);
209 	}
210     }
211 
212   /* Read core's symbol table.  */
213 
214   /* This will probably give us more than we need, but that's ok.  */
215   core_sym_bytes = bfd_get_symtab_upper_bound (core_bfd);
216   if (core_sym_bytes < 0)
217     {
218       fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
219 	       bfd_errmsg (bfd_get_error ()));
220       done (1);
221     }
222 
223   core_syms = (asymbol **) xmalloc (core_sym_bytes);
224   core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
225 
226   if (core_num_syms < 0)
227     {
228       fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
229 	       bfd_errmsg (bfd_get_error ()));
230       done (1);
231     }
232 
233   synth_count = bfd_get_synthetic_symtab (core_bfd, core_num_syms, core_syms,
234 					  0, NULL, &synthsyms);
235   if (synth_count > 0)
236     {
237       asymbol **symp;
238       long new_size;
239       long i;
240 
241       new_size = (core_num_syms + synth_count + 1) * sizeof (*core_syms);
242       core_syms = (asymbol **) xrealloc (core_syms, new_size);
243       symp = core_syms + core_num_syms;
244       core_num_syms += synth_count;
245       for (i = 0; i < synth_count; i++)
246 	*symp++ = synthsyms + i;
247       *symp = 0;
248     }
249 
250   min_insn_size = 1;
251   offset_to_code = 0;
252 
253   switch (bfd_get_arch (core_bfd))
254     {
255     case bfd_arch_vax:
256       offset_to_code = 2;
257       break;
258 
259     case bfd_arch_alpha:
260       min_insn_size = 4;
261       break;
262 
263     default:
264       break;
265     }
266 
267   if (function_mapping_file)
268     read_function_mappings (function_mapping_file);
269 }
270 
271 /* Read in the text space of an a.out file.  */
272 
273 void
core_get_text_space(bfd * cbfd)274 core_get_text_space (bfd *cbfd)
275 {
276   core_text_space = malloc (bfd_section_size (core_text_sect));
277 
278   if (!core_text_space)
279     {
280       fprintf (stderr, _("%s: ran out room for %lu bytes of text space\n"),
281 	       whoami, (unsigned long) bfd_section_size (core_text_sect));
282       done (1);
283     }
284 
285   if (!bfd_get_section_contents (cbfd, core_text_sect, core_text_space,
286 				 0, bfd_section_size (core_text_sect)))
287     {
288       bfd_perror ("bfd_get_section_contents");
289       free (core_text_space);
290       core_text_space = 0;
291     }
292 
293   if (!core_text_space)
294     fprintf (stderr, _("%s: can't do -c\n"), whoami);
295 }
296 
297 
298 void
find_call(Sym * parent,bfd_vma p_lowpc,bfd_vma p_highpc)299 find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
300 {
301   if (core_text_space == 0)
302     return;
303 
304   hist_clip_symbol_address (&p_lowpc, &p_highpc);
305 
306   switch (bfd_get_arch (core_bfd))
307     {
308     case bfd_arch_i386:
309       i386_find_call (parent, p_lowpc, p_highpc);
310       break;
311 
312     case bfd_arch_alpha:
313       alpha_find_call (parent, p_lowpc, p_highpc);
314       break;
315 
316     case bfd_arch_vax:
317       vax_find_call (parent, p_lowpc, p_highpc);
318       break;
319 
320     case bfd_arch_sparc:
321       sparc_find_call (parent, p_lowpc, p_highpc);
322       break;
323 
324     case bfd_arch_mips:
325       mips_find_call (parent, p_lowpc, p_highpc);
326       break;
327 
328     case bfd_arch_aarch64:
329       aarch64_find_call (parent, p_lowpc, p_highpc);
330       break;
331 
332     default:
333       fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
334 	       whoami, bfd_printable_name(core_bfd));
335 
336       /* Don't give the error more than once.  */
337       ignore_direct_calls = false;
338     }
339 }
340 
341 /* Return class of symbol SYM.  The returned class can be any of:
342 	0   -> symbol is not interesting to us
343 	'T' -> symbol is a global name
344 	't' -> symbol is a local (static) name.  */
345 
346 static int
core_sym_class(asymbol * sym)347 core_sym_class (asymbol *sym)
348 {
349   symbol_info syminfo;
350   const char *name;
351   char sym_prefix;
352   int i;
353 
354   if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
355     return 0;
356 
357   /* Must be a text symbol, and static text symbols
358      don't qualify if ignore_static_funcs set.   */
359   if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
360     {
361       DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
362 			      sym->name));
363       return 0;
364     }
365 
366   bfd_get_symbol_info (core_bfd, sym, &syminfo);
367   i = syminfo.type;
368 
369   if (i == 'T')
370     return i;			/* It's a global symbol.  */
371 
372   if (i == 'W')
373     /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
374        also be a data symbol.  */
375     return 'T';
376 
377   if (i != 't')
378     {
379       /* Not a static text symbol.  */
380       DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
381 			      sym->name, i));
382       return 0;
383     }
384 
385   /* Do some more filtering on static function-names.  */
386   if (ignore_static_funcs)
387     return 0;
388 
389   /* Can't zero-length name or funny characters in name, where
390      `funny' includes: `.' (.o file names) and `$' (Pascal labels).  */
391   if (!sym->name || sym->name[0] == '\0')
392     return 0;
393 
394   for (name = sym->name; *name; ++name)
395     {
396       if (*name == '$')
397         return 0;
398 
399       while (*name == '.')
400 	{
401 	  /* Allow both nested subprograms (which end with ".NNN", where N is
402 	     a digit) and GCC cloned functions (which contain ".clone").
403 	     Allow for multiple iterations of both - apparently GCC can clone
404 	     clones and subprograms.  */
405 	  int digit_seen = 0;
406 #define CLONE_NAME	    ".clone."
407 #define CLONE_NAME_LEN	    strlen (CLONE_NAME)
408 #define CONSTPROP_NAME	    ".constprop."
409 #define CONSTPROP_NAME_LEN  strlen (CONSTPROP_NAME)
410 
411 	  if (strlen (name) > CLONE_NAME_LEN
412 	      && strncmp (name, CLONE_NAME, CLONE_NAME_LEN) == 0)
413 	    name += CLONE_NAME_LEN - 1;
414 
415 	  else if (strlen (name) > CONSTPROP_NAME_LEN
416 	      && strncmp (name, CONSTPROP_NAME, CONSTPROP_NAME_LEN) == 0)
417 	    name += CONSTPROP_NAME_LEN - 1;
418 
419 	  for (name++; *name; name++)
420 	    if (digit_seen && *name == '.')
421 	      break;
422 	    else if (ISDIGIT (*name))
423 	      digit_seen = 1;
424 	    else
425 	      return 0;
426 	}
427     }
428 
429   /* On systems where the C compiler adds an underscore to all
430      names, static names without underscores seem usually to be
431      labels in hand written assembler in the library.  We don't want
432      these names.  This is certainly necessary on a Sparc running
433      SunOS 4.1 (try profiling a program that does a lot of
434      division). I don't know whether it has harmful side effects on
435      other systems.  Perhaps it should be made configurable.  */
436   sym_prefix = bfd_get_symbol_leading_char (core_bfd);
437 
438   if ((sym_prefix && sym_prefix != sym->name[0])
439       /* GCC may add special symbols to help gdb figure out the file
440 	language.  We want to ignore these, since sometimes they mask
441 	the real function.  (dj@ctron)  */
442       || !strncmp (sym->name, "__gnu_compiled", 14)
443       || !strncmp (sym->name, "___gnu_compiled", 15))
444     {
445       return 0;
446     }
447 
448   /* If the object file supports marking of function symbols, then
449      we can zap anything that doesn't have BSF_FUNCTION set.  */
450   if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
451     return 0;
452 
453   return 't';			/* It's a static text symbol.  */
454 }
455 
456 /* Get whatever source info we can get regarding address ADDR.  */
457 
458 static bool
get_src_info(bfd_vma addr,const char ** filename,const char ** name,int * line_num)459 get_src_info (bfd_vma addr, const char **filename, const char **name,
460 	      int *line_num)
461 {
462   const char *fname = 0, *func_name = 0;
463   int l = 0;
464 
465   if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
466 			     addr - core_text_sect->vma,
467 			     &fname, &func_name, (unsigned int *) &l)
468       && fname && func_name && l)
469     {
470       DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
471 			      (unsigned long) addr, fname, l, func_name));
472       *filename = fname;
473       *name = func_name;
474       *line_num = l;
475       return true;
476     }
477   else
478     {
479       DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
480 			      (unsigned long) addr,
481 			      fname ? fname : "<unknown>", l,
482 			      func_name ? func_name : "<unknown>"));
483       return false;
484     }
485 }
486 
487 static char buf[BUFSIZE];
488 static char address[BUFSIZE];
489 static char name[BUFSIZE];
490 
491 /* Return number of symbols in a symbol-table file.  */
492 
493 static unsigned int
num_of_syms_in(FILE * f)494 num_of_syms_in (FILE * f)
495 {
496   char   type;
497   unsigned int num = 0;
498 
499   while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
500     {
501       if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) == 3)
502         if (type == 't' || type == 'T')
503 	  {
504 	    /* PR 20499 - prevent integer overflow computing argument to xmalloc.  */
505 	    if (++num >= UINT_MAX / sizeof (Sym))
506 	      return -1U;
507 	  }
508     }
509 
510   return num;
511 }
512 
513 /* Read symbol table from a file.  */
514 
515 void
core_create_syms_from(const char * sym_table_file)516 core_create_syms_from (const char * sym_table_file)
517 {
518   char type;
519   bfd_vma min_vma = ~(bfd_vma) 0;
520   bfd_vma max_vma = 0;
521   FILE * f;
522 
523   f = fopen (sym_table_file, "r");
524   if (!f)
525     {
526       fprintf (stderr, _("%s: could not open %s.\n"), whoami, sym_table_file);
527       done (1);
528     }
529 
530   /* Pass 1 - determine upper bound on number of function names.  */
531   symtab.len = num_of_syms_in (f);
532 
533   if (symtab.len == 0)
534     {
535       fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, sym_table_file);
536       done (1);
537     }
538   else if (symtab.len == -1U)
539     {
540       fprintf (stderr, _("%s: file `%s' has too many symbols\n"),
541 	       whoami, sym_table_file);
542       done (1);
543     }
544 
545   symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
546 
547   /* Pass 2 - create symbols.  */
548   symtab.limit = symtab.base;
549 
550   if (fseek (f, 0, SEEK_SET) != 0)
551     {
552       perror (sym_table_file);
553       done (1);
554     }
555 
556   while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
557     {
558       if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) != 3)
559 	continue;
560       if (type != 't' && type != 'T')
561 	continue;
562 
563       sym_init (symtab.limit);
564 
565       uint64_t addr;
566       sscanf (address, "%" SCNx64, &addr);
567       symtab.limit->addr = addr;
568 
569       symtab.limit->name = (char *) xmalloc (strlen (name) + 1);
570       strcpy ((char *) symtab.limit->name, name);
571       symtab.limit->mapped = 0;
572       symtab.limit->is_func = true;
573       symtab.limit->is_bb_head = true;
574       symtab.limit->is_static = (type == 't');
575       min_vma = MIN (symtab.limit->addr, min_vma);
576       max_vma = MAX (symtab.limit->addr, max_vma);
577 
578       ++symtab.limit;
579     }
580   fclose (f);
581 
582   symtab.len = symtab.limit - symtab.base;
583   symtab_finalize (&symtab);
584 }
585 
586 static int
search_mapped_symbol(const void * l,const void * r)587 search_mapped_symbol (const void * l, const void * r)
588 {
589     return strcmp ((const char *) l, ((const struct function_map *) r)->function_name);
590 }
591 
592 /* Read in symbol table from core.
593    One symbol per function is entered.  */
594 
595 void
core_create_function_syms(void)596 core_create_function_syms (void)
597 {
598   bfd_vma min_vma = ~ (bfd_vma) 0;
599   bfd_vma max_vma = 0;
600   int cxxclass;
601   long i;
602   struct function_map * found = NULL;
603   int core_has_func_syms = 0;
604 
605   switch (core_bfd->xvec->flavour)
606     {
607     default:
608       break;
609     case bfd_target_coff_flavour:
610     case bfd_target_ecoff_flavour:
611     case bfd_target_xcoff_flavour:
612     case bfd_target_elf_flavour:
613     case bfd_target_som_flavour:
614       core_has_func_syms = 1;
615     }
616 
617   /* Pass 1 - determine upper bound on number of function names.  */
618   symtab.len = 0;
619 
620   for (i = 0; i < core_num_syms; ++i)
621     {
622       if (!core_sym_class (core_syms[i]))
623 	continue;
624 
625       /* Don't create a symtab entry for a function that has
626 	 a mapping to a file, unless it's the first function
627 	 in the file.  */
628       if (symbol_map_count != 0)
629 	{
630 	  /* Note: some systems (SunOS 5.8) crash if bsearch base argument
631 	     is NULL.  */
632 	  found = (struct function_map *) bsearch
633 	    (core_syms[i]->name, symbol_map, symbol_map_count,
634 	     sizeof (struct function_map), search_mapped_symbol);
635 	}
636       if (found == NULL || found->is_first)
637 	++symtab.len;
638     }
639 
640   if (symtab.len == 0)
641     {
642       fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
643       done (1);
644     }
645 
646   symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
647 
648   /* Pass 2 - create symbols.  */
649   symtab.limit = symtab.base;
650 
651   for (i = 0; i < core_num_syms; ++i)
652     {
653       asection *sym_sec;
654 
655       cxxclass = core_sym_class (core_syms[i]);
656 
657       if (!cxxclass)
658 	{
659 	  DBG (AOUTDEBUG,
660 	       printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
661 		       (unsigned long) core_syms[i]->value,
662 		       core_syms[i]->name));
663 	  continue;
664 	}
665 
666       if (symbol_map_count != 0)
667 	{
668 	  /* Note: some systems (SunOS 5.8) crash if bsearch base argument
669 	     is NULL.  */
670 	  found = (struct function_map *) bsearch
671 	    (core_syms[i]->name, symbol_map, symbol_map_count,
672 	     sizeof (struct function_map), search_mapped_symbol);
673 	}
674       if (found && ! found->is_first)
675 	continue;
676 
677       sym_init (symtab.limit);
678 
679       /* Symbol offsets are always section-relative.  */
680       sym_sec = core_syms[i]->section;
681       symtab.limit->addr = core_syms[i]->value;
682       if (sym_sec)
683 	symtab.limit->addr += bfd_section_vma (sym_sec);
684 
685       if (found)
686 	{
687 	  symtab.limit->name = found->file_name;
688 	  symtab.limit->mapped = 1;
689 	}
690       else
691 	{
692 	  symtab.limit->name = core_syms[i]->name;
693 	  symtab.limit->mapped = 0;
694 	}
695 
696       /* Lookup filename and line number, if we can.  */
697       {
698 	const char * filename;
699 	const char * func_name;
700 
701 	if (get_src_info (symtab.limit->addr, & filename, & func_name,
702 			  & symtab.limit->line_num))
703 	  {
704 	    symtab.limit->file = source_file_lookup_path (filename);
705 
706 	    /* FIXME: Checking __osf__ here does not work with a cross
707 	       gprof.  */
708 #ifdef __osf__
709 	    /* Suppress symbols that are not function names.  This is
710 	       useful to suppress code-labels and aliases.
711 
712 	       This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
713 	       labels do not appear in the symbol table info, so this isn't
714 	       necessary.  */
715 
716 	    if (strcmp (symtab.limit->name, func_name) != 0)
717 	      {
718 		/* The symbol's address maps to a different name, so
719 		   it can't be a function-entry point.  This happens
720 		   for labels, for example.  */
721 		DBG (AOUTDEBUG,
722 		     printf ("[core_create_function_syms: rej %s (maps to %s)\n",
723 			     symtab.limit->name, func_name));
724 		continue;
725 	      }
726 #endif
727 	  }
728       }
729 
730       symtab.limit->is_func = (!core_has_func_syms
731 			       || (core_syms[i]->flags & BSF_FUNCTION) != 0);
732       symtab.limit->is_bb_head = true;
733 
734       if (cxxclass == 't')
735 	symtab.limit->is_static = true;
736 
737       /* Keep track of the minimum and maximum vma addresses used by all
738 	 symbols.  When computing the max_vma, use the ending address of the
739 	 section containing the symbol, if available.  */
740       min_vma = MIN (symtab.limit->addr, min_vma);
741       if (sym_sec)
742 	max_vma = MAX (bfd_section_vma (sym_sec)
743 		       + bfd_section_size (sym_sec) - 1,
744 		       max_vma);
745       else
746 	max_vma = MAX (symtab.limit->addr, max_vma);
747 
748       DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
749 			      (long) (symtab.limit - symtab.base),
750 			      symtab.limit->name,
751 			      (unsigned long) symtab.limit->addr));
752       ++symtab.limit;
753     }
754 
755   symtab.len = symtab.limit - symtab.base;
756   symtab_finalize (&symtab);
757 }
758 
759 /* Read in symbol table from core.
760    One symbol per line of source code is entered.  */
761 
762 void
core_create_line_syms(void)763 core_create_line_syms (void)
764 {
765   char *prev_name, *prev_filename;
766   unsigned int prev_name_len, prev_filename_len;
767   bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0;
768   Sym *prev, dummy, *sym;
769   const char *filename;
770   int prev_line_num;
771   Sym_Table ltab;
772   bfd_vma vma_high;
773 
774   /* Create symbols for functions as usual.  This is necessary in
775      cases where parts of a program were not compiled with -g.  For
776      those parts we still want to get info at the function level.  */
777   core_create_function_syms ();
778 
779   /* Pass 1: count the number of symbols.  */
780 
781   /* To find all line information, walk through all possible
782      text-space addresses (one by one!) and get the debugging
783      info for each address.  When the debugging info changes,
784      it is time to create a new symbol.
785 
786      Of course, this is rather slow and it would be better if
787      BFD would provide an iterator for enumerating all line infos.  */
788   prev_name_len = 1024;
789   prev_filename_len = 1024;
790   prev_name = (char *) xmalloc (prev_name_len);
791   prev_filename = (char *) xmalloc (prev_filename_len);
792   ltab.len = 0;
793   prev_line_num = 0;
794 
795   vma_high = core_text_sect->vma + bfd_section_size (core_text_sect);
796   for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
797     {
798       unsigned int len;
799 
800       if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
801 	  || (prev_line_num == dummy.line_num
802 	      && prev_name != NULL
803 	      && strcmp (prev_name, dummy.name) == 0
804 	      && filename_cmp (prev_filename, filename) == 0))
805 	continue;
806 
807       ++ltab.len;
808       prev_line_num = dummy.line_num;
809 
810       len = strlen (dummy.name);
811       if (len >= prev_name_len)
812 	{
813 	  prev_name_len = len + 1024;
814 	  free (prev_name);
815 	  prev_name = (char *) xmalloc (prev_name_len);
816 	}
817 
818       strcpy (prev_name, dummy.name);
819       len = strlen (filename);
820 
821       if (len >= prev_filename_len)
822 	{
823 	  prev_filename_len = len + 1024;
824 	  free (prev_filename);
825 	  prev_filename = (char *) xmalloc (prev_filename_len);
826 	}
827 
828       strcpy (prev_filename, filename);
829 
830       min_vma = MIN (vma, min_vma);
831       max_vma = MAX (vma, max_vma);
832     }
833 
834   free (prev_name);
835   free (prev_filename);
836 
837   /* Make room for function symbols, too.  */
838   ltab.len += symtab.len;
839   ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
840   ltab.limit = ltab.base;
841 
842   /* Pass 2 - create symbols.  */
843 
844   /* We now set is_static as we go along, rather than by running
845      through the symbol table at the end.
846 
847      The old way called symtab_finalize before the is_static pass,
848      causing a problem since symtab_finalize uses is_static as part of
849      its address conflict resolution algorithm.  Since global symbols
850      were preferred over static symbols, and all line symbols were
851      global at that point, static function names that conflicted with
852      their own line numbers (static, but labeled as global) were
853      rejected in favor of the line num.
854 
855      This was not the desired functionality.  We always want to keep
856      our function symbols and discard any conflicting line symbols.
857      Perhaps symtab_finalize should be modified to make this
858      distinction as well, but the current fix works and the code is a
859      lot cleaner now.  */
860   prev = 0;
861 
862   for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
863     {
864       sym_init (ltab.limit);
865 
866       if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
867 	  || (prev && prev->line_num == ltab.limit->line_num
868 	      && strcmp (prev->name, ltab.limit->name) == 0
869 	      && filename_cmp (prev->file->name, filename) == 0))
870 	continue;
871 
872       /* Make name pointer a malloc'ed string.  */
873       ltab.limit->name = xstrdup (ltab.limit->name);
874       ltab.limit->file = source_file_lookup_path (filename);
875 
876       ltab.limit->addr = vma;
877 
878       /* Set is_static based on the enclosing function, using either:
879 	 1) the previous symbol, if it's from the same function, or
880 	 2) a symtab lookup.  */
881       if (prev && ltab.limit->file == prev->file &&
882 	  strcmp (ltab.limit->name, prev->name) == 0)
883 	{
884 	  ltab.limit->is_static = prev->is_static;
885 	}
886       else
887 	{
888 	  sym = sym_lookup(&symtab, ltab.limit->addr);
889           if (sym)
890 	    ltab.limit->is_static = sym->is_static;
891 	}
892 
893       prev = ltab.limit;
894 
895       DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
896 			      (unsigned long) (ltab.limit - ltab.base),
897 			      ltab.limit->name,
898 			      (unsigned long) ltab.limit->addr));
899       ++ltab.limit;
900     }
901 
902   /* Copy in function symbols.  */
903   memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
904   ltab.limit += symtab.len;
905 
906   if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
907     {
908       fprintf (stderr,
909 	       _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
910 	       whoami, ltab.len, (long) (ltab.limit - ltab.base));
911       done (1);
912     }
913 
914   /* Finalize ltab and make it symbol table.  */
915   symtab_finalize (&ltab);
916   free (symtab.base);
917   symtab = ltab;
918 }
919