Blame gprof/corefile.c

Packit Service 72eb06
/* corefile.c
Packit Service 72eb06
Packit Service 72eb06
   Copyright (C) 1999-2018 Free Software Foundation, Inc.
Packit Service 72eb06
Packit Service 72eb06
   This file is part of GNU Binutils.
Packit Service 72eb06
Packit Service 72eb06
   This program is free software; you can redistribute it and/or modify
Packit Service 72eb06
   it under the terms of the GNU General Public License as published by
Packit Service 72eb06
   the Free Software Foundation; either version 3 of the License, or
Packit Service 72eb06
   (at your option) any later version.
Packit Service 72eb06
Packit Service 72eb06
   This program is distributed in the hope that it will be useful,
Packit Service 72eb06
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 72eb06
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 72eb06
   GNU General Public License for more details.
Packit Service 72eb06
Packit Service 72eb06
   You should have received a copy of the GNU General Public License
Packit Service 72eb06
   along with this program; if not, write to the Free Software
Packit Service 72eb06
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
Packit Service 72eb06
   02110-1301, USA.  */
Packit Service 72eb06

Packit Service 72eb06
#include "gprof.h"
Packit Service 72eb06
#include "libiberty.h"
Packit Service 72eb06
#include "filenames.h"
Packit Service 72eb06
#include "search_list.h"
Packit Service 72eb06
#include "source.h"
Packit Service 72eb06
#include "symtab.h"
Packit Service 72eb06
#include "hist.h"
Packit Service 72eb06
#include "corefile.h"
Packit Service 72eb06
#include "safe-ctype.h"
Packit Service 72eb06
#include <limits.h>    /* For UINT_MAX.  */
Packit Service 72eb06
Packit Service 72eb06
bfd *core_bfd;
Packit Service 72eb06
static int core_num_syms;
Packit Service 72eb06
static asymbol **core_syms;
Packit Service 72eb06
asection *core_text_sect;
Packit Service 72eb06
void * core_text_space;
Packit Service 72eb06
Packit Service 72eb06
static int min_insn_size;
Packit Service 72eb06
int offset_to_code;
Packit Service 72eb06
Packit Service 72eb06
/* For mapping symbols to specific .o files during file ordering.  */
Packit Service 72eb06
struct function_map * symbol_map;
Packit Service 72eb06
unsigned int symbol_map_count;
Packit Service 72eb06
Packit Service 72eb06
static void read_function_mappings (const char *);
Packit Service 72eb06
static int core_sym_class (asymbol *);
Packit Service 72eb06
static bfd_boolean get_src_info
Packit Service 72eb06
  (bfd_vma, const char **, const char **, int *);
Packit Service 72eb06
Packit Service 72eb06
extern void i386_find_call  (Sym *, bfd_vma, bfd_vma);
Packit Service 72eb06
extern void alpha_find_call (Sym *, bfd_vma, bfd_vma);
Packit Service 72eb06
extern void vax_find_call   (Sym *, bfd_vma, bfd_vma);
Packit Service 72eb06
extern void tahoe_find_call (Sym *, bfd_vma, bfd_vma);
Packit Service 72eb06
extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
Packit Service 72eb06
extern void mips_find_call  (Sym *, bfd_vma, bfd_vma);
Packit Service 72eb06
extern void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
Packit Service 72eb06
Packit Service 72eb06
static void
Packit Service 72eb06
parse_error (const char *filename)
Packit Service 72eb06
{
Packit Service 72eb06
  fprintf (stderr, _("%s: unable to parse mapping file %s.\n"), whoami, filename);
Packit Service 72eb06
  done (1);
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
/* Compare two function_map structs based on function name.
Packit Service 72eb06
   We want to sort in ascending order.  */
Packit Service 72eb06
Packit Service 72eb06
static int
Packit Service 72eb06
cmp_symbol_map (const void * l, const void * r)
Packit Service 72eb06
{
Packit Service 72eb06
  return strcmp (((struct function_map *) l)->function_name,
Packit Service 72eb06
		 ((struct function_map *) r)->function_name);
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
#define BUFSIZE      (1024)
Packit Service 72eb06
/* This is BUFSIZE - 1 as a string.  Suitable for use in fprintf/sscanf format strings.  */
Packit Service 72eb06
#define STR_BUFSIZE  "1023"
Packit Service 72eb06
Packit Service 72eb06
static void
Packit Service 72eb06
read_function_mappings (const char *filename)
Packit Service 72eb06
{
Packit Service 72eb06
  FILE * file = fopen (filename, "r");
Packit Service 72eb06
  char dummy[BUFSIZE];
Packit Service 72eb06
  int count = 0;
Packit Service 72eb06
  unsigned int i;
Packit Service 72eb06
Packit Service 72eb06
  if (!file)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* First parse the mapping file so we know how big we need to
Packit Service 72eb06
     make our tables.  We also do some sanity checks at this
Packit Service 72eb06
     time.  */
Packit Service 72eb06
  while (!feof (file))
Packit Service 72eb06
    {
Packit Service 72eb06
      int matches;
Packit Service 72eb06
Packit Service 72eb06
      matches = fscanf (file, "%" STR_BUFSIZE "[^\n:]", dummy);
Packit Service 72eb06
      if (!matches)
Packit Service 72eb06
	parse_error (filename);
Packit Service 72eb06
Packit Service 72eb06
      /* Just skip messages about files with no symbols.  */
Packit Service 72eb06
      if (!strncmp (dummy, "No symbols in ", 14))
Packit Service 72eb06
	{
Packit Service 72eb06
	  matches = fscanf (file, "\n");
Packit Service 72eb06
	  if (matches == EOF)
Packit Service 72eb06
	    parse_error (filename);
Packit Service 72eb06
	  continue;
Packit Service 72eb06
	}
Packit Service 72eb06
Packit Service 72eb06
      /* Don't care what else is on this line at this point.  */
Packit Service 72eb06
      matches = fscanf (file, "%" STR_BUFSIZE "[^\n]\n", dummy);
Packit Service 72eb06
      if (!matches)
Packit Service 72eb06
	parse_error (filename);
Packit Service 72eb06
      count++;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Now we know how big we need to make our table.  */
Packit Service 72eb06
  symbol_map = ((struct function_map *)
Packit Service 72eb06
		xmalloc (count * sizeof (struct function_map)));
Packit Service 72eb06
Packit Service 72eb06
  /* Rewind the input file so we can read it again.  */
Packit Service 72eb06
  rewind (file);
Packit Service 72eb06
Packit Service 72eb06
  /* Read each entry and put it into the table.  */
Packit Service 72eb06
  count = 0;
Packit Service 72eb06
  while (!feof (file))
Packit Service 72eb06
    {
Packit Service 72eb06
      int matches;
Packit Service 72eb06
      char *tmp;
Packit Service 72eb06
Packit Service 72eb06
      matches = fscanf (file, "%" STR_BUFSIZE "[^\n:]", dummy);
Packit Service 72eb06
      if (!matches)
Packit Service 72eb06
	parse_error (filename);
Packit Service 72eb06
Packit Service 72eb06
      /* Just skip messages about files with no symbols.  */
Packit Service 72eb06
      if (!strncmp (dummy, "No symbols in ", 14))
Packit Service 72eb06
	{
Packit Service 72eb06
	  matches = fscanf (file, "\n");
Packit Service 72eb06
	  if (matches == EOF)
Packit Service 72eb06
	    parse_error (filename);
Packit Service 72eb06
	  continue;
Packit Service 72eb06
	}
Packit Service 72eb06
Packit Service 72eb06
      /* dummy has the filename, go ahead and copy it.  */
Packit Service 72eb06
      symbol_map[count].file_name = (char *) xmalloc (strlen (dummy) + 1);
Packit Service 72eb06
      strcpy (symbol_map[count].file_name, dummy);
Packit Service 72eb06
Packit Service 72eb06
      /* Now we need the function name.  */
Packit Service 72eb06
      matches = fscanf (file, "%" STR_BUFSIZE "[^\n]\n", dummy);
Packit Service 72eb06
      if (!matches)
Packit Service 72eb06
	parse_error (filename);
Packit Service 72eb06
      tmp = strrchr (dummy, ' ') + 1;
Packit Service 72eb06
      symbol_map[count].function_name = (char *) xmalloc (strlen (tmp) + 1);
Packit Service 72eb06
      strcpy (symbol_map[count].function_name, tmp);
Packit Service 72eb06
      count++;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Record the size of the map table for future reference.  */
Packit Service 72eb06
  symbol_map_count = count;
Packit Service 72eb06
Packit Service 72eb06
  for (i = 0; i < symbol_map_count; ++i)
Packit Service 72eb06
    if (i == 0
Packit Service 72eb06
        || filename_cmp (symbol_map[i].file_name, symbol_map[i - 1].file_name))
Packit Service 72eb06
      symbol_map[i].is_first = 1;
Packit Service 72eb06
Packit Service 72eb06
  qsort (symbol_map, symbol_map_count, sizeof (struct function_map), cmp_symbol_map);
Packit Service 72eb06
Packit Service 72eb06
  fclose (file);
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
void
Packit Service 72eb06
core_init (const char * aout_name)
Packit Service 72eb06
{
Packit Service 72eb06
  int core_sym_bytes;
Packit Service 72eb06
  asymbol *synthsyms;
Packit Service 72eb06
  long synth_count;
Packit Service 72eb06
Packit Service 72eb06
  core_bfd = bfd_openr (aout_name, 0);
Packit Service 72eb06
Packit Service 72eb06
  if (!core_bfd)
Packit Service 72eb06
    {
Packit Service 72eb06
      perror (aout_name);
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  if (!bfd_check_format (core_bfd, bfd_object))
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, _("%s: %s: not in executable format\n"), whoami, aout_name);
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Get core's text section.  */
Packit Service 72eb06
  core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
Packit Service 72eb06
  if (!core_text_sect)
Packit Service 72eb06
    {
Packit Service 72eb06
      core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
Packit Service 72eb06
      if (!core_text_sect)
Packit Service 72eb06
	{
Packit Service 72eb06
	  fprintf (stderr, _("%s: can't find .text section in %s\n"),
Packit Service 72eb06
		   whoami, aout_name);
Packit Service 72eb06
	  done (1);
Packit Service 72eb06
	}
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Read core's symbol table.  */
Packit Service 72eb06
Packit Service 72eb06
  /* This will probably give us more than we need, but that's ok.  */
Packit Service 72eb06
  core_sym_bytes = bfd_get_symtab_upper_bound (core_bfd);
Packit Service 72eb06
  if (core_sym_bytes < 0)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
Packit Service 72eb06
	       bfd_errmsg (bfd_get_error ()));
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  core_syms = (asymbol **) xmalloc (core_sym_bytes);
Packit Service 72eb06
  core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
Packit Service 72eb06
Packit Service 72eb06
  if (core_num_syms < 0)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
Packit Service 72eb06
	       bfd_errmsg (bfd_get_error ()));
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  synth_count = bfd_get_synthetic_symtab (core_bfd, core_num_syms, core_syms,
Packit Service 72eb06
					  0, NULL, &synthsyms);
Packit Service 72eb06
  if (synth_count > 0)
Packit Service 72eb06
    {
Packit Service 72eb06
      asymbol **symp;
Packit Service 72eb06
      long new_size;
Packit Service 72eb06
      long i;
Packit Service 72eb06
Packit Service 72eb06
      new_size = (core_num_syms + synth_count + 1) * sizeof (*core_syms);
Packit Service 72eb06
      core_syms = (asymbol **) xrealloc (core_syms, new_size);
Packit Service 72eb06
      symp = core_syms + core_num_syms;
Packit Service 72eb06
      core_num_syms += synth_count;
Packit Service 72eb06
      for (i = 0; i < synth_count; i++)
Packit Service 72eb06
	*symp++ = synthsyms + i;
Packit Service 72eb06
      *symp = 0;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  min_insn_size = 1;
Packit Service 72eb06
  offset_to_code = 0;
Packit Service 72eb06
Packit Service 72eb06
  switch (bfd_get_arch (core_bfd))
Packit Service 72eb06
    {
Packit Service 72eb06
    case bfd_arch_vax:
Packit Service 72eb06
    case bfd_arch_tahoe:
Packit Service 72eb06
      offset_to_code = 2;
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    case bfd_arch_alpha:
Packit Service 72eb06
      min_insn_size = 4;
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    default:
Packit Service 72eb06
      break;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  if (function_mapping_file)
Packit Service 72eb06
    read_function_mappings (function_mapping_file);
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
/* Read in the text space of an a.out file.  */
Packit Service 72eb06
Packit Service 72eb06
void
Packit Service 72eb06
core_get_text_space (bfd *cbfd)
Packit Service 72eb06
{
Packit Service 72eb06
  core_text_space = malloc (bfd_get_section_size (core_text_sect));
Packit Service 72eb06
Packit Service 72eb06
  if (!core_text_space)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, _("%s: ran out room for %lu bytes of text space\n"),
Packit Service 72eb06
	       whoami, (unsigned long) bfd_get_section_size (core_text_sect));
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  if (!bfd_get_section_contents (cbfd, core_text_sect, core_text_space,
Packit Service 72eb06
				 0, bfd_get_section_size (core_text_sect)))
Packit Service 72eb06
    {
Packit Service 72eb06
      bfd_perror ("bfd_get_section_contents");
Packit Service 72eb06
      free (core_text_space);
Packit Service 72eb06
      core_text_space = 0;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  if (!core_text_space)
Packit Service 72eb06
    fprintf (stderr, _("%s: can't do -c\n"), whoami);
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
Packit Service 72eb06
void
Packit Service 72eb06
find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
Packit Service 72eb06
{
Packit Service 72eb06
  if (core_text_space == 0)
Packit Service 72eb06
    return;
Packit Service 72eb06
Packit Service 72eb06
  hist_clip_symbol_address (&p_lowpc, &p_highpc);
Packit Service 72eb06
Packit Service 72eb06
  switch (bfd_get_arch (core_bfd))
Packit Service 72eb06
    {
Packit Service 72eb06
    case bfd_arch_i386:
Packit Service 72eb06
      i386_find_call (parent, p_lowpc, p_highpc);
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    case bfd_arch_alpha:
Packit Service 72eb06
      alpha_find_call (parent, p_lowpc, p_highpc);
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    case bfd_arch_vax:
Packit Service 72eb06
      vax_find_call (parent, p_lowpc, p_highpc);
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    case bfd_arch_sparc:
Packit Service 72eb06
      sparc_find_call (parent, p_lowpc, p_highpc);
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    case bfd_arch_tahoe:
Packit Service 72eb06
      tahoe_find_call (parent, p_lowpc, p_highpc);
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    case bfd_arch_mips:
Packit Service 72eb06
      mips_find_call (parent, p_lowpc, p_highpc);
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    case bfd_arch_aarch64:
Packit Service 72eb06
      aarch64_find_call (parent, p_lowpc, p_highpc);
Packit Service 72eb06
      break;
Packit Service 72eb06
Packit Service 72eb06
    default:
Packit Service 72eb06
      fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
Packit Service 72eb06
	       whoami, bfd_printable_name(core_bfd));
Packit Service 72eb06
Packit Service 72eb06
      /* Don't give the error more than once.  */
Packit Service 72eb06
      ignore_direct_calls = FALSE;
Packit Service 72eb06
    }
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
/* Return class of symbol SYM.  The returned class can be any of:
Packit Service 72eb06
	0   -> symbol is not interesting to us
Packit Service 72eb06
	'T' -> symbol is a global name
Packit Service 72eb06
	't' -> symbol is a local (static) name.  */
Packit Service 72eb06
Packit Service 72eb06
static int
Packit Service 72eb06
core_sym_class (asymbol *sym)
Packit Service 72eb06
{
Packit Service 72eb06
  symbol_info syminfo;
Packit Service 72eb06
  const char *name;
Packit Service 72eb06
  char sym_prefix;
Packit Service 72eb06
  int i;
Packit Service 72eb06
Packit Service 72eb06
  if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
Packit Service 72eb06
    return 0;
Packit Service 72eb06
Packit Service 72eb06
  /* Must be a text symbol, and static text symbols
Packit Service 72eb06
     don't qualify if ignore_static_funcs set.   */
Packit Service 72eb06
  if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
Packit Service 72eb06
    {
Packit Service 72eb06
      DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
Packit Service 72eb06
			      sym->name));
Packit Service 72eb06
      return 0;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  bfd_get_symbol_info (core_bfd, sym, &syminfo);
Packit Service 72eb06
  i = syminfo.type;
Packit Service 72eb06
Packit Service 72eb06
  if (i == 'T')
Packit Service 72eb06
    return i;			/* It's a global symbol.  */
Packit Service 72eb06
Packit Service 72eb06
  if (i == 'W')
Packit Service 72eb06
    /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
Packit Service 72eb06
       also be a data symbol.  */
Packit Service 72eb06
    return 'T';
Packit Service 72eb06
Packit Service 72eb06
  if (i != 't')
Packit Service 72eb06
    {
Packit Service 72eb06
      /* Not a static text symbol.  */
Packit Service 72eb06
      DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
Packit Service 72eb06
			      sym->name, i));
Packit Service 72eb06
      return 0;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Do some more filtering on static function-names.  */
Packit Service 72eb06
  if (ignore_static_funcs)
Packit Service 72eb06
    return 0;
Packit Service 72eb06
Packit Service 72eb06
  /* Can't zero-length name or funny characters in name, where
Packit Service 72eb06
     `funny' includes: `.' (.o file names) and `$' (Pascal labels).  */
Packit Service 72eb06
  if (!sym->name || sym->name[0] == '\0')
Packit Service 72eb06
    return 0;
Packit Service 72eb06
Packit Service 72eb06
  for (name = sym->name; *name; ++name)
Packit Service 72eb06
    {
Packit Service 72eb06
      if (*name == '$')
Packit Service 72eb06
        return 0;
Packit Service 72eb06
Packit Service 72eb06
      while (*name == '.')
Packit Service 72eb06
	{
Packit Service 72eb06
	  /* Allow both nested subprograms (which end with ".NNN", where N is
Packit Service 72eb06
	     a digit) and GCC cloned functions (which contain ".clone").
Packit Service 72eb06
	     Allow for multiple iterations of both - apparently GCC can clone
Packit Service 72eb06
	     clones and subprograms.  */
Packit Service 72eb06
	  int digit_seen = 0;
Packit Service 72eb06
#define CLONE_NAME	    ".clone."
Packit Service 72eb06
#define CLONE_NAME_LEN	    strlen (CLONE_NAME)
Packit Service 72eb06
#define CONSTPROP_NAME	    ".constprop."
Packit Service 72eb06
#define CONSTPROP_NAME_LEN  strlen (CONSTPROP_NAME)
Packit Service 72eb06
Packit Service 72eb06
	  if (strlen (name) > CLONE_NAME_LEN
Packit Service 72eb06
	      && strncmp (name, CLONE_NAME, CLONE_NAME_LEN) == 0)
Packit Service 72eb06
	    name += CLONE_NAME_LEN - 1;
Packit Service 72eb06
Packit Service 72eb06
	  else if (strlen (name) > CONSTPROP_NAME_LEN
Packit Service 72eb06
	      && strncmp (name, CONSTPROP_NAME, CONSTPROP_NAME_LEN) == 0)
Packit Service 72eb06
	    name += CONSTPROP_NAME_LEN - 1;
Packit Service 72eb06
Packit Service 72eb06
	  for (name++; *name; name++)
Packit Service 72eb06
	    if (digit_seen && *name == '.')
Packit Service 72eb06
	      break;
Packit Service 72eb06
	    else if (ISDIGIT (*name))
Packit Service 72eb06
	      digit_seen = 1;
Packit Service 72eb06
	    else
Packit Service 72eb06
	      return 0;
Packit Service 72eb06
	}
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* On systems where the C compiler adds an underscore to all
Packit Service 72eb06
     names, static names without underscores seem usually to be
Packit Service 72eb06
     labels in hand written assembler in the library.  We don't want
Packit Service 72eb06
     these names.  This is certainly necessary on a Sparc running
Packit Service 72eb06
     SunOS 4.1 (try profiling a program that does a lot of
Packit Service 72eb06
     division). I don't know whether it has harmful side effects on
Packit Service 72eb06
     other systems.  Perhaps it should be made configurable.  */
Packit Service 72eb06
  sym_prefix = bfd_get_symbol_leading_char (core_bfd);
Packit Service 72eb06
Packit Service 72eb06
  if ((sym_prefix && sym_prefix != sym->name[0])
Packit Service 72eb06
      /* GCC may add special symbols to help gdb figure out the file
Packit Service 72eb06
	language.  We want to ignore these, since sometimes they mask
Packit Service 72eb06
	the real function.  (dj@ctron)  */
Packit Service 72eb06
      || !strncmp (sym->name, "__gnu_compiled", 14)
Packit Service 72eb06
      || !strncmp (sym->name, "___gnu_compiled", 15))
Packit Service 72eb06
    {
Packit Service 72eb06
      return 0;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* If the object file supports marking of function symbols, then
Packit Service 72eb06
     we can zap anything that doesn't have BSF_FUNCTION set.  */
Packit Service 72eb06
  if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
Packit Service 72eb06
    return 0;
Packit Service 72eb06
Packit Service 72eb06
  return 't';			/* It's a static text symbol.  */
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
/* Get whatever source info we can get regarding address ADDR.  */
Packit Service 72eb06
Packit Service 72eb06
static bfd_boolean
Packit Service 72eb06
get_src_info (bfd_vma addr, const char **filename, const char **name, int *line_num)
Packit Service 72eb06
{
Packit Service 72eb06
  const char *fname = 0, *func_name = 0;
Packit Service 72eb06
  int l = 0;
Packit Service 72eb06
Packit Service 72eb06
  if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
Packit Service 72eb06
			     addr - core_text_sect->vma,
Packit Service 72eb06
			     &fname, &func_name, (unsigned int *) &l)
Packit Service 72eb06
      && fname && func_name && l)
Packit Service 72eb06
    {
Packit Service 72eb06
      DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
Packit Service 72eb06
			      (unsigned long) addr, fname, l, func_name));
Packit Service 72eb06
      *filename = fname;
Packit Service 72eb06
      *name = func_name;
Packit Service 72eb06
      *line_num = l;
Packit Service 72eb06
      return TRUE;
Packit Service 72eb06
    }
Packit Service 72eb06
  else
Packit Service 72eb06
    {
Packit Service 72eb06
      DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
Packit Service 72eb06
			      (unsigned long) addr,
Packit Service 72eb06
			      fname ? fname : "<unknown>", l,
Packit Service 72eb06
			      func_name ? func_name : "<unknown>"));
Packit Service 72eb06
      return FALSE;
Packit Service 72eb06
    }
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
static char buf[BUFSIZE];
Packit Service 72eb06
static char address[BUFSIZE];
Packit Service 72eb06
static char name[BUFSIZE];
Packit Service 72eb06
Packit Service 72eb06
/* Return number of symbols in a symbol-table file.  */
Packit Service 72eb06
Packit Service 72eb06
static unsigned int
Packit Service 72eb06
num_of_syms_in (FILE * f)
Packit Service 72eb06
{
Packit Service 72eb06
  char   type;
Packit Service 72eb06
  unsigned int num = 0;
Packit Service 72eb06
Packit Service 72eb06
  while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
Packit Service 72eb06
    {
Packit Service 72eb06
      if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) == 3)
Packit Service 72eb06
        if (type == 't' || type == 'T')
Packit Service 72eb06
	  {
Packit Service 72eb06
	    /* PR 20499 - prevent integer overflow computing argument to xmalloc.  */	  
Packit Service 72eb06
	    if (++num >= UINT_MAX / sizeof (Sym))
Packit Service 72eb06
	      return -1U;
Packit Service 72eb06
	  }
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  return num;
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
/* Read symbol table from a file.  */
Packit Service 72eb06
Packit Service 72eb06
void
Packit Service 72eb06
core_create_syms_from (const char * sym_table_file)
Packit Service 72eb06
{
Packit Service 72eb06
  char type;
Packit Service 72eb06
  bfd_vma min_vma = ~(bfd_vma) 0;
Packit Service 72eb06
  bfd_vma max_vma = 0;
Packit Service 72eb06
  FILE * f;
Packit Service 72eb06
Packit Service 72eb06
  f = fopen (sym_table_file, "r");
Packit Service 72eb06
  if (!f)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, _("%s: could not open %s.\n"), whoami, sym_table_file);
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Pass 1 - determine upper bound on number of function names.  */
Packit Service 72eb06
  symtab.len = num_of_syms_in (f);
Packit Service 72eb06
Packit Service 72eb06
  if (symtab.len == 0)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, sym_table_file);
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
  else if (symtab.len == -1U)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, _("%s: file `%s' has too many symbols\n"),
Packit Service 72eb06
	       whoami, sym_table_file);
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
Packit Service 72eb06
Packit Service 72eb06
  /* Pass 2 - create symbols.  */
Packit Service 72eb06
  symtab.limit = symtab.base;
Packit Service 72eb06
Packit Service 72eb06
  if (fseek (f, 0, SEEK_SET) != 0)
Packit Service 72eb06
    {
Packit Service 72eb06
      perror (sym_table_file);
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
Packit Service 72eb06
    {
Packit Service 72eb06
      if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) != 3)
Packit Service 72eb06
	continue;
Packit Service 72eb06
      if (type != 't' && type != 'T')
Packit Service 72eb06
	continue;
Packit Service 72eb06
Packit Service 72eb06
      sym_init (symtab.limit);
Packit Service 72eb06
Packit Service 72eb06
      sscanf (address, "%" BFD_VMA_FMT "x", &(symtab.limit->addr) );
Packit Service 72eb06
Packit Service 72eb06
      symtab.limit->name = (char *) xmalloc (strlen (name) + 1);
Packit Service 72eb06
      strcpy ((char *) symtab.limit->name, name);
Packit Service 72eb06
      symtab.limit->mapped = 0;
Packit Service 72eb06
      symtab.limit->is_func = TRUE;
Packit Service 72eb06
      symtab.limit->is_bb_head = TRUE;
Packit Service 72eb06
      symtab.limit->is_static = (type == 't');
Packit Service 72eb06
      min_vma = MIN (symtab.limit->addr, min_vma);
Packit Service 72eb06
      max_vma = MAX (symtab.limit->addr, max_vma);
Packit Service 72eb06
Packit Service 72eb06
      ++symtab.limit;
Packit Service 72eb06
    }
Packit Service 72eb06
  fclose (f);
Packit Service 72eb06
Packit Service 72eb06
  symtab.len = symtab.limit - symtab.base;
Packit Service 72eb06
  symtab_finalize (&symtab);
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
static int
Packit Service 72eb06
search_mapped_symbol (const void * l, const void * r)
Packit Service 72eb06
{
Packit Service 72eb06
    return strcmp ((const char *) l, ((const struct function_map *) r)->function_name);
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
/* Read in symbol table from core.
Packit Service 72eb06
   One symbol per function is entered.  */
Packit Service 72eb06
Packit Service 72eb06
void
Packit Service 72eb06
core_create_function_syms (void)
Packit Service 72eb06
{
Packit Service 72eb06
  bfd_vma min_vma = ~ (bfd_vma) 0;
Packit Service 72eb06
  bfd_vma max_vma = 0;
Packit Service 72eb06
  int cxxclass;
Packit Service 72eb06
  long i;
Packit Service 72eb06
  struct function_map * found = NULL;
Packit Service 72eb06
  int core_has_func_syms = 0;
Packit Service 72eb06
Packit Service 72eb06
  switch (core_bfd->xvec->flavour)
Packit Service 72eb06
    {
Packit Service 72eb06
    default:
Packit Service 72eb06
      break;
Packit Service 72eb06
    case bfd_target_coff_flavour:
Packit Service 72eb06
    case bfd_target_ecoff_flavour:
Packit Service 72eb06
    case bfd_target_xcoff_flavour:
Packit Service 72eb06
    case bfd_target_elf_flavour:
Packit Service 72eb06
    case bfd_target_nlm_flavour:
Packit Service 72eb06
    case bfd_target_som_flavour:
Packit Service 72eb06
      core_has_func_syms = 1;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Pass 1 - determine upper bound on number of function names.  */
Packit Service 72eb06
  symtab.len = 0;
Packit Service 72eb06
Packit Service 72eb06
  for (i = 0; i < core_num_syms; ++i)
Packit Service 72eb06
    {
Packit Service 72eb06
      if (!core_sym_class (core_syms[i]))
Packit Service 72eb06
	continue;
Packit Service 72eb06
Packit Service 72eb06
      /* Don't create a symtab entry for a function that has
Packit Service 72eb06
	 a mapping to a file, unless it's the first function
Packit Service 72eb06
	 in the file.  */
Packit Service 72eb06
      if (symbol_map_count != 0)
Packit Service 72eb06
	{
Packit Service 72eb06
	  /* Note: some systems (SunOS 5.8) crash if bsearch base argument
Packit Service 72eb06
	     is NULL.  */
Packit Service 72eb06
	  found = (struct function_map *) bsearch
Packit Service 72eb06
	    (core_syms[i]->name, symbol_map, symbol_map_count,
Packit Service 72eb06
	     sizeof (struct function_map), search_mapped_symbol);
Packit Service 72eb06
	}
Packit Service 72eb06
      if (found == NULL || found->is_first)
Packit Service 72eb06
	++symtab.len;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  if (symtab.len == 0)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
Packit Service 72eb06
Packit Service 72eb06
  /* Pass 2 - create symbols.  */
Packit Service 72eb06
  symtab.limit = symtab.base;
Packit Service 72eb06
Packit Service 72eb06
  for (i = 0; i < core_num_syms; ++i)
Packit Service 72eb06
    {
Packit Service 72eb06
      asection *sym_sec;
Packit Service 72eb06
Packit Service 72eb06
      cxxclass = core_sym_class (core_syms[i]);
Packit Service 72eb06
Packit Service 72eb06
      if (!cxxclass)
Packit Service 72eb06
	{
Packit Service 72eb06
	  DBG (AOUTDEBUG,
Packit Service 72eb06
	       printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
Packit Service 72eb06
		       (unsigned long) core_syms[i]->value,
Packit Service 72eb06
		       core_syms[i]->name));
Packit Service 72eb06
	  continue;
Packit Service 72eb06
	}
Packit Service 72eb06
Packit Service 72eb06
      if (symbol_map_count != 0)
Packit Service 72eb06
	{
Packit Service 72eb06
	  /* Note: some systems (SunOS 5.8) crash if bsearch base argument
Packit Service 72eb06
	     is NULL.  */
Packit Service 72eb06
	  found = (struct function_map *) bsearch
Packit Service 72eb06
	    (core_syms[i]->name, symbol_map, symbol_map_count,
Packit Service 72eb06
	     sizeof (struct function_map), search_mapped_symbol);
Packit Service 72eb06
	}
Packit Service 72eb06
      if (found && ! found->is_first)
Packit Service 72eb06
	continue;
Packit Service 72eb06
Packit Service 72eb06
      sym_init (symtab.limit);
Packit Service 72eb06
Packit Service 72eb06
      /* Symbol offsets are always section-relative.  */
Packit Service 72eb06
      sym_sec = core_syms[i]->section;
Packit Service 72eb06
      symtab.limit->addr = core_syms[i]->value;
Packit Service 72eb06
      if (sym_sec)
Packit Service 72eb06
	symtab.limit->addr += bfd_get_section_vma (sym_sec->owner, sym_sec);
Packit Service 72eb06
Packit Service 72eb06
      if (found)
Packit Service 72eb06
	{
Packit Service 72eb06
	  symtab.limit->name = found->file_name;
Packit Service 72eb06
	  symtab.limit->mapped = 1;
Packit Service 72eb06
	}
Packit Service 72eb06
      else
Packit Service 72eb06
	{
Packit Service 72eb06
	  symtab.limit->name = core_syms[i]->name;
Packit Service 72eb06
	  symtab.limit->mapped = 0;
Packit Service 72eb06
	}
Packit Service 72eb06
Packit Service 72eb06
      /* Lookup filename and line number, if we can.  */
Packit Service 72eb06
      {
Packit Service 72eb06
	const char * filename;
Packit Service 72eb06
	const char * func_name;
Packit Service 72eb06
Packit Service 72eb06
	if (get_src_info (symtab.limit->addr, & filename, & func_name,
Packit Service 72eb06
			  & symtab.limit->line_num))
Packit Service 72eb06
	  {
Packit Service 72eb06
	    symtab.limit->file = source_file_lookup_path (filename);
Packit Service 72eb06
Packit Service 72eb06
	    /* FIXME: Checking __osf__ here does not work with a cross
Packit Service 72eb06
	       gprof.  */
Packit Service 72eb06
#ifdef __osf__
Packit Service 72eb06
	    /* Suppress symbols that are not function names.  This is
Packit Service 72eb06
	       useful to suppress code-labels and aliases.
Packit Service 72eb06
Packit Service 72eb06
	       This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
Packit Service 72eb06
	       labels do not appear in the symbol table info, so this isn't
Packit Service 72eb06
	       necessary.  */
Packit Service 72eb06
Packit Service 72eb06
	    if (strcmp (symtab.limit->name, func_name) != 0)
Packit Service 72eb06
	      {
Packit Service 72eb06
		/* The symbol's address maps to a different name, so
Packit Service 72eb06
		   it can't be a function-entry point.  This happens
Packit Service 72eb06
		   for labels, for example.  */
Packit Service 72eb06
		DBG (AOUTDEBUG,
Packit Service 72eb06
		     printf ("[core_create_function_syms: rej %s (maps to %s)\n",
Packit Service 72eb06
			     symtab.limit->name, func_name));
Packit Service 72eb06
		continue;
Packit Service 72eb06
	      }
Packit Service 72eb06
#endif
Packit Service 72eb06
	  }
Packit Service 72eb06
      }
Packit Service 72eb06
Packit Service 72eb06
      symtab.limit->is_func = (!core_has_func_syms
Packit Service 72eb06
			       || (core_syms[i]->flags & BSF_FUNCTION) != 0);
Packit Service 72eb06
      symtab.limit->is_bb_head = TRUE;
Packit Service 72eb06
Packit Service 72eb06
      if (cxxclass == 't')
Packit Service 72eb06
	symtab.limit->is_static = TRUE;
Packit Service 72eb06
Packit Service 72eb06
      /* Keep track of the minimum and maximum vma addresses used by all
Packit Service 72eb06
	 symbols.  When computing the max_vma, use the ending address of the
Packit Service 72eb06
	 section containing the symbol, if available.  */
Packit Service 72eb06
      min_vma = MIN (symtab.limit->addr, min_vma);
Packit Service 72eb06
      if (sym_sec)
Packit Service 72eb06
	max_vma = MAX (bfd_get_section_vma (sym_sec->owner, sym_sec)
Packit Service 72eb06
		       + bfd_section_size (sym_sec->owner, sym_sec) - 1,
Packit Service 72eb06
		       max_vma);
Packit Service 72eb06
      else
Packit Service 72eb06
	max_vma = MAX (symtab.limit->addr, max_vma);
Packit Service 72eb06
Packit Service 72eb06
      DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
Packit Service 72eb06
			      (long) (symtab.limit - symtab.base),
Packit Service 72eb06
			      symtab.limit->name,
Packit Service 72eb06
			      (unsigned long) symtab.limit->addr));
Packit Service 72eb06
      ++symtab.limit;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  symtab.len = symtab.limit - symtab.base;
Packit Service 72eb06
  symtab_finalize (&symtab);
Packit Service 72eb06
}
Packit Service 72eb06
Packit Service 72eb06
/* Read in symbol table from core.
Packit Service 72eb06
   One symbol per line of source code is entered.  */
Packit Service 72eb06
Packit Service 72eb06
void
Packit Service 72eb06
core_create_line_syms (void)
Packit Service 72eb06
{
Packit Service 72eb06
  char *prev_name, *prev_filename;
Packit Service 72eb06
  unsigned int prev_name_len, prev_filename_len;
Packit Service 72eb06
  bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0;
Packit Service 72eb06
  Sym *prev, dummy, *sym;
Packit Service 72eb06
  const char *filename;
Packit Service 72eb06
  int prev_line_num;
Packit Service 72eb06
  Sym_Table ltab;
Packit Service 72eb06
  bfd_vma vma_high;
Packit Service 72eb06
Packit Service 72eb06
  /* Create symbols for functions as usual.  This is necessary in
Packit Service 72eb06
     cases where parts of a program were not compiled with -g.  For
Packit Service 72eb06
     those parts we still want to get info at the function level.  */
Packit Service 72eb06
  core_create_function_syms ();
Packit Service 72eb06
Packit Service 72eb06
  /* Pass 1: count the number of symbols.  */
Packit Service 72eb06
Packit Service 72eb06
  /* To find all line information, walk through all possible
Packit Service 72eb06
     text-space addresses (one by one!) and get the debugging
Packit Service 72eb06
     info for each address.  When the debugging info changes,
Packit Service 72eb06
     it is time to create a new symbol.
Packit Service 72eb06
Packit Service 72eb06
     Of course, this is rather slow and it would be better if
Packit Service 72eb06
     BFD would provide an iterator for enumerating all line infos.  */
Packit Service 72eb06
  prev_name_len = PATH_MAX;
Packit Service 72eb06
  prev_filename_len = PATH_MAX;
Packit Service 72eb06
  prev_name = (char *) xmalloc (prev_name_len);
Packit Service 72eb06
  prev_filename = (char *) xmalloc (prev_filename_len);
Packit Service 72eb06
  ltab.len = 0;
Packit Service 72eb06
  prev_line_num = 0;
Packit Service 72eb06
Packit Service 72eb06
  vma_high = core_text_sect->vma + bfd_get_section_size (core_text_sect);
Packit Service 72eb06
  for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
Packit Service 72eb06
    {
Packit Service 72eb06
      unsigned int len;
Packit Service 72eb06
Packit Service 72eb06
      if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
Packit Service 72eb06
	  || (prev_line_num == dummy.line_num
Packit Service 72eb06
	      && prev_name != NULL
Packit Service 72eb06
	      && strcmp (prev_name, dummy.name) == 0
Packit Service 72eb06
	      && filename_cmp (prev_filename, filename) == 0))
Packit Service 72eb06
	continue;
Packit Service 72eb06
Packit Service 72eb06
      ++ltab.len;
Packit Service 72eb06
      prev_line_num = dummy.line_num;
Packit Service 72eb06
Packit Service 72eb06
      len = strlen (dummy.name);
Packit Service 72eb06
      if (len >= prev_name_len)
Packit Service 72eb06
	{
Packit Service 72eb06
	  prev_name_len = len + 1024;
Packit Service 72eb06
	  free (prev_name);
Packit Service 72eb06
	  prev_name = (char *) xmalloc (prev_name_len);
Packit Service 72eb06
	}
Packit Service 72eb06
Packit Service 72eb06
      strcpy (prev_name, dummy.name);
Packit Service 72eb06
      len = strlen (filename);
Packit Service 72eb06
Packit Service 72eb06
      if (len >= prev_filename_len)
Packit Service 72eb06
	{
Packit Service 72eb06
	  prev_filename_len = len + 1024;
Packit Service 72eb06
	  free (prev_filename);
Packit Service 72eb06
	  prev_filename = (char *) xmalloc (prev_filename_len);
Packit Service 72eb06
	}
Packit Service 72eb06
Packit Service 72eb06
      strcpy (prev_filename, filename);
Packit Service 72eb06
Packit Service 72eb06
      min_vma = MIN (vma, min_vma);
Packit Service 72eb06
      max_vma = MAX (vma, max_vma);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  free (prev_name);
Packit Service 72eb06
  free (prev_filename);
Packit Service 72eb06
Packit Service 72eb06
  /* Make room for function symbols, too.  */
Packit Service 72eb06
  ltab.len += symtab.len;
Packit Service 72eb06
  ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
Packit Service 72eb06
  ltab.limit = ltab.base;
Packit Service 72eb06
Packit Service 72eb06
  /* Pass 2 - create symbols.  */
Packit Service 72eb06
Packit Service 72eb06
  /* We now set is_static as we go along, rather than by running
Packit Service 72eb06
     through the symbol table at the end.
Packit Service 72eb06
Packit Service 72eb06
     The old way called symtab_finalize before the is_static pass,
Packit Service 72eb06
     causing a problem since symtab_finalize uses is_static as part of
Packit Service 72eb06
     its address conflict resolution algorithm.  Since global symbols
Packit Service 72eb06
     were preferred over static symbols, and all line symbols were
Packit Service 72eb06
     global at that point, static function names that conflicted with
Packit Service 72eb06
     their own line numbers (static, but labeled as global) were
Packit Service 72eb06
     rejected in favor of the line num.
Packit Service 72eb06
Packit Service 72eb06
     This was not the desired functionality.  We always want to keep
Packit Service 72eb06
     our function symbols and discard any conflicting line symbols.
Packit Service 72eb06
     Perhaps symtab_finalize should be modified to make this
Packit Service 72eb06
     distinction as well, but the current fix works and the code is a
Packit Service 72eb06
     lot cleaner now.  */
Packit Service 72eb06
  prev = 0;
Packit Service 72eb06
Packit Service 72eb06
  for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
Packit Service 72eb06
    {
Packit Service 72eb06
      sym_init (ltab.limit);
Packit Service 72eb06
Packit Service 72eb06
      if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
Packit Service 72eb06
	  || (prev && prev->line_num == ltab.limit->line_num
Packit Service 72eb06
	      && strcmp (prev->name, ltab.limit->name) == 0
Packit Service 72eb06
	      && filename_cmp (prev->file->name, filename) == 0))
Packit Service 72eb06
	continue;
Packit Service 72eb06
Packit Service 72eb06
      /* Make name pointer a malloc'ed string.  */
Packit Service 72eb06
      ltab.limit->name = xstrdup (ltab.limit->name);
Packit Service 72eb06
      ltab.limit->file = source_file_lookup_path (filename);
Packit Service 72eb06
Packit Service 72eb06
      ltab.limit->addr = vma;
Packit Service 72eb06
Packit Service 72eb06
      /* Set is_static based on the enclosing function, using either:
Packit Service 72eb06
	 1) the previous symbol, if it's from the same function, or
Packit Service 72eb06
	 2) a symtab lookup.  */
Packit Service 72eb06
      if (prev && ltab.limit->file == prev->file &&
Packit Service 72eb06
	  strcmp (ltab.limit->name, prev->name) == 0)
Packit Service 72eb06
	{
Packit Service 72eb06
	  ltab.limit->is_static = prev->is_static;
Packit Service 72eb06
	}
Packit Service 72eb06
      else
Packit Service 72eb06
	{
Packit Service 72eb06
	  sym = sym_lookup(&symtab, ltab.limit->addr);
Packit Service 72eb06
          if (sym)
Packit Service 72eb06
	    ltab.limit->is_static = sym->is_static;
Packit Service 72eb06
	}
Packit Service 72eb06
Packit Service 72eb06
      prev = ltab.limit;
Packit Service 72eb06
Packit Service 72eb06
      DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
Packit Service 72eb06
			      (unsigned long) (ltab.limit - ltab.base),
Packit Service 72eb06
			      ltab.limit->name,
Packit Service 72eb06
			      (unsigned long) ltab.limit->addr));
Packit Service 72eb06
      ++ltab.limit;
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Copy in function symbols.  */
Packit Service 72eb06
  memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
Packit Service 72eb06
  ltab.limit += symtab.len;
Packit Service 72eb06
Packit Service 72eb06
  if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
Packit Service 72eb06
    {
Packit Service 72eb06
      fprintf (stderr,
Packit Service 72eb06
	       _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
Packit Service 72eb06
	       whoami, ltab.len, (long) (ltab.limit - ltab.base));
Packit Service 72eb06
      done (1);
Packit Service 72eb06
    }
Packit Service 72eb06
Packit Service 72eb06
  /* Finalize ltab and make it symbol table.  */
Packit Service 72eb06
  symtab_finalize (&ltab);
Packit Service 72eb06
  free (symtab.base);
Packit Service 72eb06
  symtab = ltab;
Packit Service 72eb06
}