mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-05 15:15:42 +00:00
gprof: only process line numbers for intersection of vmas and histograms
Some programs like RTOS firmware may have a large number of symbols. 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, which reduces processing time for such a firmware from ~2 minutes to ~2 seconds. Add symbol table access function, get_symtab, get_symtab_direct and set_symtab to delay loading the symbol table until its first use. * aarch64.c (aarch64_find_call): Call get_symtab to get the symbol table pointer * alpha.c (alpha_find_call): Likewise. * basic_blocks.c (bb_read_rec): Likewise. (bb_write_blocks): Likewise. (print_exec_counts): Likewise. (print_annotated_source): Likewise. * call_graph.c (cg_tally): Likewise. (cg_write_arcs): Likewise. * cg_arcs.c (cycle_link): Likewise. (propagate_flags): Likewise. (cg_assemble): Likewise. * cg_print.c (cg_print): Likewise. (cg_print_index): Likewise. (cg_print_function_ordering): Likewise. * corefile.c: Include "gmon_io.h". (core_create_syms_from): Call get_symtab_direct to get the symbol table pointer. (core_create_function_syms): Likewise. (core_create_line_syms): Likewise. 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. * gmon_io.c (gmon_histograms_first): New. (gmon_out_read): Set gmon_histograms_first to true if all histogram records come first. (gmon_out_write): Call get_symtab to get the symbol table pointer. * hist.c (scale_and_align_entries): Likewise. (hist_assign_samples_1): Likewise. (hist_print): Likewise. * i386.c (i386_find_call): Likewise. * mips.c (mips_find_call): Likewise. * sparc.c (sparc_find_call): Likewise. * sym_ids.c (sym_id_parse): Likewise. * vax.c (vax_find_call): Likewise. * gmon_io.h (gmon_histograms_first): New. * gprof.c (man): Don't create profile info. (symtab_init): New. * gprof.h (symtab_init): New. * symtab.c (symtab): Changed to static. (get_symtab_direct): New. (get_symtab): Likewise. (set_symtab): Likewise. * symtab.h (symtab): Removed. (get_symtab_direct): New. (get_symtab): Likewise. (set_symtab): Likewise. Signed-off-by: Richard Allen <rsaxvc@gmail.com> Co-Authored-By: H.J. Lu <hjl.tools@gmail.com>
This commit is contained in:
@@ -50,6 +50,7 @@ aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
|
|||||||
bfd_vma pc, dest_pc, offset;
|
bfd_vma pc, dest_pc, offset;
|
||||||
unsigned int insn;
|
unsigned int insn;
|
||||||
Sym *child;
|
Sym *child;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
|
DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
|
||||||
parent->name, (unsigned long) p_lowpc,
|
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))
|
if (hist_check_address (dest_pc))
|
||||||
{
|
{
|
||||||
child = sym_lookup (&symtab, dest_pc);
|
child = sym_lookup (symtab, dest_pc);
|
||||||
|
|
||||||
if (child)
|
if (child)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ alpha_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
|
|||||||
bfd_vma pc, dest_pc;
|
bfd_vma pc, dest_pc;
|
||||||
unsigned int insn;
|
unsigned int insn;
|
||||||
Sym *child;
|
Sym *child;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
if (indirect_child.name == NULL)
|
if (indirect_child.name == NULL)
|
||||||
{
|
{
|
||||||
@@ -149,7 +150,7 @@ alpha_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
|
|||||||
^ 0x100000) - 0x100000);
|
^ 0x100000) - 0x100000);
|
||||||
if (hist_check_address (dest_pc))
|
if (hist_check_address (dest_pc))
|
||||||
{
|
{
|
||||||
child = sym_lookup (&symtab, dest_pc);
|
child = sym_lookup (symtab, dest_pc);
|
||||||
if (child)
|
if (child)
|
||||||
{
|
{
|
||||||
DBG (CALLDEBUG,
|
DBG (CALLDEBUG,
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ bb_read_rec (FILE *ifp, const char *filename)
|
|||||||
unsigned int nblocks, b;
|
unsigned int nblocks, b;
|
||||||
bfd_vma addr, ncalls;
|
bfd_vma addr, ncalls;
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
|
Sym_Table *symtab;
|
||||||
|
|
||||||
if (gmon_io_read_32 (ifp, &nblocks))
|
if (gmon_io_read_32 (ifp, &nblocks))
|
||||||
{
|
{
|
||||||
@@ -130,6 +131,8 @@ bb_read_rec (FILE *ifp, const char *filename)
|
|||||||
done (1);
|
done (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symtab = get_symtab ();
|
||||||
|
|
||||||
nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks);
|
nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks);
|
||||||
if (gmon_file_version == 0)
|
if (gmon_file_version == 0)
|
||||||
fskip_string (ifp);
|
fskip_string (ifp);
|
||||||
@@ -163,7 +166,7 @@ bb_read_rec (FILE *ifp, const char *filename)
|
|||||||
profiling at the line-by-line level: */
|
profiling at the line-by-line level: */
|
||||||
if (line_granularity)
|
if (line_granularity)
|
||||||
{
|
{
|
||||||
sym = sym_lookup (&symtab, addr);
|
sym = sym_lookup (symtab, addr);
|
||||||
|
|
||||||
if (sym)
|
if (sym)
|
||||||
{
|
{
|
||||||
@@ -210,9 +213,10 @@ bb_write_blocks (FILE *ofp, const char *filename)
|
|||||||
unsigned int nblocks = 0;
|
unsigned int nblocks = 0;
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
int i;
|
int i;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
/* Count how many non-zero blocks with have: */
|
/* 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++)
|
for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
|
||||||
;
|
;
|
||||||
@@ -228,7 +232,7 @@ bb_write_blocks (FILE *ofp, const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write counts: */
|
/* 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++)
|
for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
|
||||||
{
|
{
|
||||||
@@ -252,6 +256,7 @@ print_exec_counts (void)
|
|||||||
{
|
{
|
||||||
Sym **sorted_bbs, *sym;
|
Sym **sorted_bbs, *sym;
|
||||||
unsigned int i, j, len;
|
unsigned int i, j, len;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
if (first_output)
|
if (first_output)
|
||||||
first_output = false;
|
first_output = false;
|
||||||
@@ -259,10 +264,10 @@ print_exec_counts (void)
|
|||||||
printf ("\f\n");
|
printf ("\f\n");
|
||||||
|
|
||||||
/* Sort basic-blocks according to function name and line number: */
|
/* 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;
|
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
|
/* Accept symbol if it's in the INCL_EXEC table
|
||||||
or there is no INCL_EXEC table
|
or there is no INCL_EXEC table
|
||||||
@@ -461,10 +466,11 @@ print_annotated_source (void)
|
|||||||
Source_File *sf;
|
Source_File *sf;
|
||||||
int i, table_len;
|
int i, table_len;
|
||||||
FILE *ofp;
|
FILE *ofp;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
/* Find maximum line number for each source file that user is
|
/* Find maximum line number for each source file that user is
|
||||||
interested in: */
|
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
|
/* Accept symbol if it's file is known, its line number is
|
||||||
bigger than anything we have seen for that file so far and
|
bigger than anything we have seen for that file so far and
|
||||||
@@ -490,7 +496,7 @@ print_annotated_source (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Count executions per line: */
|
/* 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
|
if (sym->file && sym->file->num_lines
|
||||||
&& (sym_lookup (&syms[INCL_ANNO], sym->addr)
|
&& (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 *parent;
|
||||||
Sym *child;
|
Sym *child;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
parent = sym_lookup (&symtab, from_pc);
|
parent = sym_lookup (symtab, from_pc);
|
||||||
child = sym_lookup (&symtab, self_pc);
|
child = sym_lookup (symtab, self_pc);
|
||||||
|
|
||||||
if (child == NULL || parent == NULL)
|
if (child == NULL || parent == NULL)
|
||||||
return;
|
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
|
For normal profiling, is_func will be set on all symbols, so this
|
||||||
code will do nothing. */
|
code will do nothing. */
|
||||||
while (child >= symtab.base && ! child->is_func)
|
while (child >= symtab->base && ! child->is_func)
|
||||||
--child;
|
--child;
|
||||||
|
|
||||||
if (child < symtab.base)
|
if (child < symtab->base)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table
|
/* 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;
|
Arc *arc;
|
||||||
Sym *sym;
|
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)
|
for (arc = sym->cg.children; arc; arc = arc->next_child)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -275,11 +275,12 @@ cycle_link (void)
|
|||||||
Sym *sym, *cyc, *member;
|
Sym *sym, *cyc, *member;
|
||||||
Arc *arc;
|
Arc *arc;
|
||||||
int num;
|
int num;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
/* count the number of cycles, and initialize the cycle lists: */
|
/* count the number of cycles, and initialize the cycle lists: */
|
||||||
|
|
||||||
num_cycles = 0;
|
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: */
|
/* this is how you find unattached cycles: */
|
||||||
if (sym->cg.cyc.head == sym && sym->cg.cyc.next)
|
if (sym->cg.cyc.head == sym && sym->cg.cyc.next)
|
||||||
@@ -300,7 +301,7 @@ cycle_link (void)
|
|||||||
*/
|
*/
|
||||||
num = 0;
|
num = 0;
|
||||||
cyc = cycle_header;
|
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))
|
if (!(sym->cg.cyc.head == sym && sym->cg.cyc.next != 0))
|
||||||
{
|
{
|
||||||
@@ -440,9 +441,10 @@ propagate_flags (Sym **symbols)
|
|||||||
{
|
{
|
||||||
int sym_index;
|
int sym_index;
|
||||||
Sym *old_head, *child;
|
Sym *old_head, *child;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
old_head = 0;
|
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];
|
child = symbols[sym_index];
|
||||||
/*
|
/*
|
||||||
@@ -597,12 +599,13 @@ cg_assemble (void)
|
|||||||
Sym *parent, **time_sorted_syms, **top_sorted_syms;
|
Sym *parent, **time_sorted_syms, **top_sorted_syms;
|
||||||
unsigned int sym_index;
|
unsigned int sym_index;
|
||||||
Arc *arc;
|
Arc *arc;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
/* Initialize various things:
|
/* Initialize various things:
|
||||||
Zero out child times.
|
Zero out child times.
|
||||||
Count self-recursive calls.
|
Count self-recursive calls.
|
||||||
Indicate that nothing is on cycles. */
|
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;
|
parent->cg.child_time = 0.0;
|
||||||
arc = arc_lookup (parent, parent);
|
arc = arc_lookup (parent, parent);
|
||||||
@@ -633,7 +636,7 @@ cg_assemble (void)
|
|||||||
|
|
||||||
/* Topologically order things. If any node is unnumbered, number
|
/* Topologically order things. If any node is unnumbered, number
|
||||||
it and any of its descendents. */
|
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)
|
if (parent->cg.top_order == DFN_NAN)
|
||||||
cg_dfn (parent);
|
cg_dfn (parent);
|
||||||
@@ -643,14 +646,14 @@ cg_assemble (void)
|
|||||||
cycle_link ();
|
cycle_link ();
|
||||||
|
|
||||||
/* Sort the symbol table in reverse topological order. */
|
/* Sort the symbol table in reverse topological order. */
|
||||||
top_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
|
top_sorted_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *));
|
||||||
for (sym_index = 0; sym_index < symtab.len; ++sym_index)
|
for (sym_index = 0; sym_index < symtab->len; ++sym_index)
|
||||||
top_sorted_syms[sym_index] = &symtab.base[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,
|
DBG (DFNDEBUG,
|
||||||
printf ("[cg_assemble] topological sort listing\n");
|
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 ("[cg_assemble] ");
|
||||||
printf ("%d:", top_sorted_syms[sym_index]->cg.top_order);
|
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
|
/* Starting from the topological bottom, propagate children times
|
||||||
up to parents. */
|
up to parents. */
|
||||||
cycle_time ();
|
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]);
|
propagate_time (top_sorted_syms[sym_index]);
|
||||||
|
|
||||||
free (top_sorted_syms);
|
free (top_sorted_syms);
|
||||||
|
|
||||||
/* Now, sort by CG.PROP.SELF + CG.PROP.CHILD. Sorting both the regular
|
/* Now, sort by CG.PROP.SELF + CG.PROP.CHILD. Sorting both the regular
|
||||||
function names and cycle headers. */
|
function names and cycle headers. */
|
||||||
time_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *));
|
time_sorted_syms = (Sym **) xmalloc ((symtab->len + num_cycles) * sizeof (Sym *));
|
||||||
for (sym_index = 0; sym_index < symtab.len; sym_index++)
|
for (sym_index = 0; sym_index < symtab->len; sym_index++)
|
||||||
time_sorted_syms[sym_index] = &symtab.base[sym_index];
|
time_sorted_syms[sym_index] = &symtab->base[sym_index];
|
||||||
|
|
||||||
for (sym_index = 1; sym_index <= num_cycles; 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);
|
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;
|
time_sorted_syms[sym_index]->cg.index = sym_index + 1;
|
||||||
|
|
||||||
return time_sorted_syms;
|
return time_sorted_syms;
|
||||||
|
|||||||
@@ -504,13 +504,14 @@ cg_print (Sym ** timesortsym)
|
|||||||
{
|
{
|
||||||
unsigned int sym_index;
|
unsigned int sym_index;
|
||||||
Sym *parent;
|
Sym *parent;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
if (print_descriptions && bsd_style_output)
|
if (print_descriptions && bsd_style_output)
|
||||||
bsd_callg_blurb (stdout);
|
bsd_callg_blurb (stdout);
|
||||||
|
|
||||||
print_header ();
|
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];
|
parent = timesortsym[sym_index];
|
||||||
|
|
||||||
@@ -570,18 +571,19 @@ cg_print_index (void)
|
|||||||
const char *filename;
|
const char *filename;
|
||||||
char buf[20];
|
char buf[20];
|
||||||
int column_width = (output_width - 1) / 3; /* Don't write in last col! */
|
int column_width = (output_width - 1) / 3; /* Don't write in last col! */
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
/* Now, sort regular function name
|
/* Now, sort regular function name
|
||||||
alphabetically to create an index. */
|
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
|
if (ignore_zeros && symtab->base[sym_index].ncalls == 0
|
||||||
&& symtab.base[sym_index].hist.time == 0)
|
&& symtab->base[sym_index].hist.time == 0)
|
||||||
continue;
|
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);
|
qsort (name_sorted_syms, nnames, sizeof (Sym *), cmp_name);
|
||||||
@@ -787,6 +789,7 @@ cg_print_function_ordering (void)
|
|||||||
#endif
|
#endif
|
||||||
Sym **unused_syms, **used_syms, **scratch_syms;
|
Sym **unused_syms, **used_syms, **scratch_syms;
|
||||||
Arc **unplaced_arcs, **high_arcs, **scratch_arcs;
|
Arc **unplaced_arcs, **high_arcs, **scratch_arcs;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
sym_index = 0;
|
sym_index = 0;
|
||||||
used = 0;
|
used = 0;
|
||||||
@@ -797,29 +800,29 @@ cg_print_function_ordering (void)
|
|||||||
scratch_arc_count = 0;
|
scratch_arc_count = 0;
|
||||||
|
|
||||||
/* First group all the unused functions together. */
|
/* First group all the unused functions together. */
|
||||||
unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
|
unused_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *));
|
||||||
used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
|
used_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *));
|
||||||
scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
|
scratch_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *));
|
||||||
high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
||||||
scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
||||||
unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
||||||
|
|
||||||
/* Walk through all the functions; mark those which are never
|
/* Walk through all the functions; mark those which are never
|
||||||
called as placed (we'll emit them as a group later). */
|
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];
|
unused_syms[unused++] = &symtab->base[sym_index];
|
||||||
symtab.base[sym_index].has_been_placed = 1;
|
symtab->base[sym_index].has_been_placed = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
used_syms[used++] = &symtab.base[sym_index];
|
used_syms[used++] = &symtab->base[sym_index];
|
||||||
symtab.base[sym_index].has_been_placed = 0;
|
symtab->base[sym_index].has_been_placed = 0;
|
||||||
symtab.base[sym_index].next = 0;
|
symtab->base[sym_index].next = 0;
|
||||||
symtab.base[sym_index].prev = 0;
|
symtab->base[sym_index].prev = 0;
|
||||||
symtab.base[sym_index].nuses = 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++)
|
for (sym_index = 0; sym_index < unused; sym_index++)
|
||||||
printf("%s\n", unused_syms[sym_index]->name);
|
printf("%s\n", unused_syms[sym_index]->name);
|
||||||
|
|
||||||
unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
|
unused_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *));
|
||||||
used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
|
used_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *));
|
||||||
scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
|
scratch_syms = (Sym **) xmalloc (symtab->len * sizeof (Sym *));
|
||||||
high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
||||||
scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
|
||||||
unplaced_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;
|
unsigned long sym_index;
|
||||||
Arc **scratch_arcs;
|
Arc **scratch_arcs;
|
||||||
char *last;
|
char *last;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
scratch_arc_count = 0;
|
scratch_arc_count = 0;
|
||||||
|
|
||||||
@@ -1251,11 +1255,11 @@ cg_print_file_ordering (void)
|
|||||||
scratch_arcs, &scratch_arc_count);
|
scratch_arcs, &scratch_arc_count);
|
||||||
|
|
||||||
/* Output .o's not handled by the main placement algorithm. */
|
/* 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
|
if (symtab->base[sym_index].mapped
|
||||||
&& ! symtab.base[sym_index].has_been_placed)
|
&& ! symtab->base[sym_index].has_been_placed)
|
||||||
printf ("%s\n", symtab.base[sym_index].name);
|
printf ("%s\n", symtab->base[sym_index].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort (symbol_map, symbol_map_count, sizeof (struct function_map), cmp_symbol_map);
|
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))
|
if (last && !filename_cmp (last, symbol_map[sym_index].file_name))
|
||||||
continue;
|
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;
|
continue;
|
||||||
|
|
||||||
if (!filename_cmp (symtab.base[index2].name,
|
if (!filename_cmp (symtab->base[index2].name,
|
||||||
symbol_map[sym_index].file_name))
|
symbol_map[sym_index].file_name))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we didn't find it in the symbol table, then it must
|
/* If we didn't find it in the symbol table, then it must
|
||||||
be a .o with no text symbols. Output it last. */
|
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);
|
printf ("%s\n", symbol_map[sym_index].file_name);
|
||||||
last = symbol_map[sym_index].file_name;
|
last = symbol_map[sym_index].file_name;
|
||||||
}
|
}
|
||||||
|
|||||||
180
gprof/corefile.c
180
gprof/corefile.c
@@ -27,6 +27,7 @@
|
|||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "hist.h"
|
#include "hist.h"
|
||||||
#include "corefile.h"
|
#include "corefile.h"
|
||||||
|
#include "gmon_io.h"
|
||||||
#include "safe-ctype.h"
|
#include "safe-ctype.h"
|
||||||
#include <limits.h> /* For UINT_MAX. */
|
#include <limits.h> /* For UINT_MAX. */
|
||||||
|
|
||||||
@@ -523,6 +524,7 @@ core_create_syms_from (const char * sym_table_file)
|
|||||||
{
|
{
|
||||||
char type;
|
char type;
|
||||||
FILE * f;
|
FILE * f;
|
||||||
|
Sym_Table *symtab;
|
||||||
|
|
||||||
f = fopen (sym_table_file, "r");
|
f = fopen (sym_table_file, "r");
|
||||||
if (!f)
|
if (!f)
|
||||||
@@ -531,25 +533,27 @@ core_create_syms_from (const char * sym_table_file)
|
|||||||
done (1);
|
done (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass 1 - determine upper bound on number of function names. */
|
symtab = get_symtab_direct ();
|
||||||
symtab.len = num_of_syms_in (f);
|
|
||||||
|
|
||||||
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);
|
fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, sym_table_file);
|
||||||
done (1);
|
done (1);
|
||||||
}
|
}
|
||||||
else if (symtab.len == -1U)
|
else if (symtab->len == -1U)
|
||||||
{
|
{
|
||||||
fprintf (stderr, _("%s: file `%s' has too many symbols\n"),
|
fprintf (stderr, _("%s: file `%s' has too many symbols\n"),
|
||||||
whoami, sym_table_file);
|
whoami, sym_table_file);
|
||||||
done (1);
|
done (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
|
symtab->base = (Sym *) xmalloc (symtab->len * sizeof (Sym));
|
||||||
|
|
||||||
/* Pass 2 - create symbols. */
|
/* Pass 2 - create symbols. */
|
||||||
symtab.limit = symtab.base;
|
symtab->limit = symtab->base;
|
||||||
|
|
||||||
if (fseek (f, 0, SEEK_SET) != 0)
|
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')
|
if (type != 't' && type != 'T')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sym_init (symtab.limit);
|
sym_init (symtab->limit);
|
||||||
|
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
sscanf (address, "%" SCNx64, &addr);
|
sscanf (address, "%" SCNx64, &addr);
|
||||||
symtab.limit->addr = addr;
|
symtab->limit->addr = addr;
|
||||||
|
|
||||||
symtab.limit->name = (char *) xmalloc (strlen (name) + 1);
|
symtab->limit->name = (char *) xmalloc (strlen (name) + 1);
|
||||||
strcpy ((char *) symtab.limit->name, name);
|
strcpy ((char *) symtab->limit->name, name);
|
||||||
symtab.limit->mapped = 0;
|
symtab->limit->mapped = 0;
|
||||||
symtab.limit->is_func = true;
|
symtab->limit->is_func = true;
|
||||||
symtab.limit->is_bb_head = true;
|
symtab->limit->is_bb_head = true;
|
||||||
symtab.limit->is_static = (type == 't');
|
symtab->limit->is_static = (type == 't');
|
||||||
|
|
||||||
++symtab.limit;
|
++symtab->limit;
|
||||||
}
|
}
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
|
||||||
symtab.len = symtab.limit - symtab.base;
|
symtab->len = symtab->limit - symtab->base;
|
||||||
symtab_finalize (&symtab);
|
symtab_finalize (symtab);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -601,6 +605,7 @@ core_create_function_syms (void)
|
|||||||
long i;
|
long i;
|
||||||
struct function_map * found = NULL;
|
struct function_map * found = NULL;
|
||||||
int core_has_func_syms = 0;
|
int core_has_func_syms = 0;
|
||||||
|
Sym_Table *symtab = get_symtab_direct ();
|
||||||
|
|
||||||
switch (core_bfd->xvec->flavour)
|
switch (core_bfd->xvec->flavour)
|
||||||
{
|
{
|
||||||
@@ -615,7 +620,7 @@ core_create_function_syms (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Pass 1 - determine upper bound on number of function names. */
|
/* Pass 1 - determine upper bound on number of function names. */
|
||||||
symtab.len = 0;
|
symtab->len = 0;
|
||||||
|
|
||||||
for (i = 0; i < core_num_syms; ++i)
|
for (i = 0; i < core_num_syms; ++i)
|
||||||
{
|
{
|
||||||
@@ -634,19 +639,19 @@ core_create_function_syms (void)
|
|||||||
sizeof (struct function_map), search_mapped_symbol);
|
sizeof (struct function_map), search_mapped_symbol);
|
||||||
}
|
}
|
||||||
if (found == NULL || found->is_first)
|
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);
|
fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
|
||||||
done (1);
|
done (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));
|
symtab->base = (Sym *) xmalloc (symtab->len * sizeof (Sym));
|
||||||
|
|
||||||
/* Pass 2 - create symbols. */
|
/* Pass 2 - create symbols. */
|
||||||
symtab.limit = symtab.base;
|
symtab->limit = symtab->base;
|
||||||
|
|
||||||
for (i = 0; i < core_num_syms; ++i)
|
for (i = 0; i < core_num_syms; ++i)
|
||||||
{
|
{
|
||||||
@@ -674,23 +679,23 @@ core_create_function_syms (void)
|
|||||||
if (found && ! found->is_first)
|
if (found && ! found->is_first)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sym_init (symtab.limit);
|
sym_init (symtab->limit);
|
||||||
|
|
||||||
/* Symbol offsets are always section-relative. */
|
/* Symbol offsets are always section-relative. */
|
||||||
sym_sec = core_syms[i]->section;
|
sym_sec = core_syms[i]->section;
|
||||||
symtab.limit->addr = core_syms[i]->value;
|
symtab->limit->addr = core_syms[i]->value;
|
||||||
if (sym_sec)
|
if (sym_sec)
|
||||||
symtab.limit->addr += bfd_section_vma (sym_sec);
|
symtab->limit->addr += bfd_section_vma (sym_sec);
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
symtab.limit->name = found->file_name;
|
symtab->limit->name = found->file_name;
|
||||||
symtab.limit->mapped = 1;
|
symtab->limit->mapped = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
symtab.limit->name = core_syms[i]->name;
|
symtab->limit->name = core_syms[i]->name;
|
||||||
symtab.limit->mapped = 0;
|
symtab->limit->mapped = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup filename and line number, if we can. */
|
/* Lookup filename and line number, if we can. */
|
||||||
@@ -698,10 +703,10 @@ core_create_function_syms (void)
|
|||||||
const char * filename;
|
const char * filename;
|
||||||
const char * func_name;
|
const char * func_name;
|
||||||
|
|
||||||
if (get_src_info (symtab.limit->addr, & filename, & func_name,
|
if (get_src_info (symtab->limit->addr, & filename, & func_name,
|
||||||
& symtab.limit->line_num))
|
& 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
|
/* FIXME: Checking __osf__ here does not work with a cross
|
||||||
gprof. */
|
gprof. */
|
||||||
@@ -713,36 +718,36 @@ core_create_function_syms (void)
|
|||||||
labels do not appear in the symbol table info, so this isn't
|
labels do not appear in the symbol table info, so this isn't
|
||||||
necessary. */
|
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
|
/* The symbol's address maps to a different name, so
|
||||||
it can't be a function-entry point. This happens
|
it can't be a function-entry point. This happens
|
||||||
for labels, for example. */
|
for labels, for example. */
|
||||||
DBG (AOUTDEBUG,
|
DBG (AOUTDEBUG,
|
||||||
printf ("[core_create_function_syms: rej %s (maps to %s)\n",
|
printf ("[core_create_function_syms: rej %s (maps to %s)\n",
|
||||||
symtab.limit->name, func_name));
|
symtab->limit->name, func_name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
symtab.limit->is_func = (!core_has_func_syms
|
symtab->limit->is_func = (!core_has_func_syms
|
||||||
|| (core_syms[i]->flags & BSF_FUNCTION) != 0);
|
|| (core_syms[i]->flags & BSF_FUNCTION) != 0);
|
||||||
symtab.limit->is_bb_head = true;
|
symtab->limit->is_bb_head = true;
|
||||||
|
|
||||||
if (cxxclass == 't')
|
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",
|
DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
|
||||||
(long) (symtab.limit - symtab.base),
|
(long) (symtab->limit - symtab->base),
|
||||||
symtab.limit->name,
|
symtab->limit->name,
|
||||||
(unsigned long) symtab.limit->addr));
|
(unsigned long) symtab->limit->addr));
|
||||||
++symtab.limit;
|
++symtab->limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
symtab.len = symtab.limit - symtab.base;
|
symtab->len = symtab->limit - symtab->base;
|
||||||
symtab_finalize (&symtab);
|
symtab_finalize (symtab);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read in symbol table from core.
|
/* Read in symbol table from core.
|
||||||
@@ -755,8 +760,10 @@ core_create_line_syms (void)
|
|||||||
Sym prev, *sym;
|
Sym prev, *sym;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
Sym_Table ltab;
|
Sym_Table ltab;
|
||||||
bfd_vma vma_high;
|
|
||||||
size_t ltab_reserved;
|
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
|
/* Create symbols for functions as usual. This is necessary in
|
||||||
cases where parts of a program were not compiled with -g. For
|
cases where parts of a program were not compiled with -g. For
|
||||||
@@ -786,19 +793,82 @@ core_create_line_syms (void)
|
|||||||
lot cleaner now. */
|
lot cleaner now. */
|
||||||
memset (&prev, 0, sizeof (prev));
|
memset (&prev, 0, sizeof (prev));
|
||||||
|
|
||||||
vma_high = core_text_sect->vma + bfd_section_size (core_text_sect);
|
/* The profile information in the profile data file includes histogram
|
||||||
for (vma = core_text_sect->vma; vma < vma_high; vma += insn_boundary)
|
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)
|
if (ltab.len >= ltab_reserved)
|
||||||
{
|
{
|
||||||
/* Reserve more space for line symbols. */
|
/* Reserve more space for line symbols. */
|
||||||
ltab_reserved *= 2;
|
ltab_reserved *= 2;
|
||||||
ltab.base = (Sym *) xrealloc (ltab.base, ltab_reserved * sizeof (Sym));
|
ltab.base = xrealloc (ltab.base,
|
||||||
|
ltab_reserved * sizeof (Sym));
|
||||||
ltab.limit = ltab.base + ltab.len;
|
ltab.limit = ltab.base + ltab.len;
|
||||||
}
|
}
|
||||||
sym_init (ltab.limit);
|
sym_init (ltab.limit);
|
||||||
|
|
||||||
if (!get_src_info (vma, &filename, <ab.limit->name, <ab.limit->line_num)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (!get_src_info (vma, &filename, <ab.limit->name,
|
||||||
|
<ab.limit->line_num)
|
||||||
|| (prev.name && prev.line_num == ltab.limit->line_num
|
|| (prev.name && prev.line_num == ltab.limit->line_num
|
||||||
&& strcmp (prev.name, ltab.limit->name) == 0
|
&& strcmp (prev.name, ltab.limit->name) == 0
|
||||||
&& filename_cmp (prev.file->name, filename) == 0))
|
&& filename_cmp (prev.file->name, filename) == 0))
|
||||||
@@ -820,7 +890,7 @@ core_create_line_syms (void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sym = sym_lookup(&symtab, ltab.limit->addr);
|
sym = sym_lookup (symtab, ltab.limit->addr);
|
||||||
if (sym)
|
if (sym)
|
||||||
ltab.limit->is_static = sym->is_static;
|
ltab.limit->is_static = sym->is_static;
|
||||||
}
|
}
|
||||||
@@ -836,17 +906,17 @@ core_create_line_syms (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Reserve space for function symbols and/or trim excess space. */
|
/* 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.base = xrealloc (ltab.base, ltab_reserved * sizeof (Sym));
|
||||||
ltab.limit = ltab.base + ltab.len;
|
ltab.limit = ltab.base + ltab.len;
|
||||||
|
|
||||||
/* Copy in function symbols. */
|
/* Copy in function symbols. */
|
||||||
memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
|
memcpy (ltab.limit, symtab->base, symtab->len * sizeof (Sym));
|
||||||
ltab.limit += symtab.len;
|
ltab.limit += symtab->len;
|
||||||
ltab.len += symtab.len;
|
ltab.len += symtab->len;
|
||||||
|
|
||||||
/* Finalize ltab and make it symbol table. */
|
/* Finalize ltab and make it symbol table. */
|
||||||
symtab_finalize (<ab);
|
symtab_finalize (<ab);
|
||||||
free (symtab.base);
|
free (symtab->base);
|
||||||
symtab = ltab;
|
set_symtab (<ab);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ static int gmon_write_raw_arc
|
|||||||
int gmon_input = 0;
|
int gmon_input = 0;
|
||||||
int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */
|
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
|
static enum gmon_ptr_size
|
||||||
gmon_get_ptr_size (void)
|
gmon_get_ptr_size (void)
|
||||||
{
|
{
|
||||||
@@ -327,6 +331,10 @@ gmon_out_read (const char *filename)
|
|||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case GMON_TAG_TIME_HIST:
|
case GMON_TAG_TIME_HIST:
|
||||||
|
if (narcs || nbbs)
|
||||||
|
gmon_histograms_first = false;
|
||||||
|
else
|
||||||
|
gmon_histograms_first = true;
|
||||||
++nhist;
|
++nhist;
|
||||||
gmon_input |= INPUT_HISTOGRAM;
|
gmon_input |= INPUT_HISTOGRAM;
|
||||||
hist_read_rec (ifp, filename);
|
hist_read_rec (ifp, filename);
|
||||||
@@ -576,6 +584,7 @@ gmon_out_write (const char *filename)
|
|||||||
{
|
{
|
||||||
FILE *ofp;
|
FILE *ofp;
|
||||||
struct gmon_hdr ghdr;
|
struct gmon_hdr ghdr;
|
||||||
|
Sym_Table *symtab;
|
||||||
|
|
||||||
ofp = fopen (filename, FOPEN_WB);
|
ofp = fopen (filename, FOPEN_WB);
|
||||||
if (!ofp)
|
if (!ofp)
|
||||||
@@ -584,6 +593,8 @@ gmon_out_write (const char *filename)
|
|||||||
done (1);
|
done (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symtab = get_symtab ();
|
||||||
|
|
||||||
if (file_format == FF_AUTO || file_format == FF_MAGIC)
|
if (file_format == FF_AUTO || file_format == FF_MAGIC)
|
||||||
{
|
{
|
||||||
/* Write gmon header. */
|
/* Write gmon header. */
|
||||||
@@ -704,7 +715,7 @@ gmon_out_write (const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Dump the normalized raw arc information. */
|
/* 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)
|
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_input; /* What input did we see? */
|
||||||
extern int gmon_file_version; /* File version are we dealing with. */
|
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_vma (FILE *ifp, bfd_vma *valp);
|
||||||
extern int gmon_io_read_32 (FILE *ifp, unsigned int *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)
|
if (ignore_direct_calls)
|
||||||
core_get_text_space (core_bfd);
|
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)
|
if (file_format == FF_PROF)
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@@ -644,6 +633,23 @@ This program is free software. This program has absolutely no warranty.\n"));
|
|||||||
return 0;
|
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
|
void
|
||||||
done (int status)
|
done (int status)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -132,4 +132,6 @@ extern bool first_output; /* no output so far? */
|
|||||||
|
|
||||||
extern void done (int status) ATTRIBUTE_NORETURN;
|
extern void done (int status) ATTRIBUTE_NORETURN;
|
||||||
|
|
||||||
|
extern void symtab_init (void);
|
||||||
|
|
||||||
#endif /* gprof_h */
|
#endif /* gprof_h */
|
||||||
|
|||||||
31
gprof/hist.c
31
gprof/hist.c
@@ -294,8 +294,9 @@ scale_and_align_entries (void)
|
|||||||
Sym *sym;
|
Sym *sym;
|
||||||
bfd_vma bin_of_entry;
|
bfd_vma bin_of_entry;
|
||||||
bfd_vma bin_of_code;
|
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);
|
histogram *r = find_histogram_for_pc (sym->addr);
|
||||||
|
|
||||||
@@ -366,6 +367,7 @@ hist_assign_samples_1 (histogram *r)
|
|||||||
unsigned int bin_count;
|
unsigned int bin_count;
|
||||||
unsigned int i, j, k;
|
unsigned int i, j, k;
|
||||||
double count_time, credit;
|
double count_time, credit;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
bfd_vma lowpc = r->lowpc / sizeof (UNIT);
|
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
|
PR gprof/13325: Make sure that K does not get decremented
|
||||||
and J will never be less than 0. */
|
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_low_pc = symtab->base[j].hist.scaled_addr;
|
||||||
sym_high_pc = symtab.base[j + 1].hist.scaled_addr;
|
sym_high_pc = symtab->base[j + 1].hist.scaled_addr;
|
||||||
|
|
||||||
/* If high end of bin is below entry address,
|
/* If high end of bin is below entry address,
|
||||||
go for next bin. */
|
go for next bin. */
|
||||||
@@ -414,12 +416,12 @@ hist_assign_samples_1 (histogram *r)
|
|||||||
DBG (SAMPLEDEBUG,
|
DBG (SAMPLEDEBUG,
|
||||||
printf (
|
printf (
|
||||||
"[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
|
"[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),
|
(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));
|
(long) overlap));
|
||||||
|
|
||||||
addr = symtab.base[j].addr;
|
addr = symtab->base[j].addr;
|
||||||
credit = overlap * count_time / hist_scale;
|
credit = overlap * count_time / hist_scale;
|
||||||
|
|
||||||
/* Credit symbol if it appears in INCL_FLAT or that
|
/* 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
|
|| (syms[INCL_FLAT].len == 0
|
||||||
&& !sym_lookup (&syms[EXCL_FLAT], addr)))
|
&& !sym_lookup (&syms[EXCL_FLAT], addr)))
|
||||||
{
|
{
|
||||||
symtab.base[j].hist.time += credit;
|
symtab->base[j].hist.time += credit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -569,6 +571,7 @@ hist_print (void)
|
|||||||
unsigned log_scale;
|
unsigned log_scale;
|
||||||
double top_time;
|
double top_time;
|
||||||
bfd_vma addr;
|
bfd_vma addr;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
if (first_output)
|
if (first_output)
|
||||||
first_output = false;
|
first_output = false;
|
||||||
@@ -592,12 +595,12 @@ hist_print (void)
|
|||||||
|
|
||||||
/* Sort the symbol table by time (call-count and name as secondary
|
/* Sort the symbol table by time (call-count and name as secondary
|
||||||
and tertiary keys). */
|
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)
|
for (sym_index = 0; sym_index < symtab->len; ++sym_index)
|
||||||
time_sorted_syms[sym_index] = &symtab.base[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)
|
if (bsd_style_output)
|
||||||
{
|
{
|
||||||
@@ -611,7 +614,7 @@ hist_print (void)
|
|||||||
top_dog = 0;
|
top_dog = 0;
|
||||||
top_time = 0.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];
|
sym = time_sorted_syms[sym_index];
|
||||||
|
|
||||||
@@ -648,7 +651,7 @@ hist_print (void)
|
|||||||
I-cache misses etc.). */
|
I-cache misses etc.). */
|
||||||
print_header (SItab[log_scale].prefix);
|
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;
|
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;
|
unsigned char *instructp;
|
||||||
Sym *child;
|
Sym *child;
|
||||||
bfd_vma pc, destpc;
|
bfd_vma pc, destpc;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
|
DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
|
||||||
parent->name, (unsigned long) p_lowpc,
|
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;
|
destpc = bfd_get_32 (core_bfd, instructp + 1) + pc + 5;
|
||||||
if (hist_check_address (destpc))
|
if (hist_check_address (destpc))
|
||||||
{
|
{
|
||||||
child = sym_lookup (&symtab, destpc);
|
child = sym_lookup (symtab, destpc);
|
||||||
if (child && child->addr == 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;
|
int offset;
|
||||||
Sym *child;
|
Sym *child;
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
if (!inited)
|
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;
|
dest_pc = (pc & ~(bfd_vma) 0xfffffff) | offset;
|
||||||
if (hist_check_address (dest_pc))
|
if (hist_check_address (dest_pc))
|
||||||
{
|
{
|
||||||
child = sym_lookup (&symtab, dest_pc);
|
child = sym_lookup (symtab, dest_pc);
|
||||||
if (child)
|
if (child)
|
||||||
{
|
{
|
||||||
DBG (CALLDEBUG,
|
DBG (CALLDEBUG,
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ sparc_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
|
|||||||
bfd_vma pc, dest_pc;
|
bfd_vma pc, dest_pc;
|
||||||
unsigned int insn;
|
unsigned int insn;
|
||||||
Sym *child;
|
Sym *child;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
|
DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
|
||||||
parent->name, (unsigned long) p_lowpc,
|
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);
|
^ 0x20000000) - 0x20000000);
|
||||||
if (hist_check_address (dest_pc))
|
if (hist_check_address (dest_pc))
|
||||||
{
|
{
|
||||||
child = sym_lookup (&symtab, dest_pc);
|
child = sym_lookup (symtab, dest_pc);
|
||||||
if (child)
|
if (child)
|
||||||
{
|
{
|
||||||
DBG (CALLDEBUG,
|
DBG (CALLDEBUG,
|
||||||
|
|||||||
@@ -278,13 +278,14 @@ sym_id_parse (void)
|
|||||||
Sym *sym, *left, *right;
|
Sym *sym, *left, *right;
|
||||||
struct sym_id *id;
|
struct sym_id *id;
|
||||||
Sym_Table *tab;
|
Sym_Table *tab;
|
||||||
|
Sym_Table *symtab = get_symtab_direct ();
|
||||||
|
|
||||||
/* Convert symbol ids into Syms, so we can deal with them more easily. */
|
/* Convert symbol ids into Syms, so we can deal with them more easily. */
|
||||||
for (id = id_list; id; id = id->next)
|
for (id = id_list; id; id = id->next)
|
||||||
parse_id (id);
|
parse_id (id);
|
||||||
|
|
||||||
/* First determine size of each table. */
|
/* 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)
|
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. */
|
/* 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)
|
for (id = id_list; id; id = id->next)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,8 +28,40 @@
|
|||||||
|
|
||||||
static int cmp_addr (const void *, const void *);
|
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). */
|
/* Initialize a symbol (so it's empty). */
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,9 @@ typedef struct
|
|||||||
}
|
}
|
||||||
Sym_Table;
|
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 sym_init (Sym *);
|
||||||
extern void symtab_finalize (Sym_Table *);
|
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;
|
operandenum firstmode;
|
||||||
bfd_vma pc, destpc;
|
bfd_vma pc, destpc;
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
|
Sym_Table *symtab = get_symtab ();
|
||||||
|
|
||||||
if (!inited)
|
if (!inited)
|
||||||
{
|
{
|
||||||
@@ -321,7 +322,7 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
|
|||||||
destpc = pc + vax_offset (operand);
|
destpc = pc + vax_offset (operand);
|
||||||
if (hist_check_address (destpc))
|
if (hist_check_address (destpc))
|
||||||
{
|
{
|
||||||
child = sym_lookup (&symtab, destpc);
|
child = sym_lookup (symtab, destpc);
|
||||||
if (child)
|
if (child)
|
||||||
{
|
{
|
||||||
DBG (CALLDEBUG,
|
DBG (CALLDEBUG,
|
||||||
|
|||||||
Reference in New Issue
Block a user