@@ -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)
{
@@ -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,
@@ -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)
@@ -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)
{
@@ -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;
@@ -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;
}
@@ -27,6 +27,7 @@
#include "symtab.h"
#include "hist.h"
#include "corefile.h"
+#include "gmon_io.h"
#include "safe-ctype.h"
#include <limits.h> /* 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);
}
+ symtab = get_symtab_direct ();
+
/* Pass 1 - determine upper bound on number of function names. */
- symtab.len = num_of_syms_in (f);
+ symtab->len = num_of_syms_in (f);
- if (symtab.len == 0)
+ 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;
+
+ /* 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 (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;
+ }
- 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;
+ 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;
+ }
+ }
+ 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);
- /* Make name pointer a malloc'ed string. */
- ltab.limit->name = xstrdup (ltab.limit->name);
- ltab.limit->file = source_file_lookup_path (filename);
+ 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;
- ltab.limit->addr = vma;
+ /* Make name pointer a malloc'ed string. */
+ ltab.limit->name = xstrdup (ltab.limit->name);
+ ltab.limit->file = source_file_lookup_path (filename);
- /* 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;
- }
+ 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;
+ 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;
+ }
/* 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);
}
@@ -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)
{
@@ -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);
@@ -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)
{
@@ -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 */
@@ -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;
@@ -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)
{
/*
@@ -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,
@@ -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,
@@ -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)
{
@@ -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). */
@@ -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 *);
@@ -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,