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