This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: objdump -d --line-numbers performance question
- From: Nick Clifton <nickc at redhat dot com>
- To: Emile Snyder <binutils at talentcodeworks dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Tue, 01 Mar 2005 11:21:06 +0000
- Subject: Re: objdump -d --line-numbers performance question
- References: <1109363210.2119.229.camel@basalt>
Hi Emile,
Looking at elf_find_function() it jumps out that it's doing a linear
search through the entire set of symbols every time it's called. But
show_line() has access to find_symbol_for_address which does a binary
search on a sorted set of symbols.
So. The attached patch uses find_symbol_for_address() in show_line(),
and then passes down a fake asymbol** list consisting of just the found
symbol and a null end marker. So far it always produces identical
'objdump -d --line-numbers' output for me as the stock objdump, but my
run time on one representative file has gone from ~2 hours to ~4
minutes.
Does this look right? If not, can anyone give me some pointers on the
right way to try to optimize things?
Actually this looks like a very good idea. I only have two improvements
to suggest:
1. Be paranoid. If the call to bfd_find_nearest_line() fails to find
the desired information with the abbreviated symbol table then it should
be re-called with the full symbol table.
2. Use the latest sources. The 2.15 release is not going to have any
new features added to it, so it is best to produce a patch against the
latest sources in the binutils CVS repository.
To that end, please could you try out the attached patch which is meant
to address both of these points. If you can confirm that it does still
work (and reduce the search times) then I will commit it to the sources.
Cheers
Nick
Index: binutils/objdump.c
===================================================================
RCS file: /cvs/src/src/binutils/objdump.c,v
retrieving revision 1.100
diff -c -3 -p -r1.100 objdump.c
*** binutils/objdump.c 23 Feb 2005 12:25:57 -0000 1.100
--- binutils/objdump.c 1 Mar 2005 11:05:40 -0000
*************** skip_to_line (struct print_file_list *p,
*** 1026,1042 ****
listing. */
static void
! show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
{
! const char *filename;
! const char *functionname;
! unsigned int line;
if (! with_line_numbers && ! with_source_code)
return;
! if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename,
! &functionname, &line))
return;
if (filename != NULL && *filename == '\0')
--- 1026,1065 ----
listing. */
static void
! show_line (bfd *abfd, asection *section, bfd_vma addr_offset,
! struct disassemble_info * info)
{
! const char *filename = NULL;
! const char *functionname = NULL;
! unsigned int line = 0;
! asymbol *foundsym;
! long symplace;
if (! with_line_numbers && ! with_source_code)
return;
! /* bfd_find_nearest_line will perform a linear search of the symbol table
! for a matching address, but we already have a sorted symbol table and
! a binary search function, so try creating a fake symbol table first. */
! foundsym = find_symbol_for_address (section->vma + addr_offset,
! info, & symplace);
! if (foundsym)
! {
! asymbol *mocksyms[2];
!
! mocksyms[0] = foundsym;
! mocksyms[1] = NULL;
!
! /* We do not need to check the return code here since if it
! is zero then functionname will not have been initialised. */
! (void) bfd_find_nearest_line (abfd, section, mocksyms, addr_offset,
! & filename, & functionname, & line);
! }
!
! if ((functionname == NULL || filename == NULL)
! /* Ourt shortcut failed. Try a full search. */
! && (! bfd_find_nearest_line (abfd, section, syms, addr_offset,
! & filename, & functionname, & line)))
return;
if (filename != NULL && *filename == '\0')
*************** disassemble_bytes (struct disassemble_in
*** 1320,1326 ****
/* The line number tables will refer to unadjusted
section VMAs, so we must undo any VMA modifications
when calling show_line. */
! show_line (aux->abfd, section, addr_offset - adjust_section_vma);
if (! prefix_addresses)
{
--- 1343,1349 ----
/* The line number tables will refer to unadjusted
section VMAs, so we must undo any VMA modifications
when calling show_line. */
! show_line (aux->abfd, section, addr_offset - adjust_section_vma, info);
if (! prefix_addresses)
{