diff --git a/gprof/aarch64.c b/gprof/aarch64.c index 3ab6067dbac..0365930961a 100644 --- a/gprof/aarch64.c +++ b/gprof/aarch64.c @@ -50,6 +50,7 @@ aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) bfd_vma pc, dest_pc, offset; unsigned int insn; Sym *child; + Sym_Table *symtab = get_symtab (); DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n", parent->name, (unsigned long) p_lowpc, @@ -75,7 +76,7 @@ aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) if (hist_check_address (dest_pc)) { - child = sym_lookup (&symtab, dest_pc); + child = sym_lookup (symtab, dest_pc); if (child) { diff --git a/gprof/alpha.c b/gprof/alpha.c index df714be6c81..b7740d8b586 100644 --- a/gprof/alpha.c +++ b/gprof/alpha.c @@ -95,6 +95,7 @@ alpha_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) bfd_vma pc, dest_pc; unsigned int insn; Sym *child; + Sym_Table *symtab = get_symtab (); if (indirect_child.name == NULL) { @@ -149,7 +150,7 @@ alpha_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) ^ 0x100000) - 0x100000); if (hist_check_address (dest_pc)) { - child = sym_lookup (&symtab, dest_pc); + child = sym_lookup (symtab, dest_pc); if (child) { DBG (CALLDEBUG, diff --git a/gprof/basic_blocks.c b/gprof/basic_blocks.c index 4a4e491495f..d8659382d2c 100644 --- a/gprof/basic_blocks.c +++ b/gprof/basic_blocks.c @@ -122,6 +122,7 @@ bb_read_rec (FILE *ifp, const char *filename) unsigned int nblocks, b; bfd_vma addr, ncalls; Sym *sym; + Sym_Table *symtab; if (gmon_io_read_32 (ifp, &nblocks)) { @@ -130,6 +131,8 @@ bb_read_rec (FILE *ifp, const char *filename) done (1); } + symtab = get_symtab (); + nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks); if (gmon_file_version == 0) fskip_string (ifp); @@ -163,7 +166,7 @@ bb_read_rec (FILE *ifp, const char *filename) profiling at the line-by-line level: */ if (line_granularity) { - sym = sym_lookup (&symtab, addr); + sym = sym_lookup (symtab, addr); if (sym) { @@ -210,9 +213,10 @@ bb_write_blocks (FILE *ofp, const char *filename) unsigned int nblocks = 0; Sym *sym; int i; + Sym_Table *symtab = get_symtab (); /* Count how many non-zero blocks with have: */ - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { for (i = 0; i < NBBS && sym->bb_addr[i]; i++) ; @@ -228,7 +232,7 @@ bb_write_blocks (FILE *ofp, const char *filename) } /* Write counts: */ - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { for (i = 0; i < NBBS && sym->bb_addr[i]; i++) { @@ -252,6 +256,7 @@ print_exec_counts (void) { Sym **sorted_bbs, *sym; unsigned int i, j, len; + Sym_Table *symtab = get_symtab (); if (first_output) first_output = false; @@ -259,10 +264,10 @@ print_exec_counts (void) printf ("\f\n"); /* Sort basic-blocks according to function name and line number: */ - sorted_bbs = (Sym **) xmalloc (symtab.len * sizeof (sorted_bbs[0])); + sorted_bbs = (Sym **) xmalloc (symtab->len * sizeof (sorted_bbs[0])); len = 0; - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { /* Accept symbol if it's in the INCL_EXEC table or there is no INCL_EXEC table @@ -461,10 +466,11 @@ print_annotated_source (void) Source_File *sf; int i, table_len; FILE *ofp; + Sym_Table *symtab = get_symtab (); /* Find maximum line number for each source file that user is interested in: */ - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { /* Accept symbol if it's file is known, its line number is bigger than anything we have seen for that file so far and @@ -490,7 +496,7 @@ print_annotated_source (void) } /* Count executions per line: */ - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { if (sym->file && sym->file->num_lines && (sym_lookup (&syms[INCL_ANNO], sym->addr) diff --git a/gprof/call_graph.c b/gprof/call_graph.c index 259cbaaef1b..b76a8adde58 100644 --- a/gprof/call_graph.c +++ b/gprof/call_graph.c @@ -35,9 +35,10 @@ cg_tally (bfd_vma from_pc, bfd_vma self_pc, unsigned long count) { Sym *parent; Sym *child; + Sym_Table *symtab = get_symtab (); - parent = sym_lookup (&symtab, from_pc); - child = sym_lookup (&symtab, self_pc); + parent = sym_lookup (symtab, from_pc); + child = sym_lookup (symtab, self_pc); if (child == NULL || parent == NULL) return; @@ -51,10 +52,10 @@ cg_tally (bfd_vma from_pc, bfd_vma self_pc, unsigned long count) For normal profiling, is_func will be set on all symbols, so this code will do nothing. */ - while (child >= symtab.base && ! child->is_func) + while (child >= symtab->base && ! child->is_func) --child; - if (child < symtab.base) + if (child < symtab->base) return; /* Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table @@ -108,8 +109,9 @@ cg_write_arcs (FILE *ofp, const char *filename) { Arc *arc; Sym *sym; + Sym_Table *symtab = get_symtab (); - for (sym = symtab.base; sym < symtab.limit; sym++) + for (sym = symtab->base; sym < symtab->limit; sym++) { for (arc = sym->cg.children; arc; arc = arc->next_child) { diff --git a/gprof/cg_arcs.c b/gprof/cg_arcs.c index cfffb09ff87..a19686b2710 100644 --- a/gprof/cg_arcs.c +++ b/gprof/cg_arcs.c @@ -275,11 +275,12 @@ cycle_link (void) Sym *sym, *cyc, *member; Arc *arc; int num; + Sym_Table *symtab = get_symtab (); /* count the number of cycles, and initialize the cycle lists: */ num_cycles = 0; - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { /* this is how you find unattached cycles: */ if (sym->cg.cyc.head == sym && sym->cg.cyc.next) @@ -300,7 +301,7 @@ cycle_link (void) */ num = 0; cyc = cycle_header; - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { if (!(sym->cg.cyc.head == sym && sym->cg.cyc.next != 0)) { @@ -440,9 +441,10 @@ propagate_flags (Sym **symbols) { int sym_index; Sym *old_head, *child; + Sym_Table *symtab = get_symtab (); old_head = 0; - for (sym_index = symtab.len - 1; sym_index >= 0; --sym_index) + for (sym_index = symtab->len - 1; sym_index >= 0; --sym_index) { child = symbols[sym_index]; /* @@ -597,12 +599,13 @@ cg_assemble (void) Sym *parent, **time_sorted_syms, **top_sorted_syms; unsigned int sym_index; Arc *arc; + Sym_Table *symtab = get_symtab (); /* Initialize various things: Zero out child times. Count self-recursive calls. Indicate that nothing is on cycles. */ - for (parent = symtab.base; parent < symtab.limit; parent++) + for (parent = symtab->base; parent < symtab->limit; parent++) { parent->cg.child_time = 0.0; arc = arc_lookup (parent, parent); @@ -633,7 +636,7 @@ cg_assemble (void) /* Topologically order things. If any node is unnumbered, number it and any of its descendents. */ - for (parent = symtab.base; parent < symtab.limit; parent++) + for (parent = symtab->base; parent < symtab->limit; parent++) { if (parent->cg.top_order == DFN_NAN) cg_dfn (parent); @@ -643,14 +646,14 @@ cg_assemble (void) cycle_link (); /* Sort the symbol table in reverse topological order. */ - top_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); - for (sym_index = 0; sym_index < symtab.len; ++sym_index) - top_sorted_syms[sym_index] = &symtab.base[sym_index]; + top_sorted_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *)); + for (sym_index = 0; sym_index < symtab->len; ++sym_index) + top_sorted_syms[sym_index] = &symtab->base[sym_index]; - qsort (top_sorted_syms, symtab.len, sizeof (Sym *), cmp_topo); + qsort (top_sorted_syms, symtab->len, sizeof (Sym *), cmp_topo); DBG (DFNDEBUG, printf ("[cg_assemble] topological sort listing\n"); - for (sym_index = 0; sym_index < symtab.len; ++sym_index) + for (sym_index = 0; sym_index < symtab->len; ++sym_index) { printf ("[cg_assemble] "); printf ("%d:", top_sorted_syms[sym_index]->cg.top_order); @@ -668,24 +671,24 @@ cg_assemble (void) /* Starting from the topological bottom, propagate children times up to parents. */ cycle_time (); - for (sym_index = 0; sym_index < symtab.len; ++sym_index) + for (sym_index = 0; sym_index < symtab->len; ++sym_index) propagate_time (top_sorted_syms[sym_index]); free (top_sorted_syms); /* Now, sort by CG.PROP.SELF + CG.PROP.CHILD. Sorting both the regular function names and cycle headers. */ - time_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *)); - for (sym_index = 0; sym_index < symtab.len; sym_index++) - time_sorted_syms[sym_index] = &symtab.base[sym_index]; + time_sorted_syms = (Sym **) xmalloc ((symtab->len + num_cycles) * sizeof (Sym *)); + for (sym_index = 0; sym_index < symtab->len; sym_index++) + time_sorted_syms[sym_index] = &symtab->base[sym_index]; for (sym_index = 1; sym_index <= num_cycles; sym_index++) - time_sorted_syms[symtab.len + sym_index - 1] = &cycle_header[sym_index]; + time_sorted_syms[symtab->len + sym_index - 1] = &cycle_header[sym_index]; - qsort (time_sorted_syms, symtab.len + num_cycles, sizeof (Sym *), + qsort (time_sorted_syms, symtab->len + num_cycles, sizeof (Sym *), cmp_total); - for (sym_index = 0; sym_index < symtab.len + num_cycles; sym_index++) + for (sym_index = 0; sym_index < symtab->len + num_cycles; sym_index++) time_sorted_syms[sym_index]->cg.index = sym_index + 1; return time_sorted_syms; diff --git a/gprof/cg_print.c b/gprof/cg_print.c index 1d8e7d6b5b3..c8e80d9d3a5 100644 --- a/gprof/cg_print.c +++ b/gprof/cg_print.c @@ -504,13 +504,14 @@ cg_print (Sym ** timesortsym) { unsigned int sym_index; Sym *parent; + Sym_Table *symtab = get_symtab (); if (print_descriptions && bsd_style_output) bsd_callg_blurb (stdout); print_header (); - for (sym_index = 0; sym_index < symtab.len + num_cycles; ++sym_index) + for (sym_index = 0; sym_index < symtab->len + num_cycles; ++sym_index) { parent = timesortsym[sym_index]; @@ -570,18 +571,19 @@ cg_print_index (void) const char *filename; char buf[20]; int column_width = (output_width - 1) / 3; /* Don't write in last col! */ + Sym_Table *symtab = get_symtab (); /* Now, sort regular function name alphabetically to create an index. */ - name_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *)); + name_sorted_syms = (Sym **) xmalloc ((symtab->len + num_cycles) * sizeof (Sym *)); - for (sym_index = 0, nnames = 0; sym_index < symtab.len; sym_index++) + for (sym_index = 0, nnames = 0; sym_index < symtab->len; sym_index++) { - if (ignore_zeros && symtab.base[sym_index].ncalls == 0 - && symtab.base[sym_index].hist.time == 0) + if (ignore_zeros && symtab->base[sym_index].ncalls == 0 + && symtab->base[sym_index].hist.time == 0) continue; - name_sorted_syms[nnames++] = &symtab.base[sym_index]; + name_sorted_syms[nnames++] = &symtab->base[sym_index]; } qsort (name_sorted_syms, nnames, sizeof (Sym *), cmp_name); @@ -787,6 +789,7 @@ cg_print_function_ordering (void) #endif Sym **unused_syms, **used_syms, **scratch_syms; Arc **unplaced_arcs, **high_arcs, **scratch_arcs; + Sym_Table *symtab = get_symtab (); sym_index = 0; used = 0; @@ -797,29 +800,29 @@ cg_print_function_ordering (void) scratch_arc_count = 0; /* First group all the unused functions together. */ - unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); - used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); - scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + unused_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *)); + used_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *)); + scratch_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *)); high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); /* Walk through all the functions; mark those which are never called as placed (we'll emit them as a group later). */ - for (sym_index = 0, used = 0, unused = 0; sym_index < symtab.len; sym_index++) + for (sym_index = 0, used = 0, unused = 0; sym_index < symtab->len; sym_index++) { - if (symtab.base[sym_index].ncalls == 0) + if (symtab->base[sym_index].ncalls == 0) { - unused_syms[unused++] = &symtab.base[sym_index]; - symtab.base[sym_index].has_been_placed = 1; + unused_syms[unused++] = &symtab->base[sym_index]; + symtab->base[sym_index].has_been_placed = 1; } else { - used_syms[used++] = &symtab.base[sym_index]; - symtab.base[sym_index].has_been_placed = 0; - symtab.base[sym_index].next = 0; - symtab.base[sym_index].prev = 0; - symtab.base[sym_index].nuses = 0; + used_syms[used++] = &symtab->base[sym_index]; + symtab->base[sym_index].has_been_placed = 0; + symtab->base[sym_index].next = 0; + symtab->base[sym_index].prev = 0; + symtab->base[sym_index].nuses = 0; } } @@ -961,9 +964,9 @@ cg_print_function_ordering (void) for (sym_index = 0; sym_index < unused; sym_index++) printf("%s\n", unused_syms[sym_index]->name); - unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); - used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); - scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + unused_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *)); + used_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *)); + scratch_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *)); high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); @@ -1236,6 +1239,7 @@ cg_print_file_ordering (void) unsigned long sym_index; Arc **scratch_arcs; char *last; + Sym_Table *symtab = get_symtab (); scratch_arc_count = 0; @@ -1251,11 +1255,11 @@ cg_print_file_ordering (void) scratch_arcs, &scratch_arc_count); /* Output .o's not handled by the main placement algorithm. */ - for (sym_index = 0; sym_index < symtab.len; sym_index++) + for (sym_index = 0; sym_index < symtab->len; sym_index++) { - if (symtab.base[sym_index].mapped - && ! symtab.base[sym_index].has_been_placed) - printf ("%s\n", symtab.base[sym_index].name); + if (symtab->base[sym_index].mapped + && ! symtab->base[sym_index].has_been_placed) + printf ("%s\n", symtab->base[sym_index].name); } qsort (symbol_map, symbol_map_count, sizeof (struct function_map), cmp_symbol_map); @@ -1271,19 +1275,19 @@ cg_print_file_ordering (void) if (last && !filename_cmp (last, symbol_map[sym_index].file_name)) continue; - for (index2 = 0; index2 < symtab.len; index2++) + for (index2 = 0; index2 < symtab->len; index2++) { - if (! symtab.base[index2].mapped) + if (! symtab->base[index2].mapped) continue; - if (!filename_cmp (symtab.base[index2].name, + if (!filename_cmp (symtab->base[index2].name, symbol_map[sym_index].file_name)) break; } /* If we didn't find it in the symbol table, then it must be a .o with no text symbols. Output it last. */ - if (index2 == symtab.len) + if (index2 == symtab->len) printf ("%s\n", symbol_map[sym_index].file_name); last = symbol_map[sym_index].file_name; } diff --git a/gprof/corefile.c b/gprof/corefile.c index bc26bd7883e..74dbfb5cb86 100644 --- a/gprof/corefile.c +++ b/gprof/corefile.c @@ -27,6 +27,7 @@ #include "symtab.h" #include "hist.h" #include "corefile.h" +#include "gmon_io.h" #include "safe-ctype.h" #include /* For UINT_MAX. */ @@ -523,6 +524,7 @@ core_create_syms_from (const char * sym_table_file) { char type; FILE * f; + Sym_Table *symtab; f = fopen (sym_table_file, "r"); if (!f) @@ -531,25 +533,27 @@ core_create_syms_from (const char * sym_table_file) done (1); } - /* Pass 1 - determine upper bound on number of function names. */ - symtab.len = num_of_syms_in (f); + symtab = get_symtab_direct (); - if (symtab.len == 0) + /* 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); } - else if (symtab.len == -1U) + else if (symtab->len == -1U) { fprintf (stderr, _("%s: file `%s' has too many symbols\n"), whoami, sym_table_file); done (1); } - symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym)); + symtab->base = (Sym *) xmalloc (symtab->len * sizeof (Sym)); /* Pass 2 - create symbols. */ - symtab.limit = symtab.base; + symtab->limit = symtab->base; if (fseek (f, 0, SEEK_SET) != 0) { @@ -564,25 +568,25 @@ core_create_syms_from (const char * sym_table_file) if (type != 't' && type != 'T') continue; - sym_init (symtab.limit); + sym_init (symtab->limit); uint64_t addr; sscanf (address, "%" SCNx64, &addr); - symtab.limit->addr = addr; + symtab->limit->addr = 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'); + 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'); - ++symtab.limit; + ++symtab->limit; } fclose (f); - symtab.len = symtab.limit - symtab.base; - symtab_finalize (&symtab); + symtab->len = symtab->limit - symtab->base; + symtab_finalize (symtab); } static int @@ -601,6 +605,7 @@ core_create_function_syms (void) long i; struct function_map * found = NULL; int core_has_func_syms = 0; + Sym_Table *symtab = get_symtab_direct (); switch (core_bfd->xvec->flavour) { @@ -615,7 +620,7 @@ core_create_function_syms (void) } /* Pass 1 - determine upper bound on number of function names. */ - symtab.len = 0; + symtab->len = 0; for (i = 0; i < core_num_syms; ++i) { @@ -634,19 +639,19 @@ core_create_function_syms (void) sizeof (struct function_map), search_mapped_symbol); } if (found == NULL || found->is_first) - ++symtab.len; + ++symtab->len; } - if (symtab.len == 0) + if (symtab->len == 0) { fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name); done (1); } - symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym)); + symtab->base = (Sym *) xmalloc (symtab->len * sizeof (Sym)); /* Pass 2 - create symbols. */ - symtab.limit = symtab.base; + symtab->limit = symtab->base; for (i = 0; i < core_num_syms; ++i) { @@ -674,23 +679,23 @@ core_create_function_syms (void) if (found && ! found->is_first) continue; - sym_init (symtab.limit); + sym_init (symtab->limit); /* Symbol offsets are always section-relative. */ sym_sec = core_syms[i]->section; - symtab.limit->addr = core_syms[i]->value; + symtab->limit->addr = core_syms[i]->value; if (sym_sec) - symtab.limit->addr += bfd_section_vma (sym_sec); + symtab->limit->addr += bfd_section_vma (sym_sec); if (found) { - symtab.limit->name = found->file_name; - symtab.limit->mapped = 1; + symtab->limit->name = found->file_name; + symtab->limit->mapped = 1; } else { - symtab.limit->name = core_syms[i]->name; - symtab.limit->mapped = 0; + symtab->limit->name = core_syms[i]->name; + symtab->limit->mapped = 0; } /* Lookup filename and line number, if we can. */ @@ -698,10 +703,10 @@ core_create_function_syms (void) const char * filename; const char * func_name; - if (get_src_info (symtab.limit->addr, & filename, & func_name, - & symtab.limit->line_num)) + if (get_src_info (symtab->limit->addr, & filename, & func_name, + & symtab->limit->line_num)) { - symtab.limit->file = source_file_lookup_path (filename); + symtab->limit->file = source_file_lookup_path (filename); /* FIXME: Checking __osf__ here does not work with a cross gprof. */ @@ -713,36 +718,36 @@ core_create_function_syms (void) labels do not appear in the symbol table info, so this isn't necessary. */ - if (strcmp (symtab.limit->name, func_name) != 0) + if (strcmp (symtab->limit->name, func_name) != 0) { /* The symbol's address maps to a different name, so it can't be a function-entry point. This happens for labels, for example. */ DBG (AOUTDEBUG, printf ("[core_create_function_syms: rej %s (maps to %s)\n", - symtab.limit->name, func_name)); + symtab->limit->name, func_name)); continue; } #endif } } - symtab.limit->is_func = (!core_has_func_syms + symtab->limit->is_func = (!core_has_func_syms || (core_syms[i]->flags & BSF_FUNCTION) != 0); - symtab.limit->is_bb_head = true; + symtab->limit->is_bb_head = true; if (cxxclass == 't') - symtab.limit->is_static = true; + symtab->limit->is_static = true; DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n", - (long) (symtab.limit - symtab.base), - symtab.limit->name, - (unsigned long) symtab.limit->addr)); - ++symtab.limit; + (long) (symtab->limit - symtab->base), + symtab->limit->name, + (unsigned long) symtab->limit->addr)); + ++symtab->limit; } - symtab.len = symtab.limit - symtab.base; - symtab_finalize (&symtab); + symtab->len = symtab->limit - symtab->base; + symtab_finalize (symtab); } /* Read in symbol table from core. @@ -755,8 +760,10 @@ core_create_line_syms (void) Sym prev, *sym; const char *filename; Sym_Table ltab; - bfd_vma vma_high; size_t ltab_reserved; + Sym_Table *symtab = get_symtab_direct (); + bfd_vma bfd_vma_low = core_text_sect->vma; + bfd_vma bfd_vma_high = bfd_vma_low + bfd_section_size (core_text_sect); /* Create symbols for functions as usual. This is necessary in cases where parts of a program were not compiled with -g. For @@ -786,67 +793,130 @@ core_create_line_syms (void) lot cleaner now. */ memset (&prev, 0, sizeof (prev)); - vma_high = core_text_sect->vma + bfd_section_size (core_text_sect); - for (vma = core_text_sect->vma; vma < vma_high; vma += insn_boundary) - { - if (ltab.len >= ltab_reserved) - { - /* Reserve more space for line symbols. */ - ltab_reserved *= 2; - ltab.base = (Sym *) xrealloc (ltab.base, ltab_reserved * sizeof (Sym)); - ltab.limit = ltab.base + ltab.len; - } - sym_init (ltab.limit); + /* The profile information in the profile data file includes histogram + records, which capture low PC and high PC of program execution. If + all histogram records come in the profile data file before any + call-graph records and basic-block records, we can look up only the + line numbers within low PC and high PC in histogram records. */ + if (gmon_histograms_first) + for (size_t i = 0; i < num_histograms; ++i) + { + bfd_vma hist_vma_high = histograms[i].highpc; + bfd_vma vma_low = MAX (histograms[i].lowpc, bfd_vma_low); + bfd_vma vma_high = MIN (bfd_vma_high, hist_vma_high); + for (vma = vma_low; vma < vma_high; vma += insn_boundary) + { + if (ltab.len >= ltab_reserved) + { + /* Reserve more space for line symbols. */ + ltab_reserved *= 2; + ltab.base = xrealloc (ltab.base, + ltab_reserved * sizeof (Sym)); + ltab.limit = ltab.base + ltab.len; + } + sym_init (ltab.limit); - if (!get_src_info (vma, &filename, <ab.limit->name, <ab.limit->line_num) - || (prev.name && prev.line_num == ltab.limit->line_num - && strcmp (prev.name, ltab.limit->name) == 0 - && filename_cmp (prev.file->name, filename) == 0)) - continue; + if (!get_src_info (vma, &filename, <ab.limit->name, + <ab.limit->line_num) + || (prev.name && prev.line_num == ltab.limit->line_num + && strcmp (prev.name, ltab.limit->name) == 0 + && filename_cmp (prev.file->name, filename) == 0)) + continue; - /* Make name pointer a malloc'ed string. */ - ltab.limit->name = xstrdup (ltab.limit->name); - ltab.limit->file = source_file_lookup_path (filename); + /* Make name pointer a malloc'ed string. */ + ltab.limit->name = xstrdup (ltab.limit->name); + ltab.limit->file = source_file_lookup_path (filename); - ltab.limit->addr = vma; + ltab.limit->addr = vma; - /* Set is_static based on the enclosing function, using either: - 1) the previous symbol, if it's from the same function, or - 2) a symtab lookup. */ - if (ltab.limit->file == prev.file - && strcmp (ltab.limit->name, prev.name) == 0) - { - ltab.limit->is_static = prev.is_static; - } - else - { - sym = sym_lookup(&symtab, ltab.limit->addr); - if (sym) - ltab.limit->is_static = sym->is_static; - } + /* Set is_static based on the enclosing function, using either: + 1) the previous symbol, if it's from the same function, or + 2) a symtab lookup. */ + if (prev.name && ltab.limit->file == prev.file + && strcmp (ltab.limit->name, prev.name) == 0) + { + ltab.limit->is_static = prev.is_static; + } + else + { + sym = sym_lookup (symtab, ltab.limit->addr); + if (sym) + ltab.limit->is_static = sym->is_static; + } - prev = *ltab.limit; + prev = *ltab.limit; - DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n", - (unsigned long) (ltab.limit - ltab.base), - ltab.limit->name, - (unsigned long) ltab.limit->addr)); - ++ltab.limit; - ++ltab.len; - } + DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n", + (unsigned long) (ltab.limit - ltab.base), + ltab.limit->name, + (unsigned long) ltab.limit->addr)); + ++ltab.limit; + ++ltab.len; + } + } + else + for (vma = bfd_vma_low; vma < bfd_vma_high; vma += insn_boundary) + { + if (ltab.len >= ltab_reserved) + { + /* Reserve more space for line symbols. */ + ltab_reserved *= 2; + ltab.base = (Sym *) xrealloc (ltab.base, + ltab_reserved * sizeof (Sym)); + ltab.limit = ltab.base + ltab.len; + } + sym_init (ltab.limit); + + if (!get_src_info (vma, &filename, <ab.limit->name, + <ab.limit->line_num) + || (prev.name && prev.line_num == ltab.limit->line_num + && strcmp (prev.name, ltab.limit->name) == 0 + && filename_cmp (prev.file->name, filename) == 0)) + continue; + + /* Make name pointer a malloc'ed string. */ + ltab.limit->name = xstrdup (ltab.limit->name); + ltab.limit->file = source_file_lookup_path (filename); + + ltab.limit->addr = vma; + + /* Set is_static based on the enclosing function, using either: + 1) the previous symbol, if it's from the same function, or + 2) a symtab lookup. */ + if (ltab.limit->file == prev.file + && strcmp (ltab.limit->name, prev.name) == 0) + { + ltab.limit->is_static = prev.is_static; + } + else + { + sym = sym_lookup (symtab, ltab.limit->addr); + if (sym) + ltab.limit->is_static = sym->is_static; + } + + prev = *ltab.limit; + + DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n", + (unsigned long) (ltab.limit - ltab.base), + ltab.limit->name, + (unsigned long) ltab.limit->addr)); + ++ltab.limit; + ++ltab.len; + } /* Reserve space for function symbols and/or trim excess space. */ - ltab_reserved = ltab.len + symtab.len; + ltab_reserved = ltab.len + symtab->len; ltab.base = xrealloc (ltab.base, ltab_reserved * sizeof (Sym)); ltab.limit = ltab.base + ltab.len; /* Copy in function symbols. */ - memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym)); - ltab.limit += symtab.len; - ltab.len += symtab.len; + memcpy (ltab.limit, symtab->base, symtab->len * sizeof (Sym)); + ltab.limit += symtab->len; + ltab.len += symtab->len; /* Finalize ltab and make it symbol table. */ symtab_finalize (<ab); - free (symtab.base); - symtab = ltab; + free (symtab->base); + set_symtab (<ab); } diff --git a/gprof/gmon_io.c b/gprof/gmon_io.c index 9a069504d85..36ba7987a27 100644 --- a/gprof/gmon_io.c +++ b/gprof/gmon_io.c @@ -58,6 +58,10 @@ static int gmon_write_raw_arc int gmon_input = 0; int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */ +/* True if all histogram records come before any call-graph records and + basic-block records. */ +bool gmon_histograms_first = false; + static enum gmon_ptr_size gmon_get_ptr_size (void) { @@ -327,6 +331,10 @@ gmon_out_read (const char *filename) switch (tag) { case GMON_TAG_TIME_HIST: + if (narcs || nbbs) + gmon_histograms_first = false; + else + gmon_histograms_first = true; ++nhist; gmon_input |= INPUT_HISTOGRAM; hist_read_rec (ifp, filename); @@ -576,6 +584,7 @@ gmon_out_write (const char *filename) { FILE *ofp; struct gmon_hdr ghdr; + Sym_Table *symtab; ofp = fopen (filename, FOPEN_WB); if (!ofp) @@ -584,6 +593,8 @@ gmon_out_write (const char *filename) done (1); } + symtab = get_symtab (); + if (file_format == FF_AUTO || file_format == FF_MAGIC) { /* Write gmon header. */ @@ -704,7 +715,7 @@ gmon_out_write (const char *filename) } /* Dump the normalized raw arc information. */ - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { for (arc = sym->cg.children; arc; arc = arc->next_child) { diff --git a/gprof/gmon_io.h b/gprof/gmon_io.h index 746ca61f98e..43c18693be5 100644 --- a/gprof/gmon_io.h +++ b/gprof/gmon_io.h @@ -28,6 +28,7 @@ extern int gmon_input; /* What input did we see? */ extern int gmon_file_version; /* File version are we dealing with. */ +extern bool gmon_histograms_first; extern int gmon_io_read_vma (FILE *ifp, bfd_vma *valp); extern int gmon_io_read_32 (FILE *ifp, unsigned int *valp); diff --git a/gprof/gprof.c b/gprof/gprof.c index 9392575f747..cea269bc80f 100644 --- a/gprof/gprof.c +++ b/gprof/gprof.c @@ -527,17 +527,6 @@ This program is free software. This program has absolutely no warranty.\n")); if (ignore_direct_calls) core_get_text_space (core_bfd); - /* Create symbols from core image. */ - if (external_symbol_table) - core_create_syms_from (external_symbol_table); - else if (line_granularity) - core_create_line_syms (); - else - core_create_function_syms (); - - /* Translate sym specs into syms. */ - sym_id_parse (); - if (file_format == FF_PROF) { fprintf (stderr, @@ -644,6 +633,23 @@ This program is free software. This program has absolutely no warranty.\n")); return 0; } +/* Initialize the symbol table. */ + +void +symtab_init (void) +{ + /* Create symbols from core image. */ + if (external_symbol_table) + core_create_syms_from (external_symbol_table); + else if (line_granularity) + core_create_line_syms (); + else + core_create_function_syms (); + + /* Translate sym specs into syms. */ + sym_id_parse (); +} + void done (int status) { diff --git a/gprof/gprof.h b/gprof/gprof.h index 1d8d8964772..4222731603f 100644 --- a/gprof/gprof.h +++ b/gprof/gprof.h @@ -132,4 +132,6 @@ extern bool first_output; /* no output so far? */ extern void done (int status) ATTRIBUTE_NORETURN; +extern void symtab_init (void); + #endif /* gprof_h */ diff --git a/gprof/hist.c b/gprof/hist.c index 2d3b0b11ac5..ef4756531c6 100644 --- a/gprof/hist.c +++ b/gprof/hist.c @@ -294,8 +294,9 @@ scale_and_align_entries (void) Sym *sym; bfd_vma bin_of_entry; bfd_vma bin_of_code; + Sym_Table *symtab = get_symtab (); - for (sym = symtab.base; sym < symtab.limit; sym++) + for (sym = symtab->base; sym < symtab->limit; sym++) { histogram *r = find_histogram_for_pc (sym->addr); @@ -366,6 +367,7 @@ hist_assign_samples_1 (histogram *r) unsigned int bin_count; unsigned int i, j, k; double count_time, credit; + Sym_Table *symtab = get_symtab (); bfd_vma lowpc = r->lowpc / sizeof (UNIT); @@ -392,10 +394,10 @@ hist_assign_samples_1 (histogram *r) PR gprof/13325: Make sure that K does not get decremented and J will never be less than 0. */ - for (j = k - 1; j < symtab.len; k = ++j) + for (j = k - 1; j < symtab->len; k = ++j) { - sym_low_pc = symtab.base[j].hist.scaled_addr; - sym_high_pc = symtab.base[j + 1].hist.scaled_addr; + sym_low_pc = symtab->base[j].hist.scaled_addr; + sym_high_pc = symtab->base[j + 1].hist.scaled_addr; /* If high end of bin is below entry address, go for next bin. */ @@ -414,12 +416,12 @@ hist_assign_samples_1 (histogram *r) DBG (SAMPLEDEBUG, printf ( "[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n", - (unsigned long) symtab.base[j].addr, + (unsigned long) symtab->base[j].addr, (unsigned long) (sizeof (UNIT) * sym_high_pc), - symtab.base[j].name, overlap * count_time / hist_scale, + symtab->base[j].name, overlap * count_time / hist_scale, (long) overlap)); - addr = symtab.base[j].addr; + addr = symtab->base[j].addr; credit = overlap * count_time / hist_scale; /* Credit symbol if it appears in INCL_FLAT or that @@ -429,7 +431,7 @@ hist_assign_samples_1 (histogram *r) || (syms[INCL_FLAT].len == 0 && !sym_lookup (&syms[EXCL_FLAT], addr))) { - symtab.base[j].hist.time += credit; + symtab->base[j].hist.time += credit; } else { @@ -569,6 +571,7 @@ hist_print (void) unsigned log_scale; double top_time; bfd_vma addr; + Sym_Table *symtab = get_symtab (); if (first_output) first_output = false; @@ -592,12 +595,12 @@ hist_print (void) /* Sort the symbol table by time (call-count and name as secondary and tertiary keys). */ - time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + time_sorted_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *)); - for (sym_index = 0; sym_index < symtab.len; ++sym_index) - time_sorted_syms[sym_index] = &symtab.base[sym_index]; + for (sym_index = 0; sym_index < symtab->len; ++sym_index) + time_sorted_syms[sym_index] = &symtab->base[sym_index]; - qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time); + qsort (time_sorted_syms, symtab->len, sizeof (Sym *), cmp_time); if (bsd_style_output) { @@ -611,7 +614,7 @@ hist_print (void) top_dog = 0; top_time = 0.0; - for (sym_index = 0; sym_index < symtab.len; ++sym_index) + for (sym_index = 0; sym_index < symtab->len; ++sym_index) { sym = time_sorted_syms[sym_index]; @@ -648,7 +651,7 @@ hist_print (void) I-cache misses etc.). */ print_header (SItab[log_scale].prefix); - for (sym_index = 0; sym_index < symtab.len; ++sym_index) + for (sym_index = 0; sym_index < symtab->len; ++sym_index) { addr = time_sorted_syms[sym_index]->addr; diff --git a/gprof/i386.c b/gprof/i386.c index 62f6f96b20a..350dcb238dd 100644 --- a/gprof/i386.c +++ b/gprof/i386.c @@ -52,6 +52,7 @@ i386_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) unsigned char *instructp; Sym *child; bfd_vma pc, destpc; + Sym_Table *symtab = get_symtab (); DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n", parent->name, (unsigned long) p_lowpc, @@ -76,7 +77,7 @@ i386_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) destpc = bfd_get_32 (core_bfd, instructp + 1) + pc + 5; if (hist_check_address (destpc)) { - child = sym_lookup (&symtab, destpc); + child = sym_lookup (symtab, destpc); if (child && child->addr == destpc) { /* diff --git a/gprof/mips.c b/gprof/mips.c index 0ccd17db525..873403c6a13 100644 --- a/gprof/mips.c +++ b/gprof/mips.c @@ -46,6 +46,7 @@ mips_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) int offset; Sym *child; static bool inited = false; + Sym_Table *symtab = get_symtab (); if (!inited) { @@ -75,7 +76,7 @@ mips_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) dest_pc = (pc & ~(bfd_vma) 0xfffffff) | offset; if (hist_check_address (dest_pc)) { - child = sym_lookup (&symtab, dest_pc); + child = sym_lookup (symtab, dest_pc); if (child) { DBG (CALLDEBUG, diff --git a/gprof/sparc.c b/gprof/sparc.c index 019e58b185f..ac0975eb012 100644 --- a/gprof/sparc.c +++ b/gprof/sparc.c @@ -47,6 +47,7 @@ sparc_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) bfd_vma pc, dest_pc; unsigned int insn; Sym *child; + Sym_Table *symtab = get_symtab (); DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n", parent->name, (unsigned long) p_lowpc, @@ -69,7 +70,7 @@ sparc_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) ^ 0x20000000) - 0x20000000); if (hist_check_address (dest_pc)) { - child = sym_lookup (&symtab, dest_pc); + child = sym_lookup (symtab, dest_pc); if (child) { DBG (CALLDEBUG, diff --git a/gprof/sym_ids.c b/gprof/sym_ids.c index 9f26679cfc0..81be06c6a88 100644 --- a/gprof/sym_ids.c +++ b/gprof/sym_ids.c @@ -278,13 +278,14 @@ sym_id_parse (void) Sym *sym, *left, *right; struct sym_id *id; Sym_Table *tab; + Sym_Table *symtab = get_symtab_direct (); /* Convert symbol ids into Syms, so we can deal with them more easily. */ for (id = id_list; id; id = id->next) parse_id (id); /* First determine size of each table. */ - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { for (id = id_list; id; id = id->next) { @@ -315,7 +316,7 @@ sym_id_parse (void) } /* Make a second pass through symtab, creating syms as necessary. */ - for (sym = symtab.base; sym < symtab.limit; ++sym) + for (sym = symtab->base; sym < symtab->limit; ++sym) { for (id = id_list; id; id = id->next) { diff --git a/gprof/symtab.c b/gprof/symtab.c index cc619aa728e..e8b0b340680 100644 --- a/gprof/symtab.c +++ b/gprof/symtab.c @@ -28,8 +28,40 @@ static int cmp_addr (const void *, const void *); -Sym_Table symtab; +/* The symbol table. */ +static Sym_Table symtab; +/* Return the pointer to the symbol table. */ + +Sym_Table * +get_symtab_direct (void) +{ + return &symtab; +} + +/* Return the pointer to the symbol table and initialize it if it isn't + initialized yet. */ + +Sym_Table * +get_symtab (void) +{ + static Sym_Table *symtab_p; + if (!symtab_p) + { + symtab_init (); + + symtab_p = &symtab; + } + return symtab_p; +} + +/* Set the symbol table to *LTAB. */ + +void +set_symtab (Sym_Table *ltab) +{ + symtab = *ltab; +} /* Initialize a symbol (so it's empty). */ diff --git a/gprof/symtab.h b/gprof/symtab.h index 436f665f9a5..19031b917b0 100644 --- a/gprof/symtab.h +++ b/gprof/symtab.h @@ -110,7 +110,9 @@ typedef struct } Sym_Table; -extern Sym_Table symtab; /* The symbol table. */ +extern Sym_Table *get_symtab (void); +extern Sym_Table *get_symtab_direct (void); +extern void set_symtab (Sym_Table *); extern void sym_init (Sym *); extern void symtab_finalize (Sym_Table *); diff --git a/gprof/vax.c b/gprof/vax.c index fafe2b17b53..47cbe138b3d 100644 --- a/gprof/vax.c +++ b/gprof/vax.c @@ -238,6 +238,7 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) operandenum firstmode; bfd_vma pc, destpc; static bool inited = false; + Sym_Table *symtab = get_symtab (); if (!inited) { @@ -321,7 +322,7 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) destpc = pc + vax_offset (operand); if (hist_check_address (destpc)) { - child = sym_lookup (&symtab, destpc); + child = sym_lookup (symtab, destpc); if (child) { DBG (CALLDEBUG,