xref: /netbsd-src/external/gpl3/binutils/dist/gprof/corefile.c (revision dd7241df2fae9da4ea2bd20a68f001fa86ecf909)
12a6b7db3Sskrll /* corefile.c
22a6b7db3Sskrll 
3*dd7241dfSchristos    Copyright (C) 1999-2024 Free Software Foundation, Inc.
42a6b7db3Sskrll 
52a6b7db3Sskrll    This file is part of GNU Binutils.
62a6b7db3Sskrll 
72a6b7db3Sskrll    This program is free software; you can redistribute it and/or modify
82a6b7db3Sskrll    it under the terms of the GNU General Public License as published by
92a6b7db3Sskrll    the Free Software Foundation; either version 3 of the License, or
102a6b7db3Sskrll    (at your option) any later version.
112a6b7db3Sskrll 
122a6b7db3Sskrll    This program is distributed in the hope that it will be useful,
132a6b7db3Sskrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
142a6b7db3Sskrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152a6b7db3Sskrll    GNU General Public License for more details.
162a6b7db3Sskrll 
172a6b7db3Sskrll    You should have received a copy of the GNU General Public License
182a6b7db3Sskrll    along with this program; if not, write to the Free Software
192a6b7db3Sskrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
202a6b7db3Sskrll    02110-1301, USA.  */
212a6b7db3Sskrll 
222a6b7db3Sskrll #include "gprof.h"
232a6b7db3Sskrll #include "libiberty.h"
24b410d692Schristos #include "filenames.h"
252a6b7db3Sskrll #include "search_list.h"
262a6b7db3Sskrll #include "source.h"
272a6b7db3Sskrll #include "symtab.h"
282a6b7db3Sskrll #include "hist.h"
292a6b7db3Sskrll #include "corefile.h"
302a6b7db3Sskrll #include "safe-ctype.h"
316f226886Schristos #include <limits.h>    /* For UINT_MAX.  */
322a6b7db3Sskrll 
33abf07352Sskrll #include <stdlib.h>
34abf07352Sskrll 
352a6b7db3Sskrll bfd *core_bfd;
362a6b7db3Sskrll static int core_num_syms;
372a6b7db3Sskrll static asymbol **core_syms;
382a6b7db3Sskrll asection *core_text_sect;
3932998b1cSchristos void * core_text_space;
402a6b7db3Sskrll 
412a6b7db3Sskrll static int min_insn_size;
422a6b7db3Sskrll int offset_to_code;
432a6b7db3Sskrll 
442a6b7db3Sskrll /* For mapping symbols to specific .o files during file ordering.  */
452a6b7db3Sskrll struct function_map * symbol_map;
462a6b7db3Sskrll unsigned int symbol_map_count;
472a6b7db3Sskrll 
482a6b7db3Sskrll static void read_function_mappings (const char *);
492a6b7db3Sskrll static int core_sym_class (asymbol *);
5003f5171aSchristos static bool get_src_info
512a6b7db3Sskrll   (bfd_vma, const char **, const char **, int *);
522a6b7db3Sskrll 
532a6b7db3Sskrll extern void i386_find_call  (Sym *, bfd_vma, bfd_vma);
542a6b7db3Sskrll extern void alpha_find_call (Sym *, bfd_vma, bfd_vma);
552a6b7db3Sskrll extern void vax_find_call   (Sym *, bfd_vma, bfd_vma);
562a6b7db3Sskrll extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
572a6b7db3Sskrll extern void mips_find_call  (Sym *, bfd_vma, bfd_vma);
585f4eaf39Schristos extern void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
592a6b7db3Sskrll 
602a6b7db3Sskrll static void
parse_error(const char * filename)612a6b7db3Sskrll parse_error (const char *filename)
622a6b7db3Sskrll {
632a6b7db3Sskrll   fprintf (stderr, _("%s: unable to parse mapping file %s.\n"), whoami, filename);
642a6b7db3Sskrll   done (1);
652a6b7db3Sskrll }
662a6b7db3Sskrll 
6732998b1cSchristos /* Compare two function_map structs based on function name.
6832998b1cSchristos    We want to sort in ascending order.  */
6932998b1cSchristos 
7032998b1cSchristos static int
cmp_symbol_map(const void * l,const void * r)7132998b1cSchristos cmp_symbol_map (const void * l, const void * r)
7232998b1cSchristos {
7332998b1cSchristos   return strcmp (((struct function_map *) l)->function_name,
7432998b1cSchristos 		 ((struct function_map *) r)->function_name);
7532998b1cSchristos }
7632998b1cSchristos 
776f226886Schristos #define BUFSIZE      (1024)
786f226886Schristos /* This is BUFSIZE - 1 as a string.  Suitable for use in fprintf/sscanf format strings.  */
796f226886Schristos #define STR_BUFSIZE  "1023"
806f226886Schristos 
812a6b7db3Sskrll static void
read_function_mappings(const char * filename)822a6b7db3Sskrll read_function_mappings (const char *filename)
832a6b7db3Sskrll {
842a6b7db3Sskrll   FILE * file = fopen (filename, "r");
856f226886Schristos   char dummy[BUFSIZE];
862a6b7db3Sskrll   int count = 0;
8732998b1cSchristos   unsigned int i;
882a6b7db3Sskrll 
892a6b7db3Sskrll   if (!file)
902a6b7db3Sskrll     {
912a6b7db3Sskrll       fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
922a6b7db3Sskrll       done (1);
932a6b7db3Sskrll     }
942a6b7db3Sskrll 
952a6b7db3Sskrll   /* First parse the mapping file so we know how big we need to
962a6b7db3Sskrll      make our tables.  We also do some sanity checks at this
972a6b7db3Sskrll      time.  */
982a6b7db3Sskrll   while (!feof (file))
992a6b7db3Sskrll     {
1002a6b7db3Sskrll       int matches;
1012a6b7db3Sskrll 
1026f226886Schristos       matches = fscanf (file, "%" STR_BUFSIZE "[^\n:]", dummy);
1032a6b7db3Sskrll       if (!matches)
1042a6b7db3Sskrll 	parse_error (filename);
1052a6b7db3Sskrll 
1062a6b7db3Sskrll       /* Just skip messages about files with no symbols.  */
1072a6b7db3Sskrll       if (!strncmp (dummy, "No symbols in ", 14))
1082a6b7db3Sskrll 	{
1092a6b7db3Sskrll 	  matches = fscanf (file, "\n");
1102a6b7db3Sskrll 	  if (matches == EOF)
1112a6b7db3Sskrll 	    parse_error (filename);
1122a6b7db3Sskrll 	  continue;
1132a6b7db3Sskrll 	}
1142a6b7db3Sskrll 
1152a6b7db3Sskrll       /* Don't care what else is on this line at this point.  */
1166f226886Schristos       matches = fscanf (file, "%" STR_BUFSIZE "[^\n]\n", dummy);
1172a6b7db3Sskrll       if (!matches)
1182a6b7db3Sskrll 	parse_error (filename);
1192a6b7db3Sskrll       count++;
1202a6b7db3Sskrll     }
1212a6b7db3Sskrll 
1222a6b7db3Sskrll   /* Now we know how big we need to make our table.  */
1232a6b7db3Sskrll   symbol_map = ((struct function_map *)
1242a6b7db3Sskrll 		xmalloc (count * sizeof (struct function_map)));
1252a6b7db3Sskrll 
1262a6b7db3Sskrll   /* Rewind the input file so we can read it again.  */
1272a6b7db3Sskrll   rewind (file);
1282a6b7db3Sskrll 
1292a6b7db3Sskrll   /* Read each entry and put it into the table.  */
1302a6b7db3Sskrll   count = 0;
1312a6b7db3Sskrll   while (!feof (file))
1322a6b7db3Sskrll     {
1332a6b7db3Sskrll       int matches;
1342a6b7db3Sskrll       char *tmp;
1352a6b7db3Sskrll 
1366f226886Schristos       matches = fscanf (file, "%" STR_BUFSIZE "[^\n:]", dummy);
1372a6b7db3Sskrll       if (!matches)
1382a6b7db3Sskrll 	parse_error (filename);
1392a6b7db3Sskrll 
1402a6b7db3Sskrll       /* Just skip messages about files with no symbols.  */
1412a6b7db3Sskrll       if (!strncmp (dummy, "No symbols in ", 14))
1422a6b7db3Sskrll 	{
1432a6b7db3Sskrll 	  matches = fscanf (file, "\n");
1442a6b7db3Sskrll 	  if (matches == EOF)
1452a6b7db3Sskrll 	    parse_error (filename);
1462a6b7db3Sskrll 	  continue;
1472a6b7db3Sskrll 	}
1482a6b7db3Sskrll 
1492a6b7db3Sskrll       /* dummy has the filename, go ahead and copy it.  */
15032998b1cSchristos       symbol_map[count].file_name = (char *) xmalloc (strlen (dummy) + 1);
1512a6b7db3Sskrll       strcpy (symbol_map[count].file_name, dummy);
1522a6b7db3Sskrll 
1532a6b7db3Sskrll       /* Now we need the function name.  */
1546f226886Schristos       matches = fscanf (file, "%" STR_BUFSIZE "[^\n]\n", dummy);
1552a6b7db3Sskrll       if (!matches)
1562a6b7db3Sskrll 	parse_error (filename);
1572a6b7db3Sskrll       tmp = strrchr (dummy, ' ') + 1;
15832998b1cSchristos       symbol_map[count].function_name = (char *) xmalloc (strlen (tmp) + 1);
1592a6b7db3Sskrll       strcpy (symbol_map[count].function_name, tmp);
1602a6b7db3Sskrll       count++;
1612a6b7db3Sskrll     }
1622a6b7db3Sskrll 
1632a6b7db3Sskrll   /* Record the size of the map table for future reference.  */
1642a6b7db3Sskrll   symbol_map_count = count;
1652a6b7db3Sskrll 
16632998b1cSchristos   for (i = 0; i < symbol_map_count; ++i)
167b410d692Schristos     if (i == 0
168b410d692Schristos         || filename_cmp (symbol_map[i].file_name, symbol_map[i - 1].file_name))
16932998b1cSchristos       symbol_map[i].is_first = 1;
17032998b1cSchristos 
17132998b1cSchristos   qsort (symbol_map, symbol_map_count, sizeof (struct function_map), cmp_symbol_map);
1725f4eaf39Schristos 
1735f4eaf39Schristos   fclose (file);
17432998b1cSchristos }
1752a6b7db3Sskrll 
1762a6b7db3Sskrll void
core_init(const char * aout_name)1772a6b7db3Sskrll core_init (const char * aout_name)
1782a6b7db3Sskrll {
1792a6b7db3Sskrll   int core_sym_bytes;
1802a6b7db3Sskrll   asymbol *synthsyms;
1812a6b7db3Sskrll   long synth_count;
1822a6b7db3Sskrll 
1832a6b7db3Sskrll   core_bfd = bfd_openr (aout_name, 0);
1842a6b7db3Sskrll 
1852a6b7db3Sskrll   if (!core_bfd)
1862a6b7db3Sskrll     {
1872a6b7db3Sskrll       perror (aout_name);
1882a6b7db3Sskrll       done (1);
1892a6b7db3Sskrll     }
1902a6b7db3Sskrll 
191106c59e5Schristos   core_bfd->flags |= BFD_DECOMPRESS;
192106c59e5Schristos 
1932a6b7db3Sskrll   if (!bfd_check_format (core_bfd, bfd_object))
1942a6b7db3Sskrll     {
1952a6b7db3Sskrll       fprintf (stderr, _("%s: %s: not in executable format\n"), whoami, aout_name);
1962a6b7db3Sskrll       done (1);
1972a6b7db3Sskrll     }
1982a6b7db3Sskrll 
1992a6b7db3Sskrll   /* Get core's text section.  */
2002a6b7db3Sskrll   core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
2012a6b7db3Sskrll   if (!core_text_sect)
2022a6b7db3Sskrll     {
2032a6b7db3Sskrll       core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
2042a6b7db3Sskrll       if (!core_text_sect)
2052a6b7db3Sskrll 	{
2062a6b7db3Sskrll 	  fprintf (stderr, _("%s: can't find .text section in %s\n"),
2072a6b7db3Sskrll 		   whoami, aout_name);
2082a6b7db3Sskrll 	  done (1);
2092a6b7db3Sskrll 	}
2102a6b7db3Sskrll     }
2112a6b7db3Sskrll 
2122a6b7db3Sskrll   /* Read core's symbol table.  */
2132a6b7db3Sskrll 
2142a6b7db3Sskrll   /* This will probably give us more than we need, but that's ok.  */
2152a6b7db3Sskrll   core_sym_bytes = bfd_get_symtab_upper_bound (core_bfd);
2162a6b7db3Sskrll   if (core_sym_bytes < 0)
2172a6b7db3Sskrll     {
2182a6b7db3Sskrll       fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
2192a6b7db3Sskrll 	       bfd_errmsg (bfd_get_error ()));
2202a6b7db3Sskrll       done (1);
2212a6b7db3Sskrll     }
2222a6b7db3Sskrll 
2232a6b7db3Sskrll   core_syms = (asymbol **) xmalloc (core_sym_bytes);
2242a6b7db3Sskrll   core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
2252a6b7db3Sskrll 
2262a6b7db3Sskrll   if (core_num_syms < 0)
2272a6b7db3Sskrll     {
2282a6b7db3Sskrll       fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
2292a6b7db3Sskrll 	       bfd_errmsg (bfd_get_error ()));
2302a6b7db3Sskrll       done (1);
2312a6b7db3Sskrll     }
2322a6b7db3Sskrll 
2332a6b7db3Sskrll   synth_count = bfd_get_synthetic_symtab (core_bfd, core_num_syms, core_syms,
2342a6b7db3Sskrll 					  0, NULL, &synthsyms);
2352a6b7db3Sskrll   if (synth_count > 0)
2362a6b7db3Sskrll     {
2372a6b7db3Sskrll       asymbol **symp;
2382a6b7db3Sskrll       long new_size;
2392a6b7db3Sskrll       long i;
2402a6b7db3Sskrll 
2412a6b7db3Sskrll       new_size = (core_num_syms + synth_count + 1) * sizeof (*core_syms);
24232998b1cSchristos       core_syms = (asymbol **) xrealloc (core_syms, new_size);
2432a6b7db3Sskrll       symp = core_syms + core_num_syms;
2442a6b7db3Sskrll       core_num_syms += synth_count;
2452a6b7db3Sskrll       for (i = 0; i < synth_count; i++)
2462a6b7db3Sskrll 	*symp++ = synthsyms + i;
2472a6b7db3Sskrll       *symp = 0;
2482a6b7db3Sskrll     }
2492a6b7db3Sskrll 
2502a6b7db3Sskrll   min_insn_size = 1;
2512a6b7db3Sskrll   offset_to_code = 0;
2522a6b7db3Sskrll 
2532a6b7db3Sskrll   switch (bfd_get_arch (core_bfd))
2542a6b7db3Sskrll     {
2552a6b7db3Sskrll     case bfd_arch_vax:
2562a6b7db3Sskrll       offset_to_code = 2;
2572a6b7db3Sskrll       break;
2582a6b7db3Sskrll 
2592a6b7db3Sskrll     case bfd_arch_alpha:
2602a6b7db3Sskrll       min_insn_size = 4;
2612a6b7db3Sskrll       break;
2622a6b7db3Sskrll 
2632a6b7db3Sskrll     default:
2642a6b7db3Sskrll       break;
2652a6b7db3Sskrll     }
2662a6b7db3Sskrll 
2672a6b7db3Sskrll   if (function_mapping_file)
2682a6b7db3Sskrll     read_function_mappings (function_mapping_file);
2692a6b7db3Sskrll }
2702a6b7db3Sskrll 
2712a6b7db3Sskrll /* Read in the text space of an a.out file.  */
2722a6b7db3Sskrll 
2732a6b7db3Sskrll void
core_get_text_space(bfd * cbfd)2742a6b7db3Sskrll core_get_text_space (bfd *cbfd)
2752a6b7db3Sskrll {
276106c59e5Schristos   core_text_space = malloc (bfd_section_size (core_text_sect));
2772a6b7db3Sskrll 
2782a6b7db3Sskrll   if (!core_text_space)
2792a6b7db3Sskrll     {
2802a6b7db3Sskrll       fprintf (stderr, _("%s: ran out room for %lu bytes of text space\n"),
281106c59e5Schristos 	       whoami, (unsigned long) bfd_section_size (core_text_sect));
2822a6b7db3Sskrll       done (1);
2832a6b7db3Sskrll     }
2842a6b7db3Sskrll 
2852a6b7db3Sskrll   if (!bfd_get_section_contents (cbfd, core_text_sect, core_text_space,
286106c59e5Schristos 				 0, bfd_section_size (core_text_sect)))
2872a6b7db3Sskrll     {
2882a6b7db3Sskrll       bfd_perror ("bfd_get_section_contents");
2892a6b7db3Sskrll       free (core_text_space);
2902a6b7db3Sskrll       core_text_space = 0;
2912a6b7db3Sskrll     }
2922a6b7db3Sskrll 
2932a6b7db3Sskrll   if (!core_text_space)
2942a6b7db3Sskrll     fprintf (stderr, _("%s: can't do -c\n"), whoami);
2952a6b7db3Sskrll }
2962a6b7db3Sskrll 
2972a6b7db3Sskrll 
2982a6b7db3Sskrll void
find_call(Sym * parent,bfd_vma p_lowpc,bfd_vma p_highpc)2992a6b7db3Sskrll find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
3002a6b7db3Sskrll {
3012a6b7db3Sskrll   if (core_text_space == 0)
3022a6b7db3Sskrll     return;
3032a6b7db3Sskrll 
3042a6b7db3Sskrll   hist_clip_symbol_address (&p_lowpc, &p_highpc);
3052a6b7db3Sskrll 
3062a6b7db3Sskrll   switch (bfd_get_arch (core_bfd))
3072a6b7db3Sskrll     {
3082a6b7db3Sskrll     case bfd_arch_i386:
3092a6b7db3Sskrll       i386_find_call (parent, p_lowpc, p_highpc);
3102a6b7db3Sskrll       break;
3112a6b7db3Sskrll 
3122a6b7db3Sskrll     case bfd_arch_alpha:
3132a6b7db3Sskrll       alpha_find_call (parent, p_lowpc, p_highpc);
3142a6b7db3Sskrll       break;
3152a6b7db3Sskrll 
3162a6b7db3Sskrll     case bfd_arch_vax:
3172a6b7db3Sskrll       vax_find_call (parent, p_lowpc, p_highpc);
3182a6b7db3Sskrll       break;
3192a6b7db3Sskrll 
3202a6b7db3Sskrll     case bfd_arch_sparc:
3212a6b7db3Sskrll       sparc_find_call (parent, p_lowpc, p_highpc);
3222a6b7db3Sskrll       break;
3232a6b7db3Sskrll 
3242a6b7db3Sskrll     case bfd_arch_mips:
3252a6b7db3Sskrll       mips_find_call (parent, p_lowpc, p_highpc);
3262a6b7db3Sskrll       break;
3272a6b7db3Sskrll 
3285f4eaf39Schristos     case bfd_arch_aarch64:
3295f4eaf39Schristos       aarch64_find_call (parent, p_lowpc, p_highpc);
3305f4eaf39Schristos       break;
3315f4eaf39Schristos 
3322a6b7db3Sskrll     default:
3332a6b7db3Sskrll       fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
3342a6b7db3Sskrll 	       whoami, bfd_printable_name(core_bfd));
3352a6b7db3Sskrll 
3362a6b7db3Sskrll       /* Don't give the error more than once.  */
33703f5171aSchristos       ignore_direct_calls = false;
3382a6b7db3Sskrll     }
3392a6b7db3Sskrll }
3402a6b7db3Sskrll 
3412a6b7db3Sskrll /* Return class of symbol SYM.  The returned class can be any of:
3422a6b7db3Sskrll 	0   -> symbol is not interesting to us
3432a6b7db3Sskrll 	'T' -> symbol is a global name
3442a6b7db3Sskrll 	't' -> symbol is a local (static) name.  */
3452a6b7db3Sskrll 
3462a6b7db3Sskrll static int
core_sym_class(asymbol * sym)3472a6b7db3Sskrll core_sym_class (asymbol *sym)
3482a6b7db3Sskrll {
3492a6b7db3Sskrll   symbol_info syminfo;
3502a6b7db3Sskrll   const char *name;
3512a6b7db3Sskrll   char sym_prefix;
3522a6b7db3Sskrll   int i;
3532a6b7db3Sskrll 
3542a6b7db3Sskrll   if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
3552a6b7db3Sskrll     return 0;
3562a6b7db3Sskrll 
3572a6b7db3Sskrll   /* Must be a text symbol, and static text symbols
3582a6b7db3Sskrll      don't qualify if ignore_static_funcs set.   */
3592a6b7db3Sskrll   if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
3602a6b7db3Sskrll     {
3612a6b7db3Sskrll       DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
3622a6b7db3Sskrll 			      sym->name));
3632a6b7db3Sskrll       return 0;
3642a6b7db3Sskrll     }
3652a6b7db3Sskrll 
3662a6b7db3Sskrll   bfd_get_symbol_info (core_bfd, sym, &syminfo);
3672a6b7db3Sskrll   i = syminfo.type;
3682a6b7db3Sskrll 
3692a6b7db3Sskrll   if (i == 'T')
3702a6b7db3Sskrll     return i;			/* It's a global symbol.  */
3712a6b7db3Sskrll 
3722a6b7db3Sskrll   if (i == 'W')
3732a6b7db3Sskrll     /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
3742a6b7db3Sskrll        also be a data symbol.  */
3752a6b7db3Sskrll     return 'T';
3762a6b7db3Sskrll 
3772a6b7db3Sskrll   if (i != 't')
3782a6b7db3Sskrll     {
3792a6b7db3Sskrll       /* Not a static text symbol.  */
3802a6b7db3Sskrll       DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
3812a6b7db3Sskrll 			      sym->name, i));
3822a6b7db3Sskrll       return 0;
3832a6b7db3Sskrll     }
3842a6b7db3Sskrll 
3852a6b7db3Sskrll   /* Do some more filtering on static function-names.  */
3862a6b7db3Sskrll   if (ignore_static_funcs)
3872a6b7db3Sskrll     return 0;
3882a6b7db3Sskrll 
3892a6b7db3Sskrll   /* Can't zero-length name or funny characters in name, where
3902a6b7db3Sskrll      `funny' includes: `.' (.o file names) and `$' (Pascal labels).  */
3912a6b7db3Sskrll   if (!sym->name || sym->name[0] == '\0')
3922a6b7db3Sskrll     return 0;
3932a6b7db3Sskrll 
3942a6b7db3Sskrll   for (name = sym->name; *name; ++name)
3952a6b7db3Sskrll     {
3962a6b7db3Sskrll       if (*name == '$')
3972a6b7db3Sskrll         return 0;
3982a6b7db3Sskrll 
399b410d692Schristos       while (*name == '.')
40032998b1cSchristos 	{
401b410d692Schristos 	  /* Allow both nested subprograms (which end with ".NNN", where N is
402b410d692Schristos 	     a digit) and GCC cloned functions (which contain ".clone").
403b410d692Schristos 	     Allow for multiple iterations of both - apparently GCC can clone
404b410d692Schristos 	     clones and subprograms.  */
405b410d692Schristos 	  int digit_seen = 0;
406b410d692Schristos #define CLONE_NAME	    ".clone."
407b410d692Schristos #define CLONE_NAME_LEN	    strlen (CLONE_NAME)
4085f4eaf39Schristos #define CONSTPROP_NAME	    ".constprop."
4095f4eaf39Schristos #define CONSTPROP_NAME_LEN  strlen (CONSTPROP_NAME)
41032998b1cSchristos 
411b410d692Schristos 	  if (strlen (name) > CLONE_NAME_LEN
412b410d692Schristos 	      && strncmp (name, CLONE_NAME, CLONE_NAME_LEN) == 0)
413b410d692Schristos 	    name += CLONE_NAME_LEN - 1;
414b410d692Schristos 
4155f4eaf39Schristos 	  else if (strlen (name) > CONSTPROP_NAME_LEN
4165f4eaf39Schristos 	      && strncmp (name, CONSTPROP_NAME, CONSTPROP_NAME_LEN) == 0)
4175f4eaf39Schristos 	    name += CONSTPROP_NAME_LEN - 1;
4185f4eaf39Schristos 
4192a6b7db3Sskrll 	  for (name++; *name; name++)
420b410d692Schristos 	    if (digit_seen && *name == '.')
42132998b1cSchristos 	      break;
422b410d692Schristos 	    else if (ISDIGIT (*name))
423b410d692Schristos 	      digit_seen = 1;
424b410d692Schristos 	    else
425b410d692Schristos 	      return 0;
42632998b1cSchristos 	}
4272a6b7db3Sskrll     }
4282a6b7db3Sskrll 
4292a6b7db3Sskrll   /* On systems where the C compiler adds an underscore to all
4302a6b7db3Sskrll      names, static names without underscores seem usually to be
4312a6b7db3Sskrll      labels in hand written assembler in the library.  We don't want
4322a6b7db3Sskrll      these names.  This is certainly necessary on a Sparc running
4332a6b7db3Sskrll      SunOS 4.1 (try profiling a program that does a lot of
4342a6b7db3Sskrll      division). I don't know whether it has harmful side effects on
4352a6b7db3Sskrll      other systems.  Perhaps it should be made configurable.  */
4362a6b7db3Sskrll   sym_prefix = bfd_get_symbol_leading_char (core_bfd);
4372a6b7db3Sskrll 
4382a6b7db3Sskrll   if ((sym_prefix && sym_prefix != sym->name[0])
4392a6b7db3Sskrll       /* GCC may add special symbols to help gdb figure out the file
4402a6b7db3Sskrll 	language.  We want to ignore these, since sometimes they mask
4412a6b7db3Sskrll 	the real function.  (dj@ctron)  */
4422a6b7db3Sskrll       || !strncmp (sym->name, "__gnu_compiled", 14)
4432a6b7db3Sskrll       || !strncmp (sym->name, "___gnu_compiled", 15))
4442a6b7db3Sskrll     {
4452a6b7db3Sskrll       return 0;
4462a6b7db3Sskrll     }
4472a6b7db3Sskrll 
4482a6b7db3Sskrll   /* If the object file supports marking of function symbols, then
4492a6b7db3Sskrll      we can zap anything that doesn't have BSF_FUNCTION set.  */
4502a6b7db3Sskrll   if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
4512a6b7db3Sskrll     return 0;
4522a6b7db3Sskrll 
4532a6b7db3Sskrll   return 't';			/* It's a static text symbol.  */
4542a6b7db3Sskrll }
4552a6b7db3Sskrll 
4562a6b7db3Sskrll /* Get whatever source info we can get regarding address ADDR.  */
4572a6b7db3Sskrll 
45803f5171aSchristos static bool
get_src_info(bfd_vma addr,const char ** filename,const char ** name,int * line_num)45903f5171aSchristos get_src_info (bfd_vma addr, const char **filename, const char **name,
46003f5171aSchristos 	      int *line_num)
4612a6b7db3Sskrll {
4622a6b7db3Sskrll   const char *fname = 0, *func_name = 0;
4632a6b7db3Sskrll   int l = 0;
4642a6b7db3Sskrll 
4652a6b7db3Sskrll   if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
4662a6b7db3Sskrll 			     addr - core_text_sect->vma,
4672a6b7db3Sskrll 			     &fname, &func_name, (unsigned int *) &l)
4682a6b7db3Sskrll       && fname && func_name && l)
4692a6b7db3Sskrll     {
4702a6b7db3Sskrll       DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
4712a6b7db3Sskrll 			      (unsigned long) addr, fname, l, func_name));
4722a6b7db3Sskrll       *filename = fname;
4732a6b7db3Sskrll       *name = func_name;
4742a6b7db3Sskrll       *line_num = l;
47503f5171aSchristos       return true;
4762a6b7db3Sskrll     }
4772a6b7db3Sskrll   else
4782a6b7db3Sskrll     {
4792a6b7db3Sskrll       DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
4802a6b7db3Sskrll 			      (unsigned long) addr,
4812a6b7db3Sskrll 			      fname ? fname : "<unknown>", l,
4822a6b7db3Sskrll 			      func_name ? func_name : "<unknown>"));
48303f5171aSchristos       return false;
4842a6b7db3Sskrll     }
4852a6b7db3Sskrll }
4862a6b7db3Sskrll 
4876f226886Schristos static char buf[BUFSIZE];
4886f226886Schristos static char address[BUFSIZE];
4896f226886Schristos static char name[BUFSIZE];
4906f226886Schristos 
49132998b1cSchristos /* Return number of symbols in a symbol-table file.  */
49232998b1cSchristos 
4936f226886Schristos static unsigned int
num_of_syms_in(FILE * f)49432998b1cSchristos num_of_syms_in (FILE * f)
49532998b1cSchristos {
49632998b1cSchristos   char   type;
4976f226886Schristos   unsigned int num = 0;
49832998b1cSchristos 
49932998b1cSchristos   while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
50032998b1cSchristos     {
5016f226886Schristos       if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) == 3)
50232998b1cSchristos         if (type == 't' || type == 'T')
5036f226886Schristos 	  {
5046f226886Schristos 	    /* PR 20499 - prevent integer overflow computing argument to xmalloc.  */
5056f226886Schristos 	    if (++num >= UINT_MAX / sizeof (Sym))
5066f226886Schristos 	      return -1U;
50732998b1cSchristos 	  }
5086f226886Schristos     }
50932998b1cSchristos 
51032998b1cSchristos   return num;
51132998b1cSchristos }
51232998b1cSchristos 
51332998b1cSchristos /* Read symbol table from a file.  */
51432998b1cSchristos 
51532998b1cSchristos void
core_create_syms_from(const char * sym_table_file)51632998b1cSchristos core_create_syms_from (const char * sym_table_file)
51732998b1cSchristos {
51832998b1cSchristos   char type;
51932998b1cSchristos   bfd_vma min_vma = ~(bfd_vma) 0;
52032998b1cSchristos   bfd_vma max_vma = 0;
52132998b1cSchristos   FILE * f;
52232998b1cSchristos 
52332998b1cSchristos   f = fopen (sym_table_file, "r");
52432998b1cSchristos   if (!f)
52532998b1cSchristos     {
52632998b1cSchristos       fprintf (stderr, _("%s: could not open %s.\n"), whoami, sym_table_file);
52732998b1cSchristos       done (1);
52832998b1cSchristos     }
52932998b1cSchristos 
53032998b1cSchristos   /* Pass 1 - determine upper bound on number of function names.  */
53132998b1cSchristos   symtab.len = num_of_syms_in (f);
53232998b1cSchristos 
53332998b1cSchristos   if (symtab.len == 0)
53432998b1cSchristos     {
53532998b1cSchristos       fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, sym_table_file);
53632998b1cSchristos       done (1);
53732998b1cSchristos     }
5386f226886Schristos   else if (symtab.len == -1U)
5396f226886Schristos     {
5406f226886Schristos       fprintf (stderr, _("%s: file `%s' has too many symbols\n"),
5416f226886Schristos 	       whoami, sym_table_file);
5426f226886Schristos       done (1);
5436f226886Schristos     }
54432998b1cSchristos 
54532998b1cSchristos   symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
54632998b1cSchristos 
54732998b1cSchristos   /* Pass 2 - create symbols.  */
54832998b1cSchristos   symtab.limit = symtab.base;
54932998b1cSchristos 
55032998b1cSchristos   if (fseek (f, 0, SEEK_SET) != 0)
55132998b1cSchristos     {
55232998b1cSchristos       perror (sym_table_file);
55332998b1cSchristos       done (1);
55432998b1cSchristos     }
55532998b1cSchristos 
55632998b1cSchristos   while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
55732998b1cSchristos     {
5586f226886Schristos       if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) != 3)
5596f226886Schristos 	continue;
56032998b1cSchristos       if (type != 't' && type != 'T')
56132998b1cSchristos 	continue;
56232998b1cSchristos 
56332998b1cSchristos       sym_init (symtab.limit);
56432998b1cSchristos 
565*dd7241dfSchristos       uint64_t addr;
566*dd7241dfSchristos       sscanf (address, "%" SCNx64, &addr);
567*dd7241dfSchristos       symtab.limit->addr = addr;
56832998b1cSchristos 
56932998b1cSchristos       symtab.limit->name = (char *) xmalloc (strlen (name) + 1);
57032998b1cSchristos       strcpy ((char *) symtab.limit->name, name);
57132998b1cSchristos       symtab.limit->mapped = 0;
57203f5171aSchristos       symtab.limit->is_func = true;
57303f5171aSchristos       symtab.limit->is_bb_head = true;
57432998b1cSchristos       symtab.limit->is_static = (type == 't');
57532998b1cSchristos       min_vma = MIN (symtab.limit->addr, min_vma);
57632998b1cSchristos       max_vma = MAX (symtab.limit->addr, max_vma);
57732998b1cSchristos 
57832998b1cSchristos       ++symtab.limit;
57932998b1cSchristos     }
58032998b1cSchristos   fclose (f);
58132998b1cSchristos 
58232998b1cSchristos   symtab.len = symtab.limit - symtab.base;
58332998b1cSchristos   symtab_finalize (&symtab);
58432998b1cSchristos }
58532998b1cSchristos 
58632998b1cSchristos static int
search_mapped_symbol(const void * l,const void * r)58732998b1cSchristos search_mapped_symbol (const void * l, const void * r)
58832998b1cSchristos {
58932998b1cSchristos     return strcmp ((const char *) l, ((const struct function_map *) r)->function_name);
59032998b1cSchristos }
59132998b1cSchristos 
5922a6b7db3Sskrll /* Read in symbol table from core.
5932a6b7db3Sskrll    One symbol per function is entered.  */
5942a6b7db3Sskrll 
5952a6b7db3Sskrll void
core_create_function_syms(void)59632998b1cSchristos core_create_function_syms (void)
5972a6b7db3Sskrll {
5982a6b7db3Sskrll   bfd_vma min_vma = ~ (bfd_vma) 0;
5992a6b7db3Sskrll   bfd_vma max_vma = 0;
60032998b1cSchristos   int cxxclass;
60132998b1cSchristos   long i;
602b410d692Schristos   struct function_map * found = NULL;
60332998b1cSchristos   int core_has_func_syms = 0;
60432998b1cSchristos 
60532998b1cSchristos   switch (core_bfd->xvec->flavour)
60632998b1cSchristos     {
60732998b1cSchristos     default:
60832998b1cSchristos       break;
60932998b1cSchristos     case bfd_target_coff_flavour:
61032998b1cSchristos     case bfd_target_ecoff_flavour:
61132998b1cSchristos     case bfd_target_xcoff_flavour:
61232998b1cSchristos     case bfd_target_elf_flavour:
61332998b1cSchristos     case bfd_target_som_flavour:
61432998b1cSchristos       core_has_func_syms = 1;
61532998b1cSchristos     }
6162a6b7db3Sskrll 
6172a6b7db3Sskrll   /* Pass 1 - determine upper bound on number of function names.  */
6182a6b7db3Sskrll   symtab.len = 0;
6192a6b7db3Sskrll 
6202a6b7db3Sskrll   for (i = 0; i < core_num_syms; ++i)
6212a6b7db3Sskrll     {
6222a6b7db3Sskrll       if (!core_sym_class (core_syms[i]))
6232a6b7db3Sskrll 	continue;
6242a6b7db3Sskrll 
62532998b1cSchristos       /* Don't create a symtab entry for a function that has
6262a6b7db3Sskrll 	 a mapping to a file, unless it's the first function
6272a6b7db3Sskrll 	 in the file.  */
628b410d692Schristos       if (symbol_map_count != 0)
629b410d692Schristos 	{
630b410d692Schristos 	  /* Note: some systems (SunOS 5.8) crash if bsearch base argument
631b410d692Schristos 	     is NULL.  */
632b410d692Schristos 	  found = (struct function_map *) bsearch
633b410d692Schristos 	    (core_syms[i]->name, symbol_map, symbol_map_count,
634b410d692Schristos 	     sizeof (struct function_map), search_mapped_symbol);
635b410d692Schristos 	}
63632998b1cSchristos       if (found == NULL || found->is_first)
6372a6b7db3Sskrll 	++symtab.len;
6382a6b7db3Sskrll     }
6392a6b7db3Sskrll 
6402a6b7db3Sskrll   if (symtab.len == 0)
6412a6b7db3Sskrll     {
6422a6b7db3Sskrll       fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
6432a6b7db3Sskrll       done (1);
6442a6b7db3Sskrll     }
6452a6b7db3Sskrll 
64632998b1cSchristos   symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
6472a6b7db3Sskrll 
6482a6b7db3Sskrll   /* Pass 2 - create symbols.  */
6492a6b7db3Sskrll   symtab.limit = symtab.base;
6502a6b7db3Sskrll 
6512a6b7db3Sskrll   for (i = 0; i < core_num_syms; ++i)
6522a6b7db3Sskrll     {
6532a6b7db3Sskrll       asection *sym_sec;
6542a6b7db3Sskrll 
65532998b1cSchristos       cxxclass = core_sym_class (core_syms[i]);
6562a6b7db3Sskrll 
65732998b1cSchristos       if (!cxxclass)
6582a6b7db3Sskrll 	{
6592a6b7db3Sskrll 	  DBG (AOUTDEBUG,
6602a6b7db3Sskrll 	       printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
6612a6b7db3Sskrll 		       (unsigned long) core_syms[i]->value,
6622a6b7db3Sskrll 		       core_syms[i]->name));
6632a6b7db3Sskrll 	  continue;
6642a6b7db3Sskrll 	}
6652a6b7db3Sskrll 
666b410d692Schristos       if (symbol_map_count != 0)
667b410d692Schristos 	{
668b410d692Schristos 	  /* Note: some systems (SunOS 5.8) crash if bsearch base argument
669b410d692Schristos 	     is NULL.  */
670b410d692Schristos 	  found = (struct function_map *) bsearch
671b410d692Schristos 	    (core_syms[i]->name, symbol_map, symbol_map_count,
67232998b1cSchristos 	     sizeof (struct function_map), search_mapped_symbol);
673b410d692Schristos 	}
67432998b1cSchristos       if (found && ! found->is_first)
6752a6b7db3Sskrll 	continue;
6762a6b7db3Sskrll 
6772a6b7db3Sskrll       sym_init (symtab.limit);
6782a6b7db3Sskrll 
6792a6b7db3Sskrll       /* Symbol offsets are always section-relative.  */
6802a6b7db3Sskrll       sym_sec = core_syms[i]->section;
6812a6b7db3Sskrll       symtab.limit->addr = core_syms[i]->value;
6822a6b7db3Sskrll       if (sym_sec)
683106c59e5Schristos 	symtab.limit->addr += bfd_section_vma (sym_sec);
6842a6b7db3Sskrll 
68532998b1cSchristos       if (found)
6862a6b7db3Sskrll 	{
68732998b1cSchristos 	  symtab.limit->name = found->file_name;
6882a6b7db3Sskrll 	  symtab.limit->mapped = 1;
6892a6b7db3Sskrll 	}
6902a6b7db3Sskrll       else
6912a6b7db3Sskrll 	{
6922a6b7db3Sskrll 	  symtab.limit->name = core_syms[i]->name;
6932a6b7db3Sskrll 	  symtab.limit->mapped = 0;
6942a6b7db3Sskrll 	}
6952a6b7db3Sskrll 
6962a6b7db3Sskrll       /* Lookup filename and line number, if we can.  */
6972a6b7db3Sskrll       {
69832998b1cSchristos 	const char * filename;
69932998b1cSchristos 	const char * func_name;
7002a6b7db3Sskrll 
7012a6b7db3Sskrll 	if (get_src_info (symtab.limit->addr, & filename, & func_name,
7022a6b7db3Sskrll 			  & symtab.limit->line_num))
7032a6b7db3Sskrll 	  {
7042a6b7db3Sskrll 	    symtab.limit->file = source_file_lookup_path (filename);
7052a6b7db3Sskrll 
7062a6b7db3Sskrll 	    /* FIXME: Checking __osf__ here does not work with a cross
7072a6b7db3Sskrll 	       gprof.  */
7082a6b7db3Sskrll #ifdef __osf__
7092a6b7db3Sskrll 	    /* Suppress symbols that are not function names.  This is
7102a6b7db3Sskrll 	       useful to suppress code-labels and aliases.
7112a6b7db3Sskrll 
7122a6b7db3Sskrll 	       This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
7132a6b7db3Sskrll 	       labels do not appear in the symbol table info, so this isn't
7142a6b7db3Sskrll 	       necessary.  */
7152a6b7db3Sskrll 
7162a6b7db3Sskrll 	    if (strcmp (symtab.limit->name, func_name) != 0)
7172a6b7db3Sskrll 	      {
7182a6b7db3Sskrll 		/* The symbol's address maps to a different name, so
7192a6b7db3Sskrll 		   it can't be a function-entry point.  This happens
7202a6b7db3Sskrll 		   for labels, for example.  */
7212a6b7db3Sskrll 		DBG (AOUTDEBUG,
7222a6b7db3Sskrll 		     printf ("[core_create_function_syms: rej %s (maps to %s)\n",
7232a6b7db3Sskrll 			     symtab.limit->name, func_name));
7242a6b7db3Sskrll 		continue;
7252a6b7db3Sskrll 	      }
7262a6b7db3Sskrll #endif
7272a6b7db3Sskrll 	  }
7282a6b7db3Sskrll       }
7292a6b7db3Sskrll 
73032998b1cSchristos       symtab.limit->is_func = (!core_has_func_syms
73132998b1cSchristos 			       || (core_syms[i]->flags & BSF_FUNCTION) != 0);
73203f5171aSchristos       symtab.limit->is_bb_head = true;
7332a6b7db3Sskrll 
73432998b1cSchristos       if (cxxclass == 't')
73503f5171aSchristos 	symtab.limit->is_static = true;
7362a6b7db3Sskrll 
7372a6b7db3Sskrll       /* Keep track of the minimum and maximum vma addresses used by all
7382a6b7db3Sskrll 	 symbols.  When computing the max_vma, use the ending address of the
7392a6b7db3Sskrll 	 section containing the symbol, if available.  */
7402a6b7db3Sskrll       min_vma = MIN (symtab.limit->addr, min_vma);
7412a6b7db3Sskrll       if (sym_sec)
742106c59e5Schristos 	max_vma = MAX (bfd_section_vma (sym_sec)
743106c59e5Schristos 		       + bfd_section_size (sym_sec) - 1,
7442a6b7db3Sskrll 		       max_vma);
7452a6b7db3Sskrll       else
7462a6b7db3Sskrll 	max_vma = MAX (symtab.limit->addr, max_vma);
7472a6b7db3Sskrll 
7482a6b7db3Sskrll       DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
7492a6b7db3Sskrll 			      (long) (symtab.limit - symtab.base),
7502a6b7db3Sskrll 			      symtab.limit->name,
7512a6b7db3Sskrll 			      (unsigned long) symtab.limit->addr));
7522a6b7db3Sskrll       ++symtab.limit;
7532a6b7db3Sskrll     }
7542a6b7db3Sskrll 
7552a6b7db3Sskrll   symtab.len = symtab.limit - symtab.base;
7562a6b7db3Sskrll   symtab_finalize (&symtab);
7572a6b7db3Sskrll }
7582a6b7db3Sskrll 
7592a6b7db3Sskrll /* Read in symbol table from core.
7602a6b7db3Sskrll    One symbol per line of source code is entered.  */
7612a6b7db3Sskrll 
7622a6b7db3Sskrll void
core_create_line_syms(void)76332998b1cSchristos core_create_line_syms (void)
7642a6b7db3Sskrll {
7652a6b7db3Sskrll   char *prev_name, *prev_filename;
7662a6b7db3Sskrll   unsigned int prev_name_len, prev_filename_len;
7672a6b7db3Sskrll   bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0;
76832998b1cSchristos   Sym *prev, dummy, *sym;
7692a6b7db3Sskrll   const char *filename;
7702a6b7db3Sskrll   int prev_line_num;
7712a6b7db3Sskrll   Sym_Table ltab;
7722a6b7db3Sskrll   bfd_vma vma_high;
7732a6b7db3Sskrll 
7742a6b7db3Sskrll   /* Create symbols for functions as usual.  This is necessary in
7752a6b7db3Sskrll      cases where parts of a program were not compiled with -g.  For
7762a6b7db3Sskrll      those parts we still want to get info at the function level.  */
7772a6b7db3Sskrll   core_create_function_syms ();
7782a6b7db3Sskrll 
7792a6b7db3Sskrll   /* Pass 1: count the number of symbols.  */
7802a6b7db3Sskrll 
7812a6b7db3Sskrll   /* To find all line information, walk through all possible
7822a6b7db3Sskrll      text-space addresses (one by one!) and get the debugging
7832a6b7db3Sskrll      info for each address.  When the debugging info changes,
7842a6b7db3Sskrll      it is time to create a new symbol.
7852a6b7db3Sskrll 
7862a6b7db3Sskrll      Of course, this is rather slow and it would be better if
7872a6b7db3Sskrll      BFD would provide an iterator for enumerating all line infos.  */
78803f5171aSchristos   prev_name_len = 1024;
78903f5171aSchristos   prev_filename_len = 1024;
79032998b1cSchristos   prev_name = (char *) xmalloc (prev_name_len);
79132998b1cSchristos   prev_filename = (char *) xmalloc (prev_filename_len);
7922a6b7db3Sskrll   ltab.len = 0;
7932a6b7db3Sskrll   prev_line_num = 0;
7942a6b7db3Sskrll 
795106c59e5Schristos   vma_high = core_text_sect->vma + bfd_section_size (core_text_sect);
7962a6b7db3Sskrll   for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
7972a6b7db3Sskrll     {
7982a6b7db3Sskrll       unsigned int len;
7992a6b7db3Sskrll 
8002a6b7db3Sskrll       if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
8012a6b7db3Sskrll 	  || (prev_line_num == dummy.line_num
8022a6b7db3Sskrll 	      && prev_name != NULL
8032a6b7db3Sskrll 	      && strcmp (prev_name, dummy.name) == 0
804b410d692Schristos 	      && filename_cmp (prev_filename, filename) == 0))
8052a6b7db3Sskrll 	continue;
8062a6b7db3Sskrll 
8072a6b7db3Sskrll       ++ltab.len;
8082a6b7db3Sskrll       prev_line_num = dummy.line_num;
8092a6b7db3Sskrll 
8102a6b7db3Sskrll       len = strlen (dummy.name);
8112a6b7db3Sskrll       if (len >= prev_name_len)
8122a6b7db3Sskrll 	{
8132a6b7db3Sskrll 	  prev_name_len = len + 1024;
8142a6b7db3Sskrll 	  free (prev_name);
81532998b1cSchristos 	  prev_name = (char *) xmalloc (prev_name_len);
8162a6b7db3Sskrll 	}
8172a6b7db3Sskrll 
8182a6b7db3Sskrll       strcpy (prev_name, dummy.name);
8192a6b7db3Sskrll       len = strlen (filename);
8202a6b7db3Sskrll 
8212a6b7db3Sskrll       if (len >= prev_filename_len)
8222a6b7db3Sskrll 	{
8232a6b7db3Sskrll 	  prev_filename_len = len + 1024;
8242a6b7db3Sskrll 	  free (prev_filename);
82532998b1cSchristos 	  prev_filename = (char *) xmalloc (prev_filename_len);
8262a6b7db3Sskrll 	}
8272a6b7db3Sskrll 
8282a6b7db3Sskrll       strcpy (prev_filename, filename);
8292a6b7db3Sskrll 
8302a6b7db3Sskrll       min_vma = MIN (vma, min_vma);
8312a6b7db3Sskrll       max_vma = MAX (vma, max_vma);
8322a6b7db3Sskrll     }
8332a6b7db3Sskrll 
8342a6b7db3Sskrll   free (prev_name);
8352a6b7db3Sskrll   free (prev_filename);
8362a6b7db3Sskrll 
8372a6b7db3Sskrll   /* Make room for function symbols, too.  */
8382a6b7db3Sskrll   ltab.len += symtab.len;
8392a6b7db3Sskrll   ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
8402a6b7db3Sskrll   ltab.limit = ltab.base;
8412a6b7db3Sskrll 
8422a6b7db3Sskrll   /* Pass 2 - create symbols.  */
8432a6b7db3Sskrll 
8442a6b7db3Sskrll   /* We now set is_static as we go along, rather than by running
8452a6b7db3Sskrll      through the symbol table at the end.
8462a6b7db3Sskrll 
8472a6b7db3Sskrll      The old way called symtab_finalize before the is_static pass,
8482a6b7db3Sskrll      causing a problem since symtab_finalize uses is_static as part of
8492a6b7db3Sskrll      its address conflict resolution algorithm.  Since global symbols
8506f226886Schristos      were preferred over static symbols, and all line symbols were
8512a6b7db3Sskrll      global at that point, static function names that conflicted with
8522a6b7db3Sskrll      their own line numbers (static, but labeled as global) were
8532a6b7db3Sskrll      rejected in favor of the line num.
8542a6b7db3Sskrll 
8552a6b7db3Sskrll      This was not the desired functionality.  We always want to keep
8562a6b7db3Sskrll      our function symbols and discard any conflicting line symbols.
8572a6b7db3Sskrll      Perhaps symtab_finalize should be modified to make this
8582a6b7db3Sskrll      distinction as well, but the current fix works and the code is a
8592a6b7db3Sskrll      lot cleaner now.  */
8602a6b7db3Sskrll   prev = 0;
8612a6b7db3Sskrll 
8622a6b7db3Sskrll   for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
8632a6b7db3Sskrll     {
8642a6b7db3Sskrll       sym_init (ltab.limit);
8652a6b7db3Sskrll 
8662a6b7db3Sskrll       if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
8672a6b7db3Sskrll 	  || (prev && prev->line_num == ltab.limit->line_num
8682a6b7db3Sskrll 	      && strcmp (prev->name, ltab.limit->name) == 0
869b410d692Schristos 	      && filename_cmp (prev->file->name, filename) == 0))
8702a6b7db3Sskrll 	continue;
8712a6b7db3Sskrll 
8722a6b7db3Sskrll       /* Make name pointer a malloc'ed string.  */
8732a6b7db3Sskrll       ltab.limit->name = xstrdup (ltab.limit->name);
8742a6b7db3Sskrll       ltab.limit->file = source_file_lookup_path (filename);
8752a6b7db3Sskrll 
8762a6b7db3Sskrll       ltab.limit->addr = vma;
8772a6b7db3Sskrll 
8782a6b7db3Sskrll       /* Set is_static based on the enclosing function, using either:
8792a6b7db3Sskrll 	 1) the previous symbol, if it's from the same function, or
8802a6b7db3Sskrll 	 2) a symtab lookup.  */
8812a6b7db3Sskrll       if (prev && ltab.limit->file == prev->file &&
8822a6b7db3Sskrll 	  strcmp (ltab.limit->name, prev->name) == 0)
8832a6b7db3Sskrll 	{
8842a6b7db3Sskrll 	  ltab.limit->is_static = prev->is_static;
8852a6b7db3Sskrll 	}
8862a6b7db3Sskrll       else
8872a6b7db3Sskrll 	{
8882a6b7db3Sskrll 	  sym = sym_lookup(&symtab, ltab.limit->addr);
88932998b1cSchristos           if (sym)
8902a6b7db3Sskrll 	    ltab.limit->is_static = sym->is_static;
8912a6b7db3Sskrll 	}
8922a6b7db3Sskrll 
8932a6b7db3Sskrll       prev = ltab.limit;
8942a6b7db3Sskrll 
8952a6b7db3Sskrll       DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
8962a6b7db3Sskrll 			      (unsigned long) (ltab.limit - ltab.base),
8972a6b7db3Sskrll 			      ltab.limit->name,
8982a6b7db3Sskrll 			      (unsigned long) ltab.limit->addr));
8992a6b7db3Sskrll       ++ltab.limit;
9002a6b7db3Sskrll     }
9012a6b7db3Sskrll 
9022a6b7db3Sskrll   /* Copy in function symbols.  */
9032a6b7db3Sskrll   memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
9042a6b7db3Sskrll   ltab.limit += symtab.len;
9052a6b7db3Sskrll 
9062a6b7db3Sskrll   if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
9072a6b7db3Sskrll     {
9082a6b7db3Sskrll       fprintf (stderr,
9092a6b7db3Sskrll 	       _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
9102a6b7db3Sskrll 	       whoami, ltab.len, (long) (ltab.limit - ltab.base));
9112a6b7db3Sskrll       done (1);
9122a6b7db3Sskrll     }
9132a6b7db3Sskrll 
9142a6b7db3Sskrll   /* Finalize ltab and make it symbol table.  */
9152a6b7db3Sskrll   symtab_finalize (&ltab);
9162a6b7db3Sskrll   free (symtab.base);
9172a6b7db3Sskrll   symtab = ltab;
9182a6b7db3Sskrll }
919