summaryrefslogtreecommitdiff
path: root/gprof
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2009-06-12 15:33:30 +0000
committerNick Clifton <nickc@redhat.com>2009-06-12 15:33:30 +0000
commit8ba26b8d98b1bad5e7c5fcf5a6062c1262b0272b (patch)
tree233f9d2bef9102cd7d08596ad6fd6157294882c8 /gprof
parent35b0c3f16d70501acb0ecf66e9720df07c4ff1b6 (diff)
downloadbinutils-redhat-8ba26b8d98b1bad5e7c5fcf5a6062c1262b0272b.tar.gz
* corefile.c (num_of_syms_in): New function - computes the number
of symbols in a given file. (core_create_syms_from): New function - populates a symbol table from the symbols found in a specified file. * corefile.h: Prototype core_create_syms_from. * gprof.c (long_options): Add --external-symbol-table. (usage): Mention it. (main): Initiailize external_symbol_table from --external-symbol-table option. If set use it. * gprof.texi: Document the new option. * NEWS: Mention new feature added to gprof.
Diffstat (limited to 'gprof')
-rw-r--r--gprof/ChangeLog13
-rw-r--r--gprof/corefile.c104
-rw-r--r--gprof/corefile.h11
-rw-r--r--gprof/gprof.c22
-rw-r--r--gprof/gprof.texi16
5 files changed, 147 insertions, 19 deletions
diff --git a/gprof/ChangeLog b/gprof/ChangeLog
index 56c478a30f..b7f139f260 100644
--- a/gprof/ChangeLog
+++ b/gprof/ChangeLog
@@ -1,3 +1,16 @@
+2009-06-12 Homer Xing <homer.xing@yahoo.com>
+
+ * corefile.c (num_of_syms_in): New function - computes the number
+ of symbols in a given file.
+ (core_create_syms_from): New function - populates a symbol table
+ from the symbols found in a specified file.
+ * corefile.h: Prototype core_create_syms_from.
+ * gprof.c (long_options): Add --external-symbol-table.
+ (usage): Mention it.
+ (main): Initiailize external_symbol_table from
+ --external-symbol-table option. If set use it.
+ * gprof.texi: Document the new option.
+
2009-06-04 Alan Modra <amodra@bigpond.net.au>
* dep-in.sed: Don't use \n in replacement part of s command.
diff --git a/gprof/corefile.c b/gprof/corefile.c
index 1f2575f361..6ddb52b3f0 100644
--- a/gprof/corefile.c
+++ b/gprof/corefile.c
@@ -1,6 +1,6 @@
/* corefile.c
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -33,13 +33,13 @@ bfd *core_bfd;
static int core_num_syms;
static asymbol **core_syms;
asection *core_text_sect;
-PTR core_text_space;
+void * core_text_space;
static int min_insn_size;
int offset_to_code;
/* For mapping symbols to specific .o files during file ordering. */
-struct function_map *symbol_map;
+struct function_map * symbol_map;
unsigned int symbol_map_count;
static void read_function_mappings (const char *);
@@ -434,6 +434,104 @@ get_src_info (bfd_vma addr, const char **filename, const char **name, int *line_
}
}
+/* Return number of symbols in a symbol-table file. */
+
+static int
+num_of_syms_in (FILE * f)
+{
+ const int BUFSIZE = 1024;
+ char * buf = (char *) xmalloc (BUFSIZE);
+ char * address = (char *) xmalloc (BUFSIZE);
+ char type;
+ char * name = (char *) xmalloc (BUFSIZE);
+ int num = 0;
+
+ while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
+ {
+ if (sscanf (buf, "%s %c %s", address, &type, name) == 3)
+ if (type == 't' || type == 'T')
+ ++num;
+ }
+
+ free (buf);
+ free (address);
+ free (name);
+
+ return num;
+}
+
+/* Read symbol table from a file. */
+
+void
+core_create_syms_from (const char * sym_table_file)
+{
+ const int BUFSIZE = 1024;
+ char * buf = (char *) xmalloc (BUFSIZE);
+ char * address = (char *) xmalloc (BUFSIZE);
+ char type;
+ char * name = (char *) xmalloc (BUFSIZE);
+ bfd_vma min_vma = ~(bfd_vma) 0;
+ bfd_vma max_vma = 0;
+ FILE * f;
+
+ f = fopen (sym_table_file, "r");
+ if (!f)
+ {
+ fprintf (stderr, _("%s: could not open %s.\n"), whoami, sym_table_file);
+ done (1);
+ }
+
+ /* Pass 1 - determine upper bound on number of function names. */
+ symtab.len = num_of_syms_in (f);
+
+ if (symtab.len == 0)
+ {
+ fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, sym_table_file);
+ done (1);
+ }
+
+ symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
+
+ /* Pass 2 - create symbols. */
+ symtab.limit = symtab.base;
+
+ if (fseek (f, 0, SEEK_SET) != 0)
+ {
+ perror (sym_table_file);
+ done (1);
+ }
+
+ while (!feof (f) && fgets (buf, sizeof (buf), f))
+ {
+ if (sscanf (buf, "%s %c %s", address, &type, name) == 3)
+ if (type != 't' && type != 'T')
+ continue;
+
+ sym_init (symtab.limit);
+
+ sscanf (address, "%lx", &(symtab.limit->addr) );
+
+ symtab.limit->name = (char *) xmalloc (strlen (name) + 1);
+ strcpy ((char *) symtab.limit->name, name);
+ symtab.limit->mapped = 0;
+ symtab.limit->is_func = TRUE;
+ symtab.limit->is_bb_head = TRUE;
+ symtab.limit->is_static = (type == 't');
+ min_vma = MIN (symtab.limit->addr, min_vma);
+ max_vma = MAX (symtab.limit->addr, max_vma);
+
+ ++symtab.limit;
+ }
+ fclose (f);
+
+ symtab.len = symtab.limit - symtab.base;
+ symtab_finalize (&symtab);
+
+ free (buf);
+ free (address);
+ free (name);
+}
+
/* Read in symbol table from core.
One symbol per function is entered. */
diff --git a/gprof/corefile.h b/gprof/corefile.h
index 7fd38b9dd2..ccdaf13fd4 100644
--- a/gprof/corefile.h
+++ b/gprof/corefile.h
@@ -1,6 +1,6 @@
/* corefile.h
- Copyright 2000, 2001, 2002, 2004, 2007 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2004, 2007, 2009 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -28,12 +28,12 @@ struct function_map
char *file_name;
};
-extern struct function_map *symbol_map;
+extern struct function_map * symbol_map;
extern unsigned int symbol_map_count;
-extern bfd *core_bfd; /* BFD for core-file. */
-extern asection *core_text_sect;/* Core text section. */
-extern PTR core_text_space; /* Text space of a.out in core. */
+extern bfd * core_bfd; /* BFD for core-file. */
+extern asection * core_text_sect; /* Core text section. */
+extern void * core_text_space; /* Text space of a.out in core. */
extern int offset_to_code; /* Offset (in bytes) of code from entry
address of routine. */
@@ -41,5 +41,6 @@ extern void core_init (const char *);
extern void core_get_text_space (bfd *);
extern void core_create_function_syms (void);
extern void core_create_line_syms (void);
+extern void core_create_syms_from (const char *);
#endif /* corefile_h */
diff --git a/gprof/gprof.c b/gprof/gprof.c
index 26bec34e57..8d545389c5 100644
--- a/gprof/gprof.c
+++ b/gprof/gprof.c
@@ -47,9 +47,10 @@
static void usage (FILE *, int) ATTRIBUTE_NORETURN;
-const char *whoami;
-const char *function_mapping_file;
-const char *a_out_name = A_OUTNAME;
+const char * whoami;
+const char * function_mapping_file;
+static const char * external_symbol_table;
+const char * a_out_name = A_OUTNAME;
long hz = HZ_WRONG;
/*
@@ -98,6 +99,7 @@ static struct option long_options[] =
{"line", no_argument, 0, 'l'},
{"no-static", no_argument, 0, 'a'},
{"ignore-non-functions", no_argument, 0, 'D'},
+ {"external-symbol-table", required_argument, 0, 'S'},
/* output styles: */
@@ -155,7 +157,7 @@ static void
usage (FILE *stream, int status)
{
fprintf (stream, _("\
-Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n\
+Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqSQZ][name]] [-I dirs]\n\
[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n\
[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n\
[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n\
@@ -166,7 +168,7 @@ Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n\
[--no-static] [--print-path] [--separate-files]\n\
[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n\
[--version] [--width=n] [--ignore-non-functions]\n\
- [--demangle[=STYLE]] [--no-demangle] [@FILE]\n\
+ [--demangle[=STYLE]] [--no-demangle] [--external-symbol-table=name] [@FILE]\n\
[image-file] [profile-file...]\n"),
whoami);
if (REPORT_BUGS_TO[0] && status == 0)
@@ -199,7 +201,7 @@ main (int argc, char **argv)
expandargv (&argc, &argv);
while ((ch = getopt_long (argc, argv,
- "aA::bBcC::d::De:E:f:F:hiI:J::k:lLm:n:N:O:p::P::q::Q::rR:st:Tvw:xyzZ::",
+ "aA::bBcC::d::De:E:f:F:hiI:J::k:lLm:n:N:O:p::P::q::Q::rR:sS:t:Tvw:xyzZ::",
long_options, 0))
!= EOF)
{
@@ -398,6 +400,10 @@ main (int argc, char **argv)
output_style |= STYLE_SUMMARY_FILE;
user_specified |= STYLE_SUMMARY_FILE;
break;
+ case 'S':
+ external_symbol_table = optarg;
+ DBG (AOUTDEBUG, printf ("external-symbol-table: %s\n", optarg));
+ break;
case 't':
bb_table_length = atoi (optarg);
if (bb_table_length < 0)
@@ -512,7 +518,9 @@ This program is free software. This program has absolutely no warranty.\n"));
core_get_text_space (core_bfd);
/* Create symbols from core image. */
- if (line_granularity)
+ if (external_symbol_table)
+ core_create_syms_from (external_symbol_table);
+ else if (line_granularity)
core_create_line_syms ();
else
core_create_function_syms ();
diff --git a/gprof/gprof.texi b/gprof/gprof.texi
index 1f86383de7..058d5e7026 100644
--- a/gprof/gprof.texi
+++ b/gprof/gprof.texi
@@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*-
@setfilename gprof.info
@c Copyright 1988, 1992, 1993, 1998, 1999, 2000, 2001, 2002, 2003,
-@c 2004, 2007, 2008
+@c 2004, 2007, 2008, 2009
@c Free Software Foundation, Inc.
@settitle GNU gprof
@setchapternewpage odd
@@ -24,7 +24,7 @@ END-INFO-DIR-ENTRY
This file documents the gprof profiler of the GNU system.
@c man begin COPYRIGHT
-Copyright @copyright{} 1988, 92, 97, 98, 99, 2000, 2001, 2003, 2007, 2008 Free Software Foundation, Inc.
+Copyright @copyright{} 1988, 92, 97, 98, 99, 2000, 2001, 2003, 2007, 2008, 2009 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
@@ -57,7 +57,7 @@ execute programs. @sc{gnu} @code{gprof} was written by Jay Fenlason.
Eric S. Raymond made some minor corrections and additions in 2003.
@vskip 0pt plus 1filll
-Copyright @copyright{} 1988, 92, 97, 98, 99, 2000, 2003, 2008 Free Software Foundation, Inc.
+Copyright @copyright{} 1988, 92, 97, 98, 99, 2000, 2003, 2008, 2009 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
@@ -128,7 +128,8 @@ gprof [ -[abcDhilLrsTvwxyz] ] [ -[ACeEfFJnNOpPqQZ][@var{name}] ]
[ --static-call-graph ] [ --sum ] [ --table-length=@var{len} ]
[ --traditional ] [ --version ] [ --width=@var{n} ]
[ --ignore-non-functions ] [ --demangle[=@var{STYLE}] ]
- [ --no-demangle ] [ @var{image-file} ] [ @var{profile-file} @dots{} ]
+ [ --no-demangle ] [--external-symbol-table=name]
+ [ @var{image-file} ] [ @var{profile-file} @dots{} ]
@c man end
@end smallexample
@@ -725,6 +726,13 @@ to only propagate times for symbols matching @var{symspec}.
The @samp{-n} option causes @code{gprof}, in its call graph analysis,
not to propagate times for symbols matching @var{symspec}.
+@item -S@var{filename}
+@itemx --external-symbol-table=@var{filename}
+The @samp{-S} option causes @code{gprof} to read an external symbol table
+file, such as @file{/proc/kallsyms}, rather than read the symbol table
+from the given object file (the default is @code{a.out}). This is useful
+for profiling kernel modules.
+
@item -z
@itemx --display-unused-functions
If you give the @samp{-z} option, @code{gprof} will mention all