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