* corefile.c: Rename from core.c.
authorIan Lance Taylor <ian@airs.com>
Tue, 28 Apr 1998 23:52:20 +0000 (23:52 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 28 Apr 1998 23:52:20 +0000 (23:52 +0000)
* corefile.h: Rename from core.h.
* Many .c files: Include corefile.h rather than core.h.
* Makefile.am (sources): Change core.c to corefile.c.
(noinst_HEADERS): Change core.h to corefile.h.
($(OBJECTS)): Depend upon corefile.h rather than core.h.
(corefile.o): Rename target from core.o, depend upon corefile.c.
* Makefile.in, po/POTFILES.in: Rebuild.

20 files changed:
gprof/.Sanitize
gprof/ChangeLog
gprof/Makefile.am
gprof/Makefile.in
gprof/alpha.c
gprof/basic_blocks.c
gprof/call_graph.c
gprof/core.c [deleted file]
gprof/core.h [deleted file]
gprof/corefile.c [new file with mode: 0644]
gprof/corefile.h [new file with mode: 0644]
gprof/gmon_io.c
gprof/gprof.c
gprof/hist.c
gprof/i386.c
gprof/po/POTFILES.in
gprof/sparc.c
gprof/symtab.c
gprof/tahoe.c
gprof/vax.c

index ac1ec54091a0b9e3d8b209278ec9a80ef3cb2062..b5d3f3e632157fe41849c8cac51a188d397c1ad0 100644 (file)
@@ -50,8 +50,8 @@ cg_print.h
 configure
 configure.bat
 configure.in
-core.c
-core.h
+corefile.c
+corefile.h
 flat_bl.m
 fsf_callg_bl.m
 gconfig.in
index 7d4d438086dfe0d330c1baf68680aa468e80a5d0..e22276a5f827b6d2e7df505779cafbbd7d14faaf 100644 (file)
@@ -1,3 +1,14 @@
+Tue Apr 28 19:50:09 1998  Ian Lance Taylor  <ian@cygnus.com>
+
+       * corefile.c: Rename from core.c.
+       * corefile.h: Rename from core.h.
+       * Many .c files: Include corefile.h rather than core.h.
+       * Makefile.am (sources): Change core.c to corefile.c.
+       (noinst_HEADERS): Change core.h to corefile.h.
+       ($(OBJECTS)): Depend upon corefile.h rather than core.h.
+       (corefile.o): Rename target from core.o, depend upon corefile.c.
+       * Makefile.in, po/POTFILES.in: Rebuild.
+
 Mon Apr 27 16:50:40 1998  Ian Lance Taylor  <ian@cygnus.com>
 
        * configure.in: Change version number to 2.9.4
index 7a3f73e29d6d58ab5e6a835612e70ded3ec73901..7ae149212a5c5a8bce759db67727a69ca294ca1d 100644 (file)
@@ -12,7 +12,7 @@ bin_PROGRAMS = gprof
 
 ## Convenience var listing pure sources.
 sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
-       cg_print.c core.c gmon_io.c gprof.c hertz.c hist.c source.c \
+       cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
        search_list.c symtab.c sym_ids.c utils.c \
        i386.c alpha.c vax.c tahoe.c sparc.c
 gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
@@ -21,7 +21,7 @@ gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLLIBS)
 
 noinst_HEADERS = \
        basic_blocks.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \
-       core.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
+       corefile.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
        search_list.h source.h sym_ids.h symtab.h utils.h
 
 EXTRA_DIST = flat_bl.c bsd_callg_bl.c fsf_callg_bl.c bbconv.pl
@@ -45,7 +45,7 @@ man_MANS = gprof.1
 
 # Dependencies.
 $(OBJECTS): ../bfd/bfd.h call_graph.h cg_arcs.h cg_print.h \
-       core.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
+       corefile.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
        search_list.h source.h sym_ids.h symtab.h utils.h \
        $(srcdir)/../include/libiberty.h $(srcdir)/../bfd/sysdep.h \
        gconfig.h ../bfd/config.h
@@ -55,7 +55,7 @@ call_graph.o: call_graph.c
 cg_arcs.o: cg_arcs.c
 cg_dfn.o: cg_dfn.c
 cg_print.o: cg_print.c
-core.o: core.c
+corefile.o: corefile.c
 flat_bl.o: flat_bl.c
 fsf_callg_bl.o: fsf_callg_bl.c
 gmon_io.o: gmon_io.c
index 6c121c6cc4f8b893197c32abf157c71939c9df34..743146392139f23016b9bb8eb30e9689838adae0 100644 (file)
@@ -107,7 +107,7 @@ INCLUDES = -D_GNU_SOURCE -DDEBUG -I../bfd -I$(srcdir)/../include -I$(srcdir)/../
 bin_PROGRAMS = gprof
 
 sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
-       cg_print.c core.c gmon_io.c gprof.c hertz.c hist.c source.c \
+       cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
        search_list.c symtab.c sym_ids.c utils.c \
        i386.c alpha.c vax.c tahoe.c sparc.c
 gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
@@ -116,7 +116,7 @@ gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLLIBS)
 
 noinst_HEADERS = \
        basic_blocks.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \
-       core.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
+       corefile.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
        search_list.h source.h sym_ids.h symtab.h utils.h
 
 EXTRA_DIST = flat_bl.c bsd_callg_bl.c fsf_callg_bl.c bbconv.pl
@@ -140,7 +140,7 @@ CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
 gprof_OBJECTS =  basic_blocks.o call_graph.o cg_arcs.o cg_dfn.o \
-cg_print.o core.o gmon_io.o gprof.o hertz.o hist.o source.o \
+cg_print.o corefile.o gmon_io.o gprof.o hertz.o hist.o source.o \
 search_list.o symtab.o sym_ids.o utils.o i386.o alpha.o vax.o tahoe.o \
 sparc.o flat_bl.o bsd_callg_bl.o fsf_callg_bl.o
 gprof_LDFLAGS = 
@@ -650,7 +650,7 @@ po/POTFILES.in: @MAINT@ Makefile
 
 # Dependencies.
 $(OBJECTS): ../bfd/bfd.h call_graph.h cg_arcs.h cg_print.h \
-       core.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
+       corefile.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
        search_list.h source.h sym_ids.h symtab.h utils.h \
        $(srcdir)/../include/libiberty.h $(srcdir)/../bfd/sysdep.h \
        gconfig.h ../bfd/config.h
@@ -660,7 +660,7 @@ call_graph.o: call_graph.c
 cg_arcs.o: cg_arcs.c
 cg_dfn.o: cg_dfn.c
 cg_print.o: cg_print.c
-core.o: core.c
+corefile.o: corefile.c
 flat_bl.o: flat_bl.c
 fsf_callg_bl.o: fsf_callg_bl.c
 gmon_io.o: gmon_io.c
index 2c9a8dd2642c40aee47274277c3c914026842669..d9d55d5cfce98b90aeb6174d5f798a11c4f509d8 100644 (file)
@@ -18,7 +18,7 @@
  */
 #include "gprof.h"
 #include "cg_arcs.h"
-#include "core.h"
+#include "corefile.h"
 #include "hist.h"
 #include "symtab.h"
 
index 00525dda56c272307170591203da368c9472dfce..0c0fc43377489997807ea2c1d218d31c6733c439 100644 (file)
@@ -6,7 +6,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include "basic_blocks.h"
-#include "core.h"
+#include "corefile.h"
 #include "gmon_io.h"
 #include "gmon_out.h"
 #include "gprof.h"
index 2c56caf5fbc8117df482b4abdc62e2b5ab594a61..693d337404636bb5e1f6302c4d798e74f974762f 100644 (file)
@@ -1,6 +1,6 @@
 #include "cg_arcs.h"
 #include "call_graph.h"
-#include "core.h"
+#include "corefile.h"
 #include "gmon_io.h"
 #include "gmon_out.h"
 #include "symtab.h"
diff --git a/gprof/core.c b/gprof/core.c
deleted file mode 100644 (file)
index d074d3a..0000000
+++ /dev/null
@@ -1,737 +0,0 @@
-#include "libiberty.h"
-#include "gprof.h"
-#include "core.h"
-#include "symtab.h"
-
-bfd *core_bfd;
-int core_num_syms;
-asymbol **core_syms;
-asection *core_text_sect;
-PTR core_text_space;
-
-int min_insn_size;
-int offset_to_code;
-
-/* For mapping symbols to specific .o files during file ordering.  */
-struct function_map {
-  char *function_name;
-  char *file_name;
-};
-
-struct function_map *symbol_map;
-unsigned int symbol_map_count;
-
-extern void i386_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
-extern void alpha_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
-extern void vax_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
-extern void tahoe_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
-extern void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
-
-static void
-DEFUN (read_function_mappings, (filename), const char *filename)
-{
-  FILE *file = fopen (filename, "r");
-  char dummy[1024];
-  int count = 0;
-
-  if (!file)
-    {
-      fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
-      done (1);
-    }
-
-  /* First parse the mapping file so we know how big we need to
-     make our tables.  We also do some sanity checks at this
-     time.  */
-  while (!feof (file))
-    {
-      int matches;
-
-      matches = fscanf (file, "%[^\n:]", dummy);
-      if (!matches)
-       {
-         fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
-                  whoami, filename);
-         done (1);
-       }
-
-      /* Just skip messages about files with no symbols.  */
-      if (!strncmp (dummy, "No symbols in ", 14))
-       {
-         fscanf (file, "\n");
-         continue;
-       }
-
-      /* Don't care what else is on this line at this point.  */
-      fscanf (file, "%[^\n]\n", dummy);
-      count++;
-    }
-
-  /* Now we know how big we need to make our table.  */
-  symbol_map = ((struct function_map *)
-               xmalloc (count * sizeof (struct function_map)));
-
-  /* Rewind the input file so we can read it again.  */
-  rewind (file);
-
-  /* Read each entry and put it into the table.  */
-  count = 0;
-  while (!feof (file))
-    {
-      int matches;
-      char *tmp;
-
-      matches = fscanf (file, "%[^\n:]", dummy);
-      if (!matches)
-       {
-         fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
-                  whoami, filename);
-         done (1);
-       }
-
-      /* Just skip messages about files with no symbols.  */
-      if (!strncmp (dummy, "No symbols in ", 14))
-       {
-         fscanf (file, "\n");
-         continue;
-       }
-
-      /* dummy has the filename, go ahead and copy it.  */
-      symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
-      strcpy (symbol_map[count].file_name, dummy);
-
-      /* Now we need the function name.  */
-      fscanf (file, "%[^\n]\n", dummy);
-      tmp = strrchr (dummy, ' ') + 1;
-      symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
-      strcpy (symbol_map[count].function_name, tmp);
-      count++;
-    }
-
-  /* Record the size of the map table for future reference.  */
-  symbol_map_count = count;
-}
-
-void
-DEFUN (core_init, (a_out_name), const char *a_out_name)
-{
-  core_bfd = bfd_openr (a_out_name, 0);
-
-  if (!core_bfd)
-    {
-      perror (a_out_name);
-      done (1);
-    }
-
-  if (!bfd_check_format (core_bfd, bfd_object))
-    {
-      fprintf (stderr, _("%s: %s: not in a.out format\n"), whoami, a_out_name);
-      done (1);
-    }
-
-  /* get core's text section: */
-  core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
-  if (!core_text_sect)
-    {
-      core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
-      if (!core_text_sect)
-       {
-         fprintf (stderr, _("%s: can't find .text section in %s\n"),
-                  whoami, a_out_name);
-         done (1);
-       }
-    }
-
-  /* read core's symbol table: */
-
-  /* this will probably give us more than we need, but that's ok:  */
-  core_num_syms = bfd_get_symtab_upper_bound (core_bfd);
-  if (core_num_syms < 0)
-    {
-      fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
-              bfd_errmsg (bfd_get_error ()));
-      done (1);
-    }
-
-  core_syms = (asymbol **) xmalloc (core_num_syms);
-  core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
-  if (core_num_syms < 0)
-    {
-      fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
-              bfd_errmsg (bfd_get_error ()));
-      done (1);
-    }
-
-  min_insn_size = 1;
-  offset_to_code = 0;
-
-  switch (bfd_get_arch (core_bfd))
-    {
-    case bfd_arch_vax:
-    case bfd_arch_tahoe:
-      offset_to_code = 2;
-      break;
-
-    case bfd_arch_alpha:
-      min_insn_size = 4;
-      break;
-
-    default:
-      break;
-    }
-
-  if (function_mapping_file)
-    read_function_mappings (function_mapping_file);
-}
-
-
-/*
- * Read in the text space of an a.out file
- */
-void
-DEFUN (core_get_text_space, (core_bfd), bfd * core_bfd)
-{
-  core_text_space = (PTR) malloc (core_text_sect->_raw_size);
-
-  if (!core_text_space)
-    {
-      fprintf (stderr, _("%s: ran out room for %ld bytes of text space\n"),
-              whoami, core_text_sect->_raw_size);
-      done (1);
-    }
-  if (!bfd_get_section_contents (core_bfd, core_text_sect, core_text_space,
-                                0, core_text_sect->_raw_size))
-    {
-      bfd_perror ("bfd_get_section_contents");
-      free (core_text_space);
-      core_text_space = 0;
-    }
-  if (!core_text_space)
-    {
-      fprintf (stderr, _("%s: can't do -c\n"), whoami);
-    }
-}
-
-
-void
-DEFUN (find_call, (parent, p_lowpc, p_highpc),
-       Sym * parent AND bfd_vma p_lowpc AND bfd_vma p_highpc)
-{
-  switch (bfd_get_arch (core_bfd))
-    {
-    case bfd_arch_i386:
-      i386_find_call (parent, p_lowpc, p_highpc);
-      break;
-
-    case bfd_arch_alpha:
-      alpha_find_call (parent, p_lowpc, p_highpc);
-      break;
-
-    case bfd_arch_vax:
-      vax_find_call (parent, p_lowpc, p_highpc);
-      break;
-
-    case bfd_arch_sparc:
-      sparc_find_call (parent, p_lowpc, p_highpc);
-      break;
-
-    case bfd_arch_tahoe:
-      tahoe_find_call (parent, p_lowpc, p_highpc);
-      break;
-
-    default:
-      fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
-              whoami, bfd_printable_name(core_bfd));
-
-      /* Don't give the error more than once.  */
-      ignore_direct_calls = FALSE;
-    }
-}
-
-/*
- * Return class of symbol SYM.  The returned class can be any of:
- *      0   -> symbol is not interesting to us
- *      'T' -> symbol is a global name
- *      't' -> symbol is a local (static) name
- */
-static int
-DEFUN (core_sym_class, (sym), asymbol * sym)
-{
-  symbol_info syminfo;
-  const char *name;
-  char sym_prefix;
-  int i;
-
-  if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
-    {
-      return 0;
-    }
-
-  /*
-   * Must be a text symbol, and static text symbols don't qualify if
-   * ignore_static_funcs set.
-   */
-  if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
-    {
-      DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
-                             sym->name));
-      return 0;
-    }
-
-  bfd_get_symbol_info (core_bfd, sym, &syminfo);
-  i = syminfo.type;
-
-  if (i == 'T')
-    {
-      return i;                        /* it's a global symbol */
-    }
-
-  if (i == 'W')
-    {
-      /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
-         also be a data symbol.  */
-      return 'T';
-    }
-
-  if (i != 't')
-    {
-      /* not a static text symbol */
-      DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
-                             sym->name, i));
-      return 0;
-    }
-
-  /* do some more filtering on static function-names: */
-
-  if (ignore_static_funcs)
-    {
-      return 0;
-    }
-  /*
-   * Can't zero-length name or funny characters in name, where
-   * `funny' includes: `.' (.o file names) and `$' (Pascal labels).
-   */
-  if (!sym->name || sym->name[0] == '\0')
-    {
-      return 0;
-    }
-
-  for (name = sym->name; *name; ++name)
-    {
-      if (*name == '.' || *name == '$')
-       {
-         return 0;
-       }
-    }
-  /*
-   * On systems where the C compiler adds an underscore to all
-   * names, static names without underscores seem usually to be
-   * labels in hand written assembler in the library.  We don't want
-   * these names.  This is certainly necessary on a Sparc running
-   * SunOS 4.1 (try profiling a program that does a lot of
-   * division). I don't know whether it has harmful side effects on
-   * other systems.  Perhaps it should be made configurable.
-   */
-  sym_prefix = bfd_get_symbol_leading_char (core_bfd);
-  if ((sym_prefix && sym_prefix != sym->name[0])
-  /*
-   * GCC may add special symbols to help gdb figure out the file
-   * language.  We want to ignore these, since sometimes they mask
-   * the real function.  (dj@ctron)
-   */
-      || !strncmp (sym->name, "__gnu_compiled", 14)
-      || !strncmp (sym->name, "___gnu_compiled", 15))
-    {
-      return 0;
-    }
-
-  /* If the object file supports marking of function symbols, then we can
-     zap anything that doesn't have BSF_FUNCTION set.  */
-  if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
-    return 0;
-
-  return 't';                  /* it's a static text symbol */
-}
-
-
-/*
- * Get whatever source info we can get regarding address ADDR:
- */
-static bool
-DEFUN (get_src_info, (addr, filename, name, line_num),
-       bfd_vma addr AND const char **filename AND const char **name
-       AND int *line_num)
-{
-  const char *fname = 0, *func_name = 0;
-  int l = 0;
-
-  if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
-                            addr - core_text_sect->vma,
-                            &fname, &func_name, (unsigned int *) &l)
-      && fname && func_name && l)
-    {
-      DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
-                             addr, fname, l, func_name));
-      *filename = fname;
-      *name = func_name;
-      *line_num = l;
-      return TRUE;
-    }
-  else
-    {
-      DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
-                             (long) addr, fname ? fname : "<unknown>", l,
-                             func_name ? func_name : "<unknown>"));
-      return FALSE;
-    }
-}
-
-
-/*
- * Read in symbol table from core.  One symbol per function is
- * entered.
- */
-void
-DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
-{
-  bfd_vma min_vma = ~0, max_vma = 0;
-  int class;
-  long i, found, skip;
-  unsigned int j;
-
-  /* pass 1 - determine upper bound on number of function names: */
-  symtab.len = 0;
-  for (i = 0; i < core_num_syms; ++i)
-    {
-      if (!core_sym_class (core_syms[i]))
-       {
-         continue;
-       }
-
-      /* This should be replaced with a binary search or hashed
-        search.  Gross. 
-
-        Don't create a symtab entry for a function that has
-        a mapping to a file, unless it's the first function
-        in the file.  */
-      skip = 0;
-      for (j = 0; j < symbol_map_count; j++)
-       if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
-         {
-           if (j > 0 && ! strcmp (symbol_map [j].file_name,
-                                  symbol_map [j - 1].file_name))
-             skip = 1;
-           break;
-         }
-      if (!skip)
-        ++symtab.len;
-    }
-
-  if (symtab.len == 0)
-    {
-      fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
-      done (1);
-    }
-
-  /* the "+ 2" is for the sentinels: */
-  symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
-
-  /* pass 2 - create symbols: */
-
-  symtab.limit = symtab.base;
-  for (i = 0; i < core_num_syms; ++i)
-    {
-      class = core_sym_class (core_syms[i]);
-      if (!class)
-       {
-         DBG (AOUTDEBUG,
-              printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
-                      core_syms[i]->value, core_syms[i]->name));
-         continue;
-       }
-      /* This should be replaced with a binary search or hashed
-        search.  Gross.   */
-
-      skip = 0;
-      found = 0;
-      for (j = 0; j < symbol_map_count; j++)
-       if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
-         {
-           if (j > 0 && ! strcmp (symbol_map [j].file_name,
-                                  symbol_map [j - 1].file_name))
-             skip = 1;
-           else
-             found = j;
-           break;
-         }
-
-      if (skip)
-       continue;
-
-      sym_init (symtab.limit);
-
-      /* symbol offsets are always section-relative: */
-
-      symtab.limit->addr = core_syms[i]->value + core_syms[i]->section->vma;
-      if (symbol_map_count
-         && !strcmp (core_syms[i]->name, symbol_map[found].function_name))
-       {
-         symtab.limit->name = symbol_map[found].file_name;
-         symtab.limit->mapped = 1;
-       }
-      else
-       {
-         symtab.limit->name = core_syms[i]->name;
-         symtab.limit->mapped = 0;
-       }
-
-      /* Lookup filename and line number, if we can */
-
-      {
-       const char *filename, *func_name;
-       
-       if (get_src_info (symtab.limit->addr, &filename, &func_name,
-                         &symtab.limit->line_num))
-         {
-           symtab.limit->file = source_file_lookup_path (filename);
-
-           /* FIXME: Checking __osf__ here does not work with a cross
-               gprof.  */
-#ifdef __osf__
-           /*
-            * Suppress symbols that are not function names.  This is
-            * useful to suppress code-labels and aliases.
-            *
-            * This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
-            * labels do not appear in the symbol table info, so this isn't
-            * necessary.
-            */
-
-           if (strcmp (symtab.limit->name, func_name) != 0)
-             {
-               /*
-                * The symbol's address maps to a different name, so
-                * it can't be a function-entry point.  This happens
-                * for labels, for example.
-                */
-               DBG (AOUTDEBUG,
-                    printf ("[core_create_function_syms: rej %s (maps to %s)\n",
-                            symtab.limit->name, func_name));
-               continue;
-             }
-#endif
-         }
-      }
-
-      symtab.limit->is_func = TRUE;
-      symtab.limit->is_bb_head = TRUE;
-      if (class == 't')
-       {
-         symtab.limit->is_static = TRUE;
-       }
-
-      min_vma = MIN (symtab.limit->addr, min_vma);
-      max_vma = MAX (symtab.limit->addr, max_vma);
-
-      /*
-       * If we see "main" without an initial '_', we assume names
-       * are *not* prefixed by '_'.
-       */
-      if (symtab.limit->name[0] == 'm' && discard_underscores
-         && strcmp (symtab.limit->name, "main") == 0)
-       {
-         discard_underscores = 0;
-       }
-
-      DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
-                             (long) (symtab.limit - symtab.base),
-                             symtab.limit->name, symtab.limit->addr));
-      ++symtab.limit;
-    }
-
-  /* create sentinels: */
-
-  sym_init (symtab.limit);
-  symtab.limit->name = "<locore>";
-  symtab.limit->addr = 0;
-  symtab.limit->end_addr = min_vma - 1;
-  ++symtab.limit;
-
-  sym_init (symtab.limit);
-  symtab.limit->name = "<hicore>";
-  symtab.limit->addr = max_vma + 1;
-  symtab.limit->end_addr = ~0;
-  ++symtab.limit;
-
-  symtab.len = symtab.limit - symtab.base;
-  symtab_finalize (&symtab);
-}
-
-
-/*
- * Read in symbol table from core.  One symbol per line of source code
- * is entered.
- */
-void
-DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
-{
-  char prev_name[PATH_MAX], prev_filename[PATH_MAX];
-  bfd_vma vma, min_vma = ~0, max_vma = 0;
-  bfd_vma offset;
-  Sym *prev, dummy, *sentinel, *sym;
-  const char *filename;
-  int prev_line_num;
-  Sym_Table ltab;
-  /*
-   * Create symbols for functions as usual.  This is necessary in
-   * cases where parts of a program were not compiled with -g.  For
-   * those parts we still want to get info at the function level:
-   */
-  core_create_function_syms (core_bfd);
-
-  /* pass 1 - counter number of symbols: */
-
-  /*
-   * To find all line information, walk through all possible
-   * text-space addresses (one by one!) and get the debugging
-   * info for each address.  When the debugging info changes,
-   * it is time to create a new symbol.
-   *
-   * Of course, this is rather slow and it would be better if
-   * bfd would provide an iterator for enumerating all line infos
-   */
-  prev_name[0] = '\0';
-  ltab.len = 0;
-  prev_filename[0] = '\0';
-  prev_line_num = 0;
-  for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
-    {
-      vma = core_text_sect->vma + offset;
-      if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
-         || (prev_line_num == dummy.line_num &&
-             strcmp (prev_name, dummy.name) == 0
-             && strcmp (prev_filename, filename) == 0))
-       {
-         continue;
-       }
-
-      ++ltab.len;
-      prev_line_num = dummy.line_num;
-      strcpy (prev_name, dummy.name);
-      strcpy (prev_filename, filename);
-
-      min_vma = MIN (vma, min_vma);
-      max_vma = MAX (vma, max_vma);
-    }
-
-  /* make room for function symbols, too: */
-  ltab.len += symtab.len;
-  ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
-  ltab.limit = ltab.base;
-
-  /* pass 2 - create symbols: */
-
-  /* We now set is_static as we go along, rather than by running
-     through the symbol table at the end.
-
-     The old way called symtab_finalize before the is_static pass,
-     causing a problem since symtab_finalize uses is_static as part of
-     its address conflict resolution algorithm.  Since global symbols
-     were prefered over static symbols, and all line symbols were
-     global at that point, static function names that conflicted with
-     their own line numbers (static, but labeled as global) were
-     rejected in favor of the line num.
-
-     This was not the desired functionality.  We always want to keep
-     our function symbols and discard any conflicting line symbols.
-     Perhaps symtab_finalize should be modified to make this
-     distinction as well, but the current fix works and the code is a
-     lot cleaner now.  */
-
-  prev = 0;
-  for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
-    {
-      sym_init (ltab.limit);
-      if (!get_src_info (core_text_sect->vma + offset, &filename,
-                        &ltab.limit->name, &ltab.limit->line_num)
-         || (prev && prev->line_num == ltab.limit->line_num
-             && strcmp (prev->name, ltab.limit->name) == 0
-             && strcmp (prev->file->name, filename) == 0))
-       {
-         continue;
-       }
-
-      /* make name pointer a malloc'ed string: */
-      ltab.limit->name = xstrdup (ltab.limit->name);
-      ltab.limit->file = source_file_lookup_path (filename);
-
-      ltab.limit->addr = core_text_sect->vma + offset;
-
-      /* Set is_static based on the enclosing function, using either:
-       * 1) the previous symbol, if it's from the same function, or
-       * 2) a symtab lookup
-       */
-
-      if (prev && ltab.limit->file == prev->file &&
-         strcmp (ltab.limit->name, prev->name) == 0)
-       {
-         ltab.limit->is_static = prev->is_static;
-       }
-      else
-       {
-         sym = sym_lookup(&symtab, ltab.limit->addr);
-         ltab.limit->is_static = sym->is_static;
-       }
-
-      prev = ltab.limit;
-
-      /*
-       * If we see "main" without an initial '_', we assume names
-       * are *not* prefixed by '_'.
-       */
-      if (ltab.limit->name[0] == 'm' && discard_underscores
-         && strcmp (ltab.limit->name, "main") == 0)
-       {
-         discard_underscores = 0;
-       }
-
-      DBG (AOUTDEBUG, printf ("[core_create_line_syms] %d %s 0x%lx\n",
-                             ltab.limit - ltab.base, ltab.limit->name,
-                             ltab.limit->addr));
-      ++ltab.limit;
-    }
-
-  /* update sentinels: */
-
-  sentinel = sym_lookup (&symtab, 0);
-  if (strcmp (sentinel->name, "<locore>") == 0
-      && min_vma <= sentinel->end_addr)
-    {
-      sentinel->end_addr = min_vma - 1;
-    }
-
-  sentinel = sym_lookup (&symtab, ~0);
-  if (strcmp (sentinel->name, "<hicore>") == 0 && max_vma >= sentinel->addr)
-    {
-      sentinel->addr = max_vma + 1;
-    }
-
-  /* copy in function symbols: */
-  memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
-  ltab.limit += symtab.len;
-
-  if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
-    {
-      fprintf (stderr,
-              _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
-              whoami, ltab.len, (long) (ltab.limit - ltab.base));
-      done (1);
-    }
-
-  /* finalize ltab and make it symbol table: */
-
-  symtab_finalize (&ltab);
-  free (symtab.base);
-  symtab = ltab;
-
-}
diff --git a/gprof/core.h b/gprof/core.h
deleted file mode 100644 (file)
index a78b58a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef core_h
-#define core_h
-
-#include "bfd.h"
-
-extern bfd *core_bfd;          /* bfd for core-file */
-extern int core_num_syms;      /* # of entries in symbol-table */
-extern asymbol **core_syms;    /* symbol table in a.out */
-extern asection *core_text_sect;       /* core text section */
-extern PTR core_text_space;    /* text space of a.out in core */
-
-extern int min_insn_size;      /* size of smallest instruction, in bytes */
-extern int offset_to_code;     /* offset (in bytes) of code from entry
-                                  address of routine */
-
-extern void core_init PARAMS ((const char *a_out_name));
-extern void core_get_text_space PARAMS ((bfd * core_bfd));
-extern void core_create_function_syms PARAMS ((bfd * core_bfd));
-extern void core_create_line_syms PARAMS ((bfd * core_bfd));
-
-#endif /* core_h */
diff --git a/gprof/corefile.c b/gprof/corefile.c
new file mode 100644 (file)
index 0000000..3f3468b
--- /dev/null
@@ -0,0 +1,737 @@
+#include "libiberty.h"
+#include "gprof.h"
+#include "corefile.h"
+#include "symtab.h"
+
+bfd *core_bfd;
+int core_num_syms;
+asymbol **core_syms;
+asection *core_text_sect;
+PTR core_text_space;
+
+int min_insn_size;
+int offset_to_code;
+
+/* For mapping symbols to specific .o files during file ordering.  */
+struct function_map {
+  char *function_name;
+  char *file_name;
+};
+
+struct function_map *symbol_map;
+unsigned int symbol_map_count;
+
+extern void i386_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void alpha_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void vax_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void tahoe_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+
+static void
+DEFUN (read_function_mappings, (filename), const char *filename)
+{
+  FILE *file = fopen (filename, "r");
+  char dummy[1024];
+  int count = 0;
+
+  if (!file)
+    {
+      fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
+      done (1);
+    }
+
+  /* First parse the mapping file so we know how big we need to
+     make our tables.  We also do some sanity checks at this
+     time.  */
+  while (!feof (file))
+    {
+      int matches;
+
+      matches = fscanf (file, "%[^\n:]", dummy);
+      if (!matches)
+       {
+         fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
+                  whoami, filename);
+         done (1);
+       }
+
+      /* Just skip messages about files with no symbols.  */
+      if (!strncmp (dummy, "No symbols in ", 14))
+       {
+         fscanf (file, "\n");
+         continue;
+       }
+
+      /* Don't care what else is on this line at this point.  */
+      fscanf (file, "%[^\n]\n", dummy);
+      count++;
+    }
+
+  /* Now we know how big we need to make our table.  */
+  symbol_map = ((struct function_map *)
+               xmalloc (count * sizeof (struct function_map)));
+
+  /* Rewind the input file so we can read it again.  */
+  rewind (file);
+
+  /* Read each entry and put it into the table.  */
+  count = 0;
+  while (!feof (file))
+    {
+      int matches;
+      char *tmp;
+
+      matches = fscanf (file, "%[^\n:]", dummy);
+      if (!matches)
+       {
+         fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
+                  whoami, filename);
+         done (1);
+       }
+
+      /* Just skip messages about files with no symbols.  */
+      if (!strncmp (dummy, "No symbols in ", 14))
+       {
+         fscanf (file, "\n");
+         continue;
+       }
+
+      /* dummy has the filename, go ahead and copy it.  */
+      symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
+      strcpy (symbol_map[count].file_name, dummy);
+
+      /* Now we need the function name.  */
+      fscanf (file, "%[^\n]\n", dummy);
+      tmp = strrchr (dummy, ' ') + 1;
+      symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
+      strcpy (symbol_map[count].function_name, tmp);
+      count++;
+    }
+
+  /* Record the size of the map table for future reference.  */
+  symbol_map_count = count;
+}
+
+void
+DEFUN (core_init, (a_out_name), const char *a_out_name)
+{
+  core_bfd = bfd_openr (a_out_name, 0);
+
+  if (!core_bfd)
+    {
+      perror (a_out_name);
+      done (1);
+    }
+
+  if (!bfd_check_format (core_bfd, bfd_object))
+    {
+      fprintf (stderr, _("%s: %s: not in a.out format\n"), whoami, a_out_name);
+      done (1);
+    }
+
+  /* get core's text section: */
+  core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
+  if (!core_text_sect)
+    {
+      core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
+      if (!core_text_sect)
+       {
+         fprintf (stderr, _("%s: can't find .text section in %s\n"),
+                  whoami, a_out_name);
+         done (1);
+       }
+    }
+
+  /* read core's symbol table: */
+
+  /* this will probably give us more than we need, but that's ok:  */
+  core_num_syms = bfd_get_symtab_upper_bound (core_bfd);
+  if (core_num_syms < 0)
+    {
+      fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
+              bfd_errmsg (bfd_get_error ()));
+      done (1);
+    }
+
+  core_syms = (asymbol **) xmalloc (core_num_syms);
+  core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
+  if (core_num_syms < 0)
+    {
+      fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
+              bfd_errmsg (bfd_get_error ()));
+      done (1);
+    }
+
+  min_insn_size = 1;
+  offset_to_code = 0;
+
+  switch (bfd_get_arch (core_bfd))
+    {
+    case bfd_arch_vax:
+    case bfd_arch_tahoe:
+      offset_to_code = 2;
+      break;
+
+    case bfd_arch_alpha:
+      min_insn_size = 4;
+      break;
+
+    default:
+      break;
+    }
+
+  if (function_mapping_file)
+    read_function_mappings (function_mapping_file);
+}
+
+
+/*
+ * Read in the text space of an a.out file
+ */
+void
+DEFUN (core_get_text_space, (core_bfd), bfd * core_bfd)
+{
+  core_text_space = (PTR) malloc (core_text_sect->_raw_size);
+
+  if (!core_text_space)
+    {
+      fprintf (stderr, _("%s: ran out room for %ld bytes of text space\n"),
+              whoami, core_text_sect->_raw_size);
+      done (1);
+    }
+  if (!bfd_get_section_contents (core_bfd, core_text_sect, core_text_space,
+                                0, core_text_sect->_raw_size))
+    {
+      bfd_perror ("bfd_get_section_contents");
+      free (core_text_space);
+      core_text_space = 0;
+    }
+  if (!core_text_space)
+    {
+      fprintf (stderr, _("%s: can't do -c\n"), whoami);
+    }
+}
+
+
+void
+DEFUN (find_call, (parent, p_lowpc, p_highpc),
+       Sym * parent AND bfd_vma p_lowpc AND bfd_vma p_highpc)
+{
+  switch (bfd_get_arch (core_bfd))
+    {
+    case bfd_arch_i386:
+      i386_find_call (parent, p_lowpc, p_highpc);
+      break;
+
+    case bfd_arch_alpha:
+      alpha_find_call (parent, p_lowpc, p_highpc);
+      break;
+
+    case bfd_arch_vax:
+      vax_find_call (parent, p_lowpc, p_highpc);
+      break;
+
+    case bfd_arch_sparc:
+      sparc_find_call (parent, p_lowpc, p_highpc);
+      break;
+
+    case bfd_arch_tahoe:
+      tahoe_find_call (parent, p_lowpc, p_highpc);
+      break;
+
+    default:
+      fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
+              whoami, bfd_printable_name(core_bfd));
+
+      /* Don't give the error more than once.  */
+      ignore_direct_calls = FALSE;
+    }
+}
+
+/*
+ * Return class of symbol SYM.  The returned class can be any of:
+ *      0   -> symbol is not interesting to us
+ *      'T' -> symbol is a global name
+ *      't' -> symbol is a local (static) name
+ */
+static int
+DEFUN (core_sym_class, (sym), asymbol * sym)
+{
+  symbol_info syminfo;
+  const char *name;
+  char sym_prefix;
+  int i;
+
+  if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
+    {
+      return 0;
+    }
+
+  /*
+   * Must be a text symbol, and static text symbols don't qualify if
+   * ignore_static_funcs set.
+   */
+  if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
+    {
+      DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
+                             sym->name));
+      return 0;
+    }
+
+  bfd_get_symbol_info (core_bfd, sym, &syminfo);
+  i = syminfo.type;
+
+  if (i == 'T')
+    {
+      return i;                        /* it's a global symbol */
+    }
+
+  if (i == 'W')
+    {
+      /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
+         also be a data symbol.  */
+      return 'T';
+    }
+
+  if (i != 't')
+    {
+      /* not a static text symbol */
+      DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
+                             sym->name, i));
+      return 0;
+    }
+
+  /* do some more filtering on static function-names: */
+
+  if (ignore_static_funcs)
+    {
+      return 0;
+    }
+  /*
+   * Can't zero-length name or funny characters in name, where
+   * `funny' includes: `.' (.o file names) and `$' (Pascal labels).
+   */
+  if (!sym->name || sym->name[0] == '\0')
+    {
+      return 0;
+    }
+
+  for (name = sym->name; *name; ++name)
+    {
+      if (*name == '.' || *name == '$')
+       {
+         return 0;
+       }
+    }
+  /*
+   * On systems where the C compiler adds an underscore to all
+   * names, static names without underscores seem usually to be
+   * labels in hand written assembler in the library.  We don't want
+   * these names.  This is certainly necessary on a Sparc running
+   * SunOS 4.1 (try profiling a program that does a lot of
+   * division). I don't know whether it has harmful side effects on
+   * other systems.  Perhaps it should be made configurable.
+   */
+  sym_prefix = bfd_get_symbol_leading_char (core_bfd);
+  if ((sym_prefix && sym_prefix != sym->name[0])
+  /*
+   * GCC may add special symbols to help gdb figure out the file
+   * language.  We want to ignore these, since sometimes they mask
+   * the real function.  (dj@ctron)
+   */
+      || !strncmp (sym->name, "__gnu_compiled", 14)
+      || !strncmp (sym->name, "___gnu_compiled", 15))
+    {
+      return 0;
+    }
+
+  /* If the object file supports marking of function symbols, then we can
+     zap anything that doesn't have BSF_FUNCTION set.  */
+  if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
+    return 0;
+
+  return 't';                  /* it's a static text symbol */
+}
+
+
+/*
+ * Get whatever source info we can get regarding address ADDR:
+ */
+static bool
+DEFUN (get_src_info, (addr, filename, name, line_num),
+       bfd_vma addr AND const char **filename AND const char **name
+       AND int *line_num)
+{
+  const char *fname = 0, *func_name = 0;
+  int l = 0;
+
+  if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
+                            addr - core_text_sect->vma,
+                            &fname, &func_name, (unsigned int *) &l)
+      && fname && func_name && l)
+    {
+      DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
+                             addr, fname, l, func_name));
+      *filename = fname;
+      *name = func_name;
+      *line_num = l;
+      return TRUE;
+    }
+  else
+    {
+      DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
+                             (long) addr, fname ? fname : "<unknown>", l,
+                             func_name ? func_name : "<unknown>"));
+      return FALSE;
+    }
+}
+
+
+/*
+ * Read in symbol table from core.  One symbol per function is
+ * entered.
+ */
+void
+DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
+{
+  bfd_vma min_vma = ~0, max_vma = 0;
+  int class;
+  long i, found, skip;
+  unsigned int j;
+
+  /* pass 1 - determine upper bound on number of function names: */
+  symtab.len = 0;
+  for (i = 0; i < core_num_syms; ++i)
+    {
+      if (!core_sym_class (core_syms[i]))
+       {
+         continue;
+       }
+
+      /* This should be replaced with a binary search or hashed
+        search.  Gross. 
+
+        Don't create a symtab entry for a function that has
+        a mapping to a file, unless it's the first function
+        in the file.  */
+      skip = 0;
+      for (j = 0; j < symbol_map_count; j++)
+       if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
+         {
+           if (j > 0 && ! strcmp (symbol_map [j].file_name,
+                                  symbol_map [j - 1].file_name))
+             skip = 1;
+           break;
+         }
+      if (!skip)
+        ++symtab.len;
+    }
+
+  if (symtab.len == 0)
+    {
+      fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
+      done (1);
+    }
+
+  /* the "+ 2" is for the sentinels: */
+  symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
+
+  /* pass 2 - create symbols: */
+
+  symtab.limit = symtab.base;
+  for (i = 0; i < core_num_syms; ++i)
+    {
+      class = core_sym_class (core_syms[i]);
+      if (!class)
+       {
+         DBG (AOUTDEBUG,
+              printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
+                      core_syms[i]->value, core_syms[i]->name));
+         continue;
+       }
+      /* This should be replaced with a binary search or hashed
+        search.  Gross.   */
+
+      skip = 0;
+      found = 0;
+      for (j = 0; j < symbol_map_count; j++)
+       if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
+         {
+           if (j > 0 && ! strcmp (symbol_map [j].file_name,
+                                  symbol_map [j - 1].file_name))
+             skip = 1;
+           else
+             found = j;
+           break;
+         }
+
+      if (skip)
+       continue;
+
+      sym_init (symtab.limit);
+
+      /* symbol offsets are always section-relative: */
+
+      symtab.limit->addr = core_syms[i]->value + core_syms[i]->section->vma;
+      if (symbol_map_count
+         && !strcmp (core_syms[i]->name, symbol_map[found].function_name))
+       {
+         symtab.limit->name = symbol_map[found].file_name;
+         symtab.limit->mapped = 1;
+       }
+      else
+       {
+         symtab.limit->name = core_syms[i]->name;
+         symtab.limit->mapped = 0;
+       }
+
+      /* Lookup filename and line number, if we can */
+
+      {
+       const char *filename, *func_name;
+       
+       if (get_src_info (symtab.limit->addr, &filename, &func_name,
+                         &symtab.limit->line_num))
+         {
+           symtab.limit->file = source_file_lookup_path (filename);
+
+           /* FIXME: Checking __osf__ here does not work with a cross
+               gprof.  */
+#ifdef __osf__
+           /*
+            * Suppress symbols that are not function names.  This is
+            * useful to suppress code-labels and aliases.
+            *
+            * This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
+            * labels do not appear in the symbol table info, so this isn't
+            * necessary.
+            */
+
+           if (strcmp (symtab.limit->name, func_name) != 0)
+             {
+               /*
+                * The symbol's address maps to a different name, so
+                * it can't be a function-entry point.  This happens
+                * for labels, for example.
+                */
+               DBG (AOUTDEBUG,
+                    printf ("[core_create_function_syms: rej %s (maps to %s)\n",
+                            symtab.limit->name, func_name));
+               continue;
+             }
+#endif
+         }
+      }
+
+      symtab.limit->is_func = TRUE;
+      symtab.limit->is_bb_head = TRUE;
+      if (class == 't')
+       {
+         symtab.limit->is_static = TRUE;
+       }
+
+      min_vma = MIN (symtab.limit->addr, min_vma);
+      max_vma = MAX (symtab.limit->addr, max_vma);
+
+      /*
+       * If we see "main" without an initial '_', we assume names
+       * are *not* prefixed by '_'.
+       */
+      if (symtab.limit->name[0] == 'm' && discard_underscores
+         && strcmp (symtab.limit->name, "main") == 0)
+       {
+         discard_underscores = 0;
+       }
+
+      DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
+                             (long) (symtab.limit - symtab.base),
+                             symtab.limit->name, symtab.limit->addr));
+      ++symtab.limit;
+    }
+
+  /* create sentinels: */
+
+  sym_init (symtab.limit);
+  symtab.limit->name = "<locore>";
+  symtab.limit->addr = 0;
+  symtab.limit->end_addr = min_vma - 1;
+  ++symtab.limit;
+
+  sym_init (symtab.limit);
+  symtab.limit->name = "<hicore>";
+  symtab.limit->addr = max_vma + 1;
+  symtab.limit->end_addr = ~0;
+  ++symtab.limit;
+
+  symtab.len = symtab.limit - symtab.base;
+  symtab_finalize (&symtab);
+}
+
+
+/*
+ * Read in symbol table from core.  One symbol per line of source code
+ * is entered.
+ */
+void
+DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
+{
+  char prev_name[PATH_MAX], prev_filename[PATH_MAX];
+  bfd_vma vma, min_vma = ~0, max_vma = 0;
+  bfd_vma offset;
+  Sym *prev, dummy, *sentinel, *sym;
+  const char *filename;
+  int prev_line_num;
+  Sym_Table ltab;
+  /*
+   * Create symbols for functions as usual.  This is necessary in
+   * cases where parts of a program were not compiled with -g.  For
+   * those parts we still want to get info at the function level:
+   */
+  core_create_function_syms (core_bfd);
+
+  /* pass 1 - counter number of symbols: */
+
+  /*
+   * To find all line information, walk through all possible
+   * text-space addresses (one by one!) and get the debugging
+   * info for each address.  When the debugging info changes,
+   * it is time to create a new symbol.
+   *
+   * Of course, this is rather slow and it would be better if
+   * bfd would provide an iterator for enumerating all line infos
+   */
+  prev_name[0] = '\0';
+  ltab.len = 0;
+  prev_filename[0] = '\0';
+  prev_line_num = 0;
+  for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
+    {
+      vma = core_text_sect->vma + offset;
+      if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
+         || (prev_line_num == dummy.line_num &&
+             strcmp (prev_name, dummy.name) == 0
+             && strcmp (prev_filename, filename) == 0))
+       {
+         continue;
+       }
+
+      ++ltab.len;
+      prev_line_num = dummy.line_num;
+      strcpy (prev_name, dummy.name);
+      strcpy (prev_filename, filename);
+
+      min_vma = MIN (vma, min_vma);
+      max_vma = MAX (vma, max_vma);
+    }
+
+  /* make room for function symbols, too: */
+  ltab.len += symtab.len;
+  ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
+  ltab.limit = ltab.base;
+
+  /* pass 2 - create symbols: */
+
+  /* We now set is_static as we go along, rather than by running
+     through the symbol table at the end.
+
+     The old way called symtab_finalize before the is_static pass,
+     causing a problem since symtab_finalize uses is_static as part of
+     its address conflict resolution algorithm.  Since global symbols
+     were prefered over static symbols, and all line symbols were
+     global at that point, static function names that conflicted with
+     their own line numbers (static, but labeled as global) were
+     rejected in favor of the line num.
+
+     This was not the desired functionality.  We always want to keep
+     our function symbols and discard any conflicting line symbols.
+     Perhaps symtab_finalize should be modified to make this
+     distinction as well, but the current fix works and the code is a
+     lot cleaner now.  */
+
+  prev = 0;
+  for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
+    {
+      sym_init (ltab.limit);
+      if (!get_src_info (core_text_sect->vma + offset, &filename,
+                        &ltab.limit->name, &ltab.limit->line_num)
+         || (prev && prev->line_num == ltab.limit->line_num
+             && strcmp (prev->name, ltab.limit->name) == 0
+             && strcmp (prev->file->name, filename) == 0))
+       {
+         continue;
+       }
+
+      /* make name pointer a malloc'ed string: */
+      ltab.limit->name = xstrdup (ltab.limit->name);
+      ltab.limit->file = source_file_lookup_path (filename);
+
+      ltab.limit->addr = core_text_sect->vma + offset;
+
+      /* Set is_static based on the enclosing function, using either:
+       * 1) the previous symbol, if it's from the same function, or
+       * 2) a symtab lookup
+       */
+
+      if (prev && ltab.limit->file == prev->file &&
+         strcmp (ltab.limit->name, prev->name) == 0)
+       {
+         ltab.limit->is_static = prev->is_static;
+       }
+      else
+       {
+         sym = sym_lookup(&symtab, ltab.limit->addr);
+         ltab.limit->is_static = sym->is_static;
+       }
+
+      prev = ltab.limit;
+
+      /*
+       * If we see "main" without an initial '_', we assume names
+       * are *not* prefixed by '_'.
+       */
+      if (ltab.limit->name[0] == 'm' && discard_underscores
+         && strcmp (ltab.limit->name, "main") == 0)
+       {
+         discard_underscores = 0;
+       }
+
+      DBG (AOUTDEBUG, printf ("[core_create_line_syms] %d %s 0x%lx\n",
+                             ltab.limit - ltab.base, ltab.limit->name,
+                             ltab.limit->addr));
+      ++ltab.limit;
+    }
+
+  /* update sentinels: */
+
+  sentinel = sym_lookup (&symtab, 0);
+  if (strcmp (sentinel->name, "<locore>") == 0
+      && min_vma <= sentinel->end_addr)
+    {
+      sentinel->end_addr = min_vma - 1;
+    }
+
+  sentinel = sym_lookup (&symtab, ~0);
+  if (strcmp (sentinel->name, "<hicore>") == 0 && max_vma >= sentinel->addr)
+    {
+      sentinel->addr = max_vma + 1;
+    }
+
+  /* copy in function symbols: */
+  memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
+  ltab.limit += symtab.len;
+
+  if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
+    {
+      fprintf (stderr,
+              _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
+              whoami, ltab.len, (long) (ltab.limit - ltab.base));
+      done (1);
+    }
+
+  /* finalize ltab and make it symbol table: */
+
+  symtab_finalize (&ltab);
+  free (symtab.base);
+  symtab = ltab;
+
+}
diff --git a/gprof/corefile.h b/gprof/corefile.h
new file mode 100644 (file)
index 0000000..b396f85
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef corefile_h
+#define corefile_h
+
+#include "bfd.h"
+
+extern bfd *core_bfd;          /* bfd for core-file */
+extern int core_num_syms;      /* # of entries in symbol-table */
+extern asymbol **core_syms;    /* symbol table in a.out */
+extern asection *core_text_sect;       /* core text section */
+extern PTR core_text_space;    /* text space of a.out in core */
+
+extern int min_insn_size;      /* size of smallest instruction, in bytes */
+extern int offset_to_code;     /* offset (in bytes) of code from entry
+                                  address of routine */
+
+extern void core_init PARAMS ((const char *a_out_name));
+extern void core_get_text_space PARAMS ((bfd * core_bfd));
+extern void core_create_function_syms PARAMS ((bfd * core_bfd));
+extern void core_create_line_syms PARAMS ((bfd * core_bfd));
+
+#endif /* corefile_h */
index 9524c8bf339df382196ef0faedcf0ba1ac4e06bd..af4d8ac7935cba99c4b3db44ab56cbb3d0c3bce0 100644 (file)
@@ -4,7 +4,7 @@
 #include "cg_arcs.h"
 #include "basic_blocks.h"
 #include "bfd.h"
-#include "core.h"
+#include "corefile.h"
 #include "call_graph.h"
 #include "gmon_io.h"
 #include "gmon_out.h"
index 888335b7d242a35aa55d729e3fbdfabd34866e46..b6e260cff8b70db92b38463f926a4b5f8d0a3b53 100644 (file)
@@ -23,7 +23,7 @@
 #include "call_graph.h"
 #include "cg_arcs.h"
 #include "cg_print.h"
-#include "core.h"
+#include "corefile.h"
 #include "gmon_io.h"
 #include "hertz.h"
 #include "hist.h"
index 745c121f1e847a5f6cfef3865626783c3402d390..e027d9a5528e69e6750bae17ff22e9a3a3bcddae 100644 (file)
@@ -4,7 +4,7 @@
 #include <stdio.h>
 #include "libiberty.h"
 #include "gprof.h"
-#include "core.h"
+#include "corefile.h"
 #include "gmon_io.h"
 #include "gmon_out.h"
 #include "hist.h"
index d09d34ed5a1aad35f04580e6508381a7b9c6fe56..6ce4eea404626af4d4661795ecca1faca0e29ad1 100644 (file)
@@ -18,7 +18,7 @@
  */
 #include "gprof.h"
 #include "cg_arcs.h"
-#include "core.h"
+#include "corefile.h"
 #include "hist.h"
 #include "symtab.h"
 
index 60cf18a8ef461d74c3ff9e3b499784d9ec49ac36..5ae8116a5c1aa504d2ce909f98694b7a17a9bc7f 100644 (file)
@@ -9,8 +9,8 @@ cg_dfn.c
 cg_dfn.h
 cg_print.c
 cg_print.h
-core.c
-core.h
+corefile.c
+corefile.h
 gmon.h
 gmon_io.c
 gmon_io.h
index 77457ac4de16f9cc29814113b27a6fbcf81b6907..fd0f469e9c0e6f543f54f620dc1eff1a64d643af 100644 (file)
@@ -18,7 +18,7 @@
  */
 #include "gprof.h"
 #include "cg_arcs.h"
-#include "core.h"
+#include "corefile.h"
 #include "hist.h"
 #include "symtab.h"
 
index 1ac61cc384a1a3062891c5bfa64f9e04689fbaab..182c6574b4c9bb9c68afff89fd8b086a5ded5f36 100644 (file)
@@ -1,6 +1,6 @@
 #include "gprof.h"
 #include "cg_arcs.h"
-#include "core.h"
+#include "corefile.h"
 #include "symtab.h"
 
 Sym_Table symtab;
index 3bcd3c571edaefab0f91075c499415fb962a8425..55db2786ccb417edae63f2f0e425bac14fdf0083 100644 (file)
@@ -18,7 +18,7 @@
  */
 #include "gprof.h"
 #include "cg_arcs.h"
-#include "core.h"
+#include "corefile.h"
 #include "hist.h"
 #include "symtab.h"
 
index 020409cba6f0137b05f347e58c82c042f5c22d58..c1f77df584ddd77ad8311b5de24595284e9fb07b 100644 (file)
@@ -18,7 +18,7 @@
  */
 #include "gprof.h"
 #include "cg_arcs.h"
-#include "core.h"
+#include "corefile.h"
 #include "hist.h"
 #include "symtab.h"