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