Back to index

cell-binutils  2.17cvs20070401
corefile.c
Go to the documentation of this file.
00001 /* corefile.c
00002 
00003    Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
00004    Free Software Foundation, Inc.
00005 
00006    This file is part of GNU Binutils.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
00021    02110-1301, USA.  */
00022 
00023 #include "libiberty.h"
00024 #include "gprof.h"
00025 #include "search_list.h"
00026 #include "source.h"
00027 #include "symtab.h"
00028 #include "corefile.h"
00029 
00030 bfd *core_bfd;
00031 static int core_num_syms;
00032 static asymbol **core_syms;
00033 asection *core_text_sect;
00034 PTR core_text_space;
00035 
00036 static int min_insn_size;
00037 int offset_to_code;
00038 
00039 /* For mapping symbols to specific .o files during file ordering.  */
00040 struct function_map *symbol_map;
00041 unsigned int symbol_map_count;
00042 
00043 static void read_function_mappings (const char *);
00044 static int core_sym_class (asymbol *);
00045 static bfd_boolean get_src_info
00046   (bfd_vma, const char **, const char **, int *);
00047 
00048 extern void i386_find_call  (Sym *, bfd_vma, bfd_vma);
00049 extern void alpha_find_call (Sym *, bfd_vma, bfd_vma);
00050 extern void vax_find_call   (Sym *, bfd_vma, bfd_vma);
00051 extern void tahoe_find_call (Sym *, bfd_vma, bfd_vma);
00052 extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
00053 extern void mips_find_call  (Sym *, bfd_vma, bfd_vma);
00054 
00055 static void
00056 parse_error (const char *filename)
00057 {
00058   fprintf (stderr, _("%s: unable to parse mapping file %s.\n"), whoami, filename);
00059   done (1);
00060 }
00061 
00062 static void
00063 read_function_mappings (const char *filename)
00064 {
00065   FILE *file = fopen (filename, "r");
00066   char dummy[1024];
00067   int count = 0;
00068 
00069   if (!file)
00070     {
00071       fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
00072       done (1);
00073     }
00074 
00075   /* First parse the mapping file so we know how big we need to
00076      make our tables.  We also do some sanity checks at this
00077      time.  */
00078   while (!feof (file))
00079     {
00080       int matches;
00081 
00082       matches = fscanf (file, "%[^\n:]", dummy);
00083       if (!matches)
00084        parse_error (filename);
00085 
00086       /* Just skip messages about files with no symbols.  */
00087       if (!strncmp (dummy, "No symbols in ", 14))
00088        {
00089          matches = fscanf (file, "\n");
00090          if (matches == EOF)
00091            parse_error (filename);
00092          continue;
00093        }
00094 
00095       /* Don't care what else is on this line at this point.  */
00096       matches = fscanf (file, "%[^\n]\n", dummy);
00097       if (!matches)
00098        parse_error (filename);
00099       count++;
00100     }
00101 
00102   /* Now we know how big we need to make our table.  */
00103   symbol_map = ((struct function_map *)
00104               xmalloc (count * sizeof (struct function_map)));
00105 
00106   /* Rewind the input file so we can read it again.  */
00107   rewind (file);
00108 
00109   /* Read each entry and put it into the table.  */
00110   count = 0;
00111   while (!feof (file))
00112     {
00113       int matches;
00114       char *tmp;
00115 
00116       matches = fscanf (file, "%[^\n:]", dummy);
00117       if (!matches)
00118        parse_error (filename);
00119 
00120       /* Just skip messages about files with no symbols.  */
00121       if (!strncmp (dummy, "No symbols in ", 14))
00122        {
00123          matches = fscanf (file, "\n");
00124          if (matches == EOF)
00125            parse_error (filename);
00126          continue;
00127        }
00128 
00129       /* dummy has the filename, go ahead and copy it.  */
00130       symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
00131       strcpy (symbol_map[count].file_name, dummy);
00132 
00133       /* Now we need the function name.  */
00134       matches = fscanf (file, "%[^\n]\n", dummy);
00135       if (!matches)
00136        parse_error (filename);
00137       tmp = strrchr (dummy, ' ') + 1;
00138       symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
00139       strcpy (symbol_map[count].function_name, tmp);
00140       count++;
00141     }
00142 
00143   /* Record the size of the map table for future reference.  */
00144   symbol_map_count = count;
00145 }
00146 
00147 
00148 void
00149 core_init (const char *aout_name)
00150 {
00151   int core_sym_bytes;
00152   asymbol *synthsyms;
00153   long synth_count;
00154 
00155   core_bfd = bfd_openr (aout_name, 0);
00156 
00157   if (!core_bfd)
00158     {
00159       perror (aout_name);
00160       done (1);
00161     }
00162 
00163   if (!bfd_check_format (core_bfd, bfd_object))
00164     {
00165       fprintf (stderr, _("%s: %s: not in executable format\n"), whoami, aout_name);
00166       done (1);
00167     }
00168 
00169   /* Get core's text section.  */
00170   core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
00171   if (!core_text_sect)
00172     {
00173       core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
00174       if (!core_text_sect)
00175        {
00176          fprintf (stderr, _("%s: can't find .text section in %s\n"),
00177                  whoami, aout_name);
00178          done (1);
00179        }
00180     }
00181 
00182   /* Read core's symbol table.  */
00183 
00184   /* This will probably give us more than we need, but that's ok.  */
00185   core_sym_bytes = bfd_get_symtab_upper_bound (core_bfd);
00186   if (core_sym_bytes < 0)
00187     {
00188       fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
00189               bfd_errmsg (bfd_get_error ()));
00190       done (1);
00191     }
00192 
00193   core_syms = (asymbol **) xmalloc (core_sym_bytes);
00194   core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
00195 
00196   if (core_num_syms < 0)
00197     {
00198       fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
00199               bfd_errmsg (bfd_get_error ()));
00200       done (1);
00201     }
00202 
00203   synth_count = bfd_get_synthetic_symtab (core_bfd, core_num_syms, core_syms,
00204                                      0, NULL, &synthsyms);
00205   if (synth_count > 0)
00206     {
00207       asymbol **symp;
00208       long new_size;
00209       long i;
00210 
00211       new_size = (core_num_syms + synth_count + 1) * sizeof (*core_syms);
00212       core_syms = xrealloc (core_syms, new_size);
00213       symp = core_syms + core_num_syms;
00214       core_num_syms += synth_count;
00215       for (i = 0; i < synth_count; i++)
00216        *symp++ = synthsyms + i;
00217       *symp = 0;
00218     }
00219 
00220   min_insn_size = 1;
00221   offset_to_code = 0;
00222 
00223   switch (bfd_get_arch (core_bfd))
00224     {
00225     case bfd_arch_vax:
00226     case bfd_arch_tahoe:
00227       offset_to_code = 2;
00228       break;
00229 
00230     case bfd_arch_alpha:
00231       min_insn_size = 4;
00232       break;
00233 
00234     default:
00235       break;
00236     }
00237 
00238   if (function_mapping_file)
00239     read_function_mappings (function_mapping_file);
00240 }
00241 
00242 /* Read in the text space of an a.out file.  */
00243 
00244 void
00245 core_get_text_space (bfd *cbfd)
00246 {
00247   core_text_space = malloc (bfd_get_section_size (core_text_sect));
00248 
00249   if (!core_text_space)
00250     {
00251       fprintf (stderr, _("%s: ran out room for %lu bytes of text space\n"),
00252               whoami, (unsigned long) bfd_get_section_size (core_text_sect));
00253       done (1);
00254     }
00255 
00256   if (!bfd_get_section_contents (cbfd, core_text_sect, core_text_space,
00257                              0, bfd_get_section_size (core_text_sect)))
00258     {
00259       bfd_perror ("bfd_get_section_contents");
00260       free (core_text_space);
00261       core_text_space = 0;
00262     }
00263 
00264   if (!core_text_space)
00265     fprintf (stderr, _("%s: can't do -c\n"), whoami);
00266 }
00267 
00268 
00269 void
00270 find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
00271 {
00272   switch (bfd_get_arch (core_bfd))
00273     {
00274     case bfd_arch_i386:
00275       i386_find_call (parent, p_lowpc, p_highpc);
00276       break;
00277 
00278     case bfd_arch_alpha:
00279       alpha_find_call (parent, p_lowpc, p_highpc);
00280       break;
00281 
00282     case bfd_arch_vax:
00283       vax_find_call (parent, p_lowpc, p_highpc);
00284       break;
00285 
00286     case bfd_arch_sparc:
00287       sparc_find_call (parent, p_lowpc, p_highpc);
00288       break;
00289 
00290     case bfd_arch_tahoe:
00291       tahoe_find_call (parent, p_lowpc, p_highpc);
00292       break;
00293 
00294     case bfd_arch_mips:
00295       mips_find_call (parent, p_lowpc, p_highpc);
00296       break;
00297 
00298     default:
00299       fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
00300               whoami, bfd_printable_name(core_bfd));
00301 
00302       /* Don't give the error more than once.  */
00303       ignore_direct_calls = FALSE;
00304     }
00305 }
00306 
00307 /* Return class of symbol SYM.  The returned class can be any of:
00308        0   -> symbol is not interesting to us
00309        'T' -> symbol is a global name
00310        't' -> symbol is a local (static) name.  */
00311 
00312 static int
00313 core_sym_class (asymbol *sym)
00314 {
00315   symbol_info syminfo;
00316   const char *name;
00317   char sym_prefix;
00318   int i;
00319 
00320   if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
00321     return 0;
00322 
00323   /* Must be a text symbol, and static text symbols
00324      don't qualify if ignore_static_funcs set.   */
00325   if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
00326     {
00327       DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
00328                            sym->name));
00329       return 0;
00330     }
00331 
00332   bfd_get_symbol_info (core_bfd, sym, &syminfo);
00333   i = syminfo.type;
00334 
00335   if (i == 'T')
00336     return i;               /* It's a global symbol.  */
00337 
00338   if (i == 'W')
00339     /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
00340        also be a data symbol.  */
00341     return 'T';
00342 
00343   if (i != 't')
00344     {
00345       /* Not a static text symbol.  */
00346       DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
00347                            sym->name, i));
00348       return 0;
00349     }
00350 
00351   /* Do some more filtering on static function-names.  */
00352   if (ignore_static_funcs)
00353     return 0;
00354 
00355   /* Can't zero-length name or funny characters in name, where
00356      `funny' includes: `.' (.o file names) and `$' (Pascal labels).  */
00357   if (!sym->name || sym->name[0] == '\0')
00358     return 0;
00359 
00360   for (name = sym->name; *name; ++name)
00361     {
00362       if (*name == '.' || *name == '$')
00363        return 0;
00364     }
00365 
00366   /* On systems where the C compiler adds an underscore to all
00367      names, static names without underscores seem usually to be
00368      labels in hand written assembler in the library.  We don't want
00369      these names.  This is certainly necessary on a Sparc running
00370      SunOS 4.1 (try profiling a program that does a lot of
00371      division). I don't know whether it has harmful side effects on
00372      other systems.  Perhaps it should be made configurable.  */
00373   sym_prefix = bfd_get_symbol_leading_char (core_bfd);
00374 
00375   if ((sym_prefix && sym_prefix != sym->name[0])
00376       /* GCC may add special symbols to help gdb figure out the file
00377        language.  We want to ignore these, since sometimes they mask
00378        the real function.  (dj@ctron)  */
00379       || !strncmp (sym->name, "__gnu_compiled", 14)
00380       || !strncmp (sym->name, "___gnu_compiled", 15))
00381     {
00382       return 0;
00383     }
00384 
00385   /* If the object file supports marking of function symbols, then
00386      we can zap anything that doesn't have BSF_FUNCTION set.  */
00387   if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
00388     return 0;
00389 
00390   return 't';               /* It's a static text symbol.  */
00391 }
00392 
00393 /* Get whatever source info we can get regarding address ADDR.  */
00394 
00395 static bfd_boolean
00396 get_src_info (bfd_vma addr, const char **filename, const char **name, int *line_num)
00397 {
00398   const char *fname = 0, *func_name = 0;
00399   int l = 0;
00400 
00401   if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
00402                           addr - core_text_sect->vma,
00403                           &fname, &func_name, (unsigned int *) &l)
00404       && fname && func_name && l)
00405     {
00406       DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
00407                            (unsigned long) addr, fname, l, func_name));
00408       *filename = fname;
00409       *name = func_name;
00410       *line_num = l;
00411       return TRUE;
00412     }
00413   else
00414     {
00415       DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
00416                            (long) addr, fname ? fname : "<unknown>", l,
00417                            func_name ? func_name : "<unknown>"));
00418       return FALSE;
00419     }
00420 }
00421 
00422 /* Read in symbol table from core.
00423    One symbol per function is entered.  */
00424 
00425 void
00426 core_create_function_syms ()
00427 {
00428   bfd_vma min_vma = ~(bfd_vma) 0;
00429   bfd_vma max_vma = 0;
00430   int class;
00431   long i, found, skip;
00432   unsigned int j;
00433 
00434   /* Pass 1 - determine upper bound on number of function names.  */
00435   symtab.len = 0;
00436 
00437   for (i = 0; i < core_num_syms; ++i)
00438     {
00439       if (!core_sym_class (core_syms[i]))
00440        continue;
00441 
00442       /* This should be replaced with a binary search or hashed
00443         search.  Gross.
00444 
00445         Don't create a symtab entry for a function that has
00446         a mapping to a file, unless it's the first function
00447         in the file.  */
00448       skip = 0;
00449       for (j = 0; j < symbol_map_count; j++)
00450        if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
00451          {
00452            if (j > 0 && ! strcmp (symbol_map [j].file_name,
00453                                symbol_map [j - 1].file_name))
00454              skip = 1;
00455            break;
00456          }
00457 
00458       if (!skip)
00459        ++symtab.len;
00460     }
00461 
00462   if (symtab.len == 0)
00463     {
00464       fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
00465       done (1);
00466     }
00467 
00468   /* The "+ 2" is for the sentinels.  */
00469   symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
00470 
00471   /* Pass 2 - create symbols.  */
00472   symtab.limit = symtab.base;
00473 
00474   for (i = 0; i < core_num_syms; ++i)
00475     {
00476       asection *sym_sec;
00477 
00478       class = core_sym_class (core_syms[i]);
00479 
00480       if (!class)
00481        {
00482          DBG (AOUTDEBUG,
00483               printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
00484                      (unsigned long) core_syms[i]->value,
00485                      core_syms[i]->name));
00486          continue;
00487        }
00488 
00489       /* This should be replaced with a binary search or hashed
00490         search.  Gross.   */
00491       skip = 0;
00492       found = 0;
00493 
00494       for (j = 0; j < symbol_map_count; j++)
00495        if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
00496          {
00497            if (j > 0 && ! strcmp (symbol_map [j].file_name,
00498                                symbol_map [j - 1].file_name))
00499              skip = 1;
00500            else
00501              found = j;
00502            break;
00503          }
00504 
00505       if (skip)
00506        continue;
00507 
00508       sym_init (symtab.limit);
00509 
00510       /* Symbol offsets are always section-relative.  */
00511       sym_sec = core_syms[i]->section;
00512       symtab.limit->addr = core_syms[i]->value;
00513       if (sym_sec)
00514        symtab.limit->addr += bfd_get_section_vma (sym_sec->owner, sym_sec);
00515 
00516       if (symbol_map_count
00517          && !strcmp (core_syms[i]->name, symbol_map[found].function_name))
00518        {
00519          symtab.limit->name = symbol_map[found].file_name;
00520          symtab.limit->mapped = 1;
00521        }
00522       else
00523        {
00524          symtab.limit->name = core_syms[i]->name;
00525          symtab.limit->mapped = 0;
00526        }
00527 
00528       /* Lookup filename and line number, if we can.  */
00529       {
00530        const char *filename, *func_name;
00531 
00532        if (get_src_info (symtab.limit->addr, &filename, &func_name,
00533                        &symtab.limit->line_num))
00534          {
00535            symtab.limit->file = source_file_lookup_path (filename);
00536 
00537            /* FIXME: Checking __osf__ here does not work with a cross
00538               gprof.  */
00539 #ifdef __osf__
00540            /* Suppress symbols that are not function names.  This is
00541               useful to suppress code-labels and aliases.
00542 
00543               This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
00544               labels do not appear in the symbol table info, so this isn't
00545               necessary.  */
00546 
00547            if (strcmp (symtab.limit->name, func_name) != 0)
00548              {
00549               /* The symbol's address maps to a different name, so
00550                  it can't be a function-entry point.  This happens
00551                  for labels, for example.  */
00552               DBG (AOUTDEBUG,
00553                    printf ("[core_create_function_syms: rej %s (maps to %s)\n",
00554                           symtab.limit->name, func_name));
00555               continue;
00556              }
00557 #endif
00558          }
00559       }
00560 
00561       symtab.limit->is_func = TRUE;
00562       symtab.limit->is_bb_head = TRUE;
00563 
00564       if (class == 't')
00565        symtab.limit->is_static = TRUE;
00566 
00567       /* Keep track of the minimum and maximum vma addresses used by all
00568         symbols.  When computing the max_vma, use the ending address of the
00569         section containing the symbol, if available.  */
00570       min_vma = MIN (symtab.limit->addr, min_vma);
00571       if (sym_sec)
00572        max_vma = MAX (bfd_get_section_vma (sym_sec->owner, sym_sec)
00573                      + bfd_section_size (sym_sec->owner, sym_sec) - 1,
00574                      max_vma);
00575       else
00576        max_vma = MAX (symtab.limit->addr, max_vma);
00577 
00578       /* If we see "main" without an initial '_', we assume names
00579         are *not* prefixed by '_'.  */
00580       if (symtab.limit->name[0] == 'm' && discard_underscores
00581          && strcmp (symtab.limit->name, "main") == 0)
00582        discard_underscores = 0;
00583 
00584       DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
00585                            (long) (symtab.limit - symtab.base),
00586                            symtab.limit->name,
00587                            (unsigned long) symtab.limit->addr));
00588       ++symtab.limit;
00589     }
00590 
00591   /* Create sentinels.  */
00592   sym_init (symtab.limit);
00593   symtab.limit->name = "<locore>";
00594   symtab.limit->addr = 0;
00595   symtab.limit->end_addr = min_vma - 1;
00596   ++symtab.limit;
00597 
00598   sym_init (symtab.limit);
00599   symtab.limit->name = "<hicore>";
00600   symtab.limit->addr = max_vma + 1;
00601   symtab.limit->end_addr = ~(bfd_vma) 0;
00602   ++symtab.limit;
00603 
00604   symtab.len = symtab.limit - symtab.base;
00605   symtab_finalize (&symtab);
00606 }
00607 
00608 /* Read in symbol table from core.
00609    One symbol per line of source code is entered.  */
00610 
00611 void
00612 core_create_line_syms ()
00613 {
00614   char *prev_name, *prev_filename;
00615   unsigned int prev_name_len, prev_filename_len;
00616   bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0;
00617   Sym *prev, dummy, *sentinel, *sym;
00618   const char *filename;
00619   int prev_line_num;
00620   Sym_Table ltab;
00621   bfd_vma vma_high;
00622 
00623   /* Create symbols for functions as usual.  This is necessary in
00624      cases where parts of a program were not compiled with -g.  For
00625      those parts we still want to get info at the function level.  */
00626   core_create_function_syms ();
00627 
00628   /* Pass 1: count the number of symbols.  */
00629 
00630   /* To find all line information, walk through all possible
00631      text-space addresses (one by one!) and get the debugging
00632      info for each address.  When the debugging info changes,
00633      it is time to create a new symbol.
00634 
00635      Of course, this is rather slow and it would be better if
00636      BFD would provide an iterator for enumerating all line infos.  */
00637   prev_name_len = PATH_MAX;
00638   prev_filename_len = PATH_MAX;
00639   prev_name = xmalloc (prev_name_len);
00640   prev_filename = xmalloc (prev_filename_len);
00641   ltab.len = 0;
00642   prev_line_num = 0;
00643 
00644   vma_high = core_text_sect->vma + bfd_get_section_size (core_text_sect);
00645   for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
00646     {
00647       unsigned int len;
00648 
00649       if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
00650          || (prev_line_num == dummy.line_num
00651              && prev_name != NULL
00652              && strcmp (prev_name, dummy.name) == 0
00653              && strcmp (prev_filename, filename) == 0))
00654        continue;
00655 
00656       ++ltab.len;
00657       prev_line_num = dummy.line_num;
00658 
00659       len = strlen (dummy.name);
00660       if (len >= prev_name_len)
00661        {
00662          prev_name_len = len + 1024;
00663          free (prev_name);
00664          prev_name = xmalloc (prev_name_len);
00665        }
00666 
00667       strcpy (prev_name, dummy.name);
00668       len = strlen (filename);
00669 
00670       if (len >= prev_filename_len)
00671        {
00672          prev_filename_len = len + 1024;
00673          free (prev_filename);
00674          prev_filename = xmalloc (prev_filename_len);
00675        }
00676 
00677       strcpy (prev_filename, filename);
00678 
00679       min_vma = MIN (vma, min_vma);
00680       max_vma = MAX (vma, max_vma);
00681     }
00682 
00683   free (prev_name);
00684   free (prev_filename);
00685 
00686   /* Make room for function symbols, too.  */
00687   ltab.len += symtab.len;
00688   ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
00689   ltab.limit = ltab.base;
00690 
00691   /* Pass 2 - create symbols.  */
00692 
00693   /* We now set is_static as we go along, rather than by running
00694      through the symbol table at the end.
00695 
00696      The old way called symtab_finalize before the is_static pass,
00697      causing a problem since symtab_finalize uses is_static as part of
00698      its address conflict resolution algorithm.  Since global symbols
00699      were prefered over static symbols, and all line symbols were
00700      global at that point, static function names that conflicted with
00701      their own line numbers (static, but labeled as global) were
00702      rejected in favor of the line num.
00703 
00704      This was not the desired functionality.  We always want to keep
00705      our function symbols and discard any conflicting line symbols.
00706      Perhaps symtab_finalize should be modified to make this
00707      distinction as well, but the current fix works and the code is a
00708      lot cleaner now.  */
00709   prev = 0;
00710 
00711   for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
00712     {
00713       sym_init (ltab.limit);
00714 
00715       if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
00716          || (prev && prev->line_num == ltab.limit->line_num
00717              && strcmp (prev->name, ltab.limit->name) == 0
00718              && strcmp (prev->file->name, filename) == 0))
00719        continue;
00720 
00721       /* Make name pointer a malloc'ed string.  */
00722       ltab.limit->name = xstrdup (ltab.limit->name);
00723       ltab.limit->file = source_file_lookup_path (filename);
00724 
00725       ltab.limit->addr = vma;
00726 
00727       /* Set is_static based on the enclosing function, using either:
00728         1) the previous symbol, if it's from the same function, or
00729         2) a symtab lookup.  */
00730       if (prev && ltab.limit->file == prev->file &&
00731          strcmp (ltab.limit->name, prev->name) == 0)
00732        {
00733          ltab.limit->is_static = prev->is_static;
00734        }
00735       else
00736        {
00737          sym = sym_lookup(&symtab, ltab.limit->addr);
00738          ltab.limit->is_static = sym->is_static;
00739        }
00740 
00741       prev = ltab.limit;
00742 
00743       /* If we see "main" without an initial '_', we assume names
00744         are *not* prefixed by '_'.  */
00745       if (ltab.limit->name[0] == 'm' && discard_underscores
00746          && strcmp (ltab.limit->name, "main") == 0)
00747        discard_underscores = 0;
00748 
00749       DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
00750                            (unsigned long) (ltab.limit - ltab.base),
00751                            ltab.limit->name,
00752                            (unsigned long) ltab.limit->addr));
00753       ++ltab.limit;
00754     }
00755 
00756   /* Update sentinels.  */
00757   sentinel = sym_lookup (&symtab, (bfd_vma) 0);
00758 
00759   if (sentinel
00760       && strcmp (sentinel->name, "<locore>") == 0
00761       && min_vma <= sentinel->end_addr)
00762     sentinel->end_addr = min_vma - 1;
00763 
00764   sentinel = sym_lookup (&symtab, ~(bfd_vma) 0);
00765 
00766   if (sentinel
00767       && strcmp (sentinel->name, "<hicore>") == 0
00768       && max_vma >= sentinel->addr)
00769     sentinel->addr = max_vma + 1;
00770 
00771   /* Copy in function symbols.  */
00772   memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
00773   ltab.limit += symtab.len;
00774 
00775   if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
00776     {
00777       fprintf (stderr,
00778               _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
00779               whoami, ltab.len, (long) (ltab.limit - ltab.base));
00780       done (1);
00781     }
00782 
00783   /* Finalize ltab and make it symbol table.  */
00784   symtab_finalize (&ltab);
00785   free (symtab.base);
00786   symtab = ltab;
00787 }