This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: objdump -d --line-numbers performance question


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)
  	    {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]