diff options
author | Jeff Law <law@redhat.com> | 1995-12-31 06:36:30 +0000 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 1995-12-31 06:36:30 +0000 |
commit | 64c50fc5db62e96b429cd2f2e166e878569f4a15 (patch) | |
tree | 440c0e7c9b11ad2afa68adf0a5b3e1ccb7106ca5 /gprof/core.c | |
parent | 71128bd7a98889baab8044ccc1138a62371dda4c (diff) | |
download | binutils-64c50fc5db62e96b429cd2f2e166e878569f4a15.zip binutils-64c50fc5db62e96b429cd2f2e166e878569f4a15.tar.gz binutils-64c50fc5db62e96b429cd2f2e166e878569f4a15.tar.bz2 |
* 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.
Diffstat (limited to 'gprof/core.c')
-rw-r--r-- | gprof/core.c | 146 |
1 files changed, 143 insertions, 3 deletions
diff --git a/gprof/core.c b/gprof/core.c index aa6012a..d514178 100644 --- a/gprof/core.c +++ b/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__ /* |