From 0e27a8f69b7c9365e4ec543a3d27a24c968a7c16 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 12 Jun 2009 15:33:30 +0000 Subject: [PATCH] * 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. --- binutils/ChangeLog | 4 ++ binutils/NEWS | 3 ++ gprof/ChangeLog | 13 ++++++ gprof/corefile.c | 104 +++++++++++++++++++++++++++++++++++++++++++-- gprof/corefile.h | 11 ++--- gprof/gprof.c | 22 +++++++--- gprof/gprof.texi | 16 +++++-- 7 files changed, 154 insertions(+), 19 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index e70dd68e82..cc1e87d400 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2009-06-12 Homer Xing + + * NEWS: Mention new feature added to gprof. + 2009-06-12 John Reiser * readelf.c (process_symbol_table): Set gnubuckets to NULL after diff --git a/binutils/NEWS b/binutils/NEWS index 7ce6d66a3c..9a33f266ce 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,4 +1,7 @@ -*- text -*- +* The gprof program has been given a new command line option: + --external-symbols-table= which reads in symbols from a specified + file. * The plugin target has been added to bfd. It can load the same shared objects used by gold and uses them to provide basic support for new file formats. 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 + + * 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 * 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 -- 2.34.1