diff options
author | Richard Allen <rsaxvc@gmail.com> | 2025-02-16 16:50:05 -0600 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-03-03 08:33:55 +1030 |
commit | b8189cf9e40bd90502c9a2ce0df39dd54419bea4 (patch) | |
tree | b3da28c7520f4fdc3cf9a24ceba3bac0ff7d6133 | |
parent | 44abbf103d1d30499a8f3081b3d893bbc7aae2eb (diff) | |
download | binutils-b8189cf9e40bd90502c9a2ce0df39dd54419bea4.zip binutils-b8189cf9e40bd90502c9a2ce0df39dd54419bea4.tar.gz binutils-b8189cf9e40bd90502c9a2ce0df39dd54419bea4.tar.bz2 |
gprof: only process line numbers for intersection of vmas and histograms
Some programs like RTOS firmware may have a large number of symbols.
By loading the histograms before loading symbols, we can look up
only the line numbers that were captured in the histogram file,
which reduces processing time for such a firmware from ~2 minutes
to ~2 seconds.
Signed-off-by: Richard Allen <rsaxvc@gmail.com>
-rw-r--r-- | gprof/corefile.c | 96 | ||||
-rw-r--r-- | gprof/gprof.c | 23 |
2 files changed, 63 insertions, 56 deletions
diff --git a/gprof/corefile.c b/gprof/corefile.c index bc26bd7..a8970b3 100644 --- a/gprof/corefile.c +++ b/gprof/corefile.c @@ -755,8 +755,9 @@ core_create_line_syms (void) Sym prev, *sym; const char *filename; Sym_Table ltab; - bfd_vma vma_high; size_t ltab_reserved; + 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,53 +787,58 @@ 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) + for (size_t i = 0; i < num_histograms; ++i) { - if (ltab.len >= ltab_reserved) + 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) { - /* 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; + if (ltab.len >= ltab_reserved) + { + /* Reserve more space for line symbols. */ + ltab_reserved *= 2; + ltab.base = xrealloc (ltab.base, ltab_reserved * sizeof (Sym)); + ltab.limit = ltab.base + ltab.len; + } + sym_init (ltab.limit); + + if (!get_src_info (vma, &filename, <ab.limit->name, <ab.limit->line_num) + || (prev.name && prev.line_num == ltab.limit->line_num + && strcmp (prev.name, ltab.limit->name) == 0 + && filename_cmp (prev.file->name, filename) == 0)) + continue; + + /* Make name pointer a malloc'ed string. */ + ltab.limit->name = xstrdup (ltab.limit->name); + ltab.limit->file = source_file_lookup_path (filename); + + ltab.limit->addr = vma; + + /* Set is_static based on the enclosing function, using either: + 1) the previous symbol, if it's from the same function, or + 2) a symtab lookup. */ + if (prev.name && ltab.limit->file == prev.file + && strcmp (ltab.limit->name, prev.name) == 0) + { + ltab.limit->is_static = prev.is_static; + } + else + { + sym = sym_lookup(&symtab, ltab.limit->addr); + if (sym) + ltab.limit->is_static = sym->is_static; + } + + 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; } - sym_init (ltab.limit); - - if (!get_src_info (vma, &filename, <ab.limit->name, <ab.limit->line_num) - || (prev.name && prev.line_num == ltab.limit->line_num - && strcmp (prev.name, ltab.limit->name) == 0 - && filename_cmp (prev.file->name, filename) == 0)) - continue; - - /* Make name pointer a malloc'ed string. */ - ltab.limit->name = xstrdup (ltab.limit->name); - ltab.limit->file = source_file_lookup_path (filename); - - ltab.limit->addr = vma; - - /* Set is_static based on the enclosing function, using either: - 1) the previous symbol, if it's from the same function, or - 2) a symtab lookup. */ - if (ltab.limit->file == prev.file - && strcmp (ltab.limit->name, prev.name) == 0) - { - ltab.limit->is_static = prev.is_static; - } - else - { - sym = sym_lookup(&symtab, ltab.limit->addr); - if (sym) - ltab.limit->is_static = sym->is_static; - } - - prev = *ltab.limit; - - DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n", - (unsigned long) (ltab.limit - ltab.base), - ltab.limit->name, - (unsigned long) ltab.limit->addr)); - ++ltab.limit; - ++ltab.len; } /* Reserve space for function symbols and/or trim excess space. */ diff --git a/gprof/gprof.c b/gprof/gprof.c index 9392575..d1cbf25 100644 --- a/gprof/gprof.c +++ b/gprof/gprof.c @@ -527,17 +527,6 @@ This program is free software. This program has absolutely no warranty.\n")); if (ignore_direct_calls) core_get_text_space (core_bfd); - /* Create symbols from core image. */ - if (external_symbol_table) - core_create_syms_from (external_symbol_table); - else if (line_granularity) - core_create_line_syms (); - else - core_create_function_syms (); - - /* Translate sym specs into syms. */ - sym_id_parse (); - if (file_format == FF_PROF) { fprintf (stderr, @@ -557,6 +546,18 @@ This program is free software. This program has absolutely no warranty.\n")); while (optind++ < argc); } + /* 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 user did not specify output style, try to guess something reasonable. */ if (output_style == 0) |