]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gprof: only process line numbers for intersection of vmas and histograms
authorRichard Allen <rsaxvc@gmail.com>
Sat, 8 Mar 2025 08:44:18 +0000 (16:44 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 14 Mar 2025 14:03:52 +0000 (07:03 -0700)
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>
19 files changed:
gprof/aarch64.c
gprof/alpha.c
gprof/basic_blocks.c
gprof/call_graph.c
gprof/cg_arcs.c
gprof/cg_print.c
gprof/corefile.c
gprof/gmon_io.c
gprof/gmon_io.h
gprof/gprof.c
gprof/gprof.h
gprof/hist.c
gprof/i386.c
gprof/mips.c
gprof/sparc.c
gprof/sym_ids.c
gprof/symtab.c
gprof/symtab.h
gprof/vax.c

index 3ab6067dbac9e4e73ad52955731716628d00d9b1..0365930961a70ab963362430d1514dabc1b8a9d1 100644 (file)
@@ -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)
                {
index df714be6c814ef32d539c1c55b8fa24e653e4929..b7740d8b58611e9faef6a16e67cde96ed7dcad4b 100644 (file)
@@ -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,
index 4a4e491495f5f84032ea7ff967bdf1dcf22b12f8..d8659382d2c58abcf88dec0a966f8e9e74f540dc 100644 (file)
@@ -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)
index 259cbaaef1ba93039725300a629bce66a2f7ecc8..b76a8adde58e5699b1275ac5365b7d020ae8e790 100644 (file)
@@ -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)
        {
index cfffb09ff87b68cae7ec5310e71a49c74ec6cc2e..a19686b2710e877330ee23b58c228c10126837fa 100644 (file)
@@ -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;
index 1d8e7d6b5b359d42fe2a9a987c2cc707de4319b2..c8e80d9d3a563e842ac356a42b416c9f23823b4b 100644 (file)
@@ -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;
     }
index bc26bd7883e820feea761b5d16ca7b5d6a2af9c5..74dbfb5cb8607985faadaf45b9910799f538295b 100644 (file)
@@ -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, &ltab.limit->name,
+                              &ltab.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, &ltab.limit->name, &ltab.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, &ltab.limit->name,
+                          &ltab.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 (&ltab);
-  free (symtab.base);
-  symtab = ltab;
+  free (symtab->base);
+  set_symtab (&ltab);
 }
index 9a069504d8532de29ad8c2ce671d682ff7bbd234..36ba7987a27567a7a888d0c5cea1b56e02b66df6 100644 (file)
@@ -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)
            {
index 746ca61f98e6349618e85cb10a14bcacc320de46..43c18693be591c5771a8e7cca19ae28dade46adf 100644 (file)
@@ -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);
index 9392575f7476348e6db8d111b3bf20aec44c1f0f..cea269bc80f4f4214a7840445619df739216a35d 100644 (file)
@@ -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)
 {
index 1d8d89647727c07584a5e9cd5b9c724ab9ce1c73..4222731603f10aa09e1896b731c4b8b7a74213d0 100644 (file)
@@ -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 */
index 2d3b0b11ac5566d44f6a4a4d32b8c262f306b807..ef4756531c6abe9b3188540a7ce7bef6c8ef9d66 100644 (file)
@@ -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;
 
index 62f6f96b20a6ea57d04224e1022a6613bd876e74..350dcb238dde242c12e5c475134f198d681d8197 100644 (file)
@@ -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)
                {
                  /*
index 0ccd17db525c2da2c83b23c70cb303b15ae36f65..873403c6a13b68894f13d7e1bd35805fe5f3e981 100644 (file)
@@ -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,
index 019e58b185fa6434b3ea35a8de9db1d2b0c8d036..ac0975eb012c24f4b72892ba4b61f88ca9fe7761 100644 (file)
@@ -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,
index 9f26679cfc009fbdad8aa08920119b16337df96c..81be06c6a8803c5b8383f6260890d2640481ae51 100644 (file)
@@ -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)
        {
index cc619aa728ef6b8ce895a404f1f7500e825e6591..e8b0b340680e1ba025ab30a1c7344fe5aeb07f88 100644 (file)
 
 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).  */
 
index 436f665f9a5c1f2b0ff4385c54030cd298846704..19031b917b015b83181ed213299f48ccbd99d557 100644 (file)
@@ -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 *);
index fafe2b17b53e6c2def76149b428ae1eb1b74b850..47cbe138b3dd1e88fad8e85976080072cd473504 100644 (file)
@@ -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,