* elf.c (_bfd_elf_make_section_from_shdr): Only set SEC_DATA if
[deliverable/binutils-gdb.git] / gprof / gprof.c
index af54a9ded16c4193b213e1172bd0b942e51f07d2..c8e0995543bcf81bcc6cf2ac8d9a26c9c4e10771 100644 (file)
@@ -17,6 +17,8 @@
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+#define VERSION "5.6 (Cygnus)"
+
 #ifndef lint
 char copyright[] =
 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
@@ -29,6 +31,10 @@ static char sccsid[] = "@(#)gprof.c  5.6 (Berkeley) 6/1/90";
 
 #include "gprof.h"
 
+#ifndef FOPEN_RB
+#define FOPEN_RB "r"
+#endif
+
 bfd    *abfd;
 
 char   *whoami;
@@ -109,6 +115,10 @@ main(argc, argv)
        case 'T': /* "Traditional" output format */
            bsd_style_output = 1;
            break;
+        case 'v':
+           printf ("gprof version %s\n", VERSION);
+           exit(0);
+           break;
        case 'z':
            zflag = TRUE;
            break;
@@ -238,13 +248,25 @@ bfd       *abfd;
 {
     register long      i;
     int                        askfor;
-    int                        nosyms;
+    long               nosyms;
     asymbol            **syms;
-    i = get_symtab_upper_bound (abfd); /* This will probably give us more
-                                        * than we need, but that's ok.
-                                        */
+    i = bfd_get_symtab_upper_bound (abfd);/* This will probably give us more
+                                          * than we need, but that's ok.
+                                          */
+    if (i < 0)
+      {
+       fprintf (stderr, "%s: %s: %s\n", whoami, a_outname,
+                bfd_errmsg (bfd_get_error ()));
+       exit (1);
+      }
     syms = (asymbol**)xmalloc (i);
     nosyms = bfd_canonicalize_symtab (abfd, syms);
+    if (nosyms < 0)
+      {
+       fprintf (stderr, "%s: %s: %s\n", whoami, a_outname,
+                bfd_errmsg (bfd_get_error ()));
+       exit (1);
+      }
 
     nname = 0;
     for (i = 0; i < nosyms; i++) {
@@ -373,7 +395,7 @@ openpfile(filename)
     struct rawhdr raw;
     FILE       *pfile;
 
-    if((pfile = fopen(filename, "r")) == NULL) {
+    if((pfile = fopen(filename, FOPEN_RB)) == NULL) {
        perror(filename);
        done();
     }
@@ -576,7 +598,7 @@ asgnsamples()
 
     /* read samples and assign to namelist symbols */
     scale = highpc - lowpc;
-    scale /= nsamples;
+    scale /= nsamples - 1;
     alignentries();
     for (i = 0, j = 1; i < nsamples; i++) {
        ccnt = samples[i];
@@ -683,6 +705,8 @@ funcsymbol( symp )
   extern int   aflag;          /* if static functions aren't desired */
   CONST char   *name;
   int i;
+  char         symprefix;
+  symbol_info  syminfo;
 
   /*
    *   must be a text symbol,
@@ -699,6 +723,33 @@ funcsymbol( symp )
 #endif
     return FALSE;
   }
+
+
+  symprefix = bfd_get_symbol_leading_char (abfd);
+  bfd_get_symbol_info (abfd, symp, &syminfo);
+  i = syminfo.type;
+#if defined(DEBUG) && 0
+  if (i != 'T' && i != 't')
+    fprintf (stderr, "%s(%d):  %s is of class %c\n", __FILE__, __LINE__, symp->name, i);
+#endif
+
+  /*
+   * Any external text symbol should be okay.  (Only problem would be
+   * variables in the text section.)
+   */
+
+  if (i == 'T')
+    return TRUE;
+
+  /*
+   * 't' is static text; -a says to ignore it.  So if it's not
+   * a static text symbol, *or* it is and the user gave -a, we
+   * ignore it.
+   */
+
+  if (i != 't' || aflag)
+    return FALSE;
+
   /*
    *   can't have any `funny' characters in name,
    *   where `funny' includes  `.', .o file names
@@ -713,13 +764,23 @@ funcsymbol( symp )
     }
   }
 
-  i = bfd_decode_symclass (symp);
-#if defined(DEBUG) && 0
-  if (i != 'T' && i != 't')
-    fprintf (stderr, "%s(%d):  %s is of class %c\n", __FILE__, __LINE__, symp->name, i);
-#endif
+  /* 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.
+   */
+
+  if (symprefix && symprefix != *symp->name
+      /* 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 (symp->name, "__gnu_compiled", 14))
+    return FALSE;
 
-  return (i == 'T' || i == 't');
+  return TRUE;
 }
 
 done()
This page took 0.025662 seconds and 4 git commands to generate.