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