mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 17:18:55 +00:00
* gprof.c (long_options): Add "--function-ordering" and
"--file-ordering" options. (usage): Add new options to usage message. (main): Handle new options. * gprof.h (STYLE_FUNCTION_ORDER): Define. (STYLE_FILE_ORDER): Define. (function_mapping_file): Declare. * cg_arcs.c (arcs, numarcs): New globals. (arc_add): Put new arcs into the arc array so the function/file ordering code can examine them. * cg_arcs.h (struct arc): New field "has_been_placed". (arcs, numarcs): Declare new globals. * core.c (symbol_map, symbol_map_count): New globals. (read_function_mappings): New function to read in a function to object map file. (core_init): Call read_function_mappings if a function mapping file exists. (core_create_function_syms): Handle function to object file mappings. * symtab.h (struct sym): New fields "mapped", "has_been_placed", "nuses", "prev". * cg_print.c (cmp_arc_count): New function for sorting arcs. (cmp_fun_nuses): Likewise for functions. (cg_print_function_ordering): New function to print a suggested function ordering. (cg_print_file_ordering): Likewise for ordering .o files. (order_and_dump_functions_by_arcs): Helper function for function and object file ordering code. Gprof changes for mentor vm work.
This commit is contained in:
146
gprof/core.c
146
gprof/core.c
@@ -9,6 +9,98 @@ 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 = 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)
|
||||
@@ -59,6 +151,9 @@ DEFUN (core_init, (a_out_name), const char *a_out_name)
|
||||
bfd_errmsg (bfd_get_error ()));
|
||||
done (1);
|
||||
}
|
||||
|
||||
if (function_mapping_file)
|
||||
read_function_mappings (function_mapping_file);
|
||||
}
|
||||
|
||||
|
||||
@@ -232,7 +327,7 @@ 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;
|
||||
@@ -242,7 +337,24 @@ DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
++symtab.len;
|
||||
|
||||
/* 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)
|
||||
@@ -267,13 +379,41 @@ DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
|
||||
core_syms[i]->value, core_syms[i]->name));
|
||||
continue;
|
||||
}
|
||||
/* 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__
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user