X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gprof%2Fsym_ids.c;h=cbd16e62ccda572f0a1909cc9d2c6ec1440b2271;hb=ba241f2d5a6f1ac57e746d230892e27a70def4a6;hp=e2c9e38d90dcf1988ec6b159718b161ab6d3ca3c;hpb=37503931d0e0114248e20c27c117f326a6e48963;p=deliverable%2Fbinutils-gdb.git diff --git a/gprof/sym_ids.c b/gprof/sym_ids.c index e2c9e38d90..cbd16e62cc 100644 --- a/gprof/sym_ids.c +++ b/gprof/sym_ids.c @@ -1,12 +1,12 @@ /* sym_ids.c - Copyright 2000 Free Software Foundation, Inc. + Copyright (C) 1999-2014 Free Software Foundation, Inc. This file is part of GNU Binutils. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,37 +16,53 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ -#include - +#include "gprof.h" #include "libiberty.h" +#include "safe-ctype.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" #include "cg_arcs.h" #include "sym_ids.h" +#include "corefile.h" + +struct match + { + int prev_index; /* Index of prev match. */ + Sym *prev_match; /* Previous match. */ + Sym *first_match; /* Chain of all matches. */ + Sym sym; + }; struct sym_id { struct sym_id *next; char *spec; /* Parsing modifies this. */ Table_Id which_table; - bool has_right; - - struct match - { - int prev_index; /* Index of prev match. */ - Sym *prev_match; /* Previous match. */ - Sym *first_match; /* Chain of all matches. */ - Sym sym; - } - left, right; - } - *id_list; + bfd_boolean has_right; + + struct match left, right; + }; + +static struct sym_id *id_list; + +static void parse_spec + (char *, Sym *); +static void parse_id + (struct sym_id *); +static bfd_boolean match + (Sym *, Sym *); +static void extend_match + (struct match *, Sym *, Sym_Table *, bfd_boolean); + Sym_Table syms[NUM_TABLES]; #ifdef DEBUG -const char *table_name[] = +static const char *table_name[] = { "INCL_GRAPH", "EXCL_GRAPH", "INCL_ARCS", "EXCL_ARCS", @@ -71,8 +87,7 @@ static Source_File non_existent_file = void -DEFUN (sym_id_add, (spec, which_table), - const char *spec AND Table_Id which_table) +sym_id_add (const char *spec, Table_Id which_table) { struct sym_id *id; int len = strlen (spec); @@ -91,39 +106,39 @@ DEFUN (sym_id_add, (spec, which_table), /* A spec has the syntax FILENAME:(FUNCNAME|LINENUM). As a convenience to the user, a spec without a colon is interpreted as: - - (i) a FILENAME if it contains a dot - (ii) a FUNCNAME if it starts with a non-digit character - (iii) a LINENUM if it starts with a digit - + + (i) a FILENAME if it contains a dot + (ii) a FUNCNAME if it starts with a non-digit character + (iii) a LINENUM if it starts with a digit + A FUNCNAME containing a dot can be specified by :FUNCNAME, a FILENAME not containing a dot can be specified by FILENAME. */ static void -DEFUN (parse_spec, (spec, sym), char *spec AND Sym * sym) +parse_spec (char *spec, Sym *sym) { char *colon; sym_init (sym); colon = strrchr (spec, ':'); - + if (colon) { *colon = '\0'; - + if (colon > spec) { sym->file = source_file_lookup_name (spec); - + if (!sym->file) sym->file = &non_existent_file; } - + spec = colon + 1; - + if (strlen (spec)) { - if (isdigit ((unsigned char) spec[0])) + if (ISDIGIT (spec[0])) sym->line_num = atoi (spec); else sym->name = spec; @@ -135,11 +150,11 @@ DEFUN (parse_spec, (spec, sym), char *spec AND Sym * sym) if (strchr (spec, '.')) { sym->file = source_file_lookup_name (spec); - + if (!sym->file) sym->file = &non_existent_file; } - else if (isdigit ((unsigned char) *spec)) + else if (ISDIGIT (*spec)) { sym->line_num = atoi (spec); } @@ -155,7 +170,7 @@ DEFUN (parse_spec, (spec, sym), char *spec AND Sym * sym) by parse_spec(). */ static void -DEFUN (parse_id, (id), struct sym_id *id) +parse_id (struct sym_id *id) { char *slash; @@ -174,19 +189,19 @@ DEFUN (parse_id, (id), struct sym_id *id) if (debug_level & IDDEBUG) { printf ("%s:", id->left.sym.file ? id->left.sym.file->name : "*"); - + if (id->left.sym.name) printf ("%s", id->left.sym.name); else if (id->left.sym.line_num) printf ("%d", id->left.sym.line_num); else printf ("*"); - + if (id->has_right) { printf ("/%s:", id->right.sym.file ? id->right.sym.file->name : "*"); - + if (id->right.sym.name) printf ("%s", id->right.sym.name); else if (id->right.sym.line_num) @@ -194,7 +209,7 @@ DEFUN (parse_id, (id), struct sym_id *id) else printf ("*"); } - + printf ("\n"); } #endif @@ -203,21 +218,27 @@ DEFUN (parse_id, (id), struct sym_id *id) /* Return TRUE iff PATTERN matches SYM. */ -static bool -DEFUN (match, (pattern, sym), Sym * pattern AND Sym * sym) +static bfd_boolean +match (Sym *pattern, Sym *sym) { - return (pattern->file ? pattern->file == sym->file : TRUE) - && (pattern->line_num ? pattern->line_num == sym->line_num : TRUE) - && (pattern->name - ? strcmp (pattern->name, - sym->name+(discard_underscores && sym->name[0] == '_')) == 0 - : TRUE); + if (pattern->file && pattern->file != sym->file) + return FALSE; + if (pattern->line_num && pattern->line_num != sym->line_num) + return FALSE; + if (pattern->name) + { + const char *sym_name = sym->name; + if (*sym_name && bfd_get_symbol_leading_char (core_bfd) == *sym_name) + sym_name++; + if (strcmp (pattern->name, sym_name) != 0) + return FALSE; + } + return TRUE; } static void -DEFUN (extend_match, (m, sym, tab, second_pass), - struct match *m AND Sym * sym AND Sym_Table * tab AND bool second_pass) +extend_match (struct match *m, Sym *sym, Sym_Table *tab, bfd_boolean second_pass) { if (m->prev_match != sym - 1) { @@ -231,7 +252,7 @@ DEFUN (extend_match, (m, sym, tab, second_pass), tab->base[tab->len].next = m->first_match; m->first_match = &tab->base[tab->len]; } - + ++tab->len; } @@ -246,13 +267,13 @@ DEFUN (extend_match, (m, sym, tab, second_pass), /* Go through sym_id list produced by option processing and fill in the various symbol tables indicating what symbols should be displayed or suppressed for the various kinds of outputs. - + This can potentially produce huge tables and in particulars tons of arcs, but this happens only if the user makes silly requests---you get what you ask for! */ void -DEFUN_VOID (sym_id_parse) +sym_id_parse () { Sym *sym, *left, *right; struct sym_id *id; @@ -285,7 +306,7 @@ DEFUN_VOID (sym_id_parse) tab->len = 0; } } - + if (right_ids.len) { right_ids.base = (Sym *) xmalloc (right_ids.len * sizeof (Sym)); @@ -327,7 +348,7 @@ DEFUN_VOID (sym_id_parse) (unsigned long) right->addr, (unsigned long) right->end_addr, table_name[id->which_table])); - + arc_add (left, right, (unsigned long) 0); } } @@ -350,18 +371,17 @@ DEFUN_VOID (sym_id_parse) time requesting -k a/b. Fortunately, those symbol tables don't get very big (the user has to type them!), so a linear search is probably tolerable. */ -bool -DEFUN (sym_id_arc_is_present, (symtab, from, to), - Sym_Table * symtab AND Sym * from AND Sym * to) +bfd_boolean +sym_id_arc_is_present (Sym_Table *sym_tab, Sym *from, Sym *to) { Sym *sym; - for (sym = symtab->base; sym < symtab->limit; ++sym) + for (sym = sym_tab->base; sym < sym_tab->limit; ++sym) { if (from->addr >= sym->addr && from->addr <= sym->end_addr && arc_lookup (sym, to)) return TRUE; } - + return FALSE; }