* v850-opc.c (v850_opcodes): Fix order of displacement
[deliverable/binutils-gdb.git] / gprof / core.c
index a525c60e9723504eeaaabd49b1b839af49b2ec78..3103dc281fca8c0dc583728c9c53c90f60c637f8 100644 (file)
 #include "core.h"
 #include "symtab.h"
 
+#ifndef MIN_INSN_SIZE
+/* If not defined in MACHINE_H, assume smallest instruction is 1 byte
+   long.  THis is safe but may be needlessly slow on machines where
+   all instructions are longer.  */
+#define MIN_INSN_SIZE 1
+#endif
+
 bfd *core_bfd;
 int core_num_syms;
 asymbol **core_syms;
 asection *core_text_sect;
 PTR core_text_space;
 
+/* For mapping symbols to specific .o files during file ordering.  */
+struct function_map {
+  char *function_name;
+  char *file_name;
+};
+
+struct function_map *symbol_map;
+int symbol_map_count;
+
+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)
@@ -19,13 +119,13 @@ DEFUN (core_init, (a_out_name), const char *a_out_name)
     {
       perror (a_out_name);
       done (1);
-    }                          /* if */
+    }
 
   if (!bfd_check_format (core_bfd, bfd_object))
     {
       fprintf (stderr, "%s: %s: not in a.out format\n", whoami, a_out_name);
       done (1);
-    }                          /* if */
+    }
 
   /* get core's text section: */
   core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
@@ -37,8 +137,8 @@ DEFUN (core_init, (a_out_name), const char *a_out_name)
          fprintf (stderr, "%s: can't find .text section in %s\n",
                   whoami, a_out_name);
          done (1);
-       }                       /* if */
-    }                          /* if */
+       }
+    }
 
   /* read core's symbol table: */
 
@@ -49,7 +149,7 @@ DEFUN (core_init, (a_out_name), const char *a_out_name)
       fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
               bfd_errmsg (bfd_get_error ()));
       done (1);
-    }                          /* if */
+    }
 
   core_syms = (asymbol **) xmalloc (core_num_syms);
   core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
@@ -58,8 +158,11 @@ DEFUN (core_init, (a_out_name), const char *a_out_name)
       fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
               bfd_errmsg (bfd_get_error ()));
       done (1);
-    }                          /* if */
-}                              /* core_init */
+    }
+
+  if (function_mapping_file)
+    read_function_mappings (function_mapping_file);
+}
 
 
 /*
@@ -75,19 +178,19 @@ DEFUN (core_get_text_space, (core_bfd), bfd * core_bfd)
       fprintf (stderr, "%s: ran out room for %ld bytes of text space\n",
               whoami, core_text_sect->_raw_size);
       done (1);
-    }                          /* if */
+    }
   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 */
+    }
   if (!core_text_space)
     {
       fprintf (stderr, "%s: can't do -c\n", whoami);
-    }                          /* if */
-}                              /* core_get_text_space */
+    }
+}
 
 
 /*
@@ -104,21 +207,21 @@ DEFUN (core_sym_class, (sym), asymbol * sym)
   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 (!sym->section)
-    {
-      return 0;
-    }                          /* if */
-
   if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
     {
       DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
                              sym->name));
       return 0;
-    }                          /* if */
+    }
 
   bfd_get_symbol_info (core_bfd, sym, &syminfo);
   i = syminfo.type;
@@ -126,7 +229,7 @@ DEFUN (core_sym_class, (sym), asymbol * sym)
   if (i == 'T')
     {
       return i;                        /* it's a global symbol */
-    }                          /* if */
+    }
 
   if (i != 't')
     {
@@ -134,14 +237,14 @@ DEFUN (core_sym_class, (sym), asymbol * sym)
       DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
                              sym->name, i));
       return 0;
-    }                          /* if */
+    }
 
   /* do some more filtering on static function-names: */
 
   if (ignore_static_funcs)
     {
       return 0;
-    }                          /* if */
+    }
   /*
    * Can't zero-length name or funny characters in name, where
    * `funny' includes: `.' (.o file names) and `$' (Pascal labels).
@@ -149,15 +252,15 @@ DEFUN (core_sym_class, (sym), asymbol * sym)
   if (!sym->name || sym->name[0] == '\0')
     {
       return 0;
-    }                          /* if */
+    }
 
   for (name = sym->name; *name; ++name)
     {
       if (*name == '.' || *name == '$')
        {
          return 0;
-       }                       /* if */
-    }                          /* if */
+       }
+    }
   /*
    * On systems where the C compiler adds an underscore to all
    * names, static names without underscores seem usually to be
@@ -168,7 +271,7 @@ DEFUN (core_sym_class, (sym), asymbol * sym)
    * 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]
+  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
@@ -178,9 +281,15 @@ DEFUN (core_sym_class, (sym), asymbol * sym)
       || !strncmp (sym->name, "___gnu_compiled", 15))
     {
       return 0;
-    }                          /* if */
+    }
+
+  /* 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 */
-}                              /* core_sym_class */
+}
 
 
 /*
@@ -196,7 +305,7 @@ DEFUN (get_src_info, (addr, filename, name, line_num),
 
   if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
                             addr - core_text_sect->vma,
-                            &fname, &func_name, &l)
+                            &fname, &func_name, (unsigned int *) &l)
       && fname && func_name && l)
     {
       DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
@@ -212,8 +321,8 @@ DEFUN (get_src_info, (addr, filename, name, line_num),
                              (long) addr, fname ? fname : "<unknown>", l,
                              func_name ? func_name : "<unknown>"));
       return FALSE;
-    }                          /* if */
-}                              /* get_src_info */
+    }
+}
 
 
 /*
@@ -224,9 +333,8 @@ void
 DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
 {
   bfd_vma min_vma = ~0, max_vma = 0;
-  const char *filename, *func_name;
   int class;
-  long i;
+  long i, j, found, skip;
 
   /* pass 1 - determine upper bound on number of function names: */
   symtab.len = 0;
@@ -235,15 +343,32 @@ DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
       if (!core_sym_class (core_syms[i]))
        {
          continue;
-       }                       /* if */
-      ++symtab.len;
-    }                          /* for */
+       }
+
+      /* 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);
-    }                          /* if */
+    }
 
   /* the "+ 2" is for the sentinels: */
   symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
@@ -260,14 +385,42 @@ DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
               printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
                       core_syms[i]->value, core_syms[i]->name));
          continue;
-       }                       /* if */
+       }
+      /* 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;
-      symtab.limit->name = core_syms[i]->name;
+      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;
+       }
 
 #ifdef __osf__
       /*
@@ -278,24 +431,28 @@ DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
        * labels do not appear in the symbol table info, so this isn't
        * necessary.
        */
-      if (get_src_info (symtab.limit->addr, &filename, &func_name,
-                       &symtab.limit->line_num))
-       {
-         symtab.limit->file = source_file_lookup_path (filename);
-
-         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;
-           }                   /* if */
-       }                       /* if */
+      {
+       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);
+
+           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;
@@ -303,7 +460,7 @@ DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
       if (class == 't')
        {
          symtab.limit->is_static = TRUE;
-       }                       /* if */
+       }
 
       min_vma = MIN (symtab.limit->addr, min_vma);
       max_vma = MAX (symtab.limit->addr, max_vma);
@@ -316,13 +473,13 @@ DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
          && strcmp (symtab.limit->name, "main") == 0)
        {
          discard_underscores = 0;
-       }                       /* if */
+       }
 
       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;
-    }                          /* for */
+    }
 
   /* create sentinels: */
 
@@ -340,7 +497,7 @@ DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
 
   symtab.len = symtab.limit - symtab.base;
   symtab_finalize (&symtab);
-}                              /* core_create_function_syms */
+}
 
 
 /*
@@ -384,7 +541,7 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
   prev_offset = -min_dist;
   prev_filename[0] = '\0';
   prev_line_num = 0;
-  for (offset = 0; offset < core_text_sect->_raw_size; ++offset)
+  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)
@@ -393,7 +550,7 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
              && strcmp (prev_filename, filename) == 0))
        {
          continue;
-       }                       /* if */
+       }
 
       ++ltab.len;
       prev_line_num = dummy.line_num;
@@ -403,12 +560,12 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
       if (offset - prev_offset < min_dist)
        {
          min_dist = offset - prev_offset;
-       }                       /* if */
+       }
       prev_offset = offset;
 
       min_vma = MIN (vma, min_vma);
       max_vma = MAX (vma, max_vma);
-    }                          /* for */
+    }
 
   DBG (AOUTDEBUG, printf ("[core_create_line_syms] min_dist=%lx\n", min_dist));
 
@@ -430,10 +587,10 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
              && strcmp (prev->file->name, filename) == 0))
        {
          continue;
-       }                       /* if */
+       }
 
       /* make name pointer a malloc'ed string: */
-      ltab.limit->name = strdup (ltab.limit->name);
+      ltab.limit->name = xstrdup (ltab.limit->name);
       ltab.limit->file = source_file_lookup_path (filename);
 
       ltab.limit->addr = core_text_sect->vma + offset;
@@ -447,13 +604,13 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
          && strcmp (ltab.limit->name, "main") == 0)
        {
          discard_underscores = 0;
-       }                       /* if */
+       }
 
       DBG (AOUTDEBUG, printf ("[core_create_line_syms] %d %s 0x%lx\n",
                              ltab.len, ltab.limit->name,
                              ltab.limit->addr));
       ++ltab.limit;
-    }                          /* for */
+    }
 
   /* update sentinels: */
 
@@ -462,13 +619,13 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
       && min_vma <= sentinel->end_addr)
     {
       sentinel->end_addr = min_vma - 1;
-    }                          /* if */
+    }
 
   sentinel = sym_lookup (&symtab, ~0);
   if (strcmp (sentinel->name, "<hicore>") == 0 && max_vma >= sentinel->addr)
     {
       sentinel->addr = max_vma + 1;
-    }                          /* if */
+    }
 
   /* copy in function symbols: */
   memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
@@ -480,7 +637,7 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
               "%s: somebody miscounted: ltab.len=%ld instead of %d\n",
               whoami, (long) (ltab.limit - ltab.base), ltab.len);
       done (1);
-    }                          /* if */
+    }
 
   /* finalize ltab and make it symbol table: */
 
@@ -502,9 +659,7 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
            }
          while (sym->file == sym[-1].file &&
                 strcmp (sym->name, sym[-1].name) == 0);
-       }                       /* if */
-    }                          /* for */
-
-}                              /* core_create_line_syms */
+       }
+    }
 
-/*** end of core.c ***/
+}
This page took 0.03081 seconds and 4 git commands to generate.